/*
 * Copyright (c) 2015-2021, Renesas Electronics Corporation
 * All rights reserved.
 */

/******************************************************************************
 * @file          cgp_init.c
 * - Version      : 0.01
 * @brief         Initial setting process of CPG.
 * .
 *****************************************************************************/
/******************************************************************************
 * History : DD.MM.YYYY Version  Description
 *         : 29.05.2020 0.01     First Release
 *****************************************************************************/

#include <mmio.h>
#include "cpg_register.h"
#include "cpg_init.h"
#include "rcar_def.h"

/* define for ASTPOFFR register */
#define IMP0_A_DISABLE      (((uint32_t)1U) << 12U)
#define IMP1_A_DISABLE      (((uint32_t)1U) << 13U)
#define IMP2_A_DISABLE      (((uint32_t)1U) << 14U)
#define IMP3_A_DISABLE      (((uint32_t)1U) << 15U)

typedef struct {
    uintptr_t   adr;
    uint32_t    val;
} st_reg_setting_t;

static const st_reg_setting_t s_reg_setting_rt[] = {

    /* CPG (REALTIME) registers */

    /* Realtime Module Stop Control Register 0 */
    {RMSTPCR0,      0x00000000U},
    /* Realtime Module Stop Control Register 1 */
    {RMSTPCR1,      0xFDDFFFFFU},
    /* Realtime Module Stop Control Register 2 */
    {RMSTPCR2,      0x00000000U},
    /* Realtime Module Stop Control Register 3 */
    {RMSTPCR3,      0xFF7FFF19U},
    /* Realtime Module Stop Control Register 4 */
    {RMSTPCR4,      0x00000000U},
    /* Realtime Module Stop Control Register 5 */
    {RMSTPCR5,      0x83BFFFD7U},
    /* Realtime Module Stop Control Register 6 */
    {RMSTPCR6,      0xFFFFFFFFU},
    /* Realtime Module Stop Control Register 7 */
    {RMSTPCR7,      0xFFFFFFFFU},
    /* Realtime Module Stop Control Register 8 */
    {RMSTPCR8,      0x7FF3EFF4U},
    /* Realtime Module Stop Control Register 9 */
    {RMSTPCR9,      0x03F1A017U}
};

static const st_reg_setting_t s_reg_setting_safety[] = {

    /* CPG (SAFETY) registers */

    /* Safety Module Stop Control Register 0 */
    {SAMSTPCR0,     0xFFFFFFFFU},
    /* Safety Module Stop Control Register 1 */
    {SAMSTPCR1,     0xFFFFFFFFU},
    /* Safety Module Stop Control Register 2 */
    {SAMSTPCR2,     0xFFFFFFFFU},
    /* Safety Module Stop Control Register 3 */
    {SAMSTPCR3,     0xFFFFFFFFU},
    /* Safety Module Stop Control Register 4 */
    {SAMSTPCR4,     0xFFFFFFFFU},
    /* Safety Module Stop Control Register 5 */
    {SAMSTPCR5,     0xFFFFFFFFU},
    /* Safety Module Stop Control Register 6 */
    {SAMSTPCR6,     0xFFFFFFFFU},
    /* Safety Module Stop Control Register 7 */
    {SAMSTPCR7,     0xFFFFFFFFU},
    /* Safety Module Stop Control Register 8 */
    {SAMSTPCR8,     0xFFFFFFFFU},
    /* Safety Module Stop Control Register 9 */
    {SAMSTPCR9,     0xFFFFFFFFU}
};


void cpg_init(void)
{
    uint32_t    i;
    uint32_t    ie;
    uint32_t    reg;

        /* CPG (Realtime) registers */
    ie = (uint32_t)(sizeof(s_reg_setting_rt) / sizeof(st_reg_setting_t));

    for (i = 0U; i < ie; i++)
    {
        cpg_write(s_reg_setting_rt[i].adr, s_reg_setting_rt[i].val);
    }

    /* CPG (Safety) registers */
    ie = (uint32_t)(sizeof(s_reg_setting_safety) / sizeof(st_reg_setting_t));

    for (i = 0U; i < ie; i++)
    {
        cpg_write(s_reg_setting_safety[i].adr, s_reg_setting_safety[i].val);
    }

    /* Disable automatic module clock stop function */
    reg = mmio_read_32(RCAR_PRR);
    if ((reg & RCAR_CUT_MASK) == RCAR_CUT_VER20)
    {
        reg = mmio_read_32(ASTPOFFR);
        reg |= (IMP0_A_DISABLE | IMP1_A_DISABLE | IMP2_A_DISABLE |
            IMP3_A_DISABLE);
        cpg_write(ASTPOFFR, reg);
    }
}
/* End of function cpg_init */

void cpg_write(uintptr_t regadr, uint32_t regval)
{
    uint32_t value = (regval);
    mmio_write_32((uintptr_t)CPG_CPGWPR,~value);
    mmio_write_32(regadr,value);
}
/* End of function cpg_write */

