/*******************************************************************************
 * Copyright (c) 2025 Renesas Electronics Corporation. All rights reserved.
 *
 *     RENESAS ELECTRONICS CONFIDENTIAL AND PROPRIETARY
 *
 * This software is provided as reference/sample code under the license
 * agreement between Renesas Electronics Corporation and licensee (the
 * "License Agreement") and shall be treated as specified in the License
 * Agreement.
 * These instructions, statements, and software are the confidential
 * information of Renesas Electronics Corporation. They must be used and
 * modified solely for the purpose for which it was furnished by Renesas
 * Electronics Corporation. All or part of these instructions, statements and
 * software must not be reproduced nor disclosed to any third party in any
 * form, unless permitted by the License Agreement.
 *
 * THIS SOFTWARE IS PROVIDED BY RENESAS ELEOCTRONICS CORPORATION "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
 * SATISFACTORY QUALITY, ACCURACY, TITLE AND NON-INFRINGEMENT ARE DISCLAIMED.
 * IN NO EVENT SHALL RENESAS ELECTRONICS CORPORATION BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 ******************************************************************************/

/*******************************************************************************
 * DESCRIPTION   : ECM initialize function
 ******************************************************************************/
/******************************************************************************
 * @file          ecm_enable_v4m.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_v4m.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_v4m.h"
#include "mem_io.h"
#endif /* (ECM_ERROR_ENABLE == 1) || (ECC_ENABLE == 1) */

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

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, 0xFFFFF003U}, /* ECMERRCTLR0 */
    [1]   =     {0xE6250004U, 0xA7F8C000U}, /* ECMERRCTLR1 */
    [2]   =     {0xE6250008U, 0xFFFFFFFFU}, /* ECMERRCTLR2 */
    [3]   =     {0xE625000CU, 0xFFFFFFFFU}, /* ECMERRCTLR3 */
    [4]   =     {0xE6250010U, 0xFFFFFFFFU}, /* ECMERRCTLR4 */
    [5]   =     {0xE6250014U, 0x8FFFFFFFU}, /* ECMERRCTLR5 */
    [6]   =     {0xE6250018U, 0xFF000A80U}, /* ECMERRCTLR6 */
    [7]   =     {0xE625001CU, 0x68980FFFU}, /* ECMERRCTLR7 */
    [8]   =     {0xE6250020U, 0x60A00000U}, /* ECMERRCTLR8 */
    [9]   =     {0xE6250024U, 0xFF000000U}, /* ECMERRCTLR9 */
    [10]  =     {0xE6250028U, 0x557D554CU}, /* ECMERRCTLR10 */
    [11]  =     {0xE625002CU, 0xFF3C1555U}, /* ECMERRCTLR11 */
    [12]  =     {0xE6250030U, 0x0003FFFFU}, /* ECMERRCTLR12 */
        /* Skip ECMERRCTLR13 setting */
        /* Skip ECMERRCTLR14 setting */
        /* Skip ECMERRCTLR15 setting */
    [13]  =     {0xE6250040U, 0x33F03FFFU}, /* ECMERRCTLR16 */
    [14]  =     {0xE6250044U, 0x2DFF9CE0U}, /* ECMERRCTLR17 */
    [15]  =     {0xE6250048U, 0x0CC037FFU}, /* ECMERRCTLR18 */
    [16]  =     {0xE625004CU, 0xFFFFFF31U}, /* ECMERRCTLR19 */
    [17]  =     {0xE6250050U, 0xFE60067EU}, /* ECMERRCTLR20 */
    [18]  =     {0xE6250054U, 0xBF61820FU}, /* ECMERRCTLR21 */
    [19]  =     {0xE6250058U, 0x10000000U}, /* ECMERRCTLR22 */
    [20]  =     {0xE625005CU, 0x7E90C008U}, /* ECMERRCTLR23 */
    [21]  =     {0xE6250060U, 0x7E788AD9U}, /* ECMERRCTLR24 */
    [22]  =     {0xE6250064U, 0xC7807AB7U}, /* ECMERRCTLR25 */
    [23]  =     {0xE6250068U, 0x7E90C008U}, /* ECMERRCTLR26 */
    [24]  =     {0xE625006CU, 0x7E788AD9U}, /* ECMERRCTLR27 */
    [25]  =     {0xE6250070U, 0xC7807AB7U}, /* ECMERRCTLR28 */
    [26]  =     {0xE6250074U, 0x0010C008U}, /* ECMERRCTLR29 */
    [27]  =     {0xE6250078U, 0x7E608A99U}, /* ECMERRCTLR30 */
    [28]  =     {0xE625007CU, 0x84007A00U}, /* ECMERRCTLR31 */
    [29]  =     {0xE6250080U, 0xDFFFFFFFU}, /* ECMERRCTLR32 */
    [30]  =     {0xE6250084U, 0x1FFFFFFFU}, /* ECMERRCTLR33 */
    [31]  =     {0xE6250088U, 0x0000001FU}, /* ECMERRCTLR34 */
    [32]  =     {0xE625008CU, 0xA3BEEA80U}, /* ECMERRCTLR35 */
    [33]  =     {0xE6250090U, 0xFFFFFFFFU}, /* ECMERRCTLR36 */
        /* Skip ECMERRCTLR37 setting */
    [34]  =     {0xE6250098U, 0xFFF000FFU}, /* ECMERRCTLR38 */
    [35]  =     {0xE625009CU, 0x19FF0000U}, /* ECMERRCTLR39 */
    [36]  =     {0xE62500A0U, 0x0000601EU}, /* ECMERRCTLR40 */
    [37]  =     {0xE62500A4U, 0xEFFF7FFBU}, /* ECMERRCTLR41 */
    [38]  =     {0xE62500A8U, 0x0000000FU}, /* ECMERRCTLR42 */
    };

