[PATCH 2/9] ARM: SPMP8000: Add machine base files

Zoltan Devai zoss at devai.org
Sun Oct 9 12:36:05 EDT 2011


Add the files for the basic support of the SPMP8000 SoC

Signed-off-by: Zoltan Devai <zoss at devai.org>
---
 arch/arm/mach-spmp8000/Makefile                   |   11 ++
 arch/arm/mach-spmp8000/Makefile.boot              |    1 +
 arch/arm/mach-spmp8000/core.c                     |  103 +++++++++++++
 arch/arm/mach-spmp8000/include/mach/core.h        |   29 ++++
 arch/arm/mach-spmp8000/include/mach/debug-macro.S |   19 +++
 arch/arm/mach-spmp8000/include/mach/dma.h         |   45 ++++++
 arch/arm/mach-spmp8000/include/mach/entry-macro.S |   14 ++
 arch/arm/mach-spmp8000/include/mach/gpio.h        |   21 +++
 arch/arm/mach-spmp8000/include/mach/hardware.h    |   27 ++++
 arch/arm/mach-spmp8000/include/mach/io.h          |   20 +++
 arch/arm/mach-spmp8000/include/mach/irqs.h        |   21 +++
 arch/arm/mach-spmp8000/include/mach/memory.h      |   16 ++
 arch/arm/mach-spmp8000/include/mach/regs-timer.h  |   32 ++++
 arch/arm/mach-spmp8000/include/mach/scu.h         |  146 +++++++++++++++++++
 arch/arm/mach-spmp8000/include/mach/system.h      |   45 ++++++
 arch/arm/mach-spmp8000/include/mach/timex.h       |   17 +++
 arch/arm/mach-spmp8000/include/mach/uncompress.h  |   37 +++++
 arch/arm/mach-spmp8000/include/mach/vmalloc.h     |   16 ++
 arch/arm/mach-spmp8000/timer.c                    |  160 +++++++++++++++++++++
 19 files changed, 780 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-spmp8000/Makefile
 create mode 100644 arch/arm/mach-spmp8000/Makefile.boot
 create mode 100644 arch/arm/mach-spmp8000/core.c
 create mode 100644 arch/arm/mach-spmp8000/include/mach/core.h
 create mode 100644 arch/arm/mach-spmp8000/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-spmp8000/include/mach/dma.h
 create mode 100644 arch/arm/mach-spmp8000/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-spmp8000/include/mach/gpio.h
 create mode 100644 arch/arm/mach-spmp8000/include/mach/hardware.h
 create mode 100644 arch/arm/mach-spmp8000/include/mach/io.h
 create mode 100644 arch/arm/mach-spmp8000/include/mach/irqs.h
 create mode 100644 arch/arm/mach-spmp8000/include/mach/memory.h
 create mode 100644 arch/arm/mach-spmp8000/include/mach/regs-timer.h
 create mode 100644 arch/arm/mach-spmp8000/include/mach/scu.h
 create mode 100644 arch/arm/mach-spmp8000/include/mach/system.h
 create mode 100644 arch/arm/mach-spmp8000/include/mach/timex.h
 create mode 100644 arch/arm/mach-spmp8000/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-spmp8000/include/mach/vmalloc.h
 create mode 100644 arch/arm/mach-spmp8000/timer.c

