blob: 80a77892c9a1b3e1736f41abe81f9bf4c5e11e37 [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>
Fabio Estevamba92ad62014-05-09 13:15:42 -030015#include <asm/imx-common/mxc_i2c.h>
Fabio Estevam77e62892012-09-13 03:18:20 +000016#include <asm/imx-common/iomux-v3.h>
Otavio Salvador52863372013-03-16 08:05:07 +000017#include <asm/imx-common/boot_mode.h>
Eric Benardd6cabb22014-04-04 19:05:54 +020018#include <asm/imx-common/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>
28#include <power/pmic.h>
29#include <power/pfuze100_pmic.h>
Ye.Li75e02f92014-11-06 16:29:00 +080030#include "../common/pfuze.h"
John Tobias07491552014-11-12 14:27:45 -080031#include <asm/arch/mx6-ddr.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[] = {
Eric Nelson3d3be0a2013-11-04 17:00:51 -070069 MX6_PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
70 MX6_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[] = {
Eric Nelsonafea2ba2013-02-19 10:07:01 +000074 MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
75 MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
Eric Nelson3d3be0a2013-11-04 17:00:51 -070076 MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
77 MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
78 MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
79 MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
80 MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
Eric Nelsonafea2ba2013-02-19 10:07:01 +000081 MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
82 MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
Eric Nelson3d3be0a2013-11-04 17:00:51 -070083 MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
84 MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
85 MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
86 MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
87 MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
Eric Nelsonafea2ba2013-02-19 10:07:01 +000088 MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
Fabio Estevam2ebe2462012-09-18 17:24:23 +000089 /* AR8031 PHY Reset */
Eric Nelson3d3be0a2013-11-04 17:00:51 -070090 MX6_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{
95 imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
96
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[] = {
Eric Nelson3d3be0a2013-11-04 17:00:51 -0700105 MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
106 MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
107 MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
108 MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
109 MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
110 MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
111 MX6_PAD_NANDF_D4__SD2_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
112 MX6_PAD_NANDF_D5__SD2_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
113 MX6_PAD_NANDF_D6__SD2_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
114 MX6_PAD_NANDF_D7__SD2_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
115 MX6_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[] = {
Eric Nelson3d3be0a2013-11-04 17:00:51 -0700119 MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
120 MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
121 MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
122 MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
123 MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
124 MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
125 MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
126 MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
127 MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
128 MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
129 MX6_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[] = {
Eric Nelson3d3be0a2013-11-04 17:00:51 -0700133 MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
134 MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
135 MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
136 MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
137 MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
138 MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
139 MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
140 MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
141 MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
142 MX6_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 Estevamd82dad42013-11-08 16:20:54 -0200146 MX6_PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
147 MX6_PAD_KEY_COL1__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
148 MX6_PAD_KEY_ROW0__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
149 MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
150};
151
Fabio Estevam0d29cee2014-10-21 21:14:53 -0200152static iomux_v3_cfg_t const rgb_pads[] = {
153 MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL),
154 MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL),
155 MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02 | MUX_PAD_CTRL(NO_PAD_CTRL),
156 MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03 | MUX_PAD_CTRL(NO_PAD_CTRL),
157 MX6_PAD_DI0_PIN4__IPU1_DI0_PIN04 | MUX_PAD_CTRL(NO_PAD_CTRL),
158 MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL),
159 MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL),
160 MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL),
161 MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL),
162 MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL),
163 MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL),
164 MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL),
165 MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL),
166 MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 | MUX_PAD_CTRL(NO_PAD_CTRL),
167 MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 | MUX_PAD_CTRL(NO_PAD_CTRL),
168 MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 | MUX_PAD_CTRL(NO_PAD_CTRL),
169 MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 | MUX_PAD_CTRL(NO_PAD_CTRL),
170 MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 | MUX_PAD_CTRL(NO_PAD_CTRL),
171 MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 | MUX_PAD_CTRL(NO_PAD_CTRL),
172 MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 | MUX_PAD_CTRL(NO_PAD_CTRL),
173 MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 | MUX_PAD_CTRL(NO_PAD_CTRL),
174 MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 | MUX_PAD_CTRL(NO_PAD_CTRL),
175 MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 | MUX_PAD_CTRL(NO_PAD_CTRL),
176 MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 | MUX_PAD_CTRL(NO_PAD_CTRL),
177 MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 | MUX_PAD_CTRL(NO_PAD_CTRL),
178 MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 | MUX_PAD_CTRL(NO_PAD_CTRL),
179 MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 | MUX_PAD_CTRL(NO_PAD_CTRL),
180 MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 | MUX_PAD_CTRL(NO_PAD_CTRL),
181 MX6_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 Estevam0d29cee2014-10-21 21:14:53 -0200185 MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL),
186};
187
Marco Franchi029d07f2016-06-08 15:05:31 -0300188static void enable_backlight(void)
189{
190 imx_iomux_v3_setup_multiple_pads(bl_pads, ARRAY_SIZE(bl_pads));
191 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{
196 imx_iomux_v3_setup_multiple_pads(rgb_pads, ARRAY_SIZE(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 Estevamba92ad62014-05-09 13:15:42 -0300205static struct i2c_pads_info i2c_pad_info1 = {
206 .scl = {
207 .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | I2C_PAD,
208 .gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | I2C_PAD,
209 .gp = IMX_GPIO_NR(4, 12)
210 },
211 .sda = {
212 .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | I2C_PAD,
213 .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | I2C_PAD,
214 .gp = IMX_GPIO_NR(4, 13)
215 }
216};
217
Fabio Estevamd82dad42013-11-08 16:20:54 -0200218static void setup_spi(void)
219{
220 imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
221}
222
Marek Vasut0e99f012014-03-23 22:45:41 +0100223iomux_v3_cfg_t const pcie_pads[] = {
224 MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL), /* POWER */
225 MX6_PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL), /* RESET */
226};
227
228static void setup_pcie(void)
229{
230 imx_iomux_v3_setup_multiple_pads(pcie_pads, ARRAY_SIZE(pcie_pads));
231}
232
Fabio Estevamdee3c842013-12-04 01:08:16 -0200233iomux_v3_cfg_t const di0_pads[] = {
234 MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK, /* DISP0_CLK */
235 MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02, /* DISP0_HSYNC */
236 MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03, /* DISP0_VSYNC */
237};
238
Fabio Estevam77e62892012-09-13 03:18:20 +0000239static void setup_iomux_uart(void)
240{
241 imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
242}
243
244#ifdef CONFIG_FSL_ESDHC
Shawn Guo7e5e8332012-12-30 14:14:59 +0000245struct fsl_esdhc_cfg usdhc_cfg[3] = {
246 {USDHC2_BASE_ADDR},
Fabio Estevam77e62892012-09-13 03:18:20 +0000247 {USDHC3_BASE_ADDR},
Shawn Guo7e5e8332012-12-30 14:14:59 +0000248 {USDHC4_BASE_ADDR},
Fabio Estevam77e62892012-09-13 03:18:20 +0000249};
250
Shawn Guo7e5e8332012-12-30 14:14:59 +0000251#define USDHC2_CD_GPIO IMX_GPIO_NR(2, 2)
252#define USDHC3_CD_GPIO IMX_GPIO_NR(2, 0)
253
Peng Fan03a43df2016-01-28 16:51:27 +0800254int board_mmc_get_env_dev(int devno)
255{
256 return devno - 1;
257}
258
Fabio Estevam77e62892012-09-13 03:18:20 +0000259int board_mmc_getcd(struct mmc *mmc)
260{
Shawn Guo7e5e8332012-12-30 14:14:59 +0000261 struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
Otavio Salvadorc2bed642013-03-16 08:05:06 +0000262 int ret = 0;
Shawn Guo7e5e8332012-12-30 14:14:59 +0000263
264 switch (cfg->esdhc_base) {
265 case USDHC2_BASE_ADDR:
Otavio Salvadorc2bed642013-03-16 08:05:06 +0000266 ret = !gpio_get_value(USDHC2_CD_GPIO);
267 break;
Shawn Guo7e5e8332012-12-30 14:14:59 +0000268 case USDHC3_BASE_ADDR:
Otavio Salvadorc2bed642013-03-16 08:05:06 +0000269 ret = !gpio_get_value(USDHC3_CD_GPIO);
270 break;
271 case USDHC4_BASE_ADDR:
272 ret = 1; /* eMMC/uSDHC4 is always present */
273 break;
Shawn Guo7e5e8332012-12-30 14:14:59 +0000274 }
Otavio Salvadorc2bed642013-03-16 08:05:06 +0000275
276 return ret;
Fabio Estevam77e62892012-09-13 03:18:20 +0000277}
278
279int board_mmc_init(bd_t *bis)
280{
John Tobias07491552014-11-12 14:27:45 -0800281#ifndef CONFIG_SPL_BUILD
Fabio Estevam593d0c82014-11-06 12:24:24 -0200282 int ret;
Shawn Guo7e5e8332012-12-30 14:14:59 +0000283 int i;
284
Otavio Salvadora272dbf2013-03-16 08:05:05 +0000285 /*
286 * According to the board_mmc_init() the following map is done:
Bin Meng75574052016-02-05 19:30:11 -0800287 * (U-Boot device node) (Physical Port)
Otavio Salvadora272dbf2013-03-16 08:05:05 +0000288 * mmc0 SD2
289 * mmc1 SD3
290 * mmc2 eMMC
291 */
Shawn Guo7e5e8332012-12-30 14:14:59 +0000292 for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
293 switch (i) {
294 case 0:
295 imx_iomux_v3_setup_multiple_pads(
296 usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
297 gpio_direction_input(USDHC2_CD_GPIO);
298 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
299 break;
300 case 1:
301 imx_iomux_v3_setup_multiple_pads(
302 usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
303 gpio_direction_input(USDHC3_CD_GPIO);
304 usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
305 break;
306 case 2:
307 imx_iomux_v3_setup_multiple_pads(
308 usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
309 usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
310 break;
311 default:
312 printf("Warning: you configured more USDHC controllers"
Otavio Salvadora937e222013-04-19 03:41:58 +0000313 "(%d) then supported by the board (%d)\n",
314 i + 1, CONFIG_SYS_FSL_USDHC_NUM);
Fabio Estevam593d0c82014-11-06 12:24:24 -0200315 return -EINVAL;
Otavio Salvadora937e222013-04-19 03:41:58 +0000316 }
Shawn Guo7e5e8332012-12-30 14:14:59 +0000317
Fabio Estevam593d0c82014-11-06 12:24:24 -0200318 ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
319 if (ret)
320 return ret;
Shawn Guo7e5e8332012-12-30 14:14:59 +0000321 }
Fabio Estevam77e62892012-09-13 03:18:20 +0000322
Fabio Estevam593d0c82014-11-06 12:24:24 -0200323 return 0;
John Tobias07491552014-11-12 14:27:45 -0800324#else
Fabio Estevam56cf36a2014-11-18 11:26:06 -0200325 struct src *psrc = (struct src *)SRC_BASE_ADDR;
326 unsigned reg = readl(&psrc->sbmr1) >> 11;
John Tobias07491552014-11-12 14:27:45 -0800327 /*
328 * Upon reading BOOT_CFG register the following map is done:
329 * Bit 11 and 12 of BOOT_CFG register can determine the current
330 * mmc port
331 * 0x1 SD1
332 * 0x2 SD2
333 * 0x3 SD4
334 */
335
336 switch (reg & 0x3) {
337 case 0x1:
338 imx_iomux_v3_setup_multiple_pads(
339 usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
340 usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
341 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
342 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
343 break;
344 case 0x2:
345 imx_iomux_v3_setup_multiple_pads(
346 usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
347 usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
348 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
349 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
350 break;
351 case 0x3:
352 imx_iomux_v3_setup_multiple_pads(
353 usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
354 usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
355 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
356 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
357 break;
358 }
359
360 return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
361#endif
Fabio Estevam77e62892012-09-13 03:18:20 +0000362}
363#endif
364
Fabio Estevam509c06f2016-10-24 10:22:06 -0200365static int ar8031_phy_fixup(struct phy_device *phydev)
366{
367 unsigned short val;
368
369 /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
370 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
371 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
372 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
373
374 val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
375 val &= 0xffe3;
376 val |= 0x18;
377 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
378
379 /* introduce tx clock delay */
380 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
381 val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
382 val |= 0x0100;
383 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
384
385 return 0;
386}
387
388int board_phy_config(struct phy_device *phydev)
389{
390 ar8031_phy_fixup(phydev);
391
392 if (phydev->drv->config)
393 phydev->drv->config(phydev);
394
395 return 0;
396}
397
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500398#if defined(CONFIG_VIDEO_IPUV3)
Fabio Estevam70f84b52013-11-25 10:34:26 -0200399static void disable_lvds(struct display_info_t const *dev)
400{
401 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
402
403 int reg = readl(&iomux->gpr[2]);
404
405 reg &= ~(IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
406 IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
407
408 writel(reg, &iomux->gpr[2]);
409}
410
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300411static void do_enable_hdmi(struct display_info_t const *dev)
412{
Fabio Estevam70f84b52013-11-25 10:34:26 -0200413 disable_lvds(dev);
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300414 imx_enable_hdmi_phy();
415}
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500416
Eric Benardd6cabb22014-04-04 19:05:54 +0200417struct display_info_t const displays[] = {{
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300418 .bus = -1,
419 .addr = 0,
Fabio Estevam7d66d562013-12-04 01:08:17 -0200420 .pixfmt = IPU_PIX_FMT_RGB666,
Fabio Estevam70f84b52013-11-25 10:34:26 -0200421 .detect = NULL,
Marco Franchi029d07f2016-06-08 15:05:31 -0300422 .enable = enable_lvds,
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300423 .mode = {
Fabio Estevam70f84b52013-11-25 10:34:26 -0200424 .name = "Hannstar-XGA",
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300425 .refresh = 60,
426 .xres = 1024,
427 .yres = 768,
Fabio Estevame2b20032016-03-16 12:55:03 -0300428 .pixclock = 15384,
429 .left_margin = 160,
430 .right_margin = 24,
431 .upper_margin = 29,
432 .lower_margin = 3,
433 .hsync_len = 136,
434 .vsync_len = 6,
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300435 .sync = FB_SYNC_EXT,
436 .vmode = FB_VMODE_NONINTERLACED
437} }, {
438 .bus = -1,
439 .addr = 0,
Fabio Estevam70f84b52013-11-25 10:34:26 -0200440 .pixfmt = IPU_PIX_FMT_RGB24,
441 .detect = detect_hdmi,
442 .enable = do_enable_hdmi,
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300443 .mode = {
Fabio Estevam70f84b52013-11-25 10:34:26 -0200444 .name = "HDMI",
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300445 .refresh = 60,
446 .xres = 1024,
447 .yres = 768,
Fabio Estevame2b20032016-03-16 12:55:03 -0300448 .pixclock = 15384,
449 .left_margin = 160,
450 .right_margin = 24,
451 .upper_margin = 29,
452 .lower_margin = 3,
453 .hsync_len = 136,
454 .vsync_len = 6,
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300455 .sync = FB_SYNC_EXT,
456 .vmode = FB_VMODE_NONINTERLACED
Fabio Estevam0d29cee2014-10-21 21:14:53 -0200457} }, {
458 .bus = 0,
459 .addr = 0,
460 .pixfmt = IPU_PIX_FMT_RGB24,
461 .detect = NULL,
462 .enable = enable_rgb,
463 .mode = {
464 .name = "SEIKO-WVGA",
465 .refresh = 60,
466 .xres = 800,
467 .yres = 480,
468 .pixclock = 29850,
469 .left_margin = 89,
470 .right_margin = 164,
471 .upper_margin = 23,
472 .lower_margin = 10,
473 .hsync_len = 10,
474 .vsync_len = 10,
475 .sync = 0,
476 .vmode = FB_VMODE_NONINTERLACED
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300477} } };
Eric Benardd6cabb22014-04-04 19:05:54 +0200478size_t display_count = ARRAY_SIZE(displays);
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500479
480static void setup_display(void)
481{
482 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300483 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500484 int reg;
485
Fabio Estevamdee3c842013-12-04 01:08:16 -0200486 /* Setup HSYNC, VSYNC, DISP_CLK for debugging purposes */
487 imx_iomux_v3_setup_multiple_pads(di0_pads, ARRAY_SIZE(di0_pads));
488
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500489 enable_ipu_clock();
490 imx_setup_hdmi();
491
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300492 /* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
Liu Ying6f450632013-11-29 22:38:39 +0800493 reg = readl(&mxc_ccm->CCGR3);
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300494 reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
495 writel(reg, &mxc_ccm->CCGR3);
496
497 /* set LDB0, LDB1 clk select to 011/011 */
498 reg = readl(&mxc_ccm->cs2cdr);
499 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
500 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
501 reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
502 | (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
503 writel(reg, &mxc_ccm->cs2cdr);
504
505 reg = readl(&mxc_ccm->cscmr2);
506 reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
507 writel(reg, &mxc_ccm->cscmr2);
508
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500509 reg = readl(&mxc_ccm->chsccdr);
510 reg |= (CHSCCDR_CLK_SEL_LDB_DI0
511 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300512 reg |= (CHSCCDR_CLK_SEL_LDB_DI0
513 << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500514 writel(reg, &mxc_ccm->chsccdr);
Fabio Estevam9e642cd2013-09-04 15:12:38 -0300515
516 reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
517 | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
518 | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
519 | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
520 | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
521 | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
522 | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
523 | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
524 | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
525 writel(reg, &iomux->gpr[2]);
526
527 reg = readl(&iomux->gpr[3]);
528 reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK
529 | IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
530 | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
531 << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
532 writel(reg, &iomux->gpr[3]);
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500533}
534#endif /* CONFIG_VIDEO_IPUV3 */
535
536/*
537 * Do not overwrite the console
538 * Use always serial for U-Boot console
539 */
540int overwrite_console(void)
541{
542 return 1;
543}
544
Fabio Estevam2ebe2462012-09-18 17:24:23 +0000545int board_eth_init(bd_t *bis)
546{
Fabio Estevam2ebe2462012-09-18 17:24:23 +0000547 setup_iomux_enet();
Marek Vasut0e99f012014-03-23 22:45:41 +0100548 setup_pcie();
Fabio Estevam2ebe2462012-09-18 17:24:23 +0000549
Fabio Estevamfa3ae402014-01-04 17:36:32 -0200550 return cpu_eth_init(bis);
Fabio Estevam2ebe2462012-09-18 17:24:23 +0000551}
552
Peng Fanc9498fa2014-12-02 09:55:27 +0800553#ifdef CONFIG_USB_EHCI_MX6
554#define USB_OTHERREGS_OFFSET 0x800
555#define UCTRL_PWR_POL (1 << 9)
556
557static iomux_v3_cfg_t const usb_otg_pads[] = {
558 MX6_PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
559 MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
560};
561
562static iomux_v3_cfg_t const usb_hc1_pads[] = {
563 MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
564};
565
566static void setup_usb(void)
567{
568 imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
569 ARRAY_SIZE(usb_otg_pads));
570
571 /*
572 * set daisy chain for otg_pin_id on 6q.
573 * for 6dl, this bit is reserved
574 */
575 imx_iomux_set_gpr_register(1, 13, 1, 0);
576
577 imx_iomux_v3_setup_multiple_pads(usb_hc1_pads,
578 ARRAY_SIZE(usb_hc1_pads));
579}
580
581int board_ehci_hcd_init(int port)
582{
583 u32 *usbnc_usb_ctrl;
584
585 if (port > 1)
586 return -EINVAL;
587
588 usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
589 port * 4);
590
591 setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
592
593 return 0;
594}
595
596int board_ehci_power(int port, int on)
597{
598 switch (port) {
599 case 0:
600 break;
601 case 1:
602 if (on)
603 gpio_direction_output(IMX_GPIO_NR(1, 29), 1);
604 else
605 gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
606 break;
607 default:
608 printf("MXC USB port %d not yet supported\n", port);
609 return -EINVAL;
610 }
611
612 return 0;
613}
614#endif
615
Fabio Estevam77e62892012-09-13 03:18:20 +0000616int board_early_init_f(void)
617{
618 setup_iomux_uart();
Pardeep Kumar Singla0b87ba02013-07-25 12:12:14 -0500619#if defined(CONFIG_VIDEO_IPUV3)
620 setup_display();
621#endif
Fabio Estevam77e62892012-09-13 03:18:20 +0000622
623 return 0;
624}
625
626int board_init(void)
627{
628 /* address of boot parameters */
629 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
630
Fabio Estevamd82dad42013-11-08 16:20:54 -0200631#ifdef CONFIG_MXC_SPI
632 setup_spi();
633#endif
Fabio Estevamba92ad62014-05-09 13:15:42 -0300634 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
635
Peng Fanc9498fa2014-12-02 09:55:27 +0800636#ifdef CONFIG_USB_EHCI_MX6
637 setup_usb();
638#endif
639
Fabio Estevamba92ad62014-05-09 13:15:42 -0300640 return 0;
641}
642
Ye.Li75e02f92014-11-06 16:29:00 +0800643int power_init_board(void)
Fabio Estevamba92ad62014-05-09 13:15:42 -0300644{
645 struct pmic *p;
Fabio Estevameffbec12015-07-21 20:02:49 -0300646 unsigned int reg;
647 int ret;
Fabio Estevamba92ad62014-05-09 13:15:42 -0300648
Ye.Li75e02f92014-11-06 16:29:00 +0800649 p = pfuze_common_init(I2C_PMIC);
650 if (!p)
651 return -ENODEV;
Fabio Estevamba92ad62014-05-09 13:15:42 -0300652
Peng Fane5bcd4d2015-01-27 10:14:04 +0800653 ret = pfuze_mode_init(p, APS_PFM);
654 if (ret < 0)
655 return ret;
656
Fabio Estevamba92ad62014-05-09 13:15:42 -0300657 /* Increase VGEN3 from 2.5 to 2.8V */
658 pmic_reg_read(p, PFUZE100_VGEN3VOL, &reg);
Ye.Li75e02f92014-11-06 16:29:00 +0800659 reg &= ~LDO_VOL_MASK;
660 reg |= LDOB_2_80V;
Fabio Estevamba92ad62014-05-09 13:15:42 -0300661 pmic_reg_write(p, PFUZE100_VGEN3VOL, reg);
662
663 /* Increase VGEN5 from 2.8 to 3V */
664 pmic_reg_read(p, PFUZE100_VGEN5VOL, &reg);
Ye.Li75e02f92014-11-06 16:29:00 +0800665 reg &= ~LDO_VOL_MASK;
666 reg |= LDOB_3_00V;
Fabio Estevamba92ad62014-05-09 13:15:42 -0300667 pmic_reg_write(p, PFUZE100_VGEN5VOL, reg);
668
Fabio Estevam77e62892012-09-13 03:18:20 +0000669 return 0;
670}
671
Nikita Kiryanov00cd7382014-08-20 15:08:50 +0300672#ifdef CONFIG_MXC_SPI
673int board_spi_cs_gpio(unsigned bus, unsigned cs)
674{
675 return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
676}
677#endif
678
Otavio Salvador52863372013-03-16 08:05:07 +0000679#ifdef CONFIG_CMD_BMODE
680static const struct boot_mode board_boot_modes[] = {
681 /* 4 bit bus width */
682 {"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
683 {"sd3", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
684 /* 8 bit bus width */
Ye Li4ea4a9b2016-01-30 11:53:42 +0800685 {"emmc", MAKE_CFGVAL(0x60, 0x58, 0x00, 0x00)},
Otavio Salvador52863372013-03-16 08:05:07 +0000686 {NULL, 0},
687};
688#endif
689
690int board_late_init(void)
691{
692#ifdef CONFIG_CMD_BMODE
693 add_board_boot_modes(board_boot_modes);
694#endif
Peng Fan04321fc2015-07-11 11:38:46 +0800695
696#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
697 setenv("board_name", "SABRESD");
698
Peng Fane27c4db2015-10-15 18:05:59 +0800699 if (is_mx6dqp())
700 setenv("board_rev", "MX6QP");
Peng Fan4a597d02016-05-23 18:36:06 +0800701 else if (is_mx6dq())
Peng Fan04321fc2015-07-11 11:38:46 +0800702 setenv("board_rev", "MX6Q");
Peng Fan4a597d02016-05-23 18:36:06 +0800703 else if (is_mx6sdl())
Peng Fan04321fc2015-07-11 11:38:46 +0800704 setenv("board_rev", "MX6DL");
705#endif
706
Otavio Salvador52863372013-03-16 08:05:07 +0000707 return 0;
708}
709
Fabio Estevam77e62892012-09-13 03:18:20 +0000710int checkboard(void)
711{
Pierre Aubertec10aed2013-06-04 09:00:15 +0200712 puts("Board: MX6-SabreSD\n");
Fabio Estevam77e62892012-09-13 03:18:20 +0000713 return 0;
714}
John Tobias07491552014-11-12 14:27:45 -0800715
716#ifdef CONFIG_SPL_BUILD
717#include <spl.h>
718#include <libfdt.h>
719
Diego Dorta466016e2016-10-11 11:09:27 -0300720#ifdef CONFIG_SPL_OS_BOOT
721int spl_start_uboot(void)
722{
723 gpio_direction_input(KEY_VOL_UP);
724
725 /* Only enter in Falcon mode if KEY_VOL_UP is pressed */
726 return gpio_get_value(KEY_VOL_UP);
727}
728#endif
729
Fabio Estevamc6ecd0b2014-11-14 09:36:59 -0200730static void ccgr_init(void)
731{
732 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
733
734 writel(0x00C03F3F, &ccm->CCGR0);
735 writel(0x0030FC03, &ccm->CCGR1);
736 writel(0x0FFFC000, &ccm->CCGR2);
737 writel(0x3FF00000, &ccm->CCGR3);
738 writel(0x00FFF300, &ccm->CCGR4);
739 writel(0x0F0000C3, &ccm->CCGR5);
740 writel(0x000003FF, &ccm->CCGR6);
741}
742
743static void gpr_init(void)
744{
745 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
746
747 /* enable AXI cache for VDOA/VPU/IPU */
748 writel(0xF00000CF, &iomux->gpr[4]);
Peng Fane27c4db2015-10-15 18:05:59 +0800749 if (is_mx6dqp()) {
750 /* set IPU AXI-id1 Qos=0x1 AXI-id0/2/3 Qos=0x7 */
751 writel(0x007F007F, &iomux->gpr[6]);
752 writel(0x007F007F, &iomux->gpr[7]);
753 } else {
754 /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
755 writel(0x007F007F, &iomux->gpr[6]);
756 writel(0x007F007F, &iomux->gpr[7]);
757 }
Fabio Estevamc6ecd0b2014-11-14 09:36:59 -0200758}
759
Fabio Estevam9b86c822016-09-26 09:14:25 -0300760static int mx6q_dcd_table[] = {
761 0x020e0798, 0x000C0000,
762 0x020e0758, 0x00000000,
763 0x020e0588, 0x00000030,
764 0x020e0594, 0x00000030,
765 0x020e056c, 0x00000030,
766 0x020e0578, 0x00000030,
767 0x020e074c, 0x00000030,
768 0x020e057c, 0x00000030,
769 0x020e058c, 0x00000000,
770 0x020e059c, 0x00000030,
771 0x020e05a0, 0x00000030,
772 0x020e078c, 0x00000030,
773 0x020e0750, 0x00020000,
774 0x020e05a8, 0x00000030,
775 0x020e05b0, 0x00000030,
776 0x020e0524, 0x00000030,
777 0x020e051c, 0x00000030,
778 0x020e0518, 0x00000030,
779 0x020e050c, 0x00000030,
780 0x020e05b8, 0x00000030,
781 0x020e05c0, 0x00000030,
782 0x020e0774, 0x00020000,
783 0x020e0784, 0x00000030,
784 0x020e0788, 0x00000030,
785 0x020e0794, 0x00000030,
786 0x020e079c, 0x00000030,
787 0x020e07a0, 0x00000030,
788 0x020e07a4, 0x00000030,
789 0x020e07a8, 0x00000030,
790 0x020e0748, 0x00000030,
791 0x020e05ac, 0x00000030,
792 0x020e05b4, 0x00000030,
793 0x020e0528, 0x00000030,
794 0x020e0520, 0x00000030,
795 0x020e0514, 0x00000030,
796 0x020e0510, 0x00000030,
797 0x020e05bc, 0x00000030,
798 0x020e05c4, 0x00000030,
799 0x021b0800, 0xa1390003,
800 0x021b080c, 0x001F001F,
801 0x021b0810, 0x001F001F,
802 0x021b480c, 0x001F001F,
803 0x021b4810, 0x001F001F,
804 0x021b083c, 0x43270338,
805 0x021b0840, 0x03200314,
806 0x021b483c, 0x431A032F,
807 0x021b4840, 0x03200263,
808 0x021b0848, 0x4B434748,
809 0x021b4848, 0x4445404C,
810 0x021b0850, 0x38444542,
811 0x021b4850, 0x4935493A,
812 0x021b081c, 0x33333333,
813 0x021b0820, 0x33333333,
814 0x021b0824, 0x33333333,
815 0x021b0828, 0x33333333,
816 0x021b481c, 0x33333333,
817 0x021b4820, 0x33333333,
818 0x021b4824, 0x33333333,
819 0x021b4828, 0x33333333,
820 0x021b08b8, 0x00000800,
821 0x021b48b8, 0x00000800,
822 0x021b0004, 0x00020036,
823 0x021b0008, 0x09444040,
824 0x021b000c, 0x555A7975,
825 0x021b0010, 0xFF538F64,
826 0x021b0014, 0x01FF00DB,
827 0x021b0018, 0x00001740,
828 0x021b001c, 0x00008000,
829 0x021b002c, 0x000026d2,
830 0x021b0030, 0x005A1023,
831 0x021b0040, 0x00000027,
832 0x021b0000, 0x831A0000,
833 0x021b001c, 0x04088032,
834 0x021b001c, 0x00008033,
835 0x021b001c, 0x00048031,
836 0x021b001c, 0x09408030,
837 0x021b001c, 0x04008040,
838 0x021b0020, 0x00005800,
839 0x021b0818, 0x00011117,
840 0x021b4818, 0x00011117,
841 0x021b0004, 0x00025576,
842 0x021b0404, 0x00011006,
843 0x021b001c, 0x00000000,
844};
845
846static int mx6qp_dcd_table[] = {
847 0x020e0798, 0x000c0000,
848 0x020e0758, 0x00000000,
849 0x020e0588, 0x00000030,
850 0x020e0594, 0x00000030,
851 0x020e056c, 0x00000030,
852 0x020e0578, 0x00000030,
853 0x020e074c, 0x00000030,
854 0x020e057c, 0x00000030,
855 0x020e058c, 0x00000000,
856 0x020e059c, 0x00000030,
857 0x020e05a0, 0x00000030,
858 0x020e078c, 0x00000030,
859 0x020e0750, 0x00020000,
860 0x020e05a8, 0x00000030,
861 0x020e05b0, 0x00000030,
862 0x020e0524, 0x00000030,
863 0x020e051c, 0x00000030,
864 0x020e0518, 0x00000030,
865 0x020e050c, 0x00000030,
866 0x020e05b8, 0x00000030,
867 0x020e05c0, 0x00000030,
868 0x020e0774, 0x00020000,
869 0x020e0784, 0x00000030,
870 0x020e0788, 0x00000030,
871 0x020e0794, 0x00000030,
872 0x020e079c, 0x00000030,
873 0x020e07a0, 0x00000030,
874 0x020e07a4, 0x00000030,
875 0x020e07a8, 0x00000030,
876 0x020e0748, 0x00000030,
877 0x020e05ac, 0x00000030,
878 0x020e05b4, 0x00000030,
879 0x020e0528, 0x00000030,
880 0x020e0520, 0x00000030,
881 0x020e0514, 0x00000030,
882 0x020e0510, 0x00000030,
883 0x020e05bc, 0x00000030,
884 0x020e05c4, 0x00000030,
885 0x021b0800, 0xa1390003,
886 0x021b080c, 0x001b001e,
887 0x021b0810, 0x002e0029,
888 0x021b480c, 0x001b002a,
889 0x021b4810, 0x0019002c,
890 0x021b083c, 0x43240334,
891 0x021b0840, 0x0324031a,
892 0x021b483c, 0x43340344,
893 0x021b4840, 0x03280276,
894 0x021b0848, 0x44383A3E,
895 0x021b4848, 0x3C3C3846,
896 0x021b0850, 0x2e303230,
897 0x021b4850, 0x38283E34,
898 0x021b081c, 0x33333333,
899 0x021b0820, 0x33333333,
900 0x021b0824, 0x33333333,
901 0x021b0828, 0x33333333,
902 0x021b481c, 0x33333333,
903 0x021b4820, 0x33333333,
904 0x021b4824, 0x33333333,
905 0x021b4828, 0x33333333,
906 0x021b08c0, 0x24912249,
907 0x021b48c0, 0x24914289,
908 0x021b08b8, 0x00000800,
909 0x021b48b8, 0x00000800,
910 0x021b0004, 0x00020036,
911 0x021b0008, 0x24444040,
912 0x021b000c, 0x555A7955,
913 0x021b0010, 0xFF320F64,
914 0x021b0014, 0x01ff00db,
915 0x021b0018, 0x00001740,
916 0x021b001c, 0x00008000,
917 0x021b002c, 0x000026d2,
918 0x021b0030, 0x005A1023,
919 0x021b0040, 0x00000027,
920 0x021b0400, 0x14420000,
921 0x021b0000, 0x831A0000,
922 0x021b0890, 0x00400C58,
923 0x00bb0008, 0x00000000,
924 0x00bb000c, 0x2891E41A,
925 0x00bb0038, 0x00000564,
926 0x00bb0014, 0x00000040,
927 0x00bb0028, 0x00000020,
928 0x00bb002c, 0x00000020,
929 0x021b001c, 0x04088032,
930 0x021b001c, 0x00008033,
931 0x021b001c, 0x00048031,
932 0x021b001c, 0x09408030,
933 0x021b001c, 0x04008040,
934 0x021b0020, 0x00005800,
935 0x021b0818, 0x00011117,
936 0x021b4818, 0x00011117,
937 0x021b0004, 0x00025576,
938 0x021b0404, 0x00011006,
939 0x021b001c, 0x00000000,
940};
941
942static void ddr_init(int *table, int size)
John Tobias07491552014-11-12 14:27:45 -0800943{
Fabio Estevam9b86c822016-09-26 09:14:25 -0300944 int i;
John Tobias07491552014-11-12 14:27:45 -0800945
Fabio Estevam9b86c822016-09-26 09:14:25 -0300946 for (i = 0; i < size / 2 ; i++)
947 writel(table[2 * i + 1], table[2 * i]);
John Tobias07491552014-11-12 14:27:45 -0800948}
949
Fabio Estevam9b86c822016-09-26 09:14:25 -0300950static void spl_dram_init(void)
951{
952 if (is_mx6dq())
953 ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table));
954 else if (is_mx6dqp())
955 ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table));
956}
957
John Tobias07491552014-11-12 14:27:45 -0800958void board_init_f(ulong dummy)
959{
Fabio Estevam9b86c822016-09-26 09:14:25 -0300960 /* DDR initialization */
961 spl_dram_init();
962
John Tobias07491552014-11-12 14:27:45 -0800963 /* setup AIPS and disable watchdog */
964 arch_cpu_init();
965
Fabio Estevamc6ecd0b2014-11-14 09:36:59 -0200966 ccgr_init();
967 gpr_init();
968
John Tobias07491552014-11-12 14:27:45 -0800969 /* iomux and setup of i2c */
970 board_early_init_f();
971
972 /* setup GP timer */
973 timer_init();
974
975 /* UART clocks enabled and gd valid - init serial console */
976 preloader_console_init();
977
John Tobias07491552014-11-12 14:27:45 -0800978 /* Clear the BSS. */
979 memset(__bss_start, 0, __bss_end - __bss_start);
980
981 /* load/boot image from boot device */
982 board_init_r(NULL, 0);
983}
John Tobias07491552014-11-12 14:27:45 -0800984#endif