[PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
Barry Song
21cnbao at gmail.com
Wed Jul 6 12:10:56 EST 2011
2011/7/5 Barry Song <21cnbao at gmail.com>:
> Hi Arnd,
>
> 2011/7/1 Barry Song <21cnbao at gmail.com>:
>> Hi Arnd,
>>
>> 2011/6/30 Arnd Bergmann <arnd at arndb.de>:
>>> On Thursday 30 June 2011, Barry Song wrote:
>>>
>>>> > Is this really just one bus with a huge address space, or rather some
>>>> > nested buses? I'd prefer to have the device tree representation as
>>>> > close as possible to the actual layout.
>>>>
>>>> there are two AXI buses in prima2. AXI-1 connect to memory, AXI-2 is
>>>> transferred to CSR self-defined IOBUS by CPUIF, then 1 intterupt
>>>> controller and 9 IO bridges are connected to the IOBUS .
>>>> The 9 IO bridges are SYSIOBG, PERIIOBG,CPURTCIOBG, UUSIOBG, GRAPHIOBG,
>>>> MEDIAIOBG, DSPIOBG, DISPIOBG, MEMIOBG. Every iobrg connect to a group
>>>> of controllers.
>>>> For example, DISPIOBG connect to VPP and LCD, SYSIOBG connect to CLKC,
>>>> RSTC, RSC and CPHIFBG, DSPIOBG connect to DSPIF, GPS and DSP.
>>>> PERIIOBG connect to TIMER, NAND, AUDIO, UART0, UART1, UART2, USP0,
>>>> USP1, USP2, SPI0, I2C0, I2C1, GPIO, *SYS2PCI* and so on. Then
>>>> *SYS2PCI* connect to SD.
>>>>
>>>> The indendation descible the device hierarchy
>>>> AXI-1
>>>> Memory
>>>> AXI-2
>>>> interrupt controller
>>>> IOBG...
>>>> xxxx
>>>> IOBG...
>>>> xxxx
>>>> IOBG...
>>>> xxxx
>>>> IOBG...
>>>> xxxx
>>>> IOBG...
>>>> xxxx
>>>> IOBG...
>>>> SYS2PCI
>>>> SD
>>>>
>>>> i have get the IC guy Weizeng involved, maybe he can explain better than me :-)
>>>
>>> I think it would be good to represent the IOBG devices in the device tree then.
>>> You don't need to represent AXI-1 because memory is special anyway, and I would
>>> not bother to list SYS2PCI if the intention of that block was to hide the fact
>>> that it's PCI behind it. Properly instantiating it as a PCI bridge would be
>>> a lot of work that is probably not worth it.
>>>
>>> My usual plea to hardware developers: Please make the registers
>>> autodiscoverable from software! On an AMBA bus, please use the PrimeCell
>>> register layout. If you always have an IOBG device behind, they should
>>> all have the same identifier for that kind of bus bridge.
>>>
>>> For the IOBG, it would be ideal to have a similar way of finding and
>>> configuring the connected hardware, including:
>>>
>>> * unique identifier for each distinct IP block
>>> * revision of that block
>>> * MMIO ranges and sizes, relative to the bus
>>> * interrupt numbers, relative to a local interrupt controller
>>> * location identifier (like PCI bus/device/fn number) that can be
>>> referred to by other devices
>>> * clock management for that device
>>> * power management for that device
>>>
>>> If your IODB infrastructure already has this, you should create a new
>>> bus-type for this in Linux, which will let you detect all devices
>>> in a consistent manner without having to list them in the device tree.
>>
>> IO bridges in prima2 don't have that. Configuration is hardcoded now.
>> but we have learned so much from you and hope to improve our future IC
>> design.
>
>
> i have tried to figure out the full DT:
>
> /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=ttyS0 panel=1
> bootsplash=true bpp=16 androidboot.console=ttyS1";
> linux,stdout-path = &uart1;
> };
>
> cpus {
> #address-cells = <1>;
> #size-cells = <0>;
>
> ARM-CortexA9,SiRFprimaII at 0 {
> device_type = "cpu";
> reg = <0x0>;
> d-cache-line-size = <32>;
> i-cache-line-size = <32>;
> d-cache-size = <32768>;
> i-cache-size = <32768>;
> /* from bootloader */
> timebase-frequency = <0>;
> bus-frequency = <0>;
> clock-frequency = <0>;
> };
> };
>
> axi {
> compatible = "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges = <0x40000000 0x40000000 0x80000000>;
>
> l2-cache-controller at 0x80040000 {
> compatible = "arm,pl310-cache", "cache";
> reg = <0x80040000 0x1000>;
> interrupts = <59>;
> };
sorry, here i made an mistake. l2-cache is located in AXI, but
l2-cache registers <0x80040000 0x1000> are in sirfsoc-iobus, so it can
be moved to below in the same level with interrupt-controller.
>
> sirfsoc-iobus {
> compatible = "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges = <0x56000000 0x56000000 0x1b0000
> 0x80010000 0x80010000 0x30000
> 0x88000000 0x88000000 0x40040000>;
And the ranges can be <0x40000000 0x40000000 0x80000000> directly. in
fact, except that memory is located in a single AXI, all registers in
all controllers are in sirfsoc-iobus transferred from another AXI.
>
> intc: interrupt-controller at 0x80020000 {
> #interrupt-cells = <1>;
> interrupt-controller;
> compatible = "sirf,intc", "sirf,prima2-intc";
> reg = <0x80020000 0x1000>;
> };
l2-cache-controller at 0x80040000 {
compatible = "arm,pl310-cache", "cache";
reg = <0x80040000 0x1000>;
interrupts = <59>;
};
> sys-iobg {
> compatible = "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges = <0x88000000 0x88000000 0x40000>;
>
> clock-controller at 0x88000000 {
> compatible = "sirf,clkc", "sirf,prima2-clkc";
> reg = <0x88000000 0x1000>;
> interrupts = <3>;
> };
>
> reset-controller at 0x88010000 {
> compatible = "sirf,rstc", "sirf,prima2-rstc";
> reg = <0x88010000 0x1000>;
> };
> };
>
> mem-iobg {
> compatible = "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges = <0x90000000 0x90000000 0x10000>;
>
> memory-controller at 0x90000000 {
> compatible = "sirf,memc", "sirf,prima2-memc";
> reg = <0x90000000 0x10000>;
> interrupts = <27>;
> };
> };
>
> disp-iobg {
> compatible = "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges = <0x90010000 0x90010000 0x30000>;
>
> display at 0x90010000 {
> compatible = "sirf,lcd", "sirf,prima2-lcd";
> reg = <0x90010000 0x20000>;
> interrupts = <30>;
> };
>
> vpp at 0x90020000 {
> compatible = "sirf,vpp", "sirf,prima2-vpp";
> reg = <0x90020000 0x10000>;
> interrupts = <31>;
> };
> };
>
> graphics-iobg {
> compatible = "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges = <0x98000000 0x98000000 0x8000000>;
>
> graphics at 0x98000000 {
> compatible = "sirf,graphics", "sirf,prima2-graphics";
> reg = <0x98000000 0x8000000>;
> interrupts = <6>;
> };
> };
>
> multimedia-iobg {
> compatible = "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges = <0xa0000000 0xa0000000 0x8000000>;
>
> multimedia at 0xa0000000 {
> compatible = "sirf,multimedia", "sirf,prima2-multimedia";
> reg = <0xa0000000 0x8000000>;
> interrupts = <5>;
> };
> };
>
> dsp-iobg {
> compatible = "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges = <0xa8000000 0xa8000000 0x2000000>;
>
> dspif at 0xa8000000 {
> compatible = "sirf,dspif", "sirf,prima2-dspif";
> reg = <0xa8000000 0x10000>;
> interrupts = <9>;
> };
>
> gps at 0xa8010000 {
> compatible = "sirf,gps", "sirf,prima2-gps";
> reg = <0xa8010000 0x10000>;
> interrupts = <7>;
> };
>
> dsp at 0xa9000000 {
> compatible = "sirf,dsp", "sirf,prima2-dsp";
> reg = <0xa9000000 0x1000000>;
> interrupts = <8>;
> };
> };
>
> peri-iobg {
> compatible = "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges = <0xb0000000 0xb0000000 0x180000>;
>
> timer at 0xb0020000 {
> compatible = "sirf,tick", "sirf,prima2-tick";
> reg = <0xb0020000 0x1000>;
> interrupts = <0>;
> };
>
> nand at 0xb0030000 {
> compatible = "sirf,nand", "sirf,prima2-nand";
> reg = <0xb0030000 0x10000>;
> interrupts = <41>;
> };
>
> audio at 0xb0040000 {
> compatible = "sirf,audio", "sirf,prima2-audio";
> reg = <0xb0040000 0x10000>;
> interrupts = <35>;
> };
>
> uart0: uart at 0xb0050000 {
> cell-index = <0>;
> compatible = "sirf,uart", "sirf,prima2-uart";
> reg = <0xb0050000 0x10000>;
> interrupts = <17>;
> };
>
> uart1: uart at 0xb0060000 {
> cell-index = <1>;
> compatible = "sirf,uart", "sirf,prima2-uart";
> reg = <0xb0060000 0x10000>;
> interrupts = <18>;
> };
>
> uart2: uart at 0xb0070000 {
> cell-index = <2>;
> compatible = "sirf,uart", "sirf,prima2-uart";
> reg = <0xb0070000 0x10000>;
> interrupts = <19>;
> };
>
> usp0: usp at 0xb0080000 {
> cell-index = <0>;
> compatible = "sirf,usp", "sirf,prima2-usp";
> reg = <0xb0080000 0x10000>;
> interrupts = <20>;
> };
>
> usp1: usp at 0xb0090000 {
> cell-index = <1>;
> compatible = "sirf,usp", "sirf,prima2-usp";
> reg = <0xb0090000 0x10000>;
> interrupts = <21>;
> };
>
> usp2: usp at 0xb00a0000 {
> cell-index = <2>;
> compatible = "sirf,usp", "sirf,prima2-usp";
> reg = <0xb00a0000 0x10000>;
> interrupts = <22>;
> };
>
> dmac0: dma-controller at 0xb00b0000 {
> cell-index = <0>;
> compatible = "sirf,dmac", "sirf,prima2-dmac";
> reg = <0xb00b0000 0x10000>;
> interrupts = <12>;
> };
>
> dmac1: dma-controller at 0xb0160000 {
> cell-index = <1>;
> compatible = "sirf,dmac", "sirf,prima2-dmac";
> reg = <0xb0160000 0x10000>;
> interrupts = <13>;
> };
>
> vip at 0xb00C0000 {
> compatible = "sirf,vip", "sirf,prima2-vip";
> reg = <0xb00C0000 0x10000>;
> };
>
> spi0: spi at 0xb00D0000 {
> cell-index = <0>;
> compatible = "sirf,spi", "sirf,prima2-spi";
> reg = <0xb00D0000 0x10000>;
> interrupts = <15>;
> };
>
> spi1: spi at 0xb0170000 {
> cell-index = <1>;
> compatible = "sirf,spi", "sirf,prima2-spi";
> reg = <0xb0170000 0x10000>;
> interrupts = <16>;
> };
>
> i2c0: i2c at 0xb00E0000 {
> cell-index = <0>;
> compatible = "sirf,i2c", "sirf,prima2-i2c";
> reg = <0xb00E0000 0x10000>;
> interrupts = <24>;
> };
>
> i2c1: i2c at 0xb00f0000 {
> cell-index = <1>;
> compatible = "sirf,i2c", "sirf,prima2-i2c";
> reg = <0xb00f0000 0x10000>;
> interrupts = <25>;
> };
>
> tsc at 0xb0110000 {
> compatible = "sirf,tsc", "sirf,prima2-tsc";
> reg = <0xb0110000 0x10000>;
> interrupts = <33>;
> };
>
> gpio: gpio-controller at 0xb0120000 {
> #gpio-cells = <2>;
> #interrupt-cells = <2>;
> compatible = "sirf,gpio", "sirf,prima2-gpio";
> reg = <0xb0120000 0x10000>;
> gpio-controller;
> interrupt-controller;
> };
>
> pwm at 0xb0130000 {
> compatible = "sirf,pwm", "sirf,prima2-pwm";
> reg = <0xb0130000 0x10000>;
> };
>
> efusesys at 0xb0140000 {
> compatible = "sirf,efuse", "sirf,prima2-efuse";
> reg = <0xb0140000 0x10000>;
> };
>
> pulsec at 0xb0150000 {
> compatible = "sirf,pulsec", "sirf,prima2-pulsec";
> reg = <0xb0150000 0x10000>;
> interrupts = <48>;
> };
>
> pci-iobg {
> compatible = "sirf,pciiobg", "sirf,prima2-pciiobg", "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges = <0x56000000 0x56000000 0x1b00000>;
>
> sd0: sdhci at 0x56000000 {
> cell-index = <0>;
> compatible = "sirf,sdhc", "sirf,prima2-sdhc";
> reg = <0x56000000 0x100000>;
> interrupts = <38>;
> };
>
> sd1: sdhci at 0x56100000 {
> cell-index = <1>;
> compatible = "sirf,sdhc", "sirf,prima2-sdhc";
> reg = <0x56100000 0x100000>;
> interrupts = <38>;
> };
>
> sd2: sdhci at 0x56200000 {
> cell-index = <2>;
> compatible = "sirf,sdhc", "sirf,prima2-sdhc";
> reg = <0x56200000 0x100000>;
> interrupts = <23>;
> };
>
> sd3: sdhci at 0x56300000 {
> cell-index = <3>;
> compatible = "sirf,sdhc", "sirf,prima2-sdhc";
> reg = <0x56300000 0x100000>;
> interrupts = <23>;
> };
>
> sd4: sdhci at 0x56400000 {
> cell-index = <4>;
> compatible = "sirf,sdhc", "sirf,prima2-sdhc";
> reg = <0x56400000 0x100000>;
> interrupts = <39>;
> };
>
> sd5: sdhci at 0x56500000 {
> cell-index = <5>;
> compatible = "sirf,sdhc", "sirf,prima2-sdhc";
> reg = <0x56500000 0x100000>;
> interrupts = <39>;
> };
>
> pci-copy at 0x57900000 {
> compatible = "sirf,pcicp", "sirf,prima2-pcicp";
> reg = <0x57900000 0x100000>;
> interrupts = <40>;
> };
>
> rom-interface at 0x57a00000 {
> compatible = "sirf,romif", "sirf,prima2-romif";
> reg = <0x57a00000 0x100000>;
> };
> };
> };
>
> rtc-iobg {
> compatible = "sirf,rtciobg", "sirf,prima2-rtciobg", "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> reg = <0x80030000 0x10000>;
>
> gpsrtc at 0x1000 {
> compatible = "sirf,gpsrtc", "sirf,prima2-gpsrtc";
> reg = <0x1000 0x1000>;
> interrupts = <55 56 57>;
> };
>
> sysrtc at 0x2000 {
> compatible = "sirf,sysrtc", "sirf,prima2-sysrtc";
> reg = <0x2000 0x1000>;
> interrupts = <52 53 54>;
> };
>
> pwrc at 0x3000 {
> compatible = "sirf,pwrc", "sirf,prima2-pwrc";
> reg = <0x3000 0x1000>;
> interrupts = <32>;
> };
> };
>
> uus-iobg {
> compatible = "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges = <0xb8000000 0xb8000000 0x40000>;
>
> usb0: usb at 0xb00E0000 {
> compatible = "sirf,usb", "sirf,prima2-usb";
> reg = <0xb8000000 0x10000>;
> interrupts = <10>;
> };
>
> usb1: usb at 0xb00f0000 {
> compatible = "sirf,usb", "sirf,prima2-usb";
> reg = <0xb8010000 0x10000>;
> interrupts = <11>;
> };
>
> sata at 0xb00f0000 {
> compatible = "sirf,sata", "sirf,prima2-sata";
> reg = <0xb8020000 0x10000>;
> interrupts = <37>;
> };
>
> security at 0xb00f0000 {
> compatible = "sirf,security", "sirf,prima2-security";
> reg = <0xb8030000 0x10000>;
> interrupts = <42>;
> };
> };
> };
> };
> };
>
> if it looks ok to you, i will send v3 including it and other changes
> reviewed by you before.
>
>>
>>>
>>>> > I think the namespace for the compatible values is supposed to start with
>>>> > the stock ticker name of the company making the device as a unique
>>>> > identifier. This means you'd have to use
>>>> > "csrxf,sirf-intc", "csrxf,sirf-prima2-intc" as the value, instead
>>>> > of starting with the product name. I don't know exactly how strictly
>>>> > we apply that rule, but I've taken the devicetree-discuss at lists.ozlabs.org
>>>> > mailing list on Cc, maybe someone can clarify.
>>>>
>>>> in fact, SiRF is a company name. it was merged into CSR 4 years ago.
>>>> Due to history reason, now the SoC names are still headed by sirf.
>>>> the logo in SiRFprimaII chip is CSR.
>>>> So the "SiRF" of SiRFprimaII should mean two things: old company name,
>>>> heritable CPU production-line. Anyway, "csr, sirf-intc" seems to make
>>>> more senses than "sirf, intc".
>>>>
>>>> could we change "csrxf,sirf-intc", "csrxf,sirf-prima2-intc" to
>>>> "csr,sirf-intc", "csr,sirf-prima2-intc"?
>>>
>>> Not sure how strict we interpret the rules about stock ticker symbols.
>>> 'CSR' on wallstreet is 'China Security & Surveillance Tech. Inc'. If they
>>> ever decide to produce embedded Linux machines, we'd get a conflict, unless
>>> they also use "csst" (their .com domain name) as a prefix.
>>>
>>>> > better put these in a list with one file per line, like
>>>> >
>>>> > obj-y += timer.o
>>>> > obj-y += irq.o
>>>> >
>>>> > That makes the list more consistent when you add conditional files.
>>>>
>>>> Then it could be:
>>>> obj-y += timer.o
>>>> obj-y += irq.o
>>>> obj-y += clock.o
>>>> obj-y += common.o
>>>> obj-$(CONFIG_CACHE_L2X0) := l2x0.o
>>
>> Now it is changed to:
>>
>> +obj-y := timer.o
>> +obj-y += irq.o
>> +obj-y += clock.o
>> +obj-y += rstc.o
>> +obj-y += prima2.o
>> +obj-$(CONFIG_CACHE_L2X0) += l2x0.o
>> +obj-$(CONFIG_DEBUG_LL) += lluart.o
>>
>> For clock, i have moved the static mapping to clock.c:
>>
>> diff --git a/arch/arm/mach-prima2/clock.c b/arch/arm/mach-prima2/clock.c
>> new file mode 100644
>> index 0000000..f4676bc
>> --- /dev/null
>> +++ b/arch/arm/mach-prima2/clock.c
>> ...
>> +
>> +static void __init sirfsoc_clk_init(void)
>> +{
>> + clkdev_add_table(onchip_clks, ARRAY_SIZE(onchip_clks));
>> +}
>> +
>> +static struct of_device_id clkc_ids[] = {
>> + { .compatible = "sirf,clkc" },
>> +};
>> +
>> +void __init sirfsoc_of_clk_init(void)
>> +{
>> + struct device_node *np;
>> + struct resource res;
>> + struct map_desc sirfsoc_clkc_iodesc = {
>> + .virtual = SIRFSOC_CLOCK_VA_BASE,
>> + .type = MT_DEVICE,
>> + };
>> +
>> + np = of_find_matching_node(NULL, clkc_ids);
>> + if (!np)
>> + panic("unable to find compatible clkc node in dtb\n");
>> +
>> + if (of_address_to_resource(np, 0, &res))
>> + panic("unable to find clkc range in dtb");
>> + of_node_put(np);
>> +
>> + sirfsoc_clkc_iodesc.pfn = __phys_to_pfn(res.start);
>> + sirfsoc_clkc_iodesc.length = 1 + res.end - res.start;
>> +
>> + iotable_init(&sirfsoc_clkc_iodesc, 1);
>> +
>> + sirfsoc_clk_init();
>> +}
>>
>> It looks like we can new a common function named as of_io_earlymap()
>> or something in drivers/of/address.c. of_iomap() does ioremap,
>> of_io_earlymap() does early static mapping?
>> Then all SoCs can call this function to do early static mapping. if
>> so, some lines can be deleted in sirfsoc_of_clk_init(). How do you
>> think about newing the function in drivers/of/address.c?
>>
>> For DEBUG_LL uart, i have moved the static mapping to a new file named
>> lluart.c too:
>> +#include <linux/kernel.h>
>> +#include <asm/page.h>
>> +#include <asm/mach/map.h>
>> +#include <mach/map.h>
>> +#include <mach/uart.h>
>> +
>> +void __init sirfsoc_map_lluart(void)
>> +{
>> + struct map_desc sirfsoc_lluart_map = {
>> + .virtual = SIRFSOC_UART1_VA_BASE,
>> + .pfn = __phys_to_pfn(SIRFSOC_UART1_PA_BASE),
>> + .length = SIRFSOC_UART1_SIZE,
>> + .type = MT_DEVICE,
>> + };
>> +
>> + iotable_init(&sirfsoc_lluart_map, 1);
>> +}
>> +
>>
>> only when DEBUG_LL is selected, this file will be compiled. Otherwise,
>> an empty sirfsoc_map_lluart is used:
>> --- /dev/null
>> +++ b/arch/arm/mach-prima2/common.h
>> @@ -0,0 +1,26 @@
>> +/*
>> + * This file contains common function prototypes to avoid externs in
>> the c files.
>> + *
>> + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
>> + *
>> + * Licensed under GPLv2 or later.
>> + */
>> +
>> +#ifndef __MACH_PRIMA2_COMMON_H__
>> +#define __MACH_PRIMA2_COMMON_H__
>> +
>> +#include <linux/init.h>
>> +#include <asm/mach/time.h>
>> +
>> +extern struct sys_timer sirfsoc_timer;
>> +
>> +extern void __init sirfsoc_of_irq_init(void);
>> +extern void __init sirfsoc_of_clk_init(void);
>> +
>> +#ifndef CONFIG_DEBUG_LL
>> +static inline void sirfsoc_map_lluart(void) {}
>> +#else
>> +extern void __init sirfsoc_map_lluart(void);
>> +#endif
>> +
>> +#endif
>>
>> For rstc, it is the reset controller in prima2, every bit can reset a
>> special component in the SoC. i move the mapping to a new rstc.c file
>> too. But APIs, which every driver will call to reset itself, in rstc
>> is not full finished:
>> +/*
>> + * reset controller for CSR SiRFprimaII
>> + *
>> + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
>> + *
>> + * Licensed under GPLv2 or later.
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/errno.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +
>> +void __iomem *sirfsoc_rstc_base;
>> +
>> +static struct of_device_id rstc_ids[] = {
>> + { .compatible = "sirf,rstc" },
>> +};
>> +
>> +static int __init sirfsoc_of_rstc_init(void)
>> +{
>> + struct device_node *np;
>> +
>> + np = of_find_matching_node(NULL, rstc_ids);
>> + if (!np)
>> + panic("unable to find compatible rstc node in dtb\n");
>> +
>> + sirfsoc_rstc_base = of_iomap(np, 0);
>> + if (!sirfsoc_rstc_base)
>> + panic("unable to map rstc cpu registers\n");
>> +
>> + of_node_put(np);
>> +
>> + return 0;
>> +}
>> +early_initcall(sirfsoc_of_rstc_init);
>> +
>> +/* TODO:
>> + * add APIs to control reset of every module
>> + */
>>
>>>
>>>
>>> Right. Note that you have a := in there, which needs to be +=.
>>>
>>>
>>>> > It probably makes sense to pick a new name for the combined file, too, but I
>>>> > can't think of a good one. Maybe one of platform.c, prima2.c or core.c.
>>>>
>>>> i am not sure the original purpose of board_dt.c. and i am guessing
>>>> whether Grant created that single board file to contain multiple
>>>> boards. For example:
>>>>
>>>> MACHINE_START(PRIMA2_XXX, "prima2xxx")
>>>> .boot_params = SIRFSOC_SDRAM_PA + 0x100,
>>>> .init_early = sirfsoc_init_clk,
>>>> .map_io = sirfsoc_map_io,
>>>> .init_irq = sirfsoc_of_init_irq,
>>>> .timer = &sirfsoc_timer,
>>>> .init_machine = sirfsoc_mach_init,
>>>> .dt_compat = prima2xxx_dt_match,
>>>> MACHINE_END
>>>>
>>>> MACHINE_START(PRIMA2_YYY, "prima2yyy")
>>>> .boot_params = SIRFSOC_SDRAM_PA + 0x100,
>>>> .init_early = sirfsoc_init_clk,
>>>> .map_io = sirfsoc_map_io,
>>>> .init_irq = sirfsoc_of_init_irq,
>>>> .timer = &sirfsoc_timer,
>>>> .init_machine = sirfsoc_mach_init,
>>>> .dt_compat = prima2yyy_dt_match,
>>>> MACHINE_END
>>>
>>> No, this wouldn't make any sense when the only difference is the dt_compat
>>> field: At that point you would just list all the possible boards in the
>>> global dt_match table.
>>
>> Yes. i have rename common.c to prima2.c and now there is no any
>> map_desc table due to the above changes, so it is now much shorter:
>>
>> diff --git a/arch/arm/mach-prima2/prima2.c b/arch/arm/mach-prima2/prima2.c
>> new file mode 100644
>> index 0000000..f6b04a1
>> --- /dev/null
>> +++ b/arch/arm/mach-prima2/prima2.c
>> @@ -0,0 +1,40 @@
>> +/*
>> + * Defines machines for CSR SiRFprimaII
>> + *
>> + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
>> + *
>> + * Licensed under GPLv2 or later.
>> + */
>> +
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +#include <asm/mach-types.h>
>> +#include <asm/mach/arch.h>
>> +#include <linux/of.h>
>> +#include <linux/of_platform.h>
>> +#include "common.h"
>> +
>> +static struct of_device_id sirfsoc_of_bus_ids[] __initdata = {
>> + { .compatible = "simple-bus", },
>> + {},
>> +};
>> +
>> +void __init sirfsoc_mach_init(void)
>> +{
>> + of_platform_bus_probe(NULL, sirfsoc_of_bus_ids, NULL);
>> +}
>> +
>> +static const char *prima2cb_dt_match[] __initdata = {
>> + "sirf,prima2-cb",
>> + NULL
>> +};
>> +
>> +MACHINE_START(PRIMA2_EVB, "prima2cb")
>> + .boot_params = 0x00000100,
>> + .init_early = sirfsoc_of_clk_init,
>> + .map_io = sirfsoc_map_lluart,
>> + .init_irq = sirfsoc_of_irq_init,
>> + .timer = &sirfsoc_timer,
>> + .init_machine = sirfsoc_mach_init,
>> + .dt_compat = prima2cb_dt_match,
>> +MACHINE_END
>>
>>>
>>>> after creating a new file named mach-prima2/l2x0.c, it seems we only
>>>> need to change Makefile to:
>>>> obj-$(CONFIG_CACHE_L2X0) := l2x0.o
>>>> the head file is not needed.
>>>>
>>>> Currently, rob's OF-based L2 cache is not merged yet. then i only
>>>> write the following:
>>>>
>>>> static int __init sirfsoc_of_l2x_init(void)
>>>> {
>>>> struct device_node *np;
>>>> void __iomem *sirfsoc_l2x_base;
>>>>
>>>> np = of_find_matching_node(NULL, l2x_ids);
>>>> if (!np)
>>>> panic("unable to find compatible intc node in dtb\n");
>>>>
>>>> sirfsoc_l2x_base = of_iomap(np, 0);
>>>> if (!sirfsoc_l2x_base)
>>>> panic("unable to map l2x cpu registers\n");
>>>>
>>>> of_node_put(np);
>>>>
>>>> if (!(readl_relaxed(sirfsoc_l2x_base + L2X0_CTRL) & 1)) {
>>>> /*
>>>> * set the physical memory windows L2 cache will cover
>>>> */
>>>> writel_relaxed(PLAT_PHYS_OFFSET + 1024 * 1024 * 1024,
>>>> sirfsoc_l2x_base + L2X0_ADDR_FILTERING_END);
>>>> writel_relaxed(PLAT_PHYS_OFFSET | 0x1,
>>>> sirfsoc_l2x_base + L2X0_ADDR_FILTERING_START);
>>>>
>>>> writel_relaxed(0,
>>>> sirfsoc_l2x_base + L2X0_TAG_LATENCY_CTRL);
>>>> writel_relaxed(0,
>>>> sirfsoc_l2x_base + L2X0_DATA_LATENCY_CTRL);
>>>> }
>>>> l2x0_init((void __iomem *)sirfsoc_l2x_base, 0x00040000,
>>>> 0x00000000);
>>>>
>>>> return 0;
>>>> }
>>>> early_initcall(sirfsoc_of_l2x_init);
>>>>
>>>> After Rob's patch is merged, i think sirfsoc_of_l2x_init can be much simpler.
>>>>
>>> Yes. Rob/Olof, what's the status of that patch?
>>>
>>> Arnd
>>>
>>
>> After we get aggrement on DT node name(csr/csrxf/csr.l ?), i will send
>> patch v3 with all those all changes and full DT. Really thank you very
>> much!
>>
>> -barry
>>
> -barry
>
More information about the devicetree-discuss
mailing list