1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-12-25 02:48:37 +02:00

[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
This commit is contained in:
juhosg 2008-11-26 20:00:41 +00:00
parent aedeeb1874
commit 7188638a39
7 changed files with 126 additions and 61 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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 {