All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-06-28  3:32 Barry Song
       [not found] ` <1309231954-23260-1-git-send-email-bs14-kQvG35nSl+M@public.gmane.org>
  0 siblings, 1 reply; 49+ messages in thread
From: Barry Song @ 2011-06-28  3:32 UTC (permalink / raw)
  To: linux-arm-kernel

From: Binghua Duan <binghua.duan@csr.com>

SiRFprimaII is the latest generation application processor from CSR?s
Multifunction SoC product family. Designed around an ARM cortex A9 core,
high-speed memory bus, advanced 3D accelerator and full-HD multi-format
video decoder, SiRFprimaII is able to meet the needs of complicated
applications for modern multifunction devices that require heavy concurrent
applications and fluid user experience. Integrated with GPS baseband,
analog and PMU, this new platform is designed to provide a cost effective
solution for Automotive and Consumer markets.

This patch adds the basic support for this SoC and EVB board based on device
tree. It is following the ZYNQ of Grant Likely in some degree.

the device hierarchy in SiRFprimaII is as below

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

Signed-off-by: Binghua Duan <Binghua.Duan@csr.com>
Signed-off-by: Rongjun Ying <Rongjun.Ying@csr.com>
Signed-off-by: Zhiwu Song <Zhiwu.Song@csr.com>
Signed-off-by: Yuping Luo <Yuping.Luo@csr.com>
Signed-off-by: Bin Shi <Bin.Shi@csr.com>
Signed-off-by: Huayi Li <Huayi.Li@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
 -v2:
 1. clock: use dev_id instead of con_id
 2. Kconfig: delete ISA_DMA
 3. irq: implement int controller based on DT
	 move to GENERIC_IRQ_CHIP framework
 4. timer: implement timer based on DT
 5. entry-macro.S: use get_irqnr_preamble to load the base address only once
    per IRQ exception.
 6. others:
	use readl_relaxed instead of __raw_readl
	adjust Kconfig order for PRIMA2
	use clk_get_sys instead of clk_get for system level clock
	use BUG_ON(IS_ERR(clk)) instead of BUG_ON(IS_ERR_OR_NULL(clk));
	fix typo for CLOCK_TICK_RATE
	("sirf,xxx", "sirf,prima2-xxx")  instead of ("sirf,xxx") in dts

 arch/arm/Kconfig                                |   13 +
 arch/arm/Makefile                               |    1 +
 arch/arm/boot/dts/prima2-cb.dts                 |   50 +++
 arch/arm/mach-prima2/Makefile                   |    1 +
 arch/arm/mach-prima2/Makefile.boot              |    3 +
 arch/arm/mach-prima2/board_dt.c                 |   28 ++
 arch/arm/mach-prima2/clock.c                    |  474 +++++++++++++++++++++++
 arch/arm/mach-prima2/common.c                   |   78 ++++
 arch/arm/mach-prima2/common.h                   |   23 ++
 arch/arm/mach-prima2/include/mach/clkdev.h      |   15 +
 arch/arm/mach-prima2/include/mach/debug-macro.S |   29 ++
 arch/arm/mach-prima2/include/mach/entry-macro.S |   29 ++
 arch/arm/mach-prima2/include/mach/hardware.h    |   15 +
 arch/arm/mach-prima2/include/mach/io.h          |   21 +
 arch/arm/mach-prima2/include/mach/irqs.h        |   17 +
 arch/arm/mach-prima2/include/mach/map.h         |   39 ++
 arch/arm/mach-prima2/include/mach/memory.h      |   21 +
 arch/arm/mach-prima2/include/mach/system.h      |   27 ++
 arch/arm/mach-prima2/include/mach/timex.h       |   14 +
 arch/arm/mach-prima2/include/mach/uart.h        |   18 +
 arch/arm/mach-prima2/include/mach/uncompress.h  |   40 ++
 arch/arm/mach-prima2/include/mach/vmalloc.h     |   14 +
 arch/arm/mach-prima2/irq.c                      |   76 ++++
 arch/arm/mach-prima2/timer.c                    |  220 +++++++++++
 arch/arm/mm/Kconfig                             |    2 +-
 25 files changed, 1267 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/boot/dts/prima2-cb.dts
 create mode 100644 arch/arm/mach-prima2/Makefile
 create mode 100644 arch/arm/mach-prima2/Makefile.boot
 create mode 100644 arch/arm/mach-prima2/board_dt.c
 create mode 100644 arch/arm/mach-prima2/clock.c
 create mode 100644 arch/arm/mach-prima2/common.c
 create mode 100644 arch/arm/mach-prima2/common.h
 create mode 100644 arch/arm/mach-prima2/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-prima2/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-prima2/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-prima2/include/mach/hardware.h
 create mode 100644 arch/arm/mach-prima2/include/mach/io.h
 create mode 100644 arch/arm/mach-prima2/include/mach/irqs.h
 create mode 100644 arch/arm/mach-prima2/include/mach/map.h
 create mode 100644 arch/arm/mach-prima2/include/mach/memory.h
 create mode 100644 arch/arm/mach-prima2/include/mach/system.h
 create mode 100644 arch/arm/mach-prima2/include/mach/timex.h
 create mode 100644 arch/arm/mach-prima2/include/mach/uart.h
 create mode 100644 arch/arm/mach-prima2/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-prima2/include/mach/vmalloc.h
 create mode 100644 arch/arm/mach-prima2/irq.c
 create mode 100644 arch/arm/mach-prima2/timer.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9adc278..06ee145 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -879,6 +879,19 @@ config ARCH_VT8500
 	select HAVE_PWM
 	help
 	  Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
+
+config ARCH_PRIMA2
+	bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform"
+	select CPU_V7
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+	select CLKDEV_LOOKUP
+	select GENERIC_IRQ_CHIP
+	select USE_OF
+	select ZONE_DMA
+	help
+          Support for CSR SiRFSoC ARM Cortex A9 Platform
+
 endchoice
 
 #
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index f5b2b39..1d693d0 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -169,6 +169,7 @@ machine-$(CONFIG_ARCH_OMAP3)		:= omap2
 machine-$(CONFIG_ARCH_OMAP4)		:= omap2
 machine-$(CONFIG_ARCH_ORION5X)		:= orion5x
 machine-$(CONFIG_ARCH_PNX4008)		:= pnx4008
+machine-$(CONFIG_ARCH_PRIMA2)		:= prima2
 machine-$(CONFIG_ARCH_PXA)		:= pxa
 machine-$(CONFIG_ARCH_REALVIEW)		:= realview
 machine-$(CONFIG_ARCH_RPC)		:= rpc
diff --git a/arch/arm/boot/dts/prima2-cb.dts b/arch/arm/boot/dts/prima2-cb.dts
new file mode 100644
index 0000000..1777e98
--- /dev/null
+++ b/arch/arm/boot/dts/prima2-cb.dts
@@ -0,0 +1,50 @@
+/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 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		intc: interrupt-controller at 0x80020000 {
+			interrupt-controller;
+			compatible = "sirf,intc", "sirf,prima2-intc";
+			reg = <0x80020000 0x1000>;
+			#interrupt-cells = <1>;
+		};
+
+		timer0: timer at 0xb0020000 {
+			compatible = "sirf,tick", "sirf,prima2-tick";
+			reg = <0xb0020000 0x1000>;
+			interrupts = <0>;
+		};
+
+		uart0: uart at 0xb0050000 {
+			compatible = "sirf,uart", "sirf,prima2-uart";
+			reg = <0xb0050000 0x1000>;
+			interrupts = <17>;
+		};
+
+		uart1: uart at 0xb0060000 {
+			compatible = "sirf,uart", "sirf,prima2-uart";
+			reg = <0xb0060000 0x1000>;
+			interrupts = <18>;
+		};
+	};
+};
+
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
new file mode 100644
index 0000000..c51d60d
--- /dev/null
+++ b/arch/arm/mach-prima2/Makefile
@@ -0,0 +1 @@
+obj-y := timer.o irq.o clock.o common.o board_dt.o
diff --git a/arch/arm/mach-prima2/Makefile.boot b/arch/arm/mach-prima2/Makefile.boot
new file mode 100644
index 0000000..d023db3
--- /dev/null
+++ b/arch/arm/mach-prima2/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-y		:= 0x00008000
+params_phys-y		:= 0x00000100
+initrd_phys-y		:= 0x00800000
diff --git a/arch/arm/mach-prima2/board_dt.c b/arch/arm/mach-prima2/board_dt.c
new file mode 100644
index 0000000..42ce22a
--- /dev/null
+++ b/arch/arm/mach-prima2/board_dt.c
@@ -0,0 +1,28 @@
+/*
+ * This file contains code for boards with device tree support.
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/of.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include "common.h"
+
+static const char *prima2cb_dt_match[] __initdata = {
+       "sirf,prima2-cb",
+       NULL
+};
+
+MACHINE_START(PRIMA2_EVB, "prima2cb")
+	.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      = prima2cb_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-prima2/clock.c b/arch/arm/mach-prima2/clock.c
new file mode 100644
index 0000000..7dfdaee
--- /dev/null
+++ b/arch/arm/mach-prima2/clock.c
@@ -0,0 +1,474 @@
+/*
+ * Clock tree for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <mach/map.h>
+
+#define SIRFSOC_CLKC_CLK_EN0    0x0000
+#define SIRFSOC_CLKC_CLK_EN1    0x0004
+#define SIRFSOC_CLKC_REF_CFG    0x0014
+#define SIRFSOC_CLKC_CPU_CFG    0x0018
+#define SIRFSOC_CLKC_MEM_CFG    0x001c
+#define SIRFSOC_CLKC_SYS_CFG    0x0020
+#define SIRFSOC_CLKC_IO_CFG     0x0024
+#define SIRFSOC_CLKC_DSP_CFG    0x0028
+#define SIRFSOC_CLKC_GFX_CFG    0x002c
+#define SIRFSOC_CLKC_MM_CFG     0x0030
+#define SIRFSOC_LKC_LCD_CFG     0x0034
+#define SIRFSOC_CLKC_MMC_CFG    0x0038
+#define SIRFSOC_CLKC_PLL1_CFG0  0x0040
+#define SIRFSOC_CLKC_PLL2_CFG0  0x0044
+#define SIRFSOC_CLKC_PLL3_CFG0  0x0048
+#define SIRFSOC_CLKC_PLL1_CFG1  0x004c
+#define SIRFSOC_CLKC_PLL2_CFG1  0x0050
+#define SIRFSOC_CLKC_PLL3_CFG1  0x0054
+#define SIRFSOC_CLKC_PLL1_CFG2  0x0058
+#define SIRFSOC_CLKC_PLL2_CFG2  0x005c
+#define SIRFSOC_CLKC_PLL3_CFG2  0x0060
+
+#define KHZ     1000
+#define MHZ     (KHZ * KHZ)
+
+struct clk_ops {
+        unsigned long (*get_rate)(struct clk *clk);
+        long (*round_rate)(struct clk *clk, unsigned long rate);
+        int (*set_rate)(struct clk *clk, unsigned long rate);
+        int (*enable)(struct clk *clk);
+        int (*disable)(struct clk *clk);
+        struct clk *(*get_parent)(struct clk *clk);
+        int (*set_parent)(struct clk *clk, struct clk *parent);
+};
+
+struct clk {
+        struct clk *parent;     /* parent clk */
+        unsigned long rate;     /* clock rate in Hz */
+        signed char usage;      /* clock enable count */
+        signed char enable_bit; /* enable bit: 0 ~ 63 */
+        unsigned short regofs;  /* register offset */
+        struct clk_ops *ops;    /* clock operation */
+};
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+static inline unsigned long clkc_readl(unsigned reg)
+{
+	return readl(SIRFSOC_CLOCK_VA_BASE + reg);
+}
+
+static inline void clkc_writel(u32 val, unsigned reg)
+{
+	writel(val, SIRFSOC_CLOCK_VA_BASE + reg);
+}
+
+/*
+ * osc_rtc - real time oscillator - 32.768KHz
+ * osc_sys - high speed oscillator - 26MHz
+ */
+
+static struct clk clk_rtc = {
+	.rate = 32768,
+};
+
+static struct clk clk_osc = {
+	.rate = 26 * MHZ,
+};
+
+/*
+ * std pll
+ */
+static unsigned long std_pll_get_rate(struct clk *clk)
+{
+	unsigned long fin = clk_get_rate(clk->parent);
+	u32 regcfg2 = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - SIRFSOC_CLKC_PLL1_CFG0;
+
+	if (clkc_readl(regcfg2) & BIT(2)) {
+		/* pll bypass mode */
+		clk->rate = fin;
+	} else {
+		/* fout = fin * nf / nr / od */
+		u32 cfg0 = clkc_readl(clk->regofs);
+		u32 nf = (cfg0 & (BIT(13) - 1)) + 1;
+		u32 nr = ((cfg0 >> 13) & (BIT(6) - 1)) + 1;
+		u32 od = ((cfg0 >> 19) & (BIT(4) - 1)) + 1;
+		WARN_ON(fin % MHZ);
+		clk->rate = fin / MHZ * nf / nr / od * MHZ;
+	}
+
+	return clk->rate;
+}
+
+static int std_pll_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long fin, nf, nr, od, reg;
+
+	/*
+	 * fout = fin * nf / (nr * od);
+	 * set od = 1, nr = fin/MHz, so fout = nf * MHz
+	 */
+
+	nf = rate / MHZ;
+	if (unlikely((rate % MHZ) || nf > BIT(13) || nf < 1))
+		return -EINVAL;
+
+	fin = clk_get_rate(clk->parent);
+	BUG_ON(fin < MHZ);
+
+	nr = fin / MHZ;
+	BUG_ON((fin % MHZ) || nr > BIT(6));
+
+	od = 1;
+
+	reg = (nf - 1) | ((nr - 1) << 13) | ((od - 1) << 19);
+	clkc_writel(reg, clk->regofs);
+
+	reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG1 - SIRFSOC_CLKC_PLL1_CFG0;
+	clkc_writel((nf >> 1) - 1, reg);
+
+	reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - SIRFSOC_CLKC_PLL1_CFG0;
+	while (!(clkc_readl(reg) & BIT(6)))
+		cpu_relax();
+
+	clk->rate = 0; /* set to zero will force recalculation */
+	return 0;
+}
+
+static struct clk_ops std_pll_ops = {
+	.get_rate = std_pll_get_rate,
+	.set_rate = std_pll_set_rate,
+};
+
+static struct clk clk_pll1 = {
+	.parent = &clk_osc,
+	.regofs = SIRFSOC_CLKC_PLL1_CFG0,
+	.ops = &std_pll_ops,
+};
+
+static struct clk clk_pll2 = {
+	.parent = &clk_osc,
+	.regofs = SIRFSOC_CLKC_PLL2_CFG0,
+	.ops = &std_pll_ops,
+};
+
+static struct clk clk_pll3 = {
+	.parent = &clk_osc,
+	.regofs = SIRFSOC_CLKC_PLL3_CFG0,
+	.ops = &std_pll_ops,
+};
+
+/*
+ * clock domains - cpu, mem, sys/io
+ */
+
+static struct clk clk_mem;
+
+static struct clk *dmn_get_parent(struct clk *clk)
+{
+	struct clk *clks[] = {
+		&clk_osc, &clk_rtc, &clk_pll1, &clk_pll2, &clk_pll3
+	};
+	u32 cfg = clkc_readl(clk->regofs);
+	WARN_ON((cfg & (BIT(3) - 1)) > 4);
+	return clks[cfg & (BIT(3) - 1)];
+}
+
+static int dmn_set_parent(struct clk *clk, struct clk *parent)
+{
+	const struct clk *clks[] = {
+		&clk_osc, &clk_rtc, &clk_pll1, &clk_pll2, &clk_pll3
+	};
+	u32 cfg = clkc_readl(clk->regofs);
+	int i;
+	for (i = 0; i < ARRAY_SIZE(clks); i++) {
+		if (clks[i] == parent) {
+			cfg &= ~(BIT(3) - 1);
+			clkc_writel(cfg | i, clk->regofs);
+			/* BIT(3) - switching status: 1 - busy, 0 - done */
+			while (clkc_readl(clk->regofs) & BIT(3))
+				cpu_relax();
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+static unsigned long dmn_get_rate(struct clk *clk)
+{
+	unsigned long fin = clk_get_rate(clk->parent);
+	u32 cfg = clkc_readl(clk->regofs);
+	if (cfg & BIT(24)) {
+		/* fcd bypass mode */
+		clk->rate = fin;
+	} else {
+		/*
+		 * wait count: bit[19:16], hold count: bit[23:20]
+		 */
+		u32 wait = (cfg >> 16) & (BIT(4) - 1);
+		u32 hold = (cfg >> 20) & (BIT(4) - 1);
+
+		clk->rate = fin / (wait + hold + 2);
+	}
+
+	return clk->rate;
+}
+
+static int dmn_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long fin;
+	unsigned ratio, wait, hold, reg;
+	unsigned bits = (clk == &clk_mem) ? 3 : 4;
+
+	fin = clk_get_rate(clk->parent);
+	ratio = fin / rate;
+
+	if (unlikely(ratio < 2 || ratio > BIT(bits + 1)))
+		return -EINVAL;
+
+	WARN_ON(fin % rate);
+
+	wait = (ratio >> 1) - 1;
+	hold = ratio - wait - 2;
+
+	reg = clkc_readl(clk->regofs);
+	reg &= ~(((BIT(bits) - 1) << 16) | ((BIT(bits) - 1) << 20));
+	reg |= (wait << 16) | (hold << 20) | BIT(25);
+	clkc_writel(reg, clk->regofs);
+
+	/* waiting FCD been effective */
+	while (clkc_readl(clk->regofs) & BIT(25))
+		cpu_relax();
+
+	clk->rate = 0; /* set to zero will force recalculation */
+
+	return 0;
+}
+
+/*
+ * cpu clock has no FCD register in Prima2, can only change pll
+ */
+static int cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+	int ret1, ret2;
+	struct clk *cur_parent, *tmp_parent;
+
+	cur_parent = dmn_get_parent(clk);
+	BUG_ON(cur_parent == NULL || cur_parent->usage > 1);
+
+	/* switch to tmp pll before setting parent clock's rate */
+	tmp_parent = cur_parent == &clk_pll1 ? &clk_pll2 : &clk_pll1;
+	ret1 = dmn_set_parent(clk, tmp_parent);
+	BUG_ON(ret1);
+
+	ret2 = clk_set_rate(cur_parent, rate);
+
+	ret1 = dmn_set_parent(clk, cur_parent);
+
+	clk->rate = 0; /* set to zero will force recalculation */
+
+	return ret2 ? ret2 : ret1;
+}
+
+static struct clk_ops cpu_ops = {
+	.get_parent = dmn_get_parent,
+	.set_parent = dmn_set_parent,
+	.set_rate = cpu_set_rate,
+};
+
+static struct clk clk_cpu = {
+	.parent = &clk_pll1,
+	.regofs = SIRFSOC_CLKC_CPU_CFG,
+	.ops = &cpu_ops,
+};
+
+
+static struct clk_ops msi_ops = {
+	.set_rate = dmn_set_rate,
+	.get_rate = dmn_get_rate,
+	.set_parent = dmn_set_parent,
+	.get_parent = dmn_get_parent,
+};
+
+static struct clk clk_mem = {
+	.parent = &clk_pll2,
+	.regofs = SIRFSOC_CLKC_MEM_CFG,
+	.ops = &msi_ops,
+};
+
+static struct clk clk_sys = {
+	.parent = &clk_pll3,
+	.regofs = SIRFSOC_CLKC_SYS_CFG,
+	.ops = &msi_ops,
+};
+
+static struct clk clk_io = {
+	.parent = &clk_pll3,
+	.regofs = SIRFSOC_CLKC_IO_CFG,
+	.ops = &msi_ops,
+};
+
+/*
+ * on-chip clock sets
+ */
+static struct clk_lookup onchip_clks[] = {
+	{
+		.dev_id = "rtc",
+		.clk = &clk_rtc,
+	}, {
+		.dev_id = "osc",
+		.clk = &clk_osc,
+	}, {
+		.dev_id = "pll1",
+		.clk = &clk_pll1,
+	}, {
+		.dev_id = "pll2",
+		.clk = &clk_pll2,
+	}, {
+		.dev_id = "pll3",
+		.clk = &clk_pll3,
+	}, {
+		.dev_id = "cpu",
+		.clk = &clk_cpu,
+	}, {
+		.dev_id = "mem",
+		.clk = &clk_mem,
+	}, {
+		.dev_id = "sys",
+		.clk = &clk_sys,
+	}, {
+		.dev_id = "io",
+		.clk = &clk_io,
+	},
+};
+
+int clk_enable(struct clk *clk)
+{
+	unsigned long flags;
+
+	if (unlikely(IS_ERR_OR_NULL(clk)))
+		return -EINVAL;
+
+	if (clk->parent)
+		clk_enable(clk->parent);
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	if (!clk->usage++ && clk->ops && clk->ops->enable)
+		clk->ops->enable(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+	unsigned long flags;
+
+	if (unlikely(IS_ERR_OR_NULL(clk)))
+		return;
+
+	WARN_ON(!clk->usage);
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	if (--clk->usage == 0 && clk->ops && clk->ops->disable)
+		clk->ops->disable(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+
+	if (clk->parent)
+		clk_disable(clk->parent);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (unlikely(IS_ERR_OR_NULL(clk)))
+		return 0;
+
+	if (clk->rate)
+		return clk->rate;
+
+	if (clk->ops && clk->ops->get_rate)
+		return clk->ops->get_rate(clk);
+
+	return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (unlikely(IS_ERR_OR_NULL(clk)))
+		return 0;
+
+	if (clk->ops && clk->ops->round_rate)
+		return clk->ops->round_rate(clk, rate);
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	if (unlikely(IS_ERR_OR_NULL(clk)))
+		return -EINVAL;
+
+	if (!clk->ops || !clk->ops->set_rate)
+		return -EINVAL;
+
+	return clk->ops->set_rate(clk, rate);
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	int ret;
+	unsigned long flags;
+
+	if (unlikely(IS_ERR_OR_NULL(clk)))
+		return -EINVAL;
+
+	if (!clk->ops || !clk->ops->set_parent)
+		return -EINVAL;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	ret = clk->ops->set_parent(clk, parent);
+	if (!ret) {
+		parent->usage += clk->usage;
+		clk->parent->usage -= clk->usage;
+		BUG_ON(clk->parent->usage < 0);
+		clk->parent = parent;
+	}
+	spin_unlock_irqrestore(&clocks_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+	unsigned long flags;
+
+	if (unlikely(IS_ERR_OR_NULL(clk)))
+		return NULL;
+
+	if (!clk->ops || !clk->ops->get_parent)
+		return clk->parent;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	clk->parent = clk->ops->get_parent(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+	return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+void __init sirfsoc_init_clk(void)
+{
+	clkdev_add_table(onchip_clks, ARRAY_SIZE(onchip_clks));
+}
diff --git a/arch/arm/mach-prima2/common.c b/arch/arm/mach-prima2/common.c
new file mode 100644
index 0000000..2f0cfa0
--- /dev/null
+++ b/arch/arm/mach-prima2/common.c
@@ -0,0 +1,78 @@
+/*
+ * This file contains common code that is intended to be used across
+ * boards so that it's not replicated.
+ *
+ * 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/map.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <mach/hardware.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);
+}
+
+#define IOTABLE_ENTRY(region) {\
+	.virtual 	= SIRFSOC_##region##_VA_BASE, \
+	.pfn	 	= __phys_to_pfn(SIRFSOC_##region##_PA_BASE),\
+	.length		= SIRFSOC_##region##_SIZE, \
+	.type 		= MT_DEVICE, \
+}
+
+static struct map_desc sirfsoc_iodesc[] __initdata = {
+	IOTABLE_ENTRY(UART1),
+	IOTABLE_ENTRY(CLOCK),
+	IOTABLE_ENTRY(RSTC),
+#ifdef CONFIG_CACHE_L2X0
+	IOTABLE_ENTRY(L2CC),
+#endif
+};
+
+void __init sirfsoc_map_io(void)
+{
+	iotable_init(sirfsoc_iodesc, ARRAY_SIZE(sirfsoc_iodesc));
+}
+
+#define L2X0_ADDR_FILTERING_START       0xC00
+#define L2X0_ADDR_FILTERING_END         0xC04
+
+static int __init sirfsoc_init(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+	if (!(readl_relaxed(SIRFSOC_L2CC_VA_BASE + L2X0_CTRL) & 1)) {
+		/*
+		 * set the physical memory windows L2 cache will cover
+		 */
+		writel_relaxed(PHYS_OFFSET + 1024 * 1024 * 1024,
+			SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_END);
+		writel_relaxed(PHYS_OFFSET | 0x1,
+			SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_START);
+
+		writel_relaxed(0,
+			SIRFSOC_L2CC_VA_BASE + L2X0_TAG_LATENCY_CTRL);
+		writel_relaxed(0,
+			SIRFSOC_L2CC_VA_BASE + L2X0_DATA_LATENCY_CTRL);
+	}
+	l2x0_init((void __iomem *)SIRFSOC_L2CC_VA_BASE, 0x00040000,
+		0x00000000);
+#endif
+
+	return 0;
+}
+arch_initcall(sirfsoc_init);
diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h
new file mode 100644
index 0000000..388b293
--- /dev/null
+++ b/arch/arm/mach-prima2/common.h
@@ -0,0 +1,23 @@
+/*
+ * 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_init_io(void);
+extern void __init sirfsoc_map_io(void);
+extern void __init sirfsoc_mach_init(void);
+extern void __init sirfsoc_of_init_irq(void);
+extern void __init sirfsoc_init_clk(void);
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/clkdev.h b/arch/arm/mach-prima2/include/mach/clkdev.h
new file mode 100644
index 0000000..6693251
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/clkdev.h
@@ -0,0 +1,15 @@
+/*
+ * arch/arm/mach-prima2/include/mach/clkdev.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/debug-macro.S b/arch/arm/mach-prima2/include/mach/debug-macro.S
new file mode 100644
index 0000000..bf75106
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/debug-macro.S
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-prima2/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <mach/hardware.h>
+#include <mach/uart.h>
+
+	.macro	addruart, rp, rv
+	ldr	\rp, =SIRFSOC_UART1_PA_BASE		@ physical
+	ldr	\rv, =SIRFSOC_UART1_VA_BASE		@ virtual
+	.endm
+
+	.macro	senduart,rd,rx
+	str	\rd, [\rx, #SIRFSOC_UART_TXFIFO_DATA]
+	.endm
+
+	.macro	busyuart,rd,rx
+	.endm
+
+	.macro	waituart,rd,rx
+1001:	ldr	\rd, [\rx, #SIRFSOC_UART_TXFIFO_STATUS]
+	tst	\rd, #SIRFSOC_UART1_TXFIFO_EMPTY
+	beq	1001b
+	.endm
+
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..1c8a50f
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/entry-macro.S
@@ -0,0 +1,29 @@
+/*
+ * 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_preamble, base, tmp
+	ldr     \base, =sirfsoc_intc_base
+	ldr     \base, [\base]
+	.endm
+
+	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+	ldr \irqnr, [\base, #SIRFSOC_INT_ID]	@ Get the highest priority irq
+	cmp \irqnr, #0x40			@ the irq num can't be larger than 0x3f
+	movges \irqnr, #0
+	.endm
+
+	.macro  disable_fiq
+	.endm
+
+	.macro  arch_ret_to_user, tmp1, tmp2
+	.endm
+
diff --git a/arch/arm/mach-prima2/include/mach/hardware.h b/arch/arm/mach-prima2/include/mach/hardware.h
new file mode 100644
index 0000000..105b969
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/hardware.h
@@ -0,0 +1,15 @@
+/*
+ * arch/arm/mach-prima2/include/mach/hardware.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_HARDWARE_H__
+#define __MACH_HARDWARE_H__
+
+#include <asm/sizes.h>
+#include <mach/map.h>
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/io.h b/arch/arm/mach-prima2/include/mach/io.h
new file mode 100644
index 0000000..fc54f16
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/io.h
@@ -0,0 +1,21 @@
+/*
+ * 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_IO_H
+#define __MACH_PRIMA2_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a)                 __typesafe_io(a)
+#define __mem_pci(a)            (a)
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/irqs.h b/arch/arm/mach-prima2/include/mach/irqs.h
new file mode 100644
index 0000000..bb354f9
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/irqs.h
@@ -0,0 +1,17 @@
+/*
+ * arch/arm/mach-prima2/include/mach/irqs.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define SIRFSOC_INTENAL_IRQ_START  0
+#define SIRFSOC_INTENAL_IRQ_END    59
+
+#define NR_IRQS	220
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/map.h b/arch/arm/mach-prima2/include/mach/map.h
new file mode 100644
index 0000000..7a48dc5
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/map.h
@@ -0,0 +1,39 @@
+/*
+ * memory & I/O static mapping definitions for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_PRIMA2_MAP_H__
+#define __MACH_PRIMA2_MAP_H__
+
+#include <mach/vmalloc.h>
+
+#define SIRFSOC_VA(x)			(VMALLOC_END + ((x) & 0x00FFF000))
+
+/* L2 CACHE */
+#define SIRFSOC_L2CC_PA_BASE		0x80040000
+#define SIRFSOC_L2CC_VA_BASE		SIRFSOC_VA(0x004000)
+#define SIRFSOC_L2CC_SIZE		SZ_4K
+
+/* RESET CONTROLLER */
+#define SIRFSOC_RSTC_PA_BASE           0x88010000
+#define SIRFSOC_RSTC_VA_BASE           SIRFSOC_VA(0x006000)
+#define SIRFSOC_RSTC_SIZE              SZ_4K
+
+/* CLOCK */
+#define SIRFSOC_CLOCK_PA_BASE		0x88000000
+#define SIRFSOC_CLOCK_VA_BASE		SIRFSOC_VA(0x005000)
+#define SIRFSOC_CLOCK_SIZE		SZ_4K
+
+/* UART-1: used as serial debug port */
+#define SIRFSOC_UART1_PA_BASE		0xb0060000
+#define SIRFSOC_UART1_VA_BASE		SIRFSOC_VA(0x060000)
+#define SIRFSOC_UART1_SIZE		SZ_4K
+
+/* RAM BASE*/
+#define SIRFSOC_SDRAM_PA		0x00000000
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/memory.h b/arch/arm/mach-prima2/include/mach/memory.h
new file mode 100644
index 0000000..368cd5a
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/memory.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-prima2/include/mach/memory.h
+ *
+ * Copyright (c) 2010 ? 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET        UL(0x00000000)
+
+/*
+ * Restrict DMA-able region to workaround silicon limitation.
+ * The limitation restricts buffers available for DMA to SD/MMC
+ * hardware to be below 256MB
+ */
+#define ARM_DMA_ZONE_SIZE	(SZ_256M)
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/system.h b/arch/arm/mach-prima2/include/mach/system.h
new file mode 100644
index 0000000..a84e91f
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm/mach-prima2/include/mach/system.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_SYSTEM_H__
+#define __MACH_SYSTEM_H__
+
+#include <linux/bitops.h>
+#include <mach/hardware.h>
+
+#define SIRFSOC_SYS_RST_BIT  BIT(31)
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	writel(SIRFSOC_SYS_RST_BIT, SIRFSOC_RSTC_VA_BASE);
+}
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/timex.h b/arch/arm/mach-prima2/include/mach/timex.h
new file mode 100644
index 0000000..d6f98a7
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/timex.h
@@ -0,0 +1,14 @@
+/*
+ * arch/arm/mach-prima2/include/mach/timex.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_TIMEX_H__
+#define __MACH_TIMEX_H__
+
+#define CLOCK_TICK_RATE  1000000
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/uart.h b/arch/arm/mach-prima2/include/mach/uart.h
new file mode 100644
index 0000000..53cf17a
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/uart.h
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/mach-prima2/include/mach/uart.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_PRIMA2_SIRFSOC_UART_H
+#define __MACH_PRIMA2_SIRFSOC_UART_H
+
+#define SIRFSOC_UART_TXFIFO_STATUS	0x0114
+#define SIRFSOC_UART_TXFIFO_DATA	0x0118
+
+#define SIRFSOC_UART1_TXFIFO_FULL                       (1 << 5)
+#define SIRFSOC_UART1_TXFIFO_EMPTY			(1 << 6)
+
+#endif
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..83125c6
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/uncompress.h
@@ -0,0 +1,40 @@
+/*
+ * 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/io.h>
+#include <mach/hardware.h>
+#include <mach/uart.h>
+
+void arch_decomp_setup(void)
+{
+}
+
+#define arch_decomp_wdog()
+
+static __inline__ void putc(char c)
+{
+	/*
+	 * during kernel decompression, all mappings are flat:
+	 *  virt_addr == phys_addr
+	 */
+	while (__raw_readl(SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_STATUS)
+		& SIRFSOC_UART1_TXFIFO_FULL)
+		barrier();
+
+	__raw_writel(c, SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_DATA);
+}
+
+static inline void flush(void)
+{
+}
+
+#endif
+
diff --git a/arch/arm/mach-prima2/include/mach/vmalloc.h b/arch/arm/mach-prima2/include/mach/vmalloc.h
new file mode 100644
index 0000000..116d0a5
--- /dev/null
+++ b/arch/arm/mach-prima2/include/mach/vmalloc.h
@@ -0,0 +1,14 @@
+/*
+ * arch/arm/ach-prima2/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2010 ? 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_VMALLOC_H
+#define __MACH_VMALLOC_H
+
+#define VMALLOC_END	0xFEC00000
+
+#endif
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c
new file mode 100644
index 0000000..b09b5ff
--- /dev/null
+++ b/arch/arm/mach-prima2/irq.c
@@ -0,0 +1,76 @@
+/*
+ * interrupt controller support 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/io.h>
+#include <linux/irq.h>
+#include <mach/hardware.h>
+#include <asm/mach/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define SIRFSOC_INT_RISC_MASK0          0x0018
+#define SIRFSOC_INT_RISC_MASK1          0x001C
+#define SIRFSOC_INT_RISC_LEVEL0         0x0020
+#define SIRFSOC_INT_RISC_LEVEL1         0x0024
+
+void __iomem *sirfsoc_intc_base;
+
+static __init void
+sirfsoc_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
+{
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
+
+	gc = irq_alloc_generic_chip("SIRFINTC", 1, irq_start, base, handle_level_irq);
+	ct = gc->chip_types;
+
+	ct->chip.irq_mask = irq_gc_mask_clr_bit;
+	ct->chip.irq_unmask = irq_gc_mask_set_bit;
+	ct->regs.mask = SIRFSOC_INT_RISC_MASK0;
+
+	irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, 0);
+}
+
+static __init void sirfsoc_init_irq(void)
+{
+	sirfsoc_alloc_gc(sirfsoc_intc_base, 0, 32);
+	sirfsoc_alloc_gc(sirfsoc_intc_base + 4, 32, SIRFSOC_INTENAL_IRQ_END - 32);
+
+	writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL0);
+	writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL1);
+
+	writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK0);
+	writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1);
+}
+
+static struct of_device_id intc_ids[]  = {
+	{ .compatible = "sirf,intc" },
+	{ .compatible = "sirf,prima2-intc" },
+};
+
+void __init sirfsoc_of_init_irq(void)
+{
+	struct device_node *np;
+	const unsigned int *intspec;
+
+	np = of_find_matching_node(NULL, intc_ids);
+	if (!np)
+		panic("unable to find compatible intc node in dtb\n");
+
+	/* Get the interrupts property */
+	intspec = of_get_property(np, "reg", NULL);
+	BUG_ON(!intspec);
+	sirfsoc_intc_base = of_iomap(np, 0);
+	if (!sirfsoc_intc_base)
+		panic("unable to map intc cpu registers\n");
+
+	of_node_put(np);
+
+	sirfsoc_init_irq();
+}
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c
new file mode 100644
index 0000000..9600341
--- /dev/null
+++ b/arch/arm/mach-prima2/timer.c
@@ -0,0 +1,220 @@
+/*
+ * System timer 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/interrupt.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/bitops.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <mach/map.h>
+#include <asm/mach/time.h>
+
+#define SIRFSOC_TIMER_COUNTER_LO	0x0000
+#define SIRFSOC_TIMER_COUNTER_HI	0x0004
+#define SIRFSOC_TIMER_MATCH_0		0x0008
+#define SIRFSOC_TIMER_MATCH_1		0x000C
+#define SIRFSOC_TIMER_MATCH_2		0x0010
+#define SIRFSOC_TIMER_MATCH_3		0x0014
+#define SIRFSOC_TIMER_MATCH_4		0x0018
+#define SIRFSOC_TIMER_MATCH_5		0x001C
+#define SIRFSOC_TIMER_STATUS		0x0020
+#define SIRFSOC_TIMER_INT_EN		0x0024
+#define SIRFSOC_TIMER_WATCHDOG_EN	0x0028
+#define SIRFSOC_TIMER_DIV		0x002C
+#define SIRFSOC_TIMER_LATCH		0x0030
+#define SIRFSOC_TIMER_LATCHED_LO	0x0034
+#define SIRFSOC_TIMER_LATCHED_HI	0x0038
+
+#define SIRFSOC_TIMER_WDT_INDEX		5
+
+#define SIRFSOC_TIMER_LATCH_BIT	 BIT(0)
+
+static void __iomem *sirfsoc_timer_base;
+static void __init sirfsoc_of_timer_map(void);
+
+/* timer0 interrupt handler */
+static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *ce = dev_id;
+
+	WARN_ON(!(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_STATUS) & BIT(0)));
+
+	/* clear timer0 interrupt */
+	writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS);
+
+	ce->event_handler(ce);
+
+	return IRQ_HANDLED;
+}
+
+/* read 64-bit timer counter */
+static cycle_t sirfsoc_timer_read(struct clocksource *cs)
+{
+	u64 cycles;
+
+	/* latch the 64-bit timer counter */
+	writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
+	cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_HI);
+	cycles = (cycles << 32) | readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO);
+
+	return cycles;
+}
+
+static int sirfsoc_timer_set_next_event(unsigned long delta,
+	struct clock_event_device *ce)
+{
+	unsigned long now, next;
+
+	writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
+	now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO);
+	do {
+		next = now + delta;
+		writel_relaxed(next, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0);
+		writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
+		now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO);
+	} while ((next - now) > delta);
+
+	return 0;
+}
+
+static void sirfsoc_timer_set_mode(enum clock_event_mode mode,
+	struct clock_event_device *ce)
+{
+	u32 val = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		WARN_ON(1);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		writel_relaxed(val | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		writel_relaxed(val & ~BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_RESUME:
+		break;
+	}
+}
+
+static struct clock_event_device sirfsoc_clockevent = {
+	.name = "sirfsoc_clockevent",
+	.rating = 200,
+	.features = CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode = sirfsoc_timer_set_mode,
+	.set_next_event = sirfsoc_timer_set_next_event,
+};
+
+static struct clocksource sirfsoc_clocksource = {
+	.name = "sirfsoc_clocksource",
+	.rating = 200,
+	.mask = CLOCKSOURCE_MASK(64),
+	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+	.read = sirfsoc_timer_read,
+};
+
+static struct irqaction sirfsoc_timer_irq = {
+	.name = "sirfsoc_timer0",
+	.flags = IRQF_TIMER,
+	.irq = 0,
+	.handler = sirfsoc_timer_interrupt,
+	.dev_id = &sirfsoc_clockevent,
+};
+
+/* Overwrite weak default sched_clock with more precise one */
+unsigned long long notrace sched_clock(void)
+{
+	static int is_mapped = 0;
+
+	/*
+	 * sched_clock is called earlier than .init of sys_timer
+	 * if we map timer memory in .init of sys_timer, system
+	 * will panic due to illegal memory access
+	 */
+	if(!is_mapped) {
+		sirfsoc_of_timer_map();
+		is_mapped = 1;
+	}
+
+	return sirfsoc_timer_read(NULL) * (NSEC_PER_SEC / CLOCK_TICK_RATE);
+}
+
+static void __init sirfsoc_clockevent_init(void)
+{
+	clockevents_calc_mult_shift(&sirfsoc_clockevent, CLOCK_TICK_RATE, 60);
+
+	sirfsoc_clockevent.max_delta_ns =
+		clockevent_delta2ns(-2, &sirfsoc_clockevent);
+	sirfsoc_clockevent.min_delta_ns =
+		clockevent_delta2ns(2, &sirfsoc_clockevent);
+
+	sirfsoc_clockevent.cpumask = cpumask_of(0);
+	clockevents_register_device(&sirfsoc_clockevent);
+}
+
+/* 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_sys("io", NULL);
+
+	BUG_ON(IS_ERR(clk));
+
+	rate = clk_get_rate(clk);
+
+	BUG_ON(rate < CLOCK_TICK_RATE);
+	BUG_ON(rate % CLOCK_TICK_RATE);
+
+	writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV);
+	writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
+	writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
+	writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS);
+
+	BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
+
+	BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq));
+
+	sirfsoc_clockevent_init();
+}
+
+static struct of_device_id timer_ids[] = {
+	{ .compatible = "sirf,tick" },
+	{ .compatible = "sirf,prima2-tick" },
+};
+
+static void __init sirfsoc_of_timer_map(void)
+{
+	struct device_node *np;
+	const unsigned int *intspec;
+
+	np = of_find_matching_node(NULL, timer_ids);
+	if (!np)
+		panic("unable to find compatible timer node in dtb\n");
+	sirfsoc_timer_base = of_iomap(np, 0);
+	if (!sirfsoc_timer_base)
+		panic("unable to map timer cpu registers\n");
+
+	/* Get the interrupts property */
+	intspec = of_get_property(np, "interrupts", NULL);
+	BUG_ON(!intspec);
+	sirfsoc_timer_irq.irq = be32_to_cpup(intspec);
+
+	of_node_put(np);
+}
+
+struct sys_timer sirfsoc_timer = {
+	.init = sirfsoc_timer_init,
+};
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 0074b8d..edf0681 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -821,7 +821,7 @@ config CACHE_L2X0
 	depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
 		   REALVIEW_EB_A9MP || SOC_IMX35 || SOC_IMX31 || MACH_REALVIEW_PBX || \
 		   ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \
-		   ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE
+		   ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || ARCH_PRIMA2
 	default y
 	select OUTER_CACHE
 	select OUTER_CACHE_SYNC
-- 
1.7.1



Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog@www.csr.com/blog

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-06-28  3:32 [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support Barry Song
@ 2011-06-29 21:29     ` Arnd Bergmann
  0 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-06-29 21:29 UTC (permalink / raw)
  To: Barry Song
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ, Bin Shi,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, Zhiwu Song, Rongjun Ying,
	Binghua Duan, Barry Song, tglx-hfZtesqFncYOwBW4kG4KsQ,
	Yuping Luo, Huayi Li,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tuesday 28 June 2011, Barry Song wrote:
