1 /* 2 * (C) Copyright 2004-2011 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 * SPDX-License-Identifier: GPL-2.0+ 15 */ 16 #include <common.h> 17 #include <dm.h> 18 #include <ns16550.h> 19 #ifdef CONFIG_STATUS_LED 20 #include <status_led.h> 21 #endif 22 #include <twl4030.h> 23 #include <linux/mtd/nand.h> 24 #include <asm/io.h> 25 #include <asm/arch/mmc_host_def.h> 26 #include <asm/arch/mux.h> 27 #include <asm/arch/mem.h> 28 #include <asm/arch/sys_proto.h> 29 #include <asm/gpio.h> 30 #include <asm/mach-types.h> 31 #include <asm/omap_musb.h> 32 #include <asm/errno.h> 33 #include <linux/usb/ch9.h> 34 #include <linux/usb/gadget.h> 35 #include <linux/usb/musb.h> 36 #include "beagle.h" 37 #include <command.h> 38 39 #ifdef CONFIG_USB_EHCI 40 #include <usb.h> 41 #include <asm/ehci-omap.h> 42 #endif 43 44 #define TWL4030_I2C_BUS 0 45 #define EXPANSION_EEPROM_I2C_BUS 1 46 #define EXPANSION_EEPROM_I2C_ADDRESS 0x50 47 48 #define TINCANTOOLS_ZIPPY 0x01000100 49 #define TINCANTOOLS_ZIPPY2 0x02000100 50 #define TINCANTOOLS_TRAINER 0x04000100 51 #define TINCANTOOLS_SHOWDOG 0x03000100 52 #define KBADC_BEAGLEFPGA 0x01000600 53 #define LW_BEAGLETOUCH 0x01000700 54 #define BRAINMUX_LCDOG 0x01000800 55 #define BRAINMUX_LCDOGTOUCH 0x02000800 56 #define BBTOYS_WIFI 0x01000B00 57 #define BBTOYS_VGA 0x02000B00 58 #define BBTOYS_LCD 0x03000B00 59 #define BCT_BRETTL3 0x01000F00 60 #define BCT_BRETTL4 0x02000F00 61 #define LSR_COM6L_ADPT 0x01001300 62 #define BEAGLE_NO_EEPROM 0xffffffff 63 64 DECLARE_GLOBAL_DATA_PTR; 65 66 static struct { 67 unsigned int device_vendor; 68 unsigned char revision; 69 unsigned char content; 70 char fab_revision[8]; 71 char env_var[16]; 72 char env_setting[64]; 73 } expansion_config; 74 75 static const struct ns16550_platdata beagle_serial = { 76 .base = OMAP34XX_UART3, 77 .reg_shift = 2, 78 .clock = V_NS16550_CLK 79 }; 80 81 U_BOOT_DEVICE(beagle_uart) = { 82 "ns16550_serial", 83 &beagle_serial 84 }; 85 86 /* 87 * Routine: board_init 88 * Description: Early hardware init. 89 */ 90 int board_init(void) 91 { 92 gpmc_init(); /* in SRAM or SDRAM, finish GPMC */ 93 /* board id for Linux */ 94 gd->bd->bi_arch_number = MACH_TYPE_OMAP3_BEAGLE; 95 /* boot param addr */ 96 gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100); 97 98 #if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) 99 status_led_set (STATUS_LED_BOOT, STATUS_LED_ON); 100 #endif 101 102 return 0; 103 } 104 105 /* 106 * Routine: get_board_revision 107 * Description: Detect if we are running on a Beagle revision Ax/Bx, 108 * C1/2/3, C4, xM Ax/Bx or xM Cx. This can be done by reading 109 * the level of GPIO173, GPIO172 and GPIO171. This should 110 * result in 111 * GPIO173, GPIO172, GPIO171: 1 1 1 => Ax/Bx 112 * GPIO173, GPIO172, GPIO171: 1 1 0 => C1/2/3 113 * GPIO173, GPIO172, GPIO171: 1 0 1 => C4 114 * GPIO173, GPIO172, GPIO171: 0 1 0 => xM Cx 115 * GPIO173, GPIO172, GPIO171: 0 0 0 => xM Ax/Bx 116 */ 117 static int get_board_revision(void) 118 { 119 static int revision = -1; 120 121 if (revision == -1) { 122 if (!gpio_request(171, "rev0") && 123 !gpio_request(172, "rev1") && 124 !gpio_request(173, "rev2")) { 125 gpio_direction_input(171); 126 gpio_direction_input(172); 127 gpio_direction_input(173); 128 129 revision = gpio_get_value(173) << 2 | 130 gpio_get_value(172) << 1 | 131 gpio_get_value(171); 132 } else { 133 printf("Error: unable to acquire board revision GPIOs\n"); 134 } 135 } 136 137 return revision; 138 } 139 140 #ifdef CONFIG_SPL_BUILD 141 /* 142 * Routine: get_board_mem_timings 143 * Description: If we use SPL then there is no x-loader nor config header 144 * so we have to setup the DDR timings ourself on both banks. 145 */ 146 void get_board_mem_timings(struct board_sdrc_timings *timings) 147 { 148 int pop_mfr, pop_id; 149 150 /* 151 * We need to identify what PoP memory is on the board so that 152 * we know what timings to use. If we can't identify it then 153 * we know it's an xM. To map the ID values please see nand_ids.c 154 */ 155 identify_nand_chip(&pop_mfr, &pop_id); 156 157 timings->mr = MICRON_V_MR_165; 158 switch (get_board_revision()) { 159 case REVISION_C4: 160 if (pop_mfr == NAND_MFR_STMICRO && pop_id == 0xba) { 161 /* 512MB DDR */ 162 timings->mcfg = NUMONYX_V_MCFG_165(512 << 20); 163 timings->ctrla = NUMONYX_V_ACTIMA_165; 164 timings->ctrlb = NUMONYX_V_ACTIMB_165; 165 timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz; 166 break; 167 } else if (pop_mfr == NAND_MFR_MICRON && pop_id == 0xba) { 168 /* Beagleboard Rev C4, 512MB Nand/256MB DDR*/ 169 timings->mcfg = MICRON_V_MCFG_165(128 << 20); 170 timings->ctrla = MICRON_V_ACTIMA_165; 171 timings->ctrlb = MICRON_V_ACTIMB_165; 172 timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz; 173 break; 174 } else if (pop_mfr == NAND_MFR_MICRON && pop_id == 0xbc) { 175 /* Beagleboard Rev C5, 256MB DDR */ 176 timings->mcfg = MICRON_V_MCFG_200(256 << 20); 177 timings->ctrla = MICRON_V_ACTIMA_200; 178 timings->ctrlb = MICRON_V_ACTIMB_200; 179 timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz; 180 break; 181 } 182 case REVISION_XM_AB: 183 case REVISION_XM_C: 184 if (pop_mfr == 0) { 185 /* 256MB DDR */ 186 timings->mcfg = MICRON_V_MCFG_200(256 << 20); 187 timings->ctrla = MICRON_V_ACTIMA_200; 188 timings->ctrlb = MICRON_V_ACTIMB_200; 189 timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz; 190 } else { 191 /* 512MB DDR */ 192 timings->mcfg = NUMONYX_V_MCFG_165(512 << 20); 193 timings->ctrla = NUMONYX_V_ACTIMA_165; 194 timings->ctrlb = NUMONYX_V_ACTIMB_165; 195 timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz; 196 } 197 break; 198 default: 199 /* Assume 128MB and Micron/165MHz timings to be safe */ 200 timings->mcfg = MICRON_V_MCFG_165(128 << 20); 201 timings->ctrla = MICRON_V_ACTIMA_165; 202 timings->ctrlb = MICRON_V_ACTIMB_165; 203 timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz; 204 } 205 } 206 #endif 207 208 /* 209 * Routine: get_expansion_id 210 * Description: This function checks for expansion board by checking I2C 211 * bus 1 for the availability of an AT24C01B serial EEPROM. 212 * returns the device_vendor field from the EEPROM 213 */ 214 static unsigned int get_expansion_id(void) 215 { 216 i2c_set_bus_num(EXPANSION_EEPROM_I2C_BUS); 217 218 /* return BEAGLE_NO_EEPROM if eeprom doesn't respond */ 219 if (i2c_probe(EXPANSION_EEPROM_I2C_ADDRESS) == 1) { 220 i2c_set_bus_num(TWL4030_I2C_BUS); 221 return BEAGLE_NO_EEPROM; 222 } 223 224 /* read configuration data */ 225 i2c_read(EXPANSION_EEPROM_I2C_ADDRESS, 0, 1, (u8 *)&expansion_config, 226 sizeof(expansion_config)); 227 228 /* retry reading configuration data with 16bit addressing */ 229 if ((expansion_config.device_vendor == 0xFFFFFF00) || 230 (expansion_config.device_vendor == 0xFFFFFFFF)) { 231 printf("EEPROM is blank or 8bit addressing failed: retrying with 16bit:\n"); 232 i2c_read(EXPANSION_EEPROM_I2C_ADDRESS, 0, 2, (u8 *)&expansion_config, 233 sizeof(expansion_config)); 234 } 235 236 i2c_set_bus_num(TWL4030_I2C_BUS); 237 238 return expansion_config.device_vendor; 239 } 240 241 #ifdef CONFIG_VIDEO_OMAP3 242 /* 243 * Configure DSS to display background color on DVID 244 * Configure VENC to display color bar on S-Video 245 */ 246 static void beagle_display_init(void) 247 { 248 omap3_dss_venc_config(&venc_config_std_tv, VENC_HEIGHT, VENC_WIDTH); 249 switch (get_board_revision()) { 250 case REVISION_AXBX: 251 case REVISION_CX: 252 case REVISION_C4: 253 omap3_dss_panel_config(&dvid_cfg); 254 break; 255 case REVISION_XM_AB: 256 case REVISION_XM_C: 257 default: 258 omap3_dss_panel_config(&dvid_cfg_xm); 259 break; 260 } 261 } 262 263 /* 264 * Enable DVI power 265 */ 266 static void beagle_dvi_pup(void) 267 { 268 uchar val; 269 270 switch (get_board_revision()) { 271 case REVISION_AXBX: 272 case REVISION_CX: 273 case REVISION_C4: 274 gpio_request(170, "dvi"); 275 gpio_direction_output(170, 0); 276 gpio_set_value(170, 1); 277 break; 278 case REVISION_XM_AB: 279 case REVISION_XM_C: 280 default: 281 #define GPIODATADIR1 (TWL4030_BASEADD_GPIO+3) 282 #define GPIODATAOUT1 (TWL4030_BASEADD_GPIO+6) 283 284 i2c_read(TWL4030_CHIP_GPIO, GPIODATADIR1, 1, &val, 1); 285 val |= 4; 286 i2c_write(TWL4030_CHIP_GPIO, GPIODATADIR1, 1, &val, 1); 287 288 i2c_read(TWL4030_CHIP_GPIO, GPIODATAOUT1, 1, &val, 1); 289 val |= 4; 290 i2c_write(TWL4030_CHIP_GPIO, GPIODATAOUT1, 1, &val, 1); 291 break; 292 } 293 } 294 #endif 295 296 #ifdef CONFIG_USB_MUSB_OMAP2PLUS 297 static struct musb_hdrc_config musb_config = { 298 .multipoint = 1, 299 .dyn_fifo = 1, 300 .num_eps = 16, 301 .ram_bits = 12, 302 }; 303 304 static struct omap_musb_board_data musb_board_data = { 305 .interface_type = MUSB_INTERFACE_ULPI, 306 }; 307 308 static struct musb_hdrc_platform_data musb_plat = { 309 #if defined(CONFIG_USB_MUSB_HOST) 310 .mode = MUSB_HOST, 311 #elif defined(CONFIG_USB_MUSB_GADGET) 312 .mode = MUSB_PERIPHERAL, 313 #else 314 #error "Please define either CONFIG_USB_MUSB_HOST or CONFIG_USB_MUSB_GADGET" 315 #endif 316 .config = &musb_config, 317 .power = 100, 318 .platform_ops = &omap2430_ops, 319 .board_data = &musb_board_data, 320 }; 321 #endif 322 323 /* 324 * Routine: misc_init_r 325 * Description: Configure board specific parts 326 */ 327 int misc_init_r(void) 328 { 329 struct gpio *gpio5_base = (struct gpio *)OMAP34XX_GPIO5_BASE; 330 struct gpio *gpio6_base = (struct gpio *)OMAP34XX_GPIO6_BASE; 331 struct control_prog_io *prog_io_base = (struct control_prog_io *)OMAP34XX_CTRL_BASE; 332 bool generate_fake_mac = false; 333 u32 value; 334 335 /* Enable i2c2 pullup resisters */ 336 value = readl(&prog_io_base->io1); 337 value &= ~(PRG_I2C2_PULLUPRESX); 338 writel(value, &prog_io_base->io1); 339 340 switch (get_board_revision()) { 341 case REVISION_AXBX: 342 printf("Beagle Rev Ax/Bx\n"); 343 setenv("beaglerev", "AxBx"); 344 break; 345 case REVISION_CX: 346 printf("Beagle Rev C1/C2/C3\n"); 347 setenv("beaglerev", "Cx"); 348 MUX_BEAGLE_C(); 349 break; 350 case REVISION_C4: 351 printf("Beagle Rev C4\n"); 352 setenv("beaglerev", "C4"); 353 MUX_BEAGLE_C(); 354 /* Set VAUX2 to 1.8V for EHCI PHY */ 355 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED, 356 TWL4030_PM_RECEIVER_VAUX2_VSEL_18, 357 TWL4030_PM_RECEIVER_VAUX2_DEV_GRP, 358 TWL4030_PM_RECEIVER_DEV_GRP_P1); 359 break; 360 case REVISION_XM_AB: 361 printf("Beagle xM Rev A/B\n"); 362 setenv("beaglerev", "xMAB"); 363 MUX_BEAGLE_XM(); 364 /* Set VAUX2 to 1.8V for EHCI PHY */ 365 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED, 366 TWL4030_PM_RECEIVER_VAUX2_VSEL_18, 367 TWL4030_PM_RECEIVER_VAUX2_DEV_GRP, 368 TWL4030_PM_RECEIVER_DEV_GRP_P1); 369 generate_fake_mac = true; 370 break; 371 case REVISION_XM_C: 372 printf("Beagle xM Rev C\n"); 373 setenv("beaglerev", "xMC"); 374 MUX_BEAGLE_XM(); 375 /* Set VAUX2 to 1.8V for EHCI PHY */ 376 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED, 377 TWL4030_PM_RECEIVER_VAUX2_VSEL_18, 378 TWL4030_PM_RECEIVER_VAUX2_DEV_GRP, 379 TWL4030_PM_RECEIVER_DEV_GRP_P1); 380 generate_fake_mac = true; 381 break; 382 default: 383 printf("Beagle unknown 0x%02x\n", get_board_revision()); 384 MUX_BEAGLE_XM(); 385 /* Set VAUX2 to 1.8V for EHCI PHY */ 386 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED, 387 TWL4030_PM_RECEIVER_VAUX2_VSEL_18, 388 TWL4030_PM_RECEIVER_VAUX2_DEV_GRP, 389 TWL4030_PM_RECEIVER_DEV_GRP_P1); 390 generate_fake_mac = true; 391 } 392 393 switch (get_expansion_id()) { 394 case TINCANTOOLS_ZIPPY: 395 printf("Recognized Tincantools Zippy board (rev %d %s)\n", 396 expansion_config.revision, 397 expansion_config.fab_revision); 398 MUX_TINCANTOOLS_ZIPPY(); 399 setenv("buddy", "zippy"); 400 break; 401 case TINCANTOOLS_ZIPPY2: 402 printf("Recognized Tincantools Zippy2 board (rev %d %s)\n", 403 expansion_config.revision, 404 expansion_config.fab_revision); 405 MUX_TINCANTOOLS_ZIPPY(); 406 setenv("buddy", "zippy2"); 407 break; 408 case TINCANTOOLS_TRAINER: 409 printf("Recognized Tincantools Trainer board (rev %d %s)\n", 410 expansion_config.revision, 411 expansion_config.fab_revision); 412 MUX_TINCANTOOLS_ZIPPY(); 413 MUX_TINCANTOOLS_TRAINER(); 414 setenv("buddy", "trainer"); 415 break; 416 case TINCANTOOLS_SHOWDOG: 417 printf("Recognized Tincantools Showdow board (rev %d %s)\n", 418 expansion_config.revision, 419 expansion_config.fab_revision); 420 /* Place holder for DSS2 definition for showdog lcd */ 421 setenv("defaultdisplay", "showdoglcd"); 422 setenv("buddy", "showdog"); 423 break; 424 case KBADC_BEAGLEFPGA: 425 printf("Recognized KBADC Beagle FPGA board\n"); 426 MUX_KBADC_BEAGLEFPGA(); 427 setenv("buddy", "beaglefpga"); 428 break; 429 case LW_BEAGLETOUCH: 430 printf("Recognized Liquidware BeagleTouch board\n"); 431 setenv("buddy", "beagletouch"); 432 break; 433 case BRAINMUX_LCDOG: 434 printf("Recognized Brainmux LCDog board\n"); 435 setenv("buddy", "lcdog"); 436 break; 437 case BRAINMUX_LCDOGTOUCH: 438 printf("Recognized Brainmux LCDog Touch board\n"); 439 setenv("buddy", "lcdogtouch"); 440 break; 441 case BBTOYS_WIFI: 442 printf("Recognized BeagleBoardToys WiFi board\n"); 443 MUX_BBTOYS_WIFI() 444 setenv("buddy", "bbtoys-wifi"); 445 break;; 446 case BBTOYS_VGA: 447 printf("Recognized BeagleBoardToys VGA board\n"); 448 break;; 449 case BBTOYS_LCD: 450 printf("Recognized BeagleBoardToys LCD board\n"); 451 break;; 452 case BCT_BRETTL3: 453 printf("Recognized bct electronic GmbH brettl3 board\n"); 454 break; 455 case BCT_BRETTL4: 456 printf("Recognized bct electronic GmbH brettl4 board\n"); 457 break; 458 case LSR_COM6L_ADPT: 459 printf("Recognized LSR COM6L Adapter Board\n"); 460 MUX_BBTOYS_WIFI() 461 setenv("buddy", "lsr-com6l-adpt"); 462 break; 463 case BEAGLE_NO_EEPROM: 464 printf("No EEPROM on expansion board\n"); 465 setenv("buddy", "none"); 466 break; 467 default: 468 printf("Unrecognized expansion board: %x\n", 469 expansion_config.device_vendor); 470 setenv("buddy", "unknown"); 471 } 472 473 if (expansion_config.content == 1) 474 setenv(expansion_config.env_var, expansion_config.env_setting); 475 476 twl4030_power_init(); 477 switch (get_board_revision()) { 478 case REVISION_XM_AB: 479 twl4030_led_init(TWL4030_LED_LEDEN_LEDBON); 480 break; 481 default: 482 twl4030_led_init(TWL4030_LED_LEDEN_LEDAON | TWL4030_LED_LEDEN_LEDBON); 483 break; 484 } 485 486 /* Set GPIO states before they are made outputs */ 487 writel(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1, 488 &gpio6_base->setdataout); 489 writel(GPIO31 | GPIO30 | GPIO29 | GPIO28 | GPIO22 | GPIO21 | 490 GPIO15 | GPIO14 | GPIO13 | GPIO12, &gpio5_base->setdataout); 491 492 /* Configure GPIOs to output */ 493 writel(~(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1), &gpio6_base->oe); 494 writel(~(GPIO31 | GPIO30 | GPIO29 | GPIO28 | GPIO22 | GPIO21 | 495 GPIO15 | GPIO14 | GPIO13 | GPIO12), &gpio5_base->oe); 496 497 omap_die_id_display(); 498 499 #ifdef CONFIG_VIDEO_OMAP3 500 beagle_dvi_pup(); 501 beagle_display_init(); 502 omap3_dss_enable(); 503 #endif 504 505 #ifdef CONFIG_USB_MUSB_OMAP2PLUS 506 musb_register(&musb_plat, &musb_board_data, (void *)MUSB_BASE); 507 #endif 508 509 if (generate_fake_mac) 510 omap_die_id_usbethaddr(); 511 512 return 0; 513 } 514 515 /* 516 * Routine: set_muxconf_regs 517 * Description: Setting up the configuration Mux registers specific to the 518 * hardware. Many pins need to be moved from protect to primary 519 * mode. 520 */ 521 void set_muxconf_regs(void) 522 { 523 MUX_BEAGLE(); 524 } 525 526 #if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD) 527 int board_mmc_init(bd_t *bis) 528 { 529 return omap_mmc_init(0, 0, 0, -1, -1); 530 } 531 #endif 532 533 #if defined(CONFIG_GENERIC_MMC) 534 void board_mmc_power_init(void) 535 { 536 twl4030_power_mmc_init(0); 537 } 538 #endif 539 540 #if defined(CONFIG_USB_EHCI) && !defined(CONFIG_SPL_BUILD) 541 /* Call usb_stop() before starting the kernel */ 542 void show_boot_progress(int val) 543 { 544 if (val == BOOTSTAGE_ID_RUN_OS) 545 usb_stop(); 546 } 547 548 static struct omap_usbhs_board_data usbhs_bdata = { 549 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 550 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 551 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED 552 }; 553 554 int ehci_hcd_init(int index, enum usb_init_type init, 555 struct ehci_hccr **hccr, struct ehci_hcor **hcor) 556 { 557 return omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor); 558 } 559 560 int ehci_hcd_stop(int index) 561 { 562 return omap_ehci_hcd_stop(); 563 } 564 565 #endif /* CONFIG_USB_EHCI */ 566 567 #if defined(CONFIG_USB_ETHER) && defined(CONFIG_USB_MUSB_GADGET) 568 int board_eth_init(bd_t *bis) 569 { 570 return usb_eth_initialize(bis); 571 } 572 #endif 573