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