platform_device_register(&ar71xx_mdio_device);
}
+static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
+{
+ void __iomem *base;
+ u32 t;
+
+ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
+
+ t = __raw_readl(base + cfg_reg);
+ t &= ~(3 << shift);
+ t |= (2 << shift);
+ __raw_writel(t, base + cfg_reg);
+ udelay(100);
+
+ __raw_writel(pll_val, base + pll_reg);
+
+ t |= (3 << shift);
+ __raw_writel(t, base + cfg_reg);
+ udelay(100);
+
+ t &= ~(3 << shift);
+ __raw_writel(t, base + cfg_reg);
+ udelay(100);
+
+ printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n",
+ (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg));
+
+ iounmap(base);
+}
+
+static void ar71xx_set_pll_ge0(u32 val)
+{
+ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK,
+ val, AR71XX_ETH0_PLL_SHIFT);
+}
+
+static void ar71xx_set_pll_ge1(u32 val)
+{
+ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK,
+ val, AR71XX_ETH1_PLL_SHIFT);
+}
+
+static void ar91xx_set_pll_ge0(u32 val)
+{
+ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
+ val, AR91XX_ETH0_PLL_SHIFT);
+}
+
+static void ar91xx_set_pll_ge1(u32 val)
+{
+ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
+ val, AR91XX_ETH1_PLL_SHIFT);
+}
+
+static void ar71xx_ddr_flush_ge0(void)
+{
+ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0);
+}
+
+static void ar71xx_ddr_flush_ge1(void)
+{
+ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1);
+}
+
+static void ar91xx_ddr_flush_ge0(void)
+{
+ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0);
+}
+
+static void ar91xx_ddr_flush_ge1(void)
+{
+ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1);
+}
+
static struct resource ar71xx_eth0_resources[] = {
{
.name = "mac_base",
struct ag71xx_platform_data ar71xx_eth0_data = {
.reset_bit = RESET_MODULE_GE0_MAC,
- .flush_reg = AR71XX_DDR_REG_FLUSH_GE0,
};
static struct platform_device ar71xx_eth0_device = {
struct ag71xx_platform_data ar71xx_eth1_data = {
.reset_bit = RESET_MODULE_GE1_MAC,
- .flush_reg = AR71XX_DDR_REG_FLUSH_GE1,
};
static struct platform_device ar71xx_eth1_device = {
pdata = pdev->dev.platform_data;
switch (ar71xx_soc) {
+ case AR71XX_SOC_AR7130:
+ pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
+ : ar71xx_ddr_flush_ge0;
+ pdata->set_pll = id ? ar71xx_set_pll_ge1
+ : ar71xx_set_pll_ge0;
+ break;
+
case AR71XX_SOC_AR7141:
case AR71XX_SOC_AR7161:
- case AR71XX_SOC_AR9132:
+ pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
+ : ar71xx_ddr_flush_ge0;
+ pdata->set_pll = id ? ar71xx_set_pll_ge1
+ : ar71xx_set_pll_ge0;
pdata->has_gbit = 1;
break;
- case AR71XX_SOC_AR7130:
case AR71XX_SOC_AR9130:
+ pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
+ : ar91xx_ddr_flush_ge0;
+ pdata->set_pll = id ? ar91xx_set_pll_ge1
+ : ar91xx_set_pll_ge0;
+ break;
+
+ case AR71XX_SOC_AR9132:
+ pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
+ : ar91xx_ddr_flush_ge0;
+ pdata->set_pll = id ? ar91xx_set_pll_ge1
+ : ar91xx_set_pll_ge0;
+ pdata->has_gbit = 1;
break;
default:
case PHY_INTERFACE_MODE_GMII:
case PHY_INTERFACE_MODE_RGMII:
if (!pdata->has_gbit) {
- printk(KERN_ERR "ar71xx: no gigabit available on eth%d\n",
+ printk(KERN_ERR "ar71xx: no gbit available on eth%d\n",
id);
return;
}
u32 freq;
u32 div;
- pll = ar71xx_pll_rr(PLL_REG_CPU_PLL_CFG);
+ pll = ar71xx_pll_rr(AR91XX_PLL_REG_CPU_CONFIG);
div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK);
freq = div * AR91XX_BASE_FREQ;
u32 freq;
u32 div;
- pll = ar71xx_pll_rr(PLL_REG_CPU_PLL_CFG);
+ pll = ar71xx_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
freq = div * AR71XX_BASE_FREQ;
#define ETH_FCS_LEN 4
#define AG71XX_DRV_NAME "ag71xx"
-#define AG71XX_DRV_VERSION "0.4.4"
+#define AG71XX_DRV_VERSION "0.5.0"
#define AG71XX_NAPI_TX 1
reg -= AG71XX_REG_MAC_IFCTL;
ret = __raw_readl(ag->mac_base2 + reg);
break;
+ default:
+ BUG();
}
return ret;
desc = &ring->descs[i];
spin_lock_irqsave(&ag->lock, flags);
- ar71xx_ddr_flush(pdata->flush_reg);
+ pdata->ddr_flush();
spin_unlock_irqrestore(&ag->lock, flags);
if (!ag71xx_desc_empty(desc))
DBG("%s: processing TX ring\n", ag->dev->name);
#ifdef AG71XX_NAPI_TX
- ar71xx_ddr_flush(pdata->flush_reg);
+ pdata->ddr_flush();
#endif
sent = 0;
#ifndef AG71XX_NAPI_TX
spin_lock_irqsave(&ag->lock, flags);
- ar71xx_ddr_flush(pdata->flush_reg);
+ pdata->ddr_flush();
spin_unlock_irqrestore(&ag->lock, flags);
#endif
int done;
#ifdef AG71XX_NAPI_TX
- ar71xx_ddr_flush(pdata->flush_reg);
+ pdata->ddr_flush();
ag71xx_tx_packets(ag);
#endif
#include "ag71xx.h"
-#define PLL_SEC_CONFIG 0x18050004
-#define PLL_ETH0_INT_CLOCK 0x18050010
-#define PLL_ETH1_INT_CLOCK 0x18050014
-#define PLL_ETH_EXT_CLOCK 0x18050018
-
-#define ag71xx_pll_shift(_ag) (((_ag)->pdev->id) ? 19 : 17)
-#define ag71xx_pll_offset(_ag) (((_ag)->pdev->id) ? PLL_ETH1_INT_CLOCK \
- : PLL_ETH0_INT_CLOCK)
-
-static void ag71xx_set_pll(struct ag71xx *ag, u32 pll_val)
-{
- void __iomem *pll_reg = ioremap_nocache(ag71xx_pll_offset(ag), 4);
- void __iomem *pll_cfg = ioremap_nocache(PLL_SEC_CONFIG, 4);
- u32 s;
- u32 t;
-
- s = ag71xx_pll_shift(ag);
-
- t = __raw_readl(pll_cfg);
- t &= ~(3 << s);
- t |= (2 << s);
- __raw_writel(t, pll_cfg);
- udelay(100);
-
- __raw_writel(pll_val, pll_reg);
-
- t |= (3 << s);
- __raw_writel(t, pll_cfg);
- udelay(100);
-
- t &= ~(3 << s);
- __raw_writel(t, pll_cfg);
- udelay(100);
- DBG("%s: pll_reg %#x: %#x\n", ag->dev->name,
- (unsigned int)pll_reg, __raw_readl(pll_reg));
-
- iounmap(pll_cfg);
- iounmap(pll_reg);
-}
-
static unsigned char *ag71xx_speed_str(struct ag71xx *ag)
{
switch (ag->speed) {
static void ag71xx_phy_link_update(struct ag71xx *ag)
{
+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
u32 cfg2;
u32 ifctl;
u32 pll;
}
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff);
- ag71xx_set_pll(ag, pll);
+ pdata->set_pll(pll);
ag71xx_mii_ctrl_set_speed(ag, mii_speed);
ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
/*
* PLL block
*/
-#define PLL_REG_CPU_PLL_CFG 0x00
-#define PLL_REG_SEC_PLL_CFG 0x04
-#define PLL_REG_CPU_CLK_CTRL 0x08
-#define PLL_REG_ETH_INT0_CLK 0x10
-#define PLL_REG_ETH_INT1_CLK 0x14
-#define PLL_REG_ETH_EXT_CLK 0x18
-#define PLL_REG_PCI_CLK 0x1c
+#define AR71XX_PLL_REG_CPU_CONFIG 0x00
+#define AR71XX_PLL_REG_SEC_CONFIG 0x04
+#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
+#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
#define AR71XX_PLL_DIV_SHIFT 3
#define AR71XX_PLL_DIV_MASK 0x1f
#define AR71XX_AHB_DIV_SHIFT 20
#define AR71XX_AHB_DIV_MASK 0x7
+#define AR71XX_ETH0_PLL_SHIFT 17
+#define AR71XX_ETH1_PLL_SHIFT 19
+
+#define AR91XX_PLL_REG_CPU_CONFIG 0x00
+#define AR91XX_PLL_REG_ETH_CONFIG 0x04
+#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14
+#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18
+
#define AR91XX_PLL_DIV_SHIFT 0
#define AR91XX_PLL_DIV_MASK 0x3ff
#define AR91XX_DDR_DIV_SHIFT 22
#define AR91XX_AHB_DIV_SHIFT 19
#define AR91XX_AHB_DIV_MASK 0x1
+#define AR91XX_ETH0_PLL_SHIFT 20
+#define AR91XX_ETH1_PLL_SHIFT 22
+
extern void __iomem *ar71xx_pll_base;
static inline void ar71xx_pll_wr(unsigned reg, u32 val)
int speed;
int duplex;
u32 reset_bit;
- u32 flush_reg;
u32 mii_if;
u8 mac_addr[ETH_ALEN];
u8 has_gbit:1;
+
+ void (* ddr_flush)(void);
+ void (* set_pll)(u32 pll);
};
struct ag71xx_mdio_platform_data {