blob: a5703a35b16381fc16abff2ca97d7b1f5b8db957 [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>
Fabio Estevam510922a2014-09-22 13:55:52 -030027#include <asm/arch/mxc_hdmi.h>
Stefano Babic552a8482017-06-29 10:16:06 +020028#include <asm/mach-imx/video.h>
Fabio Estevam510922a2014-09-22 13:55:52 -030029#include <asm/arch/crm_regs.h>
Ye.Li8fe280f2014-10-30 18:53:49 +080030#include <pca953x.h>
Ye.Li593243d2014-11-06 16:29:02 +080031#include <power/pmic.h>
Peng Fan258c98f2015-01-27 10:14:04 +080032#include <power/pfuze100_pmic.h>
Ye.Li593243d2014-11-06 16:29:02 +080033#include "../common/pfuze.h"
Fabio Estevamdce67bd2012-10-02 11:20:12 +000034
Fabio Estevam7dd65452012-09-24 08:09:33 +000035DECLARE_GLOBAL_DATA_PTR;
36
Benoît Thébaudeau7e2173c2013-04-26 01:34:47 +000037#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
38 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
39 PAD_CTL_SRE_FAST | PAD_CTL_HYS)
Fabio Estevam7dd65452012-09-24 08:09:33 +000040
Benoît Thébaudeau7e2173c2013-04-26 01:34:47 +000041#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
42 PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
43 PAD_CTL_SRE_FAST | PAD_CTL_HYS)
Fabio Estevam7dd65452012-09-24 08:09:33 +000044
Benoît Thébaudeau7e2173c2013-04-26 01:34:47 +000045#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
46 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
Fabio Estevamfe5ebe92012-09-25 08:43:57 +000047
Renato Frias19578162013-05-13 18:01:12 +000048#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
49 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
50 PAD_CTL_ODE | PAD_CTL_SRE_FAST)
51
Ye.Li83bb3212014-11-12 14:02:05 +080052#define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
53#define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
54 PAD_CTL_SRE_FAST)
55#define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
56
Renato Frias19578162013-05-13 18:01:12 +000057#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
58
Fabio Estevamcdbdde32014-11-14 11:27:23 -020059#define WEIM_NOR_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
60 PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
61 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
62
Ye.Li593243d2014-11-06 16:29:02 +080063#define I2C_PMIC 1
64
Fabio Estevam7dd65452012-09-24 08:09:33 +000065int dram_init(void)
66{
Vanessa Maegima369012e2016-06-08 15:17:54 -030067 gd->ram_size = imx_ddr_size();
Fabio Estevam7dd65452012-09-24 08:09:33 +000068
69 return 0;
70}
71
Fabio Estevam067a6592014-09-13 18:21:36 -030072static iomux_v3_cfg_t const uart4_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -030073 IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
74 IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
Fabio Estevam7dd65452012-09-24 08:09:33 +000075};
76
Fabio Estevam067a6592014-09-13 18:21:36 -030077static iomux_v3_cfg_t const enet_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -030078 IOMUX_PADS(PAD_KEY_COL1__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
79 IOMUX_PADS(PAD_KEY_COL2__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
80 IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
81 IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
82 IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
83 IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
84 IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
85 IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
86 IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL)),
87 IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
88 IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
89 IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
90 IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
91 IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
92 IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
Fabio Estevamfe5ebe92012-09-25 08:43:57 +000093};
94
Renato Frias19578162013-05-13 18:01:12 +000095/* I2C2 PMIC, iPod, Tuner, Codec, Touch, HDMI EDID, MIPI CSI2 card */
Vanessa Maegima823dff92017-06-29 09:33:45 -030096static struct i2c_pads_info mx6q_i2c_pad_info1 = {
Renato Frias19578162013-05-13 18:01:12 +000097 .scl = {
Vanessa Maegima823dff92017-06-29 09:33:45 -030098 .i2c_mode = MX6Q_PAD_EIM_EB2__I2C2_SCL | PC,
99 .gpio_mode = MX6Q_PAD_EIM_EB2__GPIO2_IO30 | PC,
Renato Frias19578162013-05-13 18:01:12 +0000100 .gp = IMX_GPIO_NR(2, 30)
101 },
102 .sda = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300103 .i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
104 .gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | PC,
105 .gp = IMX_GPIO_NR(4, 13)
106 }
107};
108
109static struct i2c_pads_info mx6dl_i2c_pad_info1 = {
110 .scl = {
111 .i2c_mode = MX6DL_PAD_EIM_EB2__I2C2_SCL | PC,
112 .gpio_mode = MX6DL_PAD_EIM_EB2__GPIO2_IO30 | PC,
113 .gp = IMX_GPIO_NR(2, 30)
114 },
115 .sda = {
116 .i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | PC,
117 .gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | PC,
Renato Frias19578162013-05-13 18:01:12 +0000118 .gp = IMX_GPIO_NR(4, 13)
119 }
120};
121
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200122#ifndef CONFIG_SYS_FLASH_CFI
Renato Frias19578162013-05-13 18:01:12 +0000123/*
124 * I2C3 MLB, Port Expanders (A, B, C), Video ADC, Light Sensor,
125 * Compass Sensor, Accelerometer, Res Touch
126 */
Vanessa Maegima823dff92017-06-29 09:33:45 -0300127static struct i2c_pads_info mx6q_i2c_pad_info2 = {
Renato Frias19578162013-05-13 18:01:12 +0000128 .scl = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300129 .i2c_mode = MX6Q_PAD_GPIO_3__I2C3_SCL | PC,
130 .gpio_mode = MX6Q_PAD_GPIO_3__GPIO1_IO03 | PC,
Renato Frias19578162013-05-13 18:01:12 +0000131 .gp = IMX_GPIO_NR(1, 3)
132 },
133 .sda = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300134 .i2c_mode = MX6Q_PAD_EIM_D18__I2C3_SDA | PC,
135 .gpio_mode = MX6Q_PAD_EIM_D18__GPIO3_IO18 | PC,
136 .gp = IMX_GPIO_NR(3, 18)
137 }
138};
139
140static struct i2c_pads_info mx6dl_i2c_pad_info2 = {
141 .scl = {
142 .i2c_mode = MX6DL_PAD_GPIO_3__I2C3_SCL | PC,
143 .gpio_mode = MX6DL_PAD_GPIO_3__GPIO1_IO03 | PC,
144 .gp = IMX_GPIO_NR(1, 3)
145 },
146 .sda = {
147 .i2c_mode = MX6DL_PAD_EIM_D18__I2C3_SDA | PC,
148 .gpio_mode = MX6DL_PAD_EIM_D18__GPIO3_IO18 | PC,
Renato Frias19578162013-05-13 18:01:12 +0000149 .gp = IMX_GPIO_NR(3, 18)
150 }
151};
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200152#endif
Renato Frias19578162013-05-13 18:01:12 +0000153
Fabio Estevam067a6592014-09-13 18:21:36 -0300154static iomux_v3_cfg_t const i2c3_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300155 IOMUX_PADS(PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Renato Frias19578162013-05-13 18:01:12 +0000156};
157
Fabio Estevam067a6592014-09-13 18:21:36 -0300158static iomux_v3_cfg_t const port_exp[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300159 IOMUX_PADS(PAD_SD2_DAT0__GPIO1_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Renato Friasa1f67802013-05-13 18:01:13 +0000160};
161
Ye.Li8fe280f2014-10-30 18:53:49 +0800162/*Define for building port exp gpio, pin starts from 0*/
163#define PORTEXP_IO_NR(chip, pin) \
164 ((chip << 5) + pin)
165
166/*Get the chip addr from a ioexp gpio*/
167#define PORTEXP_IO_TO_CHIP(gpio_nr) \
168 (gpio_nr >> 5)
169
170/*Get the pin number from a ioexp gpio*/
171#define PORTEXP_IO_TO_PIN(gpio_nr) \
172 (gpio_nr & 0x1f)
173
174static int port_exp_direction_output(unsigned gpio, int value)
175{
176 int ret;
177
178 i2c_set_bus_num(2);
179 ret = i2c_probe(PORTEXP_IO_TO_CHIP(gpio));
180 if (ret)
181 return ret;
182
183 ret = pca953x_set_dir(PORTEXP_IO_TO_CHIP(gpio),
184 (1 << PORTEXP_IO_TO_PIN(gpio)),
185 (PCA953X_DIR_OUT << PORTEXP_IO_TO_PIN(gpio)));
186
187 if (ret)
188 return ret;
189
190 ret = pca953x_set_val(PORTEXP_IO_TO_CHIP(gpio),
191 (1 << PORTEXP_IO_TO_PIN(gpio)),
192 (value << PORTEXP_IO_TO_PIN(gpio)));
193
194 if (ret)
195 return ret;
196
197 return 0;
198}
199
Fabio Estevamca62e5d2017-07-10 15:59:11 -0300200#ifdef CONFIG_MTD_NOR_FLASH
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200201static iomux_v3_cfg_t const eimnor_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300202 IOMUX_PADS(PAD_EIM_D16__EIM_DATA16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
203 IOMUX_PADS(PAD_EIM_D17__EIM_DATA17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
204 IOMUX_PADS(PAD_EIM_D18__EIM_DATA18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
205 IOMUX_PADS(PAD_EIM_D19__EIM_DATA19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
206 IOMUX_PADS(PAD_EIM_D20__EIM_DATA20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
207 IOMUX_PADS(PAD_EIM_D21__EIM_DATA21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
208 IOMUX_PADS(PAD_EIM_D22__EIM_DATA22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
209 IOMUX_PADS(PAD_EIM_D23__EIM_DATA23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
210 IOMUX_PADS(PAD_EIM_D24__EIM_DATA24 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
211 IOMUX_PADS(PAD_EIM_D25__EIM_DATA25 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
212 IOMUX_PADS(PAD_EIM_D26__EIM_DATA26 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
213 IOMUX_PADS(PAD_EIM_D27__EIM_DATA27 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
214 IOMUX_PADS(PAD_EIM_D28__EIM_DATA28 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
215 IOMUX_PADS(PAD_EIM_D29__EIM_DATA29 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
216 IOMUX_PADS(PAD_EIM_D30__EIM_DATA30 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
217 IOMUX_PADS(PAD_EIM_D31__EIM_DATA31 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
218 IOMUX_PADS(PAD_EIM_DA0__EIM_AD00 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
219 IOMUX_PADS(PAD_EIM_DA1__EIM_AD01 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
220 IOMUX_PADS(PAD_EIM_DA2__EIM_AD02 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
221 IOMUX_PADS(PAD_EIM_DA3__EIM_AD03 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
222 IOMUX_PADS(PAD_EIM_DA4__EIM_AD04 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
223 IOMUX_PADS(PAD_EIM_DA5__EIM_AD05 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
224 IOMUX_PADS(PAD_EIM_DA6__EIM_AD06 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
225 IOMUX_PADS(PAD_EIM_DA7__EIM_AD07 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
226 IOMUX_PADS(PAD_EIM_DA8__EIM_AD08 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
227 IOMUX_PADS(PAD_EIM_DA9__EIM_AD09 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
228 IOMUX_PADS(PAD_EIM_DA10__EIM_AD10 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
229 IOMUX_PADS(PAD_EIM_DA11__EIM_AD11 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
230 IOMUX_PADS(PAD_EIM_DA12__EIM_AD12 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
231 IOMUX_PADS(PAD_EIM_DA13__EIM_AD13 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
232 IOMUX_PADS(PAD_EIM_DA14__EIM_AD14 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
233 IOMUX_PADS(PAD_EIM_DA15__EIM_AD15 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
234 IOMUX_PADS(PAD_EIM_A16__EIM_ADDR16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
235 IOMUX_PADS(PAD_EIM_A17__EIM_ADDR17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
236 IOMUX_PADS(PAD_EIM_A18__EIM_ADDR18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
237 IOMUX_PADS(PAD_EIM_A19__EIM_ADDR19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
238 IOMUX_PADS(PAD_EIM_A20__EIM_ADDR20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
239 IOMUX_PADS(PAD_EIM_A21__EIM_ADDR21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
240 IOMUX_PADS(PAD_EIM_A22__EIM_ADDR22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
241 IOMUX_PADS(PAD_EIM_A23__EIM_ADDR23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)),
242 IOMUX_PADS(PAD_EIM_OE__EIM_OE_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
243 IOMUX_PADS(PAD_EIM_RW__EIM_RW | MUX_PAD_CTRL(NO_PAD_CTRL)),
244 IOMUX_PADS(PAD_EIM_CS0__EIM_CS0_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200245};
246
247static void eimnor_cs_setup(void)
248{
249 struct weim *weim_regs = (struct weim *)WEIM_BASE_ADDR;
250
251 writel(0x00020181, &weim_regs->cs0gcr1);
252 writel(0x00000001, &weim_regs->cs0gcr2);
253 writel(0x0a020000, &weim_regs->cs0rcr1);
254 writel(0x0000c000, &weim_regs->cs0rcr2);
255 writel(0x0804a240, &weim_regs->cs0wcr1);
256 writel(0x00000120, &weim_regs->wcr);
257
258 set_chipselect_size(CS0_128);
259}
260
Fabio Estevamcfb37772016-12-26 23:04:41 -0200261static void eim_clk_setup(void)
262{
263 struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
264 int cscmr1, ccgr6;
265
266
267 /* Turn off EIM clock */
268 ccgr6 = readl(&imx_ccm->CCGR6);
269 ccgr6 &= ~(0x3 << 10);
270 writel(ccgr6, &imx_ccm->CCGR6);
271
272 /*
273 * Configure clk_eim_slow_sel = 00 --> derive clock from AXI clk root
274 * and aclk_eim_slow_podf = 01 --> divide by 2
275 * so that we can have EIM at the maximum clock of 132MHz
276 */
277 cscmr1 = readl(&imx_ccm->cscmr1);
278 cscmr1 &= ~(MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK |
279 MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK);
280 cscmr1 |= (1 << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET);
281 writel(cscmr1, &imx_ccm->cscmr1);
282
283 /* Turn on EIM clock */
284 ccgr6 |= (0x3 << 10);
285 writel(ccgr6, &imx_ccm->CCGR6);
286}
287
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200288static void setup_iomux_eimnor(void)
289{
Vanessa Maegima823dff92017-06-29 09:33:45 -0300290 SETUP_IOMUX_PADS(eimnor_pads);
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200291
292 gpio_direction_output(IMX_GPIO_NR(5, 4), 0);
293
294 eimnor_cs_setup();
295}
Fabio Estevamca62e5d2017-07-10 15:59:11 -0300296#endif
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200297
Fabio Estevamfe5ebe92012-09-25 08:43:57 +0000298static void setup_iomux_enet(void)
299{
Vanessa Maegima823dff92017-06-29 09:33:45 -0300300 SETUP_IOMUX_PADS(enet_pads);
Fabio Estevamfe5ebe92012-09-25 08:43:57 +0000301}
302
Fabio Estevam067a6592014-09-13 18:21:36 -0300303static iomux_v3_cfg_t const usdhc3_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300304 IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
305 IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
306 IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
307 IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
308 IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
309 IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
310 IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
311 IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
312 IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
313 IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
314 IOMUX_PADS(PAD_GPIO_18__SD3_VSELECT | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
315 IOMUX_PADS(PAD_NANDF_CS2__GPIO6_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Fabio Estevam7dd65452012-09-24 08:09:33 +0000316};
317
318static void setup_iomux_uart(void)
319{
Vanessa Maegima823dff92017-06-29 09:33:45 -0300320 SETUP_IOMUX_PADS(uart4_pads);
Fabio Estevam7dd65452012-09-24 08:09:33 +0000321}
322
323#ifdef CONFIG_FSL_ESDHC
Fabio Estevam067a6592014-09-13 18:21:36 -0300324static struct fsl_esdhc_cfg usdhc_cfg[1] = {
Fabio Estevam7dd65452012-09-24 08:09:33 +0000325 {USDHC3_BASE_ADDR},
326};
327
328int board_mmc_getcd(struct mmc *mmc)
329{
330 gpio_direction_input(IMX_GPIO_NR(6, 15));
331 return !gpio_get_value(IMX_GPIO_NR(6, 15));
332}
333
334int board_mmc_init(bd_t *bis)
335{
Vanessa Maegima823dff92017-06-29 09:33:45 -0300336 SETUP_IOMUX_PADS(usdhc3_pads);
Fabio Estevam7dd65452012-09-24 08:09:33 +0000337
Benoît Thébaudeaua2ac1b32012-10-01 08:36:25 +0000338 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
Fabio Estevam7dd65452012-09-24 08:09:33 +0000339 return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
340}
341#endif
342
Ye.Li83bb3212014-11-12 14:02:05 +0800343#ifdef CONFIG_NAND_MXS
344static iomux_v3_cfg_t gpmi_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300345 IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
346 IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
347 IOMUX_PADS(PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
348 IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(GPMI_PAD_CTRL0)),
349 IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
350 IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
351 IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
352 IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
353 IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
354 IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
355 IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
356 IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
357 IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
358 IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
359 IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
360 IOMUX_PADS(PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(GPMI_PAD_CTRL1)),
Ye.Li83bb3212014-11-12 14:02:05 +0800361};
362
363static void setup_gpmi_nand(void)
364{
365 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
366
367 /* config gpmi nand iomux */
Vanessa Maegima823dff92017-06-29 09:33:45 -0300368 SETUP_IOMUX_PADS(gpmi_pads);
Ye.Li83bb3212014-11-12 14:02:05 +0800369
Ye.Li5f22d882015-01-12 17:37:13 +0800370 setup_gpmi_io_clk((MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
Ye.Li83bb3212014-11-12 14:02:05 +0800371 MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
Ye.Li5f22d882015-01-12 17:37:13 +0800372 MXC_CCM_CS2CDR_ENFC_CLK_SEL(3)));
Ye.Li83bb3212014-11-12 14:02:05 +0800373
374 /* enable apbh clock gating */
375 setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
376}
377#endif
378
Peng Fan361b7152015-07-11 11:38:47 +0800379static void setup_fec(void)
380{
381 if (is_mx6dqp()) {
382 /*
383 * select ENET MAC0 TX clock from PLL
384 */
385 imx_iomux_set_gpr_register(5, 9, 1, 1);
Peng Fan6d97dc12015-08-12 17:46:50 +0800386 enable_fec_anatop_clock(0, ENET_125MHZ);
Peng Fan361b7152015-07-11 11:38:47 +0800387 }
388
389 setup_iomux_enet();
390}
391
Fabio Estevamfe5ebe92012-09-25 08:43:57 +0000392int board_eth_init(bd_t *bis)
393{
Peng Fan361b7152015-07-11 11:38:47 +0800394 setup_fec();
Fabio Estevamfe5ebe92012-09-25 08:43:57 +0000395
Fabio Estevam579be2f2014-01-04 17:36:31 -0200396 return cpu_eth_init(bis);
Fabio Estevamfe5ebe92012-09-25 08:43:57 +0000397}
398
Fabio Estevamdce67bd2012-10-02 11:20:12 +0000399#define BOARD_REV_B 0x200
400#define BOARD_REV_A 0x100
401
402static int mx6sabre_rev(void)
403{
404 /*
405 * Get Board ID information from OCOTP_GP1[15:8]
406 * i.MX6Q ARD RevA: 0x01
407 * i.MX6Q ARD RevB: 0x02
408 */
409 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
Benoît Thébaudeau8f3ff112013-04-23 10:17:38 +0000410 struct fuse_bank *bank = &ocotp->bank[4];
411 struct fuse_bank4_regs *fuse =
412 (struct fuse_bank4_regs *)bank->fuse_regs;
413 int reg = readl(&fuse->gp1);
Fabio Estevamdce67bd2012-10-02 11:20:12 +0000414 int ret;
415
416 switch (reg >> 8 & 0x0F) {
417 case 0x02:
418 ret = BOARD_REV_B;
419 break;
420 case 0x01:
421 default:
422 ret = BOARD_REV_A;
423 break;
424 }
425
426 return ret;
427}
428
Fabio Estevam7dd65452012-09-24 08:09:33 +0000429u32 get_board_rev(void)
430{
Fabio Estevamdce67bd2012-10-02 11:20:12 +0000431 int rev = mx6sabre_rev();
432
433 return (get_cpu_rev() & ~(0xF << 8)) | rev;
Fabio Estevam7dd65452012-09-24 08:09:33 +0000434}
435
Fabio Estevam3f0a1042017-07-12 18:31:45 -0300436static int ar8031_phy_fixup(struct phy_device *phydev)
437{
438 unsigned short val;
439
440 /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
441 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
442 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
443 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
444
445 val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
446 val &= 0xffe3;
447 val |= 0x18;
448 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
449
450 /* introduce tx clock delay */
451 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
452 val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
453 val |= 0x0100;
454 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
455
456 return 0;
457}
458
459int board_phy_config(struct phy_device *phydev)
460{
461 ar8031_phy_fixup(phydev);
462
463 if (phydev->drv->config)
464 phydev->drv->config(phydev);
465
466 return 0;
467}
468
Fabio Estevam510922a2014-09-22 13:55:52 -0300469#if defined(CONFIG_VIDEO_IPUV3)
Peng Fanccf43262015-12-15 16:27:18 +0800470static void disable_lvds(struct display_info_t const *dev)
471{
472 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
473
474 clrbits_le32(&iomux->gpr[2],
475 IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
476 IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
477}
478
Fabio Estevam510922a2014-09-22 13:55:52 -0300479static void do_enable_hdmi(struct display_info_t const *dev)
480{
Peng Fanccf43262015-12-15 16:27:18 +0800481 disable_lvds(dev);
Fabio Estevam510922a2014-09-22 13:55:52 -0300482 imx_enable_hdmi_phy();
483}
484
485struct display_info_t const displays[] = {{
486 .bus = -1,
487 .addr = 0,
Peng Fanccf43262015-12-15 16:27:18 +0800488 .pixfmt = IPU_PIX_FMT_RGB666,
489 .detect = NULL,
490 .enable = NULL,
491 .mode = {
492 .name = "Hannstar-XGA",
493 .refresh = 60,
494 .xres = 1024,
495 .yres = 768,
496 .pixclock = 15385,
497 .left_margin = 220,
498 .right_margin = 40,
499 .upper_margin = 21,
500 .lower_margin = 7,
501 .hsync_len = 60,
502 .vsync_len = 10,
503 .sync = FB_SYNC_EXT,
504 .vmode = FB_VMODE_NONINTERLACED
505} }, {
506 .bus = -1,
507 .addr = 0,
Fabio Estevam510922a2014-09-22 13:55:52 -0300508 .pixfmt = IPU_PIX_FMT_RGB24,
509 .detect = detect_hdmi,
510 .enable = do_enable_hdmi,
511 .mode = {
512 .name = "HDMI",
513 .refresh = 60,
514 .xres = 1024,
515 .yres = 768,
516 .pixclock = 15385,
517 .left_margin = 220,
518 .right_margin = 40,
519 .upper_margin = 21,
520 .lower_margin = 7,
521 .hsync_len = 60,
522 .vsync_len = 10,
523 .sync = FB_SYNC_EXT,
524 .vmode = FB_VMODE_NONINTERLACED,
525} } };
526size_t display_count = ARRAY_SIZE(displays);
527
Peng Fanccf43262015-12-15 16:27:18 +0800528iomux_v3_cfg_t const backlight_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300529 IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
Peng Fanccf43262015-12-15 16:27:18 +0800530};
531
532static void setup_iomux_backlight(void)
533{
534 gpio_direction_output(IMX_GPIO_NR(2, 9), 1);
Vanessa Maegima823dff92017-06-29 09:33:45 -0300535 SETUP_IOMUX_PADS(backlight_pads);
Peng Fanccf43262015-12-15 16:27:18 +0800536}
537
Fabio Estevam510922a2014-09-22 13:55:52 -0300538static void setup_display(void)
539{
540 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
Peng Fanccf43262015-12-15 16:27:18 +0800541 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
Fabio Estevam510922a2014-09-22 13:55:52 -0300542 int reg;
543
Peng Fanccf43262015-12-15 16:27:18 +0800544 setup_iomux_backlight();
Fabio Estevam510922a2014-09-22 13:55:52 -0300545 enable_ipu_clock();
546 imx_setup_hdmi();
547
Peng Fanccf43262015-12-15 16:27:18 +0800548 /* Turn on LDB_DI0 and LDB_DI1 clocks */
549 reg = readl(&mxc_ccm->CCGR3);
550 reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
551 writel(reg, &mxc_ccm->CCGR3);
552
553 /* Set LDB_DI0 and LDB_DI1 clk select to 3b'011 */
554 reg = readl(&mxc_ccm->cs2cdr);
555 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
556 MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
557 reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
558 (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
559 writel(reg, &mxc_ccm->cs2cdr);
560
561 reg = readl(&mxc_ccm->cscmr2);
562 reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
563 writel(reg, &mxc_ccm->cscmr2);
564
Fabio Estevam510922a2014-09-22 13:55:52 -0300565 reg = readl(&mxc_ccm->chsccdr);
566 reg |= (CHSCCDR_CLK_SEL_LDB_DI0
567 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
Peng Fanccf43262015-12-15 16:27:18 +0800568 reg |= (CHSCCDR_CLK_SEL_LDB_DI0 <<
569 MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
Fabio Estevam510922a2014-09-22 13:55:52 -0300570 writel(reg, &mxc_ccm->chsccdr);
Peng Fanccf43262015-12-15 16:27:18 +0800571
572 reg = IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW |
573 IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW |
574 IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG |
575 IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT |
576 IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG |
577 IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT |
578 IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0 |
579 IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED;
580 writel(reg, &iomux->gpr[2]);
581
582 reg = readl(&iomux->gpr[3]);
583 reg &= ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK |
584 IOMUXC_GPR3_HDMI_MUX_CTL_MASK);
585 reg |= (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
586 IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET) |
587 (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
588 IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET);
589 writel(reg, &iomux->gpr[3]);
Fabio Estevam510922a2014-09-22 13:55:52 -0300590}
591#endif /* CONFIG_VIDEO_IPUV3 */
592
593/*
594 * Do not overwrite the console
595 * Use always serial for U-Boot console
596 */
597int overwrite_console(void)
598{
599 return 1;
600}
601
Fabio Estevam7dd65452012-09-24 08:09:33 +0000602int board_early_init_f(void)
603{
604 setup_iomux_uart();
Ye.Li83bb3212014-11-12 14:02:05 +0800605
606#ifdef CONFIG_NAND_MXS
607 setup_gpmi_nand();
608#endif
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200609
Fabio Estevamca62e5d2017-07-10 15:59:11 -0300610#ifdef CONFIG_MTD_NOR_FLASH
611 eim_clk_setup();
612#endif
Fabio Estevam7dd65452012-09-24 08:09:33 +0000613 return 0;
614}
615
616int board_init(void)
617{
618 /* address of boot parameters */
619 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
620
Renato Frias19578162013-05-13 18:01:12 +0000621 /* I2C 2 and 3 setup - I2C 3 hw mux with EIM */
Vanessa Maegima823dff92017-06-29 09:33:45 -0300622 if (is_mx6dq() || is_mx6dqp())
623 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1);
624 else
625 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
Renato Frias19578162013-05-13 18:01:12 +0000626 /* I2C 3 Steer */
627 gpio_direction_output(IMX_GPIO_NR(5, 4), 1);
Vanessa Maegima823dff92017-06-29 09:33:45 -0300628 SETUP_IOMUX_PADS(i2c3_pads);
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200629#ifndef CONFIG_SYS_FLASH_CFI
Vanessa Maegima823dff92017-06-29 09:33:45 -0300630 if (is_mx6dq() || is_mx6dqp())
631 setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info2);
632 else
633 setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info2);
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200634#endif
Renato Friasa1f67802013-05-13 18:01:13 +0000635 gpio_direction_output(IMX_GPIO_NR(1, 15), 1);
Vanessa Maegima823dff92017-06-29 09:33:45 -0300636 SETUP_IOMUX_PADS(port_exp);
Renato Friasa1f67802013-05-13 18:01:13 +0000637
Peng Fanccf43262015-12-15 16:27:18 +0800638#ifdef CONFIG_VIDEO_IPUV3
639 setup_display();
640#endif
Fabio Estevamca62e5d2017-07-10 15:59:11 -0300641
642#ifdef CONFIG_MTD_NOR_FLASH
Fabio Estevamcdbdde32014-11-14 11:27:23 -0200643 setup_iomux_eimnor();
Fabio Estevamca62e5d2017-07-10 15:59:11 -0300644#endif
Fabio Estevam7dd65452012-09-24 08:09:33 +0000645 return 0;
646}
647
Nikita Kiryanov155fa9a2014-08-20 15:08:50 +0300648#ifdef CONFIG_MXC_SPI
649int board_spi_cs_gpio(unsigned bus, unsigned cs)
650{
651 return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
652}
653#endif
654
Ye.Li593243d2014-11-06 16:29:02 +0800655int power_init_board(void)
656{
657 struct pmic *p;
Peng Fan361b7152015-07-11 11:38:47 +0800658 unsigned int value;
Ye.Li593243d2014-11-06 16:29:02 +0800659
660 p = pfuze_common_init(I2C_PMIC);
661 if (!p)
662 return -ENODEV;
663
Peng Fan361b7152015-07-11 11:38:47 +0800664 if (is_mx6dqp()) {
665 /* set SW2 staby volatage 0.975V*/
666 pmic_reg_read(p, PFUZE100_SW2STBY, &value);
667 value &= ~0x3f;
668 value |= 0x17;
669 pmic_reg_write(p, PFUZE100_SW2STBY, value);
670 }
Peng Fan258c98f2015-01-27 10:14:04 +0800671
Peng Fan361b7152015-07-11 11:38:47 +0800672 return pfuze_mode_init(p, APS_PFM);
Ye.Li593243d2014-11-06 16:29:02 +0800673}
674
Otavio Salvador85449db2013-03-16 08:05:07 +0000675#ifdef CONFIG_CMD_BMODE
676static const struct boot_mode board_boot_modes[] = {
677 /* 4 bit bus width */
678 {"mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
679 {NULL, 0},
680};
681#endif
682
683int board_late_init(void)
684{
685#ifdef CONFIG_CMD_BMODE
686 add_board_boot_modes(board_boot_modes);
687#endif
688
Peng Fane6fc8992015-07-11 11:38:46 +0800689#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
690 setenv("board_name", "SABREAUTO");
691
Peng Fan361b7152015-07-11 11:38:47 +0800692 if (is_mx6dqp())
693 setenv("board_rev", "MX6QP");
Peng Fan83e13942016-05-23 18:36:06 +0800694 else if (is_mx6dq())
Peng Fane6fc8992015-07-11 11:38:46 +0800695 setenv("board_rev", "MX6Q");
Peng Fan83e13942016-05-23 18:36:06 +0800696 else if (is_mx6sdl())
Peng Fane6fc8992015-07-11 11:38:46 +0800697 setenv("board_rev", "MX6DL");
698#endif
699
Otavio Salvador85449db2013-03-16 08:05:07 +0000700 return 0;
701}
702
Fabio Estevam7dd65452012-09-24 08:09:33 +0000703int checkboard(void)
704{
Fabio Estevamdce67bd2012-10-02 11:20:12 +0000705 int rev = mx6sabre_rev();
706 char *revname;
707
708 switch (rev) {
709 case BOARD_REV_B:
710 revname = "B";
711 break;
712 case BOARD_REV_A:
713 default:
714 revname = "A";
715 break;
716 }
717
718 printf("Board: MX6Q-Sabreauto rev%s\n", revname);
Fabio Estevam7dd65452012-09-24 08:09:33 +0000719
720 return 0;
721}
Ye.Li8fe280f2014-10-30 18:53:49 +0800722
723#ifdef CONFIG_USB_EHCI_MX6
724#define USB_HOST1_PWR PORTEXP_IO_NR(0x32, 7)
725#define USB_OTG_PWR PORTEXP_IO_NR(0x34, 1)
726
727iomux_v3_cfg_t const usb_otg_pads[] = {
Vanessa Maegima823dff92017-06-29 09:33:45 -0300728 IOMUX_PADS(PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL)),
Ye.Li8fe280f2014-10-30 18:53:49 +0800729};
730
731int board_ehci_hcd_init(int port)
732{
733 switch (port) {
734 case 0:
Vanessa Maegima823dff92017-06-29 09:33:45 -0300735 SETUP_IOMUX_PADS(usb_otg_pads);
Ye.Li8fe280f2014-10-30 18:53:49 +0800736
737 /*
738 * Set daisy chain for otg_pin_id on 6q.
739 * For 6dl, this bit is reserved.
740 */
741 imx_iomux_set_gpr_register(1, 13, 1, 0);
742 break;
743 case 1:
744 break;
745 default:
746 printf("MXC USB port %d not yet supported\n", port);
747 return -EINVAL;
748 }
749 return 0;
750}
751
752int board_ehci_power(int port, int on)
753{
754 switch (port) {
755 case 0:
756 if (on)
757 port_exp_direction_output(USB_OTG_PWR, 1);
758 else
759 port_exp_direction_output(USB_OTG_PWR, 0);
760 break;
761 case 1:
762 if (on)
763 port_exp_direction_output(USB_HOST1_PWR, 1);
764 else
765 port_exp_direction_output(USB_HOST1_PWR, 0);
766 break;
767 default:
768 printf("MXC USB port %d not yet supported\n", port);
769 return -EINVAL;
770 }
771
772 return 0;
773}
774#endif
Vanessa Maegima823dff92017-06-29 09:33:45 -0300775
776#ifdef CONFIG_SPL_BUILD
777#include <asm/arch/mx6-ddr.h>
778#include <spl.h>
779#include <libfdt.h>
780
Diego Dorta07f6ddb2017-07-07 15:38:34 -0300781#ifdef CONFIG_SPL_OS_BOOT
782int spl_start_uboot(void)
783{
784 return 0;
785}
786#endif
787
Vanessa Maegima823dff92017-06-29 09:33:45 -0300788static void ccgr_init(void)
789{
790 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
791
792 writel(0x00C03F3F, &ccm->CCGR0);
793 writel(0x0030FC03, &ccm->CCGR1);
794 writel(0x0FFFC000, &ccm->CCGR2);
795 writel(0x3FF00000, &ccm->CCGR3);
796 writel(0x00FFF300, &ccm->CCGR4);
797 writel(0x0F0000C3, &ccm->CCGR5);
798 writel(0x000003FF, &ccm->CCGR6);
799}
800
801static void gpr_init(void)
802{
803 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
804
805 /* enable AXI cache for VDOA/VPU/IPU */
806 writel(0xF00000CF, &iomux->gpr[4]);
807 if (is_mx6dqp()) {
808 /* set IPU AXI-id1 Qos=0x1 AXI-id0/2/3 Qos=0x7 */
809 writel(0x007F007F, &iomux->gpr[6]);
810 writel(0x007F007F, &iomux->gpr[7]);
811 } else {
812 /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
813 writel(0x007F007F, &iomux->gpr[6]);
814 writel(0x007F007F, &iomux->gpr[7]);
815 }
816}
817
818static int mx6q_dcd_table[] = {
819 0x020e0798, 0x000C0000,
820 0x020e0758, 0x00000000,
821 0x020e0588, 0x00000030,
822 0x020e0594, 0x00000030,
823 0x020e056c, 0x00000030,
824 0x020e0578, 0x00000030,
825 0x020e074c, 0x00000030,
826 0x020e057c, 0x00000030,
827 0x020e058c, 0x00000000,
828 0x020e059c, 0x00000030,
829 0x020e05a0, 0x00000030,
830 0x020e078c, 0x00000030,
831 0x020e0750, 0x00020000,
832 0x020e05a8, 0x00000028,
833 0x020e05b0, 0x00000028,
834 0x020e0524, 0x00000028,
835 0x020e051c, 0x00000028,
836 0x020e0518, 0x00000028,
837 0x020e050c, 0x00000028,
838 0x020e05b8, 0x00000028,
839 0x020e05c0, 0x00000028,
840 0x020e0774, 0x00020000,
841 0x020e0784, 0x00000028,
842 0x020e0788, 0x00000028,
843 0x020e0794, 0x00000028,
844 0x020e079c, 0x00000028,
845 0x020e07a0, 0x00000028,
846 0x020e07a4, 0x00000028,
847 0x020e07a8, 0x00000028,
848 0x020e0748, 0x00000028,
849 0x020e05ac, 0x00000028,
850 0x020e05b4, 0x00000028,
851 0x020e0528, 0x00000028,
852 0x020e0520, 0x00000028,
853 0x020e0514, 0x00000028,
854 0x020e0510, 0x00000028,
855 0x020e05bc, 0x00000028,
856 0x020e05c4, 0x00000028,
857 0x021b0800, 0xa1390003,
858 0x021b080c, 0x001F001F,
859 0x021b0810, 0x001F001F,
860 0x021b480c, 0x001F001F,
861 0x021b4810, 0x001F001F,
862 0x021b083c, 0x43260335,
863 0x021b0840, 0x031A030B,
864 0x021b483c, 0x4323033B,
865 0x021b4840, 0x0323026F,
866 0x021b0848, 0x483D4545,
867 0x021b4848, 0x44433E48,
868 0x021b0850, 0x41444840,
869 0x021b4850, 0x4835483E,
870 0x021b081c, 0x33333333,
871 0x021b0820, 0x33333333,
872 0x021b0824, 0x33333333,
873 0x021b0828, 0x33333333,
874 0x021b481c, 0x33333333,
875 0x021b4820, 0x33333333,
876 0x021b4824, 0x33333333,
877 0x021b4828, 0x33333333,
878 0x021b08b8, 0x00000800,
879 0x021b48b8, 0x00000800,
880 0x021b0004, 0x00020036,
881 0x021b0008, 0x09444040,
882 0x021b000c, 0x8A8F7955,
883 0x021b0010, 0xFF328F64,
884 0x021b0014, 0x01FF00DB,
885 0x021b0018, 0x00001740,
886 0x021b001c, 0x00008000,
887 0x021b002c, 0x000026d2,
888 0x021b0030, 0x008F1023,
889 0x021b0040, 0x00000047,
890 0x021b0000, 0x841A0000,
891 0x021b001c, 0x04088032,
892 0x021b001c, 0x00008033,
893 0x021b001c, 0x00048031,
894 0x021b001c, 0x09408030,
895 0x021b001c, 0x04008040,
896 0x021b0020, 0x00005800,
897 0x021b0818, 0x00011117,
898 0x021b4818, 0x00011117,
899 0x021b0004, 0x00025576,
900 0x021b0404, 0x00011006,
901 0x021b001c, 0x00000000,
902 0x020c4068, 0x00C03F3F,
903 0x020c406c, 0x0030FC03,
904 0x020c4070, 0x0FFFC000,
905 0x020c4074, 0x3FF00000,
906 0x020c4078, 0xFFFFF300,
907 0x020c407c, 0x0F0000F3,
908 0x020c4080, 0x00000FFF,
909 0x020e0010, 0xF00000CF,
910 0x020e0018, 0x007F007F,
911 0x020e001c, 0x007F007F,
912};
913
914static int mx6qp_dcd_table[] = {
915 0x020e0798, 0x000C0000,
916 0x020e0758, 0x00000000,
917 0x020e0588, 0x00000030,
918 0x020e0594, 0x00000030,
919 0x020e056c, 0x00000030,
920 0x020e0578, 0x00000030,
921 0x020e074c, 0x00000030,
922 0x020e057c, 0x00000030,
923 0x020e058c, 0x00000000,
924 0x020e059c, 0x00000030,
925 0x020e05a0, 0x00000030,
926 0x020e078c, 0x00000030,
927 0x020e0750, 0x00020000,
928 0x020e05a8, 0x00000030,
929 0x020e05b0, 0x00000030,
930 0x020e0524, 0x00000030,
931 0x020e051c, 0x00000030,
932 0x020e0518, 0x00000030,
933 0x020e050c, 0x00000030,
934 0x020e05b8, 0x00000030,
935 0x020e05c0, 0x00000030,
936 0x020e0774, 0x00020000,
937 0x020e0784, 0x00000030,
938 0x020e0788, 0x00000030,
939 0x020e0794, 0x00000030,
940 0x020e079c, 0x00000030,
941 0x020e07a0, 0x00000030,
942 0x020e07a4, 0x00000030,
943 0x020e07a8, 0x00000030,
944 0x020e0748, 0x00000030,
945 0x020e05ac, 0x00000030,
946 0x020e05b4, 0x00000030,
947 0x020e0528, 0x00000030,
948 0x020e0520, 0x00000030,
949 0x020e0514, 0x00000030,
950 0x020e0510, 0x00000030,
951 0x020e05bc, 0x00000030,
952 0x020e05c4, 0x00000030,
953 0x021b0800, 0xa1390003,
954 0x021b080c, 0x001b001e,
955 0x021b0810, 0x002e0029,
956 0x021b480c, 0x001b002a,
957 0x021b4810, 0x0019002c,
958 0x021b083c, 0x43240334,
959 0x021b0840, 0x0324031a,
960 0x021b483c, 0x43340344,
961 0x021b4840, 0x03280276,
962 0x021b0848, 0x44383A3E,
963 0x021b4848, 0x3C3C3846,
964 0x021b0850, 0x2e303230,
965 0x021b4850, 0x38283E34,
966 0x021b081c, 0x33333333,
967 0x021b0820, 0x33333333,
968 0x021b0824, 0x33333333,
969 0x021b0828, 0x33333333,
970 0x021b481c, 0x33333333,
971 0x021b4820, 0x33333333,
972 0x021b4824, 0x33333333,
973 0x021b4828, 0x33333333,
974 0x021b08c0, 0x24912492,
975 0x021b48c0, 0x24912492,
976 0x021b08b8, 0x00000800,
977 0x021b48b8, 0x00000800,
978 0x021b0004, 0x00020036,
979 0x021b0008, 0x09444040,
980 0x021b000c, 0x898E7955,
981 0x021b0010, 0xFF328F64,
982 0x021b0014, 0x01FF00DB,
983 0x021b0018, 0x00001740,
984 0x021b001c, 0x00008000,
985 0x021b002c, 0x000026d2,
986 0x021b0030, 0x008E1023,
987 0x021b0040, 0x00000047,
988 0x021b0400, 0x14420000,
989 0x021b0000, 0x841A0000,
990 0x00bb0008, 0x00000004,
991 0x00bb000c, 0x2891E41A,
992 0x00bb0038, 0x00000564,
993 0x00bb0014, 0x00000040,
994 0x00bb0028, 0x00000020,
995 0x00bb002c, 0x00000020,
996 0x021b001c, 0x04088032,
997 0x021b001c, 0x00008033,
998 0x021b001c, 0x00048031,
999 0x021b001c, 0x09408030,
1000 0x021b001c, 0x04008040,
1001 0x021b0020, 0x00005800,
1002 0x021b0818, 0x00011117,
1003 0x021b4818, 0x00011117,
1004 0x021b0004, 0x00025576,
1005 0x021b0404, 0x00011006,
1006 0x021b001c, 0x00000000,
1007 0x020c4068, 0x00C03F3F,
1008 0x020c406c, 0x0030FC03,
1009 0x020c4070, 0x0FFFC000,
1010 0x020c4074, 0x3FF00000,
1011 0x020c4078, 0xFFFFF300,
1012 0x020c407c, 0x0F0000F3,
1013 0x020c4080, 0x00000FFF,
1014 0x020e0010, 0xF00000CF,
1015 0x020e0018, 0x77177717,
1016 0x020e001c, 0x77177717,
1017};
1018
1019static int mx6dl_dcd_table[] = {
1020 0x020e0774, 0x000C0000,
1021 0x020e0754, 0x00000000,
1022 0x020e04ac, 0x00000030,
1023 0x020e04b0, 0x00000030,
1024 0x020e0464, 0x00000030,
1025 0x020e0490, 0x00000030,
1026 0x020e074c, 0x00000030,
1027 0x020e0494, 0x00000030,
1028 0x020e04a0, 0x00000000,
1029 0x020e04b4, 0x00000030,
1030 0x020e04b8, 0x00000030,
1031 0x020e076c, 0x00000030,
1032 0x020e0750, 0x00020000,
1033 0x020e04bc, 0x00000028,
1034 0x020e04c0, 0x00000028,
1035 0x020e04c4, 0x00000028,
1036 0x020e04c8, 0x00000028,
1037 0x020e04cc, 0x00000028,
1038 0x020e04d0, 0x00000028,
1039 0x020e04d4, 0x00000028,
1040 0x020e04d8, 0x00000028,
1041 0x020e0760, 0x00020000,
1042 0x020e0764, 0x00000028,
1043 0x020e0770, 0x00000028,
1044 0x020e0778, 0x00000028,
1045 0x020e077c, 0x00000028,
1046 0x020e0780, 0x00000028,
1047 0x020e0784, 0x00000028,
1048 0x020e078c, 0x00000028,
1049 0x020e0748, 0x00000028,
1050 0x020e0470, 0x00000028,
1051 0x020e0474, 0x00000028,
1052 0x020e0478, 0x00000028,
1053 0x020e047c, 0x00000028,
1054 0x020e0480, 0x00000028,
1055 0x020e0484, 0x00000028,
1056 0x020e0488, 0x00000028,
1057 0x020e048c, 0x00000028,
1058 0x021b0800, 0xa1390003,
1059 0x021b080c, 0x001F001F,
1060 0x021b0810, 0x001F001F,
1061 0x021b480c, 0x001F001F,
1062 0x021b4810, 0x001F001F,
1063 0x021b083c, 0x42190217,
1064 0x021b0840, 0x017B017B,
1065 0x021b483c, 0x4176017B,
1066 0x021b4840, 0x015F016C,
1067 0x021b0848, 0x4C4C4D4C,
1068 0x021b4848, 0x4A4D4C48,
1069 0x021b0850, 0x3F3F3F40,
1070 0x021b4850, 0x3538382E,
1071 0x021b081c, 0x33333333,
1072 0x021b0820, 0x33333333,
1073 0x021b0824, 0x33333333,
1074 0x021b0828, 0x33333333,
1075 0x021b481c, 0x33333333,
1076 0x021b4820, 0x33333333,
1077 0x021b4824, 0x33333333,
1078 0x021b4828, 0x33333333,
1079 0x021b08b8, 0x00000800,
1080 0x021b48b8, 0x00000800,
1081 0x021b0004, 0x00020025,
1082 0x021b0008, 0x00333030,
1083 0x021b000c, 0x676B5313,
1084 0x021b0010, 0xB66E8B63,
1085 0x021b0014, 0x01FF00DB,
1086 0x021b0018, 0x00001740,
1087 0x021b001c, 0x00008000,
1088 0x021b002c, 0x000026d2,
1089 0x021b0030, 0x006B1023,
1090 0x021b0040, 0x00000047,
1091 0x021b0000, 0x841A0000,
1092 0x021b001c, 0x04008032,
1093 0x021b001c, 0x00008033,
1094 0x021b001c, 0x00048031,
1095 0x021b001c, 0x05208030,
1096 0x021b001c, 0x04008040,
1097 0x021b0020, 0x00005800,
1098 0x021b0818, 0x00011117,
1099 0x021b4818, 0x00011117,
1100 0x021b0004, 0x00025565,
1101 0x021b0404, 0x00011006,
1102 0x021b001c, 0x00000000,
1103 0x020c4068, 0x00C03F3F,
1104 0x020c406c, 0x0030FC03,
1105 0x020c4070, 0x0FFFC000,
1106 0x020c4074, 0x3FF00000,
1107 0x020c4078, 0xFFFFF300,
1108 0x020c407c, 0x0F0000C3,
1109 0x020c4080, 0x00000FFF,
1110 0x020e0010, 0xF00000CF,
1111 0x020e0018, 0x007F007F,
1112 0x020e001c, 0x007F007F,
1113};
1114
1115static void ddr_init(int *table, int size)
1116{
1117 int i;
1118
1119 for (i = 0; i < size / 2 ; i++)
1120 writel(table[2 * i + 1], table[2 * i]);
1121}
1122
1123static void spl_dram_init(void)
1124{
1125 if (is_mx6dq())
1126 ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table));
1127 else if (is_mx6dqp())
1128 ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table));
1129 else if (is_mx6sdl())
1130 ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table));
1131}
1132
1133void board_init_f(ulong dummy)
1134{
1135 /* DDR initialization */
1136 spl_dram_init();
1137
1138 /* setup AIPS and disable watchdog */
1139 arch_cpu_init();
1140
1141 ccgr_init();
1142 gpr_init();
1143
1144 /* iomux and setup of i2c */
1145 board_early_init_f();
1146
1147 /* setup GP timer */
1148 timer_init();
1149
1150 /* UART clocks enabled and gd valid - init serial console */
1151 preloader_console_init();
1152
1153 /* Clear the BSS. */
1154 memset(__bss_start, 0, __bss_end - __bss_start);
1155
1156 /* load/boot image from boot device */
1157 board_init_r(NULL, 0);
1158}
1159#endif