jz4780-cgu.c (20242B)
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/ingenic,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 103static struct ingenic_cgu *cgu; 104 105static 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 131static 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 146static 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 184static 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 194static 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 203static 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 213static 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 223static 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 255static const struct clk_ops jz4780_core1_ops = { 256 .enable = jz4780_core1_enable, 257}; 258 259static 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 264static 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 /* 345 * Disabling the CPU clock or any parent clocks will hang the 346 * system; mark it critical. 347 */ 348 .flags = CLK_IS_CRITICAL, 349 .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 }, 350 .div = { CGU_REG_CLOCKCONTROL, 0, 1, 4, 22, -1, -1 }, 351 }, 352 353 [JZ4780_CLK_L2CACHE] = { 354 "l2cache", CGU_CLK_DIV, 355 /* 356 * The L2 cache clock is critical if caches are enabled and 357 * disabling it or any parent clocks will hang the system. 358 */ 359 .flags = CLK_IS_CRITICAL, 360 .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 }, 361 .div = { CGU_REG_CLOCKCONTROL, 4, 1, 4, -1, -1, -1 }, 362 }, 363 364 [JZ4780_CLK_AHB0] = { 365 "ahb0", CGU_CLK_MUX | CGU_CLK_DIV, 366 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 367 JZ4780_CLK_EPLL }, 368 .mux = { CGU_REG_CLOCKCONTROL, 26, 2 }, 369 .div = { CGU_REG_CLOCKCONTROL, 8, 1, 4, 21, -1, -1 }, 370 }, 371 372 [JZ4780_CLK_AHB2PMUX] = { 373 "ahb2_apb_mux", CGU_CLK_MUX, 374 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 375 JZ4780_CLK_RTCLK }, 376 .mux = { CGU_REG_CLOCKCONTROL, 24, 2 }, 377 }, 378 379 [JZ4780_CLK_AHB2] = { 380 "ahb2", CGU_CLK_DIV, 381 .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 }, 382 .div = { CGU_REG_CLOCKCONTROL, 12, 1, 4, 20, -1, -1 }, 383 }, 384 385 [JZ4780_CLK_PCLK] = { 386 "pclk", CGU_CLK_DIV, 387 .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 }, 388 .div = { CGU_REG_CLOCKCONTROL, 16, 1, 4, 20, -1, -1 }, 389 }, 390 391 [JZ4780_CLK_DDR] = { 392 "ddr", CGU_CLK_MUX | CGU_CLK_DIV, 393 /* 394 * Disabling DDR clock or its parents will render DRAM 395 * inaccessible; mark it critical. 396 */ 397 .flags = CLK_IS_CRITICAL, 398 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 }, 399 .mux = { CGU_REG_DDRCDR, 30, 2 }, 400 .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 }, 401 }, 402 403 [JZ4780_CLK_VPU] = { 404 "vpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 405 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 406 JZ4780_CLK_EPLL, -1 }, 407 .mux = { CGU_REG_VPUCDR, 30, 2 }, 408 .div = { CGU_REG_VPUCDR, 0, 1, 4, 29, 28, 27 }, 409 .gate = { CGU_REG_CLKGR1, 2 }, 410 }, 411 412 [JZ4780_CLK_I2SPLL] = { 413 "i2s_pll", CGU_CLK_MUX | CGU_CLK_DIV, 414 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_EPLL, -1, -1 }, 415 .mux = { CGU_REG_I2SCDR, 30, 1 }, 416 .div = { CGU_REG_I2SCDR, 0, 1, 8, 29, 28, 27 }, 417 }, 418 419 [JZ4780_CLK_I2S] = { 420 "i2s", CGU_CLK_MUX, 421 .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_I2SPLL, -1, -1 }, 422 .mux = { CGU_REG_I2SCDR, 31, 1 }, 423 }, 424 425 [JZ4780_CLK_LCD0PIXCLK] = { 426 "lcd0pixclk", CGU_CLK_MUX | CGU_CLK_DIV, 427 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 428 JZ4780_CLK_VPLL, -1 }, 429 .mux = { CGU_REG_LP0CDR, 30, 2 }, 430 .div = { CGU_REG_LP0CDR, 0, 1, 8, 28, 27, 26 }, 431 }, 432 433 [JZ4780_CLK_LCD1PIXCLK] = { 434 "lcd1pixclk", CGU_CLK_MUX | CGU_CLK_DIV, 435 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 436 JZ4780_CLK_VPLL, -1 }, 437 .mux = { CGU_REG_LP1CDR, 30, 2 }, 438 .div = { CGU_REG_LP1CDR, 0, 1, 8, 28, 27, 26 }, 439 }, 440 441 [JZ4780_CLK_MSCMUX] = { 442 "msc_mux", CGU_CLK_MUX, 443 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 }, 444 .mux = { CGU_REG_MSC0CDR, 30, 2 }, 445 }, 446 447 [JZ4780_CLK_MSC0] = { 448 "msc0", CGU_CLK_DIV | CGU_CLK_GATE, 449 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, 450 .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 }, 451 .gate = { CGU_REG_CLKGR0, 3 }, 452 }, 453 454 [JZ4780_CLK_MSC1] = { 455 "msc1", CGU_CLK_DIV | CGU_CLK_GATE, 456 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, 457 .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 }, 458 .gate = { CGU_REG_CLKGR0, 11 }, 459 }, 460 461 [JZ4780_CLK_MSC2] = { 462 "msc2", CGU_CLK_DIV | CGU_CLK_GATE, 463 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, 464 .div = { CGU_REG_MSC2CDR, 0, 2, 8, 29, 28, 27 }, 465 .gate = { CGU_REG_CLKGR0, 12 }, 466 }, 467 468 [JZ4780_CLK_UHC] = { 469 "uhc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 470 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 471 JZ4780_CLK_EPLL, JZ4780_CLK_OTGPHY }, 472 .mux = { CGU_REG_UHCCDR, 30, 2 }, 473 .div = { CGU_REG_UHCCDR, 0, 1, 8, 29, 28, 27 }, 474 .gate = { CGU_REG_CLKGR0, 24 }, 475 }, 476 477 [JZ4780_CLK_SSIPLL] = { 478 "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV, 479 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 }, 480 .mux = { CGU_REG_SSICDR, 30, 1 }, 481 .div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 }, 482 }, 483 484 [JZ4780_CLK_SSI] = { 485 "ssi", CGU_CLK_MUX, 486 .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_SSIPLL, -1, -1 }, 487 .mux = { CGU_REG_SSICDR, 31, 1 }, 488 }, 489 490 [JZ4780_CLK_CIMMCLK] = { 491 "cim_mclk", CGU_CLK_MUX | CGU_CLK_DIV, 492 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 }, 493 .mux = { CGU_REG_CIMCDR, 31, 1 }, 494 .div = { CGU_REG_CIMCDR, 0, 1, 8, 30, 29, 28 }, 495 }, 496 497 [JZ4780_CLK_PCMPLL] = { 498 "pcm_pll", CGU_CLK_MUX | CGU_CLK_DIV, 499 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 500 JZ4780_CLK_EPLL, JZ4780_CLK_VPLL }, 501 .mux = { CGU_REG_PCMCDR, 29, 2 }, 502 .div = { CGU_REG_PCMCDR, 0, 1, 8, 28, 27, 26 }, 503 }, 504 505 [JZ4780_CLK_PCM] = { 506 "pcm", CGU_CLK_MUX | CGU_CLK_GATE, 507 .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_PCMPLL, -1, -1 }, 508 .mux = { CGU_REG_PCMCDR, 31, 1 }, 509 .gate = { CGU_REG_CLKGR1, 3 }, 510 }, 511 512 [JZ4780_CLK_GPU] = { 513 "gpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 514 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 515 JZ4780_CLK_EPLL }, 516 .mux = { CGU_REG_GPUCDR, 30, 2 }, 517 .div = { CGU_REG_GPUCDR, 0, 1, 4, 29, 28, 27 }, 518 .gate = { CGU_REG_CLKGR1, 4 }, 519 }, 520 521 [JZ4780_CLK_HDMI] = { 522 "hdmi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 523 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 524 JZ4780_CLK_VPLL, -1 }, 525 .mux = { CGU_REG_HDMICDR, 30, 2 }, 526 .div = { CGU_REG_HDMICDR, 0, 1, 8, 29, 28, 26 }, 527 .gate = { CGU_REG_CLKGR1, 9 }, 528 }, 529 530 [JZ4780_CLK_BCH] = { 531 "bch", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 532 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 533 JZ4780_CLK_EPLL }, 534 .mux = { CGU_REG_BCHCDR, 30, 2 }, 535 .div = { CGU_REG_BCHCDR, 0, 1, 4, 29, 28, 27 }, 536 .gate = { CGU_REG_CLKGR0, 1 }, 537 }, 538 539 [JZ4780_CLK_EXCLK_DIV512] = { 540 "exclk_div512", CGU_CLK_FIXDIV, 541 .parents = { JZ4780_CLK_EXCLK }, 542 .fixdiv = { 512 }, 543 }, 544 545 [JZ4780_CLK_RTC] = { 546 "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE, 547 .parents = { JZ4780_CLK_EXCLK_DIV512, JZ4780_CLK_RTCLK }, 548 .mux = { CGU_REG_OPCR, 2, 1}, 549 }, 550 551 /* Gate-only clocks */ 552 553 [JZ4780_CLK_NEMC] = { 554 "nemc", CGU_CLK_GATE, 555 .parents = { JZ4780_CLK_AHB2, -1, -1, -1 }, 556 .gate = { CGU_REG_CLKGR0, 0 }, 557 }, 558 559 [JZ4780_CLK_OTG0] = { 560 "otg0", CGU_CLK_GATE, 561 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 562 .gate = { CGU_REG_CLKGR0, 2 }, 563 }, 564 565 [JZ4780_CLK_SSI0] = { 566 "ssi0", CGU_CLK_GATE, 567 .parents = { JZ4780_CLK_SSI, -1, -1, -1 }, 568 .gate = { CGU_REG_CLKGR0, 4 }, 569 }, 570 571 [JZ4780_CLK_SMB0] = { 572 "smb0", CGU_CLK_GATE, 573 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, 574 .gate = { CGU_REG_CLKGR0, 5 }, 575 }, 576 577 [JZ4780_CLK_SMB1] = { 578 "smb1", CGU_CLK_GATE, 579 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, 580 .gate = { CGU_REG_CLKGR0, 6 }, 581 }, 582 583 [JZ4780_CLK_SCC] = { 584 "scc", CGU_CLK_GATE, 585 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 586 .gate = { CGU_REG_CLKGR0, 7 }, 587 }, 588 589 [JZ4780_CLK_AIC] = { 590 "aic", CGU_CLK_GATE, 591 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 592 .gate = { CGU_REG_CLKGR0, 8 }, 593 }, 594 595 [JZ4780_CLK_TSSI0] = { 596 "tssi0", CGU_CLK_GATE, 597 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 598 .gate = { CGU_REG_CLKGR0, 9 }, 599 }, 600 601 [JZ4780_CLK_OWI] = { 602 "owi", CGU_CLK_GATE, 603 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 604 .gate = { CGU_REG_CLKGR0, 10 }, 605 }, 606 607 [JZ4780_CLK_KBC] = { 608 "kbc", CGU_CLK_GATE, 609 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 610 .gate = { CGU_REG_CLKGR0, 13 }, 611 }, 612 613 [JZ4780_CLK_SADC] = { 614 "sadc", CGU_CLK_GATE, 615 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 616 .gate = { CGU_REG_CLKGR0, 14 }, 617 }, 618 619 [JZ4780_CLK_UART0] = { 620 "uart0", CGU_CLK_GATE, 621 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 622 .gate = { CGU_REG_CLKGR0, 15 }, 623 }, 624 625 [JZ4780_CLK_UART1] = { 626 "uart1", CGU_CLK_GATE, 627 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 628 .gate = { CGU_REG_CLKGR0, 16 }, 629 }, 630 631 [JZ4780_CLK_UART2] = { 632 "uart2", CGU_CLK_GATE, 633 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 634 .gate = { CGU_REG_CLKGR0, 17 }, 635 }, 636 637 [JZ4780_CLK_UART3] = { 638 "uart3", CGU_CLK_GATE, 639 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 640 .gate = { CGU_REG_CLKGR0, 18 }, 641 }, 642 643 [JZ4780_CLK_SSI1] = { 644 "ssi1", CGU_CLK_GATE, 645 .parents = { JZ4780_CLK_SSI, -1, -1, -1 }, 646 .gate = { CGU_REG_CLKGR0, 19 }, 647 }, 648 649 [JZ4780_CLK_SSI2] = { 650 "ssi2", CGU_CLK_GATE, 651 .parents = { JZ4780_CLK_SSI, -1, -1, -1 }, 652 .gate = { CGU_REG_CLKGR0, 20 }, 653 }, 654 655 [JZ4780_CLK_PDMA] = { 656 "pdma", CGU_CLK_GATE, 657 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 658 .gate = { CGU_REG_CLKGR0, 21 }, 659 }, 660 661 [JZ4780_CLK_GPS] = { 662 "gps", CGU_CLK_GATE, 663 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 664 .gate = { CGU_REG_CLKGR0, 22 }, 665 }, 666 667 [JZ4780_CLK_MAC] = { 668 "mac", CGU_CLK_GATE, 669 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 670 .gate = { CGU_REG_CLKGR0, 23 }, 671 }, 672 673 [JZ4780_CLK_SMB2] = { 674 "smb2", CGU_CLK_GATE, 675 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, 676 .gate = { CGU_REG_CLKGR0, 24 }, 677 }, 678 679 [JZ4780_CLK_CIM] = { 680 "cim", CGU_CLK_GATE, 681 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 682 .gate = { CGU_REG_CLKGR0, 26 }, 683 }, 684 685 [JZ4780_CLK_LCD] = { 686 "lcd", CGU_CLK_GATE, 687 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 688 .gate = { CGU_REG_CLKGR0, 28 }, 689 }, 690 691 [JZ4780_CLK_TVE] = { 692 "tve", CGU_CLK_GATE, 693 .parents = { JZ4780_CLK_LCD, -1, -1, -1 }, 694 .gate = { CGU_REG_CLKGR0, 27 }, 695 }, 696 697 [JZ4780_CLK_IPU] = { 698 "ipu", CGU_CLK_GATE, 699 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 700 .gate = { CGU_REG_CLKGR0, 29 }, 701 }, 702 703 [JZ4780_CLK_DDR0] = { 704 "ddr0", CGU_CLK_GATE, 705 .parents = { JZ4780_CLK_DDR, -1, -1, -1 }, 706 .gate = { CGU_REG_CLKGR0, 30 }, 707 }, 708 709 [JZ4780_CLK_DDR1] = { 710 "ddr1", CGU_CLK_GATE, 711 .parents = { JZ4780_CLK_DDR, -1, -1, -1 }, 712 .gate = { CGU_REG_CLKGR0, 31 }, 713 }, 714 715 [JZ4780_CLK_SMB3] = { 716 "smb3", CGU_CLK_GATE, 717 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, 718 .gate = { CGU_REG_CLKGR1, 0 }, 719 }, 720 721 [JZ4780_CLK_TSSI1] = { 722 "tssi1", CGU_CLK_GATE, 723 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 724 .gate = { CGU_REG_CLKGR1, 1 }, 725 }, 726 727 [JZ4780_CLK_COMPRESS] = { 728 "compress", CGU_CLK_GATE, 729 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 730 .gate = { CGU_REG_CLKGR1, 5 }, 731 }, 732 733 [JZ4780_CLK_AIC1] = { 734 "aic1", CGU_CLK_GATE, 735 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 736 .gate = { CGU_REG_CLKGR1, 6 }, 737 }, 738 739 [JZ4780_CLK_GPVLC] = { 740 "gpvlc", CGU_CLK_GATE, 741 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 742 .gate = { CGU_REG_CLKGR1, 7 }, 743 }, 744 745 [JZ4780_CLK_OTG1] = { 746 "otg1", CGU_CLK_GATE, 747 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 748 .gate = { CGU_REG_CLKGR1, 8 }, 749 }, 750 751 [JZ4780_CLK_UART4] = { 752 "uart4", CGU_CLK_GATE, 753 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 754 .gate = { CGU_REG_CLKGR1, 10 }, 755 }, 756 757 [JZ4780_CLK_AHBMON] = { 758 "ahb_mon", CGU_CLK_GATE, 759 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 760 .gate = { CGU_REG_CLKGR1, 11 }, 761 }, 762 763 [JZ4780_CLK_SMB4] = { 764 "smb4", CGU_CLK_GATE, 765 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, 766 .gate = { CGU_REG_CLKGR1, 12 }, 767 }, 768 769 [JZ4780_CLK_DES] = { 770 "des", CGU_CLK_GATE, 771 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 772 .gate = { CGU_REG_CLKGR1, 13 }, 773 }, 774 775 [JZ4780_CLK_X2D] = { 776 "x2d", CGU_CLK_GATE, 777 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, 778 .gate = { CGU_REG_CLKGR1, 14 }, 779 }, 780 781 [JZ4780_CLK_CORE1] = { 782 "core1", CGU_CLK_CUSTOM, 783 .parents = { JZ4780_CLK_CPU, -1, -1, -1 }, 784 .custom = { &jz4780_core1_ops }, 785 }, 786 787}; 788 789static void __init jz4780_cgu_init(struct device_node *np) 790{ 791 int retval; 792 793 cgu = ingenic_cgu_new(jz4780_cgu_clocks, 794 ARRAY_SIZE(jz4780_cgu_clocks), np); 795 if (!cgu) { 796 pr_err("%s: failed to initialise CGU\n", __func__); 797 return; 798 } 799 800 retval = ingenic_cgu_register_clocks(cgu); 801 if (retval) { 802 pr_err("%s: failed to register CGU Clocks\n", __func__); 803 return; 804 } 805 806 ingenic_cgu_register_syscore_ops(cgu); 807} 808CLK_OF_DECLARE_DRIVER(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init);