19b75bad0SSARTRE Leo /*
29b75bad0SSARTRE Leo * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
39b75bad0SSARTRE Leo * Based on mx6qsabrelite.c file
49b75bad0SSARTRE Leo * Copyright (C) 2013, Adeneo Embedded <www.adeneo-embedded.com>
59b75bad0SSARTRE Leo * Leo Sartre, <lsartre@adeneo-embedded.com>
69b75bad0SSARTRE Leo *
71a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
89b75bad0SSARTRE Leo */
99b75bad0SSARTRE Leo
109b75bad0SSARTRE Leo #include <common.h>
119b75bad0SSARTRE Leo #include <asm/io.h>
129b75bad0SSARTRE Leo #include <asm/arch/clock.h>
139b75bad0SSARTRE Leo #include <asm/arch/imx-regs.h>
149b75bad0SSARTRE Leo #include <asm/arch/iomux.h>
159b75bad0SSARTRE Leo #include <asm/arch/mx6-pins.h>
169b75bad0SSARTRE Leo #include <asm/gpio.h>
17552a848eSStefano Babic #include <asm/mach-imx/iomux-v3.h>
18552a848eSStefano Babic #include <asm/mach-imx/sata.h>
19552a848eSStefano Babic #include <asm/mach-imx/boot_mode.h>
20552a848eSStefano Babic #include <asm/mach-imx/mxc_i2c.h>
21d7140351SOtavio Salvador #include <asm/arch/sys_proto.h>
226d551f27SOtavio Salvador #include <asm/arch/mxc_hdmi.h>
236d551f27SOtavio Salvador #include <asm/arch/crm_regs.h>
249b75bad0SSARTRE Leo #include <mmc.h>
259b75bad0SSARTRE Leo #include <fsl_esdhc.h>
264c9929d6SOtavio Salvador #include <i2c.h>
274c9929d6SOtavio Salvador #include <power/pmic.h>
284c9929d6SOtavio Salvador #include <power/pfuze100_pmic.h>
296d551f27SOtavio Salvador #include <linux/fb.h>
306d551f27SOtavio Salvador #include <ipu_pixfmt.h>
31f0222902SOtavio Salvador #include <malloc.h>
32f0222902SOtavio Salvador #include <miiphy.h>
33f0222902SOtavio Salvador #include <netdev.h>
34f0222902SOtavio Salvador #include <micrel.h>
35d7140351SOtavio Salvador #include <spi_flash.h>
36d7140351SOtavio Salvador #include <spi.h>
379b75bad0SSARTRE Leo
389b75bad0SSARTRE Leo DECLARE_GLOBAL_DATA_PTR;
399b75bad0SSARTRE Leo
409b75bad0SSARTRE Leo #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |\
419b75bad0SSARTRE Leo PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
429b75bad0SSARTRE Leo
439b75bad0SSARTRE Leo #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW |\
449b75bad0SSARTRE Leo PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
459b75bad0SSARTRE Leo
464c9929d6SOtavio Salvador #define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
474c9929d6SOtavio Salvador PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
484c9929d6SOtavio Salvador PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
494c9929d6SOtavio Salvador PAD_CTL_ODE | PAD_CTL_SRE_FAST)
504c9929d6SOtavio Salvador
5171bcdafeSOtavio Salvador #define SPI_PAD_CTRL (PAD_CTL_HYS | \
5271bcdafeSOtavio Salvador PAD_CTL_SPEED_MED | \
5371bcdafeSOtavio Salvador PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
5471bcdafeSOtavio Salvador
554c9929d6SOtavio Salvador #define MX6Q_QMX6_PFUZE_MUX IMX_GPIO_NR(6, 9)
564c9929d6SOtavio Salvador
57f0222902SOtavio Salvador
58f0222902SOtavio Salvador #define ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
59f0222902SOtavio Salvador PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
60f0222902SOtavio Salvador PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
61f0222902SOtavio Salvador
dram_init(void)629b75bad0SSARTRE Leo int dram_init(void)
639b75bad0SSARTRE Leo {
64d7140351SOtavio Salvador gd->ram_size = imx_ddr_size();
659b75bad0SSARTRE Leo
669b75bad0SSARTRE Leo return 0;
679b75bad0SSARTRE Leo }
689b75bad0SSARTRE Leo
696b3496f7SOtavio Salvador static iomux_v3_cfg_t const uart2_pads[] = {
70d7140351SOtavio Salvador IOMUX_PADS(PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
71d7140351SOtavio Salvador IOMUX_PADS(PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
729b75bad0SSARTRE Leo };
739b75bad0SSARTRE Leo
749c72fff2STom Rini #ifndef CONFIG_SPL_BUILD
756b3496f7SOtavio Salvador static iomux_v3_cfg_t const usdhc2_pads[] = {
76d7140351SOtavio Salvador IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
77d7140351SOtavio Salvador IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
78d7140351SOtavio Salvador IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
79d7140351SOtavio Salvador IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
80d7140351SOtavio Salvador IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
81d7140351SOtavio Salvador IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
82d7140351SOtavio Salvador IOMUX_PADS(PAD_GPIO_4__GPIO1_IO04 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
839b75bad0SSARTRE Leo };
849b75bad0SSARTRE Leo
8545e4d350SOtavio Salvador static iomux_v3_cfg_t const usdhc3_pads[] = {
86d7140351SOtavio Salvador IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
87d7140351SOtavio Salvador IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
88d7140351SOtavio Salvador IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
89d7140351SOtavio Salvador IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
90d7140351SOtavio Salvador IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
91d7140351SOtavio Salvador IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
92d7140351SOtavio Salvador IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
93d7140351SOtavio Salvador IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
94d7140351SOtavio Salvador IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
95d7140351SOtavio Salvador IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
96d7140351SOtavio Salvador IOMUX_PADS(PAD_SD3_RST__SD3_RESET | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
9745e4d350SOtavio Salvador };
989c72fff2STom Rini #endif
9945e4d350SOtavio Salvador
1006b3496f7SOtavio Salvador static iomux_v3_cfg_t const usdhc4_pads[] = {
101d7140351SOtavio Salvador IOMUX_PADS(PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
102d7140351SOtavio Salvador IOMUX_PADS(PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
103d7140351SOtavio Salvador IOMUX_PADS(PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
104d7140351SOtavio Salvador IOMUX_PADS(PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
105d7140351SOtavio Salvador IOMUX_PADS(PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
106d7140351SOtavio Salvador IOMUX_PADS(PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
107d7140351SOtavio Salvador IOMUX_PADS(PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
108d7140351SOtavio Salvador IOMUX_PADS(PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
109d7140351SOtavio Salvador IOMUX_PADS(PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
110d7140351SOtavio Salvador IOMUX_PADS(PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
111d7140351SOtavio Salvador IOMUX_PADS(PAD_NANDF_D6__GPIO2_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
1129b75bad0SSARTRE Leo };
1139b75bad0SSARTRE Leo
11495246ac7SOtavio Salvador static iomux_v3_cfg_t const usb_otg_pads[] = {
115d7140351SOtavio Salvador IOMUX_PADS(PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL)),
116d7140351SOtavio Salvador IOMUX_PADS(PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL)),
11795246ac7SOtavio Salvador };
11895246ac7SOtavio Salvador
119f0222902SOtavio Salvador static iomux_v3_cfg_t enet_pads_ksz9031[] = {
120d7140351SOtavio Salvador IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
121d7140351SOtavio Salvador IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
122d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
123d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
124d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
125d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
126d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
127d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
128d7140351SOtavio Salvador IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL)),
129d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RXC__GPIO6_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL)),
130d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL)),
131d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL)),
132d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL)),
133d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
134d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL)),
135f0222902SOtavio Salvador };
136f0222902SOtavio Salvador
137f0222902SOtavio Salvador static iomux_v3_cfg_t enet_pads_final_ksz9031[] = {
138d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
139d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
140d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
141d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
142d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
143d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
144f0222902SOtavio Salvador };
145f0222902SOtavio Salvador
146f0222902SOtavio Salvador static iomux_v3_cfg_t enet_pads_ar8035[] = {
147d7140351SOtavio Salvador IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
148d7140351SOtavio Salvador IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
149d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
150d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
151d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
152d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
153d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
154d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
155d7140351SOtavio Salvador IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL)),
156d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
157d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
158d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
159d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
160d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
161d7140351SOtavio Salvador IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
162f0222902SOtavio Salvador };
163f0222902SOtavio Salvador
16471bcdafeSOtavio Salvador static iomux_v3_cfg_t const ecspi1_pads[] = {
165d7140351SOtavio Salvador IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL)),
166d7140351SOtavio Salvador IOMUX_PADS(PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL)),
167d7140351SOtavio Salvador IOMUX_PADS(PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL)),
168d7140351SOtavio Salvador IOMUX_PADS(PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
16971bcdafeSOtavio Salvador };
17071bcdafeSOtavio Salvador
1714c9929d6SOtavio Salvador #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
172d7140351SOtavio Salvador struct i2c_pads_info mx6q_i2c_pad_info1 = {
1734c9929d6SOtavio Salvador .scl = {
174d7140351SOtavio Salvador .i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | PC,
175d7140351SOtavio Salvador .gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 | PC,
1764c9929d6SOtavio Salvador .gp = IMX_GPIO_NR(4, 12)
1774c9929d6SOtavio Salvador },
1784c9929d6SOtavio Salvador .sda = {
179d7140351SOtavio Salvador .i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
180d7140351SOtavio Salvador .gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | PC,
181d7140351SOtavio Salvador .gp = IMX_GPIO_NR(4, 13)
182d7140351SOtavio Salvador }
183d7140351SOtavio Salvador };
184d7140351SOtavio Salvador
185d7140351SOtavio Salvador struct i2c_pads_info mx6dl_i2c_pad_info1 = {
186d7140351SOtavio Salvador .scl = {
187d7140351SOtavio Salvador .i2c_mode = MX6DL_PAD_KEY_COL3__I2C2_SCL | PC,
188d7140351SOtavio Salvador .gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12 | PC,
189d7140351SOtavio Salvador .gp = IMX_GPIO_NR(4, 12)
190d7140351SOtavio Salvador },
191d7140351SOtavio Salvador .sda = {
192d7140351SOtavio Salvador .i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | PC,
193d7140351SOtavio Salvador .gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | PC,
1944c9929d6SOtavio Salvador .gp = IMX_GPIO_NR(4, 13)
1954c9929d6SOtavio Salvador }
1964c9929d6SOtavio Salvador };
1974c9929d6SOtavio Salvador
1984c9929d6SOtavio Salvador #define I2C_PMIC 1 /* I2C2 port is used to connect to the PMIC */
1994c9929d6SOtavio Salvador
2004c9929d6SOtavio Salvador struct interface_level {
2014c9929d6SOtavio Salvador char *name;
2024c9929d6SOtavio Salvador uchar value;
2034c9929d6SOtavio Salvador };
2044c9929d6SOtavio Salvador
2054c9929d6SOtavio Salvador static struct interface_level mipi_levels[] = {
2064c9929d6SOtavio Salvador {"0V0", 0x00},
2074c9929d6SOtavio Salvador {"2V5", 0x17},
2084c9929d6SOtavio Salvador };
2094c9929d6SOtavio Salvador
2104c9929d6SOtavio Salvador /* setup board specific PMIC */
power_init_board(void)2114c9929d6SOtavio Salvador int power_init_board(void)
2124c9929d6SOtavio Salvador {
2134c9929d6SOtavio Salvador struct pmic *p;
2144c9929d6SOtavio Salvador u32 id1, id2, i;
2154c9929d6SOtavio Salvador int ret;
2164c9929d6SOtavio Salvador char const *lv_mipi;
2174c9929d6SOtavio Salvador
2184c9929d6SOtavio Salvador /* configure I2C multiplexer */
2194c9929d6SOtavio Salvador gpio_direction_output(MX6Q_QMX6_PFUZE_MUX, 1);
2204c9929d6SOtavio Salvador
2214c9929d6SOtavio Salvador power_pfuze100_init(I2C_PMIC);
2224c9929d6SOtavio Salvador p = pmic_get("PFUZE100");
2234c9929d6SOtavio Salvador if (!p)
2244c9929d6SOtavio Salvador return -EINVAL;
2254c9929d6SOtavio Salvador
2264c9929d6SOtavio Salvador ret = pmic_probe(p);
2274c9929d6SOtavio Salvador if (ret)
2284c9929d6SOtavio Salvador return ret;
2294c9929d6SOtavio Salvador
2304c9929d6SOtavio Salvador pmic_reg_read(p, PFUZE100_DEVICEID, &id1);
2314c9929d6SOtavio Salvador pmic_reg_read(p, PFUZE100_REVID, &id2);
2324c9929d6SOtavio Salvador printf("PFUZE100 Rev. [%02x/%02x] detected\n", id1, id2);
2334c9929d6SOtavio Salvador
2344c9929d6SOtavio Salvador if (id2 >= 0x20)
2354c9929d6SOtavio Salvador return 0;
2364c9929d6SOtavio Salvador
2374c9929d6SOtavio Salvador /* set level of MIPI if specified */
23800caae6dSSimon Glass lv_mipi = env_get("lv_mipi");
2394c9929d6SOtavio Salvador if (lv_mipi)
2404c9929d6SOtavio Salvador return 0;
2414c9929d6SOtavio Salvador
2424c9929d6SOtavio Salvador for (i = 0; i < ARRAY_SIZE(mipi_levels); i++) {
2434c9929d6SOtavio Salvador if (!strcmp(mipi_levels[i].name, lv_mipi)) {
244f5cf9e65SOtavio Salvador printf("set MIPI level %s\n", mipi_levels[i].name);
2454c9929d6SOtavio Salvador ret = pmic_reg_write(p, PFUZE100_VGEN4VOL,
2464c9929d6SOtavio Salvador mipi_levels[i].value);
2474c9929d6SOtavio Salvador if (ret)
2484c9929d6SOtavio Salvador return ret;
2494c9929d6SOtavio Salvador }
2504c9929d6SOtavio Salvador }
2514c9929d6SOtavio Salvador
2524c9929d6SOtavio Salvador return 0;
2534c9929d6SOtavio Salvador }
2544c9929d6SOtavio Salvador
board_eth_init(bd_t * bis)255f0222902SOtavio Salvador int board_eth_init(bd_t *bis)
256f0222902SOtavio Salvador {
257f0222902SOtavio Salvador struct phy_device *phydev;
258f0222902SOtavio Salvador struct mii_dev *bus;
259f0222902SOtavio Salvador unsigned short id1, id2;
260f0222902SOtavio Salvador int ret;
261f0222902SOtavio Salvador
262f0222902SOtavio Salvador /* check whether KSZ9031 or AR8035 has to be configured */
263d7140351SOtavio Salvador SETUP_IOMUX_PADS(enet_pads_ar8035);
264f0222902SOtavio Salvador
265f0222902SOtavio Salvador /* phy reset */
266f0222902SOtavio Salvador gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
267f0222902SOtavio Salvador udelay(2000);
268f0222902SOtavio Salvador gpio_set_value(IMX_GPIO_NR(3, 23), 1);
269f0222902SOtavio Salvador udelay(500);
270f0222902SOtavio Salvador
271f0222902SOtavio Salvador bus = fec_get_miibus(IMX_FEC_BASE, -1);
272f0222902SOtavio Salvador if (!bus)
273f0222902SOtavio Salvador return -EINVAL;
274f0222902SOtavio Salvador phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII);
275f0222902SOtavio Salvador if (!phydev) {
276f0222902SOtavio Salvador printf("Error: phy device not found.\n");
277f0222902SOtavio Salvador ret = -ENODEV;
278f0222902SOtavio Salvador goto free_bus;
279f0222902SOtavio Salvador }
280f0222902SOtavio Salvador
281f0222902SOtavio Salvador /* get the PHY id */
282f0222902SOtavio Salvador id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
283f0222902SOtavio Salvador id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
284f0222902SOtavio Salvador
285f0222902SOtavio Salvador if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
286f0222902SOtavio Salvador /* re-configure for Micrel KSZ9031 */
287f0222902SOtavio Salvador printf("configure Micrel KSZ9031 Ethernet Phy at address %d\n",
288f0222902SOtavio Salvador phydev->addr);
289f0222902SOtavio Salvador
290f0222902SOtavio Salvador /* phy reset: gpio3-23 */
291f0222902SOtavio Salvador gpio_set_value(IMX_GPIO_NR(3, 23), 0);
292f0222902SOtavio Salvador gpio_set_value(IMX_GPIO_NR(6, 30), (phydev->addr >> 2));
293f0222902SOtavio Salvador gpio_set_value(IMX_GPIO_NR(6, 25), 1);
294f0222902SOtavio Salvador gpio_set_value(IMX_GPIO_NR(6, 27), 1);
295f0222902SOtavio Salvador gpio_set_value(IMX_GPIO_NR(6, 28), 1);
296f0222902SOtavio Salvador gpio_set_value(IMX_GPIO_NR(6, 29), 1);
297d7140351SOtavio Salvador SETUP_IOMUX_PADS(enet_pads_ksz9031);
298f0222902SOtavio Salvador gpio_set_value(IMX_GPIO_NR(6, 24), 1);
299f0222902SOtavio Salvador udelay(500);
300f0222902SOtavio Salvador gpio_set_value(IMX_GPIO_NR(3, 23), 1);
301d7140351SOtavio Salvador SETUP_IOMUX_PADS(enet_pads_final_ksz9031);
302f0222902SOtavio Salvador } else if ((id1 == 0x004d) && (id2 == 0xd072)) {
303f0222902SOtavio Salvador /* configure Atheros AR8035 - actually nothing to do */
304f0222902SOtavio Salvador printf("configure Atheros AR8035 Ethernet Phy at address %d\n",
305f0222902SOtavio Salvador phydev->addr);
306f0222902SOtavio Salvador } else {
307f0222902SOtavio Salvador printf("Unknown Ethernet-Phy: 0x%04x 0x%04x\n", id1, id2);
308f0222902SOtavio Salvador ret = -EINVAL;
309f0222902SOtavio Salvador goto free_phydev;
310f0222902SOtavio Salvador }
311f0222902SOtavio Salvador
312f0222902SOtavio Salvador ret = fec_probe(bis, -1, IMX_FEC_BASE, bus, phydev);
313f0222902SOtavio Salvador if (ret)
314f0222902SOtavio Salvador goto free_phydev;
315f0222902SOtavio Salvador
316f0222902SOtavio Salvador return 0;
317f0222902SOtavio Salvador
318f0222902SOtavio Salvador free_phydev:
319f0222902SOtavio Salvador free(phydev);
320f0222902SOtavio Salvador free_bus:
321f0222902SOtavio Salvador free(bus);
322f0222902SOtavio Salvador return ret;
323f0222902SOtavio Salvador }
324f0222902SOtavio Salvador
mx6_rgmii_rework(struct phy_device * phydev)325f0222902SOtavio Salvador int mx6_rgmii_rework(struct phy_device *phydev)
326f0222902SOtavio Salvador {
327f0222902SOtavio Salvador unsigned short id1, id2;
328f0222902SOtavio Salvador unsigned short val;
329f0222902SOtavio Salvador
330f0222902SOtavio Salvador /* check whether KSZ9031 or AR8035 has to be configured */
331f0222902SOtavio Salvador id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
332f0222902SOtavio Salvador id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
333f0222902SOtavio Salvador
334f0222902SOtavio Salvador if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
335f0222902SOtavio Salvador /* finalize phy configuration for Micrel KSZ9031 */
336f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
337f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 4);
338f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
339f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x0000);
340f0222902SOtavio Salvador
341f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
342f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 5);
343f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
344f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, MII_KSZ9031_MOD_REG);
345f0222902SOtavio Salvador
346f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
347f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 6);
348f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
349f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0xFFFF);
350f0222902SOtavio Salvador
351f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
352f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 8);
353f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
354f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x3FFF);
355f0222902SOtavio Salvador
356f0222902SOtavio Salvador /* fix KSZ9031 link up issue */
357f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 0x0);
358f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x4);
359f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC);
360f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x6);
361f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_REG);
362f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x3);
363f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC);
364f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x1A80);
365f0222902SOtavio Salvador }
366f0222902SOtavio Salvador
367f0222902SOtavio Salvador if ((id1 == 0x004d) && (id2 == 0xd072)) {
368f0222902SOtavio Salvador /* enable AR8035 ouput a 125MHz clk from CLK_25M */
369f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 0x7);
370f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, MII_KSZ9031_MOD_DATA_POST_INC_RW | 0x16);
371f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC | 0x7);
372f0222902SOtavio Salvador val = phy_read(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA);
373f0222902SOtavio Salvador val &= 0xfe63;
374f0222902SOtavio Salvador val |= 0x18;
375f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, val);
376f0222902SOtavio Salvador
377f0222902SOtavio Salvador /* introduce tx clock delay */
378f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
379f0222902SOtavio Salvador val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
380f0222902SOtavio Salvador val |= 0x0100;
381f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
382f0222902SOtavio Salvador
383f0222902SOtavio Salvador /* disable hibernation */
384f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0xb);
385f0222902SOtavio Salvador val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
386f0222902SOtavio Salvador phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3c40);
387f0222902SOtavio Salvador }
388f0222902SOtavio Salvador return 0;
389f0222902SOtavio Salvador }
390f0222902SOtavio Salvador
board_phy_config(struct phy_device * phydev)391f0222902SOtavio Salvador int board_phy_config(struct phy_device *phydev)
392f0222902SOtavio Salvador {
393f0222902SOtavio Salvador mx6_rgmii_rework(phydev);
394f0222902SOtavio Salvador
395f0222902SOtavio Salvador if (phydev->drv->config)
396f0222902SOtavio Salvador phydev->drv->config(phydev);
397f0222902SOtavio Salvador
398f0222902SOtavio Salvador return 0;
399f0222902SOtavio Salvador }
400f0222902SOtavio Salvador
setup_iomux_uart(void)4019b75bad0SSARTRE Leo static void setup_iomux_uart(void)
4029b75bad0SSARTRE Leo {
403d7140351SOtavio Salvador SETUP_IOMUX_PADS(uart2_pads);
4049b75bad0SSARTRE Leo }
4059b75bad0SSARTRE Leo
40671bcdafeSOtavio Salvador #ifdef CONFIG_MXC_SPI
setup_spi(void)40771bcdafeSOtavio Salvador static void setup_spi(void)
40871bcdafeSOtavio Salvador {
409a1ed1552SMichael Schanz SETUP_IOMUX_PADS(ecspi1_pads);
41071bcdafeSOtavio Salvador gpio_direction_output(IMX_GPIO_NR(3, 19), 0);
41171bcdafeSOtavio Salvador }
41271bcdafeSOtavio Salvador #endif
41371bcdafeSOtavio Salvador
4149b75bad0SSARTRE Leo #ifdef CONFIG_FSL_ESDHC
4156b3496f7SOtavio Salvador static struct fsl_esdhc_cfg usdhc_cfg[] = {
4169b75bad0SSARTRE Leo {USDHC2_BASE_ADDR},
41745e4d350SOtavio Salvador {USDHC3_BASE_ADDR},
4189b75bad0SSARTRE Leo {USDHC4_BASE_ADDR},
4199b75bad0SSARTRE Leo };
4209b75bad0SSARTRE Leo
board_mmc_getcd(struct mmc * mmc)4219b75bad0SSARTRE Leo int board_mmc_getcd(struct mmc *mmc)
4229b75bad0SSARTRE Leo {
4239b75bad0SSARTRE Leo struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
4249b75bad0SSARTRE Leo int ret = 0;
4259b75bad0SSARTRE Leo
4269b75bad0SSARTRE Leo switch (cfg->esdhc_base) {
4279b75bad0SSARTRE Leo case USDHC2_BASE_ADDR:
4289b75bad0SSARTRE Leo gpio_direction_input(IMX_GPIO_NR(1, 4));
4299b75bad0SSARTRE Leo ret = !gpio_get_value(IMX_GPIO_NR(1, 4));
4309b75bad0SSARTRE Leo break;
43145e4d350SOtavio Salvador case USDHC3_BASE_ADDR:
43245e4d350SOtavio Salvador ret = 1; /* eMMC is always present */
43345e4d350SOtavio Salvador break;
4349b75bad0SSARTRE Leo case USDHC4_BASE_ADDR:
4359b75bad0SSARTRE Leo gpio_direction_input(IMX_GPIO_NR(2, 6));
4369b75bad0SSARTRE Leo ret = !gpio_get_value(IMX_GPIO_NR(2, 6));
4379b75bad0SSARTRE Leo break;
4389b75bad0SSARTRE Leo default:
4399b75bad0SSARTRE Leo printf("Bad USDHC interface\n");
4409b75bad0SSARTRE Leo }
4419b75bad0SSARTRE Leo
4429b75bad0SSARTRE Leo return ret;
4439b75bad0SSARTRE Leo }
4449b75bad0SSARTRE Leo
board_mmc_init(bd_t * bis)4459b75bad0SSARTRE Leo int board_mmc_init(bd_t *bis)
4469b75bad0SSARTRE Leo {
447d7140351SOtavio Salvador #ifndef CONFIG_SPL_BUILD
4489b75bad0SSARTRE Leo s32 status = 0;
449516a863eSOtavio Salvador int i;
4509b75bad0SSARTRE Leo
4519b75bad0SSARTRE Leo usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
45245e4d350SOtavio Salvador usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
45345e4d350SOtavio Salvador usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
4549b75bad0SSARTRE Leo
455d7140351SOtavio Salvador SETUP_IOMUX_PADS(usdhc2_pads);
456d7140351SOtavio Salvador SETUP_IOMUX_PADS(usdhc3_pads);
457d7140351SOtavio Salvador SETUP_IOMUX_PADS(usdhc4_pads);
4589b75bad0SSARTRE Leo
459516a863eSOtavio Salvador for (i = 0; i < ARRAY_SIZE(usdhc_cfg); i++) {
460516a863eSOtavio Salvador status = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
461516a863eSOtavio Salvador if (status)
4629b75bad0SSARTRE Leo return status;
4639b75bad0SSARTRE Leo }
464516a863eSOtavio Salvador
465516a863eSOtavio Salvador return 0;
466d7140351SOtavio Salvador #else
467d7140351SOtavio Salvador SETUP_IOMUX_PADS(usdhc4_pads);
468d7140351SOtavio Salvador usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
469d7140351SOtavio Salvador usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
470d7140351SOtavio Salvador gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
471d7140351SOtavio Salvador
472d7140351SOtavio Salvador return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
473d7140351SOtavio Salvador #endif
474516a863eSOtavio Salvador }
4759b75bad0SSARTRE Leo #endif
4769b75bad0SSARTRE Leo
board_ehci_hcd_init(int port)47795246ac7SOtavio Salvador int board_ehci_hcd_init(int port)
47895246ac7SOtavio Salvador {
47995246ac7SOtavio Salvador switch (port) {
48095246ac7SOtavio Salvador case 0:
481d7140351SOtavio Salvador SETUP_IOMUX_PADS(usb_otg_pads);
48295246ac7SOtavio Salvador /*
48395246ac7SOtavio Salvador * set daisy chain for otg_pin_id on 6q.
48495246ac7SOtavio Salvador * for 6dl, this bit is reserved
48595246ac7SOtavio Salvador */
48695246ac7SOtavio Salvador imx_iomux_set_gpr_register(1, 13, 1, 1);
48795246ac7SOtavio Salvador break;
48895246ac7SOtavio Salvador case 1:
48995246ac7SOtavio Salvador /* nothing to do */
49095246ac7SOtavio Salvador break;
49195246ac7SOtavio Salvador default:
49295246ac7SOtavio Salvador printf("Invalid USB port: %d\n", port);
49395246ac7SOtavio Salvador return -EINVAL;
49495246ac7SOtavio Salvador }
49595246ac7SOtavio Salvador
49695246ac7SOtavio Salvador return 0;
49795246ac7SOtavio Salvador }
49895246ac7SOtavio Salvador
board_ehci_power(int port,int on)49995246ac7SOtavio Salvador int board_ehci_power(int port, int on)
50095246ac7SOtavio Salvador {
50195246ac7SOtavio Salvador switch (port) {
50295246ac7SOtavio Salvador case 0:
50395246ac7SOtavio Salvador break;
50495246ac7SOtavio Salvador case 1:
50595246ac7SOtavio Salvador gpio_direction_output(IMX_GPIO_NR(5, 5), on);
50695246ac7SOtavio Salvador break;
50795246ac7SOtavio Salvador default:
50895246ac7SOtavio Salvador printf("Invalid USB port: %d\n", port);
50995246ac7SOtavio Salvador return -EINVAL;
51095246ac7SOtavio Salvador }
51195246ac7SOtavio Salvador
51295246ac7SOtavio Salvador return 0;
51395246ac7SOtavio Salvador }
51495246ac7SOtavio Salvador
5156d551f27SOtavio Salvador struct display_info_t {
5166d551f27SOtavio Salvador int bus;
5176d551f27SOtavio Salvador int addr;
5186d551f27SOtavio Salvador int pixfmt;
5196d551f27SOtavio Salvador int (*detect)(struct display_info_t const *dev);
5206d551f27SOtavio Salvador void (*enable)(struct display_info_t const *dev);
5216d551f27SOtavio Salvador struct fb_videomode mode;
5226d551f27SOtavio Salvador };
5236d551f27SOtavio Salvador
disable_lvds(struct display_info_t const * dev)5246d551f27SOtavio Salvador static void disable_lvds(struct display_info_t const *dev)
5256d551f27SOtavio Salvador {
5266d551f27SOtavio Salvador struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
5276d551f27SOtavio Salvador
5286d551f27SOtavio Salvador clrbits_le32(&iomux->gpr[2], IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
5296d551f27SOtavio Salvador IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
5306d551f27SOtavio Salvador }
5316d551f27SOtavio Salvador
do_enable_hdmi(struct display_info_t const * dev)5326d551f27SOtavio Salvador static void do_enable_hdmi(struct display_info_t const *dev)
5336d551f27SOtavio Salvador {
5346d551f27SOtavio Salvador disable_lvds(dev);
5356d551f27SOtavio Salvador imx_enable_hdmi_phy();
5366d551f27SOtavio Salvador }
5376d551f27SOtavio Salvador
5386d551f27SOtavio Salvador static struct display_info_t const displays[] = {
5396d551f27SOtavio Salvador {
5406d551f27SOtavio Salvador .bus = -1,
5416d551f27SOtavio Salvador .addr = 0,
5426d551f27SOtavio Salvador .pixfmt = IPU_PIX_FMT_RGB666,
5436d551f27SOtavio Salvador .detect = NULL,
5446d551f27SOtavio Salvador .enable = NULL,
5456d551f27SOtavio Salvador .mode = {
5466d551f27SOtavio Salvador .name =
5476d551f27SOtavio Salvador "Hannstar-XGA",
5486d551f27SOtavio Salvador .refresh = 60,
5496d551f27SOtavio Salvador .xres = 1024,
5506d551f27SOtavio Salvador .yres = 768,
5516d551f27SOtavio Salvador .pixclock = 15385,
5526d551f27SOtavio Salvador .left_margin = 220,
5536d551f27SOtavio Salvador .right_margin = 40,
5546d551f27SOtavio Salvador .upper_margin = 21,
5556d551f27SOtavio Salvador .lower_margin = 7,
5566d551f27SOtavio Salvador .hsync_len = 60,
5576d551f27SOtavio Salvador .vsync_len = 10,
5586d551f27SOtavio Salvador .sync = FB_SYNC_EXT,
5596d551f27SOtavio Salvador .vmode = FB_VMODE_NONINTERLACED } },
5606d551f27SOtavio Salvador {
5616d551f27SOtavio Salvador .bus = -1,
5626d551f27SOtavio Salvador .addr = 0,
5636d551f27SOtavio Salvador .pixfmt = IPU_PIX_FMT_RGB24,
5646d551f27SOtavio Salvador .detect = NULL,
5656d551f27SOtavio Salvador .enable = do_enable_hdmi,
5666d551f27SOtavio Salvador .mode = {
5676d551f27SOtavio Salvador .name = "HDMI",
5686d551f27SOtavio Salvador .refresh = 60,
5696d551f27SOtavio Salvador .xres = 1024,
5706d551f27SOtavio Salvador .yres = 768,
5716d551f27SOtavio Salvador .pixclock = 15385,
5726d551f27SOtavio Salvador .left_margin = 220,
5736d551f27SOtavio Salvador .right_margin = 40,
5746d551f27SOtavio Salvador .upper_margin = 21,
5756d551f27SOtavio Salvador .lower_margin = 7,
5766d551f27SOtavio Salvador .hsync_len = 60,
5776d551f27SOtavio Salvador .vsync_len = 10,
5786d551f27SOtavio Salvador .sync = FB_SYNC_EXT,
5796d551f27SOtavio Salvador .vmode = FB_VMODE_NONINTERLACED } }
5806d551f27SOtavio Salvador };
5816d551f27SOtavio Salvador
board_video_skip(void)5826d551f27SOtavio Salvador int board_video_skip(void)
5836d551f27SOtavio Salvador {
5846d551f27SOtavio Salvador int i;
5856d551f27SOtavio Salvador int ret;
58600caae6dSSimon Glass char const *panel = env_get("panel");
5876d551f27SOtavio Salvador if (!panel) {
5886d551f27SOtavio Salvador for (i = 0; i < ARRAY_SIZE(displays); i++) {
5896d551f27SOtavio Salvador struct display_info_t const *dev = displays + i;
5906d551f27SOtavio Salvador if (dev->detect && dev->detect(dev)) {
5916d551f27SOtavio Salvador panel = dev->mode.name;
5926d551f27SOtavio Salvador printf("auto-detected panel %s\n", panel);
5936d551f27SOtavio Salvador break;
5946d551f27SOtavio Salvador }
5956d551f27SOtavio Salvador }
5966d551f27SOtavio Salvador if (!panel) {
5976d551f27SOtavio Salvador panel = displays[0].mode.name;
5986d551f27SOtavio Salvador printf("No panel detected: default to %s\n", panel);
5996d551f27SOtavio Salvador i = 0;
6006d551f27SOtavio Salvador }
6016d551f27SOtavio Salvador } else {
6026d551f27SOtavio Salvador for (i = 0; i < ARRAY_SIZE(displays); i++) {
6036d551f27SOtavio Salvador if (!strcmp(panel, displays[i].mode.name))
6046d551f27SOtavio Salvador break;
6056d551f27SOtavio Salvador }
6066d551f27SOtavio Salvador }
6076d551f27SOtavio Salvador if (i < ARRAY_SIZE(displays)) {
6086d551f27SOtavio Salvador ret = ipuv3_fb_init(&displays[i].mode, 0, displays[i].pixfmt);
6096d551f27SOtavio Salvador if (!ret) {
6106d551f27SOtavio Salvador if (displays[i].enable)
6116d551f27SOtavio Salvador displays[i].enable(displays + i);
6126d551f27SOtavio Salvador printf("Display: %s (%ux%u)\n",
6136d551f27SOtavio Salvador displays[i].mode.name, displays[i].mode.xres,
6146d551f27SOtavio Salvador displays[i].mode.yres);
6156d551f27SOtavio Salvador } else
6166d551f27SOtavio Salvador printf("LCD %s cannot be configured: %d\n",
6176d551f27SOtavio Salvador displays[i].mode.name, ret);
6186d551f27SOtavio Salvador } else {
6196d551f27SOtavio Salvador printf("unsupported panel %s\n", panel);
6206d551f27SOtavio Salvador return -EINVAL;
6216d551f27SOtavio Salvador }
6226d551f27SOtavio Salvador
6236d551f27SOtavio Salvador return 0;
6246d551f27SOtavio Salvador }
6256d551f27SOtavio Salvador
setup_display(void)6266d551f27SOtavio Salvador static void setup_display(void)
6276d551f27SOtavio Salvador {
6286d551f27SOtavio Salvador struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
6296d551f27SOtavio Salvador struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
6306d551f27SOtavio Salvador int reg;
6316d551f27SOtavio Salvador
6326d551f27SOtavio Salvador enable_ipu_clock();
6336d551f27SOtavio Salvador imx_setup_hdmi();
6346d551f27SOtavio Salvador
6356d551f27SOtavio Salvador /* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
6366d551f27SOtavio Salvador setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK |
6376d551f27SOtavio Salvador MXC_CCM_CCGR3_LDB_DI1_MASK);
6386d551f27SOtavio Salvador
6396d551f27SOtavio Salvador /* set LDB0, LDB1 clk select to 011/011 */
6406d551f27SOtavio Salvador reg = readl(&mxc_ccm->cs2cdr);
6416d551f27SOtavio Salvador reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
6426d551f27SOtavio Salvador MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
6436d551f27SOtavio Salvador reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
6446d551f27SOtavio Salvador (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
6456d551f27SOtavio Salvador writel(reg, &mxc_ccm->cs2cdr);
6466d551f27SOtavio Salvador
6476d551f27SOtavio Salvador setbits_le32(&mxc_ccm->cscmr2, MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV |
6486d551f27SOtavio Salvador MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV);
6496d551f27SOtavio Salvador
6506d551f27SOtavio Salvador setbits_le32(&mxc_ccm->chsccdr, CHSCCDR_CLK_SEL_LDB_DI0 <<
6516d551f27SOtavio Salvador MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET |
6526d551f27SOtavio Salvador CHSCCDR_CLK_SEL_LDB_DI0 <<
6536d551f27SOtavio Salvador MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
6546d551f27SOtavio Salvador
6556d551f27SOtavio Salvador reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
6566d551f27SOtavio Salvador | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
6576d551f27SOtavio Salvador | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
6586d551f27SOtavio Salvador | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
6596d551f27SOtavio Salvador | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
6606d551f27SOtavio Salvador | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
6616d551f27SOtavio Salvador | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
6626d551f27SOtavio Salvador | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
6636d551f27SOtavio Salvador | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
6646d551f27SOtavio Salvador writel(reg, &iomux->gpr[2]);
6656d551f27SOtavio Salvador
6666d551f27SOtavio Salvador reg = readl(&iomux->gpr[3]);
6676d551f27SOtavio Salvador reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK |
6686d551f27SOtavio Salvador IOMUXC_GPR3_HDMI_MUX_CTL_MASK)) |
6696d551f27SOtavio Salvador (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
6706d551f27SOtavio Salvador IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
6716d551f27SOtavio Salvador writel(reg, &iomux->gpr[3]);
6726d551f27SOtavio Salvador }
6736d551f27SOtavio Salvador
6746d551f27SOtavio Salvador /*
6756d551f27SOtavio Salvador * Do not overwrite the console
6766d551f27SOtavio Salvador * Use always serial for U-Boot console
6776d551f27SOtavio Salvador */
overwrite_console(void)6786d551f27SOtavio Salvador int overwrite_console(void)
6796d551f27SOtavio Salvador {
6806d551f27SOtavio Salvador return 1;
6816d551f27SOtavio Salvador }
6826d551f27SOtavio Salvador
board_early_init_f(void)6839b75bad0SSARTRE Leo int board_early_init_f(void)
6849b75bad0SSARTRE Leo {
6859b75bad0SSARTRE Leo setup_iomux_uart();
6866d551f27SOtavio Salvador setup_display();
6879b75bad0SSARTRE Leo
68871bcdafeSOtavio Salvador #ifdef CONFIG_MXC_SPI
68971bcdafeSOtavio Salvador setup_spi();
69071bcdafeSOtavio Salvador #endif
6919b75bad0SSARTRE Leo return 0;
6929b75bad0SSARTRE Leo }
6939b75bad0SSARTRE Leo
board_init(void)6949b75bad0SSARTRE Leo int board_init(void)
6959b75bad0SSARTRE Leo {
6969b75bad0SSARTRE Leo /* address of boot parameters */
6979b75bad0SSARTRE Leo gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
6989b75bad0SSARTRE Leo
699d7140351SOtavio Salvador
70068c27601SBreno Lima if (is_mx6dq())
701d7140351SOtavio Salvador setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1);
702d7140351SOtavio Salvador else
703d7140351SOtavio Salvador setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
7044c9929d6SOtavio Salvador
70510e40d54SSimon Glass #ifdef CONFIG_SATA
7066731bc8dSOtavio Salvador setup_sata();
7076731bc8dSOtavio Salvador #endif
7086731bc8dSOtavio Salvador
7099b75bad0SSARTRE Leo return 0;
7109b75bad0SSARTRE Leo }
7119b75bad0SSARTRE Leo
checkboard(void)7129b75bad0SSARTRE Leo int checkboard(void)
7139b75bad0SSARTRE Leo {
714d7140351SOtavio Salvador char *type = "unknown";
715d7140351SOtavio Salvador
716d7140351SOtavio Salvador if (is_cpu_type(MXC_CPU_MX6Q))
717d7140351SOtavio Salvador type = "Quad";
718d7140351SOtavio Salvador else if (is_cpu_type(MXC_CPU_MX6D))
719d7140351SOtavio Salvador type = "Dual";
720d7140351SOtavio Salvador else if (is_cpu_type(MXC_CPU_MX6DL))
721d7140351SOtavio Salvador type = "Dual-Lite";
722d7140351SOtavio Salvador else if (is_cpu_type(MXC_CPU_MX6SOLO))
723d7140351SOtavio Salvador type = "Solo";
724d7140351SOtavio Salvador
725d7140351SOtavio Salvador printf("Board: conga-QMX6 %s\n", type);
7269b75bad0SSARTRE Leo
7279b75bad0SSARTRE Leo return 0;
7289b75bad0SSARTRE Leo }
7299b75bad0SSARTRE Leo
73071bcdafeSOtavio Salvador #ifdef CONFIG_MXC_SPI
board_spi_cs_gpio(unsigned bus,unsigned cs)73171bcdafeSOtavio Salvador int board_spi_cs_gpio(unsigned bus, unsigned cs)
73271bcdafeSOtavio Salvador {
73371bcdafeSOtavio Salvador return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(3, 19)) : -EINVAL;
73471bcdafeSOtavio Salvador }
73571bcdafeSOtavio Salvador #endif
73671bcdafeSOtavio Salvador
7379b75bad0SSARTRE Leo #ifdef CONFIG_CMD_BMODE
7389b75bad0SSARTRE Leo static const struct boot_mode board_boot_modes[] = {
7399b75bad0SSARTRE Leo /* 4 bit bus width */
7409b75bad0SSARTRE Leo {"mmc0", MAKE_CFGVAL(0x50, 0x20, 0x00, 0x00)},
7419b75bad0SSARTRE Leo {"mmc1", MAKE_CFGVAL(0x50, 0x38, 0x00, 0x00)},
7429b75bad0SSARTRE Leo {NULL, 0},
7439b75bad0SSARTRE Leo };
7449b75bad0SSARTRE Leo #endif
7459b75bad0SSARTRE Leo
misc_init_r(void)7469b75bad0SSARTRE Leo int misc_init_r(void)
7479b75bad0SSARTRE Leo {
7489b75bad0SSARTRE Leo #ifdef CONFIG_CMD_BMODE
7499b75bad0SSARTRE Leo add_board_boot_modes(board_boot_modes);
7509b75bad0SSARTRE Leo #endif
7519b75bad0SSARTRE Leo return 0;
7529b75bad0SSARTRE Leo }
753d7140351SOtavio Salvador
board_late_init(void)754d7140351SOtavio Salvador int board_late_init(void)
755d7140351SOtavio Salvador {
756d7140351SOtavio Salvador #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
75768c27601SBreno Lima if (is_mx6dq())
758382bee57SSimon Glass env_set("board_rev", "MX6Q");
759d7140351SOtavio Salvador else
760382bee57SSimon Glass env_set("board_rev", "MX6DL");
761d7140351SOtavio Salvador #endif
762d7140351SOtavio Salvador
763d7140351SOtavio Salvador return 0;
764d7140351SOtavio Salvador }
765d7140351SOtavio Salvador
766d7140351SOtavio Salvador #ifdef CONFIG_SPL_BUILD
767d7140351SOtavio Salvador #include <asm/arch/mx6-ddr.h>
768d7140351SOtavio Salvador #include <spl.h>
769*0e00a84cSMasahiro Yamada #include <linux/libfdt.h>
770d7140351SOtavio Salvador #include <spi_flash.h>
771d7140351SOtavio Salvador #include <spi.h>
772d7140351SOtavio Salvador
773d7140351SOtavio Salvador const struct mx6dq_iomux_ddr_regs mx6q_ddr_ioregs = {
774d7140351SOtavio Salvador .dram_sdclk_0 = 0x00000030,
775d7140351SOtavio Salvador .dram_sdclk_1 = 0x00000030,
776d7140351SOtavio Salvador .dram_cas = 0x00000030,
777d7140351SOtavio Salvador .dram_ras = 0x00000030,
778d7140351SOtavio Salvador .dram_reset = 0x00000030,
779d7140351SOtavio Salvador .dram_sdcke0 = 0x00003000,
780d7140351SOtavio Salvador .dram_sdcke1 = 0x00003000,
781d7140351SOtavio Salvador .dram_sdba2 = 0x00000000,
782d7140351SOtavio Salvador .dram_sdodt0 = 0x00000030,
783d7140351SOtavio Salvador .dram_sdodt1 = 0x00000030,
784d7140351SOtavio Salvador .dram_sdqs0 = 0x00000030,
785d7140351SOtavio Salvador .dram_sdqs1 = 0x00000030,
786d7140351SOtavio Salvador .dram_sdqs2 = 0x00000030,
787d7140351SOtavio Salvador .dram_sdqs3 = 0x00000030,
788d7140351SOtavio Salvador .dram_sdqs4 = 0x00000030,
789d7140351SOtavio Salvador .dram_sdqs5 = 0x00000030,
790d7140351SOtavio Salvador .dram_sdqs6 = 0x00000030,
791d7140351SOtavio Salvador .dram_sdqs7 = 0x00000030,
792d7140351SOtavio Salvador .dram_dqm0 = 0x00000030,
793d7140351SOtavio Salvador .dram_dqm1 = 0x00000030,
794d7140351SOtavio Salvador .dram_dqm2 = 0x00000030,
795d7140351SOtavio Salvador .dram_dqm3 = 0x00000030,
796d7140351SOtavio Salvador .dram_dqm4 = 0x00000030,
797d7140351SOtavio Salvador .dram_dqm5 = 0x00000030,
798d7140351SOtavio Salvador .dram_dqm6 = 0x00000030,
799d7140351SOtavio Salvador .dram_dqm7 = 0x00000030,
800d7140351SOtavio Salvador };
801d7140351SOtavio Salvador
802d7140351SOtavio Salvador static const struct mx6sdl_iomux_ddr_regs mx6dl_ddr_ioregs = {
803d7140351SOtavio Salvador .dram_sdclk_0 = 0x00000030,
804d7140351SOtavio Salvador .dram_sdclk_1 = 0x00000030,
805d7140351SOtavio Salvador .dram_cas = 0x00000030,
806d7140351SOtavio Salvador .dram_ras = 0x00000030,
807d7140351SOtavio Salvador .dram_reset = 0x00000030,
808d7140351SOtavio Salvador .dram_sdcke0 = 0x00003000,
809d7140351SOtavio Salvador .dram_sdcke1 = 0x00003000,
810d7140351SOtavio Salvador .dram_sdba2 = 0x00000000,
811d7140351SOtavio Salvador .dram_sdodt0 = 0x00000030,
812d7140351SOtavio Salvador .dram_sdodt1 = 0x00000030,
813d7140351SOtavio Salvador .dram_sdqs0 = 0x00000030,
814d7140351SOtavio Salvador .dram_sdqs1 = 0x00000030,
815d7140351SOtavio Salvador .dram_sdqs2 = 0x00000030,
816d7140351SOtavio Salvador .dram_sdqs3 = 0x00000030,
817d7140351SOtavio Salvador .dram_sdqs4 = 0x00000030,
818d7140351SOtavio Salvador .dram_sdqs5 = 0x00000030,
819d7140351SOtavio Salvador .dram_sdqs6 = 0x00000030,
820d7140351SOtavio Salvador .dram_sdqs7 = 0x00000030,
821d7140351SOtavio Salvador .dram_dqm0 = 0x00000030,
822d7140351SOtavio Salvador .dram_dqm1 = 0x00000030,
823d7140351SOtavio Salvador .dram_dqm2 = 0x00000030,
824d7140351SOtavio Salvador .dram_dqm3 = 0x00000030,
825d7140351SOtavio Salvador .dram_dqm4 = 0x00000030,
826d7140351SOtavio Salvador .dram_dqm5 = 0x00000030,
827d7140351SOtavio Salvador .dram_dqm6 = 0x00000030,
828d7140351SOtavio Salvador .dram_dqm7 = 0x00000030,
829d7140351SOtavio Salvador };
830d7140351SOtavio Salvador
831d7140351SOtavio Salvador const struct mx6dq_iomux_grp_regs mx6q_grp_ioregs = {
832d7140351SOtavio Salvador .grp_ddr_type = 0x000C0000,
833d7140351SOtavio Salvador .grp_ddrmode_ctl = 0x00020000,
834d7140351SOtavio Salvador .grp_ddrpke = 0x00000000,
835d7140351SOtavio Salvador .grp_addds = 0x00000030,
836d7140351SOtavio Salvador .grp_ctlds = 0x00000030,
837d7140351SOtavio Salvador .grp_ddrmode = 0x00020000,
838d7140351SOtavio Salvador .grp_b0ds = 0x00000030,
839d7140351SOtavio Salvador .grp_b1ds = 0x00000030,
840d7140351SOtavio Salvador .grp_b2ds = 0x00000030,
841d7140351SOtavio Salvador .grp_b3ds = 0x00000030,
842d7140351SOtavio Salvador .grp_b4ds = 0x00000030,
843d7140351SOtavio Salvador .grp_b5ds = 0x00000030,
844d7140351SOtavio Salvador .grp_b6ds = 0x00000030,
845d7140351SOtavio Salvador .grp_b7ds = 0x00000030,
846d7140351SOtavio Salvador };
847d7140351SOtavio Salvador
848d7140351SOtavio Salvador static const struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
849d7140351SOtavio Salvador .grp_ddr_type = 0x000c0000,
850d7140351SOtavio Salvador .grp_ddrmode_ctl = 0x00020000,
851d7140351SOtavio Salvador .grp_ddrpke = 0x00000000,
852d7140351SOtavio Salvador .grp_addds = 0x00000030,
853d7140351SOtavio Salvador .grp_ctlds = 0x00000030,
854d7140351SOtavio Salvador .grp_ddrmode = 0x00020000,
855d7140351SOtavio Salvador .grp_b0ds = 0x00000030,
856d7140351SOtavio Salvador .grp_b1ds = 0x00000030,
857d7140351SOtavio Salvador .grp_b2ds = 0x00000030,
858d7140351SOtavio Salvador .grp_b3ds = 0x00000030,
859d7140351SOtavio Salvador .grp_b4ds = 0x00000030,
860d7140351SOtavio Salvador .grp_b5ds = 0x00000030,
861d7140351SOtavio Salvador .grp_b6ds = 0x00000030,
862d7140351SOtavio Salvador .grp_b7ds = 0x00000030,
863d7140351SOtavio Salvador };
864d7140351SOtavio Salvador
865d7140351SOtavio Salvador const struct mx6_mmdc_calibration mx6q_mmcd_calib = {
866d7140351SOtavio Salvador .p0_mpwldectrl0 = 0x0016001A,
867d7140351SOtavio Salvador .p0_mpwldectrl1 = 0x0023001C,
868d7140351SOtavio Salvador .p1_mpwldectrl0 = 0x0028003A,
869d7140351SOtavio Salvador .p1_mpwldectrl1 = 0x001F002C,
870d7140351SOtavio Salvador .p0_mpdgctrl0 = 0x43440354,
871d7140351SOtavio Salvador .p0_mpdgctrl1 = 0x033C033C,
872d7140351SOtavio Salvador .p1_mpdgctrl0 = 0x43300368,
873d7140351SOtavio Salvador .p1_mpdgctrl1 = 0x03500330,
874d7140351SOtavio Salvador .p0_mprddlctl = 0x3228242E,
875d7140351SOtavio Salvador .p1_mprddlctl = 0x2C2C2636,
876d7140351SOtavio Salvador .p0_mpwrdlctl = 0x36323A38,
877d7140351SOtavio Salvador .p1_mpwrdlctl = 0x42324440,
878d7140351SOtavio Salvador };
879d7140351SOtavio Salvador
880d7140351SOtavio Salvador const struct mx6_mmdc_calibration mx6q_2g_mmcd_calib = {
881d7140351SOtavio Salvador .p0_mpwldectrl0 = 0x00080016,
882d7140351SOtavio Salvador .p0_mpwldectrl1 = 0x001D0016,
883d7140351SOtavio Salvador .p1_mpwldectrl0 = 0x0018002C,
884d7140351SOtavio Salvador .p1_mpwldectrl1 = 0x000D001D,
885d7140351SOtavio Salvador .p0_mpdgctrl0 = 0x43200334,
886d7140351SOtavio Salvador .p0_mpdgctrl1 = 0x0320031C,
887d7140351SOtavio Salvador .p1_mpdgctrl0 = 0x0344034C,
888d7140351SOtavio Salvador .p1_mpdgctrl1 = 0x03380314,
889d7140351SOtavio Salvador .p0_mprddlctl = 0x3E36383A,
890d7140351SOtavio Salvador .p1_mprddlctl = 0x38363240,
891d7140351SOtavio Salvador .p0_mpwrdlctl = 0x36364238,
892d7140351SOtavio Salvador .p1_mpwrdlctl = 0x4230423E,
893d7140351SOtavio Salvador };
894d7140351SOtavio Salvador
895d7140351SOtavio Salvador static const struct mx6_mmdc_calibration mx6s_mmcd_calib = {
896d7140351SOtavio Salvador .p0_mpwldectrl0 = 0x00480049,
897d7140351SOtavio Salvador .p0_mpwldectrl1 = 0x00410044,
898d7140351SOtavio Salvador .p0_mpdgctrl0 = 0x42480248,
899d7140351SOtavio Salvador .p0_mpdgctrl1 = 0x023C023C,
900d7140351SOtavio Salvador .p0_mprddlctl = 0x40424644,
901d7140351SOtavio Salvador .p0_mpwrdlctl = 0x34323034,
902d7140351SOtavio Salvador };
903d7140351SOtavio Salvador
904d7140351SOtavio Salvador const struct mx6_mmdc_calibration mx6dl_mmcd_calib = {
905d7140351SOtavio Salvador .p0_mpwldectrl0 = 0x0043004B,
906d7140351SOtavio Salvador .p0_mpwldectrl1 = 0x003A003E,
907d7140351SOtavio Salvador .p1_mpwldectrl0 = 0x0047004F,
908d7140351SOtavio Salvador .p1_mpwldectrl1 = 0x004E0061,
909d7140351SOtavio Salvador .p0_mpdgctrl0 = 0x42500250,
910d7140351SOtavio Salvador .p0_mpdgctrl1 = 0x0238023C,
911d7140351SOtavio Salvador .p1_mpdgctrl0 = 0x42640264,
912d7140351SOtavio Salvador .p1_mpdgctrl1 = 0x02500258,
913d7140351SOtavio Salvador .p0_mprddlctl = 0x40424846,
914d7140351SOtavio Salvador .p1_mprddlctl = 0x46484842,
915d7140351SOtavio Salvador .p0_mpwrdlctl = 0x38382C30,
916d7140351SOtavio Salvador .p1_mpwrdlctl = 0x34343430,
917d7140351SOtavio Salvador };
918d7140351SOtavio Salvador
919d7140351SOtavio Salvador static struct mx6_ddr3_cfg mem_ddr_2g = {
920d7140351SOtavio Salvador .mem_speed = 1600,
921d7140351SOtavio Salvador .density = 2,
922d7140351SOtavio Salvador .width = 16,
923d7140351SOtavio Salvador .banks = 8,
924d7140351SOtavio Salvador .rowaddr = 14,
925d7140351SOtavio Salvador .coladdr = 10,
926d7140351SOtavio Salvador .pagesz = 2,
927d7140351SOtavio Salvador .trcd = 1310,
928d7140351SOtavio Salvador .trcmin = 4875,
929d7140351SOtavio Salvador .trasmin = 3500,
930d7140351SOtavio Salvador };
931d7140351SOtavio Salvador
932d7140351SOtavio Salvador static struct mx6_ddr3_cfg mem_ddr_4g = {
933d7140351SOtavio Salvador .mem_speed = 1600,
934d7140351SOtavio Salvador .density = 4,
935d7140351SOtavio Salvador .width = 16,
936d7140351SOtavio Salvador .banks = 8,
937d7140351SOtavio Salvador .rowaddr = 15,
938d7140351SOtavio Salvador .coladdr = 10,
939d7140351SOtavio Salvador .pagesz = 2,
940d7140351SOtavio Salvador .trcd = 1310,
941d7140351SOtavio Salvador .trcmin = 4875,
942d7140351SOtavio Salvador .trasmin = 3500,
943d7140351SOtavio Salvador };
944d7140351SOtavio Salvador
ccgr_init(void)945d7140351SOtavio Salvador static void ccgr_init(void)
946d7140351SOtavio Salvador {
947d7140351SOtavio Salvador struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
948d7140351SOtavio Salvador
949d7140351SOtavio Salvador writel(0x00C03F3F, &ccm->CCGR0);
950d7140351SOtavio Salvador writel(0x0030FC03, &ccm->CCGR1);
951d7140351SOtavio Salvador writel(0x0FFFC000, &ccm->CCGR2);
952d7140351SOtavio Salvador writel(0x3FF00000, &ccm->CCGR3);
953d7140351SOtavio Salvador writel(0x00FFF300, &ccm->CCGR4);
954d7140351SOtavio Salvador writel(0x0F0000C3, &ccm->CCGR5);
955d7140351SOtavio Salvador writel(0x000003FF, &ccm->CCGR6);
956d7140351SOtavio Salvador }
957d7140351SOtavio Salvador
958d7140351SOtavio Salvador /* Define a minimal structure so that the part number can be read via SPL */
959d7140351SOtavio Salvador struct mfgdata {
960d7140351SOtavio Salvador unsigned char tsize;
961d7140351SOtavio Salvador /* size of checksummed part in bytes */
962d7140351SOtavio Salvador unsigned char ckcnt;
963d7140351SOtavio Salvador /* checksum corrected byte */
964d7140351SOtavio Salvador unsigned char cksum;
965d7140351SOtavio Salvador /* decimal serial number, packed BCD */
966d7140351SOtavio Salvador unsigned char serial[6];
967d7140351SOtavio Salvador /* part number, right justified, ASCII */
968d7140351SOtavio Salvador unsigned char pn[16];
969d7140351SOtavio Salvador };
970d7140351SOtavio Salvador
conv_ascii(unsigned char * dst,unsigned char * src,int len)971d7140351SOtavio Salvador static void conv_ascii(unsigned char *dst, unsigned char *src, int len)
972d7140351SOtavio Salvador {
973d7140351SOtavio Salvador int remain = len;
974d7140351SOtavio Salvador unsigned char *sptr = src;
975d7140351SOtavio Salvador unsigned char *dptr = dst;
976d7140351SOtavio Salvador
977d7140351SOtavio Salvador while (remain) {
978d7140351SOtavio Salvador if (*sptr) {
979d7140351SOtavio Salvador *dptr = *sptr;
980d7140351SOtavio Salvador dptr++;
981d7140351SOtavio Salvador }
982d7140351SOtavio Salvador sptr++;
983d7140351SOtavio Salvador remain--;
984d7140351SOtavio Salvador }
985d7140351SOtavio Salvador *dptr = 0x0;
986d7140351SOtavio Salvador }
987d7140351SOtavio Salvador
988d7140351SOtavio Salvador #define CFG_MFG_ADDR_OFFSET (spi->size - SZ_16K)
is_2gb(void)989d7140351SOtavio Salvador static bool is_2gb(void)
990d7140351SOtavio Salvador {
991d7140351SOtavio Salvador struct spi_flash *spi;
992d7140351SOtavio Salvador int ret;
993d7140351SOtavio Salvador char buf[sizeof(struct mfgdata)];
994d7140351SOtavio Salvador struct mfgdata *data = (struct mfgdata *)buf;
995d7140351SOtavio Salvador unsigned char outbuf[32];
996d7140351SOtavio Salvador
997d7140351SOtavio Salvador spi = spi_flash_probe(CONFIG_ENV_SPI_BUS,
998d7140351SOtavio Salvador CONFIG_ENV_SPI_CS,
999d7140351SOtavio Salvador CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
1000d7140351SOtavio Salvador ret = spi_flash_read(spi, CFG_MFG_ADDR_OFFSET, sizeof(struct mfgdata),
1001d7140351SOtavio Salvador buf);
1002d7140351SOtavio Salvador if (ret)
1003d7140351SOtavio Salvador return false;
1004d7140351SOtavio Salvador
1005d7140351SOtavio Salvador /* Congatec Part Numbers 104 and 105 have 2GiB of RAM */
1006d7140351SOtavio Salvador conv_ascii(outbuf, data->pn, sizeof(data->pn));
1007d7140351SOtavio Salvador if (!memcmp(outbuf, "016104", 6) || !memcmp(outbuf, "016105", 6))
1008d7140351SOtavio Salvador return true;
1009d7140351SOtavio Salvador else
1010d7140351SOtavio Salvador return false;
1011d7140351SOtavio Salvador }
1012d7140351SOtavio Salvador
spl_dram_init(int width)1013d7140351SOtavio Salvador static void spl_dram_init(int width)
1014d7140351SOtavio Salvador {
1015d7140351SOtavio Salvador struct mx6_ddr_sysinfo sysinfo = {
1016d7140351SOtavio Salvador /* width of data bus:0=16,1=32,2=64 */
1017d7140351SOtavio Salvador .dsize = width / 32,
1018d7140351SOtavio Salvador /* config for full 4GB range so that get_mem_size() works */
1019d7140351SOtavio Salvador .cs_density = 32, /* 32Gb per CS */
1020d7140351SOtavio Salvador /* single chip select */
1021d7140351SOtavio Salvador .ncs = 1,
1022d7140351SOtavio Salvador .cs1_mirror = 0,
1023d7140351SOtavio Salvador .rtt_wr = 2,
1024d7140351SOtavio Salvador .rtt_nom = 2,
1025d7140351SOtavio Salvador .walat = 0,
1026d7140351SOtavio Salvador .ralat = 5,
1027d7140351SOtavio Salvador .mif3_mode = 3,
1028d7140351SOtavio Salvador .bi_on = 1,
1029d7140351SOtavio Salvador .sde_to_rst = 0x0d,
1030d7140351SOtavio Salvador .rst_to_cke = 0x20,
1031edf00937SFabio Estevam .refsel = 1, /* Refresh cycles at 32KHz */
1032edf00937SFabio Estevam .refr = 7, /* 8 refresh commands per refresh cycle */
1033d7140351SOtavio Salvador };
1034d7140351SOtavio Salvador
1035d7140351SOtavio Salvador if (is_cpu_type(MXC_CPU_MX6Q) && is_2gb()) {
1036d7140351SOtavio Salvador mx6dq_dram_iocfg(width, &mx6q_ddr_ioregs, &mx6q_grp_ioregs);
1037d7140351SOtavio Salvador mx6_dram_cfg(&sysinfo, &mx6q_2g_mmcd_calib, &mem_ddr_4g);
1038d7140351SOtavio Salvador return;
1039d7140351SOtavio Salvador }
1040d7140351SOtavio Salvador
104168c27601SBreno Lima if (is_mx6dq()) {
1042d7140351SOtavio Salvador mx6dq_dram_iocfg(width, &mx6q_ddr_ioregs, &mx6q_grp_ioregs);
1043d7140351SOtavio Salvador mx6_dram_cfg(&sysinfo, &mx6q_mmcd_calib, &mem_ddr_2g);
1044d7140351SOtavio Salvador } else if (is_cpu_type(MXC_CPU_MX6SOLO)) {
1045d7140351SOtavio Salvador sysinfo.walat = 1;
1046d7140351SOtavio Salvador mx6sdl_dram_iocfg(width, &mx6dl_ddr_ioregs, &mx6sdl_grp_ioregs);
1047d7140351SOtavio Salvador mx6_dram_cfg(&sysinfo, &mx6s_mmcd_calib, &mem_ddr_4g);
1048d7140351SOtavio Salvador } else if (is_cpu_type(MXC_CPU_MX6DL)) {
1049d7140351SOtavio Salvador sysinfo.walat = 1;
1050d7140351SOtavio Salvador mx6sdl_dram_iocfg(width, &mx6dl_ddr_ioregs, &mx6sdl_grp_ioregs);
1051d7140351SOtavio Salvador mx6_dram_cfg(&sysinfo, &mx6dl_mmcd_calib, &mem_ddr_2g);
1052d7140351SOtavio Salvador }
1053d7140351SOtavio Salvador }
1054d7140351SOtavio Salvador
board_init_f(ulong dummy)1055d7140351SOtavio Salvador void board_init_f(ulong dummy)
1056d7140351SOtavio Salvador {
1057d7140351SOtavio Salvador /* setup AIPS and disable watchdog */
1058d7140351SOtavio Salvador arch_cpu_init();
1059d7140351SOtavio Salvador
1060d7140351SOtavio Salvador ccgr_init();
1061d7140351SOtavio Salvador gpr_init();
1062d7140351SOtavio Salvador
1063d7140351SOtavio Salvador /* iomux and setup of i2c */
1064d7140351SOtavio Salvador board_early_init_f();
1065d7140351SOtavio Salvador
1066d7140351SOtavio Salvador /* setup GP timer */
1067d7140351SOtavio Salvador timer_init();
1068d7140351SOtavio Salvador
1069d7140351SOtavio Salvador /* UART clocks enabled and gd valid - init serial console */
1070d7140351SOtavio Salvador preloader_console_init();
1071d7140351SOtavio Salvador
1072d7140351SOtavio Salvador /* Needed for malloc() to work in SPL prior to board_init_r() */
1073d7140351SOtavio Salvador spl_init();
1074d7140351SOtavio Salvador
1075d7140351SOtavio Salvador /* DDR initialization */
1076d7140351SOtavio Salvador if (is_cpu_type(MXC_CPU_MX6SOLO))
1077d7140351SOtavio Salvador spl_dram_init(32);
1078d7140351SOtavio Salvador else
1079d7140351SOtavio Salvador spl_dram_init(64);
1080d7140351SOtavio Salvador
1081d7140351SOtavio Salvador /* Clear the BSS. */
1082d7140351SOtavio Salvador memset(__bss_start, 0, __bss_end - __bss_start);
1083d7140351SOtavio Salvador
1084d7140351SOtavio Salvador /* load/boot image from boot device */
1085d7140351SOtavio Salvador board_init_r(NULL, 0);
1086d7140351SOtavio Salvador }
1087d7140351SOtavio Salvador #endif
1088