> This patch adds the basic support for this SoC and EVB board based on device
> tree. It is following the ZYNQ of Grant Likely in some degree.

Hi Barry,

There are a few more things I noticed this time around, and some comments
about code that changed since v1.

> the device hierarchy in SiRFprimaII is as below
> 
> 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
> 

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.

This also includes using bus-local addresses for the 'reg' properties,
rather than global addresses.

>  1. clock: use dev_id instead of con_id
>  2. Kconfig: delete ISA_DMA
>  3. irq: implement int controller based on DT
> 	 move to GENERIC_IRQ_CHIP framework
>  4. timer: implement timer based on DT
>  5. entry-macro.S: use get_irqnr_preamble to load the base address only once
>     per IRQ exception.
>  6. others:
> 	use readl_relaxed instead of __raw_readl
> 	adjust Kconfig order for PRIMA2
> 	use clk_get_sys instead of clk_get for system level clock
> 	use BUG_ON(IS_ERR(clk)) instead of BUG_ON(IS_ERR_OR_NULL(clk));
> 	fix typo for CLOCK_TICK_RATE
> 	("sirf,xxx", "sirf,prima2-xxx")  instead of ("sirf,xxx") in dts
> 

Good progress!

> new file mode 100644
> index 0000000..1777e98
> --- /dev/null
> +++ b/arch/arm/boot/dts/prima2-cb.dts
> @@ -0,0 +1,50 @@
> +/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 {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		intc: interrupt-controller@0x80020000 {
> +			interrupt-controller;
> +			compatible = "sirf,intc", "sirf,prima2-intc";
> +			reg = <0x80020000 0x1000>;
> +			#interrupt-cells = <1>;
> +		};

Some more commends on the device tree properties:

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-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
mailing list on Cc, maybe someone can clarify.

> +		timer0: timer@0xb0020000 {
> +			compatible = "sirf,tick", "sirf,prima2-tick";
> +			reg = <0xb0020000 0x1000>;
> +			interrupts = <0>;
> +		};
> +
> +		uart0: uart@0xb0050000 {
> +			compatible = "sirf,uart", "sirf,prima2-uart";
> +			reg = <0xb0050000 0x1000>;
> +			interrupts = <17>;
> +		};
> +
> +		uart1: uart@0xb0060000 {
> +			compatible = "sirf,uart", "sirf,prima2-uart";
> +			reg = <0xb0060000 0x1000>;
> +			interrupts = <18>;
> +		};
> +	};
> +};

When you use local addresses, this would become something like

	axi1 {
		compatible = "simple-bus";
		#address-cells = <1>;
		#size-cells = <1>;
		ranges <0 0x80000000 0x10000000>;

		intc: interrupt-controller@20000 {
			interrupt-controller;
			compatible = "sirf,intc", "sirf,prima2-intc";
			reg = <0x20000 0x1000>;
			#interrupt-cells = <1>;
		};
	}
	axi2 {
		compatible = "simple-bus";
		#address-cells = <1>;
		#size-cells = <1>;
		ranges <0 0xb0000000 0x10000000>;

		timer0: timer@20000 {
			reg = <0x20000 0x1000>;
		};

		uart0: uart@50000 {
			reg = <0x50000 0x1000>;
		};

		uart1: uart@60000 {
			reg = <0x60000 0x1000>;
		};
	};



> +
> diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
> new file mode 100644
> index 0000000..c51d60d
> --- /dev/null
> +++ b/arch/arm/mach-prima2/Makefile
> @@ -0,0 +1 @@
> +obj-y := timer.o irq.o clock.o common.o board_dt.o

Minor detail:

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.

> +++ b/arch/arm/mach-prima2/board_dt.c
> @@ -0,0 +1,28 @@
> +/*
> + * This file contains code for boards with device tree support.
> + *
> + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
> + *
> + * Licensed under GPLv2 or later.
> + */
> +
> +#include <linux/of.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach-types.h>
> +#include <mach/hardware.h>
> +#include "common.h"
> +
> +static const char *prima2cb_dt_match[] __initdata = {
> +       "sirf,prima2-cb",
> +       NULL
> +};
> +
> +MACHINE_START(PRIMA2_EVB, "prima2cb")
> +       .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      = prima2cb_dt_match,
> +MACHINE_END

