blob: bdeb5f7667343622116d4100f6baac8d3454971e [file] [log] [blame]
Fabio Estevam7dd65452012-09-24 08:09:33 +00001/*
2 * Copyright (C) 2012 Freescale Semiconductor, Inc.
3 *
4 * Author: Fabio Estevam <fabio.estevam@freescale.com>
5 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
Fabio Estevam7dd65452012-09-24 08:09:33 +00007 */
8
9#include <common.h>
10#include <asm/io.h>
11#include <asm/arch/clock.h>
12#include <asm/arch/imx-regs.h>
13#include <asm/arch/iomux.h>
Eric Nelsonb47abc32013-11-13 16:36:19 -070014#include <asm/arch/mx6-pins.h>
Masahiro Yamada1221ce42016-09-21 11:28:55 +090015#include <linux/errno.h>
Fabio Estevam7dd65452012-09-24 08:09:33 +000016#include <asm/gpio.h>
Stefano Babic552a8482017-06-29 10:16:06 +020017#include <asm/mach-imx/iomux-v3.h>
18#include <asm/mach-imx/mxc_i2c.h>
19#include <asm/mach-imx/boot_mode.h>
20#include <asm/mach-imx/spi.h>
Fabio Estevam7dd65452012-09-24 08:09:33 +000021#include <mmc.h>
22#include <fsl_esdhc.h>
Fabio Estevamfe5ebe92012-09-25 08:43:57 +000023#include <miiphy.h>
24#include <netdev.h>
Fabio Estevamdce67bd2012-10-02 11:20:12 +000025#include <asm/arch/sys_proto.h>
Renato Frias19578162013-05-13 18:01:12 +000026#include <i2c.h>
Diego Dorta7594c512017-09-22 12:12:18 -030027#include <input.h>
Fabio Estevam510922a2014-09-22 13:55:52 -030028#include <asm/arch/mxc_hdmi.h>
Stefano Babic552a8482017-06-29 10:16:06 +020029#include <asm/mach-imx/video.h>
Fabio Estevam510922a2014-09-22 13:55:52 -030030#include <asm/arch/crm_regs.h>
Ye.Li8fe280f2014-10-30 18:53:49 +080031#include <pca953x.h>
Ye.Li593243d2014-11-06 16:29:02 +080032#include <power/pmic.h>
Peng Fan258c98f2015-01-27 10:14:04 +080033#include <power/pfuze100_pmic.h>
Ye.Li593243d2014-11-06 16:29:02 +080034#include "../common/pfuze.h"
Fabio Estevamdce67bd2012-10-02 11:20:12 +000035
Fabio Estevam7dd65452012-09-24 08:09:33 +000036DECLARE_GLOBAL_DATA_PTR;
37
Benoît Thébaudeau7e2173c2013-04-26 01:34:47 +000038#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
39 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
40 PAD_CTL_SRE_FAST | PAD_CTL_HYS)
Fabio Estevam7dd65452012-09-24 08:09:33 +000041
Benoît Thébaudeau7e2173c2013-04-26 01:34:47 +000042#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
43 PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
44 PAD_CTL_SRE_FAST | PAD_CTL_HYS)
Fabio Estevam7dd65452012-09-24 08:09:33 +000045
Benoît Thébaudeau7e2173c2013-04-26 01:34:47 +000046#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
47 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
Fabio Estevamfe5ebe92012-09-25 08:43:57 +000048
Renato Frias19578162013-05-13 18:01:12 +000049#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
50 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
51 PAD_CTL_ODE | PAD_CTL_SRE_FAST)
52
Ye.Li83bb3212014-11-12 14:02:05 +080053#define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
54#define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
55 PAD_CTL_SRE_FAST)
56#define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
57
Renato Frias19578162013-05-13 18:01:12 +000058#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
59
Fabio Estevamcdbdde32014-11-14 11:27:23 -020060#define WEIM_NOR_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
61 PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
62 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
63
Ye.Li593243d2014-11-06 16:29:02 +080064#define I2C_PMIC 1
65
Fabio Estevam7dd65452012-09-24 08:09:33 +000066int dram_init(void)
67{
Vanessa Maegima369012e2016-06-08 15:17:54 -030068 gd->ram_size = imx_ddr_size();
Fabio Estevam7dd65452012-09-24 08:09:33 +000069
70 return 0;
71}
72
Fabio Estevam067a6592014-09-13 18:21:36 -030073static iomux_v3_cfg_t const uart4_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -030074 IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
75 IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
Fabio Estevam7dd65452012-09-24 08:09:33 +000076};
77
Fabio Estevam067a6592014-09-13 18:21:36 -030078static iomux_v3_cfg_t const enet_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -030079 IOMUX_PADS(PAD_KEY_COL1__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
80 IOMUX_PADS(PAD_KEY_COL2__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
81 IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
82 IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
83 IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
84 IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
85 IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
86 IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
87 IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL)),
88 IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
89 IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
90 IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
91 IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
92 IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
93 IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
Fabio Estevamfe5ebe92012-09-25 08:43:57 +000094};
95
Renato Frias19578162013-05-13 18:01:12 +000096/* I2C2 PMIC, iPod, Tuner, Codec, Touch, HDMI EDID, MIPI CSI2 card */
Vanessa Maegima823dff92017-06-29 09:33:45 -030097static struct i2c_pads_info mx6q_i2c_pad_info1 = {
Renato Frias19578162013-05-13 18:01:12 +000098 .scl = {
Vanessa Maegima823dff92017-06-29 09:33:45 -030099 .i2c_mode = MX6Q_PAD_EIM_EB2__I2C2_SCL | PC,
100 .gpio_mode = MX6Q_PAD_EIM_EB2__GPIO2_IO30 | PC,
Renato Frias19578162013-05-13 18:01:12 +0000101 .gp = IMX_GPIO_NR(2, 30)
102 },
103 .sda = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300104 .i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
105 .gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | PC,
106 .gp = IMX_GPIO_NR(4, 13)
107 }
108};
109
110static struct i2c_pads_info mx6dl_i2c_pad_info1 = {
111 .scl = {
112 .i2c_mode = MX6DL_PAD_EIM_EB2__I2C2_SCL | PC,
113 .gpio_mode = MX6DL_PAD_EIM_EB2__GPIO2_IO30 | PC,
114 .gp = IMX_GPIO_NR(2, 30)
115 },
116 .sda = {
117 .i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | PC,
118 .gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | PC,
Renato Frias19578162013-05-13 18:01:12 +0000119 .gp = IMX_GPIO_NR(4, 13)
120 }
121};
122
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200123#ifndef CONFIG_SYS_FLASH_CFI
Renato Frias19578162013-05-13 18:01:12 +0000124/*
125 * I2C3 MLB, Port Expanders (A, B, C), Video ADC, Light Sensor,
126 * Compass Sensor, Accelerometer, Res Touch
127 */
Vanessa Maegima823dff92017-06-29 09:33:45 -0300128static struct i2c_pads_info mx6q_i2c_pad_info2 = {
Renato Frias19578162013-05-13 18:01:12 +0000129 .scl = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300130 .i2c_mode = MX6Q_PAD_GPIO_3__I2C3_SCL | PC,
131 .gpio_mode = MX6Q_PAD_GPIO_3__GPIO1_IO03 | PC,
Renato Frias19578162013-05-13 18:01:12 +0000132 .gp = IMX_GPIO_NR(1, 3)
133 },
134 .sda = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300135 .i2c_mode = MX6Q_PAD_EIM_D18__I2C3_SDA | PC,
136 .gpio_mode = MX6Q_PAD_EIM_D18__GPIO3_IO18 | PC,
137 .gp = IMX_GPIO_NR(3, 18)
138 }
139};
140
141static struct i2c_pads_info mx6dl_i2c_pad_info2 = {
142 .scl = {
143 .i2c_mode = MX6DL_PAD_GPIO_3__I2C3_SCL | PC,
144 .gpio_mode = MX6DL_PAD_GPIO_3__GPIO1_IO03 | PC,
145 .gp = IMX_GPIO_NR(1, 3)
146 },
147 .sda = {
148 .i2c_mode = MX6DL_PAD_EIM_D18__I2C3_SDA | PC,
149 .gpio_mode = MX6DL_PAD_EIM_D18__GPIO3_IO18 | PC,
Renato Frias19578162013-05-13 18:01:12 +0000150 .gp = IMX_GPIO_NR(3, 18)
151 }
152};
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200153#endif
Renato Frias19578162013-05-13 18:01:12 +0000154
Fabio Estevam067a6592014-09-13 18:21:36 -0300155static iomux_v3_cfg_t const i2c3_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300156 IOMUX_PADS(PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Renato Frias19578162013-05-13 18:01:12 +0000157};
158
Fabio Estevam067a6592014-09-13 18:21:36 -0300159static iomux_v3_cfg_t const port_exp[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300160 IOMUX_PADS(PAD_SD2_DAT0__GPIO1_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Renato Friasa1f67802013-05-13 18:01:13 +0000161};
162
Ye.Li8fe280f2014-10-30 18:53:49 +0800163/*Define for building port exp gpio, pin starts from 0*/
164#define PORTEXP_IO_NR(chip, pin) \
165 ((chip << 5) + pin)
166
167/*Get the chip addr from a ioexp gpio*/
168#define PORTEXP_IO_TO_CHIP(gpio_nr) \
169 (gpio_nr >> 5)
170
171/*Get the pin number from a ioexp gpio*/
172#define PORTEXP_IO_TO_PIN(gpio_nr) \
173 (gpio_nr & 0x1f)
174
175static int port_exp_direction_output(unsigned gpio, int value)
176{
177 int ret;
178
179 i2c_set_bus_num(2);
180 ret = i2c_probe(PORTEXP_IO_TO_CHIP(gpio));
181 if (ret)
182 return ret;
183
184 ret = pca953x_set_dir(PORTEXP_IO_TO_CHIP(gpio),
185 (1 << PORTEXP_IO_TO_PIN(gpio)),
186 (PCA953X_DIR_OUT << PORTEXP_IO_TO_PIN(gpio)));
187
188 if (ret)
189 return ret;
190
191 ret = pca953x_set_val(PORTEXP_IO_TO_CHIP(gpio),
192 (1 << PORTEXP_IO_TO_PIN(gpio)),
193 (value << PORTEXP_IO_TO_PIN(gpio)));
194
195 if (ret)
196 return ret;
197
198 return 0;
199}
200
Fabio Estevamca62e5d2017-07-10 15:59:11 -0300201#ifdef CONFIG_MTD_NOR_FLASH
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200202static iomux_v3_cfg_t const eimnor_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300203 IOMUX_PADS(PAD_EIM_D16__EIM_DATA16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
204 IOMUX_PADS(PAD_EIM_D17__EIM_DATA17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
205 IOMUX_PADS(PAD_EIM_D18__EIM_DATA18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
206 IOMUX_PADS(PAD_EIM_D19__EIM_DATA19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
207 IOMUX_PADS(PAD_EIM_D20__EIM_DATA20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
208 IOMUX_PADS(PAD_EIM_D21__EIM_DATA21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
209 IOMUX_PADS(PAD_EIM_D22__EIM_DATA22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
210 IOMUX_PADS(PAD_EIM_D23__EIM_DATA23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
211 IOMUX_PADS(PAD_EIM_D24__EIM_DATA24 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
212 IOMUX_PADS(PAD_EIM_D25__EIM_DATA25 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
213 IOMUX_PADS(PAD_EIM_D26__EIM_DATA26 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
214 IOMUX_PADS(PAD_EIM_D27__EIM_DATA27 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
215 IOMUX_PADS(PAD_EIM_D28__EIM_DATA28 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
216 IOMUX_PADS(PAD_EIM_D29__EIM_DATA29 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
217 IOMUX_PADS(PAD_EIM_D30__EIM_DATA30 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
218 IOMUX_PADS(PAD_EIM_D31__EIM_DATA31 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
219 IOMUX_PADS(PAD_EIM_DA0__EIM_AD00 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
220 IOMUX_PADS(PAD_EIM_DA1__EIM_AD01 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
221 IOMUX_PADS(PAD_EIM_DA2__EIM_AD02 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
222 IOMUX_PADS(PAD_EIM_DA3__EIM_AD03 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
223 IOMUX_PADS(PAD_EIM_DA4__EIM_AD04 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
224 IOMUX_PADS(PAD_EIM_DA5__EIM_AD05 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
225 IOMUX_PADS(PAD_EIM_DA6__EIM_AD06 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
226 IOMUX_PADS(PAD_EIM_DA7__EIM_AD07 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
227 IOMUX_PADS(PAD_EIM_DA8__EIM_AD08 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
228 IOMUX_PADS(PAD_EIM_DA9__EIM_AD09 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
229 IOMUX_PADS(PAD_EIM_DA10__EIM_AD10 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
230 IOMUX_PADS(PAD_EIM_DA11__EIM_AD11 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
231 IOMUX_PADS(PAD_EIM_DA12__EIM_AD12 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
232 IOMUX_PADS(PAD_EIM_DA13__EIM_AD13 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
233 IOMUX_PADS(PAD_EIM_DA14__EIM_AD14 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
234 IOMUX_PADS(PAD_EIM_DA15__EIM_AD15 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
235 IOMUX_PADS(PAD_EIM_A16__EIM_ADDR16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
236 IOMUX_PADS(PAD_EIM_A17__EIM_ADDR17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
237 IOMUX_PADS(PAD_EIM_A18__EIM_ADDR18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
238 IOMUX_PADS(PAD_EIM_A19__EIM_ADDR19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
239 IOMUX_PADS(PAD_EIM_A20__EIM_ADDR20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
240 IOMUX_PADS(PAD_EIM_A21__EIM_ADDR21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
241 IOMUX_PADS(PAD_EIM_A22__EIM_ADDR22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
242 IOMUX_PADS(PAD_EIM_A23__EIM_ADDR23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
243 IOMUX_PADS(PAD_EIM_OE__EIM_OE_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
244 IOMUX_PADS(PAD_EIM_RW__EIM_RW | MUX_PAD_CTRL(NO_PAD_CTRL)),
245 IOMUX_PADS(PAD_EIM_CS0__EIM_CS0_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200246};
247
248static void eimnor_cs_setup(void)
249{
250 struct weim *weim_regs = (struct weim *)WEIM_BASE_ADDR;
251
252 writel(0x00020181, &weim_regs->cs0gcr1);
253 writel(0x00000001, &weim_regs->cs0gcr2);
254 writel(0x0a020000, &weim_regs->cs0rcr1);
255 writel(0x0000c000, &weim_regs->cs0rcr2);
256 writel(0x0804a240, &weim_regs->cs0wcr1);
257 writel(0x00000120, &weim_regs->wcr);
258
259 set_chipselect_size(CS0_128);
260}
261
Fabio Estevamcfb37772016-12-26 23:04:41 -0200262static void eim_clk_setup(void)
263{
264 struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
265 int cscmr1, ccgr6;
266
267
268 /* Turn off EIM clock */
269 ccgr6 = readl(&imx_ccm->CCGR6);
270 ccgr6 &= ~(0x3 << 10);
271 writel(ccgr6, &imx_ccm->CCGR6);
272
273 /*
274 * Configure clk_eim_slow_sel = 00 --> derive clock from AXI clk root
275 * and aclk_eim_slow_podf = 01 --> divide by 2
276 * so that we can have EIM at the maximum clock of 132MHz
277 */
278 cscmr1 = readl(&imx_ccm->cscmr1);
279 cscmr1 &= ~(MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK |
280 MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK);
281 cscmr1 |= (1 << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET);
282 writel(cscmr1, &imx_ccm->cscmr1);
283
284 /* Turn on EIM clock */
285 ccgr6 |= (0x3 << 10);
286 writel(ccgr6, &imx_ccm->CCGR6);
287}
288
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200289static void setup_iomux_eimnor(void)
290{
Vanessa Maegima823dff92017-06-29 09:33:45 -0300291 SETUP_IOMUX_PADS(eimnor_pads);
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200292
293 gpio_direction_output(IMX_GPIO_NR(5, 4), 0);
294
295 eimnor_cs_setup();
296}
Fabio Estevamca62e5d2017-07-10 15:59:11 -0300297#endif
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200298
Fabio Estevamfe5ebe92012-09-25 08:43:57 +0000299static void setup_iomux_enet(void)
300{
Vanessa Maegima823dff92017-06-29 09:33:45 -0300301 SETUP_IOMUX_PADS(enet_pads);
Fabio Estevamfe5ebe92012-09-25 08:43:57 +0000302}
303
Fabio Estevam067a6592014-09-13 18:21:36 -0300304static iomux_v3_cfg_t const usdhc3_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300305 IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
306 IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
307 IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
308 IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
309 IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
310 IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
311 IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
312 IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
313 IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
314 IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
315 IOMUX_PADS(PAD_GPIO_18__SD3_VSELECT | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
316 IOMUX_PADS(PAD_NANDF_CS2__GPIO6_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Fabio Estevam7dd65452012-09-24 08:09:33 +0000317};
318
319static void setup_iomux_uart(void)
320{
Vanessa Maegima823dff92017-06-29 09:33:45 -0300321 SETUP_IOMUX_PADS(uart4_pads);
Fabio Estevam7dd65452012-09-24 08:09:33 +0000322}
323
324#ifdef CONFIG_FSL_ESDHC
Fabio Estevam067a6592014-09-13 18:21:36 -0300325static struct fsl_esdhc_cfg usdhc_cfg[1] = {
Fabio Estevam7dd65452012-09-24 08:09:33 +0000326 {USDHC3_BASE_ADDR},
327};
328
329int board_mmc_getcd(struct mmc *mmc)
330{
331 gpio_direction_input(IMX_GPIO_NR(6, 15));
332 return !gpio_get_value(IMX_GPIO_NR(6, 15));
333}
334
335int board_mmc_init(bd_t *bis)
336{
Vanessa Maegima823dff92017-06-29 09:33:45 -0300337 SETUP_IOMUX_PADS(usdhc3_pads);
Fabio Estevam7dd65452012-09-24 08:09:33 +0000338
Benoît Thébaudeaua2ac1b32012-10-01 08:36:25 +0000339 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
Fabio Estevam7dd65452012-09-24 08:09:33 +0000340 return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
341}
342#endif
343
Ye.Li83bb3212014-11-12 14:02:05 +0800344#ifdef CONFIG_NAND_MXS
345static iomux_v3_cfg_t gpmi_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300346 IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
347 IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
348 IOMUX_PADS(PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
349 IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(GPMI_PAD_CTRL0)),
350 IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
351 IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
352 IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
353 IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
354 IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
355 IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
356 IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
357 IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
358 IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
359 IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
360 IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
361 IOMUX_PADS(PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(GPMI_PAD_CTRL1)),
Ye.Li83bb3212014-11-12 14:02:05 +0800362};
363
364static void setup_gpmi_nand(void)
365{
366 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
367
368 /* config gpmi nand iomux */
Vanessa Maegima823dff92017-06-29 09:33:45 -0300369 SETUP_IOMUX_PADS(gpmi_pads);
Ye.Li83bb3212014-11-12 14:02:05 +0800370
Ye.Li5f22d882015-01-12 17:37:13 +0800371 setup_gpmi_io_clk((MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
Ye.Li83bb3212014-11-12 14:02:05 +0800372 MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
Ye.Li5f22d882015-01-12 17:37:13 +0800373 MXC_CCM_CS2CDR_ENFC_CLK_SEL(3)));
Ye.Li83bb3212014-11-12 14:02:05 +0800374
375 /* enable apbh clock gating */
376 setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
377}
378#endif
379
Peng Fan361b7152015-07-11 11:38:47 +0800380static void setup_fec(void)
381{
382 if (is_mx6dqp()) {
383 /*
384 * select ENET MAC0 TX clock from PLL
385 */
386 imx_iomux_set_gpr_register(5, 9, 1, 1);
Peng Fan6d97dc12015-08-12 17:46:50 +0800387 enable_fec_anatop_clock(0, ENET_125MHZ);
Peng Fan361b7152015-07-11 11:38:47 +0800388 }
389
390 setup_iomux_enet();
391}
392
Fabio Estevamfe5ebe92012-09-25 08:43:57 +0000393int board_eth_init(bd_t *bis)
394{
Peng Fan361b7152015-07-11 11:38:47 +0800395 setup_fec();
Fabio Estevamfe5ebe92012-09-25 08:43:57 +0000396
Fabio Estevam579be2f2014-01-04 17:36:31 -0200397 return cpu_eth_init(bis);
Fabio Estevamfe5ebe92012-09-25 08:43:57 +0000398}
399
Fabio Estevamdce67bd2012-10-02 11:20:12 +0000400#define BOARD_REV_B 0x200
401#define BOARD_REV_A 0x100
402
403static int mx6sabre_rev(void)
404{
405 /*
406 * Get Board ID information from OCOTP_GP1[15:8]
407 * i.MX6Q ARD RevA: 0x01
408 * i.MX6Q ARD RevB: 0x02
409 */
410 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
Benoît Thébaudeau8f3ff112013-04-23 10:17:38 +0000411 struct fuse_bank *bank = &ocotp->bank[4];
412 struct fuse_bank4_regs *fuse =
413 (struct fuse_bank4_regs *)bank->fuse_regs;
414 int reg = readl(&fuse->gp1);
Fabio Estevamdce67bd2012-10-02 11:20:12 +0000415 int ret;
416
417 switch (reg >> 8 & 0x0F) {
418 case 0x02:
419 ret = BOARD_REV_B;
420 break;
421 case 0x01:
422 default:
423 ret = BOARD_REV_A;
424 break;
425 }
426
427 return ret;
428}
429
Fabio Estevam7dd65452012-09-24 08:09:33 +0000430u32 get_board_rev(void)
431{
Fabio Estevamdce67bd2012-10-02 11:20:12 +0000432 int rev = mx6sabre_rev();
433
434 return (get_cpu_rev() & ~(0xF << 8)) | rev;
Fabio Estevam7dd65452012-09-24 08:09:33 +0000435}
436
Fabio Estevam3f0a1042017-07-12 18:31:45 -0300437static int ar8031_phy_fixup(struct phy_device *phydev)
438{
439 unsigned short val;
440
441 /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
442 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
443 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
444 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
445
446 val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
447 val &= 0xffe3;
448 val |= 0x18;
449 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
450
451 /* introduce tx clock delay */
452 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
453 val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
454 val |= 0x0100;
455 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
456
457 return 0;
458}
459
460int board_phy_config(struct phy_device *phydev)
461{
462 ar8031_phy_fixup(phydev);
463
464 if (phydev->drv->config)
465 phydev->drv->config(phydev);
466
467 return 0;
468}
469
Fabio Estevam510922a2014-09-22 13:55:52 -0300470#if defined(CONFIG_VIDEO_IPUV3)
Peng Fanccf43262015-12-15 16:27:18 +0800471static void disable_lvds(struct display_info_t const *dev)
472{
473 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
474
475 clrbits_le32(&iomux->gpr[2],
476 IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
477 IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
478}
479
Fabio Estevam510922a2014-09-22 13:55:52 -0300480static void do_enable_hdmi(struct display_info_t const *dev)
481{
Peng Fanccf43262015-12-15 16:27:18 +0800482 disable_lvds(dev);
Fabio Estevam510922a2014-09-22 13:55:52 -0300483 imx_enable_hdmi_phy();
484}
485
486struct display_info_t const displays[] = {{
487 .bus = -1,
488 .addr = 0,
Peng Fanccf43262015-12-15 16:27:18 +0800489 .pixfmt = IPU_PIX_FMT_RGB666,
490 .detect = NULL,
491 .enable = NULL,
492 .mode = {
493 .name = "Hannstar-XGA",
494 .refresh = 60,
495 .xres = 1024,
496 .yres = 768,
497 .pixclock = 15385,
498 .left_margin = 220,
499 .right_margin = 40,
500 .upper_margin = 21,
501 .lower_margin = 7,
502 .hsync_len = 60,
503 .vsync_len = 10,
504 .sync = FB_SYNC_EXT,
505 .vmode = FB_VMODE_NONINTERLACED
506} }, {
507 .bus = -1,
508 .addr = 0,
Fabio Estevam510922a2014-09-22 13:55:52 -0300509 .pixfmt = IPU_PIX_FMT_RGB24,
510 .detect = detect_hdmi,
511 .enable = do_enable_hdmi,
512 .mode = {
513 .name = "HDMI",
514 .refresh = 60,
515 .xres = 1024,
516 .yres = 768,
517 .pixclock = 15385,
518 .left_margin = 220,
519 .right_margin = 40,
520 .upper_margin = 21,
521 .lower_margin = 7,
522 .hsync_len = 60,
523 .vsync_len = 10,
524 .sync = FB_SYNC_EXT,
525 .vmode = FB_VMODE_NONINTERLACED,
526} } };
527size_t display_count = ARRAY_SIZE(displays);
528
Peng Fanccf43262015-12-15 16:27:18 +0800529iomux_v3_cfg_t const backlight_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300530 IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
Peng Fanccf43262015-12-15 16:27:18 +0800531};
532
533static void setup_iomux_backlight(void)
534{
535 gpio_direction_output(IMX_GPIO_NR(2, 9), 1);
Vanessa Maegima823dff92017-06-29 09:33:45 -0300536 SETUP_IOMUX_PADS(backlight_pads);
Peng Fanccf43262015-12-15 16:27:18 +0800537}
538
Fabio Estevam510922a2014-09-22 13:55:52 -0300539static void setup_display(void)
540{
541 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
Peng Fanccf43262015-12-15 16:27:18 +0800542 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
Fabio Estevam510922a2014-09-22 13:55:52 -0300543 int reg;
544
Peng Fanccf43262015-12-15 16:27:18 +0800545 setup_iomux_backlight();
Fabio Estevam510922a2014-09-22 13:55:52 -0300546 enable_ipu_clock();
547 imx_setup_hdmi();
548
Peng Fanccf43262015-12-15 16:27:18 +0800549 /* Turn on LDB_DI0 and LDB_DI1 clocks */
550 reg = readl(&mxc_ccm->CCGR3);
551 reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
552 writel(reg, &mxc_ccm->CCGR3);
553
554 /* Set LDB_DI0 and LDB_DI1 clk select to 3b'011 */
555 reg = readl(&mxc_ccm->cs2cdr);
556 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
557 MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
558 reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
559 (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
560 writel(reg, &mxc_ccm->cs2cdr);
561
562 reg = readl(&mxc_ccm->cscmr2);
563 reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
564 writel(reg, &mxc_ccm->cscmr2);
565
Fabio Estevam510922a2014-09-22 13:55:52 -0300566 reg = readl(&mxc_ccm->chsccdr);
567 reg |= (CHSCCDR_CLK_SEL_LDB_DI0
568 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
Peng Fanccf43262015-12-15 16:27:18 +0800569 reg |= (CHSCCDR_CLK_SEL_LDB_DI0 <<
570 MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
Fabio Estevam510922a2014-09-22 13:55:52 -0300571 writel(reg, &mxc_ccm->chsccdr);
Peng Fanccf43262015-12-15 16:27:18 +0800572
573 reg = IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW |
574 IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW |
575 IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG |
576 IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT |
577 IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG |
578 IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT |
579 IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0 |
580 IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED;
581 writel(reg, &iomux->gpr[2]);
582
583 reg = readl(&iomux->gpr[3]);
584 reg &= ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK |
585 IOMUXC_GPR3_HDMI_MUX_CTL_MASK);
586 reg |= (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
587 IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET) |
588 (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
589 IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET);
590 writel(reg, &iomux->gpr[3]);
Fabio Estevam510922a2014-09-22 13:55:52 -0300591}
592#endif /* CONFIG_VIDEO_IPUV3 */
593
594/*
595 * Do not overwrite the console
596 * Use always serial for U-Boot console
597 */
598int overwrite_console(void)
599{
600 return 1;
601}
602
Fabio Estevam7dd65452012-09-24 08:09:33 +0000603int board_early_init_f(void)
604{
605 setup_iomux_uart();
Ye.Li83bb3212014-11-12 14:02:05 +0800606
607#ifdef CONFIG_NAND_MXS
608 setup_gpmi_nand();
609#endif
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200610
Fabio Estevamca62e5d2017-07-10 15:59:11 -0300611#ifdef CONFIG_MTD_NOR_FLASH
612 eim_clk_setup();
613#endif
Fabio Estevam7dd65452012-09-24 08:09:33 +0000614 return 0;
615}
616
617int board_init(void)
618{
619 /* address of boot parameters */
620 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
621
Renato Frias19578162013-05-13 18:01:12 +0000622 /* I2C 2 and 3 setup - I2C 3 hw mux with EIM */
Vanessa Maegima823dff92017-06-29 09:33:45 -0300623 if (is_mx6dq() || is_mx6dqp())
624 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1);
625 else
626 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
Renato Frias19578162013-05-13 18:01:12 +0000627 /* I2C 3 Steer */
628 gpio_direction_output(IMX_GPIO_NR(5, 4), 1);
Vanessa Maegima823dff92017-06-29 09:33:45 -0300629 SETUP_IOMUX_PADS(i2c3_pads);
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200630#ifndef CONFIG_SYS_FLASH_CFI
Vanessa Maegima823dff92017-06-29 09:33:45 -0300631 if (is_mx6dq() || is_mx6dqp())
632 setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info2);
633 else
634 setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info2);
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200635#endif
Renato Friasa1f67802013-05-13 18:01:13 +0000636 gpio_direction_output(IMX_GPIO_NR(1, 15), 1);
Vanessa Maegima823dff92017-06-29 09:33:45 -0300637 SETUP_IOMUX_PADS(port_exp);
Renato Friasa1f67802013-05-13 18:01:13 +0000638
Peng Fanccf43262015-12-15 16:27:18 +0800639#ifdef CONFIG_VIDEO_IPUV3
640 setup_display();
641#endif
Fabio Estevamca62e5d2017-07-10 15:59:11 -0300642
643#ifdef CONFIG_MTD_NOR_FLASH
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200644 setup_iomux_eimnor();
Fabio Estevamca62e5d2017-07-10 15:59:11 -0300645#endif
Fabio Estevam7dd65452012-09-24 08:09:33 +0000646 return 0;
647}
648
Nikita Kiryanov155fa9a2014-08-20 15:08:50 +0300649#ifdef CONFIG_MXC_SPI
650int board_spi_cs_gpio(unsigned bus, unsigned cs)
651{
652 return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
653}
654#endif
655
Ye.Li593243d2014-11-06 16:29:02 +0800656int power_init_board(void)
657{
658 struct pmic *p;
Peng Fan361b7152015-07-11 11:38:47 +0800659 unsigned int value;
Ye.Li593243d2014-11-06 16:29:02 +0800660
661 p = pfuze_common_init(I2C_PMIC);
662 if (!p)
663 return -ENODEV;
664
Peng Fan361b7152015-07-11 11:38:47 +0800665 if (is_mx6dqp()) {
666 /* set SW2 staby volatage 0.975V*/
667 pmic_reg_read(p, PFUZE100_SW2STBY, &value);
668 value &= ~0x3f;
669 value |= 0x17;
670 pmic_reg_write(p, PFUZE100_SW2STBY, value);
671 }
Peng Fan258c98f2015-01-27 10:14:04 +0800672
Peng Fan361b7152015-07-11 11:38:47 +0800673 return pfuze_mode_init(p, APS_PFM);
Ye.Li593243d2014-11-06 16:29:02 +0800674}
675
Otavio Salvador85449db2013-03-16 08:05:07 +0000676#ifdef CONFIG_CMD_BMODE
677static const struct boot_mode board_boot_modes[] = {
678 /* 4 bit bus width */
679 {"mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
680 {NULL, 0},
681};
682#endif
683
684int board_late_init(void)
685{
686#ifdef CONFIG_CMD_BMODE
687 add_board_boot_modes(board_boot_modes);
688#endif
689
Peng Fane6fc8992015-07-11 11:38:46 +0800690#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
Simon Glass382bee52017-08-03 12:22:09 -0600691 env_set("board_name", "SABREAUTO");
Peng Fane6fc8992015-07-11 11:38:46 +0800692
Peng Fan361b7152015-07-11 11:38:47 +0800693 if (is_mx6dqp())
Simon Glass382bee52017-08-03 12:22:09 -0600694 env_set("board_rev", "MX6QP");
Peng Fan83e13942016-05-23 18:36:06 +0800695 else if (is_mx6dq())
Simon Glass382bee52017-08-03 12:22:09 -0600696 env_set("board_rev", "MX6Q");
Peng Fan83e13942016-05-23 18:36:06 +0800697 else if (is_mx6sdl())
Simon Glass382bee52017-08-03 12:22:09 -0600698 env_set("board_rev", "MX6DL");
Peng Fane6fc8992015-07-11 11:38:46 +0800699#endif
700
Otavio Salvador85449db2013-03-16 08:05:07 +0000701 return 0;
702}
703
Fabio Estevam7dd65452012-09-24 08:09:33 +0000704int checkboard(void)
705{
Fabio Estevamdce67bd2012-10-02 11:20:12 +0000706 int rev = mx6sabre_rev();
707 char *revname;
708
709 switch (rev) {
710 case BOARD_REV_B:
711 revname = "B";
712 break;
713 case BOARD_REV_A:
714 default:
715 revname = "A";
716 break;
717 }
718
719 printf("Board: MX6Q-Sabreauto rev%s\n", revname);
Fabio Estevam7dd65452012-09-24 08:09:33 +0000720
721 return 0;
722}
Ye.Li8fe280f2014-10-30 18:53:49 +0800723
724#ifdef CONFIG_USB_EHCI_MX6
725#define USB_HOST1_PWR PORTEXP_IO_NR(0x32, 7)
726#define USB_OTG_PWR PORTEXP_IO_NR(0x34, 1)
727
728iomux_v3_cfg_t const usb_otg_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300729 IOMUX_PADS(PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL)),
Ye.Li8fe280f2014-10-30 18:53:49 +0800730};
731
732int board_ehci_hcd_init(int port)
733{
734 switch (port) {
735 case 0:
Vanessa Maegima823dff92017-06-29 09:33:45 -0300736 SETUP_IOMUX_PADS(usb_otg_pads);
Ye.Li8fe280f2014-10-30 18:53:49 +0800737
738 /*
739 * Set daisy chain for otg_pin_id on 6q.
740 * For 6dl, this bit is reserved.
741 */
742 imx_iomux_set_gpr_register(1, 13, 1, 0);
743 break;
744 case 1:
745 break;
746 default:
747 printf("MXC USB port %d not yet supported\n", port);
748 return -EINVAL;
749 }
750 return 0;
751}
752
753int board_ehci_power(int port, int on)
754{
755 switch (port) {
756 case 0:
757 if (on)
758 port_exp_direction_output(USB_OTG_PWR, 1);
759 else
760 port_exp_direction_output(USB_OTG_PWR, 0);
761 break;
762 case 1:
763 if (on)
764 port_exp_direction_output(USB_HOST1_PWR, 1);
765 else
766 port_exp_direction_output(USB_HOST1_PWR, 0);
767 break;
768 default:
769 printf("MXC USB port %d not yet supported\n", port);
770 return -EINVAL;
771 }
772
773 return 0;
774}
775#endif
Vanessa Maegima823dff92017-06-29 09:33:45 -0300776
777#ifdef CONFIG_SPL_BUILD
778#include <asm/arch/mx6-ddr.h>
779#include <spl.h>
780#include <libfdt.h>
781
Diego Dorta07f6ddb2017-07-07 15:38:34 -0300782#ifdef CONFIG_SPL_OS_BOOT
783int spl_start_uboot(void)
784{
785 return 0;
786}
787#endif
788
Vanessa Maegima823dff92017-06-29 09:33:45 -0300789static void ccgr_init(void)
790{
791 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
792
793 writel(0x00C03F3F, &ccm->CCGR0);
794 writel(0x0030FC03, &ccm->CCGR1);
795 writel(0x0FFFC000, &ccm->CCGR2);
796 writel(0x3FF00000, &ccm->CCGR3);
797 writel(0x00FFF300, &ccm->CCGR4);
798 writel(0x0F0000C3, &ccm->CCGR5);
799 writel(0x000003FF, &ccm->CCGR6);
800}
801
Vanessa Maegima823dff92017-06-29 09:33:45 -0300802static int mx6q_dcd_table[] = {
803 0x020e0798, 0x000C0000,
804 0x020e0758, 0x00000000,
805 0x020e0588, 0x00000030,
806 0x020e0594, 0x00000030,
807 0x020e056c, 0x00000030,
808 0x020e0578, 0x00000030,
809 0x020e074c, 0x00000030,
810 0x020e057c, 0x00000030,
811 0x020e058c, 0x00000000,
812 0x020e059c, 0x00000030,
813 0x020e05a0, 0x00000030,
814 0x020e078c, 0x00000030,
815 0x020e0750, 0x00020000,
816 0x020e05a8, 0x00000028,
817 0x020e05b0, 0x00000028,
818 0x020e0524, 0x00000028,
819 0x020e051c, 0x00000028,
820 0x020e0518, 0x00000028,
821 0x020e050c, 0x00000028,
822 0x020e05b8, 0x00000028,
823 0x020e05c0, 0x00000028,
824 0x020e0774, 0x00020000,
825 0x020e0784, 0x00000028,
826 0x020e0788, 0x00000028,
827 0x020e0794, 0x00000028,
828 0x020e079c, 0x00000028,
829 0x020e07a0, 0x00000028,
830 0x020e07a4, 0x00000028,
831 0x020e07a8, 0x00000028,
832 0x020e0748, 0x00000028,
833 0x020e05ac, 0x00000028,
834 0x020e05b4, 0x00000028,
835 0x020e0528, 0x00000028,
836 0x020e0520, 0x00000028,
837 0x020e0514, 0x00000028,
838 0x020e0510, 0x00000028,
839 0x020e05bc, 0x00000028,
840 0x020e05c4, 0x00000028,
841 0x021b0800, 0xa1390003,
842 0x021b080c, 0x001F001F,
843 0x021b0810, 0x001F001F,
844 0x021b480c, 0x001F001F,
845 0x021b4810, 0x001F001F,
846 0x021b083c, 0x43260335,
847 0x021b0840, 0x031A030B,
848 0x021b483c, 0x4323033B,
849 0x021b4840, 0x0323026F,
850 0x021b0848, 0x483D4545,
851 0x021b4848, 0x44433E48,
852 0x021b0850, 0x41444840,
853 0x021b4850, 0x4835483E,
854 0x021b081c, 0x33333333,
855 0x021b0820, 0x33333333,
856 0x021b0824, 0x33333333,
857 0x021b0828, 0x33333333,
858 0x021b481c, 0x33333333,
859 0x021b4820, 0x33333333,
860 0x021b4824, 0x33333333,
861 0x021b4828, 0x33333333,
862 0x021b08b8, 0x00000800,
863 0x021b48b8, 0x00000800,
864 0x021b0004, 0x00020036,
865 0x021b0008, 0x09444040,
866 0x021b000c, 0x8A8F7955,
867 0x021b0010, 0xFF328F64,
868 0x021b0014, 0x01FF00DB,
869 0x021b0018, 0x00001740,
870 0x021b001c, 0x00008000,
871 0x021b002c, 0x000026d2,
872 0x021b0030, 0x008F1023,
873 0x021b0040, 0x00000047,
874 0x021b0000, 0x841A0000,
875 0x021b001c, 0x04088032,
876 0x021b001c, 0x00008033,
877 0x021b001c, 0x00048031,
878 0x021b001c, 0x09408030,
879 0x021b001c, 0x04008040,
880 0x021b0020, 0x00005800,
881 0x021b0818, 0x00011117,
882 0x021b4818, 0x00011117,
883 0x021b0004, 0x00025576,
884 0x021b0404, 0x00011006,
885 0x021b001c, 0x00000000,
886 0x020c4068, 0x00C03F3F,
887 0x020c406c, 0x0030FC03,
888 0x020c4070, 0x0FFFC000,
889 0x020c4074, 0x3FF00000,
890 0x020c4078, 0xFFFFF300,
891 0x020c407c, 0x0F0000F3,
892 0x020c4080, 0x00000FFF,
893 0x020e0010, 0xF00000CF,
894 0x020e0018, 0x007F007F,
895 0x020e001c, 0x007F007F,
896};
897
898static int mx6qp_dcd_table[] = {
899 0x020e0798, 0x000C0000,
900 0x020e0758, 0x00000000,
901 0x020e0588, 0x00000030,
902 0x020e0594, 0x00000030,
903 0x020e056c, 0x00000030,
904 0x020e0578, 0x00000030,
905 0x020e074c, 0x00000030,
906 0x020e057c, 0x00000030,
907 0x020e058c, 0x00000000,
908 0x020e059c, 0x00000030,
909 0x020e05a0, 0x00000030,
910 0x020e078c, 0x00000030,
911 0x020e0750, 0x00020000,
912 0x020e05a8, 0x00000030,
913 0x020e05b0, 0x00000030,
914 0x020e0524, 0x00000030,
915 0x020e051c, 0x00000030,
916 0x020e0518, 0x00000030,
917 0x020e050c, 0x00000030,
918 0x020e05b8, 0x00000030,
919 0x020e05c0, 0x00000030,
920 0x020e0774, 0x00020000,
921 0x020e0784, 0x00000030,
922 0x020e0788, 0x00000030,
923 0x020e0794, 0x00000030,
924 0x020e079c, 0x00000030,
925 0x020e07a0, 0x00000030,
926 0x020e07a4, 0x00000030,
927 0x020e07a8, 0x00000030,
928 0x020e0748, 0x00000030,
929 0x020e05ac, 0x00000030,
930 0x020e05b4, 0x00000030,
931 0x020e0528, 0x00000030,
932 0x020e0520, 0x00000030,
933 0x020e0514, 0x00000030,
934 0x020e0510, 0x00000030,
935 0x020e05bc, 0x00000030,
936 0x020e05c4, 0x00000030,
937 0x021b0800, 0xa1390003,
938 0x021b080c, 0x001b001e,
939 0x021b0810, 0x002e0029,
940 0x021b480c, 0x001b002a,
941 0x021b4810, 0x0019002c,
942 0x021b083c, 0x43240334,
943 0x021b0840, 0x0324031a,
944 0x021b483c, 0x43340344,
945 0x021b4840, 0x03280276,
946 0x021b0848, 0x44383A3E,
947 0x021b4848, 0x3C3C3846,
948 0x021b0850, 0x2e303230,
949 0x021b4850, 0x38283E34,
950 0x021b081c, 0x33333333,
951 0x021b0820, 0x33333333,
952 0x021b0824, 0x33333333,
953 0x021b0828, 0x33333333,
954 0x021b481c, 0x33333333,
955 0x021b4820, 0x33333333,
956 0x021b4824, 0x33333333,
957 0x021b4828, 0x33333333,
958 0x021b08c0, 0x24912492,
959 0x021b48c0, 0x24912492,
960 0x021b08b8, 0x00000800,
961 0x021b48b8, 0x00000800,
962 0x021b0004, 0x00020036,
963 0x021b0008, 0x09444040,
964 0x021b000c, 0x898E7955,
965 0x021b0010, 0xFF328F64,
966 0x021b0014, 0x01FF00DB,
967 0x021b0018, 0x00001740,
968 0x021b001c, 0x00008000,
969 0x021b002c, 0x000026d2,
970 0x021b0030, 0x008E1023,
971 0x021b0040, 0x00000047,
972 0x021b0400, 0x14420000,
973 0x021b0000, 0x841A0000,
974 0x00bb0008, 0x00000004,
975 0x00bb000c, 0x2891E41A,
976 0x00bb0038, 0x00000564,
977 0x00bb0014, 0x00000040,
978 0x00bb0028, 0x00000020,
979 0x00bb002c, 0x00000020,
980 0x021b001c, 0x04088032,
981 0x021b001c, 0x00008033,
982 0x021b001c, 0x00048031,
983 0x021b001c, 0x09408030,
984 0x021b001c, 0x04008040,
985 0x021b0020, 0x00005800,
986 0x021b0818, 0x00011117,
987 0x021b4818, 0x00011117,
988 0x021b0004, 0x00025576,
989 0x021b0404, 0x00011006,
990 0x021b001c, 0x00000000,
991 0x020c4068, 0x00C03F3F,
992 0x020c406c, 0x0030FC03,
993 0x020c4070, 0x0FFFC000,
994 0x020c4074, 0x3FF00000,
995 0x020c4078, 0xFFFFF300,
996 0x020c407c, 0x0F0000F3,
997 0x020c4080, 0x00000FFF,
998 0x020e0010, 0xF00000CF,
999 0x020e0018, 0x77177717,
1000 0x020e001c, 0x77177717,
1001};
1002
1003static int mx6dl_dcd_table[] = {
1004 0x020e0774, 0x000C0000,
1005 0x020e0754, 0x00000000,
1006 0x020e04ac, 0x00000030,
1007 0x020e04b0, 0x00000030,
1008 0x020e0464, 0x00000030,
1009 0x020e0490, 0x00000030,
1010 0x020e074c, 0x00000030,
1011 0x020e0494, 0x00000030,
1012 0x020e04a0, 0x00000000,
1013 0x020e04b4, 0x00000030,
1014 0x020e04b8, 0x00000030,
1015 0x020e076c, 0x00000030,
1016 0x020e0750, 0x00020000,
1017 0x020e04bc, 0x00000028,
1018 0x020e04c0, 0x00000028,
1019 0x020e04c4, 0x00000028,
1020 0x020e04c8, 0x00000028,
1021 0x020e04cc, 0x00000028,
1022 0x020e04d0, 0x00000028,
1023 0x020e04d4, 0x00000028,
1024 0x020e04d8, 0x00000028,
1025 0x020e0760, 0x00020000,
1026 0x020e0764, 0x00000028,
1027 0x020e0770, 0x00000028,
1028 0x020e0778, 0x00000028,
1029 0x020e077c, 0x00000028,
1030 0x020e0780, 0x00000028,
1031 0x020e0784, 0x00000028,
1032 0x020e078c, 0x00000028,
1033 0x020e0748, 0x00000028,
1034 0x020e0470, 0x00000028,
1035 0x020e0474, 0x00000028,
1036 0x020e0478, 0x00000028,
1037 0x020e047c, 0x00000028,
1038 0x020e0480, 0x00000028,
1039 0x020e0484, 0x00000028,
1040 0x020e0488, 0x00000028,
1041 0x020e048c, 0x00000028,
1042 0x021b0800, 0xa1390003,
1043 0x021b080c, 0x001F001F,
1044 0x021b0810, 0x001F001F,
1045 0x021b480c, 0x001F001F,
1046 0x021b4810, 0x001F001F,
1047 0x021b083c, 0x42190217,
1048 0x021b0840, 0x017B017B,
1049 0x021b483c, 0x4176017B,
1050 0x021b4840, 0x015F016C,
1051 0x021b0848, 0x4C4C4D4C,
1052 0x021b4848, 0x4A4D4C48,
1053 0x021b0850, 0x3F3F3F40,
1054 0x021b4850, 0x3538382E,
1055 0x021b081c, 0x33333333,
1056 0x021b0820, 0x33333333,
1057 0x021b0824, 0x33333333,
1058 0x021b0828, 0x33333333,
1059 0x021b481c, 0x33333333,
1060 0x021b4820, 0x33333333,
1061 0x021b4824, 0x33333333,
1062 0x021b4828, 0x33333333,
1063 0x021b08b8, 0x00000800,
1064 0x021b48b8, 0x00000800,
1065 0x021b0004, 0x00020025,
1066 0x021b0008, 0x00333030,
1067 0x021b000c, 0x676B5313,
1068 0x021b0010, 0xB66E8B63,
1069 0x021b0014, 0x01FF00DB,
1070 0x021b0018, 0x00001740,
1071 0x021b001c, 0x00008000,
1072 0x021b002c, 0x000026d2,
1073 0x021b0030, 0x006B1023,
1074 0x021b0040, 0x00000047,
1075 0x021b0000, 0x841A0000,
1076 0x021b001c, 0x04008032,
1077 0x021b001c, 0x00008033,
1078 0x021b001c, 0x00048031,
1079 0x021b001c, 0x05208030,
1080 0x021b001c, 0x04008040,
1081 0x021b0020, 0x00005800,
1082 0x021b0818, 0x00011117,
1083 0x021b4818, 0x00011117,
1084 0x021b0004, 0x00025565,
1085 0x021b0404, 0x00011006,
1086 0x021b001c, 0x00000000,
1087 0x020c4068, 0x00C03F3F,
1088 0x020c406c, 0x0030FC03,
1089 0x020c4070, 0x0FFFC000,
1090 0x020c4074, 0x3FF00000,
1091 0x020c4078, 0xFFFFF300,
1092 0x020c407c, 0x0F0000C3,
1093 0x020c4080, 0x00000FFF,
1094 0x020e0010, 0xF00000CF,
1095 0x020e0018, 0x007F007F,
1096 0x020e001c, 0x007F007F,
1097};
1098
1099static void ddr_init(int *table, int size)
1100{
1101 int i;
1102
1103 for (i = 0; i < size / 2 ; i++)
1104 writel(table[2 * i + 1], table[2 * i]);
1105}
1106
1107static void spl_dram_init(void)
1108{
1109 if (is_mx6dq())
1110 ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table));
1111 else if (is_mx6dqp())
1112 ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table));
1113 else if (is_mx6sdl())
1114 ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table));
1115}
1116
1117void board_init_f(ulong dummy)
1118{
1119 /* DDR initialization */
1120 spl_dram_init();
1121
1122 /* setup AIPS and disable watchdog */
1123 arch_cpu_init();
1124
1125 ccgr_init();
1126 gpr_init();
1127
1128 /* iomux and setup of i2c */
1129 board_early_init_f();
1130
1131 /* setup GP timer */
1132 timer_init();
1133
1134 /* UART clocks enabled and gd valid - init serial console */
1135 preloader_console_init();
1136
1137 /* Clear the BSS. */
1138 memset(__bss_start, 0, __bss_end - __bss_start);
1139
1140 /* load/boot image from boot device */
1141 board_init_r(NULL, 0);
1142}
1143#endif