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