Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * PLL clock descriptions for TI DA850/OMAP-L138/AM18XX
0004  *
0005  * Copyright (C) 2018 David Lechner <david@lechnology.com>
0006  */
0007 
0008 #include <linux/bitops.h>
0009 #include <linux/clk-provider.h>
0010 #include <linux/clk/davinci.h>
0011 #include <linux/clkdev.h>
0012 #include <linux/device.h>
0013 #include <linux/init.h>
0014 #include <linux/io.h>
0015 #include <linux/kernel.h>
0016 #include <linux/mfd/da8xx-cfgchip.h>
0017 #include <linux/mfd/syscon.h>
0018 #include <linux/of_address.h>
0019 #include <linux/of.h>
0020 #include <linux/types.h>
0021 
0022 #include "pll.h"
0023 
0024 #define OCSEL_OCSRC_OSCIN       0x14
0025 #define OCSEL_OCSRC_PLL0_SYSCLK(n)  (0x16 + (n))
0026 #define OCSEL_OCSRC_PLL1_OBSCLK     0x1e
0027 #define OCSEL_OCSRC_PLL1_SYSCLK(n)  (0x16 + (n))
0028 
0029 static const struct davinci_pll_clk_info da850_pll0_info = {
0030     .name = "pll0",
0031     .unlock_reg = CFGCHIP(0),
0032     .unlock_mask = CFGCHIP0_PLL_MASTER_LOCK,
0033     .pllm_mask = GENMASK(4, 0),
0034     .pllm_min = 4,
0035     .pllm_max = 32,
0036     .pllout_min_rate = 300000000,
0037     .pllout_max_rate = 600000000,
0038     .flags = PLL_HAS_CLKMODE | PLL_HAS_PREDIV | PLL_HAS_POSTDIV |
0039          PLL_HAS_EXTCLKSRC,
0040 };
0041 
0042 /*
0043  * NB: Technically, the clocks flagged as SYSCLK_FIXED_DIV are "fixed ratio",
0044  * meaning that we could change the divider as long as we keep the correct
0045  * ratio between all of the clocks, but we don't support that because there is
0046  * currently not a need for it.
0047  */
0048 
0049 SYSCLK(1, pll0_sysclk1, pll0_pllen, 5, SYSCLK_FIXED_DIV);
0050 SYSCLK(2, pll0_sysclk2, pll0_pllen, 5, SYSCLK_FIXED_DIV);
0051 SYSCLK(3, pll0_sysclk3, pll0_pllen, 5, 0);
0052 SYSCLK(4, pll0_sysclk4, pll0_pllen, 5, SYSCLK_FIXED_DIV);
0053 SYSCLK(5, pll0_sysclk5, pll0_pllen, 5, 0);
0054 SYSCLK(6, pll0_sysclk6, pll0_pllen, 5, SYSCLK_ARM_RATE | SYSCLK_FIXED_DIV);
0055 SYSCLK(7, pll0_sysclk7, pll0_pllen, 5, 0);
0056 
0057 static const char * const da850_pll0_obsclk_parent_names[] = {
0058     "oscin",
0059     "pll0_sysclk1",
0060     "pll0_sysclk2",
0061     "pll0_sysclk3",
0062     "pll0_sysclk4",
0063     "pll0_sysclk5",
0064     "pll0_sysclk6",
0065     "pll0_sysclk7",
0066     "pll1_obsclk",
0067 };
0068 
0069 static u32 da850_pll0_obsclk_table[] = {
0070     OCSEL_OCSRC_OSCIN,
0071     OCSEL_OCSRC_PLL0_SYSCLK(1),
0072     OCSEL_OCSRC_PLL0_SYSCLK(2),
0073     OCSEL_OCSRC_PLL0_SYSCLK(3),
0074     OCSEL_OCSRC_PLL0_SYSCLK(4),
0075     OCSEL_OCSRC_PLL0_SYSCLK(5),
0076     OCSEL_OCSRC_PLL0_SYSCLK(6),
0077     OCSEL_OCSRC_PLL0_SYSCLK(7),
0078     OCSEL_OCSRC_PLL1_OBSCLK,
0079 };
0080 
0081 static const struct davinci_pll_obsclk_info da850_pll0_obsclk_info = {
0082     .name = "pll0_obsclk",
0083     .parent_names = da850_pll0_obsclk_parent_names,
0084     .num_parents = ARRAY_SIZE(da850_pll0_obsclk_parent_names),
0085     .table = da850_pll0_obsclk_table,
0086     .ocsrc_mask = GENMASK(4, 0),
0087 };
0088 
0089 int da850_pll0_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
0090 {
0091     struct clk *clk;
0092 
0093     davinci_pll_clk_register(dev, &da850_pll0_info, "ref_clk", base, cfgchip);
0094 
0095     clk = davinci_pll_sysclk_register(dev, &pll0_sysclk1, base);
0096     clk_register_clkdev(clk, "pll0_sysclk1", "da850-psc0");
0097 
0098     clk = davinci_pll_sysclk_register(dev, &pll0_sysclk2, base);
0099     clk_register_clkdev(clk, "pll0_sysclk2", "da850-psc0");
0100     clk_register_clkdev(clk, "pll0_sysclk2", "da850-psc1");
0101     clk_register_clkdev(clk, "pll0_sysclk2", "da850-async3-clksrc");
0102 
0103     clk = davinci_pll_sysclk_register(dev, &pll0_sysclk3, base);
0104     clk_register_clkdev(clk, "pll0_sysclk3", "da850-async1-clksrc");
0105 
0106     clk = davinci_pll_sysclk_register(dev, &pll0_sysclk4, base);
0107     clk_register_clkdev(clk, "pll0_sysclk4", "da850-psc0");
0108     clk_register_clkdev(clk, "pll0_sysclk4", "da850-psc1");
0109 
0110     davinci_pll_sysclk_register(dev, &pll0_sysclk5, base);
0111 
0112     clk = davinci_pll_sysclk_register(dev, &pll0_sysclk6, base);
0113     clk_register_clkdev(clk, "pll0_sysclk6", "da850-psc0");
0114 
0115     davinci_pll_sysclk_register(dev, &pll0_sysclk7, base);
0116 
0117     davinci_pll_auxclk_register(dev, "pll0_auxclk", base);
0118 
0119     clk = clk_register_fixed_factor(dev, "async2", "pll0_auxclk",
0120                     CLK_IS_CRITICAL, 1, 1);
0121 
0122     clk_register_clkdev(clk, NULL, "i2c_davinci.1");
0123     clk_register_clkdev(clk, "timer0", NULL);
0124     clk_register_clkdev(clk, NULL, "davinci-wdt");
0125 
0126     davinci_pll_obsclk_register(dev, &da850_pll0_obsclk_info, base);
0127 
0128     return 0;
0129 }
0130 
0131 static const struct davinci_pll_sysclk_info *da850_pll0_sysclk_info[] = {
0132     &pll0_sysclk1,
0133     &pll0_sysclk2,
0134     &pll0_sysclk3,
0135     &pll0_sysclk4,
0136     &pll0_sysclk5,
0137     &pll0_sysclk6,
0138     &pll0_sysclk7,
0139     NULL
0140 };
0141 
0142 void of_da850_pll0_init(struct device_node *node)
0143 {
0144     void __iomem *base;
0145     struct regmap *cfgchip;
0146 
0147     base = of_iomap(node, 0);
0148     if (!base) {
0149         pr_err("%s: ioremap failed\n", __func__);
0150         return;
0151     }
0152 
0153     cfgchip = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
0154 
0155     of_davinci_pll_init(NULL, node, &da850_pll0_info,
0156                 &da850_pll0_obsclk_info,
0157                 da850_pll0_sysclk_info, 7, base, cfgchip);
0158 }
0159 
0160 static const struct davinci_pll_clk_info da850_pll1_info = {
0161     .name = "pll1",
0162     .unlock_reg = CFGCHIP(3),
0163     .unlock_mask = CFGCHIP3_PLL1_MASTER_LOCK,
0164     .pllm_mask = GENMASK(4, 0),
0165     .pllm_min = 4,
0166     .pllm_max = 32,
0167     .pllout_min_rate = 300000000,
0168     .pllout_max_rate = 600000000,
0169     .flags = PLL_HAS_POSTDIV,
0170 };
0171 
0172 SYSCLK(1, pll1_sysclk1, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
0173 SYSCLK(2, pll1_sysclk2, pll1_pllen, 5, 0);
0174 SYSCLK(3, pll1_sysclk3, pll1_pllen, 5, 0);
0175 
0176 static const char * const da850_pll1_obsclk_parent_names[] = {
0177     "oscin",
0178     "pll1_sysclk1",
0179     "pll1_sysclk2",
0180     "pll1_sysclk3",
0181 };
0182 
0183 static u32 da850_pll1_obsclk_table[] = {
0184     OCSEL_OCSRC_OSCIN,
0185     OCSEL_OCSRC_PLL1_SYSCLK(1),
0186     OCSEL_OCSRC_PLL1_SYSCLK(2),
0187     OCSEL_OCSRC_PLL1_SYSCLK(3),
0188 };
0189 
0190 static const struct davinci_pll_obsclk_info da850_pll1_obsclk_info = {
0191     .name = "pll1_obsclk",
0192     .parent_names = da850_pll1_obsclk_parent_names,
0193     .num_parents = ARRAY_SIZE(da850_pll1_obsclk_parent_names),
0194     .table = da850_pll1_obsclk_table,
0195     .ocsrc_mask = GENMASK(4, 0),
0196 };
0197 
0198 int da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
0199 {
0200     struct clk *clk;
0201 
0202     davinci_pll_clk_register(dev, &da850_pll1_info, "oscin", base, cfgchip);
0203 
0204     davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
0205 
0206     clk = davinci_pll_sysclk_register(dev, &pll1_sysclk2, base);
0207     clk_register_clkdev(clk, "pll1_sysclk2", "da850-async3-clksrc");
0208 
0209     davinci_pll_sysclk_register(dev, &pll1_sysclk3, base);
0210 
0211     davinci_pll_obsclk_register(dev, &da850_pll1_obsclk_info, base);
0212 
0213     return 0;
0214 }
0215 
0216 static const struct davinci_pll_sysclk_info *da850_pll1_sysclk_info[] = {
0217     &pll1_sysclk1,
0218     &pll1_sysclk2,
0219     &pll1_sysclk3,
0220     NULL
0221 };
0222 
0223 int of_da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
0224 {
0225     return of_davinci_pll_init(dev, dev->of_node, &da850_pll1_info,
0226                    &da850_pll1_obsclk_info,
0227                    da850_pll1_sysclk_info, 3, base, cfgchip);
0228 }