186887f8eSPeter Barada /* 286887f8eSPeter Barada * (C) Copyright 2011 386887f8eSPeter Barada * Logic Product Development <www.logicpd.com> 486887f8eSPeter Barada * 586887f8eSPeter Barada * Author : 686887f8eSPeter Barada * Peter Barada <peter.barada@logicpd.com> 786887f8eSPeter Barada * 886887f8eSPeter Barada * Derived from Beagle Board and 3430 SDP code by 986887f8eSPeter Barada * Richard Woodruff <r-woodruff2@ti.com> 1086887f8eSPeter Barada * Syed Mohammed Khasim <khasim@ti.com> 1186887f8eSPeter Barada * 121a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 1386887f8eSPeter Barada */ 1486887f8eSPeter Barada #include <common.h> 157b77b1f6SAdam Ford #include <dm.h> 167b77b1f6SAdam Ford #include <ns16550.h> 1786887f8eSPeter Barada #include <netdev.h> 1886887f8eSPeter Barada #include <flash.h> 1986887f8eSPeter Barada #include <nand.h> 2086887f8eSPeter Barada #include <i2c.h> 2186887f8eSPeter Barada #include <twl4030.h> 2286887f8eSPeter Barada #include <asm/io.h> 2386887f8eSPeter Barada #include <asm/arch/mmc_host_def.h> 2486887f8eSPeter Barada #include <asm/arch/mux.h> 2586887f8eSPeter Barada #include <asm/arch/mem.h> 2686887f8eSPeter Barada #include <asm/arch/sys_proto.h> 2786887f8eSPeter Barada #include <asm/gpio.h> 2886887f8eSPeter Barada #include <asm/mach-types.h> 29*6ae3900aSMasahiro Yamada #include <linux/mtd/rawnand.h> 30588e41d2SAdam Ford #include <asm/omap_musb.h> 311221ce45SMasahiro Yamada #include <linux/errno.h> 32588e41d2SAdam Ford #include <linux/usb/ch9.h> 33588e41d2SAdam Ford #include <linux/usb/gadget.h> 34588e41d2SAdam Ford #include <linux/usb/musb.h> 3586887f8eSPeter Barada #include "omap3logic.h" 3674cd48e1SAdam Ford #ifdef CONFIG_USB_EHCI_HCD 3774cd48e1SAdam Ford #include <usb.h> 3874cd48e1SAdam Ford #include <asm/ehci-omap.h> 3974cd48e1SAdam Ford #endif 4086887f8eSPeter Barada 4186887f8eSPeter Barada DECLARE_GLOBAL_DATA_PTR; 4286887f8eSPeter Barada 4315fde737SAdam Ford /* This is only needed until SPL gets OF support */ 4415fde737SAdam Ford #ifdef CONFIG_SPL_BUILD 457b77b1f6SAdam Ford static const struct ns16550_platdata omap3logic_serial = { 462f6ed3b8SAdam Ford .base = OMAP34XX_UART1, 472f6ed3b8SAdam Ford .reg_shift = 2, 4817fa0326SHeiko Schocher .clock = V_NS16550_CLK, 4917fa0326SHeiko Schocher .fcr = UART_FCR_DEFVAL, 507b77b1f6SAdam Ford }; 517b77b1f6SAdam Ford 527b77b1f6SAdam Ford U_BOOT_DEVICE(omap3logic_uart) = { 53c7b9686dSThomas Chou "ns16550_serial", 547b77b1f6SAdam Ford &omap3logic_serial 557b77b1f6SAdam Ford }; 5615fde737SAdam Ford #endif 577b77b1f6SAdam Ford 5815fde737SAdam Ford /* 5915fde737SAdam Ford * two dimensional array of strucures containining board name and Linux 6015fde737SAdam Ford * machine IDs; row it selected based on CPU column is slected based 6115fde737SAdam Ford * on hsusb0_data5 pin having a pulldown resistor 6215fde737SAdam Ford */ 6386887f8eSPeter Barada static struct board_id { 6486887f8eSPeter Barada char *name; 6586887f8eSPeter Barada int machine_id; 66c63d270dSTom Rini char *fdtfile; 6786887f8eSPeter Barada } boards[2][2] = { 6886887f8eSPeter Barada { 6986887f8eSPeter Barada { 7086887f8eSPeter Barada .name = "OMAP35xx SOM LV", 7186887f8eSPeter Barada .machine_id = MACH_TYPE_OMAP3530_LV_SOM, 72c63d270dSTom Rini .fdtfile = "logicpd-som-lv-35xx-devkit.dtb", 7386887f8eSPeter Barada }, 7486887f8eSPeter Barada { 7586887f8eSPeter Barada .name = "OMAP35xx Torpedo", 7686887f8eSPeter Barada .machine_id = MACH_TYPE_OMAP3_TORPEDO, 77c63d270dSTom Rini .fdtfile = "logicpd-torpedo-35xx-devkit.dtb", 7886887f8eSPeter Barada }, 7986887f8eSPeter Barada }, 8086887f8eSPeter Barada { 8186887f8eSPeter Barada { 8286887f8eSPeter Barada .name = "DM37xx SOM LV", 83c63d270dSTom Rini .fdtfile = "logicpd-som-lv-37xx-devkit.dtb", 8486887f8eSPeter Barada }, 8586887f8eSPeter Barada { 8686887f8eSPeter Barada .name = "DM37xx Torpedo", 87c63d270dSTom Rini .fdtfile = "logicpd-torpedo-37xx-devkit.dtb", 8886887f8eSPeter Barada }, 8986887f8eSPeter Barada }, 9086887f8eSPeter Barada }; 9186887f8eSPeter Barada 9249c7303fSAdam Ford #ifdef CONFIG_SPL_OS_BOOT 9349c7303fSAdam Ford int spl_start_uboot(void) 9449c7303fSAdam Ford { 9549c7303fSAdam Ford /* break into full u-boot on 'c' */ 9649c7303fSAdam Ford return serial_tstc() && serial_getc() == 'c'; 9749c7303fSAdam Ford } 9849c7303fSAdam Ford #endif 9949c7303fSAdam Ford 10049c7303fSAdam Ford #if defined(CONFIG_SPL_BUILD) 10149c7303fSAdam Ford /* 10249c7303fSAdam Ford * Routine: get_board_mem_timings 10349c7303fSAdam Ford * Description: If we use SPL then there is no x-loader nor config header 10449c7303fSAdam Ford * so we have to setup the DDR timings ourself on the first bank. This 10549c7303fSAdam Ford * provides the timing values back to the function that configures 10649c7303fSAdam Ford * the memory. 10749c7303fSAdam Ford */ 10849c7303fSAdam Ford void get_board_mem_timings(struct board_sdrc_timings *timings) 10949c7303fSAdam Ford { 11049c7303fSAdam Ford timings->mr = MICRON_V_MR_165; 11149c7303fSAdam Ford /* 256MB DDR */ 11249c7303fSAdam Ford timings->mcfg = MICRON_V_MCFG_200(256 << 20); 11349c7303fSAdam Ford timings->ctrla = MICRON_V_ACTIMA_200; 11449c7303fSAdam Ford timings->ctrlb = MICRON_V_ACTIMB_200; 11549c7303fSAdam Ford timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz; 11649c7303fSAdam Ford } 11749c7303fSAdam Ford #endif 11849c7303fSAdam Ford 119588e41d2SAdam Ford #ifdef CONFIG_USB_MUSB_OMAP2PLUS 120588e41d2SAdam Ford static struct musb_hdrc_config musb_config = { 121588e41d2SAdam Ford .multipoint = 1, 122588e41d2SAdam Ford .dyn_fifo = 1, 123588e41d2SAdam Ford .num_eps = 16, 124588e41d2SAdam Ford .ram_bits = 12, 125588e41d2SAdam Ford }; 126588e41d2SAdam Ford 127588e41d2SAdam Ford static struct omap_musb_board_data musb_board_data = { 128588e41d2SAdam Ford .interface_type = MUSB_INTERFACE_ULPI, 129588e41d2SAdam Ford }; 130588e41d2SAdam Ford 131588e41d2SAdam Ford static struct musb_hdrc_platform_data musb_plat = { 132588e41d2SAdam Ford #if defined(CONFIG_USB_MUSB_HOST) 133588e41d2SAdam Ford .mode = MUSB_HOST, 134588e41d2SAdam Ford #elif defined(CONFIG_USB_MUSB_GADGET) 135588e41d2SAdam Ford .mode = MUSB_PERIPHERAL, 136588e41d2SAdam Ford #else 137588e41d2SAdam Ford #error "Please define either CONFIG_USB_MUSB_HOST or CONFIG_USB_MUSB_GADGET" 138588e41d2SAdam Ford #endif 139588e41d2SAdam Ford .config = &musb_config, 140588e41d2SAdam Ford .power = 100, 141588e41d2SAdam Ford .platform_ops = &omap2430_ops, 142588e41d2SAdam Ford .board_data = &musb_board_data, 143588e41d2SAdam Ford }; 144588e41d2SAdam Ford #endif 145588e41d2SAdam Ford 14674cd48e1SAdam Ford #if defined(CONFIG_USB_EHCI_HCD) && !defined(CONFIG_SPL_BUILD) 14774cd48e1SAdam Ford /* Call usb_stop() before starting the kernel */ 14874cd48e1SAdam Ford void show_boot_progress(int val) 14974cd48e1SAdam Ford { 15074cd48e1SAdam Ford if (val == BOOTSTAGE_ID_RUN_OS) 15174cd48e1SAdam Ford usb_stop(); 15274cd48e1SAdam Ford } 15374cd48e1SAdam Ford 15474cd48e1SAdam Ford static struct omap_usbhs_board_data usbhs_bdata = { 15574cd48e1SAdam Ford .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 15674cd48e1SAdam Ford .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 15774cd48e1SAdam Ford .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED 15874cd48e1SAdam Ford }; 15974cd48e1SAdam Ford 16074cd48e1SAdam Ford int ehci_hcd_init(int index, enum usb_init_type init, 16174cd48e1SAdam Ford struct ehci_hccr **hccr, struct ehci_hcor **hcor) 16274cd48e1SAdam Ford { 16374cd48e1SAdam Ford return omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor); 16474cd48e1SAdam Ford } 16574cd48e1SAdam Ford 16674cd48e1SAdam Ford int ehci_hcd_stop(int index) 16774cd48e1SAdam Ford { 16874cd48e1SAdam Ford return omap_ehci_hcd_stop(); 16974cd48e1SAdam Ford } 17074cd48e1SAdam Ford 17174cd48e1SAdam Ford #endif /* CONFIG_USB_EHCI_HCD */ 17274cd48e1SAdam Ford 173588e41d2SAdam Ford 17449c7303fSAdam Ford /* 17549c7303fSAdam Ford * Routine: misc_init_r 17649c7303fSAdam Ford * Description: Configure board specific parts 17749c7303fSAdam Ford */ 17849c7303fSAdam Ford int misc_init_r(void) 17949c7303fSAdam Ford { 18049c7303fSAdam Ford twl4030_power_init(); 18149c7303fSAdam Ford omap_die_id_display(); 18249c7303fSAdam Ford 183588e41d2SAdam Ford #ifdef CONFIG_USB_MUSB_OMAP2PLUS 184588e41d2SAdam Ford musb_register(&musb_plat, &musb_board_data, (void *)MUSB_BASE); 185588e41d2SAdam Ford #endif 186588e41d2SAdam Ford 18749c7303fSAdam Ford return 0; 18849c7303fSAdam Ford } 18949c7303fSAdam Ford 19086887f8eSPeter Barada /* 19186887f8eSPeter Barada * BOARD_ID_GPIO - GPIO of pin with optional pulldown resistor on SOM LV 19286887f8eSPeter Barada */ 19386887f8eSPeter Barada #define BOARD_ID_GPIO 189 /* hsusb0_data5 pin */ 19486887f8eSPeter Barada 19586887f8eSPeter Barada /* 19686887f8eSPeter Barada * Routine: board_init 19786887f8eSPeter Barada * Description: Early hardware init. 19886887f8eSPeter Barada */ 19986887f8eSPeter Barada int board_init(void) 20086887f8eSPeter Barada { 20186887f8eSPeter Barada gpmc_init(); /* in SRAM or SDRAM, finish GPMC */ 20286887f8eSPeter Barada 20386887f8eSPeter Barada /* boot param addr */ 20486887f8eSPeter Barada gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100); 20586887f8eSPeter Barada 206c63d270dSTom Rini return 0; 207c63d270dSTom Rini } 208c63d270dSTom Rini 209c63d270dSTom Rini #ifdef CONFIG_BOARD_LATE_INIT 210c63d270dSTom Rini int board_late_init(void) 211c63d270dSTom Rini { 212c63d270dSTom Rini struct board_id *board; 213c63d270dSTom Rini unsigned int val; 214c63d270dSTom Rini 21586887f8eSPeter Barada /* 21686887f8eSPeter Barada * To identify between a SOM LV and Torpedo module, 21786887f8eSPeter Barada * a pulldown resistor is on hsusb0_data5 for the SOM LV module. 21886887f8eSPeter Barada * Drive the pin (and let it soak), then read it back. 21986887f8eSPeter Barada * If the pin is still high its a Torpedo. If low its a SOM LV 22086887f8eSPeter Barada */ 22186887f8eSPeter Barada 22286887f8eSPeter Barada /* Mux hsusb0_data5 as a GPIO */ 22386887f8eSPeter Barada MUX_VAL(CP(HSUSB0_DATA5), (IEN | PTD | DIS | M4)); 22486887f8eSPeter Barada 22586887f8eSPeter Barada if (gpio_request(BOARD_ID_GPIO, "husb0_data5.gpio_189") == 0) { 22686887f8eSPeter Barada 22786887f8eSPeter Barada /* 22886887f8eSPeter Barada * Drive BOARD_ID_GPIO - the pulldown resistor on the SOM LV 22986887f8eSPeter Barada * will drain the voltage. 23086887f8eSPeter Barada */ 23186887f8eSPeter Barada gpio_direction_output(BOARD_ID_GPIO, 0); 23286887f8eSPeter Barada gpio_set_value(BOARD_ID_GPIO, 1); 23386887f8eSPeter Barada 23486887f8eSPeter Barada /* Let it soak for a bit */ 23586887f8eSPeter Barada sdelay(0x100); 23686887f8eSPeter Barada 23786887f8eSPeter Barada /* 23886887f8eSPeter Barada * Read state of BOARD_ID_GPIO as an input and if its set. 23986887f8eSPeter Barada * If so the board is a Torpedo 24086887f8eSPeter Barada */ 24186887f8eSPeter Barada gpio_direction_input(BOARD_ID_GPIO); 24286887f8eSPeter Barada val = gpio_get_value(BOARD_ID_GPIO); 24386887f8eSPeter Barada gpio_free(BOARD_ID_GPIO); 24486887f8eSPeter Barada 24586887f8eSPeter Barada board = &boards[!!(get_cpu_family() == CPU_OMAP36XX)][!!val]; 24686887f8eSPeter Barada printf("Board: %s\n", board->name); 24786887f8eSPeter Barada 24886887f8eSPeter Barada /* Set the machine_id passed to Linux */ 249c63d270dSTom Rini if (board->machine_id) 25086887f8eSPeter Barada gd->bd->bi_arch_number = board->machine_id; 251c63d270dSTom Rini 252c63d270dSTom Rini /* If the user has not set fdtimage, set the default */ 25300caae6dSSimon Glass if (!env_get("fdtimage")) 254382bee57SSimon Glass env_set("fdtimage", board->fdtfile); 25586887f8eSPeter Barada } 25686887f8eSPeter Barada 25786887f8eSPeter Barada /* restore hsusb0_data5 pin as hsusb0_data5 */ 25886887f8eSPeter Barada MUX_VAL(CP(HSUSB0_DATA5), (IEN | PTD | DIS | M0)); 25926ef7a27SAdam Ford return 0; 26026ef7a27SAdam Ford } 26126ef7a27SAdam Ford #endif 26226ef7a27SAdam Ford 2634aa2ba3aSMasahiro Yamada #if defined(CONFIG_MMC) 26486887f8eSPeter Barada int board_mmc_init(bd_t *bis) 26586887f8eSPeter Barada { 266e3913f56SNikita Kiryanov return omap_mmc_init(0, 0, 0, -1, -1); 26786887f8eSPeter Barada } 26886887f8eSPeter Barada #endif 26986887f8eSPeter Barada 2704aa2ba3aSMasahiro Yamada #if defined(CONFIG_MMC) 271aac5450eSPaul Kocialkowski void board_mmc_power_init(void) 272aac5450eSPaul Kocialkowski { 273aac5450eSPaul Kocialkowski twl4030_power_mmc_init(0); 274aac5450eSPaul Kocialkowski } 275aac5450eSPaul Kocialkowski #endif 276aac5450eSPaul Kocialkowski 27786887f8eSPeter Barada #ifdef CONFIG_SMC911X 27886887f8eSPeter Barada /* GPMC CS1 settings for Logic SOM LV/Torpedo LAN92xx Ethernet chip */ 27986887f8eSPeter Barada static const u32 gpmc_lan92xx_config[] = { 28086887f8eSPeter Barada NET_LAN92XX_GPMC_CONFIG1, 28186887f8eSPeter Barada NET_LAN92XX_GPMC_CONFIG2, 28286887f8eSPeter Barada NET_LAN92XX_GPMC_CONFIG3, 28386887f8eSPeter Barada NET_LAN92XX_GPMC_CONFIG4, 28486887f8eSPeter Barada NET_LAN92XX_GPMC_CONFIG5, 28586887f8eSPeter Barada NET_LAN92XX_GPMC_CONFIG6, 28686887f8eSPeter Barada }; 28786887f8eSPeter Barada 28886887f8eSPeter Barada int board_eth_init(bd_t *bis) 28986887f8eSPeter Barada { 29086887f8eSPeter Barada enable_gpmc_cs_config(gpmc_lan92xx_config, &gpmc_cfg->cs[1], 29186887f8eSPeter Barada CONFIG_SMC911X_BASE, GPMC_SIZE_16M); 29286887f8eSPeter Barada 29386887f8eSPeter Barada return smc911x_initialize(0, CONFIG_SMC911X_BASE); 29486887f8eSPeter Barada } 29586887f8eSPeter Barada #endif 29686887f8eSPeter Barada 29786887f8eSPeter Barada 298