brintos

brintos / linux-shallow public Read only

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