[U-Boot] [RFC PATCH 10/13] arm: nexell: add timer support

Andre Przywara andre.przywara at arm.com
Thu Nov 30 01:25:08 UTC 2017


From: Amit Singh Tomar <amittomer25 at gmail.com>

Nexell based SoCs (S5P4414 and S5P6818) contain the same timer block as
present on Samsungs SoCs.

Add this timer code when compiling for Nexell SoC and provide the
necessary glue functions to make the Samsung timer driver happy.

Signed-off-by: Amit Singh Tomar <amittomer25 at gmail.com>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/arm/include/asm/arch-nexell/clk.h |  1 +
 arch/arm/include/asm/arch-nexell/pwm.h | 62 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-nexell/Makefile          |  2 ++
 arch/arm/mach-nexell/board.c           | 37 +++++++++++++++++---
 4 files changed, 97 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-nexell/pwm.h

diff --git a/arch/arm/include/asm/arch-nexell/clk.h b/arch/arm/include/asm/arch-nexell/clk.h
index bfd145f555..8cf56ef52c 100644
--- a/arch/arm/include/asm/arch-nexell/clk.h
+++ b/arch/arm/include/asm/arch-nexell/clk.h
@@ -9,5 +9,6 @@
 #define __ASM_ARCH_CLK_H_
 
 unsigned long get_uart_clk(int dev_index);
+unsigned long get_pwm_clk(void);
 
 #endif
diff --git a/arch/arm/include/asm/arch-nexell/pwm.h b/arch/arm/include/asm/arch-nexell/pwm.h
new file mode 100644
index 0000000000..7290c61366
--- /dev/null
+++ b/arch/arm/include/asm/arch-nexell/pwm.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Kyungmin Park <kyungmin.park at samsung.com>
+ * Minkyu Kang <mk7.kang at samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __ASM_ARM_ARCH_PWM_H_
+#define __ASM_ARM_ARCH_PWM_H_
+
+#define PRESCALER_0		(8 - 1)		/* prescaler of timer 0, 1 */
+#define PRESCALER_1		(16 - 1)	/* prescaler of timer 2, 3, 4 */
+
+/* Divider MUX */
+#define MUX_DIV_1		0		/* 1/1 period */
+#define MUX_DIV_2		1		/* 1/2 period */
+#define MUX_DIV_4		2		/* 1/4 period */
+#define MUX_DIV_8		3		/* 1/8 period */
+#define MUX_DIV_16		4		/* 1/16 period */
+
+#define MUX_DIV_SHIFT(x)	(x * 4)
+
+#define TCON_OFFSET(x)		((x + 1) * (!!x) << 2)
+
+#define TCON_START(x)		(1 << TCON_OFFSET(x))
+#define TCON_UPDATE(x)		(1 << (TCON_OFFSET(x) + 1))
+#define TCON_INVERTER(x)	(1 << (TCON_OFFSET(x) + 2))
+#define TCON_AUTO_RELOAD(x)	(1 << (TCON_OFFSET(x) + 3))
+#define TCON4_AUTO_RELOAD	(1 << 22)
+
+#define NEXELL_TIMER_BASE	0xc0017000
+
+#ifndef __ASSEMBLY__
+struct s5p_timer {
+	unsigned int	tcfg0;
+	unsigned int	tcfg1;
+	unsigned int	tcon;
+	unsigned int	tcntb0;
+	unsigned int	tcmpb0;
+	unsigned int	tcnto0;
+	unsigned int	tcntb1;
+	unsigned int	tcmpb1;
+	unsigned int	tcnto1;
+	unsigned int	tcntb2;
+	unsigned int	tcmpb2;
+	unsigned int	tcnto2;
+	unsigned int	tcntb3;
+	unsigned int	tcmpb3;
+	unsigned int	tcnto3;
+	unsigned int	tcntb4;
+	unsigned int	tcnto4;
+	unsigned int	tintcstat;
+};
+#endif	/* __ASSEMBLY__ */
+
+static inline unsigned long samsung_get_base_timer(void)
+{
+	return NEXELL_TIMER_BASE;
+}
+
+#endif
diff --git a/arch/arm/mach-nexell/Makefile b/arch/arm/mach-nexell/Makefile
index c4c8293cbc..c59ad631e6 100644
--- a/arch/arm/mach-nexell/Makefile
+++ b/arch/arm/mach-nexell/Makefile
@@ -6,3 +6,5 @@
 
 obj-y	:= board.o
 obj-$(CONFIG_ARM64)     += mmu-arm64.o
+obj-y += ../cpu/armv7/s5p-common/timer.o
+obj-y += ../cpu/armv7/s5p-common/pwm.o
diff --git a/arch/arm/mach-nexell/board.c b/arch/arm/mach-nexell/board.c
index 54a9d8c1f5..e9b4f94630 100644
--- a/arch/arm/mach-nexell/board.c
+++ b/arch/arm/mach-nexell/board.c
@@ -10,9 +10,27 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 #define NEXELL_PLLSETREG0	0xc0010008UL
+#define NEXELL_CLKDIVREG1	0xc0010024UL
+#define IP_RESET1		0xc0012004UL
 
 #define OSC_FREQ 24000000
 
+int arch_cpu_init(void)
+{
+	u32 val;
+
+	/*
+	 * Reset timer block #4.
+	 * Ideally this should be done through the reset driver, but
+	 * unfortunately our timer driver is not DM driven.
+	 */
+	val = readl(IP_RESET1);
+	val |= BIT(4);
+	writel(val, IP_RESET1);
+
+	return 0;
+}
+
 /* TODO: dummy implementation for now, add proper reset code */
 void reset_cpu(ulong addr)
 {
@@ -35,11 +53,6 @@ int dram_init(void)
 	return 0;
 }
 
-ulong get_tbclk(void)
-{
-	return CONFIG_SYS_HZ;
-}
-
 static unsigned long get_pll_freq(int pll_index)
 {
 	uint32_t reg;
@@ -85,6 +98,20 @@ unsigned long get_uart_clk(int dev_index)
 	return get_level1_clk_freq(clock_ofs[dev_index]);
 }
 
+/* This is reading the PCLK frequency, which drives the PWM timer. */
+unsigned long get_pwm_clk(void)
+{
+	uint32_t reg;
+	unsigned int pll_index, div;
+
+	reg = readl(NEXELL_CLKDIVREG1);
+	pll_index = reg & 0x7;
+	div = ((reg >> 3) & 0x3f) + 1;		/* BCLK divider */
+	div *= ((reg >> 9) & 0x3f) + 1;		/* PCLK divider */
+
+	return get_pll_freq(pll_index) / div;
+}
+
 int board_init(void)
 {
 	return 0;
-- 
2.14.1



More information about the U-Boot mailing list