18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de> 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Common Clock Framework support for S3C2410 and following SoCs. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/clk-provider.h> 98c2ecf20Sopenharmony_ci#include <linux/clk/samsung.h> 108c2ecf20Sopenharmony_ci#include <linux/of.h> 118c2ecf20Sopenharmony_ci#include <linux/of_address.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <dt-bindings/clock/s3c2410.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include "clk.h" 168c2ecf20Sopenharmony_ci#include "clk-pll.h" 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#define LOCKTIME 0x00 198c2ecf20Sopenharmony_ci#define MPLLCON 0x04 208c2ecf20Sopenharmony_ci#define UPLLCON 0x08 218c2ecf20Sopenharmony_ci#define CLKCON 0x0c 228c2ecf20Sopenharmony_ci#define CLKSLOW 0x10 238c2ecf20Sopenharmony_ci#define CLKDIVN 0x14 248c2ecf20Sopenharmony_ci#define CAMDIVN 0x18 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* the soc types */ 278c2ecf20Sopenharmony_cienum supported_socs { 288c2ecf20Sopenharmony_ci S3C2410, 298c2ecf20Sopenharmony_ci S3C2440, 308c2ecf20Sopenharmony_ci S3C2442, 318c2ecf20Sopenharmony_ci}; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci/* list of PLLs to be registered */ 348c2ecf20Sopenharmony_cienum s3c2410_plls { 358c2ecf20Sopenharmony_ci mpll, upll, 368c2ecf20Sopenharmony_ci}; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistatic void __iomem *reg_base; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* 418c2ecf20Sopenharmony_ci * list of controller registers to be saved and restored during a 428c2ecf20Sopenharmony_ci * suspend/resume cycle. 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_cistatic unsigned long s3c2410_clk_regs[] __initdata = { 458c2ecf20Sopenharmony_ci LOCKTIME, 468c2ecf20Sopenharmony_ci MPLLCON, 478c2ecf20Sopenharmony_ci UPLLCON, 488c2ecf20Sopenharmony_ci CLKCON, 498c2ecf20Sopenharmony_ci CLKSLOW, 508c2ecf20Sopenharmony_ci CLKDIVN, 518c2ecf20Sopenharmony_ci CAMDIVN, 528c2ecf20Sopenharmony_ci}; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ciPNAME(fclk_p) = { "mpll", "div_slow" }; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic struct samsung_mux_clock s3c2410_common_muxes[] __initdata = { 578c2ecf20Sopenharmony_ci MUX(FCLK, "fclk", fclk_p, CLKSLOW, 4, 1), 588c2ecf20Sopenharmony_ci}; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic struct clk_div_table divslow_d[] = { 618c2ecf20Sopenharmony_ci { .val = 0, .div = 1 }, 628c2ecf20Sopenharmony_ci { .val = 1, .div = 2 }, 638c2ecf20Sopenharmony_ci { .val = 2, .div = 4 }, 648c2ecf20Sopenharmony_ci { .val = 3, .div = 6 }, 658c2ecf20Sopenharmony_ci { .val = 4, .div = 8 }, 668c2ecf20Sopenharmony_ci { .val = 5, .div = 10 }, 678c2ecf20Sopenharmony_ci { .val = 6, .div = 12 }, 688c2ecf20Sopenharmony_ci { .val = 7, .div = 14 }, 698c2ecf20Sopenharmony_ci { /* sentinel */ }, 708c2ecf20Sopenharmony_ci}; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic struct samsung_div_clock s3c2410_common_dividers[] __initdata = { 738c2ecf20Sopenharmony_ci DIV_T(0, "div_slow", "xti", CLKSLOW, 0, 3, divslow_d), 748c2ecf20Sopenharmony_ci DIV(PCLK, "pclk", "hclk", CLKDIVN, 0, 1), 758c2ecf20Sopenharmony_ci}; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic struct samsung_gate_clock s3c2410_common_gates[] __initdata = { 788c2ecf20Sopenharmony_ci GATE(PCLK_SPI, "spi", "pclk", CLKCON, 18, 0, 0), 798c2ecf20Sopenharmony_ci GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 17, 0, 0), 808c2ecf20Sopenharmony_ci GATE(PCLK_I2C, "i2c", "pclk", CLKCON, 16, 0, 0), 818c2ecf20Sopenharmony_ci GATE(PCLK_ADC, "adc", "pclk", CLKCON, 15, 0, 0), 828c2ecf20Sopenharmony_ci GATE(PCLK_RTC, "rtc", "pclk", CLKCON, 14, 0, 0), 838c2ecf20Sopenharmony_ci GATE(PCLK_GPIO, "gpio", "pclk", CLKCON, 13, CLK_IGNORE_UNUSED, 0), 848c2ecf20Sopenharmony_ci GATE(PCLK_UART2, "uart2", "pclk", CLKCON, 12, 0, 0), 858c2ecf20Sopenharmony_ci GATE(PCLK_UART1, "uart1", "pclk", CLKCON, 11, 0, 0), 868c2ecf20Sopenharmony_ci GATE(PCLK_UART0, "uart0", "pclk", CLKCON, 10, 0, 0), 878c2ecf20Sopenharmony_ci GATE(PCLK_SDI, "sdi", "pclk", CLKCON, 9, 0, 0), 888c2ecf20Sopenharmony_ci GATE(PCLK_PWM, "pwm", "pclk", CLKCON, 8, 0, 0), 898c2ecf20Sopenharmony_ci GATE(HCLK_USBD, "usb-device", "hclk", CLKCON, 7, 0, 0), 908c2ecf20Sopenharmony_ci GATE(HCLK_USBH, "usb-host", "hclk", CLKCON, 6, 0, 0), 918c2ecf20Sopenharmony_ci GATE(HCLK_LCD, "lcd", "hclk", CLKCON, 5, 0, 0), 928c2ecf20Sopenharmony_ci GATE(HCLK_NAND, "nand", "hclk", CLKCON, 4, 0, 0), 938c2ecf20Sopenharmony_ci}; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci/* should be added _after_ the soc-specific clocks are created */ 968c2ecf20Sopenharmony_cistatic struct samsung_clock_alias s3c2410_common_aliases[] __initdata = { 978c2ecf20Sopenharmony_ci ALIAS(PCLK_I2C, "s3c2410-i2c.0", "i2c"), 988c2ecf20Sopenharmony_ci ALIAS(PCLK_ADC, NULL, "adc"), 998c2ecf20Sopenharmony_ci ALIAS(PCLK_RTC, NULL, "rtc"), 1008c2ecf20Sopenharmony_ci ALIAS(PCLK_PWM, NULL, "timers"), 1018c2ecf20Sopenharmony_ci ALIAS(HCLK_LCD, NULL, "lcd"), 1028c2ecf20Sopenharmony_ci ALIAS(HCLK_USBD, NULL, "usb-device"), 1038c2ecf20Sopenharmony_ci ALIAS(HCLK_USBH, NULL, "usb-host"), 1048c2ecf20Sopenharmony_ci ALIAS(UCLK, NULL, "usb-bus-host"), 1058c2ecf20Sopenharmony_ci ALIAS(UCLK, NULL, "usb-bus-gadget"), 1068c2ecf20Sopenharmony_ci ALIAS(ARMCLK, NULL, "armclk"), 1078c2ecf20Sopenharmony_ci ALIAS(UCLK, NULL, "uclk"), 1088c2ecf20Sopenharmony_ci ALIAS(HCLK, NULL, "hclk"), 1098c2ecf20Sopenharmony_ci ALIAS(MPLL, NULL, "mpll"), 1108c2ecf20Sopenharmony_ci ALIAS(FCLK, NULL, "fclk"), 1118c2ecf20Sopenharmony_ci ALIAS(PCLK, NULL, "watchdog"), 1128c2ecf20Sopenharmony_ci ALIAS(PCLK_SDI, NULL, "sdi"), 1138c2ecf20Sopenharmony_ci ALIAS(HCLK_NAND, NULL, "nand"), 1148c2ecf20Sopenharmony_ci ALIAS(PCLK_I2S, NULL, "iis"), 1158c2ecf20Sopenharmony_ci ALIAS(PCLK_I2C, NULL, "i2c"), 1168c2ecf20Sopenharmony_ci}; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci/* S3C2410 specific clocks */ 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistatic struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = { 1218c2ecf20Sopenharmony_ci /* sorted in descending order */ 1228c2ecf20Sopenharmony_ci /* 2410A extras */ 1238c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 270000000, 127, 1, 1), 1248c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 268000000, 126, 1, 1), 1258c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 266000000, 125, 1, 1), 1268c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 226000000, 105, 1, 1), 1278c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 210000000, 132, 2, 1), 1288c2ecf20Sopenharmony_ci /* 2410 common */ 1298c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 202800000, 161, 3, 1), 1308c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 192000000, 88, 1, 1), 1318c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 186000000, 85, 1, 1), 1328c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 180000000, 82, 1, 1), 1338c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 170000000, 77, 1, 1), 1348c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 158000000, 71, 1, 1), 1358c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 152000000, 68, 1, 1), 1368c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 147000000, 90, 2, 1), 1378c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 135000000, 82, 2, 1), 1388c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 124000000, 116, 1, 2), 1398c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 118500000, 150, 2, 2), 1408c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 113000000, 105, 1, 2), 1418c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 101250000, 127, 2, 2), 1428c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 90000000, 112, 2, 2), 1438c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 84750000, 105, 2, 2), 1448c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 79000000, 71, 1, 2), 1458c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 67500000, 82, 2, 2), 1468c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 56250000, 142, 2, 3), 1478c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 48000000, 120, 2, 3), 1488c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 50700000, 161, 3, 3), 1498c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 45000000, 82, 1, 3), 1508c2ecf20Sopenharmony_ci PLL_S3C2410_MPLL_RATE(12 * MHZ, 33750000, 82, 2, 3), 1518c2ecf20Sopenharmony_ci { /* sentinel */ }, 1528c2ecf20Sopenharmony_ci}; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic struct samsung_pll_clock s3c2410_plls[] __initdata = { 1558c2ecf20Sopenharmony_ci [mpll] = PLL(pll_s3c2410_mpll, MPLL, "mpll", "xti", 1568c2ecf20Sopenharmony_ci LOCKTIME, MPLLCON, NULL), 1578c2ecf20Sopenharmony_ci [upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti", 1588c2ecf20Sopenharmony_ci LOCKTIME, UPLLCON, NULL), 1598c2ecf20Sopenharmony_ci}; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistatic struct samsung_div_clock s3c2410_dividers[] __initdata = { 1628c2ecf20Sopenharmony_ci DIV(HCLK, "hclk", "mpll", CLKDIVN, 1, 1), 1638c2ecf20Sopenharmony_ci}; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_cistatic struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = { 1668c2ecf20Sopenharmony_ci /* 1678c2ecf20Sopenharmony_ci * armclk is directly supplied by the fclk, without 1688c2ecf20Sopenharmony_ci * switching possibility like on the s3c244x below. 1698c2ecf20Sopenharmony_ci */ 1708c2ecf20Sopenharmony_ci FFACTOR(ARMCLK, "armclk", "fclk", 1, 1, 0), 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci /* uclk is fed from the unmodified upll */ 1738c2ecf20Sopenharmony_ci FFACTOR(UCLK, "uclk", "upll", 1, 1, 0), 1748c2ecf20Sopenharmony_ci}; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_cistatic struct samsung_clock_alias s3c2410_aliases[] __initdata = { 1778c2ecf20Sopenharmony_ci ALIAS(PCLK_UART0, "s3c2410-uart.0", "uart"), 1788c2ecf20Sopenharmony_ci ALIAS(PCLK_UART1, "s3c2410-uart.1", "uart"), 1798c2ecf20Sopenharmony_ci ALIAS(PCLK_UART2, "s3c2410-uart.2", "uart"), 1808c2ecf20Sopenharmony_ci ALIAS(PCLK_UART0, "s3c2410-uart.0", "clk_uart_baud0"), 1818c2ecf20Sopenharmony_ci ALIAS(PCLK_UART1, "s3c2410-uart.1", "clk_uart_baud0"), 1828c2ecf20Sopenharmony_ci ALIAS(PCLK_UART2, "s3c2410-uart.2", "clk_uart_baud0"), 1838c2ecf20Sopenharmony_ci ALIAS(UCLK, NULL, "clk_uart_baud1"), 1848c2ecf20Sopenharmony_ci}; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci/* S3C244x specific clocks */ 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_cistatic struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = { 1898c2ecf20Sopenharmony_ci /* sorted in descending order */ 1908c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 400000000, 0x5c, 1, 1), 1918c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 390000000, 0x7a, 2, 1), 1928c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 380000000, 0x57, 1, 1), 1938c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 370000000, 0xb1, 4, 1), 1948c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 360000000, 0x70, 2, 1), 1958c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 350000000, 0xa7, 4, 1), 1968c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 340000000, 0x4d, 1, 1), 1978c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 330000000, 0x66, 2, 1), 1988c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 320000000, 0x98, 4, 1), 1998c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 310000000, 0x93, 4, 1), 2008c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 300000000, 0x75, 3, 1), 2018c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 240000000, 0x70, 1, 2), 2028c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 230000000, 0x6b, 1, 2), 2038c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 220000000, 0x66, 1, 2), 2048c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 210000000, 0x84, 2, 2), 2058c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 200000000, 0x5c, 1, 2), 2068c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 190000000, 0x57, 1, 2), 2078c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 180000000, 0x70, 2, 2), 2088c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 170000000, 0x4d, 1, 2), 2098c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 160000000, 0x98, 4, 2), 2108c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 150000000, 0x75, 3, 2), 2118c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 120000000, 0x70, 1, 3), 2128c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 110000000, 0x66, 1, 3), 2138c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 100000000, 0x5c, 1, 3), 2148c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 90000000, 0x70, 2, 3), 2158c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 80000000, 0x98, 4, 3), 2168c2ecf20Sopenharmony_ci PLL_S3C2440_MPLL_RATE(12 * MHZ, 75000000, 0x75, 3, 3), 2178c2ecf20Sopenharmony_ci { /* sentinel */ }, 2188c2ecf20Sopenharmony_ci}; 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic struct samsung_pll_clock s3c244x_common_plls[] __initdata = { 2218c2ecf20Sopenharmony_ci [mpll] = PLL(pll_s3c2440_mpll, MPLL, "mpll", "xti", 2228c2ecf20Sopenharmony_ci LOCKTIME, MPLLCON, NULL), 2238c2ecf20Sopenharmony_ci [upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti", 2248c2ecf20Sopenharmony_ci LOCKTIME, UPLLCON, NULL), 2258c2ecf20Sopenharmony_ci}; 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ciPNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" }; 2288c2ecf20Sopenharmony_ciPNAME(armclk_p) = { "fclk", "hclk" }; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cistatic struct samsung_mux_clock s3c244x_common_muxes[] __initdata = { 2318c2ecf20Sopenharmony_ci MUX(HCLK, "hclk", hclk_p, CLKDIVN, 1, 2), 2328c2ecf20Sopenharmony_ci MUX(ARMCLK, "armclk", armclk_p, CAMDIVN, 12, 1), 2338c2ecf20Sopenharmony_ci}; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cistatic struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = { 2368c2ecf20Sopenharmony_ci FFACTOR(0, "div_hclk_2", "fclk", 1, 2, 0), 2378c2ecf20Sopenharmony_ci FFACTOR(0, "ff_cam", "div_cam", 2, 1, CLK_SET_RATE_PARENT), 2388c2ecf20Sopenharmony_ci}; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_cistatic struct clk_div_table div_hclk_4_d[] = { 2418c2ecf20Sopenharmony_ci { .val = 0, .div = 4 }, 2428c2ecf20Sopenharmony_ci { .val = 1, .div = 8 }, 2438c2ecf20Sopenharmony_ci { /* sentinel */ }, 2448c2ecf20Sopenharmony_ci}; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_cistatic struct clk_div_table div_hclk_3_d[] = { 2478c2ecf20Sopenharmony_ci { .val = 0, .div = 3 }, 2488c2ecf20Sopenharmony_ci { .val = 1, .div = 6 }, 2498c2ecf20Sopenharmony_ci { /* sentinel */ }, 2508c2ecf20Sopenharmony_ci}; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic struct samsung_div_clock s3c244x_common_dividers[] __initdata = { 2538c2ecf20Sopenharmony_ci DIV(UCLK, "uclk", "upll", CLKDIVN, 3, 1), 2548c2ecf20Sopenharmony_ci DIV(0, "div_hclk", "fclk", CLKDIVN, 1, 1), 2558c2ecf20Sopenharmony_ci DIV_T(0, "div_hclk_4", "fclk", CAMDIVN, 9, 1, div_hclk_4_d), 2568c2ecf20Sopenharmony_ci DIV_T(0, "div_hclk_3", "fclk", CAMDIVN, 8, 1, div_hclk_3_d), 2578c2ecf20Sopenharmony_ci DIV(0, "div_cam", "upll", CAMDIVN, 0, 3), 2588c2ecf20Sopenharmony_ci}; 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_cistatic struct samsung_gate_clock s3c244x_common_gates[] __initdata = { 2618c2ecf20Sopenharmony_ci GATE(HCLK_CAM, "cam", "hclk", CLKCON, 19, 0, 0), 2628c2ecf20Sopenharmony_ci}; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_cistatic struct samsung_clock_alias s3c244x_common_aliases[] __initdata = { 2658c2ecf20Sopenharmony_ci ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"), 2668c2ecf20Sopenharmony_ci ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"), 2678c2ecf20Sopenharmony_ci ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"), 2688c2ecf20Sopenharmony_ci ALIAS(PCLK_UART0, "s3c2440-uart.0", "clk_uart_baud2"), 2698c2ecf20Sopenharmony_ci ALIAS(PCLK_UART1, "s3c2440-uart.1", "clk_uart_baud2"), 2708c2ecf20Sopenharmony_ci ALIAS(PCLK_UART2, "s3c2440-uart.2", "clk_uart_baud2"), 2718c2ecf20Sopenharmony_ci ALIAS(HCLK_CAM, NULL, "camif"), 2728c2ecf20Sopenharmony_ci ALIAS(CAMIF, NULL, "camif-upll"), 2738c2ecf20Sopenharmony_ci}; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci/* S3C2440 specific clocks */ 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ciPNAME(s3c2440_camif_p) = { "upll", "ff_cam" }; 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_cistatic struct samsung_mux_clock s3c2440_muxes[] __initdata = { 2808c2ecf20Sopenharmony_ci MUX(CAMIF, "camif", s3c2440_camif_p, CAMDIVN, 4, 1), 2818c2ecf20Sopenharmony_ci}; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cistatic struct samsung_gate_clock s3c2440_gates[] __initdata = { 2848c2ecf20Sopenharmony_ci GATE(PCLK_AC97, "ac97", "pclk", CLKCON, 20, 0, 0), 2858c2ecf20Sopenharmony_ci}; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci/* S3C2442 specific clocks */ 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_cistatic struct samsung_fixed_factor_clock s3c2442_ffactor[] __initdata = { 2908c2ecf20Sopenharmony_ci FFACTOR(0, "upll_3", "upll", 1, 3, 0), 2918c2ecf20Sopenharmony_ci}; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ciPNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" }; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_cistatic struct samsung_mux_clock s3c2442_muxes[] __initdata = { 2968c2ecf20Sopenharmony_ci MUX(CAMIF, "camif", s3c2442_camif_p, CAMDIVN, 4, 2), 2978c2ecf20Sopenharmony_ci}; 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci/* 3008c2ecf20Sopenharmony_ci * fixed rate clocks generated outside the soc 3018c2ecf20Sopenharmony_ci * Only necessary until the devicetree-move is complete 3028c2ecf20Sopenharmony_ci */ 3038c2ecf20Sopenharmony_ci#define XTI 1 3048c2ecf20Sopenharmony_cistatic struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = { 3058c2ecf20Sopenharmony_ci FRATE(XTI, "xti", NULL, 0, 0), 3068c2ecf20Sopenharmony_ci}; 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_cistatic void __init s3c2410_common_clk_register_fixed_ext( 3098c2ecf20Sopenharmony_ci struct samsung_clk_provider *ctx, 3108c2ecf20Sopenharmony_ci unsigned long xti_f) 3118c2ecf20Sopenharmony_ci{ 3128c2ecf20Sopenharmony_ci struct samsung_clock_alias xti_alias = ALIAS(XTI, NULL, "xtal"); 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci s3c2410_common_frate_clks[0].fixed_rate = xti_f; 3158c2ecf20Sopenharmony_ci samsung_clk_register_fixed_rate(ctx, s3c2410_common_frate_clks, 3168c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2410_common_frate_clks)); 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci samsung_clk_register_alias(ctx, &xti_alias, 1); 3198c2ecf20Sopenharmony_ci} 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_civoid __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, 3228c2ecf20Sopenharmony_ci int current_soc, 3238c2ecf20Sopenharmony_ci void __iomem *base) 3248c2ecf20Sopenharmony_ci{ 3258c2ecf20Sopenharmony_ci struct samsung_clk_provider *ctx; 3268c2ecf20Sopenharmony_ci reg_base = base; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci if (np) { 3298c2ecf20Sopenharmony_ci reg_base = of_iomap(np, 0); 3308c2ecf20Sopenharmony_ci if (!reg_base) 3318c2ecf20Sopenharmony_ci panic("%s: failed to map registers\n", __func__); 3328c2ecf20Sopenharmony_ci } 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci ctx = samsung_clk_init(np, reg_base, NR_CLKS); 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci /* Register external clocks only in non-dt cases */ 3378c2ecf20Sopenharmony_ci if (!np) 3388c2ecf20Sopenharmony_ci s3c2410_common_clk_register_fixed_ext(ctx, xti_f); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci if (current_soc == S3C2410) { 3418c2ecf20Sopenharmony_ci if (_get_rate("xti") == 12 * MHZ) { 3428c2ecf20Sopenharmony_ci s3c2410_plls[mpll].rate_table = pll_s3c2410_12mhz_tbl; 3438c2ecf20Sopenharmony_ci s3c2410_plls[upll].rate_table = pll_s3c2410_12mhz_tbl; 3448c2ecf20Sopenharmony_ci } 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci /* Register PLLs. */ 3478c2ecf20Sopenharmony_ci samsung_clk_register_pll(ctx, s3c2410_plls, 3488c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2410_plls), reg_base); 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci } else { /* S3C2440, S3C2442 */ 3518c2ecf20Sopenharmony_ci if (_get_rate("xti") == 12 * MHZ) { 3528c2ecf20Sopenharmony_ci /* 3538c2ecf20Sopenharmony_ci * plls follow different calculation schemes, with the 3548c2ecf20Sopenharmony_ci * upll following the same scheme as the s3c2410 plls 3558c2ecf20Sopenharmony_ci */ 3568c2ecf20Sopenharmony_ci s3c244x_common_plls[mpll].rate_table = 3578c2ecf20Sopenharmony_ci pll_s3c244x_12mhz_tbl; 3588c2ecf20Sopenharmony_ci s3c244x_common_plls[upll].rate_table = 3598c2ecf20Sopenharmony_ci pll_s3c2410_12mhz_tbl; 3608c2ecf20Sopenharmony_ci } 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci /* Register PLLs. */ 3638c2ecf20Sopenharmony_ci samsung_clk_register_pll(ctx, s3c244x_common_plls, 3648c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c244x_common_plls), reg_base); 3658c2ecf20Sopenharmony_ci } 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci /* Register common internal clocks. */ 3688c2ecf20Sopenharmony_ci samsung_clk_register_mux(ctx, s3c2410_common_muxes, 3698c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2410_common_muxes)); 3708c2ecf20Sopenharmony_ci samsung_clk_register_div(ctx, s3c2410_common_dividers, 3718c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2410_common_dividers)); 3728c2ecf20Sopenharmony_ci samsung_clk_register_gate(ctx, s3c2410_common_gates, 3738c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2410_common_gates)); 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci if (current_soc == S3C2440 || current_soc == S3C2442) { 3768c2ecf20Sopenharmony_ci samsung_clk_register_div(ctx, s3c244x_common_dividers, 3778c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c244x_common_dividers)); 3788c2ecf20Sopenharmony_ci samsung_clk_register_gate(ctx, s3c244x_common_gates, 3798c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c244x_common_gates)); 3808c2ecf20Sopenharmony_ci samsung_clk_register_mux(ctx, s3c244x_common_muxes, 3818c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c244x_common_muxes)); 3828c2ecf20Sopenharmony_ci samsung_clk_register_fixed_factor(ctx, s3c244x_common_ffactor, 3838c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c244x_common_ffactor)); 3848c2ecf20Sopenharmony_ci } 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci /* Register SoC-specific clocks. */ 3878c2ecf20Sopenharmony_ci switch (current_soc) { 3888c2ecf20Sopenharmony_ci case S3C2410: 3898c2ecf20Sopenharmony_ci samsung_clk_register_div(ctx, s3c2410_dividers, 3908c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2410_dividers)); 3918c2ecf20Sopenharmony_ci samsung_clk_register_fixed_factor(ctx, s3c2410_ffactor, 3928c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2410_ffactor)); 3938c2ecf20Sopenharmony_ci samsung_clk_register_alias(ctx, s3c2410_aliases, 3948c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2410_aliases)); 3958c2ecf20Sopenharmony_ci break; 3968c2ecf20Sopenharmony_ci case S3C2440: 3978c2ecf20Sopenharmony_ci samsung_clk_register_mux(ctx, s3c2440_muxes, 3988c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2440_muxes)); 3998c2ecf20Sopenharmony_ci samsung_clk_register_gate(ctx, s3c2440_gates, 4008c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2440_gates)); 4018c2ecf20Sopenharmony_ci break; 4028c2ecf20Sopenharmony_ci case S3C2442: 4038c2ecf20Sopenharmony_ci samsung_clk_register_mux(ctx, s3c2442_muxes, 4048c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2442_muxes)); 4058c2ecf20Sopenharmony_ci samsung_clk_register_fixed_factor(ctx, s3c2442_ffactor, 4068c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2442_ffactor)); 4078c2ecf20Sopenharmony_ci break; 4088c2ecf20Sopenharmony_ci } 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci /* 4118c2ecf20Sopenharmony_ci * Register common aliases at the end, as some of the aliased clocks 4128c2ecf20Sopenharmony_ci * are SoC specific. 4138c2ecf20Sopenharmony_ci */ 4148c2ecf20Sopenharmony_ci samsung_clk_register_alias(ctx, s3c2410_common_aliases, 4158c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2410_common_aliases)); 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci if (current_soc == S3C2440 || current_soc == S3C2442) { 4188c2ecf20Sopenharmony_ci samsung_clk_register_alias(ctx, s3c244x_common_aliases, 4198c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c244x_common_aliases)); 4208c2ecf20Sopenharmony_ci } 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci samsung_clk_sleep_init(reg_base, s3c2410_clk_regs, 4238c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2410_clk_regs)); 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci samsung_clk_of_add_provider(np, ctx); 4268c2ecf20Sopenharmony_ci} 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_cistatic void __init s3c2410_clk_init(struct device_node *np) 4298c2ecf20Sopenharmony_ci{ 4308c2ecf20Sopenharmony_ci s3c2410_common_clk_init(np, 0, S3C2410, NULL); 4318c2ecf20Sopenharmony_ci} 4328c2ecf20Sopenharmony_ciCLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init); 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_cistatic void __init s3c2440_clk_init(struct device_node *np) 4358c2ecf20Sopenharmony_ci{ 4368c2ecf20Sopenharmony_ci s3c2410_common_clk_init(np, 0, S3C2440, NULL); 4378c2ecf20Sopenharmony_ci} 4388c2ecf20Sopenharmony_ciCLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init); 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_cistatic void __init s3c2442_clk_init(struct device_node *np) 4418c2ecf20Sopenharmony_ci{ 4428c2ecf20Sopenharmony_ci s3c2410_common_clk_init(np, 0, S3C2442, NULL); 4438c2ecf20Sopenharmony_ci} 4448c2ecf20Sopenharmony_ciCLK_OF_DECLARE(s3c2442_clk, "samsung,s3c2442-clock", s3c2442_clk_init); 445