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 104*eda1dfafSdbatzle@dcbcyber.com setenv("board_name", "panda-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)) 118*eda1dfafSdbatzle@dcbcyber.com setenv("board_name", "panda-a4"); 1197d47d1caSDan Murphy #endif 1207d47d1caSDan Murphy } 1217d47d1caSDan Murphy 1227d47d1caSDan Murphy return board_id; 1237d47d1caSDan Murphy } 1247d47d1caSDan Murphy 125c57cca25SSteve Sakoman /** 126675cc77aSHardik Patel * is_panda_es_rev_b3() - Detect if we are running on rev B3 of panda board ES 127675cc77aSHardik Patel * 128675cc77aSHardik Patel * 129675cc77aSHardik Patel * Detect if we are running on B3 version of ES panda board, 130675cc77aSHardik Patel * This can be done by reading the level of GPIO 171 and checking the 131675cc77aSHardik Patel * processor revisions. 132675cc77aSHardik Patel * GPIO171: 1 => Panda ES Rev B3 133675cc77aSHardik Patel * 134675cc77aSHardik Patel * Return : return 1 if Panda ES Rev B3 , else return 0 135675cc77aSHardik Patel */ 136675cc77aSHardik Patel u8 is_panda_es_rev_b3(void) 137675cc77aSHardik Patel { 138675cc77aSHardik Patel int processor_rev = omap_revision(); 139675cc77aSHardik Patel int ret = 0; 140675cc77aSHardik Patel 141675cc77aSHardik Patel if ((processor_rev >= OMAP4460_ES1_0 && 142675cc77aSHardik Patel processor_rev <= OMAP4460_ES1_1)) { 143675cc77aSHardik Patel 144675cc77aSHardik Patel /* Setup the mux for the common board ID pins (gpio 171) */ 145675cc77aSHardik Patel writew((IEN | M3), 146675cc77aSHardik Patel (*ctrl)->control_padconf_core_base + UNIPRO_TX0); 147675cc77aSHardik Patel 148675cc77aSHardik Patel /* if processor_rev is panda ES and GPIO171 is 1,it is rev b3 */ 149675cc77aSHardik Patel ret = gpio_get_value(PANDA_BOARD_ID_2_GPIO); 150675cc77aSHardik Patel } 151675cc77aSHardik Patel return ret; 152675cc77aSHardik Patel } 153675cc77aSHardik Patel 154675cc77aSHardik Patel #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS 155675cc77aSHardik Patel /* 156675cc77aSHardik Patel * emif_get_reg_dump() - emif_get_reg_dump strong function 157675cc77aSHardik Patel * 158675cc77aSHardik Patel * @emif_nr - emif base 159675cc77aSHardik Patel * @regs - reg dump of timing values 160675cc77aSHardik Patel * 161675cc77aSHardik Patel * Strong function to override emif_get_reg_dump weak function in sdram_elpida.c 162675cc77aSHardik Patel */ 163675cc77aSHardik Patel void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs) 164675cc77aSHardik Patel { 165675cc77aSHardik Patel u32 omap4_rev = omap_revision(); 166675cc77aSHardik Patel 167675cc77aSHardik Patel /* Same devices and geometry on both EMIFs */ 168675cc77aSHardik Patel if (omap4_rev == OMAP4430_ES1_0) 169675cc77aSHardik Patel *regs = &emif_regs_elpida_380_mhz_1cs; 170675cc77aSHardik Patel else if (omap4_rev == OMAP4430_ES2_0) 171675cc77aSHardik Patel *regs = &emif_regs_elpida_200_mhz_2cs; 172675cc77aSHardik Patel else if (omap4_rev == OMAP4430_ES2_3) 173675cc77aSHardik Patel *regs = &emif_regs_elpida_400_mhz_1cs; 174675cc77aSHardik Patel else if (omap4_rev < OMAP4470_ES1_0) { 175675cc77aSHardik Patel if(is_panda_es_rev_b3()) 176675cc77aSHardik Patel *regs = &emif_regs_elpida_400_mhz_1cs; 177675cc77aSHardik Patel else 178675cc77aSHardik Patel *regs = &emif_regs_elpida_400_mhz_2cs; 179675cc77aSHardik Patel } 180675cc77aSHardik Patel else 181675cc77aSHardik Patel *regs = &emif_regs_elpida_400_mhz_1cs; 182675cc77aSHardik Patel } 18338e5a5abSNishanth Menon 18438e5a5abSNishanth Menon void emif_get_dmm_regs(const struct dmm_lisa_map_regs 18538e5a5abSNishanth Menon **dmm_lisa_regs) 18638e5a5abSNishanth Menon { 18738e5a5abSNishanth Menon u32 omap_rev = omap_revision(); 18838e5a5abSNishanth Menon 18938e5a5abSNishanth Menon if (omap_rev == OMAP4430_ES1_0) 19038e5a5abSNishanth Menon *dmm_lisa_regs = &lisa_map_2G_x_1_x_2; 19138e5a5abSNishanth Menon else if (omap_rev == OMAP4430_ES2_3) 19238e5a5abSNishanth Menon *dmm_lisa_regs = &lisa_map_2G_x_2_x_2; 19338e5a5abSNishanth Menon else if (omap_rev < OMAP4460_ES1_0) 19438e5a5abSNishanth Menon *dmm_lisa_regs = &lisa_map_2G_x_2_x_2; 19538e5a5abSNishanth Menon else 19638e5a5abSNishanth Menon *dmm_lisa_regs = &ma_lisa_map_2G_x_2_x_2; 19738e5a5abSNishanth Menon } 19838e5a5abSNishanth Menon 199675cc77aSHardik Patel #endif 200675cc77aSHardik Patel 201675cc77aSHardik Patel /** 202c57cca25SSteve Sakoman * @brief misc_init_r - Configure Panda board specific configurations 203c57cca25SSteve Sakoman * such as power configurations, ethernet initialization as phase2 of 204c57cca25SSteve Sakoman * boot sequence 205c57cca25SSteve Sakoman * 206c57cca25SSteve Sakoman * @return 0 207c57cca25SSteve Sakoman */ 208c57cca25SSteve Sakoman int misc_init_r(void) 209c57cca25SSteve Sakoman { 210df65a3feSChris Lalancette int phy_type; 211df65a3feSChris Lalancette u32 auxclk, altclksrc; 2128a0c6d6fSNishanth Menon u32 id[4]; 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 2668a0c6d6fSNishanth Menon id[0] = readl(STD_FUSE_DIE_ID_0); 2678a0c6d6fSNishanth Menon id[1] = readl(STD_FUSE_DIE_ID_1); 2688a0c6d6fSNishanth Menon id[2] = readl(STD_FUSE_DIE_ID_2); 2698a0c6d6fSNishanth Menon id[3] = readl(STD_FUSE_DIE_ID_3); 2708a0c6d6fSNishanth Menon usb_fake_mac_from_die_id(id); 271e84b8f6cSDan Murphy 272c57cca25SSteve Sakoman return 0; 273c57cca25SSteve Sakoman } 2742ad853c3SSteve Sakoman 275508a58faSSricharan void set_muxconf_regs_essential(void) 276508a58faSSricharan { 2779239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_core_base, 2789239f5b6SLokesh Vutla core_padconf_array_essential, 279508a58faSSricharan sizeof(core_padconf_array_essential) / 280508a58faSSricharan sizeof(struct pad_conf_entry)); 281508a58faSSricharan 2829239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_wkup_base, 2839239f5b6SLokesh Vutla wkup_padconf_array_essential, 284508a58faSSricharan sizeof(wkup_padconf_array_essential) / 285508a58faSSricharan sizeof(struct pad_conf_entry)); 286508a58faSSricharan 287508a58faSSricharan if (omap_revision() >= OMAP4460_ES1_0) 2889239f5b6SLokesh Vutla do_set_mux((*ctrl)->control_padconf_wkup_base, 289508a58faSSricharan wkup_padconf_array_essential_4460, 290508a58faSSricharan sizeof(wkup_padconf_array_essential_4460) / 291508a58faSSricharan sizeof(struct pad_conf_entry)); 292508a58faSSricharan } 293508a58faSSricharan 294508a58faSSricharan #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC) 2957e982c95SSukumar Ghorai int board_mmc_init(bd_t *bis) 2967e982c95SSukumar Ghorai { 297e3913f56SNikita Kiryanov return omap_mmc_init(0, 0, 0, -1, -1); 2987e982c95SSukumar Ghorai } 2997e982c95SSukumar Ghorai #endif 300508a58faSSricharan 30143b62393SGovindraj.R #ifdef CONFIG_USB_EHCI 30243b62393SGovindraj.R 30343b62393SGovindraj.R static struct omap_usbhs_board_data usbhs_bdata = { 30443b62393SGovindraj.R .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 30543b62393SGovindraj.R .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, 30643b62393SGovindraj.R .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 30743b62393SGovindraj.R }; 30843b62393SGovindraj.R 309127efc4fSTroy Kisky int ehci_hcd_init(int index, enum usb_init_type init, 310127efc4fSTroy Kisky struct ehci_hccr **hccr, struct ehci_hcor **hcor) 31143b62393SGovindraj.R { 31243b62393SGovindraj.R int ret; 31343b62393SGovindraj.R unsigned int utmi_clk; 31443b62393SGovindraj.R 31543b62393SGovindraj.R /* Now we can enable our port clocks */ 31643b62393SGovindraj.R utmi_clk = readl((void *)CM_L3INIT_HSUSBHOST_CLKCTRL); 31743b62393SGovindraj.R utmi_clk |= HSUSBHOST_CLKCTRL_CLKSEL_UTMI_P1_MASK; 318e7300f46SWolfgang Denk setbits_le32((void *)CM_L3INIT_HSUSBHOST_CLKCTRL, utmi_clk); 31943b62393SGovindraj.R 32016297cfbSMateusz Zalega ret = omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor); 32143b62393SGovindraj.R if (ret < 0) 32243b62393SGovindraj.R return ret; 32343b62393SGovindraj.R 32443b62393SGovindraj.R return 0; 32543b62393SGovindraj.R } 32643b62393SGovindraj.R 327676ae068SLucas Stach int ehci_hcd_stop(int index) 32843b62393SGovindraj.R { 32943b62393SGovindraj.R return omap_ehci_hcd_stop(); 33043b62393SGovindraj.R } 33143b62393SGovindraj.R #endif 33243b62393SGovindraj.R 333508a58faSSricharan /* 334508a58faSSricharan * get_board_rev() - get board revision 335508a58faSSricharan */ 336508a58faSSricharan u32 get_board_rev(void) 337508a58faSSricharan { 338508a58faSSricharan return 0x20; 339508a58faSSricharan } 340