1 /* 2 * IMX6UL Clock Control Module 3 * 4 * Copyright (c) 2018 Jean-Christophe Dubois <jcd@tribudubois.net> 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 or later. 7 * See the COPYING file in the top-level directory. 8 * 9 * To get the timer frequencies right, we need to emulate at least part of 10 * the CCM. 11 */ 12 13 #include "qemu/osdep.h" 14 #include "hw/registerfields.h" 15 #include "migration/vmstate.h" 16 #include "hw/misc/imx6ul_ccm.h" 17 #include "qemu/log.h" 18 #include "qemu/module.h" 19 20 #include "trace.h" 21 22 static const uint32_t ccm_mask[CCM_MAX] = { 23 [CCM_CCR] = 0xf01fef80, 24 [CCM_CCDR] = 0xfffeffff, 25 [CCM_CSR] = 0xffffffff, 26 [CCM_CCSR] = 0xfffffef2, 27 [CCM_CACRR] = 0xfffffff8, 28 [CCM_CBCDR] = 0xc1f8e000, 29 [CCM_CBCMR] = 0xfc03cfff, 30 [CCM_CSCMR1] = 0x80700000, 31 [CCM_CSCMR2] = 0xe01ff003, 32 [CCM_CSCDR1] = 0xfe00c780, 33 [CCM_CS1CDR] = 0xfe00fe00, 34 [CCM_CS2CDR] = 0xf8007000, 35 [CCM_CDCDR] = 0xf00fffff, 36 [CCM_CHSCCDR] = 0xfffc01ff, 37 [CCM_CSCDR2] = 0xfe0001ff, 38 [CCM_CSCDR3] = 0xffffc1ff, 39 [CCM_CDHIPR] = 0xffffffff, 40 [CCM_CTOR] = 0x00000000, 41 [CCM_CLPCR] = 0xf39ff01c, 42 [CCM_CISR] = 0xfb85ffbe, 43 [CCM_CIMR] = 0xfb85ffbf, 44 [CCM_CCOSR] = 0xfe00fe00, 45 [CCM_CGPR] = 0xfffc3fea, 46 [CCM_CCGR0] = 0x00000000, 47 [CCM_CCGR1] = 0x00000000, 48 [CCM_CCGR2] = 0x00000000, 49 [CCM_CCGR3] = 0x00000000, 50 [CCM_CCGR4] = 0x00000000, 51 [CCM_CCGR5] = 0x00000000, 52 [CCM_CCGR6] = 0x00000000, 53 [CCM_CMEOR] = 0xafffff1f, 54 }; 55 56 static const uint32_t analog_mask[CCM_ANALOG_MAX] = { 57 [CCM_ANALOG_PLL_ARM] = 0xfff60f80, 58 [CCM_ANALOG_PLL_USB1] = 0xfffe0fbc, 59 [CCM_ANALOG_PLL_USB2] = 0xfffe0fbc, 60 [CCM_ANALOG_PLL_SYS] = 0xfffa0ffe, 61 [CCM_ANALOG_PLL_SYS_SS] = 0x00000000, 62 [CCM_ANALOG_PLL_SYS_NUM] = 0xc0000000, 63 [CCM_ANALOG_PLL_SYS_DENOM] = 0xc0000000, 64 [CCM_ANALOG_PLL_AUDIO] = 0xffe20f80, 65 [CCM_ANALOG_PLL_AUDIO_NUM] = 0xc0000000, 66 [CCM_ANALOG_PLL_AUDIO_DENOM] = 0xc0000000, 67 [CCM_ANALOG_PLL_VIDEO] = 0xffe20f80, 68 [CCM_ANALOG_PLL_VIDEO_NUM] = 0xc0000000, 69 [CCM_ANALOG_PLL_VIDEO_DENOM] = 0xc0000000, 70 [CCM_ANALOG_PLL_ENET] = 0xffc20ff0, 71 [CCM_ANALOG_PFD_480] = 0x40404040, 72 [CCM_ANALOG_PFD_528] = 0x40404040, 73 [PMU_MISC0] = 0x01fe8306, 74 [PMU_MISC1] = 0x07fcede0, 75 [PMU_MISC2] = 0x005f5f5f, 76 }; 77 78 static const char *imx6ul_ccm_reg_name(uint32_t reg) 79 { 80 static char unknown[20]; 81 82 switch (reg) { 83 case CCM_CCR: 84 return "CCR"; 85 case CCM_CCDR: 86 return "CCDR"; 87 case CCM_CSR: 88 return "CSR"; 89 case CCM_CCSR: 90 return "CCSR"; 91 case CCM_CACRR: 92 return "CACRR"; 93 case CCM_CBCDR: 94 return "CBCDR"; 95 case CCM_CBCMR: 96 return "CBCMR"; 97 case CCM_CSCMR1: 98 return "CSCMR1"; 99 case CCM_CSCMR2: 100 return "CSCMR2"; 101 case CCM_CSCDR1: 102 return "CSCDR1"; 103 case CCM_CS1CDR: 104 return "CS1CDR"; 105 case CCM_CS2CDR: 106 return "CS2CDR"; 107 case CCM_CDCDR: 108 return "CDCDR"; 109 case CCM_CHSCCDR: 110 return "CHSCCDR"; 111 case CCM_CSCDR2: 112 return "CSCDR2"; 113 case CCM_CSCDR3: 114 return "CSCDR3"; 115 case CCM_CDHIPR: 116 return "CDHIPR"; 117 case CCM_CTOR: 118 return "CTOR"; 119 case CCM_CLPCR: 120 return "CLPCR"; 121 case CCM_CISR: 122 return "CISR"; 123 case CCM_CIMR: 124 return "CIMR"; 125 case CCM_CCOSR: 126 return "CCOSR"; 127 case CCM_CGPR: 128 return "CGPR"; 129 case CCM_CCGR0: 130 return "CCGR0"; 131 case CCM_CCGR1: 132 return "CCGR1"; 133 case CCM_CCGR2: 134 return "CCGR2"; 135 case CCM_CCGR3: 136 return "CCGR3"; 137 case CCM_CCGR4: 138 return "CCGR4"; 139 case CCM_CCGR5: 140 return "CCGR5"; 141 case CCM_CCGR6: 142 return "CCGR6"; 143 case CCM_CMEOR: 144 return "CMEOR"; 145 default: 146 sprintf(unknown, "%u ?", reg); 147 return unknown; 148 } 149 } 150 151 static const char *imx6ul_analog_reg_name(uint32_t reg) 152 { 153 static char unknown[20]; 154 155 switch (reg) { 156 case CCM_ANALOG_PLL_ARM: 157 return "PLL_ARM"; 158 case CCM_ANALOG_PLL_ARM_SET: 159 return "PLL_ARM_SET"; 160 case CCM_ANALOG_PLL_ARM_CLR: 161 return "PLL_ARM_CLR"; 162 case CCM_ANALOG_PLL_ARM_TOG: 163 return "PLL_ARM_TOG"; 164 case CCM_ANALOG_PLL_USB1: 165 return "PLL_USB1"; 166 case CCM_ANALOG_PLL_USB1_SET: 167 return "PLL_USB1_SET"; 168 case CCM_ANALOG_PLL_USB1_CLR: 169 return "PLL_USB1_CLR"; 170 case CCM_ANALOG_PLL_USB1_TOG: 171 return "PLL_USB1_TOG"; 172 case CCM_ANALOG_PLL_USB2: 173 return "PLL_USB2"; 174 case CCM_ANALOG_PLL_USB2_SET: 175 return "PLL_USB2_SET"; 176 case CCM_ANALOG_PLL_USB2_CLR: 177 return "PLL_USB2_CLR"; 178 case CCM_ANALOG_PLL_USB2_TOG: 179 return "PLL_USB2_TOG"; 180 case CCM_ANALOG_PLL_SYS: 181 return "PLL_SYS"; 182 case CCM_ANALOG_PLL_SYS_SET: 183 return "PLL_SYS_SET"; 184 case CCM_ANALOG_PLL_SYS_CLR: 185 return "PLL_SYS_CLR"; 186 case CCM_ANALOG_PLL_SYS_TOG: 187 return "PLL_SYS_TOG"; 188 case CCM_ANALOG_PLL_SYS_SS: 189 return "PLL_SYS_SS"; 190 case CCM_ANALOG_PLL_SYS_NUM: 191 return "PLL_SYS_NUM"; 192 case CCM_ANALOG_PLL_SYS_DENOM: 193 return "PLL_SYS_DENOM"; 194 case CCM_ANALOG_PLL_AUDIO: 195 return "PLL_AUDIO"; 196 case CCM_ANALOG_PLL_AUDIO_SET: 197 return "PLL_AUDIO_SET"; 198 case CCM_ANALOG_PLL_AUDIO_CLR: 199 return "PLL_AUDIO_CLR"; 200 case CCM_ANALOG_PLL_AUDIO_TOG: 201 return "PLL_AUDIO_TOG"; 202 case CCM_ANALOG_PLL_AUDIO_NUM: 203 return "PLL_AUDIO_NUM"; 204 case CCM_ANALOG_PLL_AUDIO_DENOM: 205 return "PLL_AUDIO_DENOM"; 206 case CCM_ANALOG_PLL_VIDEO: 207 return "PLL_VIDEO"; 208 case CCM_ANALOG_PLL_VIDEO_SET: 209 return "PLL_VIDEO_SET"; 210 case CCM_ANALOG_PLL_VIDEO_CLR: 211 return "PLL_VIDEO_CLR"; 212 case CCM_ANALOG_PLL_VIDEO_TOG: 213 return "PLL_VIDEO_TOG"; 214 case CCM_ANALOG_PLL_VIDEO_NUM: 215 return "PLL_VIDEO_NUM"; 216 case CCM_ANALOG_PLL_VIDEO_DENOM: 217 return "PLL_VIDEO_DENOM"; 218 case CCM_ANALOG_PLL_ENET: 219 return "PLL_ENET"; 220 case CCM_ANALOG_PLL_ENET_SET: 221 return "PLL_ENET_SET"; 222 case CCM_ANALOG_PLL_ENET_CLR: 223 return "PLL_ENET_CLR"; 224 case CCM_ANALOG_PLL_ENET_TOG: 225 return "PLL_ENET_TOG"; 226 case CCM_ANALOG_PFD_480: 227 return "PFD_480"; 228 case CCM_ANALOG_PFD_480_SET: 229 return "PFD_480_SET"; 230 case CCM_ANALOG_PFD_480_CLR: 231 return "PFD_480_CLR"; 232 case CCM_ANALOG_PFD_480_TOG: 233 return "PFD_480_TOG"; 234 case CCM_ANALOG_PFD_528: 235 return "PFD_528"; 236 case CCM_ANALOG_PFD_528_SET: 237 return "PFD_528_SET"; 238 case CCM_ANALOG_PFD_528_CLR: 239 return "PFD_528_CLR"; 240 case CCM_ANALOG_PFD_528_TOG: 241 return "PFD_528_TOG"; 242 case CCM_ANALOG_MISC0: 243 return "MISC0"; 244 case CCM_ANALOG_MISC0_SET: 245 return "MISC0_SET"; 246 case CCM_ANALOG_MISC0_CLR: 247 return "MISC0_CLR"; 248 case CCM_ANALOG_MISC0_TOG: 249 return "MISC0_TOG"; 250 case CCM_ANALOG_MISC2: 251 return "MISC2"; 252 case CCM_ANALOG_MISC2_SET: 253 return "MISC2_SET"; 254 case CCM_ANALOG_MISC2_CLR: 255 return "MISC2_CLR"; 256 case CCM_ANALOG_MISC2_TOG: 257 return "MISC2_TOG"; 258 case PMU_REG_1P1: 259 return "PMU_REG_1P1"; 260 case PMU_REG_3P0: 261 return "PMU_REG_3P0"; 262 case PMU_REG_2P5: 263 return "PMU_REG_2P5"; 264 case PMU_REG_CORE: 265 return "PMU_REG_CORE"; 266 case PMU_MISC1: 267 return "PMU_MISC1"; 268 case PMU_MISC1_SET: 269 return "PMU_MISC1_SET"; 270 case PMU_MISC1_CLR: 271 return "PMU_MISC1_CLR"; 272 case PMU_MISC1_TOG: 273 return "PMU_MISC1_TOG"; 274 case USB_ANALOG_DIGPROG: 275 return "USB_ANALOG_DIGPROG"; 276 default: 277 sprintf(unknown, "%u ?", reg); 278 return unknown; 279 } 280 } 281 282 #define CKIH_FREQ 24000000 /* 24MHz crystal input */ 283 284 static const VMStateDescription vmstate_imx6ul_ccm = { 285 .name = TYPE_IMX6UL_CCM, 286 .version_id = 1, 287 .minimum_version_id = 1, 288 .fields = (const VMStateField[]) { 289 VMSTATE_UINT32_ARRAY(ccm, IMX6ULCCMState, CCM_MAX), 290 VMSTATE_UINT32_ARRAY(analog, IMX6ULCCMState, CCM_ANALOG_MAX), 291 VMSTATE_END_OF_LIST() 292 }, 293 }; 294 295 static uint64_t imx6ul_analog_get_osc_clk(IMX6ULCCMState *dev) 296 { 297 uint64_t freq = CKIH_FREQ; 298 299 trace_ccm_freq((uint32_t)freq); 300 301 return freq; 302 } 303 304 static uint64_t imx6ul_analog_get_pll2_clk(IMX6ULCCMState *dev) 305 { 306 uint64_t freq = imx6ul_analog_get_osc_clk(dev); 307 308 if (FIELD_EX32(dev->analog[CCM_ANALOG_PLL_SYS], 309 ANALOG_PLL_SYS, DIV_SELECT)) { 310 freq *= 22; 311 } else { 312 freq *= 20; 313 } 314 315 trace_ccm_freq((uint32_t)freq); 316 317 return freq; 318 } 319 320 static uint64_t imx6ul_analog_get_pll3_clk(IMX6ULCCMState *dev) 321 { 322 uint64_t freq = imx6ul_analog_get_osc_clk(dev) * 20; 323 324 trace_ccm_freq((uint32_t)freq); 325 326 return freq; 327 } 328 329 static uint64_t imx6ul_analog_get_pll2_pfd0_clk(IMX6ULCCMState *dev) 330 { 331 uint64_t freq = 0; 332 333 freq = imx6ul_analog_get_pll2_clk(dev) * 18 334 / FIELD_EX32(dev->analog[CCM_ANALOG_PFD_528], 335 ANALOG_PFD_528, PFD0_FRAC); 336 337 trace_ccm_freq((uint32_t)freq); 338 339 return freq; 340 } 341 342 static uint64_t imx6ul_analog_get_pll2_pfd2_clk(IMX6ULCCMState *dev) 343 { 344 uint64_t freq = 0; 345 346 freq = imx6ul_analog_get_pll2_clk(dev) * 18 347 / FIELD_EX32(dev->analog[CCM_ANALOG_PFD_528], 348 ANALOG_PFD_528, PFD2_FRAC); 349 350 trace_ccm_freq((uint32_t)freq); 351 352 return freq; 353 } 354 355 static uint64_t imx6ul_analog_pll2_bypass_clk(IMX6ULCCMState *dev) 356 { 357 uint64_t freq = 0; 358 359 trace_ccm_freq((uint32_t)freq); 360 361 return freq; 362 } 363 364 static uint64_t imx6ul_ccm_get_periph_clk2_sel_clk(IMX6ULCCMState *dev) 365 { 366 uint64_t freq = 0; 367 368 switch (FIELD_EX32(dev->ccm[CCM_CBCMR], CBCMR, PERIPH_CLK2_SEL)) { 369 case 0: 370 freq = imx6ul_analog_get_pll3_clk(dev); 371 break; 372 case 1: 373 freq = imx6ul_analog_get_osc_clk(dev); 374 break; 375 case 2: 376 freq = imx6ul_analog_pll2_bypass_clk(dev); 377 break; 378 case 3: 379 /* We should never get there as 3 is a reserved value */ 380 qemu_log_mask(LOG_GUEST_ERROR, 381 "[%s]%s: unsupported PERIPH_CLK2_SEL value 3\n", 382 TYPE_IMX6UL_CCM, __func__); 383 /* freq is set to 0 as we don't know what it should be */ 384 break; 385 default: 386 g_assert_not_reached(); 387 } 388 389 trace_ccm_freq((uint32_t)freq); 390 391 return freq; 392 } 393 394 static uint64_t imx6ul_ccm_get_periph_clk_sel_clk(IMX6ULCCMState *dev) 395 { 396 uint64_t freq = 0; 397 398 switch (FIELD_EX32(dev->ccm[CCM_CBCMR], CBCMR, PRE_PERIPH_CLK_SEL)) { 399 case 0: 400 freq = imx6ul_analog_get_pll2_clk(dev); 401 break; 402 case 1: 403 freq = imx6ul_analog_get_pll2_pfd2_clk(dev); 404 break; 405 case 2: 406 freq = imx6ul_analog_get_pll2_pfd0_clk(dev); 407 break; 408 case 3: 409 freq = imx6ul_analog_get_pll2_pfd2_clk(dev) / 2; 410 break; 411 default: 412 g_assert_not_reached(); 413 } 414 415 trace_ccm_freq((uint32_t)freq); 416 417 return freq; 418 } 419 420 static uint64_t imx6ul_ccm_get_periph_clk2_clk(IMX6ULCCMState *dev) 421 { 422 uint64_t freq = 0; 423 424 freq = imx6ul_ccm_get_periph_clk2_sel_clk(dev) 425 / (1 + FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, PERIPH_CLK2_PODF)); 426 427 trace_ccm_freq((uint32_t)freq); 428 429 return freq; 430 } 431 432 static uint64_t imx6ul_ccm_get_periph_sel_clk(IMX6ULCCMState *dev) 433 { 434 uint64_t freq = 0; 435 436 switch (FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, PERIPH_CLK_SEL)) { 437 case 0: 438 freq = imx6ul_ccm_get_periph_clk_sel_clk(dev); 439 break; 440 case 1: 441 freq = imx6ul_ccm_get_periph_clk2_clk(dev); 442 break; 443 default: 444 g_assert_not_reached(); 445 } 446 447 trace_ccm_freq((uint32_t)freq); 448 449 return freq; 450 } 451 452 static uint64_t imx6ul_ccm_get_ahb_clk(IMX6ULCCMState *dev) 453 { 454 uint64_t freq = 0; 455 456 freq = imx6ul_ccm_get_periph_sel_clk(dev) 457 / (1 + FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, AHB_PODF)); 458 459 trace_ccm_freq((uint32_t)freq); 460 461 return freq; 462 } 463 464 static uint64_t imx6ul_ccm_get_ipg_clk(IMX6ULCCMState *dev) 465 { 466 uint64_t freq = 0; 467 468 freq = imx6ul_ccm_get_ahb_clk(dev) 469 / (1 + FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, IPG_PODF)); 470 471 trace_ccm_freq((uint32_t)freq); 472 473 return freq; 474 } 475 476 static uint64_t imx6ul_ccm_get_per_sel_clk(IMX6ULCCMState *dev) 477 { 478 uint64_t freq = 0; 479 480 switch (FIELD_EX32(dev->ccm[CCM_CSCMR1], CSCMR1, PERCLK_CLK_SEL)) { 481 case 0: 482 freq = imx6ul_ccm_get_ipg_clk(dev); 483 break; 484 case 1: 485 freq = imx6ul_analog_get_osc_clk(dev); 486 break; 487 default: 488 g_assert_not_reached(); 489 } 490 491 trace_ccm_freq((uint32_t)freq); 492 493 return freq; 494 } 495 496 static uint64_t imx6ul_ccm_get_per_clk(IMX6ULCCMState *dev) 497 { 498 uint64_t freq = 0; 499 500 freq = imx6ul_ccm_get_per_sel_clk(dev) 501 / (1 + FIELD_EX32(dev->ccm[CCM_CSCMR1], CSCMR1, PERCLK_PODF)); 502 503 trace_ccm_freq((uint32_t)freq); 504 505 return freq; 506 } 507 508 static uint32_t imx6ul_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock) 509 { 510 uint32_t freq = 0; 511 IMX6ULCCMState *s = IMX6UL_CCM(dev); 512 513 switch (clock) { 514 case CLK_NONE: 515 break; 516 case CLK_IPG: 517 freq = imx6ul_ccm_get_ipg_clk(s); 518 break; 519 case CLK_IPG_HIGH: 520 freq = imx6ul_ccm_get_per_clk(s); 521 break; 522 case CLK_32k: 523 freq = CKIL_FREQ; 524 break; 525 default: 526 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n", 527 TYPE_IMX6UL_CCM, __func__, clock); 528 break; 529 } 530 531 trace_ccm_clock_freq(clock, freq); 532 533 return freq; 534 } 535 536 static void imx6ul_ccm_reset(DeviceState *dev) 537 { 538 IMX6ULCCMState *s = IMX6UL_CCM(dev); 539 540 trace_ccm_entry(); 541 542 s->ccm[CCM_CCR] = 0x0401167F; 543 s->ccm[CCM_CCDR] = 0x00000000; 544 s->ccm[CCM_CSR] = 0x00000010; 545 s->ccm[CCM_CCSR] = 0x00000100; 546 s->ccm[CCM_CACRR] = 0x00000000; 547 s->ccm[CCM_CBCDR] = 0x00018D00; 548 s->ccm[CCM_CBCMR] = 0x24860324; 549 s->ccm[CCM_CSCMR1] = 0x04900080; 550 s->ccm[CCM_CSCMR2] = 0x03192F06; 551 s->ccm[CCM_CSCDR1] = 0x00490B00; 552 s->ccm[CCM_CS1CDR] = 0x0EC102C1; 553 s->ccm[CCM_CS2CDR] = 0x000336C1; 554 s->ccm[CCM_CDCDR] = 0x33F71F92; 555 s->ccm[CCM_CHSCCDR] = 0x000248A4; 556 s->ccm[CCM_CSCDR2] = 0x00029B48; 557 s->ccm[CCM_CSCDR3] = 0x00014841; 558 s->ccm[CCM_CDHIPR] = 0x00000000; 559 s->ccm[CCM_CTOR] = 0x00000000; 560 s->ccm[CCM_CLPCR] = 0x00000079; 561 s->ccm[CCM_CISR] = 0x00000000; 562 s->ccm[CCM_CIMR] = 0xFFFFFFFF; 563 s->ccm[CCM_CCOSR] = 0x000A0001; 564 s->ccm[CCM_CGPR] = 0x0000FE62; 565 s->ccm[CCM_CCGR0] = 0xFFFFFFFF; 566 s->ccm[CCM_CCGR1] = 0xFFFFFFFF; 567 s->ccm[CCM_CCGR2] = 0xFC3FFFFF; 568 s->ccm[CCM_CCGR3] = 0xFFFFFFFF; 569 s->ccm[CCM_CCGR4] = 0xFFFFFFFF; 570 s->ccm[CCM_CCGR5] = 0xFFFFFFFF; 571 s->ccm[CCM_CCGR6] = 0xFFFFFFFF; 572 s->ccm[CCM_CMEOR] = 0xFFFFFFFF; 573 574 s->analog[CCM_ANALOG_PLL_ARM] = 0x00013063; 575 s->analog[CCM_ANALOG_PLL_USB1] = 0x00012000; 576 s->analog[CCM_ANALOG_PLL_USB2] = 0x00012000; 577 s->analog[CCM_ANALOG_PLL_SYS] = 0x00013001; 578 s->analog[CCM_ANALOG_PLL_SYS_SS] = 0x00000000; 579 s->analog[CCM_ANALOG_PLL_SYS_NUM] = 0x00000000; 580 s->analog[CCM_ANALOG_PLL_SYS_DENOM] = 0x00000012; 581 s->analog[CCM_ANALOG_PLL_AUDIO] = 0x00011006; 582 s->analog[CCM_ANALOG_PLL_AUDIO_NUM] = 0x05F5E100; 583 s->analog[CCM_ANALOG_PLL_AUDIO_DENOM] = 0x2964619C; 584 s->analog[CCM_ANALOG_PLL_VIDEO] = 0x0001100C; 585 s->analog[CCM_ANALOG_PLL_VIDEO_NUM] = 0x05F5E100; 586 s->analog[CCM_ANALOG_PLL_VIDEO_DENOM] = 0x10A24447; 587 s->analog[CCM_ANALOG_PLL_ENET] = 0x00011001; 588 s->analog[CCM_ANALOG_PFD_480] = 0x1311100C; 589 s->analog[CCM_ANALOG_PFD_528] = 0x1018101B; 590 591 s->analog[PMU_REG_1P1] = 0x00001073; 592 s->analog[PMU_REG_3P0] = 0x00000F74; 593 s->analog[PMU_REG_2P5] = 0x00001073; 594 s->analog[PMU_REG_CORE] = 0x00482012; 595 s->analog[PMU_MISC0] = 0x04000000; 596 s->analog[PMU_MISC1] = 0x00000000; 597 s->analog[PMU_MISC2] = 0x00272727; 598 s->analog[PMU_LOWPWR_CTRL] = 0x00004009; 599 600 s->analog[USB_ANALOG_USB1_VBUS_DETECT] = 0x01000004; 601 s->analog[USB_ANALOG_USB1_CHRG_DETECT] = 0x00000000; 602 s->analog[USB_ANALOG_USB1_VBUS_DETECT_STAT] = 0x00000000; 603 s->analog[USB_ANALOG_USB1_CHRG_DETECT_STAT] = 0x00000000; 604 s->analog[USB_ANALOG_USB1_MISC] = 0x00000002; 605 s->analog[USB_ANALOG_USB2_VBUS_DETECT] = 0x01000004; 606 s->analog[USB_ANALOG_USB2_CHRG_DETECT] = 0x00000000; 607 s->analog[USB_ANALOG_USB2_MISC] = 0x00000002; 608 s->analog[USB_ANALOG_DIGPROG] = 0x00640000; 609 610 /* all PLLs need to be locked */ 611 s->analog[CCM_ANALOG_PLL_ARM] |= CCM_ANALOG_PLL_LOCK; 612 s->analog[CCM_ANALOG_PLL_USB1] |= CCM_ANALOG_PLL_LOCK; 613 s->analog[CCM_ANALOG_PLL_USB2] |= CCM_ANALOG_PLL_LOCK; 614 s->analog[CCM_ANALOG_PLL_SYS] |= CCM_ANALOG_PLL_LOCK; 615 s->analog[CCM_ANALOG_PLL_AUDIO] |= CCM_ANALOG_PLL_LOCK; 616 s->analog[CCM_ANALOG_PLL_VIDEO] |= CCM_ANALOG_PLL_LOCK; 617 s->analog[CCM_ANALOG_PLL_ENET] |= CCM_ANALOG_PLL_LOCK; 618 619 s->analog[TEMPMON_TEMPSENSE0] = 0x00000001; 620 s->analog[TEMPMON_TEMPSENSE1] = 0x00000001; 621 s->analog[TEMPMON_TEMPSENSE2] = 0x00000000; 622 } 623 624 static uint64_t imx6ul_ccm_read(void *opaque, hwaddr offset, unsigned size) 625 { 626 uint32_t value = 0; 627 uint32_t index = offset >> 2; 628 IMX6ULCCMState *s = (IMX6ULCCMState *)opaque; 629 630 assert(index < CCM_MAX); 631 632 value = s->ccm[index]; 633 634 trace_ccm_read_reg(imx6ul_ccm_reg_name(index), (uint32_t)value); 635 636 return (uint64_t)value; 637 } 638 639 static void imx6ul_ccm_write(void *opaque, hwaddr offset, uint64_t value, 640 unsigned size) 641 { 642 uint32_t index = offset >> 2; 643 IMX6ULCCMState *s = (IMX6ULCCMState *)opaque; 644 645 assert(index < CCM_MAX); 646 647 trace_ccm_write_reg(imx6ul_ccm_reg_name(index), (uint32_t)value); 648 649 s->ccm[index] = (s->ccm[index] & ccm_mask[index]) | 650 ((uint32_t)value & ~ccm_mask[index]); 651 } 652 653 static uint64_t imx6ul_analog_read(void *opaque, hwaddr offset, unsigned size) 654 { 655 uint32_t value; 656 uint32_t index = offset >> 2; 657 IMX6ULCCMState *s = (IMX6ULCCMState *)opaque; 658 659 assert(index < CCM_ANALOG_MAX); 660 661 switch (index) { 662 case CCM_ANALOG_PLL_ARM_SET: 663 case CCM_ANALOG_PLL_USB1_SET: 664 case CCM_ANALOG_PLL_USB2_SET: 665 case CCM_ANALOG_PLL_SYS_SET: 666 case CCM_ANALOG_PLL_AUDIO_SET: 667 case CCM_ANALOG_PLL_VIDEO_SET: 668 case CCM_ANALOG_PLL_ENET_SET: 669 case CCM_ANALOG_PFD_480_SET: 670 case CCM_ANALOG_PFD_528_SET: 671 case CCM_ANALOG_MISC0_SET: 672 case PMU_MISC1_SET: 673 case CCM_ANALOG_MISC2_SET: 674 case USB_ANALOG_USB1_VBUS_DETECT_SET: 675 case USB_ANALOG_USB1_CHRG_DETECT_SET: 676 case USB_ANALOG_USB1_MISC_SET: 677 case USB_ANALOG_USB2_VBUS_DETECT_SET: 678 case USB_ANALOG_USB2_CHRG_DETECT_SET: 679 case USB_ANALOG_USB2_MISC_SET: 680 case TEMPMON_TEMPSENSE0_SET: 681 case TEMPMON_TEMPSENSE1_SET: 682 case TEMPMON_TEMPSENSE2_SET: 683 /* 684 * All REG_NAME_SET register access are in fact targeting 685 * the REG_NAME register. 686 */ 687 value = s->analog[index - 1]; 688 break; 689 case CCM_ANALOG_PLL_ARM_CLR: 690 case CCM_ANALOG_PLL_USB1_CLR: 691 case CCM_ANALOG_PLL_USB2_CLR: 692 case CCM_ANALOG_PLL_SYS_CLR: 693 case CCM_ANALOG_PLL_AUDIO_CLR: 694 case CCM_ANALOG_PLL_VIDEO_CLR: 695 case CCM_ANALOG_PLL_ENET_CLR: 696 case CCM_ANALOG_PFD_480_CLR: 697 case CCM_ANALOG_PFD_528_CLR: 698 case CCM_ANALOG_MISC0_CLR: 699 case PMU_MISC1_CLR: 700 case CCM_ANALOG_MISC2_CLR: 701 case USB_ANALOG_USB1_VBUS_DETECT_CLR: 702 case USB_ANALOG_USB1_CHRG_DETECT_CLR: 703 case USB_ANALOG_USB1_MISC_CLR: 704 case USB_ANALOG_USB2_VBUS_DETECT_CLR: 705 case USB_ANALOG_USB2_CHRG_DETECT_CLR: 706 case USB_ANALOG_USB2_MISC_CLR: 707 case TEMPMON_TEMPSENSE0_CLR: 708 case TEMPMON_TEMPSENSE1_CLR: 709 case TEMPMON_TEMPSENSE2_CLR: 710 /* 711 * All REG_NAME_CLR register access are in fact targeting 712 * the REG_NAME register. 713 */ 714 value = s->analog[index - 2]; 715 break; 716 case CCM_ANALOG_PLL_ARM_TOG: 717 case CCM_ANALOG_PLL_USB1_TOG: 718 case CCM_ANALOG_PLL_USB2_TOG: 719 case CCM_ANALOG_PLL_SYS_TOG: 720 case CCM_ANALOG_PLL_AUDIO_TOG: 721 case CCM_ANALOG_PLL_VIDEO_TOG: 722 case CCM_ANALOG_PLL_ENET_TOG: 723 case CCM_ANALOG_PFD_480_TOG: 724 case CCM_ANALOG_PFD_528_TOG: 725 case CCM_ANALOG_MISC0_TOG: 726 case PMU_MISC1_TOG: 727 case CCM_ANALOG_MISC2_TOG: 728 case USB_ANALOG_USB1_VBUS_DETECT_TOG: 729 case USB_ANALOG_USB1_CHRG_DETECT_TOG: 730 case USB_ANALOG_USB1_MISC_TOG: 731 case USB_ANALOG_USB2_VBUS_DETECT_TOG: 732 case USB_ANALOG_USB2_CHRG_DETECT_TOG: 733 case USB_ANALOG_USB2_MISC_TOG: 734 case TEMPMON_TEMPSENSE0_TOG: 735 case TEMPMON_TEMPSENSE1_TOG: 736 case TEMPMON_TEMPSENSE2_TOG: 737 /* 738 * All REG_NAME_TOG register access are in fact targeting 739 * the REG_NAME register. 740 */ 741 value = s->analog[index - 3]; 742 break; 743 default: 744 value = s->analog[index]; 745 break; 746 } 747 748 trace_ccm_read_reg(imx6ul_analog_reg_name(index), (uint32_t)value); 749 750 return (uint64_t)value; 751 } 752 753 static void imx6ul_analog_write(void *opaque, hwaddr offset, uint64_t value, 754 unsigned size) 755 { 756 uint32_t index = offset >> 2; 757 IMX6ULCCMState *s = (IMX6ULCCMState *)opaque; 758 759 assert(index < CCM_ANALOG_MAX); 760 761 trace_ccm_write_reg(imx6ul_analog_reg_name(index), (uint32_t)value); 762 763 switch (index) { 764 case CCM_ANALOG_PLL_ARM_SET: 765 case CCM_ANALOG_PLL_USB1_SET: 766 case CCM_ANALOG_PLL_USB2_SET: 767 case CCM_ANALOG_PLL_SYS_SET: 768 case CCM_ANALOG_PLL_AUDIO_SET: 769 case CCM_ANALOG_PLL_VIDEO_SET: 770 case CCM_ANALOG_PLL_ENET_SET: 771 case CCM_ANALOG_PFD_480_SET: 772 case CCM_ANALOG_PFD_528_SET: 773 case CCM_ANALOG_MISC0_SET: 774 case PMU_MISC1_SET: 775 case CCM_ANALOG_MISC2_SET: 776 case USB_ANALOG_USB1_VBUS_DETECT_SET: 777 case USB_ANALOG_USB1_CHRG_DETECT_SET: 778 case USB_ANALOG_USB1_MISC_SET: 779 case USB_ANALOG_USB2_VBUS_DETECT_SET: 780 case USB_ANALOG_USB2_CHRG_DETECT_SET: 781 case USB_ANALOG_USB2_MISC_SET: 782 /* 783 * All REG_NAME_SET register access are in fact targeting 784 * the REG_NAME register. So we change the value of the 785 * REG_NAME register, setting bits passed in the value. 786 */ 787 s->analog[index - 1] |= (value & ~analog_mask[index - 1]); 788 break; 789 case CCM_ANALOG_PLL_ARM_CLR: 790 case CCM_ANALOG_PLL_USB1_CLR: 791 case CCM_ANALOG_PLL_USB2_CLR: 792 case CCM_ANALOG_PLL_SYS_CLR: 793 case CCM_ANALOG_PLL_AUDIO_CLR: 794 case CCM_ANALOG_PLL_VIDEO_CLR: 795 case CCM_ANALOG_PLL_ENET_CLR: 796 case CCM_ANALOG_PFD_480_CLR: 797 case CCM_ANALOG_PFD_528_CLR: 798 case CCM_ANALOG_MISC0_CLR: 799 case PMU_MISC1_CLR: 800 case CCM_ANALOG_MISC2_CLR: 801 case USB_ANALOG_USB1_VBUS_DETECT_CLR: 802 case USB_ANALOG_USB1_CHRG_DETECT_CLR: 803 case USB_ANALOG_USB1_MISC_CLR: 804 case USB_ANALOG_USB2_VBUS_DETECT_CLR: 805 case USB_ANALOG_USB2_CHRG_DETECT_CLR: 806 case USB_ANALOG_USB2_MISC_CLR: 807 /* 808 * All REG_NAME_CLR register access are in fact targeting 809 * the REG_NAME register. So we change the value of the 810 * REG_NAME register, unsetting bits passed in the value. 811 */ 812 s->analog[index - 2] &= ~(value & ~analog_mask[index - 2]); 813 break; 814 case CCM_ANALOG_PLL_ARM_TOG: 815 case CCM_ANALOG_PLL_USB1_TOG: 816 case CCM_ANALOG_PLL_USB2_TOG: 817 case CCM_ANALOG_PLL_SYS_TOG: 818 case CCM_ANALOG_PLL_AUDIO_TOG: 819 case CCM_ANALOG_PLL_VIDEO_TOG: 820 case CCM_ANALOG_PLL_ENET_TOG: 821 case CCM_ANALOG_PFD_480_TOG: 822 case CCM_ANALOG_PFD_528_TOG: 823 case CCM_ANALOG_MISC0_TOG: 824 case PMU_MISC1_TOG: 825 case CCM_ANALOG_MISC2_TOG: 826 case USB_ANALOG_USB1_VBUS_DETECT_TOG: 827 case USB_ANALOG_USB1_CHRG_DETECT_TOG: 828 case USB_ANALOG_USB1_MISC_TOG: 829 case USB_ANALOG_USB2_VBUS_DETECT_TOG: 830 case USB_ANALOG_USB2_CHRG_DETECT_TOG: 831 case USB_ANALOG_USB2_MISC_TOG: 832 /* 833 * All REG_NAME_TOG register access are in fact targeting 834 * the REG_NAME register. So we change the value of the 835 * REG_NAME register, toggling bits passed in the value. 836 */ 837 s->analog[index - 3] ^= (value & ~analog_mask[index - 3]); 838 break; 839 default: 840 s->analog[index] = (s->analog[index] & analog_mask[index]) | 841 (value & ~analog_mask[index]); 842 break; 843 } 844 } 845 846 static const struct MemoryRegionOps imx6ul_ccm_ops = { 847 .read = imx6ul_ccm_read, 848 .write = imx6ul_ccm_write, 849 .endianness = DEVICE_NATIVE_ENDIAN, 850 .valid = { 851 /* 852 * Our device would not work correctly if the guest was doing 853 * unaligned access. This might not be a limitation on the real 854 * device but in practice there is no reason for a guest to access 855 * this device unaligned. 856 */ 857 .min_access_size = 4, 858 .max_access_size = 4, 859 .unaligned = false, 860 }, 861 }; 862 863 static const struct MemoryRegionOps imx6ul_analog_ops = { 864 .read = imx6ul_analog_read, 865 .write = imx6ul_analog_write, 866 .endianness = DEVICE_NATIVE_ENDIAN, 867 .valid = { 868 /* 869 * Our device would not work correctly if the guest was doing 870 * unaligned access. This might not be a limitation on the real 871 * device but in practice there is no reason for a guest to access 872 * this device unaligned. 873 */ 874 .min_access_size = 4, 875 .max_access_size = 4, 876 .unaligned = false, 877 }, 878 }; 879 880 static void imx6ul_ccm_init(Object *obj) 881 { 882 DeviceState *dev = DEVICE(obj); 883 SysBusDevice *sd = SYS_BUS_DEVICE(obj); 884 IMX6ULCCMState *s = IMX6UL_CCM(obj); 885 886 /* initialize a container for the all memory range */ 887 memory_region_init(&s->container, OBJECT(dev), TYPE_IMX6UL_CCM, 0x8000); 888 889 /* We initialize an IO memory region for the CCM part */ 890 memory_region_init_io(&s->ioccm, OBJECT(dev), &imx6ul_ccm_ops, s, 891 TYPE_IMX6UL_CCM ".ccm", CCM_MAX * sizeof(uint32_t)); 892 893 /* Add the CCM as a subregion at offset 0 */ 894 memory_region_add_subregion(&s->container, 0, &s->ioccm); 895 896 /* We initialize an IO memory region for the ANALOG part */ 897 memory_region_init_io(&s->ioanalog, OBJECT(dev), &imx6ul_analog_ops, s, 898 TYPE_IMX6UL_CCM ".analog", 899 CCM_ANALOG_MAX * sizeof(uint32_t)); 900 901 /* Add the ANALOG as a subregion at offset 0x4000 */ 902 memory_region_add_subregion(&s->container, 0x4000, &s->ioanalog); 903 904 sysbus_init_mmio(sd, &s->container); 905 } 906 907 static void imx6ul_ccm_class_init(ObjectClass *klass, void *data) 908 { 909 DeviceClass *dc = DEVICE_CLASS(klass); 910 IMXCCMClass *ccm = IMX_CCM_CLASS(klass); 911 912 dc->reset = imx6ul_ccm_reset; 913 dc->vmsd = &vmstate_imx6ul_ccm; 914 dc->desc = "i.MX6UL Clock Control Module"; 915 916 ccm->get_clock_frequency = imx6ul_ccm_get_clock_frequency; 917 } 918 919 static const TypeInfo imx6ul_ccm_info = { 920 .name = TYPE_IMX6UL_CCM, 921 .parent = TYPE_IMX_CCM, 922 .instance_size = sizeof(IMX6ULCCMState), 923 .instance_init = imx6ul_ccm_init, 924 .class_init = imx6ul_ccm_class_init, 925 }; 926 927 static void imx6ul_ccm_register_types(void) 928 { 929 type_register_static(&imx6ul_ccm_info); 930 } 931 932 type_init(imx6ul_ccm_register_types) 933