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