How about removing the remaining board file entirely and merging the contents into
common.c? We don't want to have board specific files any more, so the naming
and the split is rather obsolete.

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.

> +#define IOTABLE_ENTRY(region) {\
> +	.virtual 	= SIRFSOC_##region##_VA_BASE, \
> +	.pfn	 	= __phys_to_pfn(SIRFSOC_##region##_PA_BASE),\
> +	.length		= SIRFSOC_##region##_SIZE, \
> +	.type 		= MT_DEVICE, \
> +}
> +
> +static struct map_desc sirfsoc_iodesc[] __initdata = {
> +	IOTABLE_ENTRY(UART1),
> +	IOTABLE_ENTRY(CLOCK),
> +	IOTABLE_ENTRY(RSTC),
> +#ifdef CONFIG_CACHE_L2X0
> +	IOTABLE_ENTRY(L2CC),
> +#endif
> +};

I've thought about this some more, and I think you can get rid of most
entries in the global table after all:

* sirfsoc_init_clk() can get the physical address from the device tree
and call iotable_init for just one entry.

* RSTC does not seem to be needed early at all, you can simply ioremap it.

* L2CC is only accessed from an arch_initcall, which is late enough
  for ioremap.

* UART1 is only needed for early printk, so I would put the function
  that does this remaining iotable_init() call into a separate file
  that only gets compiled when that is enabled.

> +void __init sirfsoc_map_io(void)
> +{
> +	iotable_init(sirfsoc_iodesc, ARRAY_SIZE(sirfsoc_iodesc));
> +}
> +
> +#define L2X0_ADDR_FILTERING_START       0xC00
> +#define L2X0_ADDR_FILTERING_END         0xC04
> +
> +static int __init sirfsoc_init(void)
> +{
> +#ifdef CONFIG_CACHE_L2X0
> +	if (!(readl_relaxed(SIRFSOC_L2CC_VA_BASE + L2X0_CTRL) & 1)) {
> +		/*
> +		 * set the physical memory windows L2 cache will cover
> +		 */
> +		writel_relaxed(PHYS_OFFSET + 1024 * 1024 * 1024,
> +			SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_END);
> +		writel_relaxed(PHYS_OFFSET | 0x1,
> +			SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_START);
> +
> +		writel_relaxed(0,
> +			SIRFSOC_L2CC_VA_BASE + L2X0_TAG_LATENCY_CTRL);
> +		writel_relaxed(0,
> +			SIRFSOC_L2CC_VA_BASE + L2X0_DATA_LATENCY_CTRL);
> +	}
> +	l2x0_init((void __iomem *)SIRFSOC_L2CC_VA_BASE, 0x00040000,
> +		0x00000000);
> +#endif
> +
> +	return 0;
> +}
> +arch_initcall(sirfsoc_init);

I would also suggest moving the l2x0 code into a new l2x0.c file that
is conditionally compiled. In the header file, you then do

#ifdef CONFIG_CACHE_L2X0
extern void sirfsoc_l2x0_init(void);
#else
static inline void sirfsoc_l2x0_init(void) {}
#endif

> +#ifndef __ASM_ARCH_IRQS_H
> +#define __ASM_ARCH_IRQS_H
> +
> +#define SIRFSOC_INTENAL_IRQ_START  0
> +#define SIRFSOC_INTENAL_IRQ_END    59

Typo, I assume: INTERNAL, not INTENAL


> +
> +static struct of_device_id intc_ids[]  = {
> +	{ .compatible = "sirf,intc" },
> +	{ .compatible = "sirf,prima2-intc" },
> +};

You should only list one of these in the driver: The idea is that as 
long as all variants of the hardware are identical, you can just list
the most general name (sirf,intc), and if you need to tell the difference
you list the more specific names and add a .data=... member that you
use to differentiate between them. Note that it's usually easier to
change the code than to change the device tree, so we want to have 
the full list in the device tree, but the code just needs to pick
one that fits the purpose.

It's the same for the other drivers.

> +static void __init sirfsoc_of_timer_map(void);

You can remove this forward declaration if you move the sched_clock()
function down.

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-06-29 21:29     ` Arnd Bergmann
  0 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-06-29 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 28 June 2011, Barry Song wrote:
> This patch adds the basic support for this SoC and EVB board based on device
> tree. It is following the ZYNQ of Grant Likely in some degree.

Hi Barry,

There are a few more things I noticed this time around, and some comments
about code that changed since v1.

> the device hierarchy in SiRFprimaII is as below
> 
> 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
> 

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.

This also includes using bus-local addresses for the 'reg' properties,
rather than global addresses.

>  1. clock: use dev_id instead of con_id
>  2. Kconfig: delete ISA_DMA
>  3. irq: implement int controller based on DT
> 	 move to GENERIC_IRQ_CHIP framework
>  4. timer: implement timer based on DT
>  5. entry-macro.S: use get_irqnr_preamble to load the base address only once
>     per IRQ exception.
>  6. others:
> 	use readl_relaxed instead of __raw_readl
> 	adjust Kconfig order for PRIMA2
> 	use clk_get_sys instead of clk_get for system level clock
> 	use BUG_ON(IS_ERR(clk)) instead of BUG_ON(IS_ERR_OR_NULL(clk));
> 	fix typo for CLOCK_TICK_RATE
> 	("sirf,xxx", "sirf,prima2-xxx")  instead of ("sirf,xxx") in dts
> 

Good progress!

> new file mode 100644
> index 0000000..1777e98
> --- /dev/null
> +++ b/arch/arm/boot/dts/prima2-cb.dts
> @@ -0,0 +1,50 @@
> +/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 {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		intc: interrupt-controller at 0x80020000 {
> +			interrupt-controller;
> +			compatible = "sirf,intc", "sirf,prima2-intc";
> +			reg = <0x80020000 0x1000>;
> +			#interrupt-cells = <1>;
> +		};

Some more commends on the device tree properties:

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.

> +		timer0: timer at 0xb0020000 {
> +			compatible = "sirf,tick", "sirf,prima2-tick";
> +			reg = <0xb0020000 0x1000>;
> +			interrupts = <0>;
> +		};
> +
> +		uart0: uart at 0xb0050000 {
> +			compatible = "sirf,uart", "sirf,prima2-uart";
> +			reg = <0xb0050000 0x1000>;
> +			interrupts = <17>;
> +		};
> +
> +		uart1: uart at 0xb0060000 {
> +			compatible = "sirf,uart", "sirf,prima2-uart";
> +			reg = <0xb0060000 0x1000>;
> +			interrupts = <18>;
> +		};
> +	};
> +};

When you use local addresses, this would become something like

	axi1 {
		compatible = "simple-bus";
		#address-cells = <1>;
		#size-cells = <1>;
		ranges <0 0x80000000 0x10000000>;

		intc: interrupt-controller at 20000 {
			interrupt-controller;
			compatible = "sirf,intc", "sirf,prima2-intc";
			reg = <0x20000 0x1000>;
			#interrupt-cells = <1>;
		};
	}
	axi2 {
		compatible = "simple-bus";
		#address-cells = <1>;
		#size-cells = <1>;
		ranges <0 0xb0000000 0x10000000>;

		timer0: timer at 20000 {
			reg = <0x20000 0x1000>;
		};

		uart0: uart at 50000 {
			reg = <0x50000 0x1000>;
		};

		uart1: uart at 60000 {
			reg = <0x60000 0x1000>;
		};
	};



> +
> diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
> new file mode 100644
> index 0000000..c51d60d
> --- /dev/null
> +++ b/arch/arm/mach-prima2/Makefile
> @@ -0,0 +1 @@
> +obj-y := timer.o irq.o clock.o common.o board_dt.o

Minor detail:

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.

> +++ b/arch/arm/mach-prima2/board_dt.c
> @@ -0,0 +1,28 @@
> +/*
> + * This file contains code for boards with device tree support.
> + *
> + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
> + *
> + * Licensed under GPLv2 or later.
> + */
> +
> +#include <linux/of.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach-types.h>
> +#include <mach/hardware.h>
> +#include "common.h"
> +
> +static const char *prima2cb_dt_match[] __initdata = {
> +       "sirf,prima2-cb",
> +       NULL
> +};
> +
> +MACHINE_START(PRIMA2_EVB, "prima2cb")
> +       .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      = prima2cb_dt_match,
> +MACHINE_END

How about removing the remaining board file entirely and merging the contents into
common.c? We don't want to have board specific files any more, so the naming
and the split is rather obsolete.

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.

> +#define IOTABLE_ENTRY(region) {\
> +	.virtual 	= SIRFSOC_##region##_VA_BASE, \
> +	.pfn	 	= __phys_to_pfn(SIRFSOC_##region##_PA_BASE),\
> +	.length		= SIRFSOC_##region##_SIZE, \
> +	.type 		= MT_DEVICE, \
> +}
> +
> +static struct map_desc sirfsoc_iodesc[] __initdata = {
> +	IOTABLE_ENTRY(UART1),
> +	IOTABLE_ENTRY(CLOCK),
> +	IOTABLE_ENTRY(RSTC),
> +#ifdef CONFIG_CACHE_L2X0
> +	IOTABLE_ENTRY(L2CC),
> +#endif
> +};

I've thought about this some more, and I think you can get rid of most
entries in the global table after all:

* sirfsoc_init_clk() can get the physical address from the device tree
and call iotable_init for just one entry.

* RSTC does not seem to be needed early at all, you can simply ioremap it.

* L2CC is only accessed from an arch_initcall, which is late enough
  for ioremap.

* UART1 is only needed for early printk, so I would put the function
  that does this remaining iotable_init() call into a separate file
  that only gets compiled when that is enabled.

> +void __init sirfsoc_map_io(void)
> +{
> +	iotable_init(sirfsoc_iodesc, ARRAY_SIZE(sirfsoc_iodesc));
> +}
> +
> +#define L2X0_ADDR_FILTERING_START       0xC00
> +#define L2X0_ADDR_FILTERING_END         0xC04
> +
> +static int __init sirfsoc_init(void)
> +{
> +#ifdef CONFIG_CACHE_L2X0
> +	if (!(readl_relaxed(SIRFSOC_L2CC_VA_BASE + L2X0_CTRL) & 1)) {
> +		/*
> +		 * set the physical memory windows L2 cache will cover
> +		 */
> +		writel_relaxed(PHYS_OFFSET + 1024 * 1024 * 1024,
> +			SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_END);
> +		writel_relaxed(PHYS_OFFSET | 0x1,
> +			SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_START);
> +
> +		writel_relaxed(0,
> +			SIRFSOC_L2CC_VA_BASE + L2X0_TAG_LATENCY_CTRL);
> +		writel_relaxed(0,
> +			SIRFSOC_L2CC_VA_BASE + L2X0_DATA_LATENCY_CTRL);
> +	}
> +	l2x0_init((void __iomem *)SIRFSOC_L2CC_VA_BASE, 0x00040000,
> +		0x00000000);
> +#endif
> +
> +	return 0;
> +}
> +arch_initcall(sirfsoc_init);

I would also suggest moving the l2x0 code into a new l2x0.c file that
is conditionally compiled. In the header file, you then do

#ifdef CONFIG_CACHE_L2X0
extern void sirfsoc_l2x0_init(void);
#else
static inline void sirfsoc_l2x0_init(void) {}
#endif

> +#ifndef __ASM_ARCH_IRQS_H
> +#define __ASM_ARCH_IRQS_H
> +
> +#define SIRFSOC_INTENAL_IRQ_START  0
> +#define SIRFSOC_INTENAL_IRQ_END    59

Typo, I assume: INTERNAL, not INTENAL


> +
> +static struct of_device_id intc_ids[]  = {
> +	{ .compatible = "sirf,intc" },
> +	{ .compatible = "sirf,prima2-intc" },
> +};

You should only list one of these in the driver: The idea is that as 
long as all variants of the hardware are identical, you can just list
the most general name (sirf,intc), and if you need to tell the difference
you list the more specific names and add a .data=... member that you
use to differentiate between them. Note that it's usually easier to
change the code than to change the device tree, so we want to have 
the full list in the device tree, but the code just needs to pick
one that fits the purpose.

It's the same for the other drivers.

> +static void __init sirfsoc_of_timer_map(void);

You can remove this forward declaration if you move the sched_clock()
function down.

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-06-29 21:29     ` Arnd Bergmann
@ 2011-06-30  3:39         ` Barry Song
  -1 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-06-30  3:39 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ, Barry Song, Bin Shi,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, Zhiwu Song, Rongjun Ying,
	Binghua Duan, Barry Song, tglx-hfZtesqFncYOwBW4kG4KsQ,
	Yuping Luo, Huayi Li,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi Arnd,
Thanks!

2011/6/30 Arnd Bergmann <arnd@arndb.de>:
> On Tuesday 28 June 2011, Barry Song wrote:
>> This patch adds the basic support for this SoC and EVB board based on device
>> tree. It is following the ZYNQ of Grant Likely in some degree.
>
> Hi Barry,
>
> There are a few more things I noticed this time around, and some comments
> about code that changed since v1.
>
>> the device hierarchy in SiRFprimaII is as below
>>
>> 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
>>
>
> 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.
>
> This also includes using bus-local addresses for the 'reg' properties,
> rather than global addresses.
>
>>  1. clock: use dev_id instead of con_id
>>  2. Kconfig: delete ISA_DMA
>>  3. irq: implement int controller based on DT
>>        move to GENERIC_IRQ_CHIP framework
>>  4. timer: implement timer based on DT
>>  5. entry-macro.S: use get_irqnr_preamble to load the base address only once
>>     per IRQ exception.
>>  6. others:
>>       use readl_relaxed instead of __raw_readl
>>       adjust Kconfig order for PRIMA2
>>       use clk_get_sys instead of clk_get for system level clock
>>       use BUG_ON(IS_ERR(clk)) instead of BUG_ON(IS_ERR_OR_NULL(clk));
>>       fix typo for CLOCK_TICK_RATE
>>       ("sirf,xxx", "sirf,prima2-xxx")  instead of ("sirf,xxx") in dts
>>
>
> Good progress!
>
>> new file mode 100644
>> index 0000000..1777e98
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/prima2-cb.dts
>> @@ -0,0 +1,50 @@
>> +/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 {
>> +             compatible = "simple-bus";
>> +             #address-cells = <1>;
>> +             #size-cells = <1>;
>> +             ranges;
>> +
>> +             intc: interrupt-controller@0x80020000 {
>> +                     interrupt-controller;
>> +                     compatible = "sirf,intc", "sirf,prima2-intc";
>> +                     reg = <0x80020000 0x1000>;
>> +                     #interrupt-cells = <1>;
>> +             };
>
> Some more commends on the device tree properties:
>
> 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@lists.ozlabs.org
> mailing list on Cc, maybe someone can clarify.
>
>> +             timer0: timer@0xb0020000 {
>> +                     compatible = "sirf,tick", "sirf,prima2-tick";
>> +                     reg = <0xb0020000 0x1000>;
>> +                     interrupts = <0>;
>> +             };
>> +
>> +             uart0: uart@0xb0050000 {
>> +                     compatible = "sirf,uart", "sirf,prima2-uart";
>> +                     reg = <0xb0050000 0x1000>;
>> +                     interrupts = <17>;
>> +             };
>> +
>> +             uart1: uart@0xb0060000 {
>> +                     compatible = "sirf,uart", "sirf,prima2-uart";
>> +                     reg = <0xb0060000 0x1000>;
>> +                     interrupts = <18>;
>> +             };
>> +     };
>> +};
>
> When you use local addresses, this would become something like
>
>        axi1 {
>                compatible = "simple-bus";
>                #address-cells = <1>;
>                #size-cells = <1>;
>                ranges <0 0x80000000 0x10000000>;
>
>                intc: interrupt-controller@20000 {
>                        interrupt-controller;
>                        compatible = "sirf,intc", "sirf,prima2-intc";
>                        reg = <0x20000 0x1000>;
>                        #interrupt-cells = <1>;
>                };
>        }
>        axi2 {
>                compatible = "simple-bus";
>                #address-cells = <1>;
>                #size-cells = <1>;
>                ranges <0 0xb0000000 0x10000000>;
>
>                timer0: timer@20000 {
>                        reg = <0x20000 0x1000>;
>                };
>
>                uart0: uart@50000 {
>                        reg = <0x50000 0x1000>;
>                };
>
>                uart1: uart@60000 {
>                        reg = <0x60000 0x1000>;
>                };
>        };
>
>
>
>> +
>> diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
>> new file mode 100644
>> index 0000000..c51d60d
>> --- /dev/null
>> +++ b/arch/arm/mach-prima2/Makefile
>> @@ -0,0 +1 @@
>> +obj-y := timer.o irq.o clock.o common.o board_dt.o
>
> Minor detail:
>
> 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.
>
>> +++ b/arch/arm/mach-prima2/board_dt.c
>> @@ -0,0 +1,28 @@
>> +/*
>> + * This file contains code for boards with device tree support.
>> + *
>> + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
>> + *
>> + * Licensed under GPLv2 or later.
>> + */
>> +
>> +#include <linux/of.h>
>> +#include <asm/mach/arch.h>
>> +#include <asm/mach-types.h>
>> +#include <mach/hardware.h>
>> +#include "common.h"
>> +
>> +static const char *prima2cb_dt_match[] __initdata = {
>> +       "sirf,prima2-cb",
>> +       NULL
>> +};
>> +
>> +MACHINE_START(PRIMA2_EVB, "prima2cb")
>> +       .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      = prima2cb_dt_match,
>> +MACHINE_END
>
> How about removing the remaining board file entirely and merging the contents into
> common.c? We don't want to have board specific files any more, so the naming
> and the split is rather obsolete.

that could be. but i am not sure whether grant built this single file
to contain multi-board defines?

>
> 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.
>
>> +#define IOTABLE_ENTRY(region) {\
>> +     .virtual        = SIRFSOC_##region##_VA_BASE, \
>> +     .pfn            = __phys_to_pfn(SIRFSOC_##region##_PA_BASE),\
>> +     .length         = SIRFSOC_##region##_SIZE, \
>> +     .type           = MT_DEVICE, \
>> +}
>> +
>> +static struct map_desc sirfsoc_iodesc[] __initdata = {
>> +     IOTABLE_ENTRY(UART1),
>> +     IOTABLE_ENTRY(CLOCK),
>> +     IOTABLE_ENTRY(RSTC),
>> +#ifdef CONFIG_CACHE_L2X0
>> +     IOTABLE_ENTRY(L2CC),
>> +#endif
>> +};
>
> I've thought about this some more, and I think you can get rid of most
> entries in the global table after all:
>
> * sirfsoc_init_clk() can get the physical address from the device tree
> and call iotable_init for just one entry.
>
> * RSTC does not seem to be needed early at all, you can simply ioremap it.
>
> * L2CC is only accessed from an arch_initcall, which is late enough
>  for ioremap.
>
> * UART1 is only needed for early printk, so I would put the function
>  that does this remaining iotable_init() call into a separate file
>  that only gets compiled when that is enabled.
>
>> +void __init sirfsoc_map_io(void)
>> +{
>> +     iotable_init(sirfsoc_iodesc, ARRAY_SIZE(sirfsoc_iodesc));
>> +}
>> +
>> +#define L2X0_ADDR_FILTERING_START       0xC00
>> +#define L2X0_ADDR_FILTERING_END         0xC04
>> +
>> +static int __init sirfsoc_init(void)
>> +{
>> +#ifdef CONFIG_CACHE_L2X0
>> +     if (!(readl_relaxed(SIRFSOC_L2CC_VA_BASE + L2X0_CTRL) & 1)) {
>> +             /*
>> +              * set the physical memory windows L2 cache will cover
>> +              */
>> +             writel_relaxed(PHYS_OFFSET + 1024 * 1024 * 1024,
>> +                     SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_END);
>> +             writel_relaxed(PHYS_OFFSET | 0x1,
>> +                     SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_START);
>> +
>> +             writel_relaxed(0,
>> +                     SIRFSOC_L2CC_VA_BASE + L2X0_TAG_LATENCY_CTRL);
>> +             writel_relaxed(0,
>> +                     SIRFSOC_L2CC_VA_BASE + L2X0_DATA_LATENCY_CTRL);
>> +     }
>> +     l2x0_init((void __iomem *)SIRFSOC_L2CC_VA_BASE, 0x00040000,
>> +             0x00000000);
>> +#endif
>> +
>> +     return 0;
>> +}
>> +arch_initcall(sirfsoc_init);
>
> I would also suggest moving the l2x0 code into a new l2x0.c file that
> is conditionally compiled. In the header file, you then do
>
> #ifdef CONFIG_CACHE_L2X0
> extern void sirfsoc_l2x0_init(void);
> #else
> static inline void sirfsoc_l2x0_init(void) {}
> #endif
>
>> +#ifndef __ASM_ARCH_IRQS_H
>> +#define __ASM_ARCH_IRQS_H
>> +
>> +#define SIRFSOC_INTENAL_IRQ_START  0
>> +#define SIRFSOC_INTENAL_IRQ_END    59
>
> Typo, I assume: INTERNAL, not INTENAL
>
>
>> +
>> +static struct of_device_id intc_ids[]  = {
>> +     { .compatible = "sirf,intc" },
>> +     { .compatible = "sirf,prima2-intc" },
>> +};
>
> You should only list one of these in the driver: The idea is that as
> long as all variants of the hardware are identical, you can just list
> the most general name (sirf,intc), and if you need to tell the difference
> you list the more specific names and add a .data=... member that you
> use to differentiate between them. Note that it's usually easier to
> change the code than to change the device tree, so we want to have
> the full list in the device tree, but the code just needs to pick
> one that fits the purpose.
>
> It's the same for the other drivers.
>
>> +static void __init sirfsoc_of_timer_map(void);
>
> You can remove this forward declaration if you move the sched_clock()
> function down.
>
>        Arnd
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
>



-- 
Barry Song, Linux Kernel Developer
http://21cnbao.blog.51cto.com
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-06-30  3:39         ` Barry Song
  0 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-06-30  3:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,
Thanks!

