From: Amit Singh Tomar <amittome...@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 <amittome...@gmail.com>
Signed-off-by: Andre Przywara <andre.przyw...@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.p...@samsung.com>
+ * Minkyu Kang <mk7.k...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to