/*
 * BCM2835 CPRMAN clock manager
 *
 * Copyright (c) 2020 Luc Michel <luc@lmichel.fr>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

/*
 * This peripheral is roughly divided into 3 main parts:
 *   - the PLLs
 *   - the PLL channels
 *   - the clock muxes
 *
 * A main oscillator (xosc) feeds all the PLLs. Each PLLs has one or more
 * channels. Those channel are then connected to the clock muxes. Each mux has
 * multiples sources (usually the xosc, some of the PLL channels and some "test
 * debug" clocks). A mux is configured to select a given source through its
 * control register. Each mux has one output clock that also goes out of the
 * CPRMAN. This output clock usually connects to another peripheral in the SoC
 * (so a given mux is dedicated to a peripheral).
 *
 * At each level (PLL, channel and mux), the clock can be altered through
 * dividers (and multipliers in case of the PLLs), and can be disabled (in this
 * case, the next levels see no clock).
 *
 * This can be sum-up as follows (this is an example and not the actual BCM2835
 * clock tree):
 *
 *          /-->[PLL]-|->[PLL channel]--...            [mux]--> to peripherals
 *          |         |->[PLL channel]  muxes takes    [mux]
 *          |         \->[PLL channel]  inputs from    [mux]
 *          |                           some channels  [mux]
 * [xosc]---|-->[PLL]-|->[PLL channel]  and other srcs [mux]
 *          |         \->[PLL channel]           ...-->[mux]
 *          |                                          [mux]
 *          \-->[PLL]--->[PLL channel]                 [mux]
 *
 * The page at https://elinux.org/The_Undocumented_Pi gives the actual clock
 * tree configuration.
 *
 * The CPRMAN exposes clock outputs with the name of the clock mux suffixed
 * with "-out" (e.g. "uart-out", "h264-out", ...).
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "migration/vmstate.h"
#include "hw/qdev-properties.h"
#include "hw/misc/bcm2835_cprman.h"
#include "hw/misc/bcm2835_cprman_internals.h"
#include "trace.h"

/* PLL */

static void pll_reset(DeviceState *dev)
{
    CprmanPllState *s = CPRMAN_PLL(dev);
    const PLLResetInfo *info = &PLL_RESET_INFO[s->id];

    *s->reg_cm = info->cm;
    *s->reg_a2w_ctrl = info->a2w_ctrl;
    memcpy(s->reg_a2w_ana, info->a2w_ana, sizeof(info->a2w_ana));
    *s->reg_a2w_frac = info->a2w_frac;
}

static bool pll_is_locked(const CprmanPllState *pll)
{
    return !FIELD_EX32(*pll->reg_a2w_ctrl, A2W_PLLx_CTRL, PWRDN)
        && !FIELD_EX32(*pll->reg_cm, CM_PLLx, ANARST);
}

static void pll_update(CprmanPllState *pll)
{
    uint64_t freq, ndiv, fdiv, pdiv;

    if (!pll_is_locked(pll)) {
        clock_update(pll->out, 0);
        return;
    }

    pdiv = FIELD_EX32(*pll->reg_a2w_ctrl, A2W_PLLx_CTRL, PDIV);

    if (!pdiv) {
        clock_update(pll->out, 0);
        return;
    }

    ndiv = FIELD_EX32(*pll->reg_a2w_ctrl, A2W_PLLx_CTRL, NDIV);
    fdiv = FIELD_EX32(*pll->reg_a2w_frac, A2W_PLLx_FRAC, FRAC);

    if (pll->reg_a2w_ana[1] & pll->prediv_mask) {
        /* The prescaler doubles the parent frequency */
        ndiv *= 2;
        fdiv *= 2;
    }

    /*
     * We have a multiplier with an integer part (ndiv) and a fractional part
     * (fdiv), and a divider (pdiv).
     */
    freq = clock_get_hz(pll->xosc_in) *
        ((ndiv << R_A2W_PLLx_FRAC_FRAC_LENGTH) + fdiv);
    freq /= pdiv;
    freq >>= R_A2W_PLLx_FRAC_FRAC_LENGTH;

    clock_update_hz(pll->out, freq);
}

