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 S3C2443 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/io.h> 118c2ecf20Sopenharmony_ci#include <linux/of.h> 128c2ecf20Sopenharmony_ci#include <linux/of_address.h> 138c2ecf20Sopenharmony_ci#include <linux/reboot.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <dt-bindings/clock/s3c2443.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include "clk.h" 188c2ecf20Sopenharmony_ci#include "clk-pll.h" 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci/* S3C2416 clock controller register offsets */ 218c2ecf20Sopenharmony_ci#define LOCKCON0 0x00 228c2ecf20Sopenharmony_ci#define LOCKCON1 0x04 238c2ecf20Sopenharmony_ci#define MPLLCON 0x10 248c2ecf20Sopenharmony_ci#define EPLLCON 0x18 258c2ecf20Sopenharmony_ci#define EPLLCON_K 0x1C 268c2ecf20Sopenharmony_ci#define CLKSRC 0x20 278c2ecf20Sopenharmony_ci#define CLKDIV0 0x24 288c2ecf20Sopenharmony_ci#define CLKDIV1 0x28 298c2ecf20Sopenharmony_ci#define CLKDIV2 0x2C 308c2ecf20Sopenharmony_ci#define HCLKCON 0x30 318c2ecf20Sopenharmony_ci#define PCLKCON 0x34 328c2ecf20Sopenharmony_ci#define SCLKCON 0x38 338c2ecf20Sopenharmony_ci#define SWRST 0x44 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci/* the soc types */ 368c2ecf20Sopenharmony_cienum supported_socs { 378c2ecf20Sopenharmony_ci S3C2416, 388c2ecf20Sopenharmony_ci S3C2443, 398c2ecf20Sopenharmony_ci S3C2450, 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic void __iomem *reg_base; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/* 458c2ecf20Sopenharmony_ci * list of controller registers to be saved and restored during a 468c2ecf20Sopenharmony_ci * suspend/resume cycle. 478c2ecf20Sopenharmony_ci */ 488c2ecf20Sopenharmony_cistatic unsigned long s3c2443_clk_regs[] __initdata = { 498c2ecf20Sopenharmony_ci LOCKCON0, 508c2ecf20Sopenharmony_ci LOCKCON1, 518c2ecf20Sopenharmony_ci MPLLCON, 528c2ecf20Sopenharmony_ci EPLLCON, 538c2ecf20Sopenharmony_ci EPLLCON_K, 548c2ecf20Sopenharmony_ci CLKSRC, 558c2ecf20Sopenharmony_ci CLKDIV0, 568c2ecf20Sopenharmony_ci CLKDIV1, 578c2ecf20Sopenharmony_ci CLKDIV2, 588c2ecf20Sopenharmony_ci PCLKCON, 598c2ecf20Sopenharmony_ci HCLKCON, 608c2ecf20Sopenharmony_ci SCLKCON, 618c2ecf20Sopenharmony_ci}; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ciPNAME(epllref_p) = { "mpllref", "mpllref", "xti", "ext" }; 648c2ecf20Sopenharmony_ciPNAME(esysclk_p) = { "epllref", "epll" }; 658c2ecf20Sopenharmony_ciPNAME(mpllref_p) = { "xti", "mdivclk" }; 668c2ecf20Sopenharmony_ciPNAME(msysclk_p) = { "mpllref", "mpll" }; 678c2ecf20Sopenharmony_ciPNAME(armclk_p) = { "armdiv" , "hclk" }; 688c2ecf20Sopenharmony_ciPNAME(i2s0_p) = { "div_i2s0", "ext_i2s", "epllref", "epllref" }; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic struct samsung_mux_clock s3c2443_common_muxes[] __initdata = { 718c2ecf20Sopenharmony_ci MUX(0, "epllref", epllref_p, CLKSRC, 7, 2), 728c2ecf20Sopenharmony_ci MUX(ESYSCLK, "esysclk", esysclk_p, CLKSRC, 6, 1), 738c2ecf20Sopenharmony_ci MUX(0, "mpllref", mpllref_p, CLKSRC, 3, 1), 748c2ecf20Sopenharmony_ci MUX(MSYSCLK, "msysclk", msysclk_p, CLKSRC, 4, 1), 758c2ecf20Sopenharmony_ci MUX(ARMCLK, "armclk", armclk_p, CLKDIV0, 13, 1), 768c2ecf20Sopenharmony_ci MUX(0, "mux_i2s0", i2s0_p, CLKSRC, 14, 2), 778c2ecf20Sopenharmony_ci}; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic struct clk_div_table hclk_d[] = { 808c2ecf20Sopenharmony_ci { .val = 0, .div = 1 }, 818c2ecf20Sopenharmony_ci { .val = 1, .div = 2 }, 828c2ecf20Sopenharmony_ci { .val = 3, .div = 4 }, 838c2ecf20Sopenharmony_ci { /* sentinel */ }, 848c2ecf20Sopenharmony_ci}; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic struct clk_div_table mdivclk_d[] = { 878c2ecf20Sopenharmony_ci { .val = 0, .div = 1 }, 888c2ecf20Sopenharmony_ci { .val = 1, .div = 3 }, 898c2ecf20Sopenharmony_ci { .val = 2, .div = 5 }, 908c2ecf20Sopenharmony_ci { .val = 3, .div = 7 }, 918c2ecf20Sopenharmony_ci { .val = 4, .div = 9 }, 928c2ecf20Sopenharmony_ci { .val = 5, .div = 11 }, 938c2ecf20Sopenharmony_ci { .val = 6, .div = 13 }, 948c2ecf20Sopenharmony_ci { .val = 7, .div = 15 }, 958c2ecf20Sopenharmony_ci { /* sentinel */ }, 968c2ecf20Sopenharmony_ci}; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic struct samsung_div_clock s3c2443_common_dividers[] __initdata = { 998c2ecf20Sopenharmony_ci DIV_T(0, "mdivclk", "xti", CLKDIV0, 6, 3, mdivclk_d), 1008c2ecf20Sopenharmony_ci DIV(0, "prediv", "msysclk", CLKDIV0, 4, 2), 1018c2ecf20Sopenharmony_ci DIV_T(HCLK, "hclk", "prediv", CLKDIV0, 0, 2, hclk_d), 1028c2ecf20Sopenharmony_ci DIV(PCLK, "pclk", "hclk", CLKDIV0, 2, 1), 1038c2ecf20Sopenharmony_ci DIV(0, "div_hsspi0_epll", "esysclk", CLKDIV1, 24, 2), 1048c2ecf20Sopenharmony_ci DIV(0, "div_fimd", "esysclk", CLKDIV1, 16, 8), 1058c2ecf20Sopenharmony_ci DIV(0, "div_i2s0", "esysclk", CLKDIV1, 12, 4), 1068c2ecf20Sopenharmony_ci DIV(0, "div_uart", "esysclk", CLKDIV1, 8, 4), 1078c2ecf20Sopenharmony_ci DIV(0, "div_hsmmc1", "esysclk", CLKDIV1, 6, 2), 1088c2ecf20Sopenharmony_ci DIV(0, "div_usbhost", "esysclk", CLKDIV1, 4, 2), 1098c2ecf20Sopenharmony_ci}; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_cistatic struct samsung_gate_clock s3c2443_common_gates[] __initdata = { 1128c2ecf20Sopenharmony_ci GATE(SCLK_HSMMC_EXT, "sclk_hsmmcext", "ext", SCLKCON, 13, 0, 0), 1138c2ecf20Sopenharmony_ci GATE(SCLK_HSMMC1, "sclk_hsmmc1", "div_hsmmc1", SCLKCON, 12, 0, 0), 1148c2ecf20Sopenharmony_ci GATE(SCLK_FIMD, "sclk_fimd", "div_fimd", SCLKCON, 10, 0, 0), 1158c2ecf20Sopenharmony_ci GATE(SCLK_I2S0, "sclk_i2s0", "mux_i2s0", SCLKCON, 9, 0, 0), 1168c2ecf20Sopenharmony_ci GATE(SCLK_UART, "sclk_uart", "div_uart", SCLKCON, 8, 0, 0), 1178c2ecf20Sopenharmony_ci GATE(SCLK_USBH, "sclk_usbhost", "div_usbhost", SCLKCON, 1, 0, 0), 1188c2ecf20Sopenharmony_ci GATE(HCLK_DRAM, "dram", "hclk", HCLKCON, 19, CLK_IGNORE_UNUSED, 0), 1198c2ecf20Sopenharmony_ci GATE(HCLK_SSMC, "ssmc", "hclk", HCLKCON, 18, CLK_IGNORE_UNUSED, 0), 1208c2ecf20Sopenharmony_ci GATE(HCLK_HSMMC1, "hsmmc1", "hclk", HCLKCON, 16, 0, 0), 1218c2ecf20Sopenharmony_ci GATE(HCLK_USBD, "usb-device", "hclk", HCLKCON, 12, 0, 0), 1228c2ecf20Sopenharmony_ci GATE(HCLK_USBH, "usb-host", "hclk", HCLKCON, 11, 0, 0), 1238c2ecf20Sopenharmony_ci GATE(HCLK_LCD, "lcd", "hclk", HCLKCON, 9, 0, 0), 1248c2ecf20Sopenharmony_ci GATE(HCLK_DMA5, "dma5", "hclk", HCLKCON, 5, CLK_IGNORE_UNUSED, 0), 1258c2ecf20Sopenharmony_ci GATE(HCLK_DMA4, "dma4", "hclk", HCLKCON, 4, CLK_IGNORE_UNUSED, 0), 1268c2ecf20Sopenharmony_ci GATE(HCLK_DMA3, "dma3", "hclk", HCLKCON, 3, CLK_IGNORE_UNUSED, 0), 1278c2ecf20Sopenharmony_ci GATE(HCLK_DMA2, "dma2", "hclk", HCLKCON, 2, CLK_IGNORE_UNUSED, 0), 1288c2ecf20Sopenharmony_ci GATE(HCLK_DMA1, "dma1", "hclk", HCLKCON, 1, CLK_IGNORE_UNUSED, 0), 1298c2ecf20Sopenharmony_ci GATE(HCLK_DMA0, "dma0", "hclk", HCLKCON, 0, CLK_IGNORE_UNUSED, 0), 1308c2ecf20Sopenharmony_ci GATE(PCLK_GPIO, "gpio", "pclk", PCLKCON, 13, CLK_IGNORE_UNUSED, 0), 1318c2ecf20Sopenharmony_ci GATE(PCLK_RTC, "rtc", "pclk", PCLKCON, 12, 0, 0), 1328c2ecf20Sopenharmony_ci GATE(PCLK_WDT, "wdt", "pclk", PCLKCON, 11, 0, 0), 1338c2ecf20Sopenharmony_ci GATE(PCLK_PWM, "pwm", "pclk", PCLKCON, 10, 0, 0), 1348c2ecf20Sopenharmony_ci GATE(PCLK_I2S0, "i2s0", "pclk", PCLKCON, 9, 0, 0), 1358c2ecf20Sopenharmony_ci GATE(PCLK_AC97, "ac97", "pclk", PCLKCON, 8, 0, 0), 1368c2ecf20Sopenharmony_ci GATE(PCLK_ADC, "adc", "pclk", PCLKCON, 7, 0, 0), 1378c2ecf20Sopenharmony_ci GATE(PCLK_SPI0, "spi0", "pclk", PCLKCON, 6, 0, 0), 1388c2ecf20Sopenharmony_ci GATE(PCLK_I2C0, "i2c0", "pclk", PCLKCON, 4, 0, 0), 1398c2ecf20Sopenharmony_ci GATE(PCLK_UART3, "uart3", "pclk", PCLKCON, 3, 0, 0), 1408c2ecf20Sopenharmony_ci GATE(PCLK_UART2, "uart2", "pclk", PCLKCON, 2, 0, 0), 1418c2ecf20Sopenharmony_ci GATE(PCLK_UART1, "uart1", "pclk", PCLKCON, 1, 0, 0), 1428c2ecf20Sopenharmony_ci GATE(PCLK_UART0, "uart0", "pclk", PCLKCON, 0, 0, 0), 1438c2ecf20Sopenharmony_ci}; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_cistatic struct samsung_clock_alias s3c2443_common_aliases[] __initdata = { 1468c2ecf20Sopenharmony_ci ALIAS(MSYSCLK, NULL, "msysclk"), 1478c2ecf20Sopenharmony_ci ALIAS(ARMCLK, NULL, "armclk"), 1488c2ecf20Sopenharmony_ci ALIAS(MPLL, NULL, "mpll"), 1498c2ecf20Sopenharmony_ci ALIAS(EPLL, NULL, "epll"), 1508c2ecf20Sopenharmony_ci ALIAS(HCLK, NULL, "hclk"), 1518c2ecf20Sopenharmony_ci ALIAS(HCLK_SSMC, NULL, "nand"), 1528c2ecf20Sopenharmony_ci ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"), 1538c2ecf20Sopenharmony_ci ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"), 1548c2ecf20Sopenharmony_ci ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"), 1558c2ecf20Sopenharmony_ci ALIAS(PCLK_UART3, "s3c2440-uart.3", "uart"), 1568c2ecf20Sopenharmony_ci ALIAS(PCLK_UART0, "s3c2440-uart.0", "clk_uart_baud2"), 1578c2ecf20Sopenharmony_ci ALIAS(PCLK_UART1, "s3c2440-uart.1", "clk_uart_baud2"), 1588c2ecf20Sopenharmony_ci ALIAS(PCLK_UART2, "s3c2440-uart.2", "clk_uart_baud2"), 1598c2ecf20Sopenharmony_ci ALIAS(PCLK_UART3, "s3c2440-uart.3", "clk_uart_baud2"), 1608c2ecf20Sopenharmony_ci ALIAS(SCLK_UART, NULL, "clk_uart_baud3"), 1618c2ecf20Sopenharmony_ci ALIAS(PCLK_PWM, NULL, "timers"), 1628c2ecf20Sopenharmony_ci ALIAS(PCLK_RTC, NULL, "rtc"), 1638c2ecf20Sopenharmony_ci ALIAS(PCLK_WDT, NULL, "watchdog"), 1648c2ecf20Sopenharmony_ci ALIAS(PCLK_ADC, NULL, "adc"), 1658c2ecf20Sopenharmony_ci ALIAS(PCLK_I2C0, "s3c2410-i2c.0", "i2c"), 1668c2ecf20Sopenharmony_ci ALIAS(HCLK_USBD, NULL, "usb-device"), 1678c2ecf20Sopenharmony_ci ALIAS(HCLK_USBH, NULL, "usb-host"), 1688c2ecf20Sopenharmony_ci ALIAS(SCLK_USBH, NULL, "usb-bus-host"), 1698c2ecf20Sopenharmony_ci ALIAS(PCLK_SPI0, "s3c2443-spi.0", "spi"), 1708c2ecf20Sopenharmony_ci ALIAS(PCLK_SPI0, "s3c2443-spi.0", "spi_busclk0"), 1718c2ecf20Sopenharmony_ci ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "hsmmc"), 1728c2ecf20Sopenharmony_ci ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"), 1738c2ecf20Sopenharmony_ci ALIAS(PCLK_I2S0, "samsung-i2s.0", "iis"), 1748c2ecf20Sopenharmony_ci ALIAS(SCLK_I2S0, NULL, "i2s-if"), 1758c2ecf20Sopenharmony_ci ALIAS(HCLK_LCD, NULL, "lcd"), 1768c2ecf20Sopenharmony_ci ALIAS(SCLK_FIMD, NULL, "sclk_fimd"), 1778c2ecf20Sopenharmony_ci}; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci/* S3C2416 specific clocks */ 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_cistatic struct samsung_pll_clock s3c2416_pll_clks[] __initdata = { 1828c2ecf20Sopenharmony_ci PLL(pll_6552_s3c2416, MPLL, "mpll", "mpllref", LOCKCON0, MPLLCON, NULL), 1838c2ecf20Sopenharmony_ci PLL(pll_6553, EPLL, "epll", "epllref", LOCKCON1, EPLLCON, NULL), 1848c2ecf20Sopenharmony_ci}; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ciPNAME(s3c2416_hsmmc0_p) = { "sclk_hsmmc0", "sclk_hsmmcext" }; 1878c2ecf20Sopenharmony_ciPNAME(s3c2416_hsmmc1_p) = { "sclk_hsmmc1", "sclk_hsmmcext" }; 1888c2ecf20Sopenharmony_ciPNAME(s3c2416_hsspi0_p) = { "hsspi0_epll", "hsspi0_mpll" }; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_cistatic struct clk_div_table armdiv_s3c2416_d[] = { 1918c2ecf20Sopenharmony_ci { .val = 0, .div = 1 }, 1928c2ecf20Sopenharmony_ci { .val = 1, .div = 2 }, 1938c2ecf20Sopenharmony_ci { .val = 2, .div = 3 }, 1948c2ecf20Sopenharmony_ci { .val = 3, .div = 4 }, 1958c2ecf20Sopenharmony_ci { .val = 5, .div = 6 }, 1968c2ecf20Sopenharmony_ci { .val = 7, .div = 8 }, 1978c2ecf20Sopenharmony_ci { /* sentinel */ }, 1988c2ecf20Sopenharmony_ci}; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_cistatic struct samsung_div_clock s3c2416_dividers[] __initdata = { 2018c2ecf20Sopenharmony_ci DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 3, armdiv_s3c2416_d), 2028c2ecf20Sopenharmony_ci DIV(0, "div_hsspi0_mpll", "msysclk", CLKDIV2, 0, 4), 2038c2ecf20Sopenharmony_ci DIV(0, "div_hsmmc0", "esysclk", CLKDIV2, 6, 2), 2048c2ecf20Sopenharmony_ci}; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_cistatic struct samsung_mux_clock s3c2416_muxes[] __initdata = { 2078c2ecf20Sopenharmony_ci MUX(MUX_HSMMC0, "mux_hsmmc0", s3c2416_hsmmc0_p, CLKSRC, 16, 1), 2088c2ecf20Sopenharmony_ci MUX(MUX_HSMMC1, "mux_hsmmc1", s3c2416_hsmmc1_p, CLKSRC, 17, 1), 2098c2ecf20Sopenharmony_ci MUX(MUX_HSSPI0, "mux_hsspi0", s3c2416_hsspi0_p, CLKSRC, 18, 1), 2108c2ecf20Sopenharmony_ci}; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_cistatic struct samsung_gate_clock s3c2416_gates[] __initdata = { 2138c2ecf20Sopenharmony_ci GATE(0, "hsspi0_mpll", "div_hsspi0_mpll", SCLKCON, 19, 0, 0), 2148c2ecf20Sopenharmony_ci GATE(0, "hsspi0_epll", "div_hsspi0_epll", SCLKCON, 14, 0, 0), 2158c2ecf20Sopenharmony_ci GATE(0, "sclk_hsmmc0", "div_hsmmc0", SCLKCON, 6, 0, 0), 2168c2ecf20Sopenharmony_ci GATE(HCLK_2D, "2d", "hclk", HCLKCON, 20, 0, 0), 2178c2ecf20Sopenharmony_ci GATE(HCLK_HSMMC0, "hsmmc0", "hclk", HCLKCON, 15, 0, 0), 2188c2ecf20Sopenharmony_ci GATE(HCLK_IROM, "irom", "hclk", HCLKCON, 13, CLK_IGNORE_UNUSED, 0), 2198c2ecf20Sopenharmony_ci GATE(PCLK_PCM, "pcm", "pclk", PCLKCON, 19, 0, 0), 2208c2ecf20Sopenharmony_ci}; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_cistatic struct samsung_clock_alias s3c2416_aliases[] __initdata = { 2238c2ecf20Sopenharmony_ci ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"), 2248c2ecf20Sopenharmony_ci ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"), 2258c2ecf20Sopenharmony_ci ALIAS(MUX_HSMMC0, "s3c-sdhci.0", "mmc_busclk.2"), 2268c2ecf20Sopenharmony_ci ALIAS(MUX_HSMMC1, "s3c-sdhci.1", "mmc_busclk.2"), 2278c2ecf20Sopenharmony_ci ALIAS(MUX_HSSPI0, "s3c2443-spi.0", "spi_busclk2"), 2288c2ecf20Sopenharmony_ci ALIAS(ARMDIV, NULL, "armdiv"), 2298c2ecf20Sopenharmony_ci}; 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci/* S3C2443 specific clocks */ 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_cistatic struct samsung_pll_clock s3c2443_pll_clks[] __initdata = { 2348c2ecf20Sopenharmony_ci PLL(pll_3000, MPLL, "mpll", "mpllref", LOCKCON0, MPLLCON, NULL), 2358c2ecf20Sopenharmony_ci PLL(pll_2126, EPLL, "epll", "epllref", LOCKCON1, EPLLCON, NULL), 2368c2ecf20Sopenharmony_ci}; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_cistatic struct clk_div_table armdiv_s3c2443_d[] = { 2398c2ecf20Sopenharmony_ci { .val = 0, .div = 1 }, 2408c2ecf20Sopenharmony_ci { .val = 8, .div = 2 }, 2418c2ecf20Sopenharmony_ci { .val = 2, .div = 3 }, 2428c2ecf20Sopenharmony_ci { .val = 9, .div = 4 }, 2438c2ecf20Sopenharmony_ci { .val = 10, .div = 6 }, 2448c2ecf20Sopenharmony_ci { .val = 11, .div = 8 }, 2458c2ecf20Sopenharmony_ci { .val = 13, .div = 12 }, 2468c2ecf20Sopenharmony_ci { .val = 15, .div = 16 }, 2478c2ecf20Sopenharmony_ci { /* sentinel */ }, 2488c2ecf20Sopenharmony_ci}; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_cistatic struct samsung_div_clock s3c2443_dividers[] __initdata = { 2518c2ecf20Sopenharmony_ci DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 4, armdiv_s3c2443_d), 2528c2ecf20Sopenharmony_ci DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4), 2538c2ecf20Sopenharmony_ci}; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_cistatic struct samsung_gate_clock s3c2443_gates[] __initdata = { 2568c2ecf20Sopenharmony_ci GATE(SCLK_HSSPI0, "sclk_hsspi0", "div_hsspi0_epll", SCLKCON, 14, 0, 0), 2578c2ecf20Sopenharmony_ci GATE(SCLK_CAM, "sclk_cam", "div_cam", SCLKCON, 11, 0, 0), 2588c2ecf20Sopenharmony_ci GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, CLK_IGNORE_UNUSED, 0), 2598c2ecf20Sopenharmony_ci GATE(HCLK_CAM, "cam", "hclk", HCLKCON, 8, 0, 0), 2608c2ecf20Sopenharmony_ci GATE(PCLK_SPI1, "spi1", "pclk", PCLKCON, 15, 0, 0), 2618c2ecf20Sopenharmony_ci GATE(PCLK_SDI, "sdi", "pclk", PCLKCON, 5, 0, 0), 2628c2ecf20Sopenharmony_ci}; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_cistatic struct samsung_clock_alias s3c2443_aliases[] __initdata = { 2658c2ecf20Sopenharmony_ci ALIAS(SCLK_HSSPI0, "s3c2443-spi.0", "spi_busclk2"), 2668c2ecf20Sopenharmony_ci ALIAS(SCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.2"), 2678c2ecf20Sopenharmony_ci ALIAS(SCLK_CAM, NULL, "camif-upll"), 2688c2ecf20Sopenharmony_ci ALIAS(PCLK_SPI1, "s3c2410-spi.0", "spi"), 2698c2ecf20Sopenharmony_ci ALIAS(PCLK_SDI, NULL, "sdi"), 2708c2ecf20Sopenharmony_ci ALIAS(HCLK_CFC, NULL, "cfc"), 2718c2ecf20Sopenharmony_ci ALIAS(ARMDIV, NULL, "armdiv"), 2728c2ecf20Sopenharmony_ci}; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci/* S3C2450 specific clocks */ 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ciPNAME(s3c2450_cam_p) = { "div_cam", "hclk" }; 2778c2ecf20Sopenharmony_ciPNAME(s3c2450_hsspi1_p) = { "hsspi1_epll", "hsspi1_mpll" }; 2788c2ecf20Sopenharmony_ciPNAME(i2s1_p) = { "div_i2s1", "ext_i2s", "epllref", "epllref" }; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_cistatic struct samsung_div_clock s3c2450_dividers[] __initdata = { 2818c2ecf20Sopenharmony_ci DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4), 2828c2ecf20Sopenharmony_ci DIV(0, "div_hsspi1_epll", "esysclk", CLKDIV2, 24, 2), 2838c2ecf20Sopenharmony_ci DIV(0, "div_hsspi1_mpll", "msysclk", CLKDIV2, 16, 4), 2848c2ecf20Sopenharmony_ci DIV(0, "div_i2s1", "esysclk", CLKDIV2, 12, 4), 2858c2ecf20Sopenharmony_ci}; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_cistatic struct samsung_mux_clock s3c2450_muxes[] __initdata = { 2888c2ecf20Sopenharmony_ci MUX(0, "mux_cam", s3c2450_cam_p, CLKSRC, 20, 1), 2898c2ecf20Sopenharmony_ci MUX(MUX_HSSPI1, "mux_hsspi1", s3c2450_hsspi1_p, CLKSRC, 19, 1), 2908c2ecf20Sopenharmony_ci MUX(0, "mux_i2s1", i2s1_p, CLKSRC, 12, 2), 2918c2ecf20Sopenharmony_ci}; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_cistatic struct samsung_gate_clock s3c2450_gates[] __initdata = { 2948c2ecf20Sopenharmony_ci GATE(SCLK_I2S1, "sclk_i2s1", "div_i2s1", SCLKCON, 5, 0, 0), 2958c2ecf20Sopenharmony_ci GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, 0, 0), 2968c2ecf20Sopenharmony_ci GATE(HCLK_CAM, "cam", "hclk", HCLKCON, 8, 0, 0), 2978c2ecf20Sopenharmony_ci GATE(HCLK_DMA7, "dma7", "hclk", HCLKCON, 7, CLK_IGNORE_UNUSED, 0), 2988c2ecf20Sopenharmony_ci GATE(HCLK_DMA6, "dma6", "hclk", HCLKCON, 6, CLK_IGNORE_UNUSED, 0), 2998c2ecf20Sopenharmony_ci GATE(PCLK_I2S1, "i2s1", "pclk", PCLKCON, 17, 0, 0), 3008c2ecf20Sopenharmony_ci GATE(PCLK_I2C1, "i2c1", "pclk", PCLKCON, 16, 0, 0), 3018c2ecf20Sopenharmony_ci GATE(PCLK_SPI1, "spi1", "pclk", PCLKCON, 14, 0, 0), 3028c2ecf20Sopenharmony_ci}; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_cistatic struct samsung_clock_alias s3c2450_aliases[] __initdata = { 3058c2ecf20Sopenharmony_ci ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi"), 3068c2ecf20Sopenharmony_ci ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi_busclk0"), 3078c2ecf20Sopenharmony_ci ALIAS(MUX_HSSPI1, "s3c2443-spi.1", "spi_busclk2"), 3088c2ecf20Sopenharmony_ci ALIAS(PCLK_I2C1, "s3c2410-i2c.1", "i2c"), 3098c2ecf20Sopenharmony_ci}; 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_cistatic int s3c2443_restart(struct notifier_block *this, 3128c2ecf20Sopenharmony_ci unsigned long mode, void *cmd) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci __raw_writel(0x533c2443, reg_base + SWRST); 3158c2ecf20Sopenharmony_ci return NOTIFY_DONE; 3168c2ecf20Sopenharmony_ci} 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_cistatic struct notifier_block s3c2443_restart_handler = { 3198c2ecf20Sopenharmony_ci .notifier_call = s3c2443_restart, 3208c2ecf20Sopenharmony_ci .priority = 129, 3218c2ecf20Sopenharmony_ci}; 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci/* 3248c2ecf20Sopenharmony_ci * fixed rate clocks generated outside the soc 3258c2ecf20Sopenharmony_ci * Only necessary until the devicetree-move is complete 3268c2ecf20Sopenharmony_ci */ 3278c2ecf20Sopenharmony_cistatic struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = { 3288c2ecf20Sopenharmony_ci FRATE(0, "xti", NULL, 0, 0), 3298c2ecf20Sopenharmony_ci FRATE(0, "ext", NULL, 0, 0), 3308c2ecf20Sopenharmony_ci FRATE(0, "ext_i2s", NULL, 0, 0), 3318c2ecf20Sopenharmony_ci FRATE(0, "ext_uart", NULL, 0, 0), 3328c2ecf20Sopenharmony_ci}; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_cistatic void __init s3c2443_common_clk_register_fixed_ext( 3358c2ecf20Sopenharmony_ci struct samsung_clk_provider *ctx, unsigned long xti_f) 3368c2ecf20Sopenharmony_ci{ 3378c2ecf20Sopenharmony_ci s3c2443_common_frate_clks[0].fixed_rate = xti_f; 3388c2ecf20Sopenharmony_ci samsung_clk_register_fixed_rate(ctx, s3c2443_common_frate_clks, 3398c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2443_common_frate_clks)); 3408c2ecf20Sopenharmony_ci} 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_civoid __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f, 3438c2ecf20Sopenharmony_ci int current_soc, 3448c2ecf20Sopenharmony_ci void __iomem *base) 3458c2ecf20Sopenharmony_ci{ 3468c2ecf20Sopenharmony_ci struct samsung_clk_provider *ctx; 3478c2ecf20Sopenharmony_ci int ret; 3488c2ecf20Sopenharmony_ci reg_base = base; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci if (np) { 3518c2ecf20Sopenharmony_ci reg_base = of_iomap(np, 0); 3528c2ecf20Sopenharmony_ci if (!reg_base) 3538c2ecf20Sopenharmony_ci panic("%s: failed to map registers\n", __func__); 3548c2ecf20Sopenharmony_ci } 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci ctx = samsung_clk_init(np, reg_base, NR_CLKS); 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci /* Register external clocks only in non-dt cases */ 3598c2ecf20Sopenharmony_ci if (!np) 3608c2ecf20Sopenharmony_ci s3c2443_common_clk_register_fixed_ext(ctx, xti_f); 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci /* Register PLLs. */ 3638c2ecf20Sopenharmony_ci if (current_soc == S3C2416 || current_soc == S3C2450) 3648c2ecf20Sopenharmony_ci samsung_clk_register_pll(ctx, s3c2416_pll_clks, 3658c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2416_pll_clks), reg_base); 3668c2ecf20Sopenharmony_ci else 3678c2ecf20Sopenharmony_ci samsung_clk_register_pll(ctx, s3c2443_pll_clks, 3688c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2443_pll_clks), reg_base); 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci /* Register common internal clocks. */ 3718c2ecf20Sopenharmony_ci samsung_clk_register_mux(ctx, s3c2443_common_muxes, 3728c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2443_common_muxes)); 3738c2ecf20Sopenharmony_ci samsung_clk_register_div(ctx, s3c2443_common_dividers, 3748c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2443_common_dividers)); 3758c2ecf20Sopenharmony_ci samsung_clk_register_gate(ctx, s3c2443_common_gates, 3768c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2443_common_gates)); 3778c2ecf20Sopenharmony_ci samsung_clk_register_alias(ctx, s3c2443_common_aliases, 3788c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2443_common_aliases)); 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci /* Register SoC-specific clocks. */ 3818c2ecf20Sopenharmony_ci switch (current_soc) { 3828c2ecf20Sopenharmony_ci case S3C2450: 3838c2ecf20Sopenharmony_ci samsung_clk_register_div(ctx, s3c2450_dividers, 3848c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2450_dividers)); 3858c2ecf20Sopenharmony_ci samsung_clk_register_mux(ctx, s3c2450_muxes, 3868c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2450_muxes)); 3878c2ecf20Sopenharmony_ci samsung_clk_register_gate(ctx, s3c2450_gates, 3888c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2450_gates)); 3898c2ecf20Sopenharmony_ci samsung_clk_register_alias(ctx, s3c2450_aliases, 3908c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2450_aliases)); 3918c2ecf20Sopenharmony_ci fallthrough; /* as s3c2450 extends the s3c2416 clocks */ 3928c2ecf20Sopenharmony_ci case S3C2416: 3938c2ecf20Sopenharmony_ci samsung_clk_register_div(ctx, s3c2416_dividers, 3948c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2416_dividers)); 3958c2ecf20Sopenharmony_ci samsung_clk_register_mux(ctx, s3c2416_muxes, 3968c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2416_muxes)); 3978c2ecf20Sopenharmony_ci samsung_clk_register_gate(ctx, s3c2416_gates, 3988c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2416_gates)); 3998c2ecf20Sopenharmony_ci samsung_clk_register_alias(ctx, s3c2416_aliases, 4008c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2416_aliases)); 4018c2ecf20Sopenharmony_ci break; 4028c2ecf20Sopenharmony_ci case S3C2443: 4038c2ecf20Sopenharmony_ci samsung_clk_register_div(ctx, s3c2443_dividers, 4048c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2443_dividers)); 4058c2ecf20Sopenharmony_ci samsung_clk_register_gate(ctx, s3c2443_gates, 4068c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2443_gates)); 4078c2ecf20Sopenharmony_ci samsung_clk_register_alias(ctx, s3c2443_aliases, 4088c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2443_aliases)); 4098c2ecf20Sopenharmony_ci break; 4108c2ecf20Sopenharmony_ci } 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci samsung_clk_sleep_init(reg_base, s3c2443_clk_regs, 4138c2ecf20Sopenharmony_ci ARRAY_SIZE(s3c2443_clk_regs)); 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci samsung_clk_of_add_provider(np, ctx); 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci ret = register_restart_handler(&s3c2443_restart_handler); 4188c2ecf20Sopenharmony_ci if (ret) 4198c2ecf20Sopenharmony_ci pr_warn("cannot register restart handler, %d\n", ret); 4208c2ecf20Sopenharmony_ci} 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_cistatic void __init s3c2416_clk_init(struct device_node *np) 4238c2ecf20Sopenharmony_ci{ 4248c2ecf20Sopenharmony_ci s3c2443_common_clk_init(np, 0, S3C2416, NULL); 4258c2ecf20Sopenharmony_ci} 4268c2ecf20Sopenharmony_ciCLK_OF_DECLARE(s3c2416_clk, "samsung,s3c2416-clock", s3c2416_clk_init); 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_cistatic void __init s3c2443_clk_init(struct device_node *np) 4298c2ecf20Sopenharmony_ci{ 4308c2ecf20Sopenharmony_ci s3c2443_common_clk_init(np, 0, S3C2443, NULL); 4318c2ecf20Sopenharmony_ci} 4328c2ecf20Sopenharmony_ciCLK_OF_DECLARE(s3c2443_clk, "samsung,s3c2443-clock", s3c2443_clk_init); 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_cistatic void __init s3c2450_clk_init(struct device_node *np) 4358c2ecf20Sopenharmony_ci{ 4368c2ecf20Sopenharmony_ci s3c2443_common_clk_init(np, 0, S3C2450, NULL); 4378c2ecf20Sopenharmony_ci} 4388c2ecf20Sopenharmony_ciCLK_OF_DECLARE(s3c2450_clk, "samsung,s3c2450-clock", s3c2450_clk_init); 439