aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2012-11-17 13:24:23 -0500
committerLinus Walleij <linus.walleij@linaro.org>2012-11-17 13:38:27 -0500
commit379df2793efdca18e91cb8570f844ad1f83eb609 (patch)
tree6f61e172528c1fdade27517301787e4c0b174243
parent328ba305e3871d4256398a80f45517ec9c814999 (diff)
ARM: integrator: push down SC dependencies
This pushes the dependencies on the Integrator/AP system controller (SC) down into the PCI V3 driver and the AP-specific board file. First, the platform data for the PL010 UART is moved into the integrator_ap.c board file, and the Integrator/CP is assigned with NULL pdata. This way the callback functions can reference the dynamically remapped AP syscon address in both the ATAG and DT boot path, and this remapping is localized to the board file. Second the PCIv3 driver is making its own dynamic remapping of the SC for the few registers it is using. When we convert the PCIv3 driver over to using device tree having a dynamically assigned base address will be useful, but we will have to use the definition from <mach/platform.h> for now, the only improvement is that it's done dynamically. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--arch/arm/mach-integrator/common.h7
-rw-r--r--arch/arm/mach-integrator/core.c50
-rw-r--r--arch/arm/mach-integrator/include/mach/platform.h1
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c46
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c4
-rw-r--r--arch/arm/mach-integrator/pci_v3.c23
6 files changed, 69 insertions, 62 deletions
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
index fc9f47d289f4..79197d8b34aa 100644
--- a/arch/arm/mach-integrator/common.h
+++ b/arch/arm/mach-integrator/common.h
@@ -1,5 +1,10 @@
1#include <linux/amba/serial.h> 1#include <linux/amba/serial.h>
2extern struct amba_pl010_data integrator_uart_data; 2#ifdef CONFIG_ARCH_INTEGRATOR_AP
3extern struct amba_pl010_data ap_uart_data;
4#else
5/* Not used without Integrator/AP support anyway */
6struct amba_pl010_data ap_uart_data {};
7#endif
3void integrator_init_early(void); 8void integrator_init_early(void);
4int integrator_init(bool is_cp); 9int integrator_init(bool is_cp);
5void integrator_reserve(void); 10void integrator_reserve(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 161fbf8596bd..39c060f75e47 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -18,7 +18,6 @@
18#include <linux/memblock.h> 18#include <linux/memblock.h>
19#include <linux/sched.h> 19#include <linux/sched.h>
20#include <linux/smp.h> 20#include <linux/smp.h>
21#include <linux/termios.h>
22#include <linux/amba/bus.h> 21#include <linux/amba/bus.h>
23#include <linux/amba/serial.h> 22#include <linux/amba/serial.h>
24#include <linux/io.h> 23#include <linux/io.h>
@@ -47,10 +46,10 @@ static AMBA_APB_DEVICE(rtc, "rtc", 0,
47 INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL); 46 INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL);
48 47
49static AMBA_APB_DEVICE(uart0, "uart0", 0, 48static AMBA_APB_DEVICE(uart0, "uart0", 0,
50 INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, &integrator_uart_data); 49 INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, NULL);
51 50
52static AMBA_APB_DEVICE(uart1, "uart1", 0, 51static AMBA_APB_DEVICE(uart1, "uart1", 0,
53 INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, &integrator_uart_data); 52 INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, NULL);
54 53
55static AMBA_APB_DEVICE(kmi0, "kmi0", 0, KMI0_BASE, KMI0_IRQ, NULL); 54static AMBA_APB_DEVICE(kmi0, "kmi0", 0, KMI0_BASE, KMI0_IRQ, NULL);
56static AMBA_APB_DEVICE(kmi1, "kmi1", 0, KMI1_BASE, KMI1_IRQ, NULL); 55static AMBA_APB_DEVICE(kmi1, "kmi1", 0, KMI1_BASE, KMI1_IRQ, NULL);
@@ -78,6 +77,8 @@ int __init integrator_init(bool is_cp)
78 uart1_device.periphid = 0x00041010; 77 uart1_device.periphid = 0x00041010;
79 kmi0_device.periphid = 0x00041050; 78 kmi0_device.periphid = 0x00041050;
80 kmi1_device.periphid = 0x00041050; 79 kmi1_device.periphid = 0x00041050;
80 uart0_device.dev.platform_data = &ap_uart_data;
81 uart1_device.dev.platform_data = &ap_uart_data;
81 } 82 }
82 83
83 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { 84 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
@@ -90,49 +91,6 @@ int __init integrator_init(bool is_cp)
90 91
91#endif 92#endif
92 93
93/*
94 * On the Integrator platform, the port RTS and DTR are provided by
95 * bits in the following SC_CTRLS register bits:
96 * RTS DTR
97 * UART0 7 6
98 * UART1 5 4
99 */
100#define SC_CTRLC __io_address(INTEGRATOR_SC_CTRLC)
101#define SC_CTRLS __io_address(INTEGRATOR_SC_CTRLS)
102
103static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl)
104{
105 unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
106 u32 phybase = dev->res.start;
107
108 if (phybase == INTEGRATOR_UART0_BASE) {
109 /* UART0 */
110 rts_mask = 1 << 4;
111 dtr_mask = 1 << 5;
112 } else {
113 /* UART1 */
114 rts_mask = 1 << 6;
115 dtr_mask = 1 << 7;
116 }
117
118 if (mctrl & TIOCM_RTS)
119 ctrlc |= rts_mask;
120 else
121 ctrls |= rts_mask;
122
123 if (mctrl & TIOCM_DTR)
124 ctrlc |= dtr_mask;
125 else
126 ctrls |= dtr_mask;
127
128 __raw_writel(ctrls, SC_CTRLS);
129 __raw_writel(ctrlc, SC_CTRLC);
130}
131
132struct amba_pl010_data integrator_uart_data = {
133 .set_mctrl = integrator_uart_set_mctrl,
134};
135
136static DEFINE_RAW_SPINLOCK(cm_lock); 94static DEFINE_RAW_SPINLOCK(cm_lock);
137 95
138/** 96/**
diff --git a/arch/arm/mach-integrator/include/mach/platform.h b/arch/arm/mach-integrator/include/mach/platform.h
index efeac5d0bc9e..be5859efe10e 100644
--- a/arch/arm/mach-integrator/include/mach/platform.h
+++ b/arch/arm/mach-integrator/include/mach/platform.h
@@ -190,7 +190,6 @@
190#define INTEGRATOR_SC_CTRLC_OFFSET 0x0C 190#define INTEGRATOR_SC_CTRLC_OFFSET 0x0C
191#define INTEGRATOR_SC_DEC_OFFSET 0x10 191#define INTEGRATOR_SC_DEC_OFFSET 0x10
192#define INTEGRATOR_SC_ARB_OFFSET 0x14 192#define INTEGRATOR_SC_ARB_OFFSET 0x14
193#define INTEGRATOR_SC_PCIENABLE_OFFSET 0x18
194#define INTEGRATOR_SC_LOCK_OFFSET 0x1C 193#define INTEGRATOR_SC_LOCK_OFFSET 0x1C
195 194
196#define INTEGRATOR_SC_BASE 0x11000000 195#define INTEGRATOR_SC_BASE 0x11000000
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 771cbe44b662..a0a7cbbb7a70 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -39,6 +39,7 @@
39#include <linux/of_platform.h> 39#include <linux/of_platform.h>
40#include <linux/stat.h> 40#include <linux/stat.h>
41#include <linux/sys_soc.h> 41#include <linux/sys_soc.h>
42#include <linux/termios.h>
42#include <video/vga.h> 43#include <video/vga.h>
43 44
44#include <mach/hardware.h> 45#include <mach/hardware.h>
@@ -63,7 +64,7 @@
63#include "common.h" 64#include "common.h"
64 65
65/* Base address to the AP system controller */ 66/* Base address to the AP system controller */
66static void __iomem *ap_syscon_base; 67void __iomem *ap_syscon_base;
67 68
68/* 69/*
69 * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx 70 * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
@@ -251,6 +252,45 @@ static struct physmap_flash_data ap_flash_data = {
251}; 252};
252 253
253/* 254/*
255 * For the PL010 found in the Integrator/AP some of the UART control is
256 * implemented in the system controller and accessed using a callback
257 * from the driver.
258 */
259static void integrator_uart_set_mctrl(struct amba_device *dev,
260 void __iomem *base, unsigned int mctrl)
261{
262 unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
263 u32 phybase = dev->res.start;
264
265 if (phybase == INTEGRATOR_UART0_BASE) {
266 /* UART0 */
267 rts_mask = 1 << 4;
268 dtr_mask = 1 << 5;
269 } else {
270 /* UART1 */
271 rts_mask = 1 << 6;
272 dtr_mask = 1 << 7;
273 }
274
275 if (mctrl & TIOCM_RTS)
276 ctrlc |= rts_mask;
277 else
278 ctrls |= rts_mask;
279
280 if (mctrl & TIOCM_DTR)
281 ctrlc |= dtr_mask;
282 else
283 ctrls |= dtr_mask;
284
285 __raw_writel(ctrls, ap_syscon_base + INTEGRATOR_SC_CTRLS_OFFSET);
286 __raw_writel(ctrlc, ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
287}
288
289struct amba_pl010_data ap_uart_data = {
290 .set_mctrl = integrator_uart_set_mctrl,
291};
292
293/*
254 * Where is the timer (VA)? 294 * Where is the timer (VA)?
255 */ 295 */
256#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE) 296#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
@@ -447,9 +487,9 @@ static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
447 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE, 487 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,
448 "rtc", NULL), 488 "rtc", NULL),
449 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE, 489 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
450 "uart0", &integrator_uart_data), 490 "uart0", &ap_uart_data),
451 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE, 491 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
452 "uart1", &integrator_uart_data), 492 "uart1", &ap_uart_data),
453 OF_DEV_AUXDATA("arm,primecell", KMI0_BASE, 493 OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,
454 "kmi0", NULL), 494 "kmi0", NULL),
455 OF_DEV_AUXDATA("arm,primecell", KMI1_BASE, 495 OF_DEV_AUXDATA("arm,primecell", KMI1_BASE,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index c4b6af9a4239..29df06b35d0d 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -306,9 +306,9 @@ static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {
306 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE, 306 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,
307 "rtc", NULL), 307 "rtc", NULL),
308 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE, 308 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
309 "uart0", &integrator_uart_data), 309 "uart0", NULL),
310 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE, 310 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
311 "uart1", &integrator_uart_data), 311 "uart1", NULL),
312 OF_DEV_AUXDATA("arm,primecell", KMI0_BASE, 312 OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,
313 "kmi0", NULL), 313 "kmi0", NULL),
314 OF_DEV_AUXDATA("arm,primecell", KMI1_BASE, 314 OF_DEV_AUXDATA("arm,primecell", KMI1_BASE,
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index bbeca59df66b..000edcda4596 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -388,9 +388,10 @@ static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
388 * means I can't get additional information on the reason for the pm2fb 388 * means I can't get additional information on the reason for the pm2fb
389 * problems. I suppose I'll just have to mind-meld with the machine. ;) 389 * problems. I suppose I'll just have to mind-meld with the machine. ;)
390 */ 390 */
391#define SC_PCI __io_address(INTEGRATOR_SC_PCIENABLE) 391static void __iomem *ap_syscon_base;
392#define SC_LBFADDR __io_address(INTEGRATOR_SC_BASE + 0x20) 392#define INTEGRATOR_SC_PCIENABLE_OFFSET 0x18
393#define SC_LBFCODE __io_address(INTEGRATOR_SC_BASE + 0x24) 393#define INTEGRATOR_SC_LBFADDR_OFFSET 0x20
394#define INTEGRATOR_SC_LBFCODE_OFFSET 0x24
394 395
395static int 396static int
396v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) 397v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
@@ -401,13 +402,13 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
401 char buf[128]; 402 char buf[128];
402 403
403 sprintf(buf, "V3 fault: addr 0x%08lx, FSR 0x%03x, PC 0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n", 404 sprintf(buf, "V3 fault: addr 0x%08lx, FSR 0x%03x, PC 0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
404 addr, fsr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255, 405 addr, fsr, pc, instr, __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET), __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
405 v3_readb(V3_LB_ISTAT)); 406 v3_readb(V3_LB_ISTAT));
406 printk(KERN_DEBUG "%s", buf); 407 printk(KERN_DEBUG "%s", buf);
407#endif 408#endif
408 409
409 v3_writeb(V3_LB_ISTAT, 0); 410 v3_writeb(V3_LB_ISTAT, 0);
410 __raw_writel(3, SC_PCI); 411 __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
411 412
412 /* 413 /*
413 * If the instruction being executed was a read, 414 * If the instruction being executed was a read,
@@ -449,15 +450,15 @@ static irqreturn_t v3_irq(int dummy, void *devid)
449 450
450 sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x " 451 sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x "
451 "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr, 452 "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr,
452 __raw_readl(SC_LBFADDR), 453 __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET),
453 __raw_readl(SC_LBFCODE) & 255, 454 __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
454 v3_readb(V3_LB_ISTAT)); 455 v3_readb(V3_LB_ISTAT));
455 printascii(buf); 456 printascii(buf);
456#endif 457#endif
457 458
458 v3_writew(V3_PCI_STAT, 0xf000); 459 v3_writew(V3_PCI_STAT, 0xf000);
459 v3_writeb(V3_LB_ISTAT, 0); 460 v3_writeb(V3_LB_ISTAT, 0);
460 __raw_writel(3, SC_PCI); 461 __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
461 462
462#ifdef CONFIG_DEBUG_LL 463#ifdef CONFIG_DEBUG_LL
463 /* 464 /*
@@ -480,6 +481,10 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
480 if (nr == 0) { 481 if (nr == 0) {
481 sys->mem_offset = PHYS_PCI_MEM_BASE; 482 sys->mem_offset = PHYS_PCI_MEM_BASE;
482 ret = pci_v3_setup_resources(sys); 483 ret = pci_v3_setup_resources(sys);
484 /* Remap the Integrator system controller */
485 ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100);
486 if (!ap_syscon_base)
487 return -EINVAL;
483 } 488 }
484 489
485 return ret; 490 return ret;
@@ -568,7 +573,7 @@ void __init pci_v3_preinit(void)
568 v3_writeb(V3_LB_ISTAT, 0); 573 v3_writeb(V3_LB_ISTAT, 0);
569 v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10)); 574 v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));
570 v3_writeb(V3_LB_IMASK, 0x28); 575 v3_writeb(V3_LB_IMASK, 0x28);
571 __raw_writel(3, SC_PCI); 576 __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
572 577
573 /* 578 /*
574 * Grab the PCI error interrupt. 579 * Grab the PCI error interrupt.