static void pll_xosc_update(void *opaque)
{
    pll_update(CPRMAN_PLL(opaque));
}

static void pll_init(Object *obj)
{
    CprmanPllState *s = CPRMAN_PLL(obj);

    s->xosc_in = qdev_init_clock_in(DEVICE(s), "xosc-in", pll_xosc_update, s);
    s->out = qdev_init_clock_out(DEVICE(s), "out");
}

static const VMStateDescription pll_vmstate = {
    .name = TYPE_CPRMAN_PLL,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_CLOCK(xosc_in, CprmanPllState),
        VMSTATE_END_OF_LIST()
    }
};

static void pll_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->reset = pll_reset;
    dc->vmsd = &pll_vmstate;
}

static const TypeInfo cprman_pll_info = {
    .name = TYPE_CPRMAN_PLL,
    .parent = TYPE_DEVICE,
    .instance_size = sizeof(CprmanPllState),
    .class_init = pll_class_init,
    .instance_init = pll_init,
};


/* PLL channel */

static void pll_channel_reset(DeviceState *dev)
{
    CprmanPllChannelState *s = CPRMAN_PLL_CHANNEL(dev);
    const PLLChannelResetInfo *info = &PLL_CHANNEL_RESET_INFO[s->id];

    *s->reg_a2w_ctrl = info->a2w_ctrl;
}

static bool pll_channel_is_enabled(CprmanPllChannelState *channel)
{
    /*
     * XXX I'm not sure of the purpose of the LOAD field. The Linux driver does
     * not set it when enabling the channel, but does clear it when disabling
     * it.
     */
    return !FIELD_EX32(*channel->reg_a2w_ctrl, A2W_PLLx_CHANNELy, DISABLE)
        && !(*channel->reg_cm & channel->hold_mask);
}

static void pll_channel_update(CprmanPllChannelState *channel)
{
    uint64_t freq, div;

    if (!pll_channel_is_enabled(channel)) {
        clock_update(channel->out, 0);
        return;
    }

    div = FIELD_EX32(*channel->reg_a2w_ctrl, A2W_PLLx_CHANNELy, DIV);

    if (!div) {
        /*
         * It seems that when the divider value is 0, it is considered as
         * being maximum by the hardware (see the Linux driver).
         */
        div = R_A2W_PLLx_CHANNELy_DIV_MASK;
    }

    /* Some channels have an additional fixed divider */
    freq = clock_get_hz(channel->pll_in) / (div * channel->fixed_divider);

    clock_update_hz(channel->out, freq);
}

/* Update a PLL and all its channels */
static void pll_update_all_channels(BCM2835CprmanState *s,
                                    CprmanPllState *pll)
{
    size_t i;

    pll_update(pll);

    for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) {
        CprmanPllChannelState *channel = &s->channels[i];
        if (channel->parent == pll->id) {
            pll_channel_update(channel);
        }
    }
}

static void pll_channel_pll_in_update(void *opaque)
{
    pll_channel_update(CPRMAN_PLL_CHANNEL(opaque));
}

static void pll_channel_init(Object *obj)
{
    CprmanPllChannelState *s = CPRMAN_PLL_CHANNEL(obj);

    s->pll_in = qdev_init_clock_in(DEVICE(s), "pll-in",
                                   pll_channel_pll_in_update, s);
    s->out = qdev_init_clock_out(DEVICE(s), "out");
}

static const VMStateDescription pll_channel_vmstate = {
    .name = TYPE_CPRMAN_PLL_CHANNEL,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_CLOCK(pll_in, CprmanPllChannelState),
        VMSTATE_END_OF_LIST()
    }
};

static void pll_channel_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->reset = pll_channel_reset;
    dc->vmsd = &pll_channel_vmstate;
}