2011/6/30 Arnd Bergmann <arnd@arndb.de>:
> On Tuesday 28 June 2011, Barry Song wrote:
>> This patch adds the basic support for this SoC and EVB board based on device
>> tree. It is following the ZYNQ of Grant Likely in some degree.
>
> Hi Barry,
>
> There are a few more things I noticed this time around, and some comments
> about code that changed since v1.
>
>> the device hierarchy in SiRFprimaII is as below
>>
>> 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
>>
>
> 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.
>
> This also includes using bus-local addresses for the 'reg' properties,
> rather than global addresses.
>
>> ?1. clock: use dev_id instead of con_id
>> ?2. Kconfig: delete ISA_DMA
>> ?3. irq: implement int controller based on DT
>> ? ? ? ?move to GENERIC_IRQ_CHIP framework
>> ?4. timer: implement timer based on DT
>> ?5. entry-macro.S: use get_irqnr_preamble to load the base address only once
>> ? ? per IRQ exception.
>> ?6. others:
>> ? ? ? use readl_relaxed instead of __raw_readl
>> ? ? ? adjust Kconfig order for PRIMA2
>> ? ? ? use clk_get_sys instead of clk_get for system level clock
>> ? ? ? use BUG_ON(IS_ERR(clk)) instead of BUG_ON(IS_ERR_OR_NULL(clk));
>> ? ? ? fix typo for CLOCK_TICK_RATE
>> ? ? ? ("sirf,xxx", "sirf,prima2-xxx") ?instead of ("sirf,xxx") in dts
>>
>
> Good progress!
>
>> new file mode 100644
>> index 0000000..1777e98
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/prima2-cb.dts
>> @@ -0,0 +1,50 @@
>> +/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 {
>> + ? ? ? ? ? ? compatible = "simple-bus";
>> + ? ? ? ? ? ? #address-cells = <1>;
>> + ? ? ? ? ? ? #size-cells = <1>;
>> + ? ? ? ? ? ? ranges;
>> +
>> + ? ? ? ? ? ? intc: interrupt-controller at 0x80020000 {
>> + ? ? ? ? ? ? ? ? ? ? interrupt-controller;
>> + ? ? ? ? ? ? ? ? ? ? compatible = "sirf,intc", "sirf,prima2-intc";
>> + ? ? ? ? ? ? ? ? ? ? reg = <0x80020000 0x1000>;
>> + ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>;
>> + ? ? ? ? ? ? };
>
> Some more commends on the device tree properties:
>
> 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.
>
>> + ? ? ? ? ? ? timer0: timer at 0xb0020000 {
>> + ? ? ? ? ? ? ? ? ? ? compatible = "sirf,tick", "sirf,prima2-tick";
>> + ? ? ? ? ? ? ? ? ? ? reg = <0xb0020000 0x1000>;
>> + ? ? ? ? ? ? ? ? ? ? interrupts = <0>;
>> + ? ? ? ? ? ? };
>> +
>> + ? ? ? ? ? ? uart0: uart at 0xb0050000 {
>> + ? ? ? ? ? ? ? ? ? ? compatible = "sirf,uart", "sirf,prima2-uart";
>> + ? ? ? ? ? ? ? ? ? ? reg = <0xb0050000 0x1000>;
>> + ? ? ? ? ? ? ? ? ? ? interrupts = <17>;
>> + ? ? ? ? ? ? };
>> +
>> + ? ? ? ? ? ? uart1: uart at 0xb0060000 {
>> + ? ? ? ? ? ? ? ? ? ? compatible = "sirf,uart", "sirf,prima2-uart";
>> + ? ? ? ? ? ? ? ? ? ? reg = <0xb0060000 0x1000>;
>> + ? ? ? ? ? ? ? ? ? ? interrupts = <18>;
>> + ? ? ? ? ? ? };
>> + ? ? };
>> +};
>
> When you use local addresses, this would become something like
>
> ? ? ? ?axi1 {
> ? ? ? ? ? ? ? ?compatible = "simple-bus";
> ? ? ? ? ? ? ? ?#address-cells = <1>;
> ? ? ? ? ? ? ? ?#size-cells = <1>;
> ? ? ? ? ? ? ? ?ranges <0 0x80000000 0x10000000>;
>
> ? ? ? ? ? ? ? ?intc: interrupt-controller at 20000 {
> ? ? ? ? ? ? ? ? ? ? ? ?interrupt-controller;
> ? ? ? ? ? ? ? ? ? ? ? ?compatible = "sirf,intc", "sirf,prima2-intc";
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0x20000 0x1000>;
> ? ? ? ? ? ? ? ? ? ? ? ?#interrupt-cells = <1>;
> ? ? ? ? ? ? ? ?};
> ? ? ? ?}
> ? ? ? ?axi2 {
> ? ? ? ? ? ? ? ?compatible = "simple-bus";
> ? ? ? ? ? ? ? ?#address-cells = <1>;
> ? ? ? ? ? ? ? ?#size-cells = <1>;
> ? ? ? ? ? ? ? ?ranges <0 0xb0000000 0x10000000>;
>
> ? ? ? ? ? ? ? ?timer0: timer at 20000 {
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0x20000 0x1000>;
> ? ? ? ? ? ? ? ?};
>
> ? ? ? ? ? ? ? ?uart0: uart at 50000 {
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0x50000 0x1000>;
> ? ? ? ? ? ? ? ?};
>
> ? ? ? ? ? ? ? ?uart1: uart at 60000 {
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0x60000 0x1000>;
> ? ? ? ? ? ? ? ?};
> ? ? ? ?};
>
>
>
>> +
>> diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
>> new file mode 100644
>> index 0000000..c51d60d
>> --- /dev/null
>> +++ b/arch/arm/mach-prima2/Makefile
>> @@ -0,0 +1 @@
>> +obj-y := timer.o irq.o clock.o common.o board_dt.o
>
> Minor detail:
>
> 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.
>
>> +++ b/arch/arm/mach-prima2/board_dt.c
>> @@ -0,0 +1,28 @@
>> +/*
>> + * This file contains code for boards with device tree support.
>> + *
>> + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
>> + *
>> + * Licensed under GPLv2 or later.
>> + */
>> +
>> +#include <linux/of.h>
>> +#include <asm/mach/arch.h>
>> +#include <asm/mach-types.h>
>> +#include <mach/hardware.h>
>> +#include "common.h"
>> +
>> +static const char *prima2cb_dt_match[] __initdata = {
>> + ? ? ? "sirf,prima2-cb",
>> + ? ? ? NULL
>> +};
>> +
>> +MACHINE_START(PRIMA2_EVB, "prima2cb")
>> + ? ? ? .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 ? ? ?= prima2cb_dt_match,
>> +MACHINE_END
>
> How about removing the remaining board file entirely and merging the contents into
> common.c? We don't want to have board specific files any more, so the naming
> and the split is rather obsolete.

that could be. but i am not sure whether grant built this single file
to contain multi-board defines?

>
> 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.
>
>> +#define IOTABLE_ENTRY(region) {\
>> + ? ? .virtual ? ? ? ?= SIRFSOC_##region##_VA_BASE, \
>> + ? ? .pfn ? ? ? ? ? ?= __phys_to_pfn(SIRFSOC_##region##_PA_BASE),\
>> + ? ? .length ? ? ? ? = SIRFSOC_##region##_SIZE, \
>> + ? ? .type ? ? ? ? ? = MT_DEVICE, \
>> +}
>> +
>> +static struct map_desc sirfsoc_iodesc[] __initdata = {
>> + ? ? IOTABLE_ENTRY(UART1),
>> + ? ? IOTABLE_ENTRY(CLOCK),
>> + ? ? IOTABLE_ENTRY(RSTC),
>> +#ifdef CONFIG_CACHE_L2X0
>> + ? ? IOTABLE_ENTRY(L2CC),
>> +#endif
>> +};
>
> I've thought about this some more, and I think you can get rid of most
> entries in the global table after all:
>
> * sirfsoc_init_clk() can get the physical address from the device tree
> and call iotable_init for just one entry.
>
> * RSTC does not seem to be needed early at all, you can simply ioremap it.
>
> * L2CC is only accessed from an arch_initcall, which is late enough
> ?for ioremap.
>
> * UART1 is only needed for early printk, so I would put the function
> ?that does this remaining iotable_init() call into a separate file
> ?that only gets compiled when that is enabled.
>
>> +void __init sirfsoc_map_io(void)
>> +{
>> + ? ? iotable_init(sirfsoc_iodesc, ARRAY_SIZE(sirfsoc_iodesc));
>> +}
>> +
>> +#define L2X0_ADDR_FILTERING_START ? ? ? 0xC00
>> +#define L2X0_ADDR_FILTERING_END ? ? ? ? 0xC04
>> +
>> +static int __init sirfsoc_init(void)
>> +{
>> +#ifdef CONFIG_CACHE_L2X0
>> + ? ? if (!(readl_relaxed(SIRFSOC_L2CC_VA_BASE + L2X0_CTRL) & 1)) {
>> + ? ? ? ? ? ? /*
>> + ? ? ? ? ? ? ?* set the physical memory windows L2 cache will cover
>> + ? ? ? ? ? ? ?*/
>> + ? ? ? ? ? ? writel_relaxed(PHYS_OFFSET + 1024 * 1024 * 1024,
>> + ? ? ? ? ? ? ? ? ? ? SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_END);
>> + ? ? ? ? ? ? writel_relaxed(PHYS_OFFSET | 0x1,
>> + ? ? ? ? ? ? ? ? ? ? SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_START);
>> +
>> + ? ? ? ? ? ? writel_relaxed(0,
>> + ? ? ? ? ? ? ? ? ? ? SIRFSOC_L2CC_VA_BASE + L2X0_TAG_LATENCY_CTRL);
>> + ? ? ? ? ? ? writel_relaxed(0,
>> + ? ? ? ? ? ? ? ? ? ? SIRFSOC_L2CC_VA_BASE + L2X0_DATA_LATENCY_CTRL);
>> + ? ? }
>> + ? ? l2x0_init((void __iomem *)SIRFSOC_L2CC_VA_BASE, 0x00040000,
>> + ? ? ? ? ? ? 0x00000000);
>> +#endif
>> +
>> + ? ? return 0;
>> +}
>> +arch_initcall(sirfsoc_init);
>
> I would also suggest moving the l2x0 code into a new l2x0.c file that
> is conditionally compiled. In the header file, you then do
>
> #ifdef CONFIG_CACHE_L2X0
> extern void sirfsoc_l2x0_init(void);
> #else
> static inline void sirfsoc_l2x0_init(void) {}
> #endif
>
>> +#ifndef __ASM_ARCH_IRQS_H
>> +#define __ASM_ARCH_IRQS_H
>> +
>> +#define SIRFSOC_INTENAL_IRQ_START ?0
>> +#define SIRFSOC_INTENAL_IRQ_END ? ?59
>
> Typo, I assume: INTERNAL, not INTENAL
>
>
>> +
>> +static struct of_device_id intc_ids[] ?= {
>> + ? ? { .compatible = "sirf,intc" },
>> + ? ? { .compatible = "sirf,prima2-intc" },
>> +};
>
> You should only list one of these in the driver: The idea is that as
> long as all variants of the hardware are identical, you can just list
> the most general name (sirf,intc), and if you need to tell the difference
> you list the more specific names and add a .data=... member that you
> use to differentiate between them. Note that it's usually easier to
> change the code than to change the device tree, so we want to have
> the full list in the device tree, but the code just needs to pick
> one that fits the purpose.
>
> It's the same for the other drivers.
>
>> +static void __init sirfsoc_of_timer_map(void);
>
> You can remove this forward declaration if you move the sched_clock()
> function down.
>
> ? ? ? ?Arnd
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
>



-- 
Barry Song, Linux Kernel Developer
http://21cnbao.blog.51cto.com

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-06-29 21:29     ` Arnd Bergmann
@ 2011-06-30  7:19       ` Barry Song
  -1 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-06-30  7:19 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux, devicetree-discuss, workgroup.linux, Grant Likely,
	weizeng.he, tglx, linux-arm-kernel

Hi Arnd,
Thanks.

2011/6/30 Arnd Bergmann <arnd@arndb.de>:
> On Tuesday 28 June 2011, Barry Song wrote:
>> This patch adds the basic support for this SoC and EVB board based on device
>> tree. It is following the ZYNQ of Grant Likely in some degree.
>
> Hi Barry,
>
> There are a few more things I noticed this time around, and some comments
> about code that changed since v1.
>
>> the device hierarchy in SiRFprimaII is as below
>>
>> 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
>>
>
> 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 :-)

>
> This also includes using bus-local addresses for the 'reg' properties,
> rather than global addresses.
>
>>  1. clock: use dev_id instead of con_id
>>  2. Kconfig: delete ISA_DMA
>>  3. irq: implement int controller based on DT
>>        move to GENERIC_IRQ_CHIP framework
>>  4. timer: implement timer based on DT
>>  5. entry-macro.S: use get_irqnr_preamble to load the base address only once
>>     per IRQ exception.
>>  6. others:
>>       use readl_relaxed instead of __raw_readl
>>       adjust Kconfig order for PRIMA2
>>       use clk_get_sys instead of clk_get for system level clock
>>       use BUG_ON(IS_ERR(clk)) instead of BUG_ON(IS_ERR_OR_NULL(clk));
>>       fix typo for CLOCK_TICK_RATE
>>       ("sirf,xxx", "sirf,prima2-xxx")  instead of ("sirf,xxx") in dts
>>
>
> Good progress!
>
>> new file mode 100644
>> index 0000000..1777e98
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/prima2-cb.dts
>> @@ -0,0 +1,50 @@
>> +/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 {
>> +             compatible = "simple-bus";
>> +             #address-cells = <1>;
>> +             #size-cells = <1>;
>> +             ranges;
>> +
>> +             intc: interrupt-controller@0x80020000 {
>> +                     interrupt-controller;
>> +                     compatible = "sirf,intc", "sirf,prima2-intc";
>> +                     reg = <0x80020000 0x1000>;
>> +                     #interrupt-cells = <1>;
>> +             };
>
> Some more commends on the device tree properties:
>
> 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@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"?

>
>> +             timer0: timer@0xb0020000 {
>> +                     compatible = "sirf,tick", "sirf,prima2-tick";
>> +                     reg = <0xb0020000 0x1000>;
>> +                     interrupts = <0>;
>> +             };
>> +
>> +             uart0: uart@0xb0050000 {
>> +                     compatible = "sirf,uart", "sirf,prima2-uart";
>> +                     reg = <0xb0050000 0x1000>;
>> +                     interrupts = <17>;
>> +             };
>> +
>> +             uart1: uart@0xb0060000 {
>> +                     compatible = "sirf,uart", "sirf,prima2-uart";
>> +                     reg = <0xb0060000 0x1000>;
>> +                     interrupts = <18>;
>> +             };
>> +     };
>> +};
>
> When you use local addresses, this would become something like
>
>        axi1 {
>                compatible = "simple-bus";
>                #address-cells = <1>;
>                #size-cells = <1>;
>                ranges <0 0x80000000 0x10000000>;
>
>                intc: interrupt-controller@20000 {
>                        interrupt-controller;
>                        compatible = "sirf,intc", "sirf,prima2-intc";
>                        reg = <0x20000 0x1000>;
>                        #interrupt-cells = <1>;
>                };
>        }
>        axi2 {
>                compatible = "simple-bus";
>                #address-cells = <1>;
>                #size-cells = <1>;
>                ranges <0 0xb0000000 0x10000000>;
>
>                timer0: timer@20000 {
>                        reg = <0x20000 0x1000>;
>                };
>
>                uart0: uart@50000 {
>                        reg = <0x50000 0x1000>;
>                };
>
>                uart1: uart@60000 {
>                        reg = <0x60000 0x1000>;
>                };
>        };
>

Ok. i will send the full DT in patch v3.

>
>
>> +
>> diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
>> new file mode 100644
>> index 0000000..c51d60d
>> --- /dev/null
>> +++ b/arch/arm/mach-prima2/Makefile
>> @@ -0,0 +1 @@
>> +obj-y := timer.o irq.o clock.o common.o board_dt.o
>
> Minor detail:
>
> 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

>
>> +++ b/arch/arm/mach-prima2/board_dt.c
>> @@ -0,0 +1,28 @@
>> +/*
>> + * This file contains code for boards with device tree support.
>> + *
>> + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
>> + *
>> + * Licensed under GPLv2 or later.
>> + */
>> +
>> +#include <linux/of.h>
>> +#include <asm/mach/arch.h>
>> +#include <asm/mach-types.h>
>> +#include <mach/hardware.h>
>> +#include "common.h"
>> +
>> +static const char *prima2cb_dt_match[] __initdata = {
>> +       "sirf,prima2-cb",
>> +       NULL
>> +};
>> +
>> +MACHINE_START(PRIMA2_EVB, "prima2cb")
>> +       .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      = prima2cb_dt_match,
>> +MACHINE_END
>
> How about removing the remaining board file entirely and merging the contents into
> common.c? We don't want to have board specific files any more, so the naming
> and the split is rather obsolete.
>
> 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

