aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2008-11-26 20:00:41 +0000
committerGabor Juhos <juhosg@openwrt.org>2008-11-26 20:00:41 +0000
commit31ecd080e3ab771813abc400fbb429be7758b416 (patch)
treeddc6afd4848b31cdcabf6123a2b911aa10ae71f8
parent7813d1dd295fb19ce6b8894b9b435a3cf32ea3f4 (diff)
downloadmaster-187ad058-31ecd080e3ab771813abc400fbb429be7758b416.tar.gz
master-187ad058-31ecd080e3ab771813abc400fbb429be7758b416.tar.bz2
master-187ad058-31ecd080e3ab771813abc400fbb429be7758b416.zip
[ar71xx] ag71xx: introduce SoC specific fuctions for DDR flush and PLL setup
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@13369 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r--target/linux/ar71xx/files/arch/mips/ar71xx/platform.c102
-rw-r--r--target/linux/ar71xx/files/arch/mips/ar71xx/setup.c4
-rw-r--r--target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h4
-rw-r--r--target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c8
-rw-r--r--target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_phy.c43
-rw-r--r--target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/ar71xx.h22
-rw-r--r--target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/platform.h4
7 files changed, 126 insertions, 61 deletions
diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/platform.c b/target/linux/ar71xx/files/arch/mips/ar71xx/platform.c
index deda410279..b2add194f7 100644
--- a/target/linux/ar71xx/files/arch/mips/ar71xx/platform.c
+++ b/target/linux/ar71xx/files/arch/mips/ar71xx/platform.c
@@ -172,6 +172,79 @@ void __init ar71xx_add_device_mdio(u32 phy_mask)
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",
@@ -198,7 +271,6 @@ static struct resource ar71xx_eth0_resources[] = {
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 = {
@@ -237,7 +309,6 @@ static struct resource ar71xx_eth1_resources[] = {
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 = {
@@ -301,14 +372,35 @@ void __init ar71xx_add_device_eth(unsigned int id)
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:
@@ -319,7 +411,7 @@ void __init ar71xx_add_device_eth(unsigned int id)
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;
}
diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/setup.c b/target/linux/ar71xx/files/arch/mips/ar71xx/setup.c
index 758f541423..a5d26e72c6 100644
--- a/target/linux/ar71xx/files/arch/mips/ar71xx/setup.c
+++ b/target/linux/ar71xx/files/arch/mips/ar71xx/setup.c
@@ -149,7 +149,7 @@ static void __init ar91xx_detect_sys_frequency(void)
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;
@@ -169,7 +169,7 @@ static void __init ar71xx_detect_sys_frequency(void)
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;
diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h
index f7865523c3..06ec3c3bf6 100644
--- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h
+++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h
@@ -37,7 +37,7 @@
#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
@@ -331,6 +331,8 @@ static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg)
reg -= AG71XX_REG_MAC_IFCTL;
ret = __raw_readl(ag->mac_base2 + reg);
break;
+ default:
+ BUG();
}
return ret;
diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
index 47fc674077..3d60a8bab6 100644
--- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
+++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
@@ -384,7 +384,7 @@ static int ag71xx_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
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))
@@ -480,7 +480,7 @@ static void ag71xx_tx_packets(struct ag71xx *ag)
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;
@@ -523,7 +523,7 @@ static int ag71xx_rx_packets(struct ag71xx *ag, int limit)
#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
@@ -592,7 +592,7 @@ static int ag71xx_poll(struct napi_struct *napi, int limit)
int done;
#ifdef AG71XX_NAPI_TX
- ar71xx_ddr_flush(pdata->flush_reg);
+ pdata->ddr_flush();
ag71xx_tx_packets(ag);
#endif
diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_phy.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_phy.c
index 9173b48ad5..cedbfe616b 100644
--- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_phy.c
+++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_phy.c
@@ -13,46 +13,6 @@
#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) {
@@ -79,6 +39,7 @@ static unsigned char *ag71xx_speed_str(struct ag71xx *ag)
static void ag71xx_phy_link_update(struct ag71xx *ag)
{
+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
u32 cfg2;
u32 ifctl;
u32 pll;
@@ -126,7 +87,7 @@ static void ag71xx_phy_link_update(struct ag71xx *ag)
}
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);
diff --git a/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/ar71xx.h b/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/ar71xx.h
index f68bfff199..e9a69cd56b 100644
--- a/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/ar71xx.h
+++ b/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/ar71xx.h
@@ -106,13 +106,10 @@ extern enum ar71xx_soc_type ar71xx_soc;
/*
* 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
@@ -123,6 +120,14 @@ extern enum ar71xx_soc_type ar71xx_soc;
#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
@@ -130,6 +135,9 @@ extern enum ar71xx_soc_type ar71xx_soc;
#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)
diff --git a/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/platform.h b/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/platform.h
index f845c42f30..9d567a6c8d 100644
--- a/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/platform.h
+++ b/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/platform.h
@@ -25,11 +25,13 @@ struct ag71xx_platform_data {
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 {