^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2014 MundoReader S.L.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Heiko Stuebner <heiko@sntech.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Xing Zheng <zhengxing@rock-chips.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/div64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/gcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/clk/rockchip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "clk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define PLL_MODE_MASK 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define PLL_MODE_SLOW 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define PLL_MODE_NORM 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define PLL_MODE_DEEP 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define PLL_RK3328_MODE_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct rockchip_clk_pll {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct clk_mux pll_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) const struct clk_ops *pll_mux_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct notifier_block clk_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) void __iomem *reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int lock_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned int lock_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) enum rockchip_pll_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) const struct rockchip_pll_rate_table *rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned int rate_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned long scaling;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) spinlock_t *lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct rockchip_clk_provider *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #ifdef CONFIG_ROCKCHIP_CLK_BOOST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) bool boost_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u32 boost_backup_pll_usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned long boost_backup_pll_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned long boost_low_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned long boost_high_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct regmap *boost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct hlist_node debug_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define to_rockchip_clk_pll_nb(nb) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) container_of(nb, struct rockchip_clk_pll, clk_nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #ifdef CONFIG_ROCKCHIP_CLK_BOOST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static void rockchip_boost_disable_low(struct rockchip_clk_pll *pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static HLIST_HEAD(clk_boost_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static DEFINE_MUTEX(clk_boost_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static inline void rockchip_boost_disable_low(struct rockchip_clk_pll *pll) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define MHZ (1000UL * 1000UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define KHZ (1000UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* CLK_PLL_TYPE_RK3066_AUTO type ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define PLL_FREF_MIN (269 * KHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define PLL_FREF_MAX (2200 * MHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define PLL_FVCO_MIN (440 * MHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define PLL_FVCO_MAX (2200 * MHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define PLL_FOUT_MIN (27500 * KHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define PLL_FOUT_MAX (2200 * MHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define PLL_NF_MAX (4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define PLL_NR_MAX (64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define PLL_NO_MAX (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* CLK_PLL_TYPE_RK3036/3366/3399_AUTO type ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define MIN_FOUTVCO_FREQ (800 * MHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define MAX_FOUTVCO_FREQ (2000 * MHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static struct rockchip_pll_rate_table auto_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int rockchip_pll_clk_adaptive_scaling(struct clk *clk, int sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct clk *parent = clk_get_parent(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct rockchip_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (IS_ERR_OR_NULL(parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) pll = to_rockchip_clk_pll(__clk_get_hw(parent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) pll->sel = sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) EXPORT_SYMBOL(rockchip_pll_clk_adaptive_scaling);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int rockchip_pll_clk_rate_to_scale(struct clk *clk, unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) const struct rockchip_pll_rate_table *rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct clk *parent = clk_get_parent(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct rockchip_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (IS_ERR_OR_NULL(parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) pll = to_rockchip_clk_pll(__clk_get_hw(parent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (!pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) rate_table = pll->rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) for (i = 0; i < pll->rate_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (rate >= rate_table[i].rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) EXPORT_SYMBOL(rockchip_pll_clk_rate_to_scale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int rockchip_pll_clk_scale_to_rate(struct clk *clk, unsigned int scale)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) const struct rockchip_pll_rate_table *rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct clk *parent = clk_get_parent(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct rockchip_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (IS_ERR_OR_NULL(parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) pll = to_rockchip_clk_pll(__clk_get_hw(parent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (!pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) rate_table = pll->rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) for (i = 0; i < pll->rate_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (i == scale)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return rate_table[i].rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) EXPORT_SYMBOL(rockchip_pll_clk_scale_to_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static struct rockchip_pll_rate_table *rk_pll_rate_table_get(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return &auto_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static int rockchip_pll_clk_set_postdiv(unsigned long fout_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u32 *postdiv1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u32 *postdiv2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u32 *foutvco)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unsigned long freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (fout_hz < MIN_FOUTVCO_FREQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) for (*postdiv1 = 1; *postdiv1 <= 7; (*postdiv1)++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) for (*postdiv2 = 1; *postdiv2 <= 7; (*postdiv2)++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) freq = fout_hz * (*postdiv1) * (*postdiv2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (freq >= MIN_FOUTVCO_FREQ &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) freq <= MAX_FOUTVCO_FREQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *foutvco = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) pr_err("CANNOT FIND postdiv1/2 to make fout in range from 800M to 2000M,fout = %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) fout_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *postdiv1 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *postdiv2 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static struct rockchip_pll_rate_table *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) rockchip_pll_clk_set_by_auto(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) unsigned long fin_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) unsigned long fout_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct rockchip_pll_rate_table *rate_table = rk_pll_rate_table_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* FIXME set postdiv1/2 always 1*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u32 foutvco = fout_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) u64 fin_64, frac_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u32 f_frac, postdiv1, postdiv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) unsigned long clk_gcd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) rockchip_pll_clk_set_postdiv(fout_hz, &postdiv1, &postdiv2, &foutvco);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) rate_table->postdiv1 = postdiv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) rate_table->postdiv2 = postdiv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) rate_table->dsmpd = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) fin_hz /= MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) foutvco /= MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) clk_gcd = gcd(fin_hz, foutvco);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) rate_table->refdiv = fin_hz / clk_gcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) rate_table->fbdiv = foutvco / clk_gcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) rate_table->frac = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) pr_debug("fin = %lu, fout = %lu, clk_gcd = %lu, refdiv = %u, fbdiv = %u, postdiv1 = %u, postdiv2 = %u, frac = %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) fin_hz, fout_hz, clk_gcd, rate_table->refdiv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) rate_table->fbdiv, rate_table->postdiv1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) rate_table->postdiv2, rate_table->frac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) pr_debug("frac div running, fin_hz = %lu, fout_hz = %lu, fin_INT_mhz = %lu, fout_INT_mhz = %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) fin_hz, fout_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) fin_hz / MHZ * MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) fout_hz / MHZ * MHZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) pr_debug("frac get postdiv1 = %u, postdiv2 = %u, foutvco = %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) rate_table->postdiv1, rate_table->postdiv2, foutvco);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) clk_gcd = gcd(fin_hz / MHZ, foutvco / MHZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) rate_table->refdiv = fin_hz / MHZ / clk_gcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) rate_table->fbdiv = foutvco / MHZ / clk_gcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) pr_debug("frac get refdiv = %u, fbdiv = %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) rate_table->refdiv, rate_table->fbdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) rate_table->frac = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) f_frac = (foutvco % MHZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) fin_64 = fin_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) do_div(fin_64, (u64)rate_table->refdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) frac_64 = (u64)f_frac << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) do_div(frac_64, fin_64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) rate_table->frac = (u32)frac_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (rate_table->frac > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) rate_table->dsmpd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) pr_debug("frac = %x\n", rate_table->frac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static struct rockchip_pll_rate_table *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) rockchip_rk3066_pll_clk_set_by_auto(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) unsigned long fin_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) unsigned long fout_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct rockchip_pll_rate_table *rate_table = rk_pll_rate_table_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) u32 nr, nf, no, nonr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) u32 nr_out, nf_out, no_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u32 n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) u32 numerator, denominator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u64 fref, fvco, fout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unsigned long clk_gcd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) nr_out = PLL_NR_MAX + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) no_out = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) nf_out = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) clk_gcd = gcd(fin_hz, fout_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) numerator = fout_hz / clk_gcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) denominator = fin_hz / clk_gcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) for (n = 1;; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) nf = numerator * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) nonr = denominator * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) for (no = 1; no <= PLL_NO_MAX; no++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (!(no == 1 || !(no % 2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (nonr % no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) nr = nonr / no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (nr > PLL_NR_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) fref = fin_hz / nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (fref < PLL_FREF_MIN || fref > PLL_FREF_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) fvco = fref * nf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) fout = fvco / no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* select the best from all available PLL settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if ((no > no_out) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ((no == no_out) && (nr < nr_out))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) nr_out = nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) nf_out = nf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) no_out = no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* output the best PLL setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if ((nr_out <= PLL_NR_MAX) && (no_out > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) rate_table->nr = nr_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) rate_table->nf = nf_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) rate_table->no = no_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static struct rockchip_pll_rate_table *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) rockchip_rk3588_pll_clk_set_by_auto(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) unsigned long fin_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) unsigned long fout_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct rockchip_pll_rate_table *rate_table = rk_pll_rate_table_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) u64 fvco_min = 2250 * MHZ, fvco_max = 4500 * MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) u64 fout_min = 37 * MHZ, fout_max = 4500 * MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) u32 p, m, s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) u64 fvco, fref, fout, ffrac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (fout_hz > fout_max || fout_hz < fout_min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) for (s = 0; s <= 6; s++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) fvco = (u64)fout_hz << s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (fvco < fvco_min || fvco > fvco_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) for (p = 2; p <= 4; p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) for (m = 64; m <= 1023; m++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (fvco == m * fin_hz / p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) rate_table->p = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) rate_table->m = m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) rate_table->s = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) rate_table->k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) pr_err("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) for (s = 0; s <= 6; s++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) fvco = (u64)fout_hz << s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (fvco < fvco_min || fvco > fvco_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) for (p = 1; p <= 4; p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) for (m = 64; m <= 1023; m++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if ((fvco >= m * fin_hz / p) && (fvco < (m + 1) * fin_hz / p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) rate_table->p = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) rate_table->m = m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) rate_table->s = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) fref = fin_hz / p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) ffrac = fvco - (m * fref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) fout = ffrac * 65536;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) rate_table->k = fout / fref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) pr_err("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct rockchip_clk_pll *pll, unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) for (i = 0; i < pll->rate_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (rate == rate_table[i].rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (i < pll->sel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) pll->scaling = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return &rate_table[pll->sel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) pll->scaling = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return &rate_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) pll->scaling = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (pll->type == pll_rk3066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return rockchip_rk3066_pll_clk_set_by_auto(pll, 24 * MHZ, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) else if (pll->type == pll_rk3588 || pll->type == pll_rk3588_core)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return rockchip_rk3588_pll_clk_set_by_auto(pll, 24 * MHZ, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return rockchip_pll_clk_set_by_auto(pll, 24 * MHZ, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static long rockchip_pll_round_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) unsigned long drate, unsigned long *prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return drate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * Wait for the pll to reach the locked state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * The calling set_rate function is responsible for making sure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * grf regmap is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct regmap *grf = pll->ctx->grf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ret = regmap_read_poll_timeout(grf, pll->lock_offset, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) val & BIT(pll->lock_shift), 0, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) pr_err("%s: timeout waiting for pll to lock\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * PLL used in RK3036
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) #define RK3036_PLLCON(i) (i * 0x4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) #define RK3036_PLLCON0_FBDIV_MASK 0xfff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) #define RK3036_PLLCON0_FBDIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) #define RK3036_PLLCON0_POSTDIV1_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) #define RK3036_PLLCON0_POSTDIV1_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) #define RK3036_PLLCON1_REFDIV_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) #define RK3036_PLLCON1_REFDIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) #define RK3036_PLLCON1_POSTDIV2_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) #define RK3036_PLLCON1_POSTDIV2_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) #define RK3036_PLLCON1_LOCK_STATUS BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) #define RK3036_PLLCON1_DSMPD_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) #define RK3036_PLLCON1_DSMPD_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) #define RK3036_PLLCON1_PWRDOWN BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) #define RK3036_PLLCON1_PLLPDSEL BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #define RK3036_PLLCON2_FRAC_MASK 0xffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) #define RK3036_PLLCON2_FRAC_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) u32 pllcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * Lock time typical 250, max 500 input clock cycles @24MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * So define a very safe maximum of 1000us, meaning 24000 cycles.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ret = readl_relaxed_poll_timeout(pll->reg_base + RK3036_PLLCON(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) pllcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) pllcon & RK3036_PLLCON1_LOCK_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 0, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) pr_err("%s: timeout waiting for pll to lock\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) static unsigned long __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) rockchip_rk3036_pll_con_to_rate(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) u32 con0, u32 con1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) unsigned int fbdiv, postdiv1, refdiv, postdiv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) u64 rate64 = 24000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) fbdiv = ((con0 >> RK3036_PLLCON0_FBDIV_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) RK3036_PLLCON0_FBDIV_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) postdiv1 = ((con0 >> RK3036_PLLCON0_POSTDIV1_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) RK3036_PLLCON0_POSTDIV1_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) refdiv = ((con1 >> RK3036_PLLCON1_REFDIV_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) RK3036_PLLCON1_REFDIV_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) postdiv2 = ((con1 >> RK3036_PLLCON1_POSTDIV2_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) RK3036_PLLCON1_POSTDIV2_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) rate64 *= fbdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) do_div(rate64, refdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) do_div(rate64, postdiv1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) do_div(rate64, postdiv2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return (unsigned long)rate64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct rockchip_pll_rate_table *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) u32 pllcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) rate->fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) & RK3036_PLLCON0_FBDIV_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) rate->postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) & RK3036_PLLCON0_POSTDIV1_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) rate->refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) & RK3036_PLLCON1_REFDIV_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) rate->postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) & RK3036_PLLCON1_POSTDIV2_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) rate->dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) & RK3036_PLLCON1_DSMPD_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) rate->frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) & RK3036_PLLCON2_FRAC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct rockchip_pll_rate_table cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) u64 rate64 = prate, frac_rate64 = prate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (pll->sel && pll->scaling)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return pll->scaling;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) rockchip_rk3036_pll_get_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) rate64 *= cur.fbdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) do_div(rate64, cur.refdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (cur.dsmpd == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* fractional mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) frac_rate64 *= cur.frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) do_div(frac_rate64, cur.refdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) rate64 += frac_rate64 >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) do_div(rate64, cur.postdiv1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) do_div(rate64, cur.postdiv2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return (unsigned long)rate64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) const struct rockchip_pll_rate_table *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct clk_mux *pll_mux = &pll->pll_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct rockchip_pll_rate_table cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) u32 pllcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) int rate_change_remuxed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int cur_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) rate->postdiv2, rate->dsmpd, rate->frac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) rockchip_rk3036_pll_get_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) cur.rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (cur_parent == PLL_MODE_NORM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) rate_change_remuxed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /* update pll values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) RK3036_PLLCON0_FBDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) RK3036_PLLCON0_POSTDIV1_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) pll->reg_base + RK3036_PLLCON(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) RK3036_PLLCON1_REFDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) RK3036_PLLCON1_POSTDIV2_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) RK3036_PLLCON1_DSMPD_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) pll->reg_base + RK3036_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /* GPLL CON2 is not HIWORD_MASK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) pllcon &= ~(RK3036_PLLCON2_FRAC_MASK << RK3036_PLLCON2_FRAC_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (IS_ENABLED(CONFIG_ROCKCHIP_CLK_BOOST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) rockchip_boost_disable_low(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* wait for the pll to lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) ret = rockchip_rk3036_pll_wait_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) rockchip_rk3036_pll_set_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (rate_change_remuxed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) const struct rockchip_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) __func__, __clk_get_name(hw->clk), drate, prate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /* Get required rate settings from table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) rate = rockchip_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) drate, __clk_get_name(hw->clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return rockchip_rk3036_pll_set_params(pll, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) static int rockchip_rk3036_pll_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) pll->reg_base + RK3036_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) rockchip_rk3036_pll_wait_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static void rockchip_rk3036_pll_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) writel(HIWORD_UPDATE(RK3036_PLLCON1_PWRDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) RK3036_PLLCON1_PWRDOWN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) pll->reg_base + RK3036_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) u32 pllcon = readl(pll->reg_base + RK3036_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return !(pllcon & RK3036_PLLCON1_PWRDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) static int rockchip_rk3036_pll_init(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) const struct rockchip_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct rockchip_pll_rate_table cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) unsigned long drate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) drate = clk_hw_get_rate(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) rate = rockchip_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /* when no rate setting for the current rate, rely on clk_set_rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) rockchip_rk3036_pll_get_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) cur.dsmpd, cur.frac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) rate->dsmpd, rate->frac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) rate->dsmpd != cur.dsmpd ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) (!cur.dsmpd && (rate->frac != cur.frac))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct clk *parent = clk_get_parent(hw->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (!parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) pr_warn("%s: parent of %s not available\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) __func__, __clk_get_name(hw->clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) __func__, __clk_get_name(hw->clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) rockchip_rk3036_pll_set_params(pll, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) .recalc_rate = rockchip_rk3036_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) .enable = rockchip_rk3036_pll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) .disable = rockchip_rk3036_pll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) .is_enabled = rockchip_rk3036_pll_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static const struct clk_ops rockchip_rk3036_pll_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) .recalc_rate = rockchip_rk3036_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) .round_rate = rockchip_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) .set_rate = rockchip_rk3036_pll_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) .enable = rockchip_rk3036_pll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) .disable = rockchip_rk3036_pll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) .is_enabled = rockchip_rk3036_pll_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) .init = rockchip_rk3036_pll_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * PLL used in RK3066, RK3188 and RK3288
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) #define RK3066_PLL_RESET_DELAY(nr) ((nr * 500) / 24 + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) #define RK3066_PLLCON(i) (i * 0x4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) #define RK3066_PLLCON0_OD_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) #define RK3066_PLLCON0_OD_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) #define RK3066_PLLCON0_NR_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) #define RK3066_PLLCON0_NR_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) #define RK3066_PLLCON1_NF_MASK 0x1fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) #define RK3066_PLLCON1_NF_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) #define RK3066_PLLCON2_NB_MASK 0xfff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) #define RK3066_PLLCON2_NB_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) #define RK3066_PLLCON3_RESET (1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) #define RK3066_PLLCON3_PWRDOWN (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) #define RK3066_PLLCON3_BYPASS (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct rockchip_pll_rate_table *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) u32 pllcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) & RK3066_PLLCON0_NR_MASK) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) & RK3066_PLLCON0_OD_MASK) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) & RK3066_PLLCON1_NF_MASK) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) & RK3066_PLLCON2_NB_MASK) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct rockchip_pll_rate_table cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) u64 rate64 = prate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) u32 pllcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (pllcon & RK3066_PLLCON3_BYPASS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) pr_debug("%s: pll %s is bypassed\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return prate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (pll->sel && pll->scaling)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return pll->scaling;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) rockchip_rk3066_pll_get_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) rate64 *= cur.nf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) do_div(rate64, cur.nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) do_div(rate64, cur.no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return (unsigned long)rate64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) const struct rockchip_pll_rate_table *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct clk_mux *pll_mux = &pll->pll_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct rockchip_pll_rate_table cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) int rate_change_remuxed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) int cur_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) __func__, rate->rate, rate->nr, rate->no, rate->nf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) rockchip_rk3066_pll_get_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) cur.rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (cur_parent == PLL_MODE_NORM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) rate_change_remuxed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) /* enter reset mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) writel(HIWORD_UPDATE(RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) pll->reg_base + RK3066_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /* update pll values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) writel(HIWORD_UPDATE(rate->nr - 1, RK3066_PLLCON0_NR_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) RK3066_PLLCON0_NR_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) HIWORD_UPDATE(rate->no - 1, RK3066_PLLCON0_OD_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) RK3066_PLLCON0_OD_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) pll->reg_base + RK3066_PLLCON(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) writel_relaxed(HIWORD_UPDATE(rate->nf - 1, RK3066_PLLCON1_NF_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) RK3066_PLLCON1_NF_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) pll->reg_base + RK3066_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) writel_relaxed(HIWORD_UPDATE(rate->nb - 1, RK3066_PLLCON2_NB_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) RK3066_PLLCON2_NB_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) pll->reg_base + RK3066_PLLCON(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) /* leave reset and wait the reset_delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) writel(HIWORD_UPDATE(0, RK3066_PLLCON3_RESET, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) pll->reg_base + RK3066_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) udelay(RK3066_PLL_RESET_DELAY(rate->nr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) /* wait for the pll to lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ret = rockchip_pll_wait_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) rockchip_rk3066_pll_set_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (rate_change_remuxed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) const struct rockchip_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct regmap *grf = pll->ctx->grf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (IS_ERR(grf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) pr_debug("%s: grf regmap not available, aborting rate change\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return PTR_ERR(grf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) __func__, clk_hw_get_name(hw), old_rate, drate, prate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) /* Get required rate settings from table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) rate = rockchip_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) drate, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) ret = rockchip_rk3066_pll_set_params(pll, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) pll->scaling = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) writel(HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) pll->reg_base + RK3066_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) rockchip_pll_wait_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) static void rockchip_rk3066_pll_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) writel(HIWORD_UPDATE(RK3066_PLLCON3_PWRDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) RK3066_PLLCON3_PWRDOWN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) pll->reg_base + RK3066_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) u32 pllcon = readl(pll->reg_base + RK3066_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return !(pllcon & RK3066_PLLCON3_PWRDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) static int rockchip_rk3066_pll_init(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) const struct rockchip_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct rockchip_pll_rate_table cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) unsigned long drate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) drate = clk_hw_get_rate(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) rate = rockchip_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) /* when no rate setting for the current rate, rely on clk_set_rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) rockchip_rk3066_pll_get_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) || rate->nb != cur.nb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) __func__, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) rockchip_rk3066_pll_set_params(pll, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) .recalc_rate = rockchip_rk3066_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) .enable = rockchip_rk3066_pll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .disable = rockchip_rk3066_pll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .is_enabled = rockchip_rk3066_pll_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .recalc_rate = rockchip_rk3066_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .round_rate = rockchip_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .set_rate = rockchip_rk3066_pll_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) .enable = rockchip_rk3066_pll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .disable = rockchip_rk3066_pll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) .is_enabled = rockchip_rk3066_pll_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .init = rockchip_rk3066_pll_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) * PLL used in RK3399
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) #define RK3399_PLLCON(i) (i * 0x4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) #define RK3399_PLLCON0_FBDIV_MASK 0xfff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) #define RK3399_PLLCON0_FBDIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) #define RK3399_PLLCON1_REFDIV_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) #define RK3399_PLLCON1_REFDIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) #define RK3399_PLLCON1_POSTDIV1_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) #define RK3399_PLLCON1_POSTDIV1_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) #define RK3399_PLLCON1_POSTDIV2_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) #define RK3399_PLLCON1_POSTDIV2_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) #define RK3399_PLLCON2_FRAC_MASK 0xffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) #define RK3399_PLLCON2_FRAC_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) #define RK3399_PLLCON2_LOCK_STATUS BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) #define RK3399_PLLCON3_PWRDOWN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) #define RK3399_PLLCON3_DSMPD_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) #define RK3399_PLLCON3_DSMPD_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) u32 pllcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * Lock time typical 250, max 500 input clock cycles @24MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * So define a very safe maximum of 1000us, meaning 24000 cycles.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ret = readl_relaxed_poll_timeout(pll->reg_base + RK3399_PLLCON(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) pllcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) pllcon & RK3399_PLLCON2_LOCK_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 0, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) pr_err("%s: timeout waiting for pll to lock\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct rockchip_pll_rate_table *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) u32 pllcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) & RK3399_PLLCON0_FBDIV_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) & RK3399_PLLCON1_REFDIV_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) & RK3399_PLLCON1_POSTDIV1_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) & RK3399_PLLCON1_POSTDIV2_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) & RK3399_PLLCON2_FRAC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) & RK3399_PLLCON3_DSMPD_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct rockchip_pll_rate_table cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) u64 rate64 = prate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (pll->sel && pll->scaling)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) return pll->scaling;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) rockchip_rk3399_pll_get_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) rate64 *= cur.fbdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) do_div(rate64, cur.refdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (cur.dsmpd == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) /* fractional mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) u64 frac_rate64 = prate * cur.frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) do_div(frac_rate64, cur.refdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) rate64 += frac_rate64 >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) do_div(rate64, cur.postdiv1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) do_div(rate64, cur.postdiv2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return (unsigned long)rate64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) const struct rockchip_pll_rate_table *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) struct clk_mux *pll_mux = &pll->pll_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) struct rockchip_pll_rate_table cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) u32 pllcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) int rate_change_remuxed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) int cur_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) rate->postdiv2, rate->dsmpd, rate->frac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) rockchip_rk3399_pll_get_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) cur.rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (cur_parent == PLL_MODE_NORM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) rate_change_remuxed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) /* set pll power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) RK3399_PLLCON3_PWRDOWN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) pll->reg_base + RK3399_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) /* update pll values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) RK3399_PLLCON0_FBDIV_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) pll->reg_base + RK3399_PLLCON(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) RK3399_PLLCON1_REFDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) RK3399_PLLCON1_POSTDIV1_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) RK3399_PLLCON1_POSTDIV2_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) pll->reg_base + RK3399_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) /* xPLL CON2 is not HIWORD_MASK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) RK3399_PLLCON3_DSMPD_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) pll->reg_base + RK3399_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) /* set pll power up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) writel(HIWORD_UPDATE(0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) RK3399_PLLCON3_PWRDOWN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) pll->reg_base + RK3399_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /* wait for the pll to lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) ret = rockchip_rk3399_pll_wait_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) rockchip_rk3399_pll_set_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (rate_change_remuxed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) const struct rockchip_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) unsigned long old_rate = rockchip_rk3399_pll_recalc_rate(hw, prate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) /* Get required rate settings from table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) rate = rockchip_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) drate, __clk_get_name(hw->clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) ret = rockchip_rk3399_pll_set_params(pll, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) pll->scaling = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) static int rockchip_rk3399_pll_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) pll->reg_base + RK3399_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) rockchip_rk3399_pll_wait_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) static void rockchip_rk3399_pll_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) RK3399_PLLCON3_PWRDOWN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) pll->reg_base + RK3399_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return !(pllcon & RK3399_PLLCON3_PWRDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) static int rockchip_rk3399_pll_init(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) const struct rockchip_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) struct rockchip_pll_rate_table cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) unsigned long drate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) drate = clk_hw_get_rate(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) rate = rockchip_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /* when no rate setting for the current rate, rely on clk_set_rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) rockchip_rk3399_pll_get_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) cur.dsmpd, cur.frac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) rate->dsmpd, rate->frac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) rate->dsmpd != cur.dsmpd ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) (!cur.dsmpd && (rate->frac != cur.frac))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) struct clk *parent = clk_get_parent(hw->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) if (!parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) pr_warn("%s: parent of %s not available\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) __func__, __clk_get_name(hw->clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) __func__, __clk_get_name(hw->clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) rockchip_rk3399_pll_set_params(pll, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) .recalc_rate = rockchip_rk3399_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) .enable = rockchip_rk3399_pll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) .disable = rockchip_rk3399_pll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) .is_enabled = rockchip_rk3399_pll_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static const struct clk_ops rockchip_rk3399_pll_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) .recalc_rate = rockchip_rk3399_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) .round_rate = rockchip_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) .set_rate = rockchip_rk3399_pll_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) .enable = rockchip_rk3399_pll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) .disable = rockchip_rk3399_pll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) .is_enabled = rockchip_rk3399_pll_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) .init = rockchip_rk3399_pll_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) * PLL used in RK3588
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) #define RK3588_PLLCON(i) (i * 0x4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) #define RK3588_PLLCON0_M_MASK 0x3ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) #define RK3588_PLLCON0_M_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) #define RK3588_PLLCON1_P_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) #define RK3588_PLLCON1_P_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) #define RK3588_PLLCON1_S_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) #define RK3588_PLLCON1_S_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) #define RK3588_PLLCON2_K_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) #define RK3588_PLLCON2_K_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) #define RK3588_PLLCON1_PWRDOWN BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) #define RK3588_PLLCON6_LOCK_STATUS BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static int rockchip_rk3588_pll_wait_lock(struct rockchip_clk_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) u32 pllcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) * Lock time typical 250, max 500 input clock cycles @24MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) * So define a very safe maximum of 1000us, meaning 24000 cycles.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) ret = readl_relaxed_poll_timeout(pll->reg_base + RK3588_PLLCON(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) pllcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) pllcon & RK3588_PLLCON6_LOCK_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 0, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) pr_err("%s: timeout waiting for pll to lock\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) static long rockchip_rk3588_pll_round_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) unsigned long drate, unsigned long *prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if ((drate < 37 * MHZ) || (drate > 4500 * MHZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) return drate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) static void rockchip_rk3588_pll_get_params(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) struct rockchip_pll_rate_table *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) u32 pllcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) rate->m = ((pllcon >> RK3588_PLLCON0_M_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) & RK3588_PLLCON0_M_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) rate->p = ((pllcon >> RK3588_PLLCON1_P_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) & RK3588_PLLCON1_P_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) rate->s = ((pllcon >> RK3588_PLLCON1_S_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) & RK3588_PLLCON1_S_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) rate->k = ((pllcon >> RK3588_PLLCON2_K_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) & RK3588_PLLCON2_K_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) static unsigned long rockchip_rk3588_pll_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) struct rockchip_pll_rate_table cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) u64 rate64 = prate, postdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) if (pll->sel && pll->scaling)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) return pll->scaling;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) rockchip_rk3588_pll_get_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) if (cur.p == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return prate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) rate64 *= cur.m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) do_div(rate64, cur.p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (cur.k) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) /* fractional mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) u64 frac_rate64 = prate * cur.k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) postdiv = cur.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) postdiv *= 65536;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) do_div(frac_rate64, postdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) rate64 += frac_rate64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) rate64 = rate64 >> cur.s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return (unsigned long)rate64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) static int rockchip_rk3588_pll_set_params(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) const struct rockchip_pll_rate_table *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) struct clk_mux *pll_mux = &pll->pll_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) struct rockchip_pll_rate_table cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) int rate_change_remuxed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) int cur_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) pr_debug("%s: rate settings for %lu p: %d, m: %d, s: %d, k: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) __func__, rate->rate, rate->p, rate->m, rate->s, rate->k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) rockchip_rk3588_pll_get_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) cur.rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (pll->type == pll_rk3588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (cur_parent == PLL_MODE_NORM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) rate_change_remuxed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) /* set pll power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) writel(HIWORD_UPDATE(RK3588_PLLCON1_PWRDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) RK3588_PLLCON1_PWRDOWN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) pll->reg_base + RK3588_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) /* update pll values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) writel_relaxed(HIWORD_UPDATE(rate->m, RK3588_PLLCON0_M_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) RK3588_PLLCON0_M_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) pll->reg_base + RK3588_PLLCON(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) writel_relaxed(HIWORD_UPDATE(rate->p, RK3588_PLLCON1_P_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) RK3588_PLLCON1_P_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) HIWORD_UPDATE(rate->s, RK3588_PLLCON1_S_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) RK3588_PLLCON1_S_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) pll->reg_base + RK3588_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) writel_relaxed(HIWORD_UPDATE(rate->k, RK3588_PLLCON2_K_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) RK3588_PLLCON2_K_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) pll->reg_base + RK3588_PLLCON(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) /* set pll power up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) writel(HIWORD_UPDATE(0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) RK3588_PLLCON1_PWRDOWN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) pll->reg_base + RK3588_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) /* wait for the pll to lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) ret = rockchip_rk3588_pll_wait_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) rockchip_rk3588_pll_set_params(pll, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) if ((pll->type == pll_rk3588) && rate_change_remuxed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) static int rockchip_rk3588_pll_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) const struct rockchip_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) unsigned long old_rate = rockchip_rk3588_pll_recalc_rate(hw, prate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) /* Get required rate settings from table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) rate = rockchip_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) drate, __clk_get_name(hw->clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) ret = rockchip_rk3588_pll_set_params(pll, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) pll->scaling = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) static int rockchip_rk3588_pll_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) struct clk_mux *pll_mux = &pll->pll_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) writel(HIWORD_UPDATE(0, RK3588_PLLCON1_PWRDOWN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) pll->reg_base + RK3588_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) rockchip_rk3588_pll_wait_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) static void rockchip_rk3588_pll_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) struct clk_mux *pll_mux = &pll->pll_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) writel(HIWORD_UPDATE(RK3588_PLLCON1_PWRDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) RK3588_PLLCON1_PWRDOWN, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) pll->reg_base + RK3588_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) static int rockchip_rk3588_pll_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) u32 pllcon = readl(pll->reg_base + RK3588_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) return !(pllcon & RK3588_PLLCON1_PWRDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) static int rockchip_rk3588_pll_init(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) static const struct clk_ops rockchip_rk3588_pll_clk_norate_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) .recalc_rate = rockchip_rk3588_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) .enable = rockchip_rk3588_pll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) .disable = rockchip_rk3588_pll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) .is_enabled = rockchip_rk3588_pll_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) static const struct clk_ops rockchip_rk3588_pll_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) .recalc_rate = rockchip_rk3588_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) .round_rate = rockchip_rk3588_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) .set_rate = rockchip_rk3588_pll_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) .enable = rockchip_rk3588_pll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) .disable = rockchip_rk3588_pll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) .is_enabled = rockchip_rk3588_pll_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) .init = rockchip_rk3588_pll_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) #ifdef CONFIG_ROCKCHIP_CLK_COMPENSATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) int rockchip_pll_clk_compensation(struct clk *clk, int ppm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) struct clk *parent = clk_get_parent(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) struct rockchip_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) static u32 frac, fbdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) bool negative;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) u32 pllcon, pllcon0, pllcon2, fbdiv_mask, frac_mask, frac_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) u64 fracdiv, m, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if ((ppm > 1000) || (ppm < -1000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) if (IS_ERR_OR_NULL(parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) pll = to_rockchip_clk_pll(__clk_get_hw(parent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) if (!pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) switch (pll->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) case pll_rk3036:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) case pll_rk3328:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) pllcon0 = RK3036_PLLCON(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) pllcon2 = RK3036_PLLCON(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) fbdiv_mask = RK3036_PLLCON0_FBDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) frac_mask = RK3036_PLLCON2_FRAC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) frac_shift = RK3036_PLLCON2_FRAC_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) if (!frac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) writel(HIWORD_UPDATE(RK3036_PLLCON1_PLLPDSEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) RK3036_PLLCON1_PLLPDSEL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) pll->reg_base + RK3036_PLLCON(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) case pll_rk3066:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) case pll_rk3399:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) pllcon0 = RK3399_PLLCON(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) pllcon2 = RK3399_PLLCON(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) fbdiv_mask = RK3399_PLLCON0_FBDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) frac_mask = RK3399_PLLCON2_FRAC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) frac_shift = RK3399_PLLCON2_FRAC_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) case pll_rk3588:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) pllcon0 = RK3588_PLLCON(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) pllcon2 = RK3588_PLLCON(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) fbdiv_mask = RK3588_PLLCON0_M_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) frac_mask = RK3588_PLLCON2_K_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) frac_shift = RK3588_PLLCON2_K_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) negative = !!(ppm & BIT(31));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) ppm = negative ? ~ppm + 1 : ppm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if (!frac) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) frac = readl_relaxed(pll->reg_base + pllcon2) & frac_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) fbdiv = readl_relaxed(pll->reg_base + pllcon0) & fbdiv_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) switch (pll->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) case pll_rk3036:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) case pll_rk3328:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) case pll_rk3066:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) case pll_rk3399:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) * delta frac frac ppm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) * -------------- = (fbdiv + ----------) * ---------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) * 1 << 24 1 << 24 1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) m = div64_u64((uint64_t)frac * ppm, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) n = div64_u64((uint64_t)ppm << 24, 1000000) * fbdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) fracdiv = negative ? frac - (m + n) : frac + (m + n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) if (!frac || fracdiv > frac_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) pllcon = readl_relaxed(pll->reg_base + pllcon2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) pllcon &= ~(frac_mask << frac_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) pllcon |= fracdiv << frac_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) writel_relaxed(pllcon, pll->reg_base + pllcon2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) case pll_rk3588:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) m = div64_u64((uint64_t)frac * ppm, 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) n = div64_u64((uint64_t)ppm * 65535 * fbdiv, 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) fracdiv = negative ? frac - (div64_u64(m + n, 10)) : frac + (div64_u64(m + n, 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) if (!frac || fracdiv > frac_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) writel_relaxed(HIWORD_UPDATE(fracdiv, frac_mask, frac_shift),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) pll->reg_base + pllcon2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) EXPORT_SYMBOL(rockchip_pll_clk_compensation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) * Common registering of pll clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) enum rockchip_pll_type pll_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) const char *name, const char *const *parent_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) u8 num_parents, int con_offset, int grf_lock_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) int lock_shift, int mode_offset, int mode_shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) struct rockchip_pll_rate_table *rate_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) unsigned long flags, u8 clk_pll_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) const char *pll_parents[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) struct rockchip_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) struct clk_mux *pll_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) struct clk *pll_clk, *mux_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) char pll_name[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if ((pll_type != pll_rk3328 && num_parents != 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) (pll_type == pll_rk3328 && num_parents != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) pr_err("%s: needs two parent clocks\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) /* name the actual pll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) snprintf(pll_name, sizeof(pll_name), "pll_%s", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) pll = kzalloc(sizeof(*pll), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) if (!pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) /* create the mux on top of the real pll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) pll->pll_mux_ops = &clk_mux_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) pll_mux = &pll->pll_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) pll_mux->reg = ctx->reg_base + mode_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) pll_mux->shift = mode_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) if (pll_type == pll_rk3328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) pll_mux->mask = PLL_RK3328_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) pll_mux->mask = PLL_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) pll_mux->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) pll_mux->lock = &ctx->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) pll_mux->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) pll_mux->flags |= CLK_MUX_HIWORD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) /* the actual muxing is xin24m, pll-output, xin32k */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) pll_parents[0] = parent_names[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) pll_parents[1] = pll_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) pll_parents[2] = parent_names[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) init.flags = CLK_SET_RATE_PARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) init.ops = pll->pll_mux_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) init.parent_names = pll_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) if (pll_type == pll_rk3328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) init.num_parents = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) init.num_parents = ARRAY_SIZE(pll_parents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) mux_clk = clk_register(NULL, &pll_mux->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (IS_ERR(mux_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) goto err_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) /* now create the actual pll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) init.name = pll_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) #ifndef CONFIG_ROCKCHIP_LOW_PERFORMANCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) /* keep all plls untouched for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) init.flags = flags | CLK_IGNORE_UNUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) init.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) init.parent_names = &parent_names[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (rate_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) /* find count of rates in rate_table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) for (len = 0; rate_table[len].rate != 0; )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) pll->rate_count = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) pll->rate_table = kmemdup(rate_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) pll->rate_count *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) sizeof(struct rockchip_pll_rate_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) WARN(!pll->rate_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) "%s: could not allocate rate table for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) __func__, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) switch (pll_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) case pll_rk3036:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) case pll_rk3328:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) init.ops = &rockchip_rk3036_pll_clk_norate_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) init.ops = &rockchip_rk3036_pll_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) #ifdef CONFIG_ROCKCHIP_PLL_RK3066
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) case pll_rk3066:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) if (!pll->rate_table || IS_ERR(ctx->grf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) init.ops = &rockchip_rk3066_pll_clk_norate_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) init.ops = &rockchip_rk3066_pll_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) #ifdef CONFIG_ROCKCHIP_PLL_RK3399
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) case pll_rk3399:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) init.ops = &rockchip_rk3399_pll_clk_norate_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) init.ops = &rockchip_rk3399_pll_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) #ifdef CONFIG_ROCKCHIP_PLL_RK3588
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) case pll_rk3588:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) case pll_rk3588_core:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) init.ops = &rockchip_rk3588_pll_clk_norate_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) init.ops = &rockchip_rk3588_pll_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) init.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) pr_warn("%s: Unknown pll type for pll clk %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) __func__, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) pll->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) pll->type = pll_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) pll->reg_base = ctx->reg_base + con_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) pll->lock_offset = grf_lock_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) pll->lock_shift = lock_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) pll->flags = clk_pll_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) pll->lock = &ctx->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) pll->ctx = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) pll_clk = clk_register(NULL, &pll->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (IS_ERR(pll_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) pr_err("%s: failed to register pll clock %s : %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) __func__, name, PTR_ERR(pll_clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) goto err_pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) return mux_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) err_pll:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) clk_unregister(mux_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) mux_clk = pll_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) err_mux:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) kfree(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) return mux_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) #ifdef CONFIG_ROCKCHIP_CLK_BOOST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) static unsigned long rockchip_pll_con_to_rate(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) u32 con0, u32 con1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) switch (pll->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) case pll_rk3036:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) case pll_rk3328:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) return rockchip_rk3036_pll_con_to_rate(pll, con0, con1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) case pll_rk3066:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) case pll_rk3399:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) pr_warn("%s: Unknown pll type\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) void rockchip_boost_init(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) struct rockchip_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) u32 value, con0, con1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) if (!hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) np = of_parse_phandle(pll->ctx->cru_node, "rockchip,boost", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) pr_debug("%s: failed to get boost np\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) pll->boost = syscon_node_to_regmap(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) if (IS_ERR(pll->boost)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) pr_debug("%s: failed to get boost regmap\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) if (!of_property_read_u32(np, "rockchip,boost-low-con0", &con0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) !of_property_read_u32(np, "rockchip,boost-low-con1", &con1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) pr_debug("boost-low-con=0x%x 0x%x\n", con0, con1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) regmap_write(pll->boost, BOOST_PLL_L_CON(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) HIWORD_UPDATE(con0, BOOST_PLL_CON_MASK, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) regmap_write(pll->boost, BOOST_PLL_L_CON(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) HIWORD_UPDATE(con1, BOOST_PLL_CON_MASK, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) pll->boost_low_rate = rockchip_pll_con_to_rate(pll, con0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) con1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) pr_debug("boost-low-rate=%lu\n", pll->boost_low_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) if (!of_property_read_u32(np, "rockchip,boost-high-con0", &con0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) !of_property_read_u32(np, "rockchip,boost-high-con1", &con1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) pr_debug("boost-high-con=0x%x 0x%x\n", con0, con1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) regmap_write(pll->boost, BOOST_PLL_H_CON(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) HIWORD_UPDATE(con0, BOOST_PLL_CON_MASK, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) regmap_write(pll->boost, BOOST_PLL_H_CON(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) HIWORD_UPDATE(con1, BOOST_PLL_CON_MASK, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) pll->boost_high_rate = rockchip_pll_con_to_rate(pll, con0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) con1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) pr_debug("boost-high-rate=%lu\n", pll->boost_high_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) if (!of_property_read_u32(np, "rockchip,boost-backup-pll", &value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) pr_debug("boost-backup-pll=0x%x\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) regmap_write(pll->boost, BOOST_CLK_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) HIWORD_UPDATE(value, BOOST_BACKUP_PLL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) BOOST_BACKUP_PLL_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) if (!of_property_read_u32(np, "rockchip,boost-backup-pll-usage",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) &pll->boost_backup_pll_usage)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) pr_debug("boost-backup-pll-usage=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) pll->boost_backup_pll_usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) regmap_write(pll->boost, BOOST_CLK_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) HIWORD_UPDATE(pll->boost_backup_pll_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) BOOST_BACKUP_PLL_USAGE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) BOOST_BACKUP_PLL_USAGE_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) if (!of_property_read_u32(np, "rockchip,boost-switch-threshold",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) &value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) pr_debug("boost-switch-threshold=0x%x\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) regmap_write(pll->boost, BOOST_SWITCH_THRESHOLD, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) if (!of_property_read_u32(np, "rockchip,boost-statis-threshold",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) &value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) pr_debug("boost-statis-threshold=0x%x\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) regmap_write(pll->boost, BOOST_STATIS_THRESHOLD, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (!of_property_read_u32(np, "rockchip,boost-statis-enable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) &value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) pr_debug("boost-statis-enable=0x%x\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) regmap_write(pll->boost, BOOST_BOOST_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) HIWORD_UPDATE(value, BOOST_STATIS_ENABLE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) BOOST_STATIS_ENABLE_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (!of_property_read_u32(np, "rockchip,boost-enable", &value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) pr_debug("boost-enable=0x%x\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) regmap_write(pll->boost, BOOST_BOOST_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) HIWORD_UPDATE(value, BOOST_ENABLE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) BOOST_ENABLE_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) pll->boost_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) if (pll->boost_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) mutex_lock(&clk_boost_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) hlist_add_head(&pll->debug_node, &clk_boost_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) mutex_unlock(&clk_boost_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) void rockchip_boost_enable_recovery_sw_low(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) struct rockchip_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) if (!hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) if (!pll->boost_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) regmap_write(pll->boost, BOOST_BOOST_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) HIWORD_UPDATE(1, BOOST_RECOVERY_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) BOOST_RECOVERY_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) regmap_read(pll->boost, BOOST_FSM_STATUS, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) } while (!(val & BOOST_BUSY_STATE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) regmap_write(pll->boost, BOOST_BOOST_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) HIWORD_UPDATE(1, BOOST_SW_CTRL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) BOOST_SW_CTRL_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) HIWORD_UPDATE(1, BOOST_LOW_FREQ_EN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) BOOST_LOW_FREQ_EN_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) static void rockchip_boost_disable_low(struct rockchip_clk_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) if (!pll->boost_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) regmap_write(pll->boost, BOOST_BOOST_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) HIWORD_UPDATE(0, BOOST_LOW_FREQ_EN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) BOOST_LOW_FREQ_EN_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) void rockchip_boost_disable_recovery_sw(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) struct rockchip_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) if (!hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) if (!pll->boost_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) regmap_write(pll->boost, BOOST_BOOST_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) HIWORD_UPDATE(0, BOOST_RECOVERY_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) BOOST_RECOVERY_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) regmap_write(pll->boost, BOOST_BOOST_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) HIWORD_UPDATE(0, BOOST_SW_CTRL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) BOOST_SW_CTRL_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) void rockchip_boost_add_core_div(struct clk_hw *hw, unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) struct rockchip_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) unsigned int div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) if (!hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) pll = to_rockchip_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) if (!pll->boost_enabled || pll->boost_backup_pll_rate == prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) /* todo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) if (pll->boost_backup_pll_usage == BOOST_BACKUP_PLL_USAGE_TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) * cpu clock rate should be less than or equal to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) * low rate when change pll rate in boost module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) if (pll->boost_low_rate && prate > pll->boost_low_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) div = DIV_ROUND_UP(prate, pll->boost_low_rate) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) regmap_write(pll->boost, BOOST_CLK_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) HIWORD_UPDATE(div, BOOST_CORE_DIV_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) BOOST_CORE_DIV_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) pll->boost_backup_pll_rate = prate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) static int boost_summary_show(struct seq_file *s, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) struct rockchip_clk_pll *pll = (struct rockchip_clk_pll *)s->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) u32 boost_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) u32 freq_cnt0 = 0, freq_cnt1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) u64 freq_cnt = 0, high_freq_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) u32 short_count = 0, short_threshold = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) u32 interval_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) seq_puts(s, " device boost_count high_freq_count high_freq_time short_count short_threshold interval_count\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) seq_puts(s, "------------------------------------------------------------------------------------------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) seq_printf(s, " %s\n", clk_hw_get_name(&pll->hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) regmap_read(pll->boost, BOOST_SWITCH_CNT, &boost_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) regmap_read(pll->boost, BOOST_HIGH_PERF_CNT0, &freq_cnt0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) regmap_read(pll->boost, BOOST_HIGH_PERF_CNT1, &freq_cnt1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) freq_cnt = ((u64)freq_cnt1 << 32) + (u64)freq_cnt0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) high_freq_time = freq_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) do_div(high_freq_time, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) regmap_read(pll->boost, BOOST_SHORT_SWITCH_CNT, &short_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) regmap_read(pll->boost, BOOST_STATIS_THRESHOLD, &short_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) regmap_read(pll->boost, BOOST_SWITCH_THRESHOLD, &interval_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) seq_printf(s, "%22u %17llu %15llu %12u %16u %15u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) boost_count, freq_cnt, high_freq_time, short_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) short_threshold, interval_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) static int boost_summary_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) return single_open(file, boost_summary_show, inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) static const struct file_operations boost_summary_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) .open = boost_summary_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) .read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) .llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) .release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) static int boost_config_show(struct seq_file *s, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) struct rockchip_clk_pll *pll = (struct rockchip_clk_pll *)s->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) seq_printf(s, "boost_enabled: %d\n", pll->boost_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) seq_printf(s, "boost_low_rate: %lu\n", pll->boost_low_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) seq_printf(s, "boost_high_rate: %lu\n", pll->boost_high_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) static int boost_config_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) return single_open(file, boost_config_show, inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) static const struct file_operations boost_config_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) .open = boost_config_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) .read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) .llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) .release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) static int boost_debug_create_one(struct rockchip_clk_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) struct dentry *rootdir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) struct dentry *pdentry, *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) pdentry = debugfs_lookup(clk_hw_get_name(&pll->hw), rootdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) if (!pdentry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) pr_err("%s: failed to lookup %s dentry\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) clk_hw_get_name(&pll->hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) d = debugfs_create_file("boost_summary", 0444, pdentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) pll, &boost_summary_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) if (!d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) pr_err("%s: failed to create boost_summary file\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) d = debugfs_create_file("boost_config", 0444, pdentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) pll, &boost_config_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) if (!d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) pr_err("%s: failed to create boost config file\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) static int __init boost_debug_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) struct rockchip_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) struct dentry *rootdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) rootdir = debugfs_lookup("clk", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) if (!rootdir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) pr_err("%s: failed to lookup clk dentry\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) mutex_lock(&clk_boost_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) hlist_for_each_entry(pll, &clk_boost_list, debug_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) boost_debug_create_one(pll, rootdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) mutex_unlock(&clk_boost_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) late_initcall(boost_debug_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) #endif /* MODULE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) #endif /* CONFIG_DEBUG_FS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) #endif /* CONFIG_ROCKCHIP_CLK_BOOST */