aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c2440
diff options
context:
space:
mode:
authorThomas Abraham <thomas.abraham@linaro.org>2011-10-24 05:47:40 -0400
committerKukjin Kim <kgene.kim@samsung.com>2011-12-22 20:06:55 -0500
commit046c217c65a7670b4ee1aecdb9854284e32b2d6c (patch)
tree4219455716aaebe392d8d3094b85ee733dc8f77d /arch/arm/mach-s3c2440
parent4d84e970d0faec772a9eaa818feee38aeca121b2 (diff)
ARM: S3C2440: move handling of fclk/n clock to platform code
s3c2440 uses fclk/n (fclk divided by n) clock as one of the possible clocks used to generate the baud rate clock. The divider 'n' in this case can be logically represented outside of the uart controller. This patch creates a new clock by name "fclk_n" for s3c2440 based platforms to represent the fclk/n clock in the platform code. This clock provides a get_rate callback that checks the UCON0/1/2 registers to determine the clock rate. The samsung uart driver would receive the "fclk_n" clock name as one of the possible baud rate clock options and the driver need not determine clock rate of fclk/n. Cc: Ben Dooks <ben-linux@fluff.org> Cc: Vasily Khoruzhick <anarsoul@gmail.com> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch/arm/mach-s3c2440')
-rw-r--r--arch/arm/mach-s3c2440/clock.c37
-rw-r--r--arch/arm/mach-s3c2440/mach-rx1950.c4
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c4
3 files changed, 41 insertions, 4 deletions
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
index f9e6bdaf41d2..f85853c5d5eb 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -34,6 +34,7 @@
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35#include <linux/clk.h> 35#include <linux/clk.h>
36#include <linux/io.h> 36#include <linux/io.h>
37#include <linux/serial_core.h>
37 38
38#include <mach/hardware.h> 39#include <mach/hardware.h>
39#include <linux/atomic.h> 40#include <linux/atomic.h>
@@ -43,6 +44,7 @@
43 44
44#include <plat/clock.h> 45#include <plat/clock.h>
45#include <plat/cpu.h> 46#include <plat/cpu.h>
47#include <plat/regs-serial.h>
46 48
47/* S3C2440 extended clock support */ 49/* S3C2440 extended clock support */
48 50
@@ -108,6 +110,40 @@ static struct clk s3c2440_clk_ac97 = {
108 .ctrlbit = S3C2440_CLKCON_CAMERA, 110 .ctrlbit = S3C2440_CLKCON_CAMERA,
109}; 111};
110 112
113static unsigned long s3c2440_fclk_n_getrate(struct clk *clk)
114{
115 unsigned long ucon0, ucon1, ucon2, divisor;
116
117 /* the fun of calculating the uart divisors on the s3c2440 */
118 ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
119 ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
120 ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
121
122 ucon0 &= S3C2440_UCON0_DIVMASK;
123 ucon1 &= S3C2440_UCON1_DIVMASK;
124 ucon2 &= S3C2440_UCON2_DIVMASK;
125
126 if (ucon0 != 0)
127 divisor = (ucon0 >> S3C2440_UCON_DIVSHIFT) + 6;
128 else if (ucon1 != 0)
129 divisor = (ucon1 >> S3C2440_UCON_DIVSHIFT) + 21;
130 else if (ucon2 != 0)
131 divisor = (ucon2 >> S3C2440_UCON_DIVSHIFT) + 36;
132 else
133 /* manual calims 44, seems to be 9 */
134 divisor = 9;
135
136 return clk_get_rate(clk->parent) / divisor;
137}
138
139static struct clk s3c2440_clk_fclk_n = {
140 .name = "fclk_n",
141 .parent = &clk_f,
142 .ops = &(struct clk_ops) {
143 .get_rate = s3c2440_fclk_n_getrate,
144 },
145};
146
111static int s3c2440_clk_add(struct sys_device *sysdev) 147static int s3c2440_clk_add(struct sys_device *sysdev)
112{ 148{
113 struct clk *clock_upll; 149 struct clk *clock_upll;
@@ -126,6 +162,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
126 s3c2440_clk_cam.parent = clock_h; 162 s3c2440_clk_cam.parent = clock_h;
127 s3c2440_clk_ac97.parent = clock_p; 163 s3c2440_clk_ac97.parent = clock_p;
128 s3c2440_clk_cam_upll.parent = clock_upll; 164 s3c2440_clk_cam_upll.parent = clock_upll;
165 s3c24xx_register_clock(&s3c2440_clk_fclk_n);
129 166
130 s3c24xx_register_clock(&s3c2440_clk_ac97); 167 s3c24xx_register_clock(&s3c2440_clk_ac97);
131 s3c24xx_register_clock(&s3c2440_clk_cam); 168 s3c24xx_register_clock(&s3c2440_clk_cam);
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
index 0d3453bf567c..094c4bff7fe4 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -70,8 +70,8 @@ static struct map_desc rx1950_iodesc[] __initdata = {
70 70
71static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = { 71static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = {
72 [0] = { 72 [0] = {
73 .name = "fclk", 73 .name = "fclk_n",
74 .divisor = 0x0a, 74 .divisor = 1,
75 .min_baud = 0, 75 .min_baud = 0,
76 .max_baud = 0, 76 .max_baud = 0,
77 }, 77 },
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index e19499c2f909..f934f5b88a4a 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -70,8 +70,8 @@ static struct map_desc rx3715_iodesc[] __initdata = {
70 70
71static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = { 71static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = {
72 [0] = { 72 [0] = {
73 .name = "fclk", 73 .name = "fclk_n",
74 .divisor = 0, 74 .divisor = 1,
75 .min_baud = 0, 75 .min_baud = 0,
76 .max_baud = 0, 76 .max_baud = 0,
77 } 77 }