summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-samsung
diff options
context:
space:
mode:
authorJuergen Beisert <jbe@pengutronix.de>2012-01-02 12:43:55 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2012-01-02 13:32:13 +0100
commit4e7151d11c48db519c0c5ce0780617bcdd68667e (patch)
tree3b3c8c22f093d79dc66050dc6adfd7da24ba4517 /arch/arm/mach-samsung
parentb5a92c0ff1236aa45605d48eca0a3b6694f672e1 (diff)
downloadbarebox-4e7151d11c48db519c0c5ce0780617bcdd68667e.tar.gz
barebox-4e7151d11c48db519c0c5ce0780617bcdd68667e.tar.xz
MACH SAMSUNG/S3C: Separate S3C24XX clock management
There are major differences in the clock tree of the S3C24xx family and the more recent CPUs of the S3C family. Keep the S3C24XX clock routines separate to avoid an ifdef hell. But also use generic function names to be able to share drivers among the S3C family. Signed-off-by: Juergen Beisert <jbe@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-samsung')
-rw-r--r--arch/arm/mach-samsung/Makefile2
-rw-r--r--arch/arm/mach-samsung/generic.c117
-rw-r--r--arch/arm/mach-samsung/include/mach/s3c-clocks.h31
-rw-r--r--arch/arm/mach-samsung/include/mach/s3c-generic.h12
-rw-r--r--arch/arm/mach-samsung/include/mach/s3c-iomap.h11
-rw-r--r--arch/arm/mach-samsung/lowlevel-init.S2
-rw-r--r--arch/arm/mach-samsung/s3c24xx-clocks.c137
7 files changed, 179 insertions, 133 deletions
diff --git a/arch/arm/mach-samsung/Makefile b/arch/arm/mach-samsung/Makefile
index f329cdbdae..c590180958 100644
--- a/arch/arm/mach-samsung/Makefile
+++ b/arch/arm/mach-samsung/Makefile
@@ -1,3 +1,3 @@
obj-y += generic.o
-obj-$(CONFIG_ARCH_S3C24xx) += gpio-s3c24x0.o
+obj-$(CONFIG_ARCH_S3C24xx) += gpio-s3c24x0.o s3c24xx-clocks.o
obj-$(CONFIG_S3C24XX_LOW_LEVEL_INIT) += lowlevel-init.o
diff --git a/arch/arm/mach-samsung/generic.c b/arch/arm/mach-samsung/generic.c
index 3c24b1aa35..3f6e8014c8 100644
--- a/arch/arm/mach-samsung/generic.c
+++ b/arch/arm/mach-samsung/generic.c
@@ -28,100 +28,7 @@
#include <clock.h>
#include <io.h>
#include <mach/s3c-iomap.h>
-
-/**
- * Calculate the current M-PLL clock.
- * @return Current frequency in Hz
- */
-uint32_t s3c24xx_get_mpllclk(void)
-{
- uint32_t m, p, s, reg_val;
-
- reg_val = readl(MPLLCON);
- m = ((reg_val & 0xFF000) >> 12) + 8;
- p = ((reg_val & 0x003F0) >> 4) + 2;
- s = reg_val & 0x3;
-#ifdef CONFIG_CPU_S3C2410
- return (S3C24XX_CLOCK_REFERENCE * m) / (p << s);
-#endif
-#ifdef CONFIG_CPU_S3C2440
- return 2 * m * (S3C24XX_CLOCK_REFERENCE / (p << s));
-#endif
-}
-
-/**
- * Calculate the current U-PLL clock
- * @return Current frequency in Hz
- */
-uint32_t s3c24xx_get_upllclk(void)
-{
- uint32_t m, p, s, reg_val;
-
- reg_val = readl(UPLLCON);
- m = ((reg_val & 0xFF000) >> 12) + 8;
- p = ((reg_val & 0x003F0) >> 4) + 2;
- s = reg_val & 0x3;
-
- return (S3C24XX_CLOCK_REFERENCE * m) / (p << s);
-}
-
-/**
- * Calculate the FCLK frequency used for the ARM CPU core
- * @return Current frequency in Hz
- */
-uint32_t s3c24xx_get_fclk(void)
-{
- return s3c24xx_get_mpllclk();
-}
-
-/**
- * Calculate the HCLK frequency used for the AHB bus (CPU to main peripheral)
- * @return Current frequency in Hz
- */
-uint32_t s3c24xx_get_hclk(void)
-{
- uint32_t f_clk;
-
- f_clk = s3c24xx_get_fclk();
-#ifdef CONFIG_CPU_S3C2410
- if (readl(CLKDIVN) & 0x02)
- return f_clk >> 1;
-#endif
-#ifdef CONFIG_CPU_S3C2440
- switch(readl(CLKDIVN) & 0x06) {
- case 2:
- return f_clk >> 1;
- case 4:
- return f_clk >> 2; /* TODO consider CAMDIVN */
- case 6:
- return f_clk / 3; /* TODO consider CAMDIVN */
- }
-#endif
- return f_clk;
-}
-
-/**
- * Calculate the PCLK frequency used for the slower peripherals
- * @return Current frequency in Hz
- */
-uint32_t s3c24xx_get_pclk(void)
-{
- uint32_t p_clk;
-
- p_clk = s3c24xx_get_hclk();
- if (readl(CLKDIVN) & 0x01)
- return p_clk >> 1;
- return p_clk;
-}
-
-/**
- * Calculate the UCLK frequency used by the USB host device
- * @return Current frequency in Hz
- */
-uint32_t s3c24xx_get_uclk(void)
-{
- return s3c24xx_get_upllclk();
-}
+#include <mach/s3c-generic.h>
/**
* Calculate the amount of connected and available memory
@@ -169,26 +76,6 @@ uint32_t s3c24x0_get_memory_size(void)
return size;
}
-/**
- * Show the user the current clock settings
- */
-int s3c24xx_dump_clocks(void)
-{
- printf("refclk: %7d kHz\n", S3C24XX_CLOCK_REFERENCE / 1000);
- printf("mpll: %7d kHz\n", s3c24xx_get_mpllclk() / 1000);
- printf("upll: %7d kHz\n", s3c24xx_get_upllclk() / 1000);
- printf("fclk: %7d kHz\n", s3c24xx_get_fclk() / 1000);
- printf("hclk: %7d kHz\n", s3c24xx_get_hclk() / 1000);
- printf("pclk: %7d kHz\n", s3c24xx_get_pclk() / 1000);
- printf("SDRAM1: CL%d@%dMHz\n", ((readl(BANKCON6) & 0xc) >> 2) + 2, s3c24xx_get_hclk() / 1000000);
- if ((readl(BANKCON7) & (0x3 << 15)) == (0x3 << 15))
- printf("SDRAM2: CL%d@%dMHz\n", ((readl(BANKCON7) & 0xc) >> 2) + 2,
- s3c24xx_get_hclk() / 1000000);
- return 0;
-}
-
-late_initcall(s3c24xx_dump_clocks);
-
static uint64_t s3c24xx_clocksource_read(void)
{
/* note: its a down counter */
@@ -203,7 +90,7 @@ static struct clocksource cs = {
static int clocksource_init (void)
{
- uint32_t p_clk = s3c24xx_get_pclk();
+ uint32_t p_clk = s3c_get_pclk();
writel(0x00000000, TCON); /* stop all timers */
writel(0x00ffffff, TCFG0); /* PCLK / (255 + 1) for timer 4 */
diff --git a/arch/arm/mach-samsung/include/mach/s3c-clocks.h b/arch/arm/mach-samsung/include/mach/s3c-clocks.h
new file mode 100644
index 0000000000..44b2a6c8ee
--- /dev/null
+++ b/arch/arm/mach-samsung/include/mach/s3c-clocks.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 Juergen Beisert, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_S3C_CLOCKS_H
+# define __MACH_S3C_CLOCKS_H
+
+#ifdef CONFIG_ARCH_S3C24xx
+# define S3C_LOCKTIME (S3C_CLOCK_POWER_BASE)
+# define S3C_MPLLCON (S3C_CLOCK_POWER_BASE + 0x4)
+# define S3C_UPLLCON (S3C_CLOCK_POWER_BASE + 0x8)
+# define S3C_CLKCON (S3C_CLOCK_POWER_BASE + 0xc)
+# define S3C_CLKSLOW (S3C_CLOCK_POWER_BASE + 0x10)
+# define S3C_CLKDIVN (S3C_CLOCK_POWER_BASE + 0x14)
+
+# define S3C_MPLLCON_GET_MDIV(x) ((((x) >> 12) & 0xff) + 8)
+# define S3C_MPLLCON_GET_PDIV(x) ((((x) >> 4) & 0x3f) + 2)
+# define S3C_MPLLCON_GET_SDIV(x) ((x) & 0x3)
+#endif
+
+#endif /* __MACH_S3C_CLOCKS_H */
diff --git a/arch/arm/mach-samsung/include/mach/s3c-generic.h b/arch/arm/mach-samsung/include/mach/s3c-generic.h
index b8abcf1d9c..33f025d894 100644
--- a/arch/arm/mach-samsung/include/mach/s3c-generic.h
+++ b/arch/arm/mach-samsung/include/mach/s3c-generic.h
@@ -24,10 +24,10 @@
* MA 02111-1307 USA
*/
-uint32_t s3c24xx_get_mpllclk(void);
-uint32_t s3c24xx_get_upllclk(void);
-uint32_t s3c24xx_get_fclk(void);
-uint32_t s3c24xx_get_hclk(void);
-uint32_t s3c24xx_get_pclk(void);
-uint32_t s3c24xx_get_uclk(void);
+uint32_t s3c_get_mpllclk(void);
+uint32_t s3c_get_upllclk(void);
+uint32_t s3c_get_fclk(void);
+uint32_t s3c_get_hclk(void);
+uint32_t s3c_get_pclk(void);
+uint32_t s3c_get_uclk(void);
uint32_t s3c24x0_get_memory_size(void);
diff --git a/arch/arm/mach-samsung/include/mach/s3c-iomap.h b/arch/arm/mach-samsung/include/mach/s3c-iomap.h
index a990d80c4a..7cedf6a9f8 100644
--- a/arch/arm/mach-samsung/include/mach/s3c-iomap.h
+++ b/arch/arm/mach-samsung/include/mach/s3c-iomap.h
@@ -25,7 +25,7 @@
#define S3C2410_USB_HOST_BASE 0x49000000
#define S3C2410_INTERRUPT_BASE 0x4A000000
#define S3C2410_DMA_BASE 0x4B000000
-#define S3C24X0_CLOCK_POWER_BASE 0x4C000000
+#define S3C_CLOCK_POWER_BASE 0x4C000000
#define S3C2410_LCD_BASE 0x4D000000
#define S3C24X0_NAND_BASE 0x4E000000
#define S3C24X0_UART_BASE 0x50000000
@@ -40,15 +40,6 @@
#define S3C2410_SPI_BASE 0x59000000
#define S3C2410_SDI_BASE 0x5A000000
-/* Clock control (direct access) */
-
-#define LOCKTIME (S3C24X0_CLOCK_POWER_BASE)
-#define MPLLCON (S3C24X0_CLOCK_POWER_BASE + 0x4)
-#define UPLLCON (S3C24X0_CLOCK_POWER_BASE + 0x8)
-#define CLKCON (S3C24X0_CLOCK_POWER_BASE + 0xc)
-#define CLKSLOW (S3C24X0_CLOCK_POWER_BASE + 0x10)
-#define CLKDIVN (S3C24X0_CLOCK_POWER_BASE + 0x14)
-
/* Timer (direct access) */
#define TCFG0 (S3C24X0_TIMER_BASE + 0x00)
#define TCFG1 (S3C24X0_TIMER_BASE + 0x04)
diff --git a/arch/arm/mach-samsung/lowlevel-init.S b/arch/arm/mach-samsung/lowlevel-init.S
index 852928393b..e2e3fc0927 100644
--- a/arch/arm/mach-samsung/lowlevel-init.S
+++ b/arch/arm/mach-samsung/lowlevel-init.S
@@ -77,7 +77,7 @@ routine very early in your board_init_lowlevel routine.
.globl s3c24x0_pll_init
s3c24x0_pll_init:
- mov r0, #S3C24X0_CLOCK_POWER_BASE
+ mov r0, #S3C_CLOCK_POWER_BASE
/* configure internal clock ratio */
mov r1, #BOARD_SPECIFIC_CLKDIVN
diff --git a/arch/arm/mach-samsung/s3c24xx-clocks.c b/arch/arm/mach-samsung/s3c24xx-clocks.c
new file mode 100644
index 0000000000..beacc763b4
--- /dev/null
+++ b/arch/arm/mach-samsung/s3c24xx-clocks.c
@@ -0,0 +1,137 @@
+/*
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <io.h>
+#include <mach/s3c-iomap.h>
+#include <mach/s3c-generic.h>
+#include <mach/s3c-clocks.h>
+
+/**
+ * Calculate the current M-PLL clock.
+ * @return Current frequency in Hz
+ */
+uint32_t s3c_get_mpllclk(void)
+{
+ uint32_t m, p, s, reg_val;
+
+ reg_val = readl(S3C_MPLLCON);
+ m = ((reg_val & 0xFF000) >> 12) + 8;
+ p = ((reg_val & 0x003F0) >> 4) + 2;
+ s = reg_val & 0x3;
+#ifdef CONFIG_CPU_S3C2410
+ return (S3C24XX_CLOCK_REFERENCE * m) / (p << s);
+#endif
+#ifdef CONFIG_CPU_S3C2440
+ return 2 * m * (S3C24XX_CLOCK_REFERENCE / (p << s));
+#endif
+}
+
+/**
+ * Calculate the current U-PLL clock
+ * @return Current frequency in Hz
+ */
+uint32_t s3c_get_upllclk(void)
+{
+ uint32_t m, p, s, reg_val;
+
+ reg_val = readl(S3C_UPLLCON);
+ m = ((reg_val & 0xFF000) >> 12) + 8;
+ p = ((reg_val & 0x003F0) >> 4) + 2;
+ s = reg_val & 0x3;
+
+ return (S3C24XX_CLOCK_REFERENCE * m) / (p << s);
+}
+
+/**
+ * Calculate the FCLK frequency used for the ARM CPU core
+ * @return Current frequency in Hz
+ */
+uint32_t s3c_get_fclk(void)
+{
+ return s3c_get_mpllclk();
+}
+
+/**
+ * Calculate the HCLK frequency used for the AHB bus (CPU to main peripheral)
+ * @return Current frequency in Hz
+ */
+uint32_t s3c_get_hclk(void)
+{
+ uint32_t f_clk;
+
+ f_clk = s3c_get_fclk();
+#ifdef CONFIG_CPU_S3C2410
+ if (readl(S3C_CLKDIVN) & 0x02)
+ return f_clk >> 1;
+#endif
+#ifdef CONFIG_CPU_S3C2440
+ switch(readl(S3C_CLKDIVN) & 0x06) {
+ case 2:
+ return f_clk >> 1;
+ case 4:
+ return f_clk >> 2; /* TODO consider CAMDIVN */
+ case 6:
+ return f_clk / 3; /* TODO consider CAMDIVN */
+ }
+#endif
+ return f_clk;
+}
+
+/**
+ * Calculate the PCLK frequency used for the slower peripherals
+ * @return Current frequency in Hz
+ */
+uint32_t s3c_get_pclk(void)
+{
+ uint32_t p_clk;
+
+ p_clk = s3c_get_hclk();
+ if (readl(S3C_CLKDIVN) & 0x01)
+ return p_clk >> 1;
+ return p_clk;
+}
+
+/**
+ * Calculate the UCLK frequency used by the USB host device
+ * @return Current frequency in Hz
+ */
+uint32_t s3c24_get_uclk(void)
+{
+ return s3c_get_upllclk();
+}
+
+/**
+ * Show the user the current clock settings
+ */
+int s3c24xx_dump_clocks(void)
+{
+ printf("refclk: %7d kHz\n", S3C24XX_CLOCK_REFERENCE / 1000);
+ printf("mpll: %7d kHz\n", s3c_get_mpllclk() / 1000);
+ printf("upll: %7d kHz\n", s3c_get_upllclk() / 1000);
+ printf("fclk: %7d kHz\n", s3c_get_fclk() / 1000);
+ printf("hclk: %7d kHz\n", s3c_get_hclk() / 1000);
+ printf("pclk: %7d kHz\n", s3c_get_pclk() / 1000);
+ printf("SDRAM1: CL%d@%dMHz\n", ((readl(BANKCON6) & 0xc) >> 2) + 2, s3c_get_hclk() / 1000000);
+ if ((readl(BANKCON7) & (0x3 << 15)) == (0x3 << 15))
+ printf("SDRAM2: CL%d@%dMHz\n", ((readl(BANKCON7) & 0xc) >> 2) + 2,
+ s3c_get_hclk() / 1000000);
+ return 0;
+}
+
+late_initcall(s3c24xx_dump_clocks);