]>
Commit | Line | Data |
---|---|---|
cba69eee IC |
1 | /* |
2 | * (C) Copyright 2012-2013 Henrik Nordstrom <[email protected]> | |
3 | * (C) Copyright 2013 Luke Kenneth Casson Leighton <[email protected]> | |
4 | * | |
5 | * (C) Copyright 2007-2011 | |
6 | * Allwinner Technology Co., Ltd. <www.allwinnertech.com> | |
7 | * Tom Cubie <[email protected]> | |
8 | * | |
9 | * Some board init for the Allwinner A10-evb board. | |
10 | * | |
11 | * SPDX-License-Identifier: GPL-2.0+ | |
12 | */ | |
13 | ||
14 | #include <common.h> | |
e79c7c88 | 15 | #include <mmc.h> |
24289208 HG |
16 | #ifdef CONFIG_AXP152_POWER |
17 | #include <axp152.h> | |
18 | #endif | |
14bc66bd HN |
19 | #ifdef CONFIG_AXP209_POWER |
20 | #include <axp209.h> | |
21 | #endif | |
5c7f10fd OS |
22 | #ifdef CONFIG_AXP221_POWER |
23 | #include <axp221.h> | |
24 | #endif | |
cba69eee | 25 | #include <asm/arch/clock.h> |
b41d7d05 | 26 | #include <asm/arch/cpu.h> |
2d7a084b | 27 | #include <asm/arch/display.h> |
cba69eee | 28 | #include <asm/arch/dram.h> |
e24ea55c IC |
29 | #include <asm/arch/gpio.h> |
30 | #include <asm/arch/mmc.h> | |
1a800f7a | 31 | #include <asm/arch/usbc.h> |
b41d7d05 | 32 | #include <asm/io.h> |
1a800f7a | 33 | #include <linux/usb/musb.h> |
b41d7d05 | 34 | #include <net.h> |
cba69eee | 35 | |
55410089 HG |
36 | #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD) |
37 | /* So that we can use pin names in Kconfig and sunxi_name_to_gpio() */ | |
38 | int soft_i2c_gpio_sda; | |
39 | int soft_i2c_gpio_scl; | |
40 | #endif | |
41 | ||
cba69eee IC |
42 | DECLARE_GLOBAL_DATA_PTR; |
43 | ||
44 | /* add board specific code here */ | |
45 | int board_init(void) | |
46 | { | |
47 | int id_pfr1; | |
48 | ||
49 | gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100); | |
50 | ||
51 | asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1)); | |
52 | debug("id_pfr1: 0x%08x\n", id_pfr1); | |
53 | /* Generic Timer Extension available? */ | |
54 | if ((id_pfr1 >> 16) & 0xf) { | |
55 | debug("Setting CNTFRQ\n"); | |
56 | /* CNTFRQ == 24 MHz */ | |
57 | asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r"(24000000)); | |
58 | } | |
59 | ||
60 | return 0; | |
61 | } | |
62 | ||
63 | int dram_init(void) | |
64 | { | |
65 | gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); | |
66 | ||
67 | return 0; | |
68 | } | |
69 | ||
e24ea55c IC |
70 | #ifdef CONFIG_GENERIC_MMC |
71 | static void mmc_pinmux_setup(int sdc) | |
72 | { | |
73 | unsigned int pin; | |
74 | ||
75 | switch (sdc) { | |
76 | case 0: | |
77 | /* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-PF5 */ | |
78 | for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) { | |
79 | sunxi_gpio_set_cfgpin(pin, SUNXI_GPF0_SDC0); | |
80 | sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); | |
81 | sunxi_gpio_set_drv(pin, 2); | |
82 | } | |
83 | break; | |
84 | ||
85 | case 1: | |
bbff84b3 HG |
86 | /* CMD-PG3, CLK-PG4, D0~D3-PG5-8 */ |
87 | for (pin = SUNXI_GPG(3); pin <= SUNXI_GPG(8); pin++) { | |
88 | sunxi_gpio_set_cfgpin(pin, SUN5I_GPG3_SDC1); | |
e24ea55c IC |
89 | sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); |
90 | sunxi_gpio_set_drv(pin, 2); | |
91 | } | |
92 | break; | |
93 | ||
94 | case 2: | |
95 | /* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-PC11 */ | |
96 | for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) { | |
97 | sunxi_gpio_set_cfgpin(pin, SUNXI_GPC6_SDC2); | |
98 | sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); | |
99 | sunxi_gpio_set_drv(pin, 2); | |
100 | } | |
101 | break; | |
102 | ||
103 | case 3: | |
104 | /* CMD-PI4, CLK-PI5, D0~D3-PI6~9 : 2 */ | |
105 | for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) { | |
106 | sunxi_gpio_set_cfgpin(pin, SUN4I_GPI4_SDC3); | |
107 | sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); | |
108 | sunxi_gpio_set_drv(pin, 2); | |
109 | } | |
110 | break; | |
111 | ||
112 | default: | |
113 | printf("sunxi: invalid MMC slot %d for pinmux setup\n", sdc); | |
114 | break; | |
115 | } | |
116 | } | |
117 | ||
118 | int board_mmc_init(bd_t *bis) | |
119 | { | |
e79c7c88 HG |
120 | __maybe_unused struct mmc *mmc0, *mmc1; |
121 | __maybe_unused char buf[512]; | |
122 | ||
e24ea55c | 123 | mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT); |
e79c7c88 HG |
124 | mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT); |
125 | if (!mmc0) | |
126 | return -1; | |
127 | ||
2ccfac01 | 128 | #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1 |
e24ea55c | 129 | mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA); |
e79c7c88 HG |
130 | mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA); |
131 | if (!mmc1) | |
132 | return -1; | |
133 | #endif | |
134 | ||
135 | #if CONFIG_MMC_SUNXI_SLOT == 0 && CONFIG_MMC_SUNXI_SLOT_EXTRA == 2 | |
136 | /* | |
137 | * Both mmc0 and mmc2 are bootable, figure out where we're booting | |
138 | * from. Try mmc0 first, just like the brom does. | |
139 | */ | |
140 | if (mmc_getcd(mmc0) && mmc_init(mmc0) == 0 && | |
141 | mmc0->block_dev.block_read(0, 16, 1, buf) == 1) { | |
142 | buf[12] = 0; | |
143 | if (strcmp(&buf[4], "eGON.BT0") == 0) | |
144 | return 0; | |
145 | } | |
146 | ||
147 | /* no bootable card in mmc0, so we must be booting from mmc2, swap */ | |
148 | mmc0->block_dev.dev = 1; | |
149 | mmc1->block_dev.dev = 0; | |
e24ea55c IC |
150 | #endif |
151 | ||
152 | return 0; | |
153 | } | |
154 | #endif | |
155 | ||
6620377e HG |
156 | void i2c_init_board(void) |
157 | { | |
158 | sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUNXI_GPB0_TWI0); | |
159 | sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUNXI_GPB0_TWI0); | |
160 | clock_twi_onoff(0, 1); | |
55410089 HG |
161 | #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD) |
162 | soft_i2c_gpio_sda = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SDA); | |
163 | soft_i2c_gpio_scl = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SCL); | |
164 | #endif | |
6620377e HG |
165 | } |
166 | ||
cba69eee IC |
167 | #ifdef CONFIG_SPL_BUILD |
168 | void sunxi_board_init(void) | |
169 | { | |
14bc66bd | 170 | int power_failed = 0; |
cba69eee IC |
171 | unsigned long ramsize; |
172 | ||
24289208 HG |
173 | #ifdef CONFIG_AXP152_POWER |
174 | power_failed = axp152_init(); | |
175 | power_failed |= axp152_set_dcdc2(1400); | |
176 | power_failed |= axp152_set_dcdc3(1500); | |
177 | power_failed |= axp152_set_dcdc4(1250); | |
178 | power_failed |= axp152_set_ldo2(3000); | |
179 | #endif | |
14bc66bd HN |
180 | #ifdef CONFIG_AXP209_POWER |
181 | power_failed |= axp209_init(); | |
182 | power_failed |= axp209_set_dcdc2(1400); | |
183 | power_failed |= axp209_set_dcdc3(1250); | |
184 | power_failed |= axp209_set_ldo2(3000); | |
185 | power_failed |= axp209_set_ldo3(2800); | |
186 | power_failed |= axp209_set_ldo4(2800); | |
5c7f10fd OS |
187 | #endif |
188 | #ifdef CONFIG_AXP221_POWER | |
189 | power_failed = axp221_init(); | |
1262a85f | 190 | power_failed |= axp221_set_dcdc1(CONFIG_AXP221_DCDC1_VOLT); |
d3a96f7a HG |
191 | power_failed |= axp221_set_dcdc2(1200); /* A31:VDD-GPU, A23:VDD-SYS */ |
192 | power_failed |= axp221_set_dcdc3(1200); /* VDD-CPU */ | |
193 | #ifdef CONFIG_MACH_SUN6I | |
194 | power_failed |= axp221_set_dcdc4(1200); /* A31:VDD-SYS */ | |
195 | #else | |
196 | power_failed |= axp221_set_dcdc4(0); /* A23:unused */ | |
197 | #endif | |
198 | power_failed |= axp221_set_dcdc5(1500); /* VCC-DRAM */ | |
5c7f10fd | 199 | power_failed |= axp221_set_dldo1(CONFIG_AXP221_DLDO1_VOLT); |
5c7f10fd | 200 | power_failed |= axp221_set_dldo4(CONFIG_AXP221_DLDO4_VOLT); |
5c7f10fd | 201 | power_failed |= axp221_set_aldo1(CONFIG_AXP221_ALDO1_VOLT); |
5c7f10fd | 202 | power_failed |= axp221_set_aldo2(CONFIG_AXP221_ALDO2_VOLT); |
5c7f10fd | 203 | power_failed |= axp221_set_aldo3(CONFIG_AXP221_ALDO3_VOLT); |
6906df1a | 204 | power_failed |= axp221_set_eldo(3, CONFIG_AXP221_ELDO3_VOLT); |
14bc66bd HN |
205 | #endif |
206 | ||
cba69eee IC |
207 | printf("DRAM:"); |
208 | ramsize = sunxi_dram_init(); | |
209 | printf(" %lu MiB\n", ramsize >> 20); | |
210 | if (!ramsize) | |
211 | hang(); | |
14bc66bd HN |
212 | |
213 | /* | |
214 | * Only clock up the CPU to full speed if we are reasonably | |
215 | * assured it's being powered with suitable core voltage | |
216 | */ | |
217 | if (!power_failed) | |
e71b422b | 218 | clock_set_pll1(CONFIG_SYS_CLK_FREQ); |
14bc66bd HN |
219 | else |
220 | printf("Failed to set core voltage! Can't set CPU frequency\n"); | |
cba69eee IC |
221 | } |
222 | #endif | |
b41d7d05 | 223 | |
1a800f7a HG |
224 | #if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET) |
225 | static struct musb_hdrc_config musb_config = { | |
226 | .multipoint = 1, | |
227 | .dyn_fifo = 1, | |
228 | .num_eps = 6, | |
229 | .ram_bits = 11, | |
230 | }; | |
231 | ||
232 | static struct musb_hdrc_platform_data musb_plat = { | |
233 | #if defined(CONFIG_MUSB_HOST) | |
234 | .mode = MUSB_HOST, | |
235 | #else | |
236 | .mode = MUSB_PERIPHERAL, | |
237 | #endif | |
238 | .config = &musb_config, | |
239 | .power = 250, | |
240 | .platform_ops = &sunxi_musb_ops, | |
241 | }; | |
242 | #endif | |
243 | ||
b41d7d05 JL |
244 | #ifdef CONFIG_MISC_INIT_R |
245 | int misc_init_r(void) | |
246 | { | |
cac5b1cc | 247 | unsigned int sid[4]; |
b41d7d05 | 248 | |
cac5b1cc HG |
249 | if (!getenv("ethaddr") && sunxi_get_sid(sid) == 0 && |
250 | sid[0] != 0 && sid[3] != 0) { | |
251 | uint8_t mac_addr[6]; | |
b41d7d05 | 252 | |
cac5b1cc HG |
253 | mac_addr[0] = 0x02; /* Non OUI / registered MAC address */ |
254 | mac_addr[1] = (sid[0] >> 0) & 0xff; | |
255 | mac_addr[2] = (sid[3] >> 24) & 0xff; | |
256 | mac_addr[3] = (sid[3] >> 16) & 0xff; | |
257 | mac_addr[4] = (sid[3] >> 8) & 0xff; | |
258 | mac_addr[5] = (sid[3] >> 0) & 0xff; | |
b41d7d05 | 259 | |
cac5b1cc | 260 | eth_setenv_enetaddr("ethaddr", mac_addr); |
b41d7d05 JL |
261 | } |
262 | ||
1a800f7a HG |
263 | #if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET) |
264 | musb_register(&musb_plat, NULL, (void *)SUNXI_USB0_BASE); | |
265 | #endif | |
b41d7d05 JL |
266 | return 0; |
267 | } | |
268 | #endif | |
2d7a084b LV |
269 | |
270 | #ifdef CONFIG_OF_BOARD_SETUP | |
271 | int ft_board_setup(void *blob, bd_t *bd) | |
272 | { | |
273 | #ifdef CONFIG_VIDEO_DT_SIMPLEFB | |
274 | return sunxi_simplefb_setup(blob); | |
275 | #endif | |
276 | } | |
277 | #endif /* CONFIG_OF_BOARD_SETUP */ |