---------------------------------------------------------------
This series will do the following: - Switch the Integrator/AP and /CP to use the SoC bus when booting from device tree. - Group all devices on the SoC below this bus so as to set a good example of how to do this. The bus was invented by Lee Jones, let's show how it's to be used on a DT:ed SoC. - Fetch the special system controller offsets from two special device tree nodes for each case and replace the static mappings with these at boot. - Move some static remaps to the ATAG-only code path and delete some static maps that aren't used. - Push dependencies on system controller remaps down to the Integrator/AP board file and the PCIv3 driver respectively and use only dynamic remappings. - Fix up conditional BUG() usage in the PCIv3 driver to be simpler and more to the point. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJQp9xhAAoJEEEQszewGV1zBmIQAJbGZ1VaD1+G2cpDTkhvN6wv 08hCpqhPpBLR4Zuy5ld1ZpOPfVaPonO2RT6/isTxlT1qgNhOQEJbaj0cGwnaQ5b/ vqvjkkgiOkVkfKTQMb0IwvCNkGB4o1RWiBmvZ+VrPcWfmAkXoCQ4uQuT/I+msjeJ dApJNJP8dwuCJTlX+JsUEDGK5Rtk1UrRMn/ZeQ8JNn7WcztkTd7l5I8oqTrmjtcE 08DfvuByL2InwN1Drs5quaW4NaWg6ZSmMGMDJaH2ETXbZALR1/AXdhBkMSkWm3ty 68O52eIqqJYT+pL3W4MOww7fG9602kK6pqDnYs4yIHQ7pWEns2m4jqAryuTRGYxv hech+i/37b5ghgwuLSsMNNVO+c7gSIT4lHY1bStRGdJMrlRVSPDwn1wJhXs3PeC7 D+TQIngHUfwSN0kjme57MwmKx3epjF5M5A3JjcWGKewbnjj28K7TuGs0voHxh/5L FVf9YC/k07mQoGlaLAm4aa5RGCH0YjoD/7Hllaopa/yxajVx1YtwklV4kZZ9QFPl N2F74bDyQjr9j+lK7oa6Z3YjywZX2L19cfYEhoXQ/qvYx/n4Qg5qCVAcq+siCOt5 6TPmo3zP9Wa6f6aLmiFqVQEHd+Xc1KFFGBLzOJ3NQRqZreDdB9cHTF/VKB3xYBzT MT1tLweT+uqMZElSIsS+ =zpgo -----END PGP SIGNATURE----- Merge tag 'integrator-for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator into next/cleanup From Linus Walleij <linus.walleij@linaro.org>: This series will do the following: - Switch the Integrator/AP and /CP to use the SoC bus when booting from device tree. - Group all devices on the SoC below this bus so as to set a good example of how to do this. The bus was invented by Lee Jones, let's show how it's to be used on a DT:ed SoC. - Fetch the special system controller offsets from two special device tree nodes for each case and replace the static mappings with these at boot. - Move some static remaps to the ATAG-only code path and delete some static maps that aren't used. - Push dependencies on system controller remaps down to the Integrator/AP board file and the PCIv3 driver respectively and use only dynamic remappings. - Fix up conditional BUG() usage in the PCIv3 driver to be simpler and more to the point. * tag 'integrator-for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator: ARM: integrator: use BUG_ON where possible ARM: integrator: push down SC dependencies ARM: integrator: delete static UART1 mapping ARM: integrator: delete SC mapping on the CP ARM: integrator: remove static CP syscon mapping ARM: integrator: remove static AP syscon mapping ARM: integrator: hook the CP into the SoC bus ARM: integrator: hook the AP into the SoC bus Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
4c929c8a88
|
@ -9,6 +9,10 @@ Required properties (in root node):
|
|||
|
||||
FPGA type interrupt controllers, see the versatile-fpga-irq binding doc.
|
||||
|
||||
In the root node the Integrator/CP must have a /cpcon node pointing
|
||||
to the CP control registers, and the Integrator/AP must have a
|
||||
/syscon node pointing to the Integrator/AP system controller.
|
||||
|
||||
|
||||
ARM Versatile Application and Platform Baseboards
|
||||
-------------------------------------------------
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk";
|
||||
};
|
||||
|
||||
syscon {
|
||||
/* AP system controller registers */
|
||||
reg = <0x11000000 0x100>;
|
||||
};
|
||||
|
||||
timer0: timer@13000000 {
|
||||
compatible = "arm,integrator-timer";
|
||||
};
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk";
|
||||
};
|
||||
|
||||
cpcon {
|
||||
/* CP controller registers */
|
||||
reg = <0xcb000000 0x100>;
|
||||
};
|
||||
|
||||
timer0: timer@13000000 {
|
||||
compatible = "arm,sp804", "arm,primecell";
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@ config ARCH_INTEGRATOR_AP
|
|||
select MIGHT_HAVE_PCI
|
||||
select SERIAL_AMBA_PL010
|
||||
select SERIAL_AMBA_PL010_CONSOLE
|
||||
select SOC_BUS
|
||||
help
|
||||
Include support for the ARM(R) Integrator/AP and
|
||||
Integrator/PP2 platforms.
|
||||
|
@ -19,6 +20,7 @@ config ARCH_INTEGRATOR_CP
|
|||
select PLAT_VERSATILE_CLCD
|
||||
select SERIAL_AMBA_PL011
|
||||
select SERIAL_AMBA_PL011_CONSOLE
|
||||
select SOC_BUS
|
||||
help
|
||||
Include support for the ARM(R) Integrator CP platform.
|
||||
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
#include <linux/amba/serial.h>
|
||||
extern struct amba_pl010_data integrator_uart_data;
|
||||
#ifdef CONFIG_ARCH_INTEGRATOR_AP
|
||||
extern struct amba_pl010_data ap_uart_data;
|
||||
#else
|
||||
/* Not used without Integrator/AP support anyway */
|
||||
struct amba_pl010_data ap_uart_data {};
|
||||
#endif
|
||||
void integrator_init_early(void);
|
||||
int integrator_init(bool is_cp);
|
||||
void integrator_reserve(void);
|
||||
void integrator_restart(char, const char *);
|
||||
void integrator_init_sysfs(struct device *parent, u32 id);
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
#include <linux/memblock.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/termios.h>
|
||||
#include <linux/amba/bus.h>
|
||||
#include <linux/amba/serial.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/platform.h>
|
||||
|
@ -46,10 +46,10 @@ static AMBA_APB_DEVICE(rtc, "rtc", 0,
|
|||
INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL);
|
||||
|
||||
static AMBA_APB_DEVICE(uart0, "uart0", 0,
|
||||
INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, &integrator_uart_data);
|
||||
INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, NULL);
|
||||
|
||||
static AMBA_APB_DEVICE(uart1, "uart1", 0,
|
||||
INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, &integrator_uart_data);
|
||||
INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, NULL);
|
||||
|
||||
static AMBA_APB_DEVICE(kmi0, "kmi0", 0, KMI0_BASE, KMI0_IRQ, NULL);
|
||||
static AMBA_APB_DEVICE(kmi1, "kmi1", 0, KMI1_BASE, KMI1_IRQ, NULL);
|
||||
|
@ -77,6 +77,8 @@ int __init integrator_init(bool is_cp)
|
|||
uart1_device.periphid = 0x00041010;
|
||||
kmi0_device.periphid = 0x00041050;
|
||||
kmi1_device.periphid = 0x00041050;
|
||||
uart0_device.dev.platform_data = &ap_uart_data;
|
||||
uart1_device.dev.platform_data = &ap_uart_data;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
||||
|
@ -89,49 +91,6 @@ int __init integrator_init(bool is_cp)
|
|||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On the Integrator platform, the port RTS and DTR are provided by
|
||||
* bits in the following SC_CTRLS register bits:
|
||||
* RTS DTR
|
||||
* UART0 7 6
|
||||
* UART1 5 4
|
||||
*/
|
||||
#define SC_CTRLC __io_address(INTEGRATOR_SC_CTRLC)
|
||||
#define SC_CTRLS __io_address(INTEGRATOR_SC_CTRLS)
|
||||
|
||||
static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl)
|
||||
{
|
||||
unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
|
||||
u32 phybase = dev->res.start;
|
||||
|
||||
if (phybase == INTEGRATOR_UART0_BASE) {
|
||||
/* UART0 */
|
||||
rts_mask = 1 << 4;
|
||||
dtr_mask = 1 << 5;
|
||||
} else {
|
||||
/* UART1 */
|
||||
rts_mask = 1 << 6;
|
||||
dtr_mask = 1 << 7;
|
||||
}
|
||||
|
||||
if (mctrl & TIOCM_RTS)
|
||||
ctrlc |= rts_mask;
|
||||
else
|
||||
ctrls |= rts_mask;
|
||||
|
||||
if (mctrl & TIOCM_DTR)
|
||||
ctrlc |= dtr_mask;
|
||||
else
|
||||
ctrls |= dtr_mask;
|
||||
|
||||
__raw_writel(ctrls, SC_CTRLS);
|
||||
__raw_writel(ctrlc, SC_CTRLC);
|
||||
}
|
||||
|
||||
struct amba_pl010_data integrator_uart_data = {
|
||||
.set_mctrl = integrator_uart_set_mctrl,
|
||||
};
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(cm_lock);
|
||||
|
||||
/**
|
||||
|
@ -169,3 +128,93 @@ void integrator_restart(char mode, const char *cmd)
|
|||
{
|
||||
cm_control(CM_CTRL_RESET, CM_CTRL_RESET);
|
||||
}
|
||||
|
||||
static u32 integrator_id;
|
||||
|
||||
static ssize_t intcp_get_manf(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%02x\n", integrator_id >> 24);
|
||||
}
|
||||
|
||||
static struct device_attribute intcp_manf_attr =
|
||||
__ATTR(manufacturer, S_IRUGO, intcp_get_manf, NULL);
|
||||
|
||||
static ssize_t intcp_get_arch(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
const char *arch;
|
||||
|
||||
switch ((integrator_id >> 16) & 0xff) {
|
||||
case 0x00:
|
||||
arch = "ASB little-endian";
|
||||
break;
|
||||
case 0x01:
|
||||
arch = "AHB little-endian";
|
||||
break;
|
||||
case 0x03:
|
||||
arch = "AHB-Lite system bus, bi-endian";
|
||||
break;
|
||||
case 0x04:
|
||||
arch = "AHB";
|
||||
break;
|
||||
default:
|
||||
arch = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%s\n", arch);
|
||||
}
|
||||
|
||||
static struct device_attribute intcp_arch_attr =
|
||||
__ATTR(architecture, S_IRUGO, intcp_get_arch, NULL);
|
||||
|
||||
static ssize_t intcp_get_fpga(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
const char *fpga;
|
||||
|
||||
switch ((integrator_id >> 12) & 0xf) {
|
||||
case 0x01:
|
||||
fpga = "XC4062";
|
||||
break;
|
||||
case 0x02:
|
||||
fpga = "XC4085";
|
||||
break;
|
||||
case 0x04:
|
||||
fpga = "EPM7256AE (Altera PLD)";
|
||||
break;
|
||||
default:
|
||||
fpga = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%s\n", fpga);
|
||||
}
|
||||
|
||||
static struct device_attribute intcp_fpga_attr =
|
||||
__ATTR(fpga, S_IRUGO, intcp_get_fpga, NULL);
|
||||
|
||||
static ssize_t intcp_get_build(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%02x\n", (integrator_id >> 4) & 0xFF);
|
||||
}
|
||||
|
||||
static struct device_attribute intcp_build_attr =
|
||||
__ATTR(build, S_IRUGO, intcp_get_build, NULL);
|
||||
|
||||
|
||||
|
||||
void integrator_init_sysfs(struct device *parent, u32 id)
|
||||
{
|
||||
integrator_id = id;
|
||||
device_create_file(parent, &intcp_manf_attr);
|
||||
device_create_file(parent, &intcp_arch_attr);
|
||||
device_create_file(parent, &intcp_fpga_attr);
|
||||
device_create_file(parent, &intcp_build_attr);
|
||||
}
|
||||
|
|
|
@ -190,7 +190,6 @@
|
|||
#define INTEGRATOR_SC_CTRLC_OFFSET 0x0C
|
||||
#define INTEGRATOR_SC_DEC_OFFSET 0x10
|
||||
#define INTEGRATOR_SC_ARB_OFFSET 0x14
|
||||
#define INTEGRATOR_SC_PCIENABLE_OFFSET 0x18
|
||||
#define INTEGRATOR_SC_LOCK_OFFSET 0x1C
|
||||
|
||||
#define INTEGRATOR_SC_BASE 0x11000000
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
#include <linux/of_irq.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/sys_soc.h>
|
||||
#include <linux/termios.h>
|
||||
#include <video/vga.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
@ -60,7 +63,10 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
/* Base address to the AP system controller */
|
||||
void __iomem *ap_syscon_base;
|
||||
|
||||
/*
|
||||
* All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
|
||||
* is the (PA >> 12).
|
||||
*
|
||||
|
@ -68,7 +74,6 @@
|
|||
* just for now).
|
||||
*/
|
||||
#define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE)
|
||||
#define VA_SC_BASE __io_address(INTEGRATOR_SC_BASE)
|
||||
#define VA_EBI_BASE __io_address(INTEGRATOR_EBI_BASE)
|
||||
#define VA_CMIC_BASE __io_address(INTEGRATOR_HDR_IC)
|
||||
|
||||
|
@ -96,11 +101,6 @@ static struct map_desc ap_io_desc[] __initdata = {
|
|||
.pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = IO_ADDRESS(INTEGRATOR_SC_BASE),
|
||||
.pfn = __phys_to_pfn(INTEGRATOR_SC_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE),
|
||||
.pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE),
|
||||
|
@ -121,11 +121,6 @@ static struct map_desc ap_io_desc[] __initdata = {
|
|||
.pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE),
|
||||
.pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE),
|
||||
.pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE),
|
||||
|
@ -201,8 +196,6 @@ device_initcall(irq_syscore_init);
|
|||
/*
|
||||
* Flash handling.
|
||||
*/
|
||||
#define SC_CTRLC (VA_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET)
|
||||
#define SC_CTRLS (VA_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET)
|
||||
#define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
|
||||
#define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
|
||||
|
||||
|
@ -210,7 +203,8 @@ static int ap_flash_init(struct platform_device *dev)
|
|||
{
|
||||
u32 tmp;
|
||||
|
||||
writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
|
||||
writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP,
|
||||
ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
|
||||
|
||||
tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
|
||||
writel(tmp, EBI_CSR1);
|
||||
|
@ -227,7 +221,8 @@ static void ap_flash_exit(struct platform_device *dev)
|
|||
{
|
||||
u32 tmp;
|
||||
|
||||
writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
|
||||
writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP,
|
||||
ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
|
||||
|
||||
tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
|
||||
writel(tmp, EBI_CSR1);
|
||||
|
@ -241,9 +236,12 @@ static void ap_flash_exit(struct platform_device *dev)
|
|||
|
||||
static void ap_flash_set_vpp(struct platform_device *pdev, int on)
|
||||
{
|
||||
void __iomem *reg = on ? SC_CTRLS : SC_CTRLC;
|
||||
|
||||
writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
|
||||
if (on)
|
||||
writel(INTEGRATOR_SC_CTRL_nFLVPPEN,
|
||||
ap_syscon_base + INTEGRATOR_SC_CTRLS_OFFSET);
|
||||
else
|
||||
writel(INTEGRATOR_SC_CTRL_nFLVPPEN,
|
||||
ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
|
||||
}
|
||||
|
||||
static struct physmap_flash_data ap_flash_data = {
|
||||
|
@ -253,6 +251,45 @@ static struct physmap_flash_data ap_flash_data = {
|
|||
.set_vpp = ap_flash_set_vpp,
|
||||
};
|
||||
|
||||
/*
|
||||
* For the PL010 found in the Integrator/AP some of the UART control is
|
||||
* implemented in the system controller and accessed using a callback
|
||||
* from the driver.
|
||||
*/
|
||||
static void integrator_uart_set_mctrl(struct amba_device *dev,
|
||||
void __iomem *base, unsigned int mctrl)
|
||||
{
|
||||
unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
|
||||
u32 phybase = dev->res.start;
|
||||
|
||||
if (phybase == INTEGRATOR_UART0_BASE) {
|
||||
/* UART0 */
|
||||
rts_mask = 1 << 4;
|
||||
dtr_mask = 1 << 5;
|
||||
} else {
|
||||
/* UART1 */
|
||||
rts_mask = 1 << 6;
|
||||
dtr_mask = 1 << 7;
|
||||
}
|
||||
|
||||
if (mctrl & TIOCM_RTS)
|
||||
ctrlc |= rts_mask;
|
||||
else
|
||||
ctrls |= rts_mask;
|
||||
|
||||
if (mctrl & TIOCM_DTR)
|
||||
ctrlc |= dtr_mask;
|
||||
else
|
||||
ctrls |= dtr_mask;
|
||||
|
||||
__raw_writel(ctrls, ap_syscon_base + INTEGRATOR_SC_CTRLS_OFFSET);
|
||||
__raw_writel(ctrlc, ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
|
||||
}
|
||||
|
||||
struct amba_pl010_data ap_uart_data = {
|
||||
.set_mctrl = integrator_uart_set_mctrl,
|
||||
};
|
||||
|
||||
/*
|
||||
* Where is the timer (VA)?
|
||||
*/
|
||||
|
@ -450,9 +487,9 @@ static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
|
|||
OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,
|
||||
"rtc", NULL),
|
||||
OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
|
||||
"uart0", &integrator_uart_data),
|
||||
"uart0", &ap_uart_data),
|
||||
OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
|
||||
"uart1", &integrator_uart_data),
|
||||
"uart1", &ap_uart_data),
|
||||
OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,
|
||||
"kmi0", NULL),
|
||||
OF_DEV_AUXDATA("arm,primecell", KMI1_BASE,
|
||||
|
@ -465,12 +502,60 @@ static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
|
|||
static void __init ap_init_of(void)
|
||||
{
|
||||
unsigned long sc_dec;
|
||||
struct device_node *root;
|
||||
struct device_node *syscon;
|
||||
struct device *parent;
|
||||
struct soc_device *soc_dev;
|
||||
struct soc_device_attribute *soc_dev_attr;
|
||||
u32 ap_sc_id;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table,
|
||||
ap_auxdata_lookup, NULL);
|
||||
/* Here we create an SoC device for the root node */
|
||||
root = of_find_node_by_path("/");
|
||||
if (!root)
|
||||
return;
|
||||
syscon = of_find_node_by_path("/syscon");
|
||||
if (!syscon)
|
||||
return;
|
||||
|
||||
sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
|
||||
ap_syscon_base = of_iomap(syscon, 0);
|
||||
if (!ap_syscon_base)
|
||||
return;
|
||||
|
||||
ap_sc_id = readl(ap_syscon_base);
|
||||
|
||||
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
|
||||
if (!soc_dev_attr)
|
||||
return;
|
||||
|
||||
err = of_property_read_string(root, "compatible",
|
||||
&soc_dev_attr->soc_id);
|
||||
if (err)
|
||||
return;
|
||||
err = of_property_read_string(root, "model", &soc_dev_attr->machine);
|
||||
if (err)
|
||||
return;
|
||||
soc_dev_attr->family = "Integrator";
|
||||
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c",
|
||||
'A' + (ap_sc_id & 0x0f));
|
||||
|
||||
soc_dev = soc_device_register(soc_dev_attr);
|
||||
if (IS_ERR_OR_NULL(soc_dev)) {
|
||||
kfree(soc_dev_attr->revision);
|
||||
kfree(soc_dev_attr);
|
||||
return;
|
||||
}
|
||||
|
||||
parent = soc_device_to_device(soc_dev);
|
||||
|
||||
if (!IS_ERR_OR_NULL(parent))
|
||||
integrator_init_sysfs(parent, ap_sc_id);
|
||||
|
||||
of_platform_populate(root, of_default_bus_match_table,
|
||||
ap_auxdata_lookup, parent);
|
||||
|
||||
sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct lm_device *lmdev;
|
||||
|
||||
|
@ -513,6 +598,27 @@ MACHINE_END
|
|||
|
||||
#ifdef CONFIG_ATAGS
|
||||
|
||||
/*
|
||||
* For the ATAG boot some static mappings are needed. This will
|
||||
* go away with the ATAG support down the road.
|
||||
*/
|
||||
|
||||
static struct map_desc ap_io_desc_atag[] __initdata = {
|
||||
{
|
||||
.virtual = IO_ADDRESS(INTEGRATOR_SC_BASE),
|
||||
.pfn = __phys_to_pfn(INTEGRATOR_SC_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
};
|
||||
|
||||
static void __init ap_map_io_atag(void)
|
||||
{
|
||||
iotable_init(ap_io_desc_atag, ARRAY_SIZE(ap_io_desc_atag));
|
||||
ap_syscon_base = __io_address(INTEGRATOR_SC_BASE);
|
||||
ap_map_io();
|
||||
}
|
||||
|
||||
/*
|
||||
* This is where non-devicetree initialization code is collected and stashed
|
||||
* for eventual deletion.
|
||||
|
@ -581,7 +687,7 @@ static void __init ap_init(void)
|
|||
|
||||
platform_device_register(&cfi_flash_device);
|
||||
|
||||
sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
|
||||
sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct lm_device *lmdev;
|
||||
|
||||
|
@ -608,7 +714,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")
|
|||
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
|
||||
.atag_offset = 0x100,
|
||||
.reserve = integrator_reserve,
|
||||
.map_io = ap_map_io,
|
||||
.map_io = ap_map_io_atag,
|
||||
.nr_irqs = NR_IRQS_INTEGRATOR_AP,
|
||||
.init_early = ap_init_early,
|
||||
.init_irq = ap_init_irq,
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/of_irq.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/sys_soc.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/platform.h>
|
||||
|
@ -51,11 +52,13 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
/* Base address to the CP controller */
|
||||
static void __iomem *intcp_con_base;
|
||||
|
||||
#define INTCP_PA_FLASH_BASE 0x24000000
|
||||
|
||||
#define INTCP_PA_CLCD_BASE 0xc0000000
|
||||
|
||||
#define INTCP_VA_CTRL_BASE __io_address(INTEGRATOR_CP_CTL_BASE)
|
||||
#define INTCP_FLASHPROG 0x04
|
||||
#define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0)
|
||||
#define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1)
|
||||
|
@ -81,11 +84,6 @@ static struct map_desc intcp_io_desc[] __initdata = {
|
|||
.pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = IO_ADDRESS(INTEGRATOR_SC_BASE),
|
||||
.pfn = __phys_to_pfn(INTEGRATOR_SC_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE),
|
||||
.pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE),
|
||||
|
@ -106,11 +104,6 @@ static struct map_desc intcp_io_desc[] __initdata = {
|
|||
.pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE),
|
||||
.pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE),
|
||||
.pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE),
|
||||
|
@ -126,11 +119,6 @@ static struct map_desc intcp_io_desc[] __initdata = {
|
|||
.pfn = __phys_to_pfn(INTEGRATOR_CP_SIC_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = IO_ADDRESS(INTEGRATOR_CP_CTL_BASE),
|
||||
.pfn = __phys_to_pfn(INTEGRATOR_CP_CTL_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -146,9 +134,9 @@ static int intcp_flash_init(struct platform_device *dev)
|
|||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
|
||||
val = readl(intcp_con_base + INTCP_FLASHPROG);
|
||||
val |= CINTEGRATOR_FLASHPROG_FLWREN;
|
||||
writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
|
||||
writel(val, intcp_con_base + INTCP_FLASHPROG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -157,21 +145,21 @@ static void intcp_flash_exit(struct platform_device *dev)
|
|||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
|
||||
val = readl(intcp_con_base + INTCP_FLASHPROG);
|
||||
val &= ~(CINTEGRATOR_FLASHPROG_FLVPPEN|CINTEGRATOR_FLASHPROG_FLWREN);
|
||||
writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
|
||||
writel(val, intcp_con_base + INTCP_FLASHPROG);
|
||||
}
|
||||
|
||||
static void intcp_flash_set_vpp(struct platform_device *pdev, int on)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
|
||||
val = readl(intcp_con_base + INTCP_FLASHPROG);
|
||||
if (on)
|
||||
val |= CINTEGRATOR_FLASHPROG_FLVPPEN;
|
||||
else
|
||||
val &= ~CINTEGRATOR_FLASHPROG_FLVPPEN;
|
||||
writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
|
||||
writel(val, intcp_con_base + INTCP_FLASHPROG);
|
||||
}
|
||||
|
||||
static struct physmap_flash_data intcp_flash_data = {
|
||||
|
@ -190,7 +178,7 @@ static struct physmap_flash_data intcp_flash_data = {
|
|||
static unsigned int mmc_status(struct device *dev)
|
||||
{
|
||||
unsigned int status = readl(__io_address(0xca000000 + 4));
|
||||
writel(8, __io_address(INTEGRATOR_CP_CTL_BASE + 8));
|
||||
writel(8, intcp_con_base + 8);
|
||||
|
||||
return status & 8;
|
||||
}
|
||||
|
@ -318,9 +306,9 @@ static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {
|
|||
OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,
|
||||
"rtc", NULL),
|
||||
OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
|
||||
"uart0", &integrator_uart_data),
|
||||
"uart0", NULL),
|
||||
OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
|
||||
"uart1", &integrator_uart_data),
|
||||
"uart1", NULL),
|
||||
OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,
|
||||
"kmi0", NULL),
|
||||
OF_DEV_AUXDATA("arm,primecell", KMI1_BASE,
|
||||
|
@ -338,8 +326,57 @@ static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {
|
|||
|
||||
static void __init intcp_init_of(void)
|
||||
{
|
||||
of_platform_populate(NULL, of_default_bus_match_table,
|
||||
intcp_auxdata_lookup, NULL);
|
||||
struct device_node *root;
|
||||
struct device_node *cpcon;
|
||||
struct device *parent;
|
||||
struct soc_device *soc_dev;
|
||||
struct soc_device_attribute *soc_dev_attr;
|
||||
u32 intcp_sc_id;
|
||||
int err;
|
||||
|
||||
/* Here we create an SoC device for the root node */
|
||||
root = of_find_node_by_path("/");
|
||||
if (!root)
|
||||
return;
|
||||
cpcon = of_find_node_by_path("/cpcon");
|
||||
if (!cpcon)
|
||||
return;
|
||||
|
||||
intcp_con_base = of_iomap(cpcon, 0);
|
||||
if (!intcp_con_base)
|
||||
return;
|
||||
|
||||
intcp_sc_id = readl(intcp_con_base);
|
||||
|
||||
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
|
||||
if (!soc_dev_attr)
|
||||
return;
|
||||
|
||||
err = of_property_read_string(root, "compatible",
|
||||
&soc_dev_attr->soc_id);
|
||||
if (err)
|
||||
return;
|
||||
err = of_property_read_string(root, "model", &soc_dev_attr->machine);
|
||||
if (err)
|
||||
return;
|
||||
soc_dev_attr->family = "Integrator";
|
||||
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c",
|
||||
'A' + (intcp_sc_id & 0x0f));
|
||||
|
||||
soc_dev = soc_device_register(soc_dev_attr);
|
||||
if (IS_ERR_OR_NULL(soc_dev)) {
|
||||
kfree(soc_dev_attr->revision);
|
||||
kfree(soc_dev_attr);
|
||||
return;
|
||||
}
|
||||
|
||||
parent = soc_device_to_device(soc_dev);
|
||||
|
||||
if (!IS_ERR_OR_NULL(parent))
|
||||
integrator_init_sysfs(parent, intcp_sc_id);
|
||||
|
||||
of_platform_populate(root, of_default_bus_match_table,
|
||||
intcp_auxdata_lookup, parent);
|
||||
}
|
||||
|
||||
static const char * intcp_dt_board_compat[] = {
|
||||
|
@ -364,6 +401,28 @@ MACHINE_END
|
|||
|
||||
#ifdef CONFIG_ATAGS
|
||||
|
||||
/*
|
||||
* For the ATAG boot some static mappings are needed. This will
|
||||
* go away with the ATAG support down the road.
|
||||
*/
|
||||
|
||||
static struct map_desc intcp_io_desc_atag[] __initdata = {
|
||||
{
|
||||
.virtual = IO_ADDRESS(INTEGRATOR_CP_CTL_BASE),
|
||||
.pfn = __phys_to_pfn(INTEGRATOR_CP_CTL_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
};
|
||||
|
||||
static void __init intcp_map_io_atag(void)
|
||||
{
|
||||
iotable_init(intcp_io_desc_atag, ARRAY_SIZE(intcp_io_desc_atag));
|
||||
intcp_con_base = __io_address(INTEGRATOR_CP_CTL_BASE);
|
||||
intcp_map_io();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is where non-devicetree initialization code is collected and stashed
|
||||
* for eventual deletion.
|
||||
|
@ -503,7 +562,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
|
|||
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
|
||||
.atag_offset = 0x100,
|
||||
.reserve = integrator_reserve,
|
||||
.map_io = intcp_map_io,
|
||||
.map_io = intcp_map_io_atag,
|
||||
.nr_irqs = NR_IRQS_INTEGRATOR_CP,
|
||||
.init_early = intcp_init_early,
|
||||
.init_irq = intcp_init_irq,
|
||||
|
|
|
@ -191,12 +191,9 @@ static void __iomem *v3_open_config_window(struct pci_bus *bus,
|
|||
/*
|
||||
* Trap out illegal values
|
||||
*/
|
||||
if (offset > 255)
|
||||
BUG();
|
||||
if (busnr > 255)
|
||||
BUG();
|
||||
if (devfn > 255)
|
||||
BUG();
|
||||
BUG_ON(offset > 255);
|
||||
BUG_ON(busnr > 255);
|
||||
BUG_ON(devfn > 255);
|
||||
|
||||
if (busnr == 0) {
|
||||
int slot = PCI_SLOT(devfn);
|
||||
|
@ -388,9 +385,10 @@ static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
|
|||
* means I can't get additional information on the reason for the pm2fb
|
||||
* problems. I suppose I'll just have to mind-meld with the machine. ;)
|
||||
*/
|
||||
#define SC_PCI __io_address(INTEGRATOR_SC_PCIENABLE)
|
||||
#define SC_LBFADDR __io_address(INTEGRATOR_SC_BASE + 0x20)
|
||||
#define SC_LBFCODE __io_address(INTEGRATOR_SC_BASE + 0x24)
|
||||
static void __iomem *ap_syscon_base;
|
||||
#define INTEGRATOR_SC_PCIENABLE_OFFSET 0x18
|
||||
#define INTEGRATOR_SC_LBFADDR_OFFSET 0x20
|
||||
#define INTEGRATOR_SC_LBFCODE_OFFSET 0x24
|
||||
|
||||
static int
|
||||
v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
|
||||
|
@ -401,13 +399,13 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
|
|||
char buf[128];
|
||||
|
||||
sprintf(buf, "V3 fault: addr 0x%08lx, FSR 0x%03x, PC 0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
|
||||
addr, fsr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
|
||||
addr, fsr, pc, instr, __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET), __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
|
||||
v3_readb(V3_LB_ISTAT));
|
||||
printk(KERN_DEBUG "%s", buf);
|
||||
#endif
|
||||
|
||||
v3_writeb(V3_LB_ISTAT, 0);
|
||||
__raw_writel(3, SC_PCI);
|
||||
__raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
|
||||
|
||||
/*
|
||||
* If the instruction being executed was a read,
|
||||
|
@ -449,15 +447,15 @@ static irqreturn_t v3_irq(int dummy, void *devid)
|
|||
|
||||
sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x "
|
||||
"ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr,
|
||||
__raw_readl(SC_LBFADDR),
|
||||
__raw_readl(SC_LBFCODE) & 255,
|
||||
__raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET),
|
||||
__raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
|
||||
v3_readb(V3_LB_ISTAT));
|
||||
printascii(buf);
|
||||
#endif
|
||||
|
||||
v3_writew(V3_PCI_STAT, 0xf000);
|
||||
v3_writeb(V3_LB_ISTAT, 0);
|
||||
__raw_writel(3, SC_PCI);
|
||||
__raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
|
||||
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
/*
|
||||
|
@ -480,6 +478,10 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
|
|||
if (nr == 0) {
|
||||
sys->mem_offset = PHYS_PCI_MEM_BASE;
|
||||
ret = pci_v3_setup_resources(sys);
|
||||
/* Remap the Integrator system controller */
|
||||
ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100);
|
||||
if (!ap_syscon_base)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -568,7 +570,7 @@ void __init pci_v3_preinit(void)
|
|||
v3_writeb(V3_LB_ISTAT, 0);
|
||||
v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));
|
||||
v3_writeb(V3_LB_IMASK, 0x28);
|
||||
__raw_writel(3, SC_PCI);
|
||||
__raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
|
||||
|
||||
/*
|
||||
* Grab the PCI error interrupt.
|
||||
|
|
Loading…
Reference in New Issue