aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2012-09-21 00:16:43 -0400
committerOlof Johansson <olof@lixom.net>2012-09-21 00:16:43 -0400
commitea832c41dacbc4a5f3888d9ef7c38213914aba2a (patch)
treebee97817d9a55f000e2bec5fa5d62d325050e6a6 /arch/arm/mach-pxa
parentb74aae9a2074e1caa2e40bf119f3a633f77c94e4 (diff)
parent84bae6c379e362aa017efd417199f51d5c2273ac (diff)
Merge branch 'next/dt' into next/multiplatform
* next/dt: (182 commits) ARM: tegra: Add Avionic Design Tamonten Evaluation Carrier support ARM: tegra: Add Avionic Design Medcom-Wide support ARM: tegra: Add Avionic Design Plutux support ARM: tegra: Add Avionic Design Tamonten support ARM: tegra: dts: Add pwm label ARM: dt: tegra: whistler: configure power off ARM: mxs: m28evk: Disable OCOTP OUI loading ARM: imx6q: use pll2_pfd2_396m as the enfc_sel's parent ARM: dts: imx6q-sabrelite: add usbotg pinctrl support ARM: dts: imx23-olinuxino: Add USB host support ARM: dts: imx6q-sabrelite: add usbmisc device ARM: dts: mx23: Add USB resources ARM: dts: mxs: Add ethernetX to macX aliases ARM: msm: Remove non-DT targets from 8960 ARM: msm: Add DT support for 8960 ARM: msm: Move io mapping prototypes to common.h ARM: msm: Rename board-msm8x60 to signify its DT only status ARM: msm: Make 8660 a DT only target ARM: msm: Move 8660 to DT timer ARM: msm: Add DT support to msm_timer ...
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r--arch/arm/mach-pxa/Kconfig12
-rw-r--r--arch/arm/mach-pxa/Makefile3
-rw-r--r--arch/arm/mach-pxa/clock-pxa3xx.c8
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx-regs.h1
-rw-r--r--arch/arm/mach-pxa/irq.c131
-rw-r--r--arch/arm/mach-pxa/pxa-dt.c63
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c23
7 files changed, 215 insertions, 26 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index fe2d1f80ef50..8e6288de69b9 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -25,6 +25,18 @@ config PXA_V7_MACH_AUTO
25if !ARCH_PXA_V7 25if !ARCH_PXA_V7
26comment "Intel/Marvell Dev Platforms (sorted by hardware release time)" 26comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
27 27
28config MACH_PXA3XX_DT
29 bool "Support PXA3xx platforms from device tree"
30 select PXA3xx
31 select CPU_PXA300
32 select POWER_SUPPLY
33 select HAVE_PWM
34 select USE_OF
35 help
36 Include support for Marvell PXA3xx based platforms using
37 the device tree. Needn't select any other machine while
38 MACH_PXA3XX_DT is enabled.
39
28config ARCH_LUBBOCK 40config ARCH_LUBBOCK
29 bool "Intel DBPXA250 Development Platform (aka Lubbock)" 41 bool "Intel DBPXA250 Development Platform (aka Lubbock)"
30 select PXA25x 42 select PXA25x
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index be0f7df8685c..2bedc9ed076c 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -26,6 +26,9 @@ obj-$(CONFIG_CPU_PXA930) += pxa930.o
26 26
27# NOTE: keep the order of boards in accordance to their order in Kconfig 27# NOTE: keep the order of boards in accordance to their order in Kconfig
28 28
29# Device Tree support
30obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o
31
29# Intel/Marvell Dev Platforms 32# Intel/Marvell Dev Platforms
30obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o 33obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
31obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o 34obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
diff --git a/arch/arm/mach-pxa/clock-pxa3xx.c b/arch/arm/mach-pxa/clock-pxa3xx.c
index 2a37a9a8f621..d4e9499832dc 100644
--- a/arch/arm/mach-pxa/clock-pxa3xx.c
+++ b/arch/arm/mach-pxa/clock-pxa3xx.c
@@ -127,8 +127,10 @@ void clk_pxa3xx_cken_enable(struct clk *clk)
127 127
128 if (clk->cken < 32) 128 if (clk->cken < 32)
129 CKENA |= mask; 129 CKENA |= mask;
130 else 130 else if (clk->cken < 64)
131 CKENB |= mask; 131 CKENB |= mask;
132 else
133 CKENC |= mask;
132} 134}
133 135
134void clk_pxa3xx_cken_disable(struct clk *clk) 136void clk_pxa3xx_cken_disable(struct clk *clk)
@@ -137,8 +139,10 @@ void clk_pxa3xx_cken_disable(struct clk *clk)
137 139
138 if (clk->cken < 32) 140 if (clk->cken < 32)
139 CKENA &= ~mask; 141 CKENA &= ~mask;
140 else 142 else if (clk->cken < 64)
141 CKENB &= ~mask; 143 CKENB &= ~mask;
144 else
145 CKENC &= ~mask;
142} 146}
143 147
144const struct clkops clk_pxa3xx_cken_ops = { 148const struct clkops clk_pxa3xx_cken_ops = {
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
index 207ecb49a61b..f4d48d20754e 100644
--- a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
@@ -131,6 +131,7 @@
131#define AICSR __REG(0x41340008) /* Application Subsystem Interrupt Control/Status Register */ 131#define AICSR __REG(0x41340008) /* Application Subsystem Interrupt Control/Status Register */
132#define CKENA __REG(0x4134000C) /* A Clock Enable Register */ 132#define CKENA __REG(0x4134000C) /* A Clock Enable Register */
133#define CKENB __REG(0x41340010) /* B Clock Enable Register */ 133#define CKENB __REG(0x41340010) /* B Clock Enable Register */
134#define CKENC __REG(0x41340024) /* C Clock Enable Register */
134#define AC97_DIV __REG(0x41340014) /* AC97 clock divisor value register */ 135#define AC97_DIV __REG(0x41340014) /* AC97 clock divisor value register */
135 136
136#define ACCR_XPDIS (1 << 31) /* Core PLL Output Disable */ 137#define ACCR_XPDIS (1 << 31) /* Core PLL Output Disable */
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 5dae15ea6718..b6cc1816463e 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -17,6 +17,8 @@
17#include <linux/syscore_ops.h> 17#include <linux/syscore_ops.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/irq.h> 19#include <linux/irq.h>
20#include <linux/of_address.h>
21#include <linux/of_irq.h>
20 22
21#include <asm/exception.h> 23#include <asm/exception.h>
22 24
@@ -25,8 +27,6 @@
25 27
26#include "generic.h" 28#include "generic.h"
27 29
28#define IRQ_BASE io_p2v(0x40d00000)
29
30#define ICIP (0x000) 30#define ICIP (0x000)
31#define ICMR (0x004) 31#define ICMR (0x004)
32#define ICLR (0x008) 32#define ICLR (0x008)
@@ -48,22 +48,19 @@
48 * This is for peripheral IRQs internal to the PXA chip. 48 * This is for peripheral IRQs internal to the PXA chip.
49 */ 49 */
50 50
51static void __iomem *pxa_irq_base;
51static int pxa_internal_irq_nr; 52static int pxa_internal_irq_nr;
52 53static bool cpu_has_ipr;
53static inline int cpu_has_ipr(void)
54{
55 return !cpu_is_pxa25x();
56}
57 54
58static inline void __iomem *irq_base(int i) 55static inline void __iomem *irq_base(int i)
59{ 56{
60 static unsigned long phys_base[] = { 57 static unsigned long phys_base_offset[] = {
61 0x40d00000, 58 0x0,
62 0x40d0009c, 59 0x9c,
63 0x40d00130, 60 0x130,
64 }; 61 };
65 62
66 return io_p2v(phys_base[i]); 63 return pxa_irq_base + phys_base_offset[i];
67} 64}
68 65
69void pxa_mask_irq(struct irq_data *d) 66void pxa_mask_irq(struct irq_data *d)
@@ -96,8 +93,8 @@ asmlinkage void __exception_irq_entry icip_handle_irq(struct pt_regs *regs)
96 uint32_t icip, icmr, mask; 93 uint32_t icip, icmr, mask;
97 94
98 do { 95 do {
99 icip = __raw_readl(IRQ_BASE + ICIP); 96 icip = __raw_readl(pxa_irq_base + ICIP);
100 icmr = __raw_readl(IRQ_BASE + ICMR); 97 icmr = __raw_readl(pxa_irq_base + ICMR);
101 mask = icip & icmr; 98 mask = icip & icmr;
102 99
103 if (mask == 0) 100 if (mask == 0)
@@ -128,6 +125,8 @@ void __init pxa_init_irq(int irq_nr, int (*fn)(struct irq_data *, unsigned int))
128 BUG_ON(irq_nr > MAX_INTERNAL_IRQS); 125 BUG_ON(irq_nr > MAX_INTERNAL_IRQS);
129 126
130 pxa_internal_irq_nr = irq_nr; 127 pxa_internal_irq_nr = irq_nr;
128 cpu_has_ipr = !cpu_is_pxa25x();
129 pxa_irq_base = io_p2v(0x40d00000);
131 130
132 for (n = 0; n < irq_nr; n += 32) { 131 for (n = 0; n < irq_nr; n += 32) {
133 void __iomem *base = irq_base(n >> 5); 132 void __iomem *base = irq_base(n >> 5);
@@ -136,8 +135,8 @@ void __init pxa_init_irq(int irq_nr, int (*fn)(struct irq_data *, unsigned int))
136 __raw_writel(0, base + ICLR); /* all IRQs are IRQ, not FIQ */ 135 __raw_writel(0, base + ICLR); /* all IRQs are IRQ, not FIQ */
137 for (i = n; (i < (n + 32)) && (i < irq_nr); i++) { 136 for (i = n; (i < (n + 32)) && (i < irq_nr); i++) {
138 /* initialize interrupt priority */ 137 /* initialize interrupt priority */
139 if (cpu_has_ipr()) 138 if (cpu_has_ipr)
140 __raw_writel(i | IPR_VALID, IRQ_BASE + IPR(i)); 139 __raw_writel(i | IPR_VALID, pxa_irq_base + IPR(i));
141 140
142 irq = PXA_IRQ(i); 141 irq = PXA_IRQ(i);
143 irq_set_chip_and_handler(irq, &pxa_internal_irq_chip, 142 irq_set_chip_and_handler(irq, &pxa_internal_irq_chip,
@@ -168,9 +167,9 @@ static int pxa_irq_suspend(void)
168 __raw_writel(0, base + ICMR); 167 __raw_writel(0, base + ICMR);
169 } 168 }
170 169
171 if (cpu_has_ipr()) { 170 if (cpu_has_ipr) {
172 for (i = 0; i < pxa_internal_irq_nr; i++) 171 for (i = 0; i < pxa_internal_irq_nr; i++)
173 saved_ipr[i] = __raw_readl(IRQ_BASE + IPR(i)); 172 saved_ipr[i] = __raw_readl(pxa_irq_base + IPR(i));
174 } 173 }
175 174
176 return 0; 175 return 0;
@@ -187,11 +186,11 @@ static void pxa_irq_resume(void)
187 __raw_writel(0, base + ICLR); 186 __raw_writel(0, base + ICLR);
188 } 187 }
189 188
190 if (cpu_has_ipr()) 189 if (cpu_has_ipr)
191 for (i = 0; i < pxa_internal_irq_nr; i++) 190 for (i = 0; i < pxa_internal_irq_nr; i++)
192 __raw_writel(saved_ipr[i], IRQ_BASE + IPR(i)); 191 __raw_writel(saved_ipr[i], pxa_irq_base + IPR(i));
193 192
194 __raw_writel(1, IRQ_BASE + ICCR); 193 __raw_writel(1, pxa_irq_base + ICCR);
195} 194}
196#else 195#else
197#define pxa_irq_suspend NULL 196#define pxa_irq_suspend NULL
@@ -202,3 +201,93 @@ struct syscore_ops pxa_irq_syscore_ops = {
202 .suspend = pxa_irq_suspend, 201 .suspend = pxa_irq_suspend,
203 .resume = pxa_irq_resume, 202 .resume = pxa_irq_resume,
204}; 203};
204
205#ifdef CONFIG_OF
206static struct irq_domain *pxa_irq_domain;
207
208static int pxa_irq_map(struct irq_domain *h, unsigned int virq,
209 irq_hw_number_t hw)
210{
211 void __iomem *base = irq_base(hw / 32);
212
213 /* initialize interrupt priority */
214 if (cpu_has_ipr)
215 __raw_writel(hw | IPR_VALID, pxa_irq_base + IPR(hw));
216
217 irq_set_chip_and_handler(hw, &pxa_internal_irq_chip,
218 handle_level_irq);
219 irq_set_chip_data(hw, base);
220 set_irq_flags(hw, IRQF_VALID);
221
222 return 0;
223}
224
225static struct irq_domain_ops pxa_irq_ops = {
226 .map = pxa_irq_map,
227 .xlate = irq_domain_xlate_onecell,
228};
229
230static const struct of_device_id intc_ids[] __initconst = {
231 { .compatible = "marvell,pxa-intc", },
232 {}
233};
234
235void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int))
236{
237 struct device_node *node;
238 const struct of_device_id *of_id;
239 struct pxa_intc_conf *conf;
240 struct resource res;
241 int n, ret;
242
243 node = of_find_matching_node(NULL, intc_ids);
244 if (!node) {
245 pr_err("Failed to find interrupt controller in arch-pxa\n");
246 return;
247 }
248 of_id = of_match_node(intc_ids, node);
249 conf = of_id->data;
250
251 ret = of_property_read_u32(node, "marvell,intc-nr-irqs",
252 &pxa_internal_irq_nr);
253 if (ret) {
254 pr_err("Not found marvell,intc-nr-irqs property\n");
255 return;
256 }
257
258 ret = of_address_to_resource(node, 0, &res);
259 if (ret < 0) {
260 pr_err("No registers defined for node\n");
261 return;
262 }
263 pxa_irq_base = io_p2v(res.start);
264
265 if (of_find_property(node, "marvell,intc-priority", NULL))
266 cpu_has_ipr = 1;
267
268 ret = irq_alloc_descs(-1, 0, pxa_internal_irq_nr, 0);
269 if (ret < 0) {
270 pr_err("Failed to allocate IRQ numbers\n");
271 return;
272 }
273
274 pxa_irq_domain = irq_domain_add_legacy(node, pxa_internal_irq_nr, 0, 0,
275 &pxa_irq_ops, NULL);
276 if (!pxa_irq_domain)
277 panic("Unable to add PXA IRQ domain\n");
278
279 irq_set_default_host(pxa_irq_domain);
280
281 for (n = 0; n < pxa_internal_irq_nr; n += 32) {
282 void __iomem *base = irq_base(n >> 5);
283
284 __raw_writel(0, base + ICMR); /* disable all IRQs */
285 __raw_writel(0, base + ICLR); /* all IRQs are IRQ, not FIQ */
286 }
287
288 /* only unmasked interrupts kick us out of idle */
289 __raw_writel(1, irq_base(0) + ICCR);
290
291 pxa_internal_irq_chip.irq_set_wake = fn;
292}
293#endif /* CONFIG_OF */
diff --git a/arch/arm/mach-pxa/pxa-dt.c b/arch/arm/mach-pxa/pxa-dt.c
new file mode 100644
index 000000000000..c9192cea0033
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa-dt.c
@@ -0,0 +1,63 @@
1/*
2 * linux/arch/arm/mach-pxa/pxa-dt.c
3 *
4 * Copyright (C) 2012 Daniel Mack
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * publishhed by the Free Software Foundation.
9 */
10
11#include <linux/irq.h>
12#include <linux/irqdomain.h>
13#include <linux/of_irq.h>
14#include <linux/of_platform.h>
15#include <asm/mach/arch.h>
16#include <asm/mach/time.h>
17#include <mach/irqs.h>
18#include <mach/pxa3xx.h>
19
20#include "generic.h"
21
22#ifdef CONFIG_PXA3xx
23extern void __init pxa3xx_dt_init_irq(void);
24
25static const struct of_dev_auxdata pxa3xx_auxdata_lookup[] __initconst = {
26 OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL),
27 OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL),
28 OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40700000, "pxa2xx-uart.2", NULL),
29 OF_DEV_AUXDATA("mrvl,pxa-uart", 0x41600000, "pxa2xx-uart.3", NULL),
30 OF_DEV_AUXDATA("marvell,pxa-mmc", 0x41100000, "pxa2xx-mci.0", NULL),
31 OF_DEV_AUXDATA("mrvl,pxa-gpio", 0x40e00000, "pxa-gpio", NULL),
32 OF_DEV_AUXDATA("marvell,pxa-ohci", 0x4c000000, "pxa27x-ohci", NULL),
33 OF_DEV_AUXDATA("mrvl,pxa-i2c", 0x40301680, "pxa2xx-i2c.0", NULL),
34 OF_DEV_AUXDATA("mrvl,pwri2c", 0x40f500c0, "pxa3xx-i2c.1", NULL),
35 OF_DEV_AUXDATA("marvell,pxa3xx-nand", 0x43100000, "pxa3xx-nand", NULL),
36 {}
37};
38
39static void __init pxa3xx_dt_init(void)
40{
41 of_platform_populate(NULL, of_default_bus_match_table,
42 pxa3xx_auxdata_lookup, NULL);
43}
44
45static const char *pxa3xx_dt_board_compat[] __initdata = {
46 "marvell,pxa300",
47 "marvell,pxa310",
48 "marvell,pxa320",
49 NULL,
50};
51#endif
52
53#ifdef CONFIG_PXA3xx
54DT_MACHINE_START(PXA_DT, "Marvell PXA3xx (Device Tree Support)")
55 .map_io = pxa3xx_map_io,
56 .init_irq = pxa3xx_dt_init_irq,
57 .handle_irq = pxa3xx_handle_irq,
58 .timer = &pxa_timer,
59 .restart = pxa_restart,
60 .init_machine = pxa3xx_dt_init,
61 .dt_compat = pxa3xx_dt_board_compat,
62MACHINE_END
63#endif
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index dffb7e813d98..ff9c9574ec3e 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -19,6 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/irq.h> 20#include <linux/irq.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/of.h>
22#include <linux/syscore_ops.h> 23#include <linux/syscore_ops.h>
23#include <linux/i2c/pxa-i2c.h> 24#include <linux/i2c/pxa-i2c.h>
24 25
@@ -40,6 +41,8 @@
40#define PECR_IE(n) ((1 << ((n) * 2)) << 28) 41#define PECR_IE(n) ((1 << ((n) * 2)) << 28)
41#define PECR_IS(n) ((1 << ((n) * 2)) << 29) 42#define PECR_IS(n) ((1 << ((n) * 2)) << 29)
42 43
44extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int));
45
43static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1); 46static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1);
44static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1); 47static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1);
45static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1); 48static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1);
@@ -382,7 +385,7 @@ static void __init pxa_init_ext_wakeup_irq(int (*fn)(struct irq_data *,
382 pxa_ext_wakeup_chip.irq_set_wake = fn; 385 pxa_ext_wakeup_chip.irq_set_wake = fn;
383} 386}
384 387
385void __init pxa3xx_init_irq(void) 388static void __init __pxa3xx_init_irq(void)
386{ 389{
387 /* enable CP6 access */ 390 /* enable CP6 access */
388 u32 value; 391 u32 value;
@@ -390,10 +393,23 @@ void __init pxa3xx_init_irq(void)
390 value |= (1 << 6); 393 value |= (1 << 6);
391 __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value)); 394 __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
392 395
393 pxa_init_irq(56, pxa3xx_set_wake);
394 pxa_init_ext_wakeup_irq(pxa3xx_set_wake); 396 pxa_init_ext_wakeup_irq(pxa3xx_set_wake);
395} 397}
396 398
399void __init pxa3xx_init_irq(void)
400{
401 __pxa3xx_init_irq();
402 pxa_init_irq(56, pxa3xx_set_wake);
403}
404
405#ifdef CONFIG_OF
406void __init pxa3xx_dt_init_irq(void)
407{
408 __pxa3xx_init_irq();
409 pxa_dt_irq_init(pxa3xx_set_wake);
410}
411#endif /* CONFIG_OF */
412
397static struct map_desc pxa3xx_io_desc[] __initdata = { 413static struct map_desc pxa3xx_io_desc[] __initdata = {
398 { /* Mem Ctl */ 414 { /* Mem Ctl */
399 .virtual = (unsigned long)SMEMC_VIRT, 415 .virtual = (unsigned long)SMEMC_VIRT,
@@ -466,7 +482,8 @@ static int __init pxa3xx_init(void)
466 register_syscore_ops(&pxa3xx_mfp_syscore_ops); 482 register_syscore_ops(&pxa3xx_mfp_syscore_ops);
467 register_syscore_ops(&pxa3xx_clock_syscore_ops); 483 register_syscore_ops(&pxa3xx_clock_syscore_ops);
468 484
469 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 485 if (!of_have_populated_dt())
486 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
470 } 487 }
471 488
472 return ret; 489 return ret;