2 * linux/arch/arm/mach-integrator/integrator_ap.c
4 * Copyright (C) 2000-2003 Deep Blue Solutions Ltd
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <linux/types.h>
21 #include <linux/kernel.h>
22 #include <linux/init.h>
23 #include <linux/list.h>
24 #include <linux/platform_device.h>
25 #include <linux/slab.h>
26 #include <linux/string.h>
27 #include <linux/syscore_ops.h>
28 #include <linux/amba/bus.h>
29 #include <linux/amba/kmi.h>
30 #include <linux/clocksource.h>
31 #include <linux/clockchips.h>
32 #include <linux/interrupt.h>
34 #include <linux/irqchip/versatile-fpga.h>
35 #include <linux/mtd/physmap.h>
36 #include <linux/clk.h>
37 #include <linux/platform_data/clk-integrator.h>
38 #include <linux/of_irq.h>
39 #include <linux/of_address.h>
40 #include <linux/of_platform.h>
41 #include <linux/stat.h>
42 #include <linux/sys_soc.h>
43 #include <linux/termios.h>
44 #include <linux/sched_clock.h>
46 #include <mach/hardware.h>
47 #include <mach/platform.h>
48 #include <asm/hardware/arm_timer.h>
49 #include <asm/setup.h>
50 #include <asm/param.h> /* HZ */
51 #include <asm/mach-types.h>
54 #include <mach/irqs.h>
56 #include <asm/mach/arch.h>
57 #include <asm/mach/irq.h>
58 #include <asm/mach/map.h>
59 #include <asm/mach/time.h>
64 /* Base address to the AP system controller */
65 void __iomem
*ap_syscon_base
;
68 * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
71 * Setup a VA for the Integrator interrupt controller (for header #0,
74 #define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE)
75 #define VA_EBI_BASE __io_address(INTEGRATOR_EBI_BASE)
76 #define VA_CMIC_BASE __io_address(INTEGRATOR_HDR_IC)
80 * ef000000 Cache flush
81 * f1000000 10000000 Core module registers
82 * f1100000 11000000 System controller registers
83 * f1200000 12000000 EBI registers
84 * f1300000 13000000 Counter/Timer
85 * f1400000 14000000 Interrupt controller
86 * f1600000 16000000 UART 0
87 * f1700000 17000000 UART 1
88 * f1a00000 1a000000 Debug LEDs
89 * f1b00000 1b000000 GPIO
92 static struct map_desc ap_io_desc
[] __initdata __maybe_unused
= {
94 .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE
),
95 .pfn
= __phys_to_pfn(INTEGRATOR_HDR_BASE
),
99 .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE
),
100 .pfn
= __phys_to_pfn(INTEGRATOR_EBI_BASE
),
104 .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE
),
105 .pfn
= __phys_to_pfn(INTEGRATOR_CT_BASE
),
109 .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE
),
110 .pfn
= __phys_to_pfn(INTEGRATOR_IC_BASE
),
114 .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE
),
115 .pfn
= __phys_to_pfn(INTEGRATOR_UART0_BASE
),
119 .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE
),
120 .pfn
= __phys_to_pfn(INTEGRATOR_DBG_BASE
),
124 .virtual = IO_ADDRESS(INTEGRATOR_AP_GPIO_BASE
),
125 .pfn
= __phys_to_pfn(INTEGRATOR_AP_GPIO_BASE
),
131 static void __init
ap_map_io(void)
133 iotable_init(ap_io_desc
, ARRAY_SIZE(ap_io_desc
));
138 static unsigned long ic_irq_enable
;
140 static int irq_suspend(void)
142 ic_irq_enable
= readl(VA_IC_BASE
+ IRQ_ENABLE
);
146 static void irq_resume(void)
148 /* disable all irq sources */
149 writel(-1, VA_CMIC_BASE
+ IRQ_ENABLE_CLEAR
);
150 writel(-1, VA_IC_BASE
+ IRQ_ENABLE_CLEAR
);
151 writel(-1, VA_IC_BASE
+ FIQ_ENABLE_CLEAR
);
153 writel(ic_irq_enable
, VA_IC_BASE
+ IRQ_ENABLE_SET
);
156 #define irq_suspend NULL
157 #define irq_resume NULL
160 static struct syscore_ops irq_syscore_ops
= {
161 .suspend
= irq_suspend
,
162 .resume
= irq_resume
,
165 static int __init
irq_syscore_init(void)
167 register_syscore_ops(&irq_syscore_ops
);
172 device_initcall(irq_syscore_init
);
177 #define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
178 #define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
180 static int ap_flash_init(struct platform_device
*dev
)
184 writel(INTEGRATOR_SC_CTRL_nFLVPPEN
| INTEGRATOR_SC_CTRL_nFLWP
,
185 ap_syscon_base
+ INTEGRATOR_SC_CTRLC_OFFSET
);
187 tmp
= readl(EBI_CSR1
) | INTEGRATOR_EBI_WRITE_ENABLE
;
188 writel(tmp
, EBI_CSR1
);
190 if (!(readl(EBI_CSR1
) & INTEGRATOR_EBI_WRITE_ENABLE
)) {
191 writel(0xa05f, EBI_LOCK
);
192 writel(tmp
, EBI_CSR1
);
198 static void ap_flash_exit(struct platform_device
*dev
)
202 writel(INTEGRATOR_SC_CTRL_nFLVPPEN
| INTEGRATOR_SC_CTRL_nFLWP
,
203 ap_syscon_base
+ INTEGRATOR_SC_CTRLC_OFFSET
);
205 tmp
= readl(EBI_CSR1
) & ~INTEGRATOR_EBI_WRITE_ENABLE
;
206 writel(tmp
, EBI_CSR1
);
208 if (readl(EBI_CSR1
) & INTEGRATOR_EBI_WRITE_ENABLE
) {
209 writel(0xa05f, EBI_LOCK
);
210 writel(tmp
, EBI_CSR1
);
215 static void ap_flash_set_vpp(struct platform_device
*pdev
, int on
)
218 writel(INTEGRATOR_SC_CTRL_nFLVPPEN
,
219 ap_syscon_base
+ INTEGRATOR_SC_CTRLS_OFFSET
);
221 writel(INTEGRATOR_SC_CTRL_nFLVPPEN
,
222 ap_syscon_base
+ INTEGRATOR_SC_CTRLC_OFFSET
);
225 static struct physmap_flash_data ap_flash_data
= {
227 .init
= ap_flash_init
,
228 .exit
= ap_flash_exit
,
229 .set_vpp
= ap_flash_set_vpp
,
233 * For the PL010 found in the Integrator/AP some of the UART control is
234 * implemented in the system controller and accessed using a callback
237 static void integrator_uart_set_mctrl(struct amba_device
*dev
,
238 void __iomem
*base
, unsigned int mctrl
)
240 unsigned int ctrls
= 0, ctrlc
= 0, rts_mask
, dtr_mask
;
241 u32 phybase
= dev
->res
.start
;
243 if (phybase
== INTEGRATOR_UART0_BASE
) {
253 if (mctrl
& TIOCM_RTS
)
258 if (mctrl
& TIOCM_DTR
)
263 __raw_writel(ctrls
, ap_syscon_base
+ INTEGRATOR_SC_CTRLS_OFFSET
);
264 __raw_writel(ctrlc
, ap_syscon_base
+ INTEGRATOR_SC_CTRLC_OFFSET
);
267 struct amba_pl010_data ap_uart_data
= {
268 .set_mctrl
= integrator_uart_set_mctrl
,
272 * Where is the timer (VA)?
274 #define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
275 #define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
276 #define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
278 static unsigned long timer_reload
;
280 static u32 notrace
integrator_read_sched_clock(void)
282 return -readl((void __iomem
*) TIMER2_VA_BASE
+ TIMER_VALUE
);
285 static void integrator_clocksource_init(unsigned long inrate
,
288 u32 ctrl
= TIMER_CTRL_ENABLE
| TIMER_CTRL_PERIODIC
;
289 unsigned long rate
= inrate
;
291 if (rate
>= 1500000) {
293 ctrl
|= TIMER_CTRL_DIV16
;
296 writel(0xffff, base
+ TIMER_LOAD
);
297 writel(ctrl
, base
+ TIMER_CTRL
);
299 clocksource_mmio_init(base
+ TIMER_VALUE
, "timer2",
300 rate
, 200, 16, clocksource_mmio_readl_down
);
301 setup_sched_clock(integrator_read_sched_clock
, 16, rate
);
304 static void __iomem
* clkevt_base
;
307 * IRQ handler for the timer
309 static irqreturn_t
integrator_timer_interrupt(int irq
, void *dev_id
)
311 struct clock_event_device
*evt
= dev_id
;
313 /* clear the interrupt */
314 writel(1, clkevt_base
+ TIMER_INTCLR
);
316 evt
->event_handler(evt
);
321 static void clkevt_set_mode(enum clock_event_mode mode
, struct clock_event_device
*evt
)
323 u32 ctrl
= readl(clkevt_base
+ TIMER_CTRL
) & ~TIMER_CTRL_ENABLE
;
326 writel(ctrl
, clkevt_base
+ TIMER_CTRL
);
329 case CLOCK_EVT_MODE_PERIODIC
:
330 /* Enable the timer and start the periodic tick */
331 writel(timer_reload
, clkevt_base
+ TIMER_LOAD
);
332 ctrl
|= TIMER_CTRL_PERIODIC
| TIMER_CTRL_ENABLE
;
333 writel(ctrl
, clkevt_base
+ TIMER_CTRL
);
335 case CLOCK_EVT_MODE_ONESHOT
:
336 /* Leave the timer disabled, .set_next_event will enable it */
337 ctrl
&= ~TIMER_CTRL_PERIODIC
;
338 writel(ctrl
, clkevt_base
+ TIMER_CTRL
);
340 case CLOCK_EVT_MODE_UNUSED
:
341 case CLOCK_EVT_MODE_SHUTDOWN
:
342 case CLOCK_EVT_MODE_RESUME
:
344 /* Just leave in disabled state */
350 static int clkevt_set_next_event(unsigned long next
, struct clock_event_device
*evt
)
352 unsigned long ctrl
= readl(clkevt_base
+ TIMER_CTRL
);
354 writel(ctrl
& ~TIMER_CTRL_ENABLE
, clkevt_base
+ TIMER_CTRL
);
355 writel(next
, clkevt_base
+ TIMER_LOAD
);
356 writel(ctrl
| TIMER_CTRL_ENABLE
, clkevt_base
+ TIMER_CTRL
);
361 static struct clock_event_device integrator_clockevent
= {
363 .features
= CLOCK_EVT_FEAT_PERIODIC
| CLOCK_EVT_FEAT_ONESHOT
,
364 .set_mode
= clkevt_set_mode
,
365 .set_next_event
= clkevt_set_next_event
,
369 static struct irqaction integrator_timer_irq
= {
371 .flags
= IRQF_DISABLED
| IRQF_TIMER
| IRQF_IRQPOLL
,
372 .handler
= integrator_timer_interrupt
,
373 .dev_id
= &integrator_clockevent
,
376 static void integrator_clockevent_init(unsigned long inrate
,
377 void __iomem
*base
, int irq
)
379 unsigned long rate
= inrate
;
380 unsigned int ctrl
= 0;
383 /* Calculate and program a divisor */
384 if (rate
> 0x100000 * HZ
) {
386 ctrl
|= TIMER_CTRL_DIV256
;
387 } else if (rate
> 0x10000 * HZ
) {
389 ctrl
|= TIMER_CTRL_DIV16
;
391 timer_reload
= rate
/ HZ
;
392 writel(ctrl
, clkevt_base
+ TIMER_CTRL
);
394 setup_irq(irq
, &integrator_timer_irq
);
395 clockevents_config_and_register(&integrator_clockevent
,
401 void __init
ap_init_early(void)
407 static void __init
ap_of_timer_init(void)
409 struct device_node
*node
;
417 clk
= clk_get_sys("ap_timer", NULL
);
419 clk_prepare_enable(clk
);
420 rate
= clk_get_rate(clk
);
422 err
= of_property_read_string(of_aliases
,
423 "arm,timer-primary", &path
);
426 node
= of_find_node_by_path(path
);
427 base
= of_iomap(node
, 0);
430 writel(0, base
+ TIMER_CTRL
);
431 integrator_clocksource_init(rate
, base
);
433 err
= of_property_read_string(of_aliases
,
434 "arm,timer-secondary", &path
);
437 node
= of_find_node_by_path(path
);
438 base
= of_iomap(node
, 0);
441 irq
= irq_of_parse_and_map(node
, 0);
442 writel(0, base
+ TIMER_CTRL
);
443 integrator_clockevent_init(rate
, base
, irq
);
446 static const struct of_device_id fpga_irq_of_match
[] __initconst
= {
447 { .compatible
= "arm,versatile-fpga-irq", .data
= fpga_irq_of_init
, },
451 static void __init
ap_init_irq_of(void)
453 /* disable core module IRQs */
454 writel(0xffffffffU
, VA_CMIC_BASE
+ IRQ_ENABLE_CLEAR
);
455 of_irq_init(fpga_irq_of_match
);
456 integrator_clk_init(false);
459 /* For the Device Tree, add in the UART callbacks as AUXDATA */
460 static struct of_dev_auxdata ap_auxdata_lookup
[] __initdata
= {
461 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE
,
463 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE
,
464 "uart0", &ap_uart_data
),
465 OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE
,
466 "uart1", &ap_uart_data
),
467 OF_DEV_AUXDATA("arm,primecell", KMI0_BASE
,
469 OF_DEV_AUXDATA("arm,primecell", KMI1_BASE
,
471 OF_DEV_AUXDATA("cfi-flash", INTEGRATOR_FLASH_BASE
,
472 "physmap-flash", &ap_flash_data
),
476 static void __init
ap_init_of(void)
478 unsigned long sc_dec
;
479 struct device_node
*root
;
480 struct device_node
*syscon
;
481 struct device
*parent
;
482 struct soc_device
*soc_dev
;
483 struct soc_device_attribute
*soc_dev_attr
;
488 /* Here we create an SoC device for the root node */
489 root
= of_find_node_by_path("/");
492 syscon
= of_find_node_by_path("/syscon");
496 ap_syscon_base
= of_iomap(syscon
, 0);
500 ap_sc_id
= readl(ap_syscon_base
);
502 soc_dev_attr
= kzalloc(sizeof(*soc_dev_attr
), GFP_KERNEL
);
506 err
= of_property_read_string(root
, "compatible",
507 &soc_dev_attr
->soc_id
);
510 err
= of_property_read_string(root
, "model", &soc_dev_attr
->machine
);
513 soc_dev_attr
->family
= "Integrator";
514 soc_dev_attr
->revision
= kasprintf(GFP_KERNEL
, "%c",
515 'A' + (ap_sc_id
& 0x0f));
517 soc_dev
= soc_device_register(soc_dev_attr
);
518 if (IS_ERR(soc_dev
)) {
519 kfree(soc_dev_attr
->revision
);
524 parent
= soc_device_to_device(soc_dev
);
525 integrator_init_sysfs(parent
, ap_sc_id
);
527 of_platform_populate(root
, of_default_bus_match_table
,
528 ap_auxdata_lookup
, parent
);
530 sc_dec
= readl(ap_syscon_base
+ INTEGRATOR_SC_DEC_OFFSET
);
531 for (i
= 0; i
< 4; i
++) {
532 struct lm_device
*lmdev
;
534 if ((sc_dec
& (16 << i
)) == 0)
537 lmdev
= kzalloc(sizeof(struct lm_device
), GFP_KERNEL
);
541 lmdev
->resource
.start
= 0xc0000000 + 0x10000000 * i
;
542 lmdev
->resource
.end
= lmdev
->resource
.start
+ 0x0fffffff;
543 lmdev
->resource
.flags
= IORESOURCE_MEM
;
544 lmdev
->irq
= IRQ_AP_EXPINT0
+ i
;
547 lm_device_register(lmdev
);
551 static const char * ap_dt_board_compat
[] = {
556 DT_MACHINE_START(INTEGRATOR_AP_DT
, "ARM Integrator/AP (Device Tree)")
557 .reserve
= integrator_reserve
,
559 .init_early
= ap_init_early
,
560 .init_irq
= ap_init_irq_of
,
561 .handle_irq
= fpga_handle_irq
,
562 .init_time
= ap_of_timer_init
,
563 .init_machine
= ap_init_of
,
564 .restart
= integrator_restart
,
565 .dt_compat
= ap_dt_board_compat
,
573 * For the ATAG boot some static mappings are needed. This will
574 * go away with the ATAG support down the road.
577 static struct map_desc ap_io_desc_atag
[] __initdata
= {
579 .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE
),
580 .pfn
= __phys_to_pfn(INTEGRATOR_SC_BASE
),
586 static void __init
ap_map_io_atag(void)
588 iotable_init(ap_io_desc_atag
, ARRAY_SIZE(ap_io_desc_atag
));
593 * This is where non-devicetree initialization code is collected and stashed
594 * for eventual deletion.
597 static struct platform_device pci_v3_device
= {
602 static struct resource cfi_flash_resource
= {
603 .start
= INTEGRATOR_FLASH_BASE
,
604 .end
= INTEGRATOR_FLASH_BASE
+ INTEGRATOR_FLASH_SIZE
- 1,
605 .flags
= IORESOURCE_MEM
,
608 static struct platform_device cfi_flash_device
= {
609 .name
= "physmap-flash",
612 .platform_data
= &ap_flash_data
,
615 .resource
= &cfi_flash_resource
,
618 static void __init
ap_timer_init(void)
623 clk
= clk_get_sys("ap_timer", NULL
);
625 clk_prepare_enable(clk
);
626 rate
= clk_get_rate(clk
);
628 writel(0, TIMER0_VA_BASE
+ TIMER_CTRL
);
629 writel(0, TIMER1_VA_BASE
+ TIMER_CTRL
);
630 writel(0, TIMER2_VA_BASE
+ TIMER_CTRL
);
632 integrator_clocksource_init(rate
, (void __iomem
*)TIMER2_VA_BASE
);
633 integrator_clockevent_init(rate
, (void __iomem
*)TIMER1_VA_BASE
,
637 #define INTEGRATOR_SC_VALID_INT 0x003fffff
639 static void __init
ap_init_irq(void)
641 /* Disable all interrupts initially. */
642 /* Do the core module ones */
643 writel(-1, VA_CMIC_BASE
+ IRQ_ENABLE_CLEAR
);
645 /* do the header card stuff next */
646 writel(-1, VA_IC_BASE
+ IRQ_ENABLE_CLEAR
);
647 writel(-1, VA_IC_BASE
+ FIQ_ENABLE_CLEAR
);
649 fpga_irq_init(VA_IC_BASE
, "SC", IRQ_PIC_START
,
650 -1, INTEGRATOR_SC_VALID_INT
, NULL
);
651 integrator_clk_init(false);
654 static void __init
ap_init(void)
656 unsigned long sc_dec
;
659 platform_device_register(&pci_v3_device
);
660 platform_device_register(&cfi_flash_device
);
662 ap_syscon_base
= __io_address(INTEGRATOR_SC_BASE
);
663 sc_dec
= readl(ap_syscon_base
+ INTEGRATOR_SC_DEC_OFFSET
);
664 for (i
= 0; i
< 4; i
++) {
665 struct lm_device
*lmdev
;
667 if ((sc_dec
& (16 << i
)) == 0)
670 lmdev
= kzalloc(sizeof(struct lm_device
), GFP_KERNEL
);
674 lmdev
->resource
.start
= 0xc0000000 + 0x10000000 * i
;
675 lmdev
->resource
.end
= lmdev
->resource
.start
+ 0x0fffffff;
676 lmdev
->resource
.flags
= IORESOURCE_MEM
;
677 lmdev
->irq
= IRQ_AP_EXPINT0
+ i
;
680 lm_device_register(lmdev
);
683 integrator_init(false);
686 MACHINE_START(INTEGRATOR
, "ARM-Integrator")
687 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
688 .atag_offset
= 0x100,
689 .reserve
= integrator_reserve
,
690 .map_io
= ap_map_io_atag
,
691 .init_early
= ap_init_early
,
692 .init_irq
= ap_init_irq
,
693 .handle_irq
= fpga_handle_irq
,
694 .init_time
= ap_timer_init
,
695 .init_machine
= ap_init
,
696 .restart
= integrator_restart
,