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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue