rjw | 1f88458 | 2022-01-06 17:20:42 +0800 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright (c) 2018 MediaTek Inc. |
| 3 | * Author: Yong Wu <yong.wu@mediatek.com> |
| 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License version 2 as |
| 7 | * published by the Free Software Foundation. |
| 8 | * |
| 9 | * This program is distributed in the hope that it will be useful, |
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | * GNU General Public License for more details. |
| 13 | */ |
| 14 | |
| 15 | #include <linux/clk-provider.h> |
| 16 | #include <linux/io.h> |
| 17 | |
| 18 | #include "clkdbg.h" |
| 19 | |
| 20 | #define DUMP_INIT_STATE 0 |
| 21 | |
| 22 | /* |
| 23 | * clkdbg dump_regs |
| 24 | */ |
| 25 | |
| 26 | enum { |
| 27 | topckgen, |
| 28 | infracfg, |
| 29 | scpsys, |
| 30 | apmixedsys, |
| 31 | audiosys, |
| 32 | }; |
| 33 | |
| 34 | #define REGBASE_V(_phys, _id_name) { .phys = _phys, .name = #_id_name } |
| 35 | |
| 36 | /* |
| 37 | * checkpatch.pl ERROR:COMPLEX_MACRO |
| 38 | * |
| 39 | * #define REGBASE(_phys, _id_name) [_id_name] = REGBASE_V(_phys, _id_name) |
| 40 | */ |
| 41 | |
| 42 | static struct regbase rb[] = { |
| 43 | [topckgen] = REGBASE_V(0x10000000, topckgen), |
| 44 | [infracfg] = REGBASE_V(0x10001000, infracfg), |
| 45 | [scpsys] = REGBASE_V(0x10006000, scpsys), |
| 46 | [apmixedsys] = REGBASE_V(0x1000c000, apmixedsys), |
| 47 | [audiosys] = REGBASE_V(0x11220000, audiosys), |
| 48 | }; |
| 49 | |
| 50 | #define REGNAME(_base, _ofs, _name) \ |
| 51 | { .base = &rb[_base], .ofs = _ofs, .name = #_name } |
| 52 | |
| 53 | static struct regname rn[] = { |
| 54 | REGNAME(topckgen, 0x040, CLK_CFG_0), |
| 55 | REGNAME(topckgen, 0x050, CLK_CFG_1), |
| 56 | REGNAME(topckgen, 0x060, CLK_CFG_2), |
| 57 | REGNAME(topckgen, 0x070, CLK_CFG_3), |
| 58 | REGNAME(topckgen, 0x080, CLK_CFG_4), |
| 59 | REGNAME(topckgen, 0x090, CLK_CFG_5), |
| 60 | REGNAME(topckgen, 0x0a0, CLK_CFG_6), |
| 61 | REGNAME(topckgen, 0x0b0, CLK_CFG_7), |
| 62 | /* audsys reg need special clk to access */ |
| 63 | /* REGNAME(audiosys, 0x000, AUDIO_TOP_CON0), |
| 64 | * REGNAME(audiosys, 0x004, AUDIO_TOP_CON1), |
| 65 | */ |
| 66 | REGNAME(infracfg, 0x090, MODULE_SW_CG_0), |
| 67 | REGNAME(infracfg, 0x094, MODULE_SW_CG_1), |
| 68 | REGNAME(infracfg, 0x0ac, MODULE_SW_CG_2), |
| 69 | REGNAME(infracfg, 0x0c8, MODULE_SW_CG_3), |
| 70 | |
| 71 | REGNAME(apmixedsys, 0x204, ARMPLL_CON0), |
| 72 | REGNAME(apmixedsys, 0x208, ARMPLL_CON1_PCW), |
| 73 | REGNAME(apmixedsys, 0x210, ARMPLL_CON3_PWR), |
| 74 | REGNAME(apmixedsys, 0x214, MAINPLL_CON0), |
| 75 | REGNAME(apmixedsys, 0x218, MAINPLL_CON1_PCW), |
| 76 | REGNAME(apmixedsys, 0x220, MAINPLL_CON3_PWR), |
| 77 | REGNAME(apmixedsys, 0x224, UNIVPLL_CON0), |
| 78 | REGNAME(apmixedsys, 0x228, UNIVPLL_CON1_PCW), |
| 79 | REGNAME(apmixedsys, 0x230, UNIVPLL_CON3_PWR), |
| 80 | REGNAME(apmixedsys, 0x234, MSDCPLL_CON0), |
| 81 | REGNAME(apmixedsys, 0x238, MSDCPLL_CON1_PCW), |
| 82 | REGNAME(apmixedsys, 0x240, MSDCPLL_CON3_PWR), |
| 83 | REGNAME(apmixedsys, 0x244, APLL1_CON0), |
| 84 | REGNAME(apmixedsys, 0xC, APLL1_TUNER_EN), |
| 85 | /* If tuner enable, use 0x40. */ |
| 86 | REGNAME(apmixedsys, 0x40, APLL1_PCW_TUREN), |
| 87 | REGNAME(apmixedsys, 0x248, APLL1_CON1_PD), |
| 88 | REGNAME(apmixedsys, 0x24C, APLL1_CON1_PCW), |
| 89 | REGNAME(apmixedsys, 0x250, APLL1_CON3_PWR), |
| 90 | REGNAME(apmixedsys, 0x258, APLL2_CON0), |
| 91 | REGNAME(apmixedsys, 0x260, APLL2_CON1_PCW), |
| 92 | REGNAME(apmixedsys, 0x264, APLL2_CON3_PWR), |
| 93 | REGNAME(apmixedsys, 0x26C, MPLL_CON0), |
| 94 | REGNAME(apmixedsys, 0x270, MPLL_CON1_PCW), |
| 95 | REGNAME(apmixedsys, 0x278, MPLL_CON3_PWR), |
| 96 | REGNAME(apmixedsys, 0x27C, ETHERPLL_CON0), |
| 97 | REGNAME(apmixedsys, 0x280, ETHERPLL_CON1_PCW), |
| 98 | REGNAME(apmixedsys, 0x288, ETHERPLL_CON3_PWR), |
| 99 | |
| 100 | REGNAME(scpsys, 0x0160, PWR_STATUS), |
| 101 | REGNAME(scpsys, 0x0164, PWR_STATUS_2ND), |
| 102 | REGNAME(scpsys, 0x0318, MD1_PWR_CON), |
| 103 | {} |
| 104 | }; |
| 105 | |
| 106 | static const struct regname *get_all_regnames(void) |
| 107 | { |
| 108 | return rn; |
| 109 | } |
| 110 | |
| 111 | static void __init init_regbase(void) |
| 112 | { |
| 113 | size_t i; |
| 114 | |
| 115 | for (i = 0; i < ARRAY_SIZE(rb); i++) |
| 116 | rb[i].virt = ioremap(rb[i].phys, PAGE_SIZE); |
| 117 | } |
| 118 | |
| 119 | /* |
| 120 | * clkdbg fmeter |
| 121 | */ |
| 122 | |
| 123 | #include <linux/delay.h> |
| 124 | |
| 125 | #define clk_readl(addr) readl(addr) |
| 126 | #define clk_writel(addr, val) \ |
| 127 | do { writel(val, addr); wmb(); } while (0) /* sync write */ |
| 128 | |
| 129 | #define FMCLK(_t, _i, _n) { .type = _t, .id = _i, .name = _n } |
| 130 | |
| 131 | static const struct fmeter_clk fclks[] = { |
| 132 | FMCLK(CKGEN, 1, "hf_faxi_ck"), |
| 133 | FMCLK(CKGEN, 2, "f_fuart_ck"), |
| 134 | FMCLK(CKGEN, 3, "hf_fspi_ck"), |
| 135 | FMCLK(CKGEN, 4, "hf_fmsdc50_0_hclk_ck"), |
| 136 | FMCLK(CKGEN, 5, "hf_fmsdc50_0_ck"), |
| 137 | FMCLK(CKGEN, 6, "hf_fmsdc30_1_ck"), |
| 138 | FMCLK(CKGEN, 7, "hf_faudio_ck"), |
| 139 | FMCLK(CKGEN, 8, "hf_faud_intbus_ck"), |
| 140 | FMCLK(CKGEN, 9, "hf_faud_1_ck"), |
| 141 | FMCLK(CKGEN, 10, "hf_faud_2_ck"), |
| 142 | FMCLK(CKGEN, 11, "hf_faud_engen1_ck"), |
| 143 | FMCLK(CKGEN, 12, "hf_faud_engen2_ck"), |
| 144 | FMCLK(CKGEN, 13, "hf_fdxcc_ck"), |
| 145 | FMCLK(CKGEN, 14, "hf_fhsm_crypto_ck"), |
| 146 | FMCLK(CKGEN, 15, "hf_fhsm_arc_ck"), |
| 147 | FMCLK(CKGEN, 16, "hf_fgcpu_ck"), |
| 148 | FMCLK(CKGEN, 17, "hf_fecc_ck"), |
| 149 | FMCLK(CKGEN, 18, "f_fusb_top_ck"), |
| 150 | FMCLK(CKGEN, 19, "hf_fspm_ck"), |
| 151 | FMCLK(CKGEN, 20, "hf_fi2c_ck"), |
| 152 | FMCLK(CKGEN, 21, "f_fpwrap_ulposc_ck"), |
| 153 | FMCLK(CKGEN, 22, "hf_fmsdc50_2_hclk_ck"), |
| 154 | FMCLK(CKGEN, 23, "hf_fmsdc30_2_ck"), |
| 155 | FMCLK(CKGEN, 24, "hf_fnfi1x_bclk_ck"), |
| 156 | FMCLK(CKGEN, 25, "hf_fspinfi_bclk_ck"), |
| 157 | FMCLK(CKGEN, 26, "hf_fpcie_mac_ck"), |
| 158 | FMCLK(CKGEN, 27, "f_fssusb_top_ck"), |
| 159 | FMCLK(CKGEN, 28, "hf_fspislv_ck"), |
| 160 | FMCLK(CKGEN, 29, "hf_fether_125m_ck"), |
| 161 | FMCLK(CKGEN, 30, "hf_fether_50m_rmii_ck"), |
| 162 | FMCLK(CKGEN, 31, "hf_fether_62p4m_ck"), |
| 163 | FMCLK(CKGEN, 32, "hf_fpwm_ck"), |
| 164 | FMCLK(CKGEN, 50, "hd_faxi_east_ck"), |
| 165 | FMCLK(CKGEN, 51, "hd_faxi_west_ck"), |
| 166 | FMCLK(CKGEN, 52, "hd_faxi_north_ck"), |
| 167 | FMCLK(CKGEN, 53, "hd_faxi_south_ck"), |
| 168 | FMCLK(CKGEN, 55, "fmem_ck_bfe_dcm_ch0"), |
| 169 | FMCLK(CKGEN, 56, "fmem_ck_aft_dcm_ch0"), |
| 170 | FMCLK(CKGEN, 57, "fmem_ck_bfe_dcm_ch1"), |
| 171 | FMCLK(CKGEN, 58, "fmem_ck_aft_dcm_ch1"), |
| 172 | |
| 173 | FMCLK(ABIST, 1, "AD_ARMPLL_CK"), |
| 174 | FMCLK(ABIST, 2, "AD_MAINPLL_1092M_CK"), |
| 175 | FMCLK(ABIST, 3, "AD_MDBPIPLL_DIV3_CK"), |
| 176 | FMCLK(ABIST, 4, "AD_MDBPIPLL_DIV7_CK"), |
| 177 | FMCLK(ABIST, 5, "AD_MDBRPPLL_DIV6_CK"), |
| 178 | FMCLK(ABIST, 6, "AD_MAIN_H546M_CK"), |
| 179 | FMCLK(ABIST, 7, "AD_MAIN_H364M_CK"), |
| 180 | FMCLK(ABIST, 8, "AD_MAIN_H218P4M_CK"), |
| 181 | FMCLK(ABIST, 9, "AD_MAIN_H156M_CK"), |
| 182 | FMCLK(ABIST, 10, "AD_UNIVPLL_1248M_CK"), |
| 183 | FMCLK(ABIST, 11, "AD_USB20_192M_CK"), |
| 184 | FMCLK(ABIST, 12, "AD_UNIV_624M_CK"), |
| 185 | FMCLK(ABIST, 13, "AD_UNIV_416M_CK"), |
| 186 | FMCLK(ABIST, 14, "AD_UNIV_249P6M_CK"), |
| 187 | FMCLK(ABIST, 15, "AD_UNIV_178P3M_CK"), |
| 188 | FMCLK(ABIST, 16, "AD_MDPLL1_FS26M_CK"), |
| 189 | FMCLK(ABIST, 17, "rtc32k_ck_i"), |
| 190 | FMCLK(ABIST, 18, "AD_MSDCPLL_416M_CK"), |
| 191 | FMCLK(ABIST, 19, "AD_APLLGP_TST_CK"), |
| 192 | FMCLK(ABIST, 20, "AD_APLL1_196P608M_CK"), |
| 193 | FMCLK(ABIST, 21, "AD_APLL2_180P6336M_CK"), |
| 194 | FMCLK(ABIST, 22, "AD_MPLL_208M_CK"), |
| 195 | FMCLK(ABIST, 23, "mcusys_arm_clk_out_all"), |
| 196 | FMCLK(ABIST, 24, "msdc01_in_ck"), |
| 197 | FMCLK(ABIST, 25, "msdc02_in_ck"), |
| 198 | FMCLK(ABIST, 26, "msdc11_in_ck"), |
| 199 | FMCLK(ABIST, 27, "msdc12_in_ck"), |
| 200 | FMCLK(ABIST, 28, "DA_USB20_48M_DIV_CK"), |
| 201 | FMCLK(ABIST, 29, "DA_UNIV_48M_DIV_CK"), |
| 202 | FMCLK(ABIST, 30, "DA_MPLL_104M_DIV_CK"), |
| 203 | FMCLK(ABIST, 31, "DA_MPLL_52M_DIV_CK"), |
| 204 | FMCLK(ABIST, 32, "DA_ARMCPU_MON_CK"), |
| 205 | FMCLK(ABIST, 33, "AD_ETHERPLL_500M_CK"), |
| 206 | FMCLK(ABIST, 34, "msdc21_in_ck"), |
| 207 | FMCLK(ABIST, 35, "msdc22_in_ck"), |
| 208 | FMCLK(ABIST, 60, "clkmon1_ck"), |
| 209 | FMCLK(ABIST, 61, "clkmon2_ck"), |
| 210 | FMCLK(ABIST, 62, "clkmon3_ck"), |
| 211 | FMCLK(ABIST, 63, "clkmon4_ck"), |
| 212 | {} |
| 213 | }; |
| 214 | |
| 215 | #define CLK_MISC_CFG_0 (rb[topckgen].virt + 0x104) |
| 216 | #define CLK_DBG_CFG (rb[topckgen].virt + 0x10C) |
| 217 | #define CLK26CALI_0 (rb[topckgen].virt + 0x220) |
| 218 | #define CLK26CALI_1 (rb[topckgen].virt + 0x224) |
| 219 | |
| 220 | static unsigned int mt_get_abist_freq(unsigned int ID) |
| 221 | { |
| 222 | int output = 0, i = 0; |
| 223 | unsigned int temp, clk26cali_0, clk_dbg_cfg; |
| 224 | unsigned int clk_misc_cfg_0, clk26cali_1; |
| 225 | |
| 226 | clk_dbg_cfg = clk_readl(CLK_DBG_CFG); |
| 227 | /* sel abist_cksw and enable freq meter sel abist */ |
| 228 | clk_writel(CLK_DBG_CFG, (clk_dbg_cfg & 0xFFC0FFFC)|(ID << 16)); |
| 229 | clk_misc_cfg_0 = clk_readl(CLK_MISC_CFG_0); |
| 230 | /* select divider, WAIT CONFIRM, div 3, then output *4. */ |
| 231 | clk_writel(CLK_MISC_CFG_0, (clk_misc_cfg_0 & 0x00FFFFFF) | (0x3 << 24)); |
| 232 | clk26cali_0 = clk_readl(CLK26CALI_0); |
| 233 | clk26cali_1 = clk_readl(CLK26CALI_1); |
| 234 | clk_writel(CLK26CALI_0, 0x1000); |
| 235 | clk_writel(CLK26CALI_0, 0x1010); |
| 236 | |
| 237 | /* wait frequency meter finish */ |
| 238 | while (clk_readl(CLK26CALI_0) & 0x10) { |
| 239 | mdelay(10); |
| 240 | i++; |
| 241 | if (i > 10) { |
| 242 | /* pr_err("<freqmeter>abist(%d), timeout\n", ID); */ |
| 243 | break; |
| 244 | } |
| 245 | } |
| 246 | |
| 247 | temp = clk_readl(CLK26CALI_1) & 0xFFFF; |
| 248 | |
| 249 | output = ((temp * 26000)) / 1024; /* Khz */ |
| 250 | |
| 251 | clk_writel(CLK_DBG_CFG, clk_dbg_cfg); |
| 252 | clk_writel(CLK_MISC_CFG_0, clk_misc_cfg_0); |
| 253 | clk_writel(CLK26CALI_0, clk26cali_0); |
| 254 | clk_writel(CLK26CALI_1, clk26cali_1); |
| 255 | |
| 256 | return output * 4; |
| 257 | } |
| 258 | |
| 259 | static unsigned int mt_get_ckgen_freq(unsigned int ID) |
| 260 | { |
| 261 | int output = 0, i = 0; |
| 262 | unsigned int temp, clk26cali_0, clk_dbg_cfg; |
| 263 | unsigned int clk_misc_cfg_0, clk26cali_1; |
| 264 | |
| 265 | clk_dbg_cfg = clk_readl(CLK_DBG_CFG); |
| 266 | /* sel ckgen_cksw[22] and enable freq meter sel ckgen[21:16], |
| 267 | * 01:hd_faxi_ck |
| 268 | */ |
| 269 | clk_writel(CLK_DBG_CFG, (clk_dbg_cfg & 0xFFFFC0FC)|(ID << 8)|(0x1)); |
| 270 | clk_misc_cfg_0 = clk_readl(CLK_MISC_CFG_0); |
| 271 | /* select divider dvt set zero */ |
| 272 | clk_writel(CLK_MISC_CFG_0, (clk_misc_cfg_0 & 0x00FFFFFF)); |
| 273 | clk26cali_0 = clk_readl(CLK26CALI_0); |
| 274 | clk26cali_1 = clk_readl(CLK26CALI_1); |
| 275 | clk_writel(CLK26CALI_0, 0x1000); |
| 276 | clk_writel(CLK26CALI_0, 0x1010); |
| 277 | |
| 278 | /* wait frequency meter finish */ |
| 279 | while (clk_readl(CLK26CALI_0) & 0x10) { |
| 280 | mdelay(10); |
| 281 | i++; |
| 282 | if (i > 10) { |
| 283 | /* pr_err("<freqmeter>ckgen(%d), timeout\n", ID); */ |
| 284 | break; |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | temp = clk_readl(CLK26CALI_1) & 0xFFFF; |
| 289 | |
| 290 | output = ((temp * 26000)) / 1024; /* Khz */ |
| 291 | |
| 292 | clk_writel(CLK_DBG_CFG, clk_dbg_cfg); |
| 293 | clk_writel(CLK_MISC_CFG_0, clk_misc_cfg_0); |
| 294 | clk_writel(CLK26CALI_0, clk26cali_0); |
| 295 | clk_writel(CLK26CALI_1, clk26cali_1); |
| 296 | |
| 297 | return output; |
| 298 | } |
| 299 | |
| 300 | static u32 fmeter_freq_op(const struct fmeter_clk *fclk) |
| 301 | { |
| 302 | if (fclk->type == ABIST) |
| 303 | return mt_get_abist_freq(fclk->id); |
| 304 | else if (fclk->type == CKGEN) |
| 305 | return mt_get_ckgen_freq(fclk->id); |
| 306 | return 0; |
| 307 | } |
| 308 | |
| 309 | static const struct fmeter_clk *get_all_fmeter_clks(void) |
| 310 | { |
| 311 | return fclks; |
| 312 | } |
| 313 | |
| 314 | /* |
| 315 | * clkdbg dump_state |
| 316 | */ |
| 317 | |
| 318 | static const char * const *get_all_clk_names(void) |
| 319 | { |
| 320 | static const char * const clks[] = { |
| 321 | "armpll", |
| 322 | "mainpll", |
| 323 | "univpll", |
| 324 | "msdcpll", |
| 325 | "apll1", |
| 326 | "apll2", |
| 327 | "mpll", |
| 328 | "etherpll", |
| 329 | "syspll_ck", |
| 330 | "syspll_d2", |
| 331 | "syspll1_d2", |
| 332 | "syspll1_d4", |
| 333 | "syspll1_d8", |
| 334 | "syspll1_d16", |
| 335 | "syspll_d3", |
| 336 | "syspll2_d2", |
| 337 | "syspll2_d4", |
| 338 | "syspll2_d8", |
| 339 | "syspll_d5", |
| 340 | "syspll3_d2", |
| 341 | "syspll3_d4", |
| 342 | "syspll_d7", |
| 343 | "syspll4_d2", |
| 344 | "syspll4_d4", |
| 345 | "usb20_192m_ck", |
| 346 | "usb20_192m_d2", |
| 347 | "usb20_192m_d4", |
| 348 | "univpll_d2", |
| 349 | "univpll1_d2", |
| 350 | "univpll1_d4", |
| 351 | "univpll1_d8", |
| 352 | "univpll_d3", |
| 353 | "univpll2_d2", |
| 354 | "univpll2_d4", |
| 355 | "univpll2_d8", |
| 356 | "univpll2_d16", |
| 357 | "univpll_d5", |
| 358 | "univpll3_d2", |
| 359 | "univpll3_d4", |
| 360 | "msdcpll_ck", |
| 361 | "msdcpll_d2", |
| 362 | "apll1_ck", |
| 363 | "apll1_d2", |
| 364 | "apll1_d4", |
| 365 | "apll1_d8", |
| 366 | "apll2_ck", |
| 367 | "apll2_d2", |
| 368 | "apll2_d4", |
| 369 | "apll2_d8", |
| 370 | "etherpll_ck", |
| 371 | "etherpll_d4", |
| 372 | "etherpll_d10", |
| 373 | "hd_faxi_ck", |
| 374 | "f_fuart_ck", |
| 375 | "spi_ck", |
| 376 | "msdc50_0_ck", |
| 377 | "msdc30_1_ck", |
| 378 | "audio_ck", |
| 379 | "aud_1_ck", |
| 380 | "aud_engen1_ck", |
| 381 | "aud_engen2_ck", |
| 382 | "hsm_crypto_ck", |
| 383 | "i2c_ck", |
| 384 | "msdc5_2hclk_ck", |
| 385 | "msdc30_2_ck", |
| 386 | "nfi1x_bclk_ck", |
| 387 | "pcie_mac_ck", |
| 388 | "f_fssusb_top_ck", |
| 389 | "spislv_ck", |
| 390 | "ether_125m_ck", |
| 391 | "pwm_ck", |
| 392 | "arm_div_pll1", |
| 393 | "arm_div_pll2", |
| 394 | |
| 395 | /* CLK_CFG_0 */ |
| 396 | "axi_sel", |
| 397 | "uart_sel", |
| 398 | "spi_sel", |
| 399 | "msdc5_0hclk", |
| 400 | |
| 401 | /* CLK_CFG_1 */ |
| 402 | "msdc50_0_sel", |
| 403 | "msdc30_1_sel", |
| 404 | "audio_sel", |
| 405 | "aud_intbus_sel", |
| 406 | "aud_1_sel", |
| 407 | "aud_2_sel", |
| 408 | "aud_engen1_sel", |
| 409 | "aud_engen2_sel", |
| 410 | |
| 411 | /* CLK_CFG_3 */ |
| 412 | "dxcc_sel", |
| 413 | "hsm_crypto_sel", |
| 414 | "hsm_arc_sel", |
| 415 | "gcpu_sel", |
| 416 | |
| 417 | /* CLK_CFG_4 */ |
| 418 | "ecc_sel", |
| 419 | "usb_top_sel", |
| 420 | "spm_sel", |
| 421 | "i2c_sel", |
| 422 | |
| 423 | /* CLK_CFG_5 */ |
| 424 | "ulposc_sel", |
| 425 | "msdc5_2hclk_sel", |
| 426 | "msdc30_2_sel", |
| 427 | "nfi1x_bclk_sel", |
| 428 | |
| 429 | /* CLK_CFG_6 */ |
| 430 | "spinfi_bclk_sel", |
| 431 | "pcie_mac_sel", |
| 432 | "ssusb_top_sel", |
| 433 | "spislv_sel", |
| 434 | |
| 435 | /* CLK_CFG_7 */ |
| 436 | "ether_125m_sel", |
| 437 | "ether_50_sel", |
| 438 | "ether_62p4m_sel", |
| 439 | "pwm_sel", |
| 440 | |
| 441 | "i2s0_m_ck_sel", |
| 442 | "i2s1_m_ck_sel", |
| 443 | "i2s2_m_ck_sel", |
| 444 | "i2s3_m_ck_sel", |
| 445 | "i2s4_m_ck_sel", |
| 446 | |
| 447 | "apll12_div0", |
| 448 | "apll12_div1", |
| 449 | "apll12_div2", |
| 450 | "apll12_div3", |
| 451 | "apll12_div4", |
| 452 | "apll12_divb", |
| 453 | |
| 454 | "arm_div_pll1_en", |
| 455 | "arm_div_pll2_en", |
| 456 | |
| 457 | /* IFR0 */ |
| 458 | "ifr_apxgpt", |
| 459 | "ifr_icusb", |
| 460 | "ifr_gce", |
| 461 | "ifr_therm", |
| 462 | "ifr_i2c_ap", |
| 463 | "ifr_i2c_ccu", |
| 464 | "ifr_i2c_sspm", |
| 465 | "ifr_i2c_rsv", |
| 466 | "ifr_pwm_hclk", |
| 467 | "ifr_pwm1", |
| 468 | "ifr_pwm2", |
| 469 | "ifr_pwm3", |
| 470 | "ifr_pwm4", |
| 471 | "ifr_pwm5", |
| 472 | "ifr_pwm", |
| 473 | "ifr_uart0", |
| 474 | "ifr_uart1", |
| 475 | "ifr_uart2", |
| 476 | "ifr_uart3", |
| 477 | "ifr_gce_26m", |
| 478 | "ifr_dma", |
| 479 | /* IFR1 */ |
| 480 | "ifr_spi0", |
| 481 | "ifr_msdc0", |
| 482 | "ifr_msdc1", |
| 483 | "ifr_msdc2", |
| 484 | "ifr_trng", |
| 485 | "ifr_ccif1_ap", |
| 486 | "ifr_ccif1_md", |
| 487 | "ifr_pcie", |
| 488 | "ifr_nfi", |
| 489 | "ifr_ap_dma", |
| 490 | "ifr_dapc", |
| 491 | "ifr_ccif_ap", |
| 492 | "ifr_debugsys", |
| 493 | "ifr_ccif_md", |
| 494 | "ifr_hsm", |
| 495 | "ifr_hsm_ao", |
| 496 | "ifr_ether", |
| 497 | "ifr_spi_slave", |
| 498 | /* IFR2 */ |
| 499 | "ifr_pwmfb", |
| 500 | "ifr_ssusb", |
| 501 | "ifr_cldmabclk", |
| 502 | "ifr_audio26m", |
| 503 | "ifr_spi1", |
| 504 | "ifr_spi2", |
| 505 | "ifr_spi3", |
| 506 | "ifr_spi4", |
| 507 | "ifr_spi5", |
| 508 | "ifr_cq_dma", |
| 509 | /* IFR3 */ |
| 510 | "ifr_i2c6", |
| 511 | "ifr_msdc0_clk", |
| 512 | "ifr_msdc1_clk", |
| 513 | "ifr_msdc2_clk", |
| 514 | "ifr_mcu_pm_bclk", |
| 515 | "ifr_ccif2_ap", |
| 516 | "ifr_ccif2_md", |
| 517 | "ifr_uart4", |
| 518 | "ifr_uart5", |
| 519 | "ifr_uart6", |
| 520 | /* end */ |
| 521 | NULL |
| 522 | }; |
| 523 | |
| 524 | return clks; |
| 525 | } |
| 526 | |
| 527 | /* |
| 528 | * clkdbg pwr_status |
| 529 | */ |
| 530 | |
| 531 | static const char * const *get_pwr_names(void) |
| 532 | { |
| 533 | static const char * const pwr_names[] = { |
| 534 | [0] = "MD1", |
| 535 | }; |
| 536 | |
| 537 | return pwr_names; |
| 538 | } |
| 539 | |
| 540 | u32 get_spm_pwr_status(void) |
| 541 | { |
| 542 | static void __iomem *scpsys_base, *pwr_sta, *pwr_sta_2nd; |
| 543 | |
| 544 | if (scpsys_base == NULL || pwr_sta == NULL || pwr_sta_2nd == NULL) { |
| 545 | scpsys_base = ioremap(0x10006000, PAGE_SIZE); |
| 546 | pwr_sta = scpsys_base + 0x180; |
| 547 | pwr_sta_2nd = scpsys_base + 0x184; |
| 548 | } |
| 549 | |
| 550 | return clk_readl(pwr_sta) & clk_readl(pwr_sta_2nd); |
| 551 | } |
| 552 | |
| 553 | /* |
| 554 | * clkdbg dump_clks |
| 555 | */ |
| 556 | |
| 557 | static void setup_provider_clk(struct provider_clk *pvdck) |
| 558 | { |
| 559 | static const struct { |
| 560 | const char *pvdname; |
| 561 | u32 pwr_mask; |
| 562 | } pvd_pwr_mask[] = { |
| 563 | }; |
| 564 | |
| 565 | size_t i; |
| 566 | const char *pvdname = pvdck->provider_name; |
| 567 | |
| 568 | if (pvdname == NULL) |
| 569 | return; |
| 570 | |
| 571 | for (i = 0; i < ARRAY_SIZE(pvd_pwr_mask); i++) { |
| 572 | if (strcmp(pvdname, pvd_pwr_mask[i].pvdname) == 0) { |
| 573 | pvdck->pwr_mask = pvd_pwr_mask[i].pwr_mask; |
| 574 | return; |
| 575 | } |
| 576 | } |
| 577 | } |
| 578 | |
| 579 | /* |
| 580 | * init functions |
| 581 | */ |
| 582 | |
| 583 | static const struct clkdbg_ops clkdbg_mt2731_ops = { |
| 584 | .get_all_fmeter_clks = get_all_fmeter_clks, |
| 585 | .fmeter_freq = fmeter_freq_op, |
| 586 | .get_all_regnames = get_all_regnames, |
| 587 | .get_all_clk_names = get_all_clk_names, |
| 588 | .get_pwr_names = get_pwr_names, |
| 589 | .setup_provider_clk = setup_provider_clk, |
| 590 | .get_spm_pwr_status = get_spm_pwr_status, |
| 591 | }; |
| 592 | |
| 593 | static void __init init_custom_cmds(void) |
| 594 | { |
| 595 | static const struct cmd_fn cmds[] = { |
| 596 | {} |
| 597 | }; |
| 598 | |
| 599 | set_custom_cmds(cmds); |
| 600 | } |
| 601 | |
| 602 | static int __init clkdbg_mt2731_init(void) |
| 603 | { |
| 604 | if (of_machine_is_compatible("mediatek,mt2731") == 0) |
| 605 | return -ENODEV; |
| 606 | |
| 607 | init_regbase(); |
| 608 | |
| 609 | init_custom_cmds(); |
| 610 | set_clkdbg_ops(&clkdbg_mt2731_ops); |
| 611 | |
| 612 | #if DUMP_INIT_STATE |
| 613 | print_regs(); |
| 614 | print_fmeter_all(); |
| 615 | #endif /* DUMP_INIT_STATE */ |
| 616 | |
| 617 | return 0; |
| 618 | } |
| 619 | late_initcall(clkdbg_mt2731_init); |