11556Srgrimes// SPDX-License-Identifier: GPL-2.0-or-later 21556Srgrimes/* 31556Srgrimes * Copyright (C) 2015 Atmel Corporation, 41556Srgrimes * Nicolas Ferre <nicolas.ferre@atmel.com> 51556Srgrimes * 61556Srgrimes * Based on clk-programmable & clk-peripheral drivers by Boris BREZILLON. 71556Srgrimes */ 81556Srgrimes 91556Srgrimes#include <linux/bitfield.h> 101556Srgrimes#include <linux/clk-provider.h> 111556Srgrimes#include <linux/clkdev.h> 121556Srgrimes#include <linux/clk/at91_pmc.h> 131556Srgrimes#include <linux/of.h> 141556Srgrimes#include <linux/mfd/syscon.h> 151556Srgrimes#include <linux/regmap.h> 161556Srgrimes 171556Srgrimes#include "pmc.h" 181556Srgrimes 191556Srgrimes#define GENERATED_MAX_DIV 255 201556Srgrimes 211556Srgrimesstruct clk_generated { 221556Srgrimes struct clk_hw hw; 231556Srgrimes struct regmap *regmap; 241556Srgrimes struct clk_range range; 251556Srgrimes spinlock_t *lock; 261556Srgrimes u32 *mux_table; 271556Srgrimes u32 id; 281556Srgrimes u32 gckdiv; 291556Srgrimes const struct clk_pcr_layout *layout; 301556Srgrimes struct at91_clk_pms pms; 311556Srgrimes u8 parent_id; 323044Sdg int chg_pid; 333044Sdg}; 341556Srgrimes 351556Srgrimes#define to_clk_generated(hw) \ 361556Srgrimes container_of(hw, struct clk_generated, hw) 371556Srgrimes 381556Srgrimesstatic int clk_generated_set(struct clk_generated *gck, int status) 391556Srgrimes{ 401556Srgrimes unsigned long flags; 411556Srgrimes unsigned int enable = status ? AT91_PMC_PCR_GCKEN : 0; 421556Srgrimes 431556Srgrimes spin_lock_irqsave(gck->lock, flags); 441556Srgrimes regmap_write(gck->regmap, gck->layout->offset, 451556Srgrimes (gck->id & gck->layout->pid_mask)); 461556Srgrimes regmap_update_bits(gck->regmap, gck->layout->offset, 471556Srgrimes AT91_PMC_PCR_GCKDIV_MASK | gck->layout->gckcss_mask | 481556Srgrimes gck->layout->cmd | enable, 491556Srgrimes field_prep(gck->layout->gckcss_mask, gck->parent_id) | 501556Srgrimes gck->layout->cmd | 511556Srgrimes FIELD_PREP(AT91_PMC_PCR_GCKDIV_MASK, gck->gckdiv) | 521556Srgrimes enable); 531556Srgrimes spin_unlock_irqrestore(gck->lock, flags); 541556Srgrimes 551556Srgrimes return 0; 561556Srgrimes} 571556Srgrimes 581556Srgrimesstatic int clk_generated_enable(struct clk_hw *hw) 591556Srgrimes{ 601556Srgrimes struct clk_generated *gck = to_clk_generated(hw); 611556Srgrimes 621556Srgrimes pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n", 631556Srgrimes __func__, gck->gckdiv, gck->parent_id); 641556Srgrimes 651556Srgrimes clk_generated_set(gck, 1); 661556Srgrimes 671556Srgrimes return 0; 681556Srgrimes} 691556Srgrimes 701556Srgrimesstatic void clk_generated_disable(struct clk_hw *hw) 711556Srgrimes{ 721556Srgrimes struct clk_generated *gck = to_clk_generated(hw); 731556Srgrimes unsigned long flags; 741556Srgrimes 751556Srgrimes spin_lock_irqsave(gck->lock, flags); 761556Srgrimes regmap_write(gck->regmap, gck->layout->offset, 771556Srgrimes (gck->id & gck->layout->pid_mask)); 781556Srgrimes regmap_update_bits(gck->regmap, gck->layout->offset, 791556Srgrimes gck->layout->cmd | AT91_PMC_PCR_GCKEN, 801556Srgrimes gck->layout->cmd); 811556Srgrimes spin_unlock_irqrestore(gck->lock, flags); 821556Srgrimes} 831556Srgrimes 841556Srgrimesstatic int clk_generated_is_enabled(struct clk_hw *hw) 851556Srgrimes{ 861556Srgrimes struct clk_generated *gck = to_clk_generated(hw); 871556Srgrimes unsigned long flags; 881556Srgrimes unsigned int status; 891556Srgrimes 901556Srgrimes spin_lock_irqsave(gck->lock, flags); 911556Srgrimes regmap_write(gck->regmap, gck->layout->offset, 921556Srgrimes (gck->id & gck->layout->pid_mask)); 931556Srgrimes regmap_read(gck->regmap, gck->layout->offset, &status); 941556Srgrimes spin_unlock_irqrestore(gck->lock, flags); 951556Srgrimes 961556Srgrimes return !!(status & AT91_PMC_PCR_GCKEN); 971556Srgrimes} 981556Srgrimes 991556Srgrimesstatic unsigned long 1001556Srgrimesclk_generated_recalc_rate(struct clk_hw *hw, 1011556Srgrimes unsigned long parent_rate) 1021556Srgrimes{ 1031556Srgrimes struct clk_generated *gck = to_clk_generated(hw); 1041556Srgrimes 1051556Srgrimes return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1); 1061556Srgrimes} 1071556Srgrimes 1081556Srgrimesstatic void clk_generated_best_diff(struct clk_rate_request *req, 1091556Srgrimes struct clk_hw *parent, 1101556Srgrimes unsigned long parent_rate, u32 div, 1111556Srgrimes int *best_diff, long *best_rate) 1121556Srgrimes{ 1131556Srgrimes unsigned long tmp_rate; 1141556Srgrimes int tmp_diff; 1151556Srgrimes 1161556Srgrimes if (!div) 1171556Srgrimes tmp_rate = parent_rate; 1181556Srgrimes else 1191556Srgrimes tmp_rate = parent_rate / div; 1201556Srgrimes 1211556Srgrimes if (tmp_rate < req->min_rate || tmp_rate > req->max_rate) 1221556Srgrimes return; 1231556Srgrimes 1241556Srgrimes tmp_diff = abs(req->rate - tmp_rate); 1251556Srgrimes 1261556Srgrimes if (*best_diff < 0 || *best_diff >= tmp_diff) { 1271556Srgrimes *best_rate = tmp_rate; 1281556Srgrimes *best_diff = tmp_diff; 1291556Srgrimes req->best_parent_rate = parent_rate; 1301556Srgrimes req->best_parent_hw = parent; 1311556Srgrimes } 1321556Srgrimes} 1331556Srgrimes 1341556Srgrimesstatic int clk_generated_determine_rate(struct clk_hw *hw, 1351556Srgrimes struct clk_rate_request *req) 1361556Srgrimes{ 1371556Srgrimes struct clk_generated *gck = to_clk_generated(hw); 1381556Srgrimes struct clk_hw *parent = NULL; 1391556Srgrimes long best_rate = -EINVAL; 1401556Srgrimes unsigned long min_rate, parent_rate; 1411556Srgrimes int best_diff = -1; 1421556Srgrimes int i; 1431556Srgrimes u32 div; 1441556Srgrimes 1451556Srgrimes /* do not look for a rate that is outside of our range */ 1461556Srgrimes if (gck->range.max && req->rate > gck->range.max) 1471556Srgrimes req->rate = gck->range.max; 1481556Srgrimes if (gck->range.min && req->rate < gck->range.min) 1491556Srgrimes req->rate = gck->range.min; 1501556Srgrimes 1511556Srgrimes for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 1521556Srgrimes if (gck->chg_pid == i) 1531556Srgrimes continue; 1541556Srgrimes 1551556Srgrimes parent = clk_hw_get_parent_by_index(hw, i); 1561556Srgrimes if (!parent) 1571556Srgrimes continue; 1581556Srgrimes 1591556Srgrimes parent_rate = clk_hw_get_rate(parent); 1601556Srgrimes min_rate = DIV_ROUND_CLOSEST(parent_rate, GENERATED_MAX_DIV + 1); 1611556Srgrimes if (!parent_rate || 1621556Srgrimes (gck->range.max && min_rate > gck->range.max)) 1631556Srgrimes continue; 1641556Srgrimes 1651556Srgrimes div = DIV_ROUND_CLOSEST(parent_rate, req->rate); 1661556Srgrimes if (div > GENERATED_MAX_DIV + 1) 1671556Srgrimes div = GENERATED_MAX_DIV + 1; 1681556Srgrimes 1691556Srgrimes clk_generated_best_diff(req, parent, parent_rate, div, 1701556Srgrimes &best_diff, &best_rate); 1711556Srgrimes 1721556Srgrimes if (!best_diff) 1731556Srgrimes break; 1741556Srgrimes } 1751556Srgrimes 1761556Srgrimes /* 1771556Srgrimes * The audio_pll rate can be modified, unlike the five others clocks 1781556Srgrimes * that should never be altered. 1791556Srgrimes * The audio_pll can technically be used by multiple consumers. However, 1801556Srgrimes * with the rate locking, the first consumer to enable to clock will be 1811556Srgrimes * the one definitely setting the rate of the clock. 1821556Srgrimes * Since audio IPs are most likely to request the same rate, we enforce 1831556Srgrimes * that the only clks able to modify gck rate are those of audio IPs. 1841556Srgrimes */ 185 186 if (gck->chg_pid < 0) 187 goto end; 188 189 parent = clk_hw_get_parent_by_index(hw, gck->chg_pid); 190 if (!parent) 191 goto end; 192 193 for (div = 1; div < GENERATED_MAX_DIV + 2; div++) { 194 struct clk_rate_request req_parent; 195 196 clk_hw_forward_rate_request(hw, req, parent, &req_parent, req->rate * div); 197 if (__clk_determine_rate(parent, &req_parent)) 198 continue; 199 clk_generated_best_diff(req, parent, req_parent.rate, div, 200 &best_diff, &best_rate); 201 202 if (!best_diff) 203 break; 204 } 205 206end: 207 pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n", 208 __func__, best_rate, 209 __clk_get_name((req->best_parent_hw)->clk), 210 req->best_parent_rate); 211 212 if (best_rate < 0 || (gck->range.max && best_rate > gck->range.max)) 213 return -EINVAL; 214 215 req->rate = best_rate; 216 return 0; 217} 218 219/* No modification of hardware as we have the flag CLK_SET_PARENT_GATE set */ 220static int clk_generated_set_parent(struct clk_hw *hw, u8 index) 221{ 222 struct clk_generated *gck = to_clk_generated(hw); 223 224 if (index >= clk_hw_get_num_parents(hw)) 225 return -EINVAL; 226 227 if (gck->mux_table) 228 gck->parent_id = clk_mux_index_to_val(gck->mux_table, 0, index); 229 else 230 gck->parent_id = index; 231 232 return 0; 233} 234 235static u8 clk_generated_get_parent(struct clk_hw *hw) 236{ 237 struct clk_generated *gck = to_clk_generated(hw); 238 239 return gck->parent_id; 240} 241 242/* No modification of hardware as we have the flag CLK_SET_RATE_GATE set */ 243static int clk_generated_set_rate(struct clk_hw *hw, 244 unsigned long rate, 245 unsigned long parent_rate) 246{ 247 struct clk_generated *gck = to_clk_generated(hw); 248 u32 div; 249 250 if (!rate) 251 return -EINVAL; 252 253 if (gck->range.max && rate > gck->range.max) 254 return -EINVAL; 255 256 div = DIV_ROUND_CLOSEST(parent_rate, rate); 257 if (div > GENERATED_MAX_DIV + 1 || !div) 258 return -EINVAL; 259 260 gck->gckdiv = div - 1; 261 return 0; 262} 263 264static int clk_generated_save_context(struct clk_hw *hw) 265{ 266 struct clk_generated *gck = to_clk_generated(hw); 267 268 gck->pms.status = clk_generated_is_enabled(&gck->hw); 269 270 return 0; 271} 272 273static void clk_generated_restore_context(struct clk_hw *hw) 274{ 275 struct clk_generated *gck = to_clk_generated(hw); 276 277 if (gck->pms.status) 278 clk_generated_set(gck, gck->pms.status); 279} 280 281static const struct clk_ops generated_ops = { 282 .enable = clk_generated_enable, 283 .disable = clk_generated_disable, 284 .is_enabled = clk_generated_is_enabled, 285 .recalc_rate = clk_generated_recalc_rate, 286 .determine_rate = clk_generated_determine_rate, 287 .get_parent = clk_generated_get_parent, 288 .set_parent = clk_generated_set_parent, 289 .set_rate = clk_generated_set_rate, 290 .save_context = clk_generated_save_context, 291 .restore_context = clk_generated_restore_context, 292}; 293 294/** 295 * clk_generated_startup - Initialize a given clock to its default parent and 296 * divisor parameter. 297 * 298 * @gck: Generated clock to set the startup parameters for. 299 * 300 * Take parameters from the hardware and update local clock configuration 301 * accordingly. 302 */ 303static void clk_generated_startup(struct clk_generated *gck) 304{ 305 u32 tmp; 306 unsigned long flags; 307 308 spin_lock_irqsave(gck->lock, flags); 309 regmap_write(gck->regmap, gck->layout->offset, 310 (gck->id & gck->layout->pid_mask)); 311 regmap_read(gck->regmap, gck->layout->offset, &tmp); 312 spin_unlock_irqrestore(gck->lock, flags); 313 314 gck->parent_id = field_get(gck->layout->gckcss_mask, tmp); 315 gck->gckdiv = FIELD_GET(AT91_PMC_PCR_GCKDIV_MASK, tmp); 316} 317 318struct clk_hw * __init 319at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, 320 const struct clk_pcr_layout *layout, 321 const char *name, const char **parent_names, 322 struct clk_hw **parent_hws, 323 u32 *mux_table, u8 num_parents, u8 id, 324 const struct clk_range *range, 325 int chg_pid) 326{ 327 struct clk_generated *gck; 328 struct clk_init_data init = {}; 329 struct clk_hw *hw; 330 int ret; 331 332 if (!(parent_names || parent_hws)) 333 return ERR_PTR(-ENOMEM); 334 335 gck = kzalloc(sizeof(*gck), GFP_KERNEL); 336 if (!gck) 337 return ERR_PTR(-ENOMEM); 338 339 init.name = name; 340 init.ops = &generated_ops; 341 if (parent_hws) 342 init.parent_hws = (const struct clk_hw **)parent_hws; 343 else 344 init.parent_names = parent_names; 345 init.num_parents = num_parents; 346 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; 347 if (chg_pid >= 0) 348 init.flags |= CLK_SET_RATE_PARENT; 349 350 gck->id = id; 351 gck->hw.init = &init; 352 gck->regmap = regmap; 353 gck->lock = lock; 354 gck->range = *range; 355 gck->chg_pid = chg_pid; 356 gck->layout = layout; 357 gck->mux_table = mux_table; 358 359 clk_generated_startup(gck); 360 hw = &gck->hw; 361 ret = clk_hw_register(NULL, &gck->hw); 362 if (ret) { 363 kfree(gck); 364 hw = ERR_PTR(ret); 365 } 366 367 return hw; 368} 369