blob: b8dcd03fd9b622bd887c2328bcb48317cc193059 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Lukasz Majewskia3eec242017-10-31 17:58:05 +01002/*
3 * Copyright (C) 2017 DENX Software Engineering
4 * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
Lukasz Majewskia3eec242017-10-31 17:58:05 +01005 */
6
7#include <common.h>
8#include <dm.h>
9#include <asm/io.h>
10#include <asm/arch/clock.h>
11#include <asm/arch/imx-regs.h>
12#include <asm/arch/iomux.h>
13#include <asm/arch/mx6-pins.h>
14#include <asm/arch/mx6-ddr.h>
15#include <asm/arch/sys_proto.h>
Simon Glass9fb625c2019-08-01 09:46:51 -060016#include <env.h>
Lukasz Majewskia3eec242017-10-31 17:58:05 +010017#include <errno.h>
18#include <asm/gpio.h>
19#include <malloc.h>
20#include <asm/mach-imx/iomux-v3.h>
Lukasz Majewskia3eec242017-10-31 17:58:05 +010021#include <asm/mach-imx/boot_mode.h>
Lukasz Majewskia3eec242017-10-31 17:58:05 +010022#include <miiphy.h>
23#include <netdev.h>
24#include <i2c.h>
25
26#include <dm.h>
27#include <dm/platform_data/serial_mxc.h>
28#include <dm/platdata.h>
29
Lukasz Majewskia3eec242017-10-31 17:58:05 +010030#include "common.h"
31
32DECLARE_GLOBAL_DATA_PTR;
33
34static bool hw_ids_valid;
35static bool sw_ids_valid;
36static u32 cpu_id;
37static u32 unit_id;
38
39#define SW0 IMX_GPIO_NR(2, 4)
40#define SW1 IMX_GPIO_NR(2, 5)
41#define SW2 IMX_GPIO_NR(2, 6)
42#define SW3 IMX_GPIO_NR(2, 7)
43#define HW0 IMX_GPIO_NR(6, 7)
44#define HW1 IMX_GPIO_NR(6, 9)
45#define HW2 IMX_GPIO_NR(6, 10)
46#define HW3 IMX_GPIO_NR(6, 11)
47#define HW4 IMX_GPIO_NR(4, 7)
48#define HW5 IMX_GPIO_NR(4, 11)
49#define HW6 IMX_GPIO_NR(4, 13)
50#define HW7 IMX_GPIO_NR(4, 15)
51
52int gpio_table_sw_ids[] = {
53 SW0, SW1, SW2, SW3
54};
55
56const char *gpio_table_sw_ids_names[] = {
57 "sw0", "sw1", "sw2", "sw3"
58};
59
60int gpio_table_hw_ids[] = {
61 HW0, HW1, HW2, HW3, HW4, HW5, HW6, HW7
62};
63
64const char *gpio_table_hw_ids_names[] = {
65 "hw0", "hw1", "hw2", "hw3", "hw4", "hw5", "hw6", "hw7"
66};
67
68static int get_board_id(int *ids, const char **c, int size,
69 bool *valid, u32 *id)
70{
71 int i, ret, val;
72
73 *valid = false;
74
75 for (i = 0; i < size; i++) {
76 ret = gpio_request(ids[i], c[i]);
77 if (ret) {
78 printf("Can't request SWx gpios\n");
79 return ret;
80 }
81 }
82
83 for (i = 0; i < size; i++) {
84 ret = gpio_direction_input(ids[i]);
85 if (ret) {
86 printf("Can't set SWx gpios direction\n");
87 return ret;
88 }
89 }
90
91 for (i = 0; i < size; i++) {
92 val = gpio_get_value(ids[i]);
93 if (val < 0) {
94 printf("Can't get SW%d ID\n", i);
95 *id = 0;
96 return val;
97 }
98 *id |= val << i;
99 }
100 *valid = true;
101
102 return 0;
103}
104
105int dram_init(void)
106{
107 gd->ram_size = imx_ddr_size();
108
109 return 0;
110}
111
Lukasz Majewskia3eec242017-10-31 17:58:05 +0100112iomux_v3_cfg_t const misc_pads[] = {
113 /* Prod ID GPIO pins */
114 MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL),
115 MX6_PAD_NANDF_D5__GPIO2_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
116 MX6_PAD_NANDF_D6__GPIO2_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
117 MX6_PAD_NANDF_D7__GPIO2_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
118
119 /* HW revision GPIO pins */
120 MX6_PAD_NANDF_CLE__GPIO6_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
121 MX6_PAD_NANDF_WP_B__GPIO6_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
122 MX6_PAD_NANDF_RB0__GPIO6_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
123 MX6_PAD_NANDF_CS0__GPIO6_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
124 MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
125 MX6_PAD_KEY_ROW2__GPIO4_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
126 MX6_PAD_KEY_ROW3__GPIO4_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL),
127 MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
128
129 /* XTALOSC */
130 MX6_PAD_GPIO_3__XTALOSC_REF_CLK_24M | MUX_PAD_CTRL(NO_PAD_CTRL),
Lukasz Majewski27aede22018-05-11 16:51:08 +0200131
132 /* Emergency recovery pin */
133 MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
Lukasz Majewskia3eec242017-10-31 17:58:05 +0100134};
135
Lukasz Majewskia3eec242017-10-31 17:58:05 +0100136/*
137 * Do not overwrite the console
138 * Always use serial for U-Boot console
139 */
140int overwrite_console(void)
141{
142 return 1;
143}
144
145#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
146int ft_board_setup(void *blob, bd_t *bd)
147{
148 fdt_fixup_ethernet(blob);
149 return 0;
150}
151#endif
152
Lukasz Majewski32e07512019-09-03 16:38:42 +0200153int board_phy_config(struct phy_device *phydev)
154{
155 /* display5 due to PCB routing can only work with 100 Mbps */
156 phydev->advertising &= ~(ADVERTISED_1000baseX_Half |
157 ADVERTISED_1000baseX_Full |
158 SUPPORTED_1000baseT_Half |
159 SUPPORTED_1000baseT_Full);
160
161 if (phydev->drv->config)
162 return phydev->drv->config(phydev);
163
164 return 0;
165}
166
Lukasz Majewskia3eec242017-10-31 17:58:05 +0100167int board_init(void)
168{
Lukasz Majewskie95b4bd2019-09-03 16:38:43 +0200169 struct gpio_desc phy_int_gbe, spi2_wp;
Lukasz Majewski32e07512019-09-03 16:38:42 +0200170 int ret;
171
Lukasz Majewskia3eec242017-10-31 17:58:05 +0100172 debug("board init\n");
173 /* address of boot parameters */
174 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
175
Lukasz Majewski32e07512019-09-03 16:38:42 +0200176 /* Setup misc (application specific) stuff */
Lukasz Majewskia3eec242017-10-31 17:58:05 +0100177 SETUP_IOMUX_PADS(misc_pads);
178
179 get_board_id(gpio_table_sw_ids, &gpio_table_sw_ids_names[0],
180 ARRAY_SIZE(gpio_table_sw_ids), &sw_ids_valid, &unit_id);
181 debug("SWx unit_id 0x%x\n", unit_id);
182
183 get_board_id(gpio_table_hw_ids, &gpio_table_hw_ids_names[0],
184 ARRAY_SIZE(gpio_table_hw_ids), &hw_ids_valid, &cpu_id);
185 debug("HWx cpu_id 0x%x\n", cpu_id);
186
187 if (hw_ids_valid && sw_ids_valid)
188 printf("ID: unit type 0x%x rev 0x%x\n", unit_id, cpu_id);
189
190 udelay(25);
191
Lukasz Majewski32e07512019-09-03 16:38:42 +0200192 /* Setup low level FEC (ETH) */
193 ret = dm_gpio_lookup_name("GPIO1_28", &phy_int_gbe);
194 if (ret) {
195 printf("Cannot get GPIO1_28\n");
196 } else {
197 ret = dm_gpio_request(&phy_int_gbe, "INT_GBE");
198 if (!ret)
199 dm_gpio_set_dir_flags(&phy_int_gbe, GPIOD_IS_IN);
200 }
201
202 iomuxc_set_rgmii_io_voltage(DDR_SEL_1P5V_IO);
203 enable_fec_anatop_clock(0, ENET_125MHZ);
204
Lukasz Majewskie95b4bd2019-09-03 16:38:43 +0200205 /* Setup #WP for SPI-NOR memory */
206 ret = dm_gpio_lookup_name("GPIO7_0", &spi2_wp);
207 if (ret) {
208 printf("Cannot get GPIO7_0\n");
209 } else {
210 ret = dm_gpio_request(&spi2_wp, "spi2_#wp");
211 if (!ret)
212 dm_gpio_set_dir_flags(&spi2_wp, GPIOD_IS_OUT |
213 GPIOD_IS_OUT_ACTIVE);
214 }
215
Lukasz Majewskia3eec242017-10-31 17:58:05 +0100216 return 0;
217}
218
219#ifdef CONFIG_CMD_BMODE
220static const struct boot_mode board_boot_modes[] = {
221 /* eMMC, USDHC-4, 8-bit bus width */
222 /* SPI-NOR, ECSPI-2 SS0, 3-bytes addressing */
223 {"emmc", MAKE_CFGVAL(0x60, 0x58, 0x00, 0x00)},
224 {"spinor", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x09)},
225 {NULL, 0},
226};
227
228static void setup_boot_modes(void)
229{
230 add_board_boot_modes(board_boot_modes);
231}
232#else
233static inline void setup_boot_modes(void) {}
234#endif
235
236int misc_init_r(void)
237{
Lukasz Majewskifeeff152019-09-03 16:38:49 +0200238 struct gpio_desc em_pad;
Lukasz Majewski27aede22018-05-11 16:51:08 +0200239 int ret;
240
Lukasz Majewskia3eec242017-10-31 17:58:05 +0100241 setup_boot_modes();
Lukasz Majewski27aede22018-05-11 16:51:08 +0200242
Lukasz Majewskifeeff152019-09-03 16:38:49 +0200243 ret = dm_gpio_lookup_name("GPIO3_29", &em_pad);
244 if (ret) {
245 printf("Can't find emergency PAD gpio\n");
246 return ret;
247 }
248
249 ret = dm_gpio_request(&em_pad, "Emergency_PAD");
Lukasz Majewski27aede22018-05-11 16:51:08 +0200250 if (ret) {
251 printf("Can't request emergency PAD gpio\n");
252 return ret;
253 }
254
Lukasz Majewskifeeff152019-09-03 16:38:49 +0200255 dm_gpio_set_dir_flags(&em_pad, GPIOD_IS_IN);
Lukasz Majewski27aede22018-05-11 16:51:08 +0200256
Lukasz Majewskia3eec242017-10-31 17:58:05 +0100257 return 0;
258}