#
cdl_option CYGHWR_HAL_ARM_SOC_PLL_REF_CLOCK {
# Flavor: data
- user_value 33554432
- # value_source user
+ # No user value, uncomment the following line to provide one.
+ # user_value 26000000
+ # value_source default
# Default value: 26000000
# Legal values: 26000000 27000000 33554432 32768000
};
#
cdl_option CYGHWR_HAL_ARM_SOC_PLL_REF_CLOCK {
# Flavor: data
- user_value 33554432
- # value_source user
+ # No user value, uncomment the following line to provide one.
+ # user_value 26000000
+ # value_source default
# Default value: 26000000
# Legal values: 26000000 27000000 33554432 32768000
};
# Legal values: 0x10000000 0x08000000 0x04000000
};
+# SDRAM clock
+# This option specifies the SDRAM clock im MHz of the TX51 module.
+#
+cdl_option CYGNUM_HAL_ARM_TX51_SDRAM_CLK {
+ # Flavor: data
+ # No user value, uncomment the following line to provide one.
+ # user_value 166
+ # value_source default
+ # Default value: 166
+ # Legal values: 166 200
+};
+
# Enable low level debugging with LED
# This option enables low level debugging by blink codes
# of the LED on STK5.
struct tx25_gpio_setup *gs = &tx25_fec_gpio_data[i];
tx25_write_reg(IOMUXC_BASE_ADDR, gs->iomux_addr,
- gs->off_func);
+ gs->off_func);
if (gs->on_func & 0x80) {
/* configure as input */
tx25_set_reg(MX25_GPIO_ADDR(gs->grp),
GPIO_GDIR, 1 << gs->shift, 0);
}
tx25_write_reg(IOMUXC_BASE_ADDR, gs->iomux_addr,
- gs->off_func);
+ gs->off_func);
}
for (i = 0; i < NUM_ELEMS(tx25_fec_gpio_data); i++) {
struct tx25_gpio_setup *gs = &tx25_fec_gpio_data[i];
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);
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "fec_esa", &esa_set, CONFIG_BOOL);
if (!(ok && esa_set)) {
diag_printf("FEC disabled; set fec_esa=true to enable networking\n");
return false;
tx27_set_reg(SOC_GPIOB_BASE + GPIO_DR, 0, GPR_MASK(30));
}
- const unsigned int phy_mode_mask = 0x1060;
- // deassert PD0-15 (except 5,6,12 => PHY MODE[0..2])
+ const unsigned int phy_mode_mask = 0x10e0;
+ // deassert PD0-15 (except 5,6,7,12 => PHY MODE[0..2], INTSEL)
tx27_set_reg(SOC_GPIOD_BASE + GPIO_OCR1, 0xffffffff, 0);
tx27_set_reg(SOC_GPIOD_BASE + GPIO_DR, phy_mode_mask, ~phy_mode_mask);
tx27_set_reg(SOC_GPIOD_BASE + GPIO_DDIR, 0xffff, 0);
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) {
};
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, },
+ { IOMUXC_SW_MUX_CTL_PAD_GPIO1_3, 0x10, 0x10, 1, 3, }, /* PHY Power enable */
+ { IOMUXC_SW_MUX_CTL_PAD_NANDF_D9, 0x12, 0x13, 3, 31, }, /* Mode[0] */
+ { IOMUXC_SW_MUX_CTL_PAD_EIM_EB3, 0x13, 0x11, 2, 23, }, /* Mode[1] */
+ { IOMUXC_SW_MUX_CTL_PAD_EIM_CS2, 0x13, 0x11, 2, 27, }, /* Mode[2] */
+#if 0
+ { IOMUXC_SW_MUX_CTL_PAD_EIM_CS3, 0x13, 0x11, 2, 28, }, /* nINTSEL */
+#endif
};
static inline void tx51_phy_power_off(void)
mxc_fec_reg_write(hw_reg, paur, value << 16);
}
-/*!
- * This function enables the FEC for reception of packets
- */
-static void
-mxc_fec_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
-{
- mxc_fec_priv_t *priv = sc ? sc->driver_private : NULL;
- volatile mxc_fec_reg_t *hw_reg = priv ? priv->hw_reg : NULL;
-
- if (!(priv && hw_reg)) {
- diag_printf("BUG[start]: FEC driver not initialized\n");
- return;
- }
- if (enaddr == NULL) {
- diag_printf("BUG[start]: no MAC address supplied\n");
- return;
- }
- mxc_fec_set_mac_address(hw_reg, enaddr);
-
- priv->tx_busy = 0;
- mxc_fec_reg_write(hw_reg, rdar, mxc_fec_reg_read(hw_reg, rdar) | FEC_RX_TX_ACTIVE);
- mxc_fec_reg_write(hw_reg, ecr, mxc_fec_reg_read(hw_reg, ecr) | FEC_ETHER_EN);
#ifdef CYGPKG_HAL_ARM_MX25
+static int mxc_fec_mii_setup(mxc_fec_priv_t *priv)
+{
+ volatile mxc_fec_reg_t *hw_reg = priv->hw_reg;
/*
* setup the MII gasket for RMII mode
*/
hal_delay_us(FEC_COMMON_TICK);
/* configure gasket for RMII, 50 MHz, no loopback, and no echo */
- mxc_fec_reg_write16(hw_reg, miigsk_cfgr, MIIGSK_CFGR_IF_MODE_RMII);
+ mxc_fec_reg_write16(hw_reg, miigsk_cfgr, MIIGSK_CFGR_IF_MODE_RMII |
+ ((!priv || (priv->status & FEC_STATUS_100M)) ?
+ 0 : MIIGSK_CFGR_FRCONT));
/* re-enable the gasket */
mxc_fec_reg_write16(hw_reg, miigsk_enr, MIIGSK_ENR_EN);
while ((mxc_fec_reg_read16(hw_reg, miigsk_enr) & MIIGSK_ENR_READY) == 0) {
if (--max_loops <= 0) {
diag_printf("WAIT for MII Gasket ready timed out\n");
- break;
+ return -1;
}
}
+ return 0;
+}
+#else
+static inline int mxc_fec_mii_setup(mxc_fec_priv_t *priv)
+{
+ return 0;
+}
#endif
+
+/*!
+ * This function enables the FEC for reception of packets
+ */
+static void
+mxc_fec_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ mxc_fec_priv_t *priv = sc ? sc->driver_private : NULL;
+ volatile mxc_fec_reg_t *hw_reg = priv ? priv->hw_reg : NULL;
+
+ if (!(priv && hw_reg)) {
+ diag_printf("BUG[start]: FEC driver not initialized\n");
+ return;
+ }
+ if (enaddr == NULL) {
+ diag_printf("BUG[start]: no MAC address supplied\n");
+ return;
+ }
+ mxc_fec_set_mac_address(hw_reg, enaddr);
+
+ priv->tx_busy = 0;
+ mxc_fec_reg_write(hw_reg, rdar, mxc_fec_reg_read(hw_reg, rdar) | FEC_RX_TX_ACTIVE);
+ mxc_fec_reg_write(hw_reg, ecr, mxc_fec_reg_read(hw_reg, ecr) | FEC_ETHER_EN);
}
/*!
volatile mxc_fec_reg_t *hw_reg = priv ? priv->hw_reg : NULL;
unsigned long value;
int dbg = net_debug;
+ static unsigned long last_poll;
+ int poll_intvl = (priv->status & FEC_STATUS_LINK_ON) ? 100 : 10;
if (priv == NULL || hw_reg == NULL) {
diag_printf("BUG[POLL]: FEC driver not initialized\n");
priv->tx_busy = 0;
} else {
if (value & FEC_EVENT_TX) {
+ last_poll = 0;
sc->funs->eth_drv->tx_done(sc, priv->tx_key, 0);
priv->tx_busy = 0;
}
}
-
if (value & FEC_EVENT_RX) {
+ last_poll = 0;
mxc_fec_check_rx_bd(sc);
}
if (value & FEC_EVENT_HBERR) {
- diag_printf("WARNGING[POLL]: Hearbeat error!\n");
+ diag_printf("WARNGING[POLL]: Heartbeat error!\n");
}
if (value & FEC_EVENT_EBERR) {
diag_printf("WARNING[POLL]: Ethernet Bus Error!\n");
}
+
+ if (value & (FEC_EVENT_TX_ERR | FEC_EVENT_HBERR | FEC_EVENT_EBERR) ||
+ last_poll++ > poll_intvl) {
+#ifdef CYGPKG_DEVS_ETH_PHY
+ unsigned short value;
+ value = _eth_phy_state(priv->phy);
+#else
+ unsigned short value;
+ mxc_fec_mii_read(hw_reg, priv->phy_addr, 1, &value);
+#endif
+ last_poll = 0;
+ if (value & PHY_STATUS_LINK_ST) {
+ if (!(priv->status & FEC_STATUS_LINK_ON)) {
+ mxc_fec_phy_status(priv, value, true);
+ }
+ } else {
+ if (priv->status & FEC_STATUS_LINK_ON) {
+ mxc_fec_phy_status(priv, value, true);
+ }
+ }
+ }
}
static int
{
#ifdef CYGPKG_DEVS_ETH_PHY
if (value & ETH_PHY_STAT_LINK) {
+ int changed = !(dev->status & FEC_STATUS_LINK_ON);
+
dev->status |= FEC_STATUS_LINK_ON;
if (value & ETH_PHY_STAT_FDX) {
dev->status |= FEC_STATUS_FULL_DPLX;
dev->status &= ~FEC_STATUS_FULL_DPLX;
}
if (value & ETH_PHY_STAT_100MB) {
+ changed |= !(dev->status & ETH_PHY_STAT_100MB);
dev->status |= FEC_STATUS_100M;
} else {
+ changed |= !!(dev->status & ETH_PHY_STAT_100MB);
dev->status &= ~FEC_STATUS_100M;
}
+ if (changed) {
+ mxc_fec_mii_setup(dev);
+ }
} else {
dev->status &= ~FEC_STATUS_LINK_ON;
}
#else
+ int changed = 0;
mxc_fec_mii_read(dev->hw_reg, dev->phy_addr, PHY_STATUS_REG, &value);
if (value & PHY_STATUS_LINK_ST) {
+ changed |= !(dev->status & FEC_STATUS_LINK_ON);
dev->status |= FEC_STATUS_LINK_ON;
} else {
+ changed |= dev->status & FEC_STATUS_LINK_ON;
dev->status &= ~FEC_STATUS_LINK_ON;
}
dev->status &= ~FEC_STATUS_FULL_DPLX;
}
if (value & PHY_DIAG_RATE) {
+ changed |= !(dev->status & FEC_STATUS_100M);
dev->status |= FEC_STATUS_100M;
} else {
+ changed |= dev->status & FEC_STATUS_100M;
dev->status &= ~FEC_STATUS_100M;
}
+ if (changed) {
+ mxc_fec_mii_setup(dev);
+ }
#endif
if (!show) {
return;
This option specifies the SDRAM size of the TX51 module."
}
+ cdl_option CYGNUM_HAL_ARM_TX51_SDRAM_CLK {
+ display "SDRAM clock"
+ flavor data
+ legal_values { 166 200 }
+ default_value { 166 }
+ description "
+ This option specifies the SDRAM clock im MHz of the TX51 module."
+ }
+
cdl_option CYGOPT_HAL_ARM_TX51_DEBUG {
display "Enable low level debugging with LED"
flavor bool
#define ESDCTL_VAL (0x80000000 | (SREFR << 28) | (RA_BITS << 24) | (CA_BITS << 20) | \
(DSIZ << 16) | (SRT << 14) | (PWDT << 12))
-#define SDRAM_CLK 200
+#define SDRAM_CLK CYGNUM_HAL_ARM_TX51_SDRAM_CLK
+
#define NS_TO_CK(ns) (((ns) * SDRAM_CLK + 999) / 1000)
.macro CK_VAL, name, clks, offs
.endif
.endm
-#if SDRAM_SIZE <= SZ_128M
+#if SDRAM_CLK < 200
/* MT46H32M32LF-6 */
-NS_VAL tRFC, 125, 10 /* clks - 10 (0..15) */
-NS_VAL tXSR, 138, 25 /* clks - 25 (0..15) */
-NS_VAL tXP, 25, 1 /* clks - 1 (0..7) */
-CK_VAL tWTR, 1, 1 /* clks - 1 (0..1) */
-NS_VAL tRP, 18, 2 /* clks - 2 (0..3) */
-CK_VAL tMRD, 2, 1 /* clks - 1 (0..3) */
-NS_VAL tWR, 15, 2 /* clks - 2 (0..1) */
-NS_VAL tRAS, 42, 1 /* clks - 1 (0..15) */
-NS_VAL tRRD, 12, 1 /* clks - 1 (0..3) */
-NS_VAL tRCD, 18, 1 /* clks - 1 (0..7) */
-NS_VAL tRC, 60, 1 /* 0: 20 *: clks - 1 (0..15) */
+NS_VAL tRFC, 125, 10 /* clks - 10 (0..15) */
+NS_VAL tXSR, 138, 25 /* clks - 25 (0..15) */
+NS_VAL tXP, 25, 1 /* clks - 1 (0..7) */
+CK_VAL tWTR, 1, 1 /* clks - 1 (0..1) */
+NS_VAL tRP, 18, 2 /* clks - 2 (0..3) */
+CK_VAL tMRD, 2, 1 /* clks - 1 (0..3) */
+NS_VAL tWR, 15, 2 /* clks - 2 (0..1) */
+NS_VAL tRAS, 42, 1 /* clks - 1 (0..15) */
+NS_VAL tRRD, 12, 1 /* clks - 1 (0..3) */
+NS_VAL tRCD, 18, 1 /* clks - 1 (0..7) */
+NS_VAL tRC, 60, 1 /* 0: 20 *: clks - 1 (0..15) */
#else
/* MT46H64M32LF-5 or -6 */
-NS_VAL tRFC, 72, 10 /* clks - 10 (0..15) */
-NS_VAL tXSR, 113, 25 /* clks - 25 (0..15) */
-CK_VAL tXP, 2, 1 /* clks - 1 (0..7) */
-CK_VAL tWTR, 2, 1 /* clks - 1 (0..1) */
-NS_VAL tRP, 18, 2 /* clks - 2 (0..3) */
-CK_VAL tMRD, 2, 1 /* clks - 1 (0..3) */
-NS_VAL tWR, 15, 2 /* clks - 2 (0..1) */
-NS_VAL tRAS, 42, 1 /* clks - 1 (0..15) */
-NS_VAL tRRD, 12, 1 /* clks - 1 (0..3) */
-NS_VAL tRCD, 18, 1 /* clks - 1 (0..7) */
-NS_VAL tRC, 60, 1 /* 0: 20 *: clks - 1 (0..15) */
+NS_VAL tRFC, 72, 10 /* clks - 10 (0..15) */
+NS_VAL tXSR, 113, 25 /* clks - 25 (0..15) */
+CK_VAL tXP, 2, 1 /* clks - 1 (0..7) */
+CK_VAL tWTR, 2, 1 /* clks - 1 (0..1) */
+NS_VAL tRP, 18, 2 /* clks - 2 (0..3) */
+CK_VAL tMRD, 2, 1 /* clks - 1 (0..3) */
+NS_VAL tWR, 15, 2 /* clks - 2 (0..1) */
+NS_VAL tRAS, 42, 1 /* clks - 1 (0..15) */
+NS_VAL tRRD, 12, 1 /* clks - 1 (0..3) */
+NS_VAL tRCD, 18, 1 /* clks - 1 (0..7) */
+NS_VAL tRC, 60, 1 /* 0: 20 *: clks - 1 (0..15) */
#endif
#define ESDCFG_VAL ((tRFC << 28) | (tXSR << 24) | (tXP << 21) | \
#if SDRAM_CLK == 200
CCM_CBCDR_VAL3: .word 0x59E35100
#else
-CCM_CBCDR_VAL3: .word 0x21E35100
+CCM_CBCDR_VAL3: .word 0x01E35100
#endif
CCM_CBCMR_VAL1: .word 0x000010C0
CCM_CBCMR_VAL2: .word 0x000020C0
DDR_CLK,
NFC_CLK,
USB_CLK,
+ AXI_A_CLK,
+ AXI_B_CLK,
+ EMI_SLOW_CLK,
};
enum peri_clocks {
diag_printf("========================================\n");
diag_printf("%-16d%-16d%-16d\n\n", pll_clock(PLL1), pll_clock(PLL2),
pll_clock(PLL3));
- diag_printf("CPU\t\tAHB\t\tIPG\t\tEMI_CLK\n");
+ diag_printf("AXI_A\t\tAXI_B\t\tEMI_SLOW_CLK\n");
+ diag_printf("========================================================\n");
+ diag_printf("%-16d%-16d%-16d\n\n",
+ get_main_clock(AXI_A_CLK),
+ get_main_clock(AXI_B_CLK),
+ get_main_clock(EMI_SLOW_CLK));
+ diag_printf("CPU\t\tAHB\t\tIPG\t\tDDR_CLK\n");
diag_printf("========================================================\n");
diag_printf("%-16d%-16d%-16d%-16d\n\n",
get_main_clock(CPU_CLK),
pll = pll_clock(PLL1);
ret_val = pll / (pdf + 1);
break;
+
case AHB_CLK:
max_pdf = (cbcdr >> 10) & 0x7;
pll = get_periph_clk();
ret_val = pll / (max_pdf + 1);
break;
+
+ case AXI_A_CLK:
+ pdf = (cbcdr >> 16) & 0x7;
+ pll = get_periph_clk();
+ ret_val = pll / (pdf + 1);
+ break;
+
+ case AXI_B_CLK:
+ pdf = (cbcdr >> 19) & 0x7;
+ pll = get_periph_clk();
+ ret_val = pll / (pdf + 1);
+ break;
+
+ case EMI_SLOW_CLK:
+ pll = get_emi_core_clk();
+ pdf = (cbcdr >> 22) & 0x7;
+ ret_val = pll / (pdf + 1);
+ break;
+
case IPG_CLK:
max_pdf = (cbcdr >> 10) & 0x7;
ipg_pdf = (cbcdr >> 8) & 0x3;
pll = get_periph_clk();
ret_val = pll / ((max_pdf + 1) * (ipg_pdf + 1));
break;
+
case IPG_PER_CLK:
clk_sel = cbcmr & 1;
if (clk_sel == 0) {
ret_val = pll / ((max_pdf + 1) * (ipg_pdf + 1));
}
break;
+
case DDR_CLK:
if (cbcdr & (1 << 30)) {
pll = pll_clock(PLL1);
ret_val = pll / (pdf + 1);
break;
+
case NFC_CLK:
pdf = (cbcdr >> 22) & 0x7;
nfc_pdf = (cbcdr >> 13) & 0x7;
pll = get_emi_core_clk();
ret_val = pll / ((pdf + 1) * (nfc_pdf + 1));
break;
+
case USB_CLK:
clk_sel = (cscmr1 >> 22) & 3;
if (clk_sel == 0) {
max_pdf = (cscdr1 >> 6) & 0x3;
ret_val = pll / ((pdf + 1) * (max_pdf + 1));
break;
+
default:
diag_printf("Unknown clock: %d\n", clk);
return ERR_WRONG_CLK;