提交 b6d1c33a 编写于 作者: A Andrew Lunn 提交者: Nicolas Pitre

ARM: Orion: Consolidate the address map setup

Compile tested on Dove, orion5x, mv78xx0. Boot tested on Kirkwood.
Signed-off-by: NAndrew Lunn <andrew@lunn.ch>
Tested-by: NMichael Walle <michael@walle.cc>
Acked-by: NNicolas Pitre <nico@linaro.org>
Signed-off-by: NNicolas Pitre <nico@fluxnic.net>
上级 527ef055
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <plat/addr-map.h>
#include "common.h" #include "common.h"
/* /*
...@@ -34,14 +35,6 @@ ...@@ -34,14 +35,6 @@
#define ATTR_PCIE_MEM 0xe8 #define ATTR_PCIE_MEM 0xe8
#define ATTR_SCRATCHPAD 0x0 #define ATTR_SCRATCHPAD 0x0
/*
* CPU Address Decode Windows registers
*/
#define WIN_CTRL(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x0)
#define WIN_BASE(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x4)
#define WIN_REMAP_LO(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x8)
#define WIN_REMAP_HI(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0xc)
struct mbus_dram_target_info dove_mbus_dram_info; struct mbus_dram_target_info dove_mbus_dram_info;
static inline void __iomem *ddr_map_sc(int i) static inline void __iomem *ddr_map_sc(int i)
...@@ -49,78 +42,62 @@ static inline void __iomem *ddr_map_sc(int i) ...@@ -49,78 +42,62 @@ static inline void __iomem *ddr_map_sc(int i)
return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4)); return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4));
} }
static int cpu_win_can_remap(int win) /*
{ * Description of the windows needed by the platform code
if (win < 4) */
return 1; static struct __initdata orion_addr_map_cfg addr_map_cfg = {
.num_wins = 8,
return 0; .remappable_wins = 4,
} .bridge_virt_base = BRIDGE_VIRT_BASE,
};
static void __init setup_cpu_win(int win, u32 base, u32 size,
u8 target, u8 attr, int remap)
{
u32 ctrl;
base &= 0xffff0000;
ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
writel(base, WIN_BASE(win));
writel(ctrl, WIN_CTRL(win));
if (cpu_win_can_remap(win)) {
if (remap < 0)
remap = base;
writel(remap & 0xffff0000, WIN_REMAP_LO(win));
writel(0, WIN_REMAP_HI(win));
}
}
void __init dove_setup_cpu_mbus(void)
{
int i;
int cs;
static const struct __initdata orion_addr_map_info addr_map_info[] = {
/* /*
* First, disable and clear windows. * Windows for PCIe IO+MEM space.
*/ */
for (i = 0; i < 8; i++) { { 0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE,
writel(0, WIN_BASE(i)); TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE
writel(0, WIN_CTRL(i)); },
if (cpu_win_can_remap(i)) { { 1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE,
writel(0, WIN_REMAP_LO(i)); TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE
writel(0, WIN_REMAP_HI(i)); },
} { 2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE,
} TARGET_PCIE0, ATTR_PCIE_MEM, -1
},
{ 3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE,
TARGET_PCIE1, ATTR_PCIE_MEM, -1
},
/* /*
* Setup windows for PCIe IO+MEM space. * Window for CESA engine.
*/ */
setup_cpu_win(0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE, { 4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE,
TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE); TARGET_CESA, ATTR_CESA, -1
setup_cpu_win(1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE, },
TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE);
setup_cpu_win(2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE,
TARGET_PCIE0, ATTR_PCIE_MEM, -1);
setup_cpu_win(3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE,
TARGET_PCIE1, ATTR_PCIE_MEM, -1);
/* /*
* Setup window for CESA engine. * Window to the BootROM for Standby and Sleep Resume
*/ */
setup_cpu_win(4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE, { 5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE,
TARGET_CESA, ATTR_CESA, -1); TARGET_BOOTROM, ATTR_BOOTROM, -1
},
/* /*
* Setup the Window to the BootROM for Standby and Sleep Resume * Window to the PMU Scratch Pad space
*/ */
setup_cpu_win(5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE, { 6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE,
TARGET_BOOTROM, ATTR_BOOTROM, -1); TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1
},
/* End marker */
{ -1, 0, 0, 0, 0, 0 }
};
void __init dove_setup_cpu_mbus(void)
{
int i;
int cs;
/* /*
* Setup the Window to the PMU Scratch Pad space * Disable, clear and configure windows.
*/ */
setup_cpu_win(6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE, orion_config_wins(&addr_map_cfg, addr_map_info);
TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1);
/* /*
* Setup MBUS dram target info. * Setup MBUS dram target info.
......
...@@ -13,12 +13,12 @@ ...@@ -13,12 +13,12 @@
#include <linux/mbus.h> #include <linux/mbus.h>
#include <linux/io.h> #include <linux/io.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <plat/addr-map.h>
#include "common.h" #include "common.h"
/* /*
* Generic Address Decode Windows bit settings * Generic Address Decode Windows bit settings
*/ */
#define TARGET_DDR 0
#define TARGET_DEV_BUS 1 #define TARGET_DEV_BUS 1
#define TARGET_SRAM 3 #define TARGET_SRAM 3
#define TARGET_PCIE 4 #define TARGET_PCIE 4
...@@ -35,119 +35,59 @@ ...@@ -35,119 +35,59 @@
#define ATTR_PCIE1_MEM 0xd8 #define ATTR_PCIE1_MEM 0xd8
#define ATTR_SRAM 0x01 #define ATTR_SRAM 0x01
/* struct mbus_dram_target_info kirkwood_mbus_dram_info;
* 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 * Description of the windows needed by the platform code
*/ */
#define WIN_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) static struct __initdata orion_addr_map_cfg addr_map_cfg = {
#define WIN_CTRL_OFF 0x0000 .num_wins = 8,
#define WIN_BASE_OFF 0x0004 .remappable_wins = 4,
#define WIN_REMAP_LO_OFF 0x0008 .bridge_virt_base = BRIDGE_VIRT_BASE,
#define WIN_REMAP_HI_OFF 0x000c };
struct mbus_dram_target_info kirkwood_mbus_dram_info;
static int __init cpu_win_can_remap(int win)
{
if (win < 4)
return 1;
return 0;
}
static void __init setup_cpu_win(int win, u32 base, u32 size,
u8 target, u8 attr, int remap)
{
void __iomem *addr = (void __iomem *)WIN_OFF(win);
u32 ctrl;
base &= 0xffff0000;
ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
writel(base, addr + WIN_BASE_OFF);
writel(ctrl, addr + WIN_CTRL_OFF);
if (cpu_win_can_remap(win)) {
if (remap < 0)
remap = base;
writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF);
writel(0, addr + WIN_REMAP_HI_OFF);
}
}
void __init kirkwood_setup_cpu_mbus(void)
{
void __iomem *addr;
int i;
int cs;
static const struct __initdata orion_addr_map_info addr_map_info[] = {
/* /*
* First, disable and clear windows. * Windows for PCIe IO+MEM space.
*/ */
for (i = 0; i < 8; i++) { { 0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE,
addr = (void __iomem *)WIN_OFF(i); TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE
},
writel(0, addr + WIN_BASE_OFF); { 1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
writel(0, addr + WIN_CTRL_OFF); TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE
if (cpu_win_can_remap(i)) { },
writel(0, addr + WIN_REMAP_LO_OFF); { 2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE,
writel(0, addr + WIN_REMAP_HI_OFF); TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE
} },
} { 3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE,
TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE
},
/* /*
* Setup windows for PCIe IO+MEM space. * Window for NAND controller.
*/ */
setup_cpu_win(0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE, { 4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE); TARGET_DEV_BUS, ATTR_DEV_NAND, -1
setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE, },
TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE);
setup_cpu_win(2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE,
TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE);
setup_cpu_win(3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE,
TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE);
/* /*
* Setup window for NAND controller. * Window for SRAM.
*/ */
setup_cpu_win(4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE, { 5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
TARGET_DEV_BUS, ATTR_DEV_NAND, -1); TARGET_SRAM, ATTR_SRAM, -1
},
/* End marker */
{ -1, 0, 0, 0, 0, 0 }
};
void __init kirkwood_setup_cpu_mbus(void)
{
/* /*
* Setup window for SRAM. * Disable, clear and configure windows.
*/ */
setup_cpu_win(5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE, orion_config_wins(&addr_map_cfg, addr_map_info);
TARGET_SRAM, ATTR_SRAM, -1);
/* /*
* Setup MBUS dram target info. * Setup MBUS dram target info.
*/ */
kirkwood_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; orion_setup_cpu_mbus_target(&addr_map_cfg, &kirkwood_mbus_dram_info,
DDR_WINDOW_CPU_BASE);
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 = &kirkwood_mbus_dram_info.cs[cs++];
w->cs_index = i;
w->mbus_attr = 0xf & ~(1 << i);
w->base = base & 0xffff0000;
w->size = (size | 0x0000ffff) + 1;
}
}
kirkwood_mbus_dram_info.num_cs = cs;
} }
...@@ -12,12 +12,12 @@ ...@@ -12,12 +12,12 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/mbus.h> #include <linux/mbus.h>
#include <linux/io.h> #include <linux/io.h>
#include <plat/addr-map.h>
#include "common.h" #include "common.h"
/* /*
* Generic Address Decode Windows bit settings * Generic Address Decode Windows bit settings
*/ */
#define TARGET_DDR 0
#define TARGET_DEV_BUS 1 #define TARGET_DEV_BUS 1
#define TARGET_PCIE0 4 #define TARGET_PCIE0 4
#define TARGET_PCIE1 8 #define TARGET_PCIE1 8
...@@ -31,22 +31,11 @@ ...@@ -31,22 +31,11 @@
#define ATTR_PCIE_IO(l) (0xf0 & ~(0x10 << (l))) #define ATTR_PCIE_IO(l) (0xf0 & ~(0x10 << (l)))
#define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l))) #define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l)))
/*
* 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 * CPU Address Decode Windows registers
*/ */
#define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) #define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4))
#define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4)) #define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4))
#define WIN_CTRL_OFF 0x0000
#define WIN_BASE_OFF 0x0004
#define WIN_REMAP_LO_OFF 0x0008
#define WIN_REMAP_HI_OFF 0x000c
struct mbus_dram_target_info mv78xx0_mbus_dram_info; struct mbus_dram_target_info mv78xx0_mbus_dram_info;
...@@ -63,94 +52,45 @@ static void __init __iomem *win_cfg_base(int win) ...@@ -63,94 +52,45 @@ static void __init __iomem *win_cfg_base(int win)
return (void __iomem *)((win < 8) ? WIN0_OFF(win) : WIN8_OFF(win)); return (void __iomem *)((win < 8) ? WIN0_OFF(win) : WIN8_OFF(win));
} }
static int __init cpu_win_can_remap(int win) /*
{ * Description of the windows needed by the platform code
if (win < 8) */
return 1; static struct __initdata orion_addr_map_cfg addr_map_cfg = {
.num_wins = 14,
return 0; .remappable_wins = 8,
} .win_cfg_base = win_cfg_base,
};
static void __init setup_cpu_win(int win, u32 base, u32 size,
u8 target, u8 attr, int remap)
{
void __iomem *addr = win_cfg_base(win);
u32 ctrl;
base &= 0xffff0000;
ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
writel(base, addr + WIN_BASE_OFF);
writel(ctrl, addr + WIN_CTRL_OFF);
if (cpu_win_can_remap(win)) {
if (remap < 0)
remap = base;
writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF);
writel(0, addr + WIN_REMAP_HI_OFF);
}
}
void __init mv78xx0_setup_cpu_mbus(void) void __init mv78xx0_setup_cpu_mbus(void)
{ {
void __iomem *addr;
int i;
int cs;
/* /*
* First, disable and clear windows. * Disable, clear and configure windows.
*/ */
for (i = 0; i < 14; i++) { orion_config_wins(&addr_map_cfg, NULL);
addr = win_cfg_base(i);
writel(0, addr + WIN_BASE_OFF);
writel(0, addr + WIN_CTRL_OFF);
if (cpu_win_can_remap(i)) {
writel(0, addr + WIN_REMAP_LO_OFF);
writel(0, addr + WIN_REMAP_HI_OFF);
}
}
/* /*
* Setup MBUS dram target info. * Setup MBUS dram target info.
*/ */
mv78xx0_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
if (mv78xx0_core_index() == 0) if (mv78xx0_core_index() == 0)
addr = (void __iomem *)DDR_WINDOW_CPU0_BASE; orion_setup_cpu_mbus_target(&addr_map_cfg,
&mv78xx0_mbus_dram_info,
DDR_WINDOW_CPU0_BASE);
else else
addr = (void __iomem *)DDR_WINDOW_CPU1_BASE; orion_setup_cpu_mbus_target(&addr_map_cfg,
&mv78xx0_mbus_dram_info,
for (i = 0, cs = 0; i < 4; i++) { DDR_WINDOW_CPU1_BASE);
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 = &mv78xx0_mbus_dram_info.cs[cs++];
w->cs_index = i;
w->mbus_attr = 0xf & ~(1 << i);
w->base = base & 0xffff0000;
w->size = (size | 0x0000ffff) + 1;
}
}
mv78xx0_mbus_dram_info.num_cs = cs;
} }
void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size, void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
int maj, int min) int maj, int min)
{ {
setup_cpu_win(window, base, size, TARGET_PCIE(maj), orion_setup_cpu_win(&addr_map_cfg, window, base, size,
ATTR_PCIE_IO(min), -1); TARGET_PCIE(maj), ATTR_PCIE_IO(min), -1);
} }
void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size, void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
int maj, int min) int maj, int min)
{ {
setup_cpu_win(window, base, size, TARGET_PCIE(maj), orion_setup_cpu_win(&addr_map_cfg, window, base, size,
ATTR_PCIE_MEM(min), -1); TARGET_PCIE(maj), ATTR_PCIE_MEM(min), -1);
} }
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/mbus.h> #include <linux/mbus.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/errno.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <plat/addr-map.h>
#include "common.h" #include "common.h"
/* /*
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
/* /*
* Generic Address Decode Windows bit settings * Generic Address Decode Windows bit settings
*/ */
#define TARGET_DDR 0
#define TARGET_DEV_BUS 1 #define TARGET_DEV_BUS 1
#define TARGET_PCI 3 #define TARGET_PCI 3
#define TARGET_PCIE 4 #define TARGET_PCIE 4
...@@ -57,27 +56,11 @@ ...@@ -57,27 +56,11 @@
#define ATTR_DEV_BOOT 0xf #define ATTR_DEV_BOOT 0xf
#define ATTR_SRAM 0x0 #define ATTR_SRAM 0x0
/*
* Helpers to get DDR bank info
*/
#define ORION5X_DDR_REG(x) (ORION5X_DDR_VIRT_BASE | (x))
#define DDR_BASE_CS(n) ORION5X_DDR_REG(0x1500 + ((n) << 3))
#define DDR_SIZE_CS(n) ORION5X_DDR_REG(0x1504 + ((n) << 3))
/*
* CPU Address Decode Windows registers
*/
#define ORION5X_BRIDGE_REG(x) (ORION5X_BRIDGE_VIRT_BASE | (x))
#define CPU_WIN_CTRL(n) ORION5X_BRIDGE_REG(0x000 | ((n) << 4))
#define CPU_WIN_BASE(n) ORION5X_BRIDGE_REG(0x004 | ((n) << 4))
#define CPU_WIN_REMAP_LO(n) ORION5X_BRIDGE_REG(0x008 | ((n) << 4))
#define CPU_WIN_REMAP_HI(n) ORION5X_BRIDGE_REG(0x00c | ((n) << 4))
struct mbus_dram_target_info orion5x_mbus_dram_info; struct mbus_dram_target_info orion5x_mbus_dram_info;
static int __initdata win_alloc_count; static int __initdata win_alloc_count;
static int __init orion5x_cpu_win_can_remap(int win) static int __init cpu_win_can_remap(const struct orion_addr_map_cfg *cfg,
const int win)
{ {
u32 dev, rev; u32 dev, rev;
...@@ -91,116 +74,83 @@ static int __init orion5x_cpu_win_can_remap(int win) ...@@ -91,116 +74,83 @@ static int __init orion5x_cpu_win_can_remap(int win)
return 0; return 0;
} }
static int __init setup_cpu_win(int win, u32 base, u32 size, /*
u8 target, u8 attr, int remap) * Description of the windows needed by the platform code
{ */
if (win >= 8) { static struct __initdata orion_addr_map_cfg addr_map_cfg = {
printk(KERN_ERR "setup_cpu_win: trying to allocate " .num_wins = 8,
"window %d\n", win); .cpu_win_can_remap = cpu_win_can_remap,
return -ENOSPC; .bridge_virt_base = ORION5X_BRIDGE_VIRT_BASE,
} };
writel(base & 0xffff0000, CPU_WIN_BASE(win));
writel(((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1,
CPU_WIN_CTRL(win));
if (orion5x_cpu_win_can_remap(win)) {
if (remap < 0)
remap = base;
writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win));
writel(0, CPU_WIN_REMAP_HI(win));
}
return 0;
}
void __init orion5x_setup_cpu_mbus_bridge(void)
{
int i;
int cs;
static const struct __initdata orion_addr_map_info addr_map_info[] = {
/* /*
* First, disable and clear windows. * Setup windows for PCI+PCIe IO+MEM space.
*/ */
for (i = 0; i < 8; i++) { { 0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE,
writel(0, CPU_WIN_BASE(i)); TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE
writel(0, CPU_WIN_CTRL(i)); },
if (orion5x_cpu_win_can_remap(i)) { { 1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE,
writel(0, CPU_WIN_REMAP_LO(i)); TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE
writel(0, CPU_WIN_REMAP_HI(i)); },
} { 2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE,
} TARGET_PCIE, ATTR_PCIE_MEM, -1
},
{ 3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE,
TARGET_PCI, ATTR_PCI_MEM, -1
},
/* End marker */
{ -1, 0, 0, 0, 0, 0 }
};
void __init orion5x_setup_cpu_mbus_bridge(void)
{
/* /*
* Setup windows for PCI+PCIe IO+MEM space. * Disable, clear and configure windows.
*/ */
setup_cpu_win(0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE, orion_config_wins(&addr_map_cfg, addr_map_info);
TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE);
setup_cpu_win(1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE,
TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE);
setup_cpu_win(2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE,
TARGET_PCIE, ATTR_PCIE_MEM, -1);
setup_cpu_win(3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE,
TARGET_PCI, ATTR_PCI_MEM, -1);
win_alloc_count = 4; win_alloc_count = 4;
/* /*
* Setup MBUS dram target info. * Setup MBUS dram target info.
*/ */
orion5x_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; orion_setup_cpu_mbus_target(&addr_map_cfg, &orion5x_mbus_dram_info,
ORION5X_DDR_WINDOW_CPU_BASE);
for (i = 0, cs = 0; i < 4; i++) {
u32 base = readl(DDR_BASE_CS(i));
u32 size = readl(DDR_SIZE_CS(i));
/*
* Chip select enabled?
*/
if (size & 1) {
struct mbus_dram_window *w;
w = &orion5x_mbus_dram_info.cs[cs++];
w->cs_index = i;
w->mbus_attr = 0xf & ~(1 << i);
w->base = base & 0xffff0000;
w->size = (size | 0x0000ffff) + 1;
}
}
orion5x_mbus_dram_info.num_cs = cs;
} }
void __init orion5x_setup_dev_boot_win(u32 base, u32 size) void __init orion5x_setup_dev_boot_win(u32 base, u32 size)
{ {
setup_cpu_win(win_alloc_count++, base, size, orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
TARGET_DEV_BUS, ATTR_DEV_BOOT, -1); TARGET_DEV_BUS, ATTR_DEV_BOOT, -1);
} }
void __init orion5x_setup_dev0_win(u32 base, u32 size) void __init orion5x_setup_dev0_win(u32 base, u32 size)
{ {
setup_cpu_win(win_alloc_count++, base, size, orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
TARGET_DEV_BUS, ATTR_DEV_CS0, -1); TARGET_DEV_BUS, ATTR_DEV_CS0, -1);
} }
void __init orion5x_setup_dev1_win(u32 base, u32 size) void __init orion5x_setup_dev1_win(u32 base, u32 size)
{ {
setup_cpu_win(win_alloc_count++, base, size, orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
TARGET_DEV_BUS, ATTR_DEV_CS1, -1); TARGET_DEV_BUS, ATTR_DEV_CS1, -1);
} }
void __init orion5x_setup_dev2_win(u32 base, u32 size) void __init orion5x_setup_dev2_win(u32 base, u32 size)
{ {
setup_cpu_win(win_alloc_count++, base, size, orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
TARGET_DEV_BUS, ATTR_DEV_CS2, -1); TARGET_DEV_BUS, ATTR_DEV_CS2, -1);
} }
void __init orion5x_setup_pcie_wa_win(u32 base, u32 size) void __init orion5x_setup_pcie_wa_win(u32 base, u32 size)
{ {
setup_cpu_win(win_alloc_count++, base, size, orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
TARGET_PCIE, ATTR_PCIE_WA, -1); TARGET_PCIE, ATTR_PCIE_WA, -1);
} }
int __init orion5x_setup_sram_win(void) void __init orion5x_setup_sram_win(void)
{ {
return setup_cpu_win(win_alloc_count++, ORION5X_SRAM_PHYS_BASE, orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++,
ORION5X_SRAM_SIZE, TARGET_SRAM, ATTR_SRAM, -1); ORION5X_SRAM_PHYS_BASE, ORION5X_SRAM_SIZE,
TARGET_SRAM, ATTR_SRAM, -1);
} }
...@@ -169,12 +169,7 @@ void __init orion5x_xor_init(void) ...@@ -169,12 +169,7 @@ void __init orion5x_xor_init(void)
****************************************************************************/ ****************************************************************************/
static void __init orion5x_crypto_init(void) static void __init orion5x_crypto_init(void)
{ {
int ret; orion5x_setup_sram_win();
ret = orion5x_setup_sram_win();
if (ret)
return;
orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE, orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE,
SZ_8K, IRQ_ORION5X_CESA); SZ_8K, IRQ_ORION5X_CESA);
} }
......
...@@ -27,7 +27,7 @@ void orion5x_setup_dev0_win(u32 base, u32 size); ...@@ -27,7 +27,7 @@ void orion5x_setup_dev0_win(u32 base, u32 size);
void orion5x_setup_dev1_win(u32 base, u32 size); void orion5x_setup_dev1_win(u32 base, u32 size);
void orion5x_setup_dev2_win(u32 base, u32 size); void orion5x_setup_dev2_win(u32 base, u32 size);
void orion5x_setup_pcie_wa_win(u32 base, u32 size); void orion5x_setup_pcie_wa_win(u32 base, u32 size);
int orion5x_setup_sram_win(void); void orion5x_setup_sram_win(void);
void orion5x_ehci0_init(void); void orion5x_ehci0_init(void);
void orion5x_ehci1_init(void); void orion5x_ehci1_init(void);
......
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
******************************************************************************/ ******************************************************************************/
#define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x00000) #define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x00000)
#define ORION5X_DDR_WINDOW_CPU_BASE (ORION5X_DDR_VIRT_BASE | 0x1500)
#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000) #define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000)
#define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000) #define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000)
#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x)) #define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x))
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Makefile for the linux kernel. # 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-m :=
obj-n := obj-n :=
obj- := obj- :=
......
/*
* 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/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
#include <plat/addr-map.h>
/*
* 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,
struct mbus_dram_target_info *info,
const u32 ddr_window_cpu_base)
{
void __iomem *addr;
int i;
int cs;
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 = &info->cs[cs++];
w->cs_index = i;
w->mbus_attr = 0xf & ~(1 << i);
w->base = base & 0xffff0000;
w->size = (size | 0x0000ffff) + 1;
}
}
info->num_cs = cs;
}
/*
* 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
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,
struct mbus_dram_target_info *info,
const u32 ddr_window_cpu_base);
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册