MACHINE_START(PRIMA2_ZZZ, "prima2zzz)
       .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      = prima2zzz_dt_match,
MACHINE_END

>
>> +#define IOTABLE_ENTRY(region) {\
>> +     .virtual        = SIRFSOC_##region##_VA_BASE, \
>> +     .pfn            = __phys_to_pfn(SIRFSOC_##region##_PA_BASE),\
>> +     .length         = SIRFSOC_##region##_SIZE, \
>> +     .type           = MT_DEVICE, \
>> +}
>> +
>> +static struct map_desc sirfsoc_iodesc[] __initdata = {
>> +     IOTABLE_ENTRY(UART1),
>> +     IOTABLE_ENTRY(CLOCK),
>> +     IOTABLE_ENTRY(RSTC),
>> +#ifdef CONFIG_CACHE_L2X0
>> +     IOTABLE_ENTRY(L2CC),
>> +#endif
>> +};
>
> I've thought about this some more, and I think you can get rid of most
> entries in the global table after all:
>
> * sirfsoc_init_clk() can get the physical address from the device tree
> and call iotable_init for just one entry.

Ok.
>
> * RSTC does not seem to be needed early at all, you can simply ioremap it.
>
Ok.

> * L2CC is only accessed from an arch_initcall, which is late enough
>  for ioremap.
>
> * UART1 is only needed for early printk, so I would put the function
>  that does this remaining iotable_init() call into a separate file
>  that only gets compiled when that is enabled.
>
>> +void __init sirfsoc_map_io(void)
>> +{
>> +     iotable_init(sirfsoc_iodesc, ARRAY_SIZE(sirfsoc_iodesc));
>> +}
>> +
>> +#define L2X0_ADDR_FILTERING_START       0xC00
>> +#define L2X0_ADDR_FILTERING_END         0xC04
>> +
>> +static int __init sirfsoc_init(void)
>> +{
>> +#ifdef CONFIG_CACHE_L2X0
>> +     if (!(readl_relaxed(SIRFSOC_L2CC_VA_BASE + L2X0_CTRL) & 1)) {
>> +             /*
>> +              * set the physical memory windows L2 cache will cover
>> +              */
>> +             writel_relaxed(PHYS_OFFSET + 1024 * 1024 * 1024,
>> +                     SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_END);
>> +             writel_relaxed(PHYS_OFFSET | 0x1,
>> +                     SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_START);
>> +
>> +             writel_relaxed(0,
>> +                     SIRFSOC_L2CC_VA_BASE + L2X0_TAG_LATENCY_CTRL);
>> +             writel_relaxed(0,
>> +                     SIRFSOC_L2CC_VA_BASE + L2X0_DATA_LATENCY_CTRL);
>> +     }
>> +     l2x0_init((void __iomem *)SIRFSOC_L2CC_VA_BASE, 0x00040000,
>> +             0x00000000);
>> +#endif
>> +
>> +     return 0;
>> +}
>> +arch_initcall(sirfsoc_init);
>
> I would also suggest moving the l2x0 code into a new l2x0.c file that
> is conditionally compiled. In the header file, you then do
>
> #ifdef CONFIG_CACHE_L2X0
> extern void sirfsoc_l2x0_init(void);
> #else
> static inline void sirfsoc_l2x0_init(void) {}
> #endif

yes.

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.

>
>> +#ifndef __ASM_ARCH_IRQS_H
>> +#define __ASM_ARCH_IRQS_H
>> +
>> +#define SIRFSOC_INTENAL_IRQ_START  0
>> +#define SIRFSOC_INTENAL_IRQ_END    59
>
> Typo, I assume: INTERNAL, not INTENAL

Yes.

>
>
>> +
>> +static struct of_device_id intc_ids[]  = {
>> +     { .compatible = "sirf,intc" },
>> +     { .compatible = "sirf,prima2-intc" },
>> +};
>
> You should only list one of these in the driver: The idea is that as
> long as all variants of the hardware are identical, you can just list
> the most general name (sirf,intc), and if you need to tell the difference
> you list the more specific names and add a .data=... member that you
> use to differentiate between them. Note that it's usually easier to
> change the code than to change the device tree, so we want to have
> the full list in the device tree, but the code just needs to pick
> one that fits the purpose.

Ok.

>
> It's the same for the other drivers.
>
>> +static void __init sirfsoc_of_timer_map(void);
>
> You can remove this forward declaration if you move the sched_clock()
> function down.

Ok

>
>        Arnd
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-06-30  7:19       ` Barry Song
  0 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-06-30  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,
Thanks.

2011/6/30 Arnd Bergmann <arnd@arndb.de>:
> On Tuesday 28 June 2011, Barry Song wrote:
>> This patch adds the basic support for this SoC and EVB board based on device
>> tree. It is following the ZYNQ of Grant Likely in some degree.
>
> Hi Barry,
>
> There are a few more things I noticed this time around, and some comments
> about code that changed since v1.
>
>> the device hierarchy in SiRFprimaII is as below
>>
>> 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
>>
>
> 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 :-)

>
> This also includes using bus-local addresses for the 'reg' properties,
> rather than global addresses.
>
>> ?1. clock: use dev_id instead of con_id
>> ?2. Kconfig: delete ISA_DMA
>> ?3. irq: implement int controller based on DT
>> ? ? ? ?move to GENERIC_IRQ_CHIP framework
>> ?4. timer: implement timer based on DT
>> ?5. entry-macro.S: use get_irqnr_preamble to load the base address only once
>> ? ? per IRQ exception.
>> ?6. others:
>> ? ? ? use readl_relaxed instead of __raw_readl
>> ? ? ? adjust Kconfig order for PRIMA2
>> ? ? ? use clk_get_sys instead of clk_get for system level clock
>> ? ? ? use BUG_ON(IS_ERR(clk)) instead of BUG_ON(IS_ERR_OR_NULL(clk));
>> ? ? ? fix typo for CLOCK_TICK_RATE
>> ? ? ? ("sirf,xxx", "sirf,prima2-xxx") ?instead of ("sirf,xxx") in dts
>>
>
> Good progress!
>
>> new file mode 100644
>> index 0000000..1777e98
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/prima2-cb.dts
>> @@ -0,0 +1,50 @@
>> +/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 {
>> + ? ? ? ? ? ? compatible = "simple-bus";
>> + ? ? ? ? ? ? #address-cells = <1>;
>> + ? ? ? ? ? ? #size-cells = <1>;
>> + ? ? ? ? ? ? ranges;
>> +
>> + ? ? ? ? ? ? intc: interrupt-controller at 0x80020000 {
>> + ? ? ? ? ? ? ? ? ? ? interrupt-controller;
>> + ? ? ? ? ? ? ? ? ? ? compatible = "sirf,intc", "sirf,prima2-intc";
>> + ? ? ? ? ? ? ? ? ? ? reg = <0x80020000 0x1000>;
>> + ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>;
>> + ? ? ? ? ? ? };
>
> Some more commends on the device tree properties:
>
> 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"?

>
>> + ? ? ? ? ? ? timer0: timer at 0xb0020000 {
>> + ? ? ? ? ? ? ? ? ? ? compatible = "sirf,tick", "sirf,prima2-tick";
>> + ? ? ? ? ? ? ? ? ? ? reg = <0xb0020000 0x1000>;
>> + ? ? ? ? ? ? ? ? ? ? interrupts = <0>;
>> + ? ? ? ? ? ? };
>> +
>> + ? ? ? ? ? ? uart0: uart at 0xb0050000 {
>> + ? ? ? ? ? ? ? ? ? ? compatible = "sirf,uart", "sirf,prima2-uart";
>> + ? ? ? ? ? ? ? ? ? ? reg = <0xb0050000 0x1000>;
>> + ? ? ? ? ? ? ? ? ? ? interrupts = <17>;
>> + ? ? ? ? ? ? };
>> +
>> + ? ? ? ? ? ? uart1: uart at 0xb0060000 {
>> + ? ? ? ? ? ? ? ? ? ? compatible = "sirf,uart", "sirf,prima2-uart";
>> + ? ? ? ? ? ? ? ? ? ? reg = <0xb0060000 0x1000>;
>> + ? ? ? ? ? ? ? ? ? ? interrupts = <18>;
>> + ? ? ? ? ? ? };
>> + ? ? };
>> +};
>
> When you use local addresses, this would become something like
>
> ? ? ? ?axi1 {
> ? ? ? ? ? ? ? ?compatible = "simple-bus";
> ? ? ? ? ? ? ? ?#address-cells = <1>;
> ? ? ? ? ? ? ? ?#size-cells = <1>;
> ? ? ? ? ? ? ? ?ranges <0 0x80000000 0x10000000>;
>
> ? ? ? ? ? ? ? ?intc: interrupt-controller at 20000 {
> ? ? ? ? ? ? ? ? ? ? ? ?interrupt-controller;
> ? ? ? ? ? ? ? ? ? ? ? ?compatible = "sirf,intc", "sirf,prima2-intc";
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0x20000 0x1000>;
> ? ? ? ? ? ? ? ? ? ? ? ?#interrupt-cells = <1>;
> ? ? ? ? ? ? ? ?};
> ? ? ? ?}
> ? ? ? ?axi2 {
> ? ? ? ? ? ? ? ?compatible = "simple-bus";
> ? ? ? ? ? ? ? ?#address-cells = <1>;
> ? ? ? ? ? ? ? ?#size-cells = <1>;
> ? ? ? ? ? ? ? ?ranges <0 0xb0000000 0x10000000>;
>
> ? ? ? ? ? ? ? ?timer0: timer at 20000 {
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0x20000 0x1000>;
> ? ? ? ? ? ? ? ?};
>
> ? ? ? ? ? ? ? ?uart0: uart at 50000 {
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0x50000 0x1000>;
> ? ? ? ? ? ? ? ?};
>
> ? ? ? ? ? ? ? ?uart1: uart at 60000 {
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0x60000 0x1000>;
> ? ? ? ? ? ? ? ?};
> ? ? ? ?};
>

Ok. i will send the full DT in patch v3.

>
>
>> +
>> diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
>> new file mode 100644
>> index 0000000..c51d60d
>> --- /dev/null
>> +++ b/arch/arm/mach-prima2/Makefile
>> @@ -0,0 +1 @@
>> +obj-y := timer.o irq.o clock.o common.o board_dt.o
>
> Minor detail:
>
> 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

>
>> +++ b/arch/arm/mach-prima2/board_dt.c
>> @@ -0,0 +1,28 @@
>> +/*
>> + * This file contains code for boards with device tree support.
>> + *
>> + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
>> + *
>> + * Licensed under GPLv2 or later.
>> + */
>> +
>> +#include <linux/of.h>
>> +#include <asm/mach/arch.h>
>> +#include <asm/mach-types.h>
>> +#include <mach/hardware.h>
>> +#include "common.h"
>> +
>> +static const char *prima2cb_dt_match[] __initdata = {
>> + ? ? ? "sirf,prima2-cb",
>> + ? ? ? NULL
>> +};
>> +
>> +MACHINE_START(PRIMA2_EVB, "prima2cb")
>> + ? ? ? .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 ? ? ?= prima2cb_dt_match,
>> +MACHINE_END
>
> How about removing the remaining board file entirely and merging the contents into
> common.c? We don't want to have board specific files any more, so the naming
> and the split is rather obsolete.
>
> 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

MACHINE_START(PRIMA2_ZZZ, "prima2zzz)
       .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      = prima2zzz_dt_match,
MACHINE_END

>
>> +#define IOTABLE_ENTRY(region) {\
>> + ? ? .virtual ? ? ? ?= SIRFSOC_##region##_VA_BASE, \
>> + ? ? .pfn ? ? ? ? ? ?= __phys_to_pfn(SIRFSOC_##region##_PA_BASE),\
>> + ? ? .length ? ? ? ? = SIRFSOC_##region##_SIZE, \
>> + ? ? .type ? ? ? ? ? = MT_DEVICE, \
>> +}
>> +
>> +static struct map_desc sirfsoc_iodesc[] __initdata = {
>> + ? ? IOTABLE_ENTRY(UART1),
>> + ? ? IOTABLE_ENTRY(CLOCK),
>> + ? ? IOTABLE_ENTRY(RSTC),
>> +#ifdef CONFIG_CACHE_L2X0
>> + ? ? IOTABLE_ENTRY(L2CC),
>> +#endif
>> +};
>
> I've thought about this some more, and I think you can get rid of most
> entries in the global table after all:
>
> * sirfsoc_init_clk() can get the physical address from the device tree
> and call iotable_init for just one entry.

Ok.
>
> * RSTC does not seem to be needed early at all, you can simply ioremap it.
>
Ok.

> * L2CC is only accessed from an arch_initcall, which is late enough
> ?for ioremap.
>
> * UART1 is only needed for early printk, so I would put the function
> ?that does this remaining iotable_init() call into a separate file
> ?that only gets compiled when that is enabled.
>
>> +void __init sirfsoc_map_io(void)
>> +{
>> + ? ? iotable_init(sirfsoc_iodesc, ARRAY_SIZE(sirfsoc_iodesc));
>> +}
>> +
>> +#define L2X0_ADDR_FILTERING_START ? ? ? 0xC00
>> +#define L2X0_ADDR_FILTERING_END ? ? ? ? 0xC04
>> +
>> +static int __init sirfsoc_init(void)
>> +{
>> +#ifdef CONFIG_CACHE_L2X0
>> + ? ? if (!(readl_relaxed(SIRFSOC_L2CC_VA_BASE + L2X0_CTRL) & 1)) {
>> + ? ? ? ? ? ? /*
>> + ? ? ? ? ? ? ?* set the physical memory windows L2 cache will cover
>> + ? ? ? ? ? ? ?*/
>> + ? ? ? ? ? ? writel_relaxed(PHYS_OFFSET + 1024 * 1024 * 1024,
>> + ? ? ? ? ? ? ? ? ? ? SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_END);
>> + ? ? ? ? ? ? writel_relaxed(PHYS_OFFSET | 0x1,
>> + ? ? ? ? ? ? ? ? ? ? SIRFSOC_L2CC_VA_BASE + L2X0_ADDR_FILTERING_START);
>> +
>> + ? ? ? ? ? ? writel_relaxed(0,
>> + ? ? ? ? ? ? ? ? ? ? SIRFSOC_L2CC_VA_BASE + L2X0_TAG_LATENCY_CTRL);
>> + ? ? ? ? ? ? writel_relaxed(0,
>> + ? ? ? ? ? ? ? ? ? ? SIRFSOC_L2CC_VA_BASE + L2X0_DATA_LATENCY_CTRL);
>> + ? ? }
>> + ? ? l2x0_init((void __iomem *)SIRFSOC_L2CC_VA_BASE, 0x00040000,
>> + ? ? ? ? ? ? 0x00000000);
>> +#endif
>> +
>> + ? ? return 0;
>> +}
>> +arch_initcall(sirfsoc_init);
>
> I would also suggest moving the l2x0 code into a new l2x0.c file that
> is conditionally compiled. In the header file, you then do
>
> #ifdef CONFIG_CACHE_L2X0
> extern void sirfsoc_l2x0_init(void);
> #else
> static inline void sirfsoc_l2x0_init(void) {}
> #endif

yes.

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.

>
>> +#ifndef __ASM_ARCH_IRQS_H
>> +#define __ASM_ARCH_IRQS_H
>> +
>> +#define SIRFSOC_INTENAL_IRQ_START ?0
>> +#define SIRFSOC_INTENAL_IRQ_END ? ?59
>
> Typo, I assume: INTERNAL, not INTENAL

Yes.

>
>
>> +
>> +static struct of_device_id intc_ids[] ?= {
>> + ? ? { .compatible = "sirf,intc" },
>> + ? ? { .compatible = "sirf,prima2-intc" },
>> +};
>
> You should only list one of these in the driver: The idea is that as
> long as all variants of the hardware are identical, you can just list
> the most general name (sirf,intc), and if you need to tell the difference
> you list the more specific names and add a .data=... member that you
> use to differentiate between them. Note that it's usually easier to
> change the code than to change the device tree, so we want to have
> the full list in the device tree, but the code just needs to pick
> one that fits the purpose.

Ok.

>
> It's the same for the other drivers.
>
>> +static void __init sirfsoc_of_timer_map(void);
>
> You can remove this forward declaration if you move the sched_clock()
> function down.

Ok

>
> ? ? ? ?Arnd
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-06-30  7:19       ` Barry Song
@ 2011-06-30 10:36           ` Arnd Bergmann
  -1 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-06-30 10:36 UTC (permalink / raw)
  To: Barry Song, Rob Herring, Olof Johansson
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

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.

> > 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-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.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


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.

> 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

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-06-30 10:36           ` Arnd Bergmann
  0 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-06-30 10:36 UTC (permalink / raw)
  To: linux-arm-kernel

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.

> > 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


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.

> 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

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-06-30 10:36           ` Arnd Bergmann
@ 2011-06-30 15:03               ` Rob Herring
  -1 siblings, 0 replies; 49+ messages in thread
From: Rob Herring @ 2011-06-30 15:03 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 06/30/2011 05:36 AM, Arnd Bergmann wrote:
> 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.
> 
>>> 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-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.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
> 
> 
> 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.
> 
>> 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?

I need to send out a new version that drops aux value/mask from
device-tree. However, as is it won't help much with the above code
because of the extra register setup. Perhaps I can add the following
bindings:

tag-ram-latency = <>;
data-ram-latency = <>;
filter-ranges = <start end>;

Any comments on these? Is there anything already defined in this area
for latency/waitstates? I'll have to go back and check, but I think
these are all pl310 specific.

Rob

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-06-30 15:03               ` Rob Herring
  0 siblings, 0 replies; 49+ messages in thread
From: Rob Herring @ 2011-06-30 15:03 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/30/2011 05:36 AM, Arnd Bergmann wrote:
> 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.
> 
>>> 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
> 
> 
> 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.
> 
>> 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?

I need to send out a new version that drops aux value/mask from
device-tree. However, as is it won't help much with the above code
because of the extra register setup. Perhaps I can add the following
bindings:

tag-ram-latency = <>;
data-ram-latency = <>;
filter-ranges = <start end>;

Any comments on these? Is there anything already defined in this area
for latency/waitstates? I'll have to go back and check, but I think
these are all pl310 specific.

Rob

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-06-30 10:36           ` Arnd Bergmann
@ 2011-07-01  0:04             ` Barry Song
  -1 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-01  0:04 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux, devicetree-discuss, workgroup.linux, Grant Likely,
	weizeng.he, Olof Johansson, tglx, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 8924 bytes --]

2011/6/30 Arnd Bergmann <arnd@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.
>
>> > 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@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.

Hi Arnd,

ha-ha.

except Wall St and stock, i really didn't realize CSR is something
related with 'China Security & Surveillance Tech. Inc' . it seems CSR
is much more extensively known as a company in Wireless Technology,
Audio, Connectivity and GPS.
if we lost this name, people might not know it came from *that* CSR
focusing on Wireless/Audio/Connectivity/GPS. people will ask, what is
CSRXF? if we really use stock sticker symbols, CSR.L is the more
normal symbol in UK market. if we move to stock sticker symbol, could
we use CSR.L?

if 'China Security & Surveillance Tech. Inc' begin to move to Linux,
it seems CSST make more senses to them than CSR too :-)  as we check
the attached logo of 'China Security & Surveillance Tech. Inc' , CSST
is the abbreviation of the name of this China Company.

-barry

>
>> > 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
>
>
> 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.
>
>> 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

[-- Attachment #2: CSST.PNG --]
[-- Type: image/png, Size: 32704 bytes --]

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-01  0:04             ` Barry Song
  0 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-01  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

2011/6/30 Arnd Bergmann <arnd@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.
>
>> > 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.

Hi Arnd,

ha-ha.

except Wall St and stock, i really didn't realize CSR is something
related with 'China Security & Surveillance Tech. Inc' . it seems CSR
is much more extensively known as a company in Wireless Technology,
Audio, Connectivity and GPS.
if we lost this name, people might not know it came from *that* CSR
focusing on Wireless/Audio/Connectivity/GPS. people will ask, what is
CSRXF? if we really use stock sticker symbols, CSR.L is the more
normal symbol in UK market. if we move to stock sticker symbol, could
we use CSR.L?

if 'China Security & Surveillance Tech. Inc' begin to move to Linux,
it seems CSST make more senses to them than CSR too :-)  as we check
the attached logo of 'China Security & Surveillance Tech. Inc' , CSST
is the abbreviation of the name of this China Company.

-barry

>
>> > 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
>
>
> 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.
>
>> 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CSST.PNG
Type: image/png
Size: 32704 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110701/415f8d8e/attachment-0001.png>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-06-30 10:36           ` Arnd Bergmann
@ 2011-07-01  6:20               ` Barry Song
  -1 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-01  6:20 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi Arnd,

2011/6/30 Arnd Bergmann <arnd@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 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@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
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-01  6:20               ` Barry Song
  0 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-01  6:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

2011/6/30 Arnd Bergmann <arnd@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 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

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-01  6:20               ` Barry Song
@ 2011-07-01 16:19                   ` Arnd Bergmann
  -1 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-07-01 16:19 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ

On Friday 01 July 2011, Barry Song wrote:
> 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?

I think that's a good idea, but the ARM specific implementation cannot
be in common code. Other architectures have stuff similar to iotable_init
in asm/fixmap.h. If we decide on a function prototype for this, the
implementation can be arch/*/.

How about this:

extern void of_set_fixmap(struct device_node *np, int index,
	unsigned long of_fixmap_offset, pgprot_t flags); 

> 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:

Ok, sounds good.

> +/* TODO:
> + * add APIs to control reset of every module
> + */

Hmm, how about this: You enumerate every bit in the reset registers, and
then add a device tree property to the devices where this is needed containing
the number. Then you just need a simple interface like

void sirfsoc_reset_device(struct device *dev)
{
	int len, i;
	unsigned int *reset_bits = of_get_property(dev->of_node, "reset-bit", &len);

	for (i = 0; i<len/4; i++)
		sirfsoc_reset_line(reset_bits[i]);
}


> +#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

Very nice!

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-01 16:19                   ` Arnd Bergmann
  0 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-07-01 16:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 01 July 2011, Barry Song wrote:
> 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?

I think that's a good idea, but the ARM specific implementation cannot
be in common code. Other architectures have stuff similar to iotable_init
in asm/fixmap.h. If we decide on a function prototype for this, the
implementation can be arch/*/.

How about this:

extern void of_set_fixmap(struct device_node *np, int index,
	unsigned long of_fixmap_offset, pgprot_t flags); 

> 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:

Ok, sounds good.

> +/* TODO:
> + * add APIs to control reset of every module
> + */

Hmm, how about this: You enumerate every bit in the reset registers, and
then add a device tree property to the devices where this is needed containing
the number. Then you just need a simple interface like

void sirfsoc_reset_device(struct device *dev)
{
	int len, i;
	unsigned int *reset_bits = of_get_property(dev->of_node, "reset-bit", &len);

	for (i = 0; i<len/4; i++)
		sirfsoc_reset_line(reset_bits[i]);
}


> +#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

Very nice!

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-01  0:04             ` Barry Song
@ 2011-07-01 16:26               ` Arnd Bergmann
  -1 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-07-01 16:26 UTC (permalink / raw)
  To: Barry Song
  Cc: linux, devicetree-discuss, workgroup.linux, Grant Likely,
	weizeng.he, Olof Johansson, tglx, linux-arm-kernel

On Friday 01 July 2011, Barry Song wrote:
> except Wall St and stock, i really didn't realize CSR is something
> related with 'China Security & Surveillance Tech. Inc' . it seems CSR
> is much more extensively known as a company in Wireless Technology,
> Audio, Connectivity and GPS.
> if we lost this name, people might not know it came from that CSR
> focusing on Wireless/Audio/Connectivity/GPS. people will ask, what is
> CSRXF? if we really use stock sticker symbols, CSR.L is the more
> normal symbol in UK market. if we move to stock sticker symbol, could
> we use CSR.L?

CSR.L sounds ok to me, but I don't know if there are limitations on the
character set used here, can we have dots?

Maybe the best solution after all is to go with 'sirf,...': it is
actually a company name, and you own the .com address, and there is
no other company listed on wallstreet with that shortcut.

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-01 16:26               ` Arnd Bergmann
  0 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-07-01 16:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 01 July 2011, Barry Song wrote:
> except Wall St and stock, i really didn't realize CSR is something
> related with 'China Security & Surveillance Tech. Inc' . it seems CSR
> is much more extensively known as a company in Wireless Technology,
> Audio, Connectivity and GPS.
> if we lost this name, people might not know it came from that CSR
> focusing on Wireless/Audio/Connectivity/GPS. people will ask, what is
> CSRXF? if we really use stock sticker symbols, CSR.L is the more
> normal symbol in UK market. if we move to stock sticker symbol, could
> we use CSR.L?

CSR.L sounds ok to me, but I don't know if there are limitations on the
character set used here, can we have dots?

Maybe the best solution after all is to go with 'sirf,...': it is
actually a company name, and you own the .com address, and there is
no other company listed on wallstreet with that shortcut.

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-01 16:19                   ` Arnd Bergmann
@ 2011-07-02 12:25                     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 49+ messages in thread
From: Russell King - ARM Linux @ 2011-07-02 12:25 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: devicetree-discuss, Barry Song, workgroup.linux, Grant Likely,
	weizeng.he, Olof Johansson, tglx, linux-arm-kernel

On Fri, Jul 01, 2011 at 06:19:43PM +0200, Arnd Bergmann wrote:
> On Friday 01 July 2011, Barry Song wrote:
> > 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?
> 
> I think that's a good idea, but the ARM specific implementation cannot
> be in common code. Other architectures have stuff similar to iotable_init
> in asm/fixmap.h. If we decide on a function prototype for this, the
> implementation can be arch/*/.

One of the issues with fixmap is that its based around single pages
and indexing an area.  It's idiotic to use such a thing if you have
to map the ISA memory regions for VGA.

Plus, of course, forcing everything down the route of ioremap() and
fixmap forces everyone to use 2-level page tables and 4K page table
entries, avoiding the possibility of having just a single 1st level
page table entry covering their IO space.  Not only does it increase
TLB pressure but it also makes page table walking more expensive.

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-02 12:25                     ` Russell King - ARM Linux
  0 siblings, 0 replies; 49+ messages in thread
From: Russell King - ARM Linux @ 2011-07-02 12:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jul 01, 2011 at 06:19:43PM +0200, Arnd Bergmann wrote:
> On Friday 01 July 2011, Barry Song wrote:
> > 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?
> 
> I think that's a good idea, but the ARM specific implementation cannot
> be in common code. Other architectures have stuff similar to iotable_init
> in asm/fixmap.h. If we decide on a function prototype for this, the
> implementation can be arch/*/.

One of the issues with fixmap is that its based around single pages
and indexing an area.  It's idiotic to use such a thing if you have
to map the ISA memory regions for VGA.

Plus, of course, forcing everything down the route of ioremap() and
fixmap forces everyone to use 2-level page tables and 4K page table
entries, avoiding the possibility of having just a single 1st level
page table entry covering their IO space.  Not only does it increase
TLB pressure but it also makes page table walking more expensive.

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-02 12:25                     ` Russell King - ARM Linux
@ 2011-07-02 19:34                         ` Arnd Bergmann
  -1 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-07-02 19:34 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Saturday 02 July 2011 14:25:27 Russell King - ARM Linux wrote:
> On Fri, Jul 01, 2011 at 06:19:43PM +0200, Arnd Bergmann wrote:
> > On Friday 01 July 2011, Barry Song wrote:
> > > 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?
> > 
> > I think that's a good idea, but the ARM specific implementation cannot
> > be in common code. Other architectures have stuff similar to iotable_init
> > in asm/fixmap.h. If we decide on a function prototype for this, the
> > implementation can be arch/*/.
> 
> One of the issues with fixmap is that its based around single pages
> and indexing an area.  It's idiotic to use such a thing if you have
> to map the ISA memory regions for VGA.
> 
> Plus, of course, forcing everything down the route of ioremap() and
> fixmap forces everyone to use 2-level page tables and 4K page table
> entries, avoiding the possibility of having just a single 1st level
> page table entry covering their IO space.  Not only does it increase
> TLB pressure but it also makes page table walking more expensive.

I didn't mean converting ARM to use fixmap, but having a common prototype
for the function to do an early mapping of devices, regardless if it's
based on fixmap or iotable.

We already discussed the issue of large TLBs for iotable before. If
we ever want to conver that to the fixmap API, we would first have
to extend it with a more straightforward way to do large mappings,
and I'm not going to start that discussion.

I actually didn't know that we had fixmap support on ARM until I looked
now. In fact there are now at least three interfaces that would let you
establish early mappings:

* iotable (ARM only)
* fixmap (some architectures, unused on ARM except for kmap_atomic)
* early_ioremap (x86 only, built on top of fixmap)

Maybe we could implement early_ioremap on ARM on top of iotable,
with support for large pages, and build of_io_earlymap() as suggested
by Barry on top of that?

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-02 19:34                         ` Arnd Bergmann
  0 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-07-02 19:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 02 July 2011 14:25:27 Russell King - ARM Linux wrote:
> On Fri, Jul 01, 2011 at 06:19:43PM +0200, Arnd Bergmann wrote:
> > On Friday 01 July 2011, Barry Song wrote:
> > > 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?
> > 
> > I think that's a good idea, but the ARM specific implementation cannot
> > be in common code. Other architectures have stuff similar to iotable_init
> > in asm/fixmap.h. If we decide on a function prototype for this, the
> > implementation can be arch/*/.
> 
> One of the issues with fixmap is that its based around single pages
> and indexing an area.  It's idiotic to use such a thing if you have
> to map the ISA memory regions for VGA.
> 
> Plus, of course, forcing everything down the route of ioremap() and
> fixmap forces everyone to use 2-level page tables and 4K page table
> entries, avoiding the possibility of having just a single 1st level
> page table entry covering their IO space.  Not only does it increase
> TLB pressure but it also makes page table walking more expensive.

I didn't mean converting ARM to use fixmap, but having a common prototype
for the function to do an early mapping of devices, regardless if it's
based on fixmap or iotable.

We already discussed the issue of large TLBs for iotable before. If
we ever want to conver that to the fixmap API, we would first have
to extend it with a more straightforward way to do large mappings,
and I'm not going to start that discussion.

I actually didn't know that we had fixmap support on ARM until I looked
now. In fact there are now at least three interfaces that would let you
establish early mappings:

* iotable (ARM only)
* fixmap (some architectures, unused on ARM except for kmap_atomic)
* early_ioremap (x86 only, built on top of fixmap)

Maybe we could implement early_ioremap on ARM on top of iotable,
with support for large pages, and build of_io_earlymap() as suggested
by Barry on top of that?

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-01 16:19                   ` Arnd Bergmann
@ 2011-07-04  2:55                       ` Barry Song
  -1 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-04  2:55 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

