X-Git-Url: https://git.archive.openwrt.org/?p=openwrt.git;a=blobdiff_plain;f=target%2Flinux%2Far71xx%2Ffiles%2Farch%2Fmips%2Fath79%2Fdev-eth.c;h=d7f3595b88035ecb61a5641f7a0a6eec05b970ee;hp=45817e171ac02b0b50f1ed8ab0dba528b59448d1;hb=9bf369fc7e407f8ee8f3910d7cb2f44f049a7261;hpb=62977660d8f0b0f77c7d6ad40f9496336a1a8e26 diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c index 45817e171a..d7f3595b88 100644 --- a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -146,6 +147,31 @@ static void ath79_mii_ctrl_set_speed(unsigned int reg, unsigned int speed) iounmap(base); } +static unsigned long ar934x_get_mdio_ref_clock(void) +{ + void __iomem *base; + unsigned long ret; + u32 t; + + base = ioremap(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); + + ret = 0; + t = __raw_readl(base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG); + if (t & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) { + ret = 100 * 1000 * 1000; + } else { + struct clk *clk; + + clk = clk_get(NULL, "ref"); + if (!IS_ERR(clk)) + ret = clk_get_rate(clk); + } + + iounmap(base); + + return ret; +} + void __init ath79_register_mdio(unsigned int id, u32 phy_mask) { struct platform_device *mdio_dev; @@ -154,7 +180,9 @@ void __init ath79_register_mdio(unsigned int id, u32 phy_mask) if (ath79_soc == ATH79_SOC_AR9341 || ath79_soc == ATH79_SOC_AR9342 || - ath79_soc == ATH79_SOC_AR9344) + ath79_soc == ATH79_SOC_AR9344 || + ath79_soc == ATH79_SOC_QCA9556 || + ath79_soc == ATH79_SOC_QCA9558) max_id = 1; else max_id = 0; @@ -175,6 +203,8 @@ void __init ath79_register_mdio(unsigned int id, u32 phy_mask) case ATH79_SOC_AR9341: case ATH79_SOC_AR9342: case ATH79_SOC_AR9344: + case ATH79_SOC_QCA9556: + case ATH79_SOC_QCA9558: if (id == 0) { mdio_dev = &ath79_mdio0_device; mdio_data = &ath79_mdio0_data; @@ -215,11 +245,24 @@ void __init ath79_register_mdio(unsigned int id, u32 phy_mask) case ATH79_SOC_AR9341: case ATH79_SOC_AR9342: case ATH79_SOC_AR9344: + if (id == 1) { + mdio_data->builtin_switch = 1; + mdio_data->ref_clock = ar934x_get_mdio_ref_clock(); + mdio_data->mdio_clock = 6250000; + } + mdio_data->is_ar934x = 1; + break; + + case ATH79_SOC_QCA9558: if (id == 1) mdio_data->builtin_switch = 1; mdio_data->is_ar934x = 1; break; + case ATH79_SOC_QCA9556: + mdio_data->is_ar934x = 1; + break; + default: break; } @@ -319,6 +362,26 @@ static void ar934x_set_speed_ge0(int speed) iounmap(base); } +static void qca955x_set_speed_xmii(int speed) +{ + void __iomem *base; + u32 val = ath79_get_eth_pll(0, speed); + + base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); + __raw_writel(val, base + QCA955X_PLL_ETH_XMII_CONTROL_REG); + iounmap(base); +} + +static void qca955x_set_speed_sgmii(int speed) +{ + void __iomem *base; + u32 val = ath79_get_eth_pll(1, speed); + + base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); + __raw_writel(val, base + QCA955X_PLL_ETH_SGMII_CONTROL_REG); + iounmap(base); +} + static void ath79_set_speed_dummy(int speed) { } @@ -376,8 +439,8 @@ static struct resource ath79_eth0_resources[] = { }, { .name = "mac_irq", .flags = IORESOURCE_IRQ, - .start = ATH79_CPU_IRQ_GE0, - .end = ATH79_CPU_IRQ_GE0, + .start = ATH79_CPU_IRQ(4), + .end = ATH79_CPU_IRQ(4), }, }; @@ -404,8 +467,8 @@ static struct resource ath79_eth1_resources[] = { }, { .name = "mac_irq", .flags = IORESOURCE_IRQ, - .start = ATH79_CPU_IRQ_GE1, - .end = ATH79_CPU_IRQ_GE1, + .start = ATH79_CPU_IRQ(5), + .end = ATH79_CPU_IRQ(5), }, }; @@ -504,6 +567,8 @@ static void __init ath79_init_eth_pll_data(unsigned int id) case ATH79_SOC_AR9341: case ATH79_SOC_AR9342: case ATH79_SOC_AR9344: + case ATH79_SOC_QCA9556: + case ATH79_SOC_QCA9558: pll_10 = AR934X_PLL_VAL_10; pll_100 = AR934X_PLL_VAL_100; pll_1000 = AR934X_PLL_VAL_1000; @@ -579,6 +644,18 @@ static int __init ath79_setup_phy_if_mode(unsigned int id, } break; + case ATH79_SOC_QCA9556: + case ATH79_SOC_QCA9558: + switch (pdata->phy_if_mode) { + case PHY_INTERFACE_MODE_MII: + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_SGMII: + break; + default: + return -EINVAL; + } + break; + default: BUG(); } @@ -625,6 +702,18 @@ static int __init ath79_setup_phy_if_mode(unsigned int id, } break; + case ATH79_SOC_QCA9556: + case ATH79_SOC_QCA9558: + switch (pdata->phy_if_mode) { + case PHY_INTERFACE_MODE_MII: + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_SGMII: + break; + default: + return -EINVAL; + } + break; + default: BUG(); } @@ -652,6 +741,30 @@ void __init ath79_setup_ar933x_phy4_switch(bool mac, bool mdio) iounmap(base); } +void __init ath79_setup_ar934x_eth_cfg(u32 mask) +{ + void __iomem *base; + u32 t; + + base = ioremap(AR934X_GMAC_BASE, AR934X_GMAC_SIZE); + + t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); + + t &= ~(AR934X_ETH_CFG_RGMII_GMAC0 | + AR934X_ETH_CFG_MII_GMAC0 | + AR934X_ETH_CFG_GMII_GMAC0 | + AR934X_ETH_CFG_SW_ONLY_MODE | + AR934X_ETH_CFG_SW_PHY_SWAP); + + t |= mask; + + __raw_writel(t, base + AR934X_GMAC_REG_ETH_CFG); + /* flush write */ + __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); + + iounmap(base); +} + static int ath79_eth_instance __initdata; void __init ath79_register_eth(unsigned int id) { @@ -850,6 +963,30 @@ void __init ath79_register_eth(unsigned int id) pdata->fifo_cfg3 = 0x01f00140; break; + case ATH79_SOC_QCA9556: + case ATH79_SOC_QCA9558: + if (id == 0) { + pdata->reset_bit = QCA955X_RESET_GE0_MAC | + QCA955X_RESET_GE0_MDIO; + pdata->set_speed = qca955x_set_speed_xmii; + } else { + pdata->reset_bit = QCA955X_RESET_GE1_MAC | + QCA955X_RESET_GE1_MDIO; + pdata->set_speed = qca955x_set_speed_sgmii; + } + + pdata->ddr_flush = ath79_ddr_no_flush; + pdata->has_gbit = 1; + pdata->is_ar724x = 1; + + if (!pdata->fifo_cfg1) + pdata->fifo_cfg1 = 0x0010ffff; + if (!pdata->fifo_cfg2) + pdata->fifo_cfg2 = 0x015500aa; + if (!pdata->fifo_cfg3) + pdata->fifo_cfg3 = 0x01f00140; + break; + default: BUG(); } @@ -857,6 +994,7 @@ void __init ath79_register_eth(unsigned int id) switch (pdata->phy_if_mode) { case PHY_INTERFACE_MODE_GMII: case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_SGMII: if (!pdata->has_gbit) { printk(KERN_ERR "ar71xx: no gbit available on eth%d\n", id); @@ -891,6 +1029,11 @@ void __init ath79_register_eth(unsigned int id) pdata->mii_bus_dev = &ath79_mdio1_device.dev; break; + case ATH79_SOC_QCA9556: + case ATH79_SOC_QCA9558: + /* don't assign any MDIO device by default */ + break; + default: pdata->mii_bus_dev = &ath79_mdio0_device.dev; break; @@ -951,7 +1094,10 @@ void __init ath79_init_mac(unsigned char *dst, const unsigned char *src, { int t; - if (!is_valid_ether_addr(src)) { + if (!dst) + return; + + if (!src || !is_valid_ether_addr(src)) { memset(dst, '\0', ETH_ALEN); return; } @@ -971,7 +1117,10 @@ void __init ath79_init_local_mac(unsigned char *dst, const unsigned char *src) { int i; - if (!is_valid_ether_addr(src)) { + if (!dst) + return; + + if (!src || !is_valid_ether_addr(src)) { memset(dst, '\0', ETH_ALEN); return; }