0001
0002
0003
0004
0005
0006
0007 #include <linux/of_address.h>
0008 #include <linux/platform_device.h>
0009 #include <linux/bitfield.h>
0010 #include <linux/seq_file.h>
0011 #include <linux/debugfs.h>
0012 #include <linux/regmap.h>
0013 #include <linux/module.h>
0014
0015 static DEFINE_MUTEX(measure_lock);
0016
0017 #define MSR_CLK_DUTY 0x0
0018 #define MSR_CLK_REG0 0x4
0019 #define MSR_CLK_REG1 0x8
0020 #define MSR_CLK_REG2 0xc
0021
0022 #define MSR_DURATION GENMASK(15, 0)
0023 #define MSR_ENABLE BIT(16)
0024 #define MSR_CONT BIT(17)
0025 #define MSR_INTR BIT(18)
0026 #define MSR_RUN BIT(19)
0027 #define MSR_CLK_SRC GENMASK(26, 20)
0028 #define MSR_BUSY BIT(31)
0029
0030 #define MSR_VAL_MASK GENMASK(15, 0)
0031
0032 #define DIV_MIN 32
0033 #define DIV_STEP 32
0034 #define DIV_MAX 640
0035
0036 #define CLK_MSR_MAX 128
0037
0038 struct meson_msr_id {
0039 struct meson_msr *priv;
0040 unsigned int id;
0041 const char *name;
0042 };
0043
0044 struct meson_msr {
0045 struct regmap *regmap;
0046 struct meson_msr_id msr_table[CLK_MSR_MAX];
0047 };
0048
0049 #define CLK_MSR_ID(__id, __name) \
0050 [__id] = {.id = __id, .name = __name,}
0051
0052 static struct meson_msr_id clk_msr_m8[CLK_MSR_MAX] = {
0053 CLK_MSR_ID(0, "ring_osc_out_ee0"),
0054 CLK_MSR_ID(1, "ring_osc_out_ee1"),
0055 CLK_MSR_ID(2, "ring_osc_out_ee2"),
0056 CLK_MSR_ID(3, "a9_ring_osck"),
0057 CLK_MSR_ID(6, "vid_pll"),
0058 CLK_MSR_ID(7, "clk81"),
0059 CLK_MSR_ID(8, "encp"),
0060 CLK_MSR_ID(9, "encl"),
0061 CLK_MSR_ID(11, "eth_rmii"),
0062 CLK_MSR_ID(13, "amclk"),
0063 CLK_MSR_ID(14, "fec_clk_0"),
0064 CLK_MSR_ID(15, "fec_clk_1"),
0065 CLK_MSR_ID(16, "fec_clk_2"),
0066 CLK_MSR_ID(18, "a9_clk_div16"),
0067 CLK_MSR_ID(19, "hdmi_sys"),
0068 CLK_MSR_ID(20, "rtc_osc_clk_out"),
0069 CLK_MSR_ID(21, "i2s_clk_in_src0"),
0070 CLK_MSR_ID(22, "clk_rmii_from_pad"),
0071 CLK_MSR_ID(23, "hdmi_ch0_tmds"),
0072 CLK_MSR_ID(24, "lvds_fifo"),
0073 CLK_MSR_ID(26, "sc_clk_int"),
0074 CLK_MSR_ID(28, "sar_adc"),
0075 CLK_MSR_ID(30, "mpll_clk_test_out"),
0076 CLK_MSR_ID(31, "audac_clkpi"),
0077 CLK_MSR_ID(32, "vdac"),
0078 CLK_MSR_ID(33, "sdhc_rx"),
0079 CLK_MSR_ID(34, "sdhc_sd"),
0080 CLK_MSR_ID(35, "mali"),
0081 CLK_MSR_ID(36, "hdmi_tx_pixel"),
0082 CLK_MSR_ID(38, "vdin_meas"),
0083 CLK_MSR_ID(39, "pcm_sclk"),
0084 CLK_MSR_ID(40, "pcm_mclk"),
0085 CLK_MSR_ID(41, "eth_rx_tx"),
0086 CLK_MSR_ID(42, "pwm_d"),
0087 CLK_MSR_ID(43, "pwm_c"),
0088 CLK_MSR_ID(44, "pwm_b"),
0089 CLK_MSR_ID(45, "pwm_a"),
0090 CLK_MSR_ID(46, "pcm2_sclk"),
0091 CLK_MSR_ID(47, "ddr_dpll_pt"),
0092 CLK_MSR_ID(48, "pwm_f"),
0093 CLK_MSR_ID(49, "pwm_e"),
0094 CLK_MSR_ID(59, "hcodec"),
0095 CLK_MSR_ID(60, "usb_32k_alt"),
0096 CLK_MSR_ID(61, "gpio"),
0097 CLK_MSR_ID(62, "vid2_pll"),
0098 CLK_MSR_ID(63, "mipi_csi_cfg"),
0099 };
0100
0101 static struct meson_msr_id clk_msr_gx[CLK_MSR_MAX] = {
0102 CLK_MSR_ID(0, "ring_osc_out_ee_0"),
0103 CLK_MSR_ID(1, "ring_osc_out_ee_1"),
0104 CLK_MSR_ID(2, "ring_osc_out_ee_2"),
0105 CLK_MSR_ID(3, "a53_ring_osc"),
0106 CLK_MSR_ID(4, "gp0_pll"),
0107 CLK_MSR_ID(6, "enci"),
0108 CLK_MSR_ID(7, "clk81"),
0109 CLK_MSR_ID(8, "encp"),
0110 CLK_MSR_ID(9, "encl"),
0111 CLK_MSR_ID(10, "vdac"),
0112 CLK_MSR_ID(11, "rgmii_tx"),
0113 CLK_MSR_ID(12, "pdm"),
0114 CLK_MSR_ID(13, "amclk"),
0115 CLK_MSR_ID(14, "fec_0"),
0116 CLK_MSR_ID(15, "fec_1"),
0117 CLK_MSR_ID(16, "fec_2"),
0118 CLK_MSR_ID(17, "sys_pll_div16"),
0119 CLK_MSR_ID(18, "sys_cpu_div16"),
0120 CLK_MSR_ID(19, "hdmitx_sys"),
0121 CLK_MSR_ID(20, "rtc_osc_out"),
0122 CLK_MSR_ID(21, "i2s_in_src0"),
0123 CLK_MSR_ID(22, "eth_phy_ref"),
0124 CLK_MSR_ID(23, "hdmi_todig"),
0125 CLK_MSR_ID(26, "sc_int"),
0126 CLK_MSR_ID(28, "sar_adc"),
0127 CLK_MSR_ID(31, "mpll_test_out"),
0128 CLK_MSR_ID(32, "vdec"),
0129 CLK_MSR_ID(35, "mali"),
0130 CLK_MSR_ID(36, "hdmi_tx_pixel"),
0131 CLK_MSR_ID(37, "i958"),
0132 CLK_MSR_ID(38, "vdin_meas"),
0133 CLK_MSR_ID(39, "pcm_sclk"),
0134 CLK_MSR_ID(40, "pcm_mclk"),
0135 CLK_MSR_ID(41, "eth_rx_or_rmii"),
0136 CLK_MSR_ID(42, "mp0_out"),
0137 CLK_MSR_ID(43, "fclk_div5"),
0138 CLK_MSR_ID(44, "pwm_b"),
0139 CLK_MSR_ID(45, "pwm_a"),
0140 CLK_MSR_ID(46, "vpu"),
0141 CLK_MSR_ID(47, "ddr_dpll_pt"),
0142 CLK_MSR_ID(48, "mp1_out"),
0143 CLK_MSR_ID(49, "mp2_out"),
0144 CLK_MSR_ID(50, "mp3_out"),
0145 CLK_MSR_ID(51, "nand_core"),
0146 CLK_MSR_ID(52, "sd_emmc_b"),
0147 CLK_MSR_ID(53, "sd_emmc_a"),
0148 CLK_MSR_ID(55, "vid_pll_div_out"),
0149 CLK_MSR_ID(56, "cci"),
0150 CLK_MSR_ID(57, "wave420l_c"),
0151 CLK_MSR_ID(58, "wave420l_b"),
0152 CLK_MSR_ID(59, "hcodec"),
0153 CLK_MSR_ID(60, "alt_32k"),
0154 CLK_MSR_ID(61, "gpio_msr"),
0155 CLK_MSR_ID(62, "hevc"),
0156 CLK_MSR_ID(66, "vid_lock"),
0157 CLK_MSR_ID(70, "pwm_f"),
0158 CLK_MSR_ID(71, "pwm_e"),
0159 CLK_MSR_ID(72, "pwm_d"),
0160 CLK_MSR_ID(73, "pwm_c"),
0161 CLK_MSR_ID(75, "aoclkx2_int"),
0162 CLK_MSR_ID(76, "aoclk_int"),
0163 CLK_MSR_ID(77, "rng_ring_osc_0"),
0164 CLK_MSR_ID(78, "rng_ring_osc_1"),
0165 CLK_MSR_ID(79, "rng_ring_osc_2"),
0166 CLK_MSR_ID(80, "rng_ring_osc_3"),
0167 CLK_MSR_ID(81, "vapb"),
0168 CLK_MSR_ID(82, "ge2d"),
0169 };
0170
0171 static struct meson_msr_id clk_msr_axg[CLK_MSR_MAX] = {
0172 CLK_MSR_ID(0, "ring_osc_out_ee_0"),
0173 CLK_MSR_ID(1, "ring_osc_out_ee_1"),
0174 CLK_MSR_ID(2, "ring_osc_out_ee_2"),
0175 CLK_MSR_ID(3, "a53_ring_osc"),
0176 CLK_MSR_ID(4, "gp0_pll"),
0177 CLK_MSR_ID(5, "gp1_pll"),
0178 CLK_MSR_ID(7, "clk81"),
0179 CLK_MSR_ID(9, "encl"),
0180 CLK_MSR_ID(17, "sys_pll_div16"),
0181 CLK_MSR_ID(18, "sys_cpu_div16"),
0182 CLK_MSR_ID(20, "rtc_osc_out"),
0183 CLK_MSR_ID(23, "mmc_clk"),
0184 CLK_MSR_ID(28, "sar_adc"),
0185 CLK_MSR_ID(31, "mpll_test_out"),
0186 CLK_MSR_ID(40, "mod_eth_tx_clk"),
0187 CLK_MSR_ID(41, "mod_eth_rx_clk_rmii"),
0188 CLK_MSR_ID(42, "mp0_out"),
0189 CLK_MSR_ID(43, "fclk_div5"),
0190 CLK_MSR_ID(44, "pwm_b"),
0191 CLK_MSR_ID(45, "pwm_a"),
0192 CLK_MSR_ID(46, "vpu"),
0193 CLK_MSR_ID(47, "ddr_dpll_pt"),
0194 CLK_MSR_ID(48, "mp1_out"),
0195 CLK_MSR_ID(49, "mp2_out"),
0196 CLK_MSR_ID(50, "mp3_out"),
0197 CLK_MSR_ID(51, "sd_emmm_c"),
0198 CLK_MSR_ID(52, "sd_emmc_b"),
0199 CLK_MSR_ID(61, "gpio_msr"),
0200 CLK_MSR_ID(66, "audio_slv_lrclk_c"),
0201 CLK_MSR_ID(67, "audio_slv_lrclk_b"),
0202 CLK_MSR_ID(68, "audio_slv_lrclk_a"),
0203 CLK_MSR_ID(69, "audio_slv_sclk_c"),
0204 CLK_MSR_ID(70, "audio_slv_sclk_b"),
0205 CLK_MSR_ID(71, "audio_slv_sclk_a"),
0206 CLK_MSR_ID(72, "pwm_d"),
0207 CLK_MSR_ID(73, "pwm_c"),
0208 CLK_MSR_ID(74, "wifi_beacon"),
0209 CLK_MSR_ID(75, "tdmin_lb_lrcl"),
0210 CLK_MSR_ID(76, "tdmin_lb_sclk"),
0211 CLK_MSR_ID(77, "rng_ring_osc_0"),
0212 CLK_MSR_ID(78, "rng_ring_osc_1"),
0213 CLK_MSR_ID(79, "rng_ring_osc_2"),
0214 CLK_MSR_ID(80, "rng_ring_osc_3"),
0215 CLK_MSR_ID(81, "vapb"),
0216 CLK_MSR_ID(82, "ge2d"),
0217 CLK_MSR_ID(84, "audio_resample"),
0218 CLK_MSR_ID(85, "audio_pdm_sys"),
0219 CLK_MSR_ID(86, "audio_spdifout"),
0220 CLK_MSR_ID(87, "audio_spdifin"),
0221 CLK_MSR_ID(88, "audio_lrclk_f"),
0222 CLK_MSR_ID(89, "audio_lrclk_e"),
0223 CLK_MSR_ID(90, "audio_lrclk_d"),
0224 CLK_MSR_ID(91, "audio_lrclk_c"),
0225 CLK_MSR_ID(92, "audio_lrclk_b"),
0226 CLK_MSR_ID(93, "audio_lrclk_a"),
0227 CLK_MSR_ID(94, "audio_sclk_f"),
0228 CLK_MSR_ID(95, "audio_sclk_e"),
0229 CLK_MSR_ID(96, "audio_sclk_d"),
0230 CLK_MSR_ID(97, "audio_sclk_c"),
0231 CLK_MSR_ID(98, "audio_sclk_b"),
0232 CLK_MSR_ID(99, "audio_sclk_a"),
0233 CLK_MSR_ID(100, "audio_mclk_f"),
0234 CLK_MSR_ID(101, "audio_mclk_e"),
0235 CLK_MSR_ID(102, "audio_mclk_d"),
0236 CLK_MSR_ID(103, "audio_mclk_c"),
0237 CLK_MSR_ID(104, "audio_mclk_b"),
0238 CLK_MSR_ID(105, "audio_mclk_a"),
0239 CLK_MSR_ID(106, "pcie_refclk_n"),
0240 CLK_MSR_ID(107, "pcie_refclk_p"),
0241 CLK_MSR_ID(108, "audio_locker_out"),
0242 CLK_MSR_ID(109, "audio_locker_in"),
0243 };
0244
0245 static struct meson_msr_id clk_msr_g12a[CLK_MSR_MAX] = {
0246 CLK_MSR_ID(0, "ring_osc_out_ee_0"),
0247 CLK_MSR_ID(1, "ring_osc_out_ee_1"),
0248 CLK_MSR_ID(2, "ring_osc_out_ee_2"),
0249 CLK_MSR_ID(3, "sys_cpu_ring_osc"),
0250 CLK_MSR_ID(4, "gp0_pll"),
0251 CLK_MSR_ID(6, "enci"),
0252 CLK_MSR_ID(7, "clk81"),
0253 CLK_MSR_ID(8, "encp"),
0254 CLK_MSR_ID(9, "encl"),
0255 CLK_MSR_ID(10, "vdac"),
0256 CLK_MSR_ID(11, "eth_tx"),
0257 CLK_MSR_ID(12, "hifi_pll"),
0258 CLK_MSR_ID(13, "mod_tcon"),
0259 CLK_MSR_ID(14, "fec_0"),
0260 CLK_MSR_ID(15, "fec_1"),
0261 CLK_MSR_ID(16, "fec_2"),
0262 CLK_MSR_ID(17, "sys_pll_div16"),
0263 CLK_MSR_ID(18, "sys_cpu_div16"),
0264 CLK_MSR_ID(19, "lcd_an_ph2"),
0265 CLK_MSR_ID(20, "rtc_osc_out"),
0266 CLK_MSR_ID(21, "lcd_an_ph3"),
0267 CLK_MSR_ID(22, "eth_phy_ref"),
0268 CLK_MSR_ID(23, "mpll_50m"),
0269 CLK_MSR_ID(24, "eth_125m"),
0270 CLK_MSR_ID(25, "eth_rmii"),
0271 CLK_MSR_ID(26, "sc_int"),
0272 CLK_MSR_ID(27, "in_mac"),
0273 CLK_MSR_ID(28, "sar_adc"),
0274 CLK_MSR_ID(29, "pcie_inp"),
0275 CLK_MSR_ID(30, "pcie_inn"),
0276 CLK_MSR_ID(31, "mpll_test_out"),
0277 CLK_MSR_ID(32, "vdec"),
0278 CLK_MSR_ID(33, "sys_cpu_ring_osc_1"),
0279 CLK_MSR_ID(34, "eth_mpll_50m"),
0280 CLK_MSR_ID(35, "mali"),
0281 CLK_MSR_ID(36, "hdmi_tx_pixel"),
0282 CLK_MSR_ID(37, "cdac"),
0283 CLK_MSR_ID(38, "vdin_meas"),
0284 CLK_MSR_ID(39, "bt656"),
0285 CLK_MSR_ID(41, "eth_rx_or_rmii"),
0286 CLK_MSR_ID(42, "mp0_out"),
0287 CLK_MSR_ID(43, "fclk_div5"),
0288 CLK_MSR_ID(44, "pwm_b"),
0289 CLK_MSR_ID(45, "pwm_a"),
0290 CLK_MSR_ID(46, "vpu"),
0291 CLK_MSR_ID(47, "ddr_dpll_pt"),
0292 CLK_MSR_ID(48, "mp1_out"),
0293 CLK_MSR_ID(49, "mp2_out"),
0294 CLK_MSR_ID(50, "mp3_out"),
0295 CLK_MSR_ID(51, "sd_emmc_c"),
0296 CLK_MSR_ID(52, "sd_emmc_b"),
0297 CLK_MSR_ID(53, "sd_emmc_a"),
0298 CLK_MSR_ID(54, "vpu_clkc"),
0299 CLK_MSR_ID(55, "vid_pll_div_out"),
0300 CLK_MSR_ID(56, "wave420l_a"),
0301 CLK_MSR_ID(57, "wave420l_c"),
0302 CLK_MSR_ID(58, "wave420l_b"),
0303 CLK_MSR_ID(59, "hcodec"),
0304 CLK_MSR_ID(61, "gpio_msr"),
0305 CLK_MSR_ID(62, "hevcb"),
0306 CLK_MSR_ID(63, "dsi_meas"),
0307 CLK_MSR_ID(64, "spicc_1"),
0308 CLK_MSR_ID(65, "spicc_0"),
0309 CLK_MSR_ID(66, "vid_lock"),
0310 CLK_MSR_ID(67, "dsi_phy"),
0311 CLK_MSR_ID(68, "hdcp22_esm"),
0312 CLK_MSR_ID(69, "hdcp22_skp"),
0313 CLK_MSR_ID(70, "pwm_f"),
0314 CLK_MSR_ID(71, "pwm_e"),
0315 CLK_MSR_ID(72, "pwm_d"),
0316 CLK_MSR_ID(73, "pwm_c"),
0317 CLK_MSR_ID(75, "hevcf"),
0318 CLK_MSR_ID(77, "rng_ring_osc_0"),
0319 CLK_MSR_ID(78, "rng_ring_osc_1"),
0320 CLK_MSR_ID(79, "rng_ring_osc_2"),
0321 CLK_MSR_ID(80, "rng_ring_osc_3"),
0322 CLK_MSR_ID(81, "vapb"),
0323 CLK_MSR_ID(82, "ge2d"),
0324 CLK_MSR_ID(83, "co_rx"),
0325 CLK_MSR_ID(84, "co_tx"),
0326 CLK_MSR_ID(89, "hdmi_todig"),
0327 CLK_MSR_ID(90, "hdmitx_sys"),
0328 CLK_MSR_ID(91, "sys_cpub_div16"),
0329 CLK_MSR_ID(92, "sys_pll_cpub_div16"),
0330 CLK_MSR_ID(94, "eth_phy_rx"),
0331 CLK_MSR_ID(95, "eth_phy_pll"),
0332 CLK_MSR_ID(96, "vpu_b"),
0333 CLK_MSR_ID(97, "cpu_b_tmp"),
0334 CLK_MSR_ID(98, "ts"),
0335 CLK_MSR_ID(99, "ring_osc_out_ee_3"),
0336 CLK_MSR_ID(100, "ring_osc_out_ee_4"),
0337 CLK_MSR_ID(101, "ring_osc_out_ee_5"),
0338 CLK_MSR_ID(102, "ring_osc_out_ee_6"),
0339 CLK_MSR_ID(103, "ring_osc_out_ee_7"),
0340 CLK_MSR_ID(104, "ring_osc_out_ee_8"),
0341 CLK_MSR_ID(105, "ring_osc_out_ee_9"),
0342 CLK_MSR_ID(106, "ephy_test"),
0343 CLK_MSR_ID(107, "au_dac_g128x"),
0344 CLK_MSR_ID(108, "audio_locker_out"),
0345 CLK_MSR_ID(109, "audio_locker_in"),
0346 CLK_MSR_ID(110, "audio_tdmout_c_sclk"),
0347 CLK_MSR_ID(111, "audio_tdmout_b_sclk"),
0348 CLK_MSR_ID(112, "audio_tdmout_a_sclk"),
0349 CLK_MSR_ID(113, "audio_tdmin_lb_sclk"),
0350 CLK_MSR_ID(114, "audio_tdmin_c_sclk"),
0351 CLK_MSR_ID(115, "audio_tdmin_b_sclk"),
0352 CLK_MSR_ID(116, "audio_tdmin_a_sclk"),
0353 CLK_MSR_ID(117, "audio_resample"),
0354 CLK_MSR_ID(118, "audio_pdm_sys"),
0355 CLK_MSR_ID(119, "audio_spdifout_b"),
0356 CLK_MSR_ID(120, "audio_spdifout"),
0357 CLK_MSR_ID(121, "audio_spdifin"),
0358 CLK_MSR_ID(122, "audio_pdm_dclk"),
0359 };
0360
0361 static struct meson_msr_id clk_msr_sm1[CLK_MSR_MAX] = {
0362 CLK_MSR_ID(0, "ring_osc_out_ee_0"),
0363 CLK_MSR_ID(1, "ring_osc_out_ee_1"),
0364 CLK_MSR_ID(2, "ring_osc_out_ee_2"),
0365 CLK_MSR_ID(3, "ring_osc_out_ee_3"),
0366 CLK_MSR_ID(4, "gp0_pll"),
0367 CLK_MSR_ID(5, "gp1_pll"),
0368 CLK_MSR_ID(6, "enci"),
0369 CLK_MSR_ID(7, "clk81"),
0370 CLK_MSR_ID(8, "encp"),
0371 CLK_MSR_ID(9, "encl"),
0372 CLK_MSR_ID(10, "vdac"),
0373 CLK_MSR_ID(11, "eth_tx"),
0374 CLK_MSR_ID(12, "hifi_pll"),
0375 CLK_MSR_ID(13, "mod_tcon"),
0376 CLK_MSR_ID(14, "fec_0"),
0377 CLK_MSR_ID(15, "fec_1"),
0378 CLK_MSR_ID(16, "fec_2"),
0379 CLK_MSR_ID(17, "sys_pll_div16"),
0380 CLK_MSR_ID(18, "sys_cpu_div16"),
0381 CLK_MSR_ID(19, "lcd_an_ph2"),
0382 CLK_MSR_ID(20, "rtc_osc_out"),
0383 CLK_MSR_ID(21, "lcd_an_ph3"),
0384 CLK_MSR_ID(22, "eth_phy_ref"),
0385 CLK_MSR_ID(23, "mpll_50m"),
0386 CLK_MSR_ID(24, "eth_125m"),
0387 CLK_MSR_ID(25, "eth_rmii"),
0388 CLK_MSR_ID(26, "sc_int"),
0389 CLK_MSR_ID(27, "in_mac"),
0390 CLK_MSR_ID(28, "sar_adc"),
0391 CLK_MSR_ID(29, "pcie_inp"),
0392 CLK_MSR_ID(30, "pcie_inn"),
0393 CLK_MSR_ID(31, "mpll_test_out"),
0394 CLK_MSR_ID(32, "vdec"),
0395 CLK_MSR_ID(34, "eth_mpll_50m"),
0396 CLK_MSR_ID(35, "mali"),
0397 CLK_MSR_ID(36, "hdmi_tx_pixel"),
0398 CLK_MSR_ID(37, "cdac"),
0399 CLK_MSR_ID(38, "vdin_meas"),
0400 CLK_MSR_ID(39, "bt656"),
0401 CLK_MSR_ID(40, "arm_ring_osc_out_4"),
0402 CLK_MSR_ID(41, "eth_rx_or_rmii"),
0403 CLK_MSR_ID(42, "mp0_out"),
0404 CLK_MSR_ID(43, "fclk_div5"),
0405 CLK_MSR_ID(44, "pwm_b"),
0406 CLK_MSR_ID(45, "pwm_a"),
0407 CLK_MSR_ID(46, "vpu"),
0408 CLK_MSR_ID(47, "ddr_dpll_pt"),
0409 CLK_MSR_ID(48, "mp1_out"),
0410 CLK_MSR_ID(49, "mp2_out"),
0411 CLK_MSR_ID(50, "mp3_out"),
0412 CLK_MSR_ID(51, "sd_emmc_c"),
0413 CLK_MSR_ID(52, "sd_emmc_b"),
0414 CLK_MSR_ID(53, "sd_emmc_a"),
0415 CLK_MSR_ID(54, "vpu_clkc"),
0416 CLK_MSR_ID(55, "vid_pll_div_out"),
0417 CLK_MSR_ID(56, "wave420l_a"),
0418 CLK_MSR_ID(57, "wave420l_c"),
0419 CLK_MSR_ID(58, "wave420l_b"),
0420 CLK_MSR_ID(59, "hcodec"),
0421 CLK_MSR_ID(60, "arm_ring_osc_out_5"),
0422 CLK_MSR_ID(61, "gpio_msr"),
0423 CLK_MSR_ID(62, "hevcb"),
0424 CLK_MSR_ID(63, "dsi_meas"),
0425 CLK_MSR_ID(64, "spicc_1"),
0426 CLK_MSR_ID(65, "spicc_0"),
0427 CLK_MSR_ID(66, "vid_lock"),
0428 CLK_MSR_ID(67, "dsi_phy"),
0429 CLK_MSR_ID(68, "hdcp22_esm"),
0430 CLK_MSR_ID(69, "hdcp22_skp"),
0431 CLK_MSR_ID(70, "pwm_f"),
0432 CLK_MSR_ID(71, "pwm_e"),
0433 CLK_MSR_ID(72, "pwm_d"),
0434 CLK_MSR_ID(73, "pwm_c"),
0435 CLK_MSR_ID(74, "arm_ring_osc_out_6"),
0436 CLK_MSR_ID(75, "hevcf"),
0437 CLK_MSR_ID(76, "arm_ring_osc_out_7"),
0438 CLK_MSR_ID(77, "rng_ring_osc_0"),
0439 CLK_MSR_ID(78, "rng_ring_osc_1"),
0440 CLK_MSR_ID(79, "rng_ring_osc_2"),
0441 CLK_MSR_ID(80, "rng_ring_osc_3"),
0442 CLK_MSR_ID(81, "vapb"),
0443 CLK_MSR_ID(82, "ge2d"),
0444 CLK_MSR_ID(83, "co_rx"),
0445 CLK_MSR_ID(84, "co_tx"),
0446 CLK_MSR_ID(85, "arm_ring_osc_out_8"),
0447 CLK_MSR_ID(86, "arm_ring_osc_out_9"),
0448 CLK_MSR_ID(87, "mipi_dsi_phy"),
0449 CLK_MSR_ID(88, "cis2_adapt"),
0450 CLK_MSR_ID(89, "hdmi_todig"),
0451 CLK_MSR_ID(90, "hdmitx_sys"),
0452 CLK_MSR_ID(91, "nna_core"),
0453 CLK_MSR_ID(92, "nna_axi"),
0454 CLK_MSR_ID(93, "vad"),
0455 CLK_MSR_ID(94, "eth_phy_rx"),
0456 CLK_MSR_ID(95, "eth_phy_pll"),
0457 CLK_MSR_ID(96, "vpu_b"),
0458 CLK_MSR_ID(97, "cpu_b_tmp"),
0459 CLK_MSR_ID(98, "ts"),
0460 CLK_MSR_ID(99, "arm_ring_osc_out_10"),
0461 CLK_MSR_ID(100, "arm_ring_osc_out_11"),
0462 CLK_MSR_ID(101, "arm_ring_osc_out_12"),
0463 CLK_MSR_ID(102, "arm_ring_osc_out_13"),
0464 CLK_MSR_ID(103, "arm_ring_osc_out_14"),
0465 CLK_MSR_ID(104, "arm_ring_osc_out_15"),
0466 CLK_MSR_ID(105, "arm_ring_osc_out_16"),
0467 CLK_MSR_ID(106, "ephy_test"),
0468 CLK_MSR_ID(107, "au_dac_g128x"),
0469 CLK_MSR_ID(108, "audio_locker_out"),
0470 CLK_MSR_ID(109, "audio_locker_in"),
0471 CLK_MSR_ID(110, "audio_tdmout_c_sclk"),
0472 CLK_MSR_ID(111, "audio_tdmout_b_sclk"),
0473 CLK_MSR_ID(112, "audio_tdmout_a_sclk"),
0474 CLK_MSR_ID(113, "audio_tdmin_lb_sclk"),
0475 CLK_MSR_ID(114, "audio_tdmin_c_sclk"),
0476 CLK_MSR_ID(115, "audio_tdmin_b_sclk"),
0477 CLK_MSR_ID(116, "audio_tdmin_a_sclk"),
0478 CLK_MSR_ID(117, "audio_resample"),
0479 CLK_MSR_ID(118, "audio_pdm_sys"),
0480 CLK_MSR_ID(119, "audio_spdifout_b"),
0481 CLK_MSR_ID(120, "audio_spdifout"),
0482 CLK_MSR_ID(121, "audio_spdifin"),
0483 CLK_MSR_ID(122, "audio_pdm_dclk"),
0484 CLK_MSR_ID(123, "audio_resampled"),
0485 CLK_MSR_ID(124, "earcrx_pll"),
0486 CLK_MSR_ID(125, "earcrx_pll_test"),
0487 CLK_MSR_ID(126, "csi_phy0"),
0488 CLK_MSR_ID(127, "csi2_data"),
0489 };
0490
0491 static int meson_measure_id(struct meson_msr_id *clk_msr_id,
0492 unsigned int duration)
0493 {
0494 struct meson_msr *priv = clk_msr_id->priv;
0495 unsigned int val;
0496 int ret;
0497
0498 ret = mutex_lock_interruptible(&measure_lock);
0499 if (ret)
0500 return ret;
0501
0502 regmap_write(priv->regmap, MSR_CLK_REG0, 0);
0503
0504
0505 regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_DURATION,
0506 FIELD_PREP(MSR_DURATION, duration - 1));
0507
0508
0509 regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_CLK_SRC,
0510 FIELD_PREP(MSR_CLK_SRC, clk_msr_id->id));
0511
0512
0513 regmap_update_bits(priv->regmap, MSR_CLK_REG0,
0514 MSR_RUN | MSR_ENABLE,
0515 MSR_RUN | MSR_ENABLE);
0516
0517 ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0,
0518 val, !(val & MSR_BUSY), 10, 10000);
0519 if (ret) {
0520 mutex_unlock(&measure_lock);
0521 return ret;
0522 }
0523
0524
0525 regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0);
0526
0527
0528 regmap_read(priv->regmap, MSR_CLK_REG2, &val);
0529
0530 mutex_unlock(&measure_lock);
0531
0532 if (val >= MSR_VAL_MASK)
0533 return -EINVAL;
0534
0535 return DIV_ROUND_CLOSEST_ULL((val & MSR_VAL_MASK) * 1000000ULL,
0536 duration);
0537 }
0538
0539 static int meson_measure_best_id(struct meson_msr_id *clk_msr_id,
0540 unsigned int *precision)
0541 {
0542 unsigned int duration = DIV_MAX;
0543 int ret;
0544
0545
0546 do {
0547 ret = meson_measure_id(clk_msr_id, duration);
0548 if (ret >= 0)
0549 *precision = (2 * 1000000) / duration;
0550 else
0551 duration -= DIV_STEP;
0552 } while (duration >= DIV_MIN && ret == -EINVAL);
0553
0554 return ret;
0555 }
0556
0557 static int clk_msr_show(struct seq_file *s, void *data)
0558 {
0559 struct meson_msr_id *clk_msr_id = s->private;
0560 unsigned int precision = 0;
0561 int val;
0562
0563 val = meson_measure_best_id(clk_msr_id, &precision);
0564 if (val < 0)
0565 return val;
0566
0567 seq_printf(s, "%d\t+/-%dHz\n", val, precision);
0568
0569 return 0;
0570 }
0571 DEFINE_SHOW_ATTRIBUTE(clk_msr);
0572
0573 static int clk_msr_summary_show(struct seq_file *s, void *data)
0574 {
0575 struct meson_msr_id *msr_table = s->private;
0576 unsigned int precision = 0;
0577 int val, i;
0578
0579 seq_puts(s, " clock rate precision\n");
0580 seq_puts(s, "---------------------------------------------\n");
0581
0582 for (i = 0 ; i < CLK_MSR_MAX ; ++i) {
0583 if (!msr_table[i].name)
0584 continue;
0585
0586 val = meson_measure_best_id(&msr_table[i], &precision);
0587 if (val < 0)
0588 return val;
0589
0590 seq_printf(s, " %-20s %10d +/-%dHz\n",
0591 msr_table[i].name, val, precision);
0592 }
0593
0594 return 0;
0595 }
0596 DEFINE_SHOW_ATTRIBUTE(clk_msr_summary);
0597
0598 static const struct regmap_config meson_clk_msr_regmap_config = {
0599 .reg_bits = 32,
0600 .val_bits = 32,
0601 .reg_stride = 4,
0602 .max_register = MSR_CLK_REG2,
0603 };
0604
0605 static int meson_msr_probe(struct platform_device *pdev)
0606 {
0607 const struct meson_msr_id *match_data;
0608 struct meson_msr *priv;
0609 struct dentry *root, *clks;
0610 void __iomem *base;
0611 int i;
0612
0613 priv = devm_kzalloc(&pdev->dev, sizeof(struct meson_msr),
0614 GFP_KERNEL);
0615 if (!priv)
0616 return -ENOMEM;
0617
0618 match_data = device_get_match_data(&pdev->dev);
0619 if (!match_data) {
0620 dev_err(&pdev->dev, "failed to get match data\n");
0621 return -ENODEV;
0622 }
0623
0624 memcpy(priv->msr_table, match_data, sizeof(priv->msr_table));
0625
0626 base = devm_platform_ioremap_resource(pdev, 0);
0627 if (IS_ERR(base))
0628 return PTR_ERR(base);
0629
0630 priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
0631 &meson_clk_msr_regmap_config);
0632 if (IS_ERR(priv->regmap))
0633 return PTR_ERR(priv->regmap);
0634
0635 root = debugfs_create_dir("meson-clk-msr", NULL);
0636 clks = debugfs_create_dir("clks", root);
0637
0638 debugfs_create_file("measure_summary", 0444, root,
0639 priv->msr_table, &clk_msr_summary_fops);
0640
0641 for (i = 0 ; i < CLK_MSR_MAX ; ++i) {
0642 if (!priv->msr_table[i].name)
0643 continue;
0644
0645 priv->msr_table[i].priv = priv;
0646
0647 debugfs_create_file(priv->msr_table[i].name, 0444, clks,
0648 &priv->msr_table[i], &clk_msr_fops);
0649 }
0650
0651 return 0;
0652 }
0653
0654 static const struct of_device_id meson_msr_match_table[] = {
0655 {
0656 .compatible = "amlogic,meson-gx-clk-measure",
0657 .data = (void *)clk_msr_gx,
0658 },
0659 {
0660 .compatible = "amlogic,meson8-clk-measure",
0661 .data = (void *)clk_msr_m8,
0662 },
0663 {
0664 .compatible = "amlogic,meson8b-clk-measure",
0665 .data = (void *)clk_msr_m8,
0666 },
0667 {
0668 .compatible = "amlogic,meson-axg-clk-measure",
0669 .data = (void *)clk_msr_axg,
0670 },
0671 {
0672 .compatible = "amlogic,meson-g12a-clk-measure",
0673 .data = (void *)clk_msr_g12a,
0674 },
0675 {
0676 .compatible = "amlogic,meson-sm1-clk-measure",
0677 .data = (void *)clk_msr_sm1,
0678 },
0679 { }
0680 };
0681 MODULE_DEVICE_TABLE(of, meson_msr_match_table);
0682
0683 static struct platform_driver meson_msr_driver = {
0684 .probe = meson_msr_probe,
0685 .driver = {
0686 .name = "meson_msr",
0687 .of_match_table = meson_msr_match_table,
0688 },
0689 };
0690 module_platform_driver(meson_msr_driver);
0691 MODULE_LICENSE("GPL v2");