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