]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * (C) Copyright 2013 | |
3 | * Gumstix Inc. <www.gumstix.com> | |
4 | * Maintainer: Ash Charles <ash@gumstix.com> | |
5 | * | |
6 | * SPDX-License-Identifier: GPL-2.0+ | |
7 | */ | |
8 | #include <common.h> | |
9 | #include <netdev.h> | |
10 | #include <asm/arch/sys_proto.h> | |
11 | #include <asm/arch/mmc_host_def.h> | |
12 | #include <twl6030.h> | |
13 | #include <asm/emif.h> | |
14 | #include <asm/arch/clock.h> | |
15 | #include <asm/arch/gpio.h> | |
16 | #include <asm/gpio.h> | |
17 | ||
18 | #include "duovero_mux_data.h" | |
19 | ||
20 | #define WIFI_EN 43 | |
21 | ||
22 | #if defined(CONFIG_CMD_NET) | |
23 | #define SMSC_NRESET 45 | |
24 | static void setup_net_chip(void); | |
25 | #endif | |
26 | ||
27 | #ifdef CONFIG_USB_EHCI | |
28 | #include <usb.h> | |
29 | #include <asm/arch/ehci.h> | |
30 | #include <asm/ehci-omap.h> | |
31 | #endif | |
32 | ||
33 | DECLARE_GLOBAL_DATA_PTR; | |
34 | ||
35 | const struct omap_sysinfo sysinfo = { | |
36 | "Board: duovero\n" | |
37 | }; | |
38 | ||
39 | struct omap4_scrm_regs *const scrm = (struct omap4_scrm_regs *)0x4a30a000; | |
40 | ||
41 | /** | |
42 | * @brief board_init | |
43 | * | |
44 | * @return 0 | |
45 | */ | |
46 | int board_init(void) | |
47 | { | |
48 | gpmc_init(); | |
49 | ||
50 | gd->bd->bi_arch_number = MACH_TYPE_OMAP4_DUOVERO; | |
51 | gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; | |
52 | ||
53 | return 0; | |
54 | } | |
55 | ||
56 | /** | |
57 | * @brief misc_init_r - Configure board specific configurations | |
58 | * such as power configurations, ethernet initialization as phase2 of | |
59 | * boot sequence | |
60 | * | |
61 | * @return 0 | |
62 | */ | |
63 | int misc_init_r(void) | |
64 | { | |
65 | int ret = 0; | |
66 | u8 val; | |
67 | ||
68 | /* wifi setup: first enable 32Khz clock from 6030 pmic */ | |
69 | val = 0xe1; | |
70 | ret = i2c_write(TWL6030_CHIP_PM, 0xbe, 1, &val, 1); | |
71 | if (ret) | |
72 | printf("Failed to enable 32Khz clock to wifi module\n"); | |
73 | ||
74 | /* then setup WIFI_EN as an output pin and send reset pulse */ | |
75 | if (!gpio_request(WIFI_EN, "")) { | |
76 | gpio_direction_output(WIFI_EN, 0); | |
77 | gpio_set_value(WIFI_EN, 1); | |
78 | udelay(1); | |
79 | gpio_set_value(WIFI_EN, 0); | |
80 | udelay(1); | |
81 | gpio_set_value(WIFI_EN, 1); | |
82 | } | |
83 | ||
84 | #if defined(CONFIG_CMD_NET) | |
85 | setup_net_chip(); | |
86 | #endif | |
87 | return 0; | |
88 | } | |
89 | ||
90 | void set_muxconf_regs_essential(void) | |
91 | { | |
92 | do_set_mux((*ctrl)->control_padconf_core_base, | |
93 | core_padconf_array_essential, | |
94 | sizeof(core_padconf_array_essential) / | |
95 | sizeof(struct pad_conf_entry)); | |
96 | ||
97 | do_set_mux((*ctrl)->control_padconf_wkup_base, | |
98 | wkup_padconf_array_essential, | |
99 | sizeof(wkup_padconf_array_essential) / | |
100 | sizeof(struct pad_conf_entry)); | |
101 | ||
102 | do_set_mux((*ctrl)->control_padconf_core_base, | |
103 | core_padconf_array_non_essential, | |
104 | sizeof(core_padconf_array_non_essential) / | |
105 | sizeof(struct pad_conf_entry)); | |
106 | ||
107 | do_set_mux((*ctrl)->control_padconf_wkup_base, | |
108 | wkup_padconf_array_non_essential, | |
109 | sizeof(wkup_padconf_array_non_essential) / | |
110 | sizeof(struct pad_conf_entry)); | |
111 | } | |
112 | ||
113 | #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC) | |
114 | int board_mmc_init(bd_t *bis) | |
115 | { | |
116 | return omap_mmc_init(0, 0, 0, -1, -1); | |
117 | } | |
118 | #endif | |
119 | ||
120 | ||
121 | #if defined(CONFIG_CMD_NET) | |
122 | ||
123 | #define GPMC_SIZE_16M 0xF | |
124 | #define GPMC_BASEADDR_MASK 0x3F | |
125 | #define GPMC_CS_ENABLE 0x1 | |
126 | ||
127 | static void enable_gpmc_net_config(const u32 *gpmc_config, struct gpmc_cs *cs, | |
128 | u32 base, u32 size) | |
129 | { | |
130 | writel(0, &cs->config7); | |
131 | sdelay(1000); | |
132 | /* Delay for settling */ | |
133 | writel(gpmc_config[0], &cs->config1); | |
134 | writel(gpmc_config[1], &cs->config2); | |
135 | writel(gpmc_config[2], &cs->config3); | |
136 | writel(gpmc_config[3], &cs->config4); | |
137 | writel(gpmc_config[4], &cs->config5); | |
138 | writel(gpmc_config[5], &cs->config6); | |
139 | ||
140 | /* | |
141 | * Enable the config. size is the CS size and goes in | |
142 | * bits 11:8. We set bit 6 to enable this CS and the base | |
143 | * address goes into bits 5:0. | |
144 | */ | |
145 | writel((size << 8) | (GPMC_CS_ENABLE << 6) | | |
146 | ((base >> 24) & GPMC_BASEADDR_MASK), | |
147 | &cs->config7); | |
148 | ||
149 | sdelay(2000); | |
150 | } | |
151 | ||
152 | /* GPMC CS configuration for an SMSC LAN9221 ethernet controller */ | |
153 | #define NET_LAN9221_GPMC_CONFIG1 0x2a001203 | |
154 | #define NET_LAN9221_GPMC_CONFIG2 0x000a0a02 | |
155 | #define NET_LAN9221_GPMC_CONFIG3 0x00020200 | |
156 | #define NET_LAN9221_GPMC_CONFIG4 0x0a030a03 | |
157 | #define NET_LAN9221_GPMC_CONFIG5 0x000a0a0a | |
158 | #define NET_LAN9221_GPMC_CONFIG6 0x8a070707 | |
159 | #define NET_LAN9221_GPMC_CONFIG7 0x00000f6c | |
160 | ||
161 | /* GPMC definitions for LAN9221 chips on expansion boards */ | |
162 | static const u32 gpmc_lan_config[] = { | |
163 | NET_LAN9221_GPMC_CONFIG1, | |
164 | NET_LAN9221_GPMC_CONFIG2, | |
165 | NET_LAN9221_GPMC_CONFIG3, | |
166 | NET_LAN9221_GPMC_CONFIG4, | |
167 | NET_LAN9221_GPMC_CONFIG5, | |
168 | NET_LAN9221_GPMC_CONFIG6, | |
169 | /*CONFIG7- computed as params */ | |
170 | }; | |
171 | ||
172 | /* | |
173 | * Routine: setup_net_chip | |
174 | * Description: Setting up the configuration GPMC registers specific to the | |
175 | * Ethernet hardware. | |
176 | */ | |
177 | static void setup_net_chip(void) | |
178 | { | |
179 | enable_gpmc_net_config(gpmc_lan_config, &gpmc_cfg->cs[5], 0x2C000000, | |
180 | GPMC_SIZE_16M); | |
181 | ||
182 | /* Make GPIO SMSC_NRESET as output pin and send reset pulse */ | |
183 | if (!gpio_request(SMSC_NRESET, "")) { | |
184 | gpio_direction_output(SMSC_NRESET, 0); | |
185 | gpio_set_value(SMSC_NRESET, 1); | |
186 | udelay(1); | |
187 | gpio_set_value(SMSC_NRESET, 0); | |
188 | udelay(1); | |
189 | gpio_set_value(SMSC_NRESET, 1); | |
190 | } | |
191 | } | |
192 | #endif | |
193 | ||
194 | int board_eth_init(bd_t *bis) | |
195 | { | |
196 | int rc = 0; | |
197 | #ifdef CONFIG_SMC911X | |
198 | rc = smc911x_initialize(0, CONFIG_SMC911X_BASE); | |
199 | #endif | |
200 | return rc; | |
201 | } | |
202 | ||
203 | #ifdef CONFIG_USB_EHCI | |
204 | ||
205 | static struct omap_usbhs_board_data usbhs_bdata = { | |
206 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | |
207 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, | |
208 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | |
209 | }; | |
210 | ||
211 | int ehci_hcd_init(int index, enum usb_init_type init, | |
212 | struct ehci_hccr **hccr, struct ehci_hcor **hcor) | |
213 | { | |
214 | int ret; | |
215 | unsigned int utmi_clk; | |
216 | u32 auxclk, altclksrc; | |
217 | ||
218 | /* Now we can enable our port clocks */ | |
219 | utmi_clk = readl((void *)CM_L3INIT_HSUSBHOST_CLKCTRL); | |
220 | utmi_clk |= HSUSBHOST_CLKCTRL_CLKSEL_UTMI_P1_MASK; | |
221 | setbits_le32((void *)CM_L3INIT_HSUSBHOST_CLKCTRL, utmi_clk); | |
222 | ||
223 | auxclk = readl(&scrm->auxclk3); | |
224 | /* Select sys_clk */ | |
225 | auxclk &= ~AUXCLK_SRCSELECT_MASK; | |
226 | auxclk |= AUXCLK_SRCSELECT_SYS_CLK << AUXCLK_SRCSELECT_SHIFT; | |
227 | /* Set the divisor to 2 */ | |
228 | auxclk &= ~AUXCLK_CLKDIV_MASK; | |
229 | auxclk |= AUXCLK_CLKDIV_2 << AUXCLK_CLKDIV_SHIFT; | |
230 | /* Request auxilary clock #3 */ | |
231 | auxclk |= AUXCLK_ENABLE_MASK; | |
232 | writel(auxclk, &scrm->auxclk3); | |
233 | ||
234 | altclksrc = readl(&scrm->altclksrc); | |
235 | ||
236 | /* Activate alternate system clock supplier */ | |
237 | altclksrc &= ~ALTCLKSRC_MODE_MASK; | |
238 | altclksrc |= ALTCLKSRC_MODE_ACTIVE; | |
239 | ||
240 | /* enable clocks */ | |
241 | altclksrc |= ALTCLKSRC_ENABLE_INT_MASK | ALTCLKSRC_ENABLE_EXT_MASK; | |
242 | ||
243 | writel(altclksrc, &scrm->altclksrc); | |
244 | ||
245 | ret = omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor); | |
246 | if (ret < 0) | |
247 | return ret; | |
248 | ||
249 | return 0; | |
250 | } | |
251 | ||
252 | int ehci_hcd_stop(int index) | |
253 | { | |
254 | return omap_ehci_hcd_stop(); | |
255 | } | |
256 | #endif | |
257 | ||
258 | /* | |
259 | * get_board_rev() - get board revision | |
260 | */ | |
261 | u32 get_board_rev(void) | |
262 | { | |
263 | return 0x20; | |
264 | } |