]> git.kernelconcepts.de Git - karo-tx-redboot.git/blobdiff - packages/devs/eth/arm/tx51karo/v1_0/include/devs_eth_arm_tx51.inl
karo: tx51: justify and adjust the delay required before releasing the ETN PHY strap...
[karo-tx-redboot.git] / packages / devs / eth / arm / tx51karo / v1_0 / include / devs_eth_arm_tx51.inl
index 1576cf1b2e1bb2f04ce661e8d7b5892d0d42f36f..ab5e1559ee7a7c76479af15b09feb12a63f47444 100644 (file)
@@ -58,6 +58,8 @@
 
 #ifdef CYGPKG_DEVS_ETH_PHY
 
+static bool mxc_fec_init(struct cyg_netdevtab_entry *tab);
+
 static char  mxc_fec_name[] = "mxc_fec";
 
 #define MX51_GPIO_ADDR(bank)                   (GPIO1_BASE_ADDR + (((bank) - 1) << 14))
@@ -70,8 +72,7 @@ static char  mxc_fec_name[] = "mxc_fec";
 //
 static char oui[3] = CYGDAT_DEVS_ETH_ARM_TX51KARO_OUI;
 
-bool
-cyg_plf_redboot_esa_validate(unsigned char *val)
+bool cyg_plf_redboot_esa_validate(unsigned char *val)
 {
        return (val[0] == oui[0]) && (val[1] == oui[1]) && (val[2] == oui[2]);
 }
@@ -79,8 +80,6 @@ cyg_plf_redboot_esa_validate(unsigned char *val)
 
 extern int tx51_mac_addr_program(unsigned char mac_addr[ETHER_ADDR_LEN]);
 
