diff options
Diffstat (limited to 'arch/arm/mach-s3c2440/clock.c')
-rw-r--r-- | arch/arm/mach-s3c2440/clock.c | 37 |
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 | ||
113 | static 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 | |||
139 | static 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 | |||
111 | static int s3c2440_clk_add(struct sys_device *sysdev) | 147 | static 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); |