sifive-prci.c (efc91ae43c8d4bbf64e4b9a28113b24a74ffd58d) | sifive-prci.c (732374a0b440d9a79c8412f318a25cd37ba6f4e2) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2020 SiFive, Inc. 4 * Copyright (C) 2020 Zong Li 5 */ 6 7#include <linux/clkdev.h> 8#include <linux/delay.h> --- 99 unchanged lines hidden (view full) --- 108 109 /* external feedback mode not supported */ 110 r |= PRCI_COREPLLCFG0_FSE_MASK; 111 112 return r; 113} 114 115/** | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2020 SiFive, Inc. 4 * Copyright (C) 2020 Zong Li 5 */ 6 7#include <linux/clkdev.h> 8#include <linux/delay.h> --- 99 unchanged lines hidden (view full) --- 108 109 /* external feedback mode not supported */ 110 r |= PRCI_COREPLLCFG0_FSE_MASK; 111 112 return r; 113} 114 115/** |
116 * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI | 116 * __prci_wrpll_read_cfg0() - read the WRPLL configuration from the PRCI |
117 * @pd: PRCI context 118 * @pwd: PRCI WRPLL metadata 119 * 120 * Read the current configuration of the PLL identified by @pwd from 121 * the PRCI identified by @pd, and store it into the local configuration 122 * cache in @pwd. 123 * 124 * Context: Any context. Caller must prevent the records pointed to by 125 * @pd and @pwd from changing during execution. 126 */ | 117 * @pd: PRCI context 118 * @pwd: PRCI WRPLL metadata 119 * 120 * Read the current configuration of the PLL identified by @pwd from 121 * the PRCI identified by @pd, and store it into the local configuration 122 * cache in @pwd. 123 * 124 * Context: Any context. Caller must prevent the records pointed to by 125 * @pd and @pwd from changing during execution. 126 */ |
127static void __prci_wrpll_read_cfg(struct __prci_data *pd, 128 struct __prci_wrpll_data *pwd) | 127static void __prci_wrpll_read_cfg0(struct __prci_data *pd, 128 struct __prci_wrpll_data *pwd) |
129{ 130 __prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs)); 131} 132 133/** | 129{ 130 __prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs)); 131} 132 133/** |
134 * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI | 134 * __prci_wrpll_write_cfg0() - write WRPLL configuration into the PRCI |
135 * @pd: PRCI context 136 * @pwd: PRCI WRPLL metadata 137 * @c: WRPLL configuration record to write 138 * 139 * Write the WRPLL configuration described by @c into the WRPLL 140 * configuration register identified by @pwd in the PRCI instance 141 * described by @c. Make a cached copy of the WRPLL's current 142 * configuration so it can be used by other code. 143 * 144 * Context: Any context. Caller must prevent the records pointed to by 145 * @pd and @pwd from changing during execution. 146 */ | 135 * @pd: PRCI context 136 * @pwd: PRCI WRPLL metadata 137 * @c: WRPLL configuration record to write 138 * 139 * Write the WRPLL configuration described by @c into the WRPLL 140 * configuration register identified by @pwd in the PRCI instance 141 * described by @c. Make a cached copy of the WRPLL's current 142 * configuration so it can be used by other code. 143 * 144 * Context: Any context. Caller must prevent the records pointed to by 145 * @pd and @pwd from changing during execution. 146 */ |
147static void __prci_wrpll_write_cfg(struct __prci_data *pd, 148 struct __prci_wrpll_data *pwd, 149 struct wrpll_cfg *c) | 147static void __prci_wrpll_write_cfg0(struct __prci_data *pd, 148 struct __prci_wrpll_data *pwd, 149 struct wrpll_cfg *c) |
150{ 151 __prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd); 152 153 memcpy(&pwd->c, c, sizeof(*c)); 154} 155 | 150{ 151 __prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd); 152 153 memcpy(&pwd->c, c, sizeof(*c)); 154} 155 |
156/** 157 * __prci_wrpll_write_cfg1() - write Clock enable/disable configuration 158 * into the PRCI 159 * @pd: PRCI context 160 * @pwd: PRCI WRPLL metadata 161 * @enable: Clock enable or disable value 162 */ 163static void __prci_wrpll_write_cfg1(struct __prci_data *pd, 164 struct __prci_wrpll_data *pwd, 165 u32 enable) 166{ 167 __prci_writel(enable, pwd->cfg1_offs, pd); 168} 169 |
|
156/* 157 * Linux clock framework integration 158 * 159 * See the Linux clock framework documentation for more information on 160 * these functions. 161 */ 162 163unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw, --- 30 unchanged lines hidden (view full) --- 194 195 r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate); 196 if (r) 197 return r; 198 199 if (pwd->enable_bypass) 200 pwd->enable_bypass(pd); 201 | 170/* 171 * Linux clock framework integration 172 * 173 * See the Linux clock framework documentation for more information on 174 * these functions. 175 */ 176 177unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw, --- 30 unchanged lines hidden (view full) --- 208 209 r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate); 210 if (r) 211 return r; 212 213 if (pwd->enable_bypass) 214 pwd->enable_bypass(pd); 215 |
202 __prci_wrpll_write_cfg(pd, pwd, &pwd->c); | 216 __prci_wrpll_write_cfg0(pd, pwd, &pwd->c); |
203 204 udelay(wrpll_calc_max_lock_us(&pwd->c)); 205 | 217 218 udelay(wrpll_calc_max_lock_us(&pwd->c)); 219 |
220 return 0; 221} 222 223int sifive_clk_is_enabled(struct clk_hw *hw) 224{ 225 struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 226 struct __prci_wrpll_data *pwd = pc->pwd; 227 struct __prci_data *pd = pc->pd; 228 u32 r; 229 230 r = __prci_readl(pd, pwd->cfg1_offs); 231 232 if (r & PRCI_COREPLLCFG1_CKE_MASK) 233 return 1; 234 else 235 return 0; 236} 237 238int sifive_prci_clock_enable(struct clk_hw *hw) 239{ 240 struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 241 struct __prci_wrpll_data *pwd = pc->pwd; 242 struct __prci_data *pd = pc->pd; 243 244 if (sifive_clk_is_enabled(hw)) 245 return 0; 246 247 __prci_wrpll_write_cfg1(pd, pwd, PRCI_COREPLLCFG1_CKE_MASK); 248 |
|
206 if (pwd->disable_bypass) 207 pwd->disable_bypass(pd); 208 209 return 0; 210} 211 | 249 if (pwd->disable_bypass) 250 pwd->disable_bypass(pd); 251 252 return 0; 253} 254 |
255void sifive_prci_clock_disable(struct clk_hw *hw) 256{ 257 struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 258 struct __prci_wrpll_data *pwd = pc->pwd; 259 struct __prci_data *pd = pc->pd; 260 u32 r; 261 262 if (pwd->enable_bypass) 263 pwd->enable_bypass(pd); 264 265 r = __prci_readl(pd, pwd->cfg1_offs); 266 r &= ~PRCI_COREPLLCFG1_CKE_MASK; 267 268 __prci_wrpll_write_cfg1(pd, pwd, r); 269} 270 |
|
212/* TLCLKSEL clock integration */ 213 214unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw, 215 unsigned long parent_rate) 216{ 217 struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 218 struct __prci_data *pd = pc->pd; 219 u32 v; --- 202 unchanged lines hidden (view full) --- 422 init.parent_names = &pic->parent_name; 423 init.num_parents = 1; 424 init.ops = pic->ops; 425 pic->hw.init = &init; 426 427 pic->pd = pd; 428 429 if (pic->pwd) | 271/* TLCLKSEL clock integration */ 272 273unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw, 274 unsigned long parent_rate) 275{ 276 struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 277 struct __prci_data *pd = pc->pd; 278 u32 v; --- 202 unchanged lines hidden (view full) --- 481 init.parent_names = &pic->parent_name; 482 init.num_parents = 1; 483 init.ops = pic->ops; 484 pic->hw.init = &init; 485 486 pic->pd = pd; 487 488 if (pic->pwd) |
430 __prci_wrpll_read_cfg(pd, pic->pwd); | 489 __prci_wrpll_read_cfg0(pd, pic->pwd); |
431 432 r = devm_clk_hw_register(dev, &pic->hw); 433 if (r) { 434 dev_warn(dev, "Failed to register clock %s: %d\n", 435 init.name, r); 436 return r; 437 } 438 --- 77 unchanged lines hidden --- | 490 491 r = devm_clk_hw_register(dev, &pic->hw); 492 if (r) { 493 dev_warn(dev, "Failed to register clock %s: %d\n", 494 init.name, r); 495 return r; 496 } 497 --- 77 unchanged lines hidden --- |