cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

imx6ul_ccm.c (27190B)


      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
     22static 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
     56static 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
     78static 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
    151static 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
    284static const VMStateDescription vmstate_imx6ul_ccm = {
    285    .name = TYPE_IMX6UL_CCM,
    286    .version_id = 1,
    287    .minimum_version_id = 1,
    288    .fields = (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
    295static 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
    304static 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
    320static 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
    329static 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
    342static 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
    355static 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
    364static 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
    394static 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
    420static 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
    432static 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
    452static 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
    464static 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
    476static 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
    496static 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
    508static 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    case CLK_HIGH:
    526        freq = CKIH_FREQ;
    527        break;
    528    case CLK_HIGH_DIV:
    529        freq = CKIH_FREQ / 8;
    530        break;
    531    default:
    532        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
    533                      TYPE_IMX6UL_CCM, __func__, clock);
    534        break;
    535    }
    536
    537    trace_ccm_clock_freq(clock, freq);
    538
    539    return freq;
    540}
    541
    542static void imx6ul_ccm_reset(DeviceState *dev)
    543{
    544    IMX6ULCCMState *s = IMX6UL_CCM(dev);
    545
    546    trace_ccm_entry();
    547
    548    s->ccm[CCM_CCR] = 0x0401167F;
    549    s->ccm[CCM_CCDR] = 0x00000000;
    550    s->ccm[CCM_CSR] = 0x00000010;
    551    s->ccm[CCM_CCSR] = 0x00000100;
    552    s->ccm[CCM_CACRR] = 0x00000000;
    553    s->ccm[CCM_CBCDR] = 0x00018D00;
    554    s->ccm[CCM_CBCMR] = 0x24860324;
    555    s->ccm[CCM_CSCMR1] = 0x04900080;
    556    s->ccm[CCM_CSCMR2] = 0x03192F06;
    557    s->ccm[CCM_CSCDR1] = 0x00490B00;
    558    s->ccm[CCM_CS1CDR] = 0x0EC102C1;
    559    s->ccm[CCM_CS2CDR] = 0x000336C1;
    560    s->ccm[CCM_CDCDR] = 0x33F71F92;
    561    s->ccm[CCM_CHSCCDR] = 0x000248A4;
    562    s->ccm[CCM_CSCDR2] = 0x00029B48;
    563    s->ccm[CCM_CSCDR3] = 0x00014841;
    564    s->ccm[CCM_CDHIPR] = 0x00000000;
    565    s->ccm[CCM_CTOR] = 0x00000000;
    566    s->ccm[CCM_CLPCR] = 0x00000079;
    567    s->ccm[CCM_CISR] = 0x00000000;
    568    s->ccm[CCM_CIMR] = 0xFFFFFFFF;
    569    s->ccm[CCM_CCOSR] = 0x000A0001;
    570    s->ccm[CCM_CGPR] = 0x0000FE62;
    571    s->ccm[CCM_CCGR0] = 0xFFFFFFFF;
    572    s->ccm[CCM_CCGR1] = 0xFFFFFFFF;
    573    s->ccm[CCM_CCGR2] = 0xFC3FFFFF;
    574    s->ccm[CCM_CCGR3] = 0xFFFFFFFF;
    575    s->ccm[CCM_CCGR4] = 0xFFFFFFFF;
    576    s->ccm[CCM_CCGR5] = 0xFFFFFFFF;
    577    s->ccm[CCM_CCGR6] = 0xFFFFFFFF;
    578    s->ccm[CCM_CMEOR] = 0xFFFFFFFF;
    579
    580    s->analog[CCM_ANALOG_PLL_ARM] = 0x00013063;
    581    s->analog[CCM_ANALOG_PLL_USB1] = 0x00012000;
    582    s->analog[CCM_ANALOG_PLL_USB2] = 0x00012000;
    583    s->analog[CCM_ANALOG_PLL_SYS] = 0x00013001;
    584    s->analog[CCM_ANALOG_PLL_SYS_SS] = 0x00000000;
    585    s->analog[CCM_ANALOG_PLL_SYS_NUM] = 0x00000000;
    586    s->analog[CCM_ANALOG_PLL_SYS_DENOM] = 0x00000012;
    587    s->analog[CCM_ANALOG_PLL_AUDIO] = 0x00011006;
    588    s->analog[CCM_ANALOG_PLL_AUDIO_NUM] = 0x05F5E100;
    589    s->analog[CCM_ANALOG_PLL_AUDIO_DENOM] = 0x2964619C;
    590    s->analog[CCM_ANALOG_PLL_VIDEO] = 0x0001100C;
    591    s->analog[CCM_ANALOG_PLL_VIDEO_NUM] = 0x05F5E100;
    592    s->analog[CCM_ANALOG_PLL_VIDEO_DENOM] = 0x10A24447;
    593    s->analog[CCM_ANALOG_PLL_ENET] = 0x00011001;
    594    s->analog[CCM_ANALOG_PFD_480] = 0x1311100C;
    595    s->analog[CCM_ANALOG_PFD_528] = 0x1018101B;
    596
    597    s->analog[PMU_REG_1P1] = 0x00001073;
    598    s->analog[PMU_REG_3P0] = 0x00000F74;
    599    s->analog[PMU_REG_2P5] = 0x00001073;
    600    s->analog[PMU_REG_CORE] = 0x00482012;
    601    s->analog[PMU_MISC0] = 0x04000000;
    602    s->analog[PMU_MISC1] = 0x00000000;
    603    s->analog[PMU_MISC2] = 0x00272727;
    604    s->analog[PMU_LOWPWR_CTRL] = 0x00004009;
    605
    606    s->analog[USB_ANALOG_USB1_VBUS_DETECT] = 0x01000004;
    607    s->analog[USB_ANALOG_USB1_CHRG_DETECT] = 0x00000000;
    608    s->analog[USB_ANALOG_USB1_VBUS_DETECT_STAT] = 0x00000000;
    609    s->analog[USB_ANALOG_USB1_CHRG_DETECT_STAT] = 0x00000000;
    610    s->analog[USB_ANALOG_USB1_MISC] = 0x00000002;
    611    s->analog[USB_ANALOG_USB2_VBUS_DETECT] = 0x01000004;
    612    s->analog[USB_ANALOG_USB2_CHRG_DETECT] = 0x00000000;
    613    s->analog[USB_ANALOG_USB2_MISC] = 0x00000002;
    614    s->analog[USB_ANALOG_DIGPROG] = 0x00640000;
    615
    616    /* all PLLs need to be locked */
    617    s->analog[CCM_ANALOG_PLL_ARM]   |= CCM_ANALOG_PLL_LOCK;
    618    s->analog[CCM_ANALOG_PLL_USB1]  |= CCM_ANALOG_PLL_LOCK;
    619    s->analog[CCM_ANALOG_PLL_USB2]  |= CCM_ANALOG_PLL_LOCK;
    620    s->analog[CCM_ANALOG_PLL_SYS]   |= CCM_ANALOG_PLL_LOCK;
    621    s->analog[CCM_ANALOG_PLL_AUDIO] |= CCM_ANALOG_PLL_LOCK;
    622    s->analog[CCM_ANALOG_PLL_VIDEO] |= CCM_ANALOG_PLL_LOCK;
    623    s->analog[CCM_ANALOG_PLL_ENET]  |= CCM_ANALOG_PLL_LOCK;
    624
    625    s->analog[TEMPMON_TEMPSENSE0] = 0x00000001;
    626    s->analog[TEMPMON_TEMPSENSE1] = 0x00000001;
    627    s->analog[TEMPMON_TEMPSENSE2] = 0x00000000;
    628}
    629
    630static uint64_t imx6ul_ccm_read(void *opaque, hwaddr offset, unsigned size)
    631{
    632    uint32_t value = 0;
    633    uint32_t index = offset >> 2;
    634    IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
    635
    636    assert(index < CCM_MAX);
    637
    638    value = s->ccm[index];
    639
    640    trace_ccm_read_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);
    641
    642    return (uint64_t)value;
    643}
    644
    645static void imx6ul_ccm_write(void *opaque, hwaddr offset, uint64_t value,
    646                           unsigned size)
    647{
    648    uint32_t index = offset >> 2;
    649    IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
    650
    651    assert(index < CCM_MAX);
    652
    653    trace_ccm_write_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);
    654
    655    s->ccm[index] = (s->ccm[index] & ccm_mask[index]) |
    656                           ((uint32_t)value & ~ccm_mask[index]);
    657}
    658
    659static uint64_t imx6ul_analog_read(void *opaque, hwaddr offset, unsigned size)
    660{
    661    uint32_t value;
    662    uint32_t index = offset >> 2;
    663    IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
    664
    665    assert(index < CCM_ANALOG_MAX);
    666
    667    switch (index) {
    668    case CCM_ANALOG_PLL_ARM_SET:
    669    case CCM_ANALOG_PLL_USB1_SET:
    670    case CCM_ANALOG_PLL_USB2_SET:
    671    case CCM_ANALOG_PLL_SYS_SET:
    672    case CCM_ANALOG_PLL_AUDIO_SET:
    673    case CCM_ANALOG_PLL_VIDEO_SET:
    674    case CCM_ANALOG_PLL_ENET_SET:
    675    case CCM_ANALOG_PFD_480_SET:
    676    case CCM_ANALOG_PFD_528_SET:
    677    case CCM_ANALOG_MISC0_SET:
    678    case PMU_MISC1_SET:
    679    case CCM_ANALOG_MISC2_SET:
    680    case USB_ANALOG_USB1_VBUS_DETECT_SET:
    681    case USB_ANALOG_USB1_CHRG_DETECT_SET:
    682    case USB_ANALOG_USB1_MISC_SET:
    683    case USB_ANALOG_USB2_VBUS_DETECT_SET:
    684    case USB_ANALOG_USB2_CHRG_DETECT_SET:
    685    case USB_ANALOG_USB2_MISC_SET:
    686    case TEMPMON_TEMPSENSE0_SET:
    687    case TEMPMON_TEMPSENSE1_SET:
    688    case TEMPMON_TEMPSENSE2_SET:
    689        /*
    690         * All REG_NAME_SET register access are in fact targeting
    691         * the REG_NAME register.
    692         */
    693        value = s->analog[index - 1];
    694        break;
    695    case CCM_ANALOG_PLL_ARM_CLR:
    696    case CCM_ANALOG_PLL_USB1_CLR:
    697    case CCM_ANALOG_PLL_USB2_CLR:
    698    case CCM_ANALOG_PLL_SYS_CLR:
    699    case CCM_ANALOG_PLL_AUDIO_CLR:
    700    case CCM_ANALOG_PLL_VIDEO_CLR:
    701    case CCM_ANALOG_PLL_ENET_CLR:
    702    case CCM_ANALOG_PFD_480_CLR:
    703    case CCM_ANALOG_PFD_528_CLR:
    704    case CCM_ANALOG_MISC0_CLR:
    705    case PMU_MISC1_CLR:
    706    case CCM_ANALOG_MISC2_CLR:
    707    case USB_ANALOG_USB1_VBUS_DETECT_CLR:
    708    case USB_ANALOG_USB1_CHRG_DETECT_CLR:
    709    case USB_ANALOG_USB1_MISC_CLR:
    710    case USB_ANALOG_USB2_VBUS_DETECT_CLR:
    711    case USB_ANALOG_USB2_CHRG_DETECT_CLR:
    712    case USB_ANALOG_USB2_MISC_CLR:
    713    case TEMPMON_TEMPSENSE0_CLR:
    714    case TEMPMON_TEMPSENSE1_CLR:
    715    case TEMPMON_TEMPSENSE2_CLR:
    716        /*
    717         * All REG_NAME_CLR register access are in fact targeting
    718         * the REG_NAME register.
    719         */
    720        value = s->analog[index - 2];
    721        break;
    722    case CCM_ANALOG_PLL_ARM_TOG:
    723    case CCM_ANALOG_PLL_USB1_TOG:
    724    case CCM_ANALOG_PLL_USB2_TOG:
    725    case CCM_ANALOG_PLL_SYS_TOG:
    726    case CCM_ANALOG_PLL_AUDIO_TOG:
    727    case CCM_ANALOG_PLL_VIDEO_TOG:
    728    case CCM_ANALOG_PLL_ENET_TOG:
    729    case CCM_ANALOG_PFD_480_TOG:
    730    case CCM_ANALOG_PFD_528_TOG:
    731    case CCM_ANALOG_MISC0_TOG:
    732    case PMU_MISC1_TOG:
    733    case CCM_ANALOG_MISC2_TOG:
    734    case USB_ANALOG_USB1_VBUS_DETECT_TOG:
    735    case USB_ANALOG_USB1_CHRG_DETECT_TOG:
    736    case USB_ANALOG_USB1_MISC_TOG:
    737    case USB_ANALOG_USB2_VBUS_DETECT_TOG:
    738    case USB_ANALOG_USB2_CHRG_DETECT_TOG:
    739    case USB_ANALOG_USB2_MISC_TOG:
    740    case TEMPMON_TEMPSENSE0_TOG:
    741    case TEMPMON_TEMPSENSE1_TOG:
    742    case TEMPMON_TEMPSENSE2_TOG:
    743        /*
    744         * All REG_NAME_TOG register access are in fact targeting
    745         * the REG_NAME register.
    746         */
    747        value = s->analog[index - 3];
    748        break;
    749    default:
    750        value = s->analog[index];
    751        break;
    752    }
    753
    754    trace_ccm_read_reg(imx6ul_analog_reg_name(index), (uint32_t)value);
    755
    756    return (uint64_t)value;
    757}
    758
    759static void imx6ul_analog_write(void *opaque, hwaddr offset, uint64_t value,
    760                              unsigned size)
    761{
    762    uint32_t index = offset >> 2;
    763    IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
    764
    765    assert(index < CCM_ANALOG_MAX);
    766
    767    trace_ccm_write_reg(imx6ul_analog_reg_name(index), (uint32_t)value);
    768
    769    switch (index) {
    770    case CCM_ANALOG_PLL_ARM_SET:
    771    case CCM_ANALOG_PLL_USB1_SET:
    772    case CCM_ANALOG_PLL_USB2_SET:
    773    case CCM_ANALOG_PLL_SYS_SET:
    774    case CCM_ANALOG_PLL_AUDIO_SET:
    775    case CCM_ANALOG_PLL_VIDEO_SET:
    776    case CCM_ANALOG_PLL_ENET_SET:
    777    case CCM_ANALOG_PFD_480_SET:
    778    case CCM_ANALOG_PFD_528_SET:
    779    case CCM_ANALOG_MISC0_SET:
    780    case PMU_MISC1_SET:
    781    case CCM_ANALOG_MISC2_SET:
    782    case USB_ANALOG_USB1_VBUS_DETECT_SET:
    783    case USB_ANALOG_USB1_CHRG_DETECT_SET:
    784    case USB_ANALOG_USB1_MISC_SET:
    785    case USB_ANALOG_USB2_VBUS_DETECT_SET:
    786    case USB_ANALOG_USB2_CHRG_DETECT_SET:
    787    case USB_ANALOG_USB2_MISC_SET:
    788        /*
    789         * All REG_NAME_SET register access are in fact targeting
    790         * the REG_NAME register. So we change the value of the
    791         * REG_NAME register, setting bits passed in the value.
    792         */
    793        s->analog[index - 1] |= (value & ~analog_mask[index - 1]);
    794        break;
    795    case CCM_ANALOG_PLL_ARM_CLR:
    796    case CCM_ANALOG_PLL_USB1_CLR:
    797    case CCM_ANALOG_PLL_USB2_CLR:
    798    case CCM_ANALOG_PLL_SYS_CLR:
    799    case CCM_ANALOG_PLL_AUDIO_CLR:
    800    case CCM_ANALOG_PLL_VIDEO_CLR:
    801    case CCM_ANALOG_PLL_ENET_CLR:
    802    case CCM_ANALOG_PFD_480_CLR:
    803    case CCM_ANALOG_PFD_528_CLR:
    804    case CCM_ANALOG_MISC0_CLR:
    805    case PMU_MISC1_CLR:
    806    case CCM_ANALOG_MISC2_CLR:
    807    case USB_ANALOG_USB1_VBUS_DETECT_CLR:
    808    case USB_ANALOG_USB1_CHRG_DETECT_CLR:
    809    case USB_ANALOG_USB1_MISC_CLR:
    810    case USB_ANALOG_USB2_VBUS_DETECT_CLR:
    811    case USB_ANALOG_USB2_CHRG_DETECT_CLR:
    812    case USB_ANALOG_USB2_MISC_CLR:
    813        /*
    814         * All REG_NAME_CLR register access are in fact targeting
    815         * the REG_NAME register. So we change the value of the
    816         * REG_NAME register, unsetting bits passed in the value.
    817         */
    818        s->analog[index - 2] &= ~(value & ~analog_mask[index - 2]);
    819        break;
    820    case CCM_ANALOG_PLL_ARM_TOG:
    821    case CCM_ANALOG_PLL_USB1_TOG:
    822    case CCM_ANALOG_PLL_USB2_TOG:
    823    case CCM_ANALOG_PLL_SYS_TOG:
    824    case CCM_ANALOG_PLL_AUDIO_TOG:
    825    case CCM_ANALOG_PLL_VIDEO_TOG:
    826    case CCM_ANALOG_PLL_ENET_TOG:
    827    case CCM_ANALOG_PFD_480_TOG:
    828    case CCM_ANALOG_PFD_528_TOG:
    829    case CCM_ANALOG_MISC0_TOG:
    830    case PMU_MISC1_TOG:
    831    case CCM_ANALOG_MISC2_TOG:
    832    case USB_ANALOG_USB1_VBUS_DETECT_TOG:
    833    case USB_ANALOG_USB1_CHRG_DETECT_TOG:
    834    case USB_ANALOG_USB1_MISC_TOG:
    835    case USB_ANALOG_USB2_VBUS_DETECT_TOG:
    836    case USB_ANALOG_USB2_CHRG_DETECT_TOG:
    837    case USB_ANALOG_USB2_MISC_TOG:
    838        /*
    839         * All REG_NAME_TOG register access are in fact targeting
    840         * the REG_NAME register. So we change the value of the
    841         * REG_NAME register, toggling bits passed in the value.
    842         */
    843        s->analog[index - 3] ^= (value & ~analog_mask[index - 3]);
    844        break;
    845    default:
    846        s->analog[index] = (s->analog[index] & analog_mask[index]) |
    847                           (value & ~analog_mask[index]);
    848        break;
    849    }
    850}
    851
    852static const struct MemoryRegionOps imx6ul_ccm_ops = {
    853    .read = imx6ul_ccm_read,
    854    .write = imx6ul_ccm_write,
    855    .endianness = DEVICE_NATIVE_ENDIAN,
    856    .valid = {
    857        /*
    858         * Our device would not work correctly if the guest was doing
    859         * unaligned access. This might not be a limitation on the real
    860         * device but in practice there is no reason for a guest to access
    861         * this device unaligned.
    862         */
    863        .min_access_size = 4,
    864        .max_access_size = 4,
    865        .unaligned = false,
    866    },
    867};
    868
    869static const struct MemoryRegionOps imx6ul_analog_ops = {
    870    .read = imx6ul_analog_read,
    871    .write = imx6ul_analog_write,
    872    .endianness = DEVICE_NATIVE_ENDIAN,
    873    .valid = {
    874        /*
    875         * Our device would not work correctly if the guest was doing
    876         * unaligned access. This might not be a limitation on the real
    877         * device but in practice there is no reason for a guest to access
    878         * this device unaligned.
    879         */
    880        .min_access_size = 4,
    881        .max_access_size = 4,
    882        .unaligned = false,
    883    },
    884};
    885
    886static void imx6ul_ccm_init(Object *obj)
    887{
    888    DeviceState *dev = DEVICE(obj);
    889    SysBusDevice *sd = SYS_BUS_DEVICE(obj);
    890    IMX6ULCCMState *s = IMX6UL_CCM(obj);
    891
    892    /* initialize a container for the all memory range */
    893    memory_region_init(&s->container, OBJECT(dev), TYPE_IMX6UL_CCM, 0x8000);
    894
    895    /* We initialize an IO memory region for the CCM part */
    896    memory_region_init_io(&s->ioccm, OBJECT(dev), &imx6ul_ccm_ops, s,
    897                          TYPE_IMX6UL_CCM ".ccm", CCM_MAX * sizeof(uint32_t));
    898
    899    /* Add the CCM as a subregion at offset 0 */
    900    memory_region_add_subregion(&s->container, 0, &s->ioccm);
    901
    902    /* We initialize an IO memory region for the ANALOG part */
    903    memory_region_init_io(&s->ioanalog, OBJECT(dev), &imx6ul_analog_ops, s,
    904                          TYPE_IMX6UL_CCM ".analog",
    905                          CCM_ANALOG_MAX * sizeof(uint32_t));
    906
    907    /* Add the ANALOG as a subregion at offset 0x4000 */
    908    memory_region_add_subregion(&s->container, 0x4000, &s->ioanalog);
    909
    910    sysbus_init_mmio(sd, &s->container);
    911}
    912
    913static void imx6ul_ccm_class_init(ObjectClass *klass, void *data)
    914{
    915    DeviceClass *dc = DEVICE_CLASS(klass);
    916    IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
    917
    918    dc->reset = imx6ul_ccm_reset;
    919    dc->vmsd = &vmstate_imx6ul_ccm;
    920    dc->desc = "i.MX6UL Clock Control Module";
    921
    922    ccm->get_clock_frequency = imx6ul_ccm_get_clock_frequency;
    923}
    924
    925static const TypeInfo imx6ul_ccm_info = {
    926    .name          = TYPE_IMX6UL_CCM,
    927    .parent        = TYPE_IMX_CCM,
    928    .instance_size = sizeof(IMX6ULCCMState),
    929    .instance_init = imx6ul_ccm_init,
    930    .class_init    = imx6ul_ccm_class_init,
    931};
    932
    933static void imx6ul_ccm_register_types(void)
    934{
    935    type_register_static(&imx6ul_ccm_info);
    936}
    937
    938type_init(imx6ul_ccm_register_types)