static const TypeInfo cprman_pll_channel_info = {
    .name = TYPE_CPRMAN_PLL_CHANNEL,
    .parent = TYPE_DEVICE,
    .instance_size = sizeof(CprmanPllChannelState),
    .class_init = pll_channel_class_init,
    .instance_init = pll_channel_init,
};


/* clock mux */

static bool clock_mux_is_enabled(CprmanClockMuxState *mux)
{
    return FIELD_EX32(*mux->reg_ctl, CM_CLOCKx_CTL, ENABLE);
}

static void clock_mux_update(CprmanClockMuxState *mux)
{
    uint64_t freq;
    uint32_t div, src = FIELD_EX32(*mux->reg_ctl, CM_CLOCKx_CTL, SRC);
    bool enabled = clock_mux_is_enabled(mux);

    *mux->reg_ctl = FIELD_DP32(*mux->reg_ctl, CM_CLOCKx_CTL, BUSY, enabled);

    if (!enabled) {
        clock_update(mux->out, 0);
        return;
    }

    freq = clock_get_hz(mux->srcs[src]);

    if (mux->int_bits == 0 && mux->frac_bits == 0) {
        clock_update_hz(mux->out, freq);
        return;
    }

    /*
     * The divider has an integer and a fractional part. The size of each part
     * varies with the muxes (int_bits and frac_bits). Both parts are
     * concatenated, with the integer part always starting at bit 12.
     *
     *         31          12 11          0
     *        ------------------------------
     * CM_DIV |      |  int  |  frac  |    |
     *        ------------------------------
     *                <-----> <------>
     *                int_bits frac_bits
     */
    div = extract32(*mux->reg_div,
                    R_CM_CLOCKx_DIV_FRAC_LENGTH - mux->frac_bits,
                    mux->int_bits + mux->frac_bits);

    if (!div) {
        clock_update(mux->out, 0);
        return;
    }

    freq = muldiv64(freq, 1 << mux->frac_bits, div);

    clock_update_hz(mux->out, freq);
}

static void clock_mux_src_update(void *opaque)
{
    CprmanClockMuxState **backref = opaque;
    CprmanClockMuxState *s = *backref;
    CprmanClockMuxSource src = backref - s->backref;

    if (FIELD_EX32(*s->reg_ctl, CM_CLOCKx_CTL, SRC) != src) {
        return;
    }

    clock_mux_update(s);
}

static void clock_mux_reset(DeviceState *dev)
{
    CprmanClockMuxState *clock = CPRMAN_CLOCK_MUX(dev);
    const ClockMuxResetInfo *info = &CLOCK_MUX_RESET_INFO[clock->id];

    *clock->reg_ctl = info->cm_ctl;
    *clock->reg_div = info->cm_div;
}

static void clock_mux_init(Object *obj)
{
    CprmanClockMuxState *s = CPRMAN_CLOCK_MUX(obj);
    size_t i;

    for (i = 0; i < CPRMAN_NUM_CLOCK_MUX_SRC; i++) {
        char *name = g_strdup_printf("srcs[%zu]", i);
        s->backref[i] = s;
        s->srcs[i] = qdev_init_clock_in(DEVICE(s), name,
                                        clock_mux_src_update,
                                        &s->backref[i]);
        g_free(name);
    }

    s->out = qdev_init_clock_out(DEVICE(s), "out");
}

static const VMStateDescription clock_mux_vmstate = {
    .name = TYPE_CPRMAN_CLOCK_MUX,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_ARRAY_CLOCK(srcs, CprmanClockMuxState,
                            CPRMAN_NUM_CLOCK_MUX_SRC),
        VMSTATE_END_OF_LIST()
    }
};

static void clock_mux_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->reset = clock_mux_reset;
    dc->vmsd = &clock_mux_vmstate;
}

