1*ffe16911SAsh Charles /* 2*ffe16911SAsh Charles * (C) Copyright 2013 3*ffe16911SAsh Charles * Gumstix Inc. <www.gumstix.com> 4*ffe16911SAsh Charles * Maintainer: Ash Charles <ash@gumstix.com> 5*ffe16911SAsh Charles * 6*ffe16911SAsh Charles * SPDX-License-Identifier: GPL-2.0+ 7*ffe16911SAsh Charles */ 8*ffe16911SAsh Charles #include <common.h> 9*ffe16911SAsh Charles #include <netdev.h> 10*ffe16911SAsh Charles #include <asm/arch/sys_proto.h> 11*ffe16911SAsh Charles #include <asm/arch/mmc_host_def.h> 12*ffe16911SAsh Charles #include <twl6030.h> 13*ffe16911SAsh Charles #include <asm/emif.h> 14*ffe16911SAsh Charles #include <asm/arch/clock.h> 15*ffe16911SAsh Charles #include <asm/arch/gpio.h> 16*ffe16911SAsh Charles #include <asm/gpio.h> 17*ffe16911SAsh Charles 18*ffe16911SAsh Charles #include "duovero_mux_data.h" 19*ffe16911SAsh Charles 20*ffe16911SAsh Charles #define WIFI_EN 43 21*ffe16911SAsh Charles 22*ffe16911SAsh Charles #if defined(CONFIG_CMD_NET) 23*ffe16911SAsh Charles #define SMSC_NRESET 45 24*ffe16911SAsh Charles static void setup_net_chip(void); 25*ffe16911SAsh Charles #endif 26*ffe16911SAsh Charles 27*ffe16911SAsh Charles #ifdef CONFIG_USB_EHCI 28*ffe16911SAsh Charles #include <usb.h> 29*ffe16911SAsh Charles #include <asm/arch/ehci.h> 30*ffe16911SAsh Charles #include <asm/ehci-omap.h> 31*ffe16911SAsh Charles #endif 32*ffe16911SAsh Charles 33*ffe16911SAsh Charles DECLARE_GLOBAL_DATA_PTR; 34*ffe16911SAsh Charles 35*ffe16911SAsh Charles const struct omap_sysinfo sysinfo = { 36*ffe16911SAsh Charles "Board: duovero\n" 37*ffe16911SAsh Charles }; 38*ffe16911SAsh Charles 39*ffe16911SAsh Charles struct omap4_scrm_regs *const scrm = (struct omap4_scrm_regs *)0x4a30a000; 40*ffe16911SAsh Charles 41*ffe16911SAsh Charles /** 42*ffe16911SAsh Charles * @brief board_init 43*ffe16911SAsh Charles * 44*ffe16911SAsh Charles * @return 0 45*ffe16911SAsh Charles */ 46*ffe16911SAsh Charles int board_init(void) 47*ffe16911SAsh Charles { 48*ffe16911SAsh Charles gpmc_init(); 49*ffe16911SAsh Charles 50*ffe16911SAsh Charles gd->bd->bi_arch_number = MACH_TYPE_OMAP4_DUOVERO; 51*ffe16911SAsh Charles gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; 52*ffe16911SAsh Charles 53*ffe16911SAsh Charles return 0; 54*ffe16911SAsh Charles } 55*ffe16911SAsh Charles 56*ffe16911SAsh Charles /** 57*ffe16911SAsh Charles * @brief misc_init_r - Configure board specific configurations 58*ffe16911SAsh Charles * such as power configurations, ethernet initialization as phase2 of 59*ffe16911SAsh Charles * boot sequence 60*ffe16911SAsh Charles * 61*ffe16911SAsh Charles * @return 0 62*ffe16911SAsh Charles */ 63*ffe16911SAsh Charles int misc_init_r(void) 64*ffe16911SAsh Charles { 65*ffe16911SAsh Charles int ret = 0; 66*ffe16911SAsh Charles u8 val; 67*ffe16911SAsh Charles 68*ffe16911SAsh Charles /* wifi setup: first enable 32Khz clock from 6030 pmic */ 69*ffe16911SAsh Charles val = 0xe1; 70*ffe16911SAsh Charles ret = i2c_write(TWL6030_CHIP_PM, 0xbe, 1, &val, 1); 71*ffe16911SAsh Charles if (ret) 72*ffe16911SAsh Charles printf("Failed to enable 32Khz clock to wifi module\n"); 73*ffe16911SAsh Charles 74*ffe16911SAsh Charles /* then setup WIFI_EN as an output pin and send reset pulse */ 75*ffe16911SAsh Charles if (!gpio_request(WIFI_EN, "")) { 76*ffe16911SAsh Charles gpio_direction_output(WIFI_EN, 0); 77*ffe16911SAsh Charles gpio_set_value(WIFI_EN, 1); 78*ffe16911SAsh Charles udelay(1); 79*ffe16911SAsh Charles gpio_set_value(WIFI_EN, 0); 80*ffe16911SAsh Charles udelay(1); 81*ffe16911SAsh Charles gpio_set_value(WIFI_EN, 1); 82*ffe16911SAsh Charles } 83*ffe16911SAsh Charles 84*ffe16911SAsh Charles #if defined(CONFIG_CMD_NET) 85*ffe16911SAsh Charles setup_net_chip(); 86*ffe16911SAsh Charles #endif 87*ffe16911SAsh Charles return 0; 88*ffe16911SAsh Charles } 89*ffe16911SAsh Charles 90*ffe16911SAsh Charles void set_muxconf_regs_essential(void) 91*ffe16911SAsh Charles { 92*ffe16911SAsh Charles do_set_mux((*ctrl)->control_padconf_core_base, 93*ffe16911SAsh Charles core_padconf_array_essential, 94*ffe16911SAsh Charles sizeof(core_padconf_array_essential) / 95*ffe16911SAsh Charles sizeof(struct pad_conf_entry)); 96*ffe16911SAsh Charles 97*ffe16911SAsh Charles do_set_mux((*ctrl)->control_padconf_wkup_base, 98*ffe16911SAsh Charles wkup_padconf_array_essential, 99*ffe16911SAsh Charles sizeof(wkup_padconf_array_essential) / 100*ffe16911SAsh Charles sizeof(struct pad_conf_entry)); 101*ffe16911SAsh Charles 102*ffe16911SAsh Charles do_set_mux((*ctrl)->control_padconf_core_base, 103*ffe16911SAsh Charles core_padconf_array_non_essential, 104*ffe16911SAsh Charles sizeof(core_padconf_array_non_essential) / 105*ffe16911SAsh Charles sizeof(struct pad_conf_entry)); 106*ffe16911SAsh Charles 107*ffe16911SAsh Charles do_set_mux((*ctrl)->control_padconf_wkup_base, 108*ffe16911SAsh Charles wkup_padconf_array_non_essential, 109*ffe16911SAsh Charles sizeof(wkup_padconf_array_non_essential) / 110*ffe16911SAsh Charles sizeof(struct pad_conf_entry)); 111*ffe16911SAsh Charles } 112*ffe16911SAsh Charles 113*ffe16911SAsh Charles #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC) 114*ffe16911SAsh Charles int board_mmc_init(bd_t *bis) 115*ffe16911SAsh Charles { 116*ffe16911SAsh Charles return omap_mmc_init(0, 0, 0, -1, -1); 117*ffe16911SAsh Charles } 118*ffe16911SAsh Charles #endif 119*ffe16911SAsh Charles 120*ffe16911SAsh Charles 121*ffe16911SAsh Charles #if defined(CONFIG_CMD_NET) 122*ffe16911SAsh Charles 123*ffe16911SAsh Charles #define GPMC_SIZE_16M 0xF 124*ffe16911SAsh Charles #define GPMC_BASEADDR_MASK 0x3F 125*ffe16911SAsh Charles #define GPMC_CS_ENABLE 0x1 126*ffe16911SAsh Charles 127*ffe16911SAsh Charles static void enable_gpmc_net_config(const u32 *gpmc_config, struct gpmc_cs *cs, 128*ffe16911SAsh Charles u32 base, u32 size) 129*ffe16911SAsh Charles { 130*ffe16911SAsh Charles writel(0, &cs->config7); 131*ffe16911SAsh Charles sdelay(1000); 132*ffe16911SAsh Charles /* Delay for settling */ 133*ffe16911SAsh Charles writel(gpmc_config[0], &cs->config1); 134*ffe16911SAsh Charles writel(gpmc_config[1], &cs->config2); 135*ffe16911SAsh Charles writel(gpmc_config[2], &cs->config3); 136*ffe16911SAsh Charles writel(gpmc_config[3], &cs->config4); 137*ffe16911SAsh Charles writel(gpmc_config[4], &cs->config5); 138*ffe16911SAsh Charles writel(gpmc_config[5], &cs->config6); 139*ffe16911SAsh Charles 140*ffe16911SAsh Charles /* 141*ffe16911SAsh Charles * Enable the config. size is the CS size and goes in 142*ffe16911SAsh Charles * bits 11:8. We set bit 6 to enable this CS and the base 143*ffe16911SAsh Charles * address goes into bits 5:0. 144*ffe16911SAsh Charles */ 145*ffe16911SAsh Charles writel((size << 8) | (GPMC_CS_ENABLE << 6) | 146*ffe16911SAsh Charles ((base >> 24) & GPMC_BASEADDR_MASK), 147*ffe16911SAsh Charles &cs->config7); 148*ffe16911SAsh Charles 149*ffe16911SAsh Charles sdelay(2000); 150*ffe16911SAsh Charles } 151*ffe16911SAsh Charles 152*ffe16911SAsh Charles /* GPMC CS configuration for an SMSC LAN9221 ethernet controller */ 153*ffe16911SAsh Charles #define NET_LAN9221_GPMC_CONFIG1 0x2a001203 154*ffe16911SAsh Charles #define NET_LAN9221_GPMC_CONFIG2 0x000a0a02 155*ffe16911SAsh Charles #define NET_LAN9221_GPMC_CONFIG3 0x00020200 156*ffe16911SAsh Charles #define NET_LAN9221_GPMC_CONFIG4 0x0a030a03 157*ffe16911SAsh Charles #define NET_LAN9221_GPMC_CONFIG5 0x000a0a0a 158*ffe16911SAsh Charles #define NET_LAN9221_GPMC_CONFIG6 0x8a070707 159*ffe16911SAsh Charles #define NET_LAN9221_GPMC_CONFIG7 0x00000f6c 160*ffe16911SAsh Charles 161*ffe16911SAsh Charles /* GPMC definitions for LAN9221 chips on expansion boards */ 162*ffe16911SAsh Charles static const u32 gpmc_lan_config[] = { 163*ffe16911SAsh Charles NET_LAN9221_GPMC_CONFIG1, 164*ffe16911SAsh Charles NET_LAN9221_GPMC_CONFIG2, 165*ffe16911SAsh Charles NET_LAN9221_GPMC_CONFIG3, 166*ffe16911SAsh Charles NET_LAN9221_GPMC_CONFIG4, 167*ffe16911SAsh Charles NET_LAN9221_GPMC_CONFIG5, 168*ffe16911SAsh Charles NET_LAN9221_GPMC_CONFIG6, 169*ffe16911SAsh Charles /*CONFIG7- computed as params */ 170*ffe16911SAsh Charles }; 171*ffe16911SAsh Charles 172*ffe16911SAsh Charles /* 173*ffe16911SAsh Charles * Routine: setup_net_chip 174*ffe16911SAsh Charles * Description: Setting up the configuration GPMC registers specific to the 175*ffe16911SAsh Charles * Ethernet hardware. 176*ffe16911SAsh Charles */ 177*ffe16911SAsh Charles static void setup_net_chip(void) 178*ffe16911SAsh Charles { 179*ffe16911SAsh Charles enable_gpmc_net_config(gpmc_lan_config, &gpmc_cfg->cs[5], 0x2C000000, 180*ffe16911SAsh Charles GPMC_SIZE_16M); 181*ffe16911SAsh Charles 182*ffe16911SAsh Charles /* Make GPIO SMSC_NRESET as output pin and send reset pulse */ 183*ffe16911SAsh Charles if (!gpio_request(SMSC_NRESET, "")) { 184*ffe16911SAsh Charles gpio_direction_output(SMSC_NRESET, 0); 185*ffe16911SAsh Charles gpio_set_value(SMSC_NRESET, 1); 186*ffe16911SAsh Charles udelay(1); 187*ffe16911SAsh Charles gpio_set_value(SMSC_NRESET, 0); 188*ffe16911SAsh Charles udelay(1); 189*ffe16911SAsh Charles gpio_set_value(SMSC_NRESET, 1); 190*ffe16911SAsh Charles } 191*ffe16911SAsh Charles } 192*ffe16911SAsh Charles #endif 193*ffe16911SAsh Charles 194*ffe16911SAsh Charles int board_eth_init(bd_t *bis) 195*ffe16911SAsh Charles { 196*ffe16911SAsh Charles int rc = 0; 197*ffe16911SAsh Charles #ifdef CONFIG_SMC911X 198*ffe16911SAsh Charles rc = smc911x_initialize(0, CONFIG_SMC911X_BASE); 199*ffe16911SAsh Charles #endif 200*ffe16911SAsh Charles return rc; 201*ffe16911SAsh Charles } 202*ffe16911SAsh Charles 203*ffe16911SAsh Charles #ifdef CONFIG_USB_EHCI 204*ffe16911SAsh Charles 205*ffe16911SAsh Charles static struct omap_usbhs_board_data usbhs_bdata = { 206*ffe16911SAsh Charles .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 207*ffe16911SAsh Charles .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, 208*ffe16911SAsh Charles .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 209*ffe16911SAsh Charles }; 210*ffe16911SAsh Charles 211*ffe16911SAsh Charles int ehci_hcd_init(int index, enum usb_init_type init, 212*ffe16911SAsh Charles struct ehci_hccr **hccr, struct ehci_hcor **hcor) 213*ffe16911SAsh Charles { 214*ffe16911SAsh Charles int ret; 215*ffe16911SAsh Charles unsigned int utmi_clk; 216*ffe16911SAsh Charles u32 auxclk, altclksrc; 217*ffe16911SAsh Charles 218*ffe16911SAsh Charles /* Now we can enable our port clocks */ 219*ffe16911SAsh Charles utmi_clk = readl((void *)CM_L3INIT_HSUSBHOST_CLKCTRL); 220*ffe16911SAsh Charles utmi_clk |= HSUSBHOST_CLKCTRL_CLKSEL_UTMI_P1_MASK; 221*ffe16911SAsh Charles setbits_le32((void *)CM_L3INIT_HSUSBHOST_CLKCTRL, utmi_clk); 222*ffe16911SAsh Charles 223*ffe16911SAsh Charles auxclk = readl(&scrm->auxclk3); 224*ffe16911SAsh Charles /* Select sys_clk */ 225*ffe16911SAsh Charles auxclk &= ~AUXCLK_SRCSELECT_MASK; 226*ffe16911SAsh Charles auxclk |= AUXCLK_SRCSELECT_SYS_CLK << AUXCLK_SRCSELECT_SHIFT; 227*ffe16911SAsh Charles /* Set the divisor to 2 */ 228*ffe16911SAsh Charles auxclk &= ~AUXCLK_CLKDIV_MASK; 229*ffe16911SAsh Charles auxclk |= AUXCLK_CLKDIV_2 << AUXCLK_CLKDIV_SHIFT; 230*ffe16911SAsh Charles /* Request auxilary clock #3 */ 231*ffe16911SAsh Charles auxclk |= AUXCLK_ENABLE_MASK; 232*ffe16911SAsh Charles writel(auxclk, &scrm->auxclk3); 233*ffe16911SAsh Charles 234*ffe16911SAsh Charles altclksrc = readl(&scrm->altclksrc); 235*ffe16911SAsh Charles 236*ffe16911SAsh Charles /* Activate alternate system clock supplier */ 237*ffe16911SAsh Charles altclksrc &= ~ALTCLKSRC_MODE_MASK; 238*ffe16911SAsh Charles altclksrc |= ALTCLKSRC_MODE_ACTIVE; 239*ffe16911SAsh Charles 240*ffe16911SAsh Charles /* enable clocks */ 241*ffe16911SAsh Charles altclksrc |= ALTCLKSRC_ENABLE_INT_MASK | ALTCLKSRC_ENABLE_EXT_MASK; 242*ffe16911SAsh Charles 243*ffe16911SAsh Charles writel(altclksrc, &scrm->altclksrc); 244*ffe16911SAsh Charles 245*ffe16911SAsh Charles ret = omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor); 246*ffe16911SAsh Charles if (ret < 0) 247*ffe16911SAsh Charles return ret; 248*ffe16911SAsh Charles 249*ffe16911SAsh Charles return 0; 250*ffe16911SAsh Charles } 251*ffe16911SAsh Charles 252*ffe16911SAsh Charles int ehci_hcd_stop(int index) 253*ffe16911SAsh Charles { 254*ffe16911SAsh Charles return omap_ehci_hcd_stop(); 255*ffe16911SAsh Charles } 256*ffe16911SAsh Charles #endif 257*ffe16911SAsh Charles 258*ffe16911SAsh Charles /* 259*ffe16911SAsh Charles * get_board_rev() - get board revision 260*ffe16911SAsh Charles */ 261*ffe16911SAsh Charles u32 get_board_rev(void) 262*ffe16911SAsh Charles { 263*ffe16911SAsh Charles return 0x20; 264*ffe16911SAsh Charles } 265