1 // SPDX-License-Identifier: GPL-2.0
3 * PLL clock descriptions for TI DA850/OMAP-L138/AM18XX
5 * Copyright (C) 2018 David Lechner <david@lechnology.com>
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/kernel.h>
15 #include <linux/mfd/da8xx-cfgchip.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/of_address.h>
19 #include <linux/types.h>
23 #define OCSEL_OCSRC_OSCIN 0x14
24 #define OCSEL_OCSRC_PLL0_SYSCLK(n) (0x16 + (n))
25 #define OCSEL_OCSRC_PLL1_OBSCLK 0x1e
26 #define OCSEL_OCSRC_PLL1_SYSCLK(n) (0x16 + (n))
28 static const struct davinci_pll_clk_info da850_pll0_info
= {
30 .unlock_reg
= CFGCHIP(0),
31 .unlock_mask
= CFGCHIP0_PLL_MASTER_LOCK
,
32 .pllm_mask
= GENMASK(4, 0),
35 .pllout_min_rate
= 300000000,
36 .pllout_max_rate
= 600000000,
37 .flags
= PLL_HAS_CLKMODE
| PLL_HAS_PREDIV
| PLL_HAS_POSTDIV
|
42 * NB: Technically, the clocks flagged as SYSCLK_FIXED_DIV are "fixed ratio",
43 * meaning that we could change the divider as long as we keep the correct
44 * ratio between all of the clocks, but we don't support that because there is
45 * currently not a need for it.
48 SYSCLK(1, pll0_sysclk1
, pll0_pllen
, 5, SYSCLK_FIXED_DIV
);
49 SYSCLK(2, pll0_sysclk2
, pll0_pllen
, 5, SYSCLK_FIXED_DIV
);
50 SYSCLK(3, pll0_sysclk3
, pll0_pllen
, 5, 0);
51 SYSCLK(4, pll0_sysclk4
, pll0_pllen
, 5, SYSCLK_FIXED_DIV
);
52 SYSCLK(5, pll0_sysclk5
, pll0_pllen
, 5, 0);
53 SYSCLK(6, pll0_sysclk6
, pll0_pllen
, 5, SYSCLK_ARM_RATE
| SYSCLK_FIXED_DIV
);
54 SYSCLK(7, pll0_sysclk7
, pll0_pllen
, 5, 0);
56 static const char * const da850_pll0_obsclk_parent_names
[] = {
68 static u32 da850_pll0_obsclk_table
[] = {
70 OCSEL_OCSRC_PLL0_SYSCLK(1),
71 OCSEL_OCSRC_PLL0_SYSCLK(2),
72 OCSEL_OCSRC_PLL0_SYSCLK(3),
73 OCSEL_OCSRC_PLL0_SYSCLK(4),
74 OCSEL_OCSRC_PLL0_SYSCLK(5),
75 OCSEL_OCSRC_PLL0_SYSCLK(6),
76 OCSEL_OCSRC_PLL0_SYSCLK(7),
77 OCSEL_OCSRC_PLL1_OBSCLK
,
80 static const struct davinci_pll_obsclk_info da850_pll0_obsclk_info
= {
81 .name
= "pll0_obsclk",
82 .parent_names
= da850_pll0_obsclk_parent_names
,
83 .num_parents
= ARRAY_SIZE(da850_pll0_obsclk_parent_names
),
84 .table
= da850_pll0_obsclk_table
,
85 .ocsrc_mask
= GENMASK(4, 0),
88 int da850_pll0_init(struct device
*dev
, void __iomem
*base
, struct regmap
*cfgchip
)
92 davinci_pll_clk_register(dev
, &da850_pll0_info
, "ref_clk", base
, cfgchip
);
94 clk
= davinci_pll_sysclk_register(dev
, &pll0_sysclk1
, base
);
95 clk_register_clkdev(clk
, "pll0_sysclk1", "da850-psc0");
97 clk
= davinci_pll_sysclk_register(dev
, &pll0_sysclk2
, base
);
98 clk_register_clkdev(clk
, "pll0_sysclk2", "da850-psc0");
99 clk_register_clkdev(clk
, "pll0_sysclk2", "da850-psc1");
100 clk_register_clkdev(clk
, "pll0_sysclk2", "da850-async3-clksrc");
102 clk
= davinci_pll_sysclk_register(dev
, &pll0_sysclk3
, base
);
103 clk_register_clkdev(clk
, "pll0_sysclk3", "da850-async1-clksrc");
105 clk
= davinci_pll_sysclk_register(dev
, &pll0_sysclk4
, base
);
106 clk_register_clkdev(clk
, "pll0_sysclk4", "da850-psc0");
107 clk_register_clkdev(clk
, "pll0_sysclk4", "da850-psc1");
109 davinci_pll_sysclk_register(dev
, &pll0_sysclk5
, base
);
111 clk
= davinci_pll_sysclk_register(dev
, &pll0_sysclk6
, base
);
112 clk_register_clkdev(clk
, "pll0_sysclk6", "da850-psc0");
114 davinci_pll_sysclk_register(dev
, &pll0_sysclk7
, base
);
116 davinci_pll_auxclk_register(dev
, "pll0_auxclk", base
);
118 clk
= clk_register_fixed_factor(dev
, "async2", "pll0_auxclk",
119 CLK_IS_CRITICAL
, 1, 1);
121 clk_register_clkdev(clk
, NULL
, "i2c_davinci.1");
122 clk_register_clkdev(clk
, "timer0", NULL
);
123 clk_register_clkdev(clk
, NULL
, "davinci-wdt");
125 davinci_pll_obsclk_register(dev
, &da850_pll0_obsclk_info
, base
);
130 static const struct davinci_pll_sysclk_info
*da850_pll0_sysclk_info
[] = {
141 void of_da850_pll0_init(struct device_node
*node
)
144 struct regmap
*cfgchip
;
146 base
= of_iomap(node
, 0);
148 pr_err("%s: ioremap failed\n", __func__
);
152 cfgchip
= syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
154 of_davinci_pll_init(NULL
, node
, &da850_pll0_info
,
155 &da850_pll0_obsclk_info
,
156 da850_pll0_sysclk_info
, 7, base
, cfgchip
);
159 static const struct davinci_pll_clk_info da850_pll1_info
= {
161 .unlock_reg
= CFGCHIP(3),
162 .unlock_mask
= CFGCHIP3_PLL1_MASTER_LOCK
,
163 .pllm_mask
= GENMASK(4, 0),
166 .pllout_min_rate
= 300000000,
167 .pllout_max_rate
= 600000000,
168 .flags
= PLL_HAS_POSTDIV
,
171 SYSCLK(1, pll1_sysclk1
, pll1_pllen
, 5, SYSCLK_ALWAYS_ENABLED
);
172 SYSCLK(2, pll1_sysclk2
, pll1_pllen
, 5, 0);
173 SYSCLK(3, pll1_sysclk3
, pll1_pllen
, 5, 0);
175 static const char * const da850_pll1_obsclk_parent_names
[] = {
182 static u32 da850_pll1_obsclk_table
[] = {
184 OCSEL_OCSRC_PLL1_SYSCLK(1),
185 OCSEL_OCSRC_PLL1_SYSCLK(2),
186 OCSEL_OCSRC_PLL1_SYSCLK(3),
189 static const struct davinci_pll_obsclk_info da850_pll1_obsclk_info
= {
190 .name
= "pll1_obsclk",
191 .parent_names
= da850_pll1_obsclk_parent_names
,
192 .num_parents
= ARRAY_SIZE(da850_pll1_obsclk_parent_names
),
193 .table
= da850_pll1_obsclk_table
,
194 .ocsrc_mask
= GENMASK(4, 0),
197 int da850_pll1_init(struct device
*dev
, void __iomem
*base
, struct regmap
*cfgchip
)
201 davinci_pll_clk_register(dev
, &da850_pll1_info
, "oscin", base
, cfgchip
);
203 davinci_pll_sysclk_register(dev
, &pll1_sysclk1
, base
);
205 clk
= davinci_pll_sysclk_register(dev
, &pll1_sysclk2
, base
);
206 clk_register_clkdev(clk
, "pll1_sysclk2", "da850-async3-clksrc");
208 davinci_pll_sysclk_register(dev
, &pll1_sysclk3
, base
);
210 davinci_pll_obsclk_register(dev
, &da850_pll1_obsclk_info
, base
);
215 static const struct davinci_pll_sysclk_info
*da850_pll1_sysclk_info
[] = {
222 int of_da850_pll1_init(struct device
*dev
, void __iomem
*base
, struct regmap
*cfgchip
)
224 return of_davinci_pll_init(dev
, dev
->of_node
, &da850_pll1_info
,
225 &da850_pll1_obsclk_info
,
226 da850_pll1_sysclk_info
, 3, base
, cfgchip
);