static const TypeInfo cprman_clock_mux_info = {
    .name = TYPE_CPRMAN_CLOCK_MUX,
    .parent = TYPE_DEVICE,
    .instance_size = sizeof(CprmanClockMuxState),
    .class_init = clock_mux_class_init,
    .instance_init = clock_mux_init,
};


/* DSI0HSCK mux */

static void dsi0hsck_mux_update(CprmanDsi0HsckMuxState *s)
{
    bool src_is_plld = FIELD_EX32(*s->reg_cm, CM_DSI0HSCK, SELPLLD);
    Clock *src = src_is_plld ? s->plld_in : s->plla_in;

    clock_update(s->out, clock_get(src));
}

static void dsi0hsck_mux_in_update(void *opaque)
{
    dsi0hsck_mux_update(CPRMAN_DSI0HSCK_MUX(opaque));
}

static void dsi0hsck_mux_init(Object *obj)
{
    CprmanDsi0HsckMuxState *s = CPRMAN_DSI0HSCK_MUX(obj);
    DeviceState *dev = DEVICE(obj);

    s->plla_in = qdev_init_clock_in(dev, "plla-in", dsi0hsck_mux_in_update, s);
    s->plld_in = qdev_init_clock_in(dev, "plld-in", dsi0hsck_mux_in_update, s);
    s->out = qdev_init_clock_out(DEVICE(s), "out");
}

static const VMStateDescription dsi0hsck_mux_vmstate = {
    .name = TYPE_CPRMAN_DSI0HSCK_MUX,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_CLOCK(plla_in, CprmanDsi0HsckMuxState),
        VMSTATE_CLOCK(plld_in, CprmanDsi0HsckMuxState),
        VMSTATE_END_OF_LIST()
    }
};

static void dsi0hsck_mux_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->vmsd = &dsi0hsck_mux_vmstate;
}

static const TypeInfo cprman_dsi0hsck_mux_info = {
    .name = TYPE_CPRMAN_DSI0HSCK_MUX,
    .parent = TYPE_DEVICE,
    .instance_size = sizeof(CprmanDsi0HsckMuxState),
    .class_init = dsi0hsck_mux_class_init,
    .instance_init = dsi0hsck_mux_init,
};


/* CPRMAN "top level" model */

static uint32_t get_cm_lock(const BCM2835CprmanState *s)
{
    static const int CM_LOCK_MAPPING[CPRMAN_NUM_PLL] = {
        [CPRMAN_PLLA] = R_CM_LOCK_FLOCKA_SHIFT,
        [CPRMAN_PLLC] = R_CM_LOCK_FLOCKC_SHIFT,
        [CPRMAN_PLLD] = R_CM_LOCK_FLOCKD_SHIFT,
        [CPRMAN_PLLH] = R_CM_LOCK_FLOCKH_SHIFT,
        [CPRMAN_PLLB] = R_CM_LOCK_FLOCKB_SHIFT,
    };

    uint32_t r = 0;
    size_t i;

    for (i = 0; i < CPRMAN_NUM_PLL; i++) {
        r |= pll_is_locked(&s->plls[i]) << CM_LOCK_MAPPING[i];
    }

    return r;
}

static uint64_t cprman_read(void *opaque, hwaddr offset,
                            unsigned size)
{
    BCM2835CprmanState *s = CPRMAN(opaque);
    uint64_t r = 0;
    size_t idx = offset / sizeof(uint32_t);

    switch (idx) {
    case R_CM_LOCK:
        r = get_cm_lock(s);
        break;

    default:
        r = s->regs[idx];
    }

    trace_bcm2835_cprman_read(offset, r);
    return r;
}

static inline void update_pll_and_channels_from_cm(BCM2835CprmanState *s,
                                                   size_t idx)
{
    size_t i;

    for (i = 0; i < CPRMAN_NUM_PLL; i++) {
        if (PLL_INIT_INFO[i].cm_offset == idx) {
            pll_update_all_channels(s, &s->plls[i]);
            return;
        }
    }
}

