ag71xx: introduce SoC specific fuctions for DDR flush and PLL setup
SVN-Revision: 13369
This commit is contained in:
parent
1c77ec0587
commit
c9ae01d3c8
7 changed files with 126 additions and 61 deletions
|
@ -172,6 +172,79 @@ void __init ar71xx_add_device_mdio(u32 phy_mask)
|
||||||
platform_device_register(&ar71xx_mdio_device);
|
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[] = {
|
static struct resource ar71xx_eth0_resources[] = {
|
||||||
{
|
{
|
||||||
.name = "mac_base",
|
.name = "mac_base",
|
||||||
|
@ -198,7 +271,6 @@ static struct resource ar71xx_eth0_resources[] = {
|
||||||
|
|
||||||
struct ag71xx_platform_data ar71xx_eth0_data = {
|
struct ag71xx_platform_data ar71xx_eth0_data = {
|
||||||
.reset_bit = RESET_MODULE_GE0_MAC,
|
.reset_bit = RESET_MODULE_GE0_MAC,
|
||||||
.flush_reg = AR71XX_DDR_REG_FLUSH_GE0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device ar71xx_eth0_device = {
|
static struct platform_device ar71xx_eth0_device = {
|
||||||
|
@ -237,7 +309,6 @@ static struct resource ar71xx_eth1_resources[] = {
|
||||||
|
|
||||||
struct ag71xx_platform_data ar71xx_eth1_data = {
|
struct ag71xx_platform_data ar71xx_eth1_data = {
|
||||||
.reset_bit = RESET_MODULE_GE1_MAC,
|
.reset_bit = RESET_MODULE_GE1_MAC,
|
||||||
.flush_reg = AR71XX_DDR_REG_FLUSH_GE1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device ar71xx_eth1_device = {
|
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;
|
pdata = pdev->dev.platform_data;
|
||||||
|
|
||||||
switch (ar71xx_soc) {
|
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_AR7141:
|
||||||
case AR71XX_SOC_AR7161:
|
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;
|
pdata->has_gbit = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AR71XX_SOC_AR7130:
|
|
||||||
case AR71XX_SOC_AR9130:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -319,7 +411,7 @@ void __init ar71xx_add_device_eth(unsigned int id)
|
||||||
case PHY_INTERFACE_MODE_GMII:
|
case PHY_INTERFACE_MODE_GMII:
|
||||||
case PHY_INTERFACE_MODE_RGMII:
|
case PHY_INTERFACE_MODE_RGMII:
|
||||||
if (!pdata->has_gbit) {
|
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);
|
id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,7 @@ static void __init ar91xx_detect_sys_frequency(void)
|
||||||
u32 freq;
|
u32 freq;
|
||||||
u32 div;
|
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);
|
div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK);
|
||||||
freq = div * AR91XX_BASE_FREQ;
|
freq = div * AR91XX_BASE_FREQ;
|
||||||
|
@ -169,7 +169,7 @@ static void __init ar71xx_detect_sys_frequency(void)
|
||||||
u32 freq;
|
u32 freq;
|
||||||
u32 div;
|
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;
|
div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
|
||||||
freq = div * AR71XX_BASE_FREQ;
|
freq = div * AR71XX_BASE_FREQ;
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#define ETH_FCS_LEN 4
|
#define ETH_FCS_LEN 4
|
||||||
|
|
||||||
#define AG71XX_DRV_NAME "ag71xx"
|
#define AG71XX_DRV_NAME "ag71xx"
|
||||||
#define AG71XX_DRV_VERSION "0.4.4"
|
#define AG71XX_DRV_VERSION "0.5.0"
|
||||||
|
|
||||||
#define AG71XX_NAPI_TX 1
|
#define AG71XX_NAPI_TX 1
|
||||||
|
|
||||||
|
@ -331,6 +331,8 @@ static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg)
|
||||||
reg -= AG71XX_REG_MAC_IFCTL;
|
reg -= AG71XX_REG_MAC_IFCTL;
|
||||||
ret = __raw_readl(ag->mac_base2 + reg);
|
ret = __raw_readl(ag->mac_base2 + reg);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -384,7 +384,7 @@ static int ag71xx_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
desc = &ring->descs[i];
|
desc = &ring->descs[i];
|
||||||
|
|
||||||
spin_lock_irqsave(&ag->lock, flags);
|
spin_lock_irqsave(&ag->lock, flags);
|
||||||
ar71xx_ddr_flush(pdata->flush_reg);
|
pdata->ddr_flush();
|
||||||
spin_unlock_irqrestore(&ag->lock, flags);
|
spin_unlock_irqrestore(&ag->lock, flags);
|
||||||
|
|
||||||
if (!ag71xx_desc_empty(desc))
|
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);
|
DBG("%s: processing TX ring\n", ag->dev->name);
|
||||||
|
|
||||||
#ifdef AG71XX_NAPI_TX
|
#ifdef AG71XX_NAPI_TX
|
||||||
ar71xx_ddr_flush(pdata->flush_reg);
|
pdata->ddr_flush();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sent = 0;
|
sent = 0;
|
||||||
|
@ -523,7 +523,7 @@ static int ag71xx_rx_packets(struct ag71xx *ag, int limit)
|
||||||
|
|
||||||
#ifndef AG71XX_NAPI_TX
|
#ifndef AG71XX_NAPI_TX
|
||||||
spin_lock_irqsave(&ag->lock, flags);
|
spin_lock_irqsave(&ag->lock, flags);
|
||||||
ar71xx_ddr_flush(pdata->flush_reg);
|
pdata->ddr_flush();
|
||||||
spin_unlock_irqrestore(&ag->lock, flags);
|
spin_unlock_irqrestore(&ag->lock, flags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -592,7 +592,7 @@ static int ag71xx_poll(struct napi_struct *napi, int limit)
|
||||||
int done;
|
int done;
|
||||||
|
|
||||||
#ifdef AG71XX_NAPI_TX
|
#ifdef AG71XX_NAPI_TX
|
||||||
ar71xx_ddr_flush(pdata->flush_reg);
|
pdata->ddr_flush();
|
||||||
ag71xx_tx_packets(ag);
|
ag71xx_tx_packets(ag);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -13,46 +13,6 @@
|
||||||
|
|
||||||
#include "ag71xx.h"
|
#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)
|
static unsigned char *ag71xx_speed_str(struct ag71xx *ag)
|
||||||
{
|
{
|
||||||
switch (ag->speed) {
|
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)
|
static void ag71xx_phy_link_update(struct ag71xx *ag)
|
||||||
{
|
{
|
||||||
|
struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
|
||||||
u32 cfg2;
|
u32 cfg2;
|
||||||
u32 ifctl;
|
u32 ifctl;
|
||||||
u32 pll;
|
u32 pll;
|
||||||
|
@ -126,7 +87,7 @@ static void ag71xx_phy_link_update(struct ag71xx *ag)
|
||||||
}
|
}
|
||||||
|
|
||||||
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff);
|
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_mii_ctrl_set_speed(ag, mii_speed);
|
||||||
|
|
||||||
ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
|
ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
|
||||||
|
|
|
@ -106,13 +106,10 @@ extern enum ar71xx_soc_type ar71xx_soc;
|
||||||
/*
|
/*
|
||||||
* PLL block
|
* PLL block
|
||||||
*/
|
*/
|
||||||
#define PLL_REG_CPU_PLL_CFG 0x00
|
#define AR71XX_PLL_REG_CPU_CONFIG 0x00
|
||||||
#define PLL_REG_SEC_PLL_CFG 0x04
|
#define AR71XX_PLL_REG_SEC_CONFIG 0x04
|
||||||
#define PLL_REG_CPU_CLK_CTRL 0x08
|
#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
|
||||||
#define PLL_REG_ETH_INT0_CLK 0x10
|
#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
|
||||||
#define PLL_REG_ETH_INT1_CLK 0x14
|
|
||||||
#define PLL_REG_ETH_EXT_CLK 0x18
|
|
||||||
#define PLL_REG_PCI_CLK 0x1c
|
|
||||||
|
|
||||||
#define AR71XX_PLL_DIV_SHIFT 3
|
#define AR71XX_PLL_DIV_SHIFT 3
|
||||||
#define AR71XX_PLL_DIV_MASK 0x1f
|
#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_SHIFT 20
|
||||||
#define AR71XX_AHB_DIV_MASK 0x7
|
#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_SHIFT 0
|
||||||
#define AR91XX_PLL_DIV_MASK 0x3ff
|
#define AR91XX_PLL_DIV_MASK 0x3ff
|
||||||
#define AR91XX_DDR_DIV_SHIFT 22
|
#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_SHIFT 19
|
||||||
#define AR91XX_AHB_DIV_MASK 0x1
|
#define AR91XX_AHB_DIV_MASK 0x1
|
||||||
|
|
||||||
|
#define AR91XX_ETH0_PLL_SHIFT 20
|
||||||
|
#define AR91XX_ETH1_PLL_SHIFT 22
|
||||||
|
|
||||||
extern void __iomem *ar71xx_pll_base;
|
extern void __iomem *ar71xx_pll_base;
|
||||||
|
|
||||||
static inline void ar71xx_pll_wr(unsigned reg, u32 val)
|
static inline void ar71xx_pll_wr(unsigned reg, u32 val)
|
||||||
|
|
|
@ -25,11 +25,13 @@ struct ag71xx_platform_data {
|
||||||
int speed;
|
int speed;
|
||||||
int duplex;
|
int duplex;
|
||||||
u32 reset_bit;
|
u32 reset_bit;
|
||||||
u32 flush_reg;
|
|
||||||
u32 mii_if;
|
u32 mii_if;
|
||||||
u8 mac_addr[ETH_ALEN];
|
u8 mac_addr[ETH_ALEN];
|
||||||
|
|
||||||
u8 has_gbit:1;
|
u8 has_gbit:1;
|
||||||
|
|
||||||
|
void (* ddr_flush)(void);
|
||||||
|
void (* set_pll)(u32 pll);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ag71xx_mdio_platform_data {
|
struct ag71xx_mdio_platform_data {
|
||||||
|
|
Loading…
Reference in a new issue