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