pll.c (5511B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Zynq PLL driver 4 * 5 * Copyright (C) 2013 Xilinx 6 * 7 * Sören Brinkmann <soren.brinkmann@xilinx.com> 8 */ 9#include <linux/clk/zynq.h> 10#include <linux/clk-provider.h> 11#include <linux/slab.h> 12#include <linux/io.h> 13 14/** 15 * struct zynq_pll - pll clock 16 * @hw: Handle between common and hardware-specific interfaces 17 * @pll_ctrl: PLL control register 18 * @pll_status: PLL status register 19 * @lock: Register lock 20 * @lockbit: Indicates the associated PLL_LOCKED bit in the PLL status 21 * register. 22 */ 23struct zynq_pll { 24 struct clk_hw hw; 25 void __iomem *pll_ctrl; 26 void __iomem *pll_status; 27 spinlock_t *lock; 28 u8 lockbit; 29}; 30#define to_zynq_pll(_hw) container_of(_hw, struct zynq_pll, hw) 31 32/* Register bitfield defines */ 33#define PLLCTRL_FBDIV_MASK 0x7f000 34#define PLLCTRL_FBDIV_SHIFT 12 35#define PLLCTRL_BPQUAL_MASK (1 << 3) 36#define PLLCTRL_PWRDWN_MASK 2 37#define PLLCTRL_PWRDWN_SHIFT 1 38#define PLLCTRL_RESET_MASK 1 39#define PLLCTRL_RESET_SHIFT 0 40 41#define PLL_FBDIV_MIN 13 42#define PLL_FBDIV_MAX 66 43 44/** 45 * zynq_pll_round_rate() - Round a clock frequency 46 * @hw: Handle between common and hardware-specific interfaces 47 * @rate: Desired clock frequency 48 * @prate: Clock frequency of parent clock 49 * Return: frequency closest to @rate the hardware can generate. 50 */ 51static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate, 52 unsigned long *prate) 53{ 54 u32 fbdiv; 55 56 fbdiv = DIV_ROUND_CLOSEST(rate, *prate); 57 if (fbdiv < PLL_FBDIV_MIN) 58 fbdiv = PLL_FBDIV_MIN; 59 else if (fbdiv > PLL_FBDIV_MAX) 60 fbdiv = PLL_FBDIV_MAX; 61 62 return *prate * fbdiv; 63} 64 65/** 66 * zynq_pll_recalc_rate() - Recalculate clock frequency 67 * @hw: Handle between common and hardware-specific interfaces 68 * @parent_rate: Clock frequency of parent clock 69 * Return: current clock frequency. 70 */ 71static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw, 72 unsigned long parent_rate) 73{ 74 struct zynq_pll *clk = to_zynq_pll(hw); 75 u32 fbdiv; 76 77 /* 78 * makes probably sense to redundantly save fbdiv in the struct 79 * zynq_pll to save the IO access. 80 */ 81 fbdiv = (readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >> 82 PLLCTRL_FBDIV_SHIFT; 83 84 return parent_rate * fbdiv; 85} 86 87/** 88 * zynq_pll_is_enabled - Check if a clock is enabled 89 * @hw: Handle between common and hardware-specific interfaces 90 * Return: 1 if the clock is enabled, 0 otherwise. 91 * 92 * Not sure this is a good idea, but since disabled means bypassed for 93 * this clock implementation we say we are always enabled. 94 */ 95static int zynq_pll_is_enabled(struct clk_hw *hw) 96{ 97 unsigned long flags = 0; 98 u32 reg; 99 struct zynq_pll *clk = to_zynq_pll(hw); 100 101 spin_lock_irqsave(clk->lock, flags); 102 103 reg = readl(clk->pll_ctrl); 104 105 spin_unlock_irqrestore(clk->lock, flags); 106 107 return !(reg & (PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK)); 108} 109 110/** 111 * zynq_pll_enable - Enable clock 112 * @hw: Handle between common and hardware-specific interfaces 113 * Return: 0 on success 114 */ 115static int zynq_pll_enable(struct clk_hw *hw) 116{ 117 unsigned long flags = 0; 118 u32 reg; 119 struct zynq_pll *clk = to_zynq_pll(hw); 120 121 if (zynq_pll_is_enabled(hw)) 122 return 0; 123 124 pr_info("PLL: enable\n"); 125 126 /* Power up PLL and wait for lock */ 127 spin_lock_irqsave(clk->lock, flags); 128 129 reg = readl(clk->pll_ctrl); 130 reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK); 131 writel(reg, clk->pll_ctrl); 132 while (!(readl(clk->pll_status) & (1 << clk->lockbit))) 133 ; 134 135 spin_unlock_irqrestore(clk->lock, flags); 136 137 return 0; 138} 139 140/** 141 * zynq_pll_disable - Disable clock 142 * @hw: Handle between common and hardware-specific interfaces 143 * Returns 0 on success 144 */ 145static void zynq_pll_disable(struct clk_hw *hw) 146{ 147 unsigned long flags = 0; 148 u32 reg; 149 struct zynq_pll *clk = to_zynq_pll(hw); 150 151 if (!zynq_pll_is_enabled(hw)) 152 return; 153 154 pr_info("PLL: shutdown\n"); 155 156 /* shut down PLL */ 157 spin_lock_irqsave(clk->lock, flags); 158 159 reg = readl(clk->pll_ctrl); 160 reg |= PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK; 161 writel(reg, clk->pll_ctrl); 162 163 spin_unlock_irqrestore(clk->lock, flags); 164} 165 166static const struct clk_ops zynq_pll_ops = { 167 .enable = zynq_pll_enable, 168 .disable = zynq_pll_disable, 169 .is_enabled = zynq_pll_is_enabled, 170 .round_rate = zynq_pll_round_rate, 171 .recalc_rate = zynq_pll_recalc_rate 172}; 173 174/** 175 * clk_register_zynq_pll() - Register PLL with the clock framework 176 * @name: PLL name 177 * @parent: Parent clock name 178 * @pll_ctrl: Pointer to PLL control register 179 * @pll_status: Pointer to PLL status register 180 * @lock_index: Bit index to this PLL's lock status bit in @pll_status 181 * @lock: Register lock 182 * Return: handle to the registered clock. 183 */ 184struct clk *clk_register_zynq_pll(const char *name, const char *parent, 185 void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index, 186 spinlock_t *lock) 187{ 188 struct zynq_pll *pll; 189 struct clk *clk; 190 u32 reg; 191 const char *parent_arr[1] = {parent}; 192 unsigned long flags = 0; 193 struct clk_init_data initd = { 194 .name = name, 195 .parent_names = parent_arr, 196 .ops = &zynq_pll_ops, 197 .num_parents = 1, 198 .flags = 0 199 }; 200 201 pll = kmalloc(sizeof(*pll), GFP_KERNEL); 202 if (!pll) 203 return ERR_PTR(-ENOMEM); 204 205 /* Populate the struct */ 206 pll->hw.init = &initd; 207 pll->pll_ctrl = pll_ctrl; 208 pll->pll_status = pll_status; 209 pll->lockbit = lock_index; 210 pll->lock = lock; 211 212 spin_lock_irqsave(pll->lock, flags); 213 214 reg = readl(pll->pll_ctrl); 215 reg &= ~PLLCTRL_BPQUAL_MASK; 216 writel(reg, pll->pll_ctrl); 217 218 spin_unlock_irqrestore(pll->lock, flags); 219 220 clk = clk_register(NULL, &pll->hw); 221 if (WARN_ON(IS_ERR(clk))) 222 goto free_pll; 223 224 return clk; 225 226free_pll: 227 kfree(pll); 228 229 return clk; 230}