1*1a748d2bSBoris BREZILLON /* 2*1a748d2bSBoris BREZILLON * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> 3*1a748d2bSBoris BREZILLON * 4*1a748d2bSBoris BREZILLON * This program is free software; you can redistribute it and/or modify 5*1a748d2bSBoris BREZILLON * it under the terms of the GNU General Public License as published by 6*1a748d2bSBoris BREZILLON * the Free Software Foundation; either version 2 of the License, or 7*1a748d2bSBoris BREZILLON * (at your option) any later version. 8*1a748d2bSBoris BREZILLON * 9*1a748d2bSBoris BREZILLON */ 10*1a748d2bSBoris BREZILLON 11*1a748d2bSBoris BREZILLON #include <linux/clk-provider.h> 12*1a748d2bSBoris BREZILLON #include <linux/clkdev.h> 13*1a748d2bSBoris BREZILLON #include <linux/clk/at91_pmc.h> 14*1a748d2bSBoris BREZILLON #include <linux/of.h> 15*1a748d2bSBoris BREZILLON #include <linux/of_address.h> 16*1a748d2bSBoris BREZILLON #include <linux/of_irq.h> 17*1a748d2bSBoris BREZILLON #include <linux/io.h> 18*1a748d2bSBoris BREZILLON #include <linux/wait.h> 19*1a748d2bSBoris BREZILLON #include <linux/sched.h> 20*1a748d2bSBoris BREZILLON #include <linux/interrupt.h> 21*1a748d2bSBoris BREZILLON #include <linux/irq.h> 22*1a748d2bSBoris BREZILLON 23*1a748d2bSBoris BREZILLON #include "pmc.h" 24*1a748d2bSBoris BREZILLON 25*1a748d2bSBoris BREZILLON #define PLL_STATUS_MASK(id) (1 << (1 + (id))) 26*1a748d2bSBoris BREZILLON #define PLL_REG(id) (AT91_CKGR_PLLAR + ((id) * 4)) 27*1a748d2bSBoris BREZILLON #define PLL_DIV_MASK 0xff 28*1a748d2bSBoris BREZILLON #define PLL_DIV_MAX PLL_DIV_MASK 29*1a748d2bSBoris BREZILLON #define PLL_DIV(reg) ((reg) & PLL_DIV_MASK) 30*1a748d2bSBoris BREZILLON #define PLL_MUL(reg, layout) (((reg) >> (layout)->mul_shift) & \ 31*1a748d2bSBoris BREZILLON (layout)->mul_mask) 32*1a748d2bSBoris BREZILLON #define PLL_ICPR_SHIFT(id) ((id) * 16) 33*1a748d2bSBoris BREZILLON #define PLL_ICPR_MASK(id) (0xffff << PLL_ICPR_SHIFT(id)) 34*1a748d2bSBoris BREZILLON #define PLL_MAX_COUNT 0x3ff 35*1a748d2bSBoris BREZILLON #define PLL_COUNT_SHIFT 8 36*1a748d2bSBoris BREZILLON #define PLL_OUT_SHIFT 14 37*1a748d2bSBoris BREZILLON #define PLL_MAX_ID 1 38*1a748d2bSBoris BREZILLON 39*1a748d2bSBoris BREZILLON struct clk_pll_characteristics { 40*1a748d2bSBoris BREZILLON struct clk_range input; 41*1a748d2bSBoris BREZILLON int num_output; 42*1a748d2bSBoris BREZILLON struct clk_range *output; 43*1a748d2bSBoris BREZILLON u16 *icpll; 44*1a748d2bSBoris BREZILLON u8 *out; 45*1a748d2bSBoris BREZILLON }; 46*1a748d2bSBoris BREZILLON 47*1a748d2bSBoris BREZILLON struct clk_pll_layout { 48*1a748d2bSBoris BREZILLON u32 pllr_mask; 49*1a748d2bSBoris BREZILLON u16 mul_mask; 50*1a748d2bSBoris BREZILLON u8 mul_shift; 51*1a748d2bSBoris BREZILLON }; 52*1a748d2bSBoris BREZILLON 53*1a748d2bSBoris BREZILLON #define to_clk_pll(hw) container_of(hw, struct clk_pll, hw) 54*1a748d2bSBoris BREZILLON 55*1a748d2bSBoris BREZILLON struct clk_pll { 56*1a748d2bSBoris BREZILLON struct clk_hw hw; 57*1a748d2bSBoris BREZILLON struct at91_pmc *pmc; 58*1a748d2bSBoris BREZILLON unsigned int irq; 59*1a748d2bSBoris BREZILLON wait_queue_head_t wait; 60*1a748d2bSBoris BREZILLON u8 id; 61*1a748d2bSBoris BREZILLON u8 div; 62*1a748d2bSBoris BREZILLON u8 range; 63*1a748d2bSBoris BREZILLON u16 mul; 64*1a748d2bSBoris BREZILLON const struct clk_pll_layout *layout; 65*1a748d2bSBoris BREZILLON const struct clk_pll_characteristics *characteristics; 66*1a748d2bSBoris BREZILLON }; 67*1a748d2bSBoris BREZILLON 68*1a748d2bSBoris BREZILLON static irqreturn_t clk_pll_irq_handler(int irq, void *dev_id) 69*1a748d2bSBoris BREZILLON { 70*1a748d2bSBoris BREZILLON struct clk_pll *pll = (struct clk_pll *)dev_id; 71*1a748d2bSBoris BREZILLON 72*1a748d2bSBoris BREZILLON wake_up(&pll->wait); 73*1a748d2bSBoris BREZILLON disable_irq_nosync(pll->irq); 74*1a748d2bSBoris BREZILLON 75*1a748d2bSBoris BREZILLON return IRQ_HANDLED; 76*1a748d2bSBoris BREZILLON } 77*1a748d2bSBoris BREZILLON 78*1a748d2bSBoris BREZILLON static int clk_pll_prepare(struct clk_hw *hw) 79*1a748d2bSBoris BREZILLON { 80*1a748d2bSBoris BREZILLON struct clk_pll *pll = to_clk_pll(hw); 81*1a748d2bSBoris BREZILLON struct at91_pmc *pmc = pll->pmc; 82*1a748d2bSBoris BREZILLON const struct clk_pll_layout *layout = pll->layout; 83*1a748d2bSBoris BREZILLON u8 id = pll->id; 84*1a748d2bSBoris BREZILLON u32 mask = PLL_STATUS_MASK(id); 85*1a748d2bSBoris BREZILLON int offset = PLL_REG(id); 86*1a748d2bSBoris BREZILLON u8 out = 0; 87*1a748d2bSBoris BREZILLON u32 pllr, icpr; 88*1a748d2bSBoris BREZILLON u8 div; 89*1a748d2bSBoris BREZILLON u16 mul; 90*1a748d2bSBoris BREZILLON 91*1a748d2bSBoris BREZILLON pllr = pmc_read(pmc, offset); 92*1a748d2bSBoris BREZILLON div = PLL_DIV(pllr); 93*1a748d2bSBoris BREZILLON mul = PLL_MUL(pllr, layout); 94*1a748d2bSBoris BREZILLON 95*1a748d2bSBoris BREZILLON if ((pmc_read(pmc, AT91_PMC_SR) & mask) && 96*1a748d2bSBoris BREZILLON (div == pll->div && mul == pll->mul)) 97*1a748d2bSBoris BREZILLON return 0; 98*1a748d2bSBoris BREZILLON 99*1a748d2bSBoris BREZILLON if (characteristics->out) 100*1a748d2bSBoris BREZILLON out = characteristics->out[pll->range]; 101*1a748d2bSBoris BREZILLON if (characteristics->icpll) { 102*1a748d2bSBoris BREZILLON icpr = pmc_read(pmc, AT91_PMC_PLLICPR) & ~PLL_ICPR_MASK(id); 103*1a748d2bSBoris BREZILLON icpr |= (characteristics->icpll[pll->range] << 104*1a748d2bSBoris BREZILLON PLL_ICPR_SHIFT(id)); 105*1a748d2bSBoris BREZILLON pmc_write(pmc, AT91_PMC_PLLICPR, icpr); 106*1a748d2bSBoris BREZILLON } 107*1a748d2bSBoris BREZILLON 108*1a748d2bSBoris BREZILLON pllr &= ~layout->pllr_mask; 109*1a748d2bSBoris BREZILLON pllr |= layout->pllr_mask & 110*1a748d2bSBoris BREZILLON (pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) | 111*1a748d2bSBoris BREZILLON (out << PLL_OUT_SHIFT) | 112*1a748d2bSBoris BREZILLON ((pll->mul & layout->mul_mask) << layout->mul_shift)); 113*1a748d2bSBoris BREZILLON pmc_write(pmc, offset, pllr); 114*1a748d2bSBoris BREZILLON 115*1a748d2bSBoris BREZILLON while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) { 116*1a748d2bSBoris BREZILLON enable_irq(pll->irq); 117*1a748d2bSBoris BREZILLON wait_event(pll->wait, 118*1a748d2bSBoris BREZILLON pmc_read(pmc, AT91_PMC_SR) & mask); 119*1a748d2bSBoris BREZILLON } 120*1a748d2bSBoris BREZILLON 121*1a748d2bSBoris BREZILLON return 0; 122*1a748d2bSBoris BREZILLON } 123*1a748d2bSBoris BREZILLON 124*1a748d2bSBoris BREZILLON static int clk_pll_is_prepared(struct clk_hw *hw) 125*1a748d2bSBoris BREZILLON { 126*1a748d2bSBoris BREZILLON struct clk_pll *pll = to_clk_pll(hw); 127*1a748d2bSBoris BREZILLON struct at91_pmc *pmc = pll->pmc; 128*1a748d2bSBoris BREZILLON 129*1a748d2bSBoris BREZILLON return !!(pmc_read(pmc, AT91_PMC_SR) & 130*1a748d2bSBoris BREZILLON PLL_STATUS_MASK(pll->id)); 131*1a748d2bSBoris BREZILLON } 132*1a748d2bSBoris BREZILLON 133*1a748d2bSBoris BREZILLON static void clk_pll_unprepare(struct clk_hw *hw) 134*1a748d2bSBoris BREZILLON { 135*1a748d2bSBoris BREZILLON struct clk_pll *pll = to_clk_pll(hw); 136*1a748d2bSBoris BREZILLON struct at91_pmc *pmc = pll->pmc; 137*1a748d2bSBoris BREZILLON const struct clk_pll_layout *layout = pll->layout; 138*1a748d2bSBoris BREZILLON int offset = PLL_REG(pll->id); 139*1a748d2bSBoris BREZILLON u32 tmp = pmc_read(pmc, offset) & ~(layout->pllr_mask); 140*1a748d2bSBoris BREZILLON 141*1a748d2bSBoris BREZILLON pmc_write(pmc, offset, tmp); 142*1a748d2bSBoris BREZILLON } 143*1a748d2bSBoris BREZILLON 144*1a748d2bSBoris BREZILLON static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, 145*1a748d2bSBoris BREZILLON unsigned long parent_rate) 146*1a748d2bSBoris BREZILLON { 147*1a748d2bSBoris BREZILLON struct clk_pll *pll = to_clk_pll(hw); 148*1a748d2bSBoris BREZILLON const struct clk_pll_layout *layout = pll->layout; 149*1a748d2bSBoris BREZILLON struct at91_pmc *pmc = pll->pmc; 150*1a748d2bSBoris BREZILLON int offset = PLL_REG(pll->id); 151*1a748d2bSBoris BREZILLON u32 tmp = pmc_read(pmc, offset) & layout->pllr_mask; 152*1a748d2bSBoris BREZILLON u8 div = PLL_DIV(tmp); 153*1a748d2bSBoris BREZILLON u16 mul = PLL_MUL(tmp, layout); 154*1a748d2bSBoris BREZILLON if (!div || !mul) 155*1a748d2bSBoris BREZILLON return 0; 156*1a748d2bSBoris BREZILLON 157*1a748d2bSBoris BREZILLON return (parent_rate * (mul + 1)) / div; 158*1a748d2bSBoris BREZILLON } 159*1a748d2bSBoris BREZILLON 160*1a748d2bSBoris BREZILLON static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate, 161*1a748d2bSBoris BREZILLON unsigned long parent_rate, 162*1a748d2bSBoris BREZILLON u32 *div, u32 *mul, 163*1a748d2bSBoris BREZILLON u32 *index) { 164*1a748d2bSBoris BREZILLON unsigned long maxrate; 165*1a748d2bSBoris BREZILLON unsigned long minrate; 166*1a748d2bSBoris BREZILLON unsigned long divrate; 167*1a748d2bSBoris BREZILLON unsigned long bestdiv = 1; 168*1a748d2bSBoris BREZILLON unsigned long bestmul; 169*1a748d2bSBoris BREZILLON unsigned long tmpdiv; 170*1a748d2bSBoris BREZILLON unsigned long roundup; 171*1a748d2bSBoris BREZILLON unsigned long rounddown; 172*1a748d2bSBoris BREZILLON unsigned long remainder; 173*1a748d2bSBoris BREZILLON unsigned long bestremainder; 174*1a748d2bSBoris BREZILLON unsigned long maxmul; 175*1a748d2bSBoris BREZILLON unsigned long maxdiv; 176*1a748d2bSBoris BREZILLON unsigned long mindiv; 177*1a748d2bSBoris BREZILLON int i = 0; 178*1a748d2bSBoris BREZILLON const struct clk_pll_layout *layout = pll->layout; 179*1a748d2bSBoris BREZILLON const struct clk_pll_characteristics *characteristics = 180*1a748d2bSBoris BREZILLON pll->characteristics; 181*1a748d2bSBoris BREZILLON 182*1a748d2bSBoris BREZILLON /* Minimum divider = 1 */ 183*1a748d2bSBoris BREZILLON /* Maximum multiplier = max_mul */ 184*1a748d2bSBoris BREZILLON maxmul = layout->mul_mask + 1; 185*1a748d2bSBoris BREZILLON maxrate = (parent_rate * maxmul) / 1; 186*1a748d2bSBoris BREZILLON 187*1a748d2bSBoris BREZILLON /* Maximum divider = max_div */ 188*1a748d2bSBoris BREZILLON /* Minimum multiplier = 2 */ 189*1a748d2bSBoris BREZILLON maxdiv = PLL_DIV_MAX; 190*1a748d2bSBoris BREZILLON minrate = (parent_rate * 2) / maxdiv; 191*1a748d2bSBoris BREZILLON 192*1a748d2bSBoris BREZILLON if (parent_rate < characteristics->input.min || 193*1a748d2bSBoris BREZILLON parent_rate < characteristics->input.max) 194*1a748d2bSBoris BREZILLON return -ERANGE; 195*1a748d2bSBoris BREZILLON 196*1a748d2bSBoris BREZILLON if (parent_rate < minrate || parent_rate > maxrate) 197*1a748d2bSBoris BREZILLON return -ERANGE; 198*1a748d2bSBoris BREZILLON 199*1a748d2bSBoris BREZILLON for (i = 0; i < characteristics->num_output; i++) { 200*1a748d2bSBoris BREZILLON if (parent_rate >= characteristics->output[i].min && 201*1a748d2bSBoris BREZILLON parent_rate <= characteristics->output[i].max) 202*1a748d2bSBoris BREZILLON break; 203*1a748d2bSBoris BREZILLON } 204*1a748d2bSBoris BREZILLON 205*1a748d2bSBoris BREZILLON if (i >= characteristics->num_output) 206*1a748d2bSBoris BREZILLON return -ERANGE; 207*1a748d2bSBoris BREZILLON 208*1a748d2bSBoris BREZILLON bestmul = rate / parent_rate; 209*1a748d2bSBoris BREZILLON rounddown = parent_rate % rate; 210*1a748d2bSBoris BREZILLON roundup = rate - rounddown; 211*1a748d2bSBoris BREZILLON bestremainder = roundup < rounddown ? roundup : rounddown; 212*1a748d2bSBoris BREZILLON 213*1a748d2bSBoris BREZILLON if (!bestremainder) { 214*1a748d2bSBoris BREZILLON if (div) 215*1a748d2bSBoris BREZILLON *div = bestdiv; 216*1a748d2bSBoris BREZILLON if (mul) 217*1a748d2bSBoris BREZILLON *mul = bestmul; 218*1a748d2bSBoris BREZILLON if (index) 219*1a748d2bSBoris BREZILLON *index = i; 220*1a748d2bSBoris BREZILLON return rate; 221*1a748d2bSBoris BREZILLON } 222*1a748d2bSBoris BREZILLON 223*1a748d2bSBoris BREZILLON maxdiv = 255 / (bestmul + 1); 224*1a748d2bSBoris BREZILLON if (parent_rate / maxdiv < characteristics->input.min) 225*1a748d2bSBoris BREZILLON maxdiv = parent_rate / characteristics->input.min; 226*1a748d2bSBoris BREZILLON mindiv = parent_rate / characteristics->input.max; 227*1a748d2bSBoris BREZILLON if (parent_rate % characteristics->input.max) 228*1a748d2bSBoris BREZILLON mindiv++; 229*1a748d2bSBoris BREZILLON 230*1a748d2bSBoris BREZILLON for (tmpdiv = mindiv; tmpdiv < maxdiv; tmpdiv++) { 231*1a748d2bSBoris BREZILLON divrate = parent_rate / tmpdiv; 232*1a748d2bSBoris BREZILLON 233*1a748d2bSBoris BREZILLON rounddown = rate % divrate; 234*1a748d2bSBoris BREZILLON roundup = divrate - rounddown; 235*1a748d2bSBoris BREZILLON remainder = roundup < rounddown ? roundup : rounddown; 236*1a748d2bSBoris BREZILLON 237*1a748d2bSBoris BREZILLON if (remainder < bestremainder) { 238*1a748d2bSBoris BREZILLON bestremainder = remainder; 239*1a748d2bSBoris BREZILLON bestmul = rate / divrate; 240*1a748d2bSBoris BREZILLON bestdiv = tmpdiv; 241*1a748d2bSBoris BREZILLON } 242*1a748d2bSBoris BREZILLON 243*1a748d2bSBoris BREZILLON if (!remainder) 244*1a748d2bSBoris BREZILLON break; 245*1a748d2bSBoris BREZILLON } 246*1a748d2bSBoris BREZILLON 247*1a748d2bSBoris BREZILLON rate = (parent_rate / bestdiv) * bestmul; 248*1a748d2bSBoris BREZILLON 249*1a748d2bSBoris BREZILLON if (div) 250*1a748d2bSBoris BREZILLON *div = bestdiv; 251*1a748d2bSBoris BREZILLON if (mul) 252*1a748d2bSBoris BREZILLON *mul = bestmul; 253*1a748d2bSBoris BREZILLON if (index) 254*1a748d2bSBoris BREZILLON *index = i; 255*1a748d2bSBoris BREZILLON 256*1a748d2bSBoris BREZILLON return rate; 257*1a748d2bSBoris BREZILLON } 258*1a748d2bSBoris BREZILLON 259*1a748d2bSBoris BREZILLON static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, 260*1a748d2bSBoris BREZILLON unsigned long *parent_rate) 261*1a748d2bSBoris BREZILLON { 262*1a748d2bSBoris BREZILLON struct clk_pll *pll = to_clk_pll(hw); 263*1a748d2bSBoris BREZILLON 264*1a748d2bSBoris BREZILLON return clk_pll_get_best_div_mul(pll, rate, *parent_rate, 265*1a748d2bSBoris BREZILLON NULL, NULL, NULL); 266*1a748d2bSBoris BREZILLON } 267*1a748d2bSBoris BREZILLON 268*1a748d2bSBoris BREZILLON static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, 269*1a748d2bSBoris BREZILLON unsigned long parent_rate) 270*1a748d2bSBoris BREZILLON { 271*1a748d2bSBoris BREZILLON struct clk_pll *pll = to_clk_pll(hw); 272*1a748d2bSBoris BREZILLON struct at91_pmc *pmc = pll->pmc; 273*1a748d2bSBoris BREZILLON const struct clk_pll_layout *layout = pll->layout; 274*1a748d2bSBoris BREZILLON const struct clk_pll_characteristics *characteristics = 275*1a748d2bSBoris BREZILLON pll->characteristics; 276*1a748d2bSBoris BREZILLON u8 id = pll->id; 277*1a748d2bSBoris BREZILLON int offset = PLL_REG(id); 278*1a748d2bSBoris BREZILLON long ret; 279*1a748d2bSBoris BREZILLON u32 div; 280*1a748d2bSBoris BREZILLON u32 mul; 281*1a748d2bSBoris BREZILLON u32 index; 282*1a748d2bSBoris BREZILLON u32 tmp; 283*1a748d2bSBoris BREZILLON u8 out = 0; 284*1a748d2bSBoris BREZILLON 285*1a748d2bSBoris BREZILLON ret = clk_pll_get_best_div_mul(pll, rate, parent_rate, 286*1a748d2bSBoris BREZILLON &div, &mul, &index); 287*1a748d2bSBoris BREZILLON if (ret < 0) 288*1a748d2bSBoris BREZILLON return ret; 289*1a748d2bSBoris BREZILLON 290*1a748d2bSBoris BREZILLON pll->range = index; 291*1a748d2bSBoris BREZILLON pll->div = div; 292*1a748d2bSBoris BREZILLON pll->mul = mul; 293*1a748d2bSBoris BREZILLON 294*1a748d2bSBoris BREZILLON return 0; 295*1a748d2bSBoris BREZILLON } 296*1a748d2bSBoris BREZILLON 297*1a748d2bSBoris BREZILLON static const struct clk_ops pll_ops = { 298*1a748d2bSBoris BREZILLON .prepare = clk_pll_prepare, 299*1a748d2bSBoris BREZILLON .unprepare = clk_pll_unprepare, 300*1a748d2bSBoris BREZILLON .is_prepared = clk_pll_is_prepared, 301*1a748d2bSBoris BREZILLON .recalc_rate = clk_pll_recalc_rate, 302*1a748d2bSBoris BREZILLON .round_rate = clk_pll_round_rate, 303*1a748d2bSBoris BREZILLON .set_rate = clk_pll_set_rate, 304*1a748d2bSBoris BREZILLON }; 305*1a748d2bSBoris BREZILLON 306*1a748d2bSBoris BREZILLON static struct clk * __init 307*1a748d2bSBoris BREZILLON at91_clk_register_pll(struct at91_pmc *pmc, unsigned int irq, const char *name, 308*1a748d2bSBoris BREZILLON const char *parent_name, u8 id, 309*1a748d2bSBoris BREZILLON const struct clk_pll_layout *layout, 310*1a748d2bSBoris BREZILLON const struct clk_pll_characteristics *characteristics) 311*1a748d2bSBoris BREZILLON { 312*1a748d2bSBoris BREZILLON struct clk_pll *pll; 313*1a748d2bSBoris BREZILLON struct clk *clk = NULL; 314*1a748d2bSBoris BREZILLON struct clk_init_data init; 315*1a748d2bSBoris BREZILLON int ret; 316*1a748d2bSBoris BREZILLON int offset = PLL_REG(id); 317*1a748d2bSBoris BREZILLON u32 tmp; 318*1a748d2bSBoris BREZILLON 319*1a748d2bSBoris BREZILLON if (id > PLL_MAX_ID) 320*1a748d2bSBoris BREZILLON return ERR_PTR(-EINVAL); 321*1a748d2bSBoris BREZILLON 322*1a748d2bSBoris BREZILLON pll = kzalloc(sizeof(*pll), GFP_KERNEL); 323*1a748d2bSBoris BREZILLON if (!pll) 324*1a748d2bSBoris BREZILLON return ERR_PTR(-ENOMEM); 325*1a748d2bSBoris BREZILLON 326*1a748d2bSBoris BREZILLON init.name = name; 327*1a748d2bSBoris BREZILLON init.ops = &pll_ops; 328*1a748d2bSBoris BREZILLON init.parent_names = &parent_name; 329*1a748d2bSBoris BREZILLON init.num_parents = 1; 330*1a748d2bSBoris BREZILLON init.flags = CLK_SET_RATE_GATE; 331*1a748d2bSBoris BREZILLON 332*1a748d2bSBoris BREZILLON pll->id = id; 333*1a748d2bSBoris BREZILLON pll->hw.init = &init; 334*1a748d2bSBoris BREZILLON pll->layout = layout; 335*1a748d2bSBoris BREZILLON pll->characteristics = characteristics; 336*1a748d2bSBoris BREZILLON pll->pmc = pmc; 337*1a748d2bSBoris BREZILLON pll->irq = irq; 338*1a748d2bSBoris BREZILLON tmp = pmc_read(pmc, offset) & layout->pllr_mask; 339*1a748d2bSBoris BREZILLON pll->div = PLL_DIV(tmp); 340*1a748d2bSBoris BREZILLON pll->mul = PLL_MUL(tmp, layout); 341*1a748d2bSBoris BREZILLON init_waitqueue_head(&pll->wait); 342*1a748d2bSBoris BREZILLON irq_set_status_flags(pll->irq, IRQ_NOAUTOEN); 343*1a748d2bSBoris BREZILLON ret = request_irq(pll->irq, clk_pll_irq_handler, IRQF_TRIGGER_HIGH, 344*1a748d2bSBoris BREZILLON id ? "clk-pllb" : "clk-plla", pll); 345*1a748d2bSBoris BREZILLON if (ret) 346*1a748d2bSBoris BREZILLON return ERR_PTR(ret); 347*1a748d2bSBoris BREZILLON 348*1a748d2bSBoris BREZILLON clk = clk_register(NULL, &pll->hw); 349*1a748d2bSBoris BREZILLON if (IS_ERR(clk)) 350*1a748d2bSBoris BREZILLON kfree(pll); 351*1a748d2bSBoris BREZILLON 352*1a748d2bSBoris BREZILLON return clk; 353*1a748d2bSBoris BREZILLON } 354*1a748d2bSBoris BREZILLON 355*1a748d2bSBoris BREZILLON 356*1a748d2bSBoris BREZILLON static const struct clk_pll_layout at91rm9200_pll_layout = { 357*1a748d2bSBoris BREZILLON .pllr_mask = 0x7FFFFFF, 358*1a748d2bSBoris BREZILLON .mul_shift = 16, 359*1a748d2bSBoris BREZILLON .mul_mask = 0x7FF, 360*1a748d2bSBoris BREZILLON }; 361*1a748d2bSBoris BREZILLON 362*1a748d2bSBoris BREZILLON static const struct clk_pll_layout at91sam9g45_pll_layout = { 363*1a748d2bSBoris BREZILLON .pllr_mask = 0xFFFFFF, 364*1a748d2bSBoris BREZILLON .mul_shift = 16, 365*1a748d2bSBoris BREZILLON .mul_mask = 0xFF, 366*1a748d2bSBoris BREZILLON }; 367*1a748d2bSBoris BREZILLON 368*1a748d2bSBoris BREZILLON static const struct clk_pll_layout at91sam9g20_pllb_layout = { 369*1a748d2bSBoris BREZILLON .pllr_mask = 0x3FFFFF, 370*1a748d2bSBoris BREZILLON .mul_shift = 16, 371*1a748d2bSBoris BREZILLON .mul_mask = 0x3F, 372*1a748d2bSBoris BREZILLON }; 373*1a748d2bSBoris BREZILLON 374*1a748d2bSBoris BREZILLON static const struct clk_pll_layout sama5d3_pll_layout = { 375*1a748d2bSBoris BREZILLON .pllr_mask = 0x1FFFFFF, 376*1a748d2bSBoris BREZILLON .mul_shift = 18, 377*1a748d2bSBoris BREZILLON .mul_mask = 0x7F, 378*1a748d2bSBoris BREZILLON }; 379*1a748d2bSBoris BREZILLON 380*1a748d2bSBoris BREZILLON 381*1a748d2bSBoris BREZILLON static struct clk_pll_characteristics * __init 382*1a748d2bSBoris BREZILLON of_at91_clk_pll_get_characteristics(struct device_node *np) 383*1a748d2bSBoris BREZILLON { 384*1a748d2bSBoris BREZILLON int i; 385*1a748d2bSBoris BREZILLON int offset; 386*1a748d2bSBoris BREZILLON u32 tmp; 387*1a748d2bSBoris BREZILLON int num_output; 388*1a748d2bSBoris BREZILLON u32 num_cells; 389*1a748d2bSBoris BREZILLON struct clk_range input; 390*1a748d2bSBoris BREZILLON struct clk_range *output; 391*1a748d2bSBoris BREZILLON u8 *out = NULL; 392*1a748d2bSBoris BREZILLON u16 *icpll = NULL; 393*1a748d2bSBoris BREZILLON struct clk_pll_characteristics *characteristics; 394*1a748d2bSBoris BREZILLON 395*1a748d2bSBoris BREZILLON if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input)) 396*1a748d2bSBoris BREZILLON return NULL; 397*1a748d2bSBoris BREZILLON 398*1a748d2bSBoris BREZILLON if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells", 399*1a748d2bSBoris BREZILLON &num_cells)) 400*1a748d2bSBoris BREZILLON return NULL; 401*1a748d2bSBoris BREZILLON 402*1a748d2bSBoris BREZILLON if (num_cells < 2 || num_cells > 4) 403*1a748d2bSBoris BREZILLON return NULL; 404*1a748d2bSBoris BREZILLON 405*1a748d2bSBoris BREZILLON if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp)) 406*1a748d2bSBoris BREZILLON return NULL; 407*1a748d2bSBoris BREZILLON num_output = tmp / (sizeof(u32) * num_cells); 408*1a748d2bSBoris BREZILLON 409*1a748d2bSBoris BREZILLON characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL); 410*1a748d2bSBoris BREZILLON if (!characteristics) 411*1a748d2bSBoris BREZILLON return NULL; 412*1a748d2bSBoris BREZILLON 413*1a748d2bSBoris BREZILLON output = kzalloc(sizeof(*output) * num_output, GFP_KERNEL); 414*1a748d2bSBoris BREZILLON if (!output) 415*1a748d2bSBoris BREZILLON goto out_free_characteristics; 416*1a748d2bSBoris BREZILLON 417*1a748d2bSBoris BREZILLON if (num_cells > 2) { 418*1a748d2bSBoris BREZILLON out = kzalloc(sizeof(*out) * num_output, GFP_KERNEL); 419*1a748d2bSBoris BREZILLON if (!out) 420*1a748d2bSBoris BREZILLON goto out_free_output; 421*1a748d2bSBoris BREZILLON } 422*1a748d2bSBoris BREZILLON 423*1a748d2bSBoris BREZILLON if (num_cells > 3) { 424*1a748d2bSBoris BREZILLON icpll = kzalloc(sizeof(*icpll) * num_output, GFP_KERNEL); 425*1a748d2bSBoris BREZILLON if (!icpll) 426*1a748d2bSBoris BREZILLON goto out_free_output; 427*1a748d2bSBoris BREZILLON } 428*1a748d2bSBoris BREZILLON 429*1a748d2bSBoris BREZILLON for (i = 0; i < num_output; i++) { 430*1a748d2bSBoris BREZILLON offset = i * num_cells; 431*1a748d2bSBoris BREZILLON if (of_property_read_u32_index(np, 432*1a748d2bSBoris BREZILLON "atmel,pll-clk-output-ranges", 433*1a748d2bSBoris BREZILLON offset, &tmp)) 434*1a748d2bSBoris BREZILLON goto out_free_output; 435*1a748d2bSBoris BREZILLON output[i].min = tmp; 436*1a748d2bSBoris BREZILLON if (of_property_read_u32_index(np, 437*1a748d2bSBoris BREZILLON "atmel,pll-clk-output-ranges", 438*1a748d2bSBoris BREZILLON offset + 1, &tmp)) 439*1a748d2bSBoris BREZILLON goto out_free_output; 440*1a748d2bSBoris BREZILLON output[i].max = tmp; 441*1a748d2bSBoris BREZILLON 442*1a748d2bSBoris BREZILLON if (num_cells == 2) 443*1a748d2bSBoris BREZILLON continue; 444*1a748d2bSBoris BREZILLON 445*1a748d2bSBoris BREZILLON if (of_property_read_u32_index(np, 446*1a748d2bSBoris BREZILLON "atmel,pll-clk-output-ranges", 447*1a748d2bSBoris BREZILLON offset + 2, &tmp)) 448*1a748d2bSBoris BREZILLON goto out_free_output; 449*1a748d2bSBoris BREZILLON out[i] = tmp; 450*1a748d2bSBoris BREZILLON 451*1a748d2bSBoris BREZILLON if (num_cells == 3) 452*1a748d2bSBoris BREZILLON continue; 453*1a748d2bSBoris BREZILLON 454*1a748d2bSBoris BREZILLON if (of_property_read_u32_index(np, 455*1a748d2bSBoris BREZILLON "atmel,pll-clk-output-ranges", 456*1a748d2bSBoris BREZILLON offset + 3, &tmp)) 457*1a748d2bSBoris BREZILLON goto out_free_output; 458*1a748d2bSBoris BREZILLON icpll[i] = tmp; 459*1a748d2bSBoris BREZILLON } 460*1a748d2bSBoris BREZILLON 461*1a748d2bSBoris BREZILLON characteristics->input = input; 462*1a748d2bSBoris BREZILLON characteristics->num_output = num_output; 463*1a748d2bSBoris BREZILLON characteristics->output = output; 464*1a748d2bSBoris BREZILLON characteristics->out = out; 465*1a748d2bSBoris BREZILLON characteristics->icpll = icpll; 466*1a748d2bSBoris BREZILLON return characteristics; 467*1a748d2bSBoris BREZILLON 468*1a748d2bSBoris BREZILLON out_free_output: 469*1a748d2bSBoris BREZILLON kfree(icpll); 470*1a748d2bSBoris BREZILLON kfree(out); 471*1a748d2bSBoris BREZILLON kfree(output); 472*1a748d2bSBoris BREZILLON out_free_characteristics: 473*1a748d2bSBoris BREZILLON kfree(characteristics); 474*1a748d2bSBoris BREZILLON return NULL; 475*1a748d2bSBoris BREZILLON } 476*1a748d2bSBoris BREZILLON 477*1a748d2bSBoris BREZILLON static void __init 478*1a748d2bSBoris BREZILLON of_at91_clk_pll_setup(struct device_node *np, struct at91_pmc *pmc, 479*1a748d2bSBoris BREZILLON const struct clk_pll_layout *layout) 480*1a748d2bSBoris BREZILLON { 481*1a748d2bSBoris BREZILLON u32 id; 482*1a748d2bSBoris BREZILLON unsigned int irq; 483*1a748d2bSBoris BREZILLON struct clk *clk; 484*1a748d2bSBoris BREZILLON const char *parent_name; 485*1a748d2bSBoris BREZILLON const char *name = np->name; 486*1a748d2bSBoris BREZILLON struct clk_pll_characteristics *characteristics; 487*1a748d2bSBoris BREZILLON 488*1a748d2bSBoris BREZILLON if (of_property_read_u32(np, "reg", &id)) 489*1a748d2bSBoris BREZILLON return; 490*1a748d2bSBoris BREZILLON 491*1a748d2bSBoris BREZILLON parent_name = of_clk_get_parent_name(np, 0); 492*1a748d2bSBoris BREZILLON 493*1a748d2bSBoris BREZILLON of_property_read_string(np, "clock-output-names", &name); 494*1a748d2bSBoris BREZILLON 495*1a748d2bSBoris BREZILLON characteristics = of_at91_clk_pll_get_characteristics(np); 496*1a748d2bSBoris BREZILLON if (!characteristics) 497*1a748d2bSBoris BREZILLON return; 498*1a748d2bSBoris BREZILLON 499*1a748d2bSBoris BREZILLON irq = irq_of_parse_and_map(np, 0); 500*1a748d2bSBoris BREZILLON if (!irq) 501*1a748d2bSBoris BREZILLON return; 502*1a748d2bSBoris BREZILLON 503*1a748d2bSBoris BREZILLON clk = at91_clk_register_pll(pmc, irq, name, parent_name, id, layout, 504*1a748d2bSBoris BREZILLON characteristics); 505*1a748d2bSBoris BREZILLON if (IS_ERR(clk)) 506*1a748d2bSBoris BREZILLON goto out_free_characteristics; 507*1a748d2bSBoris BREZILLON 508*1a748d2bSBoris BREZILLON of_clk_add_provider(np, of_clk_src_simple_get, clk); 509*1a748d2bSBoris BREZILLON return; 510*1a748d2bSBoris BREZILLON 511*1a748d2bSBoris BREZILLON out_free_characteristics: 512*1a748d2bSBoris BREZILLON kfree(characteristics); 513*1a748d2bSBoris BREZILLON } 514*1a748d2bSBoris BREZILLON 515*1a748d2bSBoris BREZILLON void __init of_at91rm9200_clk_pll_setup(struct device_node *np, 516*1a748d2bSBoris BREZILLON struct at91_pmc *pmc) 517*1a748d2bSBoris BREZILLON { 518*1a748d2bSBoris BREZILLON of_at91_clk_pll_setup(np, pmc, &at91rm9200_pll_layout); 519*1a748d2bSBoris BREZILLON } 520*1a748d2bSBoris BREZILLON 521*1a748d2bSBoris BREZILLON void __init of_at91sam9g45_clk_pll_setup(struct device_node *np, 522*1a748d2bSBoris BREZILLON struct at91_pmc *pmc) 523*1a748d2bSBoris BREZILLON { 524*1a748d2bSBoris BREZILLON of_at91_clk_pll_setup(np, pmc, &at91sam9g45_pll_layout); 525*1a748d2bSBoris BREZILLON } 526*1a748d2bSBoris BREZILLON 527*1a748d2bSBoris BREZILLON void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np, 528*1a748d2bSBoris BREZILLON struct at91_pmc *pmc) 529*1a748d2bSBoris BREZILLON { 530*1a748d2bSBoris BREZILLON of_at91_clk_pll_setup(np, pmc, &at91sam9g20_pllb_layout); 531*1a748d2bSBoris BREZILLON } 532*1a748d2bSBoris BREZILLON 533*1a748d2bSBoris BREZILLON void __init of_sama5d3_clk_pll_setup(struct device_node *np, 534*1a748d2bSBoris BREZILLON struct at91_pmc *pmc) 535*1a748d2bSBoris BREZILLON { 536*1a748d2bSBoris BREZILLON of_at91_clk_pll_setup(np, pmc, &sama5d3_pll_layout); 537*1a748d2bSBoris BREZILLON } 538