Neil Armstrong | a1809222 | 2023-12-18 10:47:55 +0100 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | /* |
| 3 | * Based on Linux driver from: |
| 4 | * (C) Copyright 2018 - BayLibre, SAS |
| 5 | * Author: Neil Armstrong <narmstrong@baylibre.com> |
| 6 | * (C) Copyright 2023 - Neil Armstrong <neil.armstrong@linaro.org> |
| 7 | */ |
| 8 | |
| 9 | #include <log.h> |
| 10 | #include <clk-uclass.h> |
| 11 | #include <div64.h> |
| 12 | #include <dm.h> |
| 13 | #include <time.h> |
| 14 | #include <regmap.h> |
| 15 | #include <syscon.h> |
| 16 | #include <linux/bitops.h> |
| 17 | #include <linux/bitfield.h> |
| 18 | #include <linux/delay.h> |
| 19 | #include <linux/err.h> |
| 20 | #include <linux/kernel.h> |
| 21 | |
| 22 | #define MSR_CLK_DUTY 0x0 |
| 23 | #define MSR_CLK_REG0 0x4 |
| 24 | #define MSR_CLK_REG1 0x8 |
| 25 | #define MSR_CLK_REG2 0xc |
| 26 | |
| 27 | #define MSR_DURATION GENMASK(15, 0) |
| 28 | #define MSR_ENABLE BIT(16) |
| 29 | #define MSR_CONT BIT(17) /* continuous measurement */ |
| 30 | #define MSR_INTR BIT(18) /* interrupts */ |
| 31 | #define MSR_RUN BIT(19) |
| 32 | #define MSR_CLK_SRC GENMASK(26, 20) |
| 33 | #define MSR_BUSY BIT(31) |
| 34 | |
| 35 | #define MSR_VAL_MASK GENMASK(15, 0) |
| 36 | |
| 37 | #define DIV_MIN 32 |
| 38 | #define DIV_STEP 32 |
| 39 | #define DIV_MAX 640 |
| 40 | |
| 41 | #define CLK_MSR_MAX 128 |
| 42 | |
| 43 | struct meson_msr_id { |
| 44 | unsigned int id; |
| 45 | const char *name; |
| 46 | }; |
| 47 | |
| 48 | struct meson_msr { |
| 49 | struct regmap *regmap; |
| 50 | struct meson_msr_id *msr_table; |
| 51 | }; |
| 52 | |
| 53 | #define CLK_MSR_ID(__id, __name) \ |
| 54 | [__id] = {.id = __id, .name = __name,} |
| 55 | |
| 56 | static struct meson_msr_id clk_msr_m8[CLK_MSR_MAX] = { |
| 57 | CLK_MSR_ID(0, "ring_osc_out_ee0"), |
| 58 | CLK_MSR_ID(1, "ring_osc_out_ee1"), |
| 59 | CLK_MSR_ID(2, "ring_osc_out_ee2"), |
| 60 | CLK_MSR_ID(3, "a9_ring_osck"), |
| 61 | CLK_MSR_ID(6, "vid_pll"), |
| 62 | CLK_MSR_ID(7, "clk81"), |
| 63 | CLK_MSR_ID(8, "encp"), |
| 64 | CLK_MSR_ID(9, "encl"), |
| 65 | CLK_MSR_ID(11, "eth_rmii"), |
| 66 | CLK_MSR_ID(13, "amclk"), |
| 67 | CLK_MSR_ID(14, "fec_clk_0"), |
| 68 | CLK_MSR_ID(15, "fec_clk_1"), |
| 69 | CLK_MSR_ID(16, "fec_clk_2"), |
| 70 | CLK_MSR_ID(18, "a9_clk_div16"), |
| 71 | CLK_MSR_ID(19, "hdmi_sys"), |
| 72 | CLK_MSR_ID(20, "rtc_osc_clk_out"), |
| 73 | CLK_MSR_ID(21, "i2s_clk_in_src0"), |
| 74 | CLK_MSR_ID(22, "clk_rmii_from_pad"), |
| 75 | CLK_MSR_ID(23, "hdmi_ch0_tmds"), |
| 76 | CLK_MSR_ID(24, "lvds_fifo"), |
| 77 | CLK_MSR_ID(26, "sc_clk_int"), |
| 78 | CLK_MSR_ID(28, "sar_adc"), |
| 79 | CLK_MSR_ID(30, "mpll_clk_test_out"), |
| 80 | CLK_MSR_ID(31, "audac_clkpi"), |
| 81 | CLK_MSR_ID(32, "vdac"), |
| 82 | CLK_MSR_ID(33, "sdhc_rx"), |
| 83 | CLK_MSR_ID(34, "sdhc_sd"), |
| 84 | CLK_MSR_ID(35, "mali"), |
| 85 | CLK_MSR_ID(36, "hdmi_tx_pixel"), |
| 86 | CLK_MSR_ID(38, "vdin_meas"), |
| 87 | CLK_MSR_ID(39, "pcm_sclk"), |
| 88 | CLK_MSR_ID(40, "pcm_mclk"), |
| 89 | CLK_MSR_ID(41, "eth_rx_tx"), |
| 90 | CLK_MSR_ID(42, "pwm_d"), |
| 91 | CLK_MSR_ID(43, "pwm_c"), |
| 92 | CLK_MSR_ID(44, "pwm_b"), |
| 93 | CLK_MSR_ID(45, "pwm_a"), |
| 94 | CLK_MSR_ID(46, "pcm2_sclk"), |
| 95 | CLK_MSR_ID(47, "ddr_dpll_pt"), |
| 96 | CLK_MSR_ID(48, "pwm_f"), |
| 97 | CLK_MSR_ID(49, "pwm_e"), |
| 98 | CLK_MSR_ID(59, "hcodec"), |
| 99 | CLK_MSR_ID(60, "usb_32k_alt"), |
| 100 | CLK_MSR_ID(61, "gpio"), |
| 101 | CLK_MSR_ID(62, "vid2_pll"), |
| 102 | CLK_MSR_ID(63, "mipi_csi_cfg"), |
| 103 | }; |
| 104 | |
| 105 | static struct meson_msr_id clk_msr_gx[CLK_MSR_MAX] = { |
| 106 | CLK_MSR_ID(0, "ring_osc_out_ee_0"), |
| 107 | CLK_MSR_ID(1, "ring_osc_out_ee_1"), |
| 108 | CLK_MSR_ID(2, "ring_osc_out_ee_2"), |
| 109 | CLK_MSR_ID(3, "a53_ring_osc"), |
| 110 | CLK_MSR_ID(4, "gp0_pll"), |
| 111 | CLK_MSR_ID(6, "enci"), |
| 112 | CLK_MSR_ID(7, "clk81"), |
| 113 | CLK_MSR_ID(8, "encp"), |
| 114 | CLK_MSR_ID(9, "encl"), |
| 115 | CLK_MSR_ID(10, "vdac"), |
| 116 | CLK_MSR_ID(11, "rgmii_tx"), |
| 117 | CLK_MSR_ID(12, "pdm"), |
| 118 | CLK_MSR_ID(13, "amclk"), |
| 119 | CLK_MSR_ID(14, "fec_0"), |
| 120 | CLK_MSR_ID(15, "fec_1"), |
| 121 | CLK_MSR_ID(16, "fec_2"), |
| 122 | CLK_MSR_ID(17, "sys_pll_div16"), |
| 123 | CLK_MSR_ID(18, "sys_cpu_div16"), |
| 124 | CLK_MSR_ID(19, "hdmitx_sys"), |
| 125 | CLK_MSR_ID(20, "rtc_osc_out"), |
| 126 | CLK_MSR_ID(21, "i2s_in_src0"), |
| 127 | CLK_MSR_ID(22, "eth_phy_ref"), |
| 128 | CLK_MSR_ID(23, "hdmi_todig"), |
| 129 | CLK_MSR_ID(26, "sc_int"), |
| 130 | CLK_MSR_ID(28, "sar_adc"), |
| 131 | CLK_MSR_ID(31, "mpll_test_out"), |
| 132 | CLK_MSR_ID(32, "vdec"), |
| 133 | CLK_MSR_ID(35, "mali"), |
| 134 | CLK_MSR_ID(36, "hdmi_tx_pixel"), |
| 135 | CLK_MSR_ID(37, "i958"), |
| 136 | CLK_MSR_ID(38, "vdin_meas"), |
| 137 | CLK_MSR_ID(39, "pcm_sclk"), |
| 138 | CLK_MSR_ID(40, "pcm_mclk"), |
| 139 | CLK_MSR_ID(41, "eth_rx_or_rmii"), |
| 140 | CLK_MSR_ID(42, "mp0_out"), |
| 141 | CLK_MSR_ID(43, "fclk_div5"), |
| 142 | CLK_MSR_ID(44, "pwm_b"), |
| 143 | CLK_MSR_ID(45, "pwm_a"), |
| 144 | CLK_MSR_ID(46, "vpu"), |
| 145 | CLK_MSR_ID(47, "ddr_dpll_pt"), |
| 146 | CLK_MSR_ID(48, "mp1_out"), |
| 147 | CLK_MSR_ID(49, "mp2_out"), |
| 148 | CLK_MSR_ID(50, "mp3_out"), |
| 149 | CLK_MSR_ID(51, "nand_core"), |
| 150 | CLK_MSR_ID(52, "sd_emmc_b"), |
| 151 | CLK_MSR_ID(53, "sd_emmc_a"), |
| 152 | CLK_MSR_ID(55, "vid_pll_div_out"), |
| 153 | CLK_MSR_ID(56, "cci"), |
| 154 | CLK_MSR_ID(57, "wave420l_c"), |
| 155 | CLK_MSR_ID(58, "wave420l_b"), |
| 156 | CLK_MSR_ID(59, "hcodec"), |
| 157 | CLK_MSR_ID(60, "alt_32k"), |
| 158 | CLK_MSR_ID(61, "gpio_msr"), |
| 159 | CLK_MSR_ID(62, "hevc"), |
| 160 | CLK_MSR_ID(66, "vid_lock"), |
| 161 | CLK_MSR_ID(70, "pwm_f"), |
| 162 | CLK_MSR_ID(71, "pwm_e"), |
| 163 | CLK_MSR_ID(72, "pwm_d"), |
| 164 | CLK_MSR_ID(73, "pwm_c"), |
| 165 | CLK_MSR_ID(75, "aoclkx2_int"), |
| 166 | CLK_MSR_ID(76, "aoclk_int"), |
| 167 | CLK_MSR_ID(77, "rng_ring_osc_0"), |
| 168 | CLK_MSR_ID(78, "rng_ring_osc_1"), |
| 169 | CLK_MSR_ID(79, "rng_ring_osc_2"), |
| 170 | CLK_MSR_ID(80, "rng_ring_osc_3"), |
| 171 | CLK_MSR_ID(81, "vapb"), |
| 172 | CLK_MSR_ID(82, "ge2d"), |
| 173 | }; |
| 174 | |
| 175 | static struct meson_msr_id clk_msr_axg[CLK_MSR_MAX] = { |
| 176 | CLK_MSR_ID(0, "ring_osc_out_ee_0"), |
| 177 | CLK_MSR_ID(1, "ring_osc_out_ee_1"), |
| 178 | CLK_MSR_ID(2, "ring_osc_out_ee_2"), |
| 179 | CLK_MSR_ID(3, "a53_ring_osc"), |
| 180 | CLK_MSR_ID(4, "gp0_pll"), |
| 181 | CLK_MSR_ID(5, "gp1_pll"), |
| 182 | CLK_MSR_ID(7, "clk81"), |
| 183 | CLK_MSR_ID(9, "encl"), |
| 184 | CLK_MSR_ID(17, "sys_pll_div16"), |
| 185 | CLK_MSR_ID(18, "sys_cpu_div16"), |
| 186 | CLK_MSR_ID(20, "rtc_osc_out"), |
| 187 | CLK_MSR_ID(23, "mmc_clk"), |
| 188 | CLK_MSR_ID(28, "sar_adc"), |
| 189 | CLK_MSR_ID(31, "mpll_test_out"), |
| 190 | CLK_MSR_ID(40, "mod_eth_tx_clk"), |
| 191 | CLK_MSR_ID(41, "mod_eth_rx_clk_rmii"), |
| 192 | CLK_MSR_ID(42, "mp0_out"), |
| 193 | CLK_MSR_ID(43, "fclk_div5"), |
| 194 | CLK_MSR_ID(44, "pwm_b"), |
| 195 | CLK_MSR_ID(45, "pwm_a"), |
| 196 | CLK_MSR_ID(46, "vpu"), |
| 197 | CLK_MSR_ID(47, "ddr_dpll_pt"), |
| 198 | CLK_MSR_ID(48, "mp1_out"), |
| 199 | CLK_MSR_ID(49, "mp2_out"), |
| 200 | CLK_MSR_ID(50, "mp3_out"), |
| 201 | CLK_MSR_ID(51, "sd_emmm_c"), |
| 202 | CLK_MSR_ID(52, "sd_emmc_b"), |
| 203 | CLK_MSR_ID(61, "gpio_msr"), |
| 204 | CLK_MSR_ID(66, "audio_slv_lrclk_c"), |
| 205 | CLK_MSR_ID(67, "audio_slv_lrclk_b"), |
| 206 | CLK_MSR_ID(68, "audio_slv_lrclk_a"), |
| 207 | CLK_MSR_ID(69, "audio_slv_sclk_c"), |
| 208 | CLK_MSR_ID(70, "audio_slv_sclk_b"), |
| 209 | CLK_MSR_ID(71, "audio_slv_sclk_a"), |
| 210 | CLK_MSR_ID(72, "pwm_d"), |
| 211 | CLK_MSR_ID(73, "pwm_c"), |
| 212 | CLK_MSR_ID(74, "wifi_beacon"), |
| 213 | CLK_MSR_ID(75, "tdmin_lb_lrcl"), |
| 214 | CLK_MSR_ID(76, "tdmin_lb_sclk"), |
| 215 | CLK_MSR_ID(77, "rng_ring_osc_0"), |
| 216 | CLK_MSR_ID(78, "rng_ring_osc_1"), |
| 217 | CLK_MSR_ID(79, "rng_ring_osc_2"), |
| 218 | CLK_MSR_ID(80, "rng_ring_osc_3"), |
| 219 | CLK_MSR_ID(81, "vapb"), |
| 220 | CLK_MSR_ID(82, "ge2d"), |
| 221 | CLK_MSR_ID(84, "audio_resample"), |
| 222 | CLK_MSR_ID(85, "audio_pdm_sys"), |
| 223 | CLK_MSR_ID(86, "audio_spdifout"), |
| 224 | CLK_MSR_ID(87, "audio_spdifin"), |
| 225 | CLK_MSR_ID(88, "audio_lrclk_f"), |
| 226 | CLK_MSR_ID(89, "audio_lrclk_e"), |
| 227 | CLK_MSR_ID(90, "audio_lrclk_d"), |
| 228 | CLK_MSR_ID(91, "audio_lrclk_c"), |
| 229 | CLK_MSR_ID(92, "audio_lrclk_b"), |
| 230 | CLK_MSR_ID(93, "audio_lrclk_a"), |
| 231 | CLK_MSR_ID(94, "audio_sclk_f"), |
| 232 | CLK_MSR_ID(95, "audio_sclk_e"), |
| 233 | CLK_MSR_ID(96, "audio_sclk_d"), |
| 234 | CLK_MSR_ID(97, "audio_sclk_c"), |
| 235 | CLK_MSR_ID(98, "audio_sclk_b"), |
| 236 | CLK_MSR_ID(99, "audio_sclk_a"), |
| 237 | CLK_MSR_ID(100, "audio_mclk_f"), |
| 238 | CLK_MSR_ID(101, "audio_mclk_e"), |
| 239 | CLK_MSR_ID(102, "audio_mclk_d"), |
| 240 | CLK_MSR_ID(103, "audio_mclk_c"), |
| 241 | CLK_MSR_ID(104, "audio_mclk_b"), |
| 242 | CLK_MSR_ID(105, "audio_mclk_a"), |
| 243 | CLK_MSR_ID(106, "pcie_refclk_n"), |
| 244 | CLK_MSR_ID(107, "pcie_refclk_p"), |
| 245 | CLK_MSR_ID(108, "audio_locker_out"), |
| 246 | CLK_MSR_ID(109, "audio_locker_in"), |
| 247 | }; |
| 248 | |
| 249 | static struct meson_msr_id clk_msr_g12a[CLK_MSR_MAX] = { |
| 250 | CLK_MSR_ID(0, "ring_osc_out_ee_0"), |
| 251 | CLK_MSR_ID(1, "ring_osc_out_ee_1"), |
| 252 | CLK_MSR_ID(2, "ring_osc_out_ee_2"), |
| 253 | CLK_MSR_ID(3, "sys_cpu_ring_osc"), |
| 254 | CLK_MSR_ID(4, "gp0_pll"), |
| 255 | CLK_MSR_ID(6, "enci"), |
| 256 | CLK_MSR_ID(7, "clk81"), |
| 257 | CLK_MSR_ID(8, "encp"), |
| 258 | CLK_MSR_ID(9, "encl"), |
| 259 | CLK_MSR_ID(10, "vdac"), |
| 260 | CLK_MSR_ID(11, "eth_tx"), |
| 261 | CLK_MSR_ID(12, "hifi_pll"), |
| 262 | CLK_MSR_ID(13, "mod_tcon"), |
| 263 | CLK_MSR_ID(14, "fec_0"), |
| 264 | CLK_MSR_ID(15, "fec_1"), |
| 265 | CLK_MSR_ID(16, "fec_2"), |
| 266 | CLK_MSR_ID(17, "sys_pll_div16"), |
| 267 | CLK_MSR_ID(18, "sys_cpu_div16"), |
| 268 | CLK_MSR_ID(19, "lcd_an_ph2"), |
| 269 | CLK_MSR_ID(20, "rtc_osc_out"), |
| 270 | CLK_MSR_ID(21, "lcd_an_ph3"), |
| 271 | CLK_MSR_ID(22, "eth_phy_ref"), |
| 272 | CLK_MSR_ID(23, "mpll_50m"), |
| 273 | CLK_MSR_ID(24, "eth_125m"), |
| 274 | CLK_MSR_ID(25, "eth_rmii"), |
| 275 | CLK_MSR_ID(26, "sc_int"), |
| 276 | CLK_MSR_ID(27, "in_mac"), |
| 277 | CLK_MSR_ID(28, "sar_adc"), |
| 278 | CLK_MSR_ID(29, "pcie_inp"), |
| 279 | CLK_MSR_ID(30, "pcie_inn"), |
| 280 | CLK_MSR_ID(31, "mpll_test_out"), |
| 281 | CLK_MSR_ID(32, "vdec"), |
| 282 | CLK_MSR_ID(33, "sys_cpu_ring_osc_1"), |
| 283 | CLK_MSR_ID(34, "eth_mpll_50m"), |
| 284 | CLK_MSR_ID(35, "mali"), |
| 285 | CLK_MSR_ID(36, "hdmi_tx_pixel"), |
| 286 | CLK_MSR_ID(37, "cdac"), |
| 287 | CLK_MSR_ID(38, "vdin_meas"), |
| 288 | CLK_MSR_ID(39, "bt656"), |
| 289 | CLK_MSR_ID(41, "eth_rx_or_rmii"), |
| 290 | CLK_MSR_ID(42, "mp0_out"), |
| 291 | CLK_MSR_ID(43, "fclk_div5"), |
| 292 | CLK_MSR_ID(44, "pwm_b"), |
| 293 | CLK_MSR_ID(45, "pwm_a"), |
| 294 | CLK_MSR_ID(46, "vpu"), |
| 295 | CLK_MSR_ID(47, "ddr_dpll_pt"), |
| 296 | CLK_MSR_ID(48, "mp1_out"), |
| 297 | CLK_MSR_ID(49, "mp2_out"), |
| 298 | CLK_MSR_ID(50, "mp3_out"), |
| 299 | CLK_MSR_ID(51, "sd_emmc_c"), |
| 300 | CLK_MSR_ID(52, "sd_emmc_b"), |
| 301 | CLK_MSR_ID(53, "sd_emmc_a"), |
| 302 | CLK_MSR_ID(54, "vpu_clkc"), |
| 303 | CLK_MSR_ID(55, "vid_pll_div_out"), |
| 304 | CLK_MSR_ID(56, "wave420l_a"), |
| 305 | CLK_MSR_ID(57, "wave420l_c"), |
| 306 | CLK_MSR_ID(58, "wave420l_b"), |
| 307 | CLK_MSR_ID(59, "hcodec"), |
| 308 | CLK_MSR_ID(61, "gpio_msr"), |
| 309 | CLK_MSR_ID(62, "hevcb"), |
| 310 | CLK_MSR_ID(63, "dsi_meas"), |
| 311 | CLK_MSR_ID(64, "spicc_1"), |
| 312 | CLK_MSR_ID(65, "spicc_0"), |
| 313 | CLK_MSR_ID(66, "vid_lock"), |
| 314 | CLK_MSR_ID(67, "dsi_phy"), |
| 315 | CLK_MSR_ID(68, "hdcp22_esm"), |
| 316 | CLK_MSR_ID(69, "hdcp22_skp"), |
| 317 | CLK_MSR_ID(70, "pwm_f"), |
| 318 | CLK_MSR_ID(71, "pwm_e"), |
| 319 | CLK_MSR_ID(72, "pwm_d"), |
| 320 | CLK_MSR_ID(73, "pwm_c"), |
| 321 | CLK_MSR_ID(75, "hevcf"), |
| 322 | CLK_MSR_ID(77, "rng_ring_osc_0"), |
| 323 | CLK_MSR_ID(78, "rng_ring_osc_1"), |
| 324 | CLK_MSR_ID(79, "rng_ring_osc_2"), |
| 325 | CLK_MSR_ID(80, "rng_ring_osc_3"), |
| 326 | CLK_MSR_ID(81, "vapb"), |
| 327 | CLK_MSR_ID(82, "ge2d"), |
| 328 | CLK_MSR_ID(83, "co_rx"), |
| 329 | CLK_MSR_ID(84, "co_tx"), |
| 330 | CLK_MSR_ID(89, "hdmi_todig"), |
| 331 | CLK_MSR_ID(90, "hdmitx_sys"), |
| 332 | CLK_MSR_ID(91, "sys_cpub_div16"), |
| 333 | CLK_MSR_ID(92, "sys_pll_cpub_div16"), |
| 334 | CLK_MSR_ID(94, "eth_phy_rx"), |
| 335 | CLK_MSR_ID(95, "eth_phy_pll"), |
| 336 | CLK_MSR_ID(96, "vpu_b"), |
| 337 | CLK_MSR_ID(97, "cpu_b_tmp"), |
| 338 | CLK_MSR_ID(98, "ts"), |
| 339 | CLK_MSR_ID(99, "ring_osc_out_ee_3"), |
| 340 | CLK_MSR_ID(100, "ring_osc_out_ee_4"), |
| 341 | CLK_MSR_ID(101, "ring_osc_out_ee_5"), |
| 342 | CLK_MSR_ID(102, "ring_osc_out_ee_6"), |
| 343 | CLK_MSR_ID(103, "ring_osc_out_ee_7"), |
| 344 | CLK_MSR_ID(104, "ring_osc_out_ee_8"), |
| 345 | CLK_MSR_ID(105, "ring_osc_out_ee_9"), |
| 346 | CLK_MSR_ID(106, "ephy_test"), |
| 347 | CLK_MSR_ID(107, "au_dac_g128x"), |
| 348 | CLK_MSR_ID(108, "audio_locker_out"), |
| 349 | CLK_MSR_ID(109, "audio_locker_in"), |
| 350 | CLK_MSR_ID(110, "audio_tdmout_c_sclk"), |
| 351 | CLK_MSR_ID(111, "audio_tdmout_b_sclk"), |
| 352 | CLK_MSR_ID(112, "audio_tdmout_a_sclk"), |
| 353 | CLK_MSR_ID(113, "audio_tdmin_lb_sclk"), |
| 354 | CLK_MSR_ID(114, "audio_tdmin_c_sclk"), |
| 355 | CLK_MSR_ID(115, "audio_tdmin_b_sclk"), |
| 356 | CLK_MSR_ID(116, "audio_tdmin_a_sclk"), |
| 357 | CLK_MSR_ID(117, "audio_resample"), |
| 358 | CLK_MSR_ID(118, "audio_pdm_sys"), |
| 359 | CLK_MSR_ID(119, "audio_spdifout_b"), |
| 360 | CLK_MSR_ID(120, "audio_spdifout"), |
| 361 | CLK_MSR_ID(121, "audio_spdifin"), |
| 362 | CLK_MSR_ID(122, "audio_pdm_dclk"), |
| 363 | }; |
| 364 | |
| 365 | static struct meson_msr_id clk_msr_sm1[CLK_MSR_MAX] = { |
| 366 | CLK_MSR_ID(0, "ring_osc_out_ee_0"), |
| 367 | CLK_MSR_ID(1, "ring_osc_out_ee_1"), |
| 368 | CLK_MSR_ID(2, "ring_osc_out_ee_2"), |
| 369 | CLK_MSR_ID(3, "ring_osc_out_ee_3"), |
| 370 | CLK_MSR_ID(4, "gp0_pll"), |
| 371 | CLK_MSR_ID(5, "gp1_pll"), |
| 372 | CLK_MSR_ID(6, "enci"), |
| 373 | CLK_MSR_ID(7, "clk81"), |
| 374 | CLK_MSR_ID(8, "encp"), |
| 375 | CLK_MSR_ID(9, "encl"), |
| 376 | CLK_MSR_ID(10, "vdac"), |
| 377 | CLK_MSR_ID(11, "eth_tx"), |
| 378 | CLK_MSR_ID(12, "hifi_pll"), |
| 379 | CLK_MSR_ID(13, "mod_tcon"), |
| 380 | CLK_MSR_ID(14, "fec_0"), |
| 381 | CLK_MSR_ID(15, "fec_1"), |
| 382 | CLK_MSR_ID(16, "fec_2"), |
| 383 | CLK_MSR_ID(17, "sys_pll_div16"), |
| 384 | CLK_MSR_ID(18, "sys_cpu_div16"), |
| 385 | CLK_MSR_ID(19, "lcd_an_ph2"), |
| 386 | CLK_MSR_ID(20, "rtc_osc_out"), |
| 387 | CLK_MSR_ID(21, "lcd_an_ph3"), |
| 388 | CLK_MSR_ID(22, "eth_phy_ref"), |
| 389 | CLK_MSR_ID(23, "mpll_50m"), |
| 390 | CLK_MSR_ID(24, "eth_125m"), |
| 391 | CLK_MSR_ID(25, "eth_rmii"), |
| 392 | CLK_MSR_ID(26, "sc_int"), |
| 393 | CLK_MSR_ID(27, "in_mac"), |
| 394 | CLK_MSR_ID(28, "sar_adc"), |
| 395 | CLK_MSR_ID(29, "pcie_inp"), |
| 396 | CLK_MSR_ID(30, "pcie_inn"), |
| 397 | CLK_MSR_ID(31, "mpll_test_out"), |
| 398 | CLK_MSR_ID(32, "vdec"), |
| 399 | CLK_MSR_ID(34, "eth_mpll_50m"), |
| 400 | CLK_MSR_ID(35, "mali"), |
| 401 | CLK_MSR_ID(36, "hdmi_tx_pixel"), |
| 402 | CLK_MSR_ID(37, "cdac"), |
| 403 | CLK_MSR_ID(38, "vdin_meas"), |
| 404 | CLK_MSR_ID(39, "bt656"), |
| 405 | CLK_MSR_ID(40, "arm_ring_osc_out_4"), |
| 406 | CLK_MSR_ID(41, "eth_rx_or_rmii"), |
| 407 | CLK_MSR_ID(42, "mp0_out"), |
| 408 | CLK_MSR_ID(43, "fclk_div5"), |
| 409 | CLK_MSR_ID(44, "pwm_b"), |
| 410 | CLK_MSR_ID(45, "pwm_a"), |
| 411 | CLK_MSR_ID(46, "vpu"), |
| 412 | CLK_MSR_ID(47, "ddr_dpll_pt"), |
| 413 | CLK_MSR_ID(48, "mp1_out"), |
| 414 | CLK_MSR_ID(49, "mp2_out"), |
| 415 | CLK_MSR_ID(50, "mp3_out"), |
| 416 | CLK_MSR_ID(51, "sd_emmc_c"), |
| 417 | CLK_MSR_ID(52, "sd_emmc_b"), |
| 418 | CLK_MSR_ID(53, "sd_emmc_a"), |
| 419 | CLK_MSR_ID(54, "vpu_clkc"), |
| 420 | CLK_MSR_ID(55, "vid_pll_div_out"), |
| 421 | CLK_MSR_ID(56, "wave420l_a"), |
| 422 | CLK_MSR_ID(57, "wave420l_c"), |
| 423 | CLK_MSR_ID(58, "wave420l_b"), |
| 424 | CLK_MSR_ID(59, "hcodec"), |
| 425 | CLK_MSR_ID(60, "arm_ring_osc_out_5"), |
| 426 | CLK_MSR_ID(61, "gpio_msr"), |
| 427 | CLK_MSR_ID(62, "hevcb"), |
| 428 | CLK_MSR_ID(63, "dsi_meas"), |
| 429 | CLK_MSR_ID(64, "spicc_1"), |
| 430 | CLK_MSR_ID(65, "spicc_0"), |
| 431 | CLK_MSR_ID(66, "vid_lock"), |
| 432 | CLK_MSR_ID(67, "dsi_phy"), |
| 433 | CLK_MSR_ID(68, "hdcp22_esm"), |
| 434 | CLK_MSR_ID(69, "hdcp22_skp"), |
| 435 | CLK_MSR_ID(70, "pwm_f"), |
| 436 | CLK_MSR_ID(71, "pwm_e"), |
| 437 | CLK_MSR_ID(72, "pwm_d"), |
| 438 | CLK_MSR_ID(73, "pwm_c"), |
| 439 | CLK_MSR_ID(74, "arm_ring_osc_out_6"), |
| 440 | CLK_MSR_ID(75, "hevcf"), |
| 441 | CLK_MSR_ID(76, "arm_ring_osc_out_7"), |
| 442 | CLK_MSR_ID(77, "rng_ring_osc_0"), |
| 443 | CLK_MSR_ID(78, "rng_ring_osc_1"), |
| 444 | CLK_MSR_ID(79, "rng_ring_osc_2"), |
| 445 | CLK_MSR_ID(80, "rng_ring_osc_3"), |
| 446 | CLK_MSR_ID(81, "vapb"), |
| 447 | CLK_MSR_ID(82, "ge2d"), |
| 448 | CLK_MSR_ID(83, "co_rx"), |
| 449 | CLK_MSR_ID(84, "co_tx"), |
| 450 | CLK_MSR_ID(85, "arm_ring_osc_out_8"), |
| 451 | CLK_MSR_ID(86, "arm_ring_osc_out_9"), |
| 452 | CLK_MSR_ID(87, "mipi_dsi_phy"), |
| 453 | CLK_MSR_ID(88, "cis2_adapt"), |
| 454 | CLK_MSR_ID(89, "hdmi_todig"), |
| 455 | CLK_MSR_ID(90, "hdmitx_sys"), |
| 456 | CLK_MSR_ID(91, "nna_core"), |
| 457 | CLK_MSR_ID(92, "nna_axi"), |
| 458 | CLK_MSR_ID(93, "vad"), |
| 459 | CLK_MSR_ID(94, "eth_phy_rx"), |
| 460 | CLK_MSR_ID(95, "eth_phy_pll"), |
| 461 | CLK_MSR_ID(96, "vpu_b"), |
| 462 | CLK_MSR_ID(97, "cpu_b_tmp"), |
| 463 | CLK_MSR_ID(98, "ts"), |
| 464 | CLK_MSR_ID(99, "arm_ring_osc_out_10"), |
| 465 | CLK_MSR_ID(100, "arm_ring_osc_out_11"), |
| 466 | CLK_MSR_ID(101, "arm_ring_osc_out_12"), |
| 467 | CLK_MSR_ID(102, "arm_ring_osc_out_13"), |
| 468 | CLK_MSR_ID(103, "arm_ring_osc_out_14"), |
| 469 | CLK_MSR_ID(104, "arm_ring_osc_out_15"), |
| 470 | CLK_MSR_ID(105, "arm_ring_osc_out_16"), |
| 471 | CLK_MSR_ID(106, "ephy_test"), |
| 472 | CLK_MSR_ID(107, "au_dac_g128x"), |
| 473 | CLK_MSR_ID(108, "audio_locker_out"), |
| 474 | CLK_MSR_ID(109, "audio_locker_in"), |
| 475 | CLK_MSR_ID(110, "audio_tdmout_c_sclk"), |
| 476 | CLK_MSR_ID(111, "audio_tdmout_b_sclk"), |
| 477 | CLK_MSR_ID(112, "audio_tdmout_a_sclk"), |
| 478 | CLK_MSR_ID(113, "audio_tdmin_lb_sclk"), |
| 479 | CLK_MSR_ID(114, "audio_tdmin_c_sclk"), |
| 480 | CLK_MSR_ID(115, "audio_tdmin_b_sclk"), |
| 481 | CLK_MSR_ID(116, "audio_tdmin_a_sclk"), |
| 482 | CLK_MSR_ID(117, "audio_resample"), |
| 483 | CLK_MSR_ID(118, "audio_pdm_sys"), |
| 484 | CLK_MSR_ID(119, "audio_spdifout_b"), |
| 485 | CLK_MSR_ID(120, "audio_spdifout"), |
| 486 | CLK_MSR_ID(121, "audio_spdifin"), |
| 487 | CLK_MSR_ID(122, "audio_pdm_dclk"), |
| 488 | CLK_MSR_ID(123, "audio_resampled"), |
| 489 | CLK_MSR_ID(124, "earcrx_pll"), |
| 490 | CLK_MSR_ID(125, "earcrx_pll_test"), |
| 491 | CLK_MSR_ID(126, "csi_phy0"), |
| 492 | CLK_MSR_ID(127, "csi2_data"), |
| 493 | }; |
| 494 | |
| 495 | static int meson_clk_msr_measure_id(struct meson_msr *priv, unsigned int id, |
| 496 | unsigned int duration) |
| 497 | { |
| 498 | unsigned int val; |
| 499 | int ret; |
| 500 | |
| 501 | regmap_write(priv->regmap, MSR_CLK_REG0, 0); |
| 502 | |
| 503 | /* Set measurement duration */ |
| 504 | regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_DURATION, |
| 505 | FIELD_PREP(MSR_DURATION, duration - 1)); |
| 506 | |
| 507 | /* Set ID */ |
| 508 | regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_CLK_SRC, |
| 509 | FIELD_PREP(MSR_CLK_SRC, id)); |
| 510 | |
| 511 | /* Enable & Start */ |
| 512 | regmap_update_bits(priv->regmap, MSR_CLK_REG0, |
| 513 | MSR_RUN | MSR_ENABLE, |
| 514 | MSR_RUN | MSR_ENABLE); |
| 515 | |
| 516 | ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0, |
| 517 | val, !(val & MSR_BUSY), 10, 10000); |
| 518 | if (ret) |
| 519 | return ret; |
| 520 | |
| 521 | /* Disable */ |
| 522 | regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0); |
| 523 | |
| 524 | /* Get the value in multiple of gate time counts */ |
| 525 | regmap_read(priv->regmap, MSR_CLK_REG2, &val); |
| 526 | |
| 527 | if (val >= MSR_VAL_MASK) |
| 528 | return -EINVAL; |
| 529 | |
| 530 | return DIV_ROUND_CLOSEST_ULL((val & MSR_VAL_MASK) * 1000000ULL, |
| 531 | duration); |
| 532 | } |
| 533 | |
| 534 | static int meson_clk_msr_best_id(struct meson_msr *priv, unsigned int id, |
| 535 | unsigned int *precision) |
| 536 | { |
| 537 | unsigned int duration = DIV_MAX; |
| 538 | int ret; |
| 539 | |
| 540 | /* Start from max duration and down to min duration */ |
| 541 | do { |
| 542 | ret = meson_clk_msr_measure_id(priv, id, duration); |
| 543 | if (ret >= 0) |
| 544 | *precision = (2 * 1000000) / duration; |
| 545 | else |
| 546 | duration -= DIV_STEP; |
| 547 | } while (duration >= DIV_MIN && ret == -EINVAL); |
| 548 | |
| 549 | return ret; |
| 550 | } |
| 551 | |
| 552 | static void meson_clk_msr_dump(struct udevice *dev) |
| 553 | { |
| 554 | struct meson_msr *priv = dev_get_priv(dev); |
| 555 | unsigned int precision = 0; |
| 556 | int val, i; |
| 557 | |
| 558 | printf(" clock rate precision\n"); |
| 559 | printf("---------------------------------------------\n"); |
| 560 | |
| 561 | for (i = 0 ; i < CLK_MSR_MAX ; ++i) { |
| 562 | if (!priv->msr_table[i].name) |
| 563 | continue; |
| 564 | |
| 565 | val = meson_clk_msr_best_id(priv, i, &precision); |
| 566 | if (val < 0) |
| 567 | return; |
| 568 | |
| 569 | printf(" %-20s %10d +/-%dHz\n", |
| 570 | priv->msr_table[i].name, val, precision); |
| 571 | } |
| 572 | } |
| 573 | |
| 574 | static int meson_clk_msr_xlate(struct clk *clk, struct ofnode_phandle_args *args) |
| 575 | { |
| 576 | /* This driver doesn't expose any clocks */ |
| 577 | return -EINVAL; |
| 578 | } |
| 579 | |
| 580 | static int meson_clk_msr_probe(struct udevice *dev) |
| 581 | { |
| 582 | struct meson_msr *priv = dev_get_priv(dev); |
| 583 | int ret; |
| 584 | |
| 585 | priv->msr_table = (struct meson_msr_id *)dev_get_driver_data(dev); |
| 586 | |
| 587 | ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap); |
| 588 | if (ret) |
| 589 | return ret; |
| 590 | |
| 591 | return 0; |
| 592 | } |
| 593 | |
| 594 | static struct clk_ops meson_clk_msr_ops = { |
| 595 | .of_xlate = meson_clk_msr_xlate, |
| 596 | .dump = meson_clk_msr_dump, |
| 597 | }; |
| 598 | |
| 599 | static const struct udevice_id meson_clk_msr_ids[] = { |
| 600 | { |
| 601 | .compatible = "amlogic,meson-gx-clk-measure", |
| 602 | .data = (ulong)clk_msr_gx, |
| 603 | }, |
| 604 | { |
| 605 | .compatible = "amlogic,meson8-clk-measure", |
| 606 | .data = (ulong)clk_msr_m8, |
| 607 | }, |
| 608 | { |
| 609 | .compatible = "amlogic,meson8b-clk-measure", |
| 610 | .data = (ulong)clk_msr_m8, |
| 611 | }, |
| 612 | { |
| 613 | .compatible = "amlogic,meson-axg-clk-measure", |
| 614 | .data = (ulong)clk_msr_axg, |
| 615 | }, |
| 616 | { |
| 617 | .compatible = "amlogic,meson-g12a-clk-measure", |
| 618 | .data = (ulong)clk_msr_g12a, |
| 619 | }, |
| 620 | { |
| 621 | .compatible = "amlogic,meson-sm1-clk-measure", |
| 622 | .data = (ulong)clk_msr_sm1, |
| 623 | }, |
| 624 | { /* sentinel */ } |
| 625 | }; |
| 626 | |
| 627 | U_BOOT_DRIVER(meson_clk_msr) = { |
| 628 | .name = "meson_clk_msr", |
| 629 | .id = UCLASS_CLK, |
| 630 | .of_match = meson_clk_msr_ids, |
| 631 | .priv_auto = sizeof(struct meson_msr), |
| 632 | .ops = &meson_clk_msr_ops, |
| 633 | .probe = meson_clk_msr_probe, |
| 634 | }; |