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