linux/drivers/clk/keystone/pll.c
<<
>>
Prefs
   1/*
   2 * PLL clock driver for Keystone devices
   3 *
   4 * Copyright (C) 2013 Texas Instruments Inc.
   5 *      Murali Karicheri <m-karicheri2@ti.com>
   6 *      Santosh Shilimkar <santosh.shilimkar@ti.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 */
  13#include <linux/clk.h>
  14#include <linux/clk-provider.h>
  15#include <linux/err.h>
  16#include <linux/io.h>
  17#include <linux/slab.h>
  18#include <linux/of_address.h>
  19#include <linux/of.h>
  20#include <linux/module.h>
  21
  22#define PLLM_LOW_MASK           0x3f
  23#define PLLM_HIGH_MASK          0x7ffc0
  24#define MAIN_PLLM_HIGH_MASK     0x7f000
  25#define PLLM_HIGH_SHIFT         6
  26#define PLLD_MASK               0x3f
  27#define CLKOD_MASK              0x780000
  28#define CLKOD_SHIFT             19
  29
  30/**
  31 * struct clk_pll_data - pll data structure
  32 * @has_pllctrl: If set to non zero, lower 6 bits of multiplier is in pllm
  33 *      register of pll controller, else it is in the pll_ctrl0((bit 11-6)
  34 * @phy_pllm: Physical address of PLLM in pll controller. Used when
  35 *      has_pllctrl is non zero.
  36 * @phy_pll_ctl0: Physical address of PLL ctrl0. This could be that of
  37 *      Main PLL or any other PLLs in the device such as ARM PLL, DDR PLL
  38 *      or PA PLL available on keystone2. These PLLs are controlled by
  39 *      this register. Main PLL is controlled by a PLL controller.
  40 * @pllm: PLL register map address
  41 * @pll_ctl0: PLL controller map address
  42 * @pllm_lower_mask: multiplier lower mask
  43 * @pllm_upper_mask: multiplier upper mask
  44 * @pllm_upper_shift: multiplier upper shift
  45 * @plld_mask: divider mask
  46 * @clkod_mask: output divider mask
  47 * @clkod_shift: output divider shift
  48 * @plld_mask: divider mask
  49 * @postdiv: Fixed post divider
  50 */
  51struct clk_pll_data {
  52        bool has_pllctrl;
  53        u32 phy_pllm;
  54        u32 phy_pll_ctl0;
  55        void __iomem *pllm;
  56        void __iomem *pll_ctl0;
  57        u32 pllm_lower_mask;
  58        u32 pllm_upper_mask;
  59        u32 pllm_upper_shift;
  60        u32 plld_mask;
  61        u32 clkod_mask;
  62        u32 clkod_shift;
  63        u32 postdiv;
  64};
  65
  66/**
  67 * struct clk_pll - Main pll clock
  68 * @hw: clk_hw for the pll
  69 * @pll_data: PLL driver specific data
  70 */
  71struct clk_pll {
  72        struct clk_hw hw;
  73        struct clk_pll_data *pll_data;
  74};
  75
  76#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
  77
  78static unsigned long clk_pllclk_recalc(struct clk_hw *hw,
  79                                        unsigned long parent_rate)
  80{
  81        struct clk_pll *pll = to_clk_pll(hw);
  82        struct clk_pll_data *pll_data = pll->pll_data;
  83        unsigned long rate = parent_rate;
  84        u32  mult = 0, prediv, postdiv, val;
  85
  86        /*
  87         * get bits 0-5 of multiplier from pllctrl PLLM register
  88         * if has_pllctrl is non zero
  89         */
  90        if (pll_data->has_pllctrl) {
  91                val = readl(pll_data->pllm);
  92                mult = (val & pll_data->pllm_lower_mask);
  93        }
  94
  95        /* bit6-12 of PLLM is in Main PLL control register */
  96        val = readl(pll_data->pll_ctl0);
  97        mult |= ((val & pll_data->pllm_upper_mask)
  98                        >> pll_data->pllm_upper_shift);
  99        prediv = (val & pll_data->plld_mask);
 100
 101        if (!pll_data->has_pllctrl)
 102                /* read post divider from od bits*/
 103                postdiv = ((val & pll_data->clkod_mask) >>
 104                                 pll_data->clkod_shift) + 1;
 105        else
 106                postdiv = pll_data->postdiv;
 107
 108        rate /= (prediv + 1);
 109        rate = (rate * (mult + 1));
 110        rate /= postdiv;
 111
 112        return rate;
 113}
 114
 115static const struct clk_ops clk_pll_ops = {
 116        .recalc_rate = clk_pllclk_recalc,
 117};
 118
 119static struct clk *clk_register_pll(struct device *dev,
 120                        const char *name,
 121                        const char *parent_name,
 122                        struct clk_pll_data *pll_data)
 123{
 124        struct clk_init_data init;
 125        struct clk_pll *pll;
 126        struct clk *clk;
 127
 128        pll = kzalloc(sizeof(*pll), GFP_KERNEL);
 129        if (!pll)
 130                return ERR_PTR(-ENOMEM);
 131
 132        init.name = name;
 133        init.ops = &clk_pll_ops;
 134        init.flags = 0;
 135        init.parent_names = (parent_name ? &parent_name : NULL);
 136        init.num_parents = (parent_name ? 1 : 0);
 137
 138        pll->pll_data   = pll_data;
 139        pll->hw.init = &init;
 140
 141        clk = clk_register(NULL, &pll->hw);
 142        if (IS_ERR(clk))
 143                goto out;
 144
 145        return clk;
 146out:
 147        kfree(pll);
 148        return NULL;
 149}
 150
 151/**
 152 * _of_clk_init - PLL initialisation via DT
 153 * @node: device tree node for this clock
 154 * @pllctrl: If true, lower 6 bits of multiplier is in pllm register of
 155 *              pll controller, else it is in the control regsiter0(bit 11-6)
 156 */
 157static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl)
 158{
 159        struct clk_pll_data *pll_data;
 160        const char *parent_name;
 161        struct clk *clk;
 162        int i;
 163
 164        pll_data = kzalloc(sizeof(*pll_data), GFP_KERNEL);
 165        if (!pll_data) {
 166                pr_err("%s: Out of memory\n", __func__);
 167                return;
 168        }
 169
 170        parent_name = of_clk_get_parent_name(node, 0);
 171        if (of_property_read_u32(node, "fixed-postdiv", &pll_data->postdiv)) {
 172                /* assume the PLL has output divider register bits */
 173                pll_data->clkod_mask = CLKOD_MASK;
 174                pll_data->clkod_shift = CLKOD_SHIFT;
 175        }
 176
 177        i = of_property_match_string(node, "reg-names", "control");
 178        pll_data->pll_ctl0 = of_iomap(node, i);
 179        if (!pll_data->pll_ctl0) {
 180                pr_err("%s: ioremap failed\n", __func__);
 181                goto out;
 182        }
 183
 184        pll_data->pllm_lower_mask = PLLM_LOW_MASK;
 185        pll_data->pllm_upper_shift = PLLM_HIGH_SHIFT;
 186        pll_data->plld_mask = PLLD_MASK;
 187        pll_data->has_pllctrl = pllctrl;
 188        if (!pll_data->has_pllctrl) {
 189                pll_data->pllm_upper_mask = PLLM_HIGH_MASK;
 190        } else {
 191                pll_data->pllm_upper_mask = MAIN_PLLM_HIGH_MASK;
 192                i = of_property_match_string(node, "reg-names", "multiplier");
 193                pll_data->pllm = of_iomap(node, i);
 194                if (!pll_data->pllm) {
 195                        iounmap(pll_data->pll_ctl0);
 196                        goto out;
 197                }
 198        }
 199
 200        clk = clk_register_pll(NULL, node->name, parent_name, pll_data);
 201        if (clk) {
 202                of_clk_add_provider(node, of_clk_src_simple_get, clk);
 203                return;
 204        }
 205
 206out:
 207        pr_err("%s: error initializing pll %s\n", __func__, node->name);
 208        kfree(pll_data);
 209}
 210
 211/**
 212 * of_keystone_pll_clk_init - PLL initialisation DT wrapper
 213 * @node: device tree node for this clock
 214 */
 215static void __init of_keystone_pll_clk_init(struct device_node *node)
 216{
 217        _of_pll_clk_init(node, false);
 218}
 219CLK_OF_DECLARE(keystone_pll_clock, "ti,keystone,pll-clock",
 220                                        of_keystone_pll_clk_init);
 221
 222/**
 223 * of_keystone_pll_main_clk_init - Main PLL initialisation DT wrapper
 224 * @node: device tree node for this clock
 225 */
 226static void __init of_keystone_main_pll_clk_init(struct device_node *node)
 227{
 228        _of_pll_clk_init(node, true);
 229}
 230CLK_OF_DECLARE(keystone_main_pll_clock, "ti,keystone,main-pll-clock",
 231                                                of_keystone_main_pll_clk_init);
 232
 233/**
 234 * of_pll_div_clk_init - PLL divider setup function
 235 * @node: device tree node for this clock
 236 */
 237static void __init of_pll_div_clk_init(struct device_node *node)
 238{
 239        const char *parent_name;
 240        void __iomem *reg;
 241        u32 shift, mask;
 242        struct clk *clk;
 243        const char *clk_name = node->name;
 244
 245        of_property_read_string(node, "clock-output-names", &clk_name);
 246        reg = of_iomap(node, 0);
 247        if (!reg) {
 248                pr_err("%s: ioremap failed\n", __func__);
 249                return;
 250        }
 251
 252        parent_name = of_clk_get_parent_name(node, 0);
 253        if (!parent_name) {
 254                pr_err("%s: missing parent clock\n", __func__);
 255                return;
 256        }
 257
 258        if (of_property_read_u32(node, "bit-shift", &shift)) {
 259                pr_err("%s: missing 'shift' property\n", __func__);
 260                return;
 261        }
 262
 263        if (of_property_read_u32(node, "bit-mask", &mask)) {
 264                pr_err("%s: missing 'bit-mask' property\n", __func__);
 265                return;
 266        }
 267
 268        clk = clk_register_divider(NULL, clk_name, parent_name, 0, reg, shift,
 269                                 mask, 0, NULL);
 270        if (clk)
 271                of_clk_add_provider(node, of_clk_src_simple_get, clk);
 272        else
 273                pr_err("%s: error registering divider %s\n", __func__, clk_name);
 274}
 275CLK_OF_DECLARE(pll_divider_clock, "ti,keystone,pll-divider-clock", of_pll_div_clk_init);
 276
 277/**
 278 * of_pll_mux_clk_init - PLL mux setup function
 279 * @node: device tree node for this clock
 280 */
 281static void __init of_pll_mux_clk_init(struct device_node *node)
 282{
 283        void __iomem *reg;
 284        u32 shift, mask;
 285        struct clk *clk;
 286        const char *parents[2];
 287        const char *clk_name = node->name;
 288
 289        of_property_read_string(node, "clock-output-names", &clk_name);
 290        reg = of_iomap(node, 0);
 291        if (!reg) {
 292                pr_err("%s: ioremap failed\n", __func__);
 293                return;
 294        }
 295
 296        parents[0] = of_clk_get_parent_name(node, 0);
 297        parents[1] = of_clk_get_parent_name(node, 1);
 298        if (!parents[0] || !parents[1]) {
 299                pr_err("%s: missing parent clocks\n", __func__);
 300                return;
 301        }
 302
 303        if (of_property_read_u32(node, "bit-shift", &shift)) {
 304                pr_err("%s: missing 'shift' property\n", __func__);
 305                return;
 306        }
 307
 308        if (of_property_read_u32(node, "bit-mask", &mask)) {
 309                pr_err("%s: missing 'bit-mask' property\n", __func__);
 310                return;
 311        }
 312
 313        clk = clk_register_mux(NULL, clk_name, (const char **)&parents,
 314                                ARRAY_SIZE(parents) , 0, reg, shift, mask,
 315                                0, NULL);
 316        if (clk)
 317                of_clk_add_provider(node, of_clk_src_simple_get, clk);
 318        else
 319                pr_err("%s: error registering mux %s\n", __func__, clk_name);
 320}
 321CLK_OF_DECLARE(pll_mux_clock, "ti,keystone,pll-mux-clock", of_pll_mux_clk_init);
 322