2011/7/2 Arnd Bergmann <arnd@arndb.de>:
> On Friday 01 July 2011, Barry Song wrote:
>> 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?
>
> I think that's a good idea, but the ARM specific implementation cannot
> be in common code. Other architectures have stuff similar to iotable_init
> in asm/fixmap.h. If we decide on a function prototype for this, the
> implementation can be arch/*/.
>
> How about this:
>
> extern void of_set_fixmap(struct device_node *np, int index,
>        unsigned long of_fixmap_offset, pgprot_t flags);
>
>> 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:
>
> Ok, sounds good.
>
>> +/* TODO:
>> + * add APIs to control reset of every module
>> + */
>
> Hmm, how about this: You enumerate every bit in the reset registers, and
> then add a device tree property to the devices where this is needed containing
> the number. Then you just need a simple interface like
>
> void sirfsoc_reset_device(struct device *dev)
> {
>        int len, i;
>        unsigned int *reset_bits = of_get_property(dev->of_node, "reset-bit", &len);
>
>        for (i = 0; i<len/4; i++)
>                sirfsoc_reset_line(reset_bits[i]);
> }

Great idea. in fact there is only one reset bit for every device. So
maybe the rstc.c can be:
/*
 * 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/mutex.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>

void __iomem *sirfsoc_rstc_base;
static DEFINE_MUTEX(rstc_lock);

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);

int sirfsoc_reset_device(struct device *dev)
{
	const unsigned int *prop = of_get_property(dev->of_node, "reset-bit", NULL);
	unsigned int reset_bit;

	if (!prop)
		return -ENODEV;

	reset_bit = be32_to_cpup(prop);

	mutex_lock(&rstc_lock);

	/*
	 * Writing 1 to this bit resets corresponding block.
	 * Writing 0 to this bit de-asserts reset signal of
	 * the corresponding block.
	 */
	writel(sirfsoc_rstc_base + (reset_bit / 32) * 4,
		readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit);
	msleep(10);
	writel(sirfsoc_rstc_base + (reset_bit / 32) * 4,
		readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit);

	mutex_unlock(&rstc_lock);

	return 0;
}
>
>
>> +#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
>
> Very nice!
>
>        Arnd
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-04  2:55                       ` Barry Song
  0 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-04  2:55 UTC (permalink / raw)
  To: linux-arm-kernel

2011/7/2 Arnd Bergmann <arnd@arndb.de>:
> On Friday 01 July 2011, Barry Song wrote:
>> 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?
>
> I think that's a good idea, but the ARM specific implementation cannot
> be in common code. Other architectures have stuff similar to iotable_init
> in asm/fixmap.h. If we decide on a function prototype for this, the
> implementation can be arch/*/.
>
> How about this:
>
> extern void of_set_fixmap(struct device_node *np, int index,
> ? ? ? ?unsigned long of_fixmap_offset, pgprot_t flags);
>
>> 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:
>
> Ok, sounds good.
>
>> +/* TODO:
>> + * add APIs to control reset of every module
>> + */
>
> Hmm, how about this: You enumerate every bit in the reset registers, and
> then add a device tree property to the devices where this is needed containing
> the number. Then you just need a simple interface like
>
> void sirfsoc_reset_device(struct device *dev)
> {
> ? ? ? ?int len, i;
> ? ? ? ?unsigned int *reset_bits = of_get_property(dev->of_node, "reset-bit", &len);
>
> ? ? ? ?for (i = 0; i<len/4; i++)
> ? ? ? ? ? ? ? ?sirfsoc_reset_line(reset_bits[i]);
> }

Great idea. in fact there is only one reset bit for every device. So
maybe the rstc.c can be:
/*
 * 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/mutex.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>

void __iomem *sirfsoc_rstc_base;
static DEFINE_MUTEX(rstc_lock);

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);

int sirfsoc_reset_device(struct device *dev)
{
	const unsigned int *prop = of_get_property(dev->of_node, "reset-bit", NULL);
	unsigned int reset_bit;

	if (!prop)
		return -ENODEV;

	reset_bit = be32_to_cpup(prop);

	mutex_lock(&rstc_lock);

	/*
	 * Writing 1 to this bit resets corresponding block.
	 * Writing 0 to this bit de-asserts reset signal of
	 * the corresponding block.
	 */
	writel(sirfsoc_rstc_base + (reset_bit / 32) * 4,
		readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit);
	msleep(10);
	writel(sirfsoc_rstc_base + (reset_bit / 32) * 4,
		readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit);

	mutex_unlock(&rstc_lock);

	return 0;
}
>
>
>> +#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
>
> Very nice!
>
> ? ? ? ?Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-04  2:55                       ` Barry Song
@ 2011-07-04 14:53                         ` Arnd Bergmann
  -1 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-07-04 14:53 UTC (permalink / raw)
  To: Barry Song
  Cc: linux, devicetree-discuss, workgroup.linux, Grant Likely,
	weizeng.he, Olof Johansson, tglx, linux-arm-kernel

On Monday 04 July 2011, Barry Song wrote:
> Great idea. in fact there is only one reset bit for every device. So
> maybe the rstc.c can be
> ...

Yes, looks good.

>         /*
>          * Writing 1 to this bit resets corresponding block.
>          * Writing 0 to this bit de-asserts reset signal of
>          * the corresponding block.
>          */
>         writel(sirfsoc_rstc_base + (reset_bit / 32) * 4,
>                 readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit);
>         msleep(10);
>         writel(sirfsoc_rstc_base + (reset_bit / 32) * 4,
>                 readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit);

One remark about the msleep here: I find arbitrary wait periods a
bit unclean, and most hardware allows you to poll whether it's
done by reading back the register you have just written.

If your hardware can do that, you can replace the msleep() with a
single readl or a readl()/msleep(1) loop?

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-04 14:53                         ` Arnd Bergmann
  0 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-07-04 14:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 04 July 2011, Barry Song wrote:
> Great idea. in fact there is only one reset bit for every device. So
> maybe the rstc.c can be
> ...

Yes, looks good.

>         /*
>          * Writing 1 to this bit resets corresponding block.
>          * Writing 0 to this bit de-asserts reset signal of
>          * the corresponding block.
>          */
>         writel(sirfsoc_rstc_base + (reset_bit / 32) * 4,
>                 readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit);
>         msleep(10);
>         writel(sirfsoc_rstc_base + (reset_bit / 32) * 4,
>                 readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit);

One remark about the msleep here: I find arbitrary wait periods a
bit unclean, and most hardware allows you to poll whether it's
done by reading back the register you have just written.

If your hardware can do that, you can replace the msleep() with a
single readl or a readl()/msleep(1) loop?

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-01  0:04             ` Barry Song
@ 2011-07-04 14:59                 ` Grant Likely
  -1 siblings, 0 replies; 49+ messages in thread
From: Grant Likely @ 2011-07-04 14:59 UTC (permalink / raw)
  To: Barry Song
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Fri, Jul 01, 2011 at 08:04:06AM +0800, Barry Song wrote:
> 2011/6/30 Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>:
> > 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.
> >
> >> > 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-uLR06cmDAlatORQsKGg5Ig@public.gmane.orgbs.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.
> 
> Hi Arnd,
> 
> ha-ha.
> 
> except Wall St and stock, i really didn't realize CSR is something
> related with 'China Security & Surveillance Tech. Inc' . it seems CSR
> is much more extensively known as a company in Wireless Technology,
> Audio, Connectivity and GPS.
> if we lost this name, people might not know it came from *that* CSR
> focusing on Wireless/Audio/Connectivity/GPS. people will ask, what is
> CSRXF? if we really use stock sticker symbols, CSR.L is the more
> normal symbol in UK market. if we move to stock sticker symbol, could
> we use CSR.L?

Fine by me.  Make sure it stays in uppercase when using the stock
ticker symbol.

g.

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-04 14:59                 ` Grant Likely
  0 siblings, 0 replies; 49+ messages in thread
From: Grant Likely @ 2011-07-04 14:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jul 01, 2011 at 08:04:06AM +0800, Barry Song wrote:
> 2011/6/30 Arnd Bergmann <arnd@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.
> >
> >> > 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.
> 
> Hi Arnd,
> 
> ha-ha.
> 
> except Wall St and stock, i really didn't realize CSR is something
> related with 'China Security & Surveillance Tech. Inc' . it seems CSR
> is much more extensively known as a company in Wireless Technology,
> Audio, Connectivity and GPS.
> if we lost this name, people might not know it came from *that* CSR
> focusing on Wireless/Audio/Connectivity/GPS. people will ask, what is
> CSRXF? if we really use stock sticker symbols, CSR.L is the more
> normal symbol in UK market. if we move to stock sticker symbol, could
> we use CSR.L?

Fine by me.  Make sure it stays in uppercase when using the stock
ticker symbol.

g.

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-04 14:53                         ` Arnd Bergmann
@ 2011-07-05  1:32                             ` Barry Song
  -1 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-05  1:32 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

2011/7/4 Arnd Bergmann <arnd@arndb.de>:
> On Monday 04 July 2011, Barry Song wrote:
>> Great idea. in fact there is only one reset bit for every device. So
>> maybe the rstc.c can be
>> ...
>
> Yes, looks good.
>
>>         /*
>>          * Writing 1 to this bit resets corresponding block.
>>          * Writing 0 to this bit de-asserts reset signal of
>>          * the corresponding block.
>>          */
>>         writel(sirfsoc_rstc_base + (reset_bit / 32) * 4,
>>                 readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit);
>>         msleep(10);
>>         writel(sirfsoc_rstc_base + (reset_bit / 32) * 4,
>>                 readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit);
>
> One remark about the msleep here: I find arbitrary wait periods a
> bit unclean, and most hardware allows you to poll whether it's
> done by reading back the register you have just written.
>
> If your hardware can do that, you can replace the msleep() with a
> single readl or a readl()/msleep(1) loop?

i can't agree more. if there is such a register in chip, we would have
used it. ic guys confirmed there isn't such a register. so..delay...

>
>        Arnd
>
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-05  1:32                             ` Barry Song
  0 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-05  1:32 UTC (permalink / raw)
  To: linux-arm-kernel

2011/7/4 Arnd Bergmann <arnd@arndb.de>:
> On Monday 04 July 2011, Barry Song wrote:
>> Great idea. in fact there is only one reset bit for every device. So
>> maybe the rstc.c can be
>> ...
>
> Yes, looks good.
>
>> ? ? ? ? /*
>> ? ? ? ? ?* Writing 1 to this bit resets corresponding block.
>> ? ? ? ? ?* Writing 0 to this bit de-asserts reset signal of
>> ? ? ? ? ?* the corresponding block.
>> ? ? ? ? ?*/
>> ? ? ? ? writel(sirfsoc_rstc_base + (reset_bit / 32) * 4,
>> ? ? ? ? ? ? ? ? readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit);
>> ? ? ? ? msleep(10);
>> ? ? ? ? writel(sirfsoc_rstc_base + (reset_bit / 32) * 4,
>> ? ? ? ? ? ? ? ? readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit);
>
> One remark about the msleep here: I find arbitrary wait periods a
> bit unclean, and most hardware allows you to poll whether it's
> done by reading back the register you have just written.
>
> If your hardware can do that, you can replace the msleep() with a
> single readl or a readl()/msleep(1) loop?

i can't agree more. if there is such a register in chip, we would have
used it. ic guys confirmed there isn't such a register. so..delay...

>
> ? ? ? ?Arnd
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-01  6:20               ` Barry Song
@ 2011-07-05  8:34                 ` Barry Song
  -1 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-05  8:34 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux, devicetree-discuss, workgroup.linux, Grant Likely,
	weizeng.he, Olof Johansson, tglx, linux-arm-kernel

Hi Arnd,

