^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (C) 2012 ST Microelectronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Viresh Kumar <vireshk@kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file is licensed under the terms of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * License version 2. This program is licensed "as is" without any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * warranty of any kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * General Purpose Timer Synthesizer clock implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define pr_fmt(fmt) "clk-gpt-synth: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^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/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "clk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define GPT_MSCALE_MASK 0xFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define GPT_NSCALE_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define GPT_NSCALE_MASK 0xF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * DOC: General Purpose Timer Synthesizer clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Calculates gpt synth clk rate for different values of mscale and nscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Fout= Fin/((2 ^ (N+1)) * (M+1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define to_clk_gpt(_hw) container_of(_hw, struct clk_gpt, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static unsigned long gpt_calc_rate(struct clk_hw *hw, unsigned long prate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct clk_gpt *gpt = to_clk_gpt(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct gpt_rate_tbl *rtbl = gpt->rtbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) prate /= ((1 << (rtbl[index].nscale + 1)) * (rtbl[index].mscale + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return prate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static long clk_gpt_round_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned long *prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct clk_gpt *gpt = to_clk_gpt(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int unused;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return clk_round_rate_index(hw, drate, *prate, gpt_calc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) gpt->rtbl_cnt, &unused);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static unsigned long clk_gpt_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct clk_gpt *gpt = to_clk_gpt(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned int div = 1, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (gpt->lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) spin_lock_irqsave(gpt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) val = readl_relaxed(gpt->reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (gpt->lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) spin_unlock_irqrestore(gpt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) div += val & GPT_MSCALE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) div *= 1 << (((val >> GPT_NSCALE_SHIFT) & GPT_NSCALE_MASK) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (!div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return parent_rate / div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Configures new clock rate of gpt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static int clk_gpt_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct clk_gpt *gpt = to_clk_gpt(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct gpt_rate_tbl *rtbl = gpt->rtbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) unsigned long flags = 0, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) clk_round_rate_index(hw, drate, prate, gpt_calc_rate, gpt->rtbl_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (gpt->lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) spin_lock_irqsave(gpt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) val = readl(gpt->reg) & ~GPT_MSCALE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) val &= ~(GPT_NSCALE_MASK << GPT_NSCALE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) val |= rtbl[i].mscale & GPT_MSCALE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) val |= (rtbl[i].nscale & GPT_NSCALE_MASK) << GPT_NSCALE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) writel_relaxed(val, gpt->reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (gpt->lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) spin_unlock_irqrestore(gpt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static const struct clk_ops clk_gpt_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .recalc_rate = clk_gpt_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .round_rate = clk_gpt_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .set_rate = clk_gpt_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct clk *clk_register_gpt(const char *name, const char *parent_name, unsigned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) long flags, void __iomem *reg, struct gpt_rate_tbl *rtbl, u8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) rtbl_cnt, spinlock_t *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct clk_gpt *gpt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (!name || !parent_name || !reg || !rtbl || !rtbl_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) pr_err("Invalid arguments passed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) gpt = kzalloc(sizeof(*gpt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (!gpt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* struct clk_gpt assignments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) gpt->reg = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) gpt->rtbl = rtbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) gpt->rtbl_cnt = rtbl_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) gpt->lock = lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) gpt->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) init.ops = &clk_gpt_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) init.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) clk = clk_register(NULL, &gpt->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (!IS_ERR_OR_NULL(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) pr_err("clk register failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) kfree(gpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }