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> 14fbf1b08aSPaul Kocialkowski #include <twl6030.h> 15c57cca25SSteve Sakoman 16469ec1e3SAneesh V #include "panda_mux_data.h" 172ad853c3SSteve Sakoman 1843b62393SGovindraj.R #ifdef CONFIG_USB_EHCI 1943b62393SGovindraj.R #include <usb.h> 2043b62393SGovindraj.R #include <asm/arch/ehci.h> 2143b62393SGovindraj.R #include <asm/ehci-omap.h> 2243b62393SGovindraj.R #endif 2343b62393SGovindraj.R 24df65a3feSChris Lalancette #define PANDA_ULPI_PHY_TYPE_GPIO 182 257d47d1caSDan Murphy #define PANDA_BOARD_ID_1_GPIO 101 267d47d1caSDan Murphy #define PANDA_ES_BOARD_ID_1_GPIO 48 277d47d1caSDan Murphy #define PANDA_BOARD_ID_2_GPIO 171 287d47d1caSDan Murphy #define PANDA_ES_BOARD_ID_3_GPIO 3 297d47d1caSDan Murphy #define PANDA_ES_BOARD_ID_4_GPIO 2 30df65a3feSChris Lalancette 31c57cca25SSteve Sakoman DECLARE_GLOBAL_DATA_PTR; 32c57cca25SSteve Sakoman 33c57cca25SSteve Sakoman const struct omap_sysinfo sysinfo = { 34c57cca25SSteve Sakoman "Board: OMAP4 Panda\n" 35c57cca25SSteve Sakoman }; 36c57cca25SSteve Sakoman 37df65a3feSChris Lalancette struct omap4_scrm_regs *const scrm = (struct omap4_scrm_regs *)0x4a30a000; 38df65a3feSChris Lalancette 39c57cca25SSteve Sakoman /** 40c57cca25SSteve Sakoman * @brief board_init 41c57cca25SSteve Sakoman * 42c57cca25SSteve Sakoman * @return 0 43c57cca25SSteve Sakoman */ 44c57cca25SSteve Sakoman int board_init(void) 45c57cca25SSteve Sakoman { 4627952014SSteve Sakoman gpmc_init(); 4727952014SSteve Sakoman 48c57cca25SSteve Sakoman gd->bd->bi_arch_number = MACH_TYPE_OMAP4_PANDA; 49c57cca25SSteve Sakoman gd->bd->bi_boot_params = (0x80000000 + 0x100); /* boot param addr */ 50c57cca25SSteve Sakoman 51c57cca25SSteve Sakoman return 0; 52c57cca25SSteve Sakoman } 53c57cca25SSteve Sakoman 54c57cca25SSteve Sakoman int board_eth_init(bd_t *bis) 55c57cca25SSteve Sakoman { 56c57cca25SSteve Sakoman return 0; 57c57cca25SSteve Sakoman } 58c57cca25SSteve Sakoman 597d47d1caSDan Murphy /* 607d47d1caSDan Murphy * Routine: get_board_revision 617d47d1caSDan Murphy * Description: Detect if we are running on a panda revision A1-A6, 627d47d1caSDan Murphy * or an ES panda board. This can be done by reading 637d47d1caSDan Murphy * the level of GPIOs and checking the processor revisions. 647d47d1caSDan Murphy * This should result in: 657d47d1caSDan Murphy * Panda 4430: 667d47d1caSDan Murphy * GPIO171, GPIO101, GPIO182: 0 1 1 => A1-A5 677d47d1caSDan Murphy * GPIO171, GPIO101, GPIO182: 1 0 1 => A6 687d47d1caSDan Murphy * Panda ES: 697d47d1caSDan Murphy * GPIO2, GPIO3, GPIO171, GPIO48, GPIO182: 0 0 0 1 1 => B1/B2 707d47d1caSDan Murphy * GPIO2, GPIO3, GPIO171, GPIO48, GPIO182: 0 0 1 1 1 => B3 717d47d1caSDan Murphy */ 727d47d1caSDan Murphy int get_board_revision(void) 737d47d1caSDan Murphy { 747d47d1caSDan Murphy int board_id0, board_id1, board_id2; 757d47d1caSDan Murphy int board_id3, board_id4; 767d47d1caSDan Murphy int board_id; 777d47d1caSDan Murphy 787d47d1caSDan Murphy int processor_rev = omap_revision(); 797d47d1caSDan Murphy 807d47d1caSDan Murphy /* Setup the mux for the common board ID pins (gpio 171 and 182) */ 817d47d1caSDan Murphy writew((IEN | M3), (*ctrl)->control_padconf_core_base + UNIPRO_TX0); 827d47d1caSDan Murphy writew((IEN | M3), (*ctrl)->control_padconf_core_base + FREF_CLK2_OUT); 837d47d1caSDan Murphy 847d47d1caSDan Murphy board_id0 = gpio_get_value(PANDA_ULPI_PHY_TYPE_GPIO); 857d47d1caSDan Murphy board_id2 = gpio_get_value(PANDA_BOARD_ID_2_GPIO); 867d47d1caSDan Murphy 877d47d1caSDan Murphy if ((processor_rev >= OMAP4460_ES1_0 && 887d47d1caSDan Murphy processor_rev <= OMAP4460_ES1_1)) { 897d47d1caSDan Murphy /* 907d47d1caSDan Murphy * Setup the mux for the ES specific board ID pins (gpio 101, 917d47d1caSDan Murphy * 2 and 3. 927d47d1caSDan Murphy */ 937d47d1caSDan Murphy writew((IEN | M3), (*ctrl)->control_padconf_core_base + 947d47d1caSDan Murphy GPMC_A24); 957d47d1caSDan Murphy writew((IEN | M3), (*ctrl)->control_padconf_core_base + 967d47d1caSDan Murphy UNIPRO_RY0); 977d47d1caSDan Murphy writew((IEN | M3), (*ctrl)->control_padconf_core_base + 987d47d1caSDan Murphy UNIPRO_RX1); 997d47d1caSDan Murphy 1007d47d1caSDan Murphy board_id1 = gpio_get_value(PANDA_ES_BOARD_ID_1_GPIO); 1017d47d1caSDan Murphy board_id3 = gpio_get_value(PANDA_ES_BOARD_ID_3_GPIO); 1027d47d1caSDan Murphy board_id4 = gpio_get_value(PANDA_ES_BOARD_ID_4_GPIO); 1037d47d1caSDan Murphy 1047d47d1caSDan Murphy #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 105eda1dfafSdbatzle@dcbcyber.com setenv("board_name", "panda-es"); 1067d47d1caSDan Murphy #endif 1077d47d1caSDan Murphy board_id = ((board_id4 << 4) | (board_id3 << 3) | 1087d47d1caSDan Murphy (board_id2 << 2) | (board_id1 << 1) | (board_id0)); 1097d47d1caSDan Murphy } else { 1107d47d1caSDan Murphy /* Setup the mux for the Ax specific board ID pins (gpio 101) */ 1117d47d1caSDan Murphy writew((IEN | M3), (*ctrl)->control_padconf_core_base + 1127d47d1caSDan Murphy FREF_CLK2_OUT); 1137d47d1caSDan Murphy 1147d47d1caSDan Murphy board_id1 = gpio_get_value(PANDA_BOARD_ID_1_GPIO); 1157d47d1caSDan Murphy board_id = ((board_id2 << 2) | (board_id1 << 1) | (board_id0)); 1167d47d1caSDan Murphy 1177d47d1caSDan Murphy #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 1187d47d1caSDan Murphy if ((board_id >= 0x3) && (processor_rev == OMAP4430_ES2_3)) 119eda1dfafSdbatzle@dcbcyber.com setenv("board_name", "panda-a4"); 1207d47d1caSDan Murphy #endif 1217d47d1caSDan Murphy } 1227d47d1caSDan Murphy 1237d47d1caSDan Murphy return board_id; 1247d47d1caSDan Murphy } 1257d47d1caSDan Murphy 126c57cca25SSteve Sakoman /** 127675cc77aSHardik Patel * is_panda_es_rev_b3() - Detect if we are running on rev B3 of panda board ES 128675cc77aSHardik Patel * 129675cc77aSHardik Patel * 130675cc77aSHardik Patel * Detect if we are running on B3 version of ES panda board, 131675cc77aSHardik Patel * This can be done by reading the level of GPIO 171 and checking the 132675cc77aSHardik Patel * processor revisions. 133675cc77aSHardik Patel * GPIO171: 1 => Panda ES Rev B3 134675cc77aSHardik Patel * 135675cc77aSHardik Patel * Return : return 1 if Panda ES Rev B3 , else return 0 136675cc77aSHardik Patel */ 137675cc77aSHardik Patel u8 is_panda_es_rev_b3(void) 138675cc77aSHardik Patel { 139675cc77aSHardik Patel int processor_rev = omap_revision(); 140675cc77aSHardik Patel int ret = 0; 141675cc77aSHardik Patel 142675cc77aSHardik Patel if ((processor_rev >= OMAP4460_ES1_0 && 143675cc77aSHardik Patel processor_rev <= OMAP4460_ES1_1)) { 144675cc77aSHardik Patel 145675cc77aSHardik Patel /* Setup the mux for the common board ID pins (gpio 171) */ 146675cc77aSHardik Patel writew((IEN | M3), 147675cc77aSHardik Patel (*ctrl)->control_padconf_core_base + UNIPRO_TX0); 148675cc77aSHardik Patel 149675cc77aSHardik Patel /* if processor_rev is panda ES and GPIO171 is 1,it is rev b3 */ 150675cc77aSHardik Patel ret = gpio_get_value(PANDA_BOARD_ID_2_GPIO); 151675cc77aSHardik Patel } 152675cc77aSHardik Patel return ret; 153675cc77aSHardik Patel } 154675cc77aSHardik Patel 155675cc77aSHardik Patel #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS 156675cc77aSHardik Patel /* 157675cc77aSHardik Patel * emif_get_reg_dump() - emif_get_reg_dump strong function 158675cc77aSHardik Patel * 159675cc77aSHardik Patel * @emif_nr - emif base 160675cc77aSHardik Patel * @regs - reg dump of timing values 161675cc77aSHardik Patel * 162675cc77aSHardik Patel * Strong function to override emif_get_reg_dump weak function in sdram_elpida.c 163675cc77aSHardik Patel */ 164675cc77aSHardik Patel void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs) 165675cc77aSHardik Patel { 166675cc77aSHardik Patel u32 omap4_rev = omap_revision(); 167675cc77aSHardik Patel 168675cc77aSHardik Patel /* Same devices and geometry on both EMIFs */ 169675cc77aSHardik Patel if (omap4_rev == OMAP4430_ES1_0) 170675cc77aSHardik Patel *regs = &emif_regs_elpida_380_mhz_1cs; 171675cc77aSHardik Patel else if (omap4_rev == OMAP4430_ES2_0) 172675cc77aSHardik Patel *regs = &emif_regs_elpida_200_mhz_2cs; 173675cc77aSHardik Patel else if (omap4_rev == OMAP4430_ES2_3) 174675cc77aSHardik Patel *regs = &emif_regs_elpida_400_mhz_1cs; 175675cc77aSHardik Patel else if (omap4_rev < OMAP4470_ES1_0) { 176675cc77aSHardik Patel if(is_panda_es_rev_b3()) 177675cc77aSHardik Patel *regs = &emif_regs_elpida_400_mhz_1cs; 178675cc77aSHardik Patel else 179675cc77aSHardik Patel *regs = &emif_regs_elpida_400_mhz_2cs; 180675cc77aSHardik Patel } 181675cc77aSHardik Patel else 182675cc77aSHardik Patel *regs = &emif_regs_elpida_400_mhz_1cs; 183675cc77aSHardik Patel } 18438e5a5abSNishanth Menon 18538e5a5abSNishanth Menon void emif_get_dmm_regs(const struct dmm_lisa_map_regs 18638e5a5abSNishanth Menon **dmm_lisa_regs) 18738e5a5abSNishanth Menon { 18838e5a5abSNishanth Menon u32 omap_rev = omap_revision(); 18938e5a5abSNishanth Menon 19038e5a5abSNishanth Menon if (omap_rev == OMAP4430_ES1_0) 19138e5a5abSNishanth Menon *dmm_lisa_regs = &lisa_map_2G_x_1_x_2; 19238e5a5abSNishanth Menon else if (omap_rev == OMAP4430_ES2_3) 19338e5a5abSNishanth Menon *dmm_lisa_regs = &lisa_map_2G_x_2_x_2; 19438e5a5abSNishanth Menon else if (omap_rev < OMAP4460_ES1_0) 19538e5a5abSNishanth Menon *dmm_lisa_regs = &lisa_map_2G_x_2_x_2; 19638e5a5abSNishanth Menon else 19738e5a5abSNishanth Menon *dmm_lisa_regs = &ma_lisa_map_2G_x_2_x_2; 19838e5a5abSNishanth Menon } 19938e5a5abSNishanth Menon 200675cc77aSHardik Patel #endif 201675cc77aSHardik Patel 202675cc77aSHardik Patel /** 203c57cca25SSteve Sakoman * @brief misc_init_r - Configure Panda board specific configurations 204c57cca25SSteve Sakoman * such as power configurations, ethernet initialization as phase2 of 205c57cca25SSteve Sakoman * boot sequence 206c57cca25SSteve Sakoman * 207c57cca25SSteve Sakoman * @return 0 208c57cca25SSteve Sakoman */ 209c57cca25SSteve Sakoman int misc_init_r(void) 210c57cca25SSteve Sakoman { 211df65a3feSChris Lalancette int phy_type; 212df65a3feSChris Lalancette u32 auxclk, altclksrc; 213df65a3feSChris Lalancette 214df65a3feSChris Lalancette /* EHCI is not supported on ES1.0 */ 215df65a3feSChris Lalancette if (omap_revision() == OMAP4430_ES1_0) 216df65a3feSChris Lalancette return 0; 217df65a3feSChris Lalancette 2187d47d1caSDan Murphy get_board_revision(); 21934f667bbSDan Murphy 220df65a3feSChris Lalancette gpio_direction_input(PANDA_ULPI_PHY_TYPE_GPIO); 221df65a3feSChris Lalancette phy_type = gpio_get_value(PANDA_ULPI_PHY_TYPE_GPIO); 222df65a3feSChris Lalancette 223df65a3feSChris Lalancette if (phy_type == 1) { 224df65a3feSChris Lalancette /* ULPI PHY supplied by auxclk3 derived from sys_clk */ 225df65a3feSChris Lalancette debug("ULPI PHY supplied by auxclk3\n"); 226df65a3feSChris Lalancette 227df65a3feSChris Lalancette auxclk = readl(&scrm->auxclk3); 228df65a3feSChris Lalancette /* Select sys_clk */ 229df65a3feSChris Lalancette auxclk &= ~AUXCLK_SRCSELECT_MASK; 230df65a3feSChris Lalancette auxclk |= AUXCLK_SRCSELECT_SYS_CLK << AUXCLK_SRCSELECT_SHIFT; 231df65a3feSChris Lalancette /* Set the divisor to 2 */ 232df65a3feSChris Lalancette auxclk &= ~AUXCLK_CLKDIV_MASK; 233df65a3feSChris Lalancette auxclk |= AUXCLK_CLKDIV_2 << AUXCLK_CLKDIV_SHIFT; 234df65a3feSChris Lalancette /* Request auxilary clock #3 */ 235df65a3feSChris Lalancette auxclk |= AUXCLK_ENABLE_MASK; 236df65a3feSChris Lalancette 237df65a3feSChris Lalancette writel(auxclk, &scrm->auxclk3); 238df65a3feSChris Lalancette } else { 239df65a3feSChris Lalancette /* ULPI PHY supplied by auxclk1 derived from PER dpll */ 240df65a3feSChris Lalancette debug("ULPI PHY supplied by auxclk1\n"); 241df65a3feSChris Lalancette 242df65a3feSChris Lalancette auxclk = readl(&scrm->auxclk1); 243df65a3feSChris Lalancette /* Select per DPLL */ 244df65a3feSChris Lalancette auxclk &= ~AUXCLK_SRCSELECT_MASK; 245df65a3feSChris Lalancette auxclk |= AUXCLK_SRCSELECT_PER_DPLL << AUXCLK_SRCSELECT_SHIFT; 246df65a3feSChris Lalancette /* Set the divisor to 16 */ 247df65a3feSChris Lalancette auxclk &= ~AUXCLK_CLKDIV_MASK; 248df65a3feSChris Lalancette auxclk |= AUXCLK_CLKDIV_16 << AUXCLK_CLKDIV_SHIFT; 249df65a3feSChris Lalancette /* Request auxilary clock #3 */ 250df65a3feSChris Lalancette auxclk |= AUXCLK_ENABLE_MASK; 251df65a3feSChris Lalancette 252df65a3feSChris Lalancette writel(auxclk, &scrm->auxclk1); 253df65a3feSChris Lalancette } 254df65a3feSChris Lalancette 255df65a3feSChris Lalancette altclksrc = readl(&scrm->altclksrc); 256df65a3feSChris Lalancette 257df65a3feSChris Lalancette /* Activate alternate system clock supplier */ 258df65a3feSChris Lalancette altclksrc &= ~ALTCLKSRC_MODE_MASK; 259df65a3feSChris Lalancette altclksrc |= ALTCLKSRC_MODE_ACTIVE; 260df65a3feSChris Lalancette 261df65a3feSChris Lalancette /* enable clocks */ 262df65a3feSChris Lalancette altclksrc |= ALTCLKSRC_ENABLE_INT_MASK | ALTCLKSRC_ENABLE_EXT_MASK; 263df65a3feSChris Lalancette 264df65a3feSChris Lalancette writel(altclksrc, &scrm->altclksrc); 265df65a3feSChris Lalancette 26607815eb9SPaul Kocialkowski omap_die_id_usbethaddr(); 267e84b8f6cSDan Murphy 268c57cca25SSteve Sakoman return 0; 269c57cca25SSteve Sakoman } 2702ad853c3SSteve Sakoman 271*3ef56e61SPaul Kocialkowski void set_muxconf_regs(void) 272508a58faSSricharan { 2739239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_core_base, 2749239f5b6SLokesh Vutla core_padconf_array_essential, 275508a58faSSricharan sizeof(core_padconf_array_essential) / 276508a58faSSricharan sizeof(struct pad_conf_entry)); 277508a58faSSricharan 2789239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_wkup_base, 2799239f5b6SLokesh Vutla wkup_padconf_array_essential, 280508a58faSSricharan sizeof(wkup_padconf_array_essential) / 281508a58faSSricharan sizeof(struct pad_conf_entry)); 282508a58faSSricharan 283508a58faSSricharan if (omap_revision() >= OMAP4460_ES1_0) 2849239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_wkup_base, 285508a58faSSricharan wkup_padconf_array_essential_4460, 286508a58faSSricharan sizeof(wkup_padconf_array_essential_4460) / 287508a58faSSricharan sizeof(struct pad_conf_entry)); 288508a58faSSricharan } 289508a58faSSricharan 290508a58faSSricharan #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC) 2917e982c95SSukumar Ghorai int board_mmc_init(bd_t *bis) 2927e982c95SSukumar Ghorai { 293e3913f56SNikita Kiryanov return omap_mmc_init(0, 0, 0, -1, -1); 2947e982c95SSukumar Ghorai } 295fbf1b08aSPaul Kocialkowski 296fbf1b08aSPaul Kocialkowski void board_mmc_power_init(void) 297fbf1b08aSPaul Kocialkowski { 298fbf1b08aSPaul Kocialkowski twl6030_power_mmc_init(0); 299fbf1b08aSPaul Kocialkowski } 3007e982c95SSukumar Ghorai #endif 301508a58faSSricharan 30243b62393SGovindraj.R #ifdef CONFIG_USB_EHCI 30343b62393SGovindraj.R 30443b62393SGovindraj.R static struct omap_usbhs_board_data usbhs_bdata = { 30543b62393SGovindraj.R .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 30643b62393SGovindraj.R .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, 30743b62393SGovindraj.R .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 30843b62393SGovindraj.R }; 30943b62393SGovindraj.R 310127efc4fSTroy Kisky int ehci_hcd_init(int index, enum usb_init_type init, 311127efc4fSTroy Kisky struct ehci_hccr **hccr, struct ehci_hcor **hcor) 31243b62393SGovindraj.R { 31343b62393SGovindraj.R int ret; 31443b62393SGovindraj.R unsigned int utmi_clk; 31543b62393SGovindraj.R 31643b62393SGovindraj.R /* Now we can enable our port clocks */ 31743b62393SGovindraj.R utmi_clk = readl((void *)CM_L3INIT_HSUSBHOST_CLKCTRL); 31843b62393SGovindraj.R utmi_clk |= HSUSBHOST_CLKCTRL_CLKSEL_UTMI_P1_MASK; 319e7300f46SWolfgang Denk setbits_le32((void *)CM_L3INIT_HSUSBHOST_CLKCTRL, utmi_clk); 32043b62393SGovindraj.R 32116297cfbSMateusz Zalega ret = omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor); 32243b62393SGovindraj.R if (ret < 0) 32343b62393SGovindraj.R return ret; 32443b62393SGovindraj.R 32543b62393SGovindraj.R return 0; 32643b62393SGovindraj.R } 32743b62393SGovindraj.R 328676ae068SLucas Stach int ehci_hcd_stop(int index) 32943b62393SGovindraj.R { 33043b62393SGovindraj.R return omap_ehci_hcd_stop(); 33143b62393SGovindraj.R } 33243b62393SGovindraj.R #endif 33343b62393SGovindraj.R 334508a58faSSricharan /* 335508a58faSSricharan * get_board_rev() - get board revision 336508a58faSSricharan */ 337508a58faSSricharan u32 get_board_rev(void) 338508a58faSSricharan { 339508a58faSSricharan return 0x20; 340508a58faSSricharan } 341