summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/arch-davinci/da8xx_common.h4
-rw-r--r--arch/arm/include/asm/arch-davinci/hardware.h4
-rw-r--r--board/davinci/da8xxevm/common.c14
-rw-r--r--board/davinci/da8xxevm/da850evm.c112
-rw-r--r--drivers/net/davinci_emac.c41
-rw-r--r--include/configs/da850evm.h1
6 files changed, 171 insertions, 5 deletions
diff --git a/arch/arm/include/asm/arch-davinci/da8xx_common.h b/arch/arm/include/asm/arch-davinci/da8xx_common.h
index bc3092d..e52f613 100644
--- a/arch/arm/include/asm/arch-davinci/da8xx_common.h
+++ b/arch/arm/include/asm/arch-davinci/da8xx_common.h
@@ -30,4 +30,8 @@ void irq_init(void);
int da8xx_configure_lpsc_items(const struct lpsc_resource *item,
int n_items);
+#if defined(CONFIG_DRIVER_TI_EMAC) && defined(CONFIG_MACH_DAVINCI_DA850_EVM)
+void da850_emac_mii_mode_sel(int mode_sel);
+#endif
+
#endif /* __COMMON_H */
diff --git a/arch/arm/include/asm/arch-davinci/hardware.h b/arch/arm/include/asm/arch-davinci/hardware.h
index ef616c1..b95fa97 100644
--- a/arch/arm/include/asm/arch-davinci/hardware.h
+++ b/arch/arm/include/asm/arch-davinci/hardware.h
@@ -152,6 +152,10 @@ typedef volatile unsigned int * dv_reg_p;
#define DAVINCI_BOOTCFG_BASE 0x01c14000
#define JTAG_ID_REG (DAVINCI_BOOTCFG_BASE + 0x18)
+#define GPIO_BANK2_REG_DIR_ADDR (DAVINCI_GPIO_BASE + 0x38)
+#define GPIO_BANK2_REG_OPDATA_ADDR (DAVINCI_GPIO_BASE + 0x3c)
+#define GPIO_BANK2_REG_SET_ADDR (DAVINCI_GPIO_BASE + 0x40)
+#define GPIO_BANK2_REG_CLR_ADDR (DAVINCI_GPIO_BASE + 0x44)
#endif /* CONFIG_SOC_DA8XX */
/* Power and Sleep Controller (PSC) Domains */
diff --git a/board/davinci/da8xxevm/common.c b/board/davinci/da8xxevm/common.c
index 36bf693..2d9a64b 100644
--- a/board/davinci/da8xxevm/common.c
+++ b/board/davinci/da8xxevm/common.c
@@ -53,3 +53,17 @@ int da8xx_configure_lpsc_items(const struct lpsc_resource *item,
return 0;
}
+
+#if defined(CONFIG_DRIVER_TI_EMAC) && defined(CONFIG_MACH_DAVINCI_DA850_EVM)
+void da850_emac_mii_mode_sel(int mode_sel)
+{
+ int val;
+
+ val = readl(&davinci_syscfg_regs->cfgchip3);
+ if (mode_sel == 0)
+ val &= ~(1 << 8);
+ else
+ val |= (1 << 8);
+ writel(val, &davinci_syscfg_regs->cfgchip3);
+}
+#endif
diff --git a/board/davinci/da8xxevm/da850evm.c b/board/davinci/da8xxevm/da850evm.c
index 8c9ff7c..291757c 100644
--- a/board/davinci/da8xxevm/da850evm.c
+++ b/board/davinci/da8xxevm/da850evm.c
@@ -54,6 +54,15 @@ static const struct pinmux_config uart_pins[] = {
#ifdef CONFIG_DRIVER_TI_EMAC
static const struct pinmux_config emac_pins[] = {
+#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
+ { pinmux(14), 8, 2 },
+ { pinmux(14), 8, 3 },
+ { pinmux(14), 8, 4 },
+ { pinmux(14), 8, 5 },
+ { pinmux(14), 8, 6 },
+ { pinmux(14), 8, 7 },
+ { pinmux(15), 8, 1 },
+#else /* ! CONFIG_DRIVER_TI_EMAC_USE_RMII */
{ pinmux(2), 8, 1 },
{ pinmux(2), 8, 2 },
{ pinmux(2), 8, 3 },
@@ -69,10 +78,10 @@ static const struct pinmux_config emac_pins[] = {
{ pinmux(3), 8, 5 },
{ pinmux(3), 8, 6 },
{ pinmux(3), 8, 7 },
+#endif /* CONFIG_DRIVER_TI_EMAC_USE_RMII */
{ pinmux(4), 8, 0 },
{ pinmux(4), 8, 1 }
};
-#endif /* CONFIG_DRIVER_TI_EMAC */
/* I2C pin muxer settings */
static const struct pinmux_config i2c_pins[] = {
@@ -99,6 +108,13 @@ const struct pinmux_config nand_pins[] = {
};
#endif
+#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
+#define HAS_RMII 1
+#else
+#define HAS_RMII 0
+#endif
+#endif /* CONFIG_DRIVER_TI_EMAC */
+
static const struct pinmux_resource pinmuxes[] = {
#ifdef CONFIG_SPI_FLASH
PINMUX_ITEM(spi1_pins),
@@ -203,9 +219,8 @@ int board_init(void)
#ifdef CONFIG_DRIVER_TI_EMAC
if (davinci_configure_pin_mux(emac_pins, ARRAY_SIZE(emac_pins)) != 0)
return 1;
- /* set cfgchip3 to select MII */
- writel(readl(&davinci_syscfg_regs->cfgchip3) & ~(1 << 8),
- &davinci_syscfg_regs->cfgchip3);
+
+ da850_emac_mii_mode_sel(HAS_RMII);
#endif /* CONFIG_DRIVER_TI_EMAC */
/* enable the console UART */
@@ -218,11 +233,100 @@ int board_init(void)
#ifdef CONFIG_DRIVER_TI_EMAC
+#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
+/**
+ * rmii_hw_init
+ *
+ * DA850/OMAP-L138 EVM can interface to a daughter card for
+ * additional features. This card has an I2C GPIO Expander TCA6416
+ * to select the required functions like camera, RMII Ethernet,
+ * character LCD, video.
+ *
+ * Initialization of the expander involves configuring the
+ * polarity and direction of the ports. P07-P05 are used here.
+ * These ports are connected to a Mux chip which enables only one
+ * functionality at a time.
+ *
+ * For RMII phy to respond, the MII MDIO clock has to be disabled
+ * since both the PHY devices have address as zero. The MII MDIO
+ * clock is controlled via GPIO2[6].
+ *
+ * This code is valid for Beta version of the hardware
+ */
+int rmii_hw_init(void)
+{
+ const struct pinmux_config gpio_pins[] = {
+ { pinmux(6), 8, 1 }
+ };
+ u_int8_t buf[2];
+ unsigned int temp;
+ int ret;
+
+ /* PinMux for GPIO */
+ if (davinci_configure_pin_mux(gpio_pins, ARRAY_SIZE(gpio_pins)) != 0)
+ return 1;
+
+ /* I2C Exapnder configuration */
+ /* Set polarity to non-inverted */
+ buf[0] = 0x0;
+ buf[1] = 0x0;
+ ret = i2c_write(CONFIG_SYS_I2C_EXPANDER_ADDR, 4, 1, buf, 2);
+ if (ret) {
+ printf("\nExpander @ 0x%02x write FAILED!!!\n",
+ CONFIG_SYS_I2C_EXPANDER_ADDR);
+ return ret;
+ }
+
+ /* Configure P07-P05 as outputs */
+ buf[0] = 0x1f;
+ buf[1] = 0xff;
+ ret = i2c_write(CONFIG_SYS_I2C_EXPANDER_ADDR, 6, 1, buf, 2);
+ if (ret) {
+ printf("\nExpander @ 0x%02x write FAILED!!!\n",
+ CONFIG_SYS_I2C_EXPANDER_ADDR);
+ }
+
+ /* For Ethernet RMII selection
+ * P07(SelA)=0
+ * P06(SelB)=1
+ * P05(SelC)=1
+ */
+ if (i2c_read(CONFIG_SYS_I2C_EXPANDER_ADDR, 2, 1, buf, 1)) {
+ printf("\nExpander @ 0x%02x read FAILED!!!\n",
+ CONFIG_SYS_I2C_EXPANDER_ADDR);
+ }
+
+ buf[0] &= 0x1f;
+ buf[0] |= (0 << 7) | (1 << 6) | (1 << 5);
+ if (i2c_write(CONFIG_SYS_I2C_EXPANDER_ADDR, 2, 1, buf, 1)) {
+ printf("\nExpander @ 0x%02x write FAILED!!!\n",
+ CONFIG_SYS_I2C_EXPANDER_ADDR);
+ }
+
+ /* Set the output as high */
+ temp = REG(GPIO_BANK2_REG_SET_ADDR);
+ temp |= (0x01 << 6);
+ REG(GPIO_BANK2_REG_SET_ADDR) = temp;
+
+ /* Set the GPIO direction as output */
+ temp = REG(GPIO_BANK2_REG_DIR_ADDR);
+ temp &= ~(0x01 << 6);
+ REG(GPIO_BANK2_REG_DIR_ADDR) = temp;
+
+ return 0;
+}
+#endif /* CONFIG_DRIVER_TI_EMAC_USE_RMII */
+
/*
* Initializes on-board ethernet controllers.
*/
int board_eth_init(bd_t *bis)
{
+#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
+ /* Select RMII fucntion through the expander */
+ if (rmii_hw_init())
+ printf("RMII hardware init failed!!!\n");
+#endif
if (!davinci_emac_initialize()) {
printf("Error: Ethernet init failed!\n");
return -1;
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index e06896f..43a3d79 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -243,8 +243,35 @@ static int gen_get_link_speed(int phy_addr)
{
u_int16_t tmp;
- if (davinci_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) && (tmp & 0x04))
+ if (davinci_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) &&
+ (tmp & 0x04)) {
+#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
+ defined(CONFIG_MACH_DAVINCI_DA850_EVM)
+ davinci_eth_phy_read(phy_addr, PHY_ANLPAR, &tmp);
+
+ /* Speed doesn't matter, there is no setting for it in EMAC. */
+ if (tmp & (PHY_ANLPAR_TXFD | PHY_ANLPAR_10FD)) {
+ /* set EMAC for Full Duplex */
+ writel(EMAC_MACCONTROL_MIIEN_ENABLE |
+ EMAC_MACCONTROL_FULLDUPLEX_ENABLE,
+ &adap_emac->MACCONTROL);
+ } else {
+ /*set EMAC for Half Duplex */
+ writel(EMAC_MACCONTROL_MIIEN_ENABLE,
+ &adap_emac->MACCONTROL);
+ }
+
+ if (tmp & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX))
+ writel(readl(&adap_emac->MACCONTROL) |
+ EMAC_MACCONTROL_RMIISPEED_100,
+ &adap_emac->MACCONTROL);
+ else
+ writel(readl(&adap_emac->MACCONTROL) &
+ ~EMAC_MACCONTROL_RMIISPEED_100,
+ &adap_emac->MACCONTROL);
+#endif
return(1);
+ }
return(0);
}
@@ -326,6 +353,12 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
}
#endif
+#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
+ defined(CONFIG_MACH_DAVINCI_DA850_EVM)
+ adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0;
+ adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0;
+ adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0;
+#endif
rx_desc = emac_rx_desc;
writel(1, &adap_emac->TXCONTROL);
@@ -480,6 +513,12 @@ static void davinci_eth_close(struct eth_device *dev)
writel(0, &adap_ewrap->EWCTL);
#endif
+#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
+ defined(CONFIG_MACH_DAVINCI_DA850_EVM)
+ adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0;
+ adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0;
+ adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0;
+#endif
debug_emac("- emac_close\n");
}
diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h
index f3d5a54..bbb5a9b 100644
--- a/include/configs/da850evm.h
+++ b/include/configs/da850evm.h
@@ -88,6 +88,7 @@
#define CONFIG_DRIVER_DAVINCI_I2C
#define CONFIG_SYS_I2C_SPEED 25000
#define CONFIG_SYS_I2C_SLAVE 10 /* Bogus, master-only in U-Boot */
+#define CONFIG_SYS_I2C_EXPANDER_ADDR 0x20
/*
* Flash & Environment