diff mbox series

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

Message ID 20171130012511.16333-11-andre.przywara@arm.com
State RFC
Delegated to: Tom Rini
Headers show
Series Nexell S5P6818 SoC support | expand

Commit Message

Andre Przywara Nov. 30, 2017, 1:25 a.m. UTC
From: Amit Singh Tomar <amittomer25@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@gmail.com>
Signed-off-by: Andre Przywara <andre.przywara@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

Comments

Simon Glass Dec. 2, 2017, 3:31 a.m. UTC | #1
On 29 November 2017 at 18:25, Andre Przywara <andre.przywara@arm.com> wrote:
> From: Amit Singh Tomar <amittomer25@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@gmail.com>
> Signed-off-by: Andre Przywara <andre.przywara@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

Reviewed-by: Simon Glass <sjg@chromium.org>

But I encourage use of setclrbits_le32()
diff mbox series

Patch

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@samsung.com>
+ * Minkyu Kang <mk7.kang@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;