12b45ebefSNeil Armstrong // SPDX-License-Identifier: GPL-2.0+
22b45ebefSNeil Armstrong /*
32b45ebefSNeil Armstrong * Copyright (c) 2018 BayLibre, SAS
42b45ebefSNeil Armstrong * Author: Neil Armstrong <narmstrong@baylibre.com>
52b45ebefSNeil Armstrong */
62b45ebefSNeil Armstrong
72b45ebefSNeil Armstrong #include <linux/of_address.h>
82b45ebefSNeil Armstrong #include <linux/platform_device.h>
92b45ebefSNeil Armstrong #include <linux/bitfield.h>
102b45ebefSNeil Armstrong #include <linux/seq_file.h>
112b45ebefSNeil Armstrong #include <linux/debugfs.h>
122b45ebefSNeil Armstrong #include <linux/regmap.h>
13d9da1785SKevin Hilman #include <linux/module.h>
142b45ebefSNeil Armstrong
153a760d98SNeil Armstrong static DEFINE_MUTEX(measure_lock);
163a760d98SNeil Armstrong
172b45ebefSNeil Armstrong #define MSR_CLK_DUTY 0x0
182b45ebefSNeil Armstrong #define MSR_CLK_REG0 0x4
192b45ebefSNeil Armstrong #define MSR_CLK_REG1 0x8
202b45ebefSNeil Armstrong #define MSR_CLK_REG2 0xc
212b45ebefSNeil Armstrong
222b45ebefSNeil Armstrong #define MSR_DURATION GENMASK(15, 0)
232b45ebefSNeil Armstrong #define MSR_ENABLE BIT(16)
242b45ebefSNeil Armstrong #define MSR_CONT BIT(17) /* continuous measurement */
252b45ebefSNeil Armstrong #define MSR_INTR BIT(18) /* interrupts */
262b45ebefSNeil Armstrong #define MSR_RUN BIT(19)
272b45ebefSNeil Armstrong #define MSR_CLK_SRC GENMASK(26, 20)
282b45ebefSNeil Armstrong #define MSR_BUSY BIT(31)
292b45ebefSNeil Armstrong
302b45ebefSNeil Armstrong #define MSR_VAL_MASK GENMASK(15, 0)
312b45ebefSNeil Armstrong
322b45ebefSNeil Armstrong #define DIV_MIN 32
332b45ebefSNeil Armstrong #define DIV_STEP 32
342b45ebefSNeil Armstrong #define DIV_MAX 640
352b45ebefSNeil Armstrong
362b45ebefSNeil Armstrong #define CLK_MSR_MAX 128
372b45ebefSNeil Armstrong
382b45ebefSNeil Armstrong struct meson_msr_id {
392b45ebefSNeil Armstrong struct meson_msr *priv;
402b45ebefSNeil Armstrong unsigned int id;
412b45ebefSNeil Armstrong const char *name;
422b45ebefSNeil Armstrong };
432b45ebefSNeil Armstrong
442b45ebefSNeil Armstrong struct meson_msr {
452b45ebefSNeil Armstrong struct regmap *regmap;
462b45ebefSNeil Armstrong struct meson_msr_id msr_table[CLK_MSR_MAX];
472b45ebefSNeil Armstrong };
482b45ebefSNeil Armstrong
492b45ebefSNeil Armstrong #define CLK_MSR_ID(__id, __name) \
502b45ebefSNeil Armstrong [__id] = {.id = __id, .name = __name,}
512b45ebefSNeil Armstrong
522b45ebefSNeil Armstrong static struct meson_msr_id clk_msr_m8[CLK_MSR_MAX] = {
532b45ebefSNeil Armstrong CLK_MSR_ID(0, "ring_osc_out_ee0"),
542b45ebefSNeil Armstrong CLK_MSR_ID(1, "ring_osc_out_ee1"),
552b45ebefSNeil Armstrong CLK_MSR_ID(2, "ring_osc_out_ee2"),
562b45ebefSNeil Armstrong CLK_MSR_ID(3, "a9_ring_osck"),
572b45ebefSNeil Armstrong CLK_MSR_ID(6, "vid_pll"),
582b45ebefSNeil Armstrong CLK_MSR_ID(7, "clk81"),
592b45ebefSNeil Armstrong CLK_MSR_ID(8, "encp"),
602b45ebefSNeil Armstrong CLK_MSR_ID(9, "encl"),
612b45ebefSNeil Armstrong CLK_MSR_ID(11, "eth_rmii"),
622b45ebefSNeil Armstrong CLK_MSR_ID(13, "amclk"),
632b45ebefSNeil Armstrong CLK_MSR_ID(14, "fec_clk_0"),
642b45ebefSNeil Armstrong CLK_MSR_ID(15, "fec_clk_1"),
652b45ebefSNeil Armstrong CLK_MSR_ID(16, "fec_clk_2"),
662b45ebefSNeil Armstrong CLK_MSR_ID(18, "a9_clk_div16"),
672b45ebefSNeil Armstrong CLK_MSR_ID(19, "hdmi_sys"),
682b45ebefSNeil Armstrong CLK_MSR_ID(20, "rtc_osc_clk_out"),
692b45ebefSNeil Armstrong CLK_MSR_ID(21, "i2s_clk_in_src0"),
702b45ebefSNeil Armstrong CLK_MSR_ID(22, "clk_rmii_from_pad"),
712b45ebefSNeil Armstrong CLK_MSR_ID(23, "hdmi_ch0_tmds"),
722b45ebefSNeil Armstrong CLK_MSR_ID(24, "lvds_fifo"),
732b45ebefSNeil Armstrong CLK_MSR_ID(26, "sc_clk_int"),
742b45ebefSNeil Armstrong CLK_MSR_ID(28, "sar_adc"),
752b45ebefSNeil Armstrong CLK_MSR_ID(30, "mpll_clk_test_out"),
762b45ebefSNeil Armstrong CLK_MSR_ID(31, "audac_clkpi"),
772b45ebefSNeil Armstrong CLK_MSR_ID(32, "vdac"),
782b45ebefSNeil Armstrong CLK_MSR_ID(33, "sdhc_rx"),
792b45ebefSNeil Armstrong CLK_MSR_ID(34, "sdhc_sd"),
802b45ebefSNeil Armstrong CLK_MSR_ID(35, "mali"),
812b45ebefSNeil Armstrong CLK_MSR_ID(36, "hdmi_tx_pixel"),
822b45ebefSNeil Armstrong CLK_MSR_ID(38, "vdin_meas"),
832b45ebefSNeil Armstrong CLK_MSR_ID(39, "pcm_sclk"),
842b45ebefSNeil Armstrong CLK_MSR_ID(40, "pcm_mclk"),
852b45ebefSNeil Armstrong CLK_MSR_ID(41, "eth_rx_tx"),
862b45ebefSNeil Armstrong CLK_MSR_ID(42, "pwm_d"),
872b45ebefSNeil Armstrong CLK_MSR_ID(43, "pwm_c"),
882b45ebefSNeil Armstrong CLK_MSR_ID(44, "pwm_b"),
892b45ebefSNeil Armstrong CLK_MSR_ID(45, "pwm_a"),
902b45ebefSNeil Armstrong CLK_MSR_ID(46, "pcm2_sclk"),
912b45ebefSNeil Armstrong CLK_MSR_ID(47, "ddr_dpll_pt"),
922b45ebefSNeil Armstrong CLK_MSR_ID(48, "pwm_f"),
932b45ebefSNeil Armstrong CLK_MSR_ID(49, "pwm_e"),
942b45ebefSNeil Armstrong CLK_MSR_ID(59, "hcodec"),
952b45ebefSNeil Armstrong CLK_MSR_ID(60, "usb_32k_alt"),
962b45ebefSNeil Armstrong CLK_MSR_ID(61, "gpio"),
972b45ebefSNeil Armstrong CLK_MSR_ID(62, "vid2_pll"),
982b45ebefSNeil Armstrong CLK_MSR_ID(63, "mipi_csi_cfg"),
992b45ebefSNeil Armstrong };
1002b45ebefSNeil Armstrong
1012b45ebefSNeil Armstrong static struct meson_msr_id clk_msr_gx[CLK_MSR_MAX] = {
1022b45ebefSNeil Armstrong CLK_MSR_ID(0, "ring_osc_out_ee_0"),
1032b45ebefSNeil Armstrong CLK_MSR_ID(1, "ring_osc_out_ee_1"),
1042b45ebefSNeil Armstrong CLK_MSR_ID(2, "ring_osc_out_ee_2"),
1052b45ebefSNeil Armstrong CLK_MSR_ID(3, "a53_ring_osc"),
1062b45ebefSNeil Armstrong CLK_MSR_ID(4, "gp0_pll"),
1072b45ebefSNeil Armstrong CLK_MSR_ID(6, "enci"),
1082b45ebefSNeil Armstrong CLK_MSR_ID(7, "clk81"),
1092b45ebefSNeil Armstrong CLK_MSR_ID(8, "encp"),
1102b45ebefSNeil Armstrong CLK_MSR_ID(9, "encl"),
1112b45ebefSNeil Armstrong CLK_MSR_ID(10, "vdac"),
1122b45ebefSNeil Armstrong CLK_MSR_ID(11, "rgmii_tx"),
1132b45ebefSNeil Armstrong CLK_MSR_ID(12, "pdm"),
1142b45ebefSNeil Armstrong CLK_MSR_ID(13, "amclk"),
1152b45ebefSNeil Armstrong CLK_MSR_ID(14, "fec_0"),
1162b45ebefSNeil Armstrong CLK_MSR_ID(15, "fec_1"),
1172b45ebefSNeil Armstrong CLK_MSR_ID(16, "fec_2"),
1182b45ebefSNeil Armstrong CLK_MSR_ID(17, "sys_pll_div16"),
1192b45ebefSNeil Armstrong CLK_MSR_ID(18, "sys_cpu_div16"),
1202b45ebefSNeil Armstrong CLK_MSR_ID(19, "hdmitx_sys"),
1212b45ebefSNeil Armstrong CLK_MSR_ID(20, "rtc_osc_out"),
1222b45ebefSNeil Armstrong CLK_MSR_ID(21, "i2s_in_src0"),
1232b45ebefSNeil Armstrong CLK_MSR_ID(22, "eth_phy_ref"),
1242b45ebefSNeil Armstrong CLK_MSR_ID(23, "hdmi_todig"),
1252b45ebefSNeil Armstrong CLK_MSR_ID(26, "sc_int"),
1262b45ebefSNeil Armstrong CLK_MSR_ID(28, "sar_adc"),
1272b45ebefSNeil Armstrong CLK_MSR_ID(31, "mpll_test_out"),
1282b45ebefSNeil Armstrong CLK_MSR_ID(32, "vdec"),
1292b45ebefSNeil Armstrong CLK_MSR_ID(35, "mali"),
1302b45ebefSNeil Armstrong CLK_MSR_ID(36, "hdmi_tx_pixel"),
1312b45ebefSNeil Armstrong CLK_MSR_ID(37, "i958"),
1322b45ebefSNeil Armstrong CLK_MSR_ID(38, "vdin_meas"),
1332b45ebefSNeil Armstrong CLK_MSR_ID(39, "pcm_sclk"),
1342b45ebefSNeil Armstrong CLK_MSR_ID(40, "pcm_mclk"),
1352b45ebefSNeil Armstrong CLK_MSR_ID(41, "eth_rx_or_rmii"),
1362b45ebefSNeil Armstrong CLK_MSR_ID(42, "mp0_out"),
1372b45ebefSNeil Armstrong CLK_MSR_ID(43, "fclk_div5"),
1382b45ebefSNeil Armstrong CLK_MSR_ID(44, "pwm_b"),
1392b45ebefSNeil Armstrong CLK_MSR_ID(45, "pwm_a"),
1402b45ebefSNeil Armstrong CLK_MSR_ID(46, "vpu"),
1412b45ebefSNeil Armstrong CLK_MSR_ID(47, "ddr_dpll_pt"),
1422b45ebefSNeil Armstrong CLK_MSR_ID(48, "mp1_out"),
1432b45ebefSNeil Armstrong CLK_MSR_ID(49, "mp2_out"),
1442b45ebefSNeil Armstrong CLK_MSR_ID(50, "mp3_out"),
1452b45ebefSNeil Armstrong CLK_MSR_ID(51, "nand_core"),
1462b45ebefSNeil Armstrong CLK_MSR_ID(52, "sd_emmc_b"),
1472b45ebefSNeil Armstrong CLK_MSR_ID(53, "sd_emmc_a"),
1482b45ebefSNeil Armstrong CLK_MSR_ID(55, "vid_pll_div_out"),
1492b45ebefSNeil Armstrong CLK_MSR_ID(56, "cci"),
1502b45ebefSNeil Armstrong CLK_MSR_ID(57, "wave420l_c"),
1512b45ebefSNeil Armstrong CLK_MSR_ID(58, "wave420l_b"),
1522b45ebefSNeil Armstrong CLK_MSR_ID(59, "hcodec"),
1532b45ebefSNeil Armstrong CLK_MSR_ID(60, "alt_32k"),
1542b45ebefSNeil Armstrong CLK_MSR_ID(61, "gpio_msr"),
1552b45ebefSNeil Armstrong CLK_MSR_ID(62, "hevc"),
1562b45ebefSNeil Armstrong CLK_MSR_ID(66, "vid_lock"),
1572b45ebefSNeil Armstrong CLK_MSR_ID(70, "pwm_f"),
1582b45ebefSNeil Armstrong CLK_MSR_ID(71, "pwm_e"),
1592b45ebefSNeil Armstrong CLK_MSR_ID(72, "pwm_d"),
1602b45ebefSNeil Armstrong CLK_MSR_ID(73, "pwm_c"),
1612b45ebefSNeil Armstrong CLK_MSR_ID(75, "aoclkx2_int"),
1622b45ebefSNeil Armstrong CLK_MSR_ID(76, "aoclk_int"),
1632b45ebefSNeil Armstrong CLK_MSR_ID(77, "rng_ring_osc_0"),
1642b45ebefSNeil Armstrong CLK_MSR_ID(78, "rng_ring_osc_1"),
1652b45ebefSNeil Armstrong CLK_MSR_ID(79, "rng_ring_osc_2"),
1662b45ebefSNeil Armstrong CLK_MSR_ID(80, "rng_ring_osc_3"),
1672b45ebefSNeil Armstrong CLK_MSR_ID(81, "vapb"),
1682b45ebefSNeil Armstrong CLK_MSR_ID(82, "ge2d"),
1692b45ebefSNeil Armstrong };
1702b45ebefSNeil Armstrong
17119e0bde7SJerome Brunet static struct meson_msr_id clk_msr_axg[CLK_MSR_MAX] = {
17219e0bde7SJerome Brunet CLK_MSR_ID(0, "ring_osc_out_ee_0"),
17319e0bde7SJerome Brunet CLK_MSR_ID(1, "ring_osc_out_ee_1"),
17419e0bde7SJerome Brunet CLK_MSR_ID(2, "ring_osc_out_ee_2"),
17519e0bde7SJerome Brunet CLK_MSR_ID(3, "a53_ring_osc"),
17619e0bde7SJerome Brunet CLK_MSR_ID(4, "gp0_pll"),
17719e0bde7SJerome Brunet CLK_MSR_ID(5, "gp1_pll"),
17819e0bde7SJerome Brunet CLK_MSR_ID(7, "clk81"),
17919e0bde7SJerome Brunet CLK_MSR_ID(9, "encl"),
18019e0bde7SJerome Brunet CLK_MSR_ID(17, "sys_pll_div16"),
18119e0bde7SJerome Brunet CLK_MSR_ID(18, "sys_cpu_div16"),
18219e0bde7SJerome Brunet CLK_MSR_ID(20, "rtc_osc_out"),
18319e0bde7SJerome Brunet CLK_MSR_ID(23, "mmc_clk"),
18419e0bde7SJerome Brunet CLK_MSR_ID(28, "sar_adc"),
18519e0bde7SJerome Brunet CLK_MSR_ID(31, "mpll_test_out"),
18619e0bde7SJerome Brunet CLK_MSR_ID(40, "mod_eth_tx_clk"),
18719e0bde7SJerome Brunet CLK_MSR_ID(41, "mod_eth_rx_clk_rmii"),
18819e0bde7SJerome Brunet CLK_MSR_ID(42, "mp0_out"),
18919e0bde7SJerome Brunet CLK_MSR_ID(43, "fclk_div5"),
19019e0bde7SJerome Brunet CLK_MSR_ID(44, "pwm_b"),
19119e0bde7SJerome Brunet CLK_MSR_ID(45, "pwm_a"),
19219e0bde7SJerome Brunet CLK_MSR_ID(46, "vpu"),
19319e0bde7SJerome Brunet CLK_MSR_ID(47, "ddr_dpll_pt"),
19419e0bde7SJerome Brunet CLK_MSR_ID(48, "mp1_out"),
19519e0bde7SJerome Brunet CLK_MSR_ID(49, "mp2_out"),
19619e0bde7SJerome Brunet CLK_MSR_ID(50, "mp3_out"),
19719e0bde7SJerome Brunet CLK_MSR_ID(51, "sd_emmm_c"),
19819e0bde7SJerome Brunet CLK_MSR_ID(52, "sd_emmc_b"),
19919e0bde7SJerome Brunet CLK_MSR_ID(61, "gpio_msr"),
20019e0bde7SJerome Brunet CLK_MSR_ID(66, "audio_slv_lrclk_c"),
20119e0bde7SJerome Brunet CLK_MSR_ID(67, "audio_slv_lrclk_b"),
20219e0bde7SJerome Brunet CLK_MSR_ID(68, "audio_slv_lrclk_a"),
20319e0bde7SJerome Brunet CLK_MSR_ID(69, "audio_slv_sclk_c"),
20419e0bde7SJerome Brunet CLK_MSR_ID(70, "audio_slv_sclk_b"),
20519e0bde7SJerome Brunet CLK_MSR_ID(71, "audio_slv_sclk_a"),
20619e0bde7SJerome Brunet CLK_MSR_ID(72, "pwm_d"),
20719e0bde7SJerome Brunet CLK_MSR_ID(73, "pwm_c"),
20819e0bde7SJerome Brunet CLK_MSR_ID(74, "wifi_beacon"),
20919e0bde7SJerome Brunet CLK_MSR_ID(75, "tdmin_lb_lrcl"),
21019e0bde7SJerome Brunet CLK_MSR_ID(76, "tdmin_lb_sclk"),
21119e0bde7SJerome Brunet CLK_MSR_ID(77, "rng_ring_osc_0"),
21219e0bde7SJerome Brunet CLK_MSR_ID(78, "rng_ring_osc_1"),
21319e0bde7SJerome Brunet CLK_MSR_ID(79, "rng_ring_osc_2"),
21419e0bde7SJerome Brunet CLK_MSR_ID(80, "rng_ring_osc_3"),
21519e0bde7SJerome Brunet CLK_MSR_ID(81, "vapb"),
21619e0bde7SJerome Brunet CLK_MSR_ID(82, "ge2d"),
21719e0bde7SJerome Brunet CLK_MSR_ID(84, "audio_resample"),
21819e0bde7SJerome Brunet CLK_MSR_ID(85, "audio_pdm_sys"),
21919e0bde7SJerome Brunet CLK_MSR_ID(86, "audio_spdifout"),
22019e0bde7SJerome Brunet CLK_MSR_ID(87, "audio_spdifin"),
22119e0bde7SJerome Brunet CLK_MSR_ID(88, "audio_lrclk_f"),
22219e0bde7SJerome Brunet CLK_MSR_ID(89, "audio_lrclk_e"),
22319e0bde7SJerome Brunet CLK_MSR_ID(90, "audio_lrclk_d"),
22419e0bde7SJerome Brunet CLK_MSR_ID(91, "audio_lrclk_c"),
22519e0bde7SJerome Brunet CLK_MSR_ID(92, "audio_lrclk_b"),
22619e0bde7SJerome Brunet CLK_MSR_ID(93, "audio_lrclk_a"),
22719e0bde7SJerome Brunet CLK_MSR_ID(94, "audio_sclk_f"),
22819e0bde7SJerome Brunet CLK_MSR_ID(95, "audio_sclk_e"),
22919e0bde7SJerome Brunet CLK_MSR_ID(96, "audio_sclk_d"),
23019e0bde7SJerome Brunet CLK_MSR_ID(97, "audio_sclk_c"),
23119e0bde7SJerome Brunet CLK_MSR_ID(98, "audio_sclk_b"),
23219e0bde7SJerome Brunet CLK_MSR_ID(99, "audio_sclk_a"),
23319e0bde7SJerome Brunet CLK_MSR_ID(100, "audio_mclk_f"),
23419e0bde7SJerome Brunet CLK_MSR_ID(101, "audio_mclk_e"),
23519e0bde7SJerome Brunet CLK_MSR_ID(102, "audio_mclk_d"),
23619e0bde7SJerome Brunet CLK_MSR_ID(103, "audio_mclk_c"),
23719e0bde7SJerome Brunet CLK_MSR_ID(104, "audio_mclk_b"),
23819e0bde7SJerome Brunet CLK_MSR_ID(105, "audio_mclk_a"),
23919e0bde7SJerome Brunet CLK_MSR_ID(106, "pcie_refclk_n"),
24019e0bde7SJerome Brunet CLK_MSR_ID(107, "pcie_refclk_p"),
24119e0bde7SJerome Brunet CLK_MSR_ID(108, "audio_locker_out"),
24219e0bde7SJerome Brunet CLK_MSR_ID(109, "audio_locker_in"),
24319e0bde7SJerome Brunet };
24419e0bde7SJerome Brunet
24519e0bde7SJerome Brunet static struct meson_msr_id clk_msr_g12a[CLK_MSR_MAX] = {
24619e0bde7SJerome Brunet CLK_MSR_ID(0, "ring_osc_out_ee_0"),
24719e0bde7SJerome Brunet CLK_MSR_ID(1, "ring_osc_out_ee_1"),
24819e0bde7SJerome Brunet CLK_MSR_ID(2, "ring_osc_out_ee_2"),
24919e0bde7SJerome Brunet CLK_MSR_ID(3, "sys_cpu_ring_osc"),
25019e0bde7SJerome Brunet CLK_MSR_ID(4, "gp0_pll"),
25119e0bde7SJerome Brunet CLK_MSR_ID(6, "enci"),
25219e0bde7SJerome Brunet CLK_MSR_ID(7, "clk81"),
25319e0bde7SJerome Brunet CLK_MSR_ID(8, "encp"),
25419e0bde7SJerome Brunet CLK_MSR_ID(9, "encl"),
25519e0bde7SJerome Brunet CLK_MSR_ID(10, "vdac"),
25619e0bde7SJerome Brunet CLK_MSR_ID(11, "eth_tx"),
25719e0bde7SJerome Brunet CLK_MSR_ID(12, "hifi_pll"),
25819e0bde7SJerome Brunet CLK_MSR_ID(13, "mod_tcon"),
25919e0bde7SJerome Brunet CLK_MSR_ID(14, "fec_0"),
26019e0bde7SJerome Brunet CLK_MSR_ID(15, "fec_1"),
26119e0bde7SJerome Brunet CLK_MSR_ID(16, "fec_2"),
26219e0bde7SJerome Brunet CLK_MSR_ID(17, "sys_pll_div16"),
26319e0bde7SJerome Brunet CLK_MSR_ID(18, "sys_cpu_div16"),
26419e0bde7SJerome Brunet CLK_MSR_ID(19, "lcd_an_ph2"),
26519e0bde7SJerome Brunet CLK_MSR_ID(20, "rtc_osc_out"),
26619e0bde7SJerome Brunet CLK_MSR_ID(21, "lcd_an_ph3"),
26719e0bde7SJerome Brunet CLK_MSR_ID(22, "eth_phy_ref"),
26819e0bde7SJerome Brunet CLK_MSR_ID(23, "mpll_50m"),
26919e0bde7SJerome Brunet CLK_MSR_ID(24, "eth_125m"),
27019e0bde7SJerome Brunet CLK_MSR_ID(25, "eth_rmii"),
27119e0bde7SJerome Brunet CLK_MSR_ID(26, "sc_int"),
27219e0bde7SJerome Brunet CLK_MSR_ID(27, "in_mac"),
27319e0bde7SJerome Brunet CLK_MSR_ID(28, "sar_adc"),
27419e0bde7SJerome Brunet CLK_MSR_ID(29, "pcie_inp"),
27519e0bde7SJerome Brunet CLK_MSR_ID(30, "pcie_inn"),
27619e0bde7SJerome Brunet CLK_MSR_ID(31, "mpll_test_out"),
27719e0bde7SJerome Brunet CLK_MSR_ID(32, "vdec"),
27819e0bde7SJerome Brunet CLK_MSR_ID(33, "sys_cpu_ring_osc_1"),
27919e0bde7SJerome Brunet CLK_MSR_ID(34, "eth_mpll_50m"),
28019e0bde7SJerome Brunet CLK_MSR_ID(35, "mali"),
28119e0bde7SJerome Brunet CLK_MSR_ID(36, "hdmi_tx_pixel"),
28219e0bde7SJerome Brunet CLK_MSR_ID(37, "cdac"),
28319e0bde7SJerome Brunet CLK_MSR_ID(38, "vdin_meas"),
28419e0bde7SJerome Brunet CLK_MSR_ID(39, "bt656"),
28519e0bde7SJerome Brunet CLK_MSR_ID(41, "eth_rx_or_rmii"),
28619e0bde7SJerome Brunet CLK_MSR_ID(42, "mp0_out"),
28719e0bde7SJerome Brunet CLK_MSR_ID(43, "fclk_div5"),
28819e0bde7SJerome Brunet CLK_MSR_ID(44, "pwm_b"),
28919e0bde7SJerome Brunet CLK_MSR_ID(45, "pwm_a"),
29019e0bde7SJerome Brunet CLK_MSR_ID(46, "vpu"),
29119e0bde7SJerome Brunet CLK_MSR_ID(47, "ddr_dpll_pt"),
29219e0bde7SJerome Brunet CLK_MSR_ID(48, "mp1_out"),
29319e0bde7SJerome Brunet CLK_MSR_ID(49, "mp2_out"),
29419e0bde7SJerome Brunet CLK_MSR_ID(50, "mp3_out"),
29519e0bde7SJerome Brunet CLK_MSR_ID(51, "sd_emmc_c"),
29619e0bde7SJerome Brunet CLK_MSR_ID(52, "sd_emmc_b"),
29719e0bde7SJerome Brunet CLK_MSR_ID(53, "sd_emmc_a"),
29819e0bde7SJerome Brunet CLK_MSR_ID(54, "vpu_clkc"),
29919e0bde7SJerome Brunet CLK_MSR_ID(55, "vid_pll_div_out"),
30019e0bde7SJerome Brunet CLK_MSR_ID(56, "wave420l_a"),
30119e0bde7SJerome Brunet CLK_MSR_ID(57, "wave420l_c"),
30219e0bde7SJerome Brunet CLK_MSR_ID(58, "wave420l_b"),
30319e0bde7SJerome Brunet CLK_MSR_ID(59, "hcodec"),
30419e0bde7SJerome Brunet CLK_MSR_ID(61, "gpio_msr"),
30519e0bde7SJerome Brunet CLK_MSR_ID(62, "hevcb"),
30619e0bde7SJerome Brunet CLK_MSR_ID(63, "dsi_meas"),
30719e0bde7SJerome Brunet CLK_MSR_ID(64, "spicc_1"),
30819e0bde7SJerome Brunet CLK_MSR_ID(65, "spicc_0"),
30919e0bde7SJerome Brunet CLK_MSR_ID(66, "vid_lock"),
31019e0bde7SJerome Brunet CLK_MSR_ID(67, "dsi_phy"),
31119e0bde7SJerome Brunet CLK_MSR_ID(68, "hdcp22_esm"),
31219e0bde7SJerome Brunet CLK_MSR_ID(69, "hdcp22_skp"),
31319e0bde7SJerome Brunet CLK_MSR_ID(70, "pwm_f"),
31419e0bde7SJerome Brunet CLK_MSR_ID(71, "pwm_e"),
31519e0bde7SJerome Brunet CLK_MSR_ID(72, "pwm_d"),
31619e0bde7SJerome Brunet CLK_MSR_ID(73, "pwm_c"),
31719e0bde7SJerome Brunet CLK_MSR_ID(75, "hevcf"),
31819e0bde7SJerome Brunet CLK_MSR_ID(77, "rng_ring_osc_0"),
31919e0bde7SJerome Brunet CLK_MSR_ID(78, "rng_ring_osc_1"),
32019e0bde7SJerome Brunet CLK_MSR_ID(79, "rng_ring_osc_2"),
32119e0bde7SJerome Brunet CLK_MSR_ID(80, "rng_ring_osc_3"),
32219e0bde7SJerome Brunet CLK_MSR_ID(81, "vapb"),
32319e0bde7SJerome Brunet CLK_MSR_ID(82, "ge2d"),
32419e0bde7SJerome Brunet CLK_MSR_ID(83, "co_rx"),
32519e0bde7SJerome Brunet CLK_MSR_ID(84, "co_tx"),
32619e0bde7SJerome Brunet CLK_MSR_ID(89, "hdmi_todig"),
32719e0bde7SJerome Brunet CLK_MSR_ID(90, "hdmitx_sys"),
328c33b2777SNeil Armstrong CLK_MSR_ID(91, "sys_cpub_div16"),
329c33b2777SNeil Armstrong CLK_MSR_ID(92, "sys_pll_cpub_div16"),
33019e0bde7SJerome Brunet CLK_MSR_ID(94, "eth_phy_rx"),
33119e0bde7SJerome Brunet CLK_MSR_ID(95, "eth_phy_pll"),
33219e0bde7SJerome Brunet CLK_MSR_ID(96, "vpu_b"),
33319e0bde7SJerome Brunet CLK_MSR_ID(97, "cpu_b_tmp"),
33419e0bde7SJerome Brunet CLK_MSR_ID(98, "ts"),
33519e0bde7SJerome Brunet CLK_MSR_ID(99, "ring_osc_out_ee_3"),
33619e0bde7SJerome Brunet CLK_MSR_ID(100, "ring_osc_out_ee_4"),
33719e0bde7SJerome Brunet CLK_MSR_ID(101, "ring_osc_out_ee_5"),
33819e0bde7SJerome Brunet CLK_MSR_ID(102, "ring_osc_out_ee_6"),
33919e0bde7SJerome Brunet CLK_MSR_ID(103, "ring_osc_out_ee_7"),
34019e0bde7SJerome Brunet CLK_MSR_ID(104, "ring_osc_out_ee_8"),
34119e0bde7SJerome Brunet CLK_MSR_ID(105, "ring_osc_out_ee_9"),
34219e0bde7SJerome Brunet CLK_MSR_ID(106, "ephy_test"),
34319e0bde7SJerome Brunet CLK_MSR_ID(107, "au_dac_g128x"),
34419e0bde7SJerome Brunet CLK_MSR_ID(108, "audio_locker_out"),
34519e0bde7SJerome Brunet CLK_MSR_ID(109, "audio_locker_in"),
34619e0bde7SJerome Brunet CLK_MSR_ID(110, "audio_tdmout_c_sclk"),
34719e0bde7SJerome Brunet CLK_MSR_ID(111, "audio_tdmout_b_sclk"),
34819e0bde7SJerome Brunet CLK_MSR_ID(112, "audio_tdmout_a_sclk"),
34919e0bde7SJerome Brunet CLK_MSR_ID(113, "audio_tdmin_lb_sclk"),
35019e0bde7SJerome Brunet CLK_MSR_ID(114, "audio_tdmin_c_sclk"),
35119e0bde7SJerome Brunet CLK_MSR_ID(115, "audio_tdmin_b_sclk"),
35219e0bde7SJerome Brunet CLK_MSR_ID(116, "audio_tdmin_a_sclk"),
35319e0bde7SJerome Brunet CLK_MSR_ID(117, "audio_resample"),
35419e0bde7SJerome Brunet CLK_MSR_ID(118, "audio_pdm_sys"),
35519e0bde7SJerome Brunet CLK_MSR_ID(119, "audio_spdifout_b"),
35619e0bde7SJerome Brunet CLK_MSR_ID(120, "audio_spdifout"),
35719e0bde7SJerome Brunet CLK_MSR_ID(121, "audio_spdifin"),
35819e0bde7SJerome Brunet CLK_MSR_ID(122, "audio_pdm_dclk"),
35919e0bde7SJerome Brunet };
36019e0bde7SJerome Brunet
36162369971SNeil Armstrong static struct meson_msr_id clk_msr_sm1[CLK_MSR_MAX] = {
36262369971SNeil Armstrong CLK_MSR_ID(0, "ring_osc_out_ee_0"),
36362369971SNeil Armstrong CLK_MSR_ID(1, "ring_osc_out_ee_1"),
36462369971SNeil Armstrong CLK_MSR_ID(2, "ring_osc_out_ee_2"),
36562369971SNeil Armstrong CLK_MSR_ID(3, "ring_osc_out_ee_3"),
36662369971SNeil Armstrong CLK_MSR_ID(4, "gp0_pll"),
36762369971SNeil Armstrong CLK_MSR_ID(5, "gp1_pll"),
36862369971SNeil Armstrong CLK_MSR_ID(6, "enci"),
36962369971SNeil Armstrong CLK_MSR_ID(7, "clk81"),
37062369971SNeil Armstrong CLK_MSR_ID(8, "encp"),
37162369971SNeil Armstrong CLK_MSR_ID(9, "encl"),
37262369971SNeil Armstrong CLK_MSR_ID(10, "vdac"),
37362369971SNeil Armstrong CLK_MSR_ID(11, "eth_tx"),
37462369971SNeil Armstrong CLK_MSR_ID(12, "hifi_pll"),
37562369971SNeil Armstrong CLK_MSR_ID(13, "mod_tcon"),
37662369971SNeil Armstrong CLK_MSR_ID(14, "fec_0"),
37762369971SNeil Armstrong CLK_MSR_ID(15, "fec_1"),
37862369971SNeil Armstrong CLK_MSR_ID(16, "fec_2"),
37962369971SNeil Armstrong CLK_MSR_ID(17, "sys_pll_div16"),
38062369971SNeil Armstrong CLK_MSR_ID(18, "sys_cpu_div16"),
38162369971SNeil Armstrong CLK_MSR_ID(19, "lcd_an_ph2"),
38262369971SNeil Armstrong CLK_MSR_ID(20, "rtc_osc_out"),
38362369971SNeil Armstrong CLK_MSR_ID(21, "lcd_an_ph3"),
38462369971SNeil Armstrong CLK_MSR_ID(22, "eth_phy_ref"),
38562369971SNeil Armstrong CLK_MSR_ID(23, "mpll_50m"),
38662369971SNeil Armstrong CLK_MSR_ID(24, "eth_125m"),
38762369971SNeil Armstrong CLK_MSR_ID(25, "eth_rmii"),
38862369971SNeil Armstrong CLK_MSR_ID(26, "sc_int"),
38962369971SNeil Armstrong CLK_MSR_ID(27, "in_mac"),
39062369971SNeil Armstrong CLK_MSR_ID(28, "sar_adc"),
39162369971SNeil Armstrong CLK_MSR_ID(29, "pcie_inp"),
39262369971SNeil Armstrong CLK_MSR_ID(30, "pcie_inn"),
39362369971SNeil Armstrong CLK_MSR_ID(31, "mpll_test_out"),
39462369971SNeil Armstrong CLK_MSR_ID(32, "vdec"),
39562369971SNeil Armstrong CLK_MSR_ID(34, "eth_mpll_50m"),
39662369971SNeil Armstrong CLK_MSR_ID(35, "mali"),
39762369971SNeil Armstrong CLK_MSR_ID(36, "hdmi_tx_pixel"),
39862369971SNeil Armstrong CLK_MSR_ID(37, "cdac"),
39962369971SNeil Armstrong CLK_MSR_ID(38, "vdin_meas"),
40062369971SNeil Armstrong CLK_MSR_ID(39, "bt656"),
40162369971SNeil Armstrong CLK_MSR_ID(40, "arm_ring_osc_out_4"),
40262369971SNeil Armstrong CLK_MSR_ID(41, "eth_rx_or_rmii"),
40362369971SNeil Armstrong CLK_MSR_ID(42, "mp0_out"),
40462369971SNeil Armstrong CLK_MSR_ID(43, "fclk_div5"),
40562369971SNeil Armstrong CLK_MSR_ID(44, "pwm_b"),
40662369971SNeil Armstrong CLK_MSR_ID(45, "pwm_a"),
40762369971SNeil Armstrong CLK_MSR_ID(46, "vpu"),
40862369971SNeil Armstrong CLK_MSR_ID(47, "ddr_dpll_pt"),
40962369971SNeil Armstrong CLK_MSR_ID(48, "mp1_out"),
41062369971SNeil Armstrong CLK_MSR_ID(49, "mp2_out"),
41162369971SNeil Armstrong CLK_MSR_ID(50, "mp3_out"),
41262369971SNeil Armstrong CLK_MSR_ID(51, "sd_emmc_c"),
41362369971SNeil Armstrong CLK_MSR_ID(52, "sd_emmc_b"),
41462369971SNeil Armstrong CLK_MSR_ID(53, "sd_emmc_a"),
41562369971SNeil Armstrong CLK_MSR_ID(54, "vpu_clkc"),
41662369971SNeil Armstrong CLK_MSR_ID(55, "vid_pll_div_out"),
41762369971SNeil Armstrong CLK_MSR_ID(56, "wave420l_a"),
41862369971SNeil Armstrong CLK_MSR_ID(57, "wave420l_c"),
41962369971SNeil Armstrong CLK_MSR_ID(58, "wave420l_b"),
42062369971SNeil Armstrong CLK_MSR_ID(59, "hcodec"),
42162369971SNeil Armstrong CLK_MSR_ID(60, "arm_ring_osc_out_5"),
42262369971SNeil Armstrong CLK_MSR_ID(61, "gpio_msr"),
42362369971SNeil Armstrong CLK_MSR_ID(62, "hevcb"),
42462369971SNeil Armstrong CLK_MSR_ID(63, "dsi_meas"),
42562369971SNeil Armstrong CLK_MSR_ID(64, "spicc_1"),
42662369971SNeil Armstrong CLK_MSR_ID(65, "spicc_0"),
42762369971SNeil Armstrong CLK_MSR_ID(66, "vid_lock"),
42862369971SNeil Armstrong CLK_MSR_ID(67, "dsi_phy"),
42962369971SNeil Armstrong CLK_MSR_ID(68, "hdcp22_esm"),
43062369971SNeil Armstrong CLK_MSR_ID(69, "hdcp22_skp"),
43162369971SNeil Armstrong CLK_MSR_ID(70, "pwm_f"),
43262369971SNeil Armstrong CLK_MSR_ID(71, "pwm_e"),
43362369971SNeil Armstrong CLK_MSR_ID(72, "pwm_d"),
43462369971SNeil Armstrong CLK_MSR_ID(73, "pwm_c"),
43562369971SNeil Armstrong CLK_MSR_ID(74, "arm_ring_osc_out_6"),
43662369971SNeil Armstrong CLK_MSR_ID(75, "hevcf"),
43762369971SNeil Armstrong CLK_MSR_ID(76, "arm_ring_osc_out_7"),
43862369971SNeil Armstrong CLK_MSR_ID(77, "rng_ring_osc_0"),
43962369971SNeil Armstrong CLK_MSR_ID(78, "rng_ring_osc_1"),
44062369971SNeil Armstrong CLK_MSR_ID(79, "rng_ring_osc_2"),
44162369971SNeil Armstrong CLK_MSR_ID(80, "rng_ring_osc_3"),
44262369971SNeil Armstrong CLK_MSR_ID(81, "vapb"),
44362369971SNeil Armstrong CLK_MSR_ID(82, "ge2d"),
44462369971SNeil Armstrong CLK_MSR_ID(83, "co_rx"),
44562369971SNeil Armstrong CLK_MSR_ID(84, "co_tx"),
44662369971SNeil Armstrong CLK_MSR_ID(85, "arm_ring_osc_out_8"),
44762369971SNeil Armstrong CLK_MSR_ID(86, "arm_ring_osc_out_9"),
44862369971SNeil Armstrong CLK_MSR_ID(87, "mipi_dsi_phy"),
44962369971SNeil Armstrong CLK_MSR_ID(88, "cis2_adapt"),
45062369971SNeil Armstrong CLK_MSR_ID(89, "hdmi_todig"),
45162369971SNeil Armstrong CLK_MSR_ID(90, "hdmitx_sys"),
45262369971SNeil Armstrong CLK_MSR_ID(91, "nna_core"),
45362369971SNeil Armstrong CLK_MSR_ID(92, "nna_axi"),
45462369971SNeil Armstrong CLK_MSR_ID(93, "vad"),
45562369971SNeil Armstrong CLK_MSR_ID(94, "eth_phy_rx"),
45662369971SNeil Armstrong CLK_MSR_ID(95, "eth_phy_pll"),
45762369971SNeil Armstrong CLK_MSR_ID(96, "vpu_b"),
45862369971SNeil Armstrong CLK_MSR_ID(97, "cpu_b_tmp"),
45962369971SNeil Armstrong CLK_MSR_ID(98, "ts"),
46062369971SNeil Armstrong CLK_MSR_ID(99, "arm_ring_osc_out_10"),
46162369971SNeil Armstrong CLK_MSR_ID(100, "arm_ring_osc_out_11"),
46262369971SNeil Armstrong CLK_MSR_ID(101, "arm_ring_osc_out_12"),
46362369971SNeil Armstrong CLK_MSR_ID(102, "arm_ring_osc_out_13"),
46462369971SNeil Armstrong CLK_MSR_ID(103, "arm_ring_osc_out_14"),
46562369971SNeil Armstrong CLK_MSR_ID(104, "arm_ring_osc_out_15"),
46662369971SNeil Armstrong CLK_MSR_ID(105, "arm_ring_osc_out_16"),
46762369971SNeil Armstrong CLK_MSR_ID(106, "ephy_test"),
46862369971SNeil Armstrong CLK_MSR_ID(107, "au_dac_g128x"),
46962369971SNeil Armstrong CLK_MSR_ID(108, "audio_locker_out"),
47062369971SNeil Armstrong CLK_MSR_ID(109, "audio_locker_in"),
47162369971SNeil Armstrong CLK_MSR_ID(110, "audio_tdmout_c_sclk"),
47262369971SNeil Armstrong CLK_MSR_ID(111, "audio_tdmout_b_sclk"),
47362369971SNeil Armstrong CLK_MSR_ID(112, "audio_tdmout_a_sclk"),
47462369971SNeil Armstrong CLK_MSR_ID(113, "audio_tdmin_lb_sclk"),
47562369971SNeil Armstrong CLK_MSR_ID(114, "audio_tdmin_c_sclk"),
47662369971SNeil Armstrong CLK_MSR_ID(115, "audio_tdmin_b_sclk"),
47762369971SNeil Armstrong CLK_MSR_ID(116, "audio_tdmin_a_sclk"),
47862369971SNeil Armstrong CLK_MSR_ID(117, "audio_resample"),
47962369971SNeil Armstrong CLK_MSR_ID(118, "audio_pdm_sys"),
48062369971SNeil Armstrong CLK_MSR_ID(119, "audio_spdifout_b"),
48162369971SNeil Armstrong CLK_MSR_ID(120, "audio_spdifout"),
48262369971SNeil Armstrong CLK_MSR_ID(121, "audio_spdifin"),
48362369971SNeil Armstrong CLK_MSR_ID(122, "audio_pdm_dclk"),
48462369971SNeil Armstrong CLK_MSR_ID(123, "audio_resampled"),
48562369971SNeil Armstrong CLK_MSR_ID(124, "earcrx_pll"),
48662369971SNeil Armstrong CLK_MSR_ID(125, "earcrx_pll_test"),
48762369971SNeil Armstrong CLK_MSR_ID(126, "csi_phy0"),
48862369971SNeil Armstrong CLK_MSR_ID(127, "csi2_data"),
48962369971SNeil Armstrong };
49062369971SNeil Armstrong
meson_measure_id(struct meson_msr_id * clk_msr_id,unsigned int duration)4912b45ebefSNeil Armstrong static int meson_measure_id(struct meson_msr_id *clk_msr_id,
4922b45ebefSNeil Armstrong unsigned int duration)
4932b45ebefSNeil Armstrong {
4942b45ebefSNeil Armstrong struct meson_msr *priv = clk_msr_id->priv;
4952b45ebefSNeil Armstrong unsigned int val;
4962b45ebefSNeil Armstrong int ret;
4972b45ebefSNeil Armstrong
4983a760d98SNeil Armstrong ret = mutex_lock_interruptible(&measure_lock);
4993a760d98SNeil Armstrong if (ret)
5003a760d98SNeil Armstrong return ret;
5013a760d98SNeil Armstrong
5022b45ebefSNeil Armstrong regmap_write(priv->regmap, MSR_CLK_REG0, 0);
5032b45ebefSNeil Armstrong
5042b45ebefSNeil Armstrong /* Set measurement duration */
5052b45ebefSNeil Armstrong regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_DURATION,
5062b45ebefSNeil Armstrong FIELD_PREP(MSR_DURATION, duration - 1));
5072b45ebefSNeil Armstrong
5082b45ebefSNeil Armstrong /* Set ID */
5092b45ebefSNeil Armstrong regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_CLK_SRC,
5102b45ebefSNeil Armstrong FIELD_PREP(MSR_CLK_SRC, clk_msr_id->id));
5112b45ebefSNeil Armstrong
5122b45ebefSNeil Armstrong /* Enable & Start */
5132b45ebefSNeil Armstrong regmap_update_bits(priv->regmap, MSR_CLK_REG0,
5142b45ebefSNeil Armstrong MSR_RUN | MSR_ENABLE,
5152b45ebefSNeil Armstrong MSR_RUN | MSR_ENABLE);
5162b45ebefSNeil Armstrong
5172b45ebefSNeil Armstrong ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0,
5182b45ebefSNeil Armstrong val, !(val & MSR_BUSY), 10, 10000);
5193a760d98SNeil Armstrong if (ret) {
5203a760d98SNeil Armstrong mutex_unlock(&measure_lock);
5212b45ebefSNeil Armstrong return ret;
5223a760d98SNeil Armstrong }
5232b45ebefSNeil Armstrong
5242b45ebefSNeil Armstrong /* Disable */
5252b45ebefSNeil Armstrong regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0);
5262b45ebefSNeil Armstrong
5272b45ebefSNeil Armstrong /* Get the value in multiple of gate time counts */
5282b45ebefSNeil Armstrong regmap_read(priv->regmap, MSR_CLK_REG2, &val);
5292b45ebefSNeil Armstrong
5303a760d98SNeil Armstrong mutex_unlock(&measure_lock);
5313a760d98SNeil Armstrong
5322b45ebefSNeil Armstrong if (val >= MSR_VAL_MASK)
5332b45ebefSNeil Armstrong return -EINVAL;
5342b45ebefSNeil Armstrong
5352b45ebefSNeil Armstrong return DIV_ROUND_CLOSEST_ULL((val & MSR_VAL_MASK) * 1000000ULL,
5362b45ebefSNeil Armstrong duration);
5372b45ebefSNeil Armstrong }
5382b45ebefSNeil Armstrong
meson_measure_best_id(struct meson_msr_id * clk_msr_id,unsigned int * precision)5392b45ebefSNeil Armstrong static int meson_measure_best_id(struct meson_msr_id *clk_msr_id,
5402b45ebefSNeil Armstrong unsigned int *precision)
5412b45ebefSNeil Armstrong {
5422b45ebefSNeil Armstrong unsigned int duration = DIV_MAX;
5432b45ebefSNeil Armstrong int ret;
5442b45ebefSNeil Armstrong
5452b45ebefSNeil Armstrong /* Start from max duration and down to min duration */
5462b45ebefSNeil Armstrong do {
5472b45ebefSNeil Armstrong ret = meson_measure_id(clk_msr_id, duration);
5482b45ebefSNeil Armstrong if (ret >= 0)
5492b45ebefSNeil Armstrong *precision = (2 * 1000000) / duration;
5502b45ebefSNeil Armstrong else
5512b45ebefSNeil Armstrong duration -= DIV_STEP;
5522b45ebefSNeil Armstrong } while (duration >= DIV_MIN && ret == -EINVAL);
5532b45ebefSNeil Armstrong
5542b45ebefSNeil Armstrong return ret;
5552b45ebefSNeil Armstrong }
5562b45ebefSNeil Armstrong
clk_msr_show(struct seq_file * s,void * data)5572b45ebefSNeil Armstrong static int clk_msr_show(struct seq_file *s, void *data)
5582b45ebefSNeil Armstrong {
5592b45ebefSNeil Armstrong struct meson_msr_id *clk_msr_id = s->private;
5602b45ebefSNeil Armstrong unsigned int precision = 0;
5612b45ebefSNeil Armstrong int val;
5622b45ebefSNeil Armstrong
5632b45ebefSNeil Armstrong val = meson_measure_best_id(clk_msr_id, &precision);
5642b45ebefSNeil Armstrong if (val < 0)
5652b45ebefSNeil Armstrong return val;
5662b45ebefSNeil Armstrong
5672b45ebefSNeil Armstrong seq_printf(s, "%d\t+/-%dHz\n", val, precision);
5682b45ebefSNeil Armstrong
5692b45ebefSNeil Armstrong return 0;
5702b45ebefSNeil Armstrong }
5712b45ebefSNeil Armstrong DEFINE_SHOW_ATTRIBUTE(clk_msr);
5722b45ebefSNeil Armstrong
clk_msr_summary_show(struct seq_file * s,void * data)5732b45ebefSNeil Armstrong static int clk_msr_summary_show(struct seq_file *s, void *data)
5742b45ebefSNeil Armstrong {
5752b45ebefSNeil Armstrong struct meson_msr_id *msr_table = s->private;
5762b45ebefSNeil Armstrong unsigned int precision = 0;
5772b45ebefSNeil Armstrong int val, i;
5782b45ebefSNeil Armstrong
5792b45ebefSNeil Armstrong seq_puts(s, " clock rate precision\n");
5802b45ebefSNeil Armstrong seq_puts(s, "---------------------------------------------\n");
5812b45ebefSNeil Armstrong
5822b45ebefSNeil Armstrong for (i = 0 ; i < CLK_MSR_MAX ; ++i) {
5832b45ebefSNeil Armstrong if (!msr_table[i].name)
5842b45ebefSNeil Armstrong continue;
5852b45ebefSNeil Armstrong
5862b45ebefSNeil Armstrong val = meson_measure_best_id(&msr_table[i], &precision);
5872b45ebefSNeil Armstrong if (val < 0)
5882b45ebefSNeil Armstrong return val;
5892b45ebefSNeil Armstrong
5902b45ebefSNeil Armstrong seq_printf(s, " %-20s %10d +/-%dHz\n",
5912b45ebefSNeil Armstrong msr_table[i].name, val, precision);
5922b45ebefSNeil Armstrong }
5932b45ebefSNeil Armstrong
5942b45ebefSNeil Armstrong return 0;
5952b45ebefSNeil Armstrong }
5962b45ebefSNeil Armstrong DEFINE_SHOW_ATTRIBUTE(clk_msr_summary);
5972b45ebefSNeil Armstrong
5982b45ebefSNeil Armstrong static const struct regmap_config meson_clk_msr_regmap_config = {
5992b45ebefSNeil Armstrong .reg_bits = 32,
6002b45ebefSNeil Armstrong .val_bits = 32,
6012b45ebefSNeil Armstrong .reg_stride = 4,
6022b45ebefSNeil Armstrong .max_register = MSR_CLK_REG2,
6032b45ebefSNeil Armstrong };
6042b45ebefSNeil Armstrong
meson_msr_probe(struct platform_device * pdev)6052b45ebefSNeil Armstrong static int meson_msr_probe(struct platform_device *pdev)
6062b45ebefSNeil Armstrong {
6072b45ebefSNeil Armstrong const struct meson_msr_id *match_data;
6082b45ebefSNeil Armstrong struct meson_msr *priv;
6092b45ebefSNeil Armstrong struct dentry *root, *clks;
6102b45ebefSNeil Armstrong void __iomem *base;
6112b45ebefSNeil Armstrong int i;
6122b45ebefSNeil Armstrong
6132b45ebefSNeil Armstrong priv = devm_kzalloc(&pdev->dev, sizeof(struct meson_msr),
6142b45ebefSNeil Armstrong GFP_KERNEL);
6152b45ebefSNeil Armstrong if (!priv)
6162b45ebefSNeil Armstrong return -ENOMEM;
6172b45ebefSNeil Armstrong
6182b45ebefSNeil Armstrong match_data = device_get_match_data(&pdev->dev);
6192b45ebefSNeil Armstrong if (!match_data) {
6202b45ebefSNeil Armstrong dev_err(&pdev->dev, "failed to get match data\n");
6212b45ebefSNeil Armstrong return -ENODEV;
6222b45ebefSNeil Armstrong }
6232b45ebefSNeil Armstrong
6242b45ebefSNeil Armstrong memcpy(priv->msr_table, match_data, sizeof(priv->msr_table));
6252b45ebefSNeil Armstrong
626*d54dbe9fSCai Huoqing base = devm_platform_ioremap_resource(pdev, 0);
627a06bc969SQiheng Lin if (IS_ERR(base))
6282b45ebefSNeil Armstrong return PTR_ERR(base);
6292b45ebefSNeil Armstrong
6302b45ebefSNeil Armstrong priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
6312b45ebefSNeil Armstrong &meson_clk_msr_regmap_config);
6322b45ebefSNeil Armstrong if (IS_ERR(priv->regmap))
6332b45ebefSNeil Armstrong return PTR_ERR(priv->regmap);
6342b45ebefSNeil Armstrong
6352b45ebefSNeil Armstrong root = debugfs_create_dir("meson-clk-msr", NULL);
6362b45ebefSNeil Armstrong clks = debugfs_create_dir("clks", root);
6372b45ebefSNeil Armstrong
6382b45ebefSNeil Armstrong debugfs_create_file("measure_summary", 0444, root,
6392b45ebefSNeil Armstrong priv->msr_table, &clk_msr_summary_fops);
6402b45ebefSNeil Armstrong
6412b45ebefSNeil Armstrong for (i = 0 ; i < CLK_MSR_MAX ; ++i) {
6422b45ebefSNeil Armstrong if (!priv->msr_table[i].name)
6432b45ebefSNeil Armstrong continue;
6442b45ebefSNeil Armstrong
6452b45ebefSNeil Armstrong priv->msr_table[i].priv = priv;
6462b45ebefSNeil Armstrong
6472b45ebefSNeil Armstrong debugfs_create_file(priv->msr_table[i].name, 0444, clks,
6482b45ebefSNeil Armstrong &priv->msr_table[i], &clk_msr_fops);
6492b45ebefSNeil Armstrong }
6502b45ebefSNeil Armstrong
6512b45ebefSNeil Armstrong return 0;
6522b45ebefSNeil Armstrong }
6532b45ebefSNeil Armstrong
6542b45ebefSNeil Armstrong static const struct of_device_id meson_msr_match_table[] = {
6552b45ebefSNeil Armstrong {
6562b45ebefSNeil Armstrong .compatible = "amlogic,meson-gx-clk-measure",
6572b45ebefSNeil Armstrong .data = (void *)clk_msr_gx,
6582b45ebefSNeil Armstrong },
6592b45ebefSNeil Armstrong {
6602b45ebefSNeil Armstrong .compatible = "amlogic,meson8-clk-measure",
6612b45ebefSNeil Armstrong .data = (void *)clk_msr_m8,
6622b45ebefSNeil Armstrong },
6632b45ebefSNeil Armstrong {
6642b45ebefSNeil Armstrong .compatible = "amlogic,meson8b-clk-measure",
6652b45ebefSNeil Armstrong .data = (void *)clk_msr_m8,
6662b45ebefSNeil Armstrong },
66719e0bde7SJerome Brunet {
66819e0bde7SJerome Brunet .compatible = "amlogic,meson-axg-clk-measure",
66919e0bde7SJerome Brunet .data = (void *)clk_msr_axg,
67019e0bde7SJerome Brunet },
67119e0bde7SJerome Brunet {
67219e0bde7SJerome Brunet .compatible = "amlogic,meson-g12a-clk-measure",
67319e0bde7SJerome Brunet .data = (void *)clk_msr_g12a,
67419e0bde7SJerome Brunet },
67562369971SNeil Armstrong {
67662369971SNeil Armstrong .compatible = "amlogic,meson-sm1-clk-measure",
67762369971SNeil Armstrong .data = (void *)clk_msr_sm1,
67862369971SNeil Armstrong },
6792b45ebefSNeil Armstrong { /* sentinel */ }
6802b45ebefSNeil Armstrong };
681d9da1785SKevin Hilman MODULE_DEVICE_TABLE(of, meson_msr_match_table);
6822b45ebefSNeil Armstrong
6832b45ebefSNeil Armstrong static struct platform_driver meson_msr_driver = {
6842b45ebefSNeil Armstrong .probe = meson_msr_probe,
6852b45ebefSNeil Armstrong .driver = {
6862b45ebefSNeil Armstrong .name = "meson_msr",
6872b45ebefSNeil Armstrong .of_match_table = meson_msr_match_table,
6882b45ebefSNeil Armstrong },
6892b45ebefSNeil Armstrong };
690d9da1785SKevin Hilman module_platform_driver(meson_msr_driver);
691d9da1785SKevin Hilman MODULE_LICENSE("GPL v2");
692