static inline void update_channel_from_a2w(BCM2835CprmanState *s, size_t idx)
{
    size_t i;

    for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) {
        if (PLL_CHANNEL_INIT_INFO[i].a2w_ctrl_offset == idx) {
            pll_channel_update(&s->channels[i]);
            return;
        }
    }
}

static inline void update_mux_from_cm(BCM2835CprmanState *s, size_t idx)
{
    size_t i;

    for (i = 0; i < CPRMAN_NUM_CLOCK_MUX; i++) {
        if ((CLOCK_MUX_INIT_INFO[i].cm_offset == idx) ||
            (CLOCK_MUX_INIT_INFO[i].cm_offset + 4 == idx)) {
            /* matches CM_CTL or CM_DIV mux register */
            clock_mux_update(&s->clock_muxes[i]);
            return;
        }
    }
}

#define CASE_PLL_A2W_REGS(pll_) \
    case R_A2W_ ## pll_ ## _CTRL: \
    case R_A2W_ ## pll_ ## _ANA0: \
    case R_A2W_ ## pll_ ## _ANA1: \
    case R_A2W_ ## pll_ ## _ANA2: \
    case R_A2W_ ## pll_ ## _ANA3: \
    case R_A2W_ ## pll_ ## _FRAC

static void cprman_write(void *opaque, hwaddr offset,
                         uint64_t value, unsigned size)
{
    BCM2835CprmanState *s = CPRMAN(opaque);
    size_t idx = offset / sizeof(uint32_t);

    if (FIELD_EX32(value, CPRMAN, PASSWORD) != CPRMAN_PASSWORD) {
        trace_bcm2835_cprman_write_invalid_magic(offset, value);
        return;
    }

    value &= ~R_CPRMAN_PASSWORD_MASK;

    trace_bcm2835_cprman_write(offset, value);
    s->regs[idx] = value;

    switch (idx) {
    case R_CM_PLLA ... R_CM_PLLH:
    case R_CM_PLLB:
        /*
         * A given CM_PLLx register is shared by both the PLL and the channels
         * of this PLL.
         */
        update_pll_and_channels_from_cm(s, idx);
        break;

    CASE_PLL_A2W_REGS(PLLA) :
        pll_update(&s->plls[CPRMAN_PLLA]);
        break;

    CASE_PLL_A2W_REGS(PLLC) :
        pll_update(&s->plls[CPRMAN_PLLC]);
        break;

    CASE_PLL_A2W_REGS(PLLD) :
        pll_update(&s->plls[CPRMAN_PLLD]);
        break;

    CASE_PLL_A2W_REGS(PLLH) :
        pll_update(&s->plls[CPRMAN_PLLH]);
        break;

    CASE_PLL_A2W_REGS(PLLB) :
        pll_update(&s->plls[CPRMAN_PLLB]);
        break;

    case R_A2W_PLLA_DSI0:
    case R_A2W_PLLA_CORE:
    case R_A2W_PLLA_PER:
    case R_A2W_PLLA_CCP2:
    case R_A2W_PLLC_CORE2:
    case R_A2W_PLLC_CORE1:
    case R_A2W_PLLC_PER:
    case R_A2W_PLLC_CORE0:
    case R_A2W_PLLD_DSI0:
    case R_A2W_PLLD_CORE:
    case R_A2W_PLLD_PER:
    case R_A2W_PLLD_DSI1:
    case R_A2W_PLLH_AUX:
    case R_A2W_PLLH_RCAL:
    case R_A2W_PLLH_PIX:
    case R_A2W_PLLB_ARM:
        update_channel_from_a2w(s, idx);
        break;

    case R_CM_GNRICCTL ... R_CM_SMIDIV:
    case R_CM_TCNTCNT ... R_CM_VECDIV:
    case R_CM_PULSECTL ... R_CM_PULSEDIV:
    case R_CM_SDCCTL ... R_CM_ARMCTL:
    case R_CM_AVEOCTL ... R_CM_EMMCDIV:
    case R_CM_EMMC2CTL ... R_CM_EMMC2DIV:
        update_mux_from_cm(s, idx);
        break;

    case R_CM_DSI0HSCK:
        dsi0hsck_mux_update(&s->dsi0hsck_mux);
        break;
    }
}

