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