aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c2440/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-s3c2440/clock.c')
-rw-r--r--arch/arm/mach-s3c2440/clock.c37
1 files changed, 37 insertions, 0 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);