2011/7/1 Barry Song <21cnbao@gmail.com>:
> Hi Arnd,
>
> 2011/6/30 Arnd Bergmann <arnd@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@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@0x80040000 {
			compatible = "arm,pl310-cache", "cache";
			reg = <0x80040000 0x1000>;
			interrupts = <59>;
		};

		sirfsoc-iobus {
			compatible = "simple-bus";
			#address-cells = <1>;
			#size-cells = <1>;
			ranges = <0x56000000 0x56000000 0x1b0000
				0x80010000 0x80010000 0x30000
				0x88000000 0x88000000 0x40040000>;

			intc: interrupt-controller@0x80020000 {
				#interrupt-cells = <1>;
				interrupt-controller;
				compatible = "sirf,intc", "sirf,prima2-intc";
				reg = <0x80020000 0x1000>;
			};

			sys-iobg {
				compatible = "simple-bus";
				#address-cells = <1>;
				#size-cells = <1>;
				ranges = <0x88000000 0x88000000 0x40000>;

				clock-controller@0x88000000 {
					compatible = "sirf,clkc", "sirf,prima2-clkc";
					reg = <0x88000000 0x1000>;
					interrupts = <3>;
				};

				reset-controller@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@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@0x90010000 {
					compatible = "sirf,lcd", "sirf,prima2-lcd";
					reg = <0x90010000 0x20000>;
					interrupts = <30>;
				};

				vpp@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@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@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@0xa8000000 {
					compatible = "sirf,dspif", "sirf,prima2-dspif";
					reg = <0xa8000000 0x10000>;
					interrupts = <9>;
				};

				gps@0xa8010000 {
					compatible = "sirf,gps", "sirf,prima2-gps";
					reg = <0xa8010000 0x10000>;
					interrupts = <7>;
				};

				dsp@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@0xb0020000 {
					compatible = "sirf,tick", "sirf,prima2-tick";
					reg = <0xb0020000 0x1000>;
					interrupts = <0>;
				};

				nand@0xb0030000 {
					compatible = "sirf,nand", "sirf,prima2-nand";
					reg = <0xb0030000 0x10000>;
					interrupts = <41>;
				};

				audio@0xb0040000 {
					compatible = "sirf,audio", "sirf,prima2-audio";
					reg = <0xb0040000 0x10000>;
					interrupts = <35>;
				};

				uart0: uart@0xb0050000 {
					cell-index = <0>;
					compatible = "sirf,uart", "sirf,prima2-uart";
					reg = <0xb0050000 0x10000>;
					interrupts = <17>;
				};

	 			uart1: uart@0xb0060000 {
					cell-index = <1>;
					compatible = "sirf,uart", "sirf,prima2-uart";
					reg = <0xb0060000 0x10000>;
					interrupts = <18>;
				};

	 			uart2: uart@0xb0070000 {
					cell-index = <2>;
					compatible = "sirf,uart", "sirf,prima2-uart";
					reg = <0xb0070000 0x10000>;
					interrupts = <19>;
				};

	 			usp0: usp@0xb0080000 {
					cell-index = <0>;
					compatible = "sirf,usp", "sirf,prima2-usp";
					reg = <0xb0080000 0x10000>;
					interrupts = <20>;
				};

	 			usp1: usp@0xb0090000 {
					cell-index = <1>;
					compatible = "sirf,usp", "sirf,prima2-usp";
					reg = <0xb0090000 0x10000>;
					interrupts = <21>;
				};

	 			usp2: usp@0xb00a0000 {
					cell-index = <2>;
					compatible = "sirf,usp", "sirf,prima2-usp";
					reg = <0xb00a0000 0x10000>;
					interrupts = <22>;
				};

	 			dmac0: dma-controller@0xb00b0000 {
					cell-index = <0>;
					compatible = "sirf,dmac", "sirf,prima2-dmac";
					reg = <0xb00b0000 0x10000>;
					interrupts = <12>;
				};

	 			dmac1: dma-controller@0xb0160000 {
					cell-index = <1>;
					compatible = "sirf,dmac", "sirf,prima2-dmac";
					reg = <0xb0160000 0x10000>;
					interrupts = <13>;
				};

				vip@0xb00C0000 {
					compatible = "sirf,vip", "sirf,prima2-vip";
					reg = <0xb00C0000 0x10000>;
				};

	 			spi0: spi@0xb00D0000 {
					cell-index = <0>;
					compatible = "sirf,spi", "sirf,prima2-spi";
					reg = <0xb00D0000 0x10000>;
					interrupts = <15>;
				};

	 			spi1: spi@0xb0170000 {
					cell-index = <1>;
					compatible = "sirf,spi", "sirf,prima2-spi";
					reg = <0xb0170000 0x10000>;
					interrupts = <16>;
				};

	 			i2c0: i2c@0xb00E0000 {
					cell-index = <0>;
					compatible = "sirf,i2c", "sirf,prima2-i2c";
					reg = <0xb00E0000 0x10000>;
					interrupts = <24>;
				};

	 			i2c1: i2c@0xb00f0000 {
					cell-index = <1>;
					compatible = "sirf,i2c", "sirf,prima2-i2c";
					reg = <0xb00f0000 0x10000>;
					interrupts = <25>;
				};

				tsc@0xb0110000 {
					compatible = "sirf,tsc", "sirf,prima2-tsc";
					reg = <0xb0110000 0x10000>;
					interrupts = <33>;
				};

				gpio: gpio-controller@0xb0120000 {
					#gpio-cells = <2>;
					#interrupt-cells = <2>;
					compatible = "sirf,gpio", "sirf,prima2-gpio";
					reg = <0xb0120000 0x10000>;
					gpio-controller;
					interrupt-controller;
				};

				pwm@0xb0130000 {
					compatible = "sirf,pwm", "sirf,prima2-pwm";
					reg = <0xb0130000 0x10000>;
				};

				efusesys@0xb0140000 {
					compatible = "sirf,efuse", "sirf,prima2-efuse";
					reg = <0xb0140000 0x10000>;
				};

				pulsec@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@0x56000000 {
						cell-index = <0>;
						compatible = "sirf,sdhc", "sirf,prima2-sdhc";
						reg = <0x56000000 0x100000>;
						interrupts = <38>;
					};

					sd1: sdhci@0x56100000 {
						cell-index = <1>;
						compatible = "sirf,sdhc", "sirf,prima2-sdhc";
						reg = <0x56100000 0x100000>;
						interrupts = <38>;
					};

					sd2: sdhci@0x56200000 {
						cell-index = <2>;
						compatible = "sirf,sdhc", "sirf,prima2-sdhc";
						reg = <0x56200000 0x100000>;
						interrupts = <23>;
					};

					sd3: sdhci@0x56300000 {
						cell-index = <3>;
						compatible = "sirf,sdhc", "sirf,prima2-sdhc";
						reg = <0x56300000 0x100000>;
						interrupts = <23>;
					};

					sd4: sdhci@0x56400000 {
						cell-index = <4>;
						compatible = "sirf,sdhc", "sirf,prima2-sdhc";
						reg = <0x56400000 0x100000>;
						interrupts = <39>;
					};

					sd5: sdhci@0x56500000 {
						cell-index = <5>;
						compatible = "sirf,sdhc", "sirf,prima2-sdhc";
						reg = <0x56500000 0x100000>;
						interrupts = <39>;
					};

					pci-copy@0x57900000 {
						compatible = "sirf,pcicp", "sirf,prima2-pcicp";
						reg = <0x57900000 0x100000>;
						interrupts = <40>;
					};

					rom-interface@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@0x1000 {
					compatible = "sirf,gpsrtc", "sirf,prima2-gpsrtc";
					reg = <0x1000 0x1000>;
					interrupts = <55 56 57>;
				};

				sysrtc@0x2000 {
					compatible = "sirf,sysrtc", "sirf,prima2-sysrtc";
					reg = <0x2000 0x1000>;
					interrupts = <52 53 54>;
				};

				pwrc@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@0xb00E0000 {
					compatible = "sirf,usb", "sirf,prima2-usb";
					reg = <0xb8000000 0x10000>;
					interrupts = <10>;
				};

	 			usb1: usb@0xb00f0000 {
					compatible = "sirf,usb", "sirf,prima2-usb";
					reg = <0xb8010000 0x10000>;
					interrupts = <11>;
				};

				sata@0xb00f0000 {
					compatible = "sirf,sata", "sirf,prima2-sata";
					reg = <0xb8020000 0x10000>;
					interrupts = <37>;
				};

				security@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@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

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-05  8:34                 ` Barry Song
  0 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-05  8:34 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

2011/7/1 Barry Song <21cnbao@gmail.com>:
> Hi Arnd,
>
> 2011/6/30 Arnd Bergmann <arnd@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>;
		};

		sirfsoc-iobus {
			compatible = "simple-bus";
			#address-cells = <1>;
			#size-cells = <1>;
			ranges = <0x56000000 0x56000000 0x1b0000
				0x80010000 0x80010000 0x30000
				0x88000000 0x88000000 0x40040000>;

			intc: interrupt-controller at 0x80020000 {
				#interrupt-cells = <1>;
				interrupt-controller;
				compatible = "sirf,intc", "sirf,prima2-intc";
				reg = <0x80020000 0x1000>;
			};

			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

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-05  1:32                             ` Barry Song
@ 2011-07-05 11:10                                 ` Arnd Bergmann
  -1 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-07-05 11:10 UTC (permalink / raw)
  To: Barry Song
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tuesday 05 July 2011, Barry Song wrote:
> > If your hardware can do that, you can replace the msleep() with a
> > single readl or a readl()/msleep(1) loop?
> 
> i can't agree more. if there is such a register in chip, we would have
> used it. ic guys confirmed there isn't such a register. so..delay...

Ok, fair enough. Maybe add a comment then to provide an explanation
why you are waiting for exactly 10ms. This will show up when people
try to optimize boot time, so it's good to know for the reader if it
can be made shorter or not.

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-05 11:10                                 ` Arnd Bergmann
  0 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-07-05 11:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 05 July 2011, Barry Song wrote:
> > If your hardware can do that, you can replace the msleep() with a
> > single readl or a readl()/msleep(1) loop?
> 
> i can't agree more. if there is such a register in chip, we would have
> used it. ic guys confirmed there isn't such a register. so..delay...

Ok, fair enough. Maybe add a comment then to provide an explanation
why you are waiting for exactly 10ms. This will show up when people
try to optimize boot time, so it's good to know for the reader if it
can be made shorter or not.

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-05  8:34                 ` Barry Song
@ 2011-07-06  2:10                   ` Barry Song
  -1 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-06  2:10 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux, devicetree-discuss, workgroup.linux, Grant Likely,
	weizeng.he, Olof Johansson, tglx, linux-arm-kernel

2011/7/5 Barry Song <21cnbao@gmail.com>:
> Hi Arnd,
>
> 2011/7/1 Barry Song <21cnbao@gmail.com>:
>> Hi Arnd,
>>
>> 2011/6/30 Arnd Bergmann <arnd@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@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@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@0x80020000 {
>                                #interrupt-cells = <1>;
>                                interrupt-controller;
>                                compatible = "sirf,intc", "sirf,prima2-intc";
>                                reg = <0x80020000 0x1000>;
>                        };

                l2-cache-controller@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@0x88000000 {
>                                        compatible = "sirf,clkc", "sirf,prima2-clkc";
>                                        reg = <0x88000000 0x1000>;
>                                        interrupts = <3>;
>                                };
>
>                                reset-controller@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@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@0x90010000 {
>                                        compatible = "sirf,lcd", "sirf,prima2-lcd";
>                                        reg = <0x90010000 0x20000>;
>                                        interrupts = <30>;
>                                };
>
>                                vpp@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@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@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@0xa8000000 {
>                                        compatible = "sirf,dspif", "sirf,prima2-dspif";
>                                        reg = <0xa8000000 0x10000>;
>                                        interrupts = <9>;
>                                };
>
>                                gps@0xa8010000 {
>                                        compatible = "sirf,gps", "sirf,prima2-gps";
>                                        reg = <0xa8010000 0x10000>;
>                                        interrupts = <7>;
>                                };
>
>                                dsp@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@0xb0020000 {
>                                        compatible = "sirf,tick", "sirf,prima2-tick";
>                                        reg = <0xb0020000 0x1000>;
>                                        interrupts = <0>;
>                                };
>
>                                nand@0xb0030000 {
>                                        compatible = "sirf,nand", "sirf,prima2-nand";
>                                        reg = <0xb0030000 0x10000>;
>                                        interrupts = <41>;
>                                };
>
>                                audio@0xb0040000 {
>                                        compatible = "sirf,audio", "sirf,prima2-audio";
>                                        reg = <0xb0040000 0x10000>;
>                                        interrupts = <35>;
>                                };
>
>                                uart0: uart@0xb0050000 {
>                                        cell-index = <0>;
>                                        compatible = "sirf,uart", "sirf,prima2-uart";
>                                        reg = <0xb0050000 0x10000>;
>                                        interrupts = <17>;
>                                };
>
>                                uart1: uart@0xb0060000 {
>                                        cell-index = <1>;
>                                        compatible = "sirf,uart", "sirf,prima2-uart";
>                                        reg = <0xb0060000 0x10000>;
>                                        interrupts = <18>;
>                                };
>
>                                uart2: uart@0xb0070000 {
>                                        cell-index = <2>;
>                                        compatible = "sirf,uart", "sirf,prima2-uart";
>                                        reg = <0xb0070000 0x10000>;
>                                        interrupts = <19>;
>                                };
>
>                                usp0: usp@0xb0080000 {
>                                        cell-index = <0>;
>                                        compatible = "sirf,usp", "sirf,prima2-usp";
>                                        reg = <0xb0080000 0x10000>;
>                                        interrupts = <20>;
>                                };
>
>                                usp1: usp@0xb0090000 {
>                                        cell-index = <1>;
>                                        compatible = "sirf,usp", "sirf,prima2-usp";
>                                        reg = <0xb0090000 0x10000>;
>                                        interrupts = <21>;
>                                };
>
>                                usp2: usp@0xb00a0000 {
>                                        cell-index = <2>;
>                                        compatible = "sirf,usp", "sirf,prima2-usp";
>                                        reg = <0xb00a0000 0x10000>;
>                                        interrupts = <22>;
>                                };
>
>                                dmac0: dma-controller@0xb00b0000 {
>                                        cell-index = <0>;
>                                        compatible = "sirf,dmac", "sirf,prima2-dmac";
>                                        reg = <0xb00b0000 0x10000>;
>                                        interrupts = <12>;
>                                };
>
>                                dmac1: dma-controller@0xb0160000 {
>                                        cell-index = <1>;
>                                        compatible = "sirf,dmac", "sirf,prima2-dmac";
>                                        reg = <0xb0160000 0x10000>;
>                                        interrupts = <13>;
>                                };
>
>                                vip@0xb00C0000 {
>                                        compatible = "sirf,vip", "sirf,prima2-vip";
>                                        reg = <0xb00C0000 0x10000>;
>                                };
>
>                                spi0: spi@0xb00D0000 {
>                                        cell-index = <0>;
>                                        compatible = "sirf,spi", "sirf,prima2-spi";
>                                        reg = <0xb00D0000 0x10000>;
>                                        interrupts = <15>;
>                                };
>
>                                spi1: spi@0xb0170000 {
>                                        cell-index = <1>;
>                                        compatible = "sirf,spi", "sirf,prima2-spi";
>                                        reg = <0xb0170000 0x10000>;
>                                        interrupts = <16>;
>                                };
>
>                                i2c0: i2c@0xb00E0000 {
>                                        cell-index = <0>;
>                                        compatible = "sirf,i2c", "sirf,prima2-i2c";
>                                        reg = <0xb00E0000 0x10000>;
>                                        interrupts = <24>;
>                                };
>
>                                i2c1: i2c@0xb00f0000 {
>                                        cell-index = <1>;
>                                        compatible = "sirf,i2c", "sirf,prima2-i2c";
>                                        reg = <0xb00f0000 0x10000>;
>                                        interrupts = <25>;
>                                };
>
>                                tsc@0xb0110000 {
>                                        compatible = "sirf,tsc", "sirf,prima2-tsc";
>                                        reg = <0xb0110000 0x10000>;
>                                        interrupts = <33>;
>                                };
>
>                                gpio: gpio-controller@0xb0120000 {
>                                        #gpio-cells = <2>;
>                                        #interrupt-cells = <2>;
>                                        compatible = "sirf,gpio", "sirf,prima2-gpio";
>                                        reg = <0xb0120000 0x10000>;
>                                        gpio-controller;
>                                        interrupt-controller;
>                                };
>
>                                pwm@0xb0130000 {
>                                        compatible = "sirf,pwm", "sirf,prima2-pwm";
>                                        reg = <0xb0130000 0x10000>;
>                                };
>
>                                efusesys@0xb0140000 {
>                                        compatible = "sirf,efuse", "sirf,prima2-efuse";
>                                        reg = <0xb0140000 0x10000>;
>                                };
>
>                                pulsec@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@0x56000000 {
>                                                cell-index = <0>;
>                                                compatible = "sirf,sdhc", "sirf,prima2-sdhc";
>                                                reg = <0x56000000 0x100000>;
>                                                interrupts = <38>;
>                                        };
>
>                                        sd1: sdhci@0x56100000 {
>                                                cell-index = <1>;
>                                                compatible = "sirf,sdhc", "sirf,prima2-sdhc";
>                                                reg = <0x56100000 0x100000>;
>                                                interrupts = <38>;
>                                        };
>
>                                        sd2: sdhci@0x56200000 {
>                                                cell-index = <2>;
>                                                compatible = "sirf,sdhc", "sirf,prima2-sdhc";
>                                                reg = <0x56200000 0x100000>;
>                                                interrupts = <23>;
>                                        };
>
>                                        sd3: sdhci@0x56300000 {
>                                                cell-index = <3>;
>                                                compatible = "sirf,sdhc", "sirf,prima2-sdhc";
>                                                reg = <0x56300000 0x100000>;
>                                                interrupts = <23>;
>                                        };
>
>                                        sd4: sdhci@0x56400000 {
>                                                cell-index = <4>;
>                                                compatible = "sirf,sdhc", "sirf,prima2-sdhc";
>                                                reg = <0x56400000 0x100000>;
>                                                interrupts = <39>;
>                                        };
>
>                                        sd5: sdhci@0x56500000 {
>                                                cell-index = <5>;
>                                                compatible = "sirf,sdhc", "sirf,prima2-sdhc";
>                                                reg = <0x56500000 0x100000>;
>                                                interrupts = <39>;
>                                        };
>
>                                        pci-copy@0x57900000 {
>                                                compatible = "sirf,pcicp", "sirf,prima2-pcicp";
>                                                reg = <0x57900000 0x100000>;
>                                                interrupts = <40>;
>                                        };
>
>                                        rom-interface@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@0x1000 {
>                                        compatible = "sirf,gpsrtc", "sirf,prima2-gpsrtc";
>                                        reg = <0x1000 0x1000>;
>                                        interrupts = <55 56 57>;
>                                };
>
>                                sysrtc@0x2000 {
>                                        compatible = "sirf,sysrtc", "sirf,prima2-sysrtc";
>                                        reg = <0x2000 0x1000>;
>                                        interrupts = <52 53 54>;
>                                };
>
>                                pwrc@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@0xb00E0000 {
>                                        compatible = "sirf,usb", "sirf,prima2-usb";
>                                        reg = <0xb8000000 0x10000>;
>                                        interrupts = <10>;
>                                };
>
>                                usb1: usb@0xb00f0000 {
>                                        compatible = "sirf,usb", "sirf,prima2-usb";
>                                        reg = <0xb8010000 0x10000>;
>                                        interrupts = <11>;
>                                };
>
>                                sata@0xb00f0000 {
>                                        compatible = "sirf,sata", "sirf,prima2-sata";
>                                        reg = <0xb8020000 0x10000>;
>                                        interrupts = <37>;
>                                };
>
>                                security@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@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
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-06  2:10                   ` Barry Song
  0 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-06  2:10 UTC (permalink / raw)
  To: linux-arm-kernel

2011/7/5 Barry Song <21cnbao@gmail.com>:
> Hi Arnd,
>
> 2011/7/1 Barry Song <21cnbao@gmail.com>:
>> Hi Arnd,
>>
>> 2011/6/30 Arnd Bergmann <arnd@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
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-05  8:34                 ` Barry Song
@ 2011-07-06  5:30                     ` Grant Likely
  -1 siblings, 0 replies; 49+ messages in thread
From: Grant Likely @ 2011-07-06  5:30 UTC (permalink / raw)
  To: Barry Song
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tue, Jul 05, 2011 at 04:34:05PM +0800, Barry Song wrote:
> Hi Arnd,
> 
> 2011/7/1 Barry Song <21cnbao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
> > Hi Arnd,
> >
> > 2011/6/30 Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>:
> >> 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 {

memory@0

> 		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@0 {

cpu@0 {

Don't duplicate the crack that powerpc did for cpu node names.  Use a
compatible property to identify the specific CPU model.

> 			device_type = "cpu";

Drop device_type here.

> 			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@0x80040000 {

l2-cache-controller@80040000  (Drop the '0x' from node names; address
in the node name is always hex.

> 			compatible = "arm,pl310-cache", "cache";

Drop the "cache" compatible value here.

> 			reg = <0x80040000 0x1000>;
> 			interrupts = <59>;
> 		};
> 
> 		sirfsoc-iobus {
> 			compatible = "simple-bus";
> 			#address-cells = <1>;
> 			#size-cells = <1>;
> 			ranges = <0x56000000 0x56000000 0x1b0000
> 				0x80010000 0x80010000 0x30000
> 				0x88000000 0x88000000 0x40040000>;
> 
> 			intc: interrupt-controller@0x80020000 {
> 				#interrupt-cells = <1>;
> 				interrupt-controller;
> 				compatible = "sirf,intc", "sirf,prima2-intc";

This looks backwards.  Most specific values should appear first.
"sirf,intc" looks to be generic when compared to "sirf,prima2-intc".
I'm also concerned that "sirf,intc" is trying to be too generic.  As
much as possible compatible values should reflect a real
implementation of the interface, not a generic abstract name.  Future
hardware can always claim compatibility with existing older hardware.
You're probably better off dropping "sirf,intc" entirely, and doing
the same for similar properties throughout the file.

Also, for every new compatible value make sure you add documentation
for it to Documentation/devicetree/bindings. (You may have already
done so, it's just something I remind people about a lot).

These comments also apply through the rest of the file.

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-06  5:30                     ` Grant Likely
  0 siblings, 0 replies; 49+ messages in thread
From: Grant Likely @ 2011-07-06  5:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 05, 2011 at 04:34:05PM +0800, Barry Song wrote:
> Hi Arnd,
> 
> 2011/7/1 Barry Song <21cnbao@gmail.com>:
> > Hi Arnd,
> >
> > 2011/6/30 Arnd Bergmann <arnd@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 {

memory at 0

> 		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 {

cpu at 0 {

Don't duplicate the crack that powerpc did for cpu node names.  Use a
compatible property to identify the specific CPU model.

> 			device_type = "cpu";

Drop device_type here.

> 			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 {

l2-cache-controller at 80040000  (Drop the '0x' from node names; address
in the node name is always hex.

> 			compatible = "arm,pl310-cache", "cache";

Drop the "cache" compatible value here.

> 			reg = <0x80040000 0x1000>;
> 			interrupts = <59>;
> 		};
> 
> 		sirfsoc-iobus {
> 			compatible = "simple-bus";
> 			#address-cells = <1>;
> 			#size-cells = <1>;
> 			ranges = <0x56000000 0x56000000 0x1b0000
> 				0x80010000 0x80010000 0x30000
> 				0x88000000 0x88000000 0x40040000>;
> 
> 			intc: interrupt-controller at 0x80020000 {
> 				#interrupt-cells = <1>;
> 				interrupt-controller;
> 				compatible = "sirf,intc", "sirf,prima2-intc";

This looks backwards.  Most specific values should appear first.
"sirf,intc" looks to be generic when compared to "sirf,prima2-intc".
I'm also concerned that "sirf,intc" is trying to be too generic.  As
much as possible compatible values should reflect a real
implementation of the interface, not a generic abstract name.  Future
hardware can always claim compatibility with existing older hardware.
You're probably better off dropping "sirf,intc" entirely, and doing
the same for similar properties throughout the file.

Also, for every new compatible value make sure you add documentation
for it to Documentation/devicetree/bindings. (You may have already
done so, it's just something I remind people about a lot).

These comments also apply through the rest of the file.

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-06  5:30                     ` Grant Likely
@ 2011-07-06  5:58                         ` Barry Song
  -1 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-06  5:58 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

2011/7/6 Grant Likely <grant.likely@secretlab.ca>:
> On Tue, Jul 05, 2011 at 04:34:05PM +0800, Barry Song wrote:
>> Hi Arnd,
>>
>> 2011/7/1 Barry Song <21cnbao@gmail.com>:
>> > Hi Arnd,
>> >
>> > 2011/6/30 Arnd Bergmann <arnd@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 {
>
> memory@0
>
>>               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@0 {
>
> cpu@0 {
>
> Don't duplicate the crack that powerpc did for cpu node names.  Use a
> compatible property to identify the specific CPU model.
>
>>                       device_type = "cpu";
>
> Drop device_type here.
>
>>                       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@0x80040000 {
>
> l2-cache-controller@80040000  (Drop the '0x' from node names; address
> in the node name is always hex.
>
>>                       compatible = "arm,pl310-cache", "cache";
>
> Drop the "cache" compatible value here.
>
>>                       reg = <0x80040000 0x1000>;
>>                       interrupts = <59>;
>>               };
>>
>>               sirfsoc-iobus {
>>                       compatible = "simple-bus";
>>                       #address-cells = <1>;
>>                       #size-cells = <1>;
>>                       ranges = <0x56000000 0x56000000 0x1b0000
>>                               0x80010000 0x80010000 0x30000
>>                               0x88000000 0x88000000 0x40040000>;
>>
>>                       intc: interrupt-controller@0x80020000 {
>>                               #interrupt-cells = <1>;
>>                               interrupt-controller;
>>                               compatible = "sirf,intc", "sirf,prima2-intc";
>
> This looks backwards.  Most specific values should appear first.
> "sirf,intc" looks to be generic when compared to "sirf,prima2-intc".
> I'm also concerned that "sirf,intc" is trying to be too generic.  As
> much as possible compatible values should reflect a real
> implementation of the interface, not a generic abstract name.  Future
> hardware can always claim compatibility with existing older hardware.
> You're probably better off dropping "sirf,intc" entirely, and doing
> the same for similar properties throughout the file.

i have been confused by compatible in dts and drivers for some time.
if an intc ip core is shared by two chips, for example, prima2 and
atlas6. is the following right?

in dts for prima2: compatible = "sirf,prima2-intc";
in dts for atlas6:  compatible = "sirf,prima2-atlas6";
in intc drivers shared for both:     compatible = "sirf,prima2-intc",
"sirf,prima2-atlas6";

in my understanding, dts for special soc/board contains special
compatible for the chip, drivers shared by multi-soc/board contain all
compatible lists which can be supported by them?

what's the generic way for this?

>
> Also, for every new compatible value make sure you add documentation
> for it to Documentation/devicetree/bindings. (You may have already
> done so, it's just something I remind people about a lot).
>
> These comments also apply through the rest of the file.
>
>
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-06  5:58                         ` Barry Song
  0 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-06  5:58 UTC (permalink / raw)
  To: linux-arm-kernel

2011/7/6 Grant Likely <grant.likely@secretlab.ca>:
> On Tue, Jul 05, 2011 at 04:34:05PM +0800, Barry Song wrote:
>> Hi Arnd,
>>
>> 2011/7/1 Barry Song <21cnbao@gmail.com>:
>> > Hi Arnd,
>> >
>> > 2011/6/30 Arnd Bergmann <arnd@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 {
>
> memory at 0
>
>> ? ? ? ? ? ? ? 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 {
>
> cpu at 0 {
>
> Don't duplicate the crack that powerpc did for cpu node names. ?Use a
> compatible property to identify the specific CPU model.
>
>> ? ? ? ? ? ? ? ? ? ? ? device_type = "cpu";
>
> Drop device_type here.
>
>> ? ? ? ? ? ? ? ? ? ? ? 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 {
>
> l2-cache-controller at 80040000 ?(Drop the '0x' from node names; address
> in the node name is always hex.
>
>> ? ? ? ? ? ? ? ? ? ? ? compatible = "arm,pl310-cache", "cache";
>
> Drop the "cache" compatible value here.
>
>> ? ? ? ? ? ? ? ? ? ? ? reg = <0x80040000 0x1000>;
>> ? ? ? ? ? ? ? ? ? ? ? interrupts = <59>;
>> ? ? ? ? ? ? ? };
>>
>> ? ? ? ? ? ? ? sirfsoc-iobus {
>> ? ? ? ? ? ? ? ? ? ? ? compatible = "simple-bus";
>> ? ? ? ? ? ? ? ? ? ? ? #address-cells = <1>;
>> ? ? ? ? ? ? ? ? ? ? ? #size-cells = <1>;
>> ? ? ? ? ? ? ? ? ? ? ? ranges = <0x56000000 0x56000000 0x1b0000
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x80010000 0x80010000 0x30000
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x88000000 0x88000000 0x40040000>;
>>
>> ? ? ? ? ? ? ? ? ? ? ? intc: interrupt-controller at 0x80020000 {
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>;
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? interrupt-controller;
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? compatible = "sirf,intc", "sirf,prima2-intc";
>
> This looks backwards. ?Most specific values should appear first.
> "sirf,intc" looks to be generic when compared to "sirf,prima2-intc".
> I'm also concerned that "sirf,intc" is trying to be too generic. ?As
> much as possible compatible values should reflect a real
> implementation of the interface, not a generic abstract name. ?Future
> hardware can always claim compatibility with existing older hardware.
> You're probably better off dropping "sirf,intc" entirely, and doing
> the same for similar properties throughout the file.

i have been confused by compatible in dts and drivers for some time.
if an intc ip core is shared by two chips, for example, prima2 and
atlas6. is the following right?

in dts for prima2: compatible = "sirf,prima2-intc";
in dts for atlas6:  compatible = "sirf,prima2-atlas6";
in intc drivers shared for both:     compatible = "sirf,prima2-intc",
"sirf,prima2-atlas6";

in my understanding, dts for special soc/board contains special
compatible for the chip, drivers shared by multi-soc/board contain all
compatible lists which can be supported by them?

what's the generic way for this?

>
> Also, for every new compatible value make sure you add documentation
> for it to Documentation/devicetree/bindings. (You may have already
> done so, it's just something I remind people about a lot).
>
> These comments also apply through the rest of the file.
>
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-06  5:58                         ` Barry Song
@ 2011-07-06  6:01                             ` Barry Song
  -1 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-06  6:01 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

2011/7/6 Barry Song <21cnbao@gmail.com>:
> 2011/7/6 Grant Likely <grant.likely@secretlab.ca>:
>> On Tue, Jul 05, 2011 at 04:34:05PM +0800, Barry Song wrote:
>>> Hi Arnd,
>>>
>>> 2011/7/1 Barry Song <21cnbao@gmail.com>:
>>> > Hi Arnd,
>>> >
>>> > 2011/6/30 Arnd Bergmann <arnd@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 {
>>
>> memory@0
>>
>>>               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@0 {
>>
>> cpu@0 {
>>
>> Don't duplicate the crack that powerpc did for cpu node names.  Use a
>> compatible property to identify the specific CPU model.
>>
>>>                       device_type = "cpu";
>>
>> Drop device_type here.
>>
>>>                       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@0x80040000 {
>>
>> l2-cache-controller@80040000  (Drop the '0x' from node names; address
>> in the node name is always hex.
>>
>>>                       compatible = "arm,pl310-cache", "cache";
>>
>> Drop the "cache" compatible value here.
>>
>>>                       reg = <0x80040000 0x1000>;
>>>                       interrupts = <59>;
>>>               };
>>>
>>>               sirfsoc-iobus {
>>>                       compatible = "simple-bus";
>>>                       #address-cells = <1>;
>>>                       #size-cells = <1>;
>>>                       ranges = <0x56000000 0x56000000 0x1b0000
>>>                               0x80010000 0x80010000 0x30000
>>>                               0x88000000 0x88000000 0x40040000>;
>>>
>>>                       intc: interrupt-controller@0x80020000 {
>>>                               #interrupt-cells = <1>;
>>>                               interrupt-controller;
>>>                               compatible = "sirf,intc", "sirf,prima2-intc";
>>
>> This looks backwards.  Most specific values should appear first.
>> "sirf,intc" looks to be generic when compared to "sirf,prima2-intc".
>> I'm also concerned that "sirf,intc" is trying to be too generic.  As
>> much as possible compatible values should reflect a real
>> implementation of the interface, not a generic abstract name.  Future
>> hardware can always claim compatibility with existing older hardware.
>> You're probably better off dropping "sirf,intc" entirely, and doing
>> the same for similar properties throughout the file.
>
> i have been confused by compatible in dts and drivers for some time.
> if an intc ip core is shared by two chips, for example, prima2 and
> atlas6. is the following right?
>
> in dts for prima2: compatible = "sirf,prima2-intc";
> in dts for atlas6:  compatible = "sirf,prima2-atlas6";

sorry for typo. in dts for atlas6:  compatible = "sirf,atlas6-intc";

> in intc drivers shared for both:     compatible = "sirf,prima2-intc",
> "sirf,prima2-atlas6";

sorry for typo.  compatible = "sirf,prima2-intc", "sirf,atlas6-intc";

>
> in my understanding, dts for special soc/board contains special
> compatible for the chip, drivers shared by multi-soc/board contain all
> compatible lists which can be supported by them?
>
> what's the generic way for this?
>
>>
>> Also, for every new compatible value make sure you add documentation
>> for it to Documentation/devicetree/bindings. (You may have already
>> done so, it's just something I remind people about a lot).
>>
>> These comments also apply through the rest of the file.
>>
>>
>
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-06  6:01                             ` Barry Song
  0 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-06  6:01 UTC (permalink / raw)
  To: linux-arm-kernel

2011/7/6 Barry Song <21cnbao@gmail.com>:
> 2011/7/6 Grant Likely <grant.likely@secretlab.ca>:
>> On Tue, Jul 05, 2011 at 04:34:05PM +0800, Barry Song wrote:
>>> Hi Arnd,
>>>
>>> 2011/7/1 Barry Song <21cnbao@gmail.com>:
>>> > Hi Arnd,
>>> >
>>> > 2011/6/30 Arnd Bergmann <arnd@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 {
>>
>> memory at 0
>>
>>> ? ? ? ? ? ? ? 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 {
>>
>> cpu at 0 {
>>
>> Don't duplicate the crack that powerpc did for cpu node names. ?Use a
>> compatible property to identify the specific CPU model.
>>
>>> ? ? ? ? ? ? ? ? ? ? ? device_type = "cpu";
>>
>> Drop device_type here.
>>
>>> ? ? ? ? ? ? ? ? ? ? ? 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 {
>>
>> l2-cache-controller at 80040000 ?(Drop the '0x' from node names; address
>> in the node name is always hex.
>>
>>> ? ? ? ? ? ? ? ? ? ? ? compatible = "arm,pl310-cache", "cache";
>>
>> Drop the "cache" compatible value here.
>>
>>> ? ? ? ? ? ? ? ? ? ? ? reg = <0x80040000 0x1000>;
>>> ? ? ? ? ? ? ? ? ? ? ? interrupts = <59>;
>>> ? ? ? ? ? ? ? };
>>>
>>> ? ? ? ? ? ? ? sirfsoc-iobus {
>>> ? ? ? ? ? ? ? ? ? ? ? compatible = "simple-bus";
>>> ? ? ? ? ? ? ? ? ? ? ? #address-cells = <1>;
>>> ? ? ? ? ? ? ? ? ? ? ? #size-cells = <1>;
>>> ? ? ? ? ? ? ? ? ? ? ? ranges = <0x56000000 0x56000000 0x1b0000
>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x80010000 0x80010000 0x30000
>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x88000000 0x88000000 0x40040000>;
>>>
>>> ? ? ? ? ? ? ? ? ? ? ? intc: interrupt-controller at 0x80020000 {
>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>;
>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? interrupt-controller;
>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? compatible = "sirf,intc", "sirf,prima2-intc";
>>
>> This looks backwards. ?Most specific values should appear first.
>> "sirf,intc" looks to be generic when compared to "sirf,prima2-intc".
>> I'm also concerned that "sirf,intc" is trying to be too generic. ?As
>> much as possible compatible values should reflect a real
>> implementation of the interface, not a generic abstract name. ?Future
>> hardware can always claim compatibility with existing older hardware.
>> You're probably better off dropping "sirf,intc" entirely, and doing
>> the same for similar properties throughout the file.
>
> i have been confused by compatible in dts and drivers for some time.
> if an intc ip core is shared by two chips, for example, prima2 and
> atlas6. is the following right?
>
> in dts for prima2: compatible = "sirf,prima2-intc";
> in dts for atlas6: ?compatible = "sirf,prima2-atlas6";

sorry for typo. in dts for atlas6:  compatible = "sirf,atlas6-intc";

> in intc drivers shared for both: ? ? compatible = "sirf,prima2-intc",
> "sirf,prima2-atlas6";

sorry for typo.  compatible = "sirf,prima2-intc", "sirf,atlas6-intc";

>
> in my understanding, dts for special soc/board contains special
> compatible for the chip, drivers shared by multi-soc/board contain all
> compatible lists which can be supported by them?
>
> what's the generic way for this?
>
>>
>> Also, for every new compatible value make sure you add documentation
>> for it to Documentation/devicetree/bindings. (You may have already
>> done so, it's just something I remind people about a lot).
>>
>> These comments also apply through the rest of the file.
>>
>>
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-06  6:01                             ` Barry Song
@ 2011-07-06  6:28                                 ` Grant Likely
  -1 siblings, 0 replies; 49+ messages in thread
From: Grant Likely @ 2011-07-06  6:28 UTC (permalink / raw)
  To: Barry Song
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Wed, Jul 06, 2011 at 02:01:24PM +0800, Barry Song wrote:
> 2011/7/6 Barry Song <21cnbao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
> > 2011/7/6 Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>:
> >>>                       intc: interrupt-controller@0x80020000 {
> >>>                               #interrupt-cells = <1>;
> >>>                               interrupt-controller;
> >>>                               compatible = "sirf,intc", "sirf,prima2-intc";
> >>
> >> This looks backwards.  Most specific values should appear first.
> >> "sirf,intc" looks to be generic when compared to "sirf,prima2-intc".
> >> I'm also concerned that "sirf,intc" is trying to be too generic.  As
> >> much as possible compatible values should reflect a real
> >> implementation of the interface, not a generic abstract name.  Future
> >> hardware can always claim compatibility with existing older hardware.
> >> You're probably better off dropping "sirf,intc" entirely, and doing
> >> the same for similar properties throughout the file.
> >
> > i have been confused by compatible in dts and drivers for some time.
> > if an intc ip core is shared by two chips, for example, prima2 and
> > atlas6. is the following right?
> >
> > in dts for prima2: compatible = "sirf,prima2-intc";
> > in dts for atlas6:  compatible = "sirf,prima2-atlas6";
> 
> sorry for typo. in dts for atlas6:  compatible = "sirf,atlas6-intc";
> 
> > in intc drivers shared for both:     compatible = "sirf,prima2-intc",
> > "sirf,prima2-atlas6";
> 
> sorry for typo.  compatible = "sirf,prima2-intc", "sirf,atlas6-intc";
> 

Yes, that is one way to do it, just specify all the implementations
using the IP core.  If there are only a few, then this is easy.  If
there are a lot of implementations using the same core, then the list
gets rather large in a hurry.

The intent of compatible is to allow one device to claim compatibility
with another.  So, if the prima2 was already supported, and you were adding
atlas6 support, you could put the following into the atlas6 .dts:

	compatible = "sirf,atlas6-intc", "airf,prima2-intc";

and the existing driver would work.

The other option when working with IP cores it so encode the version
of the IP block into the compatible values, and make both boards use
that.  ie.  "sirf,intc-1.32".  *however* doing so requires that the
hardware folks actually do a good job of documenting the core versions
so that the compatible value you use accurately describes the
hardware.

It is also completely valid for a newer IP core to claim compatibility
with an older one in the .dts:

	ie: compatible = "sirf,intc-1.32", "sirf,intc-1.00";

Personally, I prefer anchoring compatible values to the specific
hardware implmentation rather than the IP core version.

> >
> > in my understanding, dts for special soc/board contains special
> > compatible for the chip, drivers shared by multi-soc/board contain all
> > compatible lists which can be supported by them?
> >
> > what's the generic way for this?
> >
> >>
> >> Also, for every new compatible value make sure you add documentation
> >> for it to Documentation/devicetree/bindings. (You may have already
> >> done so, it's just something I remind people about a lot).
> >>
> >> These comments also apply through the rest of the file.
> >>
> >>
> >

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-06  6:28                                 ` Grant Likely
  0 siblings, 0 replies; 49+ messages in thread
From: Grant Likely @ 2011-07-06  6:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 06, 2011 at 02:01:24PM +0800, Barry Song wrote:
> 2011/7/6 Barry Song <21cnbao@gmail.com>:
> > 2011/7/6 Grant Likely <grant.likely@secretlab.ca>:
> >>> ? ? ? ? ? ? ? ? ? ? ? intc: interrupt-controller at 0x80020000 {
> >>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>;
> >>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? interrupt-controller;
> >>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? compatible = "sirf,intc", "sirf,prima2-intc";
> >>
> >> This looks backwards. ?Most specific values should appear first.
> >> "sirf,intc" looks to be generic when compared to "sirf,prima2-intc".
> >> I'm also concerned that "sirf,intc" is trying to be too generic. ?As
> >> much as possible compatible values should reflect a real
> >> implementation of the interface, not a generic abstract name. ?Future
> >> hardware can always claim compatibility with existing older hardware.
> >> You're probably better off dropping "sirf,intc" entirely, and doing
> >> the same for similar properties throughout the file.
> >
> > i have been confused by compatible in dts and drivers for some time.
> > if an intc ip core is shared by two chips, for example, prima2 and
> > atlas6. is the following right?
> >
> > in dts for prima2: compatible = "sirf,prima2-intc";
> > in dts for atlas6: ?compatible = "sirf,prima2-atlas6";
> 
> sorry for typo. in dts for atlas6:  compatible = "sirf,atlas6-intc";
> 
> > in intc drivers shared for both: ? ? compatible = "sirf,prima2-intc",
> > "sirf,prima2-atlas6";
> 
> sorry for typo.  compatible = "sirf,prima2-intc", "sirf,atlas6-intc";
> 

Yes, that is one way to do it, just specify all the implementations
using the IP core.  If there are only a few, then this is easy.  If
there are a lot of implementations using the same core, then the list
gets rather large in a hurry.

The intent of compatible is to allow one device to claim compatibility
with another.  So, if the prima2 was already supported, and you were adding
atlas6 support, you could put the following into the atlas6 .dts:

	compatible = "sirf,atlas6-intc", "airf,prima2-intc";

and the existing driver would work.

The other option when working with IP cores it so encode the version
of the IP block into the compatible values, and make both boards use
that.  ie.  "sirf,intc-1.32".  *however* doing so requires that the
hardware folks actually do a good job of documenting the core versions
so that the compatible value you use accurately describes the
hardware.

It is also completely valid for a newer IP core to claim compatibility
with an older one in the .dts:

	ie: compatible = "sirf,intc-1.32", "sirf,intc-1.00";

Personally, I prefer anchoring compatible values to the specific
hardware implmentation rather than the IP core version.

> >
> > in my understanding, dts for special soc/board contains special
> > compatible for the chip, drivers shared by multi-soc/board contain all
> > compatible lists which can be supported by them?
> >
> > what's the generic way for this?
> >
> >>
> >> Also, for every new compatible value make sure you add documentation
> >> for it to Documentation/devicetree/bindings. (You may have already
> >> done so, it's just something I remind people about a lot).
> >>
> >> These comments also apply through the rest of the file.
> >>
> >>
> >

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-06  6:28                                 ` Grant Likely
@ 2011-07-06  7:03                                     ` Barry Song
  -1 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-06  7:03 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi Grant,
Thanks.

2011/7/6 Grant Likely <grant.likely@secretlab.ca>:
> On Wed, Jul 06, 2011 at 02:01:24PM +0800, Barry Song wrote:
>> 2011/7/6 Barry Song <21cnbao@gmail.com>:
>> > 2011/7/6 Grant Likely <grant.likely@secretlab.ca>:
>> >>>                       intc: interrupt-controller@0x80020000 {
>> >>>                               #interrupt-cells = <1>;
>> >>>                               interrupt-controller;
>> >>>                               compatible = "sirf,intc", "sirf,prima2-intc";
>> >>
>> >> This looks backwards.  Most specific values should appear first.
>> >> "sirf,intc" looks to be generic when compared to "sirf,prima2-intc".
>> >> I'm also concerned that "sirf,intc" is trying to be too generic.  As
>> >> much as possible compatible values should reflect a real
>> >> implementation of the interface, not a generic abstract name.  Future
>> >> hardware can always claim compatibility with existing older hardware.
>> >> You're probably better off dropping "sirf,intc" entirely, and doing
>> >> the same for similar properties throughout the file.
>> >
>> > i have been confused by compatible in dts and drivers for some time.
>> > if an intc ip core is shared by two chips, for example, prima2 and
>> > atlas6. is the following right?
>> >
>> > in dts for prima2: compatible = "sirf,prima2-intc";
>> > in dts for atlas6:  compatible = "sirf,prima2-atlas6";
>>
>> sorry for typo. in dts for atlas6:  compatible = "sirf,atlas6-intc";
>>
>> > in intc drivers shared for both:     compatible = "sirf,prima2-intc",
>> > "sirf,prima2-atlas6";
>>
>> sorry for typo.  compatible = "sirf,prima2-intc", "sirf,atlas6-intc";
>>
>
> Yes, that is one way to do it, just specify all the implementations
> using the IP core.  If there are only a few, then this is easy.  If
> there are a lot of implementations using the same core, then the list
> gets rather large in a hurry.
>
> The intent of compatible is to allow one device to claim compatibility
> with another.  So, if the prima2 was already supported, and you were adding
> atlas6 support, you could put the following into the atlas6 .dts:
>
>        compatible = "sirf,atlas6-intc", "airf,prima2-intc";
>
> and the existing driver would work.

it seems you mean if we only support prima2 for the moment:
prima2 .dts:    compatible = "sirf,prima2-intc"
intc driver:       compatible = "sirf,prima2-intc"

then after some time, we bring up atlas6 and find atlas6 can use
prima2 intc driver due to shared ip core, then we let alsta6 .dts
include:
compatible =  "sirf,alsta6-intc", "sirf,prima2-intc"
no matter we change compatible in intc driver to <"sirf,prima2-intc",
"sirf,alsta6-intc"> or not, the driver will always work for alsta6
even only with "sirf,prima2-intc" .

but it seems we will still add "sirf,alsta6-intc" in intc driver if
that really happen in the future. in my understanding, drivers should
explicitly claim all chips or ip cores they can support.

anyway, both prima2.dts and drivers use "sirf,prima2-xxx" should be
the right way for the moment. "sirf, xxx" is too generic now. i will
drop all "sirf, xxx" in both drivers and dts.

>
> The other option when working with IP cores it so encode the version
> of the IP block into the compatible values, and make both boards use
> that.  ie.  "sirf,intc-1.32".  *however* doing so requires that the
> hardware folks actually do a good job of documenting the core versions
> so that the compatible value you use accurately describes the
> hardware.
>
> It is also completely valid for a newer IP core to claim compatibility
> with an older one in the .dts:
>
>        ie: compatible = "sirf,intc-1.32", "sirf,intc-1.00";
>
> Personally, I prefer anchoring compatible values to the specific
> hardware implmentation rather than the IP core version.
>
>> >
>> > in my understanding, dts for special soc/board contains special
>> > compatible for the chip, drivers shared by multi-soc/board contain all
>> > compatible lists which can be supported by them?
>> >
>> > what's the generic way for this?
>> >
>> >>
>> >> Also, for every new compatible value make sure you add documentation
>> >> for it to Documentation/devicetree/bindings. (You may have already
>> >> done so, it's just something I remind people about a lot).
>> >>
>> >> These comments also apply through the rest of the file.
>> >>
>> >>
>> >
-barry
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-06  7:03                                     ` Barry Song
  0 siblings, 0 replies; 49+ messages in thread
From: Barry Song @ 2011-07-06  7:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Grant,
Thanks.

2011/7/6 Grant Likely <grant.likely@secretlab.ca>:
> On Wed, Jul 06, 2011 at 02:01:24PM +0800, Barry Song wrote:
>> 2011/7/6 Barry Song <21cnbao@gmail.com>:
>> > 2011/7/6 Grant Likely <grant.likely@secretlab.ca>:
>> >>> ? ? ? ? ? ? ? ? ? ? ? intc: interrupt-controller at 0x80020000 {
>> >>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <1>;
>> >>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? interrupt-controller;
>> >>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? compatible = "sirf,intc", "sirf,prima2-intc";
>> >>
>> >> This looks backwards. ?Most specific values should appear first.
>> >> "sirf,intc" looks to be generic when compared to "sirf,prima2-intc".
>> >> I'm also concerned that "sirf,intc" is trying to be too generic. ?As
>> >> much as possible compatible values should reflect a real
>> >> implementation of the interface, not a generic abstract name. ?Future
>> >> hardware can always claim compatibility with existing older hardware.
>> >> You're probably better off dropping "sirf,intc" entirely, and doing
>> >> the same for similar properties throughout the file.
>> >
>> > i have been confused by compatible in dts and drivers for some time.
>> > if an intc ip core is shared by two chips, for example, prima2 and
>> > atlas6. is the following right?
>> >
>> > in dts for prima2: compatible = "sirf,prima2-intc";
>> > in dts for atlas6: ?compatible = "sirf,prima2-atlas6";
>>
>> sorry for typo. in dts for atlas6: ?compatible = "sirf,atlas6-intc";
>>
>> > in intc drivers shared for both: ? ? compatible = "sirf,prima2-intc",
>> > "sirf,prima2-atlas6";
>>
>> sorry for typo. ?compatible = "sirf,prima2-intc", "sirf,atlas6-intc";
>>
>
> Yes, that is one way to do it, just specify all the implementations
> using the IP core. ?If there are only a few, then this is easy. ?If
> there are a lot of implementations using the same core, then the list
> gets rather large in a hurry.
>
> The intent of compatible is to allow one device to claim compatibility
> with another. ?So, if the prima2 was already supported, and you were adding
> atlas6 support, you could put the following into the atlas6 .dts:
>
> ? ? ? ?compatible = "sirf,atlas6-intc", "airf,prima2-intc";
>
> and the existing driver would work.

it seems you mean if we only support prima2 for the moment:
prima2 .dts:    compatible = "sirf,prima2-intc"
intc driver:       compatible = "sirf,prima2-intc"

then after some time, we bring up atlas6 and find atlas6 can use
prima2 intc driver due to shared ip core, then we let alsta6 .dts
include:
compatible =  "sirf,alsta6-intc", "sirf,prima2-intc"
no matter we change compatible in intc driver to <"sirf,prima2-intc",
"sirf,alsta6-intc"> or not, the driver will always work for alsta6
even only with "sirf,prima2-intc" .

but it seems we will still add "sirf,alsta6-intc" in intc driver if
that really happen in the future. in my understanding, drivers should
explicitly claim all chips or ip cores they can support.

anyway, both prima2.dts and drivers use "sirf,prima2-xxx" should be
the right way for the moment. "sirf, xxx" is too generic now. i will
drop all "sirf, xxx" in both drivers and dts.

>
> The other option when working with IP cores it so encode the version
> of the IP block into the compatible values, and make both boards use
> that. ?ie. ?"sirf,intc-1.32". ?*however* doing so requires that the
> hardware folks actually do a good job of documenting the core versions
> so that the compatible value you use accurately describes the
> hardware.
>
> It is also completely valid for a newer IP core to claim compatibility
> with an older one in the .dts:
>
> ? ? ? ?ie: compatible = "sirf,intc-1.32", "sirf,intc-1.00";
>
> Personally, I prefer anchoring compatible values to the specific
> hardware implmentation rather than the IP core version.
>
>> >
>> > in my understanding, dts for special soc/board contains special
>> > compatible for the chip, drivers shared by multi-soc/board contain all
>> > compatible lists which can be supported by them?
>> >
>> > what's the generic way for this?
>> >
>> >>
>> >> Also, for every new compatible value make sure you add documentation
>> >> for it to Documentation/devicetree/bindings. (You may have already
>> >> done so, it's just something I remind people about a lot).
>> >>
>> >> These comments also apply through the rest of the file.
>> >>
>> >>
>> >
-barry

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
  2011-07-06  7:03                                     ` Barry Song
@ 2011-07-06  7:40                                         ` Arnd Bergmann
  -1 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-07-06  7:40 UTC (permalink / raw)
  To: Barry Song
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	workgroup.linux-kQvG35nSl+M, weizeng.he-kQvG35nSl+M,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Wednesday 06 July 2011 09:03:45 Barry Song wrote:
> but it seems we will still add "sirf,alsta6-intc" in intc driver if
> that really happen in the future. in my understanding, drivers should
> explicitly claim all chips or ip cores they can support.

I don't think there is a need for that. I'd only add the second
one if there is a need in the driver to tell the difference.
In that case, you can add a data field to the device_id and use
that for making decisions in the driver.

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support
@ 2011-07-06  7:40                                         ` Arnd Bergmann
  0 siblings, 0 replies; 49+ messages in thread
From: Arnd Bergmann @ 2011-07-06  7:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 06 July 2011 09:03:45 Barry Song wrote:
> but it seems we will still add "sirf,alsta6-intc" in intc driver if
> that really happen in the future. in my understanding, drivers should
> explicitly claim all chips or ip cores they can support.

I don't think there is a need for that. I'd only add the second
one if there is a need in the driver to tell the difference.
In that case, you can add a data field to the device_id and use
that for making decisions in the driver.

	Arnd

^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2011-07-06  7:40 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-28  3:32 [PATCH v2] ARM: CSR: Adding CSR SiRFprimaII board support Barry Song
     [not found] ` <1309231954-23260-1-git-send-email-bs14-kQvG35nSl+M@public.gmane.org>
2011-06-29 21:29   ` Arnd Bergmann
2011-06-29 21:29     ` Arnd Bergmann
     [not found]     ` <201106292329.44447.arnd-r2nGTMty4D4@public.gmane.org>
2011-06-30  3:39       ` Barry Song
2011-06-30  3:39         ` Barry Song
2011-06-30  7:19     ` Barry Song
2011-06-30  7:19       ` Barry Song
     [not found]       ` <BANLkTinfKCMcutMDQ+mpdD4EUy9mCpZs+w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-06-30 10:36         ` Arnd Bergmann
2011-06-30 10:36           ` Arnd Bergmann
2011-07-01  0:04           ` Barry Song
2011-07-01  0:04             ` Barry Song
2011-07-01 16:26             ` Arnd Bergmann
2011-07-01 16:26               ` Arnd Bergmann
     [not found]             ` <BANLkTinkHcuXuWpCxq3tnU_10trPTjDucg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-07-04 14:59               ` Grant Likely
2011-07-04 14:59                 ` Grant Likely
     [not found]           ` <201106301236.25822.arnd-r2nGTMty4D4@public.gmane.org>
2011-06-30 15:03             ` Rob Herring
2011-06-30 15:03               ` Rob Herring
2011-07-01  6:20             ` Barry Song
2011-07-01  6:20               ` Barry Song
     [not found]               ` <BANLkTikoMu3ccUxj5KRmKzdReQcBqK4Y9Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-07-01 16:19                 ` Arnd Bergmann
2011-07-01 16:19                   ` Arnd Bergmann
2011-07-02 12:25                   ` Russell King - ARM Linux
2011-07-02 12:25                     ` Russell King - ARM Linux
     [not found]                     ` <20110702122527.GH21898-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>
2011-07-02 19:34                       ` Arnd Bergmann
2011-07-02 19:34                         ` Arnd Bergmann
     [not found]                   ` <201107011819.43316.arnd-r2nGTMty4D4@public.gmane.org>
2011-07-04  2:55                     ` Barry Song
2011-07-04  2:55                       ` Barry Song
2011-07-04 14:53                       ` Arnd Bergmann
2011-07-04 14:53                         ` Arnd Bergmann
     [not found]                         ` <201107041653.50962.arnd-r2nGTMty4D4@public.gmane.org>
2011-07-05  1:32                           ` Barry Song
2011-07-05  1:32                             ` Barry Song
     [not found]                             ` <CAGsJ_4wf0Lhe2yHg1fE2QAF40=J6ZoubpfLFWQ6X9o3db0O8LQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-07-05 11:10                               ` Arnd Bergmann
2011-07-05 11:10                                 ` Arnd Bergmann
2011-07-05  8:34               ` Barry Song
2011-07-05  8:34                 ` Barry Song
2011-07-06  2:10                 ` Barry Song
2011-07-06  2:10                   ` Barry Song
     [not found]                 ` <CAGsJ_4wSKP6EUihOVbUJJ+HUynWGp8PA=8J_WhgmOtVhpd5_Lg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-07-06  5:30                   ` Grant Likely
2011-07-06  5:30                     ` Grant Likely
     [not found]                     ` <20110706053026.GB9978-e0URQFbLeQY2iJbIjFUEsiwD8/FfD2ys@public.gmane.org>
2011-07-06  5:58                       ` Barry Song
2011-07-06  5:58                         ` Barry Song
     [not found]                         ` <CAGsJ_4xV7ecdqnB5gJDUDSg4nvebgubBj4qGJGaCtcpbj-b0gQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-07-06  6:01                           ` Barry Song
2011-07-06  6:01                             ` Barry Song
     [not found]                             ` <CAGsJ_4yxUzMr4EJd5i0oW1tOa2oK7jicAehKVXXiU_SMDpTQ0Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-07-06  6:28                               ` Grant Likely
2011-07-06  6:28                                 ` Grant Likely
     [not found]                                 ` <20110706062838.GI9978-e0URQFbLeQY2iJbIjFUEsiwD8/FfD2ys@public.gmane.org>
2011-07-06  7:03                                   ` Barry Song
2011-07-06  7:03                                     ` Barry Song
     [not found]                                     ` <CAGsJ_4xUsw21EM2GXMt4i27MGjCP_h46tCzhDqo-MCZkAVsEiw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-07-06  7:40                                       ` Arnd Bergmann
2011-07-06  7:40                                         ` Arnd Bergmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.