4 * Copyright (C) 2013 Xilinx
6 * Sören Brinkmann <soren.brinkmann@xilinx.com>
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License v2 as published by
10 * the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <linux/clk/zynq.h>
22 #include <linux/clk-provider.h>
23 #include <linux/slab.h>
28 * @hw: Handle between common and hardware-specific interfaces
29 * @pll_ctrl: PLL control register
30 * @pll_status: PLL status register
31 * @lock: Register lock
32 * @lockbit: Indicates the associated PLL_LOCKED bit in the PLL status
37 void __iomem *pll_ctrl;
38 void __iomem *pll_status;
42 #define to_zynq_pll(_hw) container_of(_hw, struct zynq_pll, hw)
44 /* Register bitfield defines */
45 #define PLLCTRL_FBDIV_MASK 0x7f000
46 #define PLLCTRL_FBDIV_SHIFT 12
47 #define PLLCTRL_BPQUAL_MASK (1 << 3)
48 #define PLLCTRL_PWRDWN_MASK 2
49 #define PLLCTRL_PWRDWN_SHIFT 1
50 #define PLLCTRL_RESET_MASK 1
51 #define PLLCTRL_RESET_SHIFT 0
54 * zynq_pll_round_rate() - Round a clock frequency
55 * @hw: Handle between common and hardware-specific interfaces
56 * @rate: Desired clock frequency
57 * @prate: Clock frequency of parent clock
58 * Returns frequency closest to @rate the hardware can generate.
60 static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate,
65 fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
71 return *prate * fbdiv;
75 * zynq_pll_recalc_rate() - Recalculate clock frequency
76 * @hw: Handle between common and hardware-specific interfaces
77 * @parent_rate: Clock frequency of parent clock
78 * Returns current clock frequency.
80 static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
81 unsigned long parent_rate)
83 struct zynq_pll *clk = to_zynq_pll(hw);
87 * makes probably sense to redundantly save fbdiv in the struct
88 * zynq_pll to save the IO access.
90 fbdiv = (readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >>
93 return parent_rate * fbdiv;
97 * zynq_pll_is_enabled - Check if a clock is enabled
98 * @hw: Handle between common and hardware-specific interfaces
99 * Returns 1 if the clock is enabled, 0 otherwise.
101 * Not sure this is a good idea, but since disabled means bypassed for
102 * this clock implementation we say we are always enabled.
104 static int zynq_pll_is_enabled(struct clk_hw *hw)
106 unsigned long flags = 0;
108 struct zynq_pll *clk = to_zynq_pll(hw);
110 spin_lock_irqsave(clk->lock, flags);
112 reg = readl(clk->pll_ctrl);
114 spin_unlock_irqrestore(clk->lock, flags);
116 return !(reg & (PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK));
120 * zynq_pll_enable - Enable clock
121 * @hw: Handle between common and hardware-specific interfaces
122 * Returns 0 on success
124 static int zynq_pll_enable(struct clk_hw *hw)
126 unsigned long flags = 0;
128 struct zynq_pll *clk = to_zynq_pll(hw);
130 if (zynq_pll_is_enabled(hw))
133 pr_info("PLL: enable\n");
135 /* Power up PLL and wait for lock */
136 spin_lock_irqsave(clk->lock, flags);
138 reg = readl(clk->pll_ctrl);
139 reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK);
140 writel(reg, clk->pll_ctrl);
141 while (!(readl(clk->pll_status) & (1 << clk->lockbit)))
144 spin_unlock_irqrestore(clk->lock, flags);
150 * zynq_pll_disable - Disable clock
151 * @hw: Handle between common and hardware-specific interfaces
152 * Returns 0 on success
154 static void zynq_pll_disable(struct clk_hw *hw)
156 unsigned long flags = 0;
158 struct zynq_pll *clk = to_zynq_pll(hw);
160 if (!zynq_pll_is_enabled(hw))
163 pr_info("PLL: shutdown\n");
166 spin_lock_irqsave(clk->lock, flags);
168 reg = readl(clk->pll_ctrl);
169 reg |= PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK;
170 writel(reg, clk->pll_ctrl);
172 spin_unlock_irqrestore(clk->lock, flags);
175 static const struct clk_ops zynq_pll_ops = {
176 .enable = zynq_pll_enable,
177 .disable = zynq_pll_disable,
178 .is_enabled = zynq_pll_is_enabled,
179 .round_rate = zynq_pll_round_rate,
180 .recalc_rate = zynq_pll_recalc_rate
184 * clk_register_zynq_pll() - Register PLL with the clock framework
185 * @np Pointer to the DT device node
187 struct clk *clk_register_zynq_pll(const char *name, const char *parent,
188 void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index,
191 struct zynq_pll *pll;
194 const char *parent_arr[1] = {parent};
195 unsigned long flags = 0;
196 struct clk_init_data initd = {
198 .parent_names = parent_arr,
199 .ops = &zynq_pll_ops,
204 pll = kmalloc(sizeof(*pll), GFP_KERNEL);
206 pr_err("%s: Could not allocate Zynq PLL clk.\n", __func__);
207 return ERR_PTR(-ENOMEM);
210 /* Populate the struct */
211 pll->hw.init = &initd;
212 pll->pll_ctrl = pll_ctrl;
213 pll->pll_status = pll_status;
214 pll->lockbit = lock_index;
217 spin_lock_irqsave(pll->lock, flags);
219 reg = readl(pll->pll_ctrl);
220 reg &= ~PLLCTRL_BPQUAL_MASK;
221 writel(reg, pll->pll_ctrl);
223 spin_unlock_irqrestore(pll->lock, flags);
225 clk = clk_register(NULL, &pll->hw);
226 if (WARN_ON(IS_ERR(clk)))