#if (ECMERRTGTR_INTC == 1)
    const ECM_ERROR_TABLE ecmerrtgtr_tbl[ECM_ERR_REG_MAX] = {
    [0]   =     {0xE6250200U, 0xFFFFF003U}, /* ECMERRTGTR0 */
    [1]   =     {0xE6250204U, 0xA7F8C000U}, /* ECMERRTGTR1 */
    [2]   =     {0xE6250208U, 0xFFFFFFFFU}, /* ECMERRTGTR2 */
    [3]   =     {0xE625020CU, 0xFFFFFFFFU}, /* ECMERRTGTR3 */
    [4]   =     {0xE6250210U, 0xFFFFFFFFU}, /* ECMERRTGTR4 */
    [5]   =     {0xE6250214U, 0x8FFFFFFFU}, /* ECMERRTGTR5 */
    [6]   =     {0xE6250218U, 0xFF000A80U}, /* ECMERRTGTR6 */
    [7]   =     {0xE625021CU, 0x68980FFFU}, /* ECMERRTGTR7 */
    [8]   =     {0xE6250220U, 0x60A00000U}, /* ECMERRTGTR8 */
    [9]   =     {0xE6250224U, 0xFF000000U}, /* ECMERRTGTR9 */
    [10]  =     {0xE6250228U, 0x557D554CU}, /* ECMERRTGTR10 */
    [11]  =     {0xE625022CU, 0xFF3C1555U}, /* ECMERRTGTR11 */
    [12]  =     {0xE6250230U, 0x0003FFFFU}, /* ECMERRTGTR12 */
        /* Skip ECMERRTGTR13 setting */
        /* Skip ECMERRTGTR14 setting */
        /* Skip ECMERRTGTR15 setting */
    [13]  =     {0xE6250240U, 0x33F03FFFU}, /* ECMERRTGTR16 */
    [14]  =     {0xE6250244U, 0x2DFF9CE0U}, /* ECMERRTGTR17 */
    [15]  =     {0xE6250248U, 0x0CC037FFU}, /* ECMERRTGTR18 */
    [16]  =     {0xE625024CU, 0xFFFFFF31U}, /* ECMERRTGTR19 */
    [17]  =     {0xE6250250U, 0xFE60067EU}, /* ECMERRTGTR20 */
    [18]  =     {0xE6250254U, 0xBF61820FU}, /* ECMERRTGTR21 */
    [19]  =     {0xE6250258U, 0x10000000U}, /* ECMERRTGTR22 */
    [20]  =     {0xE625025CU, 0x7E90C008U}, /* ECMERRTGTR23 */
    [21]  =     {0xE6250260U, 0x7E788AD9U}, /* ECMERRTGTR24 */
    [22]  =     {0xE6250264U, 0xC7807AB7U}, /* ECMERRTGTR25 */
    [23]  =     {0xE6250268U, 0x7E90C008U}, /* ECMERRTGTR26 */
    [24]  =     {0xE625026CU, 0x7E788AD9U}, /* ECMERRTGTR27 */
    [25]  =     {0xE6250270U, 0xC7807AB7U}, /* ECMERRTGTR28 */
    [26]  =     {0xE6250274U, 0x0010C008U}, /* ECMERRTGTR29 */
    [27]  =     {0xE6250278U, 0x7E608A99U}, /* ECMERRTGTR30 */
    [28]  =     {0xE625027CU, 0x84007A00U}, /* ECMERRTGTR31 */
    [29]  =     {0xE6250280U, 0xDFFFFFFFU}, /* ECMERRTGTR32 */
    [30]  =     {0xE6250284U, 0x1FFFFFFFU}, /* ECMERRTGTR33 */
    [31]  =     {0xE6250288U, 0x0000001FU}, /* ECMERRTGTR34 */
    [32]  =     {0xE625028CU, 0xA3BEEA80U}, /* ECMERRTGTR35 */
    [33]  =     {0xE6250290U, 0xFFFFFFFFU}, /* ECMERRTGTR36 */
        /* Skip ECMERRTGTR37 setting */
    [34]  =     {0xE6250298U, 0xFFF000FFU}, /* ECMERRTGTR38 */
    [35]  =     {0xE625029CU, 0x19FF0000U}, /* ECMERRTGTR39 */
    [36]  =     {0xE62502A0U, 0x0000601EU}, /* ECMERRTGTR40 */
    [37]  =     {0xE62502A4U, 0xEFFF7FFBU}, /* ECMERRTGTR41 */
    [38]  =     {0xE62502A8U, 0x0000000FU}, /* 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 */
        /* Skip ECMERRTGTR13 setting */
        /* Skip ECMERRTGTR14 setting */
        /* Skip ECMERRTGTR15 setting */
    [13]  =     {0xE6250240U, 0x00000000U}, /* ECMERRTGTR16 */
    [14]  =     {0xE6250244U, 0x00000000U}, /* ECMERRTGTR17 */
    [15]  =     {0xE6250248U, 0x00000000U}, /* ECMERRTGTR18 */
    [16]  =     {0xE625024CU, 0x00000000U}, /* ECMERRTGTR19 */
    [17]  =     {0xE6250250U, 0x00000000U}, /* ECMERRTGTR20 */
    [18]  =     {0xE6250254U, 0x00000000U}, /* ECMERRTGTR21 */
    [19]  =     {0xE6250258U, 0x00000000U}, /* ECMERRTGTR22 */
    [20]  =     {0xE625025CU, 0x00000000U}, /* ECMERRTGTR23 */
    [21]  =     {0xE6250260U, 0x00000000U}, /* ECMERRTGTR24 */
    [22]  =     {0xE6250264U, 0x00000000U}, /* ECMERRTGTR25 */
    [23]  =     {0xE6250268U, 0x00000000U}, /* ECMERRTGTR26 */
    [24]  =     {0xE625026CU, 0x00000000U}, /* ECMERRTGTR27 */
    [25]  =     {0xE6250270U, 0x00000000U}, /* ECMERRTGTR28 */
    [26]  =     {0xE6250274U, 0x00000000U}, /* ECMERRTGTR29 */
    [27]  =     {0xE6250278U, 0x00000000U}, /* ECMERRTGTR30 */
    [28]  =     {0xE625027CU, 0x00000000U}, /* ECMERRTGTR31 */
    [29]  =     {0xE6250280U, 0x00000000U}, /* ECMERRTGTR32 */
    [30]  =     {0xE6250284U, 0x00000000U}, /* ECMERRTGTR33 */
    [31]  =     {0xE6250288U, 0x00000000U}, /* ECMERRTGTR34 */
    [32]  =     {0xE625028CU, 0x00000000U}, /* ECMERRTGTR35 */
    [33]  =     {0xE6250290U, 0x00000000U}, /* ECMERRTGTR36 */
        /* Skip ECMERRTGTR37 setting */
    [34]  =     {0xE6250298U, 0x00000000U}, /* ECMERRTGTR38 */
    [35]  =     {0xE625029CU, 0x00000000U}, /* ECMERRTGTR39 */
    [36]  =     {0xE62502A0U, 0x00000000U}, /* ECMERRTGTR40 */
    [37]  =     {0xE62502A4U, 0x00000000U}, /* ECMERRTGTR41 */
    [38]  =     {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 */

