diff options
author | Vishal Mahaveer | 2024-07-31 17:06:27 -0500 |
---|---|---|
committer | Praneeth Bajjuri | 2024-08-08 12:55:18 -0500 |
commit | bfe8f8b84b1efd6630d9b228325b80631fd9d3c9 (patch) | |
tree | d4391896465c7f85d57fe71b9c0ec830a63d20b9 | |
parent | 3a5205e9803809f18edc59a40fd9df470f98a00f (diff) | |
download | ti-u-boot-bfe8f8b84b1efd6630d9b228325b80631fd9d3c9.tar.gz ti-u-boot-bfe8f8b84b1efd6630d9b228325b80631fd9d3c9.tar.xz ti-u-boot-bfe8f8b84b1efd6630d9b228325b80631fd9d3c9.zip |
clk: ti: k3-pll: Add calibration support for non fractional mode
PLL calibration needs to be enabled when operating in non fractional
mode. Add the sequence to do a fast calibration when using PLL
in this mode.
Signed-off-by: Vishal Mahaveer <vishalm@ti.com>
-rw-r--r-- | drivers/clk/clk-k3-pll.c | 81 |
1 files changed, 75 insertions, 6 deletions
diff --git a/drivers/clk/clk-k3-pll.c b/drivers/clk/clk-k3-pll.c index bf762c558ef..c1158c13290 100644 --- a/drivers/clk/clk-k3-pll.c +++ b/drivers/clk/clk-k3-pll.c | |||
@@ -25,6 +25,23 @@ | |||
25 | #define PLL_16FFT_FREQ_CTRL0 0x30 | 25 | #define PLL_16FFT_FREQ_CTRL0 0x30 |
26 | #define PLL_16FFT_FREQ_CTRL1 0x34 | 26 | #define PLL_16FFT_FREQ_CTRL1 0x34 |
27 | #define PLL_16FFT_DIV_CTRL 0x38 | 27 | #define PLL_16FFT_DIV_CTRL 0x38 |
28 | #define PLL_16FFT_CAL_CTRL 0x60 | ||
29 | #define PLL_16FFT_CAL_STAT 0x64 | ||
30 | |||
31 | /* CAL STAT register bits */ | ||
32 | #define PLL_16FFT_CAL_STAT_CAL_LOCK BIT(31) | ||
33 | |||
34 | /* CFG register bits */ | ||
35 | #define PLL_16FFT_CFG_PLL_TYPE_SHIFT (0) | ||
36 | #define PLL_16FFT_CFG_PLL_TYPE_MASK (0x3 << 0) | ||
37 | #define PLL_16FFT_CFG_PLL_TYPE_FRACF 1 | ||
38 | |||
39 | /* CAL CTRL register bits */ | ||
40 | #define PLL_16FFT_CAL_CTRL_CAL_EN BIT(31) | ||
41 | #define PLL_16FFT_CAL_CTRL_FAST_CAL BIT(20) | ||
42 | #define PLL_16FFT_CAL_CTRL_CAL_BYP BIT(15) | ||
43 | #define PLL_16FFT_CAL_CTRL_CAL_CNT_SHIFT 16 | ||
44 | #define PLL_16FFT_CAL_CTRL_CAL_CNT_MASK (0x7 << 16) | ||
28 | 45 | ||
29 | /* CTRL register bits */ | 46 | /* CTRL register bits */ |
30 | #define PLL_16FFT_CTRL_BYPASS_EN BIT(31) | 47 | #define PLL_16FFT_CTRL_BYPASS_EN BIT(31) |
@@ -40,9 +57,14 @@ | |||
40 | /* DIV CTRL register bits */ | 57 | /* DIV CTRL register bits */ |
41 | #define PLL_16FFT_DIV_CTRL_REF_DIV_MASK 0x3f | 58 | #define PLL_16FFT_DIV_CTRL_REF_DIV_MASK 0x3f |
42 | 59 | ||
43 | #define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BITS 24 | 60 | /* HSDIV register bits*/ |
44 | #define PLL_16FFT_HSDIV_CTRL_CLKOUT_EN BIT(15) | 61 | #define PLL_16FFT_HSDIV_CTRL_CLKOUT_EN BIT(15) |
45 | 62 | ||
63 | /* FREQ_CTRL1 bits */ | ||
64 | #define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BITS 24 | ||
65 | #define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MASK 0xffffff | ||
66 | #define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_SHIFT 0 | ||
67 | |||
46 | /* KICK register magic values */ | 68 | /* KICK register magic values */ |
47 | #define PLL_KICK0_VALUE 0x68ef3490 | 69 | #define PLL_KICK0_VALUE 0x68ef3490 |
48 | #define PLL_KICK1_VALUE 0xd172bc5a | 70 | #define PLL_KICK1_VALUE 0xd172bc5a |
@@ -63,18 +85,65 @@ static int ti_pll_wait_for_lock(struct clk *clk) | |||
63 | { | 85 | { |
64 | struct ti_pll_clk *pll = to_clk_pll(clk); | 86 | struct ti_pll_clk *pll = to_clk_pll(clk); |
65 | u32 stat; | 87 | u32 stat; |
88 | u32 cfg; | ||
89 | u32 cal; | ||
90 | u32 freq_ctrl1; | ||
66 | int i; | 91 | int i; |
92 | u32 pllfm; | ||
93 | u32 pll_type; | ||
94 | int success; | ||
67 | 95 | ||
68 | for (i = 0; i < 100000; i++) { | 96 | for (i = 0; i < 100000; i++) { |
69 | stat = readl(pll->reg + PLL_16FFT_STAT); | 97 | stat = readl(pll->reg + PLL_16FFT_STAT); |
70 | if (stat & PLL_16FFT_STAT_LOCK) | 98 | if (stat & PLL_16FFT_STAT_LOCK) { |
71 | return 0; | 99 | success = 1; |
100 | break; | ||
101 | } | ||
72 | } | 102 | } |
73 | 103 | ||
74 | printf("%s: pll (%s) failed to lock\n", __func__, | 104 | /* Enable calibration if not in fractional mode of the FRACF PLL */ |
75 | clk->dev->name); | 105 | freq_ctrl1 = readl(pll->reg + PLL_16FFT_FREQ_CTRL1); |
106 | pllfm = freq_ctrl1 & PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MASK; | ||
107 | pllfm >>= PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_SHIFT; | ||
108 | cfg = readl(pll->reg + PLL_16FFT_CFG); | ||
109 | pll_type = (cfg & PLL_16FFT_CFG_PLL_TYPE_MASK) >> PLL_16FFT_CFG_PLL_TYPE_SHIFT; | ||
110 | |||
111 | if (success && pll_type == PLL_16FFT_CFG_PLL_TYPE_FRACF && pllfm == 0) { | ||
112 | cal = readl(pll->reg + PLL_16FFT_CAL_CTRL); | ||
76 | 113 | ||
77 | return -EBUSY; | 114 | /* Enable calibration for FRACF */ |
115 | cal |= PLL_16FFT_CAL_CTRL_CAL_EN; | ||
116 | |||
117 | /* Enable fast cal mode */ | ||
118 | cal |= PLL_16FFT_CAL_CTRL_FAST_CAL; | ||
119 | |||
120 | /* Disable calibration bypass */ | ||
121 | cal &= ~PLL_16FFT_CAL_CTRL_CAL_BYP; | ||
122 | |||
123 | /* Set CALCNT to 2 */ | ||
124 | cal &= ~PLL_16FFT_CAL_CTRL_CAL_CNT_MASK; | ||
125 | cal |= 2 << PLL_16FFT_CAL_CTRL_CAL_CNT_SHIFT; | ||
126 | |||
127 | /* Note this register does not readback the written value. */ | ||
128 | writel(cal, pll->reg + PLL_16FFT_CAL_CTRL); | ||
129 | |||
130 | success = 0; | ||
131 | for (i = 0; i < 100000; i++) { | ||
132 | stat = readl(pll->reg + PLL_16FFT_CAL_STAT); | ||
133 | if (stat & PLL_16FFT_CAL_STAT_CAL_LOCK) { | ||
134 | success = 1; | ||
135 | break; | ||
136 | } | ||
137 | } | ||
138 | } | ||
139 | |||
140 | if (success == 0) { | ||
141 | printf("%s: pll (%s) failed to lock\n", __func__, | ||
142 | clk->dev->name); | ||
143 | return -EBUSY; | ||
144 | } else { | ||
145 | return 0; | ||
146 | } | ||
78 | } | 147 | } |
79 | 148 | ||
80 | static ulong ti_pll_clk_get_rate(struct clk *clk) | 149 | static ulong ti_pll_clk_get_rate(struct clk *clk) |