Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: thead: add support for enabling/disabling PLLs

The 2nd control word of T-Head TH1520 PLLs contains a bit to put the VCO
into reset state, which means disabling the PLL.

Some PLLs are put to disabled state by the bootloader, and the clock
driver should be able to enable them.

Add support for enabling/disabling PLLs. PLLs other than DPU ones are
set CLK_IS_CRITICAL to prevent killing the system -- they're meant to
drive CPU or system buses (even the GMAC/Video ones are driving arbitrary
buses).

Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
Reviewed-by: Drew Fustini <fustini@kernel.org>
Signed-off-by: Drew Fustini <fustini@kernel.org>

authored by

Icenowy Zheng and committed by
Drew Fustini
56a48c18 c51a37ff

+33 -5
+33 -5
drivers/clk/thead/clk-th1520-ap.c
··· 18 18 #define TH1520_PLL_FBDIV GENMASK(19, 8) 19 19 #define TH1520_PLL_REFDIV GENMASK(5, 0) 20 20 #define TH1520_PLL_BYPASS BIT(30) 21 + #define TH1520_PLL_VCO_RST BIT(29) 21 22 #define TH1520_PLL_DSMPD BIT(24) 22 23 #define TH1520_PLL_FRAC GENMASK(23, 0) 23 24 #define TH1520_PLL_FRAC_BITS 24 ··· 237 236 .determine_rate = clk_hw_determine_rate_no_reparent, 238 237 }; 239 238 239 + static void ccu_pll_disable(struct clk_hw *hw) 240 + { 241 + struct ccu_pll *pll = hw_to_ccu_pll(hw); 242 + 243 + regmap_set_bits(pll->common.map, pll->common.cfg1, 244 + TH1520_PLL_VCO_RST); 245 + } 246 + 247 + static int ccu_pll_enable(struct clk_hw *hw) 248 + { 249 + struct ccu_pll *pll = hw_to_ccu_pll(hw); 250 + 251 + return regmap_clear_bits(pll->common.map, pll->common.cfg1, 252 + TH1520_PLL_VCO_RST); 253 + } 254 + 255 + static int ccu_pll_is_enabled(struct clk_hw *hw) 256 + { 257 + struct ccu_pll *pll = hw_to_ccu_pll(hw); 258 + 259 + return !regmap_test_bits(pll->common.map, pll->common.cfg1, 260 + TH1520_PLL_VCO_RST); 261 + } 262 + 240 263 static unsigned long th1520_pll_vco_recalc_rate(struct clk_hw *hw, 241 264 unsigned long parent_rate) 242 265 { ··· 318 293 } 319 294 320 295 static const struct clk_ops clk_pll_ops = { 296 + .disable = ccu_pll_disable, 297 + .enable = ccu_pll_enable, 298 + .is_enabled = ccu_pll_is_enabled, 321 299 .recalc_rate = ccu_pll_recalc_rate, 322 300 }; 323 301 ··· 336 308 .hw.init = CLK_HW_INIT_PARENTS_DATA("cpu-pll0", 337 309 osc_24m_clk, 338 310 &clk_pll_ops, 339 - 0), 311 + CLK_IS_CRITICAL), 340 312 }, 341 313 }; 342 314 ··· 348 320 .hw.init = CLK_HW_INIT_PARENTS_DATA("cpu-pll1", 349 321 osc_24m_clk, 350 322 &clk_pll_ops, 351 - 0), 323 + CLK_IS_CRITICAL), 352 324 }, 353 325 }; 354 326 ··· 360 332 .hw.init = CLK_HW_INIT_PARENTS_DATA("gmac-pll", 361 333 osc_24m_clk, 362 334 &clk_pll_ops, 363 - 0), 335 + CLK_IS_CRITICAL), 364 336 }, 365 337 }; 366 338 ··· 380 352 .hw.init = CLK_HW_INIT_PARENTS_DATA("video-pll", 381 353 osc_24m_clk, 382 354 &clk_pll_ops, 383 - 0), 355 + CLK_IS_CRITICAL), 384 356 }, 385 357 }; 386 358 ··· 432 404 .hw.init = CLK_HW_INIT_PARENTS_DATA("tee-pll", 433 405 osc_24m_clk, 434 406 &clk_pll_ops, 435 - 0), 407 + CLK_IS_CRITICAL), 436 408 }, 437 409 }; 438 410