1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * X1000 SoC CGU driver 4 * Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> 5 */ 6 7 #include <linux/clk-provider.h> 8 #include <linux/delay.h> 9 #include <linux/io.h> 10 #include <linux/of.h> 11 12 #include <dt-bindings/clock/ingenic,x1000-cgu.h> 13 14 #include "cgu.h" 15 #include "pm.h" 16 17 /* CGU register offsets */ 18 #define CGU_REG_CPCCR 0x00 19 #define CGU_REG_APLL 0x10 20 #define CGU_REG_MPLL 0x14 21 #define CGU_REG_CLKGR 0x20 22 #define CGU_REG_OPCR 0x24 23 #define CGU_REG_DDRCDR 0x2c 24 #define CGU_REG_USBPCR 0x3c 25 #define CGU_REG_USBPCR1 0x48 26 #define CGU_REG_USBCDR 0x50 27 #define CGU_REG_MACCDR 0x54 28 #define CGU_REG_I2SCDR 0x60 29 #define CGU_REG_LPCDR 0x64 30 #define CGU_REG_MSC0CDR 0x68 31 #define CGU_REG_I2SCDR1 0x70 32 #define CGU_REG_SSICDR 0x74 33 #define CGU_REG_CIMCDR 0x7c 34 #define CGU_REG_PCMCDR 0x84 35 #define CGU_REG_MSC1CDR 0xa4 36 #define CGU_REG_CMP_INTR 0xb0 37 #define CGU_REG_CMP_INTRE 0xb4 38 #define CGU_REG_DRCG 0xd0 39 #define CGU_REG_CPCSR 0xd4 40 #define CGU_REG_PCMCDR1 0xe0 41 #define CGU_REG_MACPHYC 0xe8 42 43 /* bits within the OPCR register */ 44 #define OPCR_SPENDN0 BIT(7) 45 #define OPCR_SPENDN1 BIT(6) 46 47 /* bits within the USBPCR register */ 48 #define USBPCR_SIDDQ BIT(21) 49 #define USBPCR_OTG_DISABLE BIT(20) 50 51 /* bits within the USBPCR1 register */ 52 #define USBPCR1_REFCLKSEL_SHIFT 26 53 #define USBPCR1_REFCLKSEL_MASK (0x3 << USBPCR1_REFCLKSEL_SHIFT) 54 #define USBPCR1_REFCLKSEL_CORE (0x2 << USBPCR1_REFCLKSEL_SHIFT) 55 #define USBPCR1_REFCLKDIV_SHIFT 24 56 #define USBPCR1_REFCLKDIV_MASK (0x3 << USBPCR1_REFCLKDIV_SHIFT) 57 #define USBPCR1_REFCLKDIV_48 (0x2 << USBPCR1_REFCLKDIV_SHIFT) 58 #define USBPCR1_REFCLKDIV_24 (0x1 << USBPCR1_REFCLKDIV_SHIFT) 59 #define USBPCR1_REFCLKDIV_12 (0x0 << USBPCR1_REFCLKDIV_SHIFT) 60 61 static struct ingenic_cgu *cgu; 62 63 static unsigned long x1000_otg_phy_recalc_rate(struct clk_hw *hw, 64 unsigned long parent_rate) 65 { 66 u32 usbpcr1; 67 unsigned refclk_div; 68 69 usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1); 70 refclk_div = usbpcr1 & USBPCR1_REFCLKDIV_MASK; 71 72 switch (refclk_div) { 73 case USBPCR1_REFCLKDIV_12: 74 return 12000000; 75 76 case USBPCR1_REFCLKDIV_24: 77 return 24000000; 78 79 case USBPCR1_REFCLKDIV_48: 80 return 48000000; 81 } 82 83 return parent_rate; 84 } 85 86 static long x1000_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate, 87 unsigned long *parent_rate) 88 { 89 if (req_rate < 18000000) 90 return 12000000; 91 92 if (req_rate < 36000000) 93 return 24000000; 94 95 return 48000000; 96 } 97 98 static int x1000_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate, 99 unsigned long parent_rate) 100 { 101 unsigned long flags; 102 u32 usbpcr1, div_bits; 103 104 switch (req_rate) { 105 case 12000000: 106 div_bits = USBPCR1_REFCLKDIV_12; 107 break; 108 109 case 24000000: 110 div_bits = USBPCR1_REFCLKDIV_24; 111 break; 112 113 case 48000000: 114 div_bits = USBPCR1_REFCLKDIV_48; 115 break; 116 117 default: 118 return -EINVAL; 119 } 120 121 spin_lock_irqsave(&cgu->lock, flags); 122 123 usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1); 124 usbpcr1 &= ~USBPCR1_REFCLKDIV_MASK; 125 usbpcr1 |= div_bits; 126 writel(usbpcr1, cgu->base + CGU_REG_USBPCR1); 127 128 spin_unlock_irqrestore(&cgu->lock, flags); 129 return 0; 130 } 131 132 static int x1000_usb_phy_enable(struct clk_hw *hw) 133 { 134 void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 135 void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR; 136 137 writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr); 138 writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr); 139 return 0; 140 } 141 142 static void x1000_usb_phy_disable(struct clk_hw *hw) 143 { 144 void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 145 void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR; 146 147 writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr); 148 writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr); 149 } 150 151 static int x1000_usb_phy_is_enabled(struct clk_hw *hw) 152 { 153 void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 154 void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR; 155 156 return (readl(reg_opcr) & OPCR_SPENDN0) && 157 !(readl(reg_usbpcr) & USBPCR_SIDDQ) && 158 !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE); 159 } 160 161 static const struct clk_ops x1000_otg_phy_ops = { 162 .recalc_rate = x1000_otg_phy_recalc_rate, 163 .round_rate = x1000_otg_phy_round_rate, 164 .set_rate = x1000_otg_phy_set_rate, 165 166 .enable = x1000_usb_phy_enable, 167 .disable = x1000_usb_phy_disable, 168 .is_enabled = x1000_usb_phy_is_enabled, 169 }; 170 171 static const s8 pll_od_encoding[8] = { 172 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3, 173 }; 174 175 static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { 176 177 /* External clocks */ 178 179 [X1000_CLK_EXCLK] = { "ext", CGU_CLK_EXT }, 180 [X1000_CLK_RTCLK] = { "rtc", CGU_CLK_EXT }, 181 182 /* PLLs */ 183 184 [X1000_CLK_APLL] = { 185 "apll", CGU_CLK_PLL, 186 .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 187 .pll = { 188 .reg = CGU_REG_APLL, 189 .rate_multiplier = 1, 190 .m_shift = 24, 191 .m_bits = 7, 192 .m_offset = 1, 193 .n_shift = 18, 194 .n_bits = 5, 195 .n_offset = 1, 196 .od_shift = 16, 197 .od_bits = 2, 198 .od_max = 8, 199 .od_encoding = pll_od_encoding, 200 .bypass_reg = CGU_REG_APLL, 201 .bypass_bit = 9, 202 .enable_bit = 8, 203 .stable_bit = 10, 204 }, 205 }, 206 207 [X1000_CLK_MPLL] = { 208 "mpll", CGU_CLK_PLL, 209 .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 210 .pll = { 211 .reg = CGU_REG_MPLL, 212 .rate_multiplier = 1, 213 .m_shift = 24, 214 .m_bits = 7, 215 .m_offset = 1, 216 .n_shift = 18, 217 .n_bits = 5, 218 .n_offset = 1, 219 .od_shift = 16, 220 .od_bits = 2, 221 .od_max = 8, 222 .od_encoding = pll_od_encoding, 223 .bypass_reg = CGU_REG_MPLL, 224 .bypass_bit = 6, 225 .enable_bit = 7, 226 .stable_bit = 0, 227 }, 228 }, 229 230 /* Custom (SoC-specific) OTG PHY */ 231 232 [X1000_CLK_OTGPHY] = { 233 "otg_phy", CGU_CLK_CUSTOM, 234 .parents = { -1, -1, X1000_CLK_EXCLK, -1 }, 235 .custom = { &x1000_otg_phy_ops }, 236 }, 237 238 /* Muxes & dividers */ 239 240 [X1000_CLK_SCLKA] = { 241 "sclk_a", CGU_CLK_MUX, 242 .parents = { -1, X1000_CLK_EXCLK, X1000_CLK_APLL, -1 }, 243 .mux = { CGU_REG_CPCCR, 30, 2 }, 244 }, 245 246 [X1000_CLK_CPUMUX] = { 247 "cpu_mux", CGU_CLK_MUX, 248 .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, 249 .mux = { CGU_REG_CPCCR, 28, 2 }, 250 }, 251 252 [X1000_CLK_CPU] = { 253 "cpu", CGU_CLK_DIV | CGU_CLK_GATE, 254 .parents = { X1000_CLK_CPUMUX, -1, -1, -1 }, 255 .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 }, 256 .gate = { CGU_REG_CLKGR, 30 }, 257 }, 258 259 [X1000_CLK_L2CACHE] = { 260 "l2cache", CGU_CLK_DIV, 261 .parents = { X1000_CLK_CPUMUX, -1, -1, -1 }, 262 .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 }, 263 }, 264 265 [X1000_CLK_AHB0] = { 266 "ahb0", CGU_CLK_MUX | CGU_CLK_DIV, 267 .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, 268 .mux = { CGU_REG_CPCCR, 26, 2 }, 269 .div = { CGU_REG_CPCCR, 8, 1, 4, 21, -1, -1 }, 270 }, 271 272 [X1000_CLK_AHB2PMUX] = { 273 "ahb2_apb_mux", CGU_CLK_MUX, 274 .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, 275 .mux = { CGU_REG_CPCCR, 24, 2 }, 276 }, 277 278 [X1000_CLK_AHB2] = { 279 "ahb2", CGU_CLK_DIV, 280 .parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 }, 281 .div = { CGU_REG_CPCCR, 12, 1, 4, 20, -1, -1 }, 282 }, 283 284 [X1000_CLK_PCLK] = { 285 "pclk", CGU_CLK_DIV | CGU_CLK_GATE, 286 .parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 }, 287 .div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 }, 288 .gate = { CGU_REG_CLKGR, 28 }, 289 }, 290 291 [X1000_CLK_DDR] = { 292 "ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 293 .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, 294 .mux = { CGU_REG_DDRCDR, 30, 2 }, 295 .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 }, 296 .gate = { CGU_REG_CLKGR, 31 }, 297 }, 298 299 [X1000_CLK_MAC] = { 300 "mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 301 .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL }, 302 .mux = { CGU_REG_MACCDR, 31, 1 }, 303 .div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 }, 304 .gate = { CGU_REG_CLKGR, 25 }, 305 }, 306 307 [X1000_CLK_LCD] = { 308 "lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 309 .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL }, 310 .mux = { CGU_REG_LPCDR, 31, 1 }, 311 .div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 }, 312 .gate = { CGU_REG_CLKGR, 23 }, 313 }, 314 315 [X1000_CLK_MSCMUX] = { 316 "msc_mux", CGU_CLK_MUX, 317 .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL}, 318 .mux = { CGU_REG_MSC0CDR, 31, 1 }, 319 }, 320 321 [X1000_CLK_MSC0] = { 322 "msc0", CGU_CLK_DIV | CGU_CLK_GATE, 323 .parents = { X1000_CLK_MSCMUX, -1, -1, -1 }, 324 .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 }, 325 .gate = { CGU_REG_CLKGR, 4 }, 326 }, 327 328 [X1000_CLK_MSC1] = { 329 "msc1", CGU_CLK_DIV | CGU_CLK_GATE, 330 .parents = { X1000_CLK_MSCMUX, -1, -1, -1 }, 331 .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 }, 332 .gate = { CGU_REG_CLKGR, 5 }, 333 }, 334 335 [X1000_CLK_OTG] = { 336 "otg", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 337 .parents = { X1000_CLK_EXCLK, -1, 338 X1000_CLK_APLL, X1000_CLK_MPLL }, 339 .mux = { CGU_REG_USBCDR, 30, 2 }, 340 .div = { CGU_REG_USBCDR, 0, 1, 8, 29, 28, 27 }, 341 .gate = { CGU_REG_CLKGR, 3 }, 342 }, 343 344 [X1000_CLK_SSIPLL] = { 345 "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV, 346 .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL, -1, -1 }, 347 .mux = { CGU_REG_SSICDR, 31, 1 }, 348 .div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 }, 349 }, 350 351 [X1000_CLK_SSIPLL_DIV2] = { 352 "ssi_pll_div2", CGU_CLK_FIXDIV, 353 .parents = { X1000_CLK_SSIPLL }, 354 .fixdiv = { 2 }, 355 }, 356 357 [X1000_CLK_SSIMUX] = { 358 "ssi_mux", CGU_CLK_MUX, 359 .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL_DIV2, -1, -1 }, 360 .mux = { CGU_REG_SSICDR, 30, 1 }, 361 }, 362 363 [X1000_CLK_EXCLK_DIV512] = { 364 "exclk_div512", CGU_CLK_FIXDIV, 365 .parents = { X1000_CLK_EXCLK }, 366 .fixdiv = { 512 }, 367 }, 368 369 [X1000_CLK_RTC] = { 370 "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE, 371 .parents = { X1000_CLK_EXCLK_DIV512, X1000_CLK_RTCLK }, 372 .mux = { CGU_REG_OPCR, 2, 1}, 373 .gate = { CGU_REG_CLKGR, 27 }, 374 }, 375 376 /* Gate-only clocks */ 377 378 [X1000_CLK_EMC] = { 379 "emc", CGU_CLK_GATE, 380 .parents = { X1000_CLK_AHB2, -1, -1, -1 }, 381 .gate = { CGU_REG_CLKGR, 0 }, 382 }, 383 384 [X1000_CLK_EFUSE] = { 385 "efuse", CGU_CLK_GATE, 386 .parents = { X1000_CLK_AHB2, -1, -1, -1 }, 387 .gate = { CGU_REG_CLKGR, 1 }, 388 }, 389 390 [X1000_CLK_SFC] = { 391 "sfc", CGU_CLK_GATE, 392 .parents = { X1000_CLK_SSIPLL, -1, -1, -1 }, 393 .gate = { CGU_REG_CLKGR, 2 }, 394 }, 395 396 [X1000_CLK_I2C0] = { 397 "i2c0", CGU_CLK_GATE, 398 .parents = { X1000_CLK_PCLK, -1, -1, -1 }, 399 .gate = { CGU_REG_CLKGR, 7 }, 400 }, 401 402 [X1000_CLK_I2C1] = { 403 "i2c1", CGU_CLK_GATE, 404 .parents = { X1000_CLK_PCLK, -1, -1, -1 }, 405 .gate = { CGU_REG_CLKGR, 8 }, 406 }, 407 408 [X1000_CLK_I2C2] = { 409 "i2c2", CGU_CLK_GATE, 410 .parents = { X1000_CLK_PCLK, -1, -1, -1 }, 411 .gate = { CGU_REG_CLKGR, 9 }, 412 }, 413 414 [X1000_CLK_UART0] = { 415 "uart0", CGU_CLK_GATE, 416 .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 417 .gate = { CGU_REG_CLKGR, 14 }, 418 }, 419 420 [X1000_CLK_UART1] = { 421 "uart1", CGU_CLK_GATE, 422 .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 423 .gate = { CGU_REG_CLKGR, 15 }, 424 }, 425 426 [X1000_CLK_UART2] = { 427 "uart2", CGU_CLK_GATE, 428 .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 429 .gate = { CGU_REG_CLKGR, 16 }, 430 }, 431 432 [X1000_CLK_TCU] = { 433 "tcu", CGU_CLK_GATE, 434 .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 435 .gate = { CGU_REG_CLKGR, 18 }, 436 }, 437 438 [X1000_CLK_SSI] = { 439 "ssi", CGU_CLK_GATE, 440 .parents = { X1000_CLK_SSIMUX, -1, -1, -1 }, 441 .gate = { CGU_REG_CLKGR, 19 }, 442 }, 443 444 [X1000_CLK_OST] = { 445 "ost", CGU_CLK_GATE, 446 .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 447 .gate = { CGU_REG_CLKGR, 20 }, 448 }, 449 450 [X1000_CLK_PDMA] = { 451 "pdma", CGU_CLK_GATE, 452 .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 453 .gate = { CGU_REG_CLKGR, 21 }, 454 }, 455 }; 456 457 static void __init x1000_cgu_init(struct device_node *np) 458 { 459 int retval; 460 461 cgu = ingenic_cgu_new(x1000_cgu_clocks, 462 ARRAY_SIZE(x1000_cgu_clocks), np); 463 if (!cgu) { 464 pr_err("%s: failed to initialise CGU\n", __func__); 465 return; 466 } 467 468 retval = ingenic_cgu_register_clocks(cgu); 469 if (retval) { 470 pr_err("%s: failed to register CGU Clocks\n", __func__); 471 return; 472 } 473 474 ingenic_cgu_register_syscore_ops(cgu); 475 } 476 /* 477 * CGU has some children devices, this is useful for probing children devices 478 * in the case where the device node is compatible with "simple-mfd". 479 */ 480 CLK_OF_DECLARE_DRIVER(x1000_cgu, "ingenic,x1000-cgu", x1000_cgu_init); 481