#undef CASE_PLL_A2W_REGS

static const MemoryRegionOps cprman_ops = {
    .read = cprman_read,
    .write = cprman_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        /*
         * Although this hasn't been checked against real hardware, nor the
         * information can be found in a datasheet, it seems reasonable because
         * of the "PASSWORD" magic value found in every registers.
         */
        .min_access_size        = 4,
        .max_access_size        = 4,
        .unaligned              = false,
    },
    .impl = {
        .max_access_size = 4,
    },
};

static void cprman_reset(DeviceState *dev)
{
    BCM2835CprmanState *s = CPRMAN(dev);
    size_t i;

    memset(s->regs, 0, sizeof(s->regs));

    for (i = 0; i < CPRMAN_NUM_PLL; i++) {
        device_cold_reset(DEVICE(&s->plls[i]));
    }

    for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) {
        device_cold_reset(DEVICE(&s->channels[i]));
    }

    device_cold_reset(DEVICE(&s->dsi0hsck_mux));

    for (i = 0; i < CPRMAN_NUM_CLOCK_MUX; i++) {
        device_cold_reset(DEVICE(&s->clock_muxes[i]));
    }

    clock_update_hz(s->xosc, s->xosc_freq);
}

static void cprman_init(Object *obj)
{
    BCM2835CprmanState *s = CPRMAN(obj);
    size_t i;

    for (i = 0; i < CPRMAN_NUM_PLL; i++) {
        object_initialize_child(obj, PLL_INIT_INFO[i].name,
                                &s->plls[i], TYPE_CPRMAN_PLL);
        set_pll_init_info(s, &s->plls[i], i);
    }

    for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) {
        object_initialize_child(obj, PLL_CHANNEL_INIT_INFO[i].name,
                                &s->channels[i],
                                TYPE_CPRMAN_PLL_CHANNEL);
        set_pll_channel_init_info(s, &s->channels[i], i);
    }

    object_initialize_child(obj, "dsi0hsck-mux",
                            &s->dsi0hsck_mux, TYPE_CPRMAN_DSI0HSCK_MUX);
    s->dsi0hsck_mux.reg_cm = &s->regs[R_CM_DSI0HSCK];

    for (i = 0; i < CPRMAN_NUM_CLOCK_MUX; i++) {
        char *alias;

        object_initialize_child(obj, CLOCK_MUX_INIT_INFO[i].name,
                                &s->clock_muxes[i],
                                TYPE_CPRMAN_CLOCK_MUX);
        set_clock_mux_init_info(s, &s->clock_muxes[i], i);

        /* Expose muxes output as CPRMAN outputs */
        alias = g_strdup_printf("%s-out", CLOCK_MUX_INIT_INFO[i].name);
        qdev_alias_clock(DEVICE(&s->clock_muxes[i]), "out", DEVICE(obj), alias);
        g_free(alias);
    }

    s->xosc = clock_new(obj, "xosc");
    s->gnd = clock_new(obj, "gnd");

    clock_set(s->gnd, 0);

    memory_region_init_io(&s->iomem, obj, &cprman_ops,
                          s, "bcm2835-cprman", 0x2000);
    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
}

