From 4a2cc2fb90786424a280843824ddeff42fa8a7ad Mon Sep 17 00:00:00 2001 From: fang Date: Wed, 20 Oct 2010 17:52:30 +0800 Subject: [PATCH] add rk29 gic --- arch/arm/Kconfig | 1 + arch/arm/mach-rk29/board-rk29sdk.c | 12 +- arch/arm/mach-rk29/include/mach/entry-macro.S | 88 +++++++---- arch/arm/mach-rk29/include/mach/irqs.h | 139 +++++++++--------- arch/arm/mach-rk29/timer.c | 4 +- 5 files changed, 145 insertions(+), 99 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9d26ae3dff8e..e1007715a7de 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -722,6 +722,7 @@ config ARCH_RK29 select CPU_V7 select GENERIC_TIME select GENERIC_CLOCKEVENTS + select ARM_GIC help Support for Rockchip RK29 soc. diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c index 6014b663a9f0..6ee0dd5fd9ed 100644 --- a/arch/arm/mach-rk29/board-rk29sdk.c +++ b/arch/arm/mach-rk29/board-rk29sdk.c @@ -28,11 +28,13 @@ #include #include #include +#include #include #include + #include #include @@ -72,9 +74,15 @@ static struct map_desc rk29_io_desc[] __initdata = { }; +static void __init rk29_gic_init_irq(void) +{ + gic_dist_init(0, RK29_GICPERI_BASE, 32); + gic_cpu_init(0, RK29_GICCPU_BASE); +} + static void __init machine_rk29_init_irq(void) { - //rk29_init_irq(); + rk29_gic_init_irq(); //rk29_gpio_init(rk29_gpioBank, 8); //rk29_gpio_irq_setup(); } @@ -100,4 +108,4 @@ MACHINE_START(RK29, "RK29board") .init_irq = machine_rk29_init_irq, .init_machine = machine_rk29_board_init, .timer = &rk29_timer, -MACHINE_END \ No newline at end of file +MACHINE_END diff --git a/arch/arm/mach-rk29/include/mach/entry-macro.S b/arch/arm/mach-rk29/include/mach/entry-macro.S index 43849c8ef173..92676d7160d2 100644 --- a/arch/arm/mach-rk29/include/mach/entry-macro.S +++ b/arch/arm/mach-rk29/include/mach/entry-macro.S @@ -15,37 +15,75 @@ #include "irqs.h" #include "rk29_iomap.h" +#include .macro disable_fiq .endm .macro get_irqnr_preamble, base, tmp - ldr \base, =RK29_GICPERI_BASE .endm .macro arch_ret_to_user, tmp1, tmp2 - .endm + .endm /* + * The interrupt numbering scheme is defined in the + * interrupt controller spec. To wit: + * + * Interrupts 0-15 are IPI + * 16-28 are reserved + * 29-31 are local. We allow 30 to be used for the watchdog. + * 32-1020 are global + * 1021-1022 are reserved + * 1023 is "spurious" (no interrupt) + * + * For now, we ignore all local interrupts so only return an + * interrupt if it's between 30 and 1020. The test_for_ipi + * routine below will pick up on IPIs. + * A simple read from the controller will tell us the number + * of the highest priority enabled interrupt. + * We then just need to check whether it is in the + * valid range for an IRQ (30-1020 inclusive). + */ + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \base, =RK29_GICCPU_BASE + ldr \irqstat, [\base, #GIC_CPU_INTACK] + + ldr \tmp, =1021 + + bic \irqnr, \irqstat, #0x1c00 + + cmp \irqnr, #32 + cmpcc \irqnr, \irqnr + cmpne \irqnr, \tmp + cmpcs \irqnr, \irqnr + .endm + + /* We assume that irqstat (the raw value of the IRQ acknowledge + * register) is preserved from the macro above. + * If there is an IPI, we immediately signal end of interrupt + * on the controller, since this requires the original irqstat + * value which we won't easily be able to recreate later. + */ + + .macro test_for_ipi, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #16 + it cc + strcc \irqstat, [\base, #GIC_CPU_EOI] + it cs + cmpcs \irqnr, \irqnr + .endm + + /* As above, this assumes that irqstat and base are preserved */ + + .macro test_for_ltirq, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + mov \tmp, #0 + cmp \irqnr, #32 + itt eq + moveq \tmp, #1 + streq \irqstat, [\base, #GIC_CPU_EOI] + cmp \tmp, #0 + .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp -#if 0 - @ check the vic0 - mov \irqnr, # S3C_IRQ_OFFSET + 31 - ldr \irqstat, [ \base, # VIC_IRQ_STATUS ] - teq \irqstat, #0 - - @ otherwise try vic1 - addeq \tmp, \base, #(S3C_VA_VIC1 - S3C_VA_VIC0) - addeq \irqnr, \irqnr, #32 - ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ] - teqeq \irqstat, #0 - - @ otherwise try vic2 - addeq \tmp, \base, #(S3C_VA_VIC2 - S3C_VA_VIC0) - addeq \irqnr, \irqnr, #32 - ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ] - teqeq \irqstat, #0 - - clzne \irqstat, \irqstat - subne \irqnr, \irqnr, \irqstat -#endif - .endm \ No newline at end of file + .macro irq_prio_table + .endm diff --git a/arch/arm/mach-rk29/include/mach/irqs.h b/arch/arm/mach-rk29/include/mach/irqs.h index 070b7f3f7474..8dbb1a084b65 100644 --- a/arch/arm/mach-rk29/include/mach/irqs.h +++ b/arch/arm/mach-rk29/include/mach/irqs.h @@ -17,76 +17,75 @@ #ifndef __ARCH_ARM_MACH_RK29_IRQS_H #define __ARCH_ARM_MACH_RK29_IRQS_H -#define NR_IRQS 68 -/*irq number*/ -#define IRQ_NR_DMAC00 0 -#define IRQ_NR_DMAC01 1 -#define IRQ_NR_DMAC000 2 -#define IRQ_NR_DMAC010 3 -#define IRQ_NR_DMAC20 4 -#define IRQ_NR_DMAC21 5 -#define IRQ_NR_DMAC22 6 -#define IRQ_NR_DMAC23 7 -#define IRQ_NR_DMAC24 8 -#define IRQ_NR_GPU 9 -#define IRQ_NR_VEPU 10 -#define IRQ_NR_VDPU 11 -#define IRQ_NR_VIP 12 -#define IRQ_NR_LCDC 13 -#define IRQ_NR_IPP 14 -#define IRQ_NR_EBC 15 -#define IRQ_NR_USBOTG0 16 -#define IRQ_NR_USBOTG1 17 -#define IRQ_NR_USBHOST 18 -#define IRQ_NR_MAC 19 -#define IRQ_NR_HIF0 20 -#define IRQ_NR_HIF1 21 -#define IRQ_NR_HSADC_TS1 22 -#define IRQ_NR_SDMMC 23 -#define IRQ_NR_SDIO 24 -#define IRQ_NR_EMMC 25 -#define IRQ_NR_SARADC 26 -#define IRQ_NR_NANDC 27 -#define IRQ_NR_NANDCRDY 28 -#define IRQ_NR_SMC 29 -#define IRQ_NR_PID_FILTER 30 -#define IRQ_NR_I2SPCM8 31 -#define IRQ_NR_I2SPCM2 32 -#define IRQ_NR_SPDIF 33 -#define IRQ_NR_UART0 34 -#define IRQ_NR_UART1 35 -#define IRQ_NR_UART2 36 -#define IRQ_NR_UART3 37 -#define IRQ_NR_SPI0 38 -#define IRQ_NR_SPI1 39 -#define IRQ_NR_I2C0 40 -#define IRQ_NR_I2C1 41 -#define IRQ_NR_I2C2 42 -#define IRQ_NR_I2C3 43 -#define IRQ_NR_TIMER0 44 -#define IRQ_NR_TIMER1 45 -#define IRQ_NR_TIMER2 46 -#define IRQ_NR_TIMER3 47 -#define IRQ_NR_PWM0 48 -#define IRQ_NR_PWM1 49 -#define IRQ_NR_PWM2 50 -#define IRQ_NR_PWM3 51 -#define IRQ_NR_WDT 52 -#define IRQ_NR_RTC 53 -#define IRQ_NR_PMU 54 -#define IRQ_NR_GPIO0 55 -#define IRQ_NR_GPIO1 56 -#define IRQ_NR_GPIO2 57 -#define IRQ_NR_GPIO3 58 -#define IRQ_NR_GPIO4 59 -#define IRQ_NR_GPIO5 60 -#define IRQ_NR_GPIO6 61 -#define IRQ_NR_USB_AHB_ARB 62 -#define IRQ_NR_PERI_AHB_ARB 63 -#define IRQ_NR_A8IRQ0 64 -#define IRQ_NR_A8IRQ1 65 -#define IRQ_NR_A8IRQ2 66 -#define IRQ_NR_A8IRQ3 67 +#define RK29XX_IRQ(x) (x+32) +#define IRQ_GPU RK29XX_IRQ(9) +#define IRQ_VEPU RK29XX_IRQ(10) +#define IRQ_VDPU RK29XX_IRQ(11) +#define IRQ_VIP RK29XX_IRQ(12) +#define IRQ_LCDC RK29XX_IRQ(13) +#define IRQ_IPP RK29XX_IRQ(14) +#define IRQ_EBC RK29XX_IRQ(15) +#define IRQ_USB_OTG0 RK29XX_IRQ(16) +#define IRQ_USB_OTG1 RK29XX_IRQ(17) +#define IRQ_USB_HOST RK29XX_IRQ(18) +#define IRQ_MAC RK29XX_IRQ(19) +#define IRQ_HIF0 RK29XX_IRQ(20) +#define IRQ_HIF1 RK29XX_IRQ(21) +#define IRQ_HSADC_TSI RK29XX_IRQ(22) +#define IRQ_SDMMC RK29XX_IRQ(23) +#define IRQ_SDIO RK29XX_IRQ(24) +#define IRQ_EMMC RK29XX_IRQ(25) +#define IRQ_SARADC RK29XX_IRQ(26) +#define IRQ_NANDC RK29XX_IRQ(27) +#define IRQ_NANDC_RDY RK29XX_IRQ(28) +#define IRQ_SMC RK29XX_IRQ(29) +#define IRQ_PID_FILTER RK29XX_IRQ(30) +#define IRQ_I2S_8CH RK29XX_IRQ(31) +#define IRQ_I2S_2CH RK29XX_IRQ(32) +#define IRQ_SPDIF RK29XX_IRQ(33) +#define IRQ_UART0 RK29XX_IRQ(34) +#define IRQ_UART1 RK29XX_IRQ(35) +#define IRQ_UART2 RK29XX_IRQ(36) +#define IRQ_UART3 RK29XX_IRQ(37) + +#define IRQ_SPI0 RK29XX_IRQ(38) +#define IRQ_SPI1 RK29XX_IRQ(39) + +#define IRQ_I2C0 RK29XX_IRQ(40) +#define IRQ_I2C1 RK29XX_IRQ(41) +#define IRQ_I2C2 RK29XX_IRQ(42) +#define IRQ_I2C3 RK29XX_IRQ(43) + +#define IRQ_TIMER0 RK29XX_IRQ(44) +#define IRQ_TIMER1 RK29XX_IRQ(45) +#define IRQ_TIMER2 RK29XX_IRQ(46) +#define IRQ_TIMER3 RK29XX_IRQ(47) + +#define IRQ_PWM0 RK29XX_IRQ(48) +#define IRQ_PWM1 RK29XX_IRQ(49) +#define IRQ_PWM2 RK29XX_IRQ(50) +#define IRQ_PWM3 RK29XX_IRQ(51) + +#define IRQ_WDT RK29XX_IRQ(52) +#define IRQ_RTC RK29XX_IRQ(53) +#define IRQ_PMU RK29XX_IRQ(54) + +#define IRQ_GPIO0 RK29XX_IRQ(55) +#define IRQ_GPIO1 RK29XX_IRQ(56) +#define IRQ_GPIO2 RK29XX_IRQ(57) +#define IRQ_GPIO3 RK29XX_IRQ(58) +#define IRQ_GPIO4 RK29XX_IRQ(59) +#define IRQ_GPIO5 RK29XX_IRQ(60) +#define IRQ_GPIO6 RK29XX_IRQ(61) + +#define IRQ_USB_AHB_ARB RK29XX_IRQ(62) +#define IRQ_PERI_AHB_ARB RK29XX_IRQ(63) +#define IRQ_A8IRQ0 RK29XX_IRQ(64) +#define IRQ_A8IRQ1 RK29XX_IRQ(65) +#define IRQ_A8IRQ2 RK29XX_IRQ(66) +#define IRQ_A8IRQ3 RK29XX_IRQ(67) + +#define NR_IRQS (IRQ_A8IRQ3+1) #endif diff --git a/arch/arm/mach-rk29/timer.c b/arch/arm/mach-rk29/timer.c index cd62da5f61d8..cdc35f786ae7 100644 --- a/arch/arm/mach-rk29/timer.c +++ b/arch/arm/mach-rk29/timer.c @@ -48,11 +48,11 @@ #define RK_TIMER_INT_CLEAR(n) readl(RK29_TIMER0_BASE + 0x14 * (n - 1) + TIMER_EOI) #define TIMER_CLKEVT 2 /* timer2 */ -#define IRQ_NR_TIMER_CLKEVT IRQ_NR_TIMER2 +#define IRQ_NR_TIMER_CLKEVT IRQ_TIMER2 #define TIMER_CLKEVT_NAME "timer2" #define TIMER_CLKSRC 3 /* timer3 */ -#define IRQ_NR_TIMER_CLKSRC IRQ_NR_TIMER3 +#define IRQ_NR_TIMER_CLKSRC IRQ_TIMER3 #define TIMER_CLKSRC_NAME "timer3" static struct clk *timer_clk; -- 2.34.1