^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2020 Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Zhu YiXin <yixin.zhu@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Rahul Tanwar <rahul.tanwar@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "clk-cgu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define to_lgm_clk_pll(_hw) container_of(_hw, struct lgm_clk_pll, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define PLL_REF_DIV(x) ((x) + 0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Calculate formula:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * rate = (prate * mult + (prate * frac) / frac_div) / div
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) lgm_pll_calc_rate(unsigned long prate, unsigned int mult,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) unsigned int div, unsigned int frac, unsigned int frac_div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) u64 crate, frate, rate64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) rate64 = prate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) crate = rate64 * mult;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) frate = rate64 * frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) do_div(frate, frac_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) crate += frate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) do_div(crate, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return crate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static unsigned long lgm_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned int div, mult, frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) spin_lock_irqsave(&pll->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) mult = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 0, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) div = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 18, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) frac = lgm_get_clk_val(pll->membase, pll->reg, 2, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) spin_unlock_irqrestore(&pll->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (pll->type == TYPE_LJPLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) div *= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return lgm_pll_calc_rate(prate, mult, div, frac, BIT(24));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static int lgm_pll_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) spin_lock_irqsave(&pll->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ret = lgm_get_clk_val(pll->membase, pll->reg, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) spin_unlock_irqrestore(&pll->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static int lgm_pll_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) spin_lock_irqsave(&pll->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ret = readl_poll_timeout_atomic(pll->membase + pll->reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) val, (val & 0x1), 1, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) spin_unlock_irqrestore(&pll->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static void lgm_pll_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) spin_lock_irqsave(&pll->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) spin_unlock_irqrestore(&pll->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static const struct clk_ops lgm_pll_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .recalc_rate = lgm_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .is_enabled = lgm_pll_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .enable = lgm_pll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .disable = lgm_pll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static struct clk_hw *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) lgm_clk_register_pll(struct lgm_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) const struct lgm_pll_clk_data *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct clk_init_data init = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct lgm_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct device *dev = ctx->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) init.ops = &lgm_pll_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) init.name = list->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) init.flags = list->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) init.parent_data = list->parent_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) init.num_parents = list->num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (!pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) pll->membase = ctx->membase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) pll->lock = ctx->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) pll->reg = list->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) pll->flags = list->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) pll->type = list->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) pll->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) hw = &pll->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ret = devm_clk_hw_register(dev, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return hw;
^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) int lgm_clk_register_plls(struct lgm_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) const struct lgm_pll_clk_data *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) unsigned int nr_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) for (i = 0; i < nr_clk; i++, list++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) hw = lgm_clk_register_pll(ctx, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (IS_ERR(hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) dev_err(ctx->dev, "failed to register pll: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) list->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ctx->clk_data.hws[list->id] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }