/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright 2025 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/

/*******************************************************************************
 * DESCRIPTION   : ECM initialize function
 ******************************************************************************/
/******************************************************************************
 * @file          ecm_enable_v4h.c
 * - Version      : 0.01
 * @brief         ECM setting.
 * .
 *****************************************************************************/
/******************************************************************************
 * History : DD.MM.YYYY Version  Description
 *         : 29.01.2025 0.01     First Release
 *****************************************************************************/

#include <stdint.h>
#include "ecm_enable_v4h.h"

#if (ECM_ERROR_ENABLE == 1)
#include "log.h"
#endif /* ECM_ERROR_ENABLE == 1 */
#if ((ECM_ERROR_ENABLE == 1) || (ECC_ENABLE == 1))
#include "ecc_enable_v4h.h"
#include "mem_io.h"
#endif /* (ECM_ERROR_ENABLE == 1) || (ECC_ENABLE == 1) */

#if (ECM_ERROR_ENABLE == 1)
#define ECM_ERR_REG_MAX     (40U)

typedef struct{
    uint32_t phys_addr; /* Physical address of ECM registers. */
    uint32_t value;     /* Setting value of ECM registers. */
} ECM_ERROR_TABLE;
#endif /* ECM_ERROR_ENABLE == 1 */

#if ((ECM_ERROR_ENABLE == 1) || (ECC_ENABLE == 1))
void ecm_unlock(void)
{
    mem_write32(ECMWPCNTR, 0xACCE0001U);
}

void ecm_write(uint32_t adr, uint32_t val)
{
    mem_write32(ECMWACNTR, ((0xACCEU << 16U) | (adr & 0xffffU)));
    mem_write32(adr, val);
}

void ecm_lock(void)
{
    mem_write32(ECMWPCNTR, 0xACCE0000U);
}
#endif /* (ECM_ERROR_ENABLE == 1) || (ECC_ENABLE == 1) */

#if (ECM_ERROR_ENABLE == 1)
void ecm_error_enable(void)
{
    uint32_t reg;
    uint32_t loop;

    const ECM_ERROR_TABLE ecmerrctlr_tbl[ECM_ERR_REG_MAX] = {
    [0]   =     {0xE6250000U, 0xFFFFF00FU}, /* ECMERRCTLR0 */
    [1]   =     {0xE6250004U, 0xFFF8C000U}, /* ECMERRCTLR1 */
    [2]   =     {0xE6250008U, 0xFFFFFFFFU}, /* ECMERRCTLR2 */
    [3]   =     {0xE625000CU, 0xFFFFFFFFU}, /* ECMERRCTLR3 */
    [4]   =     {0xE6250010U, 0xFFFFFFFFU}, /* ECMERRCTLR4 */
    [5]   =     {0xE6250014U, 0xFFFFFFFFU}, /* ECMERRCTLR5 */
    [6]   =     {0xE6250018U, 0xFF000A80U}, /* ECMERRCTLR6 */
    [7]   =     {0xE625001CU, 0x6F980FFFU}, /* ECMERRCTLR7 */
    [8]   =     {0xE6250020U, 0xFFF00000U}, /* ECMERRCTLR8 */
    [9]   =     {0xE6250024U, 0xFF000000U}, /* ECMERRCTLR9 */
    [10]  =     {0xE6250028U, 0x557D554FU}, /* ECMERRCTLR10 */
    [11]  =     {0xE625002CU, 0xFFFC1555U}, /* ECMERRCTLR11 */
    [12]  =     {0xE6250030U, 0x5557FFFFU}, /* ECMERRCTLR12 */
    [13]  =     {0xE6250034U, 0x00000055U}, /* ECMERRCTLR13 */
        /* Skip ECMERRCTLR14 setting */
        /* Skip ECMERRCTLR15 setting */
    [14]  =     {0xE6250040U, 0x3FFFFFFFU}, /* ECMERRCTLR16 */
    [15]  =     {0xE6250044U, 0x2FFF8CE0U}, /* ECMERRCTLR17 */
    [16]  =     {0xE6250048U, 0x0EC03FFFU}, /* ECMERRCTLR18 */
    [17]  =     {0xE625004CU, 0xFFFFFFF9U}, /* ECMERRCTLR19 */
    [18]  =     {0xE6250050U, 0xFE66667EU}, /* ECMERRCTLR20 */
    [19]  =     {0xE6250054U, 0xBFE3BE0FU}, /* ECMERRCTLR21 */
    [20]  =     {0xE6250058U, 0x10000000U}, /* ECMERRCTLR22 */
    [21]  =     {0xE625005CU, 0x7EF3C008U}, /* ECMERRCTLR23 */
    [22]  =     {0xE6250060U, 0x7FFE8ADBU}, /* ECMERRCTLR24 */
    [23]  =     {0xE6250064U, 0xCF807FFFU}, /* ECMERRCTLR25 */
    [24]  =     {0xE6250068U, 0x7EF3C008U}, /* ECMERRCTLR26 */
    [25]  =     {0xE625006CU, 0x7FFE8ADBU}, /* ECMERRCTLR27 */
    [26]  =     {0xE6250070U, 0xCF807FFFU}, /* ECMERRCTLR28 */
    [27]  =     {0xE6250074U, 0x0073C008U}, /* ECMERRCTLR29 */
    [28]  =     {0xE6250078U, 0x7FE68A9BU}, /* ECMERRCTLR30 */
    [29]  =     {0xE625007CU, 0x8C007E00U}, /* ECMERRCTLR31 */
    [30]  =     {0xE6250080U, 0xCFFFFFFFU}, /* ECMERRCTLR32 */
    [31]  =     {0xE6250084U, 0x0FFFFFFFU}, /* ECMERRCTLR33 */
    [32]  =     {0xE6250088U, 0x000003FFU}, /* ECMERRCTLR34 */
    [33]  =     {0xE625008CU, 0xFFFFFFC0U}, /* ECMERRCTLR35 */
    [34]  =     {0xE6250090U, 0xFFFFFFFFU}, /* ECMERRCTLR36 */
        /* Skip ECMERRCTLR37 setting */
    [35]  =     {0xE6250098U, 0xFFF000FFU}, /* ECMERRCTLR38 */
    [36]  =     {0xE625009CU, 0x1FFF0000U}, /* ECMERRCTLR39 */
    [37]  =     {0xE62500A0U, 0x1FFC7FFFU}, /* ECMERRCTLR40 */
    [38]  =     {0xE62500A4U, 0xEFFF7FFBU}, /* ECMERRCTLR41 */
    [39]  =     {0xE62500A8U, 0x3FBFFDFFU}, /* ECMERRCTLR42 */
    };

#if (ECMERRTGTR_INTC == 1)
    const ECM_ERROR_TABLE ecmerrtgtr_tbl[ECM_ERR_REG_MAX] = {
    [0]   =     {0xE6250200U, 0xFFFFF00FU}, /* ECMERRTGTR0 */
    [1]   =     {0xE6250204U, 0xFFF8C000U}, /* ECMERRTGTR1 */
    [2]   =     {0xE6250208U, 0xFFFFFFFFU}, /* ECMERRTGTR2 */
    [3]   =     {0xE625020CU, 0xFFFFFFFFU}, /* ECMERRTGTR3 */
    [4]   =     {0xE6250210U, 0xFFFFFFFFU}, /* ECMERRTGTR4 */
    [5]   =     {0xE6250214U, 0xFFFFFFFFU}, /* ECMERRTGTR5 */
    [6]   =     {0xE6250218U, 0xFF000A80U}, /* ECMERRTGTR6 */
    [7]   =     {0xE625021CU, 0x6F980FFFU}, /* ECMERRTGTR7 */
    [8]   =     {0xE6250220U, 0xFFF00000U}, /* ECMERRTGTR8 */
    [9]   =     {0xE6250224U, 0xFF000000U}, /* ECMERRTGTR9 */
    [10]  =     {0xE6250228U, 0x557D554FU}, /* ECMERRTGTR10 */
    [11]  =     {0xE625022CU, 0xFFFC1555U}, /* ECMERRTGTR11 */
    [12]  =     {0xE6250230U, 0x5557FFFFU}, /* ECMERRTGTR12 */
    [13]  =     {0xE6250234U, 0x00000055U}, /* ECMERRTGTR13 */
        /* Skip ECMERRTGTR14 setting */
        /* Skip ECMERRTGTR15 setting */
    [14]  =     {0xE6250240U, 0x3FFFFFFFU}, /* ECMERRTGTR16 */
    [15]  =     {0xE6250244U, 0x2FFF8CE0U}, /* ECMERRTGTR17 */
    [16]  =     {0xE6250248U, 0x0EC03FFFU}, /* ECMERRTGTR18 */
    [17]  =     {0xE625024CU, 0xFFFFFFF9U}, /* ECMERRTGTR19 */
    [18]  =     {0xE6250250U, 0xFE66667EU}, /* ECMERRTGTR20 */
    [19]  =     {0xE6250254U, 0xBFE3BE0FU}, /* ECMERRTGTR21 */
    [20]  =     {0xE6250258U, 0x10000000U}, /* ECMERRTGTR22 */
    [21]  =     {0xE625025CU, 0x7EF3C008U}, /* ECMERRTGTR23 */
    [22]  =     {0xE6250260U, 0x7FFE8ADBU}, /* ECMERRTGTR24 */
    [23]  =     {0xE6250264U, 0xCF807FFFU}, /* ECMERRTGTR25 */
    [24]  =     {0xE6250268U, 0x7EF3C008U}, /* ECMERRTGTR26 */
    [25]  =     {0xE625026CU, 0x7FFE8ADBU}, /* ECMERRTGTR27 */
    [26]  =     {0xE6250270U, 0xCF807FFFU}, /* ECMERRTGTR28 */
    [27]  =     {0xE6250274U, 0x0073C008U}, /* ECMERRTGTR29 */
    [28]  =     {0xE6250278U, 0x7FE68A9BU}, /* ECMERRTGTR30 */
    [29]  =     {0xE625027CU, 0x8C007E00U}, /* ECMERRTGTR31 */
    [30]  =     {0xE6250280U, 0xCFFFFFFFU}, /* ECMERRTGTR32 */
    [31]  =     {0xE6250284U, 0x0FFFFFFFU}, /* ECMERRTGTR33 */
    [32]  =     {0xE6250288U, 0x000003FFU}, /* ECMERRTGTR34 */
    [33]  =     {0xE625028CU, 0xFFFFFFC0U}, /* ECMERRTGTR35 */
    [34]  =     {0xE6250290U, 0xFFFFFFFFU}, /* ECMERRTGTR36 */
        /* Skip ECMERRTGTR37 setting */
    [35]  =     {0xE6250298U, 0xFFF000FFU}, /* ECMERRTGTR38 */
    [36]  =     {0xE625029CU, 0x1FFF0000U}, /* ECMERRTGTR39 */
    [37]  =     {0xE62502A0U, 0x1FFC7FFFU}, /* ECMERRTGTR40 */
    [38]  =     {0xE62502A4U, 0xEFFF7FFBU}, /* ECMERRTGTR41 */
    [39]  =     {0xE62502A8U, 0x3FBFFDFFU}, /* ECMERRTGTR42 */
    };
#elif (ECMERRTGTR_INTC == 0)
    const ECM_ERROR_TABLE ecmerrtgtr_tbl[ECM_ERR_REG_MAX] = {
    [0]   =     {0xE6250200U, 0x00000000U}, /* ECMERRTGTR0 */
    [1]   =     {0xE6250204U, 0x00000000U}, /* ECMERRTGTR1 */
    [2]   =     {0xE6250208U, 0x00000000U}, /* ECMERRTGTR2 */
    [3]   =     {0xE625020CU, 0x00000000U}, /* ECMERRTGTR3 */
    [4]   =     {0xE6250210U, 0x00000000U}, /* ECMERRTGTR4 */
    [5]   =     {0xE6250214U, 0x00000000U}, /* ECMERRTGTR5 */
    [6]   =     {0xE6250218U, 0x00000000U}, /* ECMERRTGTR6 */
    [7]   =     {0xE625021CU, 0x00000000U}, /* ECMERRTGTR7 */
    [8]   =     {0xE6250220U, 0x00000000U}, /* ECMERRTGTR8 */
    [9]   =     {0xE6250224U, 0x00000000U}, /* ECMERRTGTR9 */
    [10]  =     {0xE6250228U, 0x00000000U}, /* ECMERRTGTR10 */
    [11]  =     {0xE625022CU, 0x00000000U}, /* ECMERRTGTR11 */
    [12]  =     {0xE6250230U, 0x00000000U}, /* ECMERRTGTR12 */
    [13]  =     {0xE6250234U, 0x00000000U}, /* ECMERRTGTR13 */
        /* Skip ECMERRTGTR14 setting */
        /* Skip ECMERRTGTR15 setting */
    [14]  =     {0xE6250240U, 0x00000000U}, /* ECMERRTGTR16 */
    [15]  =     {0xE6250244U, 0x00000000U}, /* ECMERRTGTR17 */
    [16]  =     {0xE6250248U, 0x00000000U}, /* ECMERRTGTR18 */
    [17]  =     {0xE625024CU, 0x00000000U}, /* ECMERRTGTR19 */
    [18]  =     {0xE6250250U, 0x00000000U}, /* ECMERRTGTR20 */
    [19]  =     {0xE6250254U, 0x00000000U}, /* ECMERRTGTR21 */
    [20]  =     {0xE6250258U, 0x00000000U}, /* ECMERRTGTR22 */
    [21]  =     {0xE625025CU, 0x00000000U}, /* ECMERRTGTR23 */
    [22]  =     {0xE6250260U, 0x00000000U}, /* ECMERRTGTR24 */
    [23]  =     {0xE6250264U, 0x00000000U}, /* ECMERRTGTR25 */
    [24]  =     {0xE6250268U, 0x00000000U}, /* ECMERRTGTR26 */
    [25]  =     {0xE625026CU, 0x00000000U}, /* ECMERRTGTR27 */
    [26]  =     {0xE6250270U, 0x00000000U}, /* ECMERRTGTR28 */
    [27]  =     {0xE6250274U, 0x00000000U}, /* ECMERRTGTR29 */
    [28]  =     {0xE6250278U, 0x00000000U}, /* ECMERRTGTR30 */
    [29]  =     {0xE625027CU, 0x00000000U}, /* ECMERRTGTR31 */
    [30]  =     {0xE6250280U, 0x00000000U}, /* ECMERRTGTR32 */
    [31]  =     {0xE6250284U, 0x00000000U}, /* ECMERRTGTR33 */
    [32]  =     {0xE6250288U, 0x00000000U}, /* ECMERRTGTR34 */
    [33]  =     {0xE625028CU, 0x00000000U}, /* ECMERRTGTR35 */
    [34]  =     {0xE6250290U, 0x00000000U}, /* ECMERRTGTR36 */
        /* Skip ECMERRTGTR37 setting */
    [35]  =     {0xE6250298U, 0x00000000U}, /* ECMERRTGTR38 */
    [36]  =     {0xE625029CU, 0x00000000U}, /* ECMERRTGTR39 */
    [37]  =     {0xE62502A0U, 0x00000000U}, /* ECMERRTGTR40 */
    [38]  =     {0xE62502A4U, 0x00000000U}, /* ECMERRTGTR41 */
    [39]  =     {0xE62502A8U, 0x00000000U}, /* ECMERRTGTR42 */
    };
#endif /* ECMERRTGTR_INTC == 1 */

    /* Unlock the write protect of ECM registers */
    ecm_unlock();

    NOTICE("ECMERRCTLR register setting.\n");
    for (loop = 0U; loop < ECM_ERR_REG_MAX; loop++)
    {
        /* Set ECMERRCTLR registers. */
        reg  = mem_read32(ecmerrctlr_tbl[loop].phys_addr);
        reg |= ecmerrctlr_tbl[loop].value;
        ecm_write(ecmerrctlr_tbl[loop].phys_addr, reg);

        INFO("ECMERRCTLR[\t%d]\t(0x%x) =\t0x%x \tsetting value = 0x%x\n",
            loop,
            ecmerrctlr_tbl[loop].phys_addr,
            mem_read32(ecmerrctlr_tbl[loop].phys_addr),
            ecmerrctlr_tbl[loop].value);
    }

    NOTICE("ECMERRTGTR register setting.\n");
    for (loop = 0U; loop < ECM_ERR_REG_MAX; loop++)
    {
        /* Set ECMERRTGTR registers. */
        reg  = mem_read32(ecmerrtgtr_tbl[loop].phys_addr);
        reg |= ecmerrtgtr_tbl[loop].value;
        ecm_write(ecmerrtgtr_tbl[loop].phys_addr, reg);

        INFO("ECMERRTGTR[\t%d]\t(0x%x) =\t0x%x \tsetting value = 0x%x\n",
            loop,
            ecmerrtgtr_tbl[loop].phys_addr,
            mem_read32(ecmerrtgtr_tbl[loop].phys_addr),
            ecmerrtgtr_tbl[loop].value);
    }

    /* Lock the ECM registers */
    ecm_lock();
}
/* End of function ecm_error_enable(void) */
#endif /* ECM_ERROR_ENABLE == 1 */

