1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Ingenic JZ4780 SoC CGU driver 4 * 5 * Copyright (c) 2013-2015 Imagination Technologies 6 * Author: Paul Burton <paul.burton@mips.com> 7 * Copyright (c) 2020 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> 8 */ 9 10 #include <linux/clk-provider.h> 11 #include <linux/delay.h> 12 #include <linux/io.h> 13 #include <linux/iopoll.h> 14 #include <linux/of.h> 15 16 #include <dt-bindings/clock/jz4780-cgu.h> 17 18 #include "cgu.h" 19 #include "pm.h" 20 21 /* CGU register offsets */ 22 #define CGU_REG_CLOCKCONTROL 0x00 23 #define CGU_REG_LCR 0x04 24 #define CGU_REG_APLL 0x10 25 #define CGU_REG_MPLL 0x14 26 #define CGU_REG_EPLL 0x18 27 #define CGU_REG_VPLL 0x1c 28 #define CGU_REG_CLKGR0 0x20 29 #define CGU_REG_OPCR 0x24 30 #define CGU_REG_CLKGR1 0x28 31 #define CGU_REG_DDRCDR 0x2c 32 #define CGU_REG_VPUCDR 0x30 33 #define CGU_REG_USBPCR 0x3c 34 #define CGU_REG_USBRDT 0x40 35 #define CGU_REG_USBVBFIL 0x44 36 #define CGU_REG_USBPCR1 0x48 37 #define CGU_REG_LP0CDR 0x54 38 #define CGU_REG_I2SCDR 0x60 39 #define CGU_REG_LP1CDR 0x64 40 #define CGU_REG_MSC0CDR 0x68 41 #define CGU_REG_UHCCDR 0x6c 42 #define CGU_REG_SSICDR 0x74 43 #define CGU_REG_CIMCDR 0x7c 44 #define CGU_REG_PCMCDR 0x84 45 #define CGU_REG_GPUCDR 0x88 46 #define CGU_REG_HDMICDR 0x8c 47 #define CGU_REG_MSC1CDR 0xa4 48 #define CGU_REG_MSC2CDR 0xa8 49 #define CGU_REG_BCHCDR 0xac 50 #define CGU_REG_CLOCKSTATUS 0xd4 51 52 /* bits within the OPCR register */ 53 #define OPCR_SPENDN0 BIT(7) 54 #define OPCR_SPENDN1 BIT(6) 55 56 /* bits within the USBPCR register */ 57 #define USBPCR_USB_MODE BIT(31) 58 #define USBPCR_IDPULLUP_MASK (0x3 << 28) 59 #define USBPCR_COMMONONN BIT(25) 60 #define USBPCR_VBUSVLDEXT BIT(24) 61 #define USBPCR_VBUSVLDEXTSEL BIT(23) 62 #define USBPCR_POR BIT(22) 63 #define USBPCR_SIDDQ BIT(21) 64 #define USBPCR_OTG_DISABLE BIT(20) 65 #define USBPCR_COMPDISTUNE_MASK (0x7 << 17) 66 #define USBPCR_OTGTUNE_MASK (0x7 << 14) 67 #define USBPCR_SQRXTUNE_MASK (0x7 << 11) 68 #define USBPCR_TXFSLSTUNE_MASK (0xf << 7) 69 #define USBPCR_TXPREEMPHTUNE BIT(6) 70 #define USBPCR_TXHSXVTUNE_MASK (0x3 << 4) 71 #define USBPCR_TXVREFTUNE_MASK 0xf 72 73 /* bits within the USBPCR1 register */ 74 #define USBPCR1_REFCLKSEL_SHIFT 26 75 #define USBPCR1_REFCLKSEL_MASK (0x3 << USBPCR1_REFCLKSEL_SHIFT) 76 #define USBPCR1_REFCLKSEL_CORE (0x2 << USBPCR1_REFCLKSEL_SHIFT) 77 #define USBPCR1_REFCLKDIV_SHIFT 24 78 #define USBPCR1_REFCLKDIV_MASK (0x3 << USBPCR1_REFCLKDIV_SHIFT) 79 #define USBPCR1_REFCLKDIV_19_2 (0x3 << USBPCR1_REFCLKDIV_SHIFT) 80 #define USBPCR1_REFCLKDIV_48 (0x2 << USBPCR1_REFCLKDIV_SHIFT) 81 #define USBPCR1_REFCLKDIV_24 (0x1 << USBPCR1_REFCLKDIV_SHIFT) 82 #define USBPCR1_REFCLKDIV_12 (0x0 << USBPCR1_REFCLKDIV_SHIFT) 83 #define USBPCR1_USB_SEL BIT(28) 84 #define USBPCR1_WORD_IF0 BIT(19) 85 #define USBPCR1_WORD_IF1 BIT(18) 86 87 /* bits within the USBRDT register */ 88 #define USBRDT_VBFIL_LD_EN BIT(25) 89 #define USBRDT_USBRDT_MASK 0x7fffff 90 91 /* bits within the USBVBFIL register */ 92 #define USBVBFIL_IDDIGFIL_SHIFT 16 93 #define USBVBFIL_IDDIGFIL_MASK (0xffff << USBVBFIL_IDDIGFIL_SHIFT) 94 #define USBVBFIL_USBVBFIL_MASK (0xffff) 95 96 /* bits within the LCR register */ 97 #define LCR_PD_SCPU BIT(31) 98 #define LCR_SCPUS BIT(27) 99 100 /* bits within the CLKGR1 register */ 101 #define CLKGR1_CORE1 BIT(15) 102 103 static struct ingenic_cgu *cgu; 104 105 static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw, 106 unsigned long parent_rate) 107 { 108 u32 usbpcr1; 109 unsigned refclk_div; 110 111 usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1); 112 refclk_div = usbpcr1 & USBPCR1_REFCLKDIV_MASK; 113 114 switch (refclk_div) { 115 case USBPCR1_REFCLKDIV_12: 116 return 12000000; 117 118 case USBPCR1_REFCLKDIV_24: 119 return 24000000; 120 121 case USBPCR1_REFCLKDIV_48: 122 return 48000000; 123 124 case USBPCR1_REFCLKDIV_19_2: 125 return 19200000; 126 } 127 128 return parent_rate; 129 } 130 131 static long jz4780_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate, 132 unsigned long *parent_rate) 133 { 134 if (req_rate < 15600000) 135 return 12000000; 136 137 if (req_rate < 21600000) 138 return 19200000; 139 140 if (req_rate < 36000000) 141 return 24000000; 142 143 return 48000000; 144 } 145 146 static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate, 147 unsigned long parent_rate) 148 { 149 unsigned long flags; 150 u32 usbpcr1, div_bits; 151 152 switch (req_rate) { 153 case 12000000: 154 div_bits = USBPCR1_REFCLKDIV_12; 155 break; 156 157 case 19200000: 158 div_bits = USBPCR1_REFCLKDIV_19_2; 159 break; 160 161 case 24000000: 162 div_bits = USBPCR1_REFCLKDIV_24; 163 break; 164 165 case 48000000: 166 div_bits = USBPCR1_REFCLKDIV_48; 167 break; 168 169 default: 170 return -EINVAL; 171 } 172 173 spin_lock_irqsave(&cgu->lock, flags); 174 175 usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1); 176 usbpcr1 &= ~USBPCR1_REFCLKDIV_MASK; 177 usbpcr1 |= div_bits; 178 writel(usbpcr1, cgu->base + CGU_REG_USBPCR1); 179 180 spin_unlock_irqrestore(&cgu->lock, flags); 181 return 0; 182 } 183 184 static int jz4780_otg_phy_enable(struct clk_hw *hw) 185 { 186 void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 187 void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR; 188 189 writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr); 190 writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr); 191 return 0; 192 } 193 194 static void jz4780_otg_phy_disable(struct clk_hw *hw) 195 { 196 void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 197 void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR; 198 199 writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr); 200 writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr); 201 } 202 203 static int jz4780_otg_phy_is_enabled(struct clk_hw *hw) 204 { 205 void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 206 void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR; 207 208 return (readl(reg_opcr) & OPCR_SPENDN0) && 209 !(readl(reg_usbpcr) & USBPCR_SIDDQ) && 210 !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE); 211 } 212 213 static const struct clk_ops jz4780_otg_phy_ops = { 214 .recalc_rate = jz4780_otg_phy_recalc_rate, 215 .round_rate = jz4780_otg_phy_round_rate, 216 .set_rate = jz4780_otg_phy_set_rate, 217 218 .enable = jz4780_otg_phy_enable, 219 .disable = jz4780_otg_phy_disable, 220 .is_enabled = jz4780_otg_phy_is_enabled, 221 }; 222 223 static int jz4780_core1_enable(struct clk_hw *hw) 224 { 225 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); 226 struct ingenic_cgu *cgu = ingenic_clk->cgu; 227 const unsigned int timeout = 5000; 228 unsigned long flags; 229 int retval; 230 u32 lcr, clkgr1; 231 232 spin_lock_irqsave(&cgu->lock, flags); 233 234 lcr = readl(cgu->base + CGU_REG_LCR); 235 lcr &= ~LCR_PD_SCPU; 236 writel(lcr, cgu->base + CGU_REG_LCR); 237 238 clkgr1 = readl(cgu->base + CGU_REG_CLKGR1); 239 clkgr1 &= ~CLKGR1_CORE1; 240 writel(clkgr1, cgu->base + CGU_REG_CLKGR1); 241 242 spin_unlock_irqrestore(&cgu->lock, flags); 243 244 /* wait for the CPU to be powered up */ 245 retval = readl_poll_timeout(cgu->base + CGU_REG_LCR, lcr, 246 !(lcr & LCR_SCPUS), 10, timeout); 247 if (retval == -ETIMEDOUT) { 248 pr_err("%s: Wait for power up core1 timeout\n", __func__); 249 return retval; 250 } 251 252 return 0; 253 } 254 255 static const struct clk_ops jz4780_core1_ops = { 256 .enable = jz4780_core1_enable, 257 }; 258 259 static const s8 pll_od_encoding[16] = { 260 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 261 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 262 }; 263 264 static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = { 265 266 /* External clocks */ 267 268 [JZ4780_CLK_EXCLK] = { "ext", CGU_CLK_EXT }, 269 [JZ4780_CLK_RTCLK] = { "rtc", CGU_CLK_EXT }, 270 271 /* PLLs */ 272 273 #define DEF_PLL(name) { \ 274 .reg = CGU_REG_ ## name, \ 275 .rate_multiplier = 1, \ 276 .m_shift = 19, \ 277 .m_bits = 13, \ 278 .m_offset = 1, \ 279 .n_shift = 13, \ 280 .n_bits = 6, \ 281 .n_offset = 1, \ 282 .od_shift = 9, \ 283 .od_bits = 4, \ 284 .od_max = 16, \ 285 .od_encoding = pll_od_encoding, \ 286 .stable_bit = 6, \ 287 .bypass_reg = CGU_REG_ ## name, \ 288 .bypass_bit = 1, \ 289 .enable_bit = 0, \ 290 } 291 292 [JZ4780_CLK_APLL] = { 293 "apll", CGU_CLK_PLL, 294 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 295 .pll = DEF_PLL(APLL), 296 }, 297 298 [JZ4780_CLK_MPLL] = { 299 "mpll", CGU_CLK_PLL, 300 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 301 .pll = DEF_PLL(MPLL), 302 }, 303 304 [JZ4780_CLK_EPLL] = { 305 "epll", CGU_CLK_PLL, 306 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 307 .pll = DEF_PLL(EPLL), 308 }, 309 310 [JZ4780_CLK_VPLL] = { 311 "vpll", CGU_CLK_PLL, 312 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 313 .pll = DEF_PLL(VPLL), 314 }, 315 316 #undef DEF_PLL 317 318 /* Custom (SoC-specific) OTG PHY */ 319 320 [JZ4780_CLK_OTGPHY] = { 321 "otg_phy", CGU_CLK_CUSTOM, 322 .parents = { -1, -1, JZ4780_CLK_EXCLK, -1 }, 323 .custom = { &jz4780_otg_phy_ops }, 324 }, 325 326 /* Muxes & dividers */ 327 328 [JZ4780_CLK_SCLKA] = { 329 "sclk_a", CGU_CLK_MUX, 330 .parents = { -1, JZ4780_CLK_APLL, JZ4780_CLK_EXCLK, 331 JZ4780_CLK_RTCLK }, 332 .mux = { CGU_REG_CLOCKCONTROL, 30, 2 }, 333 }, 334 335 [JZ4780_CLK_CPUMUX] = { 336 "cpumux", CGU_CLK_MUX, 337 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 338 JZ4780_CLK_EPLL }, 339 .mux = { CGU_REG_CLOCKCONTROL, 28, 2 }, 340 }, 341 342 [JZ4780_CLK_CPU] = { 343 "cpu", CGU_CLK_DIV, 344 .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 }, 345 .div = { CGU_REG_CLOCKCONTROL, 0, 1, 4, 22, -1, -1 }, 346 }, 347 348 [JZ4780_CLK_L2CACHE] = { 349 "l2cache", CGU_CLK_DIV, 350 .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 }, 351 .div = { CGU_REG_CLOCKCONTROL, 4, 1, 4, -1, -1, -1 }, 352 }, 353 354 [JZ4780_CLK_AHB0] = { 355 "ahb0", CGU_CLK_MUX | CGU_CLK_DIV, 356 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 357 JZ4780_CLK_EPLL }, 358 .mux = { CGU_REG_CLOCKCONTROL, 26, 2 }, 359 .div = { CGU_REG_CLOCKCONTROL, 8, 1, 4, 21, -1, -1 }, 360 }, 361 362 [JZ4780_CLK_AHB2PMUX] = { 363 "ahb2_apb_mux", CGU_CLK_MUX, 364 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 365 JZ4780_CLK_RTCLK }, 366 .mux = { CGU_REG_CLOCKCONTROL, 24, 2 }, 367 }, 368 369 [JZ4780_CLK_AHB2] = { 370 "ahb2", CGU_CLK_DIV, 371 .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 }, 372 .div = { CGU_REG_CLOCKCONTROL, 12, 1, 4, 20, -1, -1 }, 373 }, 374 375 [JZ4780_CLK_PCLK] = { 376 "pclk", CGU_CLK_DIV, 377 .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 }, 378 .div = { CGU_REG_CLOCKCONTROL, 16, 1, 4, 20, -1, -1 }, 379 }, 380 381 [JZ4780_CLK_DDR] = { 382 "ddr", CGU_CLK_MUX | CGU_CLK_DIV, 383 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 }, 384 .mux = { CGU_REG_DDRCDR, 30, 2 }, 385 .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 }, 386 }, 387 388 [JZ4780_CLK_VPU] = { 389 "vpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 390 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 391 JZ4780_CLK_EPLL, -1 }, 392 .mux = { CGU_REG_VPUCDR, 30, 2 }, 393 .div = { CGU_REG_VPUCDR, 0, 1, 4, 29, 28, 27 }, 394 .gate = { CGU_REG_CLKGR1, 2 }, 395 }, 396 397 [JZ4780_CLK_I2SPLL] = { 398 "i2s_pll", CGU_CLK_MUX | CGU_CLK_DIV, 399 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_EPLL, -1, -1 }, 400 .mux = { CGU_REG_I2SCDR, 30, 1 }, 401 .div = { CGU_REG_I2SCDR, 0, 1, 8, 29, 28, 27 }, 402 }, 403 404 [JZ4780_CLK_I2S] = { 405 "i2s", CGU_CLK_MUX, 406 .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_I2SPLL, -1, -1 }, 407 .mux = { CGU_REG_I2SCDR, 31, 1 }, 408 }, 409 410 [JZ4780_CLK_LCD0PIXCLK] = { 411 "lcd0pixclk", CGU_CLK_MUX | CGU_CLK_DIV, 412 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 413 JZ4780_CLK_VPLL, -1 }, 414 .mux = { CGU_REG_LP0CDR, 30, 2 }, 415 .div = { CGU_REG_LP0CDR, 0, 1, 8, 28, 27, 26 }, 416 }, 417 418 [JZ4780_CLK_LCD1PIXCLK] = { 419 "lcd1pixclk", CGU_CLK_MUX | CGU_CLK_DIV, 420 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 421 JZ4780_CLK_VPLL, -1 }, 422 .mux = { CGU_REG_LP1CDR, 30, 2 }, 423 .div = { CGU_REG_LP1CDR, 0, 1, 8, 28, 27, 26 }, 424 }, 425 426 [JZ4780_CLK_MSCMUX] = { 427 "msc_mux", CGU_CLK_MUX, 428 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 }, 429 .mux = { CGU_REG_MSC0CDR, 30, 2 }, 430 }, 431 432 [JZ4780_CLK_MSC0] = { 433 "msc0", CGU_CLK_DIV | CGU_CLK_GATE, 434 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, 435 .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 }, 436 .gate = { CGU_REG_CLKGR0, 3 }, 437 }, 438 439 [JZ4780_CLK_MSC1] = { 440 "msc1", CGU_CLK_DIV | CGU_CLK_GATE, 441 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, 442 .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 }, 443 .gate = { CGU_REG_CLKGR0, 11 }, 444 }, 445 446 [JZ4780_CLK_MSC2] = { 447 "msc2", CGU_CLK_DIV | CGU_CLK_GATE, 448 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, 449 .div = { CGU_REG_MSC2CDR, 0, 2, 8, 29, 28, 27 }, 450 .gate = { CGU_REG_CLKGR0, 12 }, 451 }, 452 453 [JZ4780_CLK_UHC] = { 454 "uhc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 455 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 456 JZ4780_CLK_EPLL, JZ4780_CLK_OTGPHY }, 457 .mux = { CGU_REG_UHCCDR, 30, 2 }, 458 .div = { CGU_REG_UHCCDR, 0, 1, 8, 29, 28, 27 }, 459 .gate = { CGU_REG_CLKGR0, 24 }, 460 }, 461 462 [JZ4780_CLK_SSIPLL] = { 463 "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV, 464 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 }, 465 .mux = { CGU_REG_SSICDR, 30, 1 }, 466 .div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 }, 467 }, 468 469 [JZ4780_CLK_SSI] = { 470 "ssi", CGU_CLK_MUX, 471 .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_SSIPLL, -1, -1 }, 472 .mux = { CGU_REG_SSICDR, 31, 1 }, 473 }, 474 475 [JZ4780_CLK_CIMMCLK] = { 476 "cim_mclk", CGU_CLK_MUX | CGU_CLK_DIV, 477 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 }, 478 .mux = { CGU_REG_CIMCDR, 31, 1 }, 479 .div = { CGU_REG_CIMCDR, 0, 1, 8, 30, 29, 28 }, 480 }, 481 482 [JZ4780_CLK_PCMPLL] = { 483 "pcm_pll", CGU_CLK_MUX | CGU_CLK_DIV, 484 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 485 JZ4780_CLK_EPLL, JZ4780_CLK_VPLL }, 486 .mux = { CGU_REG_PCMCDR, 29, 2 }, 487 .div = { CGU_REG_PCMCDR, 0, 1, 8, 28, 27, 26 }, 488 }, 489 490 [JZ4780_CLK_PCM] = { 491 "pcm", CGU_CLK_MUX | CGU_CLK_GATE, 492 .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_PCMPLL, -1, -1 }, 493 .mux = { CGU_REG_PCMCDR, 31, 1 }, 494 .gate = { CGU_REG_CLKGR1, 3 }, 495 }, 496 497 [JZ4780_CLK_GPU] = { 498 "gpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 499 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 500 JZ4780_CLK_EPLL }, 501 .mux = { CGU_REG_GPUCDR, 30, 2 }, 502 .div = { CGU_REG_GPUCDR, 0, 1, 4, 29, 28, 27 }, 503 .gate = { CGU_REG_CLKGR1, 4 }, 504 }, 505 506 [JZ4780_CLK_HDMI] = { 507 "hdmi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 508 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 509 JZ4780_CLK_VPLL, -1 }, 510 .mux = { CGU_REG_HDMICDR, 30, 2 }, 511 .div = { CGU_REG_HDMICDR, 0, 1, 8, 29, 28, 26 }, 512 .gate = { CGU_REG_CLKGR1, 9 }, 513 }, 514 515 [JZ4780_CLK_BCH] = { 516 "bch", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 517 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 518 JZ4780_CLK_EPLL }, 519 .mux = { CGU_REG_BCHCDR, 30, 2 }, 520 .div = { CGU_REG_BCHCDR, 0, 1, 4, 29, 28, 27 }, 521 .gate = { CGU_REG_CLKGR0, 1 }, 522 }, 523 524 [JZ4780_CLK_EXCLK_DIV512] = { 525 "exclk_div512", CGU_CLK_FIXDIV, 526 .parents = { JZ4780_CLK_EXCLK }, 527 .fixdiv = { 512 }, 528 }, 529 530 [JZ4780_CLK_RTC] = { 531 "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE, 532 .parents = { JZ4780_CLK_EXCLK_DIV512, JZ4780_CLK_RTCLK }, 533 .mux = { CGU_REG_OPCR, 2, 1}, 534 }, 535 536 /* Gate-only clocks */ 537 538 [JZ4780_CLK_NEMC] = { 539 "nemc", CGU_CLK_GATE, 540 .parents = { JZ4780_CLK_AHB2, -1, -1, -1 }, 541 .gate = { CGU_REG_CLKGR0, 0 }, 542 }, 543 544 [JZ4780_CLK_OTG0] = { 545 "otg0", CGU_CLK_GATE, 546 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 547 .gate = { CGU_REG_CLKGR0, 2 }, 548 }, 549 550 [JZ4780_CLK_SSI0] = { 551 "ssi0", CGU_CLK_GATE, 552 .parents = { JZ4780_CLK_SSI, -1, -1, -1 }, 553 .gate = { CGU_REG_CLKGR0, 4 }, 554 }, 555 556 [JZ4780_CLK_SMB0] = { 557 "smb0", CGU_CLK_GATE, 558 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, 559 .gate = { CGU_REG_CLKGR0, 5 }, 560 }, 561 562 [JZ4780_CLK_SMB1] = { 563 "smb1", CGU_CLK_GATE, 564 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, 565 .gate = { CGU_REG_CLKGR0, 6 }, 566 }, 567 568 [JZ4780_CLK_SCC] = { 569 "scc", CGU_CLK_GATE, 570 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 571 .gate = { CGU_REG_CLKGR0, 7 }, 572 }, 573 574 [JZ4780_CLK_AIC] = { 575 "aic", CGU_CLK_GATE, 576 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 577 .gate = { CGU_REG_CLKGR0, 8 }, 578 }, 579 580 [JZ4780_CLK_TSSI0] = { 581 "tssi0", CGU_CLK_GATE, 582 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 583 .gate = { CGU_REG_CLKGR0, 9 }, 584 }, 585 586 [JZ4780_CLK_OWI] = { 587 "owi", CGU_CLK_GATE, 588 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 589 .gate = { CGU_REG_CLKGR0, 10 }, 590 }, 591 592 [JZ4780_CLK_KBC] = { 593 "kbc", CGU_CLK_GATE, 594 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 595 .gate = { CGU_REG_CLKGR0, 13 }, 596 }, 597 598 [JZ4780_CLK_SADC] = { 599 "sadc", CGU_CLK_GATE, 600 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 601 .gate = { CGU_REG_CLKGR0, 14 }, 602 }, 603 604 [JZ4780_CLK_UART0] = { 605 "uart0", CGU_CLK_GATE, 606 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 607 .gate = { CGU_REG_CLKGR0, 15 }, 608 }, 609 610 [JZ4780_CLK_UART1] = { 611 "uart1", CGU_CLK_GATE, 612 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 613 .gate = { CGU_REG_CLKGR0, 16 }, 614 }, 615 616 [JZ4780_CLK_UART2] = { 617 "uart2", CGU_CLK_GATE, 618 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 619 .gate = { CGU_REG_CLKGR0, 17 }, 620 }, 621 622 [JZ4780_CLK_UART3] = { 623 "uart3", CGU_CLK_GATE, 624 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 625 .gate = { CGU_REG_CLKGR0, 18 }, 626 }, 627 628 [JZ4780_CLK_SSI1] = { 629 "ssi1", CGU_CLK_GATE, 630 .parents = { JZ4780_CLK_SSI, -1, -1, -1 }, 631 .gate = { CGU_REG_CLKGR0, 19 }, 632 }, 633 634 [JZ4780_CLK_SSI2] = { 635 "ssi2", CGU_CLK_GATE, 636 .parents = { JZ4780_CLK_SSI, -1, -1, -1 }, 637 .gate = { CGU_REG_CLKGR0, 20 }, 638 }, 639 640 [JZ4780_CLK_PDMA] = { 641 "pdma", CGU_CLK_GATE, 642 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 643 .gate = { CGU_REG_CLKGR0, 21 }, 644 }, 645 646 [JZ4780_CLK_GPS] = { 647 "gps", CGU_CLK_GATE, 648 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 649 .gate = { CGU_REG_CLKGR0, 22 }, 650 }, 651 652 [JZ4780_CLK_MAC] = { 653 "mac", CGU_CLK_GATE, 654 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 655 .gate = { CGU_REG_CLKGR0, 23 }, 656 }, 657 658 [JZ4780_CLK_SMB2] = { 659 "smb2", CGU_CLK_GATE, 660 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, 661 .gate = { CGU_REG_CLKGR0, 24 }, 662 }, 663 664 [JZ4780_CLK_CIM] = { 665 "cim", CGU_CLK_GATE, 666 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 667 .gate = { CGU_REG_CLKGR0, 26 }, 668 }, 669 670 [JZ4780_CLK_LCD] = { 671 "lcd", CGU_CLK_GATE, 672 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 673 .gate = { CGU_REG_CLKGR0, 28 }, 674 }, 675 676 [JZ4780_CLK_TVE] = { 677 "tve", CGU_CLK_GATE, 678 .parents = { JZ4780_CLK_LCD, -1, -1, -1 }, 679 .gate = { CGU_REG_CLKGR0, 27 }, 680 }, 681 682 [JZ4780_CLK_IPU] = { 683 "ipu", CGU_CLK_GATE, 684 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 685 .gate = { CGU_REG_CLKGR0, 29 }, 686 }, 687 688 [JZ4780_CLK_DDR0] = { 689 "ddr0", CGU_CLK_GATE, 690 .parents = { JZ4780_CLK_DDR, -1, -1, -1 }, 691 .gate = { CGU_REG_CLKGR0, 30 }, 692 }, 693 694 [JZ4780_CLK_DDR1] = { 695 "ddr1", CGU_CLK_GATE, 696 .parents = { JZ4780_CLK_DDR, -1, -1, -1 }, 697 .gate = { CGU_REG_CLKGR0, 31 }, 698 }, 699 700 [JZ4780_CLK_SMB3] = { 701 "smb3", CGU_CLK_GATE, 702 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, 703 .gate = { CGU_REG_CLKGR1, 0 }, 704 }, 705 706 [JZ4780_CLK_TSSI1] = { 707 "tssi1", CGU_CLK_GATE, 708 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 709 .gate = { CGU_REG_CLKGR1, 1 }, 710 }, 711 712 [JZ4780_CLK_COMPRESS] = { 713 "compress", CGU_CLK_GATE, 714 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 715 .gate = { CGU_REG_CLKGR1, 5 }, 716 }, 717 718 [JZ4780_CLK_AIC1] = { 719 "aic1", CGU_CLK_GATE, 720 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 721 .gate = { CGU_REG_CLKGR1, 6 }, 722 }, 723 724 [JZ4780_CLK_GPVLC] = { 725 "gpvlc", CGU_CLK_GATE, 726 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 727 .gate = { CGU_REG_CLKGR1, 7 }, 728 }, 729 730 [JZ4780_CLK_OTG1] = { 731 "otg1", CGU_CLK_GATE, 732 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 733 .gate = { CGU_REG_CLKGR1, 8 }, 734 }, 735 736 [JZ4780_CLK_UART4] = { 737 "uart4", CGU_CLK_GATE, 738 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 739 .gate = { CGU_REG_CLKGR1, 10 }, 740 }, 741 742 [JZ4780_CLK_AHBMON] = { 743 "ahb_mon", CGU_CLK_GATE, 744 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 745 .gate = { CGU_REG_CLKGR1, 11 }, 746 }, 747 748 [JZ4780_CLK_SMB4] = { 749 "smb4", CGU_CLK_GATE, 750 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, 751 .gate = { CGU_REG_CLKGR1, 12 }, 752 }, 753 754 [JZ4780_CLK_DES] = { 755 "des", CGU_CLK_GATE, 756 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 757 .gate = { CGU_REG_CLKGR1, 13 }, 758 }, 759 760 [JZ4780_CLK_X2D] = { 761 "x2d", CGU_CLK_GATE, 762 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 763 .gate = { CGU_REG_CLKGR1, 14 }, 764 }, 765 766 [JZ4780_CLK_CORE1] = { 767 "core1", CGU_CLK_CUSTOM, 768 .parents = { JZ4780_CLK_CPU, -1, -1, -1 }, 769 .custom = { &jz4780_core1_ops }, 770 }, 771 772 }; 773 774 static void __init jz4780_cgu_init(struct device_node *np) 775 { 776 int retval; 777 778 cgu = ingenic_cgu_new(jz4780_cgu_clocks, 779 ARRAY_SIZE(jz4780_cgu_clocks), np); 780 if (!cgu) { 781 pr_err("%s: failed to initialise CGU\n", __func__); 782 return; 783 } 784 785 retval = ingenic_cgu_register_clocks(cgu); 786 if (retval) { 787 pr_err("%s: failed to register CGU Clocks\n", __func__); 788 return; 789 } 790 791 ingenic_cgu_register_syscore_ops(cgu); 792 } 793 CLK_OF_DECLARE_DRIVER(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init); 794