-#define dmb()  asm volatile("dmb" : : : "memory")
-
 static inline void tx51_write_reg(CYG_ADDRWORD base_addr, CYG_WORD32 offset, CYG_WORD32 val)
 {
        if (net_debug) {
@@ -105,121 +104,87 @@ static inline void tx51_set_reg(CYG_ADDRWORD base_addr, CYG_WORD32 offset,
        CYG_WORD32 val;
 
        HAL_READ_UINT32(base_addr + offset, val);
-       if (net_debug) diag_printf("Changing reg %08x from %08x to %08x\n", base_addr + offset, val,
-                                  (val & ~clr_mask) | set_mask);
+       if (net_debug) diag_printf("Changing reg %08x from %08x to %08x\n",
+                                                          base_addr + offset, val,
+                                                          (val & ~clr_mask) | set_mask);
        val = (val & ~clr_mask) | set_mask;
        HAL_WRITE_UINT32(base_addr + offset, val);
 }
 
 static struct tx51_gpio_setup {
        cyg_uint32 iomux_addr;
-       cyg_uint8 on_func;
-       cyg_uint8 off_func;
-       cyg_uint8 grp;
-       cyg_uint8 shift;
+       unsigned on_func:5,
+               off_func:5,
+               grp:3,
+               shift:5,
+               dir:1, /* 0: input; 1: output */
+               level:1;
 } tx51_fec_gpio_data[] = {
-       /* iomux reg offset,                    func,       gpgrp, */
-       /*                                                                    gpiofn,  gpshift, */
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_CS3,              0x12, 0x13, 3, 19, },
-       { IOMUXC_SW_MUX_CTL_PAD_EIM_EB2,                0x13, 0x11, 2, 22, },
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_RB3,              0x11, 0x13, 3, 11, },
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_D11,              0x12, 0x13, 3, 29, },
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_D9,               0x12, 0x13, 3, 31, },
-       { IOMUXC_SW_MUX_CTL_PAD_EIM_EB3,                0x13, 0x11, 2, 23, },
-       { IOMUXC_SW_MUX_CTL_PAD_EIM_CS2,                0x13, 0x11, 2, 27, },
-       { IOMUXC_SW_MUX_CTL_PAD_EIM_CS3,                0x13, 0x11, 2, 28, },
-       { IOMUXC_SW_MUX_CTL_PAD_EIM_CS4,                0x13, 0x11, 2, 29, },
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_RDY_INT,  0x11, 0x13, 3, 24, },
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_CS7,              0x11, 0x13, 3, 23, },
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_D8,               0x12, 0x13, 4,  0, },
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_CS4,              0x12, 0x13, 3, 20, },
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_CS5,              0x12, 0x13, 3, 21, },
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_CS6,              0x12, 0x13, 3, 22, },
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_RB2,              0x11, 0x13, 3, 10, },
-       { IOMUXC_SW_MUX_CTL_PAD_EIM_CS5,                0x13, 0x11, 2, 30, },
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_CS2,              0x13, 0x13, 3, 18, },
-};
-
-static struct tx51_gpio_setup tx51_fec_pwr_pins[] = {
-       { IOMUXC_SW_MUX_CTL_PAD_EIM_A20,                0x11, 0x11, 2, 14, }, /* PHY reset */
-       { IOMUXC_SW_MUX_CTL_PAD_GPIO1_3,                0x10, 0x10, 1,  3, }, /* PHY power enable */
-};
-
-static struct tx51_gpio_setup tx51_fec_strap_pins[] = {
-       { IOMUXC_SW_MUX_CTL_PAD_GPIO1_3,                0x10, 0x10, 1,  3, },
-       { IOMUXC_SW_MUX_CTL_PAD_NANDF_D9,               0x12, 0x13, 3, 31, },
-       { IOMUXC_SW_MUX_CTL_PAD_EIM_EB3,                0x13, 0x11, 2, 23, },
-       { IOMUXC_SW_MUX_CTL_PAD_EIM_CS2,                0x13, 0x11, 2, 27, },
-       { IOMUXC_SW_MUX_CTL_PAD_EIM_CS3,                0x13, 0x11, 2, 28, },
+       /* iomux reg offset,                    func,       gpgrp, in/out */
+       /*                                                                    gpiofn,  gpshft,level */
+       { IOMUXC_SW_MUX_CTL_PAD_EIM_A20,                0x11, 0x11, 2, 14, 1, 0, }, /* PHY reset */
+       { IOMUXC_SW_MUX_CTL_PAD_GPIO1_3,                0x10, 0x10, 1,  3, 1, 1, }, /* PHY power enable */
+       { IOMUXC_SW_MUX_CTL_PAD_NANDF_CS3,              0x02, 0x13, 3, 19, 1, 0, }, /* MDC */
+       { IOMUXC_SW_MUX_CTL_PAD_EIM_EB2,                0x03, 0x11, 2, 22, 1, 0, }, /* MDIO */
+       { IOMUXC_SW_MUX_CTL_PAD_NANDF_RB3,              0x01, 0x13, 3, 11, 0, }, /* RX_CLK */
+       { IOMUXC_SW_MUX_CTL_PAD_NANDF_D11,              0x02, 0x13, 3, 29, 0, }, /* RX_DV */
+       { IOMUXC_SW_MUX_CTL_PAD_NANDF_D9,               0x02, 0x13, 3, 31, 1, 1, }, /* RXD0/Mode0 */
+       { IOMUXC_SW_MUX_CTL_PAD_EIM_EB3,                0x03, 0x11, 2, 23, 1, 1, }, /* RXD1/Mode1 */
+       { IOMUXC_SW_MUX_CTL_PAD_EIM_CS2,                0x03, 0x11, 2, 27, 1, 1, }, /* RXD2/Mode2 */
+       { IOMUXC_SW_MUX_CTL_PAD_EIM_CS3,                0x03, 0x11, 2, 28, 1, 1, }, /* RXD3/nINTSEL */
+       { IOMUXC_SW_MUX_CTL_PAD_EIM_CS4,                0x03, 0x11, 2, 29, 0, }, /* RX_ER/RXD4 */
+       { IOMUXC_SW_MUX_CTL_PAD_NANDF_RDY_INT,  0x01, 0x13, 3, 24, 0, }, /* TX_CLK */
+       { IOMUXC_SW_MUX_CTL_PAD_NANDF_CS7,              0x01, 0x13, 3, 23, 1, 0, }, /* TX_EN */
+       { IOMUXC_SW_MUX_CTL_PAD_NANDF_D8,               0x02, 0x13, 4,  0, 1, 0, }, /* TXD0 */
+       { IOMUXC_SW_MUX_CTL_PAD_NANDF_CS4,              0x02, 0x13, 3, 20, 1, 0, }, /* TXD1 */
+       { IOMUXC_SW_MUX_CTL_PAD_NANDF_CS5,              0x02, 0x13, 3, 21, 1, 0, }, /* TXD2 */
+       { IOMUXC_SW_MUX_CTL_PAD_NANDF_CS6,              0x02, 0x13, 3, 22, 1, 0, }, /* TXD3 */
+       { IOMUXC_SW_MUX_CTL_PAD_NANDF_RB2,              0x01, 0x13, 3, 10, 1, 0, }, /* COL/RMII/CRSDV */
+       { IOMUXC_SW_MUX_CTL_PAD_EIM_CS5,                0x03, 0x11, 2, 30, 1, 0, }, /* CRS */
+       { IOMUXC_SW_MUX_CTL_PAD_NANDF_CS2,              0x03, 0x13, 3, 18, 0, }, /* nINT/TX_ER/TXD4 */
 };
 
