Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: convert ARM RealView to common clk

This converts the ARM RealView machine over to using the common
clock. The approach is similar to the one used for the Integrator,
and we're reusing the ICST wrapper code.

We have to put the clock intialization in the timer init function
for the clocks to be available when initializing the timer,
keeping them in early_init() is too early for the common clk.

Since we now have to go down and compile drivers/clk/versatile
a CONFIG_COMMON_CLK_VERSATILE symbol has been added so the proper
code gets compiled into the kernel for either machine. A leftover
CLK_VERSATILE in the Integrator Kconfig was fixed up to use
the new symbol as well.

Tested on ARM RealView PB1176.

Cc: Pawel Moll <pawel.moll@arm.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>

authored by

Linus Walleij and committed by
Mike Turquette
f9a6aa43 bc0e489e

+137 -127
+3 -4
arch/arm/Kconfig
··· 273 273 select ARM_AMBA 274 274 select ARCH_HAS_CPUFREQ 275 275 select COMMON_CLK 276 - select CLK_VERSATILE 276 + select COMMON_CLK_VERSATILE 277 277 select HAVE_TCM 278 278 select ICST 279 279 select GENERIC_CLOCKEVENTS ··· 289 289 config ARCH_REALVIEW 290 290 bool "ARM Ltd. RealView family" 291 291 select ARM_AMBA 292 - select CLKDEV_LOOKUP 293 - select HAVE_MACH_CLKDEV 292 + select COMMON_CLK 293 + select COMMON_CLK_VERSATILE 294 294 select ICST 295 295 select GENERIC_CLOCKEVENTS 296 296 select ARCH_WANT_OPTIONAL_GPIOLIB 297 297 select PLAT_VERSATILE 298 - select PLAT_VERSATILE_CLOCK 299 298 select PLAT_VERSATILE_CLCD 300 299 select ARM_TIMER_SP804 301 300 select GPIO_PL061 if GPIOLIB
-106
arch/arm/mach-realview/core.c
··· 30 30 #include <linux/ata_platform.h> 31 31 #include <linux/amba/mmci.h> 32 32 #include <linux/gfp.h> 33 - #include <linux/clkdev.h> 34 33 #include <linux/mtd/physmap.h> 35 34 36 35 #include <mach/hardware.h> ··· 225 226 .cd_invert = true, 226 227 }; 227 228 228 - /* 229 - * Clock handling 230 - */ 231 - static const struct icst_params realview_oscvco_params = { 232 - .ref = 24000000, 233 - .vco_max = ICST307_VCO_MAX, 234 - .vco_min = ICST307_VCO_MIN, 235 - .vd_min = 4 + 8, 236 - .vd_max = 511 + 8, 237 - .rd_min = 1 + 2, 238 - .rd_max = 127 + 2, 239 - .s2div = icst307_s2div, 240 - .idx2s = icst307_idx2s, 241 - }; 242 - 243 - static void realview_oscvco_set(struct clk *clk, struct icst_vco vco) 244 - { 245 - void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET; 246 - u32 val; 247 - 248 - val = readl(clk->vcoreg) & ~0x7ffff; 249 - val |= vco.v | (vco.r << 9) | (vco.s << 16); 250 - 251 - writel(0xa05f, sys_lock); 252 - writel(val, clk->vcoreg); 253 - writel(0, sys_lock); 254 - } 255 - 256 - static const struct clk_ops oscvco_clk_ops = { 257 - .round = icst_clk_round, 258 - .set = icst_clk_set, 259 - .setvco = realview_oscvco_set, 260 - }; 261 - 262 - static struct clk oscvco_clk = { 263 - .ops = &oscvco_clk_ops, 264 - .params = &realview_oscvco_params, 265 - }; 266 - 267 - /* 268 - * These are fixed clocks. 269 - */ 270 - static struct clk ref24_clk = { 271 - .rate = 24000000, 272 - }; 273 - 274 - static struct clk sp804_clk = { 275 - .rate = 1000000, 276 - }; 277 - 278 - static struct clk dummy_apb_pclk; 279 - 280 - static struct clk_lookup lookups[] = { 281 - { /* Bus clock */ 282 - .con_id = "apb_pclk", 283 - .clk = &dummy_apb_pclk, 284 - }, { /* UART0 */ 285 - .dev_id = "dev:uart0", 286 - .clk = &ref24_clk, 287 - }, { /* UART1 */ 288 - .dev_id = "dev:uart1", 289 - .clk = &ref24_clk, 290 - }, { /* UART2 */ 291 - .dev_id = "dev:uart2", 292 - .clk = &ref24_clk, 293 - }, { /* UART3 */ 294 - .dev_id = "fpga:uart3", 295 - .clk = &ref24_clk, 296 - }, { /* UART3 is on the dev chip in PB1176 */ 297 - .dev_id = "dev:uart3", 298 - .clk = &ref24_clk, 299 - }, { /* UART4 only exists in PB1176 */ 300 - .dev_id = "fpga:uart4", 301 - .clk = &ref24_clk, 302 - }, { /* KMI0 */ 303 - .dev_id = "fpga:kmi0", 304 - .clk = &ref24_clk, 305 - }, { /* KMI1 */ 306 - .dev_id = "fpga:kmi1", 307 - .clk = &ref24_clk, 308 - }, { /* MMC0 */ 309 - .dev_id = "fpga:mmc0", 310 - .clk = &ref24_clk, 311 - }, { /* CLCD is in the PB1176 and EB DevChip */ 312 - .dev_id = "dev:clcd", 313 - .clk = &oscvco_clk, 314 - }, { /* PB:CLCD */ 315 - .dev_id = "issp:clcd", 316 - .clk = &oscvco_clk, 317 - }, { /* SSP */ 318 - .dev_id = "dev:ssp0", 319 - .clk = &ref24_clk, 320 - }, { /* SP804 timers */ 321 - .dev_id = "sp804", 322 - .clk = &sp804_clk, 323 - }, 324 - }; 325 - 326 229 void __init realview_init_early(void) 327 230 { 328 231 void __iomem *sys = __io_address(REALVIEW_SYS_BASE); 329 - 330 - if (machine_is_realview_pb1176()) 331 - oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC0_OFFSET; 332 - else 333 - oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC4_OFFSET; 334 - 335 - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 336 232 337 233 versatile_sched_clock_init(sys + REALVIEW_SYS_24MHz_OFFSET, 24000000); 338 234 }
-16
arch/arm/mach-realview/include/mach/clkdev.h
··· 1 - #ifndef __ASM_MACH_CLKDEV_H 2 - #define __ASM_MACH_CLKDEV_H 3 - 4 - #include <plat/clock.h> 5 - 6 - struct clk { 7 - unsigned long rate; 8 - const struct clk_ops *ops; 9 - const struct icst_params *params; 10 - void __iomem *vcoreg; 11 - }; 12 - 13 - #define __clk_get(clk) ({ 1; }) 14 - #define __clk_put(clk) do { } while (0) 15 - 16 - #endif
+2
arch/arm/mach-realview/realview_eb.c
··· 27 27 #include <linux/amba/mmci.h> 28 28 #include <linux/amba/pl022.h> 29 29 #include <linux/io.h> 30 + #include <linux/platform_data/clk-realview.h> 30 31 31 32 #include <mach/hardware.h> 32 33 #include <asm/irq.h> ··· 415 414 else 416 415 timer_irq = IRQ_EB_TIMER0_1; 417 416 417 + realview_clk_init(__io_address(REALVIEW_SYS_BASE), false); 418 418 realview_timer_init(timer_irq); 419 419 realview_eb_twd_init(); 420 420 }
+2
arch/arm/mach-realview/realview_pb1176.c
··· 29 29 #include <linux/mtd/physmap.h> 30 30 #include <linux/mtd/partitions.h> 31 31 #include <linux/io.h> 32 + #include <linux/platform_data/clk-realview.h> 32 33 33 34 #include <mach/hardware.h> 34 35 #include <asm/irq.h> ··· 327 326 timer2_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE); 328 327 timer3_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE) + 0x20; 329 328 329 + realview_clk_init(__io_address(REALVIEW_SYS_BASE), true); 330 330 realview_timer_init(IRQ_DC1176_TIMER0); 331 331 } 332 332
+2
arch/arm/mach-realview/realview_pb11mp.c
··· 27 27 #include <linux/amba/mmci.h> 28 28 #include <linux/amba/pl022.h> 29 29 #include <linux/io.h> 30 + #include <linux/platform_data/clk-realview.h> 30 31 31 32 #include <mach/hardware.h> 32 33 #include <asm/irq.h> ··· 313 312 timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE); 314 313 timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20; 315 314 315 + realview_clk_init(__io_address(REALVIEW_SYS_BASE), false); 316 316 realview_timer_init(IRQ_TC11MP_TIMER0_1); 317 317 realview_pb11mp_twd_init(); 318 318 }
+2
arch/arm/mach-realview/realview_pba8.c
··· 27 27 #include <linux/amba/mmci.h> 28 28 #include <linux/amba/pl022.h> 29 29 #include <linux/io.h> 30 + #include <linux/platform_data/clk-realview.h> 30 31 31 32 #include <asm/irq.h> 32 33 #include <asm/leds.h> ··· 262 261 timer2_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE); 263 262 timer3_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE) + 0x20; 264 263 264 + realview_clk_init(__io_address(REALVIEW_SYS_BASE), false); 265 265 realview_timer_init(IRQ_PBA8_TIMER0_1); 266 266 } 267 267
+2
arch/arm/mach-realview/realview_pbx.c
··· 26 26 #include <linux/amba/mmci.h> 27 27 #include <linux/amba/pl022.h> 28 28 #include <linux/io.h> 29 + #include <linux/platform_data/clk-realview.h> 29 30 30 31 #include <asm/irq.h> 31 32 #include <asm/leds.h> ··· 321 320 timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE); 322 321 timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20; 323 322 323 + realview_clk_init(__io_address(REALVIEW_SYS_BASE), false); 324 324 realview_timer_init(IRQ_PBX_TIMER0_1); 325 325 realview_pbx_twd_init(); 326 326 }
+7
drivers/clk/Kconfig
··· 40 40 Supports the clocking subsystem of the WM831x/2x series of 41 41 PMICs from Wolfson Microlectronics. 42 42 43 + config COMMON_CLK_VERSATILE 44 + tristate "Clock driver for ARM Reference designs" 45 + depends on ARCH_INTEGRATOR || ARCH_REALVIEW 46 + ---help--- 47 + Supports clocking on ARM Reference designs Integrator/AP, 48 + Integrator/CP, RealView PB1176, EB, PB11MP and PBX. 49 + 43 50 endmenu
+1 -1
drivers/clk/Makefile
··· 9 9 obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ 10 10 obj-$(CONFIG_PLAT_SPEAR) += spear/ 11 11 obj-$(CONFIG_ARCH_U300) += clk-u300.o 12 - obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/ 12 + obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ 13 13 obj-$(CONFIG_ARCH_PRIMA2) += clk-prima2.o 14 14 15 15 # Chip specific
+1
drivers/clk/versatile/Makefile
··· 1 1 # Makefile for Versatile-specific clocks 2 2 obj-$(CONFIG_ICST) += clk-icst.o 3 3 obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o 4 + obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o
+114
drivers/clk/versatile/clk-realview.c
··· 1 + #include <linux/clk.h> 2 + #include <linux/clkdev.h> 3 + #include <linux/err.h> 4 + #include <linux/io.h> 5 + #include <linux/clk-provider.h> 6 + 7 + #include <mach/hardware.h> 8 + #include <mach/platform.h> 9 + 10 + #include "clk-icst.h" 11 + 12 + /* 13 + * Implementation of the ARM RealView clock trees. 14 + */ 15 + 16 + static void __iomem *sys_lock; 17 + static void __iomem *sys_vcoreg; 18 + 19 + /** 20 + * realview_oscvco_get() - get ICST OSC settings for the RealView 21 + */ 22 + static struct icst_vco realview_oscvco_get(void) 23 + { 24 + u32 val; 25 + struct icst_vco vco; 26 + 27 + val = readl(sys_vcoreg); 28 + vco.v = val & 0x1ff; 29 + vco.r = (val >> 9) & 0x7f; 30 + vco.s = (val >> 16) & 03; 31 + return vco; 32 + } 33 + 34 + static void realview_oscvco_set(struct icst_vco vco) 35 + { 36 + u32 val; 37 + 38 + val = readl(sys_vcoreg) & ~0x7ffff; 39 + val |= vco.v | (vco.r << 9) | (vco.s << 16); 40 + 41 + /* This magic unlocks the CM VCO so it can be controlled */ 42 + writel(0xa05f, sys_lock); 43 + writel(val, sys_vcoreg); 44 + /* This locks the CM again */ 45 + writel(0, sys_lock); 46 + } 47 + 48 + static const struct icst_params realview_oscvco_params = { 49 + .ref = 24000000, 50 + .vco_max = ICST307_VCO_MAX, 51 + .vco_min = ICST307_VCO_MIN, 52 + .vd_min = 4 + 8, 53 + .vd_max = 511 + 8, 54 + .rd_min = 1 + 2, 55 + .rd_max = 127 + 2, 56 + .s2div = icst307_s2div, 57 + .idx2s = icst307_idx2s, 58 + }; 59 + 60 + static const struct clk_icst_desc __initdata realview_icst_desc = { 61 + .params = &realview_oscvco_params, 62 + .getvco = realview_oscvco_get, 63 + .setvco = realview_oscvco_set, 64 + }; 65 + 66 + /* 67 + * realview_clk_init() - set up the RealView clock tree 68 + */ 69 + void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) 70 + { 71 + struct clk *clk; 72 + 73 + sys_lock = sysbase + REALVIEW_SYS_LOCK_OFFSET; 74 + if (is_pb1176) 75 + sys_vcoreg = sysbase + REALVIEW_SYS_OSC0_OFFSET; 76 + else 77 + sys_vcoreg = sysbase + REALVIEW_SYS_OSC4_OFFSET; 78 + 79 + 80 + /* APB clock dummy */ 81 + clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); 82 + clk_register_clkdev(clk, "apb_pclk", NULL); 83 + 84 + /* 24 MHz clock */ 85 + clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT, 86 + 24000000); 87 + clk_register_clkdev(clk, NULL, "dev:uart0"); 88 + clk_register_clkdev(clk, NULL, "dev:uart1"); 89 + clk_register_clkdev(clk, NULL, "dev:uart2"); 90 + clk_register_clkdev(clk, NULL, "fpga:kmi0"); 91 + clk_register_clkdev(clk, NULL, "fpga:kmi1"); 92 + clk_register_clkdev(clk, NULL, "fpga:mmc0"); 93 + clk_register_clkdev(clk, NULL, "dev:ssp0"); 94 + if (is_pb1176) { 95 + /* 96 + * UART3 is on the dev chip in PB1176 97 + * UART4 only exists in PB1176 98 + */ 99 + clk_register_clkdev(clk, NULL, "dev:uart3"); 100 + clk_register_clkdev(clk, NULL, "dev:uart4"); 101 + } else 102 + clk_register_clkdev(clk, NULL, "fpga:uart3"); 103 + 104 + 105 + /* 1 MHz clock */ 106 + clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT, 107 + 1000000); 108 + clk_register_clkdev(clk, NULL, "sp804"); 109 + 110 + /* ICST VCO clock */ 111 + clk = icst_clk_register(NULL, &realview_icst_desc); 112 + clk_register_clkdev(clk, NULL, "dev:clcd"); 113 + clk_register_clkdev(clk, NULL, "issp:clcd"); 114 + }
+1
include/linux/platform_data/clk-realview.h
··· 1 + void realview_clk_init(void __iomem *sysbase, bool is_pb1176);