Kongyang Liu | 80bf1f7 | 2024-06-11 17:41:14 +0800 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | /* |
| 3 | * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com> |
| 4 | */ |
| 5 | |
| 6 | #include <clk-uclass.h> |
| 7 | #include <dm.h> |
| 8 | #include <linux/clk-provider.h> |
| 9 | |
| 10 | #include "clk-common.h" |
| 11 | #include "clk-cv1800b.h" |
| 12 | #include "clk-ip.h" |
| 13 | #include "clk-pll.h" |
| 14 | |
| 15 | static const char *const clk_cam_parents[] = { |
| 16 | "clk_cam0pll", |
| 17 | "clk_cam0pll_d2", |
| 18 | "clk_cam0pll_d3", |
| 19 | "clk_mipimpll_d3" |
| 20 | }; |
| 21 | |
| 22 | static const char *const clk_tpu_parents[] = { |
| 23 | "clk_tpll", |
| 24 | "clk_a0pll", |
| 25 | "clk_mipimpll", |
| 26 | "clk_fpll" |
| 27 | }; |
| 28 | |
| 29 | static const char *const clk_axi4_parents[] = { "clk_fpll", "clk_disppll" }; |
| 30 | static const char *const clk_aud_parents[] = { "clk_a0pll", "clk_a24m" }; |
| 31 | static const char *const clk_cam0_200_parents[] = { "osc", "clk_disppll" }; |
| 32 | |
| 33 | static const char *const clk_vip_sys_parents[] = { |
| 34 | "clk_mipimpll", |
| 35 | "clk_cam0pll", |
| 36 | "clk_disppll", |
| 37 | "clk_fpll" |
| 38 | }; |
| 39 | |
| 40 | static const char *const clk_axi_video_codec_parents[] = { |
| 41 | "clk_a0pll", |
| 42 | "clk_mipimpll", |
| 43 | "clk_cam1pll", |
| 44 | "clk_fpll" |
| 45 | }; |
| 46 | |
| 47 | static const char *const clk_vc_src0_parents[] = { |
| 48 | "clk_disppll", |
| 49 | "clk_mipimpll", |
| 50 | "clk_cam1pll", |
| 51 | "clk_fpll" |
| 52 | }; |
| 53 | |
| 54 | static const struct cv1800b_mmux_parent_info clk_c906_0_parents[] = { |
| 55 | { "clk_tpll", 0, 0 }, |
| 56 | { "clk_a0pll", 0, 1 }, |
| 57 | { "clk_mipimpll", 0, 2 }, |
| 58 | { "clk_mpll", 0, 3 }, |
| 59 | { "clk_fpll", 1, 0 }, |
| 60 | }; |
| 61 | |
| 62 | static const struct cv1800b_mmux_parent_info clk_c906_1_parents[] = { |
| 63 | { "clk_tpll", 0, 0 }, |
| 64 | { "clk_a0pll", 0, 1 }, |
| 65 | { "clk_disppll", 0, 2 }, |
| 66 | { "clk_mpll", 0, 3 }, |
| 67 | { "clk_fpll", 1, 0 }, |
| 68 | }; |
| 69 | |
| 70 | static const struct cv1800b_mmux_parent_info clk_a53_parents[] = { |
| 71 | { "clk_tpll", 0, 0 }, |
| 72 | { "clk_a0pll", 0, 1 }, |
| 73 | { "clk_mipimpll", 0, 2 }, |
| 74 | { "clk_mpll", 0, 3 }, |
| 75 | { "clk_fpll", 1, 0 }, |
| 76 | }; |
| 77 | |
| 78 | static struct cv1800b_clk_gate cv1800b_gate_info[] = { |
| 79 | CV1800B_GATE(CLK_XTAL_AP, "clk_xtal_ap", "osc", REG_CLK_EN_0, 3, CLK_IS_CRITICAL), |
| 80 | CV1800B_GATE(CLK_RTC_25M, "clk_rtc_25m", "osc", REG_CLK_EN_0, 8, CLK_IS_CRITICAL), |
| 81 | CV1800B_GATE(CLK_TEMPSEN, "clk_tempsen", "osc", REG_CLK_EN_0, 9, 0), |
| 82 | CV1800B_GATE(CLK_SARADC, "clk_saradc", "osc", REG_CLK_EN_0, 10, 0), |
| 83 | CV1800B_GATE(CLK_EFUSE, "clk_efuse", "osc", REG_CLK_EN_0, 11, 0), |
| 84 | CV1800B_GATE(CLK_APB_EFUSE, "clk_apb_efuse", "osc", REG_CLK_EN_0, 12, 0), |
| 85 | CV1800B_GATE(CLK_DEBUG, "clk_debug", "osc", REG_CLK_EN_0, 13, CLK_IS_CRITICAL), |
| 86 | CV1800B_GATE(CLK_XTAL_MISC, "clk_xtal_misc", "osc", REG_CLK_EN_0, 14, CLK_IS_CRITICAL), |
| 87 | CV1800B_GATE(CLK_APB_WDT, "clk_apb_wdt", "osc", REG_CLK_EN_1, 7, CLK_IS_CRITICAL), |
| 88 | CV1800B_GATE(CLK_WGN, "clk_wgn", "osc", REG_CLK_EN_3, 22, 0), |
| 89 | CV1800B_GATE(CLK_WGN0, "clk_wgn0", "osc", REG_CLK_EN_3, 23, 0), |
| 90 | CV1800B_GATE(CLK_WGN1, "clk_wgn1", "osc", REG_CLK_EN_3, 24, 0), |
| 91 | CV1800B_GATE(CLK_WGN2, "clk_wgn2", "osc", REG_CLK_EN_3, 25, 0), |
| 92 | CV1800B_GATE(CLK_KEYSCAN, "clk_keyscan", "osc", REG_CLK_EN_3, 26, 0), |
| 93 | CV1800B_GATE(CLK_TPU_FAB, "clk_tpu_fab", "clk_mipimpll", REG_CLK_EN_0, 5, 0), |
| 94 | CV1800B_GATE(CLK_AHB_ROM, "clk_ahb_rom", "clk_axi4", REG_CLK_EN_0, 6, 0), |
| 95 | CV1800B_GATE(CLK_AXI4_EMMC, "clk_axi4_emmc", "clk_axi4", REG_CLK_EN_0, 15, 0), |
| 96 | CV1800B_GATE(CLK_AXI4_SD0, "clk_axi4_sd0", "clk_axi4", REG_CLK_EN_0, 18, 0), |
| 97 | CV1800B_GATE(CLK_AXI4_SD1, "clk_axi4_sd1", "clk_axi4", REG_CLK_EN_0, 21, 0), |
| 98 | CV1800B_GATE(CLK_AXI4_ETH0, "clk_axi4_eth0", "clk_axi4", REG_CLK_EN_0, 26, 0), |
| 99 | CV1800B_GATE(CLK_AXI4_ETH1, "clk_axi4_eth1", "clk_axi4", REG_CLK_EN_0, 28, 0), |
| 100 | CV1800B_GATE(CLK_AHB_SF, "clk_ahb_sf", "clk_axi4", REG_CLK_EN_1, 0, 0), |
| 101 | CV1800B_GATE(CLK_SDMA_AXI, "clk_sdma_axi", "clk_axi4", REG_CLK_EN_1, 1, 0), |
| 102 | CV1800B_GATE(CLK_APB_I2C, "clk_apb_i2c", "clk_axi4", REG_CLK_EN_1, 6, 0), |
| 103 | CV1800B_GATE(CLK_APB_SPI0, "clk_apb_spi0", "clk_axi4", REG_CLK_EN_1, 9, 0), |
| 104 | CV1800B_GATE(CLK_APB_SPI1, "clk_apb_spi1", "clk_axi4", REG_CLK_EN_1, 10, 0), |
| 105 | CV1800B_GATE(CLK_APB_SPI2, "clk_apb_spi2", "clk_axi4", REG_CLK_EN_1, 11, 0), |
| 106 | CV1800B_GATE(CLK_APB_SPI3, "clk_apb_spi3", "clk_axi4", REG_CLK_EN_1, 12, 0), |
| 107 | CV1800B_GATE(CLK_APB_UART0, "clk_apb_uart0", "clk_axi4", REG_CLK_EN_1, 15, CLK_IS_CRITICAL), |
| 108 | CV1800B_GATE(CLK_APB_UART1, "clk_apb_uart1", "clk_axi4", REG_CLK_EN_1, 17, 0), |
| 109 | CV1800B_GATE(CLK_APB_UART2, "clk_apb_uart2", "clk_axi4", REG_CLK_EN_1, 19, 0), |
| 110 | CV1800B_GATE(CLK_APB_UART3, "clk_apb_uart3", "clk_axi4", REG_CLK_EN_1, 21, 0), |
| 111 | CV1800B_GATE(CLK_APB_UART4, "clk_apb_uart4", "clk_axi4", REG_CLK_EN_1, 23, 0), |
| 112 | CV1800B_GATE(CLK_APB_I2S0, "clk_apb_i2s0", "clk_axi4", REG_CLK_EN_1, 24, 0), |
| 113 | CV1800B_GATE(CLK_APB_I2S1, "clk_apb_i2s1", "clk_axi4", REG_CLK_EN_1, 25, 0), |
| 114 | CV1800B_GATE(CLK_APB_I2S2, "clk_apb_i2s2", "clk_axi4", REG_CLK_EN_1, 26, 0), |
| 115 | CV1800B_GATE(CLK_APB_I2S3, "clk_apb_i2s3", "clk_axi4", REG_CLK_EN_1, 27, 0), |
| 116 | CV1800B_GATE(CLK_AXI4_USB, "clk_axi4_usb", "clk_axi4", REG_CLK_EN_1, 28, 0), |
| 117 | CV1800B_GATE(CLK_APB_USB, "clk_apb_usb", "clk_axi4", REG_CLK_EN_1, 29, 0), |
| 118 | CV1800B_GATE(CLK_APB_I2C0, "clk_apb_i2c0", "clk_axi4", REG_CLK_EN_3, 17, 0), |
| 119 | CV1800B_GATE(CLK_APB_I2C1, "clk_apb_i2c1", "clk_axi4", REG_CLK_EN_3, 18, 0), |
| 120 | CV1800B_GATE(CLK_APB_I2C2, "clk_apb_i2c2", "clk_axi4", REG_CLK_EN_3, 19, 0), |
| 121 | CV1800B_GATE(CLK_APB_I2C3, "clk_apb_i2c3", "clk_axi4", REG_CLK_EN_3, 20, 0), |
| 122 | CV1800B_GATE(CLK_APB_I2C4, "clk_apb_i2c4", "clk_axi4", REG_CLK_EN_3, 21, 0), |
| 123 | CV1800B_GATE(CLK_AHB_SF1, "clk_ahb_sf1", "clk_axi4", REG_CLK_EN_3, 27, 0), |
| 124 | CV1800B_GATE(CLK_APB_AUDSRC, "clk_apb_audsrc", "clk_axi4", REG_CLK_EN_4, 2, 0), |
| 125 | CV1800B_GATE(CLK_DDR_AXI_REG, "clk_ddr_axi_reg", "clk_axi6", REG_CLK_EN_0, 7, |
| 126 | CLK_IS_CRITICAL), |
| 127 | CV1800B_GATE(CLK_APB_GPIO, "clk_apb_gpio", "clk_axi6", REG_CLK_EN_0, 29, CLK_IS_CRITICAL), |
| 128 | CV1800B_GATE(CLK_APB_GPIO_INTR, "clk_apb_gpio_intr", "clk_axi6", REG_CLK_EN_0, 30, |
| 129 | CLK_IS_CRITICAL), |
| 130 | CV1800B_GATE(CLK_APB_JPEG, "clk_apb_jpeg", "clk_axi6", REG_CLK_EN_2, 13, CLK_IGNORE_UNUSED), |
| 131 | CV1800B_GATE(CLK_APB_H264C, "clk_apb_h264c", "clk_axi6", REG_CLK_EN_2, 14, 0), |
| 132 | CV1800B_GATE(CLK_APB_H265C, "clk_apb_h265c", "clk_axi6", REG_CLK_EN_2, 15, 0), |
| 133 | CV1800B_GATE(CLK_PM, "clk_pm", "clk_axi6", REG_CLK_EN_3, 8, CLK_IS_CRITICAL), |
| 134 | CV1800B_GATE(CLK_CFG_REG_VIP, "clk_cfg_reg_vip", "clk_axi6", REG_CLK_EN_3, 31, 0), |
| 135 | CV1800B_GATE(CLK_CFG_REG_VC, "clk_cfg_reg_vc", "clk_axi6", REG_CLK_EN_4, 0, |
| 136 | CLK_IGNORE_UNUSED), |
| 137 | CV1800B_GATE(CLK_PWM, "clk_pwm", "clk_pwm_src", REG_CLK_EN_1, 8, CLK_IS_CRITICAL), |
| 138 | CV1800B_GATE(CLK_UART0, "clk_uart0", "clk_cam0_200", REG_CLK_EN_1, 14, CLK_IS_CRITICAL), |
| 139 | CV1800B_GATE(CLK_UART1, "clk_uart1", "clk_cam0_200", REG_CLK_EN_1, 16, 0), |
| 140 | CV1800B_GATE(CLK_UART2, "clk_uart2", "clk_cam0_200", REG_CLK_EN_1, 18, 0), |
| 141 | CV1800B_GATE(CLK_UART3, "clk_uart3", "clk_cam0_200", REG_CLK_EN_1, 20, 0), |
| 142 | CV1800B_GATE(CLK_UART4, "clk_uart4", "clk_cam0_200", REG_CLK_EN_1, 22, 0), |
| 143 | CV1800B_GATE(CLK_H264C, "clk_h264c", "clk_axi_video_codec", REG_CLK_EN_2, 10, 0), |
| 144 | CV1800B_GATE(CLK_H265C, "clk_h265c", "clk_axi_video_codec", REG_CLK_EN_2, 11, 0), |
| 145 | CV1800B_GATE(CLK_JPEG, "clk_jpeg", "clk_axi_video_codec", REG_CLK_EN_2, 12, |
| 146 | CLK_IGNORE_UNUSED), |
| 147 | CV1800B_GATE(CLK_CSI_MAC0_VIP, "clk_csi_mac0_vip", "clk_axi_vip", REG_CLK_EN_2, 18, 0), |
| 148 | CV1800B_GATE(CLK_CSI_MAC1_VIP, "clk_csi_mac1_vip", "clk_axi_vip", REG_CLK_EN_2, 19, 0), |
| 149 | CV1800B_GATE(CLK_ISP_TOP_VIP, "clk_isp_top_vip", "clk_axi_vip", REG_CLK_EN_2, 20, 0), |
| 150 | CV1800B_GATE(CLK_IMG_D_VIP, "clk_img_d_vip", "clk_axi_vip", REG_CLK_EN_2, 21, 0), |
| 151 | CV1800B_GATE(CLK_IMG_V_VIP, "clk_img_v_vip", "clk_axi_vip", REG_CLK_EN_2, 22, 0), |
| 152 | CV1800B_GATE(CLK_SC_TOP_VIP, "clk_sc_top_vip", "clk_axi_vip", REG_CLK_EN_2, 23, 0), |
| 153 | CV1800B_GATE(CLK_SC_D_VIP, "clk_sc_d_vip", "clk_axi_vip", REG_CLK_EN_2, 24, 0), |
| 154 | CV1800B_GATE(CLK_SC_V1_VIP, "clk_sc_v1_vip", "clk_axi_vip", REG_CLK_EN_2, 25, 0), |
| 155 | CV1800B_GATE(CLK_SC_V2_VIP, "clk_sc_v2_vip", "clk_axi_vip", REG_CLK_EN_2, 26, 0), |
| 156 | CV1800B_GATE(CLK_SC_V3_VIP, "clk_sc_v3_vip", "clk_axi_vip", REG_CLK_EN_2, 27, 0), |
| 157 | CV1800B_GATE(CLK_DWA_VIP, "clk_dwa_vip", "clk_axi_vip", REG_CLK_EN_2, 28, 0), |
| 158 | CV1800B_GATE(CLK_BT_VIP, "clk_bt_vip", "clk_axi_vip", REG_CLK_EN_2, 29, 0), |
| 159 | CV1800B_GATE(CLK_DISP_VIP, "clk_disp_vip", "clk_axi_vip", REG_CLK_EN_2, 30, 0), |
| 160 | CV1800B_GATE(CLK_DSI_MAC_VIP, "clk_dsi_mac_vip", "clk_axi_vip", REG_CLK_EN_2, 31, 0), |
| 161 | CV1800B_GATE(CLK_LVDS0_VIP, "clk_lvds0_vip", "clk_axi_vip", REG_CLK_EN_3, 0, 0), |
| 162 | CV1800B_GATE(CLK_LVDS1_VIP, "clk_lvds1_vip", "clk_axi_vip", REG_CLK_EN_3, 1, 0), |
| 163 | CV1800B_GATE(CLK_CSI0_RX_VIP, "clk_csi0_rx_vip", "clk_axi_vip", REG_CLK_EN_3, 2, 0), |
| 164 | CV1800B_GATE(CLK_CSI1_RX_VIP, "clk_csi1_rx_vip", "clk_axi_vip", REG_CLK_EN_3, 3, 0), |
| 165 | CV1800B_GATE(CLK_PAD_VI_VIP, "clk_pad_vi_vip", "clk_axi_vip", REG_CLK_EN_3, 4, 0), |
| 166 | CV1800B_GATE(CLK_PAD_VI1_VIP, "clk_pad_vi1_vip", "clk_axi_vip", REG_CLK_EN_3, 30, 0), |
| 167 | CV1800B_GATE(CLK_PAD_VI2_VIP, "clk_pad_vi2_vip", "clk_axi_vip", REG_CLK_EN_4, 7, 0), |
| 168 | CV1800B_GATE(CLK_CSI_BE_VIP, "clk_csi_be_vip", "clk_axi_vip", REG_CLK_EN_4, 8, 0), |
| 169 | CV1800B_GATE(CLK_VIP_IP0, "clk_vip_ip0", "clk_axi_vip", REG_CLK_EN_4, 9, 0), |
| 170 | CV1800B_GATE(CLK_VIP_IP1, "clk_vip_ip1", "clk_axi_vip", REG_CLK_EN_4, 10, 0), |
| 171 | CV1800B_GATE(CLK_VIP_IP2, "clk_vip_ip2", "clk_axi_vip", REG_CLK_EN_4, 11, 0), |
| 172 | CV1800B_GATE(CLK_VIP_IP3, "clk_vip_ip3", "clk_axi_vip", REG_CLK_EN_4, 12, 0), |
| 173 | CV1800B_GATE(CLK_IVE_VIP, "clk_ive_vip", "clk_axi_vip", REG_CLK_EN_4, 17, 0), |
| 174 | CV1800B_GATE(CLK_RAW_VIP, "clk_raw_vip", "clk_axi_vip", REG_CLK_EN_4, 18, 0), |
| 175 | CV1800B_GATE(CLK_OSDC_VIP, "clk_osdc_vip", "clk_axi_vip", REG_CLK_EN_4, 19, 0), |
| 176 | CV1800B_GATE(CLK_CSI_MAC2_VIP, "clk_csi_mac2_vip", "clk_axi_vip", REG_CLK_EN_4, 20, 0), |
| 177 | CV1800B_GATE(CLK_CAM0_VIP, "clk_cam0_vip", "clk_axi_vip", REG_CLK_EN_4, 21, 0), |
| 178 | CV1800B_GATE(CLK_TIMER0, "clk_timer0", "clk_xtal_misc", REG_CLK_EN_3, 9, CLK_IS_CRITICAL), |
| 179 | CV1800B_GATE(CLK_TIMER1, "clk_timer1", "clk_xtal_misc", REG_CLK_EN_3, 10, CLK_IS_CRITICAL), |
| 180 | CV1800B_GATE(CLK_TIMER2, "clk_timer2", "clk_xtal_misc", REG_CLK_EN_3, 11, CLK_IS_CRITICAL), |
| 181 | CV1800B_GATE(CLK_TIMER3, "clk_timer3", "clk_xtal_misc", REG_CLK_EN_3, 12, CLK_IS_CRITICAL), |
| 182 | CV1800B_GATE(CLK_TIMER4, "clk_timer4", "clk_xtal_misc", REG_CLK_EN_3, 13, CLK_IS_CRITICAL), |
| 183 | CV1800B_GATE(CLK_TIMER5, "clk_timer5", "clk_xtal_misc", REG_CLK_EN_3, 14, CLK_IS_CRITICAL), |
| 184 | CV1800B_GATE(CLK_TIMER6, "clk_timer6", "clk_xtal_misc", REG_CLK_EN_3, 15, CLK_IS_CRITICAL), |
| 185 | CV1800B_GATE(CLK_TIMER7, "clk_timer7", "clk_xtal_misc", REG_CLK_EN_3, 16, CLK_IS_CRITICAL), |
| 186 | }; |
| 187 | |
| 188 | struct cv1800b_clk_div cv1800b_div_info[] = { |
| 189 | CV1800B_DIV(CLK_1M, "clk_1m", "osc", REG_CLK_EN_3, 5, |
| 190 | REG_DIV_CLK_1M, 16, 6, 25, CLK_IS_CRITICAL), |
| 191 | CV1800B_DIV(CLK_EMMC_100K, "clk_emmc_100k", "clk_1m", REG_CLK_EN_0, 17, |
| 192 | REG_DIV_CLK_EMMC_100K, 16, 8, 10, 0), |
| 193 | CV1800B_DIV(CLK_SD0_100K, "clk_sd0_100k", "clk_1m", REG_CLK_EN_0, 20, |
| 194 | REG_DIV_CLK_SD0_100K, 16, 8, 10, 0), |
| 195 | CV1800B_DIV(CLK_SD1_100K, "clk_sd1_100k", "clk_1m", REG_CLK_EN_0, 23, |
| 196 | REG_DIV_CLK_SD1_100K, 16, 8, 10, 0), |
| 197 | CV1800B_DIV(CLK_GPIO_DB, "clk_gpio_db", "clk_1m", REG_CLK_EN_0, 31, |
| 198 | REG_DIV_CLK_GPIO_DB, 16, 16, 10, CLK_IS_CRITICAL) |
| 199 | }; |
| 200 | |
| 201 | struct cv1800b_clk_bypass_div cv1800b_bypass_div_info[] = { |
| 202 | CV1800B_BYPASS_DIV(CLK_AP_DEBUG, "clk_ap_debug", "clk_fpll", REG_CLK_EN_4, 5, |
| 203 | REG_DIV_CLK_AP_DEBUG, 16, 4, 5, REG_CLK_BYP_1, 4, CLK_IS_CRITICAL), |
| 204 | CV1800B_BYPASS_DIV(CLK_SRC_RTC_SYS_0, "clk_src_rtc_sys_0", "clk_fpll", REG_CLK_EN_4, 6, |
| 205 | REG_DIV_CLK_RTCSYS_SRC_0, 16, 4, 5, REG_CLK_BYP_1, 5, CLK_IS_CRITICAL), |
| 206 | CV1800B_BYPASS_DIV(CLK_CPU_GIC, "clk_cpu_gic", "clk_fpll", REG_CLK_EN_0, 2, |
| 207 | REG_DIV_CLK_CPU_GIC, 16, 4, 5, REG_CLK_BYP_0, 2, CLK_IS_CRITICAL), |
| 208 | CV1800B_BYPASS_DIV(CLK_ETH0_500M, "clk_eth0_500m", "clk_fpll", REG_CLK_EN_0, 25, |
| 209 | REG_DIV_CLK_GPIO_DB, 16, 4, 3, REG_CLK_BYP_0, 9, 0), |
| 210 | CV1800B_BYPASS_DIV(CLK_ETH1_500M, "clk_eth1_500m", "clk_fpll", REG_CLK_EN_0, 27, |
| 211 | REG_DIV_CLK_GPIO_DB, 16, 4, 3, REG_CLK_BYP_0, 10, 0), |
| 212 | CV1800B_BYPASS_DIV(CLK_AXI6, "clk_axi6", "clk_fpll", REG_CLK_EN_2, 2, REG_DIV_CLK_AXI6, 16, |
| 213 | 4, 15, REG_CLK_BYP_0, 20, CLK_IS_CRITICAL), |
| 214 | CV1800B_BYPASS_DIV(CLK_SPI, "clk_spi", "clk_fpll", REG_CLK_EN_3, 6, REG_DIV_CLK_SPI, 16, 6, |
| 215 | 8, REG_CLK_BYP_0, 30, 0), |
| 216 | CV1800B_BYPASS_DIV(CLK_DISP_SRC_VIP, "clk_disp_src_vip", "clk_disppll", REG_CLK_EN_2, 7, |
| 217 | REG_DIV_CLK_DISP_SRC_VIP, 16, 4, 8, REG_CLK_BYP_0, 25, 0), |
| 218 | CV1800B_BYPASS_DIV(CLK_CPU_AXI0, "clk_cpu_axi0", "clk_axi4", REG_CLK_EN_0, 1, |
| 219 | REG_DIV_CLK_CPU_AXI0, 16, 4, 3, REG_CLK_BYP_0, 1, CLK_IS_CRITICAL), |
| 220 | CV1800B_BYPASS_DIV(CLK_DSI_ESC, "clk_dsi_esc", "clk_axi6", REG_CLK_EN_2, 3, |
| 221 | REG_DIV_CLK_DSI_ESC, 16, 4, 5, REG_CLK_BYP_0, 21, 0), |
| 222 | CV1800B_BYPASS_DIV(CLK_I2C, "clk_i2c", "clk_axi6", REG_CLK_EN_3, 7, REG_DIV_CLK_I2C, 16, 4, |
| 223 | 1, REG_CLK_BYP_0, 31, 0), |
| 224 | }; |
| 225 | |
| 226 | struct cv1800b_clk_fixed_div cv1800b_fixed_div_info[] = { |
| 227 | CV1800B_FIXED_DIV(CLK_CAM0PLL_D2, "clk_cam0pll_d2", "clk_cam0pll", |
| 228 | REG_CAM0PLL_CLK_CSR, 1, 2, |
| 229 | CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), |
| 230 | CV1800B_FIXED_DIV(CLK_CAM0PLL_D3, "clk_cam0pll_d3", "clk_cam0pll", |
| 231 | REG_CAM0PLL_CLK_CSR, 2, 3, |
| 232 | CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), |
| 233 | CV1800B_FIXED_DIV(CLK_MIPIMPLL_D3, "clk_mipimpll_d3", "clk_mipimpll", |
| 234 | REG_MIPIMPLL_CLK_CSR, 2, 3, |
| 235 | CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), |
| 236 | CV1800B_FIXED_DIV(CLK_USB_33K, "clk_usb_33k", "clk_1m", |
| 237 | REG_CLK_EN_1, 31, 3, |
| 238 | 0), |
| 239 | }; |
| 240 | |
| 241 | struct cv1800b_clk_bypass_fixed_div cv1800b_bypass_fixed_div_info[] = { |
| 242 | CV1800B_BYPASS_FIXED_DIV(CLK_USB_125M, "clk_usb_125m", "clk_fpll", |
| 243 | REG_CLK_EN_1, 30, 12, |
| 244 | REG_CLK_BYP_0, 17, |
| 245 | CLK_SET_RATE_PARENT), |
| 246 | CV1800B_BYPASS_FIXED_DIV(CLK_USB_12M, "clk_usb_12m", "clk_fpll", |
| 247 | REG_CLK_EN_2, 0, 125, |
| 248 | REG_CLK_BYP_0, 18, |
| 249 | CLK_SET_RATE_PARENT), |
| 250 | CV1800B_BYPASS_FIXED_DIV(CLK_VC_SRC1, "clk_vc_src1", "clk_fpll", |
| 251 | REG_CLK_EN_3, 28, 2, |
| 252 | REG_CLK_BYP_1, 0, |
| 253 | CLK_SET_RATE_PARENT), |
| 254 | CV1800B_BYPASS_FIXED_DIV(CLK_VC_SRC2, "clk_vc_src2", "clk_fpll", |
| 255 | REG_CLK_EN_4, 3, 3, |
| 256 | REG_CLK_BYP_1, 3, |
| 257 | CLK_SET_RATE_PARENT), |
| 258 | }; |
| 259 | |
| 260 | struct cv1800b_clk_mux cv1800b_mux_info[] = { |
| 261 | CV1800B_MUX(CLK_CAM0, "clk_cam0", clk_cam_parents, |
| 262 | REG_CLK_EN_2, 16, |
| 263 | REG_CLK_CAM0_SRC_DIV, 16, 6, 0, |
| 264 | REG_CLK_CAM0_SRC_DIV, 8, 2, |
| 265 | CLK_IGNORE_UNUSED), |
| 266 | CV1800B_MUX(CLK_CAM1, "clk_cam1", clk_cam_parents, |
| 267 | REG_CLK_EN_2, 17, |
| 268 | REG_CLK_CAM1_SRC_DIV, 16, 6, 0, |
| 269 | REG_CLK_CAM1_SRC_DIV, 8, 2, |
| 270 | CLK_IGNORE_UNUSED), |
| 271 | }; |
| 272 | |
| 273 | struct cv1800b_clk_bypass_mux cv1800b_bypass_mux_info[] = { |
| 274 | CV1800B_BYPASS_MUX(CLK_TPU, "clk_tpu", clk_tpu_parents, |
| 275 | REG_CLK_EN_0, 4, |
| 276 | REG_DIV_CLK_TPU, 16, 4, 3, |
| 277 | REG_DIV_CLK_TPU, 8, 2, |
| 278 | REG_CLK_BYP_0, 3, |
| 279 | 0), |
| 280 | CV1800B_BYPASS_MUX(CLK_EMMC, "clk_emmc", clk_axi4_parents, |
| 281 | REG_CLK_EN_0, 16, |
| 282 | REG_DIV_CLK_EMMC, 16, 5, 15, |
| 283 | REG_DIV_CLK_EMMC, 8, 2, |
| 284 | REG_CLK_BYP_0, 5, |
| 285 | 0), |
| 286 | CV1800B_BYPASS_MUX(CLK_SD0, "clk_sd0", clk_axi4_parents, |
| 287 | REG_CLK_EN_0, 19, |
| 288 | REG_DIV_CLK_SD0, 16, 5, 15, |
| 289 | REG_DIV_CLK_SD0, 8, 2, |
| 290 | REG_CLK_BYP_0, 6, |
| 291 | 0), |
| 292 | CV1800B_BYPASS_MUX(CLK_SD1, "clk_sd1", clk_axi4_parents, |
| 293 | REG_CLK_EN_0, 22, |
| 294 | REG_DIV_CLK_SD1, 16, 5, 15, |
| 295 | REG_DIV_CLK_SD1, 8, 2, |
| 296 | REG_CLK_BYP_0, 7, |
| 297 | 0), |
| 298 | CV1800B_BYPASS_MUX(CLK_SPI_NAND, "clk_spi_nand", clk_axi4_parents, |
| 299 | REG_CLK_EN_0, 24, |
| 300 | REG_DIV_CLK_SPI_NAND, 16, 5, 8, |
| 301 | REG_DIV_CLK_SPI_NAND, 8, 2, |
| 302 | REG_CLK_BYP_0, 8, |
| 303 | 0), |
| 304 | CV1800B_BYPASS_MUX(CLK_AXI4, "clk_axi4", clk_axi4_parents, |
| 305 | REG_CLK_EN_2, 1, |
| 306 | REG_DIV_CLK_AXI4, 16, 4, 5, |
| 307 | REG_DIV_CLK_AXI4, 8, 2, |
| 308 | REG_CLK_BYP_0, 19, |
| 309 | CLK_IS_CRITICAL), |
| 310 | CV1800B_BYPASS_MUX(CLK_PWM_SRC, "clk_pwm_src", clk_axi4_parents, |
| 311 | REG_CLK_EN_4, 4, |
| 312 | REG_DIV_CLK_PWM_SRC_0, 16, 6, 10, |
| 313 | REG_DIV_CLK_PWM_SRC_0, 8, 2, |
| 314 | REG_CLK_BYP_0, 15, |
| 315 | CLK_IS_CRITICAL), |
| 316 | CV1800B_BYPASS_MUX(CLK_AUDSRC, "clk_audsrc", clk_aud_parents, |
| 317 | REG_CLK_EN_4, 1, |
| 318 | REG_DIV_CLK_AUDSRC, 16, 8, 18, |
| 319 | REG_DIV_CLK_AUDSRC, 8, 2, |
| 320 | REG_CLK_BYP_1, 2, |
| 321 | 0), |
| 322 | CV1800B_BYPASS_MUX(CLK_SDMA_AUD0, "clk_sdma_aud0", clk_aud_parents, |
| 323 | REG_CLK_EN_1, 2, |
| 324 | REG_DIV_CLK_SDMA_AUD0, 16, 8, 18, |
| 325 | REG_DIV_CLK_SDMA_AUD0, 8, 2, |
| 326 | REG_CLK_BYP_0, 11, |
| 327 | 0), |
| 328 | CV1800B_BYPASS_MUX(CLK_SDMA_AUD1, "clk_sdma_aud1", clk_aud_parents, |
| 329 | REG_CLK_EN_1, 3, |
| 330 | REG_DIV_CLK_SDMA_AUD1, 16, 8, 18, |
| 331 | REG_DIV_CLK_SDMA_AUD1, 8, 2, |
| 332 | REG_CLK_BYP_0, 12, |
| 333 | 0), |
| 334 | CV1800B_BYPASS_MUX(CLK_SDMA_AUD2, "clk_sdma_aud2", clk_aud_parents, |
| 335 | REG_CLK_EN_1, 3, |
| 336 | REG_DIV_CLK_SDMA_AUD2, 16, 8, 18, |
| 337 | REG_DIV_CLK_SDMA_AUD2, 8, 2, |
| 338 | REG_CLK_BYP_0, 13, |
| 339 | 0), |
| 340 | CV1800B_BYPASS_MUX(CLK_SDMA_AUD3, "clk_sdma_aud3", clk_aud_parents, |
| 341 | REG_CLK_EN_1, 3, |
| 342 | REG_DIV_CLK_SDMA_AUD3, 16, 8, 18, |
| 343 | REG_DIV_CLK_SDMA_AUD3, 8, 2, |
| 344 | REG_CLK_BYP_0, 14, |
| 345 | 0), |
| 346 | CV1800B_BYPASS_MUX(CLK_CAM0_200, "clk_cam0_200", clk_cam0_200_parents, |
| 347 | REG_CLK_EN_1, 13, |
| 348 | REG_DIV_CLK_CAM0_200, 16, 4, 1, |
| 349 | REG_DIV_CLK_CAM0_200, 8, 2, |
| 350 | REG_CLK_BYP_0, 16, |
| 351 | CLK_IS_CRITICAL), |
| 352 | CV1800B_BYPASS_MUX(CLK_AXI_VIP, "clk_axi_vip", clk_vip_sys_parents, |
| 353 | REG_CLK_EN_2, 4, |
| 354 | REG_DIV_CLK_AXI_VIP, 16, 4, 3, |
| 355 | REG_DIV_CLK_AXI_VIP, 8, 2, |
| 356 | REG_CLK_BYP_0, 22, |
| 357 | 0), |
| 358 | CV1800B_BYPASS_MUX(CLK_SRC_VIP_SYS_0, "clk_src_vip_sys_0", clk_vip_sys_parents, |
| 359 | REG_CLK_EN_2, 5, |
| 360 | REG_DIV_CLK_SRC_VIP_SYS_0, 16, 4, 6, |
| 361 | REG_DIV_CLK_SRC_VIP_SYS_0, 8, 2, |
| 362 | REG_CLK_BYP_0, 23, |
| 363 | 0), |
| 364 | CV1800B_BYPASS_MUX(CLK_SRC_VIP_SYS_1, "clk_src_vip_sys_1", clk_vip_sys_parents, |
| 365 | REG_CLK_EN_2, 6, |
| 366 | REG_DIV_CLK_SRC_VIP_SYS_1, 16, 4, 6, |
| 367 | REG_DIV_CLK_SRC_VIP_SYS_1, 8, 2, |
| 368 | REG_CLK_BYP_0, 24, |
| 369 | 0), |
| 370 | CV1800B_BYPASS_MUX(CLK_SRC_VIP_SYS_2, "clk_src_vip_sys_2", clk_vip_sys_parents, |
| 371 | REG_CLK_EN_3, 29, |
| 372 | REG_DIV_CLK_SRC_VIP_SYS_2, 16, 4, 2, |
| 373 | REG_DIV_CLK_SRC_VIP_SYS_2, 8, 2, |
| 374 | REG_CLK_BYP_1, 1, |
| 375 | 0), |
| 376 | CV1800B_BYPASS_MUX(CLK_SRC_VIP_SYS_3, "clk_src_vip_sys_3", clk_vip_sys_parents, |
| 377 | REG_CLK_EN_4, 15, |
| 378 | REG_DIV_CLK_SRC_VIP_SYS_3, 16, 4, 2, |
| 379 | REG_DIV_CLK_SRC_VIP_SYS_3, 8, 2, |
| 380 | REG_CLK_BYP_1, 8, |
| 381 | 0), |
| 382 | CV1800B_BYPASS_MUX(CLK_SRC_VIP_SYS_4, "clk_src_vip_sys_4", clk_vip_sys_parents, |
| 383 | REG_CLK_EN_4, 16, |
| 384 | REG_DIV_CLK_SRC_VIP_SYS_4, 16, 4, 3, |
| 385 | REG_DIV_CLK_SRC_VIP_SYS_4, 8, 2, |
| 386 | REG_CLK_BYP_1, 9, |
| 387 | 0), |
| 388 | CV1800B_BYPASS_MUX(CLK_AXI_VIDEO_CODEC, "clk_axi_video_codec", clk_axi_video_codec_parents, |
| 389 | REG_CLK_EN_2, 8, |
| 390 | REG_DIV_CLK_AXI_VIDEO_CODEC, 16, 4, 2, |
| 391 | REG_DIV_CLK_AXI_VIDEO_CODEC, 8, 2, |
| 392 | REG_CLK_BYP_0, 26, |
| 393 | 0), |
| 394 | CV1800B_BYPASS_MUX(CLK_VC_SRC0, "clk_vc_src0", clk_vc_src0_parents, |
| 395 | REG_CLK_EN_2, 9, |
| 396 | REG_DIV_CLK_VC_SRC0, 16, 4, 2, |
| 397 | REG_DIV_CLK_VC_SRC0, 8, 2, |
| 398 | REG_CLK_BYP_0, 27, |
| 399 | 0), |
| 400 | }; |
| 401 | |
| 402 | struct cv1800b_clk_mmux cv1800b_mmux_info[] = { |
| 403 | CV1800B_MMUX(CLK_C906_0, "clk_c906_0", clk_c906_0_parents, |
| 404 | REG_CLK_EN_4, 13, |
| 405 | REG_DIV_CLK_C906_0_0, 16, 4, 1, |
| 406 | REG_DIV_CLK_C906_0_1, 16, 4, 2, |
| 407 | REG_DIV_CLK_C906_0_0, 8, 2, |
| 408 | REG_DIV_CLK_C906_0_1, 8, 2, |
| 409 | REG_CLK_BYP_1, 6, |
| 410 | REG_CLK_SEL_0, 23, |
| 411 | CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE), |
| 412 | CV1800B_MMUX(CLK_C906_1, "clk_c906_1", clk_c906_1_parents, |
| 413 | REG_CLK_EN_4, 14, |
| 414 | REG_DIV_CLK_C906_1_0, 16, 4, 2, |
| 415 | REG_DIV_CLK_C906_1_1, 16, 4, 3, |
| 416 | REG_DIV_CLK_C906_1_0, 8, 2, |
| 417 | REG_DIV_CLK_C906_1_1, 8, 2, |
| 418 | REG_CLK_BYP_1, 7, |
| 419 | REG_CLK_SEL_0, 24, |
| 420 | CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE), |
| 421 | CV1800B_MMUX(CLK_A53, "clk_a53", clk_a53_parents, |
| 422 | REG_CLK_EN_0, 0, |
| 423 | REG_DIV_CLK_A53_0, 16, 4, 1, |
| 424 | REG_DIV_CLK_A53_1, 16, 4, 2, |
| 425 | REG_DIV_CLK_A53_0, 8, 2, |
| 426 | REG_DIV_CLK_A53_1, 8, 2, |
| 427 | REG_CLK_BYP_0, 0, |
| 428 | REG_CLK_SEL_0, 0, |
| 429 | CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE), |
| 430 | }; |
| 431 | |
| 432 | static struct cv1800b_clk_audio cv1800b_audio_info[] = { |
| 433 | CV1800B_AUDIO(CLK_A24M, "clk_a24m", "clk_mipimpll", |
| 434 | REG_APLL_FRAC_DIV_CTRL, 0, |
| 435 | REG_APLL_FRAC_DIV_CTRL, 3, |
| 436 | REG_APLL_FRAC_DIV_CTRL, 1, |
| 437 | REG_APLL_FRAC_DIV_CTRL, 2, |
| 438 | REG_APLL_FRAC_DIV_M, 0, 22, |
| 439 | REG_APLL_FRAC_DIV_N, 0, 22, |
| 440 | 0), |
| 441 | }; |
| 442 | |
| 443 | static struct cv1800b_clk_ipll cv1800b_ipll_info[] = { |
| 444 | CV1800B_IPLL(CLK_FPLL, "clk_fpll", "osc", REG_FPLL_CSR, |
| 445 | REG_PLL_G6_CTRL, 8, |
| 446 | REG_PLL_G6_STATUS, 2, |
| 447 | CLK_IS_CRITICAL), |
| 448 | CV1800B_IPLL(CLK_MIPIMPLL, "clk_mipimpll", "osc", REG_MIPIMPLL_CSR, |
| 449 | REG_PLL_G2_CTRL, 0, |
| 450 | REG_PLL_G2_STATUS, 0, |
| 451 | CLK_IS_CRITICAL), |
| 452 | }; |
| 453 | |
| 454 | static struct cv1800b_clk_fpll cv1800b_fpll_info[] = { |
| 455 | CV1800B_FPLL(CLK_MPLL, "clk_mpll", "osc", REG_MPLL_CSR, |
| 456 | REG_PLL_G6_CTRL, 0, |
| 457 | REG_PLL_G6_STATUS, 0, |
| 458 | REG_PLL_G6_SSC_SYN_CTRL, 2, |
| 459 | REG_PLL_G6_SSC_SYN_CTRL, 0, |
| 460 | REG_MPLL_SSC_SYN_CTRL, REG_MPLL_SSC_SYN_SET, |
| 461 | CLK_IS_CRITICAL), |
| 462 | CV1800B_FPLL(CLK_TPLL, "clk_tpll", "osc", REG_TPLL_CSR, |
| 463 | REG_PLL_G6_CTRL, 4, |
| 464 | REG_PLL_G6_STATUS, 1, |
| 465 | REG_PLL_G6_SSC_SYN_CTRL, 3, |
| 466 | REG_PLL_G6_SSC_SYN_CTRL, 0, |
| 467 | REG_TPLL_SSC_SYN_CTRL, REG_TPLL_SSC_SYN_SET, |
| 468 | CLK_IS_CRITICAL), |
| 469 | CV1800B_FPLL(CLK_A0PLL, "clk_a0pll", "clk_mipimpll", REG_A0PLL_CSR, |
| 470 | REG_PLL_G2_CTRL, 4, |
| 471 | REG_PLL_G2_STATUS, 1, |
| 472 | REG_PLL_G2_SSC_SYN_CTRL, 2, |
| 473 | REG_PLL_G2_SSC_SYN_CTRL, 0, |
| 474 | REG_A0PLL_SSC_SYN_CTRL, REG_A0PLL_SSC_SYN_SET, |
| 475 | CLK_IS_CRITICAL), |
| 476 | CV1800B_FPLL(CLK_DISPPLL, "clk_disppll", "clk_mipimpll", REG_DISPPLL_CSR, |
| 477 | REG_PLL_G2_CTRL, 8, |
| 478 | REG_PLL_G2_STATUS, 2, |
| 479 | REG_PLL_G2_SSC_SYN_CTRL, 3, |
| 480 | REG_PLL_G2_SSC_SYN_CTRL, 0, |
| 481 | REG_DISPPLL_SSC_SYN_CTRL, REG_DISPPLL_SSC_SYN_SET, |
| 482 | CLK_IS_CRITICAL), |
| 483 | CV1800B_FPLL(CLK_CAM0PLL, "clk_cam0pll", "clk_mipimpll", REG_CAM0PLL_CSR, |
| 484 | REG_PLL_G2_CTRL, 12, |
| 485 | REG_PLL_G2_STATUS, 3, |
| 486 | REG_PLL_G2_SSC_SYN_CTRL, 4, |
| 487 | REG_PLL_G2_SSC_SYN_CTRL, 0, |
| 488 | REG_CAM0PLL_SSC_SYN_CTRL, REG_CAM0PLL_SSC_SYN_SET, |
| 489 | CLK_IGNORE_UNUSED), |
| 490 | CV1800B_FPLL(CLK_CAM1PLL, "clk_cam1pll", "clk_mipimpll", REG_CAM1PLL_CSR, |
| 491 | REG_PLL_G2_CTRL, 16, |
| 492 | REG_PLL_G2_STATUS, 4, |
| 493 | REG_PLL_G2_SSC_SYN_CTRL, 5, |
| 494 | REG_PLL_G2_SSC_SYN_CTRL, 0, |
| 495 | REG_CAM1PLL_SSC_SYN_CTRL, REG_CAM1PLL_SSC_SYN_SET, |
| 496 | CLK_IS_CRITICAL), |
| 497 | }; |
| 498 | |
| 499 | static int cv1800b_register_clk(struct udevice *dev) |
| 500 | { |
| 501 | struct clk osc; |
| 502 | ulong osc_rate; |
| 503 | void *base = devfdt_get_addr_ptr(dev); |
| 504 | int i, ret; |
| 505 | |
| 506 | ret = clk_get_by_index(dev, 0, &osc); |
| 507 | if (ret) { |
| 508 | pr_err("Failed to get clock\n"); |
| 509 | return ret; |
| 510 | } |
| 511 | |
| 512 | osc_rate = clk_get_rate(&osc); |
| 513 | clk_dm(CV1800B_CLK_OSC, clk_register_fixed_rate(NULL, "osc", osc_rate)); |
| 514 | clk_dm(CV1800B_CLK_BYPASS, clk_register_fixed_rate(NULL, "bypass", osc_rate)); |
| 515 | |
| 516 | for (i = 0; i < ARRAY_SIZE(cv1800b_ipll_info); i++) { |
| 517 | struct cv1800b_clk_ipll *ipll = &cv1800b_ipll_info[i]; |
| 518 | |
| 519 | ipll->base = base; |
| 520 | ret = clk_register(&ipll->clk, "cv1800b_clk_ipll", ipll->name, |
| 521 | ipll->parent_name); |
| 522 | if (ret) { |
| 523 | pr_err("Failed to register ipll %s\n", ipll->name); |
| 524 | return ret; |
| 525 | } |
| 526 | } |
| 527 | |
| 528 | for (i = 0; i < ARRAY_SIZE(cv1800b_fpll_info); i++) { |
| 529 | struct cv1800b_clk_fpll *fpll = &cv1800b_fpll_info[i]; |
| 530 | |
| 531 | fpll->ipll.base = base; |
| 532 | ret = clk_register(&fpll->ipll.clk, "cv1800b_clk_fpll", |
| 533 | fpll->ipll.name, fpll->ipll.parent_name); |
| 534 | if (ret) { |
| 535 | pr_err("Failed to register fpll %s\n", fpll->ipll.name); |
| 536 | return ret; |
| 537 | } |
| 538 | } |
| 539 | |
| 540 | for (i = 0; i < ARRAY_SIZE(cv1800b_div_info); i++) { |
| 541 | struct cv1800b_clk_div *div = &cv1800b_div_info[i]; |
| 542 | |
| 543 | div->base = base; |
| 544 | ret = clk_register(&div->clk, "cv1800b_clk_div", div->name, |
| 545 | div->parent_name); |
| 546 | if (ret) { |
| 547 | pr_err("Failed to register div %s\n", div->name); |
| 548 | return ret; |
| 549 | } |
| 550 | } |
| 551 | |
| 552 | for (i = 0; i < ARRAY_SIZE(cv1800b_fixed_div_info); i++) { |
| 553 | struct cv1800b_clk_fixed_div *fixed_div = |
| 554 | &cv1800b_fixed_div_info[i]; |
| 555 | |
| 556 | fixed_div->base = base; |
| 557 | ret = clk_register(&fixed_div->clk, "cv1800b_clk_fixed_div", |
| 558 | fixed_div->name, fixed_div->parent_name); |
| 559 | if (ret) { |
| 560 | pr_err("Failed to register fixed div %s\n", |
| 561 | fixed_div->name); |
| 562 | return ret; |
| 563 | } |
| 564 | } |
| 565 | |
| 566 | for (i = 0; i < ARRAY_SIZE(cv1800b_bypass_fixed_div_info); i++) { |
| 567 | struct cv1800b_clk_bypass_fixed_div *bypass_fixed_div = |
| 568 | &cv1800b_bypass_fixed_div_info[i]; |
| 569 | |
| 570 | bypass_fixed_div->div.base = base; |
| 571 | ret = clk_register(&bypass_fixed_div->div.clk, |
| 572 | "cv1800b_clk_bypass_fixed_div", |
| 573 | bypass_fixed_div->div.name, |
| 574 | bypass_fixed_div->div.parent_name); |
| 575 | if (ret) { |
| 576 | pr_err("Failed to register bypass fixed div %s\n", |
| 577 | bypass_fixed_div->div.name); |
| 578 | return ret; |
| 579 | } |
| 580 | } |
| 581 | |
| 582 | for (i = 0; i < ARRAY_SIZE(cv1800b_mux_info); i++) { |
| 583 | struct cv1800b_clk_mux *mux = &cv1800b_mux_info[i]; |
| 584 | int parent; |
| 585 | |
| 586 | mux->base = base; |
| 587 | parent = cv1800b_clk_getfield(base, &mux->mux); |
| 588 | ret = clk_register(&mux->clk, "cv1800b_clk_mux", mux->name, |
| 589 | mux->parent_names[parent]); |
| 590 | if (ret) { |
| 591 | pr_err("Failed to register mux %s\n", mux->name); |
| 592 | return ret; |
| 593 | } |
| 594 | } |
| 595 | |
| 596 | for (i = 0; i < ARRAY_SIZE(cv1800b_mmux_info); i++) { |
| 597 | struct cv1800b_clk_mmux *mmux = &cv1800b_mmux_info[i]; |
| 598 | int clk_sel, parent, idx; |
| 599 | |
| 600 | mmux->base = base; |
| 601 | clk_sel = cv1800b_clk_getbit(base, &mmux->clk_sel) ? 0 : 1; |
| 602 | parent = cv1800b_clk_getfield(base, &mmux->mux[clk_sel]); |
| 603 | for (idx = 0; idx < mmux->num_parents; idx++) { |
| 604 | if (clk_sel == mmux->parent_infos[idx].clk_sel && |
| 605 | parent == mmux->parent_infos[idx].index) |
| 606 | break; |
| 607 | } |
| 608 | ret = clk_register(&mmux->clk, "cv1800b_clk_mmux", mmux->name, |
| 609 | mmux->parent_infos[idx].name); |
| 610 | if (ret) { |
| 611 | pr_err("Failed to register mmux %s\n", mmux->name); |
| 612 | return ret; |
| 613 | } |
| 614 | } |
| 615 | |
| 616 | for (i = 0; i < ARRAY_SIZE(cv1800b_audio_info); i++) { |
| 617 | struct cv1800b_clk_audio *audio = &cv1800b_audio_info[i]; |
| 618 | |
| 619 | audio->base = base; |
| 620 | ret = clk_register(&audio->clk, "cv1800b_clk_audio", |
| 621 | audio->name, audio->parent_name); |
| 622 | if (ret) { |
| 623 | pr_err("Failed to register audio %s\n", audio->name); |
| 624 | return ret; |
| 625 | } |
| 626 | } |
| 627 | |
| 628 | for (i = 0; i < ARRAY_SIZE(cv1800b_bypass_mux_info); i++) { |
| 629 | struct cv1800b_clk_bypass_mux *bypass_mux = |
| 630 | &cv1800b_bypass_mux_info[i]; |
| 631 | int parent; |
| 632 | |
| 633 | bypass_mux->mux.base = base; |
| 634 | parent = cv1800b_clk_getfield(base, &bypass_mux->mux.mux); |
| 635 | ret = clk_register(&bypass_mux->mux.clk, |
| 636 | "cv1800b_clk_bypass_mux", |
| 637 | bypass_mux->mux.name, |
| 638 | bypass_mux->mux.parent_names[parent]); |
| 639 | if (ret) { |
| 640 | pr_err("Failed to register bypass mux %s\n", |
| 641 | bypass_mux->mux.name); |
| 642 | return ret; |
| 643 | } |
| 644 | } |
| 645 | |
| 646 | for (i = 0; i < ARRAY_SIZE(cv1800b_bypass_div_info); i++) { |
| 647 | struct cv1800b_clk_bypass_div *bypass_div = |
| 648 | &cv1800b_bypass_div_info[i]; |
| 649 | |
| 650 | bypass_div->div.base = base; |
| 651 | ret = clk_register(&bypass_div->div.clk, |
| 652 | "cv1800b_clk_bypass_div", |
| 653 | bypass_div->div.name, |
| 654 | bypass_div->div.parent_name); |
| 655 | if (ret) { |
| 656 | pr_err("Failed to register bypass div %s\n", |
| 657 | bypass_div->div.name); |
| 658 | return ret; |
| 659 | } |
| 660 | } |
| 661 | |
| 662 | for (i = 0; i < ARRAY_SIZE(cv1800b_gate_info); i++) { |
| 663 | struct cv1800b_clk_gate *gate = &cv1800b_gate_info[i]; |
| 664 | |
| 665 | gate->base = base; |
| 666 | ret = clk_register(&gate->clk, "cv1800b_clk_gate", gate->name, |
| 667 | gate->parent_name); |
| 668 | if (ret) { |
| 669 | pr_err("Failed to register gate %s\n", gate->name); |
| 670 | return ret; |
| 671 | } |
| 672 | } |
| 673 | return 0; |
| 674 | } |
| 675 | |
| 676 | static int cv1800b_clk_probe(struct udevice *dev) |
| 677 | { |
| 678 | return cv1800b_register_clk(dev); |
| 679 | } |
| 680 | |
| 681 | static int cv1800b_clk_enable(struct clk *clk) |
| 682 | { |
| 683 | struct clk *c; |
| 684 | int err = clk_get_by_id(CV1800B_CLK_ID_TRANSFORM(clk->id), &c); |
| 685 | |
| 686 | if (err) |
| 687 | return err; |
| 688 | return clk_enable(c); |
| 689 | } |
| 690 | |
| 691 | static int cv1800b_clk_disable(struct clk *clk) |
| 692 | { |
| 693 | struct clk *c; |
| 694 | int err = clk_get_by_id(CV1800B_CLK_ID_TRANSFORM(clk->id), &c); |
| 695 | |
| 696 | if (err) |
| 697 | return err; |
| 698 | return clk_disable(c); |
| 699 | } |
| 700 | |
| 701 | static ulong cv1800b_clk_get_rate(struct clk *clk) |
| 702 | { |
| 703 | struct clk *c; |
| 704 | int err = clk_get_by_id(CV1800B_CLK_ID_TRANSFORM(clk->id), &c); |
| 705 | |
| 706 | if (err) |
| 707 | return err; |
| 708 | return clk_get_rate(c); |
| 709 | } |
| 710 | |
| 711 | static ulong cv1800b_clk_set_rate(struct clk *clk, ulong rate) |
| 712 | { |
| 713 | struct clk *c; |
| 714 | int err = clk_get_by_id(CV1800B_CLK_ID_TRANSFORM(clk->id), &c); |
| 715 | |
| 716 | if (err) |
| 717 | return err; |
| 718 | return clk_set_rate(c, rate); |
| 719 | } |
| 720 | |
| 721 | static int cv1800b_clk_set_parent(struct clk *clk, struct clk *parent) |
| 722 | { |
| 723 | struct clk *c, *p; |
| 724 | int err = clk_get_by_id(CV1800B_CLK_ID_TRANSFORM(clk->id), &c); |
| 725 | |
| 726 | if (err) |
| 727 | return err; |
| 728 | err = clk_get_by_id(CV1800B_CLK_ID_TRANSFORM(parent->id), &p); |
| 729 | if (err) |
| 730 | return err; |
| 731 | return clk_set_parent(c, p); |
| 732 | } |
| 733 | |
| 734 | const struct clk_ops cv1800b_clk_ops = { |
| 735 | .enable = cv1800b_clk_enable, |
| 736 | .disable = cv1800b_clk_disable, |
| 737 | .get_rate = cv1800b_clk_get_rate, |
| 738 | .set_rate = cv1800b_clk_set_rate, |
| 739 | .set_parent = cv1800b_clk_set_parent, |
| 740 | }; |
| 741 | |
| 742 | static const struct udevice_id cv1800b_clk_of_match[] = { |
| 743 | { .compatible = "sophgo,cv1800-clk" }, |
| 744 | { }, |
| 745 | }; |
| 746 | |
| 747 | U_BOOT_DRIVER(sophgo_clk) = { |
| 748 | .name = "cv1800b_clk", |
| 749 | .id = UCLASS_CLK, |
| 750 | .of_match = cv1800b_clk_of_match, |
| 751 | .probe = cv1800b_clk_probe, |
| 752 | .ops = &cv1800b_clk_ops, |
| 753 | .flags = DM_FLAG_PRE_RELOC, |
| 754 | }; |