blob: 9316b2c377208192f1ed8221029cb74e2c2f1c63 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
SARTRE Leo9b75bad2013-06-03 23:30:36 +00002/*
3 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
4 * Based on mx6qsabrelite.c file
5 * Copyright (C) 2013, Adeneo Embedded <www.adeneo-embedded.com>
6 * Leo Sartre, <lsartre@adeneo-embedded.com>
SARTRE Leo9b75bad2013-06-03 23:30:36 +00007 */
8
9#include <common.h>
Simon Glass52559322019-11-14 12:57:46 -070010#include <init.h>
Simon Glass90526e92020-05-10 11:39:56 -060011#include <net.h>
SARTRE Leo9b75bad2013-06-03 23:30:36 +000012#include <asm/io.h>
13#include <asm/arch/clock.h>
14#include <asm/arch/imx-regs.h>
15#include <asm/arch/iomux.h>
16#include <asm/arch/mx6-pins.h>
17#include <asm/gpio.h>
Stefano Babic552a8482017-06-29 10:16:06 +020018#include <asm/mach-imx/iomux-v3.h>
19#include <asm/mach-imx/sata.h>
20#include <asm/mach-imx/boot_mode.h>
21#include <asm/mach-imx/mxc_i2c.h>
Otavio Salvadord7140352015-11-19 19:02:36 -020022#include <asm/arch/sys_proto.h>
Otavio Salvador6d551f22015-07-23 11:02:30 -030023#include <asm/arch/mxc_hdmi.h>
24#include <asm/arch/crm_regs.h>
Simon Glass9fb625c2019-08-01 09:46:51 -060025#include <env.h>
SARTRE Leo9b75bad2013-06-03 23:30:36 +000026#include <mmc.h>
Yangbo Lue37ac712019-06-21 11:42:28 +080027#include <fsl_esdhc_imx.h>
Otavio Salvador4c9929d2015-07-23 11:02:28 -030028#include <i2c.h>
Diego Dorta7594c512017-09-22 12:12:18 -030029#include <input.h>
Simon Glassc05ed002020-05-10 11:40:11 -060030#include <linux/delay.h>
Otavio Salvador4c9929d2015-07-23 11:02:28 -030031#include <power/pmic.h>
32#include <power/pfuze100_pmic.h>
Otavio Salvador6d551f22015-07-23 11:02:30 -030033#include <linux/fb.h>
34#include <ipu_pixfmt.h>
Otavio Salvadorf0222902015-07-28 20:24:41 -030035#include <malloc.h>
36#include <miiphy.h>
37#include <netdev.h>
38#include <micrel.h>
Otavio Salvadord7140352015-11-19 19:02:36 -020039#include <spi_flash.h>
40#include <spi.h>
SARTRE Leo9b75bad2013-06-03 23:30:36 +000041
42DECLARE_GLOBAL_DATA_PTR;
43
44#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |\
45 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
46
47#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW |\
48 PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
49
Otavio Salvador4c9929d2015-07-23 11:02:28 -030050#define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
51 PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
52 PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
53 PAD_CTL_ODE | PAD_CTL_SRE_FAST)
54
Otavio Salvador71bcdaf2015-11-19 19:02:33 -020055#define SPI_PAD_CTRL (PAD_CTL_HYS | \
56 PAD_CTL_SPEED_MED | \
57 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
58
Otavio Salvador4c9929d2015-07-23 11:02:28 -030059#define MX6Q_QMX6_PFUZE_MUX IMX_GPIO_NR(6, 9)
60
Otavio Salvadorf0222902015-07-28 20:24:41 -030061
62#define ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
63 PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
64 PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
65
SARTRE Leo9b75bad2013-06-03 23:30:36 +000066int dram_init(void)
67{
Otavio Salvadord7140352015-11-19 19:02:36 -020068 gd->ram_size = imx_ddr_size();
SARTRE Leo9b75bad2013-06-03 23:30:36 +000069
70 return 0;
71}
72
Otavio Salvador6b3496f2015-07-23 11:02:21 -030073static iomux_v3_cfg_t const uart2_pads[] = {
Otavio Salvadord7140352015-11-19 19:02:36 -020074 IOMUX_PADS(PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
75 IOMUX_PADS(PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
SARTRE Leo9b75bad2013-06-03 23:30:36 +000076};
77
Tom Rini9c72fff2017-05-08 22:14:22 -040078#ifndef CONFIG_SPL_BUILD
Otavio Salvador6b3496f2015-07-23 11:02:21 -030079static iomux_v3_cfg_t const usdhc2_pads[] = {
Otavio Salvadord7140352015-11-19 19:02:36 -020080 IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
81 IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
82 IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
83 IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
84 IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
85 IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
86 IOMUX_PADS(PAD_GPIO_4__GPIO1_IO04 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
SARTRE Leo9b75bad2013-06-03 23:30:36 +000087};
88
Otavio Salvador45e4d352015-07-23 11:02:24 -030089static iomux_v3_cfg_t const usdhc3_pads[] = {
Otavio Salvadord7140352015-11-19 19:02:36 -020090 IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
91 IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
92 IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
93 IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
94 IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
95 IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
96 IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
97 IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
98 IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
99 IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
100 IOMUX_PADS(PAD_SD3_RST__SD3_RESET | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
Otavio Salvador45e4d352015-07-23 11:02:24 -0300101};
Tom Rini9c72fff2017-05-08 22:14:22 -0400102#endif
Otavio Salvador45e4d352015-07-23 11:02:24 -0300103
Otavio Salvador6b3496f2015-07-23 11:02:21 -0300104static iomux_v3_cfg_t const usdhc4_pads[] = {
Otavio Salvadord7140352015-11-19 19:02:36 -0200105 IOMUX_PADS(PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
106 IOMUX_PADS(PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
107 IOMUX_PADS(PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
108 IOMUX_PADS(PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
109 IOMUX_PADS(PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
110 IOMUX_PADS(PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
111 IOMUX_PADS(PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
112 IOMUX_PADS(PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
113 IOMUX_PADS(PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
114 IOMUX_PADS(PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
115 IOMUX_PADS(PAD_NANDF_D6__GPIO2_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000116};
117
Otavio Salvador95246ac2015-07-23 11:02:29 -0300118static iomux_v3_cfg_t const usb_otg_pads[] = {
Otavio Salvadord7140352015-11-19 19:02:36 -0200119 IOMUX_PADS(PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL)),
120 IOMUX_PADS(PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL)),
Otavio Salvador95246ac2015-07-23 11:02:29 -0300121};
122
Otavio Salvadorf0222902015-07-28 20:24:41 -0300123static iomux_v3_cfg_t enet_pads_ksz9031[] = {
Otavio Salvadord7140352015-11-19 19:02:36 -0200124 IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
125 IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
126 IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
127 IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
128 IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
129 IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
130 IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
131 IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
132 IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL)),
133 IOMUX_PADS(PAD_RGMII_RXC__GPIO6_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL)),
134 IOMUX_PADS(PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL)),
135 IOMUX_PADS(PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL)),
136 IOMUX_PADS(PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL)),
137 IOMUX_PADS(PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
138 IOMUX_PADS(PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Otavio Salvadorf0222902015-07-28 20:24:41 -0300139};
140
141static iomux_v3_cfg_t enet_pads_final_ksz9031[] = {
Otavio Salvadord7140352015-11-19 19:02:36 -0200142 IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
143 IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
144 IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
145 IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
146 IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
147 IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
Otavio Salvadorf0222902015-07-28 20:24:41 -0300148};
149
150static iomux_v3_cfg_t enet_pads_ar8035[] = {
Otavio Salvadord7140352015-11-19 19:02:36 -0200151 IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
152 IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
153 IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
154 IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
155 IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
156 IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
157 IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
158 IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
159 IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL)),
160 IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
161 IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
162 IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
163 IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
164 IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
165 IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
Otavio Salvadorf0222902015-07-28 20:24:41 -0300166};
167
Otavio Salvador71bcdaf2015-11-19 19:02:33 -0200168static iomux_v3_cfg_t const ecspi1_pads[] = {
Otavio Salvadord7140352015-11-19 19:02:36 -0200169 IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL)),
170 IOMUX_PADS(PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL)),
171 IOMUX_PADS(PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL)),
172 IOMUX_PADS(PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
Otavio Salvador71bcdaf2015-11-19 19:02:33 -0200173};
174
Otavio Salvador4c9929d2015-07-23 11:02:28 -0300175#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
Otavio Salvadord7140352015-11-19 19:02:36 -0200176struct i2c_pads_info mx6q_i2c_pad_info1 = {
Otavio Salvador4c9929d2015-07-23 11:02:28 -0300177 .scl = {
Otavio Salvadord7140352015-11-19 19:02:36 -0200178 .i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | PC,
179 .gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 | PC,
Otavio Salvador4c9929d2015-07-23 11:02:28 -0300180 .gp = IMX_GPIO_NR(4, 12)
181 },
182 .sda = {
Otavio Salvadord7140352015-11-19 19:02:36 -0200183 .i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
184 .gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | PC,
185 .gp = IMX_GPIO_NR(4, 13)
186 }
187};
188
189struct i2c_pads_info mx6dl_i2c_pad_info1 = {
190 .scl = {
191 .i2c_mode = MX6DL_PAD_KEY_COL3__I2C2_SCL | PC,
192 .gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12 | PC,
193 .gp = IMX_GPIO_NR(4, 12)
194 },
195 .sda = {
196 .i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | PC,
197 .gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | PC,
Otavio Salvador4c9929d2015-07-23 11:02:28 -0300198 .gp = IMX_GPIO_NR(4, 13)
199 }
200};
201
202#define I2C_PMIC 1 /* I2C2 port is used to connect to the PMIC */
203
204struct interface_level {
205 char *name;
206 uchar value;
207};
208
209static struct interface_level mipi_levels[] = {
210 {"0V0", 0x00},
211 {"2V5", 0x17},
212};
213
214/* setup board specific PMIC */
215int power_init_board(void)
216{
217 struct pmic *p;
218 u32 id1, id2, i;
219 int ret;
220 char const *lv_mipi;
221
222 /* configure I2C multiplexer */
223 gpio_direction_output(MX6Q_QMX6_PFUZE_MUX, 1);
224
225 power_pfuze100_init(I2C_PMIC);
226 p = pmic_get("PFUZE100");
227 if (!p)
228 return -EINVAL;
229
230 ret = pmic_probe(p);
231 if (ret)
232 return ret;
233
234 pmic_reg_read(p, PFUZE100_DEVICEID, &id1);
235 pmic_reg_read(p, PFUZE100_REVID, &id2);
236 printf("PFUZE100 Rev. [%02x/%02x] detected\n", id1, id2);
237
238 if (id2 >= 0x20)
239 return 0;
240
241 /* set level of MIPI if specified */
Simon Glass00caae62017-08-03 12:22:12 -0600242 lv_mipi = env_get("lv_mipi");
Otavio Salvador4c9929d2015-07-23 11:02:28 -0300243 if (lv_mipi)
244 return 0;
245
246 for (i = 0; i < ARRAY_SIZE(mipi_levels); i++) {
247 if (!strcmp(mipi_levels[i].name, lv_mipi)) {
Otavio Salvadorf5cf9e62015-09-17 15:13:18 -0300248 printf("set MIPI level %s\n", mipi_levels[i].name);
Otavio Salvador4c9929d2015-07-23 11:02:28 -0300249 ret = pmic_reg_write(p, PFUZE100_VGEN4VOL,
250 mipi_levels[i].value);
251 if (ret)
252 return ret;
253 }
254 }
255
256 return 0;
257}
Otavio Salvadorf0222902015-07-28 20:24:41 -0300258
Masahiro Yamadab75d8dc2020-06-26 15:13:33 +0900259int board_eth_init(struct bd_info *bis)
Otavio Salvadorf0222902015-07-28 20:24:41 -0300260{
261 struct phy_device *phydev;
262 struct mii_dev *bus;
263 unsigned short id1, id2;
264 int ret;
265
Otavio Salvadorf0222902015-07-28 20:24:41 -0300266 /* check whether KSZ9031 or AR8035 has to be configured */
Otavio Salvadord7140352015-11-19 19:02:36 -0200267 SETUP_IOMUX_PADS(enet_pads_ar8035);
Otavio Salvadorf0222902015-07-28 20:24:41 -0300268
269 /* phy reset */
270 gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
271 udelay(2000);
272 gpio_set_value(IMX_GPIO_NR(3, 23), 1);
273 udelay(500);
274
275 bus = fec_get_miibus(IMX_FEC_BASE, -1);
276 if (!bus)
277 return -EINVAL;
278 phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII);
279 if (!phydev) {
280 printf("Error: phy device not found.\n");
281 ret = -ENODEV;
282 goto free_bus;
283 }
284
285 /* get the PHY id */
286 id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
287 id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
288
289 if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
290 /* re-configure for Micrel KSZ9031 */
291 printf("configure Micrel KSZ9031 Ethernet Phy at address %d\n",
292 phydev->addr);
293
294 /* phy reset: gpio3-23 */
295 gpio_set_value(IMX_GPIO_NR(3, 23), 0);
296 gpio_set_value(IMX_GPIO_NR(6, 30), (phydev->addr >> 2));
297 gpio_set_value(IMX_GPIO_NR(6, 25), 1);
298 gpio_set_value(IMX_GPIO_NR(6, 27), 1);
299 gpio_set_value(IMX_GPIO_NR(6, 28), 1);
300 gpio_set_value(IMX_GPIO_NR(6, 29), 1);
Otavio Salvadord7140352015-11-19 19:02:36 -0200301 SETUP_IOMUX_PADS(enet_pads_ksz9031);
Otavio Salvadorf0222902015-07-28 20:24:41 -0300302 gpio_set_value(IMX_GPIO_NR(6, 24), 1);
303 udelay(500);
304 gpio_set_value(IMX_GPIO_NR(3, 23), 1);
Otavio Salvadord7140352015-11-19 19:02:36 -0200305 SETUP_IOMUX_PADS(enet_pads_final_ksz9031);
Otavio Salvadorf0222902015-07-28 20:24:41 -0300306 } else if ((id1 == 0x004d) && (id2 == 0xd072)) {
307 /* configure Atheros AR8035 - actually nothing to do */
308 printf("configure Atheros AR8035 Ethernet Phy at address %d\n",
309 phydev->addr);
310 } else {
311 printf("Unknown Ethernet-Phy: 0x%04x 0x%04x\n", id1, id2);
312 ret = -EINVAL;
313 goto free_phydev;
314 }
315
316 ret = fec_probe(bis, -1, IMX_FEC_BASE, bus, phydev);
317 if (ret)
318 goto free_phydev;
319
320 return 0;
321
322free_phydev:
323 free(phydev);
324free_bus:
325 free(bus);
326 return ret;
327}
328
329int mx6_rgmii_rework(struct phy_device *phydev)
330{
331 unsigned short id1, id2;
332 unsigned short val;
333
334 /* check whether KSZ9031 or AR8035 has to be configured */
335 id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
336 id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
337
338 if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
339 /* finalize phy configuration for Micrel KSZ9031 */
340 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
341 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 4);
342 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
343 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x0000);
344
345 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
346 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 5);
347 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
348 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, MII_KSZ9031_MOD_REG);
349
350 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
351 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 6);
352 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
353 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0xFFFF);
354
355 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
356 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 8);
357 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
358 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x3FFF);
359
360 /* fix KSZ9031 link up issue */
361 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 0x0);
362 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x4);
363 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC);
364 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x6);
365 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_REG);
366 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x3);
367 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC);
368 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x1A80);
369 }
370
371 if ((id1 == 0x004d) && (id2 == 0xd072)) {
372 /* enable AR8035 ouput a 125MHz clk from CLK_25M */
373 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 0x7);
374 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, MII_KSZ9031_MOD_DATA_POST_INC_RW | 0x16);
375 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC | 0x7);
376 val = phy_read(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA);
377 val &= 0xfe63;
378 val |= 0x18;
379 phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, val);
380
381 /* introduce tx clock delay */
382 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
383 val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
384 val |= 0x0100;
385 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
386
387 /* disable hibernation */
388 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0xb);
389 val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
390 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3c40);
391 }
392 return 0;
393}
394
395int board_phy_config(struct phy_device *phydev)
396{
397 mx6_rgmii_rework(phydev);
398
399 if (phydev->drv->config)
400 phydev->drv->config(phydev);
401
402 return 0;
403}
Otavio Salvador4c9929d2015-07-23 11:02:28 -0300404
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000405static void setup_iomux_uart(void)
406{
Otavio Salvadord7140352015-11-19 19:02:36 -0200407 SETUP_IOMUX_PADS(uart2_pads);
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000408}
409
Otavio Salvador71bcdaf2015-11-19 19:02:33 -0200410#ifdef CONFIG_MXC_SPI
411static void setup_spi(void)
412{
Michael Schanza1ed1552015-12-10 09:58:35 +0100413 SETUP_IOMUX_PADS(ecspi1_pads);
Otavio Salvador71bcdaf2015-11-19 19:02:33 -0200414 gpio_direction_output(IMX_GPIO_NR(3, 19), 0);
415}
416#endif
417
Yangbo Lue37ac712019-06-21 11:42:28 +0800418#ifdef CONFIG_FSL_ESDHC_IMX
Otavio Salvador6b3496f2015-07-23 11:02:21 -0300419static struct fsl_esdhc_cfg usdhc_cfg[] = {
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000420 {USDHC2_BASE_ADDR},
Otavio Salvador45e4d352015-07-23 11:02:24 -0300421 {USDHC3_BASE_ADDR},
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000422 {USDHC4_BASE_ADDR},
423};
424
425int board_mmc_getcd(struct mmc *mmc)
426{
427 struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
428 int ret = 0;
429
430 switch (cfg->esdhc_base) {
431 case USDHC2_BASE_ADDR:
432 gpio_direction_input(IMX_GPIO_NR(1, 4));
433 ret = !gpio_get_value(IMX_GPIO_NR(1, 4));
434 break;
Otavio Salvador45e4d352015-07-23 11:02:24 -0300435 case USDHC3_BASE_ADDR:
436 ret = 1; /* eMMC is always present */
437 break;
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000438 case USDHC4_BASE_ADDR:
439 gpio_direction_input(IMX_GPIO_NR(2, 6));
440 ret = !gpio_get_value(IMX_GPIO_NR(2, 6));
441 break;
442 default:
443 printf("Bad USDHC interface\n");
444 }
445
446 return ret;
447}
448
Masahiro Yamadab75d8dc2020-06-26 15:13:33 +0900449int board_mmc_init(struct bd_info *bis)
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000450{
Otavio Salvadord7140352015-11-19 19:02:36 -0200451#ifndef CONFIG_SPL_BUILD
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000452 s32 status = 0;
Otavio Salvador516a8632015-07-23 11:02:22 -0300453 int i;
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000454
455 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
Otavio Salvador45e4d352015-07-23 11:02:24 -0300456 usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
457 usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000458
Otavio Salvadord7140352015-11-19 19:02:36 -0200459 SETUP_IOMUX_PADS(usdhc2_pads);
460 SETUP_IOMUX_PADS(usdhc3_pads);
461 SETUP_IOMUX_PADS(usdhc4_pads);
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000462
Otavio Salvador516a8632015-07-23 11:02:22 -0300463 for (i = 0; i < ARRAY_SIZE(usdhc_cfg); i++) {
464 status = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
465 if (status)
466 return status;
467 }
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000468
Otavio Salvador516a8632015-07-23 11:02:22 -0300469 return 0;
Otavio Salvadord7140352015-11-19 19:02:36 -0200470#else
471 SETUP_IOMUX_PADS(usdhc4_pads);
472 usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
473 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
474 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
475
476 return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
477#endif
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000478}
479#endif
480
Otavio Salvador95246ac2015-07-23 11:02:29 -0300481int board_ehci_hcd_init(int port)
482{
483 switch (port) {
484 case 0:
Otavio Salvadord7140352015-11-19 19:02:36 -0200485 SETUP_IOMUX_PADS(usb_otg_pads);
Otavio Salvador95246ac2015-07-23 11:02:29 -0300486 /*
487 * set daisy chain for otg_pin_id on 6q.
488 * for 6dl, this bit is reserved
489 */
490 imx_iomux_set_gpr_register(1, 13, 1, 1);
491 break;
492 case 1:
493 /* nothing to do */
494 break;
495 default:
496 printf("Invalid USB port: %d\n", port);
497 return -EINVAL;
498 }
499
500 return 0;
501}
502
503int board_ehci_power(int port, int on)
504{
505 switch (port) {
506 case 0:
507 break;
508 case 1:
509 gpio_direction_output(IMX_GPIO_NR(5, 5), on);
510 break;
511 default:
512 printf("Invalid USB port: %d\n", port);
513 return -EINVAL;
514 }
515
516 return 0;
517}
518
Otavio Salvador6d551f22015-07-23 11:02:30 -0300519struct display_info_t {
520 int bus;
521 int addr;
522 int pixfmt;
523 int (*detect)(struct display_info_t const *dev);
524 void (*enable)(struct display_info_t const *dev);
525 struct fb_videomode mode;
526};
527
528static void disable_lvds(struct display_info_t const *dev)
529{
530 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
531
532 clrbits_le32(&iomux->gpr[2], IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
533 IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
534}
535
536static void do_enable_hdmi(struct display_info_t const *dev)
537{
538 disable_lvds(dev);
539 imx_enable_hdmi_phy();
540}
541
542static struct display_info_t const displays[] = {
543{
544 .bus = -1,
545 .addr = 0,
546 .pixfmt = IPU_PIX_FMT_RGB666,
547 .detect = NULL,
548 .enable = NULL,
549 .mode = {
550 .name =
551 "Hannstar-XGA",
552 .refresh = 60,
553 .xres = 1024,
554 .yres = 768,
555 .pixclock = 15385,
556 .left_margin = 220,
557 .right_margin = 40,
558 .upper_margin = 21,
559 .lower_margin = 7,
560 .hsync_len = 60,
561 .vsync_len = 10,
562 .sync = FB_SYNC_EXT,
563 .vmode = FB_VMODE_NONINTERLACED } },
564{
565 .bus = -1,
566 .addr = 0,
567 .pixfmt = IPU_PIX_FMT_RGB24,
568 .detect = NULL,
569 .enable = do_enable_hdmi,
570 .mode = {
571 .name = "HDMI",
572 .refresh = 60,
573 .xres = 1024,
574 .yres = 768,
575 .pixclock = 15385,
576 .left_margin = 220,
577 .right_margin = 40,
578 .upper_margin = 21,
579 .lower_margin = 7,
580 .hsync_len = 60,
581 .vsync_len = 10,
582 .sync = FB_SYNC_EXT,
583 .vmode = FB_VMODE_NONINTERLACED } }
584};
585
586int board_video_skip(void)
587{
588 int i;
589 int ret;
Simon Glass00caae62017-08-03 12:22:12 -0600590 char const *panel = env_get("panel");
Otavio Salvador6d551f22015-07-23 11:02:30 -0300591 if (!panel) {
592 for (i = 0; i < ARRAY_SIZE(displays); i++) {
593 struct display_info_t const *dev = displays + i;
594 if (dev->detect && dev->detect(dev)) {
595 panel = dev->mode.name;
596 printf("auto-detected panel %s\n", panel);
597 break;
598 }
599 }
600 if (!panel) {
601 panel = displays[0].mode.name;
602 printf("No panel detected: default to %s\n", panel);
603 i = 0;
604 }
605 } else {
606 for (i = 0; i < ARRAY_SIZE(displays); i++) {
607 if (!strcmp(panel, displays[i].mode.name))
608 break;
609 }
610 }
611 if (i < ARRAY_SIZE(displays)) {
612 ret = ipuv3_fb_init(&displays[i].mode, 0, displays[i].pixfmt);
613 if (!ret) {
614 if (displays[i].enable)
615 displays[i].enable(displays + i);
616 printf("Display: %s (%ux%u)\n",
617 displays[i].mode.name, displays[i].mode.xres,
618 displays[i].mode.yres);
619 } else
620 printf("LCD %s cannot be configured: %d\n",
621 displays[i].mode.name, ret);
622 } else {
623 printf("unsupported panel %s\n", panel);
624 return -EINVAL;
625 }
626
627 return 0;
628}
629
Anatolij Gustschin1e916aa2020-05-26 00:47:56 +0200630int ipu_displays_init(void)
631{
632 return board_video_skip();
633}
634
Otavio Salvador6d551f22015-07-23 11:02:30 -0300635static void setup_display(void)
636{
637 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
638 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
639 int reg;
640
641 enable_ipu_clock();
642 imx_setup_hdmi();
643
644 /* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
645 setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK |
646 MXC_CCM_CCGR3_LDB_DI1_MASK);
647
648 /* set LDB0, LDB1 clk select to 011/011 */
649 reg = readl(&mxc_ccm->cs2cdr);
650 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
651 MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
652 reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
653 (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
654 writel(reg, &mxc_ccm->cs2cdr);
655
656 setbits_le32(&mxc_ccm->cscmr2, MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV |
657 MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV);
658
659 setbits_le32(&mxc_ccm->chsccdr, CHSCCDR_CLK_SEL_LDB_DI0 <<
660 MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET |
661 CHSCCDR_CLK_SEL_LDB_DI0 <<
662 MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
663
664 reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
665 | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
666 | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
667 | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
668 | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
669 | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
670 | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
671 | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
672 | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
673 writel(reg, &iomux->gpr[2]);
674
675 reg = readl(&iomux->gpr[3]);
676 reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK |
677 IOMUXC_GPR3_HDMI_MUX_CTL_MASK)) |
678 (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
679 IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
680 writel(reg, &iomux->gpr[3]);
681}
682
683/*
684 * Do not overwrite the console
685 * Use always serial for U-Boot console
686 */
687int overwrite_console(void)
688{
689 return 1;
690}
691
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000692int board_early_init_f(void)
693{
694 setup_iomux_uart();
Otavio Salvador71bcdaf2015-11-19 19:02:33 -0200695#ifdef CONFIG_MXC_SPI
696 setup_spi();
697#endif
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000698 return 0;
699}
700
701int board_init(void)
702{
703 /* address of boot parameters */
704 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
705
Otavio Salvadord7140352015-11-19 19:02:36 -0200706
Breno Lima68c27602016-07-22 09:12:12 -0300707 if (is_mx6dq())
Otavio Salvadord7140352015-11-19 19:02:36 -0200708 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1);
709 else
710 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
Otavio Salvador4c9929d2015-07-23 11:02:28 -0300711
Fabio Estevam5e5b20c2017-09-22 23:45:29 -0300712 setup_display();
713
Simon Glass10e40d52017-06-14 21:28:25 -0600714#ifdef CONFIG_SATA
Otavio Salvador6731bc82015-07-23 11:02:31 -0300715 setup_sata();
716#endif
717
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000718 return 0;
719}
720
721int checkboard(void)
722{
Otavio Salvadord7140352015-11-19 19:02:36 -0200723 char *type = "unknown";
724
725 if (is_cpu_type(MXC_CPU_MX6Q))
726 type = "Quad";
727 else if (is_cpu_type(MXC_CPU_MX6D))
728 type = "Dual";
729 else if (is_cpu_type(MXC_CPU_MX6DL))
730 type = "Dual-Lite";
731 else if (is_cpu_type(MXC_CPU_MX6SOLO))
732 type = "Solo";
733
734 printf("Board: conga-QMX6 %s\n", type);
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000735
736 return 0;
737}
738
Otavio Salvador71bcdaf2015-11-19 19:02:33 -0200739#ifdef CONFIG_MXC_SPI
740int board_spi_cs_gpio(unsigned bus, unsigned cs)
741{
742 return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(3, 19)) : -EINVAL;
743}
744#endif
745
SARTRE Leo9b75bad2013-06-03 23:30:36 +0000746#ifdef CONFIG_CMD_BMODE
747static const struct boot_mode board_boot_modes[] = {
748 /* 4 bit bus width */
749 {"mmc0", MAKE_CFGVAL(0x50, 0x20, 0x00, 0x00)},
750 {"mmc1", MAKE_CFGVAL(0x50, 0x38, 0x00, 0x00)},
751 {NULL, 0},
752};
753#endif
754
755int misc_init_r(void)
756{
757#ifdef CONFIG_CMD_BMODE
758 add_board_boot_modes(board_boot_modes);
759#endif
760 return 0;
761}
Otavio Salvadord7140352015-11-19 19:02:36 -0200762
763int board_late_init(void)
764{
765#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
Breno Lima68c27602016-07-22 09:12:12 -0300766 if (is_mx6dq())
Simon Glass382bee52017-08-03 12:22:09 -0600767 env_set("board_rev", "MX6Q");
Otavio Salvadord7140352015-11-19 19:02:36 -0200768 else
Simon Glass382bee52017-08-03 12:22:09 -0600769 env_set("board_rev", "MX6DL");
Otavio Salvadord7140352015-11-19 19:02:36 -0200770#endif
771
772 return 0;
773}
774
775#ifdef CONFIG_SPL_BUILD
776#include <asm/arch/mx6-ddr.h>
777#include <spl.h>
Masahiro Yamadab08c8c42018-03-05 01:20:11 +0900778#include <linux/libfdt.h>
Otavio Salvadord7140352015-11-19 19:02:36 -0200779#include <spi_flash.h>
780#include <spi.h>
781
782const struct mx6dq_iomux_ddr_regs mx6q_ddr_ioregs = {
783 .dram_sdclk_0 = 0x00000030,
784 .dram_sdclk_1 = 0x00000030,
785 .dram_cas = 0x00000030,
786 .dram_ras = 0x00000030,
787 .dram_reset = 0x00000030,
788 .dram_sdcke0 = 0x00003000,
789 .dram_sdcke1 = 0x00003000,
790 .dram_sdba2 = 0x00000000,
791 .dram_sdodt0 = 0x00000030,
792 .dram_sdodt1 = 0x00000030,
793 .dram_sdqs0 = 0x00000030,
794 .dram_sdqs1 = 0x00000030,
795 .dram_sdqs2 = 0x00000030,
796 .dram_sdqs3 = 0x00000030,
797 .dram_sdqs4 = 0x00000030,
798 .dram_sdqs5 = 0x00000030,
799 .dram_sdqs6 = 0x00000030,
800 .dram_sdqs7 = 0x00000030,
801 .dram_dqm0 = 0x00000030,
802 .dram_dqm1 = 0x00000030,
803 .dram_dqm2 = 0x00000030,
804 .dram_dqm3 = 0x00000030,
805 .dram_dqm4 = 0x00000030,
806 .dram_dqm5 = 0x00000030,
807 .dram_dqm6 = 0x00000030,
808 .dram_dqm7 = 0x00000030,
809};
810
811static const struct mx6sdl_iomux_ddr_regs mx6dl_ddr_ioregs = {
812 .dram_sdclk_0 = 0x00000030,
813 .dram_sdclk_1 = 0x00000030,
814 .dram_cas = 0x00000030,
815 .dram_ras = 0x00000030,
816 .dram_reset = 0x00000030,
817 .dram_sdcke0 = 0x00003000,
818 .dram_sdcke1 = 0x00003000,
819 .dram_sdba2 = 0x00000000,
820 .dram_sdodt0 = 0x00000030,
821 .dram_sdodt1 = 0x00000030,
822 .dram_sdqs0 = 0x00000030,
823 .dram_sdqs1 = 0x00000030,
824 .dram_sdqs2 = 0x00000030,
825 .dram_sdqs3 = 0x00000030,
826 .dram_sdqs4 = 0x00000030,
827 .dram_sdqs5 = 0x00000030,
828 .dram_sdqs6 = 0x00000030,
829 .dram_sdqs7 = 0x00000030,
830 .dram_dqm0 = 0x00000030,
831 .dram_dqm1 = 0x00000030,
832 .dram_dqm2 = 0x00000030,
833 .dram_dqm3 = 0x00000030,
834 .dram_dqm4 = 0x00000030,
835 .dram_dqm5 = 0x00000030,
836 .dram_dqm6 = 0x00000030,
837 .dram_dqm7 = 0x00000030,
838};
839
840const struct mx6dq_iomux_grp_regs mx6q_grp_ioregs = {
841 .grp_ddr_type = 0x000C0000,
842 .grp_ddrmode_ctl = 0x00020000,
843 .grp_ddrpke = 0x00000000,
844 .grp_addds = 0x00000030,
845 .grp_ctlds = 0x00000030,
846 .grp_ddrmode = 0x00020000,
847 .grp_b0ds = 0x00000030,
848 .grp_b1ds = 0x00000030,
849 .grp_b2ds = 0x00000030,
850 .grp_b3ds = 0x00000030,
851 .grp_b4ds = 0x00000030,
852 .grp_b5ds = 0x00000030,
853 .grp_b6ds = 0x00000030,
854 .grp_b7ds = 0x00000030,
855};
856
857static const struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
858 .grp_ddr_type = 0x000c0000,
859 .grp_ddrmode_ctl = 0x00020000,
860 .grp_ddrpke = 0x00000000,
861 .grp_addds = 0x00000030,
862 .grp_ctlds = 0x00000030,
863 .grp_ddrmode = 0x00020000,
864 .grp_b0ds = 0x00000030,
865 .grp_b1ds = 0x00000030,
866 .grp_b2ds = 0x00000030,
867 .grp_b3ds = 0x00000030,
868 .grp_b4ds = 0x00000030,
869 .grp_b5ds = 0x00000030,
870 .grp_b6ds = 0x00000030,
871 .grp_b7ds = 0x00000030,
872};
873
874const struct mx6_mmdc_calibration mx6q_mmcd_calib = {
875 .p0_mpwldectrl0 = 0x0016001A,
876 .p0_mpwldectrl1 = 0x0023001C,
877 .p1_mpwldectrl0 = 0x0028003A,
878 .p1_mpwldectrl1 = 0x001F002C,
879 .p0_mpdgctrl0 = 0x43440354,
880 .p0_mpdgctrl1 = 0x033C033C,
881 .p1_mpdgctrl0 = 0x43300368,
882 .p1_mpdgctrl1 = 0x03500330,
883 .p0_mprddlctl = 0x3228242E,
884 .p1_mprddlctl = 0x2C2C2636,
885 .p0_mpwrdlctl = 0x36323A38,
886 .p1_mpwrdlctl = 0x42324440,
887};
888
889const struct mx6_mmdc_calibration mx6q_2g_mmcd_calib = {
890 .p0_mpwldectrl0 = 0x00080016,
891 .p0_mpwldectrl1 = 0x001D0016,
892 .p1_mpwldectrl0 = 0x0018002C,
893 .p1_mpwldectrl1 = 0x000D001D,
894 .p0_mpdgctrl0 = 0x43200334,
895 .p0_mpdgctrl1 = 0x0320031C,
896 .p1_mpdgctrl0 = 0x0344034C,
897 .p1_mpdgctrl1 = 0x03380314,
898 .p0_mprddlctl = 0x3E36383A,
899 .p1_mprddlctl = 0x38363240,
900 .p0_mpwrdlctl = 0x36364238,
901 .p1_mpwrdlctl = 0x4230423E,
902};
903
904static const struct mx6_mmdc_calibration mx6s_mmcd_calib = {
905 .p0_mpwldectrl0 = 0x00480049,
906 .p0_mpwldectrl1 = 0x00410044,
907 .p0_mpdgctrl0 = 0x42480248,
908 .p0_mpdgctrl1 = 0x023C023C,
909 .p0_mprddlctl = 0x40424644,
910 .p0_mpwrdlctl = 0x34323034,
911};
912
913const struct mx6_mmdc_calibration mx6dl_mmcd_calib = {
914 .p0_mpwldectrl0 = 0x0043004B,
915 .p0_mpwldectrl1 = 0x003A003E,
916 .p1_mpwldectrl0 = 0x0047004F,
917 .p1_mpwldectrl1 = 0x004E0061,
918 .p0_mpdgctrl0 = 0x42500250,
919 .p0_mpdgctrl1 = 0x0238023C,
920 .p1_mpdgctrl0 = 0x42640264,
921 .p1_mpdgctrl1 = 0x02500258,
922 .p0_mprddlctl = 0x40424846,
923 .p1_mprddlctl = 0x46484842,
924 .p0_mpwrdlctl = 0x38382C30,
925 .p1_mpwrdlctl = 0x34343430,
926};
927
928static struct mx6_ddr3_cfg mem_ddr_2g = {
929 .mem_speed = 1600,
930 .density = 2,
931 .width = 16,
932 .banks = 8,
933 .rowaddr = 14,
934 .coladdr = 10,
935 .pagesz = 2,
936 .trcd = 1310,
937 .trcmin = 4875,
938 .trasmin = 3500,
939};
940
941static struct mx6_ddr3_cfg mem_ddr_4g = {
942 .mem_speed = 1600,
943 .density = 4,
944 .width = 16,
945 .banks = 8,
946 .rowaddr = 15,
947 .coladdr = 10,
948 .pagesz = 2,
949 .trcd = 1310,
950 .trcmin = 4875,
951 .trasmin = 3500,
952};
953
954static void ccgr_init(void)
955{
956 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
957
958 writel(0x00C03F3F, &ccm->CCGR0);
959 writel(0x0030FC03, &ccm->CCGR1);
960 writel(0x0FFFC000, &ccm->CCGR2);
961 writel(0x3FF00000, &ccm->CCGR3);
962 writel(0x00FFF300, &ccm->CCGR4);
963 writel(0x0F0000C3, &ccm->CCGR5);
964 writel(0x000003FF, &ccm->CCGR6);
965}
966
Otavio Salvadord7140352015-11-19 19:02:36 -0200967/* Define a minimal structure so that the part number can be read via SPL */
968struct mfgdata {
969 unsigned char tsize;
970 /* size of checksummed part in bytes */
971 unsigned char ckcnt;
972 /* checksum corrected byte */
973 unsigned char cksum;
974 /* decimal serial number, packed BCD */
975 unsigned char serial[6];
976 /* part number, right justified, ASCII */
977 unsigned char pn[16];
978};
979
980static void conv_ascii(unsigned char *dst, unsigned char *src, int len)
981{
982 int remain = len;
983 unsigned char *sptr = src;
984 unsigned char *dptr = dst;
985
986 while (remain) {
987 if (*sptr) {
988 *dptr = *sptr;
989 dptr++;
990 }
991 sptr++;
992 remain--;
993 }
994 *dptr = 0x0;
995}
996
997#define CFG_MFG_ADDR_OFFSET (spi->size - SZ_16K)
998static bool is_2gb(void)
999{
1000 struct spi_flash *spi;
1001 int ret;
1002 char buf[sizeof(struct mfgdata)];
1003 struct mfgdata *data = (struct mfgdata *)buf;
1004 unsigned char outbuf[32];
1005
1006 spi = spi_flash_probe(CONFIG_ENV_SPI_BUS,
1007 CONFIG_ENV_SPI_CS,
1008 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
1009 ret = spi_flash_read(spi, CFG_MFG_ADDR_OFFSET, sizeof(struct mfgdata),
1010 buf);
1011 if (ret)
1012 return false;
1013
1014 /* Congatec Part Numbers 104 and 105 have 2GiB of RAM */
1015 conv_ascii(outbuf, data->pn, sizeof(data->pn));
1016 if (!memcmp(outbuf, "016104", 6) || !memcmp(outbuf, "016105", 6))
1017 return true;
1018 else
1019 return false;
1020}
1021
1022static void spl_dram_init(int width)
1023{
1024 struct mx6_ddr_sysinfo sysinfo = {
1025 /* width of data bus:0=16,1=32,2=64 */
1026 .dsize = width / 32,
1027 /* config for full 4GB range so that get_mem_size() works */
1028 .cs_density = 32, /* 32Gb per CS */
1029 /* single chip select */
1030 .ncs = 1,
1031 .cs1_mirror = 0,
1032 .rtt_wr = 2,
1033 .rtt_nom = 2,
1034 .walat = 0,
1035 .ralat = 5,
1036 .mif3_mode = 3,
1037 .bi_on = 1,
1038 .sde_to_rst = 0x0d,
1039 .rst_to_cke = 0x20,
Fabio Estevamedf00932016-08-29 20:37:15 -03001040 .refsel = 1, /* Refresh cycles at 32KHz */
1041 .refr = 7, /* 8 refresh commands per refresh cycle */
Otavio Salvadord7140352015-11-19 19:02:36 -02001042 };
1043
1044 if (is_cpu_type(MXC_CPU_MX6Q) && is_2gb()) {
1045 mx6dq_dram_iocfg(width, &mx6q_ddr_ioregs, &mx6q_grp_ioregs);
1046 mx6_dram_cfg(&sysinfo, &mx6q_2g_mmcd_calib, &mem_ddr_4g);
1047 return;
1048 }
1049
Breno Lima68c27602016-07-22 09:12:12 -03001050 if (is_mx6dq()) {
Otavio Salvadord7140352015-11-19 19:02:36 -02001051 mx6dq_dram_iocfg(width, &mx6q_ddr_ioregs, &mx6q_grp_ioregs);
1052 mx6_dram_cfg(&sysinfo, &mx6q_mmcd_calib, &mem_ddr_2g);
1053 } else if (is_cpu_type(MXC_CPU_MX6SOLO)) {
1054 sysinfo.walat = 1;
1055 mx6sdl_dram_iocfg(width, &mx6dl_ddr_ioregs, &mx6sdl_grp_ioregs);
1056 mx6_dram_cfg(&sysinfo, &mx6s_mmcd_calib, &mem_ddr_4g);
1057 } else if (is_cpu_type(MXC_CPU_MX6DL)) {
1058 sysinfo.walat = 1;
1059 mx6sdl_dram_iocfg(width, &mx6dl_ddr_ioregs, &mx6sdl_grp_ioregs);
1060 mx6_dram_cfg(&sysinfo, &mx6dl_mmcd_calib, &mem_ddr_2g);
1061 }
1062}
1063
1064void board_init_f(ulong dummy)
1065{
1066 /* setup AIPS and disable watchdog */
1067 arch_cpu_init();
1068
1069 ccgr_init();
1070 gpr_init();
1071
1072 /* iomux and setup of i2c */
1073 board_early_init_f();
1074
1075 /* setup GP timer */
1076 timer_init();
1077
1078 /* UART clocks enabled and gd valid - init serial console */
1079 preloader_console_init();
1080
1081 /* Needed for malloc() to work in SPL prior to board_init_r() */
1082 spl_init();
1083
1084 /* DDR initialization */
1085 if (is_cpu_type(MXC_CPU_MX6SOLO))
1086 spl_dram_init(32);
1087 else
1088 spl_dram_init(64);
1089
1090 /* Clear the BSS. */
1091 memset(__bss_start, 0, __bss_end - __bss_start);
1092
1093 /* load/boot image from boot device */
1094 board_init_r(NULL, 0);
1095}
1096#endif