blob: 6cc228ab46065d7b833b09e6cfbbdb2a5df0b360 [file] [log] [blame]
Fabio Estevam77e62892012-09-13 03:18:20 +00001/*
2 * Copyright (C) 2012 Freescale Semiconductor, Inc.
3 *
4 * Author: Fabio Estevam <fabio.estevam@freescale.com>
5 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
Fabio Estevam77e62892012-09-13 03:18:20 +00007 */
8
Fabio Estevam77e62892012-09-13 03:18:20 +00009#include <asm/arch/clock.h>
10#include <asm/arch/imx-regs.h>
11#include <asm/arch/iomux.h>
Pierre Aubertec10aed2013-06-04 09:00:15 +020012#include <asm/arch/mx6-pins.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090013#include <linux/errno.h>
Fabio Estevam77e62892012-09-13 03:18:20 +000014#include <asm/gpio.h>
Stefano Babic33731bc2017-06-29 10:16:06 +020015#include <asm/mach-imx/mxc_i2c.h>
16#include <asm/mach-imx/iomux-v3.h>
17#include <asm/mach-imx/boot_mode.h>
18#include <asm/mach-imx/video.h>
Fabio Estevam77e62892012-09-13 03:18:20 +000019#include <mmc.h>
20#include <fsl_esdhc.h>
21#include <miiphy.h>
22#include <netdev.h>
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -050023#include <asm/arch/mxc_hdmi.h>
24#include <asm/arch/crm_regs.h>
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -050025#include <asm/io.h>
26#include <asm/arch/sys_proto.h>
Fabio Estevamba92ad62014-05-09 13:15:42 -030027#include <i2c.h>
Diego Dorta2661c9c2017-09-22 12:12:18 -030028#include <input.h>
Fabio Estevamba92ad62014-05-09 13:15:42 -030029#include <power/pmic.h>
30#include <power/pfuze100_pmic.h>
Ye.Li75e02f92014-11-06 16:29:00 +080031#include "../common/pfuze.h"
Peng Fanc9498fa2014-12-02 09:55:27 +080032#include <usb.h>
John Tobias07491552014-11-12 14:27:45 -080033
Fabio Estevam77e62892012-09-13 03:18:20 +000034DECLARE_GLOBAL_DATA_PTR;
35
Benoît Thébaudeau21670242013-04-26 01:34:47 +000036#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
37 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
38 PAD_CTL_SRE_FAST | PAD_CTL_HYS)
Fabio Estevam77e62892012-09-13 03:18:20 +000039
Benoît Thébaudeau21670242013-04-26 01:34:47 +000040#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
41 PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
42 PAD_CTL_SRE_FAST | PAD_CTL_HYS)
Fabio Estevam77e62892012-09-13 03:18:20 +000043
Benoît Thébaudeau21670242013-04-26 01:34:47 +000044#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
45 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
Fabio Estevam77e62892012-09-13 03:18:20 +000046
Fabio Estevamd82dad42013-11-08 16:20:54 -020047#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
48 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
49
Fabio Estevamba92ad62014-05-09 13:15:42 -030050#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
51 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
52 PAD_CTL_ODE | PAD_CTL_SRE_FAST)
53
54#define I2C_PMIC 1
55
56#define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL)
57
Fabio Estevam0d29cee2014-10-21 21:14:53 -020058#define DISP0_PWR_EN IMX_GPIO_NR(1, 21)
59
Diego Dorta466016e2016-10-11 11:09:27 -030060#define KEY_VOL_UP IMX_GPIO_NR(1, 4)
61
Fabio Estevam77e62892012-09-13 03:18:20 +000062int dram_init(void)
63{
John Tobias07491552014-11-12 14:27:45 -080064 gd->ram_size = imx_ddr_size();
Fabio Estevam77e62892012-09-13 03:18:20 +000065 return 0;
66}
67
Fabio Estevamf533c2e2014-11-06 12:24:25 -020068static iomux_v3_cfg_t const uart1_pads[] = {
Fabio Estevamc88f1672017-05-12 12:45:23 -030069 IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
70 IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
Fabio Estevam77e62892012-09-13 03:18:20 +000071};
72
Fabio Estevamf533c2e2014-11-06 12:24:25 -020073static iomux_v3_cfg_t const enet_pads[] = {
Fabio Estevamc88f1672017-05-12 12:45:23 -030074 IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
75 IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
76 IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
77 IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
78 IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
79 IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
80 IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
81 IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
82 IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL)),
83 IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
84 IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
85 IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
86 IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
87 IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
88 IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
Fabio Estevam2ebe2462012-09-18 17:24:23 +000089 /* AR8031 PHY Reset */
Fabio Estevamc88f1672017-05-12 12:45:23 -030090 IOMUX_PADS(PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Fabio Estevam2ebe2462012-09-18 17:24:23 +000091};
92
93static void setup_iomux_enet(void)
94{
Fabio Estevamc88f1672017-05-12 12:45:23 -030095 SETUP_IOMUX_PADS(enet_pads);
Fabio Estevam2ebe2462012-09-18 17:24:23 +000096
97 /* Reset AR8031 PHY */
98 gpio_direction_output(IMX_GPIO_NR(1, 25) , 0);
Fabio Estevam66d42722016-01-05 17:02:53 -020099 mdelay(10);
Fabio Estevam2ebe2462012-09-18 17:24:23 +0000100 gpio_set_value(IMX_GPIO_NR(1, 25), 1);
Fabio Estevam66d42722016-01-05 17:02:53 -0200101 udelay(100);
Fabio Estevam2ebe2462012-09-18 17:24:23 +0000102}
103
Fabio Estevamf533c2e2014-11-06 12:24:25 -0200104static iomux_v3_cfg_t const usdhc2_pads[] = {
Fabio Estevamc88f1672017-05-12 12:45:23 -0300105 IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
106 IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
107 IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
108 IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
109 IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
110 IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
111 IOMUX_PADS(PAD_NANDF_D4__SD2_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
112 IOMUX_PADS(PAD_NANDF_D5__SD2_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
113 IOMUX_PADS(PAD_NANDF_D6__SD2_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
114 IOMUX_PADS(PAD_NANDF_D7__SD2_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
115 IOMUX_PADS(PAD_NANDF_D2__GPIO2_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL)), /* CD */
Shawn Guo7e5e8332012-12-30 14:14:59 +0000116};
117
Fabio Estevamf533c2e2014-11-06 12:24:25 -0200118static iomux_v3_cfg_t const usdhc3_pads[] = {
Fabio Estevamc88f1672017-05-12 12:45:23 -0300119 IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
120 IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
121 IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
122 IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
123 IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
124 IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
125 IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
126 IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
127 IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
128 IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
129 IOMUX_PADS(PAD_NANDF_D0__GPIO2_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL)), /* CD */
Fabio Estevam77e62892012-09-13 03:18:20 +0000130};
131
Fabio Estevamf533c2e2014-11-06 12:24:25 -0200132static iomux_v3_cfg_t const usdhc4_pads[] = {
Fabio Estevamc88f1672017-05-12 12:45:23 -0300133 IOMUX_PADS(PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
134 IOMUX_PADS(PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
135 IOMUX_PADS(PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
136 IOMUX_PADS(PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
137 IOMUX_PADS(PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
138 IOMUX_PADS(PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
139 IOMUX_PADS(PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
140 IOMUX_PADS(PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
141 IOMUX_PADS(PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
142 IOMUX_PADS(PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
Shawn Guo7e5e8332012-12-30 14:14:59 +0000143};
144
Fabio Estevamf533c2e2014-11-06 12:24:25 -0200145static iomux_v3_cfg_t const ecspi1_pads[] = {
Fabio Estevamc88f1672017-05-12 12:45:23 -0300146 IOMUX_PADS(PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL)),
147 IOMUX_PADS(PAD_KEY_COL1__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL)),
148 IOMUX_PADS(PAD_KEY_ROW0__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL)),
149 IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Fabio Estevamd82dad42013-11-08 16:20:54 -0200150};
151
Fabio Estevam0d29cee2014-10-21 21:14:53 -0200152static iomux_v3_cfg_t const rgb_pads[] = {
Fabio Estevamc88f1672017-05-12 12:45:23 -0300153 IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)),
154 IOMUX_PADS(PAD_DI0_PIN15__IPU1_DI0_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
155 IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
156 IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03 | MUX_PAD_CTRL(NO_PAD_CTRL)),
157 IOMUX_PADS(PAD_DI0_PIN4__IPU1_DI0_PIN04 | MUX_PAD_CTRL(NO_PAD_CTRL)),
158 IOMUX_PADS(PAD_DISP0_DAT0__IPU1_DISP0_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL)),
159 IOMUX_PADS(PAD_DISP0_DAT1__IPU1_DISP0_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL)),
160 IOMUX_PADS(PAD_DISP0_DAT2__IPU1_DISP0_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
161 IOMUX_PADS(PAD_DISP0_DAT3__IPU1_DISP0_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL)),
162 IOMUX_PADS(PAD_DISP0_DAT4__IPU1_DISP0_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL)),
163 IOMUX_PADS(PAD_DISP0_DAT5__IPU1_DISP0_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
164 IOMUX_PADS(PAD_DISP0_DAT6__IPU1_DISP0_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
165 IOMUX_PADS(PAD_DISP0_DAT7__IPU1_DISP0_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
166 IOMUX_PADS(PAD_DISP0_DAT8__IPU1_DISP0_DATA08 | MUX_PAD_CTRL(NO_PAD_CTRL)),
167 IOMUX_PADS(PAD_DISP0_DAT9__IPU1_DISP0_DATA09 | MUX_PAD_CTRL(NO_PAD_CTRL)),
168 IOMUX_PADS(PAD_DISP0_DAT10__IPU1_DISP0_DATA10 | MUX_PAD_CTRL(NO_PAD_CTRL)),
169 IOMUX_PADS(PAD_DISP0_DAT11__IPU1_DISP0_DATA11 | MUX_PAD_CTRL(NO_PAD_CTRL)),
170 IOMUX_PADS(PAD_DISP0_DAT12__IPU1_DISP0_DATA12 | MUX_PAD_CTRL(NO_PAD_CTRL)),
171 IOMUX_PADS(PAD_DISP0_DAT13__IPU1_DISP0_DATA13 | MUX_PAD_CTRL(NO_PAD_CTRL)),
172 IOMUX_PADS(PAD_DISP0_DAT14__IPU1_DISP0_DATA14 | MUX_PAD_CTRL(NO_PAD_CTRL)),
173 IOMUX_PADS(PAD_DISP0_DAT15__IPU1_DISP0_DATA15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
174 IOMUX_PADS(PAD_DISP0_DAT16__IPU1_DISP0_DATA16 | MUX_PAD_CTRL(NO_PAD_CTRL)),
175 IOMUX_PADS(PAD_DISP0_DAT17__IPU1_DISP0_DATA17 | MUX_PAD_CTRL(NO_PAD_CTRL)),
176 IOMUX_PADS(PAD_DISP0_DAT18__IPU1_DISP0_DATA18 | MUX_PAD_CTRL(NO_PAD_CTRL)),
177 IOMUX_PADS(PAD_DISP0_DAT19__IPU1_DISP0_DATA19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
178 IOMUX_PADS(PAD_DISP0_DAT20__IPU1_DISP0_DATA20 | MUX_PAD_CTRL(NO_PAD_CTRL)),
179 IOMUX_PADS(PAD_DISP0_DAT21__IPU1_DISP0_DATA21 | MUX_PAD_CTRL(NO_PAD_CTRL)),
180 IOMUX_PADS(PAD_DISP0_DAT22__IPU1_DISP0_DATA22 | MUX_PAD_CTRL(NO_PAD_CTRL)),
181 IOMUX_PADS(PAD_DISP0_DAT23__IPU1_DISP0_DATA23 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Marco Franchi029d07f2016-06-08 15:05:31 -0300182};
183
184static iomux_v3_cfg_t const bl_pads[] = {
Fabio Estevamc88f1672017-05-12 12:45:23 -0300185 IOMUX_PADS(PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Fabio Estevam0d29cee2014-10-21 21:14:53 -0200186};
187
Marco Franchi029d07f2016-06-08 15:05:31 -0300188static void enable_backlight(void)
189{
Fabio Estevamc88f1672017-05-12 12:45:23 -0300190 SETUP_IOMUX_PADS(bl_pads);
Marco Franchi029d07f2016-06-08 15:05:31 -0300191 gpio_direction_output(DISP0_PWR_EN, 1);
192}
193
Fabio Estevam0d29cee2014-10-21 21:14:53 -0200194static void enable_rgb(struct display_info_t const *dev)
195{
Fabio Estevamc88f1672017-05-12 12:45:23 -0300196 SETUP_IOMUX_PADS(rgb_pads);
Marco Franchi029d07f2016-06-08 15:05:31 -0300197 enable_backlight();
198}
199
200static void enable_lvds(struct display_info_t const *dev)
201{
202 enable_backlight();
Fabio Estevam0d29cee2014-10-21 21:14:53 -0200203}
204
Fabio Estevamc88f1672017-05-12 12:45:23 -0300205static struct i2c_pads_info mx6q_i2c_pad_info1 = {
Fabio Estevamba92ad62014-05-09 13:15:42 -0300206 .scl = {
Fabio Estevamc88f1672017-05-12 12:45:23 -0300207 .i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | I2C_PAD,
208 .gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 | I2C_PAD,
Fabio Estevamba92ad62014-05-09 13:15:42 -0300209 .gp = IMX_GPIO_NR(4, 12)
210 },
211 .sda = {
Fabio Estevamc88f1672017-05-12 12:45:23 -0300212 .i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | I2C_PAD,
213 .gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | I2C_PAD,
Fabio Estevamba92ad62014-05-09 13:15:42 -0300214 .gp = IMX_GPIO_NR(4, 13)
215 }
216};
217
Fabio Estevamc88f1672017-05-12 12:45:23 -0300218static struct i2c_pads_info mx6dl_i2c_pad_info1 = {
219 .scl = {
220 .i2c_mode = MX6DL_PAD_KEY_COL3__I2C2_SCL | I2C_PAD,
221 .gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12 | I2C_PAD,
222 .gp = IMX_GPIO_NR(4, 12)
223 },
224 .sda = {
225 .i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | I2C_PAD,
226 .gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | I2C_PAD,
227 .gp = IMX_GPIO_NR(4, 13)
228 }
229};
230
Fabio Estevamd82dad42013-11-08 16:20:54 -0200231static void setup_spi(void)
232{
Fabio Estevamc88f1672017-05-12 12:45:23 -0300233 SETUP_IOMUX_PADS(ecspi1_pads);
Fabio Estevamd82dad42013-11-08 16:20:54 -0200234}
235
Marek Vasut0e99f012014-03-23 22:45:41 +0100236iomux_v3_cfg_t const pcie_pads[] = {
Fabio Estevamc88f1672017-05-12 12:45:23 -0300237 IOMUX_PADS(PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL)), /* POWER */
238 IOMUX_PADS(PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL)), /* RESET */
Marek Vasut0e99f012014-03-23 22:45:41 +0100239};
240
241static void setup_pcie(void)
242{
Fabio Estevamc88f1672017-05-12 12:45:23 -0300243 SETUP_IOMUX_PADS(pcie_pads);
Marek Vasut0e99f012014-03-23 22:45:41 +0100244}
245
Fabio Estevamdee3c842013-12-04 01:08:16 -0200246iomux_v3_cfg_t const di0_pads[] = {
Fabio Estevamc88f1672017-05-12 12:45:23 -0300247 IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK), /* DISP0_CLK */
248 IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02), /* DISP0_HSYNC */
249 IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03), /* DISP0_VSYNC */
Fabio Estevamdee3c842013-12-04 01:08:16 -0200250};
251
Fabio Estevam77e62892012-09-13 03:18:20 +0000252static void setup_iomux_uart(void)
253{
Fabio Estevamc88f1672017-05-12 12:45:23 -0300254 SETUP_IOMUX_PADS(uart1_pads);
Fabio Estevam77e62892012-09-13 03:18:20 +0000255}
256
257#ifdef CONFIG_FSL_ESDHC
Shawn Guo7e5e8332012-12-30 14:14:59 +0000258struct fsl_esdhc_cfg usdhc_cfg[3] = {
259 {USDHC2_BASE_ADDR},
Fabio Estevam77e62892012-09-13 03:18:20 +0000260 {USDHC3_BASE_ADDR},
Shawn Guo7e5e8332012-12-30 14:14:59 +0000261 {USDHC4_BASE_ADDR},
Fabio Estevam77e62892012-09-13 03:18:20 +0000262};
263
Shawn Guo7e5e8332012-12-30 14:14:59 +0000264#define USDHC2_CD_GPIO IMX_GPIO_NR(2, 2)
265#define USDHC3_CD_GPIO IMX_GPIO_NR(2, 0)
266
Peng Fan03a43df2016-01-28 16:51:27 +0800267int board_mmc_get_env_dev(int devno)
268{
269 return devno - 1;
270}
271
Fabio Estevam77e62892012-09-13 03:18:20 +0000272int board_mmc_getcd(struct mmc *mmc)
273{
Shawn Guo7e5e8332012-12-30 14:14:59 +0000274 struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
Otavio Salvadorc2bed642013-03-16 08:05:06 +0000275 int ret = 0;
Shawn Guo7e5e8332012-12-30 14:14:59 +0000276
277 switch (cfg->esdhc_base) {
278 case USDHC2_BASE_ADDR:
Otavio Salvadorc2bed642013-03-16 08:05:06 +0000279 ret = !gpio_get_value(USDHC2_CD_GPIO);
280 break;
Shawn Guo7e5e8332012-12-30 14:14:59 +0000281 case USDHC3_BASE_ADDR:
Otavio Salvadorc2bed642013-03-16 08:05:06 +0000282 ret = !gpio_get_value(USDHC3_CD_GPIO);
283 break;
284 case USDHC4_BASE_ADDR:
285 ret = 1; /* eMMC/uSDHC4 is always present */
286 break;
Shawn Guo7e5e8332012-12-30 14:14:59 +0000287 }
Otavio Salvadorc2bed642013-03-16 08:05:06 +0000288
289 return ret;
Fabio Estevam77e62892012-09-13 03:18:20 +0000290}
291
292int board_mmc_init(bd_t *bis)
293{
John Tobias07491552014-11-12 14:27:45 -0800294#ifndef CONFIG_SPL_BUILD
Fabio Estevam593d0c82014-11-06 12:24:24 -0200295 int ret;
Shawn Guo7e5e8332012-12-30 14:14:59 +0000296 int i;
297
Otavio Salvadora272dbf2013-03-16 08:05:05 +0000298 /*
299 * According to the board_mmc_init() the following map is done:
Bin Meng75574052016-02-05 19:30:11 -0800300 * (U-Boot device node) (Physical Port)
Otavio Salvadora272dbf2013-03-16 08:05:05 +0000301 * mmc0 SD2
302 * mmc1 SD3
303 * mmc2 eMMC
304 */
Shawn Guo7e5e8332012-12-30 14:14:59 +0000305 for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
306 switch (i) {
307 case 0:
Fabio Estevamc88f1672017-05-12 12:45:23 -0300308 SETUP_IOMUX_PADS(usdhc2_pads);
Shawn Guo7e5e8332012-12-30 14:14:59 +0000309 gpio_direction_input(USDHC2_CD_GPIO);
310 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
311 break;
312 case 1:
Fabio Estevamc88f1672017-05-12 12:45:23 -0300313 SETUP_IOMUX_PADS(usdhc3_pads);
Shawn Guo7e5e8332012-12-30 14:14:59 +0000314 gpio_direction_input(USDHC3_CD_GPIO);
315 usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
316 break;
317 case 2:
Fabio Estevamc88f1672017-05-12 12:45:23 -0300318 SETUP_IOMUX_PADS(usdhc4_pads);
Shawn Guo7e5e8332012-12-30 14:14:59 +0000319 usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
320 break;
321 default:
322 printf("Warning: you configured more USDHC controllers"
Otavio Salvadora937e222013-04-19 03:41:58 +0000323 "(%d) then supported by the board (%d)\n",
324 i + 1, CONFIG_SYS_FSL_USDHC_NUM);
Fabio Estevam593d0c82014-11-06 12:24:24 -0200325 return -EINVAL;
Otavio Salvadora937e222013-04-19 03:41:58 +0000326 }
Shawn Guo7e5e8332012-12-30 14:14:59 +0000327
Fabio Estevam593d0c82014-11-06 12:24:24 -0200328 ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
329 if (ret)
330 return ret;
Shawn Guo7e5e8332012-12-30 14:14:59 +0000331 }
Fabio Estevam77e62892012-09-13 03:18:20 +0000332
Fabio Estevam593d0c82014-11-06 12:24:24 -0200333 return 0;
John Tobias07491552014-11-12 14:27:45 -0800334#else
Fabio Estevam56cf36a2014-11-18 11:26:06 -0200335 struct src *psrc = (struct src *)SRC_BASE_ADDR;
336 unsigned reg = readl(&psrc->sbmr1) >> 11;
John Tobias07491552014-11-12 14:27:45 -0800337 /*
338 * Upon reading BOOT_CFG register the following map is done:
339 * Bit 11 and 12 of BOOT_CFG register can determine the current
340 * mmc port
341 * 0x1 SD1
342 * 0x2 SD2
343 * 0x3 SD4
344 */
345
346 switch (reg & 0x3) {
347 case 0x1:
Fabio Estevamc88f1672017-05-12 12:45:23 -0300348 SETUP_IOMUX_PADS(usdhc2_pads);
John Tobias07491552014-11-12 14:27:45 -0800349 usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
350 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
351 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
352 break;
353 case 0x2:
Fabio Estevamc88f1672017-05-12 12:45:23 -0300354 SETUP_IOMUX_PADS(usdhc3_pads);
John Tobias07491552014-11-12 14:27:45 -0800355 usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
356 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
357 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
358 break;
359 case 0x3:
Fabio Estevamc88f1672017-05-12 12:45:23 -0300360 SETUP_IOMUX_PADS(usdhc4_pads);
John Tobias07491552014-11-12 14:27:45 -0800361 usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
362 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
363 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
364 break;
365 }
366
367 return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
368#endif
Fabio Estevam77e62892012-09-13 03:18:20 +0000369}
370#endif
371
Fabio Estevam509c06f2016-10-24 10:22:06 -0200372static int ar8031_phy_fixup(struct phy_device *phydev)
373{
374 unsigned short val;
375
376 /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
377 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
378 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
379 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
380
381 val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
382 val &= 0xffe3;
383 val |= 0x18;
384 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
385
386 /* introduce tx clock delay */
387 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
388 val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
389 val |= 0x0100;
390 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
391
392 return 0;
393}
394
395int board_phy_config(struct phy_device *phydev)
396{
397 ar8031_phy_fixup(phydev);
398
399 if (phydev->drv->config)
400 phydev->drv->config(phydev);
401
402 return 0;
403}
404
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500405#if defined(CONFIG_VIDEO_IPUV3)
Fabio Estevam70f84b52013-11-25 10:34:26 -0200406static void disable_lvds(struct display_info_t const *dev)
407{
408 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
409
410 int reg = readl(&iomux->gpr[2]);
411
412 reg &= ~(IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
413 IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
414
415 writel(reg, &iomux->gpr[2]);
416}
417
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300418static void do_enable_hdmi(struct display_info_t const *dev)
419{
Fabio Estevam70f84b52013-11-25 10:34:26 -0200420 disable_lvds(dev);
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300421 imx_enable_hdmi_phy();
422}
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500423
Eric Benardd6cabb22014-04-04 19:05:54 +0200424struct display_info_t const displays[] = {{
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300425 .bus = -1,
426 .addr = 0,
Fabio Estevam7d66d562013-12-04 01:08:17 -0200427 .pixfmt = IPU_PIX_FMT_RGB666,
Fabio Estevam70f84b52013-11-25 10:34:26 -0200428 .detect = NULL,
Marco Franchi029d07f2016-06-08 15:05:31 -0300429 .enable = enable_lvds,
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300430 .mode = {
Fabio Estevam70f84b52013-11-25 10:34:26 -0200431 .name = "Hannstar-XGA",
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300432 .refresh = 60,
433 .xres = 1024,
434 .yres = 768,
Fabio Estevame2b20032016-03-16 12:55:03 -0300435 .pixclock = 15384,
436 .left_margin = 160,
437 .right_margin = 24,
438 .upper_margin = 29,
439 .lower_margin = 3,
440 .hsync_len = 136,
441 .vsync_len = 6,
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300442 .sync = FB_SYNC_EXT,
443 .vmode = FB_VMODE_NONINTERLACED
444} }, {
445 .bus = -1,
446 .addr = 0,
Fabio Estevam70f84b52013-11-25 10:34:26 -0200447 .pixfmt = IPU_PIX_FMT_RGB24,
448 .detect = detect_hdmi,
449 .enable = do_enable_hdmi,
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300450 .mode = {
Fabio Estevam70f84b52013-11-25 10:34:26 -0200451 .name = "HDMI",
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300452 .refresh = 60,
453 .xres = 1024,
454 .yres = 768,
Fabio Estevame2b20032016-03-16 12:55:03 -0300455 .pixclock = 15384,
456 .left_margin = 160,
457 .right_margin = 24,
458 .upper_margin = 29,
459 .lower_margin = 3,
460 .hsync_len = 136,
461 .vsync_len = 6,
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300462 .sync = FB_SYNC_EXT,
463 .vmode = FB_VMODE_NONINTERLACED
Fabio Estevam0d29cee2014-10-21 21:14:53 -0200464} }, {
465 .bus = 0,
466 .addr = 0,
467 .pixfmt = IPU_PIX_FMT_RGB24,
468 .detect = NULL,
469 .enable = enable_rgb,
470 .mode = {
471 .name = "SEIKO-WVGA",
472 .refresh = 60,
473 .xres = 800,
474 .yres = 480,
475 .pixclock = 29850,
476 .left_margin = 89,
477 .right_margin = 164,
478 .upper_margin = 23,
479 .lower_margin = 10,
480 .hsync_len = 10,
481 .vsync_len = 10,
482 .sync = 0,
483 .vmode = FB_VMODE_NONINTERLACED
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300484} } };
Eric Benardd6cabb22014-04-04 19:05:54 +0200485size_t display_count = ARRAY_SIZE(displays);
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500486
487static void setup_display(void)
488{
489 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300490 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500491 int reg;
492
Fabio Estevamdee3c842013-12-04 01:08:16 -0200493 /* Setup HSYNC, VSYNC, DISP_CLK for debugging purposes */
Fabio Estevamc88f1672017-05-12 12:45:23 -0300494 SETUP_IOMUX_PADS(di0_pads);
Fabio Estevamdee3c842013-12-04 01:08:16 -0200495
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500496 enable_ipu_clock();
497 imx_setup_hdmi();
498
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300499 /* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
Liu Ying6f450632013-11-29 22:38:39 +0800500 reg = readl(&mxc_ccm->CCGR3);
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300501 reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
502 writel(reg, &mxc_ccm->CCGR3);
503
504 /* set LDB0, LDB1 clk select to 011/011 */
505 reg = readl(&mxc_ccm->cs2cdr);
506 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
507 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
508 reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
509 | (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
510 writel(reg, &mxc_ccm->cs2cdr);
511
512 reg = readl(&mxc_ccm->cscmr2);
513 reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
514 writel(reg, &mxc_ccm->cscmr2);
515
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500516 reg = readl(&mxc_ccm->chsccdr);
517 reg |= (CHSCCDR_CLK_SEL_LDB_DI0
518 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300519 reg |= (CHSCCDR_CLK_SEL_LDB_DI0
520 << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500521 writel(reg, &mxc_ccm->chsccdr);
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300522
523 reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
524 | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
525 | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
526 | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
527 | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
528 | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
529 | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
530 | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
531 | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
532 writel(reg, &iomux->gpr[2]);
533
534 reg = readl(&iomux->gpr[3]);
535 reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK
536 | IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
537 | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
538 << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
539 writel(reg, &iomux->gpr[3]);
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500540}
541#endif /* CONFIG_VIDEO_IPUV3 */
542
543/*
544 * Do not overwrite the console
545 * Use always serial for U-Boot console
546 */
547int overwrite_console(void)
548{
549 return 1;
550}
551
Fabio Estevam2ebe2462012-09-18 17:24:23 +0000552int board_eth_init(bd_t *bis)
553{
Fabio Estevam2ebe2462012-09-18 17:24:23 +0000554 setup_iomux_enet();
Marek Vasut0e99f012014-03-23 22:45:41 +0100555 setup_pcie();
Fabio Estevam2ebe2462012-09-18 17:24:23 +0000556
Fabio Estevamfa3ae402014-01-04 17:36:32 -0200557 return cpu_eth_init(bis);
Fabio Estevam2ebe2462012-09-18 17:24:23 +0000558}
559
Peng Fanc9498fa2014-12-02 09:55:27 +0800560#ifdef CONFIG_USB_EHCI_MX6
561#define USB_OTHERREGS_OFFSET 0x800
562#define UCTRL_PWR_POL (1 << 9)
563
564static iomux_v3_cfg_t const usb_otg_pads[] = {
Fabio Estevamc88f1672017-05-12 12:45:23 -0300565 IOMUX_PADS(PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL)),
566 IOMUX_PADS(PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL)),
Peng Fanc9498fa2014-12-02 09:55:27 +0800567};
568
569static iomux_v3_cfg_t const usb_hc1_pads[] = {
Fabio Estevamc88f1672017-05-12 12:45:23 -0300570 IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Peng Fanc9498fa2014-12-02 09:55:27 +0800571};
572
573static void setup_usb(void)
574{
Fabio Estevamc88f1672017-05-12 12:45:23 -0300575 SETUP_IOMUX_PADS(usb_otg_pads);
Peng Fanc9498fa2014-12-02 09:55:27 +0800576
577 /*
578 * set daisy chain for otg_pin_id on 6q.
579 * for 6dl, this bit is reserved
580 */
581 imx_iomux_set_gpr_register(1, 13, 1, 0);
582
Fabio Estevamc88f1672017-05-12 12:45:23 -0300583 SETUP_IOMUX_PADS(usb_hc1_pads);
Peng Fanc9498fa2014-12-02 09:55:27 +0800584}
585
586int board_ehci_hcd_init(int port)
587{
588 u32 *usbnc_usb_ctrl;
589
590 if (port > 1)
591 return -EINVAL;
592
593 usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
594 port * 4);
595
596 setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
597
598 return 0;
599}
600
601int board_ehci_power(int port, int on)
602{
603 switch (port) {
604 case 0:
605 break;
606 case 1:
607 if (on)
608 gpio_direction_output(IMX_GPIO_NR(1, 29), 1);
609 else
610 gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
611 break;
612 default:
613 printf("MXC USB port %d not yet supported\n", port);
614 return -EINVAL;
615 }
616
617 return 0;
618}
619#endif
620
Fabio Estevam77e62892012-09-13 03:18:20 +0000621int board_early_init_f(void)
622{
623 setup_iomux_uart();
624
625 return 0;
626}
627
628int board_init(void)
629{
630 /* address of boot parameters */
631 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
632
Fabio Estevamd82dad42013-11-08 16:20:54 -0200633#ifdef CONFIG_MXC_SPI
634 setup_spi();
635#endif
Fabio Estevamc88f1672017-05-12 12:45:23 -0300636 if (is_mx6dq() || is_mx6dqp())
637 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1);
638 else
639 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
Fabio Estevam6f73a292017-09-22 23:45:28 -0300640#if defined(CONFIG_VIDEO_IPUV3)
641 setup_display();
642#endif
Peng Fanc9498fa2014-12-02 09:55:27 +0800643#ifdef CONFIG_USB_EHCI_MX6
644 setup_usb();
645#endif
646
Fabio Estevamba92ad62014-05-09 13:15:42 -0300647 return 0;
648}
649
Ye.Li75e02f92014-11-06 16:29:00 +0800650int power_init_board(void)
Fabio Estevamba92ad62014-05-09 13:15:42 -0300651{
652 struct pmic *p;
Fabio Estevameffbec12015-07-21 20:02:49 -0300653 unsigned int reg;
654 int ret;
Fabio Estevamba92ad62014-05-09 13:15:42 -0300655
Ye.Li75e02f92014-11-06 16:29:00 +0800656 p = pfuze_common_init(I2C_PMIC);
657 if (!p)
658 return -ENODEV;
Fabio Estevamba92ad62014-05-09 13:15:42 -0300659
Peng Fane5bcd4d2015-01-27 10:14:04 +0800660 ret = pfuze_mode_init(p, APS_PFM);
661 if (ret < 0)
662 return ret;
663
Fabio Estevamba92ad62014-05-09 13:15:42 -0300664 /* Increase VGEN3 from 2.5 to 2.8V */
665 pmic_reg_read(p, PFUZE100_VGEN3VOL, &reg);
Ye.Li75e02f92014-11-06 16:29:00 +0800666 reg &= ~LDO_VOL_MASK;
667 reg |= LDOB_2_80V;
Fabio Estevamba92ad62014-05-09 13:15:42 -0300668 pmic_reg_write(p, PFUZE100_VGEN3VOL, reg);
669
670 /* Increase VGEN5 from 2.8 to 3V */
671 pmic_reg_read(p, PFUZE100_VGEN5VOL, &reg);
Ye.Li75e02f92014-11-06 16:29:00 +0800672 reg &= ~LDO_VOL_MASK;
673 reg |= LDOB_3_00V;
Fabio Estevamba92ad62014-05-09 13:15:42 -0300674 pmic_reg_write(p, PFUZE100_VGEN5VOL, reg);
675
Fabio Estevam77e62892012-09-13 03:18:20 +0000676 return 0;
677}
678
Nikita Kiryanov00cd7382014-08-20 15:08:50 +0300679#ifdef CONFIG_MXC_SPI
680int board_spi_cs_gpio(unsigned bus, unsigned cs)
681{
682 return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
683}
684#endif
685
Otavio Salvador52863372013-03-16 08:05:07 +0000686#ifdef CONFIG_CMD_BMODE
687static const struct boot_mode board_boot_modes[] = {
688 /* 4 bit bus width */
689 {"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
690 {"sd3", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
691 /* 8 bit bus width */
Ye Li4ea4a9b2016-01-30 11:53:42 +0800692 {"emmc", MAKE_CFGVAL(0x60, 0x58, 0x00, 0x00)},
Otavio Salvador52863372013-03-16 08:05:07 +0000693 {NULL, 0},
694};
695#endif
696
697int board_late_init(void)
698{
699#ifdef CONFIG_CMD_BMODE
700 add_board_boot_modes(board_boot_modes);
701#endif
Peng Fan04321fc2015-07-11 11:38:46 +0800702
703#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
Simon Glass6a38e412017-08-03 12:22:09 -0600704 env_set("board_name", "SABRESD");
Peng Fan04321fc2015-07-11 11:38:46 +0800705
Peng Fane27c4db2015-10-15 18:05:59 +0800706 if (is_mx6dqp())
Simon Glass6a38e412017-08-03 12:22:09 -0600707 env_set("board_rev", "MX6QP");
Peng Fan4a597d02016-05-23 18:36:06 +0800708 else if (is_mx6dq())
Simon Glass6a38e412017-08-03 12:22:09 -0600709 env_set("board_rev", "MX6Q");
Peng Fan4a597d02016-05-23 18:36:06 +0800710 else if (is_mx6sdl())
Simon Glass6a38e412017-08-03 12:22:09 -0600711 env_set("board_rev", "MX6DL");
Peng Fan04321fc2015-07-11 11:38:46 +0800712#endif
713
Otavio Salvador52863372013-03-16 08:05:07 +0000714 return 0;
715}
716
Fabio Estevam77e62892012-09-13 03:18:20 +0000717int checkboard(void)
718{
Pierre Aubertec10aed2013-06-04 09:00:15 +0200719 puts("Board: MX6-SabreSD\n");
Fabio Estevam77e62892012-09-13 03:18:20 +0000720 return 0;
721}
John Tobias07491552014-11-12 14:27:45 -0800722
723#ifdef CONFIG_SPL_BUILD
Fabio Estevamc88f1672017-05-12 12:45:23 -0300724#include <asm/arch/mx6-ddr.h>
John Tobias07491552014-11-12 14:27:45 -0800725#include <spl.h>
726#include <libfdt.h>
727
Diego Dorta466016e2016-10-11 11:09:27 -0300728#ifdef CONFIG_SPL_OS_BOOT
729int spl_start_uboot(void)
730{
731 gpio_direction_input(KEY_VOL_UP);
732
733 /* Only enter in Falcon mode if KEY_VOL_UP is pressed */
734 return gpio_get_value(KEY_VOL_UP);
735}
736#endif
737
Fabio Estevamc6ecd0b2014-11-14 09:36:59 -0200738static void ccgr_init(void)
739{
740 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
741
742 writel(0x00C03F3F, &ccm->CCGR0);
743 writel(0x0030FC03, &ccm->CCGR1);
744 writel(0x0FFFC000, &ccm->CCGR2);
745 writel(0x3FF00000, &ccm->CCGR3);
746 writel(0x00FFF300, &ccm->CCGR4);
747 writel(0x0F0000C3, &ccm->CCGR5);
748 writel(0x000003FF, &ccm->CCGR6);
749}
750
Fabio Estevam9b86c822016-09-26 09:14:25 -0300751static int mx6q_dcd_table[] = {
752 0x020e0798, 0x000C0000,
753 0x020e0758, 0x00000000,
754 0x020e0588, 0x00000030,
755 0x020e0594, 0x00000030,
756 0x020e056c, 0x00000030,
757 0x020e0578, 0x00000030,
758 0x020e074c, 0x00000030,
759 0x020e057c, 0x00000030,
760 0x020e058c, 0x00000000,
761 0x020e059c, 0x00000030,
762 0x020e05a0, 0x00000030,
763 0x020e078c, 0x00000030,
764 0x020e0750, 0x00020000,
765 0x020e05a8, 0x00000030,
766 0x020e05b0, 0x00000030,
767 0x020e0524, 0x00000030,
768 0x020e051c, 0x00000030,
769 0x020e0518, 0x00000030,
770 0x020e050c, 0x00000030,
771 0x020e05b8, 0x00000030,
772 0x020e05c0, 0x00000030,
773 0x020e0774, 0x00020000,
774 0x020e0784, 0x00000030,
775 0x020e0788, 0x00000030,
776 0x020e0794, 0x00000030,
777 0x020e079c, 0x00000030,
778 0x020e07a0, 0x00000030,
779 0x020e07a4, 0x00000030,
780 0x020e07a8, 0x00000030,
781 0x020e0748, 0x00000030,
782 0x020e05ac, 0x00000030,
783 0x020e05b4, 0x00000030,
784 0x020e0528, 0x00000030,
785 0x020e0520, 0x00000030,
786 0x020e0514, 0x00000030,
787 0x020e0510, 0x00000030,
788 0x020e05bc, 0x00000030,
789 0x020e05c4, 0x00000030,
790 0x021b0800, 0xa1390003,
791 0x021b080c, 0x001F001F,
792 0x021b0810, 0x001F001F,
793 0x021b480c, 0x001F001F,
794 0x021b4810, 0x001F001F,
795 0x021b083c, 0x43270338,
796 0x021b0840, 0x03200314,
797 0x021b483c, 0x431A032F,
798 0x021b4840, 0x03200263,
799 0x021b0848, 0x4B434748,
800 0x021b4848, 0x4445404C,
801 0x021b0850, 0x38444542,
802 0x021b4850, 0x4935493A,
803 0x021b081c, 0x33333333,
804 0x021b0820, 0x33333333,
805 0x021b0824, 0x33333333,
806 0x021b0828, 0x33333333,
807 0x021b481c, 0x33333333,
808 0x021b4820, 0x33333333,
809 0x021b4824, 0x33333333,
810 0x021b4828, 0x33333333,
811 0x021b08b8, 0x00000800,
812 0x021b48b8, 0x00000800,
813 0x021b0004, 0x00020036,
814 0x021b0008, 0x09444040,
815 0x021b000c, 0x555A7975,
816 0x021b0010, 0xFF538F64,
817 0x021b0014, 0x01FF00DB,
818 0x021b0018, 0x00001740,
819 0x021b001c, 0x00008000,
820 0x021b002c, 0x000026d2,
821 0x021b0030, 0x005A1023,
822 0x021b0040, 0x00000027,
823 0x021b0000, 0x831A0000,
824 0x021b001c, 0x04088032,
825 0x021b001c, 0x00008033,
826 0x021b001c, 0x00048031,
827 0x021b001c, 0x09408030,
828 0x021b001c, 0x04008040,
829 0x021b0020, 0x00005800,
830 0x021b0818, 0x00011117,
831 0x021b4818, 0x00011117,
832 0x021b0004, 0x00025576,
833 0x021b0404, 0x00011006,
834 0x021b001c, 0x00000000,
835};
836
837static int mx6qp_dcd_table[] = {
838 0x020e0798, 0x000c0000,
839 0x020e0758, 0x00000000,
840 0x020e0588, 0x00000030,
841 0x020e0594, 0x00000030,
842 0x020e056c, 0x00000030,
843 0x020e0578, 0x00000030,
844 0x020e074c, 0x00000030,
845 0x020e057c, 0x00000030,
846 0x020e058c, 0x00000000,
847 0x020e059c, 0x00000030,
848 0x020e05a0, 0x00000030,
849 0x020e078c, 0x00000030,
850 0x020e0750, 0x00020000,
851 0x020e05a8, 0x00000030,
852 0x020e05b0, 0x00000030,
853 0x020e0524, 0x00000030,
854 0x020e051c, 0x00000030,
855 0x020e0518, 0x00000030,
856 0x020e050c, 0x00000030,
857 0x020e05b8, 0x00000030,
858 0x020e05c0, 0x00000030,
859 0x020e0774, 0x00020000,
860 0x020e0784, 0x00000030,
861 0x020e0788, 0x00000030,
862 0x020e0794, 0x00000030,
863 0x020e079c, 0x00000030,
864 0x020e07a0, 0x00000030,
865 0x020e07a4, 0x00000030,
866 0x020e07a8, 0x00000030,
867 0x020e0748, 0x00000030,
868 0x020e05ac, 0x00000030,
869 0x020e05b4, 0x00000030,
870 0x020e0528, 0x00000030,
871 0x020e0520, 0x00000030,
872 0x020e0514, 0x00000030,
873 0x020e0510, 0x00000030,
874 0x020e05bc, 0x00000030,
875 0x020e05c4, 0x00000030,
876 0x021b0800, 0xa1390003,
877 0x021b080c, 0x001b001e,
878 0x021b0810, 0x002e0029,
879 0x021b480c, 0x001b002a,
880 0x021b4810, 0x0019002c,
881 0x021b083c, 0x43240334,
882 0x021b0840, 0x0324031a,
883 0x021b483c, 0x43340344,
884 0x021b4840, 0x03280276,
885 0x021b0848, 0x44383A3E,
886 0x021b4848, 0x3C3C3846,
887 0x021b0850, 0x2e303230,
888 0x021b4850, 0x38283E34,
889 0x021b081c, 0x33333333,
890 0x021b0820, 0x33333333,
891 0x021b0824, 0x33333333,
892 0x021b0828, 0x33333333,
893 0x021b481c, 0x33333333,
894 0x021b4820, 0x33333333,
895 0x021b4824, 0x33333333,
896 0x021b4828, 0x33333333,
897 0x021b08c0, 0x24912249,
898 0x021b48c0, 0x24914289,
899 0x021b08b8, 0x00000800,
900 0x021b48b8, 0x00000800,
901 0x021b0004, 0x00020036,
902 0x021b0008, 0x24444040,
903 0x021b000c, 0x555A7955,
904 0x021b0010, 0xFF320F64,
905 0x021b0014, 0x01ff00db,
906 0x021b0018, 0x00001740,
907 0x021b001c, 0x00008000,
908 0x021b002c, 0x000026d2,
909 0x021b0030, 0x005A1023,
910 0x021b0040, 0x00000027,
911 0x021b0400, 0x14420000,
912 0x021b0000, 0x831A0000,
913 0x021b0890, 0x00400C58,
914 0x00bb0008, 0x00000000,
915 0x00bb000c, 0x2891E41A,
916 0x00bb0038, 0x00000564,
917 0x00bb0014, 0x00000040,
918 0x00bb0028, 0x00000020,
919 0x00bb002c, 0x00000020,
920 0x021b001c, 0x04088032,
921 0x021b001c, 0x00008033,
922 0x021b001c, 0x00048031,
923 0x021b001c, 0x09408030,
924 0x021b001c, 0x04008040,
925 0x021b0020, 0x00005800,
926 0x021b0818, 0x00011117,
927 0x021b4818, 0x00011117,
928 0x021b0004, 0x00025576,
929 0x021b0404, 0x00011006,
930 0x021b001c, 0x00000000,
931};
932
Fabio Estevam15cb6b12017-05-12 12:45:24 -0300933static int mx6dl_dcd_table[] = {
934 0x020e0774, 0x000C0000,
935 0x020e0754, 0x00000000,
936 0x020e04ac, 0x00000030,
937 0x020e04b0, 0x00000030,
938 0x020e0464, 0x00000030,
939 0x020e0490, 0x00000030,
940 0x020e074c, 0x00000030,
941 0x020e0494, 0x00000030,
942 0x020e04a0, 0x00000000,
943 0x020e04b4, 0x00000030,
944 0x020e04b8, 0x00000030,
945 0x020e076c, 0x00000030,
946 0x020e0750, 0x00020000,
947 0x020e04bc, 0x00000030,
948 0x020e04c0, 0x00000030,
949 0x020e04c4, 0x00000030,
950 0x020e04c8, 0x00000030,
951 0x020e04cc, 0x00000030,
952 0x020e04d0, 0x00000030,
953 0x020e04d4, 0x00000030,
954 0x020e04d8, 0x00000030,
955 0x020e0760, 0x00020000,
956 0x020e0764, 0x00000030,
957 0x020e0770, 0x00000030,
958 0x020e0778, 0x00000030,
959 0x020e077c, 0x00000030,
960 0x020e0780, 0x00000030,
961 0x020e0784, 0x00000030,
962 0x020e078c, 0x00000030,
963 0x020e0748, 0x00000030,
964 0x020e0470, 0x00000030,
965 0x020e0474, 0x00000030,
966 0x020e0478, 0x00000030,
967 0x020e047c, 0x00000030,
968 0x020e0480, 0x00000030,
969 0x020e0484, 0x00000030,
970 0x020e0488, 0x00000030,
971 0x020e048c, 0x00000030,
972 0x021b0800, 0xa1390003,
973 0x021b080c, 0x001F001F,
974 0x021b0810, 0x001F001F,
975 0x021b480c, 0x001F001F,
976 0x021b4810, 0x001F001F,
977 0x021b083c, 0x4220021F,
978 0x021b0840, 0x0207017E,
979 0x021b483c, 0x4201020C,
980 0x021b4840, 0x01660172,
981 0x021b0848, 0x4A4D4E4D,
982 0x021b4848, 0x4A4F5049,
983 0x021b0850, 0x3F3C3D31,
984 0x021b4850, 0x3238372B,
985 0x021b081c, 0x33333333,
986 0x021b0820, 0x33333333,
987 0x021b0824, 0x33333333,
988 0x021b0828, 0x33333333,
989 0x021b481c, 0x33333333,
990 0x021b4820, 0x33333333,
991 0x021b4824, 0x33333333,
992 0x021b4828, 0x33333333,
993 0x021b08b8, 0x00000800,
994 0x021b48b8, 0x00000800,
995 0x021b0004, 0x0002002D,
996 0x021b0008, 0x00333030,
997 0x021b000c, 0x3F435313,
998 0x021b0010, 0xB66E8B63,
999 0x021b0014, 0x01FF00DB,
1000 0x021b0018, 0x00001740,
1001 0x021b001c, 0x00008000,
1002 0x021b002c, 0x000026d2,
1003 0x021b0030, 0x00431023,
1004 0x021b0040, 0x00000027,
1005 0x021b0000, 0x831A0000,
1006 0x021b001c, 0x04008032,
1007 0x021b001c, 0x00008033,
1008 0x021b001c, 0x00048031,
1009 0x021b001c, 0x05208030,
1010 0x021b001c, 0x04008040,
1011 0x021b0020, 0x00005800,
1012 0x021b0818, 0x00011117,
1013 0x021b4818, 0x00011117,
1014 0x021b0004, 0x0002556D,
1015 0x021b0404, 0x00011006,
1016 0x021b001c, 0x00000000,
1017};
1018
Fabio Estevam9b86c822016-09-26 09:14:25 -03001019static void ddr_init(int *table, int size)
John Tobias07491552014-11-12 14:27:45 -08001020{
Fabio Estevam9b86c822016-09-26 09:14:25 -03001021 int i;
John Tobias07491552014-11-12 14:27:45 -08001022
Fabio Estevam9b86c822016-09-26 09:14:25 -03001023 for (i = 0; i < size / 2 ; i++)
1024 writel(table[2 * i + 1], table[2 * i]);
John Tobias07491552014-11-12 14:27:45 -08001025}
1026
Fabio Estevam9b86c822016-09-26 09:14:25 -03001027static void spl_dram_init(void)
1028{
1029 if (is_mx6dq())
1030 ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table));
1031 else if (is_mx6dqp())
1032 ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table));
Fabio Estevam15cb6b12017-05-12 12:45:24 -03001033 else if (is_mx6sdl())
1034 ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table));
Fabio Estevam9b86c822016-09-26 09:14:25 -03001035}
1036
John Tobias07491552014-11-12 14:27:45 -08001037void board_init_f(ulong dummy)
1038{
Fabio Estevam9b86c822016-09-26 09:14:25 -03001039 /* DDR initialization */
1040 spl_dram_init();
1041
John Tobias07491552014-11-12 14:27:45 -08001042 /* setup AIPS and disable watchdog */
1043 arch_cpu_init();
1044
Fabio Estevamc6ecd0b2014-11-14 09:36:59 -02001045 ccgr_init();
1046 gpr_init();
1047
John Tobias07491552014-11-12 14:27:45 -08001048 /* iomux and setup of i2c */
1049 board_early_init_f();
1050
1051 /* setup GP timer */
1052 timer_init();
1053
1054 /* UART clocks enabled and gd valid - init serial console */
1055 preloader_console_init();
1056
John Tobias07491552014-11-12 14:27:45 -08001057 /* Clear the BSS. */
1058 memset(__bss_start, 0, __bss_end - __bss_start);
1059
1060 /* load/boot image from boot device */
1061 board_init_r(NULL, 0);
1062}
John Tobias07491552014-11-12 14:27:45 -08001063#endif