diff options
-rw-r--r-- | drivers/net/mv643xx_eth.c | 51 | ||||
-rw-r--r-- | include/linux/mv643xx_eth.h | 6 |
2 files changed, 57 insertions, 0 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index eebf0d288e36..aabf1c60946d 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -91,6 +91,11 @@ | |||
91 | */ | 91 | */ |
92 | #define PHY_ADDR_REG 0x0000 | 92 | #define PHY_ADDR_REG 0x0000 |
93 | #define SMI_REG 0x0004 | 93 | #define SMI_REG 0x0004 |
94 | #define WINDOW_BASE(i) (0x0200 + ((i) << 3)) | ||
95 | #define WINDOW_SIZE(i) (0x0204 + ((i) << 3)) | ||
96 | #define WINDOW_REMAP_HIGH(i) (0x0280 + ((i) << 2)) | ||
97 | #define WINDOW_BAR_ENABLE 0x0290 | ||
98 | #define WINDOW_PROTECT(i) (0x0294 + ((i) << 4)) | ||
94 | 99 | ||
95 | /* | 100 | /* |
96 | * Per-port registers. | 101 | * Per-port registers. |
@@ -512,6 +517,8 @@ struct mv643xx_shared_private { | |||
512 | 517 | ||
513 | /* used to protect SMI_REG, which is shared across ports */ | 518 | /* used to protect SMI_REG, which is shared across ports */ |
514 | spinlock_t phy_lock; | 519 | spinlock_t phy_lock; |
520 | |||
521 | u32 win_protect; | ||
515 | }; | 522 | }; |
516 | 523 | ||
517 | struct mv643xx_private { | 524 | struct mv643xx_private { |
@@ -1888,6 +1895,9 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
1888 | mp->shared = platform_get_drvdata(pd->shared); | 1895 | mp->shared = platform_get_drvdata(pd->shared); |
1889 | port_num = mp->port_num = pd->port_number; | 1896 | port_num = mp->port_num = pd->port_number; |
1890 | 1897 | ||
1898 | if (mp->shared->win_protect) | ||
1899 | wrl(mp, WINDOW_PROTECT(port_num), mp->shared->win_protect); | ||
1900 | |||
1891 | /* set default config values */ | 1901 | /* set default config values */ |
1892 | eth_port_uc_addr_get(mp, dev->dev_addr); | 1902 | eth_port_uc_addr_get(mp, dev->dev_addr); |
1893 | mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE; | 1903 | mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE; |
@@ -1992,9 +2002,44 @@ static int mv643xx_eth_remove(struct platform_device *pdev) | |||
1992 | return 0; | 2002 | return 0; |
1993 | } | 2003 | } |
1994 | 2004 | ||
2005 | static void mv643xx_eth_conf_mbus_windows(struct mv643xx_shared_private *msp, | ||
2006 | struct mbus_dram_target_info *dram) | ||
2007 | { | ||
2008 | void __iomem *base = msp->eth_base; | ||
2009 | u32 win_enable; | ||
2010 | u32 win_protect; | ||
2011 | int i; | ||
2012 | |||
2013 | for (i = 0; i < 6; i++) { | ||
2014 | writel(0, base + WINDOW_BASE(i)); | ||
2015 | writel(0, base + WINDOW_SIZE(i)); | ||
2016 | if (i < 4) | ||
2017 | writel(0, base + WINDOW_REMAP_HIGH(i)); | ||
2018 | } | ||
2019 | |||
2020 | win_enable = 0x3f; | ||
2021 | win_protect = 0; | ||
2022 | |||
2023 | for (i = 0; i < dram->num_cs; i++) { | ||
2024 | struct mbus_dram_window *cs = dram->cs + i; | ||
2025 | |||
2026 | writel((cs->base & 0xffff0000) | | ||
2027 | (cs->mbus_attr << 8) | | ||
2028 | dram->mbus_dram_target_id, base + WINDOW_BASE(i)); | ||
2029 | writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i)); | ||
2030 | |||
2031 | win_enable &= ~(1 << i); | ||
2032 | win_protect |= 3 << (2 * i); | ||
2033 | } | ||
2034 | |||
2035 | writel(win_enable, base + WINDOW_BAR_ENABLE); | ||
2036 | msp->win_protect = win_protect; | ||
2037 | } | ||
2038 | |||
1995 | static int mv643xx_eth_shared_probe(struct platform_device *pdev) | 2039 | static int mv643xx_eth_shared_probe(struct platform_device *pdev) |
1996 | { | 2040 | { |
1997 | static int mv643xx_version_printed = 0; | 2041 | static int mv643xx_version_printed = 0; |
2042 | struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; | ||
1998 | struct mv643xx_shared_private *msp; | 2043 | struct mv643xx_shared_private *msp; |
1999 | struct resource *res; | 2044 | struct resource *res; |
2000 | int ret; | 2045 | int ret; |
@@ -2021,6 +2066,12 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) | |||
2021 | 2066 | ||
2022 | platform_set_drvdata(pdev, msp); | 2067 | platform_set_drvdata(pdev, msp); |
2023 | 2068 | ||
2069 | /* | ||
2070 | * (Re-)program MBUS remapping windows if we are asked to. | ||
2071 | */ | ||
2072 | if (pd != NULL && pd->dram != NULL) | ||
2073 | mv643xx_eth_conf_mbus_windows(msp, pd->dram); | ||
2074 | |||
2024 | return 0; | 2075 | return 0; |
2025 | 2076 | ||
2026 | out_free: | 2077 | out_free: |
diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index 2d59855b61c1..4801b02b444e 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h | |||
@@ -5,6 +5,8 @@ | |||
5 | #ifndef __LINUX_MV643XX_ETH_H | 5 | #ifndef __LINUX_MV643XX_ETH_H |
6 | #define __LINUX_MV643XX_ETH_H | 6 | #define __LINUX_MV643XX_ETH_H |
7 | 7 | ||
8 | #include <linux/mbus.h> | ||
9 | |||
8 | #define MV643XX_ETH_SHARED_NAME "mv643xx_eth_shared" | 10 | #define MV643XX_ETH_SHARED_NAME "mv643xx_eth_shared" |
9 | #define MV643XX_ETH_NAME "mv643xx_eth" | 11 | #define MV643XX_ETH_NAME "mv643xx_eth" |
10 | #define MV643XX_ETH_SHARED_REGS 0x2000 | 12 | #define MV643XX_ETH_SHARED_REGS 0x2000 |
@@ -13,6 +15,10 @@ | |||
13 | #define MV643XX_ETH_SIZE_REG_4 0x2224 | 15 | #define MV643XX_ETH_SIZE_REG_4 0x2224 |
14 | #define MV643XX_ETH_BASE_ADDR_ENABLE_REG 0x2290 | 16 | #define MV643XX_ETH_BASE_ADDR_ENABLE_REG 0x2290 |
15 | 17 | ||
18 | struct mv643xx_eth_shared_platform_data { | ||
19 | struct mbus_dram_target_info *dram; | ||
20 | }; | ||
21 | |||
16 | struct mv643xx_eth_platform_data { | 22 | struct mv643xx_eth_platform_data { |
17 | struct platform_device *shared; | 23 | struct platform_device *shared; |
18 | int port_number; | 24 | int port_number; |