diff options
Diffstat (limited to 'arch/arm/plat-orion')
-rw-r--r-- | arch/arm/plat-orion/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/plat-orion/addr-map.c | 174 | ||||
-rw-r--r-- | arch/arm/plat-orion/common.c | 43 | ||||
-rw-r--r-- | arch/arm/plat-orion/include/plat/addr-map.h | 53 | ||||
-rw-r--r-- | arch/arm/plat-orion/include/plat/audio.h | 3 | ||||
-rw-r--r-- | arch/arm/plat-orion/include/plat/common.h | 17 | ||||
-rw-r--r-- | arch/arm/plat-orion/include/plat/ehci-orion.h | 1 | ||||
-rw-r--r-- | arch/arm/plat-orion/include/plat/mv_xor.h | 6 | ||||
-rw-r--r-- | arch/arm/plat-orion/include/plat/mvsdio.h | 1 | ||||
-rw-r--r-- | arch/arm/plat-orion/include/plat/pcie.h | 3 | ||||
-rw-r--r-- | arch/arm/plat-orion/pcie.c | 6 |
11 files changed, 245 insertions, 64 deletions
diff --git a/arch/arm/plat-orion/Makefile b/arch/arm/plat-orion/Makefile index 95a5fc53b6db..c20ce0f5ce33 100644 --- a/arch/arm/plat-orion/Makefile +++ b/arch/arm/plat-orion/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := irq.o pcie.o time.o common.o mpp.o +obj-y := irq.o pcie.o time.o common.o mpp.o addr-map.o obj-m := obj-n := obj- := diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c new file mode 100644 index 000000000000..367ca89ac403 --- /dev/null +++ b/arch/arm/plat-orion/addr-map.c @@ -0,0 +1,174 @@ +/* + * arch/arm/plat-orion/addr-map.c + * + * Address map functions for Marvell Orion based SoCs + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/mbus.h> +#include <linux/io.h> +#include <plat/addr-map.h> + +struct mbus_dram_target_info orion_mbus_dram_info; + +const struct mbus_dram_target_info *mv_mbus_dram_info(void) +{ + return &orion_mbus_dram_info; +} +EXPORT_SYMBOL_GPL(mv_mbus_dram_info); + +/* + * DDR target is the same on all Orion platforms. + */ +#define TARGET_DDR 0 + +/* + * Helpers to get DDR bank info + */ +#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) +#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) + +/* + * CPU Address Decode Windows registers + */ +#define WIN_CTRL_OFF 0x0000 +#define WIN_BASE_OFF 0x0004 +#define WIN_REMAP_LO_OFF 0x0008 +#define WIN_REMAP_HI_OFF 0x000c + +/* + * Default implementation + */ +static void __init __iomem * +orion_win_cfg_base(const struct orion_addr_map_cfg *cfg, int win) +{ + return (void __iomem *)(cfg->bridge_virt_base + (win << 4)); +} + +/* + * Default implementation + */ +static int __init orion_cpu_win_can_remap(const struct orion_addr_map_cfg *cfg, + const int win) +{ + if (win < cfg->remappable_wins) + return 1; + + return 0; +} + +void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg, + const int win, const u32 base, + const u32 size, const u8 target, + const u8 attr, const int remap) +{ + void __iomem *addr = cfg->win_cfg_base(cfg, win); + u32 ctrl, base_high, remap_addr; + + if (win >= cfg->num_wins) { + printk(KERN_ERR "setup_cpu_win: trying to allocate window " + "%d when only %d allowed\n", win, cfg->num_wins); + } + + base_high = base & 0xffff0000; + ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; + + writel(base_high, addr + WIN_BASE_OFF); + writel(ctrl, addr + WIN_CTRL_OFF); + if (cfg->cpu_win_can_remap(cfg, win)) { + if (remap < 0) + remap_addr = base; + else + remap_addr = remap; + writel(remap_addr & 0xffff0000, addr + WIN_REMAP_LO_OFF); + writel(0, addr + WIN_REMAP_HI_OFF); + } +} + +/* + * Configure a number of windows. + */ +static void __init orion_setup_cpu_wins(const struct orion_addr_map_cfg * cfg, + const struct orion_addr_map_info *info) +{ + while (info->win != -1) { + orion_setup_cpu_win(cfg, info->win, info->base, info->size, + info->target, info->attr, info->remap); + info++; + } +} + +static void __init orion_disable_wins(const struct orion_addr_map_cfg * cfg) +{ + void __iomem *addr; + int i; + + for (i = 0; i < cfg->num_wins; i++) { + addr = cfg->win_cfg_base(cfg, i); + + writel(0, addr + WIN_BASE_OFF); + writel(0, addr + WIN_CTRL_OFF); + if (cfg->cpu_win_can_remap(cfg, i)) { + writel(0, addr + WIN_REMAP_LO_OFF); + writel(0, addr + WIN_REMAP_HI_OFF); + } + } +} + +/* + * Disable, clear and configure windows. + */ +void __init orion_config_wins(struct orion_addr_map_cfg * cfg, + const struct orion_addr_map_info *info) +{ + if (!cfg->cpu_win_can_remap) + cfg->cpu_win_can_remap = orion_cpu_win_can_remap; + + if (!cfg->win_cfg_base) + cfg->win_cfg_base = orion_win_cfg_base; + + orion_disable_wins(cfg); + + if (info) + orion_setup_cpu_wins(cfg, info); +} + +/* + * Setup MBUS dram target info. + */ +void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg, + const u32 ddr_window_cpu_base) +{ + void __iomem *addr; + int i; + int cs; + + orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; + + addr = (void __iomem *)ddr_window_cpu_base; + + for (i = 0, cs = 0; i < 4; i++) { + u32 base = readl(addr + DDR_BASE_CS_OFF(i)); + u32 size = readl(addr + DDR_SIZE_CS_OFF(i)); + + /* + * Chip select enabled? + */ + if (size & 1) { + struct mbus_dram_window *w; + + w = &orion_mbus_dram_info.cs[cs++]; + w->cs_index = i; + w->mbus_attr = 0xf & ~(1 << i); + w->base = base & 0xffff0000; + w->size = (size | 0x0000ffff) + 1; + } + } + orion_mbus_dram_info.num_cs = cs; +} diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 9e5451b3c8e3..e5a2fde29b19 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -13,7 +13,6 @@ #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/serial_8250.h> -#include <linux/mbus.h> #include <linux/ata_platform.h> #include <linux/mv643xx_eth.h> #include <linux/mv643xx_i2c.h> @@ -203,13 +202,12 @@ void __init orion_rtc_init(unsigned long mapbase, ****************************************************************************/ static __init void ge_complete( struct mv643xx_eth_shared_platform_data *orion_ge_shared_data, - struct mbus_dram_target_info *mbus_dram_info, int tclk, + int tclk, struct resource *orion_ge_resource, unsigned long irq, struct platform_device *orion_ge_shared, struct mv643xx_eth_platform_data *eth_data, struct platform_device *orion_ge) { - orion_ge_shared_data->dram = mbus_dram_info; orion_ge_shared_data->t_clk = tclk; orion_ge_resource->start = irq; orion_ge_resource->end = irq; @@ -259,7 +257,6 @@ static struct platform_device orion_ge00 = { }; void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, - struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, unsigned long irq, unsigned long irq_err, @@ -267,7 +264,7 @@ void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, { fill_resources(&orion_ge00_shared, orion_ge00_shared_resources, mapbase + 0x2000, SZ_16K - 1, irq_err); - ge_complete(&orion_ge00_shared_data, mbus_dram_info, tclk, + ge_complete(&orion_ge00_shared_data, tclk, orion_ge00_resources, irq, &orion_ge00_shared, eth_data, &orion_ge00); } @@ -313,7 +310,6 @@ static struct platform_device orion_ge01 = { }; void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, - struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, unsigned long irq, unsigned long irq_err, @@ -321,7 +317,7 @@ void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, { fill_resources(&orion_ge01_shared, orion_ge01_shared_resources, mapbase + 0x2000, SZ_16K - 1, irq_err); - ge_complete(&orion_ge01_shared_data, mbus_dram_info, tclk, + ge_complete(&orion_ge01_shared_data, tclk, orion_ge01_resources, irq, &orion_ge01_shared, eth_data, &orion_ge01); } @@ -367,7 +363,6 @@ static struct platform_device orion_ge10 = { }; void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data, - struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, unsigned long irq, unsigned long irq_err, @@ -375,7 +370,7 @@ void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data, { fill_resources(&orion_ge10_shared, orion_ge10_shared_resources, mapbase + 0x2000, SZ_16K - 1, irq_err); - ge_complete(&orion_ge10_shared_data, mbus_dram_info, tclk, + ge_complete(&orion_ge10_shared_data, tclk, orion_ge10_resources, irq, &orion_ge10_shared, eth_data, &orion_ge10); } @@ -421,7 +416,6 @@ static struct platform_device orion_ge11 = { }; void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data, - struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, unsigned long irq, unsigned long irq_err, @@ -429,7 +423,7 @@ void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data, { fill_resources(&orion_ge11_shared, orion_ge11_shared_resources, mapbase + 0x2000, SZ_16K - 1, irq_err); - ge_complete(&orion_ge11_shared_data, mbus_dram_info, tclk, + ge_complete(&orion_ge11_shared_data, tclk, orion_ge11_resources, irq, &orion_ge11_shared, eth_data, &orion_ge11); } @@ -592,8 +586,6 @@ void __init orion_wdt_init(unsigned long tclk) /***************************************************************************** * XOR ****************************************************************************/ -static struct mv_xor_platform_shared_data orion_xor_shared_data; - static u64 orion_xor_dmamask = DMA_BIT_MASK(32); void __init orion_xor_init_channels( @@ -632,9 +624,6 @@ static struct resource orion_xor0_shared_resources[] = { static struct platform_device orion_xor0_shared = { .name = MV_XOR_SHARED_NAME, .id = 0, - .dev = { - .platform_data = &orion_xor_shared_data, - }, .num_resources = ARRAY_SIZE(orion_xor0_shared_resources), .resource = orion_xor0_shared_resources, }; @@ -687,14 +676,11 @@ static struct platform_device orion_xor01_channel = { }, }; -void __init orion_xor0_init(struct mbus_dram_target_info *mbus_dram_info, - unsigned long mapbase_low, +void __init orion_xor0_init(unsigned long mapbase_low, unsigned long mapbase_high, unsigned long irq_0, unsigned long irq_1) { - orion_xor_shared_data.dram = mbus_dram_info; - orion_xor0_shared_resources[0].start = mapbase_low; orion_xor0_shared_resources[0].end = mapbase_low + 0xff; orion_xor0_shared_resources[1].start = mapbase_high; @@ -727,9 +713,6 @@ static struct resource orion_xor1_shared_resources[] = { static struct platform_device orion_xor1_shared = { .name = MV_XOR_SHARED_NAME, .id = 1, - .dev = { - .platform_data = &orion_xor_shared_data, - }, .num_resources = ARRAY_SIZE(orion_xor1_shared_resources), .resource = orion_xor1_shared_resources, }; @@ -828,11 +811,9 @@ static struct platform_device orion_ehci = { }, }; -void __init orion_ehci_init(struct mbus_dram_target_info *mbus_dram_info, - unsigned long mapbase, +void __init orion_ehci_init(unsigned long mapbase, unsigned long irq) { - orion_ehci_data.dram = mbus_dram_info; fill_resources(&orion_ehci, orion_ehci_resources, mapbase, SZ_4K - 1, irq); @@ -854,11 +835,9 @@ static struct platform_device orion_ehci_1 = { }, }; -void __init orion_ehci_1_init(struct mbus_dram_target_info *mbus_dram_info, - unsigned long mapbase, +void __init orion_ehci_1_init(unsigned long mapbase, unsigned long irq) { - orion_ehci_data.dram = mbus_dram_info; fill_resources(&orion_ehci_1, orion_ehci_1_resources, mapbase, SZ_4K - 1, irq); @@ -880,11 +859,9 @@ static struct platform_device orion_ehci_2 = { }, }; -void __init orion_ehci_2_init(struct mbus_dram_target_info *mbus_dram_info, - unsigned long mapbase, +void __init orion_ehci_2_init(unsigned long mapbase, unsigned long irq) { - orion_ehci_data.dram = mbus_dram_info; fill_resources(&orion_ehci_2, orion_ehci_2_resources, mapbase, SZ_4K - 1, irq); @@ -911,11 +888,9 @@ static struct platform_device orion_sata = { }; void __init orion_sata_init(struct mv_sata_platform_data *sata_data, - struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, unsigned long irq) { - sata_data->dram = mbus_dram_info; orion_sata.dev.platform_data = sata_data; fill_resources(&orion_sata, orion_sata_resources, mapbase, 0x5000 - 1, irq); diff --git a/arch/arm/plat-orion/include/plat/addr-map.h b/arch/arm/plat-orion/include/plat/addr-map.h new file mode 100644 index 000000000000..fd556f77562c --- /dev/null +++ b/arch/arm/plat-orion/include/plat/addr-map.h @@ -0,0 +1,53 @@ +/* + * arch/arm/plat-orion/include/plat/addr-map.h + * + * Marvell Orion SoC address map handling. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __PLAT_ADDR_MAP_H +#define __PLAT_ADDR_MAP_H + +extern struct mbus_dram_target_info orion_mbus_dram_info; + +struct orion_addr_map_cfg { + const int num_wins; /* Total number of windows */ + const int remappable_wins; + const u32 bridge_virt_base; + + /* If NULL, the default cpu_win_can_remap will be used, using + the value in remappable_wins */ + int (*cpu_win_can_remap) (const struct orion_addr_map_cfg *cfg, + const int win); + /* If NULL, the default win_cfg_base will be used, using the + value in bridge_virt_base */ + void __iomem *(*win_cfg_base) (const struct orion_addr_map_cfg *cfg, + const int win); +}; + +/* + * Information needed to setup one address mapping. + */ +struct orion_addr_map_info { + const int win; + const u32 base; + const u32 size; + const u8 target; + const u8 attr; + const int remap; +}; + +void __init orion_config_wins(struct orion_addr_map_cfg *cfg, + const struct orion_addr_map_info *info); + +void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg, + const int win, const u32 base, + const u32 size, const u8 target, + const u8 attr, const int remap); + +void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg, + const u32 ddr_window_cpu_base); +#endif diff --git a/arch/arm/plat-orion/include/plat/audio.h b/arch/arm/plat-orion/include/plat/audio.h index 9cf1f781329b..885f8abd927b 100644 --- a/arch/arm/plat-orion/include/plat/audio.h +++ b/arch/arm/plat-orion/include/plat/audio.h @@ -1,11 +1,8 @@ #ifndef __PLAT_AUDIO_H #define __PLAT_AUDIO_H -#include <linux/mbus.h> - struct kirkwood_asoc_platform_data { u32 tclk; - struct mbus_dram_target_info *dram; int burst; }; #endif diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h index a63c357e2ab1..0fe08d77e835 100644 --- a/arch/arm/plat-orion/include/plat/common.h +++ b/arch/arm/plat-orion/include/plat/common.h @@ -37,28 +37,24 @@ void __init orion_rtc_init(unsigned long mapbase, unsigned long irq); void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, - struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, unsigned long irq, unsigned long irq_err, int tclk); void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, - struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, unsigned long irq, unsigned long irq_err, int tclk); void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data, - struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, unsigned long irq, unsigned long irq_err, int tclk); void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data, - struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, unsigned long irq, unsigned long irq_err, @@ -82,8 +78,7 @@ void __init orion_spi_1_init(unsigned long mapbase, void __init orion_wdt_init(unsigned long tclk); -void __init orion_xor0_init(struct mbus_dram_target_info *mbus_dram_info, - unsigned long mapbase_low, +void __init orion_xor0_init(unsigned long mapbase_low, unsigned long mapbase_high, unsigned long irq_0, unsigned long irq_1); @@ -93,20 +88,16 @@ void __init orion_xor1_init(unsigned long mapbase_low, unsigned long irq_0, unsigned long irq_1); -void __init orion_ehci_init(struct mbus_dram_target_info *mbus_dram_info, - unsigned long mapbase, +void __init orion_ehci_init(unsigned long mapbase, unsigned long irq); -void __init orion_ehci_1_init(struct mbus_dram_target_info *mbus_dram_info, - unsigned long mapbase, +void __init orion_ehci_1_init(unsigned long mapbase, unsigned long irq); -void __init orion_ehci_2_init(struct mbus_dram_target_info *mbus_dram_info, - unsigned long mapbase, +void __init orion_ehci_2_init(unsigned long mapbase, unsigned long irq); void __init orion_sata_init(struct mv_sata_platform_data *sata_data, - struct mbus_dram_target_info *mbus_dram_info, unsigned long mapbase, unsigned long irq); diff --git a/arch/arm/plat-orion/include/plat/ehci-orion.h b/arch/arm/plat-orion/include/plat/ehci-orion.h index 4ec668e77460..6fc78e430420 100644 --- a/arch/arm/plat-orion/include/plat/ehci-orion.h +++ b/arch/arm/plat-orion/include/plat/ehci-orion.h @@ -19,7 +19,6 @@ enum orion_ehci_phy_ver { }; struct orion_ehci_data { - struct mbus_dram_target_info *dram; enum orion_ehci_phy_ver phy_version; }; diff --git a/arch/arm/plat-orion/include/plat/mv_xor.h b/arch/arm/plat-orion/include/plat/mv_xor.h index bd5f3bdb4ae3..2ba1f7d76eef 100644 --- a/arch/arm/plat-orion/include/plat/mv_xor.h +++ b/arch/arm/plat-orion/include/plat/mv_xor.h @@ -13,12 +13,6 @@ #define MV_XOR_SHARED_NAME "mv_xor_shared" #define MV_XOR_NAME "mv_xor" -struct mbus_dram_target_info; - -struct mv_xor_platform_shared_data { - struct mbus_dram_target_info *dram; -}; - struct mv_xor_platform_data { struct platform_device *shared; int hw_id; diff --git a/arch/arm/plat-orion/include/plat/mvsdio.h b/arch/arm/plat-orion/include/plat/mvsdio.h index 14ca88676002..1190efedcb94 100644 --- a/arch/arm/plat-orion/include/plat/mvsdio.h +++ b/arch/arm/plat-orion/include/plat/mvsdio.h @@ -12,7 +12,6 @@ #include <linux/mbus.h> struct mvsdio_platform_data { - struct mbus_dram_target_info *dram; unsigned int clock; int gpio_card_detect; int gpio_write_protect; diff --git a/arch/arm/plat-orion/include/plat/pcie.h b/arch/arm/plat-orion/include/plat/pcie.h index cc99163e73fd..fe5b9e862747 100644 --- a/arch/arm/plat-orion/include/plat/pcie.h +++ b/arch/arm/plat-orion/include/plat/pcie.h @@ -20,8 +20,7 @@ int orion_pcie_x4_mode(void __iomem *base); int orion_pcie_get_local_bus_nr(void __iomem *base); void orion_pcie_set_local_bus_nr(void __iomem *base, int nr); void orion_pcie_reset(void __iomem *base); -void orion_pcie_setup(void __iomem *base, - struct mbus_dram_target_info *dram); +void orion_pcie_setup(void __iomem *base); int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus, u32 devfn, int where, int size, u32 *val); int orion_pcie_rd_conf_tlp(void __iomem *base, struct pci_bus *bus, diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c index af2d733c50b5..86dbb5bdb172 100644 --- a/arch/arm/plat-orion/pcie.c +++ b/arch/arm/plat-orion/pcie.c @@ -13,6 +13,7 @@ #include <linux/mbus.h> #include <asm/mach/pci.h> #include <plat/pcie.h> +#include <plat/addr-map.h> #include <linux/delay.h> /* @@ -175,8 +176,7 @@ static void __init orion_pcie_setup_wins(void __iomem *base, writel(((size - 1) & 0xffff0000) | 1, base + PCIE_BAR_CTRL_OFF(1)); } -void __init orion_pcie_setup(void __iomem *base, - struct mbus_dram_target_info *dram) +void __init orion_pcie_setup(void __iomem *base) { u16 cmd; u32 mask; @@ -184,7 +184,7 @@ void __init orion_pcie_setup(void __iomem *base, /* * Point PCIe unit MBUS decode windows to DRAM space. */ - orion_pcie_setup_wins(base, dram); + orion_pcie_setup_wins(base, &orion_mbus_dram_info); /* * Master + slave enable. |