static void connect_mux_sources(BCM2835CprmanState *s,
                                CprmanClockMuxState *mux,
                                const CprmanPllChannel *clk_mapping)
{
    size_t i;
    Clock *td0 = s->clock_muxes[CPRMAN_CLOCK_TD0].out;
    Clock *td1 = s->clock_muxes[CPRMAN_CLOCK_TD1].out;

    /* For sources from 0 to 3. Source 4 to 9 are mux specific */
    Clock * const CLK_SRC_MAPPING[] = {
        [CPRMAN_CLOCK_SRC_GND] = s->gnd,
        [CPRMAN_CLOCK_SRC_XOSC] = s->xosc,
        [CPRMAN_CLOCK_SRC_TD0] = td0,
        [CPRMAN_CLOCK_SRC_TD1] = td1,
    };

    for (i = 0; i < CPRMAN_NUM_CLOCK_MUX_SRC; i++) {
        CprmanPllChannel mapping = clk_mapping[i];
        Clock *src;

        if (mapping == CPRMAN_CLOCK_SRC_FORCE_GROUND) {
            src = s->gnd;
        } else if (mapping == CPRMAN_CLOCK_SRC_DSI0HSCK) {
            src = s->dsi0hsck_mux.out;
        } else if (i < CPRMAN_CLOCK_SRC_PLLA) {
            src = CLK_SRC_MAPPING[i];
        } else {
            src = s->channels[mapping].out;
        }

        clock_set_source(mux->srcs[i], src);
    }
}

static void cprman_realize(DeviceState *dev, Error **errp)
{
    BCM2835CprmanState *s = CPRMAN(dev);
    size_t i;

    for (i = 0; i < CPRMAN_NUM_PLL; i++) {
        CprmanPllState *pll = &s->plls[i];

        clock_set_source(pll->xosc_in, s->xosc);

        if (!qdev_realize(DEVICE(pll), NULL, errp)) {
            return;
        }
    }

    for (i = 0; i < CPRMAN_NUM_PLL_CHANNEL; i++) {
        CprmanPllChannelState *channel = &s->channels[i];
        CprmanPll parent = PLL_CHANNEL_INIT_INFO[i].parent;
        Clock *parent_clk = s->plls[parent].out;

        clock_set_source(channel->pll_in, parent_clk);

        if (!qdev_realize(DEVICE(channel), NULL, errp)) {
            return;
        }
    }

    clock_set_source(s->dsi0hsck_mux.plla_in,
                     s->channels[CPRMAN_PLLA_CHANNEL_DSI0].out);
    clock_set_source(s->dsi0hsck_mux.plld_in,
                     s->channels[CPRMAN_PLLD_CHANNEL_DSI0].out);

    if (!qdev_realize(DEVICE(&s->dsi0hsck_mux), NULL, errp)) {
        return;
    }

    for (i = 0; i < CPRMAN_NUM_CLOCK_MUX; i++) {
        CprmanClockMuxState *clock_mux = &s->clock_muxes[i];

        connect_mux_sources(s, clock_mux, CLOCK_MUX_INIT_INFO[i].src_mapping);

        if (!qdev_realize(DEVICE(clock_mux), NULL, errp)) {
            return;
        }
    }
}

static const VMStateDescription cprman_vmstate = {
    .name = TYPE_BCM2835_CPRMAN,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, BCM2835CprmanState, CPRMAN_NUM_REGS),
        VMSTATE_END_OF_LIST()
    }
};

static Property cprman_properties[] = {
    DEFINE_PROP_UINT32("xosc-freq-hz", BCM2835CprmanState, xosc_freq, 19200000),
    DEFINE_PROP_END_OF_LIST()
};

static void cprman_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = cprman_realize;
    dc->reset = cprman_reset;
    dc->vmsd = &cprman_vmstate;
    device_class_set_props(dc, cprman_properties);
}

static const TypeInfo cprman_info = {
    .name = TYPE_BCM2835_CPRMAN,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(BCM2835CprmanState),
    .class_init = cprman_class_init,
    .instance_init = cprman_init,
};

static void cprman_register_types(void)
{
    type_register_static(&cprman_info);
    type_register_static(&cprman_pll_info);
    type_register_static(&cprman_pll_channel_info);
    type_register_static(&cprman_clock_mux_info);
    type_register_static(&cprman_dsi0hsck_mux_info);
}

type_init(cprman_register_types);
