162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2018 BayLibre, SAS 462306a36Sopenharmony_ci * Author: Neil Armstrong <narmstrong@baylibre.com> 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/of_address.h> 862306a36Sopenharmony_ci#include <linux/platform_device.h> 962306a36Sopenharmony_ci#include <linux/bitfield.h> 1062306a36Sopenharmony_ci#include <linux/seq_file.h> 1162306a36Sopenharmony_ci#include <linux/debugfs.h> 1262306a36Sopenharmony_ci#include <linux/regmap.h> 1362306a36Sopenharmony_ci#include <linux/module.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistatic DEFINE_MUTEX(measure_lock); 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define MSR_CLK_DUTY 0x0 1862306a36Sopenharmony_ci#define MSR_CLK_REG0 0x4 1962306a36Sopenharmony_ci#define MSR_CLK_REG1 0x8 2062306a36Sopenharmony_ci#define MSR_CLK_REG2 0xc 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define MSR_DURATION GENMASK(15, 0) 2362306a36Sopenharmony_ci#define MSR_ENABLE BIT(16) 2462306a36Sopenharmony_ci#define MSR_CONT BIT(17) /* continuous measurement */ 2562306a36Sopenharmony_ci#define MSR_INTR BIT(18) /* interrupts */ 2662306a36Sopenharmony_ci#define MSR_RUN BIT(19) 2762306a36Sopenharmony_ci#define MSR_CLK_SRC GENMASK(26, 20) 2862306a36Sopenharmony_ci#define MSR_BUSY BIT(31) 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#define MSR_VAL_MASK GENMASK(15, 0) 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#define DIV_MIN 32 3362306a36Sopenharmony_ci#define DIV_STEP 32 3462306a36Sopenharmony_ci#define DIV_MAX 640 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#define CLK_MSR_MAX 128 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistruct meson_msr_id { 3962306a36Sopenharmony_ci struct meson_msr *priv; 4062306a36Sopenharmony_ci unsigned int id; 4162306a36Sopenharmony_ci const char *name; 4262306a36Sopenharmony_ci}; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistruct meson_msr { 4562306a36Sopenharmony_ci struct regmap *regmap; 4662306a36Sopenharmony_ci struct meson_msr_id msr_table[CLK_MSR_MAX]; 4762306a36Sopenharmony_ci}; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci#define CLK_MSR_ID(__id, __name) \ 5062306a36Sopenharmony_ci [__id] = {.id = __id, .name = __name,} 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic struct meson_msr_id clk_msr_m8[CLK_MSR_MAX] = { 5362306a36Sopenharmony_ci CLK_MSR_ID(0, "ring_osc_out_ee0"), 5462306a36Sopenharmony_ci CLK_MSR_ID(1, "ring_osc_out_ee1"), 5562306a36Sopenharmony_ci CLK_MSR_ID(2, "ring_osc_out_ee2"), 5662306a36Sopenharmony_ci CLK_MSR_ID(3, "a9_ring_osck"), 5762306a36Sopenharmony_ci CLK_MSR_ID(6, "vid_pll"), 5862306a36Sopenharmony_ci CLK_MSR_ID(7, "clk81"), 5962306a36Sopenharmony_ci CLK_MSR_ID(8, "encp"), 6062306a36Sopenharmony_ci CLK_MSR_ID(9, "encl"), 6162306a36Sopenharmony_ci CLK_MSR_ID(11, "eth_rmii"), 6262306a36Sopenharmony_ci CLK_MSR_ID(13, "amclk"), 6362306a36Sopenharmony_ci CLK_MSR_ID(14, "fec_clk_0"), 6462306a36Sopenharmony_ci CLK_MSR_ID(15, "fec_clk_1"), 6562306a36Sopenharmony_ci CLK_MSR_ID(16, "fec_clk_2"), 6662306a36Sopenharmony_ci CLK_MSR_ID(18, "a9_clk_div16"), 6762306a36Sopenharmony_ci CLK_MSR_ID(19, "hdmi_sys"), 6862306a36Sopenharmony_ci CLK_MSR_ID(20, "rtc_osc_clk_out"), 6962306a36Sopenharmony_ci CLK_MSR_ID(21, "i2s_clk_in_src0"), 7062306a36Sopenharmony_ci CLK_MSR_ID(22, "clk_rmii_from_pad"), 7162306a36Sopenharmony_ci CLK_MSR_ID(23, "hdmi_ch0_tmds"), 7262306a36Sopenharmony_ci CLK_MSR_ID(24, "lvds_fifo"), 7362306a36Sopenharmony_ci CLK_MSR_ID(26, "sc_clk_int"), 7462306a36Sopenharmony_ci CLK_MSR_ID(28, "sar_adc"), 7562306a36Sopenharmony_ci CLK_MSR_ID(30, "mpll_clk_test_out"), 7662306a36Sopenharmony_ci CLK_MSR_ID(31, "audac_clkpi"), 7762306a36Sopenharmony_ci CLK_MSR_ID(32, "vdac"), 7862306a36Sopenharmony_ci CLK_MSR_ID(33, "sdhc_rx"), 7962306a36Sopenharmony_ci CLK_MSR_ID(34, "sdhc_sd"), 8062306a36Sopenharmony_ci CLK_MSR_ID(35, "mali"), 8162306a36Sopenharmony_ci CLK_MSR_ID(36, "hdmi_tx_pixel"), 8262306a36Sopenharmony_ci CLK_MSR_ID(38, "vdin_meas"), 8362306a36Sopenharmony_ci CLK_MSR_ID(39, "pcm_sclk"), 8462306a36Sopenharmony_ci CLK_MSR_ID(40, "pcm_mclk"), 8562306a36Sopenharmony_ci CLK_MSR_ID(41, "eth_rx_tx"), 8662306a36Sopenharmony_ci CLK_MSR_ID(42, "pwm_d"), 8762306a36Sopenharmony_ci CLK_MSR_ID(43, "pwm_c"), 8862306a36Sopenharmony_ci CLK_MSR_ID(44, "pwm_b"), 8962306a36Sopenharmony_ci CLK_MSR_ID(45, "pwm_a"), 9062306a36Sopenharmony_ci CLK_MSR_ID(46, "pcm2_sclk"), 9162306a36Sopenharmony_ci CLK_MSR_ID(47, "ddr_dpll_pt"), 9262306a36Sopenharmony_ci CLK_MSR_ID(48, "pwm_f"), 9362306a36Sopenharmony_ci CLK_MSR_ID(49, "pwm_e"), 9462306a36Sopenharmony_ci CLK_MSR_ID(59, "hcodec"), 9562306a36Sopenharmony_ci CLK_MSR_ID(60, "usb_32k_alt"), 9662306a36Sopenharmony_ci CLK_MSR_ID(61, "gpio"), 9762306a36Sopenharmony_ci CLK_MSR_ID(62, "vid2_pll"), 9862306a36Sopenharmony_ci CLK_MSR_ID(63, "mipi_csi_cfg"), 9962306a36Sopenharmony_ci}; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cistatic struct meson_msr_id clk_msr_gx[CLK_MSR_MAX] = { 10262306a36Sopenharmony_ci CLK_MSR_ID(0, "ring_osc_out_ee_0"), 10362306a36Sopenharmony_ci CLK_MSR_ID(1, "ring_osc_out_ee_1"), 10462306a36Sopenharmony_ci CLK_MSR_ID(2, "ring_osc_out_ee_2"), 10562306a36Sopenharmony_ci CLK_MSR_ID(3, "a53_ring_osc"), 10662306a36Sopenharmony_ci CLK_MSR_ID(4, "gp0_pll"), 10762306a36Sopenharmony_ci CLK_MSR_ID(6, "enci"), 10862306a36Sopenharmony_ci CLK_MSR_ID(7, "clk81"), 10962306a36Sopenharmony_ci CLK_MSR_ID(8, "encp"), 11062306a36Sopenharmony_ci CLK_MSR_ID(9, "encl"), 11162306a36Sopenharmony_ci CLK_MSR_ID(10, "vdac"), 11262306a36Sopenharmony_ci CLK_MSR_ID(11, "rgmii_tx"), 11362306a36Sopenharmony_ci CLK_MSR_ID(12, "pdm"), 11462306a36Sopenharmony_ci CLK_MSR_ID(13, "amclk"), 11562306a36Sopenharmony_ci CLK_MSR_ID(14, "fec_0"), 11662306a36Sopenharmony_ci CLK_MSR_ID(15, "fec_1"), 11762306a36Sopenharmony_ci CLK_MSR_ID(16, "fec_2"), 11862306a36Sopenharmony_ci CLK_MSR_ID(17, "sys_pll_div16"), 11962306a36Sopenharmony_ci CLK_MSR_ID(18, "sys_cpu_div16"), 12062306a36Sopenharmony_ci CLK_MSR_ID(19, "hdmitx_sys"), 12162306a36Sopenharmony_ci CLK_MSR_ID(20, "rtc_osc_out"), 12262306a36Sopenharmony_ci CLK_MSR_ID(21, "i2s_in_src0"), 12362306a36Sopenharmony_ci CLK_MSR_ID(22, "eth_phy_ref"), 12462306a36Sopenharmony_ci CLK_MSR_ID(23, "hdmi_todig"), 12562306a36Sopenharmony_ci CLK_MSR_ID(26, "sc_int"), 12662306a36Sopenharmony_ci CLK_MSR_ID(28, "sar_adc"), 12762306a36Sopenharmony_ci CLK_MSR_ID(31, "mpll_test_out"), 12862306a36Sopenharmony_ci CLK_MSR_ID(32, "vdec"), 12962306a36Sopenharmony_ci CLK_MSR_ID(35, "mali"), 13062306a36Sopenharmony_ci CLK_MSR_ID(36, "hdmi_tx_pixel"), 13162306a36Sopenharmony_ci CLK_MSR_ID(37, "i958"), 13262306a36Sopenharmony_ci CLK_MSR_ID(38, "vdin_meas"), 13362306a36Sopenharmony_ci CLK_MSR_ID(39, "pcm_sclk"), 13462306a36Sopenharmony_ci CLK_MSR_ID(40, "pcm_mclk"), 13562306a36Sopenharmony_ci CLK_MSR_ID(41, "eth_rx_or_rmii"), 13662306a36Sopenharmony_ci CLK_MSR_ID(42, "mp0_out"), 13762306a36Sopenharmony_ci CLK_MSR_ID(43, "fclk_div5"), 13862306a36Sopenharmony_ci CLK_MSR_ID(44, "pwm_b"), 13962306a36Sopenharmony_ci CLK_MSR_ID(45, "pwm_a"), 14062306a36Sopenharmony_ci CLK_MSR_ID(46, "vpu"), 14162306a36Sopenharmony_ci CLK_MSR_ID(47, "ddr_dpll_pt"), 14262306a36Sopenharmony_ci CLK_MSR_ID(48, "mp1_out"), 14362306a36Sopenharmony_ci CLK_MSR_ID(49, "mp2_out"), 14462306a36Sopenharmony_ci CLK_MSR_ID(50, "mp3_out"), 14562306a36Sopenharmony_ci CLK_MSR_ID(51, "nand_core"), 14662306a36Sopenharmony_ci CLK_MSR_ID(52, "sd_emmc_b"), 14762306a36Sopenharmony_ci CLK_MSR_ID(53, "sd_emmc_a"), 14862306a36Sopenharmony_ci CLK_MSR_ID(55, "vid_pll_div_out"), 14962306a36Sopenharmony_ci CLK_MSR_ID(56, "cci"), 15062306a36Sopenharmony_ci CLK_MSR_ID(57, "wave420l_c"), 15162306a36Sopenharmony_ci CLK_MSR_ID(58, "wave420l_b"), 15262306a36Sopenharmony_ci CLK_MSR_ID(59, "hcodec"), 15362306a36Sopenharmony_ci CLK_MSR_ID(60, "alt_32k"), 15462306a36Sopenharmony_ci CLK_MSR_ID(61, "gpio_msr"), 15562306a36Sopenharmony_ci CLK_MSR_ID(62, "hevc"), 15662306a36Sopenharmony_ci CLK_MSR_ID(66, "vid_lock"), 15762306a36Sopenharmony_ci CLK_MSR_ID(70, "pwm_f"), 15862306a36Sopenharmony_ci CLK_MSR_ID(71, "pwm_e"), 15962306a36Sopenharmony_ci CLK_MSR_ID(72, "pwm_d"), 16062306a36Sopenharmony_ci CLK_MSR_ID(73, "pwm_c"), 16162306a36Sopenharmony_ci CLK_MSR_ID(75, "aoclkx2_int"), 16262306a36Sopenharmony_ci CLK_MSR_ID(76, "aoclk_int"), 16362306a36Sopenharmony_ci CLK_MSR_ID(77, "rng_ring_osc_0"), 16462306a36Sopenharmony_ci CLK_MSR_ID(78, "rng_ring_osc_1"), 16562306a36Sopenharmony_ci CLK_MSR_ID(79, "rng_ring_osc_2"), 16662306a36Sopenharmony_ci CLK_MSR_ID(80, "rng_ring_osc_3"), 16762306a36Sopenharmony_ci CLK_MSR_ID(81, "vapb"), 16862306a36Sopenharmony_ci CLK_MSR_ID(82, "ge2d"), 16962306a36Sopenharmony_ci}; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_cistatic struct meson_msr_id clk_msr_axg[CLK_MSR_MAX] = { 17262306a36Sopenharmony_ci CLK_MSR_ID(0, "ring_osc_out_ee_0"), 17362306a36Sopenharmony_ci CLK_MSR_ID(1, "ring_osc_out_ee_1"), 17462306a36Sopenharmony_ci CLK_MSR_ID(2, "ring_osc_out_ee_2"), 17562306a36Sopenharmony_ci CLK_MSR_ID(3, "a53_ring_osc"), 17662306a36Sopenharmony_ci CLK_MSR_ID(4, "gp0_pll"), 17762306a36Sopenharmony_ci CLK_MSR_ID(5, "gp1_pll"), 17862306a36Sopenharmony_ci CLK_MSR_ID(7, "clk81"), 17962306a36Sopenharmony_ci CLK_MSR_ID(9, "encl"), 18062306a36Sopenharmony_ci CLK_MSR_ID(17, "sys_pll_div16"), 18162306a36Sopenharmony_ci CLK_MSR_ID(18, "sys_cpu_div16"), 18262306a36Sopenharmony_ci CLK_MSR_ID(20, "rtc_osc_out"), 18362306a36Sopenharmony_ci CLK_MSR_ID(23, "mmc_clk"), 18462306a36Sopenharmony_ci CLK_MSR_ID(28, "sar_adc"), 18562306a36Sopenharmony_ci CLK_MSR_ID(31, "mpll_test_out"), 18662306a36Sopenharmony_ci CLK_MSR_ID(40, "mod_eth_tx_clk"), 18762306a36Sopenharmony_ci CLK_MSR_ID(41, "mod_eth_rx_clk_rmii"), 18862306a36Sopenharmony_ci CLK_MSR_ID(42, "mp0_out"), 18962306a36Sopenharmony_ci CLK_MSR_ID(43, "fclk_div5"), 19062306a36Sopenharmony_ci CLK_MSR_ID(44, "pwm_b"), 19162306a36Sopenharmony_ci CLK_MSR_ID(45, "pwm_a"), 19262306a36Sopenharmony_ci CLK_MSR_ID(46, "vpu"), 19362306a36Sopenharmony_ci CLK_MSR_ID(47, "ddr_dpll_pt"), 19462306a36Sopenharmony_ci CLK_MSR_ID(48, "mp1_out"), 19562306a36Sopenharmony_ci CLK_MSR_ID(49, "mp2_out"), 19662306a36Sopenharmony_ci CLK_MSR_ID(50, "mp3_out"), 19762306a36Sopenharmony_ci CLK_MSR_ID(51, "sd_emmm_c"), 19862306a36Sopenharmony_ci CLK_MSR_ID(52, "sd_emmc_b"), 19962306a36Sopenharmony_ci CLK_MSR_ID(61, "gpio_msr"), 20062306a36Sopenharmony_ci CLK_MSR_ID(66, "audio_slv_lrclk_c"), 20162306a36Sopenharmony_ci CLK_MSR_ID(67, "audio_slv_lrclk_b"), 20262306a36Sopenharmony_ci CLK_MSR_ID(68, "audio_slv_lrclk_a"), 20362306a36Sopenharmony_ci CLK_MSR_ID(69, "audio_slv_sclk_c"), 20462306a36Sopenharmony_ci CLK_MSR_ID(70, "audio_slv_sclk_b"), 20562306a36Sopenharmony_ci CLK_MSR_ID(71, "audio_slv_sclk_a"), 20662306a36Sopenharmony_ci CLK_MSR_ID(72, "pwm_d"), 20762306a36Sopenharmony_ci CLK_MSR_ID(73, "pwm_c"), 20862306a36Sopenharmony_ci CLK_MSR_ID(74, "wifi_beacon"), 20962306a36Sopenharmony_ci CLK_MSR_ID(75, "tdmin_lb_lrcl"), 21062306a36Sopenharmony_ci CLK_MSR_ID(76, "tdmin_lb_sclk"), 21162306a36Sopenharmony_ci CLK_MSR_ID(77, "rng_ring_osc_0"), 21262306a36Sopenharmony_ci CLK_MSR_ID(78, "rng_ring_osc_1"), 21362306a36Sopenharmony_ci CLK_MSR_ID(79, "rng_ring_osc_2"), 21462306a36Sopenharmony_ci CLK_MSR_ID(80, "rng_ring_osc_3"), 21562306a36Sopenharmony_ci CLK_MSR_ID(81, "vapb"), 21662306a36Sopenharmony_ci CLK_MSR_ID(82, "ge2d"), 21762306a36Sopenharmony_ci CLK_MSR_ID(84, "audio_resample"), 21862306a36Sopenharmony_ci CLK_MSR_ID(85, "audio_pdm_sys"), 21962306a36Sopenharmony_ci CLK_MSR_ID(86, "audio_spdifout"), 22062306a36Sopenharmony_ci CLK_MSR_ID(87, "audio_spdifin"), 22162306a36Sopenharmony_ci CLK_MSR_ID(88, "audio_lrclk_f"), 22262306a36Sopenharmony_ci CLK_MSR_ID(89, "audio_lrclk_e"), 22362306a36Sopenharmony_ci CLK_MSR_ID(90, "audio_lrclk_d"), 22462306a36Sopenharmony_ci CLK_MSR_ID(91, "audio_lrclk_c"), 22562306a36Sopenharmony_ci CLK_MSR_ID(92, "audio_lrclk_b"), 22662306a36Sopenharmony_ci CLK_MSR_ID(93, "audio_lrclk_a"), 22762306a36Sopenharmony_ci CLK_MSR_ID(94, "audio_sclk_f"), 22862306a36Sopenharmony_ci CLK_MSR_ID(95, "audio_sclk_e"), 22962306a36Sopenharmony_ci CLK_MSR_ID(96, "audio_sclk_d"), 23062306a36Sopenharmony_ci CLK_MSR_ID(97, "audio_sclk_c"), 23162306a36Sopenharmony_ci CLK_MSR_ID(98, "audio_sclk_b"), 23262306a36Sopenharmony_ci CLK_MSR_ID(99, "audio_sclk_a"), 23362306a36Sopenharmony_ci CLK_MSR_ID(100, "audio_mclk_f"), 23462306a36Sopenharmony_ci CLK_MSR_ID(101, "audio_mclk_e"), 23562306a36Sopenharmony_ci CLK_MSR_ID(102, "audio_mclk_d"), 23662306a36Sopenharmony_ci CLK_MSR_ID(103, "audio_mclk_c"), 23762306a36Sopenharmony_ci CLK_MSR_ID(104, "audio_mclk_b"), 23862306a36Sopenharmony_ci CLK_MSR_ID(105, "audio_mclk_a"), 23962306a36Sopenharmony_ci CLK_MSR_ID(106, "pcie_refclk_n"), 24062306a36Sopenharmony_ci CLK_MSR_ID(107, "pcie_refclk_p"), 24162306a36Sopenharmony_ci CLK_MSR_ID(108, "audio_locker_out"), 24262306a36Sopenharmony_ci CLK_MSR_ID(109, "audio_locker_in"), 24362306a36Sopenharmony_ci}; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_cistatic struct meson_msr_id clk_msr_g12a[CLK_MSR_MAX] = { 24662306a36Sopenharmony_ci CLK_MSR_ID(0, "ring_osc_out_ee_0"), 24762306a36Sopenharmony_ci CLK_MSR_ID(1, "ring_osc_out_ee_1"), 24862306a36Sopenharmony_ci CLK_MSR_ID(2, "ring_osc_out_ee_2"), 24962306a36Sopenharmony_ci CLK_MSR_ID(3, "sys_cpu_ring_osc"), 25062306a36Sopenharmony_ci CLK_MSR_ID(4, "gp0_pll"), 25162306a36Sopenharmony_ci CLK_MSR_ID(6, "enci"), 25262306a36Sopenharmony_ci CLK_MSR_ID(7, "clk81"), 25362306a36Sopenharmony_ci CLK_MSR_ID(8, "encp"), 25462306a36Sopenharmony_ci CLK_MSR_ID(9, "encl"), 25562306a36Sopenharmony_ci CLK_MSR_ID(10, "vdac"), 25662306a36Sopenharmony_ci CLK_MSR_ID(11, "eth_tx"), 25762306a36Sopenharmony_ci CLK_MSR_ID(12, "hifi_pll"), 25862306a36Sopenharmony_ci CLK_MSR_ID(13, "mod_tcon"), 25962306a36Sopenharmony_ci CLK_MSR_ID(14, "fec_0"), 26062306a36Sopenharmony_ci CLK_MSR_ID(15, "fec_1"), 26162306a36Sopenharmony_ci CLK_MSR_ID(16, "fec_2"), 26262306a36Sopenharmony_ci CLK_MSR_ID(17, "sys_pll_div16"), 26362306a36Sopenharmony_ci CLK_MSR_ID(18, "sys_cpu_div16"), 26462306a36Sopenharmony_ci CLK_MSR_ID(19, "lcd_an_ph2"), 26562306a36Sopenharmony_ci CLK_MSR_ID(20, "rtc_osc_out"), 26662306a36Sopenharmony_ci CLK_MSR_ID(21, "lcd_an_ph3"), 26762306a36Sopenharmony_ci CLK_MSR_ID(22, "eth_phy_ref"), 26862306a36Sopenharmony_ci CLK_MSR_ID(23, "mpll_50m"), 26962306a36Sopenharmony_ci CLK_MSR_ID(24, "eth_125m"), 27062306a36Sopenharmony_ci CLK_MSR_ID(25, "eth_rmii"), 27162306a36Sopenharmony_ci CLK_MSR_ID(26, "sc_int"), 27262306a36Sopenharmony_ci CLK_MSR_ID(27, "in_mac"), 27362306a36Sopenharmony_ci CLK_MSR_ID(28, "sar_adc"), 27462306a36Sopenharmony_ci CLK_MSR_ID(29, "pcie_inp"), 27562306a36Sopenharmony_ci CLK_MSR_ID(30, "pcie_inn"), 27662306a36Sopenharmony_ci CLK_MSR_ID(31, "mpll_test_out"), 27762306a36Sopenharmony_ci CLK_MSR_ID(32, "vdec"), 27862306a36Sopenharmony_ci CLK_MSR_ID(33, "sys_cpu_ring_osc_1"), 27962306a36Sopenharmony_ci CLK_MSR_ID(34, "eth_mpll_50m"), 28062306a36Sopenharmony_ci CLK_MSR_ID(35, "mali"), 28162306a36Sopenharmony_ci CLK_MSR_ID(36, "hdmi_tx_pixel"), 28262306a36Sopenharmony_ci CLK_MSR_ID(37, "cdac"), 28362306a36Sopenharmony_ci CLK_MSR_ID(38, "vdin_meas"), 28462306a36Sopenharmony_ci CLK_MSR_ID(39, "bt656"), 28562306a36Sopenharmony_ci CLK_MSR_ID(41, "eth_rx_or_rmii"), 28662306a36Sopenharmony_ci CLK_MSR_ID(42, "mp0_out"), 28762306a36Sopenharmony_ci CLK_MSR_ID(43, "fclk_div5"), 28862306a36Sopenharmony_ci CLK_MSR_ID(44, "pwm_b"), 28962306a36Sopenharmony_ci CLK_MSR_ID(45, "pwm_a"), 29062306a36Sopenharmony_ci CLK_MSR_ID(46, "vpu"), 29162306a36Sopenharmony_ci CLK_MSR_ID(47, "ddr_dpll_pt"), 29262306a36Sopenharmony_ci CLK_MSR_ID(48, "mp1_out"), 29362306a36Sopenharmony_ci CLK_MSR_ID(49, "mp2_out"), 29462306a36Sopenharmony_ci CLK_MSR_ID(50, "mp3_out"), 29562306a36Sopenharmony_ci CLK_MSR_ID(51, "sd_emmc_c"), 29662306a36Sopenharmony_ci CLK_MSR_ID(52, "sd_emmc_b"), 29762306a36Sopenharmony_ci CLK_MSR_ID(53, "sd_emmc_a"), 29862306a36Sopenharmony_ci CLK_MSR_ID(54, "vpu_clkc"), 29962306a36Sopenharmony_ci CLK_MSR_ID(55, "vid_pll_div_out"), 30062306a36Sopenharmony_ci CLK_MSR_ID(56, "wave420l_a"), 30162306a36Sopenharmony_ci CLK_MSR_ID(57, "wave420l_c"), 30262306a36Sopenharmony_ci CLK_MSR_ID(58, "wave420l_b"), 30362306a36Sopenharmony_ci CLK_MSR_ID(59, "hcodec"), 30462306a36Sopenharmony_ci CLK_MSR_ID(61, "gpio_msr"), 30562306a36Sopenharmony_ci CLK_MSR_ID(62, "hevcb"), 30662306a36Sopenharmony_ci CLK_MSR_ID(63, "dsi_meas"), 30762306a36Sopenharmony_ci CLK_MSR_ID(64, "spicc_1"), 30862306a36Sopenharmony_ci CLK_MSR_ID(65, "spicc_0"), 30962306a36Sopenharmony_ci CLK_MSR_ID(66, "vid_lock"), 31062306a36Sopenharmony_ci CLK_MSR_ID(67, "dsi_phy"), 31162306a36Sopenharmony_ci CLK_MSR_ID(68, "hdcp22_esm"), 31262306a36Sopenharmony_ci CLK_MSR_ID(69, "hdcp22_skp"), 31362306a36Sopenharmony_ci CLK_MSR_ID(70, "pwm_f"), 31462306a36Sopenharmony_ci CLK_MSR_ID(71, "pwm_e"), 31562306a36Sopenharmony_ci CLK_MSR_ID(72, "pwm_d"), 31662306a36Sopenharmony_ci CLK_MSR_ID(73, "pwm_c"), 31762306a36Sopenharmony_ci CLK_MSR_ID(75, "hevcf"), 31862306a36Sopenharmony_ci CLK_MSR_ID(77, "rng_ring_osc_0"), 31962306a36Sopenharmony_ci CLK_MSR_ID(78, "rng_ring_osc_1"), 32062306a36Sopenharmony_ci CLK_MSR_ID(79, "rng_ring_osc_2"), 32162306a36Sopenharmony_ci CLK_MSR_ID(80, "rng_ring_osc_3"), 32262306a36Sopenharmony_ci CLK_MSR_ID(81, "vapb"), 32362306a36Sopenharmony_ci CLK_MSR_ID(82, "ge2d"), 32462306a36Sopenharmony_ci CLK_MSR_ID(83, "co_rx"), 32562306a36Sopenharmony_ci CLK_MSR_ID(84, "co_tx"), 32662306a36Sopenharmony_ci CLK_MSR_ID(89, "hdmi_todig"), 32762306a36Sopenharmony_ci CLK_MSR_ID(90, "hdmitx_sys"), 32862306a36Sopenharmony_ci CLK_MSR_ID(91, "sys_cpub_div16"), 32962306a36Sopenharmony_ci CLK_MSR_ID(92, "sys_pll_cpub_div16"), 33062306a36Sopenharmony_ci CLK_MSR_ID(94, "eth_phy_rx"), 33162306a36Sopenharmony_ci CLK_MSR_ID(95, "eth_phy_pll"), 33262306a36Sopenharmony_ci CLK_MSR_ID(96, "vpu_b"), 33362306a36Sopenharmony_ci CLK_MSR_ID(97, "cpu_b_tmp"), 33462306a36Sopenharmony_ci CLK_MSR_ID(98, "ts"), 33562306a36Sopenharmony_ci CLK_MSR_ID(99, "ring_osc_out_ee_3"), 33662306a36Sopenharmony_ci CLK_MSR_ID(100, "ring_osc_out_ee_4"), 33762306a36Sopenharmony_ci CLK_MSR_ID(101, "ring_osc_out_ee_5"), 33862306a36Sopenharmony_ci CLK_MSR_ID(102, "ring_osc_out_ee_6"), 33962306a36Sopenharmony_ci CLK_MSR_ID(103, "ring_osc_out_ee_7"), 34062306a36Sopenharmony_ci CLK_MSR_ID(104, "ring_osc_out_ee_8"), 34162306a36Sopenharmony_ci CLK_MSR_ID(105, "ring_osc_out_ee_9"), 34262306a36Sopenharmony_ci CLK_MSR_ID(106, "ephy_test"), 34362306a36Sopenharmony_ci CLK_MSR_ID(107, "au_dac_g128x"), 34462306a36Sopenharmony_ci CLK_MSR_ID(108, "audio_locker_out"), 34562306a36Sopenharmony_ci CLK_MSR_ID(109, "audio_locker_in"), 34662306a36Sopenharmony_ci CLK_MSR_ID(110, "audio_tdmout_c_sclk"), 34762306a36Sopenharmony_ci CLK_MSR_ID(111, "audio_tdmout_b_sclk"), 34862306a36Sopenharmony_ci CLK_MSR_ID(112, "audio_tdmout_a_sclk"), 34962306a36Sopenharmony_ci CLK_MSR_ID(113, "audio_tdmin_lb_sclk"), 35062306a36Sopenharmony_ci CLK_MSR_ID(114, "audio_tdmin_c_sclk"), 35162306a36Sopenharmony_ci CLK_MSR_ID(115, "audio_tdmin_b_sclk"), 35262306a36Sopenharmony_ci CLK_MSR_ID(116, "audio_tdmin_a_sclk"), 35362306a36Sopenharmony_ci CLK_MSR_ID(117, "audio_resample"), 35462306a36Sopenharmony_ci CLK_MSR_ID(118, "audio_pdm_sys"), 35562306a36Sopenharmony_ci CLK_MSR_ID(119, "audio_spdifout_b"), 35662306a36Sopenharmony_ci CLK_MSR_ID(120, "audio_spdifout"), 35762306a36Sopenharmony_ci CLK_MSR_ID(121, "audio_spdifin"), 35862306a36Sopenharmony_ci CLK_MSR_ID(122, "audio_pdm_dclk"), 35962306a36Sopenharmony_ci}; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_cistatic struct meson_msr_id clk_msr_sm1[CLK_MSR_MAX] = { 36262306a36Sopenharmony_ci CLK_MSR_ID(0, "ring_osc_out_ee_0"), 36362306a36Sopenharmony_ci CLK_MSR_ID(1, "ring_osc_out_ee_1"), 36462306a36Sopenharmony_ci CLK_MSR_ID(2, "ring_osc_out_ee_2"), 36562306a36Sopenharmony_ci CLK_MSR_ID(3, "ring_osc_out_ee_3"), 36662306a36Sopenharmony_ci CLK_MSR_ID(4, "gp0_pll"), 36762306a36Sopenharmony_ci CLK_MSR_ID(5, "gp1_pll"), 36862306a36Sopenharmony_ci CLK_MSR_ID(6, "enci"), 36962306a36Sopenharmony_ci CLK_MSR_ID(7, "clk81"), 37062306a36Sopenharmony_ci CLK_MSR_ID(8, "encp"), 37162306a36Sopenharmony_ci CLK_MSR_ID(9, "encl"), 37262306a36Sopenharmony_ci CLK_MSR_ID(10, "vdac"), 37362306a36Sopenharmony_ci CLK_MSR_ID(11, "eth_tx"), 37462306a36Sopenharmony_ci CLK_MSR_ID(12, "hifi_pll"), 37562306a36Sopenharmony_ci CLK_MSR_ID(13, "mod_tcon"), 37662306a36Sopenharmony_ci CLK_MSR_ID(14, "fec_0"), 37762306a36Sopenharmony_ci CLK_MSR_ID(15, "fec_1"), 37862306a36Sopenharmony_ci CLK_MSR_ID(16, "fec_2"), 37962306a36Sopenharmony_ci CLK_MSR_ID(17, "sys_pll_div16"), 38062306a36Sopenharmony_ci CLK_MSR_ID(18, "sys_cpu_div16"), 38162306a36Sopenharmony_ci CLK_MSR_ID(19, "lcd_an_ph2"), 38262306a36Sopenharmony_ci CLK_MSR_ID(20, "rtc_osc_out"), 38362306a36Sopenharmony_ci CLK_MSR_ID(21, "lcd_an_ph3"), 38462306a36Sopenharmony_ci CLK_MSR_ID(22, "eth_phy_ref"), 38562306a36Sopenharmony_ci CLK_MSR_ID(23, "mpll_50m"), 38662306a36Sopenharmony_ci CLK_MSR_ID(24, "eth_125m"), 38762306a36Sopenharmony_ci CLK_MSR_ID(25, "eth_rmii"), 38862306a36Sopenharmony_ci CLK_MSR_ID(26, "sc_int"), 38962306a36Sopenharmony_ci CLK_MSR_ID(27, "in_mac"), 39062306a36Sopenharmony_ci CLK_MSR_ID(28, "sar_adc"), 39162306a36Sopenharmony_ci CLK_MSR_ID(29, "pcie_inp"), 39262306a36Sopenharmony_ci CLK_MSR_ID(30, "pcie_inn"), 39362306a36Sopenharmony_ci CLK_MSR_ID(31, "mpll_test_out"), 39462306a36Sopenharmony_ci CLK_MSR_ID(32, "vdec"), 39562306a36Sopenharmony_ci CLK_MSR_ID(34, "eth_mpll_50m"), 39662306a36Sopenharmony_ci CLK_MSR_ID(35, "mali"), 39762306a36Sopenharmony_ci CLK_MSR_ID(36, "hdmi_tx_pixel"), 39862306a36Sopenharmony_ci CLK_MSR_ID(37, "cdac"), 39962306a36Sopenharmony_ci CLK_MSR_ID(38, "vdin_meas"), 40062306a36Sopenharmony_ci CLK_MSR_ID(39, "bt656"), 40162306a36Sopenharmony_ci CLK_MSR_ID(40, "arm_ring_osc_out_4"), 40262306a36Sopenharmony_ci CLK_MSR_ID(41, "eth_rx_or_rmii"), 40362306a36Sopenharmony_ci CLK_MSR_ID(42, "mp0_out"), 40462306a36Sopenharmony_ci CLK_MSR_ID(43, "fclk_div5"), 40562306a36Sopenharmony_ci CLK_MSR_ID(44, "pwm_b"), 40662306a36Sopenharmony_ci CLK_MSR_ID(45, "pwm_a"), 40762306a36Sopenharmony_ci CLK_MSR_ID(46, "vpu"), 40862306a36Sopenharmony_ci CLK_MSR_ID(47, "ddr_dpll_pt"), 40962306a36Sopenharmony_ci CLK_MSR_ID(48, "mp1_out"), 41062306a36Sopenharmony_ci CLK_MSR_ID(49, "mp2_out"), 41162306a36Sopenharmony_ci CLK_MSR_ID(50, "mp3_out"), 41262306a36Sopenharmony_ci CLK_MSR_ID(51, "sd_emmc_c"), 41362306a36Sopenharmony_ci CLK_MSR_ID(52, "sd_emmc_b"), 41462306a36Sopenharmony_ci CLK_MSR_ID(53, "sd_emmc_a"), 41562306a36Sopenharmony_ci CLK_MSR_ID(54, "vpu_clkc"), 41662306a36Sopenharmony_ci CLK_MSR_ID(55, "vid_pll_div_out"), 41762306a36Sopenharmony_ci CLK_MSR_ID(56, "wave420l_a"), 41862306a36Sopenharmony_ci CLK_MSR_ID(57, "wave420l_c"), 41962306a36Sopenharmony_ci CLK_MSR_ID(58, "wave420l_b"), 42062306a36Sopenharmony_ci CLK_MSR_ID(59, "hcodec"), 42162306a36Sopenharmony_ci CLK_MSR_ID(60, "arm_ring_osc_out_5"), 42262306a36Sopenharmony_ci CLK_MSR_ID(61, "gpio_msr"), 42362306a36Sopenharmony_ci CLK_MSR_ID(62, "hevcb"), 42462306a36Sopenharmony_ci CLK_MSR_ID(63, "dsi_meas"), 42562306a36Sopenharmony_ci CLK_MSR_ID(64, "spicc_1"), 42662306a36Sopenharmony_ci CLK_MSR_ID(65, "spicc_0"), 42762306a36Sopenharmony_ci CLK_MSR_ID(66, "vid_lock"), 42862306a36Sopenharmony_ci CLK_MSR_ID(67, "dsi_phy"), 42962306a36Sopenharmony_ci CLK_MSR_ID(68, "hdcp22_esm"), 43062306a36Sopenharmony_ci CLK_MSR_ID(69, "hdcp22_skp"), 43162306a36Sopenharmony_ci CLK_MSR_ID(70, "pwm_f"), 43262306a36Sopenharmony_ci CLK_MSR_ID(71, "pwm_e"), 43362306a36Sopenharmony_ci CLK_MSR_ID(72, "pwm_d"), 43462306a36Sopenharmony_ci CLK_MSR_ID(73, "pwm_c"), 43562306a36Sopenharmony_ci CLK_MSR_ID(74, "arm_ring_osc_out_6"), 43662306a36Sopenharmony_ci CLK_MSR_ID(75, "hevcf"), 43762306a36Sopenharmony_ci CLK_MSR_ID(76, "arm_ring_osc_out_7"), 43862306a36Sopenharmony_ci CLK_MSR_ID(77, "rng_ring_osc_0"), 43962306a36Sopenharmony_ci CLK_MSR_ID(78, "rng_ring_osc_1"), 44062306a36Sopenharmony_ci CLK_MSR_ID(79, "rng_ring_osc_2"), 44162306a36Sopenharmony_ci CLK_MSR_ID(80, "rng_ring_osc_3"), 44262306a36Sopenharmony_ci CLK_MSR_ID(81, "vapb"), 44362306a36Sopenharmony_ci CLK_MSR_ID(82, "ge2d"), 44462306a36Sopenharmony_ci CLK_MSR_ID(83, "co_rx"), 44562306a36Sopenharmony_ci CLK_MSR_ID(84, "co_tx"), 44662306a36Sopenharmony_ci CLK_MSR_ID(85, "arm_ring_osc_out_8"), 44762306a36Sopenharmony_ci CLK_MSR_ID(86, "arm_ring_osc_out_9"), 44862306a36Sopenharmony_ci CLK_MSR_ID(87, "mipi_dsi_phy"), 44962306a36Sopenharmony_ci CLK_MSR_ID(88, "cis2_adapt"), 45062306a36Sopenharmony_ci CLK_MSR_ID(89, "hdmi_todig"), 45162306a36Sopenharmony_ci CLK_MSR_ID(90, "hdmitx_sys"), 45262306a36Sopenharmony_ci CLK_MSR_ID(91, "nna_core"), 45362306a36Sopenharmony_ci CLK_MSR_ID(92, "nna_axi"), 45462306a36Sopenharmony_ci CLK_MSR_ID(93, "vad"), 45562306a36Sopenharmony_ci CLK_MSR_ID(94, "eth_phy_rx"), 45662306a36Sopenharmony_ci CLK_MSR_ID(95, "eth_phy_pll"), 45762306a36Sopenharmony_ci CLK_MSR_ID(96, "vpu_b"), 45862306a36Sopenharmony_ci CLK_MSR_ID(97, "cpu_b_tmp"), 45962306a36Sopenharmony_ci CLK_MSR_ID(98, "ts"), 46062306a36Sopenharmony_ci CLK_MSR_ID(99, "arm_ring_osc_out_10"), 46162306a36Sopenharmony_ci CLK_MSR_ID(100, "arm_ring_osc_out_11"), 46262306a36Sopenharmony_ci CLK_MSR_ID(101, "arm_ring_osc_out_12"), 46362306a36Sopenharmony_ci CLK_MSR_ID(102, "arm_ring_osc_out_13"), 46462306a36Sopenharmony_ci CLK_MSR_ID(103, "arm_ring_osc_out_14"), 46562306a36Sopenharmony_ci CLK_MSR_ID(104, "arm_ring_osc_out_15"), 46662306a36Sopenharmony_ci CLK_MSR_ID(105, "arm_ring_osc_out_16"), 46762306a36Sopenharmony_ci CLK_MSR_ID(106, "ephy_test"), 46862306a36Sopenharmony_ci CLK_MSR_ID(107, "au_dac_g128x"), 46962306a36Sopenharmony_ci CLK_MSR_ID(108, "audio_locker_out"), 47062306a36Sopenharmony_ci CLK_MSR_ID(109, "audio_locker_in"), 47162306a36Sopenharmony_ci CLK_MSR_ID(110, "audio_tdmout_c_sclk"), 47262306a36Sopenharmony_ci CLK_MSR_ID(111, "audio_tdmout_b_sclk"), 47362306a36Sopenharmony_ci CLK_MSR_ID(112, "audio_tdmout_a_sclk"), 47462306a36Sopenharmony_ci CLK_MSR_ID(113, "audio_tdmin_lb_sclk"), 47562306a36Sopenharmony_ci CLK_MSR_ID(114, "audio_tdmin_c_sclk"), 47662306a36Sopenharmony_ci CLK_MSR_ID(115, "audio_tdmin_b_sclk"), 47762306a36Sopenharmony_ci CLK_MSR_ID(116, "audio_tdmin_a_sclk"), 47862306a36Sopenharmony_ci CLK_MSR_ID(117, "audio_resample"), 47962306a36Sopenharmony_ci CLK_MSR_ID(118, "audio_pdm_sys"), 48062306a36Sopenharmony_ci CLK_MSR_ID(119, "audio_spdifout_b"), 48162306a36Sopenharmony_ci CLK_MSR_ID(120, "audio_spdifout"), 48262306a36Sopenharmony_ci CLK_MSR_ID(121, "audio_spdifin"), 48362306a36Sopenharmony_ci CLK_MSR_ID(122, "audio_pdm_dclk"), 48462306a36Sopenharmony_ci CLK_MSR_ID(123, "audio_resampled"), 48562306a36Sopenharmony_ci CLK_MSR_ID(124, "earcrx_pll"), 48662306a36Sopenharmony_ci CLK_MSR_ID(125, "earcrx_pll_test"), 48762306a36Sopenharmony_ci CLK_MSR_ID(126, "csi_phy0"), 48862306a36Sopenharmony_ci CLK_MSR_ID(127, "csi2_data"), 48962306a36Sopenharmony_ci}; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_cistatic int meson_measure_id(struct meson_msr_id *clk_msr_id, 49262306a36Sopenharmony_ci unsigned int duration) 49362306a36Sopenharmony_ci{ 49462306a36Sopenharmony_ci struct meson_msr *priv = clk_msr_id->priv; 49562306a36Sopenharmony_ci unsigned int val; 49662306a36Sopenharmony_ci int ret; 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ci ret = mutex_lock_interruptible(&measure_lock); 49962306a36Sopenharmony_ci if (ret) 50062306a36Sopenharmony_ci return ret; 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci regmap_write(priv->regmap, MSR_CLK_REG0, 0); 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci /* Set measurement duration */ 50562306a36Sopenharmony_ci regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_DURATION, 50662306a36Sopenharmony_ci FIELD_PREP(MSR_DURATION, duration - 1)); 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci /* Set ID */ 50962306a36Sopenharmony_ci regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_CLK_SRC, 51062306a36Sopenharmony_ci FIELD_PREP(MSR_CLK_SRC, clk_msr_id->id)); 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci /* Enable & Start */ 51362306a36Sopenharmony_ci regmap_update_bits(priv->regmap, MSR_CLK_REG0, 51462306a36Sopenharmony_ci MSR_RUN | MSR_ENABLE, 51562306a36Sopenharmony_ci MSR_RUN | MSR_ENABLE); 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0, 51862306a36Sopenharmony_ci val, !(val & MSR_BUSY), 10, 10000); 51962306a36Sopenharmony_ci if (ret) { 52062306a36Sopenharmony_ci mutex_unlock(&measure_lock); 52162306a36Sopenharmony_ci return ret; 52262306a36Sopenharmony_ci } 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci /* Disable */ 52562306a36Sopenharmony_ci regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0); 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci /* Get the value in multiple of gate time counts */ 52862306a36Sopenharmony_ci regmap_read(priv->regmap, MSR_CLK_REG2, &val); 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci mutex_unlock(&measure_lock); 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci if (val >= MSR_VAL_MASK) 53362306a36Sopenharmony_ci return -EINVAL; 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci return DIV_ROUND_CLOSEST_ULL((val & MSR_VAL_MASK) * 1000000ULL, 53662306a36Sopenharmony_ci duration); 53762306a36Sopenharmony_ci} 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_cistatic int meson_measure_best_id(struct meson_msr_id *clk_msr_id, 54062306a36Sopenharmony_ci unsigned int *precision) 54162306a36Sopenharmony_ci{ 54262306a36Sopenharmony_ci unsigned int duration = DIV_MAX; 54362306a36Sopenharmony_ci int ret; 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci /* Start from max duration and down to min duration */ 54662306a36Sopenharmony_ci do { 54762306a36Sopenharmony_ci ret = meson_measure_id(clk_msr_id, duration); 54862306a36Sopenharmony_ci if (ret >= 0) 54962306a36Sopenharmony_ci *precision = (2 * 1000000) / duration; 55062306a36Sopenharmony_ci else 55162306a36Sopenharmony_ci duration -= DIV_STEP; 55262306a36Sopenharmony_ci } while (duration >= DIV_MIN && ret == -EINVAL); 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci return ret; 55562306a36Sopenharmony_ci} 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_cistatic int clk_msr_show(struct seq_file *s, void *data) 55862306a36Sopenharmony_ci{ 55962306a36Sopenharmony_ci struct meson_msr_id *clk_msr_id = s->private; 56062306a36Sopenharmony_ci unsigned int precision = 0; 56162306a36Sopenharmony_ci int val; 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci val = meson_measure_best_id(clk_msr_id, &precision); 56462306a36Sopenharmony_ci if (val < 0) 56562306a36Sopenharmony_ci return val; 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci seq_printf(s, "%d\t+/-%dHz\n", val, precision); 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_ci return 0; 57062306a36Sopenharmony_ci} 57162306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(clk_msr); 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_cistatic int clk_msr_summary_show(struct seq_file *s, void *data) 57462306a36Sopenharmony_ci{ 57562306a36Sopenharmony_ci struct meson_msr_id *msr_table = s->private; 57662306a36Sopenharmony_ci unsigned int precision = 0; 57762306a36Sopenharmony_ci int val, i; 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci seq_puts(s, " clock rate precision\n"); 58062306a36Sopenharmony_ci seq_puts(s, "---------------------------------------------\n"); 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci for (i = 0 ; i < CLK_MSR_MAX ; ++i) { 58362306a36Sopenharmony_ci if (!msr_table[i].name) 58462306a36Sopenharmony_ci continue; 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci val = meson_measure_best_id(&msr_table[i], &precision); 58762306a36Sopenharmony_ci if (val < 0) 58862306a36Sopenharmony_ci return val; 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci seq_printf(s, " %-20s %10d +/-%dHz\n", 59162306a36Sopenharmony_ci msr_table[i].name, val, precision); 59262306a36Sopenharmony_ci } 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci return 0; 59562306a36Sopenharmony_ci} 59662306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(clk_msr_summary); 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_cistatic const struct regmap_config meson_clk_msr_regmap_config = { 59962306a36Sopenharmony_ci .reg_bits = 32, 60062306a36Sopenharmony_ci .val_bits = 32, 60162306a36Sopenharmony_ci .reg_stride = 4, 60262306a36Sopenharmony_ci .max_register = MSR_CLK_REG2, 60362306a36Sopenharmony_ci}; 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_cistatic int meson_msr_probe(struct platform_device *pdev) 60662306a36Sopenharmony_ci{ 60762306a36Sopenharmony_ci const struct meson_msr_id *match_data; 60862306a36Sopenharmony_ci struct meson_msr *priv; 60962306a36Sopenharmony_ci struct dentry *root, *clks; 61062306a36Sopenharmony_ci void __iomem *base; 61162306a36Sopenharmony_ci int i; 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci priv = devm_kzalloc(&pdev->dev, sizeof(struct meson_msr), 61462306a36Sopenharmony_ci GFP_KERNEL); 61562306a36Sopenharmony_ci if (!priv) 61662306a36Sopenharmony_ci return -ENOMEM; 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci match_data = device_get_match_data(&pdev->dev); 61962306a36Sopenharmony_ci if (!match_data) { 62062306a36Sopenharmony_ci dev_err(&pdev->dev, "failed to get match data\n"); 62162306a36Sopenharmony_ci return -ENODEV; 62262306a36Sopenharmony_ci } 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci memcpy(priv->msr_table, match_data, sizeof(priv->msr_table)); 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci base = devm_platform_ioremap_resource(pdev, 0); 62762306a36Sopenharmony_ci if (IS_ERR(base)) 62862306a36Sopenharmony_ci return PTR_ERR(base); 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, 63162306a36Sopenharmony_ci &meson_clk_msr_regmap_config); 63262306a36Sopenharmony_ci if (IS_ERR(priv->regmap)) 63362306a36Sopenharmony_ci return PTR_ERR(priv->regmap); 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci root = debugfs_create_dir("meson-clk-msr", NULL); 63662306a36Sopenharmony_ci clks = debugfs_create_dir("clks", root); 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci debugfs_create_file("measure_summary", 0444, root, 63962306a36Sopenharmony_ci priv->msr_table, &clk_msr_summary_fops); 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci for (i = 0 ; i < CLK_MSR_MAX ; ++i) { 64262306a36Sopenharmony_ci if (!priv->msr_table[i].name) 64362306a36Sopenharmony_ci continue; 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci priv->msr_table[i].priv = priv; 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ci debugfs_create_file(priv->msr_table[i].name, 0444, clks, 64862306a36Sopenharmony_ci &priv->msr_table[i], &clk_msr_fops); 64962306a36Sopenharmony_ci } 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci return 0; 65262306a36Sopenharmony_ci} 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_cistatic const struct of_device_id meson_msr_match_table[] = { 65562306a36Sopenharmony_ci { 65662306a36Sopenharmony_ci .compatible = "amlogic,meson-gx-clk-measure", 65762306a36Sopenharmony_ci .data = (void *)clk_msr_gx, 65862306a36Sopenharmony_ci }, 65962306a36Sopenharmony_ci { 66062306a36Sopenharmony_ci .compatible = "amlogic,meson8-clk-measure", 66162306a36Sopenharmony_ci .data = (void *)clk_msr_m8, 66262306a36Sopenharmony_ci }, 66362306a36Sopenharmony_ci { 66462306a36Sopenharmony_ci .compatible = "amlogic,meson8b-clk-measure", 66562306a36Sopenharmony_ci .data = (void *)clk_msr_m8, 66662306a36Sopenharmony_ci }, 66762306a36Sopenharmony_ci { 66862306a36Sopenharmony_ci .compatible = "amlogic,meson-axg-clk-measure", 66962306a36Sopenharmony_ci .data = (void *)clk_msr_axg, 67062306a36Sopenharmony_ci }, 67162306a36Sopenharmony_ci { 67262306a36Sopenharmony_ci .compatible = "amlogic,meson-g12a-clk-measure", 67362306a36Sopenharmony_ci .data = (void *)clk_msr_g12a, 67462306a36Sopenharmony_ci }, 67562306a36Sopenharmony_ci { 67662306a36Sopenharmony_ci .compatible = "amlogic,meson-sm1-clk-measure", 67762306a36Sopenharmony_ci .data = (void *)clk_msr_sm1, 67862306a36Sopenharmony_ci }, 67962306a36Sopenharmony_ci { /* sentinel */ } 68062306a36Sopenharmony_ci}; 68162306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, meson_msr_match_table); 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_cistatic struct platform_driver meson_msr_driver = { 68462306a36Sopenharmony_ci .probe = meson_msr_probe, 68562306a36Sopenharmony_ci .driver = { 68662306a36Sopenharmony_ci .name = "meson_msr", 68762306a36Sopenharmony_ci .of_match_table = meson_msr_match_table, 68862306a36Sopenharmony_ci }, 68962306a36Sopenharmony_ci}; 69062306a36Sopenharmony_cimodule_platform_driver(meson_msr_driver); 69162306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 692