^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2012 Freescale Semiconductor, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "clk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * struct clk_pll - mxs pll clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * @hw: clk_hw for the pll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * @base: base address of the pll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * @power: the shift of power bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * @rate: the clock rate of the pll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * The mxs pll is a fixed rate clock with power and gate control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * and the shift of gate bit is always 31.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct clk_pll {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) u8 power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static int clk_pll_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) writel_relaxed(1 << pll->power, pll->base + SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static void clk_pll_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) writel_relaxed(1 << pll->power, pll->base + CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int clk_pll_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) writel_relaxed(1 << 31, pll->base + CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static void clk_pll_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) writel_relaxed(1 << 31, pll->base + SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return pll->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static const struct clk_ops clk_pll_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .prepare = clk_pll_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .unprepare = clk_pll_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .enable = clk_pll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .disable = clk_pll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .recalc_rate = clk_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct clk *mxs_clk_pll(const char *name, const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) void __iomem *base, u8 power, unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) pll = kzalloc(sizeof(*pll), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (!pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) init.ops = &clk_pll_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) init.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) init.parent_names = (parent_name ? &parent_name: NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) init.num_parents = (parent_name ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) pll->base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) pll->rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) pll->power = power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) pll->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) clk = clk_register(NULL, &pll->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) kfree(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }