brintos

brintos / linux-shallow public Read only

0
0
Text · 24.2 KiB · 17325f1 Raw
549 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * StarFive JH7110 System Clock Driver4 *5 * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>6 * Copyright (C) 2022 StarFive Technology Co., Ltd.7 */8 9#include <linux/auxiliary_bus.h>10#include <linux/clk.h>11#include <linux/clk-provider.h>12#include <linux/init.h>13#include <linux/io.h>14#include <linux/platform_device.h>15#include <linux/slab.h>16 17#include <soc/starfive/reset-starfive-jh71x0.h>18 19#include <dt-bindings/clock/starfive,jh7110-crg.h>20 21#include "clk-starfive-jh7110.h"22 23/* external clocks */24#define JH7110_SYSCLK_OSC			(JH7110_SYSCLK_END + 0)25#define JH7110_SYSCLK_GMAC1_RMII_REFIN		(JH7110_SYSCLK_END + 1)26#define JH7110_SYSCLK_GMAC1_RGMII_RXIN		(JH7110_SYSCLK_END + 2)27#define JH7110_SYSCLK_I2STX_BCLK_EXT		(JH7110_SYSCLK_END + 3)28#define JH7110_SYSCLK_I2STX_LRCK_EXT		(JH7110_SYSCLK_END + 4)29#define JH7110_SYSCLK_I2SRX_BCLK_EXT		(JH7110_SYSCLK_END + 5)30#define JH7110_SYSCLK_I2SRX_LRCK_EXT		(JH7110_SYSCLK_END + 6)31#define JH7110_SYSCLK_TDM_EXT			(JH7110_SYSCLK_END + 7)32#define JH7110_SYSCLK_MCLK_EXT			(JH7110_SYSCLK_END + 8)33#define JH7110_SYSCLK_PLL0_OUT			(JH7110_SYSCLK_END + 9)34#define JH7110_SYSCLK_PLL1_OUT			(JH7110_SYSCLK_END + 10)35#define JH7110_SYSCLK_PLL2_OUT			(JH7110_SYSCLK_END + 11)36 37static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {38	/* root */39	JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 0, 2,40		    JH7110_SYSCLK_OSC,41		    JH7110_SYSCLK_PLL0_OUT),42	JH71X0__DIV(JH7110_SYSCLK_CPU_CORE, "cpu_core", 7, JH7110_SYSCLK_CPU_ROOT),43	JH71X0__DIV(JH7110_SYSCLK_CPU_BUS, "cpu_bus", 2, JH7110_SYSCLK_CPU_CORE),44	JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 0, 2,45		    JH7110_SYSCLK_PLL2_OUT,46		    JH7110_SYSCLK_PLL1_OUT),47	JH71X0_MDIV(JH7110_SYSCLK_PERH_ROOT, "perh_root", 2, 2,48		    JH7110_SYSCLK_PLL0_OUT,49		    JH7110_SYSCLK_PLL2_OUT),50	JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 0, 2,51		    JH7110_SYSCLK_OSC,52		    JH7110_SYSCLK_PLL2_OUT),53	JH71X0__DIV(JH7110_SYSCLK_NOCSTG_BUS, "nocstg_bus", 3, JH7110_SYSCLK_BUS_ROOT),54	JH71X0__DIV(JH7110_SYSCLK_AXI_CFG0, "axi_cfg0", 3, JH7110_SYSCLK_BUS_ROOT),55	JH71X0__DIV(JH7110_SYSCLK_STG_AXIAHB, "stg_axiahb", 2, JH7110_SYSCLK_AXI_CFG0),56	JH71X0_GATE(JH7110_SYSCLK_AHB0, "ahb0", CLK_IS_CRITICAL, JH7110_SYSCLK_STG_AXIAHB),57	JH71X0_GATE(JH7110_SYSCLK_AHB1, "ahb1", CLK_IS_CRITICAL, JH7110_SYSCLK_STG_AXIAHB),58	JH71X0__DIV(JH7110_SYSCLK_APB_BUS, "apb_bus", 8, JH7110_SYSCLK_STG_AXIAHB),59	JH71X0_GATE(JH7110_SYSCLK_APB0, "apb0", CLK_IS_CRITICAL, JH7110_SYSCLK_APB_BUS),60	JH71X0__DIV(JH7110_SYSCLK_PLL0_DIV2, "pll0_div2", 2, JH7110_SYSCLK_PLL0_OUT),61	JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV2, "pll1_div2", 2, JH7110_SYSCLK_PLL1_OUT),62	JH71X0__DIV(JH7110_SYSCLK_PLL2_DIV2, "pll2_div2", 2, JH7110_SYSCLK_PLL2_OUT),63	JH71X0__DIV(JH7110_SYSCLK_AUDIO_ROOT, "audio_root", 8, JH7110_SYSCLK_PLL2_OUT),64	JH71X0__DIV(JH7110_SYSCLK_MCLK_INNER, "mclk_inner", 64, JH7110_SYSCLK_AUDIO_ROOT),65	JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 0, 2,66		    JH7110_SYSCLK_MCLK_INNER,67		    JH7110_SYSCLK_MCLK_EXT),68	JH71X0_GATE(JH7110_SYSCLK_MCLK_OUT, "mclk_out", 0, JH7110_SYSCLK_MCLK_INNER),69	JH71X0_MDIV(JH7110_SYSCLK_ISP_2X, "isp_2x", 8, 2,70		    JH7110_SYSCLK_PLL2_OUT,71		    JH7110_SYSCLK_PLL1_OUT),72	JH71X0__DIV(JH7110_SYSCLK_ISP_AXI, "isp_axi", 4, JH7110_SYSCLK_ISP_2X),73	JH71X0_GDIV(JH7110_SYSCLK_GCLK0, "gclk0", 0, 62, JH7110_SYSCLK_PLL0_DIV2),74	JH71X0_GDIV(JH7110_SYSCLK_GCLK1, "gclk1", 0, 62, JH7110_SYSCLK_PLL1_DIV2),75	JH71X0_GDIV(JH7110_SYSCLK_GCLK2, "gclk2", 0, 62, JH7110_SYSCLK_PLL2_DIV2),76	/* cores */77	JH71X0_GATE(JH7110_SYSCLK_CORE, "core", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),78	JH71X0_GATE(JH7110_SYSCLK_CORE1, "core1", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),79	JH71X0_GATE(JH7110_SYSCLK_CORE2, "core2", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),80	JH71X0_GATE(JH7110_SYSCLK_CORE3, "core3", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),81	JH71X0_GATE(JH7110_SYSCLK_CORE4, "core4", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),82	JH71X0_GATE(JH7110_SYSCLK_DEBUG, "debug", 0, JH7110_SYSCLK_CPU_BUS),83	JH71X0__DIV(JH7110_SYSCLK_RTC_TOGGLE, "rtc_toggle", 6, JH7110_SYSCLK_OSC),84	JH71X0_GATE(JH7110_SYSCLK_TRACE0, "trace0", 0, JH7110_SYSCLK_CPU_CORE),85	JH71X0_GATE(JH7110_SYSCLK_TRACE1, "trace1", 0, JH7110_SYSCLK_CPU_CORE),86	JH71X0_GATE(JH7110_SYSCLK_TRACE2, "trace2", 0, JH7110_SYSCLK_CPU_CORE),87	JH71X0_GATE(JH7110_SYSCLK_TRACE3, "trace3", 0, JH7110_SYSCLK_CPU_CORE),88	JH71X0_GATE(JH7110_SYSCLK_TRACE4, "trace4", 0, JH7110_SYSCLK_CPU_CORE),89	JH71X0_GATE(JH7110_SYSCLK_TRACE_COM, "trace_com", 0, JH7110_SYSCLK_CPU_BUS),90	/* noc */91	JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_CPU_AXI, "noc_bus_cpu_axi", CLK_IS_CRITICAL,92		    JH7110_SYSCLK_CPU_BUS),93	JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI, "noc_bus_axicfg0_axi", CLK_IS_CRITICAL,94		    JH7110_SYSCLK_AXI_CFG0),95	/* ddr */96	JH71X0__DIV(JH7110_SYSCLK_OSC_DIV2, "osc_div2", 2, JH7110_SYSCLK_OSC),97	JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV4, "pll1_div4", 2, JH7110_SYSCLK_PLL1_DIV2),98	JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV8, "pll1_div8", 2, JH7110_SYSCLK_PLL1_DIV4),99	JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 0, 4,100		    JH7110_SYSCLK_OSC_DIV2,101		    JH7110_SYSCLK_PLL1_DIV2,102		    JH7110_SYSCLK_PLL1_DIV4,103		    JH7110_SYSCLK_PLL1_DIV8),104	JH71X0_GATE(JH7110_SYSCLK_DDR_AXI, "ddr_axi", CLK_IS_CRITICAL, JH7110_SYSCLK_DDR_BUS),105	/* gpu */106	JH71X0__DIV(JH7110_SYSCLK_GPU_CORE, "gpu_core", 7, JH7110_SYSCLK_GPU_ROOT),107	JH71X0_GATE(JH7110_SYSCLK_GPU_CORE_CLK, "gpu_core_clk", 0, JH7110_SYSCLK_GPU_CORE),108	JH71X0_GATE(JH7110_SYSCLK_GPU_SYS_CLK, "gpu_sys_clk", 0, JH7110_SYSCLK_ISP_AXI),109	JH71X0_GATE(JH7110_SYSCLK_GPU_APB, "gpu_apb", 0, JH7110_SYSCLK_APB_BUS),110	JH71X0_GDIV(JH7110_SYSCLK_GPU_RTC_TOGGLE, "gpu_rtc_toggle", 0, 12, JH7110_SYSCLK_OSC),111	JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_GPU_AXI, "noc_bus_gpu_axi", 0, JH7110_SYSCLK_GPU_CORE),112	/* isp */113	JH71X0_GATE(JH7110_SYSCLK_ISP_TOP_CORE, "isp_top_core", 0, JH7110_SYSCLK_ISP_2X),114	JH71X0_GATE(JH7110_SYSCLK_ISP_TOP_AXI, "isp_top_axi", 0, JH7110_SYSCLK_ISP_AXI),115	JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_ISP_AXI, "noc_bus_isp_axi", CLK_IS_CRITICAL,116		    JH7110_SYSCLK_ISP_AXI),117	/* hifi4 */118	JH71X0__DIV(JH7110_SYSCLK_HIFI4_CORE, "hifi4_core", 15, JH7110_SYSCLK_BUS_ROOT),119	JH71X0__DIV(JH7110_SYSCLK_HIFI4_AXI, "hifi4_axi", 2, JH7110_SYSCLK_HIFI4_CORE),120	/* axi_cfg1 */121	JH71X0_GATE(JH7110_SYSCLK_AXI_CFG1_MAIN, "axi_cfg1_main", CLK_IS_CRITICAL,122		    JH7110_SYSCLK_ISP_AXI),123	JH71X0_GATE(JH7110_SYSCLK_AXI_CFG1_AHB, "axi_cfg1_ahb", CLK_IS_CRITICAL,124		    JH7110_SYSCLK_AHB0),125	/* vout */126	JH71X0_GATE(JH7110_SYSCLK_VOUT_SRC, "vout_src", 0, JH7110_SYSCLK_PLL2_OUT),127	JH71X0__DIV(JH7110_SYSCLK_VOUT_AXI, "vout_axi", 7, JH7110_SYSCLK_PLL2_OUT),128	JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_DISP_AXI, "noc_bus_disp_axi", 0, JH7110_SYSCLK_VOUT_AXI),129	JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_AHB, "vout_top_ahb", 0, JH7110_SYSCLK_AHB1),130	JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_AXI, "vout_top_axi", 0, JH7110_SYSCLK_VOUT_AXI),131	JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK, "vout_top_hdmitx0_mclk", 0,132		    JH7110_SYSCLK_MCLK),133	JH71X0__DIV(JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF, "vout_top_mipiphy_ref", 2,134		    JH7110_SYSCLK_OSC),135	/* jpegc */136	JH71X0__DIV(JH7110_SYSCLK_JPEGC_AXI, "jpegc_axi", 16, JH7110_SYSCLK_PLL2_OUT),137	JH71X0_GATE(JH7110_SYSCLK_CODAJ12_AXI, "codaj12_axi", 0, JH7110_SYSCLK_JPEGC_AXI),138	JH71X0_GDIV(JH7110_SYSCLK_CODAJ12_CORE, "codaj12_core", 0, 16, JH7110_SYSCLK_PLL2_OUT),139	JH71X0_GATE(JH7110_SYSCLK_CODAJ12_APB, "codaj12_apb", 0, JH7110_SYSCLK_APB_BUS),140	/* vdec */141	JH71X0__DIV(JH7110_SYSCLK_VDEC_AXI, "vdec_axi", 7, JH7110_SYSCLK_BUS_ROOT),142	JH71X0_GATE(JH7110_SYSCLK_WAVE511_AXI, "wave511_axi", 0, JH7110_SYSCLK_VDEC_AXI),143	JH71X0_GDIV(JH7110_SYSCLK_WAVE511_BPU, "wave511_bpu", 0, 7, JH7110_SYSCLK_BUS_ROOT),144	JH71X0_GDIV(JH7110_SYSCLK_WAVE511_VCE, "wave511_vce", 0, 7, JH7110_SYSCLK_PLL0_OUT),145	JH71X0_GATE(JH7110_SYSCLK_WAVE511_APB, "wave511_apb", 0, JH7110_SYSCLK_APB_BUS),146	JH71X0_GATE(JH7110_SYSCLK_VDEC_JPG, "vdec_jpg", 0, JH7110_SYSCLK_JPEGC_AXI),147	JH71X0_GATE(JH7110_SYSCLK_VDEC_MAIN, "vdec_main", 0, JH7110_SYSCLK_VDEC_AXI),148	JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_VDEC_AXI, "noc_bus_vdec_axi", 0, JH7110_SYSCLK_VDEC_AXI),149	/* venc */150	JH71X0__DIV(JH7110_SYSCLK_VENC_AXI, "venc_axi", 15, JH7110_SYSCLK_PLL2_OUT),151	JH71X0_GATE(JH7110_SYSCLK_WAVE420L_AXI, "wave420l_axi", 0, JH7110_SYSCLK_VENC_AXI),152	JH71X0_GDIV(JH7110_SYSCLK_WAVE420L_BPU, "wave420l_bpu", 0, 15, JH7110_SYSCLK_PLL2_OUT),153	JH71X0_GDIV(JH7110_SYSCLK_WAVE420L_VCE, "wave420l_vce", 0, 15, JH7110_SYSCLK_PLL2_OUT),154	JH71X0_GATE(JH7110_SYSCLK_WAVE420L_APB, "wave420l_apb", 0, JH7110_SYSCLK_APB_BUS),155	JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_VENC_AXI, "noc_bus_venc_axi", 0, JH7110_SYSCLK_VENC_AXI),156	/* axi_cfg0 */157	JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN_DIV, "axi_cfg0_main_div", CLK_IS_CRITICAL,158		    JH7110_SYSCLK_AHB1),159	JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN, "axi_cfg0_main", CLK_IS_CRITICAL,160		    JH7110_SYSCLK_AXI_CFG0),161	JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_HIFI4, "axi_cfg0_hifi4", CLK_IS_CRITICAL,162		    JH7110_SYSCLK_HIFI4_AXI),163	/* intmem */164	JH71X0_GATE(JH7110_SYSCLK_AXIMEM2_AXI, "aximem2_axi", 0, JH7110_SYSCLK_AXI_CFG0),165	/* qspi */166	JH71X0_GATE(JH7110_SYSCLK_QSPI_AHB, "qspi_ahb", 0, JH7110_SYSCLK_AHB1),167	JH71X0_GATE(JH7110_SYSCLK_QSPI_APB, "qspi_apb", 0, JH7110_SYSCLK_APB_BUS),168	JH71X0__DIV(JH7110_SYSCLK_QSPI_REF_SRC, "qspi_ref_src", 16, JH7110_SYSCLK_PLL0_OUT),169	JH71X0_GMUX(JH7110_SYSCLK_QSPI_REF, "qspi_ref", 0, 2,170		    JH7110_SYSCLK_OSC,171		    JH7110_SYSCLK_QSPI_REF_SRC),172	/* sdio */173	JH71X0_GATE(JH7110_SYSCLK_SDIO0_AHB, "sdio0_ahb", 0, JH7110_SYSCLK_AHB0),174	JH71X0_GATE(JH7110_SYSCLK_SDIO1_AHB, "sdio1_ahb", 0, JH7110_SYSCLK_AHB0),175	JH71X0_GDIV(JH7110_SYSCLK_SDIO0_SDCARD, "sdio0_sdcard", 0, 15, JH7110_SYSCLK_AXI_CFG0),176	JH71X0_GDIV(JH7110_SYSCLK_SDIO1_SDCARD, "sdio1_sdcard", 0, 15, JH7110_SYSCLK_AXI_CFG0),177	/* stg */178	JH71X0__DIV(JH7110_SYSCLK_USB_125M, "usb_125m", 15, JH7110_SYSCLK_PLL0_OUT),179	JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_STG_AXI, "noc_bus_stg_axi", CLK_IS_CRITICAL,180		    JH7110_SYSCLK_NOCSTG_BUS),181	/* gmac1 */182	JH71X0_GATE(JH7110_SYSCLK_GMAC1_AHB, "gmac1_ahb", 0, JH7110_SYSCLK_AHB0),183	JH71X0_GATE(JH7110_SYSCLK_GMAC1_AXI, "gmac1_axi", 0, JH7110_SYSCLK_STG_AXIAHB),184	JH71X0__DIV(JH7110_SYSCLK_GMAC_SRC, "gmac_src", 7, JH7110_SYSCLK_PLL0_OUT),185	JH71X0__DIV(JH7110_SYSCLK_GMAC1_GTXCLK, "gmac1_gtxclk", 15, JH7110_SYSCLK_PLL0_OUT),186	JH71X0__DIV(JH7110_SYSCLK_GMAC1_RMII_RTX, "gmac1_rmii_rtx", 30,187		    JH7110_SYSCLK_GMAC1_RMII_REFIN),188	JH71X0_GDIV(JH7110_SYSCLK_GMAC1_PTP, "gmac1_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),189	JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 0, 2,190		    JH7110_SYSCLK_GMAC1_RGMII_RXIN,191		    JH7110_SYSCLK_GMAC1_RMII_RTX),192	JH71X0__INV(JH7110_SYSCLK_GMAC1_RX_INV, "gmac1_rx_inv", JH7110_SYSCLK_GMAC1_RX),193	JH71X0_GMUX(JH7110_SYSCLK_GMAC1_TX, "gmac1_tx",194		    CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2,195		    JH7110_SYSCLK_GMAC1_GTXCLK,196		    JH7110_SYSCLK_GMAC1_RMII_RTX),197	JH71X0__INV(JH7110_SYSCLK_GMAC1_TX_INV, "gmac1_tx_inv", JH7110_SYSCLK_GMAC1_TX),198	JH71X0_GATE(JH7110_SYSCLK_GMAC1_GTXC, "gmac1_gtxc", 0, JH7110_SYSCLK_GMAC1_GTXCLK),199	/* gmac0 */200	JH71X0_GDIV(JH7110_SYSCLK_GMAC0_GTXCLK, "gmac0_gtxclk", 0, 15, JH7110_SYSCLK_PLL0_OUT),201	JH71X0_GDIV(JH7110_SYSCLK_GMAC0_PTP, "gmac0_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),202	JH71X0_GDIV(JH7110_SYSCLK_GMAC_PHY, "gmac_phy", 0, 31, JH7110_SYSCLK_GMAC_SRC),203	JH71X0_GATE(JH7110_SYSCLK_GMAC0_GTXC, "gmac0_gtxc", 0, JH7110_SYSCLK_GMAC0_GTXCLK),204	/* apb misc */205	JH71X0_GATE(JH7110_SYSCLK_IOMUX_APB, "iomux_apb", 0, JH7110_SYSCLK_APB_BUS),206	JH71X0_GATE(JH7110_SYSCLK_MAILBOX_APB, "mailbox_apb", 0, JH7110_SYSCLK_APB_BUS),207	JH71X0_GATE(JH7110_SYSCLK_INT_CTRL_APB, "int_ctrl_apb", 0, JH7110_SYSCLK_APB_BUS),208	/* can0 */209	JH71X0_GATE(JH7110_SYSCLK_CAN0_APB, "can0_apb", 0, JH7110_SYSCLK_APB_BUS),210	JH71X0_GDIV(JH7110_SYSCLK_CAN0_TIMER, "can0_timer", 0, 24, JH7110_SYSCLK_OSC),211	JH71X0_GDIV(JH7110_SYSCLK_CAN0_CAN, "can0_can", 0, 63, JH7110_SYSCLK_PERH_ROOT),212	/* can1 */213	JH71X0_GATE(JH7110_SYSCLK_CAN1_APB, "can1_apb", 0, JH7110_SYSCLK_APB_BUS),214	JH71X0_GDIV(JH7110_SYSCLK_CAN1_TIMER, "can1_timer", 0, 24, JH7110_SYSCLK_OSC),215	JH71X0_GDIV(JH7110_SYSCLK_CAN1_CAN, "can1_can", 0, 63, JH7110_SYSCLK_PERH_ROOT),216	/* pwm */217	JH71X0_GATE(JH7110_SYSCLK_PWM_APB, "pwm_apb", 0, JH7110_SYSCLK_APB_BUS),218	/* wdt */219	JH71X0_GATE(JH7110_SYSCLK_WDT_APB, "wdt_apb", 0, JH7110_SYSCLK_APB_BUS),220	JH71X0_GATE(JH7110_SYSCLK_WDT_CORE, "wdt_core", 0, JH7110_SYSCLK_OSC),221	/* timer */222	JH71X0_GATE(JH7110_SYSCLK_TIMER_APB, "timer_apb", 0, JH7110_SYSCLK_APB_BUS),223	JH71X0_GATE(JH7110_SYSCLK_TIMER0, "timer0", 0, JH7110_SYSCLK_OSC),224	JH71X0_GATE(JH7110_SYSCLK_TIMER1, "timer1", 0, JH7110_SYSCLK_OSC),225	JH71X0_GATE(JH7110_SYSCLK_TIMER2, "timer2", 0, JH7110_SYSCLK_OSC),226	JH71X0_GATE(JH7110_SYSCLK_TIMER3, "timer3", 0, JH7110_SYSCLK_OSC),227	/* temp sensor */228	JH71X0_GATE(JH7110_SYSCLK_TEMP_APB, "temp_apb", 0, JH7110_SYSCLK_APB_BUS),229	JH71X0_GDIV(JH7110_SYSCLK_TEMP_CORE, "temp_core", 0, 24, JH7110_SYSCLK_OSC),230	/* spi */231	JH71X0_GATE(JH7110_SYSCLK_SPI0_APB, "spi0_apb", 0, JH7110_SYSCLK_APB0),232	JH71X0_GATE(JH7110_SYSCLK_SPI1_APB, "spi1_apb", 0, JH7110_SYSCLK_APB0),233	JH71X0_GATE(JH7110_SYSCLK_SPI2_APB, "spi2_apb", 0, JH7110_SYSCLK_APB0),234	JH71X0_GATE(JH7110_SYSCLK_SPI3_APB, "spi3_apb", 0, JH7110_SYSCLK_APB_BUS),235	JH71X0_GATE(JH7110_SYSCLK_SPI4_APB, "spi4_apb", 0, JH7110_SYSCLK_APB_BUS),236	JH71X0_GATE(JH7110_SYSCLK_SPI5_APB, "spi5_apb", 0, JH7110_SYSCLK_APB_BUS),237	JH71X0_GATE(JH7110_SYSCLK_SPI6_APB, "spi6_apb", 0, JH7110_SYSCLK_APB_BUS),238	/* i2c */239	JH71X0_GATE(JH7110_SYSCLK_I2C0_APB, "i2c0_apb", 0, JH7110_SYSCLK_APB0),240	JH71X0_GATE(JH7110_SYSCLK_I2C1_APB, "i2c1_apb", 0, JH7110_SYSCLK_APB0),241	JH71X0_GATE(JH7110_SYSCLK_I2C2_APB, "i2c2_apb", 0, JH7110_SYSCLK_APB0),242	JH71X0_GATE(JH7110_SYSCLK_I2C3_APB, "i2c3_apb", 0, JH7110_SYSCLK_APB_BUS),243	JH71X0_GATE(JH7110_SYSCLK_I2C4_APB, "i2c4_apb", 0, JH7110_SYSCLK_APB_BUS),244	JH71X0_GATE(JH7110_SYSCLK_I2C5_APB, "i2c5_apb", 0, JH7110_SYSCLK_APB_BUS),245	JH71X0_GATE(JH7110_SYSCLK_I2C6_APB, "i2c6_apb", 0, JH7110_SYSCLK_APB_BUS),246	/* uart */247	JH71X0_GATE(JH7110_SYSCLK_UART0_APB, "uart0_apb", 0, JH7110_SYSCLK_APB0),248	JH71X0_GATE(JH7110_SYSCLK_UART0_CORE, "uart0_core", 0, JH7110_SYSCLK_OSC),249	JH71X0_GATE(JH7110_SYSCLK_UART1_APB, "uart1_apb", 0, JH7110_SYSCLK_APB0),250	JH71X0_GATE(JH7110_SYSCLK_UART1_CORE, "uart1_core", 0, JH7110_SYSCLK_OSC),251	JH71X0_GATE(JH7110_SYSCLK_UART2_APB, "uart2_apb", 0, JH7110_SYSCLK_APB0),252	JH71X0_GATE(JH7110_SYSCLK_UART2_CORE, "uart2_core", 0, JH7110_SYSCLK_OSC),253	JH71X0_GATE(JH7110_SYSCLK_UART3_APB, "uart3_apb", 0, JH7110_SYSCLK_APB0),254	JH71X0_GDIV(JH7110_SYSCLK_UART3_CORE, "uart3_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),255	JH71X0_GATE(JH7110_SYSCLK_UART4_APB, "uart4_apb", 0, JH7110_SYSCLK_APB0),256	JH71X0_GDIV(JH7110_SYSCLK_UART4_CORE, "uart4_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),257	JH71X0_GATE(JH7110_SYSCLK_UART5_APB, "uart5_apb", 0, JH7110_SYSCLK_APB0),258	JH71X0_GDIV(JH7110_SYSCLK_UART5_CORE, "uart5_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),259	/* pwmdac */260	JH71X0_GATE(JH7110_SYSCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7110_SYSCLK_APB0),261	JH71X0_GDIV(JH7110_SYSCLK_PWMDAC_CORE, "pwmdac_core", 0, 256, JH7110_SYSCLK_AUDIO_ROOT),262	/* spdif */263	JH71X0_GATE(JH7110_SYSCLK_SPDIF_APB, "spdif_apb", 0, JH7110_SYSCLK_APB0),264	JH71X0_GATE(JH7110_SYSCLK_SPDIF_CORE, "spdif_core", 0, JH7110_SYSCLK_MCLK),265	/* i2stx0 */266	JH71X0_GATE(JH7110_SYSCLK_I2STX0_APB, "i2stx0_apb", 0, JH7110_SYSCLK_APB0),267	JH71X0_GDIV(JH7110_SYSCLK_I2STX0_BCLK_MST, "i2stx0_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),268	JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_MST_INV, "i2stx0_bclk_mst_inv",269		    JH7110_SYSCLK_I2STX0_BCLK_MST),270	JH71X0_MDIV(JH7110_SYSCLK_I2STX0_LRCK_MST, "i2stx0_lrck_mst", 64, 2,271		    JH7110_SYSCLK_I2STX0_BCLK_MST_INV,272		    JH7110_SYSCLK_I2STX0_BCLK_MST),273	JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 0, 2,274		    JH7110_SYSCLK_I2STX0_BCLK_MST,275		    JH7110_SYSCLK_I2STX_BCLK_EXT),276	JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_INV, "i2stx0_bclk_inv", JH7110_SYSCLK_I2STX0_BCLK),277	JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 0, 2,278		    JH7110_SYSCLK_I2STX0_LRCK_MST,279		    JH7110_SYSCLK_I2STX_LRCK_EXT),280	/* i2stx1 */281	JH71X0_GATE(JH7110_SYSCLK_I2STX1_APB, "i2stx1_apb", 0, JH7110_SYSCLK_APB0),282	JH71X0_GDIV(JH7110_SYSCLK_I2STX1_BCLK_MST, "i2stx1_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),283	JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_MST_INV, "i2stx1_bclk_mst_inv",284		    JH7110_SYSCLK_I2STX1_BCLK_MST),285	JH71X0_MDIV(JH7110_SYSCLK_I2STX1_LRCK_MST, "i2stx1_lrck_mst", 64, 2,286		    JH7110_SYSCLK_I2STX1_BCLK_MST_INV,287		    JH7110_SYSCLK_I2STX1_BCLK_MST),288	JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 0, 2,289		    JH7110_SYSCLK_I2STX1_BCLK_MST,290		    JH7110_SYSCLK_I2STX_BCLK_EXT),291	JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_INV, "i2stx1_bclk_inv", JH7110_SYSCLK_I2STX1_BCLK),292	JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 0, 2,293		    JH7110_SYSCLK_I2STX1_LRCK_MST,294		    JH7110_SYSCLK_I2STX_LRCK_EXT),295	/* i2srx */296	JH71X0_GATE(JH7110_SYSCLK_I2SRX_APB, "i2srx_apb", 0, JH7110_SYSCLK_APB0),297	JH71X0_GDIV(JH7110_SYSCLK_I2SRX_BCLK_MST, "i2srx_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),298	JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_MST_INV, "i2srx_bclk_mst_inv",299		    JH7110_SYSCLK_I2SRX_BCLK_MST),300	JH71X0_MDIV(JH7110_SYSCLK_I2SRX_LRCK_MST, "i2srx_lrck_mst", 64, 2,301		    JH7110_SYSCLK_I2SRX_BCLK_MST_INV,302		    JH7110_SYSCLK_I2SRX_BCLK_MST),303	JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 0, 2,304		    JH7110_SYSCLK_I2SRX_BCLK_MST,305		    JH7110_SYSCLK_I2SRX_BCLK_EXT),306	JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_INV, "i2srx_bclk_inv", JH7110_SYSCLK_I2SRX_BCLK),307	JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 0, 2,308		    JH7110_SYSCLK_I2SRX_LRCK_MST,309		    JH7110_SYSCLK_I2SRX_LRCK_EXT),310	/* pdm */311	JH71X0_GDIV(JH7110_SYSCLK_PDM_DMIC, "pdm_dmic", 0, 64, JH7110_SYSCLK_MCLK),312	JH71X0_GATE(JH7110_SYSCLK_PDM_APB, "pdm_apb", 0, JH7110_SYSCLK_APB0),313	/* tdm */314	JH71X0_GATE(JH7110_SYSCLK_TDM_AHB, "tdm_ahb", 0, JH7110_SYSCLK_AHB0),315	JH71X0_GATE(JH7110_SYSCLK_TDM_APB, "tdm_apb", 0, JH7110_SYSCLK_APB0),316	JH71X0_GDIV(JH7110_SYSCLK_TDM_INTERNAL, "tdm_internal", 0, 64, JH7110_SYSCLK_MCLK),317	JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 0, 2,318		    JH7110_SYSCLK_TDM_INTERNAL,319		    JH7110_SYSCLK_TDM_EXT),320	JH71X0__INV(JH7110_SYSCLK_TDM_TDM_INV, "tdm_tdm_inv", JH7110_SYSCLK_TDM_TDM),321	/* jtag */322	JH71X0__DIV(JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG, "jtag_certification_trng", 4,323		    JH7110_SYSCLK_OSC),324};325 326static struct clk_hw *jh7110_sysclk_get(struct of_phandle_args *clkspec, void *data)327{328	struct jh71x0_clk_priv *priv = data;329	unsigned int idx = clkspec->args[0];330 331	if (idx < JH7110_SYSCLK_END)332		return &priv->reg[idx].hw;333 334	return ERR_PTR(-EINVAL);335}336 337static void jh7110_reset_unregister_adev(void *_adev)338{339	struct auxiliary_device *adev = _adev;340 341	auxiliary_device_delete(adev);342	auxiliary_device_uninit(adev);343}344 345static void jh7110_reset_adev_release(struct device *dev)346{347	struct auxiliary_device *adev = to_auxiliary_dev(dev);348	struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);349 350	kfree(rdev);351}352 353int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,354				     const char *adev_name,355				     u32 adev_id)356{357	struct jh71x0_reset_adev *rdev;358	struct auxiliary_device *adev;359	int ret;360 361	rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);362	if (!rdev)363		return -ENOMEM;364 365	rdev->base = priv->base;366 367	adev = &rdev->adev;368	adev->name = adev_name;369	adev->dev.parent = priv->dev;370	adev->dev.release = jh7110_reset_adev_release;371	adev->id = adev_id;372 373	ret = auxiliary_device_init(adev);374	if (ret)375		return ret;376 377	ret = auxiliary_device_add(adev);378	if (ret) {379		auxiliary_device_uninit(adev);380		return ret;381	}382 383	return devm_add_action_or_reset(priv->dev,384					jh7110_reset_unregister_adev, adev);385}386EXPORT_SYMBOL_GPL(jh7110_reset_controller_register);387 388/*389 * This clock notifier is called when the rate of PLL0 clock is to be changed.390 * The cpu_root clock should save the curent parent clock and switch its parent391 * clock to osc before PLL0 rate will be changed. Then switch its parent clock392 * back after the PLL0 rate is completed.393 */394static int jh7110_pll0_clk_notifier_cb(struct notifier_block *nb,395				       unsigned long action, void *data)396{397	struct jh71x0_clk_priv *priv = container_of(nb, struct jh71x0_clk_priv, pll_clk_nb);398	struct clk *cpu_root = priv->reg[JH7110_SYSCLK_CPU_ROOT].hw.clk;399	int ret = 0;400 401	if (action == PRE_RATE_CHANGE) {402		struct clk *osc = clk_get(priv->dev, "osc");403 404		priv->original_clk = clk_get_parent(cpu_root);405		ret = clk_set_parent(cpu_root, osc);406		clk_put(osc);407	} else if (action == POST_RATE_CHANGE) {408		ret = clk_set_parent(cpu_root, priv->original_clk);409	}410 411	return notifier_from_errno(ret);412}413 414static int __init jh7110_syscrg_probe(struct platform_device *pdev)415{416	struct jh71x0_clk_priv *priv;417	unsigned int idx;418	int ret;419	struct clk *pllclk;420 421	priv = devm_kzalloc(&pdev->dev,422			    struct_size(priv, reg, JH7110_SYSCLK_END),423			    GFP_KERNEL);424	if (!priv)425		return -ENOMEM;426 427	spin_lock_init(&priv->rmw_lock);428	priv->dev = &pdev->dev;429	priv->base = devm_platform_ioremap_resource(pdev, 0);430	if (IS_ERR(priv->base))431		return PTR_ERR(priv->base);432 433	/* Use fixed factor clocks if can not get the PLL clocks from DTS */434	pllclk = clk_get(priv->dev, "pll0_out");435	if (IS_ERR(pllclk)) {436		/* 24MHz -> 1000.0MHz */437		priv->pll[0] = devm_clk_hw_register_fixed_factor(priv->dev, "pll0_out",438								 "osc", 0, 125, 3);439		if (IS_ERR(priv->pll[0]))440			return PTR_ERR(priv->pll[0]);441	} else {442		priv->pll_clk_nb.notifier_call = jh7110_pll0_clk_notifier_cb;443		ret = clk_notifier_register(pllclk, &priv->pll_clk_nb);444		if (ret)445			return ret;446		priv->pll[0] = NULL;447	}448 449	pllclk = clk_get(priv->dev, "pll1_out");450	if (IS_ERR(pllclk)) {451		/* 24MHz -> 1066.0MHz */452		priv->pll[1] = devm_clk_hw_register_fixed_factor(priv->dev, "pll1_out",453								 "osc", 0, 533, 12);454		if (IS_ERR(priv->pll[1]))455			return PTR_ERR(priv->pll[1]);456	} else {457		clk_put(pllclk);458		priv->pll[1] = NULL;459	}460 461	pllclk = clk_get(priv->dev, "pll2_out");462	if (IS_ERR(pllclk)) {463		/* 24MHz -> 1188.0MHz */464		priv->pll[2] = devm_clk_hw_register_fixed_factor(priv->dev, "pll2_out",465								 "osc", 0, 99, 2);466		if (IS_ERR(priv->pll[2]))467			return PTR_ERR(priv->pll[2]);468	} else {469		clk_put(pllclk);470		priv->pll[2] = NULL;471	}472 473	for (idx = 0; idx < JH7110_SYSCLK_END; idx++) {474		u32 max = jh7110_sysclk_data[idx].max;475		struct clk_parent_data parents[4] = {};476		struct clk_init_data init = {477			.name = jh7110_sysclk_data[idx].name,478			.ops = starfive_jh71x0_clk_ops(max),479			.parent_data = parents,480			.num_parents =481				((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,482			.flags = jh7110_sysclk_data[idx].flags,483		};484		struct jh71x0_clk *clk = &priv->reg[idx];485		unsigned int i;486 487		for (i = 0; i < init.num_parents; i++) {488			unsigned int pidx = jh7110_sysclk_data[idx].parents[i];489 490			if (pidx < JH7110_SYSCLK_END)491				parents[i].hw = &priv->reg[pidx].hw;492			else if (pidx == JH7110_SYSCLK_OSC)493				parents[i].fw_name = "osc";494			else if (pidx == JH7110_SYSCLK_GMAC1_RMII_REFIN)495				parents[i].fw_name = "gmac1_rmii_refin";496			else if (pidx == JH7110_SYSCLK_GMAC1_RGMII_RXIN)497				parents[i].fw_name = "gmac1_rgmii_rxin";498			else if (pidx == JH7110_SYSCLK_I2STX_BCLK_EXT)499				parents[i].fw_name = "i2stx_bclk_ext";500			else if (pidx == JH7110_SYSCLK_I2STX_LRCK_EXT)501				parents[i].fw_name = "i2stx_lrck_ext";502			else if (pidx == JH7110_SYSCLK_I2SRX_BCLK_EXT)503				parents[i].fw_name = "i2srx_bclk_ext";504			else if (pidx == JH7110_SYSCLK_I2SRX_LRCK_EXT)505				parents[i].fw_name = "i2srx_lrck_ext";506			else if (pidx == JH7110_SYSCLK_TDM_EXT)507				parents[i].fw_name = "tdm_ext";508			else if (pidx == JH7110_SYSCLK_MCLK_EXT)509				parents[i].fw_name = "mclk_ext";510			else if (pidx == JH7110_SYSCLK_PLL0_OUT && !priv->pll[0])511				parents[i].fw_name = "pll0_out";512			else if (pidx == JH7110_SYSCLK_PLL1_OUT && !priv->pll[1])513				parents[i].fw_name = "pll1_out";514			else if (pidx == JH7110_SYSCLK_PLL2_OUT && !priv->pll[2])515				parents[i].fw_name = "pll2_out";516			else517				parents[i].hw = priv->pll[pidx - JH7110_SYSCLK_PLL0_OUT];518		}519 520		clk->hw.init = &init;521		clk->idx = idx;522		clk->max_div = max & JH71X0_CLK_DIV_MASK;523 524		ret = devm_clk_hw_register(&pdev->dev, &clk->hw);525		if (ret)526			return ret;527	}528 529	ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_sysclk_get, priv);530	if (ret)531		return ret;532 533	return jh7110_reset_controller_register(priv, "rst-sys", 0);534}535 536static const struct of_device_id jh7110_syscrg_match[] = {537	{ .compatible = "starfive,jh7110-syscrg" },538	{ /* sentinel */ }539};540 541static struct platform_driver jh7110_syscrg_driver = {542	.driver = {543		.name = "clk-starfive-jh7110-sys",544		.of_match_table = jh7110_syscrg_match,545		.suppress_bind_attrs = true,546	},547};548builtin_platform_driver_probe(jh7110_syscrg_driver, jh7110_syscrg_probe);549