[PATCH] ARM: CSR: Adding CSR SiRFprimaII board support
From: Barry Song <hidden>
Date: 2011-06-24 02:28:34
2011/6/22 Russell King - ARM Linux [off-list ref]:
Some comments inline, nothing really serious... On Mon, Jun 20, 2011 at 12:53:22AM -0700, Barry Song wrote:quoted
+config ARCH_PRIMA2 + ? ? bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform" + ? ? select CPU_V7 + ? ? select GENERIC_TIME + ? ? select GENERIC_CLOCKEVENTS + ? ? select CLKDEV_LOOKUP + ? ? select USE_OF + ? ? select ISA_DMA_APIDo you really provide the old ISA DMA API? ?Unless you're intending to use existing ISA drivers with their ISA DMA, you shouldn't define this.quoted
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index f5b2b39..79e6edf 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile@@ -191,6 +191,7 @@ machine-$(CONFIG_ARCH_VEXPRESS) ? ? ? ? ? := vexpress?machine-$(CONFIG_ARCH_VT8500) ? ? ? ? ? ? ? ?:= vt8500 ?machine-$(CONFIG_ARCH_W90X900) ? ? ? ? ? ? ? := w90x900 ?machine-$(CONFIG_ARCH_NUC93X) ? ? ? ? ? ? ? ?:= nuc93x +machine-$(CONFIG_ARCH_PRIMA2) ? ? ? ? ? ? ? ?:= prima2The comment at the start of this list says: # Machine directory name. ?This list is sorted alphanumerically # by CONFIG_* macro name. and I thank the NUC93x people for also missing it. ?Please ignore the NUC93x entry and place yours appropriately.quoted
diff --git a/arch/arm/boot/dts/prima2-cb.dts b/arch/arm/boot/dts/prima2-cb.dts new file mode 100644 index 0000000..6e8b17c --- /dev/null +++ b/arch/arm/boot/dts/prima2-cb.dts@@ -0,0 +1,44 @@ +/dts-v1/; +/ { + ? ? ? ?model = "SIRF Prima2 EVB"; + ? ? ? ?compatible = "sirf,prima2-cb", "sirf,prima2"; + ? ? #address-cells = <1>; + ? ? #size-cells = <1>; + ? ? interrupt-parent = <&intc>; + + ? ? ? ?memory { + ? ? ? ? ? ? ? ?reg = <0x00000000 0x20000000>; + ? ? ? ?}; + + ? ? chosen { + ? ? ? ? ? ? bootargs = "mem=512M real_root=/dev/mmcblk0p2 console=ttyS1 earlyprintk"; + ? ? ? ? ? ? linux,stdout-path = &uart1; + ? ? }; + + ? ? amba {You declare that you have an AMBA bus, does it have primcells on it? Should you be selecting ARM_AMBA in your kconfig?
Russell,
the chip has no primecells on it. And it seems we don't need ARM_AMBA.
PrimaII uses AXI protocol, but has no AMBA IP controller. and many IP
are self-defined. Nothing in the chip really has AMBA periph id.
its layout is like
AXI(0-0x3FFFFFFF)
memory
AXI(0x40000000-0xC0000000)
CPUIF(sirf-iobus)
INTC
MEMC
LCD
VPP
GRAPHIC
MULTIMEDIA
GPS
UART
...
hard-coded PCI bridge
SD/MMC
rtc-iobrg
RTC
quoted
diff --git a/arch/arm/mach-prima2/include/mach/entry-macro.S b/arch/arm/mach-prima2/include/mach/entry-macro.S new file mode 100644 index 0000000..af5611b --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/entry-macro.S@@ -0,0 +1,28 @@ +/* + * arch/arm/mach-prima2/include/mach/entry-macro.S + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <mach/hardware.h> + +#define SIRFSOC_INT_ID 0x38 + + ? ? .macro ?get_irqnr_and_base, irqnr, irqstat, base, tmp + ? ? ? ?ldr \base, =SIRFSOC_INTR_VA_BASEConsider using get_irqnr_preamble to load the base address only once per IRQ exception.quoted
diff --git a/arch/arm/mach-prima2/include/mach/isa-dma.h b/arch/arm/mach-prima2/include/mach/isa-dma.h new file mode 100644 index 0000000..f07e264 --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/isa-dma.h@@ -0,0 +1,14 @@ +/* + * arch/arm/mach-prima2/include/mach/io.h + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __MACH_PRIMA2_ISADMA_H +#define __MACH_PRIMA2_ISADMA_H + +#define MAX_DMA_CHANNELS 32 + +#endifYou don't need this if you don't define ISA_DMA_API.quoted
diff --git a/arch/arm/mach-prima2/include/mach/uncompress.h b/arch/arm/mach-prima2/include/mach/uncompress.h new file mode 100644 index 0000000..e08d7b8 --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/uncompress.h@@ -0,0 +1,42 @@ +/* + * arch/arm/mach-prima2/include/mach/uncompress.h + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __ASM_ARCH_UNCOMPRESS_H +#define __ASM_ARCH_UNCOMPRESS_H + +#include <linux/bitops.h> +#include <linux/io.h> +#include <asm/processor.h> +#include <mach/hardware.h> +#include <mach/uart.h>If you include all that, then you're in for problems with the decompressor. The decompressor is a _really_ limited environment, and most stuff from linux/ or platfform stuff will not be available.quoted
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c new file mode 100644 index 0000000..af65481 --- /dev/null +++ b/arch/arm/mach-prima2/irq.c@@ -0,0 +1,81 @@...quoted
+#define SIRFSOC_INT_PENDING0 ? ? ? ? ? ?0x0000 +#define SIRFSOC_INT_PENDING1 ? ? ? ? ? ?0x0004 +#define SIRFSOC_INT_IRQ_PENDING0 ? ? ? ?0x0008 +#define SIRFSOC_INT_IRQ_PENDING1 ? ? ? ?0x000C +#define SIRFSOC_INT_FIQ_PENDING0 ? ? ? ?0x0010 +#define SIRFSOC_INT_FIQ_PENDING1 ? ? ? ?0x0014 +#define SIRFSOC_INT_RISC_MASK0 ? ? ? ? ?0x0018 +#define SIRFSOC_INT_RISC_MASK1 ? ? ? ? ?0x001C +#define SIRFSOC_INT_RISC_LEVEL0 ? ? ? ? 0x0020 +#define SIRFSOC_INT_RISC_LEVEL1 ? ? ? ? 0x0024 + +static void sirfsoc_irq_ack(struct irq_data *d) +{ +} + +static void sirfsoc_irq_mask(struct irq_data *d) +{ + ? ? unsigned long mask; + + ? ? mask = __raw_readl(SIRFSOC_INTR_VA_BASE + SIRFSOC_INT_RISC_MASK0 + (d->irq / 32) * 4) & + ? ? ? ? ? ? ~(1 << ( d->irq % 32)); + ? ? __raw_writel(mask, SIRFSOC_INTR_VA_BASE + SIRFSOC_INT_RISC_MASK0 + (d->irq / 32) * 4); +} + +static void sirfsoc_irq_unmask(struct irq_data *d) +{ + ? ? unsigned long mask; + + ? ? mask = __raw_readl(SIRFSOC_INTR_VA_BASE + SIRFSOC_INT_RISC_MASK0 + (d->irq / 32) * 4) | + ? ? ? ? ? ? (1 << ( d->irq % 32)); + ? ? __raw_writel(mask, SIRFSOC_INTR_VA_BASE + SIRFSOC_INT_RISC_MASK0 + (d->irq / 32) * 4); +} + +int sirfsoc_irq_settype(struct irq_data *d, unsigned int type) +{ + ? ? /* + ? ? ?* Interrupt handler doesnt support setting trigger type + ? ? ?*/ + ? ? if (type == IRQ_TYPE_NONE) + ? ? ? ? ? ? return 0; + + ? ? return -EINVAL; +} + +static struct irq_chip sirfsoc_irq_chip = { + ? ? .name = "SiRF SoC", + ? ? .irq_ack = sirfsoc_irq_ack, + ? ? .irq_mask = sirfsoc_irq_mask, + ? ? .irq_unmask = sirfsoc_irq_unmask, + ? ? .irq_set_type = sirfsoc_irq_settype, +};Can you use the recently introduced generic irqchips stuff for this?quoted
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c new file mode 100644 index 0000000..f73928f --- /dev/null +++ b/arch/arm/mach-prima2/timer.c@@ -0,0 +1,181 @@...quoted
+/* initialize the kernel jiffy timer source */ +static void __init sirfsoc_timer_init(void) +{ + ? ? unsigned long rate; + ? ? /* timer's input clock is io clock */ + ? ? struct clk *clk = clk_get(NULL, "io");Rather than going down this broken path of specifying clock names as connection IDs, it would be better to obtain it by function: ? ? ? ?struct clk *clk = clk_get_sys("timer", NULL); Experience shows that people think that naming the clock signals themselves and passing strings around to drivers is easier. ?After a few years they find that what they thought was easy, is actually inflexible and has become a huge problem which they need to rework. ?(Samsung folk are currently going through this pain.) So please, don't fall into the trap of "lets give each clock signal a name and look up only by clock name". ?Use the device names as the primary matching and don't allow yourself to get into the trap of passing clock names around.quoted
+ + ? ? BUG_ON(IS_ERR_OR_NULL(clk));? ? ? ?BUG_ON(IS_ERR(clk)); If clk_get() may return NULL, then clk_get_rate() should be able to eat that value without choking.quoted
+ + ? ? rate = clk_get_rate(clk); + ? ? clk_put(clk);It's much preferable not to clk_put() a clock which you're going to continue using.quoted
+ + ? ? BUG_ON(rate < CLOCK_TICK_RATE); + ? ? BUG_ON(rate % CLOCK_TICK_RATE); + + ? ? __raw_writel(rate / CLOCK_TICK_RATE / 2 - 1, SIRFSOC_TIMER_VA_BASE + SIRFSOC_TIMER_DIV); + ? ? __raw_writel(0, SIRFSOC_TIMER_VA_BASE + SIRFSOC_TIMER_COUNTER_LO); + ? ? __raw_writel(0, SIRFSOC_TIMER_VA_BASE + SIRFSOC_TIMER_COUNTER_HI); + ? ? __raw_writel(BIT(0), SIRFSOC_TIMER_VA_BASE + SIRFSOC_TIMER_STATUS); + + ? ? if (clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)) + ? ? ? ? ? ? BUG();Confused. ?CLOCK_TICK_RATE is defined to be 100 * HZ, so 10kHz. ?Do your timers really tick at 10kHz? ?That seems needlessly slow for a 64-bit counter. ?Also consider BUG_ON()quoted
+ + ? ? if (setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)) + ? ? ? ? ? ? BUG();BUG_ON() here too. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel