1c57cca25SSteve Sakoman /* 2c57cca25SSteve Sakoman * (C) Copyright 2010 3c57cca25SSteve Sakoman * Texas Instruments Incorporated, <www.ti.com> 4c57cca25SSteve Sakoman * Steve Sakoman <steve@sakoman.com> 5c57cca25SSteve Sakoman * 61a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 7c57cca25SSteve Sakoman */ 8c57cca25SSteve Sakoman #include <common.h> 9c57cca25SSteve Sakoman #include <asm/arch/sys_proto.h> 107e982c95SSukumar Ghorai #include <asm/arch/mmc_host_def.h> 11af1d002fSLokesh Vutla #include <asm/arch/clock.h> 12df65a3feSChris Lalancette #include <asm/arch/gpio.h> 1343b62393SGovindraj.R #include <asm/gpio.h> 14c57cca25SSteve Sakoman 15469ec1e3SAneesh V #include "panda_mux_data.h" 162ad853c3SSteve Sakoman 1743b62393SGovindraj.R #ifdef CONFIG_USB_EHCI 1843b62393SGovindraj.R #include <usb.h> 1943b62393SGovindraj.R #include <asm/arch/ehci.h> 2043b62393SGovindraj.R #include <asm/ehci-omap.h> 2143b62393SGovindraj.R #endif 2243b62393SGovindraj.R 23df65a3feSChris Lalancette #define PANDA_ULPI_PHY_TYPE_GPIO 182 247d47d1caSDan Murphy #define PANDA_BOARD_ID_1_GPIO 101 257d47d1caSDan Murphy #define PANDA_ES_BOARD_ID_1_GPIO 48 267d47d1caSDan Murphy #define PANDA_BOARD_ID_2_GPIO 171 277d47d1caSDan Murphy #define PANDA_ES_BOARD_ID_3_GPIO 3 287d47d1caSDan Murphy #define PANDA_ES_BOARD_ID_4_GPIO 2 29df65a3feSChris Lalancette 30c57cca25SSteve Sakoman DECLARE_GLOBAL_DATA_PTR; 31c57cca25SSteve Sakoman 32c57cca25SSteve Sakoman const struct omap_sysinfo sysinfo = { 33c57cca25SSteve Sakoman "Board: OMAP4 Panda\n" 34c57cca25SSteve Sakoman }; 35c57cca25SSteve Sakoman 36df65a3feSChris Lalancette struct omap4_scrm_regs *const scrm = (struct omap4_scrm_regs *)0x4a30a000; 37df65a3feSChris Lalancette 38c57cca25SSteve Sakoman /** 39c57cca25SSteve Sakoman * @brief board_init 40c57cca25SSteve Sakoman * 41c57cca25SSteve Sakoman * @return 0 42c57cca25SSteve Sakoman */ 43c57cca25SSteve Sakoman int board_init(void) 44c57cca25SSteve Sakoman { 4527952014SSteve Sakoman gpmc_init(); 4627952014SSteve Sakoman 47c57cca25SSteve Sakoman gd->bd->bi_arch_number = MACH_TYPE_OMAP4_PANDA; 48c57cca25SSteve Sakoman gd->bd->bi_boot_params = (0x80000000 + 0x100); /* boot param addr */ 49c57cca25SSteve Sakoman 50c57cca25SSteve Sakoman return 0; 51c57cca25SSteve Sakoman } 52c57cca25SSteve Sakoman 53c57cca25SSteve Sakoman int board_eth_init(bd_t *bis) 54c57cca25SSteve Sakoman { 55c57cca25SSteve Sakoman return 0; 56c57cca25SSteve Sakoman } 57c57cca25SSteve Sakoman 587d47d1caSDan Murphy /* 597d47d1caSDan Murphy * Routine: get_board_revision 607d47d1caSDan Murphy * Description: Detect if we are running on a panda revision A1-A6, 617d47d1caSDan Murphy * or an ES panda board. This can be done by reading 627d47d1caSDan Murphy * the level of GPIOs and checking the processor revisions. 637d47d1caSDan Murphy * This should result in: 647d47d1caSDan Murphy * Panda 4430: 657d47d1caSDan Murphy * GPIO171, GPIO101, GPIO182: 0 1 1 => A1-A5 667d47d1caSDan Murphy * GPIO171, GPIO101, GPIO182: 1 0 1 => A6 677d47d1caSDan Murphy * Panda ES: 687d47d1caSDan Murphy * GPIO2, GPIO3, GPIO171, GPIO48, GPIO182: 0 0 0 1 1 => B1/B2 697d47d1caSDan Murphy * GPIO2, GPIO3, GPIO171, GPIO48, GPIO182: 0 0 1 1 1 => B3 707d47d1caSDan Murphy */ 717d47d1caSDan Murphy int get_board_revision(void) 727d47d1caSDan Murphy { 737d47d1caSDan Murphy int board_id0, board_id1, board_id2; 747d47d1caSDan Murphy int board_id3, board_id4; 757d47d1caSDan Murphy int board_id; 767d47d1caSDan Murphy 777d47d1caSDan Murphy int processor_rev = omap_revision(); 787d47d1caSDan Murphy 797d47d1caSDan Murphy /* Setup the mux for the common board ID pins (gpio 171 and 182) */ 807d47d1caSDan Murphy writew((IEN | M3), (*ctrl)->control_padconf_core_base + UNIPRO_TX0); 817d47d1caSDan Murphy writew((IEN | M3), (*ctrl)->control_padconf_core_base + FREF_CLK2_OUT); 827d47d1caSDan Murphy 837d47d1caSDan Murphy board_id0 = gpio_get_value(PANDA_ULPI_PHY_TYPE_GPIO); 847d47d1caSDan Murphy board_id2 = gpio_get_value(PANDA_BOARD_ID_2_GPIO); 857d47d1caSDan Murphy 867d47d1caSDan Murphy if ((processor_rev >= OMAP4460_ES1_0 && 877d47d1caSDan Murphy processor_rev <= OMAP4460_ES1_1)) { 887d47d1caSDan Murphy /* 897d47d1caSDan Murphy * Setup the mux for the ES specific board ID pins (gpio 101, 907d47d1caSDan Murphy * 2 and 3. 917d47d1caSDan Murphy */ 927d47d1caSDan Murphy writew((IEN | M3), (*ctrl)->control_padconf_core_base + 937d47d1caSDan Murphy GPMC_A24); 947d47d1caSDan Murphy writew((IEN | M3), (*ctrl)->control_padconf_core_base + 957d47d1caSDan Murphy UNIPRO_RY0); 967d47d1caSDan Murphy writew((IEN | M3), (*ctrl)->control_padconf_core_base + 977d47d1caSDan Murphy UNIPRO_RX1); 987d47d1caSDan Murphy 997d47d1caSDan Murphy board_id1 = gpio_get_value(PANDA_ES_BOARD_ID_1_GPIO); 1007d47d1caSDan Murphy board_id3 = gpio_get_value(PANDA_ES_BOARD_ID_3_GPIO); 1017d47d1caSDan Murphy board_id4 = gpio_get_value(PANDA_ES_BOARD_ID_4_GPIO); 1027d47d1caSDan Murphy 1037d47d1caSDan Murphy #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 1047d47d1caSDan Murphy setenv("board_name", strcat(CONFIG_SYS_BOARD, "-es")); 1057d47d1caSDan Murphy #endif 1067d47d1caSDan Murphy board_id = ((board_id4 << 4) | (board_id3 << 3) | 1077d47d1caSDan Murphy (board_id2 << 2) | (board_id1 << 1) | (board_id0)); 1087d47d1caSDan Murphy } else { 1097d47d1caSDan Murphy /* Setup the mux for the Ax specific board ID pins (gpio 101) */ 1107d47d1caSDan Murphy writew((IEN | M3), (*ctrl)->control_padconf_core_base + 1117d47d1caSDan Murphy FREF_CLK2_OUT); 1127d47d1caSDan Murphy 1137d47d1caSDan Murphy board_id1 = gpio_get_value(PANDA_BOARD_ID_1_GPIO); 1147d47d1caSDan Murphy board_id = ((board_id2 << 2) | (board_id1 << 1) | (board_id0)); 1157d47d1caSDan Murphy 1167d47d1caSDan Murphy #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 1177d47d1caSDan Murphy if ((board_id >= 0x3) && (processor_rev == OMAP4430_ES2_3)) 1187d47d1caSDan Murphy setenv("board_name", strcat(CONFIG_SYS_BOARD, "-a4")); 1197d47d1caSDan Murphy #endif 1207d47d1caSDan Murphy } 1217d47d1caSDan Murphy 1227d47d1caSDan Murphy return board_id; 1237d47d1caSDan Murphy } 1247d47d1caSDan Murphy 125c57cca25SSteve Sakoman /** 126c57cca25SSteve Sakoman * @brief misc_init_r - Configure Panda board specific configurations 127c57cca25SSteve Sakoman * such as power configurations, ethernet initialization as phase2 of 128c57cca25SSteve Sakoman * boot sequence 129c57cca25SSteve Sakoman * 130c57cca25SSteve Sakoman * @return 0 131c57cca25SSteve Sakoman */ 132c57cca25SSteve Sakoman int misc_init_r(void) 133c57cca25SSteve Sakoman { 134df65a3feSChris Lalancette int phy_type; 135df65a3feSChris Lalancette u32 auxclk, altclksrc; 136e84b8f6cSDan Murphy uint8_t device_mac[6]; 137df65a3feSChris Lalancette 138df65a3feSChris Lalancette /* EHCI is not supported on ES1.0 */ 139df65a3feSChris Lalancette if (omap_revision() == OMAP4430_ES1_0) 140df65a3feSChris Lalancette return 0; 141df65a3feSChris Lalancette 1427d47d1caSDan Murphy get_board_revision(); 14334f667bbSDan Murphy 144df65a3feSChris Lalancette gpio_direction_input(PANDA_ULPI_PHY_TYPE_GPIO); 145df65a3feSChris Lalancette phy_type = gpio_get_value(PANDA_ULPI_PHY_TYPE_GPIO); 146df65a3feSChris Lalancette 147df65a3feSChris Lalancette if (phy_type == 1) { 148df65a3feSChris Lalancette /* ULPI PHY supplied by auxclk3 derived from sys_clk */ 149df65a3feSChris Lalancette debug("ULPI PHY supplied by auxclk3\n"); 150df65a3feSChris Lalancette 151df65a3feSChris Lalancette auxclk = readl(&scrm->auxclk3); 152df65a3feSChris Lalancette /* Select sys_clk */ 153df65a3feSChris Lalancette auxclk &= ~AUXCLK_SRCSELECT_MASK; 154df65a3feSChris Lalancette auxclk |= AUXCLK_SRCSELECT_SYS_CLK << AUXCLK_SRCSELECT_SHIFT; 155df65a3feSChris Lalancette /* Set the divisor to 2 */ 156df65a3feSChris Lalancette auxclk &= ~AUXCLK_CLKDIV_MASK; 157df65a3feSChris Lalancette auxclk |= AUXCLK_CLKDIV_2 << AUXCLK_CLKDIV_SHIFT; 158df65a3feSChris Lalancette /* Request auxilary clock #3 */ 159df65a3feSChris Lalancette auxclk |= AUXCLK_ENABLE_MASK; 160df65a3feSChris Lalancette 161df65a3feSChris Lalancette writel(auxclk, &scrm->auxclk3); 162df65a3feSChris Lalancette } else { 163df65a3feSChris Lalancette /* ULPI PHY supplied by auxclk1 derived from PER dpll */ 164df65a3feSChris Lalancette debug("ULPI PHY supplied by auxclk1\n"); 165df65a3feSChris Lalancette 166df65a3feSChris Lalancette auxclk = readl(&scrm->auxclk1); 167df65a3feSChris Lalancette /* Select per DPLL */ 168df65a3feSChris Lalancette auxclk &= ~AUXCLK_SRCSELECT_MASK; 169df65a3feSChris Lalancette auxclk |= AUXCLK_SRCSELECT_PER_DPLL << AUXCLK_SRCSELECT_SHIFT; 170df65a3feSChris Lalancette /* Set the divisor to 16 */ 171df65a3feSChris Lalancette auxclk &= ~AUXCLK_CLKDIV_MASK; 172df65a3feSChris Lalancette auxclk |= AUXCLK_CLKDIV_16 << AUXCLK_CLKDIV_SHIFT; 173df65a3feSChris Lalancette /* Request auxilary clock #3 */ 174df65a3feSChris Lalancette auxclk |= AUXCLK_ENABLE_MASK; 175df65a3feSChris Lalancette 176df65a3feSChris Lalancette writel(auxclk, &scrm->auxclk1); 177df65a3feSChris Lalancette } 178df65a3feSChris Lalancette 179df65a3feSChris Lalancette altclksrc = readl(&scrm->altclksrc); 180df65a3feSChris Lalancette 181df65a3feSChris Lalancette /* Activate alternate system clock supplier */ 182df65a3feSChris Lalancette altclksrc &= ~ALTCLKSRC_MODE_MASK; 183df65a3feSChris Lalancette altclksrc |= ALTCLKSRC_MODE_ACTIVE; 184df65a3feSChris Lalancette 185df65a3feSChris Lalancette /* enable clocks */ 186df65a3feSChris Lalancette altclksrc |= ALTCLKSRC_ENABLE_INT_MASK | ALTCLKSRC_ENABLE_EXT_MASK; 187df65a3feSChris Lalancette 188df65a3feSChris Lalancette writel(altclksrc, &scrm->altclksrc); 189df65a3feSChris Lalancette 190e84b8f6cSDan Murphy if (!getenv("usbethaddr")) { 191e84b8f6cSDan Murphy /* 192e84b8f6cSDan Murphy * create a fake MAC address from the processor ID code. 193e84b8f6cSDan Murphy * first byte is 0x02 to signify locally administered. 194e84b8f6cSDan Murphy */ 195e84b8f6cSDan Murphy device_mac[0] = 0x02; 196e84b8f6cSDan Murphy device_mac[1] = readl(STD_FUSE_DIE_ID_3) & 0xff; 197e84b8f6cSDan Murphy device_mac[2] = readl(STD_FUSE_DIE_ID_2) & 0xff; 198e84b8f6cSDan Murphy device_mac[3] = readl(STD_FUSE_DIE_ID_1) & 0xff; 199e84b8f6cSDan Murphy device_mac[4] = readl(STD_FUSE_DIE_ID_0) & 0xff; 200e84b8f6cSDan Murphy device_mac[5] = (readl(STD_FUSE_DIE_ID_0) >> 8) & 0xff; 201e84b8f6cSDan Murphy 202e84b8f6cSDan Murphy eth_setenv_enetaddr("usbethaddr", device_mac); 203e84b8f6cSDan Murphy } 204e84b8f6cSDan Murphy 205c57cca25SSteve Sakoman return 0; 206c57cca25SSteve Sakoman } 2072ad853c3SSteve Sakoman 208508a58faSSricharan void set_muxconf_regs_essential(void) 209508a58faSSricharan { 2109239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_core_base, 2119239f5b6SLokesh Vutla core_padconf_array_essential, 212508a58faSSricharan sizeof(core_padconf_array_essential) / 213508a58faSSricharan sizeof(struct pad_conf_entry)); 214508a58faSSricharan 2159239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_wkup_base, 2169239f5b6SLokesh Vutla wkup_padconf_array_essential, 217508a58faSSricharan sizeof(wkup_padconf_array_essential) / 218508a58faSSricharan sizeof(struct pad_conf_entry)); 219508a58faSSricharan 220508a58faSSricharan if (omap_revision() >= OMAP4460_ES1_0) 2219239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_wkup_base, 222508a58faSSricharan wkup_padconf_array_essential_4460, 223508a58faSSricharan sizeof(wkup_padconf_array_essential_4460) / 224508a58faSSricharan sizeof(struct pad_conf_entry)); 225508a58faSSricharan } 226508a58faSSricharan 227469ec1e3SAneesh V void set_muxconf_regs_non_essential(void) 2282ad853c3SSteve Sakoman { 2299239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_core_base, 2309239f5b6SLokesh Vutla core_padconf_array_non_essential, 231469ec1e3SAneesh V sizeof(core_padconf_array_non_essential) / 2322ad853c3SSteve Sakoman sizeof(struct pad_conf_entry)); 2332ad853c3SSteve Sakoman 23453430a4fSRicardo Salveti de Araujo if (omap_revision() < OMAP4460_ES1_0) 2359239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_core_base, 23653430a4fSRicardo Salveti de Araujo core_padconf_array_non_essential_4430, 23753430a4fSRicardo Salveti de Araujo sizeof(core_padconf_array_non_essential_4430) / 23853430a4fSRicardo Salveti de Araujo sizeof(struct pad_conf_entry)); 23953430a4fSRicardo Salveti de Araujo else 2409239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_core_base, 24153430a4fSRicardo Salveti de Araujo core_padconf_array_non_essential_4460, 24253430a4fSRicardo Salveti de Araujo sizeof(core_padconf_array_non_essential_4460) / 24353430a4fSRicardo Salveti de Araujo sizeof(struct pad_conf_entry)); 24453430a4fSRicardo Salveti de Araujo 2459239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_wkup_base, 2469239f5b6SLokesh Vutla wkup_padconf_array_non_essential, 247469ec1e3SAneesh V sizeof(wkup_padconf_array_non_essential) / 2482ad853c3SSteve Sakoman sizeof(struct pad_conf_entry)); 24953430a4fSRicardo Salveti de Araujo 25053430a4fSRicardo Salveti de Araujo if (omap_revision() < OMAP4460_ES1_0) 2519239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_wkup_base, 25253430a4fSRicardo Salveti de Araujo wkup_padconf_array_non_essential_4430, 25353430a4fSRicardo Salveti de Araujo sizeof(wkup_padconf_array_non_essential_4430) / 25453430a4fSRicardo Salveti de Araujo sizeof(struct pad_conf_entry)); 2552ad853c3SSteve Sakoman } 2567e982c95SSukumar Ghorai 257508a58faSSricharan #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC) 2587e982c95SSukumar Ghorai int board_mmc_init(bd_t *bis) 2597e982c95SSukumar Ghorai { 260e3913f56SNikita Kiryanov return omap_mmc_init(0, 0, 0, -1, -1); 2617e982c95SSukumar Ghorai } 2627e982c95SSukumar Ghorai #endif 263508a58faSSricharan 26443b62393SGovindraj.R #ifdef CONFIG_USB_EHCI 26543b62393SGovindraj.R 26643b62393SGovindraj.R static struct omap_usbhs_board_data usbhs_bdata = { 26743b62393SGovindraj.R .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 26843b62393SGovindraj.R .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, 26943b62393SGovindraj.R .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 27043b62393SGovindraj.R }; 27143b62393SGovindraj.R 272*127efc4fSTroy Kisky int ehci_hcd_init(int index, enum usb_init_type init, 273*127efc4fSTroy Kisky struct ehci_hccr **hccr, struct ehci_hcor **hcor) 27443b62393SGovindraj.R { 27543b62393SGovindraj.R int ret; 27643b62393SGovindraj.R unsigned int utmi_clk; 27743b62393SGovindraj.R 27843b62393SGovindraj.R /* Now we can enable our port clocks */ 27943b62393SGovindraj.R utmi_clk = readl((void *)CM_L3INIT_HSUSBHOST_CLKCTRL); 28043b62393SGovindraj.R utmi_clk |= HSUSBHOST_CLKCTRL_CLKSEL_UTMI_P1_MASK; 28143b62393SGovindraj.R sr32((void *)CM_L3INIT_HSUSBHOST_CLKCTRL, 0, 32, utmi_clk); 28243b62393SGovindraj.R 28316297cfbSMateusz Zalega ret = omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor); 28443b62393SGovindraj.R if (ret < 0) 28543b62393SGovindraj.R return ret; 28643b62393SGovindraj.R 28743b62393SGovindraj.R return 0; 28843b62393SGovindraj.R } 28943b62393SGovindraj.R 290676ae068SLucas Stach int ehci_hcd_stop(int index) 29143b62393SGovindraj.R { 29243b62393SGovindraj.R return omap_ehci_hcd_stop(); 29343b62393SGovindraj.R } 29443b62393SGovindraj.R #endif 29543b62393SGovindraj.R 296508a58faSSricharan /* 297508a58faSSricharan * get_board_rev() - get board revision 298508a58faSSricharan */ 299508a58faSSricharan u32 get_board_rev(void) 300508a58faSSricharan { 301508a58faSSricharan return 0x20; 302508a58faSSricharan } 303