1#include <linux/clk.h> 2#include <linux/clk-provider.h> 3#include <linux/io.h> 4#include <linux/slab.h> 5#include <linux/kernel.h> 6#include <linux/err.h> 7 8#include "clk.h" 9#include "common.h" 10#include "hardware.h" 11 12/** 13 * pll v1 14 * 15 * @clk_hw clock source 16 * @parent the parent clock name 17 * @base base address of pll registers 18 * 19 * PLL clock version 1, found on i.MX1/21/25/27/31/35 20 */ 21 22#define MFN_BITS (10) 23#define MFN_SIGN (BIT(MFN_BITS - 1)) 24#define MFN_MASK (MFN_SIGN - 1) 25 26struct clk_pllv1 { 27 struct clk_hw hw; 28 void __iomem *base; 29}; 30 31#define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk)) 32 33static inline bool mfn_is_negative(unsigned int mfn) 34{ 35 return !cpu_is_mx1() && !cpu_is_mx21() && (mfn & MFN_SIGN); 36} 37 38static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, 39 unsigned long parent_rate) 40{ 41 struct clk_pllv1 *pll = to_clk_pllv1(hw); 42 long long ll; 43 int mfn_abs; 44 unsigned int mfi, mfn, mfd, pd; 45 u32 reg; 46 unsigned long rate; 47 48 reg = readl(pll->base); 49 50 /* 51 * Get the resulting clock rate from a PLL register value and the input 52 * frequency. PLLs with this register layout can be found on i.MX1, 53 * i.MX21, i.MX27 and i,MX31 54 * 55 * mfi + mfn / (mfd + 1) 56 * f = 2 * f_ref * -------------------- 57 * pd + 1 58 */ 59 60 mfi = (reg >> 10) & 0xf; 61 mfn = reg & 0x3ff; 62 mfd = (reg >> 16) & 0x3ff; 63 pd = (reg >> 26) & 0xf; 64 65 mfi = mfi <= 5 ? 5 : mfi; 66 67 mfn_abs = mfn; 68 69 /* 70 * On all i.MXs except i.MX1 and i.MX21 mfn is a 10bit 71 * 2's complements number. 72 * On i.MX27 the bit 9 is the sign bit. 73 */ 74 if (mfn_is_negative(mfn)) { 75 if (cpu_is_mx27()) 76 mfn_abs = mfn & MFN_MASK; 77 else 78 mfn_abs = BIT(MFN_BITS) - mfn; 79 } 80 81 rate = parent_rate * 2; 82 rate /= pd + 1; 83 84 ll = (unsigned long long)rate * mfn_abs; 85 86 do_div(ll, mfd + 1); 87 88 if (mfn_is_negative(mfn)) 89 ll = -ll; 90 91 ll = (rate * mfi) + ll; 92 93 return ll; 94} 95 96static struct clk_ops clk_pllv1_ops = { 97 .recalc_rate = clk_pllv1_recalc_rate, 98}; 99 100struct clk *imx_clk_pllv1(const char *name, const char *parent, 101 void __iomem *base) 102{ 103 struct clk_pllv1 *pll; 104 struct clk *clk; 105 struct clk_init_data init; 106 107 pll = kmalloc(sizeof(*pll), GFP_KERNEL); 108 if (!pll) 109 return ERR_PTR(-ENOMEM); 110 111 pll->base = base; 112 113 init.name = name; 114 init.ops = &clk_pllv1_ops; 115 init.flags = 0; 116 init.parent_names = &parent; 117 init.num_parents = 1; 118 119 pll->hw.init = &init; 120 121 clk = clk_register(NULL, &pll->hw); 122 if (IS_ERR(clk)) 123 kfree(pll); 124 125 return clk; 126} 127