-static inline void tx51_phy_power_off(void)
+static inline void tx51_phy_gpio_init(void)
 {
        int i;
 
-       if (net_debug) diag_printf("Switching PHY POWER off\n");
-#if 1
-       for (i = 0; i < NUM_ELEMS(tx51_fec_gpio_data); i++) {
-               struct tx51_gpio_setup *gs = &tx51_fec_gpio_data[i];
-
-               if (net_debug) diag_printf("%s: GPIO%d_%d[%d] is %d\n", __FUNCTION__,
-                                                                  gs->grp, gs->shift, i,
-                                                                  gpio_tst_bit(gs->grp, gs->shift));
-       }
-#endif
-       /* deassert all pins attached to the PHY */
-       for (i = 0; i < NUM_ELEMS(tx51_fec_pwr_pins); i++) {
-               struct tx51_gpio_setup *gs = &tx51_fec_pwr_pins[i];
+       if (net_debug) diag_printf("PHY GPIO init\n");
 
-               tx51_set_reg(MX51_GPIO_ADDR(gs->grp),
-                                        GPIO_DR, 0, 1 << gs->shift);
-               tx51_set_reg(MX51_GPIO_ADDR(gs->grp),
-                                        GPIO_GDIR, 1 << gs->shift, 0);
-       }
+       /* setup all pins attached to the PHY to required level */
        for (i = 0; i < NUM_ELEMS(tx51_fec_gpio_data); i++) {
                struct tx51_gpio_setup *gs = &tx51_fec_gpio_data[i];
-#if 0
-               tx51_set_reg(MX51_GPIO_ADDR(gs->grp),
-                                        GPIO_GDIR, 0, 1 << gs->shift);
-#else
+
                tx51_set_reg(MX51_GPIO_ADDR(gs->grp),
-                                        GPIO_DR, 0, 1 << gs->shift);
+                                        GPIO_DR, gs->level << gs->shift, !gs->level << gs->shift);
                tx51_set_reg(MX51_GPIO_ADDR(gs->grp),
                                         GPIO_GDIR, 1 << gs->shift, 0);
-#endif
-               tx51_write_reg(0, gs->iomux_addr, gs->off_func);
+               tx51_write_reg(gs->iomux_addr, 0, gs->off_func);
        }
        for (i = 0; i < NUM_ELEMS(tx51_fec_gpio_data); i++) {
                struct tx51_gpio_setup *gs = &tx51_fec_gpio_data[i];
 
-               if (gpio_tst_bit(gs->grp, gs->shift)) {
-                       diag_printf("%s: GPIO%d_%d[%d] is not low\n", __FUNCTION__,
-                                               gs->grp, gs->shift, i);
+               if (gs->dir) {
+                       if (gs->level ^ gpio_tst_bit(gs->grp, gs->shift)) {
+                               diag_printf("%s: GPIO%d_%d[%d] is not %s\n", __FUNCTION__,
+                                                       gs->grp, gs->shift, i, gs->level ? "HIGH" : "LOW");
+                       }
                }
        }
-       if (net_debug) diag_printf("PHY POWER off done\n");
+       if (net_debug) diag_printf("PHY GPIO init done\n");
 }
 
-static bool mxc_fec_init(struct cyg_netdevtab_entry *tab);
 static bool tx51_fec_init(struct cyg_netdevtab_entry *tab)
 {
-#if 1
        cyg_bool esa_set;
        int ok;
 
        /* Check, whether MAC address is enabled */
        ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
                                                                         "fec_esa", &esa_set, CONFIG_BOOL);
-#if 0
-ok |= 0;
-//esa_set |= ok;
-net_debug |= 1;
-#endif
        if (!(ok && esa_set)) {
                diag_printf("FEC disabled; set fec_esa=true to enable networking\n");
                return false;
        }
