linux/drivers/clk/davinci/pll-da850.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * PLL clock descriptions for TI DA850/OMAP-L138/AM18XX
   4 *
   5 * Copyright (C) 2018 David Lechner <david@lechnology.com>
   6 */
   7
   8#include <linux/bitops.h>
   9#include <linux/clk-provider.h>
  10#include <linux/clk/davinci.h>
  11#include <linux/clkdev.h>
  12#include <linux/device.h>
  13#include <linux/init.h>
  14#include <linux/io.h>
  15#include <linux/kernel.h>
  16#include <linux/mfd/da8xx-cfgchip.h>
  17#include <linux/mfd/syscon.h>
  18#include <linux/of_address.h>
  19#include <linux/of.h>
  20#include <linux/types.h>
  21
  22#include "pll.h"
  23
  24#define OCSEL_OCSRC_OSCIN               0x14
  25#define OCSEL_OCSRC_PLL0_SYSCLK(n)      (0x16 + (n))
  26#define OCSEL_OCSRC_PLL1_OBSCLK         0x1e
  27#define OCSEL_OCSRC_PLL1_SYSCLK(n)      (0x16 + (n))
  28
  29static const struct davinci_pll_clk_info da850_pll0_info = {
  30        .name = "pll0",
  31        .unlock_reg = CFGCHIP(0),
  32        .unlock_mask = CFGCHIP0_PLL_MASTER_LOCK,
  33        .pllm_mask = GENMASK(4, 0),
  34        .pllm_min = 4,
  35        .pllm_max = 32,
  36        .pllout_min_rate = 300000000,
  37        .pllout_max_rate = 600000000,
  38        .flags = PLL_HAS_CLKMODE | PLL_HAS_PREDIV | PLL_HAS_POSTDIV |
  39                 PLL_HAS_EXTCLKSRC,
  40};
  41
  42/*
  43 * NB: Technically, the clocks flagged as SYSCLK_FIXED_DIV are "fixed ratio",
  44 * meaning that we could change the divider as long as we keep the correct
  45 * ratio between all of the clocks, but we don't support that because there is
  46 * currently not a need for it.
  47 */
  48
  49SYSCLK(1, pll0_sysclk1, pll0_pllen, 5, SYSCLK_FIXED_DIV);
  50SYSCLK(2, pll0_sysclk2, pll0_pllen, 5, SYSCLK_FIXED_DIV);
  51SYSCLK(3, pll0_sysclk3, pll0_pllen, 5, 0);
  52SYSCLK(4, pll0_sysclk4, pll0_pllen, 5, SYSCLK_FIXED_DIV);
  53SYSCLK(5, pll0_sysclk5, pll0_pllen, 5, 0);
  54SYSCLK(6, pll0_sysclk6, pll0_pllen, 5, SYSCLK_ARM_RATE | SYSCLK_FIXED_DIV);
  55SYSCLK(7, pll0_sysclk7, pll0_pllen, 5, 0);
  56
  57static const char * const da850_pll0_obsclk_parent_names[] = {
  58        "oscin",
  59        "pll0_sysclk1",
  60        "pll0_sysclk2",
  61        "pll0_sysclk3",
  62        "pll0_sysclk4",
  63        "pll0_sysclk5",
  64        "pll0_sysclk6",
  65        "pll0_sysclk7",
  66        "pll1_obsclk",
  67};
  68
  69static u32 da850_pll0_obsclk_table[] = {
  70        OCSEL_OCSRC_OSCIN,
  71        OCSEL_OCSRC_PLL0_SYSCLK(1),
  72        OCSEL_OCSRC_PLL0_SYSCLK(2),
  73        OCSEL_OCSRC_PLL0_SYSCLK(3),
  74        OCSEL_OCSRC_PLL0_SYSCLK(4),
  75        OCSEL_OCSRC_PLL0_SYSCLK(5),
  76        OCSEL_OCSRC_PLL0_SYSCLK(6),
  77        OCSEL_OCSRC_PLL0_SYSCLK(7),
  78        OCSEL_OCSRC_PLL1_OBSCLK,
  79};
  80
  81static const struct davinci_pll_obsclk_info da850_pll0_obsclk_info = {
  82        .name = "pll0_obsclk",
  83        .parent_names = da850_pll0_obsclk_parent_names,
  84        .num_parents = ARRAY_SIZE(da850_pll0_obsclk_parent_names),
  85        .table = da850_pll0_obsclk_table,
  86        .ocsrc_mask = GENMASK(4, 0),
  87};
  88
  89int da850_pll0_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
  90{
  91        struct clk *clk;
  92
  93        davinci_pll_clk_register(dev, &da850_pll0_info, "ref_clk", base, cfgchip);
  94
  95        clk = davinci_pll_sysclk_register(dev, &pll0_sysclk1, base);
  96        clk_register_clkdev(clk, "pll0_sysclk1", "da850-psc0");
  97
  98        clk = davinci_pll_sysclk_register(dev, &pll0_sysclk2, base);
  99        clk_register_clkdev(clk, "pll0_sysclk2", "da850-psc0");
 100        clk_register_clkdev(clk, "pll0_sysclk2", "da850-psc1");
 101        clk_register_clkdev(clk, "pll0_sysclk2", "da850-async3-clksrc");
 102
 103        clk = davinci_pll_sysclk_register(dev, &pll0_sysclk3, base);
 104        clk_register_clkdev(clk, "pll0_sysclk3", "da850-async1-clksrc");
 105
 106        clk = davinci_pll_sysclk_register(dev, &pll0_sysclk4, base);
 107        clk_register_clkdev(clk, "pll0_sysclk4", "da850-psc0");
 108        clk_register_clkdev(clk, "pll0_sysclk4", "da850-psc1");
 109
 110        davinci_pll_sysclk_register(dev, &pll0_sysclk5, base);
 111
 112        clk = davinci_pll_sysclk_register(dev, &pll0_sysclk6, base);
 113        clk_register_clkdev(clk, "pll0_sysclk6", "da850-psc0");
 114
 115        davinci_pll_sysclk_register(dev, &pll0_sysclk7, base);
 116
 117        davinci_pll_auxclk_register(dev, "pll0_auxclk", base);
 118
 119        clk = clk_register_fixed_factor(dev, "async2", "pll0_auxclk",
 120                                        CLK_IS_CRITICAL, 1, 1);
 121
 122        clk_register_clkdev(clk, NULL, "i2c_davinci.1");
 123        clk_register_clkdev(clk, "timer0", NULL);
 124        clk_register_clkdev(clk, NULL, "davinci-wdt");
 125
 126        davinci_pll_obsclk_register(dev, &da850_pll0_obsclk_info, base);
 127
 128        return 0;
 129}
 130
 131static const struct davinci_pll_sysclk_info *da850_pll0_sysclk_info[] = {
 132        &pll0_sysclk1,
 133        &pll0_sysclk2,
 134        &pll0_sysclk3,
 135        &pll0_sysclk4,
 136        &pll0_sysclk5,
 137        &pll0_sysclk6,
 138        &pll0_sysclk7,
 139        NULL
 140};
 141
 142void of_da850_pll0_init(struct device_node *node)
 143{
 144        void __iomem *base;
 145        struct regmap *cfgchip;
 146
 147        base = of_iomap(node, 0);
 148        if (!base) {
 149                pr_err("%s: ioremap failed\n", __func__);
 150                return;
 151        }
 152
 153        cfgchip = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
 154
 155        of_davinci_pll_init(NULL, node, &da850_pll0_info,
 156                            &da850_pll0_obsclk_info,
 157                            da850_pll0_sysclk_info, 7, base, cfgchip);
 158}
 159
 160static const struct davinci_pll_clk_info da850_pll1_info = {
 161        .name = "pll1",
 162        .unlock_reg = CFGCHIP(3),
 163        .unlock_mask = CFGCHIP3_PLL1_MASTER_LOCK,
 164        .pllm_mask = GENMASK(4, 0),
 165        .pllm_min = 4,
 166        .pllm_max = 32,
 167        .pllout_min_rate = 300000000,
 168        .pllout_max_rate = 600000000,
 169        .flags = PLL_HAS_POSTDIV,
 170};
 171
 172SYSCLK(1, pll1_sysclk1, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
 173SYSCLK(2, pll1_sysclk2, pll1_pllen, 5, 0);
 174SYSCLK(3, pll1_sysclk3, pll1_pllen, 5, 0);
 175
 176static const char * const da850_pll1_obsclk_parent_names[] = {
 177        "oscin",
 178        "pll1_sysclk1",
 179        "pll1_sysclk2",
 180        "pll1_sysclk3",
 181};
 182
 183static u32 da850_pll1_obsclk_table[] = {
 184        OCSEL_OCSRC_OSCIN,
 185        OCSEL_OCSRC_PLL1_SYSCLK(1),
 186        OCSEL_OCSRC_PLL1_SYSCLK(2),
 187        OCSEL_OCSRC_PLL1_SYSCLK(3),
 188};
 189
 190static const struct davinci_pll_obsclk_info da850_pll1_obsclk_info = {
 191        .name = "pll1_obsclk",
 192        .parent_names = da850_pll1_obsclk_parent_names,
 193        .num_parents = ARRAY_SIZE(da850_pll1_obsclk_parent_names),
 194        .table = da850_pll1_obsclk_table,
 195        .ocsrc_mask = GENMASK(4, 0),
 196};
 197
 198int da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
 199{
 200        struct clk *clk;
 201
 202        davinci_pll_clk_register(dev, &da850_pll1_info, "oscin", base, cfgchip);
 203
 204        davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
 205
 206        clk = davinci_pll_sysclk_register(dev, &pll1_sysclk2, base);
 207        clk_register_clkdev(clk, "pll1_sysclk2", "da850-async3-clksrc");
 208
 209        davinci_pll_sysclk_register(dev, &pll1_sysclk3, base);
 210
 211        davinci_pll_obsclk_register(dev, &da850_pll1_obsclk_info, base);
 212
 213        return 0;
 214}
 215
 216static const struct davinci_pll_sysclk_info *da850_pll1_sysclk_info[] = {
 217        &pll1_sysclk1,
 218        &pll1_sysclk2,
 219        &pll1_sysclk3,
 220        NULL
 221};
 222
 223int of_da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
 224{
 225        return of_davinci_pll_init(dev, dev->of_node, &da850_pll1_info,
 226                                   &da850_pll1_obsclk_info,
 227                                   da850_pll1_sysclk_info, 3, base, cfgchip);
 228}
 229