diff --git a/arch/arm/mach-spmp8000/Makefile b/arch/arm/mach-spmp8000/Makefile
new file mode 100644
index 0000000..9d35cca
--- /dev/null
+++ b/arch/arm/mach-spmp8000/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the linux kernel.
+#
+obj-y 			:= core.o
+obj-y			+= timer.o
+obj-y			+= pinmux.o
+obj-y			+= clock.o
+obj-y			+= clkdev.o
+obj-y			+= board_letcool.o
+obj-y			+= adc.o
+obj-y			+= pwm.o
diff --git a/arch/arm/mach-spmp8000/Makefile.boot b/arch/arm/mach-spmp8000/Makefile.boot
new file mode 100644
index 0000000..dae9661
--- /dev/null
+++ b/arch/arm/mach-spmp8000/Makefile.boot
@@ -0,0 +1 @@
+zreladdr-y	:= 0x00008000
diff --git a/arch/arm/mach-spmp8000/core.c b/arch/arm/mach-spmp8000/core.c
new file mode 100644
index 0000000..ba05614
--- /dev/null
+++ b/arch/arm/mach-spmp8000/core.c
@@ -0,0 +1,103 @@
+/*
+ * SPMP8000 machines core functions
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/vic.h>
+#include <mach/hardware.h>
+#include <mach/scu.h>
+
+/* Static mappings:
+ * SCU: timer needs clk support which is inited in init_early
+ * UART: needed for earlyprintk
+ */
+static struct map_desc io_desc[] __initdata = {
+	{
+		.virtual	= IO_ADDRESS(SPMP8000_SCU_A_BASE),
+		.pfn		= __phys_to_pfn(SPMP8000_SCU_A_BASE),
+		.length		= SPMP8000_SCU_A_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(SPMP8000_SCU_B_BASE),
+		.pfn		= __phys_to_pfn(SPMP8000_SCU_B_BASE),
+		.length		= SPMP8000_SCU_B_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(SPMP8000_SCU_C_BASE),
+		.pfn		= __phys_to_pfn(SPMP8000_SCU_C_BASE),
+		.length		= SPMP8000_SCU_C_SIZE,
+		.type		= MT_DEVICE,
+	},
+#ifdef CONFIG_DEBUG_LL
+	{
+		.virtual	= IO_ADDRESS(SPMP8000_UARTC0_BASE),
+		.pfn		= __phys_to_pfn(SPMP8000_UARTC0_BASE),
+		.length		= SPMP8000_UARTC0_SIZE,
+		.type		= MT_DEVICE,
+	},
+#endif
+};
+
+#define IO_PTR(x)	((void __iomem *)IO_ADDRESS(x))
+/* Make the lookup of SCU base and clk enable registers easy for the clk
+ * code, as they are not at the same offset in each controller */
+struct scu_reg_t scu_regs[3] = {
+	{	/* SCU_A */
+		.base = IO_PTR(SPMP8000_SCU_A_BASE),
+		.clken = IO_PTR(SPMP8000_SCU_A_BASE) + SCU_A_PERI_CLKEN,
+	},
+	{	/* SCU_B */
+		.base = IO_PTR(SPMP8000_SCU_B_BASE),
+		.clken = IO_PTR(SPMP8000_SCU_B_BASE) + SCU_B_PERI_CLKEN,
+	},
+	{	/* SCU_C */
+		.base = IO_PTR(SPMP8000_SCU_C_BASE),
+		.clken = IO_PTR(SPMP8000_SCU_C_BASE) + SCU_C_PERI_CLKEN,
+	},
+};
+
+/* DMA controller names to be used for the filter
+ * function of the DMA-Engine API. */
+char *spmp8000_dma_controller_names[] = {
+	"93010000.dma",		/* APBDMA_A */
+	"92b00000.dma",		/* APBDMA_C */
+};
+
+void __init spmp8000_map_io(void)
+{
+	iotable_init(io_desc, ARRAY_SIZE(io_desc));
+}
+
+void __init spmp8000_init_irq(void)
+{
+	struct device_node *np;
+	int ret;
+
+	np = of_find_compatible_node(NULL, NULL, "arm,pl192");
+	if (!np)
+		panic("Can't find VIC0 interrupt controller\n");
+
+	ret = vic_of_init(np, NULL);
+	if (ret)
+		panic("Can't init VIC0 interrupt controller\n");
+
+	np = of_find_compatible_node(np, NULL, "arm,pl192");
+	if (!np)
+		panic("Can't find VIC1 interrupt controller\n");
+
+	ret = vic_of_init(np, NULL);
+	if (ret)
+		panic("Can't init VIC1 interrupt controller\n");
+
+	of_node_put(np);
+}
diff --git a/arch/arm/mach-spmp8000/include/mach/core.h b/arch/arm/mach-spmp8000/include/mach/core.h
new file mode 100644
index 0000000..fa1d522
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/core.h
@@ -0,0 +1,29 @@
+/*
+ * SPMP8000 generic includes
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPMP8000_GENERIC_H__
+#define __MACH_SPMP8000_GENERIC_H__
+
+/* core.c */
+extern void __init spmp8000_map_io(void);
+extern void __init spmp8000_init_irq(void);
+extern struct sys_timer spmp8000_sys_timer;
+
+/* clkdev.c */
+extern void __init spmp8000_init_clkdev(void);
+extern void spmp8000_update_arm_freqs(void); /* For cpufreq driver */
+
+/* pinmux.c */
+extern void spmp8000_pinmux_pgc_set(int pc, unsigned int conf);
+extern unsigned int spmp8000_pinmux_pgc_get(int pc);
+extern void spmp8000_pinmux_pgs_set(unsigned int pg, unsigned int func);
+extern int spmp8000_pinmux_pgs_get(int pg);
+
+#endif /* __MACH_SPMP8000_GENERIC_H__ */
diff --git a/arch/arm/mach-spmp8000/include/mach/debug-macro.S b/arch/arm/mach-spmp8000/include/mach/debug-macro.S
new file mode 100644
index 0000000..698c37e
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/debug-macro.S
@@ -0,0 +1,19 @@
+/*
+ * SPMP8000 debug-macro.S
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+	.macro  addruart, rp, rv
+	mov     \rp, #0x92000000
+	add	\rp, #0x00B00000
+	add	\rp, #0x00004000
+	orr	\rv, \rp, #0xF0000000
+	.endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-spmp8000/include/mach/dma.h b/arch/arm/mach-spmp8000/include/mach/dma.h
new file mode 100644
index 0000000..44bc9f2
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/dma.h
@@ -0,0 +1,45 @@
+/*
+ * SPMP8000 dma.h
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/module.h>
+#include <linux/dmaengine.h>
+
+#ifndef __MACH_SPMP8000_DMA_H__
+#define __MACH_SPMP8000_DMA_H__
+
+enum spmp8000_dma_controller {
+	SPMP8000_APBDMA_A	= 0,
+	SPMP8000_APBDMA_C,
+};
+
+extern char *spmp8000_dma_controller_names[];
+
+struct spmp8000_dma_params {
+	char				*dma_controller;
+	dma_addr_t			dma_address;
+	enum dma_slave_buswidth		dma_width;
+	int				maxburst;
+};
+
+/* Driver parameters */
+#define SPMP8000_APBDMA_MAX_PERIODS	64
+
+static bool spmp8000_dma_filter(struct dma_chan *chan, const char *name)
+{
+	int ret;
+
+	ret = strcmp(dev_name(chan->device->dev), name);
+
+	if (ret)
+		return false;
+
+	return true;
+}
+
+#endif /* __MACH_SPMP8000_DMA_H__ */
diff --git a/arch/arm/mach-spmp8000/include/mach/entry-macro.S b/arch/arm/mach-spmp8000/include/mach/entry-macro.S
new file mode 100644
index 0000000..3d26088
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/entry-macro.S
@@ -0,0 +1,14 @@
+/*
+ * SPMP8000 entry-macro.S
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+	.macro  disable_fiq
+	.endm
+
+	.macro  arch_ret_to_user, tmp1, tmp2
+	.endm
diff --git a/arch/arm/mach-spmp8000/include/mach/gpio.h b/arch/arm/mach-spmp8000/include/mach/gpio.h
new file mode 100644
index 0000000..3eafac2
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/gpio.h
@@ -0,0 +1,21 @@
+/*
+ * SPMP8000 machines gpio support
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPMP8000_GPIO_H__
+#define __MACH_SPMP8000_GPIO_H__
+
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value		__gpio_get_value
+#define gpio_set_value		__gpio_set_value
+#define gpio_cansleep		__gpio_cansleep
+#define gpio_to_irq		__gpio_to_irq
+
+#endif /* __MACH_SPMP8000_GPIO_H__ */
diff --git a/arch/arm/mach-spmp8000/include/mach/hardware.h b/arch/arm/mach-spmp8000/include/mach/hardware.h
new file mode 100644
index 0000000..998a184
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/hardware.h
@@ -0,0 +1,27 @@
+/*
+ * SPMP8000 hardware.h
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPMP8000_HARDWARE_H__
+#define __MACH_SPMP8000_HARDWARE_H__
+
+/* Vitual to physical translation of statically mapped space */
+#define IO_ADDRESS(x)		((x) | 0xF0000000)
+
+/* Needed for the static mappings and uncompress.h */
+#define SPMP8000_UARTC0_BASE	0x92B04000
+#define SPMP8000_UARTC0_SIZE	SZ_4K
+#define SPMP8000_SCU_C_BASE	0x92005000
+#define SPMP8000_SCU_C_SIZE	SZ_4K
+#define SPMP8000_SCU_A_BASE	0x93007000
+#define SPMP8000_SCU_A_SIZE	SZ_4K
+#define SPMP8000_SCU_B_BASE	0x90005000
+#define SPMP8000_SCU_B_SIZE	SZ_4K
+
+#endif /* __MACH_SPMP8000_HARDWARE_H__ */
diff --git a/arch/arm/mach-spmp8000/include/mach/io.h b/arch/arm/mach-spmp8000/include/mach/io.h
new file mode 100644
index 0000000..a8ea8f0
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/io.h
@@ -0,0 +1,20 @@
+/*
+ * SPMP8000 io.h
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPMP8000_IO_H__
+#define __MACH_SPMP8000_IO_H__
+
+/* FIXME This should go away */
+#define IO_SPACE_LIMIT  0
+
+#define __mem_pci(a)    (a)
+#define __io(a)         __typesafe_io(a)
+
+#endif /* __MACH_SPMP8000_IO_H__ */
diff --git a/arch/arm/mach-spmp8000/include/mach/irqs.h b/arch/arm/mach-spmp8000/include/mach/irqs.h
new file mode 100644
index 0000000..7f305d3
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/irqs.h
@@ -0,0 +1,21 @@
+/*
+ * SPMP8000 irqs.h
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPMP8000_IRQS_H__
+#define __MACH_SPMP8000_IRQS_H__
+
+#define SPMP8000_HW_IRQS		64
+#define SPMP8000_GPIO_IRQS_START	SPMP8000_HW_IRQS
+#define SPMP8000_GPIO_IRQS		(16 + 32)
+#define SPMP8000_TOTAL_IRQS		(SPMP8000_HW_IRQS + SPMP8000_GPIO_IRQS)
+
+#define NR_IRQS				SPMP8000_TOTAL_IRQS
+
+#endif /* __MACH_SPMP8000_IRQS_H__ */
diff --git a/arch/arm/mach-spmp8000/include/mach/memory.h b/arch/arm/mach-spmp8000/include/mach/memory.h
new file mode 100644
index 0000000..d2f1089
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/memory.h
@@ -0,0 +1,16 @@
+/*
+ * SPMP8000 memory.h
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPMP8000_MEMORY_H__
+#define __MACH_SPMP8000_MEMORY_H__
+
+#define PLAT_PHYS_OFFSET	UL(0x00000000)
+
+#endif /* __MACH_SPMP8000_MEMORY_H__ */
diff --git a/arch/arm/mach-spmp8000/include/mach/regs-timer.h b/arch/arm/mach-spmp8000/include/mach/regs-timer.h
new file mode 100644
index 0000000..90735df
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/regs-timer.h
@@ -0,0 +1,32 @@
+/*
+ * SPMP8000 timer support
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * These timer reg definitions are used by the timer and pwm drivers
+ */
+#ifndef __MACH_SPMP8000_REGS_TIMER_H__
+#define __MACH_SPMP8000_REGS_TIMER_H__
+
+#define SPMP8000_TMRB(tnum)	(tnum * 0x20)
+#define SPMP8000_TMRB_CTR	0x00
+#define SPMP8000_TMRB_CTR_TE	BIT(0)
+#define SPMP8000_TMRB_CTR_IE	BIT(1)
+#define SPMP8000_TMRB_CTR_OE	BIT(2)
+#define SPMP8000_TMRB_CTR_PWMON	BIT(3)
+#define SPMP8000_TMRB_CTR_UD	BIT(4)
+#define SPMP8000_TMRB_CTR_UDS	BIT(5)
+#define SPMP8000_TMRB_CTR_OM	BIT(6)
+#define SPMP8000_TMRB_CTR_ES_SH	8
+#define SPMP8000_TMRB_CTR_M_SH	10
+#define SPMP8000_TMRB_PSR	0x04
+#define SPMP8000_TMRB_LDR	0x08
+#define SPMP8000_TMRB_VLR	0x08
+#define SPMP8000_TMRB_ISR	0x0C
+#define SPMP8000_TMRB_CMP	0x10
+
+#endif /* __MACH_SPMP8000_REGS_TIMER_H__ */
diff --git a/arch/arm/mach-spmp8000/include/mach/scu.h b/arch/arm/mach-spmp8000/include/mach/scu.h
new file mode 100644
index 0000000..e3a98d4
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/scu.h
@@ -0,0 +1,146 @@
+/*
+ * SPMP8000 System Control Unit register definitions
+ * SCUs are a random collection of reset, clock, gpio, pinmux, etc. controllers
+ * so that these definitions are needed at several places.
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/bitops.h>
+#include <mach/hardware.h>
+
+#ifndef __MACH_SPMP8000_SCU_H__
+#define __MACH_SPMP8000_SCU_H__
+
+/* Used by to the clock code to directly access the SCU base and clock
+ * enabling registers, without looking up the according registers first.
+ */
+struct scu_reg_t {
+	void *base;
+	void *clken;
+};
+
+extern struct scu_reg_t scu_regs[];
+
+#define REG_SCU_BASE(x)		scu_regs[x].base
+#define REG_SCU_CLKEN(x)	scu_regs[x].clken
+#define REG_SCU_A_ID		0
+#define REG_SCU_B_ID		1
+#define REG_SCU_C_ID		2
+#define REG_SCU_A(x)		(scu_regs[REG_SCU_A_ID].base + x)
+#define REG_SCU_B(x)		(scu_regs[REG_SCU_B_ID].base + x)
+#define REG_SCU_C(x)		(scu_regs[REG_SCU_C_ID].base + x)
+
+#define SCU_A_PERI_RST		0x00
+#define SCU_A_PERI_CLKEN	0x04
+#define SCU_A_PERI_DGCLKEN	0x0C
+
+#define SCU_A_APLL_CFG		0x44
+#define APLL_CFG_P		BIT(0)
+#define APLL_CFG_S		BIT(1)
+#define APLL_CFG_F		BIT(2)
+#define APLL_CFG_E		BIT(3)
+#define APLL_CFG_AS_MASK	0x3F0
+#define APLL_CFG_AS_SHIFT	4
+#define APLL_CFG_AS_MAGIC	0x12
+#define APLL_CFG_C		BIT(10)
+#define APLL_CFG_R		BIT(11)
+#define APLL_CFG_DAR_SHIFT	16
+#define APLL_CFG_DAR_MASK	(7 << APLL_CFG_DAR_SHIFT)
+#define APLL_CFG_DS		BIT(19)
+#define APLL_CFG_ADR_SHIFT	24
+#define APLL_CFG_ADR_MASK	(7 << APLL_CFG_ADR_SHIFT)
+#define APLL_CFG_AS		BIT(27)
+
+#define SCU_A_LCD_CLK_CFG	0x80
+#define LCD_CLK_CFG_RATIO_MASK	0xFF
+#define LCD_CLK_CFG_EN		BIT(8)
+#define SCU_A_CSI_CLK_CFG	0x84
+#define CSI_CLK_CFG_RATIO_MASK	0xFF
+#define CSI_CLK_CFG_EN		BIT(8)
+#define SCU_A_I2S_BCK_CFG	0x90
+#define I2S_BCK_CFG_RATIO_MASK	0xFF
+#define I2S_BCK_CFG_EN		BIT(8)
+#define SCU_A_UART_CFG		0x94
+#define UART_CFG_RATIO_MASK	0xFF
+#define UART_CFG_EN		BIT(8)
+#define DIVIDER_ENABLE_BIT	BIT(8)
+
+#define SCU_A_CODEC_CFG		0xB0
+#define SCU_A_CODEC_CFG_VAL	0x5A
+
+#define SCU_A_SAR_GPIO_CTRL	0xE0
+#define SCU_A_SAR_GPIO_OEN	0xE4
+#define SCU_A_SAR_GPIO_O	0xE8
+#define SCU_A_SAR_GPIO_I	0xEC
+
+#define SCU_B_PERI_RST		0x00
+#define SCU_B_PERI_CLKEN	0x20
+#define SCU_B_PERI_DGCLKEN	0x24
+#define SCU_B_UPDATE_ARM_RATIO	0x28
+
+#define SCU_B_SPLL_CFG		0x04
+#define SPLL_CFG_R_MASK		3
+#define SPLL_CFG_R_SHIFT	0
+#define SPLL_CFG_F_MASK		0xFC
+#define SPLL_CFG_F_SHIFT	2
+#define SPLL_CFG_BS		BIT(8)
+#define SPLL_CFG_OD		BIT(9)
+#define SPLL_CFG_BP		BIT(10)
+#define SPLL_CFG_PD		BIT(11)
+#define SPLL_CFG_CSEL_MASK	(BIT(13) | BIT(12))
+#define SPLL_CFG_CSEL_SHIFT	12
+#define SPLL_CFG_ASEL_MASK	(BIT(15) | BIT(14))
+#define SPLL_CFG_ASEL_SHIFT	14
+#define SPLL_CFG_SE		BIT(17)
+#define SPLL_CFG_XE		BIT(18)
+#define SPLL_CFG_AE		BIT(19)
+#define SPLL_CFG_XR		BIT(20)
+#define SPLL_CFG_PL		BIT(31)
+
+#define SCU_B_GPIO3_I		0x70
+#define SCU_B_GPIO3_O		0x74
+#define SCU_B_GPIO3_E		0x78
+
+#define SCU_B_PGS0		0x80
+#define SCU_B_PGS1		0x84
+#define SCU_B_PGS2		0x88
+#define SCU_B_PGS3		0x8C
+#define SCU_B_PGC0		0x90
+#define SCU_B_PGC1		0x94
+#define SCU_B_PGC2		0x98
+#define SCU_B_PGC3		0x9C
+
+#define SCU_B_ARM_RATIO		0xD0
+#define SCU_B_ARM_AHB_RATIO	0xD4
+#define SCU_B_ARM_APB_RATIO	0xD8
+#define SCU_B_SYS_CNT_EN	0xDC
+#define SYS_CNT_EN_SYS		BIT(0)
+#define SYS_CNT_EN_SYS_RT	BIT(1)
+#define SYS_CNT_EN_SYS_AHB	BIT(2)
+#define SYS_CNT_EN_SYS_APB	BIT(3)
+#define SYS_CNT_EN_SYS_CHECK	BIT(31)
+
+#define SCU_C_PERI_RST		0x00
+#define SCU_C_PERI_CLKEN	0x04
+#define SCU_C_PERI_DGCLKEN	0x08
+
+#define SCU_C_UPDATE_SYS_RATIO	0x28
+#define SCU_C_SYS_RATIO		0x100
+#define SCU_C_SYS_RT_RATIO	0x104
+#define SCU_C_SYS_AHB_RATIO	0x108
+#define SCU_C_SYS_APB_RATIO	0x10C
+#define SCU_C_CEVA_RATIO	0x110
+#define SCU_C_CEVA_AHB_RATIO	0x114
+#define SCU_C_CEVA_APB_RATIO	0x118
+#define SCU_C_CEVA_CNT_EN	0x11C
+#define CEVA_CNT_EN_CEVA	BIT(0)
+#define CEVA_CNT_EN_CEVA_AHB	BIT(1)
+#define CEVA_CNT_EN_CEVA_APB	BIT(2)
+#define CEVA_CNT_EN_CEVA_CHECK	BIT(31)
+
+#endif /* __MACH_SPMP8000_SCU_H__ */
diff --git a/arch/arm/mach-spmp8000/include/mach/system.h b/arch/arm/mach-spmp8000/include/mach/system.h
new file mode 100644
index 0000000..be53ff3
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/system.h
@@ -0,0 +1,45 @@
+/*
+ * SPMP8000 system.h
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPMP8000_SYSTEM_H__
+#define __MACH_SPMP8000_SYSTEM_H__
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#define SPMP8000_WDT_BASE	0x90001000
+#define SPMP8000_WDT_SIZE	0x1000
+
+#define SPMP8000_WDT_CTR	0x00
+#define SPMP8000_WDT_CTR_TE	BIT(0)
+#define SPMP8000_WDT_CTR_RE	BIT(3)
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	void *base;
+
+	base = ioremap(SPMP8000_WDT_BASE, SPMP8000_WDT_SIZE);
+	if (!base) {
+		pr_err("spmp8000: Can't ioremap watchdog regs for reset. "
+			"Halt.");
+		while (1);
+	}
+
+	/* Trigger a watchdog reset */
+	writel(SPMP8000_WDT_CTR_RE | SPMP8000_WDT_CTR_TE,
+			base + SPMP8000_WDT_CTR);
+}
+
+#endif /* __MACH_SPMP8000_SYSTEM_H__ */
diff --git a/arch/arm/mach-spmp8000/include/mach/timex.h b/arch/arm/mach-spmp8000/include/mach/timex.h
new file mode 100644
index 0000000..77069c2
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/timex.h
@@ -0,0 +1,17 @@
+/*
+ * SPMP8000 timex.h
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPMP8000_TIMEX_H__
+#define __MACH_SPMP8000_TIMEX_H__
+
+/* TODO this should go away */
+#define CLOCK_TICK_RATE		(100 * HZ)
+
+#endif /* __MACH_SPMP8000_TIMEX_H__ */
diff --git a/arch/arm/mach-spmp8000/include/mach/uncompress.h b/arch/arm/mach-spmp8000/include/mach/uncompress.h
new file mode 100644
index 0000000..105778b
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/uncompress.h
@@ -0,0 +1,37 @@
+/*
+ * SPMP8000 uncompress.h
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * Based on the mach-kirkwood implementation
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/serial_reg.h>
+#include <mach/hardware.h>
+
+#define SERIAL_BASE	((volatile unsigned char *)SPMP8000_UARTC0_BASE)
+
+static void putc(const char c)
+{
+	volatile unsigned char *base = SERIAL_BASE;
+	int i;
+
+	for (i = 0; i < 0x1000; i++) {
+		if (base[UART_LSR << 2] & UART_LSR_THRE)
+			break;
+		barrier();
+	}
+
+	base[UART_TX << 2] = c;
+}
+
+static void flush(void)
+{
+}
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-spmp8000/include/mach/vmalloc.h b/arch/arm/mach-spmp8000/include/mach/vmalloc.h
new file mode 100644
index 0000000..ff40d1c
--- /dev/null
+++ b/arch/arm/mach-spmp8000/include/mach/vmalloc.h
@@ -0,0 +1,16 @@
+/*
+ * SPMP8000 vmalloc.h
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPMP8000_VMALLOC_H__
+#define __MACH_SPMP8000_VMALLOC_H__
+
+#define VMALLOC_END	0xF0000000UL
+
+#endif /* __MACH_SPMP8000_VMALLOC_H__ */
diff --git a/arch/arm/mach-spmp8000/timer.c b/arch/arm/mach-spmp8000/timer.c
new file mode 100644
index 0000000..7d5d0eb
--- /dev/null
+++ b/arch/arm/mach-spmp8000/timer.c
@@ -0,0 +1,160 @@
+/*
+ * SPMP8000 machines timer functions
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss at devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <asm/mach/time.h>
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-timer.h>
+#include <mach/irqs.h>
+
+static unsigned long clkrate;
+static const unsigned int tickrate = 1012500;
+
+/* The TIMER_B block is used as system timer
+ * T2: Clocksource
+ * T1: Clockevent
+ * T0: PWM for LCD backlight
+ * T3,4: Could be used as additional clockevent devices
+ * Timer constraints:
+ * - WDT: Can't clear the irq directly, only by resetting the whole counter
+ *   in the ISR, which means that IRQs will jitter
+ * - Timer_B: Can't reset the timer value, so at start, the first IRQ
+ *   will happen at some random time.
+ */
+#define		CS_TIMER	2
+#define		CE_TIMER	1
+static void __iomem *cs_base;
+static void __iomem *ce_base;
+
+static void tmrb_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *dev)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		writel((tickrate / HZ), ce_base + SPMP8000_TMRB_LDR);
+		/* Configure as periodic, down counter, IEN, enable timer */
+		writel(SPMP8000_TMRB_CTR_TE | SPMP8000_TMRB_CTR_IE |
+				(1 << SPMP8000_TMRB_CTR_M_SH),
+				ce_base + SPMP8000_TMRB_CTR);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		BUG();
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+		/* Disable timer */
+		writel(0, ce_base + SPMP8000_TMRB_CTR);
+		break;
+	case CLOCK_EVT_MODE_RESUME:
+		BUG();
+		break;
+	}
+}
+
+static struct clock_event_device tmrb1_clkevt = {
+	.name		= "tmrb1",
+	.features	= CLOCK_EVT_FEAT_PERIODIC,
+	.rating		= 200,
+	.set_mode	= tmrb_set_mode,
+};
+
+static irqreturn_t tmrb1_isr(int irq, void *dev_id)
+{
+	tmrb1_clkevt.event_handler(&tmrb1_clkevt);
+
+	/* Clear IRQ */
+	writel(0, ce_base + SPMP8000_TMRB_ISR);
+
+	return IRQ_HANDLED;
+};
+
+static struct irqaction tmrb1_irq = {
+	.name		= "tmrb1_irq",
+	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= tmrb1_isr,
+};
+
+static void __init spmp8000_sys_timer_init(void)
+{
+	struct device_node *np;
+	unsigned int irq;
+	struct clk *clk;
+	void *tmrb_base;
+
+	np = of_find_compatible_node(NULL, NULL, "sunplus,spmp8000-timer");
+	if (!np)
+		panic("spmp8000: unable to find timer node in dtb\n");
+
+	tmrb_base = of_iomap(np, 0);
+	if (!tmrb_base)
+		panic("spmp8000: unable to map timer cpu registers\n");
+
+	irq = of_irq_to_resource(np, CE_TIMER, NULL);
+	if (irq == NO_IRQ)
+		panic("spmp8000: unable to get interrupts of timer\n");
+
+	of_node_put(np);
+
+	cs_base = tmrb_base + SPMP8000_TMRB(CS_TIMER);
+	ce_base = tmrb_base + SPMP8000_TMRB(CE_TIMER);
+
+	clk = clk_get(NULL, "arm_apb");
+	if (IS_ERR_OR_NULL(clk))
+		panic("spmp8000: Can't get clock for timer device");
+
+	clk_enable(clk);
+	clkrate = clk_get_rate(clk);
+
+	/* Clocksource */
+	/* Disable timer */
+	writel(0, cs_base + SPMP8000_TMRB_CTR);
+
+	/* Reset counter value
+	 * Not really possible unless setting end-1 LDR value and waiting
+	 * until the counter reaches that */
+
+	/* Prescale timer */
+	writel((clkrate / tickrate) - 1, cs_base + SPMP8000_TMRB_PSR);
+
+	/* Register the clocksource */
+	clocksource_mmio_init(cs_base + SPMP8000_TMRB_VLR, "tmrb2",
+				tickrate, 200, 16, clocksource_mmio_readl_up);
+
+	/* Configure as free running (0 - 0xFFFF), up counter, enable timer */
+	writel(SPMP8000_TMRB_CTR_TE | SPMP8000_TMRB_CTR_UD,
+		cs_base + SPMP8000_TMRB_CTR);
+
+	/* Clockevent */
+	setup_irq(irq, &tmrb1_irq);
+
+	/* Disable timer */
+	writel(0, ce_base + SPMP8000_TMRB_CTR);
+
+	/* Prescale timer */
+	writel((clkrate / tickrate) - 1, ce_base + SPMP8000_TMRB_PSR);
+
+	clockevents_register_device(&tmrb1_clkevt);
+}
+
+struct sys_timer spmp8000_sys_timer = {
+	.init		= spmp8000_sys_timer_init,
+};
-- 
1.7.4.1




More information about the linux-arm-kernel mailing list