]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
8a3f6bb6 EBS |
2 | /* |
3 | * (C) Copyright 2010 | |
4 | * ISEE 2007 SL, <www.iseebcn.com> | |
8a3f6bb6 EBS |
5 | */ |
6 | #include <common.h> | |
9fb625ce | 7 | #include <env.h> |
691d719d | 8 | #include <init.h> |
336d4615 | 9 | #include <malloc.h> |
90526e9f | 10 | #include <net.h> |
f3b4bc45 | 11 | #include <status_led.h> |
b3f4ca11 SG |
12 | #include <dm.h> |
13 | #include <ns16550.h> | |
8a3f6bb6 | 14 | #include <twl4030.h> |
77eea280 | 15 | #include <netdev.h> |
fe9f6289 | 16 | #include <spl.h> |
84c3b631 | 17 | #include <asm/gpio.h> |
77eea280 | 18 | #include <asm/io.h> |
8a3f6bb6 | 19 | #include <asm/arch/mem.h> |
f49d7b6c | 20 | #include <asm/arch/mmc_host_def.h> |
8a3f6bb6 EBS |
21 | #include <asm/arch/mux.h> |
22 | #include <asm/arch/sys_proto.h> | |
c05ed00a | 23 | #include <linux/delay.h> |
a5debaa3 | 24 | #include <linux/mtd/mtd.h> |
6ae3900a | 25 | #include <linux/mtd/rawnand.h> |
97ee7060 LM |
26 | #include <linux/mtd/onenand.h> |
27 | #include <jffs2/load_kernel.h> | |
568b471e LM |
28 | #include <mtd_node.h> |
29 | #include <fdt_support.h> | |
77eea280 | 30 | #include "igep00x0.h" |
8a3f6bb6 | 31 | |
b3f4ca11 | 32 | static const struct ns16550_platdata igep_serial = { |
2f6ed3b8 AF |
33 | .base = OMAP34XX_UART3, |
34 | .reg_shift = 2, | |
17fa0326 HS |
35 | .clock = V_NS16550_CLK, |
36 | .fcr = UART_FCR_DEFVAL, | |
b3f4ca11 SG |
37 | }; |
38 | ||
39 | U_BOOT_DEVICE(igep_uart) = { | |
c7b9686d | 40 | "ns16550_serial", |
b3f4ca11 SG |
41 | &igep_serial |
42 | }; | |
43 | ||
195dc231 PP |
44 | /* |
45 | * Routine: get_board_revision | |
46 | * Description: GPIO_28 and GPIO_129 are used to read board and revision from | |
47 | * IGEP00x0 boards. First of all, it is necessary to reset USB transceiver from | |
48 | * IGEP0030 in order to read GPIO_IGEP00X0_BOARD_DETECTION correctly, because | |
49 | * this functionality is shared by USB HOST. | |
50 | * Once USB reset is applied, U-boot configures these pins as input pullup to | |
51 | * detect board and revision: | |
52 | * IGEP0020-RF = 0b00 | |
53 | * IGEP0020-RC = 0b01 | |
54 | * IGEP0030-RG = 0b10 | |
55 | * IGEP0030-RE = 0b11 | |
56 | */ | |
57 | static int get_board_revision(void) | |
58 | { | |
59 | int revision; | |
60 | ||
61 | gpio_request(IGEP0030_USB_TRANSCEIVER_RESET, | |
62 | "igep0030_usb_transceiver_reset"); | |
63 | gpio_direction_output(IGEP0030_USB_TRANSCEIVER_RESET, 0); | |
64 | ||
65 | gpio_request(GPIO_IGEP00X0_BOARD_DETECTION, "igep00x0_board_detection"); | |
66 | gpio_direction_input(GPIO_IGEP00X0_BOARD_DETECTION); | |
67 | revision = 2 * gpio_get_value(GPIO_IGEP00X0_BOARD_DETECTION); | |
68 | gpio_free(GPIO_IGEP00X0_BOARD_DETECTION); | |
69 | ||
70 | gpio_request(GPIO_IGEP00X0_REVISION_DETECTION, | |
71 | "igep00x0_revision_detection"); | |
72 | gpio_direction_input(GPIO_IGEP00X0_REVISION_DETECTION); | |
73 | revision = revision + gpio_get_value(GPIO_IGEP00X0_REVISION_DETECTION); | |
74 | gpio_free(GPIO_IGEP00X0_REVISION_DETECTION); | |
75 | ||
76 | gpio_free(IGEP0030_USB_TRANSCEIVER_RESET); | |
77 | ||
78 | return revision; | |
79 | } | |
80 | ||
97ee7060 LM |
81 | int onenand_board_init(struct mtd_info *mtd) |
82 | { | |
83 | if (gpmc_cs0_flash == MTD_DEV_TYPE_ONENAND) { | |
84 | struct onenand_chip *this = mtd->priv; | |
85 | this->base = (void *)CONFIG_SYS_ONENAND_BASE; | |
86 | return 0; | |
87 | } | |
88 | return 1; | |
89 | } | |
90 | ||
77eea280 | 91 | #if defined(CONFIG_CMD_NET) |
6ed75ba7 LM |
92 | static void reset_net_chip(int gpio) |
93 | { | |
94 | if (!gpio_request(gpio, "eth nrst")) { | |
95 | gpio_direction_output(gpio, 1); | |
96 | udelay(1); | |
97 | gpio_set_value(gpio, 0); | |
98 | udelay(40); | |
99 | gpio_set_value(gpio, 1); | |
100 | mdelay(10); | |
101 | } | |
102 | } | |
103 | ||
8a3f6bb6 EBS |
104 | /* |
105 | * Routine: setup_net_chip | |
106 | * Description: Setting up the configuration GPMC registers specific to the | |
107 | * Ethernet hardware. | |
108 | */ | |
8a3f6bb6 EBS |
109 | static void setup_net_chip(void) |
110 | { | |
111 | struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE; | |
b0c47633 LM |
112 | static const u32 gpmc_lan_config[] = { |
113 | NET_LAN9221_GPMC_CONFIG1, | |
114 | NET_LAN9221_GPMC_CONFIG2, | |
115 | NET_LAN9221_GPMC_CONFIG3, | |
116 | NET_LAN9221_GPMC_CONFIG4, | |
117 | NET_LAN9221_GPMC_CONFIG5, | |
118 | NET_LAN9221_GPMC_CONFIG6, | |
119 | }; | |
8a3f6bb6 | 120 | |
6ed75ba7 LM |
121 | enable_gpmc_cs_config(gpmc_lan_config, &gpmc_cfg->cs[5], |
122 | CONFIG_SMC911X_BASE, GPMC_SIZE_16M); | |
8a3f6bb6 EBS |
123 | |
124 | /* Enable off mode for NWE in PADCONF_GPMC_NWE register */ | |
125 | writew(readw(&ctrl_base->gpmc_nwe) | 0x0E00, &ctrl_base->gpmc_nwe); | |
126 | /* Enable off mode for NOE in PADCONF_GPMC_NADV_ALE register */ | |
127 | writew(readw(&ctrl_base->gpmc_noe) | 0x0E00, &ctrl_base->gpmc_noe); | |
128 | /* Enable off mode for ALE in PADCONF_GPMC_NADV_ALE register */ | |
129 | writew(readw(&ctrl_base->gpmc_nadv_ale) | 0x0E00, | |
130 | &ctrl_base->gpmc_nadv_ale); | |
131 | ||
6ed75ba7 | 132 | reset_net_chip(64); |
8a3f6bb6 | 133 | } |
b0c47633 LM |
134 | |
135 | int board_eth_init(bd_t *bis) | |
136 | { | |
137 | #ifdef CONFIG_SMC911X | |
138 | return smc911x_initialize(0, CONFIG_SMC911X_BASE); | |
139 | #else | |
140 | return 0; | |
141 | #endif | |
142 | } | |
77eea280 JMC |
143 | #else |
144 | static inline void setup_net_chip(void) {} | |
8a3f6bb6 EBS |
145 | #endif |
146 | ||
568b471e | 147 | #ifdef CONFIG_OF_BOARD_SETUP |
e4290aa1 LM |
148 | static int ft_enable_by_compatible(void *blob, char *compat, int enable) |
149 | { | |
150 | int off = fdt_node_offset_by_compatible(blob, -1, compat); | |
151 | if (off < 0) | |
152 | return off; | |
153 | ||
154 | if (enable) | |
155 | fdt_status_okay(blob, off); | |
156 | else | |
157 | fdt_status_disabled(blob, off); | |
158 | ||
159 | return 0; | |
160 | } | |
161 | ||
568b471e LM |
162 | int ft_board_setup(void *blob, bd_t *bd) |
163 | { | |
164 | #ifdef CONFIG_FDT_FIXUP_PARTITIONS | |
b35fb6ac | 165 | static const struct node_info nodes[] = { |
568b471e LM |
166 | { "ti,omap2-nand", MTD_DEV_TYPE_NAND, }, |
167 | { "ti,omap2-onenand", MTD_DEV_TYPE_ONENAND, }, | |
168 | }; | |
169 | ||
170 | fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); | |
171 | #endif | |
e4290aa1 LM |
172 | ft_enable_by_compatible(blob, "ti,omap2-nand", |
173 | gpmc_cs0_flash == MTD_DEV_TYPE_NAND); | |
174 | ft_enable_by_compatible(blob, "ti,omap2-onenand", | |
175 | gpmc_cs0_flash == MTD_DEV_TYPE_ONENAND); | |
176 | ||
568b471e LM |
177 | return 0; |
178 | } | |
179 | #endif | |
180 | ||
195dc231 | 181 | void set_led(void) |
a2fa28bc | 182 | { |
195dc231 PP |
183 | switch (get_board_revision()) { |
184 | case 0: | |
185 | case 1: | |
186 | gpio_request(IGEP0020_GPIO_LED, "igep0020_gpio_led"); | |
187 | gpio_direction_output(IGEP0020_GPIO_LED, 1); | |
a2fa28bc | 188 | break; |
195dc231 PP |
189 | case 2: |
190 | case 3: | |
191 | gpio_request(IGEP0030_GPIO_LED, "igep0030_gpio_led"); | |
192 | gpio_direction_output(IGEP0030_GPIO_LED, 0); | |
193 | break; | |
194 | default: | |
195 | /* Should not happen... */ | |
a2fa28bc JMC |
196 | break; |
197 | } | |
198 | } | |
199 | ||
195dc231 PP |
200 | void set_boardname(void) |
201 | { | |
202 | char rev[5] = { 'F','C','G','E', }; | |
203 | int i = get_board_revision(); | |
204 | ||
205 | rev[i+1] = 0; | |
206 | env_set("board_rev", rev + i); | |
207 | env_set("board_name", i < 2 ? "igep0020" : "igep0030"); | |
208 | } | |
209 | ||
8a3f6bb6 EBS |
210 | /* |
211 | * Routine: misc_init_r | |
212 | * Description: Configure board specific parts | |
213 | */ | |
214 | int misc_init_r(void) | |
215 | { | |
195dc231 PP |
216 | t2_t *t2_base = (t2_t *)T2_BASE; |
217 | u32 pbias_lite; | |
218 | ||
8a3f6bb6 EBS |
219 | twl4030_power_init(); |
220 | ||
195dc231 PP |
221 | /* set VSIM to 1.8V */ |
222 | twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VSIM_DEDICATED, | |
223 | TWL4030_PM_RECEIVER_VSIM_VSEL_18, | |
224 | TWL4030_PM_RECEIVER_VSIM_DEV_GRP, | |
225 | TWL4030_PM_RECEIVER_DEV_GRP_P1); | |
226 | ||
227 | /* set up dual-voltage GPIOs to 1.8V */ | |
228 | pbias_lite = readl(&t2_base->pbias_lite); | |
229 | pbias_lite &= ~PBIASLITEVMODE1; | |
230 | pbias_lite |= PBIASLITEPWRDNZ1; | |
231 | writel(pbias_lite, &t2_base->pbias_lite); | |
232 | if (get_cpu_family() == CPU_OMAP36XX) | |
233 | writel(readl(OMAP34XX_CTRL_WKUP_CTRL) | | |
234 | OMAP34XX_CTRL_WKUP_CTRL_GPIO_IO_PWRDNZ, | |
235 | OMAP34XX_CTRL_WKUP_CTRL); | |
236 | ||
8a3f6bb6 | 237 | setup_net_chip(); |
8a3f6bb6 | 238 | |
679f82c3 | 239 | omap_die_id_display(); |
8a3f6bb6 | 240 | |
195dc231 PP |
241 | set_led(); |
242 | ||
243 | set_boardname(); | |
a2fa28bc | 244 | |
8a3f6bb6 EBS |
245 | return 0; |
246 | } | |
247 | ||
a5debaa3 LM |
248 | void board_mtdparts_default(const char **mtdids, const char **mtdparts) |
249 | { | |
250 | struct mtd_info *mtd = get_mtd_device(NULL, 0); | |
251 | if (mtd) { | |
252 | static char ids[24]; | |
253 | static char parts[48]; | |
254 | const char *linux_name = "omap2-nand"; | |
255 | if (strncmp(mtd->name, "onenand0", 8) == 0) | |
256 | linux_name = "omap2-onenand"; | |
257 | snprintf(ids, sizeof(ids), "%s=%s", mtd->name, linux_name); | |
258 | snprintf(parts, sizeof(parts), "mtdparts=%s:%dk(SPL),-(UBI)", | |
259 | linux_name, 4 * mtd->erasesize >> 10); | |
260 | *mtdids = ids; | |
261 | *mtdparts = parts; | |
262 | } | |
263 | } |