-#endif
        return mxc_fec_init(tab);
 }
 
@@ -227,143 +192,47 @@ static void tx51_fec_phy_init(void)
 {
        int i;
        int phy_reset_delay = 100;
-       int dbg = net_debug;
 
-#if 0
-       net_debug |= 1;
-#endif
        /*
         * make sure the ETH PHY strap pins are pulled to the right voltage
         * before deasserting the PHY reset GPIO
         */
-       /* assert FEC PHY Reset (GPIO2_14) and switch PHY power on (GPIO1_3) */
-
-#if 0
-       tx51_phy_power_off();
-#endif
+       tx51_phy_gpio_init();
 
+       /* LAN8700 requires 21ms to power up */
+       phy_reset_delay = 22000;
        if (!gpio_tst_bit(1, 3)) {
-               if (0 || net_debug) diag_printf("Switching PHY POWER on\n");
-               gpio_clr_bit(2, 14);
-               gpio_set_bit(1, 3);
-               /* wait for 22ms for LAN8700 to power up */
-               phy_reset_delay = 22000;
-#if 1
-               if (!gpio_tst_bit(1, 3)) {
-                       diag_printf("**Failed to switch PHY power on: GPIO1_PSR[%08lx]=%08x\n",
-                                               MX51_GPIO_ADDR(1) + GPIO_PSR,
-                                               tx51_read_reg(MX51_GPIO_ADDR(1), GPIO_PSR));
-               }
-#endif
-#if 1
-               if (gpio_tst_bit(2, 14)) {
-                       diag_printf("**Failed to assert PHY reset: GPIO2_PSR[%08lx]=%08x\n",
-                                               MX51_GPIO_ADDR(2) + GPIO_PSR,
-                                               tx51_read_reg(MX51_GPIO_ADDR(2), GPIO_PSR));
-               }
-#endif
-       } else {
-               if (0 || net_debug) diag_printf("Asserting PHY RESET\n");
-               gpio_clr_bit(2, 14);
-#if 1
-               if (gpio_tst_bit(2, 14)) {
-                       diag_printf("**Failed to assert PHY reset: GPIO2_PSR[%08lx]=%08x\n",
-                                               MX51_GPIO_ADDR(2) + GPIO_PSR,
-                                               tx51_read_reg(MX51_GPIO_ADDR(2), GPIO_PSR));
-               }
-#endif
+               diag_printf("**Failed to switch PHY power on: GPIO1_PSR[%08lx]=%08x\n",
+                                       MX51_GPIO_ADDR(1) + GPIO_PSR,
+                                       tx51_read_reg(MX51_GPIO_ADDR(1), GPIO_PSR));
        }
-       for (i = 0; i < NUM_ELEMS(tx51_fec_gpio_data); i++) {
-               struct tx51_gpio_setup *gs = &tx51_fec_gpio_data[i];
-               int j;
-               int strap = 0;
-
-               for (j = 0; j < NUM_ELEMS(tx51_fec_strap_pins); j++) {
-                       struct tx51_gpio_setup *sp = &tx51_fec_strap_pins[j];
-
-                       if (gs->grp == sp->grp && gs->shift == sp->shift) {
-                               strap = 1;
-                               break;
-                       }
-               }
-               if (strap) {
-                       gpio_set_bit(gs->grp, gs->shift);
-                       if (net_debug) diag_printf("Setting GPIO%d_%d[%d] high\n",
-                                                                          gs->grp, gs->shift, i);
-               } else {
-                       gpio_clr_bit(gs->grp, gs->shift);
-                       if (net_debug) diag_printf("Setting GPIO%d_%d[%d] low\n",
-                                                                          gs->grp, gs->shift, i);
-               }
-               tx51_set_reg(MX51_GPIO_ADDR(gs->grp),
-                                        GPIO_GDIR, 1 << gs->shift, 0);
-               tx51_write_reg(0, gs->iomux_addr,
-                                          gs->off_func);
-       }
-#if 1
-       /* configure FEC strap pins to their required values */
-       for (i = 0; i < NUM_ELEMS(tx51_fec_strap_pins); i++) {
-               struct tx51_gpio_setup *gs = &tx51_fec_strap_pins[i];
-
-               if (net_debug) diag_printf("Asserting GPIO%d_%d\n", gs->grp,
-                                                                  gs->shift);
-               tx51_set_reg(MX51_GPIO_ADDR(gs->grp),
-                                        GPIO_GDIR, 1 << gs->shift, 0);
-               tx51_set_reg(MX51_GPIO_ADDR(gs->grp),
-                                        GPIO_DR, 1 << gs->shift, 0);
-               tx51_write_reg(0, gs->iomux_addr,
-                                          gs->off_func);
-               gpio_set_bit(gs->grp, gs->shift);
-               if (!gpio_tst_bit(gs->grp, gs->shift)) {
-                       diag_printf("**Failed to assert GPIO%d_%d: GPIO%d_PSR[%08lx]=%08x\n",
-                                               gs->grp, gs->shift, gs->grp,
-                                               MX51_GPIO_ADDR(gs->grp) + GPIO_PSR,
-                                               tx51_read_reg(MX51_GPIO_ADDR(gs->grp), GPIO_PSR));
-               }
+       if (gpio_tst_bit(2, 14)) {
+               diag_printf("**Failed to assert PHY reset: GPIO2_PSR[%08lx]=%08x\n",
+                                       MX51_GPIO_ADDR(2) + GPIO_PSR,
+                                       tx51_read_reg(MX51_GPIO_ADDR(2), GPIO_PSR));
        }
-#endif
-       for (i = 0; i < NUM_ELEMS(tx51_fec_gpio_data); i++) {
-               struct tx51_gpio_setup *gs = &tx51_fec_gpio_data[i];
-               int j;
-               int strap = 0;
 
-               for (j = 0; j < NUM_ELEMS(tx51_fec_strap_pins); j++) {
-                       struct tx51_gpio_setup *sp = &tx51_fec_strap_pins[j];
-
-                       if (gs->grp == sp->grp && gs->shift == sp->shift) {
-                               strap = 1;
-                               break;
-                       }
-               }
-               if (strap) {
-                       if (!gpio_tst_bit(gs->grp, gs->shift)) {
-                               diag_printf("GPIO%d_%d[%d] is low instead of high\n",
-                                                       gs->grp, gs->shift, i);
-                       }
-               } else {
-                       if (gpio_tst_bit(gs->grp, gs->shift)) {
-                               diag_printf("GPIO%d_%d[%d] is high instead of low\n",
-                                                       gs->grp, gs->shift, i);
-                       }
-               }
-       }
-       /* wait for 100us according to LAN8700 spec. before ... */
+       /* wait the specified time according to LAN8700 spec. before ... */
        HAL_DELAY_US(phy_reset_delay);
        /* ... deasserting FEC PHY reset */
-       if (0 || net_debug) diag_printf("Releasing PHY RESET\n");
+       if (net_debug) diag_printf("Releasing PHY RESET\n");
        gpio_set_bit(2, 14);
        if (!gpio_tst_bit(2, 14)) {
                diag_printf("**Failed to release PHY reset\n");
        }
+       /*
+        * Due to an RC-filter in the PHY RESET line, a minimum
+        * delay of 535us is required to let the RESET line rise
+        * above the logic high threshold of the PHY input pin.
+         */
+       HAL_DELAY_US(550);
 
        /* configure all FEC pins to their required functions */
        for (i = 0; i < NUM_ELEMS(tx51_fec_gpio_data); i++) {
                struct tx51_gpio_setup *gs = &tx51_fec_gpio_data[i];
 
-               tx51_write_reg(0, gs->iomux_addr, gs->on_func);
-               HAL_DELAY_US(10000);
+               tx51_write_reg(gs->iomux_addr, 0, gs->on_func);
        }
-       net_debug = dbg;
 }
 
 ETH_PHY_REG_LEVEL_ACCESS_FUNS(eth0_phy,
@@ -481,13 +350,13 @@ NETDEVTAB_ENTRY(mxc_fec_netdev,
 RedBoot_config_option("Set FEC network hardware address [MAC]",
                                          fec_esa,
                                          ALWAYS_ENABLED, true,
-                                         CONFIG_BOOL, false
-                                        );
+                                         CONFIG_BOOL, true
+                                         );
 RedBoot_config_option("FEC network hardware address [MAC]",
                                          fec_esa_data,
                                          "fec_esa", true,
                                          CONFIG_ESA, 0
-                                        );
+                                         );
 #endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
 
 #ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT