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

clk: samsung: add clock-driver for s3c2416, s3c2443 and s3c2450

The three SoCs share a common clock tree which only differs in the
existence of some special clocks.

As with all parts common to these three SoCs the driver is named
after the s3c2443, as it was the first SoC introducing this structure
and there exists no other label to describe this s3c24xx epoch.

The clock structure is built according to the manuals of the included
SoCs and might include changes in comparison to the previous clock
structure. As an example the sclk_uart gate was never handled previously
and the div_uart was made to be the clock used by the serial driver.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>

authored by

Heiko Stuebner and committed by
Kukjin Kim
61fbb1d2 78435c81

+561
+6
arch/arm/mach-s3c24xx/Kconfig
··· 647 647 Common code for the S3C2443 and similar processors, which includes 648 648 the S3C2416 and S3C2450. 649 649 650 + config S3C2443_COMMON_CLK 651 + bool 652 + help 653 + Temporary symbol to build the clock driver based on the common clock 654 + framework. 655 + 650 656 config S3C2443_DMA 651 657 bool 652 658 help
+1
drivers/clk/samsung/Makefile
··· 8 8 obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o 9 9 obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o 10 10 obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o 11 + obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o 11 12 obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
+462
drivers/clk/samsung/clk-s3c2443.c
··· 1 + /* 2 + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * Common Clock Framework support for S3C2443 and following SoCs. 9 + */ 10 + 11 + #include <linux/clk.h> 12 + #include <linux/clkdev.h> 13 + #include <linux/clk-provider.h> 14 + #include <linux/of.h> 15 + #include <linux/of_address.h> 16 + #include <linux/syscore_ops.h> 17 + 18 + #include <dt-bindings/clock/s3c2443.h> 19 + 20 + #include "clk.h" 21 + #include "clk-pll.h" 22 + 23 + /* S3C2416 clock controller register offsets */ 24 + #define LOCKCON0 0x00 25 + #define LOCKCON1 0x04 26 + #define MPLLCON 0x10 27 + #define EPLLCON 0x18 28 + #define EPLLCON_K 0x1C 29 + #define CLKSRC 0x20 30 + #define CLKDIV0 0x24 31 + #define CLKDIV1 0x28 32 + #define CLKDIV2 0x2C 33 + #define HCLKCON 0x30 34 + #define PCLKCON 0x34 35 + #define SCLKCON 0x38 36 + 37 + /* the soc types */ 38 + enum supported_socs { 39 + S3C2416, 40 + S3C2443, 41 + S3C2450, 42 + }; 43 + 44 + /* list of PLLs to be registered */ 45 + enum s3c2443_plls { 46 + mpll, epll, 47 + }; 48 + 49 + static void __iomem *reg_base; 50 + 51 + #ifdef CONFIG_PM_SLEEP 52 + static struct samsung_clk_reg_dump *s3c2443_save; 53 + 54 + /* 55 + * list of controller registers to be saved and restored during a 56 + * suspend/resume cycle. 57 + */ 58 + static unsigned long s3c2443_clk_regs[] __initdata = { 59 + LOCKCON0, 60 + LOCKCON1, 61 + MPLLCON, 62 + EPLLCON, 63 + EPLLCON_K, 64 + CLKSRC, 65 + CLKDIV0, 66 + CLKDIV1, 67 + CLKDIV2, 68 + PCLKCON, 69 + HCLKCON, 70 + SCLKCON, 71 + }; 72 + 73 + static int s3c2443_clk_suspend(void) 74 + { 75 + samsung_clk_save(reg_base, s3c2443_save, 76 + ARRAY_SIZE(s3c2443_clk_regs)); 77 + 78 + return 0; 79 + } 80 + 81 + static void s3c2443_clk_resume(void) 82 + { 83 + samsung_clk_restore(reg_base, s3c2443_save, 84 + ARRAY_SIZE(s3c2443_clk_regs)); 85 + } 86 + 87 + static struct syscore_ops s3c2443_clk_syscore_ops = { 88 + .suspend = s3c2443_clk_suspend, 89 + .resume = s3c2443_clk_resume, 90 + }; 91 + 92 + static void s3c2443_clk_sleep_init(void) 93 + { 94 + s3c2443_save = samsung_clk_alloc_reg_dump(s3c2443_clk_regs, 95 + ARRAY_SIZE(s3c2443_clk_regs)); 96 + if (!s3c2443_save) { 97 + pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", 98 + __func__); 99 + return; 100 + } 101 + 102 + register_syscore_ops(&s3c2443_clk_syscore_ops); 103 + return; 104 + } 105 + #else 106 + static void s3c2443_clk_sleep_init(void) {} 107 + #endif 108 + 109 + PNAME(epllref_p) = { "mpllref", "mpllref", "xti", "ext" }; 110 + PNAME(esysclk_p) = { "epllref", "epll" }; 111 + PNAME(mpllref_p) = { "xti", "mdivclk" }; 112 + PNAME(msysclk_p) = { "mpllref", "mpll" }; 113 + PNAME(armclk_p) = { "armdiv" , "hclk" }; 114 + PNAME(i2s0_p) = { "div_i2s0", "ext_i2s", "epllref", "epllref" }; 115 + 116 + struct samsung_mux_clock s3c2443_common_muxes[] __initdata = { 117 + MUX(0, "epllref", epllref_p, CLKSRC, 7, 2), 118 + MUX(ESYSCLK, "esysclk", esysclk_p, CLKSRC, 6, 1), 119 + MUX(0, "mpllref", mpllref_p, CLKSRC, 3, 1), 120 + MUX_A(MSYSCLK, "msysclk", msysclk_p, CLKSRC, 4, 1, "msysclk"), 121 + MUX_A(ARMCLK, "armclk", armclk_p, CLKDIV0, 13, 1, "armclk"), 122 + MUX(0, "mux_i2s0", i2s0_p, CLKSRC, 14, 2), 123 + }; 124 + 125 + static struct clk_div_table hclk_d[] = { 126 + { .val = 0, .div = 1 }, 127 + { .val = 1, .div = 2 }, 128 + { .val = 3, .div = 4 }, 129 + { /* sentinel */ }, 130 + }; 131 + 132 + static struct clk_div_table mdivclk_d[] = { 133 + { .val = 0, .div = 1 }, 134 + { .val = 1, .div = 3 }, 135 + { .val = 2, .div = 5 }, 136 + { .val = 3, .div = 7 }, 137 + { .val = 4, .div = 9 }, 138 + { .val = 5, .div = 11 }, 139 + { .val = 6, .div = 13 }, 140 + { .val = 7, .div = 15 }, 141 + { /* sentinel */ }, 142 + }; 143 + 144 + struct samsung_div_clock s3c2443_common_dividers[] __initdata = { 145 + DIV_T(0, "mdivclk", "xti", CLKDIV0, 6, 3, mdivclk_d), 146 + DIV(0, "prediv", "msysclk", CLKDIV0, 4, 2), 147 + DIV_T(HCLK, "hclk", "prediv", CLKDIV0, 0, 2, hclk_d), 148 + DIV(PCLK, "pclk", "hclk", CLKDIV0, 2, 1), 149 + DIV(0, "div_hsspi0_epll", "esysclk", CLKDIV1, 24, 2), 150 + DIV(0, "div_fimd", "esysclk", CLKDIV1, 16, 8), 151 + DIV(0, "div_i2s0", "esysclk", CLKDIV1, 12, 4), 152 + DIV(0, "div_uart", "esysclk", CLKDIV1, 8, 4), 153 + DIV(0, "div_hsmmc1", "esysclk", CLKDIV1, 6, 2), 154 + DIV(0, "div_usbhost", "esysclk", CLKDIV1, 4, 2), 155 + }; 156 + 157 + struct samsung_gate_clock s3c2443_common_gates[] __initdata = { 158 + GATE(SCLK_HSMMC_EXT, "sclk_hsmmcext", "ext", SCLKCON, 13, 0, 0), 159 + GATE(SCLK_HSMMC1, "sclk_hsmmc1", "div_hsmmc1", SCLKCON, 12, 0, 0), 160 + GATE(SCLK_FIMD, "sclk_fimd", "div_fimd", SCLKCON, 10, 0, 0), 161 + GATE(SCLK_I2S0, "sclk_i2s0", "mux_i2s0", SCLKCON, 9, 0, 0), 162 + GATE(SCLK_UART, "sclk_uart", "div_uart", SCLKCON, 8, 0, 0), 163 + GATE(SCLK_USBH, "sclk_usbhost", "div_usbhost", SCLKCON, 1, 0, 0), 164 + GATE(HCLK_DRAM, "dram", "hclk", HCLKCON, 19, CLK_IGNORE_UNUSED, 0), 165 + GATE(HCLK_SSMC, "ssmc", "hclk", HCLKCON, 18, CLK_IGNORE_UNUSED, 0), 166 + GATE(HCLK_HSMMC1, "hsmmc1", "hclk", HCLKCON, 16, 0, 0), 167 + GATE(HCLK_USBD, "usb-device", "hclk", HCLKCON, 12, 0, 0), 168 + GATE(HCLK_USBH, "usb-host", "hclk", HCLKCON, 11, 0, 0), 169 + GATE(HCLK_LCD, "lcd", "hclk", HCLKCON, 9, 0, 0), 170 + GATE(HCLK_DMA5, "dma5", "hclk", HCLKCON, 5, CLK_IGNORE_UNUSED, 0), 171 + GATE(HCLK_DMA4, "dma4", "hclk", HCLKCON, 4, CLK_IGNORE_UNUSED, 0), 172 + GATE(HCLK_DMA3, "dma3", "hclk", HCLKCON, 3, CLK_IGNORE_UNUSED, 0), 173 + GATE(HCLK_DMA2, "dma2", "hclk", HCLKCON, 2, CLK_IGNORE_UNUSED, 0), 174 + GATE(HCLK_DMA1, "dma1", "hclk", HCLKCON, 1, CLK_IGNORE_UNUSED, 0), 175 + GATE(HCLK_DMA0, "dma0", "hclk", HCLKCON, 0, CLK_IGNORE_UNUSED, 0), 176 + GATE(PCLK_GPIO, "gpio", "pclk", PCLKCON, 13, CLK_IGNORE_UNUSED, 0), 177 + GATE(PCLK_RTC, "rtc", "pclk", PCLKCON, 12, 0, 0), 178 + GATE(PCLK_WDT, "wdt", "pclk", PCLKCON, 11, 0, 0), 179 + GATE(PCLK_PWM, "pwm", "pclk", PCLKCON, 10, 0, 0), 180 + GATE(PCLK_I2S0, "i2s0", "pclk", PCLKCON, 9, 0, 0), 181 + GATE(PCLK_AC97, "ac97", "pclk", PCLKCON, 8, 0, 0), 182 + GATE(PCLK_ADC, "adc", "pclk", PCLKCON, 7, 0, 0), 183 + GATE(PCLK_SPI0, "spi0", "pclk", PCLKCON, 6, 0, 0), 184 + GATE(PCLK_I2C0, "i2c0", "pclk", PCLKCON, 4, 0, 0), 185 + GATE(PCLK_UART3, "uart3", "pclk", PCLKCON, 3, 0, 0), 186 + GATE(PCLK_UART2, "uart2", "pclk", PCLKCON, 2, 0, 0), 187 + GATE(PCLK_UART1, "uart1", "pclk", PCLKCON, 1, 0, 0), 188 + GATE(PCLK_UART0, "uart0", "pclk", PCLKCON, 0, 0, 0), 189 + }; 190 + 191 + struct samsung_clock_alias s3c2443_common_aliases[] __initdata = { 192 + ALIAS(HCLK, NULL, "hclk"), 193 + ALIAS(HCLK_SSMC, NULL, "nand"), 194 + ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"), 195 + ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"), 196 + ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"), 197 + ALIAS(PCLK_UART3, "s3c2440-uart.3", "uart"), 198 + ALIAS(PCLK_UART0, "s3c2440-uart.0", "clk_uart_baud2"), 199 + ALIAS(PCLK_UART1, "s3c2440-uart.1", "clk_uart_baud2"), 200 + ALIAS(PCLK_UART2, "s3c2440-uart.2", "clk_uart_baud2"), 201 + ALIAS(PCLK_UART3, "s3c2440-uart.3", "clk_uart_baud2"), 202 + ALIAS(SCLK_UART, NULL, "clk_uart_baud3"), 203 + ALIAS(PCLK_PWM, NULL, "timers"), 204 + ALIAS(PCLK_RTC, NULL, "rtc"), 205 + ALIAS(PCLK_WDT, NULL, "watchdog"), 206 + ALIAS(PCLK_ADC, NULL, "adc"), 207 + ALIAS(PCLK_I2C0, "s3c2410-i2c.0", "i2c"), 208 + ALIAS(HCLK_USBD, NULL, "usb-device"), 209 + ALIAS(HCLK_USBH, NULL, "usb-host"), 210 + ALIAS(SCLK_USBH, NULL, "usb-bus-host"), 211 + ALIAS(PCLK_SPI0, "s3c2443-spi.0", "spi"), 212 + ALIAS(PCLK_SPI0, "s3c2443-spi.0", "spi_busclk0"), 213 + ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "hsmmc"), 214 + ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"), 215 + ALIAS(PCLK_I2S0, "samsung-i2s.0", "iis"), 216 + ALIAS(SCLK_I2S0, NULL, "i2s-if"), 217 + ALIAS(HCLK_LCD, NULL, "lcd"), 218 + ALIAS(SCLK_FIMD, NULL, "sclk_fimd"), 219 + }; 220 + 221 + /* S3C2416 specific clocks */ 222 + 223 + static struct samsung_pll_clock s3c2416_pll_clks[] __initdata = { 224 + [mpll] = PLL(pll_6552_s3c2416, 0, "mpll", "mpllref", 225 + LOCKCON0, MPLLCON, NULL), 226 + [epll] = PLL(pll_6553, 0, "epll", "epllref", 227 + LOCKCON1, EPLLCON, NULL), 228 + }; 229 + 230 + PNAME(s3c2416_hsmmc0_p) = { "sclk_hsmmc0", "sclk_hsmmcext" }; 231 + PNAME(s3c2416_hsmmc1_p) = { "sclk_hsmmc1", "sclk_hsmmcext" }; 232 + PNAME(s3c2416_hsspi0_p) = { "hsspi0_epll", "hsspi0_mpll" }; 233 + 234 + static struct clk_div_table armdiv_s3c2416_d[] = { 235 + { .val = 0, .div = 1 }, 236 + { .val = 1, .div = 2 }, 237 + { .val = 2, .div = 3 }, 238 + { .val = 3, .div = 4 }, 239 + { .val = 5, .div = 6 }, 240 + { .val = 7, .div = 8 }, 241 + { /* sentinel */ }, 242 + }; 243 + 244 + struct samsung_div_clock s3c2416_dividers[] __initdata = { 245 + DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 3, armdiv_s3c2416_d), 246 + DIV(0, "div_hsspi0_mpll", "msysclk", CLKDIV2, 0, 4), 247 + DIV(0, "div_hsmmc0", "esysclk", CLKDIV2, 6, 2), 248 + }; 249 + 250 + struct samsung_mux_clock s3c2416_muxes[] __initdata = { 251 + MUX(MUX_HSMMC0, "mux_hsmmc0", s3c2416_hsmmc0_p, CLKSRC, 16, 1), 252 + MUX(MUX_HSMMC1, "mux_hsmmc1", s3c2416_hsmmc1_p, CLKSRC, 17, 1), 253 + MUX(MUX_HSSPI0, "mux_hsspi0", s3c2416_hsspi0_p, CLKSRC, 18, 1), 254 + }; 255 + 256 + struct samsung_gate_clock s3c2416_gates[] __initdata = { 257 + GATE(0, "hsspi0_mpll", "div_hsspi0_mpll", SCLKCON, 19, 0, 0), 258 + GATE(0, "hsspi0_epll", "div_hsspi0_epll", SCLKCON, 14, 0, 0), 259 + GATE(0, "sclk_hsmmc0", "div_hsmmc0", SCLKCON, 6, 0, 0), 260 + GATE(HCLK_2D, "2d", "hclk", HCLKCON, 20, 0, 0), 261 + GATE(HCLK_HSMMC0, "hsmmc0", "hclk", HCLKCON, 15, 0, 0), 262 + GATE(HCLK_IROM, "irom", "hclk", HCLKCON, 13, CLK_IGNORE_UNUSED, 0), 263 + GATE(PCLK_PCM, "pcm", "pclk", PCLKCON, 19, 0, 0), 264 + }; 265 + 266 + struct samsung_clock_alias s3c2416_aliases[] __initdata = { 267 + ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"), 268 + ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"), 269 + ALIAS(MUX_HSMMC0, "s3c-sdhci.0", "mmc_busclk.2"), 270 + ALIAS(MUX_HSMMC1, "s3c-sdhci.1", "mmc_busclk.2"), 271 + ALIAS(MUX_HSSPI0, "s3c2443-spi.0", "spi_busclk2"), 272 + ALIAS(ARMDIV, NULL, "armdiv"), 273 + }; 274 + 275 + /* S3C2443 specific clocks */ 276 + 277 + static struct samsung_pll_clock s3c2443_pll_clks[] __initdata = { 278 + [mpll] = PLL(pll_3000, 0, "mpll", "mpllref", 279 + LOCKCON0, MPLLCON, NULL), 280 + [epll] = PLL(pll_2126, 0, "epll", "epllref", 281 + LOCKCON1, EPLLCON, NULL), 282 + }; 283 + 284 + static struct clk_div_table armdiv_s3c2443_d[] = { 285 + { .val = 0, .div = 1 }, 286 + { .val = 8, .div = 2 }, 287 + { .val = 2, .div = 3 }, 288 + { .val = 9, .div = 4 }, 289 + { .val = 10, .div = 6 }, 290 + { .val = 11, .div = 8 }, 291 + { .val = 13, .div = 12 }, 292 + { .val = 15, .div = 16 }, 293 + { /* sentinel */ }, 294 + }; 295 + 296 + struct samsung_div_clock s3c2443_dividers[] __initdata = { 297 + DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 4, armdiv_s3c2443_d), 298 + DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4), 299 + }; 300 + 301 + struct samsung_gate_clock s3c2443_gates[] __initdata = { 302 + GATE(SCLK_HSSPI0, "sclk_hsspi0", "div_hsspi0_epll", SCLKCON, 14, 0, 0), 303 + GATE(SCLK_CAM, "sclk_cam", "div_cam", SCLKCON, 11, 0, 0), 304 + GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, CLK_IGNORE_UNUSED, 0), 305 + GATE(HCLK_CAM, "cam", "hclk", HCLKCON, 8, 0, 0), 306 + GATE(PCLK_SPI1, "spi1", "pclk", PCLKCON, 15, 0, 0), 307 + GATE(PCLK_SDI, "sdi", "pclk", PCLKCON, 5, 0, 0), 308 + }; 309 + 310 + struct samsung_clock_alias s3c2443_aliases[] __initdata = { 311 + ALIAS(SCLK_HSSPI0, "s3c2443-spi.0", "spi_busclk2"), 312 + ALIAS(SCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.2"), 313 + ALIAS(SCLK_CAM, NULL, "camif-upll"), 314 + ALIAS(PCLK_SPI1, "s3c2410-spi.0", "spi"), 315 + ALIAS(PCLK_SDI, NULL, "sdi"), 316 + ALIAS(HCLK_CFC, NULL, "cfc"), 317 + ALIAS(ARMDIV, NULL, "armdiv"), 318 + }; 319 + 320 + /* S3C2450 specific clocks */ 321 + 322 + PNAME(s3c2450_cam_p) = { "div_cam", "hclk" }; 323 + PNAME(s3c2450_hsspi1_p) = { "hsspi1_epll", "hsspi1_mpll" }; 324 + PNAME(i2s1_p) = { "div_i2s1", "ext_i2s", "epllref", "epllref" }; 325 + 326 + struct samsung_div_clock s3c2450_dividers[] __initdata = { 327 + DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4), 328 + DIV(0, "div_hsspi1_epll", "esysclk", CLKDIV2, 24, 2), 329 + DIV(0, "div_hsspi1_mpll", "msysclk", CLKDIV2, 16, 4), 330 + DIV(0, "div_i2s1", "esysclk", CLKDIV2, 12, 4), 331 + }; 332 + 333 + struct samsung_mux_clock s3c2450_muxes[] __initdata = { 334 + MUX(0, "mux_cam", s3c2450_cam_p, CLKSRC, 20, 1), 335 + MUX(MUX_HSSPI1, "mux_hsspi1", s3c2450_hsspi1_p, CLKSRC, 19, 1), 336 + MUX(0, "mux_i2s1", i2s1_p, CLKSRC, 12, 2), 337 + }; 338 + 339 + struct samsung_gate_clock s3c2450_gates[] __initdata = { 340 + GATE(SCLK_I2S1, "sclk_i2s1", "div_i2s1", SCLKCON, 5, 0, 0), 341 + GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, 0, 0), 342 + GATE(HCLK_CAM, "cam", "hclk", HCLKCON, 8, 0, 0), 343 + GATE(HCLK_DMA7, "dma7", "hclk", HCLKCON, 7, CLK_IGNORE_UNUSED, 0), 344 + GATE(HCLK_DMA6, "dma6", "hclk", HCLKCON, 6, CLK_IGNORE_UNUSED, 0), 345 + GATE(PCLK_I2S1, "i2s1", "pclk", PCLKCON, 17, 0, 0), 346 + GATE(PCLK_I2C1, "i2c1", "pclk", PCLKCON, 16, 0, 0), 347 + GATE(PCLK_SPI1, "spi1", "pclk", PCLKCON, 14, 0, 0), 348 + }; 349 + 350 + struct samsung_clock_alias s3c2450_aliases[] __initdata = { 351 + ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi"), 352 + ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi_busclk0"), 353 + ALIAS(MUX_HSSPI1, "s3c2443-spi.1", "spi_busclk2"), 354 + ALIAS(PCLK_I2C1, "s3c2410-i2c.1", "i2c"), 355 + }; 356 + 357 + /* 358 + * fixed rate clocks generated outside the soc 359 + * Only necessary until the devicetree-move is complete 360 + */ 361 + struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = { 362 + FRATE(0, "xti", NULL, CLK_IS_ROOT, 0), 363 + FRATE(0, "ext", NULL, CLK_IS_ROOT, 0), 364 + FRATE(0, "ext_i2s", NULL, CLK_IS_ROOT, 0), 365 + FRATE(0, "ext_uart", NULL, CLK_IS_ROOT, 0), 366 + }; 367 + 368 + static void __init s3c2443_common_clk_register_fixed_ext(unsigned long xti_f) 369 + { 370 + s3c2443_common_frate_clks[0].fixed_rate = xti_f; 371 + samsung_clk_register_fixed_rate(s3c2443_common_frate_clks, 372 + ARRAY_SIZE(s3c2443_common_frate_clks)); 373 + } 374 + 375 + void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f, 376 + int current_soc, 377 + void __iomem *base) 378 + { 379 + reg_base = base; 380 + 381 + if (np) { 382 + reg_base = of_iomap(np, 0); 383 + if (!reg_base) 384 + panic("%s: failed to map registers\n", __func__); 385 + } 386 + 387 + samsung_clk_init(np, reg_base, NR_CLKS); 388 + 389 + /* Register external clocks only in non-dt cases */ 390 + if (!np) 391 + s3c2443_common_clk_register_fixed_ext(xti_f); 392 + 393 + /* Register PLLs. */ 394 + if (current_soc == S3C2416 || current_soc == S3C2450) 395 + samsung_clk_register_pll(s3c2416_pll_clks, 396 + ARRAY_SIZE(s3c2416_pll_clks), reg_base); 397 + else 398 + samsung_clk_register_pll(s3c2443_pll_clks, 399 + ARRAY_SIZE(s3c2443_pll_clks), reg_base); 400 + 401 + /* Register common internal clocks. */ 402 + samsung_clk_register_mux(s3c2443_common_muxes, 403 + ARRAY_SIZE(s3c2443_common_muxes)); 404 + samsung_clk_register_div(s3c2443_common_dividers, 405 + ARRAY_SIZE(s3c2443_common_dividers)); 406 + samsung_clk_register_gate(s3c2443_common_gates, 407 + ARRAY_SIZE(s3c2443_common_gates)); 408 + samsung_clk_register_alias(s3c2443_common_aliases, 409 + ARRAY_SIZE(s3c2443_common_aliases)); 410 + 411 + /* Register SoC-specific clocks. */ 412 + switch (current_soc) { 413 + case S3C2450: 414 + samsung_clk_register_div(s3c2450_dividers, 415 + ARRAY_SIZE(s3c2450_dividers)); 416 + samsung_clk_register_mux(s3c2450_muxes, 417 + ARRAY_SIZE(s3c2450_muxes)); 418 + samsung_clk_register_gate(s3c2450_gates, 419 + ARRAY_SIZE(s3c2450_gates)); 420 + samsung_clk_register_alias(s3c2450_aliases, 421 + ARRAY_SIZE(s3c2450_aliases)); 422 + /* fall through, as s3c2450 extends the s3c2416 clocks */ 423 + case S3C2416: 424 + samsung_clk_register_div(s3c2416_dividers, 425 + ARRAY_SIZE(s3c2416_dividers)); 426 + samsung_clk_register_mux(s3c2416_muxes, 427 + ARRAY_SIZE(s3c2416_muxes)); 428 + samsung_clk_register_gate(s3c2416_gates, 429 + ARRAY_SIZE(s3c2416_gates)); 430 + samsung_clk_register_alias(s3c2416_aliases, 431 + ARRAY_SIZE(s3c2416_aliases)); 432 + break; 433 + case S3C2443: 434 + samsung_clk_register_div(s3c2443_dividers, 435 + ARRAY_SIZE(s3c2443_dividers)); 436 + samsung_clk_register_gate(s3c2443_gates, 437 + ARRAY_SIZE(s3c2443_gates)); 438 + samsung_clk_register_alias(s3c2443_aliases, 439 + ARRAY_SIZE(s3c2443_aliases)); 440 + break; 441 + } 442 + 443 + s3c2443_clk_sleep_init(); 444 + } 445 + 446 + static void __init s3c2416_clk_init(struct device_node *np) 447 + { 448 + s3c2443_common_clk_init(np, 0, S3C2416, 0); 449 + } 450 + CLK_OF_DECLARE(s3c2416_clk, "samsung,s3c2416-clock", s3c2416_clk_init); 451 + 452 + static void __init s3c2443_clk_init(struct device_node *np) 453 + { 454 + s3c2443_common_clk_init(np, 0, S3C2443, 0); 455 + } 456 + CLK_OF_DECLARE(s3c2443_clk, "samsung,s3c2443-clock", s3c2443_clk_init); 457 + 458 + static void __init s3c2450_clk_init(struct device_node *np) 459 + { 460 + s3c2443_common_clk_init(np, 0, S3C2450, 0); 461 + } 462 + CLK_OF_DECLARE(s3c2450_clk, "samsung,s3c2450-clock", s3c2450_clk_init);
+92
include/dt-bindings/clock/s3c2443.h
··· 1 + /* 2 + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * Device Tree binding constants clock controllers of Samsung S3C2443 and later. 9 + */ 10 + 11 + #ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_CLOCK_H 12 + #define _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_CLOCK_H 13 + 14 + /* 15 + * Let each exported clock get a unique index, which is used on DT-enabled 16 + * platforms to lookup the clock from a clock specifier. These indices are 17 + * therefore considered an ABI and so must not be changed. This implies 18 + * that new clocks should be added either in free spaces between clock groups 19 + * or at the end. 20 + */ 21 + 22 + /* Core clocks. */ 23 + #define MSYSCLK 1 24 + #define ESYSCLK 2 25 + #define ARMDIV 3 26 + #define ARMCLK 4 27 + #define HCLK 5 28 + #define PCLK 6 29 + 30 + /* Special clocks */ 31 + #define SCLK_HSSPI0 16 32 + #define SCLK_FIMD 17 33 + #define SCLK_I2S0 18 34 + #define SCLK_I2S1 19 35 + #define SCLK_HSMMC1 20 36 + #define SCLK_HSMMC_EXT 21 37 + #define SCLK_CAM 22 38 + #define SCLK_UART 23 39 + #define SCLK_USBH 24 40 + 41 + /* Muxes */ 42 + #define MUX_HSSPI0 32 43 + #define MUX_HSSPI1 33 44 + #define MUX_HSMMC0 34 45 + #define MUX_HSMMC1 35 46 + 47 + /* hclk-gates */ 48 + #define HCLK_DMA0 48 49 + #define HCLK_DMA1 49 50 + #define HCLK_DMA2 50 51 + #define HCLK_DMA3 51 52 + #define HCLK_DMA4 52 53 + #define HCLK_DMA5 53 54 + #define HCLK_DMA6 54 55 + #define HCLK_DMA7 55 56 + #define HCLK_CAM 56 57 + #define HCLK_LCD 57 58 + #define HCLK_USBH 58 59 + #define HCLK_USBD 59 60 + #define HCLK_IROM 60 61 + #define HCLK_HSMMC0 61 62 + #define HCLK_HSMMC1 62 63 + #define HCLK_CFC 63 64 + #define HCLK_SSMC 64 65 + #define HCLK_DRAM 65 66 + #define HCLK_2D 66 67 + 68 + /* pclk-gates */ 69 + #define PCLK_UART0 72 70 + #define PCLK_UART1 73 71 + #define PCLK_UART2 74 72 + #define PCLK_UART3 75 73 + #define PCLK_I2C0 76 74 + #define PCLK_SDI 77 75 + #define PCLK_SPI0 78 76 + #define PCLK_ADC 79 77 + #define PCLK_AC97 80 78 + #define PCLK_I2S0 81 79 + #define PCLK_PWM 82 80 + #define PCLK_WDT 83 81 + #define PCLK_RTC 84 82 + #define PCLK_GPIO 85 83 + #define PCLK_SPI1 86 84 + #define PCLK_CHIPID 87 85 + #define PCLK_I2C1 88 86 + #define PCLK_I2S1 89 87 + #define PCLK_PCM 90 88 + 89 + /* Total number of clocks. */ 90 + #define NR_CLKS (PCLK_PCM + 1) 91 + 92 + #endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_CLOCK_H */