xref: /rk3399_rockchip-uboot/board/ti/beagle/beagle.c (revision f835ea7158025818d69384a7ebd8c3de0f10a9f7)
1 /*
2  * (C) Copyright 2004-2008
3  * Texas Instruments, <www.ti.com>
4  *
5  * Author :
6  *	Sunil Kumar <sunilsaini05@gmail.com>
7  *	Shashi Ranjan <shashiranjanmca05@gmail.com>
8  *
9  * Derived from Beagle Board and 3430 SDP code by
10  *	Richard Woodruff <r-woodruff2@ti.com>
11  *	Syed Mohammed Khasim <khasim@ti.com>
12  *
13  *
14  * See file CREDITS for list of people who contributed to this
15  * project.
16  *
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License as
19  * published by the Free Software Foundation; either version 2 of
20  * the License, or (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30  * MA 02111-1307 USA
31  */
32 #include <common.h>
33 #ifdef CONFIG_STATUS_LED
34 #include <status_led.h>
35 #endif
36 #include <twl4030.h>
37 #include <asm/io.h>
38 #include <asm/arch/mmc_host_def.h>
39 #include <asm/arch/mux.h>
40 #include <asm/arch/sys_proto.h>
41 #include <asm/arch/gpio.h>
42 #include <asm/mach-types.h>
43 #ifdef CONFIG_USB_EHCI
44 #include <usb.h>
45 #include <asm/arch/clocks.h>
46 #include <asm/arch/clocks_omap3.h>
47 #include <asm/arch/ehci_omap3.h>
48 /* from drivers/usb/host/ehci-core.h */
49 extern struct ehci_hccr *hccr;
50 extern volatile struct ehci_hcor *hcor;
51 #endif
52 #include "beagle.h"
53 #include <command.h>
54 
55 #define pr_debug(fmt, args...) debug(fmt, ##args)
56 
57 #define TWL4030_I2C_BUS			0
58 #define EXPANSION_EEPROM_I2C_BUS	1
59 #define EXPANSION_EEPROM_I2C_ADDRESS	0x50
60 
61 #define TINCANTOOLS_ZIPPY		0x01000100
62 #define TINCANTOOLS_ZIPPY2		0x02000100
63 #define TINCANTOOLS_TRAINER		0x04000100
64 #define TINCANTOOLS_SHOWDOG		0x03000100
65 #define KBADC_BEAGLEFPGA		0x01000600
66 #define LW_BEAGLETOUCH			0x01000700
67 #define BRAINMUX_LCDOG			0x01000800
68 #define BRAINMUX_LCDOGTOUCH		0x02000800
69 #define BBTOYS_WIFI			0x01000B00
70 #define BBTOYS_VGA			0x02000B00
71 #define BBTOYS_LCD			0x03000B00
72 #define BEAGLE_NO_EEPROM		0xffffffff
73 
74 DECLARE_GLOBAL_DATA_PTR;
75 
76 static struct {
77 	unsigned int device_vendor;
78 	unsigned char revision;
79 	unsigned char content;
80 	char fab_revision[8];
81 	char env_var[16];
82 	char env_setting[64];
83 } expansion_config;
84 
85 /*
86  * Routine: board_init
87  * Description: Early hardware init.
88  */
89 int board_init(void)
90 {
91 	gpmc_init(); /* in SRAM or SDRAM, finish GPMC */
92 	/* board id for Linux */
93 	gd->bd->bi_arch_number = MACH_TYPE_OMAP3_BEAGLE;
94 	/* boot param addr */
95 	gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100);
96 
97 #if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)
98 	status_led_set (STATUS_LED_BOOT, STATUS_LED_ON);
99 #endif
100 
101 	return 0;
102 }
103 
104 /*
105  * Routine: get_board_revision
106  * Description: Detect if we are running on a Beagle revision Ax/Bx,
107  *		C1/2/3, C4 or xM. This can be done by reading
108  *		the level of GPIO173, GPIO172 and GPIO171. This should
109  *		result in
110  *		GPIO173, GPIO172, GPIO171: 1 1 1 => Ax/Bx
111  *		GPIO173, GPIO172, GPIO171: 1 1 0 => C1/2/3
112  *		GPIO173, GPIO172, GPIO171: 1 0 1 => C4
113  *		GPIO173, GPIO172, GPIO171: 0 0 0 => xM
114  */
115 int get_board_revision(void)
116 {
117 	int revision;
118 
119 	if (!omap_request_gpio(171) &&
120 	    !omap_request_gpio(172) &&
121 	    !omap_request_gpio(173)) {
122 
123 		omap_set_gpio_direction(171, 1);
124 		omap_set_gpio_direction(172, 1);
125 		omap_set_gpio_direction(173, 1);
126 
127 		revision = omap_get_gpio_datain(173) << 2 |
128 			   omap_get_gpio_datain(172) << 1 |
129 			   omap_get_gpio_datain(171);
130 
131 		omap_free_gpio(171);
132 		omap_free_gpio(172);
133 		omap_free_gpio(173);
134 	} else {
135 		printf("Error: unable to acquire board revision GPIOs\n");
136 		revision = -1;
137 	}
138 
139 	return revision;
140 }
141 
142 /*
143  * Routine: get_expansion_id
144  * Description: This function checks for expansion board by checking I2C
145  *		bus 1 for the availability of an AT24C01B serial EEPROM.
146  *		returns the device_vendor field from the EEPROM
147  */
148 unsigned int get_expansion_id(void)
149 {
150 	i2c_set_bus_num(EXPANSION_EEPROM_I2C_BUS);
151 
152 	/* return BEAGLE_NO_EEPROM if eeprom doesn't respond */
153 	if (i2c_probe(EXPANSION_EEPROM_I2C_ADDRESS) == 1) {
154 		i2c_set_bus_num(TWL4030_I2C_BUS);
155 		return BEAGLE_NO_EEPROM;
156 	}
157 
158 	/* read configuration data */
159 	i2c_read(EXPANSION_EEPROM_I2C_ADDRESS, 0, 1, (u8 *)&expansion_config,
160 		 sizeof(expansion_config));
161 
162 	i2c_set_bus_num(TWL4030_I2C_BUS);
163 
164 	return expansion_config.device_vendor;
165 }
166 
167 /*
168  * Routine: misc_init_r
169  * Description: Configure board specific parts
170  */
171 int misc_init_r(void)
172 {
173 	struct gpio *gpio5_base = (struct gpio *)OMAP34XX_GPIO5_BASE;
174 	struct gpio *gpio6_base = (struct gpio *)OMAP34XX_GPIO6_BASE;
175 	struct control_prog_io *prog_io_base = (struct control_prog_io *)OMAP34XX_CTRL_BASE;
176 
177 	/* Enable i2c2 pullup resisters */
178 	writel(~(PRG_I2C2_PULLUPRESX), &prog_io_base->io1);
179 
180 	switch (get_board_revision()) {
181 	case REVISION_AXBX:
182 		printf("Beagle Rev Ax/Bx\n");
183 		setenv("beaglerev", "AxBx");
184 		break;
185 	case REVISION_CX:
186 		printf("Beagle Rev C1/C2/C3\n");
187 		setenv("beaglerev", "Cx");
188 		MUX_BEAGLE_C();
189 		break;
190 	case REVISION_C4:
191 		printf("Beagle Rev C4\n");
192 		setenv("beaglerev", "C4");
193 		MUX_BEAGLE_C();
194 		/* Set VAUX2 to 1.8V for EHCI PHY */
195 		twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED,
196 					TWL4030_PM_RECEIVER_VAUX2_VSEL_18,
197 					TWL4030_PM_RECEIVER_VAUX2_DEV_GRP,
198 					TWL4030_PM_RECEIVER_DEV_GRP_P1);
199 		break;
200 	case REVISION_XM_A:
201 		printf("Beagle xM Rev A\n");
202 		setenv("beaglerev", "xMA");
203 		MUX_BEAGLE_XM();
204 		/* Set VAUX2 to 1.8V for EHCI PHY */
205 		twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED,
206 					TWL4030_PM_RECEIVER_VAUX2_VSEL_18,
207 					TWL4030_PM_RECEIVER_VAUX2_DEV_GRP,
208 					TWL4030_PM_RECEIVER_DEV_GRP_P1);
209 		break;
210 	case REVISION_XM_B:
211 		printf("Beagle xM Rev B\n");
212 		setenv("beaglerev", "xMB");
213 		MUX_BEAGLE_XM();
214 		/* Set VAUX2 to 1.8V for EHCI PHY */
215 		twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED,
216 					TWL4030_PM_RECEIVER_VAUX2_VSEL_18,
217 					TWL4030_PM_RECEIVER_VAUX2_DEV_GRP,
218 					TWL4030_PM_RECEIVER_DEV_GRP_P1);
219 		break;
220 	case REVISION_XM_C:
221 		printf("Beagle xM Rev C\n");
222 		setenv("beaglerev", "xMC");
223 		MUX_BEAGLE_XM();
224 		/* Set VAUX2 to 1.8V for EHCI PHY */
225 		twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED,
226 					TWL4030_PM_RECEIVER_VAUX2_VSEL_18,
227 					TWL4030_PM_RECEIVER_VAUX2_DEV_GRP,
228 					TWL4030_PM_RECEIVER_DEV_GRP_P1);
229 		break;
230 	default:
231 		printf("Beagle unknown 0x%02x\n", get_board_revision());
232 		MUX_BEAGLE_XM();
233 		/* Set VAUX2 to 1.8V for EHCI PHY */
234 		twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED,
235 					TWL4030_PM_RECEIVER_VAUX2_VSEL_18,
236 					TWL4030_PM_RECEIVER_VAUX2_DEV_GRP,
237 					TWL4030_PM_RECEIVER_DEV_GRP_P1);
238 	}
239 
240 	switch (get_expansion_id()) {
241 	case TINCANTOOLS_ZIPPY:
242 		printf("Recognized Tincantools Zippy board (rev %d %s)\n",
243 			expansion_config.revision,
244 			expansion_config.fab_revision);
245 		MUX_TINCANTOOLS_ZIPPY();
246 		setenv("buddy", "zippy");
247 		break;
248 	case TINCANTOOLS_ZIPPY2:
249 		printf("Recognized Tincantools Zippy2 board (rev %d %s)\n",
250 			expansion_config.revision,
251 			expansion_config.fab_revision);
252 		MUX_TINCANTOOLS_ZIPPY();
253 		setenv("buddy", "zippy2");
254 		break;
255 	case TINCANTOOLS_TRAINER:
256 		printf("Recognized Tincantools Trainer board (rev %d %s)\n",
257 			expansion_config.revision,
258 			expansion_config.fab_revision);
259 		MUX_TINCANTOOLS_ZIPPY();
260 		MUX_TINCANTOOLS_TRAINER();
261 		setenv("buddy", "trainer");
262 		break;
263 	case TINCANTOOLS_SHOWDOG:
264 		printf("Recognized Tincantools Showdow board (rev %d %s)\n",
265 			expansion_config.revision,
266 			expansion_config.fab_revision);
267 		/* Place holder for DSS2 definition for showdog lcd */
268 		setenv("defaultdisplay", "showdoglcd");
269 		setenv("buddy", "showdog");
270 		break;
271 	case KBADC_BEAGLEFPGA:
272 		printf("Recognized KBADC Beagle FPGA board\n");
273 		MUX_KBADC_BEAGLEFPGA();
274 		setenv("buddy", "beaglefpga");
275 		break;
276 	case LW_BEAGLETOUCH:
277 		printf("Recognized Liquidware BeagleTouch board\n");
278 		setenv("buddy", "beagletouch");
279 		break;
280 	case BRAINMUX_LCDOG:
281 		printf("Recognized Brainmux LCDog board\n");
282 		setenv("buddy", "lcdog");
283 		break;
284 	case BRAINMUX_LCDOGTOUCH:
285 		printf("Recognized Brainmux LCDog Touch board\n");
286 		setenv("buddy", "lcdogtouch");
287 		break;
288 	case BBTOYS_WIFI:
289 		printf("Recognized BeagleBoardToys WiFi board\n");
290 		MUX_BBTOYS_WIFI()
291 		setenv("buddy", "bbtoys-wifi");
292 		break;;
293 	case BBTOYS_VGA:
294 		printf("Recognized BeagleBoardToys VGA board\n");
295 		break;;
296 	case BBTOYS_LCD:
297 		printf("Recognized BeagleBoardToys LCD board\n");
298 		break;;
299 	case BEAGLE_NO_EEPROM:
300 		printf("No EEPROM on expansion board\n");
301 		setenv("buddy", "none");
302 		break;
303 	default:
304 		printf("Unrecognized expansion board: %x\n",
305 			expansion_config.device_vendor);
306 		setenv("buddy", "unknown");
307 	}
308 
309 	if (expansion_config.content == 1)
310 		setenv(expansion_config.env_var, expansion_config.env_setting);
311 
312 	twl4030_power_init();
313 	twl4030_led_init(TWL4030_LED_LEDEN_LEDAON | TWL4030_LED_LEDEN_LEDBON);
314 
315 	/* Set GPIO states before they are made outputs */
316 	writel(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1,
317 		&gpio6_base->setdataout);
318 	writel(GPIO31 | GPIO30 | GPIO29 | GPIO28 | GPIO22 | GPIO21 |
319 		GPIO15 | GPIO14 | GPIO13 | GPIO12, &gpio5_base->setdataout);
320 
321 	/* Configure GPIOs to output */
322 	writel(~(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1), &gpio6_base->oe);
323 	writel(~(GPIO31 | GPIO30 | GPIO29 | GPIO28 | GPIO22 | GPIO21 |
324 		GPIO15 | GPIO14 | GPIO13 | GPIO12), &gpio5_base->oe);
325 
326 	dieid_num_r();
327 
328 	return 0;
329 }
330 
331 /*
332  * Routine: set_muxconf_regs
333  * Description: Setting up the configuration Mux registers specific to the
334  *		hardware. Many pins need to be moved from protect to primary
335  *		mode.
336  */
337 void set_muxconf_regs(void)
338 {
339 	MUX_BEAGLE();
340 }
341 
342 #ifdef CONFIG_GENERIC_MMC
343 int board_mmc_init(bd_t *bis)
344 {
345 	omap_mmc_init(0);
346 	return 0;
347 }
348 #endif
349 
350 #ifdef CONFIG_USB_EHCI
351 
352 #define GPIO_PHY_RESET 147
353 
354 /* Reset is needed otherwise the kernel-driver will throw an error. */
355 int ehci_hcd_stop(void)
356 {
357 	pr_debug("Resetting OMAP3 EHCI\n");
358 	omap_set_gpio_dataout(GPIO_PHY_RESET, 0);
359 	writel(OMAP_UHH_SYSCONFIG_SOFTRESET, OMAP3_UHH_BASE + OMAP_UHH_SYSCONFIG);
360 	/* disable USB clocks */
361 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
362 	sr32(&prcm_base->iclken_usbhost, 0, 1, 0);
363 	sr32(&prcm_base->fclken_usbhost, 0, 2, 0);
364 	sr32(&prcm_base->iclken3_core, 2, 1, 0);
365 	sr32(&prcm_base->fclken3_core, 2, 1, 0);
366 	return 0;
367 }
368 
369 /* Call usb_stop() before starting the kernel */
370 void show_boot_progress(int val)
371 {
372 	if(val == 15)
373 		usb_stop();
374 }
375 
376 /*
377  * Initialize the OMAP3 EHCI controller and PHY on the BeagleBoard.
378  * Based on "drivers/usb/host/ehci-omap.c" from Linux 2.6.37.
379  * See there for additional Copyrights.
380  */
381 int ehci_hcd_init(void)
382 {
383 	pr_debug("Initializing OMAP3 ECHI\n");
384 
385 	/* Put the PHY in RESET */
386 	omap_request_gpio(GPIO_PHY_RESET);
387 	omap_set_gpio_direction(GPIO_PHY_RESET, 0);
388 	omap_set_gpio_dataout(GPIO_PHY_RESET, 0);
389 
390 	/* Hold the PHY in RESET for enough time till DIR is high */
391 	/* Refer: ISSUE1 */
392 	udelay(10);
393 
394 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
395 	/* Enable USBHOST_L3_ICLK (USBHOST_MICLK) */
396 	sr32(&prcm_base->iclken_usbhost, 0, 1, 1);
397 	/*
398 	 * Enable USBHOST_48M_FCLK (USBHOST_FCLK1)
399 	 * and USBHOST_120M_FCLK (USBHOST_FCLK2)
400 	 */
401 	sr32(&prcm_base->fclken_usbhost, 0, 2, 3);
402 	/* Enable USBTTL_ICLK */
403 	sr32(&prcm_base->iclken3_core, 2, 1, 1);
404 	/* Enable USBTTL_FCLK */
405 	sr32(&prcm_base->fclken3_core, 2, 1, 1);
406 	pr_debug("USB clocks enabled\n");
407 
408 	/* perform TLL soft reset, and wait until reset is complete */
409 	writel(OMAP_USBTLL_SYSCONFIG_SOFTRESET,
410 		OMAP3_USBTLL_BASE + OMAP_USBTLL_SYSCONFIG);
411 	/* Wait for TLL reset to complete */
412 	while (!(readl(OMAP3_USBTLL_BASE + OMAP_USBTLL_SYSSTATUS)
413 			& OMAP_USBTLL_SYSSTATUS_RESETDONE));
414 	pr_debug("TLL reset done\n");
415 
416 	writel(OMAP_USBTLL_SYSCONFIG_ENAWAKEUP |
417 		OMAP_USBTLL_SYSCONFIG_SIDLEMODE |
418 		OMAP_USBTLL_SYSCONFIG_CACTIVITY,
419 		OMAP3_USBTLL_BASE + OMAP_USBTLL_SYSCONFIG);
420 
421 	/* Put UHH in NoIdle/NoStandby mode */
422 	writel(OMAP_UHH_SYSCONFIG_ENAWAKEUP
423 		| OMAP_UHH_SYSCONFIG_SIDLEMODE
424 		| OMAP_UHH_SYSCONFIG_CACTIVITY
425 		| OMAP_UHH_SYSCONFIG_MIDLEMODE,
426 		OMAP3_UHH_BASE + OMAP_UHH_SYSCONFIG);
427 
428 	/* setup burst configurations */
429 	writel(OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
430 		| OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN
431 		| OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN,
432 		OMAP3_UHH_BASE + OMAP_UHH_HOSTCONFIG);
433 
434 	/*
435 	 * Refer ISSUE1:
436 	 * Hold the PHY in RESET for enough time till
437 	 * PHY is settled and ready
438 	 */
439 	udelay(10);
440 	omap_set_gpio_dataout(GPIO_PHY_RESET, 1);
441 
442 	hccr = (struct ehci_hccr *)(OMAP3_EHCI_BASE);
443 	hcor = (struct ehci_hcor *)(OMAP3_EHCI_BASE + 0x10);
444 
445 	pr_debug("OMAP3 EHCI init done\n");
446 	return 0;
447 }
448 
449 #endif /* CONFIG_USB_EHCI */
450 
451 /*
452  * This command returns the status of the user button on beagle xM
453  * Input - none
454  * Returns - 	1 if button is held down
455  *		0 if button is not held down
456  */
457 int do_userbutton (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
458 {
459 	int     button = 0;
460 	int	gpio;
461 
462 	/*
463 	 * pass address parameter as argv[0] (aka command name),
464 	 * and all remaining args
465 	 */
466 	switch (get_board_revision()) {
467 	case REVISION_AXBX:
468 	case REVISION_CX:
469 	case REVISION_C4:
470 		gpio = 7;
471 		break;
472 	case REVISION_XM_A:
473 	case REVISION_XM_B:
474 	case REVISION_XM_C:
475 	default:
476 		gpio = 4;
477 		break;
478 	}
479 	omap_request_gpio(gpio);
480 	omap_set_gpio_direction(gpio, 1);
481 	printf("The user button is currently ");
482 	if(omap_get_gpio_datain(gpio))
483 	{
484 		button = 1;
485 		printf("PRESSED.\n");
486 	}
487 	else
488 	{
489 		button = 0;
490 		printf("NOT pressed.\n");
491 	}
492 
493 	omap_free_gpio(gpio);
494 
495 	return !button;
496 }
497 
498 /* -------------------------------------------------------------------- */
499 
500 U_BOOT_CMD(
501 	userbutton, CONFIG_SYS_MAXARGS, 1,	do_userbutton,
502 	"Return the status of the BeagleBoard USER button",
503 	""
504 );
505