This commit is contained in:
2025-12-24 17:21:08 +09:00
parent a96323de19
commit 96dc62d8dc
2302 changed files with 455822 additions and 0 deletions

View File

@@ -0,0 +1,115 @@
/*******************************************************************************
* 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 2023 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : AVS driver
******************************************************************************/
/******************************************************************************
* @file avs.c
* - Version : 0.01
* @brief AVS driver.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 16.11.2023 0.01 First Release
*****************************************************************************/
#include <stdint.h>
#include <avs.h>
#include <i2c.h>
#include <log.h>
#include <mem_io.h>
#include <remap_register.h>
#define AVS_BASE (BASE_AVS_ADDR) /* Physical address:0xE60A0000, Logical address:0xFDAA0000 */
#define AVS_ADVADJP (AVS_BASE + 0x0080U)
#define ADVADJP_VOLCOND_MASK (0x000001FFU)
#define VOLCOND_NUM (5U) /* Array number */
#define VOLCOND_FLAG_4 (4U)
#define VOLCOND_FLAG_2 (2U)
/* I2C Slave Address */
#define SLAVE_RW_ADDR (0x000000C8U)
/* PMIC register Address */
#define BUCK1_DVS0CFG1 (0x00000072U)
#define BUCK1_DVS0CFG0 (0x00000073U)
#define DVS_CFG_NUM (2U) /* Array number */
/* PMIC register setting value */
#define BUCK1_DVS0CFG1_VOLCOND2 (0x0000009FU) /* Setting value for 0.7575[V] */
#define BUCK1_DVS0CFG0_VOLCOND2 (0x000000C0U) /* Setting value for 0.7575[V] */
#define BUCK1_DVS0CFG1_VOLCOND4 (0x0000009AU) /* Setting value for 0.7325[V] */
#define BUCK1_DVS0CFG0_VOLCOND4 (0x00000080U) /* Setting value for 0.7325[V] */
void avs_low_power_mode_setting(void)
{
uint32_t volcond;
/* Initialize I2C ch3. */
i2c3_init();
/* Confirm VOLCOND in ADVADJP register. */
volcond = mem_read32(AVS_ADVADJP);
volcond &= ADVADJP_VOLCOND_MASK;
NOTICE("Low Power Mode setting(AVS) VOLCOND=%d\n", volcond);
switch (volcond)
{
case VOLCOND_FLAG_2:
{
/* In case of VOLCOND=2, set supply voltage to 0.7575[V]. */
i2c3_write(SLAVE_RW_ADDR, BUCK1_DVS0CFG1, BUCK1_DVS0CFG1_VOLCOND2);
i2c3_write(SLAVE_RW_ADDR, BUCK1_DVS0CFG0, BUCK1_DVS0CFG0_VOLCOND2);
INFO("VOLCOND=0x%x SET Slave=0x%x Register=0x%x Value=0x%x\n",
volcond, SLAVE_RW_ADDR, BUCK1_DVS0CFG1, BUCK1_DVS0CFG1_VOLCOND2);
INFO("VOLCOND=0x%x SET Slave=0x%x Register=0x%x Value=0x%x\n",
volcond, SLAVE_RW_ADDR, BUCK1_DVS0CFG0, BUCK1_DVS0CFG0_VOLCOND2);
break;
}
case VOLCOND_FLAG_4:
{
/* In case of VOLCOND=4, set supply voltage to 0.7325[V]. */
i2c3_write(SLAVE_RW_ADDR, BUCK1_DVS0CFG1, BUCK1_DVS0CFG1_VOLCOND4);
i2c3_write(SLAVE_RW_ADDR, BUCK1_DVS0CFG0, BUCK1_DVS0CFG0_VOLCOND4);
INFO("VOLCOND=0x%x SET Slave=0x%x Register=0x%x Value=0x%x\n",
volcond, SLAVE_RW_ADDR, BUCK1_DVS0CFG1, BUCK1_DVS0CFG1_VOLCOND4);
INFO("VOLCOND=0x%x SET Slave=0x%x Register=0x%x Value=0x%x\n",
volcond, SLAVE_RW_ADDR, BUCK1_DVS0CFG0, BUCK1_DVS0CFG0_VOLCOND4);
break;
}
default:
{
/* Other than VOLCOND = 2 or 4, nothing to do. */
break;
}
}
/* Release I2C ch3 */
i2c3_release();
}
/* End of function avs_low_power_mode_setting(void) */

View File

@@ -0,0 +1,83 @@
/*******************************************************************************
* 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 2021-2024 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : CPG initialize
******************************************************************************/
/******************************************************************************
* @file cpg.c
* - Version : 0.03
* @brief Initial setting process of CPG.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 28.07.2021 0.01 First Release
* : 03.09.2021 0.02 Move cpg_reg_write function to cpg.h.
* : 27.12.2024 0.03 Add set_srcr function.
*****************************************************************************/
#include <cpg.h>
#include <cnf_tbl.h>
#if (RCAR_LSI == RCAR_V4H)
#include <cpg_register.h>
#endif /* RCAR_LSI == RCAR_V4H */
/* CPG write protect value */
#define CPGWPCR_PASSWORD (0xA5A50000U)
#define CPGWPCR_WPE ((uint32_t)1U << 0U)
#define CPGWPCR_WPE_VALID (0U)
#if (RCAR_LSI == RCAR_V4H)
static void set_srcr(void);
#endif /* RCAR_LSI == RCAR_V4H */
void cpg_init(void)
{
/* Release CPG write protect */
if((mem_read32(CPG_CPGWPCR) & CPGWPCR_WPE) != CPGWPCR_WPE_VALID)
{
mem_write32(CPG_CPGWPR, ~(uint32_t)(CPGWPCR_PASSWORD));
mem_write32(CPG_CPGWPCR, CPGWPCR_PASSWORD);
/* bit in WPE = 0? */
while ((mem_read32(CPG_CPGWPCR) & CPGWPCR_WPE) != CPGWPCR_WPE_VALID)
{
;
}
}
#if (RCAR_LSI == RCAR_V4H)
set_srcr();
#endif /* RCAR_LSI == RCAR_V4H */
}
/* End of function cpg_init(void) */
#if (RCAR_LSI == RCAR_V4H)
static void set_srcr(void)
{
mem_write32(CPG_SRCR28, CPGSRCR28_VAL);
mem_write32(CPG_SRCR29, CPGSRCR29_VAL);
}
/* End of function set_srcr(void) */
#endif /* RCAR_LSI == RCAR_V4H */

View File

@@ -0,0 +1,16 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation All rights reserved.
*/
#ifndef __BOOT_INIT_DRAM_
#define __BOOT_INIT_DRAM_
extern int32_t InitDram(void);
#define INITDRAM_OK (0)
#define INITDRAM_NG (0xffffffff)
#define INITDRAM_ERR_I (0xffffffff)
#define INITDRAM_ERR_O (0xfffffffe)
#define INITDRAM_ERR_T (0xfffffff0)
#endif /* __BOOT_INIT_DRAM_*/

View File

@@ -0,0 +1,6 @@
#
# Copyright (c) 2015-2022, Renesas Electronics Corporation All rights reserved.
#
OBJ_FILE += ip/ddr/s4/lpddr4x/boot_init_dram.o
OBJ_FILE += ip/ddr/dram_sub_func.o

View File

@@ -0,0 +1,17 @@
/*
* Copyright (c) 2015-2018, Renesas Electronics Corporation All rights reserved.
*/
#include <stdint.h>
#include "dram_sub_func.h"
void dram_get_boot_status(uint32_t *status)
{
*status = DRAM_BOOT_STATUS_COLD;
}
int32_t dram_update_boot_status(uint32_t status)
{
int32_t ret = 0;
return ret;
}

View File

@@ -0,0 +1,16 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation All rights reserved.
*/
#ifndef DRAM_SUB_FUNC_H_
#define DRAM_SUB_FUNC_H_
#define DRAM_BOOT_STATUS_COLD (0U)
#define DRAM_BOOT_STATUS_WARM (1U)
#define DRAM_UPDATE_STATUS_ERR (-1)
void dram_get_boot_status(uint32_t *status);
int32_t dram_update_boot_status(uint32_t status);
#endif /* DRAM_SUB_FUNC_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,254 @@
/*******************************************************************************
* Copyright (c) 2021-2022 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.
******************************************************************************/
/*******************************************************************************
* DRAM Param setting
******************************************************************************/
#define JS2_DERATE 0
#define DBSC_REFINT 1920 /* Average periodic refresh interval/Average Refresh Interval [ns] */
#define DBSC_REFINTS 0 /* 0: Average interval is REFINT. / 1: Average interval is 1/2 REFINT. */
#define REWT_TRAINING_INTERVAL 20000 /* Periodic-WriteDQ Training Interval [us] */
/*******************************************************************************
* NUMBER OF BOARD CONFIGRATION
* PLEASE DEFINE
******************************************************************************/
#define BOARDNUM 3 /* Add User platform BOARD */
/*******************************************************************************
* PLEASE SET board number or board judge function
******************************************************************************/
#define BOARD_JUDGE_AUTO
#ifdef BOARD_JUDGE_AUTO
static uint32_t _board_judge(void);
static uint32_t boardcnf_get_brd_type(void) {
return _board_judge();
}
#else /* BOARD_JUDGE_AUTO */
static uint32_t boardcnf_get_brd_type(void) {
return (0);
}
#endif /* BOARD_JUDGE_AUTO */
/*******************************************************************************
* BOARD CONFIGRATION
* PLEASE DEFINE boardcnfs[]
******************************************************************************/
struct _boardcnf_ch {
/*
0x00...0000B: 4Gb dual channel die / 2Gb single channel die
0x01...0001B: 6Gb dual channel die / 3Gb single channel die
0x02...0010B: 8Gb dual channel die / 4Gb single channel die
0x03...0011B: 12Gb dual channel die / 6Gb single channel die
0x04...0100B: 16Gb dual channel die / 8Gb single channel die
0xff...NO_MEMORY
*/
uint8_t ddr_density[CS_CNT];
/* SoC caX([5][4][3][2][1][0]) -> MEM caY: */
uint32_t ca_swap;
/* SoC dqsX([3][2][1][0]) -> MEM dqsY: */
uint16_t dqs_swap;
/* SoC dq([7][6][5][4][3][2][1][0]) -> MEM dqY/dm: (8 means DM) */
uint32_t dq_swap[SLICE_CNT];
/* SoC dm -> MEM dqY/dm: (8 means DM) */
uint8_t dm_swap[SLICE_CNT];
};
struct _boardcnf {
/* ch in use */
uint16_t phyvalid;
/* Read vref (SoC) training range : [15:8]stop / [7:0]start, 0x0000 = default val */
uint16_t vref_r;
/* Write vref (MR14) training range : [15:8]stop / [7:0]start, 0x0000 = default val */
uint16_t vref_w;
/* CA vref (MR12) training range : [15:8]stop / [7:0]start, 0x0000 = default val */
uint16_t vref_ca;
struct _boardcnf_ch ch[2];
};
static const struct _boardcnf boardcnfs[BOARDNUM] = {
/*
* boardcnf[0] RENESAS S4 Spider (16Gbit 2rank)
*/
{
0x03, /* phyvalid */
0x0000, /* vref_r */
0x0000, /* vref_w */
0x0000, /* vref_ca */
{
/* ch[0] */ { /* M0CAxB/M0DQ[23:16],M0DQ[31:24] */
/* ddr_density[] */ { 0x04, 0x04 },
/* ca_swap */ 0x243510U,
/* dqs_swap */ 0x10,
/* dq_swap[] */ { 0x21706345, 0x23510746 },
/* dm_swap[] */ { 0x08, 0x08 }
},
/* ch[1] */ { /* M0CAxA/M0DQ[15: 0] */
/* ddr_density[] */ { 0x04, 0x04 },
/* ca_swap */ 0x345210U,
/* dqs_swap */ 0x10,
/* dq_swap[] */ { 0x30124675, 0x53126047 },
/* dm_swap[] */ { 0x08, 0x08 }
}
}
},
/*
* boardcnf[1] RENESAS S4-N Spider (16Gbit 2rank)
*/
{
0x03, /* phyvalid */
0x0000, /* vref_r */
0x0000, /* vref_w */
0x0000, /* vref_ca */
{
/* ch[0] */ { /* M0CAxB/M0DQ[23:16],M0DQ[31:24] */
/* ddr_density[] */ { 0x04, 0x04 },
/* ca_swap */ 0x243510U,
/* dqs_swap */ 0x10,
/* dq_swap[] */ { 0x21705634, 0x23516048 },
/* dm_swap[] */ { 0x08, 0x07 }
},
/* ch[1] */ { /* M0CAxA/M0DQ[15: 0] */
/* ddr_density[] */ { 0x04, 0x04 },
/* ca_swap */ 0x345201U,
/* dqs_swap */ 0x10,
/* dq_swap[] */ { 0x03124675, 0x35126047 },
/* dm_swap[] */ { 0x08, 0x08 }
}
}
},
/*
* boardcnf[2] RENESAS S4(2ch)
*/
{
0x03, /* phyvalid */
0x0000, /* vref_r */
0x0000, /* vref_w */
0x0000, /* vref_ca */
{
/* ch[0] */ {
/* ddr_density[] */ { 0x04, 0x04 },
/* ca_swap */ 0x00543210U,
/* dqs_swap */ 0x10,
/* dq_swap[] */ { 0x76543210, 0x76543210 },
/* dm_swap[] */ { 0x08, 0x08 }
},
/* ch[1] */ {
/* ddr_density[] */ { 0x04, 0x04 },
/* ca_swap */ 0x00543210U,
/* dqs_swap */ 0x10,
/* dq_swap[] */ { 0x76543210, 0x76543210 },
/* dm_swap[] */ { 0x08, 0x08 }
}
}
}
};
/*******************************************************************************
* EXTAL CLOCK DEFINITION
* PLEASE DEFINE HOW TO JUDGE BORAD CLK
******************************************************************************/
/*
* RENESAS SPIDER BOARD EXAMPLE
* judge by md14/md13
*
* 16.00MHz CLK,DIV= 48,3 (md14,md13==0,0)
* 20.00MHz CLK,DIV= 60,3 (md14,md13==0,1)
* 40.00MHz CLK,DIV=120,3 (md14,md13==1,1)
*/
void boardcnf_get_brd_clk(uint32_t brd, uint32_t *clk, uint32_t *div) {
uint32_t md;
md = (mmio_read_32(RST_MODEMR0) >> 13) & 0x3;
switch(md) {
case 0x0 : *clk = 48; *div = 3; break; /* 48 / 3 = 16.00MHz */
case 0x1 : *clk = 60; *div = 3; break; /* 60 / 3 = 20.00MHz */
/* case 0x2 : *clk = 75; *div = 3; break; */ /* Not supported */
case 0x3 : *clk =120; *div = 3; break; /* 120 / 3 = 40.00MHz */
}
(void)brd;
}
/*******************************************************************************
* DDR MBPS TARGET
* PLEASE DEFINE HOW TO JUDGE DDR BPS
******************************************************************************/
/*
DDRxxxx (judge by md17) : Mbps
SSCG enable / disable for PLL1 (judge by md37/md36)
*/
void boardcnf_get_ddr_mbps(uint32_t brd, uint32_t *mbps, uint32_t *div) {
uint32_t md;
uint32_t sscg;
md = (mmio_read_32(RST_MODEMR0) >> 17) & 0x01U;
sscg = (mmio_read_32(RST_MODEMR1) >> 4) & 0x03U;
switch(sscg) {
case 0x0 :
switch(md) {
case 0x0 : *mbps = 3200; *div = 1; break;
case 0x1 : *mbps = 2120; *div = 1; break;
}
break;
case 0x1 :
switch(md) {
case 0x0 : *mbps = 3120; *div = 1; break;
case 0x1 : *mbps = 2120; *div = 1; break;
}
break;
case 0x2 :
switch(md) {
case 0x0 : *mbps = 3040; *div = 1; break;
case 0x1 : *mbps = 2120; *div = 1; break;
}
break;
case 0x3 :
switch(md) {
case 0x0 : *mbps = 3000; *div = 1; break;
case 0x1 : *mbps = 2120; *div = 1; break;
}
break;
}
(void)brd;
}
#ifdef BOARD_JUDGE_AUTO
/*******************************************************************************
* SAMPLE board detect function
******************************************************************************/
static uint32_t _board_judge(void) {
uint32_t brd;
brd = 0; /* spider (16Gbit 2rank)*/
return brd;
}
#endif

View File

@@ -0,0 +1,73 @@
/*******************************************************************************
* File Name : boot_init_dram_config.h
* Version : 1.0
* Description : This file containing structure definitions for board settings
******************************************************************************/
/*****************************************************************************
* History : Please refer the readme.txt
*
******************************************************************************/
/*******************************************************************************
* 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
* © 2020-2023 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
#ifndef BOOT_INIT_DRAM_CONFIG
#define BOOT_INIT_DRAM_CONFIG
#include <stdint.h>
#include "boot_init_dram_regdef.h"
/*******************************************************************************
* DRAM Param setting
* this parameter is depending on the user
******************************************************************************/
#define JS2_DERATE 0
#define BOARDNUM 5
#define USE_BOARD 0
/*******************************************************************************
* BOARD CONFIGRATION
* PLEASE DEFINE boardcnfs[]
******************************************************************************/
struct board_cfg_t
{
uint32_t phyvalid;
uint32_t vref_r;
uint32_t vref_w;
uint32_t vref_ca;
uint32_t ddr_density[CH_CNT][CS_CNT];
uint32_t ca_swap[CH_CNT];
uint32_t dqs_swap[CH_CNT];
uint32_t dq_swap[CH_CNT][SLICE_CNT];
uint32_t dm_swap[CH_CNT][SLICE_CNT];
};
void judge_board_clk_freq(uint32_t* board_clk, uint32_t* board_clkdiv, uint32_t* board_clkdiva);
void judge_ddr_ope_freq(uint32_t* ddr_mbps, uint32_t* ddr_mbpsdiv);
void judge_bus_clk_freq(uint32_t* bus_mbps, uint32_t* bus_mbpsdiv, const uint32_t* board_clk, const uint32_t* board_clkdiv);
extern const struct board_cfg_t board_cfg[BOARDNUM];
#endif /* BOOT_INIT_DRAM_CONFIG */

View File

@@ -0,0 +1,260 @@
/*******************************************************************************
* Copyright (c) 2021-2022 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.
******************************************************************************/
#if defined(__RH850G3K__)
#include "remap_register.h"
#endif
#define RCAR_DDR_VERSION "rev.0.30rc7"
#define DRAM_CH_CNT 0x02
#define SLICE_CNT 0x02
#define CS_CNT 0x02
/* for pll setting */
#define CLK_DIV(a, diva, b, divb) (((a) * (divb)) / ((b) * (diva)))
#define CLK_MUL(a, diva, b, divb) (((a) * (b)) / ((diva) * (divb)))
/* for ddr density setting */
#define DBMEMCONF_REG(d3, row, bank, col, dw) (((d3) << 30) | ((row) << 24) | ((bank) << 16) | ((col) << 8) | (dw))
#define DBMEMCONF_REGD(density) (DBMEMCONF_REG((density) % 2, ((density) + 1) / 2 + (28 - 3 - 10 - 1), 3, 10, 1)) /* 16bit */
#define DBMEMCONF_VAL(ch,cs) (DBMEMCONF_REGD(DBMEMCONF_DENS(ch, cs)))
/* system registers : CPG */
#define CPG_FRQCRD_KICK_BIT (1U << 31)
#define CPG_PLL3CR_KICK_BIT (1U << 31)
#define CPG_PLLECR_PLL3E_BIT (1U << 3)
#define CPG_PLLECR_PLL3ST_BIT (1U << 11)
#if defined(__RH850G3K__)
#define CPG_BASE (BASE_CPG_ADDR)
#else
#define CPG_BASE (0xE6150000U)
#endif
#define CPG_CPGWPR (CPG_BASE + 0x0000U)
#define CPG_CPGWPCR (CPG_BASE + 0x0004U)
#define CPG_FRQCRA (CPG_BASE + 0x0800U)
#define CPG_FRQCRB (CPG_BASE + 0x0804U)
#define CPG_FRQCRC (CPG_BASE + 0x0808U)
#define CPG_FRQCRD (CPG_BASE + 0x080CU)
#define CPG_PLLECR (CPG_BASE + 0x0820U)
#define CPG_PLL3CR0 (CPG_BASE + 0x083CU)
#define CPG_PLL3CR1 (CPG_BASE + 0x08C0U)
#define CPG_Z0CKKSCR (CPG_BASE + 0x08A8U)
#define CPG_Z1CKKSCR (CPG_BASE + 0x08ACU)
#define CPG_SRST4 (CPG_BASE + 0x2C10U)
#define CPG_SRSTCLR4 (CPG_BASE + 0x2C90U)
#define CPG_FSRCHKRA4 (CPG_BASE + 0x0410U)
#define CPG_FSRCHKSETR4 (CPG_BASE + 0x0510U)
#define CPG_FSRCHKCLRR4 (CPG_BASE + 0x0590U)
#if defined(__RH850G3K__)
#define RST_BASE (BASE_RESET_ADDR)
#else
#define RST_BASE (0xE6160000U)
#endif
#define RST_MODEMR0 (RST_BASE + 0x0000U)
#define RST_MODEMR1 (RST_BASE + 0x0004U)
/* Product Register */
#define PRR (0xFFF00044U)
#define PRR_PRODUCT_MASK (0x00007F00U)
#define PRR_CUT_MASK (0x000000FFU)
#define PRR_PRODUCT_S4 (0x00005A00U) /* R-Car S4 */
#define PRR_PRODUCT_10 (0x00000000U) /* ver 1.0 */
#define PRR_PRODUCT_11 (0x00000001U) /* ver 1.1 */
#define PRR_PRODUCT_12 (0x00000002U) /* ver 1.2 */
/* DBSC registers */
#if defined(__RH850G3K__)
#define DBSC_BASE (BASE_DBSC_ADDR)
#else
#define DBSC_BASE (0xE6790000U)
#endif
#define DBSC_DBSYSCONF0 (DBSC_BASE + 0x0000U)
#define DBSC_DBSYSCONF1 (DBSC_BASE + 0x0004U)
#define DBSC_DBSYSCONF1A (DBSC_BASE + 0x0008U)
#define DBSC_DBSYSCONF2 (DBSC_BASE + 0x000CU)
#define DBSC_DBPHYCONF0 (DBSC_BASE + 0x0010U)
#define DBSC_DBSYSCONF2A (DBSC_BASE + 0x0014U)
#define DBSC_DBKIND (DBSC_BASE + 0x0020U)
#define DBSC_DBKINDA (DBSC_BASE + 0x0024U)
#define DBSC_DBMEMCONF(ch, cs) (DBSC_BASE + 0x0030U + 0x2000U * (ch & 0x04U) + 0x10U * (ch & 0x03U) + 0x04U * cs)
#define DBSC_DBMEMCONF_0_0 (DBSC_BASE + 0x0030U)
#define DBSC_DBMEMCONF_0_1 (DBSC_BASE + 0x0034U)
#define DBSC_DBMEMCONF_0_2 (DBSC_BASE + 0x0038U)
#define DBSC_DBMEMCONF_0_3 (DBSC_BASE + 0x003CU)
#define DBSC_DBMEMCONF_1_0 (DBSC_BASE + 0x0040U)
#define DBSC_DBMEMCONF_1_1 (DBSC_BASE + 0x0044U)
#define DBSC_DBMEMCONF_1_2 (DBSC_BASE + 0x0048U)
#define DBSC_DBMEMCONF_1_3 (DBSC_BASE + 0x004CU)
#define DBSC_DBMEMCONF_2_0 (DBSC_BASE + 0x0050U)
#define DBSC_DBMEMCONF_2_1 (DBSC_BASE + 0x0054U)
#define DBSC_DBMEMCONF_2_2 (DBSC_BASE + 0x0058U)
#define DBSC_DBMEMCONF_2_3 (DBSC_BASE + 0x005CU)
#define DBSC_DBMEMCONF_3_0 (DBSC_BASE + 0x0060U)
#define DBSC_DBMEMCONF_3_1 (DBSC_BASE + 0x0064U)
#define DBSC_DBMEMCONF_3_2 (DBSC_BASE + 0x0068U)
#define DBSC_DBMEMCONF_3_3 (DBSC_BASE + 0x006CU)
#define DBSC_DBMEMCONFA(ch, cs) (DBSC_BASE + 0x0070U + 0x2000U * (ch & 0x04U) + 0x10U * (ch & 0x03U) + 0x04U * cs)
#define DBSC_DBMEMCONF_0_0A (DBSC_BASE + 0x0070U)
#define DBSC_DBMEMCONF_0_1A (DBSC_BASE + 0x0074U)
#define DBSC_DBMEMCONF_0_2A (DBSC_BASE + 0x0078U)
#define DBSC_DBMEMCONF_0_3A (DBSC_BASE + 0x007CU)
#define DBSC_DBMEMCONF_1_0A (DBSC_BASE + 0x0080U)
#define DBSC_DBMEMCONF_1_1A (DBSC_BASE + 0x0084U)
#define DBSC_DBMEMCONF_1_2A (DBSC_BASE + 0x0088U)
#define DBSC_DBMEMCONF_1_3A (DBSC_BASE + 0x008CU)
#define DBSC_DBMEMCONF_2_0A (DBSC_BASE + 0x0090U)
#define DBSC_DBMEMCONF_2_1A (DBSC_BASE + 0x0094U)
#define DBSC_DBMEMCONF_2_2A (DBSC_BASE + 0x0098U)
#define DBSC_DBMEMCONF_2_3A (DBSC_BASE + 0x009CU)
#define DBSC_DBMEMCONF_3_0A (DBSC_BASE + 0x00A0U)
#define DBSC_DBMEMCONF_3_1A (DBSC_BASE + 0x00A4U)
#define DBSC_DBMEMCONF_3_2A (DBSC_BASE + 0x00A8U)
#define DBSC_DBMEMCONF_3_3A (DBSC_BASE + 0x00ACU)
#define DBSC_DBSYSCNT0 (DBSC_BASE + 0x0100U)
#define DBSC_DBSYSCNT0A (DBSC_BASE + 0x0108U)
#define DBSC_DBACEN (DBSC_BASE + 0x0200U)
#define DBSC_DBRFEN (DBSC_BASE + 0x0204U)
#define DBSC_DBCMD (DBSC_BASE + 0x0208U)
#define DBSC_DBWAIT (DBSC_BASE + 0x0210U)
#define DBSC_DBTR(x) (DBSC_BASE + 0x0300U + 0x04U * (x))
#define DBSC_DBTR0 (DBSC_BASE + 0x0300U)
#define DBSC_DBTR1 (DBSC_BASE + 0x0304U)
#define DBSC_DBTR3 (DBSC_BASE + 0x030CU)
#define DBSC_DBTR4 (DBSC_BASE + 0x0310U)
#define DBSC_DBTR5 (DBSC_BASE + 0x0314U)
#define DBSC_DBTR6 (DBSC_BASE + 0x0318U)
#define DBSC_DBTR7 (DBSC_BASE + 0x031CU)
#define DBSC_DBTR8 (DBSC_BASE + 0x0320U)
#define DBSC_DBTR9 (DBSC_BASE + 0x0324U)
#define DBSC_DBTR10 (DBSC_BASE + 0x0328U)
#define DBSC_DBTR11 (DBSC_BASE + 0x032CU)
#define DBSC_DBTR12 (DBSC_BASE + 0x0330U)
#define DBSC_DBTR13 (DBSC_BASE + 0x0334U)
#define DBSC_DBTR14 (DBSC_BASE + 0x0338U)
#define DBSC_DBTR15 (DBSC_BASE + 0x033CU)
#define DBSC_DBTR16 (DBSC_BASE + 0x0340U)
#define DBSC_DBTR17 (DBSC_BASE + 0x0344U)
#define DBSC_DBTR18 (DBSC_BASE + 0x0348U)
#define DBSC_DBTR19 (DBSC_BASE + 0x034CU)
#define DBSC_DBTR20 (DBSC_BASE + 0x0350U)
#define DBSC_DBTR21 (DBSC_BASE + 0x0354U)
#define DBSC_DBTR22 (DBSC_BASE + 0x0358U)
#define DBSC_DBTR23 (DBSC_BASE + 0x035CU)
#define DBSC_DBTR24 (DBSC_BASE + 0x0360U)
#define DBSC_DBTR25 (DBSC_BASE + 0x0364U)
#define DBSC_DBTR26 (DBSC_BASE + 0x0368U)
#define DBSC_DBBL (DBSC_BASE + 0x0400U)
#define DBSC_DBBLA (DBSC_BASE + 0x0404U)
#define DBSC_DBRFCNF1 (DBSC_BASE + 0x0414U)
#define DBSC_DBRFCNF2 (DBSC_BASE + 0x0418U)
#define DBSC_DBCALCNF (DBSC_BASE + 0x0424U)
#define DBSC_DBRNK(x) (DBSC_BASE + 0x0430U + 0x04U * (x))
#define DBSC_DBRNK2 (DBSC_BASE + 0x0438U)
#define DBSC_DBRNK3 (DBSC_BASE + 0x043CU)
#define DBSC_DBRNK4 (DBSC_BASE + 0x0440U)
#define DBSC_DBRNK5 (DBSC_BASE + 0x0444U)
#define DBSC_DBDBICNT (DBSC_BASE + 0x0518U)
#define DBSC_DBDFIPMSTRCNF (DBSC_BASE + 0x0520U)
#define DBSC_DBDFICUPDCNF (DBSC_BASE + 0x052CU)
#define DBSC_DBDFISTAT(ch) (DBSC_BASE + 0x0600U + 0x2000U * (ch & 0x04U) + 0x40U * (ch & 0x03U))
#define DBSC_DBDFISTAT_0 (DBSC_BASE + 0x0600U)
#define DBSC_DBDFISTAT_1 (DBSC_BASE + 0x0640U)
#define DBSC_DBDFISTAT_2 (DBSC_BASE + 0x0680U)
#define DBSC_DBDFISTAT_3 (DBSC_BASE + 0x06C0U)
#define DBSC_DBDFICNT(ch) (DBSC_BASE + 0x0604U + 0x2000U * (ch & 0x04U) + 0x40U * (ch & 0x03U))
#define DBSC_DBDFICNT_0 (DBSC_BASE + 0x0604U)
#define DBSC_DBDFICNT_1 (DBSC_BASE + 0x0644U)
#define DBSC_DBDFICNT_2 (DBSC_BASE + 0x0684U)
#define DBSC_DBDFICNT_3 (DBSC_BASE + 0x06C4U)
#define DBSC_DBPDCNT2(ch) (DBSC_BASE + 0x0618U + 0x2000U * (ch & 0x04U) + 0x40U * (ch & 0x03U))
#define DBSC_DBPDCNT2_0 (DBSC_BASE + 0x0618U)
#define DBSC_DBPDCNT2_1 (DBSC_BASE + 0x0658U)
#define DBSC_DBPDCNT2_2 (DBSC_BASE + 0x0698U)
#define DBSC_DBPDCNT2_3 (DBSC_BASE + 0x06D8U)
#define DBSC_DBPDCNT3(ch) (DBSC_BASE + 0x061CU + 0x2000U * (ch & 0x04U) + 0x40U * (ch & 0x03U))
#define DBSC_DBPDCNT3_0 (DBSC_BASE + 0x061CU)
#define DBSC_DBPDCNT3_1 (DBSC_BASE + 0x065CU)
#define DBSC_DBPDCNT3_2 (DBSC_BASE + 0x069CU)
#define DBSC_DBPDCNT3_3 (DBSC_BASE + 0x06DCU)
#define DBSC_DBPDLK(ch) (DBSC_BASE + 0x0620U + 0x2000U * (ch & 0x04U) + 0x40U * (ch & 0x03U))
#define DBSC_DBPDLK_0 (DBSC_BASE + 0x0620U)
#define DBSC_DBPDLK_1 (DBSC_BASE + 0x0660U)
#define DBSC_DBPDLK_2 (DBSC_BASE + 0x06a0U)
#define DBSC_DBPDLK_3 (DBSC_BASE + 0x06e0U)
#define DBSC_DBPDRGA(ch) (DBSC_BASE + 0x0624U + 0x2000U * (ch & 0x04U) + 0x40U * (ch & 0x03U))
#define DBSC_DBPDRGA_0 (DBSC_BASE + 0x0624U)
#define DBSC_DBPDRGA_1 (DBSC_BASE + 0x0664U)
#define DBSC_DBPDRGA_2 (DBSC_BASE + 0x06A4U)
#define DBSC_DBPDRGA_3 (DBSC_BASE + 0x06E4U)
#define DBSC_DBPDRGD(ch) (DBSC_BASE + 0x0628U + 0x2000U * (ch & 0x04U) + 0x40U * (ch & 0x03U))
#define DBSC_DBPDRGD_0 (DBSC_BASE + 0x0628U)
#define DBSC_DBPDRGD_1 (DBSC_BASE + 0x0668U)
#define DBSC_DBPDRGD_2 (DBSC_BASE + 0x06A8U)
#define DBSC_DBPDRGD_3 (DBSC_BASE + 0x06E8U)
#define DBSC_DBPDSTAT(ch) (DBSC_BASE + 0x0630U + 0x2000U * (ch & 0x04U) + 0x40U * (ch & 0x03U))
#define DBSC_DBPDSTAT_0 (DBSC_BASE + 0x0630U)
#define DBSC_DBPDSTAT_1 (DBSC_BASE + 0x0670U)
#define DBSC_DBPDSTAT_2 (DBSC_BASE + 0x06B0U)
#define DBSC_DBPDSTAT_3 (DBSC_BASE + 0x06F0U)
#define DBSC_DBPDSTAT1(ch) (DBSC_BASE + 0x0634U + 0x2000U * (ch & 0x04U) + 0x40U * (ch & 0x03U))
#define DBSC_DBBUS0CNF0 (DBSC_BASE + 0x0800U)
#define DBSC_DBBUS0CNF1 (DBSC_BASE + 0x0804U)
#define DBSC_DBBCAMDIS (DBSC_BASE + 0x09FCU)
#define DBSC_DBSCHRW1 (DBSC_BASE + 0x1024U)
#define DBSC_SCFCTST0 (DBSC_BASE + 0x1700U)
#define DBSC_SCFCTST1 (DBSC_BASE + 0x1708U)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,354 @@
/*******************************************************************************
* Copyright (c) 2022-2023 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 : ECC setting function
******************************************************************************/
/******************************************************************************
* @file ecc_enable_s4.c
* - Version : 0.02
* @brief Enable setting process of ECC for DRAM.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 09.08.2022 0.01 First Release
* : 04.04.2023 0.02 Removed stdio.h and string.h.
*****************************************************************************/
#include <stdint.h>
static void ecm_unlock(void);
static void ecm_write(uint32_t adr, uint32_t val);
static void ecm_lock(void);
#include "boot_init_dram_regdef.h"
#include "ecc_enable_s4.h"
static void ecm_unlock(void)
{
uint32_t tmp_adr;
tmp_adr = ((0xACCEU << 16U) | (ECMWPCNTR & 0xffffU));
mem_write32(ECMWACNTR, tmp_adr);
mem_write32(ECMWPCNTR, 0xACCE0001);
}
static void ecm_write(uint32_t adr, uint32_t val)
{
mem_write32(ECMWACNTR, ((0xACCEU << 16U) | (adr & 0xffffU)));
mem_write32(adr, val);
}
static void ecm_lock(void)
{
mem_write32(ECMWACNTR, ((0xACCEU << 16U) | (ECMWACNTR & 0xffffU)));
mem_write32(ECMWPCNTR, 0xACCE0000U);
}
void enable_ecc(void)
{
NOTICE("ECC for DRAM is enable.\n");
uint32_t ecm_tmp;
/* Unlock the access protect for DBSC registers */
mem_write32(DBSC_DBSYSCNT0, 0x00001234U);
mem_write32(DBSC_DBSYSCNT0A, 0x00001234U);
/* (A) Initialization for DRAM */
mmio_write_32(DBSC_DBACEN, 0x00000000U);
/* Unlock the write protect of ECM registers */
ecm_unlock();
/* (1) Set the corresponding bits of the ECMERRTGTR, ECMERRCTLR and ECMERRFATALR registers to inform
the control domain of the fatal error. */
ecm_tmp = mem_read32(ECMERRTGTR0);
ecm_tmp &= ~(0x3U);
ecm_write(ECMERRTGTR0, ecm_tmp);
ecm_tmp = mem_read32(ECMERRCTLR0);
ecm_tmp |= 0x3U;
ecm_write(ECMERRCTLR0, ecm_tmp);
ecm_tmp = mem_read32(ECMERRFATALR0);
ecm_tmp |= 0x3U;
ecm_write(ECMERRFATALR0, ecm_tmp);
/* (B) Setting ECC protection area */
/* Set the bottom row address of the ECC protection area */
mem_write32(DBFSDRAMECCAREA00, ECC_PROT_SIZE0);
mem_write32(DBFSDRAMECCAREA01, ECC_PROT_SIZE1);
/* (2) Initialization for DRAM connected to DBSCCORE */
/* Specify RANK0 as the initialization target */
ecm_tmp = mem_read32(DBFSCONF00A);
ecm_tmp = 0x0U;
mem_write32(DBFSCONF00A, ecm_tmp);
/* Set the start and end row address of the initialization area */
mem_write32(DBFSCONF01A, START_ECC_INIT_AREA0);
mem_write32(DBFSCONF05A, END_ECC_INIT_AREA0);
/* Set 0x1 to start initialization */
ecm_tmp = mem_read32(DBFSCTRL01A);
ecm_tmp |= 0x01U;
mem_write32(DBFSCTRL01A, ecm_tmp);
/* Wait until to DRAM initialization is complete */
NOTICE("DRAM rank 0 is initializing.......\n");
do
{
ecm_tmp = mem_read32(DBFSSTAT01A);
} while ((ecm_tmp & 0x01U) != 0x01U);
/* If DRAM is connected to RANK1, Initialize RANK1 */
/* Specify RANK0 as the initialization target */
ecm_tmp = mem_read32(DBFSCONF00A);
ecm_tmp |= 0x1U;
mem_write32(DBFSCONF00A, ecm_tmp);
/* Set the start and end row address of the initialization area */
mem_write32(DBFSCONF01A, START_ECC_INIT_AREA1);
mem_write32(DBFSCONF05A, END_ECC_INIT_AREA1);
/* Set 0x1 to start initialization */
ecm_tmp = mem_read32(DBFSCTRL01A);
ecm_tmp |= 0x01U;
mem_write32(DBFSCTRL01A, ecm_tmp);
/* Wait until to DRAM initialization is complete */
NOTICE("DRAM rank 1 is initializing.......\n");
do
{
ecm_tmp = mem_read32(DBFSSTAT01A);
} while ((ecm_tmp & 0x01U) != 0x01U);
/* (C) Setting ECC protection enable */
ecm_tmp = mem_read32(DBFSCONFAXI0);
ecm_tmp |= (0x3 << 8U);
mem_write32(DBFSCONFAXI0, ecm_tmp);
/* (D) System RAM initialization */
/* Wait for initialization of System RAM */
NOTICE("System RAM is initializing.......\n");
do
{
;
} while ((mem_read32(DBFSSTAT00A) & 0x1U) != 0x1U);
/* (E) Setting for ECC error interrupt */
/* (1) Set the ECC error interrupt for read data. */
mem_write32(DBFSINTENB02A, 0xFF00U);
/* (2) Set the ECC error interrupt during RMW operation for System RAM. */
ecm_tmp = mem_read32(DBFSINTENB02A);
ecm_tmp |= (0xFFU << 24U);
mem_write32(DBFSINTENB02A, ecm_tmp);
/* (3) Set the ECC error interrupt during RMW operation for DRAM. */
mem_write32(DBFSINTENB04A, 0xFFFFU);
/* Lock the ECM registers */
ecm_lock();
/* Enable the write protect of ECM registers */
mmio_write_32(DBSC_DBACEN, 0x00000001U);
/* Enable the access protect for DBSC registers */
mem_write32(DBSC_DBSYSCNT0, 0x00000000U);
mem_write32(DBSC_DBSYSCNT0A, 0x00000000U);
}
void ecc_rtsram_enable(void)
{
uint32_t ecc_tmp;
/* Unlock the write protect of ECM registers */
ecm_unlock();
/* (1) Set the corresponding bits of the ECMERRTGTR, ECMERRCTLR and
ECMERRFATALR registers to inform the control domain of the fatal error. */
/* Set bit 29 of ECMERRTGTR7 to 0 and bit 29 of ECMERRCTLR7 to 1.
(RT-SRAM ecc 2-bit error) */
ecc_tmp = mem_read32(ECMERRTGTR7);
ecc_tmp |= (1U << 29U) ;
ecm_write(ECMERRTGTR7, ecc_tmp);
ecc_tmp = mem_read32(ECMERRCTLR7);
ecc_tmp |= (1U << 29U);
ecm_write(ECMERRCTLR7, ecc_tmp);
/* Set bit 19 of ECMERRTGTR7 to 0 and bit 19 of ECMERRCTLR7 to 1.
(RT-SRAM ecc 2-bit error (for ICUMX)) */
ecc_tmp = mem_read32(ECMERRTGTR7);
ecc_tmp |= (1U << 19U);
ecm_write(ECMERRTGTR7, ecc_tmp);
ecc_tmp = mem_read32(ECMERRCTLR7);
ecc_tmp |= (1U << 19U);
ecm_write(ECMERRCTLR7, ecc_tmp);
/* Set bit 29 and 19 of ECMERRFATALR7 to 1. (Notification of fatal error) */
ecc_tmp = mem_read32(ECMERRFATALR7);
ecc_tmp |= ((1U << 29U) | (1U << 19U));
ecm_write(ECMERRFATALR7, ecc_tmp);
/* (2) Set the corresponding bits of the ECMERRTGTR and ECMERRCTLR registers to
notify the correctable error to software. */
/* Set bit 30 of ECMERRTGTR7 to 1 and bit 30 of ECMERRCTLR7 to 1.
(RT-SRAM ecc 1-bit error) */
ecc_tmp = mem_read32(ECMERRTGTR7);
ecc_tmp |= (1U << 30U);
ecm_write(ECMERRTGTR7, ecc_tmp);
ecc_tmp = mem_read32(ECMERRCTLR7);
ecc_tmp |= (1U << 30U);
ecm_write(ECMERRCTLR7, ecc_tmp);
/* Set bit 20 of ECMERRTGTR7 to 1 and bit 20 of ECMERRCTLR7 to 1.
(RT-SRAM ecc 1-bit error (for ICUMX)) */
ecc_tmp = mem_read32(ECMERRTGTR7);
ecc_tmp |= (1U << 20U);
ecm_write(ECMERRTGTR7, ecc_tmp);
ecc_tmp = mem_read32(ECMERRCTLR7);
ecc_tmp |= (1U << 20U);
ecm_write(ECMERRCTLR7, ecc_tmp);
/* Lock the ECM registers */
ecm_lock();
}
void edc_axi_enable(void)
{
uint32_t edc_tmp;
/* Unlock the write protect of ECM registers */
ecm_unlock();
/* (1) Set the corresponding bits of the ECMERRTGTR, ECMERRCTLR
and ECMERRFATALR registers to inform the control domain of the fatal error. */
/* Set bit 10 - bit 6 of ECMERRTGTR7 to all 0 and bit 10 - bit 6 of
ECMERRCTLR7 to 1. (Error of AXI-Bus ECM of each hierarchy) */
edc_tmp = mem_read32(ECMERRTGTR7);
edc_tmp &= ~(0x1fU << 6U);
ecm_write(ECMERRTGTR7, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR7);
edc_tmp |= (0x1fU << 6U);
ecm_write(ECMERRCTLR7, edc_tmp);
/* Set bit 23 - bit 16 of ECMERRTGTR39 to all 0 and bit 23 - bit 16 of
ECMERRCTLR39 to 1. (Error of AXI-Bus ECM of each hierarchy) */
edc_tmp = mem_read32(ECMERRTGTR39);
edc_tmp &= ~(0xffU << 16U);
ecm_write(ECMERRTGTR39, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR39);
edc_tmp |= (0xffU << 6U);
ecm_write(ECMERRCTLR39, edc_tmp);
/* Set bit 26 of ECMERRTGTR1 to 0 and bit 26 of
ECMERRCTLR1 to 1. (CCI bus EDC error) */
edc_tmp = mem_read32(ECMERRTGTR1);
edc_tmp &= ~(0x1U << 26U);
ecm_write(ECMERRTGTR1, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR1);
edc_tmp |= (0x1U << 26U);
ecm_write(ECMERRCTLR1, edc_tmp);
/* Set bit 10 - bit 6 of ECMERRFATALR7 to 1.
(Notification of fatal error) */
edc_tmp = mem_read32(ECMERRFATALR7);
edc_tmp |= (0x1fU << 6U);
ecm_write(ECMERRFATALR7, edc_tmp);
/* Set bit 23 - bit 16 of ECMERRFATALR39 to 1.
(Notification of fatal error) */
edc_tmp = mem_read32(ECMERRFATALR39);
edc_tmp |= (0xffU << 16U);
ecm_write(ECMERRFATALR39, edc_tmp);
/* Set bit 26 of ECMERRFATALR1 to 1.
(Notification of fatal error) */
edc_tmp = mem_read32(ECMERRFATALR1);
edc_tmp |= (0x1U << 26U);
ecm_write(ECMERRFATALR1, edc_tmp);
/* Lock the ECM registers */
ecm_lock();
}
void edc_vram_enable(void)
{
uint32_t edc_tmp;
/* Unlock the write protect of ECM registers */
ecm_unlock();
/* (1) Set the corresponding bits of the ECMERRTGTR, ECMERRCTLR and
ECMERRFATALR registers to inform the control domain of the fatal error. */
/* Set bit 19 of ECMERRTGTR17 to 0 and bit 19 of ECMERRCTLR17 to 1.
(RT-VRAM edc 1-bit error) */
edc_tmp = mem_read32(ECMERRTGTR17);
edc_tmp &= ~(0x1U << 19U);
ecm_write(ECMERRTGTR17, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR17);
edc_tmp |= (0x1U << 19U);
ecm_write(ECMERRCTLR17, edc_tmp);
/* Set bit 18 of ECMERRTGTR17 to 0 and bit 18 of ECMERRCTLR17 to 1.
(RT-VRAM edc multi-bit error) */
edc_tmp = mem_read32(ECMERRTGTR17);
edc_tmp &= ~(0x1U << 18U);
ecm_write(ECMERRTGTR17, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR17);
edc_tmp |= (0x1U << 18U);
ecm_write(ECMERRCTLR17, edc_tmp);
/* Set bit 19, 18 of ECMERRFATALR17 to 1. (Notification of fatal error) */
edc_tmp = mem_read32(ECMERRFATALR17);
edc_tmp |= (0x3U << 18U);
ecm_write(ECMERRFATALR17, edc_tmp);
/* Set bit 0 of EDC_CFG to 1. (EDC Error Control) */
edc_tmp = mem_read32(EDC_CFG);
edc_tmp |= (0x1U << 0U);
ecm_write(EDC_CFG, edc_tmp);
/* Lock the ECM registers */
ecm_lock();
}

View File

@@ -0,0 +1,104 @@
/*******************************************************************************
* Copyright (c) 2022 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 : ECC driver header
******************************************************************************/
#ifndef ECC_PROTECT
#define ECC_PROTECT
#include "remap_register.h"
#if(__RH850__)
#include "mem_io.h"
#include "log.h"
#define ECM_BASE (BASE_ECC_ADDR)
#define DBSC_BASE (BASE_DBSC_ADDR)
#else
#include <mmio.h>
#include <debug.h>
#define ECM_BASE (0xE6250000U)
#define DBSC_BASE (0xE6790000U)
#endif/* __RH850__ */
#define RTVRAM_REG_BASE (0xFFEC0000U)
void enable_ecc(void);
void ecc_rtsram_enable(void);
void edc_axi_enable(void);
void edc_vram_enable(void);
#define DBSC_DBACEN (DBSC_BASE + 0x0200U)
#define ECMWACNTR (ECM_BASE + 0x0A04U)
#define ECMWPCNTR (ECM_BASE + 0x0A00U)
#define ECMERRTGTR0 (ECM_BASE + 0x0200U)
#define ECMERRCTLR0 (ECM_BASE + 0x0000U)
#define ECMERRTGTR1 (ECM_BASE + 0x0200U + 0x4U * 1U)
#define ECMERRCTLR1 (ECM_BASE + 0x0000U + 0x4U * 1U)
#define ECMERRTGTR7 (ECM_BASE + 0x0200U + 0x4U * 7U)
#define ECMERRCTLR7 (ECM_BASE + 0x0000U + 0x4U * 7U)
#define ECMERRTGTR17 (ECM_BASE + 0x0200U + 0x4U * 17U)
#define ECMERRCTLR17 (ECM_BASE + 0x0000U + 0x4U * 17U)
#define ECMERRTGTR39 (ECM_BASE + 0x0200U + 0x4U * 39U)
#define ECMERRCTLR39 (ECM_BASE + 0x0000U + 0x4U * 39U)
#define ECMERRFATALR0 (ECM_BASE + 0x0600U)
#define ECMERRFATALR1 (ECM_BASE + 0x0600U + 0x4U * 1U)
#define ECMERRFATALR7 (ECM_BASE + 0x0600U + 0x4U * 7U)
#define ECMERRFATALR17 (ECM_BASE + 0x0600U + 0x4U * 17U)
#define ECMERRFATALR39 (ECM_BASE + 0x0600U + 0x4U * 39U)
#define DBFSCONF00A (DBSC_BASE + 0x7640U)
#define DBFSCONF01A (DBSC_BASE + 0x7644U)
#define DBFSCONF05A (DBSC_BASE + 0x7654U)
#define DBFSCTRL01A (DBSC_BASE + 0x7604U)
#define DBFSSTAT01A (DBSC_BASE + 0x7684U)
#define DBFSSTAT00A (DBSC_BASE + 0x7680U)
#define DBFSINTENB02A (DBSC_BASE + 0x7088U)
#define DBFSINTENB04A (DBSC_BASE + 0x7090U)
#define DBFSDRAMECCAREA00 (DBSC_BASE + 0x7450U)
#define DBFSDRAMECCAREA01 (DBSC_BASE + 0x7454U)
#define DBFSCONFAXI0 (DBSC_BASE + 0x7400U)
#define EDC_CFG (RTVRAM_REG_BASE + 0x4110U)
/********************* Set by the user *********************/
/* The row address of ECC Protection Area Size for memory rank 0/1 */
#define ECC_PROT_SIZE0 (0x2000U)
#define ECC_PROT_SIZE1 (0x2000U)
/* Start and End row address of ECC Protection area for rank0 */
#define START_ECC_INIT_AREA0 (0x00000000U)
#define END_ECC_INIT_AREA0 (0x00001FFFU)
/* Start and End row address of ECC Protection area for rank1 */
#define START_ECC_INIT_AREA1 (0x00000000U)
#define END_ECC_INIT_AREA1 (0x00001FFFU)
/*********** Other settings cannot be changed ***************/
#endif/* ECC_PROTECT */

View File

@@ -0,0 +1,615 @@
/*******************************************************************************
* Copyright (c) 2021-2022 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.
******************************************************************************/
#define DDR_PHY_SLICE_REGSET_OFS_S4 0x1000
#define DDR_PHY_ADR_V_REGSET_OFS_S4 0x1200
#define DDR_PHY_ADR_G_REGSET_OFS_S4 0x1300
#define DDR_PI_REGSET_OFS_S4 0x0800
#define DDR_PHY_SLICE_REGSET_SIZE_S4 0x100
#define DDR_PHY_ADR_V_REGSET_SIZE_S4 0x80
#define DDR_PHY_ADR_G_REGSET_SIZE_S4 0x100
#define DDR_PI_REGSET_SIZE_S4 0x100
#define DDR_PHY_SLICE_REGSET_NUM_S4 140
#define DDR_PHY_ADR_V_REGSET_NUM_S4 54
#define DDR_PHY_ADR_G_REGSET_NUM_S4 143
#define DDR_PI_REGSET_NUM_S4 223
static const uint32_t DDR_PHY_SLICE_REGSET_S4[DDR_PHY_SLICE_REGSET_NUM_S4] = {
/*1000*/ 0x000004F0,
/*1001*/ 0x00000000,
/*1002*/ 0x00030200,
/*1003*/ 0x00000000,
/*1004*/ 0x00000000,
/*1005*/ 0x01030000,
/*1006*/ 0x00010000,
/*1007*/ 0x01030004,
/*1008*/ 0x00000000,
/*1009*/ 0x00000000,
/*100a*/ 0x00000000,
/*100b*/ 0x01000001,
/*100c*/ 0x00000200,
/*100d*/ 0x000800C0,
/*100e*/ 0x06010190,
/*100f*/ 0x00030030,
/*1010*/ 0x00000000,
/*1011*/ 0x00000000,
/*1012*/ 0x55555A3C,
/*1013*/ 0x00005555,
/*1014*/ 0x0000B5B5,
/*1015*/ 0x00004A4A,
/*1016*/ 0x00005656,
/*1017*/ 0x0000A9A9,
/*1018*/ 0x0000A9A9,
/*1019*/ 0x0000B5B5,
/*101a*/ 0x00000000,
/*101b*/ 0x00000000,
/*101c*/ 0x2A000000,
/*101d*/ 0x00000808,
/*101e*/ 0x04000000,
/*101f*/ 0x00000408,
/*1020*/ 0x10600000,
/*1021*/ 0x0C008006,
/*1022*/ 0x00000000,
/*1023*/ 0x00000000,
/*1024*/ 0x55AA55AA,
/*1025*/ 0x33CC33CC,
/*1026*/ 0x0FF00FF0,
/*1027*/ 0x0F0FF0F0,
/*1028*/ 0x00008E38,
/*1029*/ 0x01000100,
/*102a*/ 0x00800180,
/*102b*/ 0x00000001,
/*102c*/ 0x00000000,
/*102d*/ 0x00000000,
/*102e*/ 0x00000000,
/*102f*/ 0x00000000,
/*1030*/ 0x00000000,
/*1031*/ 0x00000000,
/*1032*/ 0x00000000,
/*1033*/ 0x00000000,
/*1034*/ 0x00000000,
/*1035*/ 0x00000000,
/*1036*/ 0x00000000,
/*1037*/ 0x00000000,
/*1038*/ 0x00000000,
/*1039*/ 0x00000000,
/*103a*/ 0x00000000,
/*103b*/ 0x00000000,
/*103c*/ 0x00000000,
/*103d*/ 0x00000000,
/*103e*/ 0x00000000,
/*103f*/ 0x00000000,
/*1040*/ 0x00000000,
/*1041*/ 0x00000000,
/*1042*/ 0x00000104,
/*1043*/ 0x00000120,
/*1044*/ 0x00000000,
/*1045*/ 0x00000000,
/*1046*/ 0x00000000,
/*1047*/ 0x00000000,
/*1048*/ 0x00000000,
/*1049*/ 0x00000000,
/*104a*/ 0x00000000,
/*104b*/ 0x00000000,
/*104c*/ 0x07FF0000,
/*104d*/ 0x00800800,
/*104e*/ 0x00081020,
/*104f*/ 0x04010000,
/*1050*/ 0x00000000,
/*1051*/ 0x00000000,
/*1052*/ 0x00000000,
/*1053*/ 0x00000000,
/*1054*/ 0x01CC0C01,
/*1055*/ 0x2003CC0C,
/*1056*/ 0x20000139,
/*1057*/ 0x07FF0200,
/*1058*/ 0x0100DD01,
/*1059*/ 0x00000103,
/*105a*/ 0x00000000,
/*105b*/ 0x00000000,
/*105c*/ 0x00060000,
/*105d*/ 0x00A000A0,
/*105e*/ 0x00A000A0,
/*105f*/ 0x00A000A0,
/*1060*/ 0x00A000A0,
/*1061*/ 0x000500A0,
/*1062*/ 0x51517042,
/*1063*/ 0x31C08000,
/*1064*/ 0x09AD0064,
/*1065*/ 0x00C0C001,
/*1066*/ 0x0E0C0101,
/*1067*/ 0x10001000,
/*1068*/ 0x0C073E42,
/*1069*/ 0x0F0C3708,
/*106a*/ 0x01C00190,
/*106b*/ 0x04000420,
/*106c*/ 0x00000322,
/*106d*/ 0x0A0000D0,
/*106e*/ 0x00030200,
/*106f*/ 0x02800000,
/*1070*/ 0x80800000,
/*1071*/ 0x000E0010,
/*1072*/ 0x76543210,
/*1073*/ 0x00000008,
/*1074*/ 0x02800280,
/*1075*/ 0x02800280,
/*1076*/ 0x02800280,
/*1077*/ 0x02800280,
/*1078*/ 0x00000280,
/*1079*/ 0x0000A000,
/*107a*/ 0x00A000A0,
/*107b*/ 0x00A000A0,
/*107c*/ 0x00A000A0,
/*107d*/ 0x00A000A0,
/*107e*/ 0x00A000A0,
/*107f*/ 0x00A000A0,
/*1080*/ 0x00A000A0,
/*1081*/ 0x00A000A0,
/*1082*/ 0x01C200A0,
/*1083*/ 0x01A00005,
/*1084*/ 0x00000000,
/*1085*/ 0x00000000,
/*1086*/ 0x00080200,
/*1087*/ 0x00000000,
/*1088*/ 0x20202020,
/*1089*/ 0x20202020,
/*108a*/ 0x01012020,
/*108b*/ 0x00000000
};
static const uint32_t DDR_PHY_ADR_V_REGSET_S4[DDR_PHY_ADR_V_REGSET_NUM_S4] = {
/*1200*/ 0x00000000,
/*1201*/ 0x00000000,
/*1202*/ 0x00000000,
/*1203*/ 0x00000000,
/*1204*/ 0x00000000,
/*1205*/ 0x00000100,
/*1206*/ 0x00000200,
/*1207*/ 0x00000000,
/*1208*/ 0x00000000,
/*1209*/ 0x00000000,
/*120a*/ 0x00000000,
/*120b*/ 0x00800200,
/*120c*/ 0x00000080,
/*120d*/ 0x00DCBA98,
/*120e*/ 0x01000000,
/*120f*/ 0x00200003,
/*1210*/ 0x00000000,
/*1211*/ 0x00000000,
/*1212*/ 0x00000000,
/*1213*/ 0x00000000,
/*1214*/ 0x00000000,
/*1215*/ 0x00000000,
/*1216*/ 0x00000000,
/*1217*/ 0x0000002A,
/*1218*/ 0x00000015,
/*1219*/ 0x00000015,
/*121a*/ 0x0000002A,
/*121b*/ 0x00000033,
/*121c*/ 0x0000000C,
/*121d*/ 0x0000000C,
/*121e*/ 0x00000033,
/*121f*/ 0x00543210,
/*1220*/ 0x003F0000,
/*1221*/ 0x0000013F,
/*1222*/ 0x20202003,
/*1223*/ 0x00202020,
/*1224*/ 0x20008008,
/*1225*/ 0x00000810,
/*1226*/ 0x00000F00,
/*1227*/ 0x00000000,
/*1228*/ 0x00000000,
/*1229*/ 0x00000000,
/*122a*/ 0x000605CC,
/*122b*/ 0x00030000,
/*122c*/ 0x00000300,
/*122d*/ 0x00000300,
/*122e*/ 0x00000300,
/*122f*/ 0x00000300,
/*1230*/ 0x00000300,
/*1231*/ 0x42080010,
/*1232*/ 0x0000803E,
/*1233*/ 0x00000008,
/*1234*/ 0x01000001,
/*1235*/ 0x00008000
};
static const uint32_t DDR_PHY_ADR_G_REGSET_S4[DDR_PHY_ADR_G_REGSET_NUM_S4] = {
/*1300*/ 0x00000000,
/*1301*/ 0x00000100,
/*1302*/ 0x00000000,
/*1303*/ 0x00000000,
/*1304*/ 0x00050000,
/*1305*/ 0x04000000,
/*1306*/ 0x00000020,
/*1307*/ 0x00000000,
/*1308*/ 0x00000000,
/*1309*/ 0x00000000,
/*130a*/ 0x00000000,
/*130b*/ 0x00002001,
/*130c*/ 0x00004003,
/*130d*/ 0x00010028,
/*130e*/ 0x01010100,
/*130f*/ 0x00800800,
/*1310*/ 0x08102000,
/*1311*/ 0x00000000,
/*1312*/ 0x00000000,
/*1313*/ 0x00010E06,
/*1314*/ 0x00000000,
/*1315*/ 0x00000000,
/*1316*/ 0x00000000,
/*1317*/ 0x00000000,
/*1318*/ 0x00040000,
/*1319*/ 0x00000000,
/*131a*/ 0x00000000,
/*131b*/ 0x00000064,
/*131c*/ 0x00000000,
/*131d*/ 0x00000100,
/*131e*/ 0x00000200,
/*131f*/ 0x80012000,
/*1320*/ 0x00041B42,
/*1321*/ 0x05000000,
/*1322*/ 0x00000000,
/*1323*/ 0x00000000,
/*1324*/ 0x00000000,
/*1325*/ 0x01000000,
/*1326*/ 0x01070501,
/*1327*/ 0x00000054,
/*1328*/ 0x00004410,
/*1329*/ 0x00004410,
/*132a*/ 0x00004410,
/*132b*/ 0x00004410,
/*132c*/ 0x00004410,
/*132d*/ 0x00004410,
/*132e*/ 0x00004410,
/*132f*/ 0x00004410,
/*1330*/ 0x00004410,
/*1331*/ 0x00000000,
/*1332*/ 0x00000000,
/*1333*/ 0x00000000,
/*1334*/ 0x00060000,
/*1335*/ 0x00000000,
/*1336*/ 0x00000090,
/*1337*/ 0x0000A25A,
/*1338*/ 0x00000008,
/*1339*/ 0x00000000,
/*133a*/ 0x00000000,
/*133b*/ 0x00000000,
/*133c*/ 0x00000000,
/*133d*/ 0x00000000,
/*133e*/ 0x03000000,
/*133f*/ 0x00000000,
/*1340*/ 0x00000000,
/*1341*/ 0x00000000,
/*1342*/ 0x04102000,
/*1343*/ 0x00041020,
/*1344*/ 0x00C98C98,
/*1345*/ 0x3F400000,
/*1346*/ 0x3F3F1F3F,
/*1347*/ 0x0000001F,
/*1348*/ 0x00000000,
/*1349*/ 0x00000000,
/*134a*/ 0x00000000,
/*134b*/ 0x00010000,
/*134c*/ 0x00000000,
/*134d*/ 0x00000000,
/*134e*/ 0x00000000,
/*134f*/ 0x00000100,
/*1350*/ 0x00000000,
/*1351*/ 0x00000000,
/*1352*/ 0x00040700,
/*1353*/ 0x00000000,
/*1354*/ 0x00000000,
/*1355*/ 0x00000000,
/*1356*/ 0x00000002,
/*1357*/ 0x00000100,
/*1358*/ 0x00000000,
/*1359*/ 0x00000000,
/*135a*/ 0x00001F00,
/*135b*/ 0x00000000,
/*135c*/ 0x00000000,
/*135d*/ 0x00080000,
/*135e*/ 0x000007FF,
/*135f*/ 0x00000000,
/*1360*/ 0x00000000,
/*1361*/ 0x00000000,
/*1362*/ 0x00000000,
/*1363*/ 0x00000000,
/*1364*/ 0x000FFFFF,
/*1365*/ 0x000FFFFF,
/*1366*/ 0x0000FFFF,
/*1367*/ 0xFFFFFFF0,
/*1368*/ 0x030FFFFF,
/*1369*/ 0x01FFFFFF,
/*136a*/ 0x0000FFFF,
/*136b*/ 0x00000000,
/*136c*/ 0x00000000,
/*136d*/ 0x00000000,
/*136e*/ 0x00000000,
/*136f*/ 0x00000000,
/*1370*/ 0x00000006,
/*1371*/ 0x00000000,
/*1372*/ 0x00001142,
/*1373*/ 0x08010600,
/*1374*/ 0x00000080,
/*1375*/ 0x03000300,
/*1376*/ 0x03000300,
/*1377*/ 0x00000300,
/*1378*/ 0x00000300,
/*1379*/ 0x00000300,
/*137a*/ 0x00000300,
/*137b*/ 0x00000005,
/*137c*/ 0x0004BFCC,
/*137d*/ 0x0000010C,
/*137e*/ 0x0000027F,
/*137f*/ 0x00000000,
/*1380*/ 0x0000027F,
/*1381*/ 0x00000000,
/*1382*/ 0x00127F00,
/*1383*/ 0x0089FF00,
/*1384*/ 0x00827FCC,
/*1385*/ 0x00000000,
/*1386*/ 0x00127F80,
/*1387*/ 0x01980000,
/*1388*/ 0x00127F80,
/*1389*/ 0x01980000,
/*138a*/ 0x00127F00,
/*138b*/ 0x01980000,
/*138c*/ 0x00127F00,
/*138d*/ 0x01980000,
/*138e*/ 0x20040006
};
static const uint32_t DDR_PI_REGSET_S4[DDR_PI_REGSET_NUM_S4] = {
/*0800*/ 0x00000B00,
/*0801*/ 0x00000000,
/*0802*/ 0x00000000,
/*0803*/ 0x00000101,
/*0804*/ 0x00640000,
/*0805*/ 0x00000001,
/*0806*/ 0x00000000,
/*0807*/ 0x00000000,
/*0808*/ 0x00000000,
/*0809*/ 0x00000000,
/*080a*/ 0x00000003,
/*080b*/ 0x00010100,
/*080c*/ 0x08000003,
/*080d*/ 0x00000103,
/*080e*/ 0x00000000,
/*080f*/ 0x00000000,
/*0810*/ 0x00000000,
/*0811*/ 0x00000000,
/*0812*/ 0x00000000,
/*0813*/ 0x00000000,
/*0814*/ 0x0A000000,
/*0815*/ 0x00000028,
/*0816*/ 0x00000100,
/*0817*/ 0x00320003,
/*0818*/ 0x00000000,
/*0819*/ 0x00000000,
/*081a*/ 0x01010102,
/*081b*/ 0x00000000,
/*081c*/ 0x55555A3C,
/*081d*/ 0x00000055,
/*081e*/ 0x000000B5,
/*081f*/ 0x0000004A,
/*0820*/ 0x00000056,
/*0821*/ 0x000000A9,
/*0822*/ 0x000000A9,
/*0823*/ 0x000000B5,
/*0824*/ 0x01000000,
/*0825*/ 0x00010000,
/*0826*/ 0x00030300,
/*0827*/ 0x0000001A,
/*0828*/ 0x000007D0,
/*0829*/ 0x00000300,
/*082a*/ 0x00000000,
/*082b*/ 0x00000000,
/*082c*/ 0x01080000,
/*082d*/ 0x00010101,
/*082e*/ 0x00000000,
/*082f*/ 0x00030000,
/*0830*/ 0x03000100,
/*0831*/ 0x00000017,
/*0832*/ 0x00000000,
/*0833*/ 0x00000000,
/*0834*/ 0x00000000,
/*0835*/ 0x0A0A140A,
/*0836*/ 0x10020300,
/*0837*/ 0x00020805,
/*0838*/ 0x00000404,
/*0839*/ 0x00000000,
/*083a*/ 0x00000000,
/*083b*/ 0x01000101,
/*083c*/ 0x00020203,
/*083d*/ 0x00340000,
/*083e*/ 0x00000000,
/*083f*/ 0x00000000,
/*0840*/ 0x01000000,
/*0841*/ 0x00000000,
/*0842*/ 0x00000800,
/*0843*/ 0x00020002,
/*0844*/ 0x00010001,
/*0845*/ 0x00010000,
/*0846*/ 0x00020002,
/*0847*/ 0x00000002,
/*0848*/ 0x00000000,
/*0849*/ 0x00000000,
/*084a*/ 0x00000000,
/*084b*/ 0x00000000,
/*084c*/ 0x00000000,
/*084d*/ 0x00000000,
/*084e*/ 0x00000000,
/*084f*/ 0x00000000,
/*0850*/ 0x00100400,
/*0851*/ 0x08010100,
/*0852*/ 0x08000000,
/*0853*/ 0x00000100,
/*0854*/ 0x00000000,
/*0855*/ 0x0000AA00,
/*0856*/ 0x00000000,
/*0857*/ 0x00010000,
/*0858*/ 0x00000000,
/*0859*/ 0x00000000,
/*085a*/ 0x00000000,
/*085b*/ 0x00000000,
/*085c*/ 0x00000000,
/*085d*/ 0x00000000,
/*085e*/ 0x00000000,
/*085f*/ 0x00000000,
/*0860*/ 0x00000000,
/*0861*/ 0x00000000,
/*0862*/ 0x00000000,
/*0863*/ 0x00000000,
/*0864*/ 0x00000000,
/*0865*/ 0x00000000,
/*0866*/ 0x00000000,
/*0867*/ 0x00000000,
/*0868*/ 0x00000000,
/*0869*/ 0x00000000,
/*086a*/ 0x00000000,
/*086b*/ 0x00000000,
/*086c*/ 0x00000000,
/*086d*/ 0x00000000,
/*086e*/ 0x00000000,
/*086f*/ 0x00000000,
/*0870*/ 0x00000000,
/*0871*/ 0x00000000,
/*0872*/ 0x00000000,
/*0873*/ 0x00000000,
/*0874*/ 0x00000000,
/*0875*/ 0x00000000,
/*0876*/ 0x00000000,
/*0877*/ 0x00000002,
/*0878*/ 0x01010001,
/*0879*/ 0x00010200,
/*087a*/ 0x04000103,
/*087b*/ 0x01050001,
/*087c*/ 0x00010600,
/*087d*/ 0x00000107,
/*087e*/ 0x00000000,
/*087f*/ 0x00000000,
/*0880*/ 0x00000100,
/*0881*/ 0x00000000,
/*0882*/ 0x00000000,
/*0883*/ 0x00000000,
/*0884*/ 0x00040100,
/*0885*/ 0x00000000,
/*0886*/ 0x00000000,
/*0887*/ 0x01000000,
/*0888*/ 0x00002B2B,
/*0889*/ 0x00000034,
/*088a*/ 0x0000006C,
/*088b*/ 0x120C046C,
/*088c*/ 0x00481248,
/*088d*/ 0x00000006,
/*088e*/ 0x00000046,
/*088f*/ 0x00000256,
/*0890*/ 0x00002073,
/*0891*/ 0x00000256,
/*0892*/ 0x04002073,
/*0893*/ 0x00000404,
/*0894*/ 0x00002A00,
/*0895*/ 0x002A002A,
/*0896*/ 0x01000100,
/*0897*/ 0x00000100,
/*0898*/ 0x00000000,
/*0899*/ 0x00000000,
/*089a*/ 0x00010000,
/*089b*/ 0x00010100,
/*089c*/ 0x00010100,
/*089d*/ 0x15040100,
/*089e*/ 0x0E0E0215,
/*089f*/ 0x00040402,
/*08a0*/ 0x000C0034,
/*08a1*/ 0x00210049,
/*08a2*/ 0x00210049,
/*08a3*/ 0x01000001,
/*08a4*/ 0x00040005,
/*08a5*/ 0x00040216,
/*08a6*/ 0x01000216,
/*08a7*/ 0x00060006,
/*08a8*/ 0x02170100,
/*08a9*/ 0x01000217,
/*08aa*/ 0x02170217,
/*08ab*/ 0x11111111,
/*08ac*/ 0x00001111,
/*08ad*/ 0x0A070600,
/*08ae*/ 0x1F130A0D,
/*08af*/ 0x1F130A14,
/*08b0*/ 0x0000C014,
/*08b1*/ 0x00C01000,
/*08b2*/ 0x00C01000,
/*08b3*/ 0x00021000,
/*08b4*/ 0x00240005,
/*08b5*/ 0x00240216,
/*08b6*/ 0x003E0216,
/*08b7*/ 0x1609003A,
/*08b8*/ 0x00000007,
/*08b9*/ 0x003A003E,
/*08ba*/ 0x00071609,
/*08bb*/ 0x00003E00,
/*08bc*/ 0x1609003A,
/*08bd*/ 0x08000007,
/*08be*/ 0x04010404,
/*08bf*/ 0x01030277,
/*08c0*/ 0x0A0A0320,
/*08c1*/ 0x18272D10,
/*08c2*/ 0x5A752F28,
/*08c3*/ 0x1E202008,
/*08c4*/ 0x272D1016,
/*08c5*/ 0x752F2818,
/*08c6*/ 0x2020085A,
/*08c7*/ 0x0000161E,
/*08c8*/ 0x0000008C,
/*08c9*/ 0x00000578,
/*08ca*/ 0x000040E6,
/*08cb*/ 0x000288FC,
/*08cc*/ 0x000040E6,
/*08cd*/ 0x000288FC,
/*08ce*/ 0x02660006,
/*08cf*/ 0x04040266,
/*08d0*/ 0xC83CC804,
/*08d1*/ 0x0000003C,
/*08d2*/ 0x00040000,
/*08d3*/ 0x0F1166F1,
/*08d4*/ 0x3F740006,
/*08d5*/ 0x0F1166F1,
/*08d6*/ 0x3F740006,
/*08d7*/ 0x0F1166F1,
/*08d8*/ 0x00040006,
/*08d9*/ 0x0F1166F1,
/*08da*/ 0x3F74002E,
/*08db*/ 0x0F1166F1,
/*08dc*/ 0x3F74002E,
/*08dd*/ 0x0F1166F1,
/*08de*/ 0x0000002E
};

View File

@@ -0,0 +1,302 @@
/*******************************************************************************
* Copyright (c) 2015-2022 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.
******************************************************************************/
#if defined(__RH850G3K__)
#include "remap_register.h"
#endif
#define RCAR_DDR_VERSION "rev.0.08rc7"
#define DRAM_CH_CNT 0x04
#define SLICE_CNT 0x02
#define CS_CNT 0x02
/* for pll setting */
#define CLK_DIV(a, diva, b, divb) (((a) * (divb)) / ((b) * (diva)))
#define CLK_MUL(a, diva, b, divb) (((a) * (b)) / ((diva) * (divb)))
/* for ddr density setting */
#define DBMEMCONF_REG(d3, row, BG, bank, col, dw) (((d3) << 30) | ((row) << 24) | ((BG) << 20) | ((bank) << 16) | ((col) << 8) | (dw))
#define DBMEMCONF_REGD(density) (DBMEMCONF_REG((density) % 2, ((density) + 1) / 2 + (28 - 2 - 2 - 10 - 1), 2, 2, 10, 1)) /* 16bit */
#define DBMEMCONF_VAL(ch,cs) (DBMEMCONF_REGD(DBMEMCONF_DENS(ch, cs)))
/* system registers : CPG */
#define CPG_FRQCRD_KICK_BIT (1U << 31)
#define CPG_PLL3CR0_KICK_BIT (1U << 31)
#define CPG_PLLECR_PLL3E_BIT (1U << 3)
#define CPG_PLLECR_PLL3ST_BIT (1U << 11)
#if defined(__RH850G3K__)
#define CPG_BASE (BASE_CPG_ADDR)
#else
#define CPG_BASE (0xE6150000U)
#endif
#define CPG_CPGWPR (CPG_BASE + 0x0000U)
#define CPG_CPGWPCR (CPG_BASE + 0x0004U)
#define CPG_FRQCRA (CPG_BASE + 0x0800U)
#define CPG_FRQCRB (CPG_BASE + 0x0804U)
#define CPG_FRQCRC (CPG_BASE + 0x0808U)
#define CPG_FRQCRD0 (CPG_BASE + 0x080CU)
#define CPG_PLLECR (CPG_BASE + 0x0820U)
#define CPG_PLL3CR0 (CPG_BASE + 0x083CU)
#define CPG_PLL3CR1 (CPG_BASE + 0x08C0U)
#define CPG_FSRCHKCLRR4 (CPG_BASE + 0x0590U)
#define CPG_FSRCHKSETR4 (CPG_BASE + 0x0510U)
#define CPG_FSRCHKRA4 (CPG_BASE + 0x0410U)
#define CPG_SRCR4 (CPG_BASE + 0x2C10U)
#define CPG_SRSTCLR4 (CPG_BASE + 0x2C90U)
#define CPG_PLL3FBCKMCSR (CPG_BASE + 0x0C60U)
#define CPG_PLL3FBCKMECR (CPG_BASE + 0x0C64U)
#define CPG_PLL3FBCKMLCH (CPG_BASE + 0x0C68U)
#define CPG_PLL3FBCKMLCL (CPG_BASE + 0x0C6CU)
#define CPG_PLL3FBCKMCNT (CPG_BASE + 0x0C70U)
#define CPG_PLL3FBCKMCNTE (CPG_BASE + 0x0C74U)
#if defined(__RH850G3K__)
#define RST_BASE (BASE_RESET_ADDR)
#else
#define RST_BASE (0xE6160000U)
#endif
#define RST_MODEMR0 (RST_BASE + 0x0000U)
#define RST_MODEMR1 (RST_BASE + 0x0004U)
/* Product Register */
#define PRR (0xFFF00044U)
#define PRR_PRODUCT_MASK (0x00007F00U)
#define PRR_CUT_MASK (0x000000FFU)
#define PRR_PRODUCT_V4H (0x00005C00U) /* R-Car V4H */
#define PRR_PRODUCT_10 (0x00000000U) /* ver 1.0 */
#define PRR_PRODUCT_20 (0x00000010U) /* ver 2.0 */
/* DBSC registers */
#if defined(__RH850G3K__)
#define DBSC_D_BASE (BASE_DBSC_ADDR + 0x14000U) /* forV4H DBSC0 clk_dbsc region DBSC1_D_BASE = 0xE67A8000U */
#define DBSC_A_BASE (BASE_DBSC_ADDR) /* forV4H DBSC0 clk_axim region DBSC1_A_BASE = 0xE6798000U */
#else
#define DBSC_D_BASE (0xE67A4000U) /* forV4H DBSC0 clk_dbsc region DBSC1_D_BASE = 0xE67A8000U */
#define DBSC_A_BASE (0xE6790000U) /* forV4H DBSC0 clk_axim region DBSC1_A_BASE = 0xE6798000U */
#endif
#define DBSC_DBSYSCONF0 (DBSC_A_BASE + 0x0000U)
#define DBSC_DBSYSCONF1 (DBSC_D_BASE + 0x0000U)
#define DBSC_DBSYSCONF1A (DBSC_A_BASE + 0x0004U)
#define DBSC_DBSYSCONF2 (DBSC_D_BASE + 0x0004U)
#define DBSC_DBPHYCONF0 (DBSC_D_BASE + 0x0008U)
#define DBSC_DBSYSCONF2A (DBSC_A_BASE + 0x0008U)
#define DBSC_DBMEMKIND (DBSC_D_BASE + 0x0020U)
#define DBSC_DBMEMKINDA (DBSC_A_BASE + 0x0020U)
#define DBSC_DBMEMCONF(ch,cs) (DBSC_D_BASE + 0x0030U + 0x10U * (ch) + 0x04U * (cs))
#define DBSC_DBMEMCONF_0_0 (DBSC_D_BASE + 0x0030U)
#define DBSC_DBMEMCONF_0_1 (DBSC_D_BASE + 0x0034U)
#define DBSC_DBMEMCONF_0_2 (DBSC_D_BASE + 0x0038U)
#define DBSC_DBMEMCONF_0_3 (DBSC_D_BASE + 0x003CU)
#define DBSC_DBMEMCONF_1_0 (DBSC_D_BASE + 0x0040U)
#define DBSC_DBMEMCONF_1_1 (DBSC_D_BASE + 0x0044U)
#define DBSC_DBMEMCONF_1_2 (DBSC_D_BASE + 0x0048U)
#define DBSC_DBMEMCONF_1_3 (DBSC_D_BASE + 0x004CU)
#define DBSC_DBMEMCONF_2_0 (DBSC_D_BASE + 0x0050U)
#define DBSC_DBMEMCONF_2_1 (DBSC_D_BASE + 0x0054U)
#define DBSC_DBMEMCONF_2_2 (DBSC_D_BASE + 0x0058U)
#define DBSC_DBMEMCONF_2_3 (DBSC_D_BASE + 0x005CU)
#define DBSC_DBMEMCONF_3_0 (DBSC_D_BASE + 0x0060U)
#define DBSC_DBMEMCONF_3_1 (DBSC_D_BASE + 0x0064U)
#define DBSC_DBMEMCONF_3_2 (DBSC_D_BASE + 0x0068U)
#define DBSC_DBMEMCONF_3_3 (DBSC_D_BASE + 0x006CU)
#define DBSC_DBMEMCONFA(ch,cs) (DBSC_A_BASE + 0x0030U + 0x10U * (ch) + 0x04U * (cs))
#define DBSC_DBMEMCONF_0_0A (DBSC_A_BASE + 0x0030U)
#define DBSC_DBMEMCONF_0_1A (DBSC_A_BASE + 0x0034U)
#define DBSC_DBMEMCONF_0_2A (DBSC_A_BASE + 0x0038U)
#define DBSC_DBMEMCONF_0_3A (DBSC_A_BASE + 0x003CU)
#define DBSC_DBMEMCONF_1_0A (DBSC_A_BASE + 0x0040U)
#define DBSC_DBMEMCONF_1_1A (DBSC_A_BASE + 0x0044U)
#define DBSC_DBMEMCONF_1_2A (DBSC_A_BASE + 0x0048U)
#define DBSC_DBMEMCONF_1_3A (DBSC_A_BASE + 0x004CU)
#define DBSC_DBMEMCONF_2_0A (DBSC_A_BASE + 0x0050U)
#define DBSC_DBMEMCONF_2_1A (DBSC_A_BASE + 0x0054U)
#define DBSC_DBMEMCONF_2_2A (DBSC_A_BASE + 0x0058U)
#define DBSC_DBMEMCONF_2_3A (DBSC_A_BASE + 0x005CU)
#define DBSC_DBMEMCONF_3_0A (DBSC_A_BASE + 0x0060U)
#define DBSC_DBMEMCONF_3_1A (DBSC_A_BASE + 0x0064U)
#define DBSC_DBMEMCONF_3_2A (DBSC_A_BASE + 0x0068U)
#define DBSC_DBMEMCONF_3_3A (DBSC_A_BASE + 0x006CU)
#define DBSC_DBSYSCNT0 (DBSC_D_BASE + 0x0100U)
#define DBSC_DBSYSCNT0A (DBSC_A_BASE + 0x0100U)
#define DBSC_DBACEN (DBSC_A_BASE + 0x0200U)
#define DBSC_DBRFEN (DBSC_D_BASE + 0x0204U)
#define DBSC_DBCMD (DBSC_D_BASE + 0x0208U)
#define DBSC_DBWAIT (DBSC_D_BASE + 0x0210U)
#define DBSC_DBTR(x) (DBSC_D_BASE + 0x0300U + 0x04U * (x))
#define DBSC_DBTR0 (DBSC_D_BASE + 0x0300U)
#define DBSC_DBTR1 (DBSC_D_BASE + 0x0304U)
#define DBSC_DBTR2 (DBSC_D_BASE + 0x0308U)
#define DBSC_DBTR3 (DBSC_D_BASE + 0x030CU)
#define DBSC_DBTR4 (DBSC_D_BASE + 0x0310U)
#define DBSC_DBTR5 (DBSC_D_BASE + 0x0314U)
#define DBSC_DBTR6 (DBSC_D_BASE + 0x0318U)
#define DBSC_DBTR7 (DBSC_D_BASE + 0x031CU)
#define DBSC_DBTR8 (DBSC_D_BASE + 0x0320U)
#define DBSC_DBTR9 (DBSC_D_BASE + 0x0324U)
#define DBSC_DBTR10 (DBSC_D_BASE + 0x0328U)
#define DBSC_DBTR11 (DBSC_D_BASE + 0x032CU)
#define DBSC_DBTR12 (DBSC_D_BASE + 0x0330U)
#define DBSC_DBTR13 (DBSC_D_BASE + 0x0334U)
#define DBSC_DBTR14 (DBSC_D_BASE + 0x0338U)
#define DBSC_DBTR15 (DBSC_D_BASE + 0x033CU)
#define DBSC_DBTR16 (DBSC_D_BASE + 0x0340U)
#define DBSC_DBTR17 (DBSC_D_BASE + 0x0344U)
#define DBSC_DBTR18 (DBSC_D_BASE + 0x0348U)
#define DBSC_DBTR19 (DBSC_D_BASE + 0x034CU)
#define DBSC_DBTR20 (DBSC_D_BASE + 0x0350U)
#define DBSC_DBTR21 (DBSC_D_BASE + 0x0354U)
#define DBSC_DBTR22 (DBSC_D_BASE + 0x0358U)
#define DBSC_DBTR23 (DBSC_D_BASE + 0x035CU)
#define DBSC_DBTR24 (DBSC_D_BASE + 0x0360U)
#define DBSC_DBTR25 (DBSC_D_BASE + 0x0364U)
#define DBSC_DBTR26 (DBSC_D_BASE + 0x0368U)
#define DBSC_DBTR27 (DBSC_D_BASE + 0x036CU)
#define DBSC_DBTR28 (DBSC_D_BASE + 0x0370U)
#define DBSC_DBTR29 (DBSC_D_BASE + 0x0374U)
#define DBSC_DBTR30 (DBSC_D_BASE + 0x0378U)
#define DBSC_DBTR31 (DBSC_D_BASE + 0x037CU)
#define DBSC_DBTR32 (DBSC_D_BASE + 0x0380U)
#define DBSC_DBTR33 (DBSC_D_BASE + 0x0384U)
#define DBSC_DBTR34 (DBSC_D_BASE + 0x0388U)
#define DBSC_DBTR35 (DBSC_D_BASE + 0x038CU)
#define DBSC_DBTR36 (DBSC_D_BASE + 0x0390U)
#define DBSC_DBTR37 (DBSC_D_BASE + 0x0394U)
#define DBSC_DBBL (DBSC_D_BASE + 0x0400U)
#define DBSC_DBBLA (DBSC_A_BASE + 0x0400U)
#define DBSC_DBRFCNF1 (DBSC_D_BASE + 0x0414U)
#define DBSC_DBRFCNF2 (DBSC_D_BASE + 0x0418U)
#define DBSC_DBCALCNF (DBSC_D_BASE + 0x0424U)
#define DBSC_DBRNK(x) (DBSC_D_BASE + 0x0430U + 0x04U * (x))
#define DBSC_DBRNK2 (DBSC_D_BASE + 0x0438U)
#define DBSC_DBRNK3 (DBSC_D_BASE + 0x043CU)
#define DBSC_DBRNK4 (DBSC_D_BASE + 0x0440U)
#define DBSC_DBRNK5 (DBSC_D_BASE + 0x0444U)
#define DBSC_DBDBICNT (DBSC_D_BASE + 0x0518U)
#define DBSC_DBDFIPMSTRCNF (DBSC_D_BASE + 0x0520U)
#define DBSC_DBDFICUPDCNF (DBSC_D_BASE + 0x0540U)
#define DBSC_DBDFISTAT(ch) (DBSC_D_BASE + 0x0600U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBDFISTAT_0 (DBSC_D_BASE + 0x0600U)
#define DBSC_DBDFISTAT_1 (DBSC_D_BASE + 0x0640U)
#define DBSC_DBDFISTAT_2 (DBSC_D_BASE + 0x0680U)
#define DBSC_DBDFISTAT_3 (DBSC_D_BASE + 0x06C0U)
#define DBSC_DBDFICNT(ch) (DBSC_D_BASE + 0x0604U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBDFICNT_0 (DBSC_D_BASE + 0x0604U)
#define DBSC_DBDFICNT_1 (DBSC_D_BASE + 0x0644U)
#define DBSC_DBDFICNT_2 (DBSC_D_BASE + 0x0684U)
#define DBSC_DBDFICNT_3 (DBSC_D_BASE + 0x06C4U)
#define DBSC_DBPDCNT0_0 (DBSC_D_BASE + 0x0610U)
#define DBSC_DBPDCNT0_1 (DBSC_D_BASE + 0x0614U)
#define DBSC_DBPDCNT0_2 (DBSC_D_BASE + 0x0618U)
#define DBSC_DBPDCNT0_3 (DBSC_D_BASE + 0x061CU)
#define DBSC_DBPDCNT1_0 (DBSC_D_BASE + 0x0650U)
#define DBSC_DBPDCNT1_1 (DBSC_D_BASE + 0x0654U)
#define DBSC_DBPDCNT1_2 (DBSC_D_BASE + 0x0658U)
#define DBSC_DBPDCNT1_3 (DBSC_D_BASE + 0x065CU)
#define DBSC_DBPDCNT2(ch) (DBSC_D_BASE + 0x0618U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBPDCNT2_0 (DBSC_D_BASE + 0x0690U)
#define DBSC_DBPDCNT2_1 (DBSC_D_BASE + 0x0694U)
#define DBSC_DBPDCNT2_2 (DBSC_D_BASE + 0x0698U)
#define DBSC_DBPDCNT2_3 (DBSC_D_BASE + 0x069CU)
#define DBSC_DBPDCNT3_0 (DBSC_D_BASE + 0x06D0U)
#define DBSC_DBPDCNT3_1 (DBSC_D_BASE + 0x06D4U)
#define DBSC_DBPDCNT3_2 (DBSC_D_BASE + 0x06D8U)
#define DBSC_DBPDCNT3_3 (DBSC_D_BASE + 0x06DCU)
#define DBSC_DBPDLK(ch) (DBSC_D_BASE + 0x0620U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBPDLK_0 (DBSC_D_BASE + 0x0620U)
#define DBSC_DBPDLK_1 (DBSC_D_BASE + 0x0660U)
#define DBSC_DBPDLK_2 (DBSC_D_BASE + 0x06a0U)
#define DBSC_DBPDLK_3 (DBSC_D_BASE + 0x06e0U)
#define DBSC_DBPDRGA(ch) (DBSC_D_BASE + 0x0624U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBPDRGA_0 (DBSC_D_BASE + 0x0624U)
#define DBSC_DBPDRGA_1 (DBSC_D_BASE + 0x0664U)
#define DBSC_DBPDRGA_2 (DBSC_D_BASE + 0x06A4U)
#define DBSC_DBPDRGA_3 (DBSC_D_BASE + 0x06E4U)
#define DBSC_DBPDRGD(ch) (DBSC_D_BASE + 0x0628U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBPDRGD_0 (DBSC_D_BASE + 0x0628U)
#define DBSC_DBPDRGD_1 (DBSC_D_BASE + 0x0668U)
#define DBSC_DBPDRGD_2 (DBSC_D_BASE + 0x06A8U)
#define DBSC_DBPDRGD_3 (DBSC_D_BASE + 0x06E8U)
#define DBSC_DBPDSTAT0(ch) (DBSC_D_BASE + 0x0630U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBPDSTAT0_0 (DBSC_D_BASE + 0x0630U)
#define DBSC_DBPDSTAT1_0 (DBSC_D_BASE + 0x0670U)
#define DBSC_DBPDSTAT1(ch) (DBSC_D_BASE + 0x0634U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBPDSTAT0_1 (DBSC_D_BASE + 0x0634U)
#define DBSC_DBPDSTA1T_1 (DBSC_D_BASE + 0x0674U)
#define DBSC_DBCAM0CTRL0 (DBSC_A_BASE + 0x0940U)
#define DBSC_DBCAMSTAT0(x) (DBSC_A_BASE + 0x0980U + 0x4000U *(x & 0x02U) + 0x10U * (x & 0x01U))
#define DBSC_DBCAM0STAT0 (DBSC_A_BASE + 0x0980U)
#define DBSC_DBCAM1STAT0 (DBSC_A_BASE + 0x0990U)
#define DBSC_DBCAM2STAT0 (DBSC_A_BASE + 0x09A0U)
#define DBSC_DBCAM3STAT0 (DBSC_A_BASE + 0x09B0U)
#define DBSC_DBCAMSTAT1(x) (DBSC_A_BASE + 0x0984U + 0x4000U *(x & 0x02U) + 0x10U * (x & 0x01U))
#define DBSC_DBCAM0STAT1 (DBSC_A_BASE + 0x0984U)
#define DBSC_DBCAM1STAT1 (DBSC_A_BASE + 0x0994U)
#define DBSC_DBCAM2STAT1 (DBSC_A_BASE + 0x09A4U)
#define DBSC_DBCAM3STAT1 (DBSC_A_BASE + 0x09B4U)
#define DBSC_DBBCAMDIS (DBSC_A_BASE + 0x09FCU)
#define DBSC_DBSCHRW1 (DBSC_A_BASE + 0x1024U)
#define DBSC_DBSCHTR0 (DBSC_A_BASE + 0x1030U)
#define DBSC_DBSCHFCTST01(x) (DBSC_A_BASE + 0x1040U + 0x04U * (x))
#define DBSC_DBSCHFCTST0 (DBSC_A_BASE + 0x1040U)
#define DBSC_DBSCHFCTST1 (DBSC_A_BASE + 0x1044U)
#define DBSC_DBSCHQOS(x,y) (DBSC_A_BASE + 0x1100U + 0x10U * (x) + 0x04U * (y))

View File

@@ -0,0 +1,220 @@
/*******************************************************************************
* Copyright (c) 2022-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 : ECC setting function
******************************************************************************/
/******************************************************************************
* @file ecc_enable_v4h.c
* - Version : 0.06
* @brief Enable setting process of ECC for DRAM.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 09.08.2022 0.01 First Release
* : 22.03.2023 0.02 Added AXI Timeout setting
* : 04.04.2023 0.03 Removed stdio.h and string.h.
* : 24.08.2023 0.04 Removed enable_ecc function.
* : 13.06.2024 0.05 Fix register setting for EDC_CFG, and revise
* : the ecm_lock()/ecm_unlock() process.
* : 07.04.2025 0.06 Remove unused functions.
*****************************************************************************/
#include <stdint.h>
#include <cnf_tbl.h>
#include <remap.h>
#include <wdt.h>
#if (ECM_ENABLE == 1)
#include "ecc_enable_v4h.h"
#include "v4h/lpddr5/boot_init_dram_regdef.h"
#include "ecm_enable_v4h.h"
#define AXI_SICREMAP_NUM (5U)
#define RGID_BASE1 (0xFE600000U)
#define RGID_BASE2 (0xE7A00000U)
#define RGID_BASE3 (0xEB800000U)
#define RGID_BASE4 (0xFD800000U)
#define RGID_BASE5 (0xFEA00000U)
#define FDT_COUNTER_MASK (0x0000FFFFU)
static void axi_timeout_setting(void);
void edc_axi_enable(void)
{
uint32_t edc_tmp;
/* Unlock the write protect of ECM registers */
ecm_unlock();
/* (1) Set the corresponding bits of the ECMERRTGTR and ECMERRCTLR registers
to inform the external device of the error via the ERROROUT# pin. */
/* Set bit 11 - bit 2 of ECMERRTGTR7 to all 0 and bit 11 - bit 2 of
ECMERRCTLR7 to 1. (Error of AXI-Bus ECM of each hierarchy) */
edc_tmp = mem_read32(ECMERRTGTR7);
edc_tmp &= ~(0x3FFU << 2U);
ecm_write(ECMERRTGTR7, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR7);
edc_tmp |= (0x3FFU << 2U);
ecm_write(ECMERRCTLR7, edc_tmp);
/* Set bit 28 - bit 16 of ECMERRTGTR39 to all 0 and bit 28 - bit 16 of
ECMERRCTLR39 to 1. (Error of AXI-Bus ECM of each hierarchy) */
edc_tmp = mem_read32(ECMERRTGTR39);
edc_tmp &= ~(0x1FFFU << 16U);
ecm_write(ECMERRTGTR39, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR39);
edc_tmp |= (0x1FFFU << 16U);
ecm_write(ECMERRCTLR39, edc_tmp);
/* Set bit 26 of ECMERRTGTR1 to 0 and bit 26 of
ECMERRCTLR1 to 1. (CCI bus EDC error) */
edc_tmp = mem_read32(ECMERRTGTR1);
edc_tmp &= ~(0x1U << 26U);
ecm_write(ECMERRTGTR1, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR1);
edc_tmp |= (0x1U << 26U);
ecm_write(ECMERRCTLR1, edc_tmp);
axi_timeout_setting();
/* Lock the ECM registers */
ecm_lock();
}
void edc_vram_enable(void)
{
uint32_t edc_tmp;
/* Unlock the write protect of ECM registers */
ecm_unlock();
/* (1) Set the corresponding bits of the ECMERRTGTR and ECMERRCTLR registers
to inform the external device of the error via the ERROROUT# pin. */
/* Set bit 30 of ECMERRTGTR7 to 0 and bit 30 of ECMERRCTLR7 to 1.
(RT-VRAM edc 1-bit error) */
edc_tmp = mem_read32(ECMERRTGTR7);
edc_tmp &= ~(0x1U << 30U);
ecm_write(ECMERRTGTR7, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR7);
edc_tmp |= (0x1U << 30U);
ecm_write(ECMERRCTLR7, edc_tmp);
/* Set bit 29 of ECMERRTGTR7 to 0 and bit 29 of ECMERRCTLR7 to 1.
(RT-VRAM edc multi-bit error) */
edc_tmp = mem_read32(ECMERRTGTR7);
edc_tmp &= ~(0x1U << 29U);
ecm_write(ECMERRTGTR7, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR7);
edc_tmp |= (0x1U << 29U);
ecm_write(ECMERRCTLR7, edc_tmp);
/* Set bit 19 of ECMERRTGTR17 to 0 and bit 19 of ECMERRCTLR17 to 1.
(RT-VRAM edc 1-bit error) */
edc_tmp = mem_read32(ECMERRTGTR17);
edc_tmp &= ~(0x1U << 19U);
ecm_write(ECMERRTGTR17, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR17);
edc_tmp |= (0x1U << 19U);
ecm_write(ECMERRCTLR17, edc_tmp);
/* Set bit 18 of ECMERRTGTR17 to 0 and bit 18 of ECMERRCTLR17 to 1.
(RT-VRAM edc multi-bit error) */
edc_tmp = mem_read32(ECMERRTGTR17);
edc_tmp &= ~(0x1U << 18U);
ecm_write(ECMERRTGTR17, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR17);
edc_tmp |= (0x1U << 18U);
ecm_write(ECMERRCTLR17, edc_tmp);
/* Set bit 0 of EDC_CFG to 1. (EDC Error Control) */
edc_tmp = mem_read32(EDC_CFG);
edc_tmp |= (0x1U << 0U);
mem_write32(EDC_CFG, edc_tmp);
/* Lock the ECM registers */
ecm_lock();
}
static void axi_timeout_setting(void)
{
uint32_t reg;
uint32_t loop;
REMAP_TABLE axi_remap_tbl[AXI_SICREMAP_NUM] = {
{RGID_BASE1, 0U},
{RGID_BASE2, 0U},
{RGID_BASE3, 0U},
{RGID_BASE4, 0U},
{RGID_BASE5, 0U},
};
/* Register of AXI Base */
for (loop = 0U; loop < AXI_SICREMAP_NUM; loop++)
{
remap_register(axi_remap_tbl[loop].base_addr, &axi_remap_tbl[loop].rmp_addr);
}
/* Set the COUNTER bits of the FDT_* registers for all safety-related modules to minimum value with 1ms or more. */
for (loop = 0U; loop < FDT_REG_MAX; loop++)
{
reg = mem_read32(g_fdt_tbl[loop].reg_addr);
reg &= ~(FDT_COUNTER_MASK);
reg |= g_fdt_tbl[loop].value;
mem_write32(g_fdt_tbl[loop].reg_addr, reg);
INFO("FDT[%d] =\t0x%08x \tsetting value = 0x%08x\n", loop, mem_read32(g_fdt_tbl[loop].reg_addr), g_fdt_tbl[loop].value);
}
for(loop = 0U; loop < INTEN_REG_MAX; loop++)
{
/* Set access protection setting value of Region ID (AXI bus of Region ID register) */
mem_write32(g_inten_tbl[loop].reg_addr, g_inten_tbl[loop].value);
INFO("INTEN[%d] =\t0x%08x \tsetting value = 0x%08x\n", loop, mem_read32(g_inten_tbl[loop].reg_addr), g_inten_tbl[loop].value);
}
/* Unregister of AXI Base */
for (loop = 0U; loop < AXI_SICREMAP_NUM; loop++)
{
remap_unregister(axi_remap_tbl[loop].rmp_addr);
}
wdt_restart();
}
#endif /* ECM_ENABLE == 1 */

View File

@@ -0,0 +1,123 @@
/*******************************************************************************
* Copyright (c) 2022-2024 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 : ECC driver header
******************************************************************************/
#ifndef ECC_PROTECT
#define ECC_PROTECT
#include "remap_register.h"
/* DBSC registers */
#if defined(__RH850G3K__)
#include "mem_io.h"
#include "log.h"
#define DBSC_D_BASE (BASE_DBSC_ADDR + 0x14000U) /* forV4H DBSC0 clk_dbsc region DBSC1_D_BASE = 0xE67A8000U */
#define DBSC_A_BASE (BASE_DBSC_ADDR) /* forV4H DBSC0 clk_axim region DBSC1_A_BASE = 0xE6798000U */
#define ECM_BASE (BASE_ECC_ADDR)
#else
#include <mmio.h>
#include <debug.h>
#define DBSC_D_BASE (0xE67A4000U) /* forV4H DBSC0 clk_dbsc region DBSC1_D_BASE = 0xE67A8000U */
#define DBSC_A_BASE (0xE6790000U) /* forV4H DBSC0 clk_axim region DBSC1_A_BASE = 0xE6798000U */
#define ECM_BASE (0xE6250000U)
#endif/* defined(__RH850G3K__) */
#define RTVRAM_REG_BASE (0xFFEC0000U)
void edc_axi_enable(void);
void edc_vram_enable(void);
#define DB0SYSCNT0 (DBSC_D_BASE + 0x0100U)
#define DB0SYSCNT0A (DBSC_A_BASE + 0x0100U)
#define DB1SYSCNT0 (DB0SYSCNT0 + 0x4000U)
#define DB1SYSCNT0A (DB0SYSCNT0A + 0x8000U)
#define DBSC_DBACEN0 (DBSC_A_BASE + 0x0200U)
#define DBSC_DBACEN1 (DBSC_DBACEN0 + 0x8000U)
#define ECMWACNTR (ECM_BASE + 0x0A04U)
#define ECMWPCNTR (ECM_BASE + 0x0A00U)
#define ECMERRTGTR0 (ECM_BASE + 0x0200U)
#define ECMERRCTLR0 (ECM_BASE + 0x0000U)
#define ECMERRTGTR1 (ECM_BASE + 0x0200U + 0x4U * 1U)
#define ECMERRCTLR1 (ECM_BASE + 0x0000U + 0x4U * 1U)
#define ECMERRTGTR7 (ECM_BASE + 0x0200U + 0x4U * 7U)
#define ECMERRCTLR7 (ECM_BASE + 0x0000U + 0x4U * 7U)
#define ECMERRTGTR17 (ECM_BASE + 0x0200U + 0x4U * 17U)
#define ECMERRCTLR17 (ECM_BASE + 0x0000U + 0x4U * 17U)
#define ECMERRTGTR39 (ECM_BASE + 0x0200U + 0x4U * 39U)
#define ECMERRCTLR39 (ECM_BASE + 0x0000U + 0x4U * 39U)
#define DB0FSCONF00A (DBSC_A_BASE + 0x7640U)
#define DB1FSCONF00A (DB0FSCONF00A + 0x8000U)
#define DB0FSCONF01A (DBSC_A_BASE + 0x7644U)
#define DB1FSCONF01A (DB0FSCONF01A + 0x8000U)
#define DB0FSCONF02A (DBSC_A_BASE + 0x7648U)
#define DB1FSCONF02A (DB0FSCONF02A + 0x8000U)
#define DB0FSCTRL01A (DBSC_A_BASE + 0x7604U)
#define DB1FSCTRL01A (DB0FSCTRL01A + 0x8000U)
#define DB0FSSTAT01A (DBSC_A_BASE + 0x7684U)
#define DB1FSSTAT01A (DB0FSSTAT01A + 0x8000U)
#define DB0FSSTAT00A (DBSC_A_BASE + 0x7680U)
#define DB1FSSTAT00A (DB0FSSTAT00A + 0x8000U)
#define DB0FSINTENB02A (DBSC_A_BASE + 0x7088U)
#define DB1FSINTENB02A (DB0FSINTENB02A + 0x8000U)
#define DB0FSINTENB04A (DBSC_A_BASE + 0x7090U)
#define DB1FSINTENB04A (DB0FSINTENB04A + 0x8000U)
#define DB0FSDRAMECCAREA0 (DBSC_A_BASE + 0x7450U)
#define DB0FSDRAMECCAREA1 (DBSC_A_BASE + 0x7454U)
#define DB1FSDRAMECCAREA0 (DB0FSDRAMECCAREA0 + 0x8000U)
#define DB1FSDRAMECCAREA1 (DB0FSDRAMECCAREA1 + 0x8000U)
#define DB0FSCONFAXI0 (DBSC_A_BASE + 0x7400U)
#define DB1FSCONFAXI0 (DB0FSCONFAXI0 + 0x8000U)
#define EDC_CFG (RTVRAM_REG_BASE + 0x4110U)
/********************* Set by the user *********************/
/* The row address of ECC Protection Area Size for memory rank 0/1 of DBSC0/1 */
#define ECC_PROT_SIZE00 (0x1000U)
#define ECC_PROT_SIZE01 (0x1000U)
#define ECC_PROT_SIZE10 (0x1000U)
#define ECC_PROT_SIZE11 (0x1000U)
/* Start and End row address of ECC Protection area for rank0 of DBSC0/1 */
#define START_ECC_INIT_AREA00 (0x00000000U)
#define START_ECC_INIT_AREA10 (0x00000000U)
#define END_ECC_INIT_AREA00 (0x00000FFFU)
#define END_ECC_INIT_AREA10 (0x00000FFFU)
/* Start and End row address of ECC Protection area for rank1 of DBSC0/1 */
#define START_ECC_INIT_AREA01 (0x00000000U)
#define START_ECC_INIT_AREA11 (0x00000000U)
#define END_ECC_INIT_AREA01 (0x00000FFFU)
#define END_ECC_INIT_AREA11 (0x00000FFFU)
/*********** Other settings cannot be changed ***************/
#endif/* ECC_PROTECT */

View File

@@ -0,0 +1,531 @@
/*******************************************************************************
* 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) || (ECM_ENABLE == 1))
#include "ecc_enable_v4h.h"
#include "mem_io.h"
#endif /* (ECM_ERROR_ENABLE == 1) || (ECM_ENABLE == 1) */
#if (ECM_ERROR_ENABLE == 1)
#define TYPE1_ECM_REG_MAX (13U)
#define TYPE2_ECM_REG_MAX (22U)
#define TYPE3_ECM_CTLREG_MAX (1U)
#define TYPE3_ECM_TGTREG_MAX (2U)
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) || (ECM_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) || (ECM_ENABLE == 1) */
#if (ECM_ERROR_ENABLE == 1)
void ecm_init_setting(void)
{
uint32_t reg;
uint32_t loop;
const ECM_ERROR_TABLE ecmerrctlr_type1_tbl[TYPE1_ECM_REG_MAX] = {
[0] = {0xFD850000U, 0x00381000U}, /* ECMERRCTLR0 */
[1] = {0xFD850004U, 0xA400C000U}, /* ECMERRCTLR1 */
/* Skip ECMERRCTLR2 setting */
/* Skip ECMERRCTLR3 setting */
/* Skip ECMERRCTLR4 setting */
/* Skip ECMERRCTLR5 setting */
[2] = {0xFD850018U, 0xCC000000U}, /* ECMERRCTLR6 */
[3] = {0xFD85001CU, 0x0C000000U}, /* ECMERRCTLR7 */
/* Skip ECMERRCTLR8 setting */
/* Skip ECMERRCTLR9 setting */
/* Skip ECMERRCTLR10 setting */
/* Skip ECMERRCTLR11 setting */
/* Skip ECMERRCTLR12 setting */
/* Skip ECMERRCTLR13 setting */
/* Skip ECMERRCTLR14 setting */
/* Skip ECMERRCTLR15 setting */
/* Skip ECMERRCTLR16 setting */
[4] = {0xFD850044U, 0x2D000000U}, /* ECMERRCTLR17 */
[5] = {0xFD850048U, 0x0EC0003FU}, /* ECMERRCTLR18 */
[6] = {0xFD85004CU, 0x00FFFF08U}, /* ECMERRCTLR19 */
[7] = {0xFD850050U, 0x0000001EU}, /* ECMERRCTLR20 */
[8] = {0xFD850054U, 0x9F800000U}, /* ECMERRCTLR21 */
/* Skip ECMERRCTLR22 setting */
/* Skip ECMERRCTLR23 setting */
/* Skip ECMERRCTLR24 setting */
/* Skip ECMERRCTLR25 setting */
/* Skip ECMERRCTLR26 setting */
/* Skip ECMERRCTLR27 setting */
/* Skip ECMERRCTLR28 setting */
/* Skip ECMERRCTLR29 setting */
/* Skip ECMERRCTLR30 setting */
/* Skip ECMERRCTLR31 setting */
/* Skip ECMERRCTLR32 setting */
/* Skip ECMERRCTLR33 setting */
/* Skip ECMERRCTLR34 setting */
[9] = {0xFD85008CU, 0x300003C0U}, /* ECMERRCTLR35 */
/* Skip ECMERRCTLR36 setting */
/* Skip ECMERRCTLR37 setting */
[10] = {0xFD850098U, 0x33300054U}, /* ECMERRCTLR38 */
/* Skip ECMERRCTLR39 setting */
/* Skip ECMERRCTLR40 setting */
[11] = {0xFD8500A4U, 0x01000880U}, /* ECMERRCTLR41 */
[12] = {0xFD8500A8U, 0x00040020U}, /* ECMERRCTLR42 */
};
const ECM_ERROR_TABLE ecmerrtgtr_type1_tbl[TYPE1_ECM_REG_MAX] = {
[0] = {0xFD850200U, 0x00381000U}, /* ECMERRTGTR0 */
[1] = {0xFD850204U, 0xA400C000U}, /* ECMERRTGTR1 */
/* Skip ECMERRTGTR2 setting */
/* Skip ECMERRTGTR3 setting */
/* Skip ECMERRTGTR4 setting */
/* Skip ECMERRTGTR5 setting */
[2] = {0xFD850218U, 0xCC000000U}, /* ECMERRTGTR6 */
[3] = {0xFD85021CU, 0x0C000000U}, /* ECMERRTGTR7 */
/* Skip ECMERRTGTR8 setting */
/* Skip ECMERRTGTR9 setting */
/* Skip ECMERRTGTR10 setting */
/* Skip ECMERRTGTR11 setting */
/* Skip ECMERRTGTR12 setting */
/* Skip ECMERRTGTR13 setting */
/* Skip ECMERRTGTR14 setting */
/* Skip ECMERRTGTR15 setting */
/* Skip ECMERRTGTR16 setting */
[4] = {0xFD850244U, 0x2D000000U}, /* ECMERRTGTR17 */
[5] = {0xFD850248U, 0x0EC0003FU}, /* ECMERRTGTR18 */
[6] = {0xFD85024CU, 0x00FFFF08U}, /* ECMERRTGTR19 */
[7] = {0xFD850250U, 0x0000001EU}, /* ECMERRTGTR20 */
[8] = {0xFD850254U, 0x9F800000U}, /* ECMERRTGTR21 */
/* Skip ECMERRTGTR22 setting */
/* Skip ECMERRTGTR23 setting */
/* Skip ECMERRTGTR24 setting */
/* Skip ECMERRTGTR25 setting */
/* Skip ECMERRTGTR26 setting */
/* Skip ECMERRTGTR27 setting */
/* Skip ECMERRTGTR28 setting */
/* Skip ECMERRTGTR29 setting */
/* Skip ECMERRTGTR30 setting */
/* Skip ECMERRTGTR31 setting */
/* Skip ECMERRTGTR32 setting */
/* Skip ECMERRTGTR33 setting */
/* Skip ECMERRTGTR34 setting */
[9] = {0xFD85028CU, 0x300003C0U}, /* ECMERRTGTR35 */
/* Skip ECMERRTGTR36 setting */
/* Skip ECMERRTGTR37 setting */
[10] = {0xFD850298U, 0x33300054U}, /* ECMERRTGTR38 */
/* Skip ECMERRTGTR39 setting */
/* Skip ECMERRTGTR40 setting */
[11] = {0xFD8502A4U, 0x01000880U}, /* ECMERRTGTR41 */
[12] = {0xFD8502A8U, 0x00040020U}, /* ECMERRTGTR42 */
};
const ECM_ERROR_TABLE ecmerrctlr_type2_tbl[TYPE2_ECM_REG_MAX] = {
[0] = {0xFD850000U, 0x4000000FU}, /* ECMERRCTLR0 */
[1] = {0xFD850004U, 0x1C004000U}, /* ECMERRCTLR1 */
[2] = {0xFD850008U, 0xFFFFFFFFU}, /* ECMERRCTLR2 */
[3] = {0xFD85000CU, 0xFFFFFFFFU}, /* ECMERRCTLR3 */
[4] = {0xFD850010U, 0xFFFFFFFFU}, /* ECMERRCTLR4 */
[5] = {0xFD850014U, 0xC1FFFFFFU}, /* ECMERRCTLR5 */
[6] = {0xFD850018U, 0x15000A80U}, /* ECMERRCTLR6 */
[7] = {0xFD85001CU, 0x00803481U}, /* ECMERRCTLR7 */
/* Skip ECMERRCTLR8 setting */
/* Skip ECMERRCTLR9 setting */
/* Skip ECMERRCTLR10 setting */
/* Skip ECMERRCTLR11 setting */
/* Skip ECMERRCTLR12 setting */
/* Skip ECMERRCTLR13 setting */
/* Skip ECMERRCTLR14 setting */
/* Skip ECMERRCTLR15 setting */
[8] = {0xFD850040U, 0x00003E9FU}, /* ECMERRCTLR16 */
[9] = {0xFD850044U, 0x00938060U}, /* ECMERRCTLR17 */
[10] = {0xFD850048U, 0x003C1FC0U}, /* ECMERRCTLR18 */
[11] = {0xFD85004CU, 0xFF0000F0U}, /* ECMERRCTLR19 */
[12] = {0xFD850050U, 0x02222220U}, /* ECMERRCTLR20 */
[13] = {0xFD850054U, 0x0061BE0FU}, /* ECMERRCTLR21 */
/* Skip ECMERRCTLR22 setting */
/* Skip ECMERRCTLR23 setting */
/* Skip ECMERRCTLR24 setting */
/* Skip ECMERRCTLR25 setting */
/* Skip ECMERRCTLR26 setting */
/* Skip ECMERRCTLR27 setting */
/* Skip ECMERRCTLR28 setting */
/* Skip ECMERRCTLR29 setting */
/* Skip ECMERRCTLR30 setting */
/* Skip ECMERRCTLR31 setting */
[14] = {0xFD850080U, 0x03E9043BU}, /* ECMERRCTLR32 */
[15] = {0xFD850084U, 0x03E9043BU}, /* ECMERRCTLR33 */
/* Skip ECMERRCTLR34 setting */
[16] = {0xFD85008CU, 0xC3F00C00U}, /* ECMERRCTLR35 */
[17] = {0xFD850090U, 0xFFFFFFFFU}, /* ECMERRCTLR36 */
/* Skip ECMERRCTLR37 setting */
[18] = {0xFD850098U, 0x00000002U}, /* ECMERRCTLR38 */
/* Skip ECMERRCTLR39 setting */
[19] = {0xFD8500A0U, 0x000067FEU}, /* ECMERRCTLR40 */
[20] = {0xFD8500A4U, 0x20010000U}, /* ECMERRCTLR41 */
[21] = {0xFD8500A8U, 0x00800400U}, /* ECMERRCTLR42 */
};
const ECM_ERROR_TABLE ecmerrtgtr_type2_tbl[TYPE2_ECM_REG_MAX] = {
[0] = {0xFD850200U, 0x4000000FU}, /* ECMERRTGTR0 */
[1] = {0xFD850204U, 0x1C004000U}, /* ECMERRTGTR1 */
[2] = {0xFD850208U, 0xFFFFFFFFU}, /* ECMERRTGTR2 */
[3] = {0xFD85020CU, 0xFFFFFFFFU}, /* ECMERRTGTR3 */
[4] = {0xFD850210U, 0xFFFFFFFFU}, /* ECMERRTGTR4 */
[5] = {0xFD850214U, 0xC1FFFFFFU}, /* ECMERRTGTR5 */
[6] = {0xFD850218U, 0x15000A80U}, /* ECMERRTGTR6 */
[7] = {0xFD85021CU, 0x00803481U}, /* ECMERRTGTR7 */
/* Skip ECMERRTGTR8 setting */
/* Skip ECMERRTGTR9 setting */
/* Skip ECMERRTGTR10 setting */
/* Skip ECMERRTGTR11 setting */
/* Skip ECMERRTGTR12 setting */
/* Skip ECMERRTGTR13 setting */
/* Skip ECMERRTGTR14 setting */
/* Skip ECMERRTGTR15 setting */
[8] = {0xFD850240U, 0x00003E9FU}, /* ECMERRTGTR16 */
[9] = {0xFD850244U, 0x00938060U}, /* ECMERRTGTR17 */
[10] = {0xFD850248U, 0x003C1FC0U}, /* ECMERRTGTR18 */
[11] = {0xFD85024CU, 0xFF0000F0U}, /* ECMERRTGTR19 */
[12] = {0xFD850250U, 0x02222220U}, /* ECMERRTGTR20 */
[13] = {0xFD850254U, 0x0061BE0FU}, /* ECMERRTGTR21 */
/* Skip ECMERRTGTR22 setting */
/* Skip ECMERRTGTR23 setting */
/* Skip ECMERRTGTR24 setting */
/* Skip ECMERRTGTR25 setting */
/* Skip ECMERRTGTR26 setting */
/* Skip ECMERRTGTR27 setting */
/* Skip ECMERRTGTR28 setting */
/* Skip ECMERRTGTR29 setting */
/* Skip ECMERRTGTR30 setting */
/* Skip ECMERRTGTR31 setting */
[14] = {0xFD850280U, 0x03E9043BU}, /* ECMERRTGTR32 */
[15] = {0xFD850284U, 0x03E9043BU}, /* ECMERRTGTR33 */
/* Skip ECMERRTGTR34 setting */
[16] = {0xFD85028CU, 0xC3F00C00U}, /* ECMERRTGTR35 */
[17] = {0xFD850290U, 0xFFFFFFFFU}, /* ECMERRTGTR36 */
/* Skip ECMERRTGTR37 setting */
[18] = {0xFD850298U, 0x00000002U}, /* ECMERRTGTR38 */
/* Skip ECMERRTGTR39 setting */
[19] = {0xFD8502A0U, 0x000067FEU}, /* ECMERRTGTR40 */
[20] = {0xFD8502A4U, 0x20010000U}, /* ECMERRTGTR41 */
[21] = {0xFD8502A8U, 0x00800400U}, /* ECMERRTGTR42 */
};
const ECM_ERROR_TABLE ecmerrctlr_type3_tbl[TYPE3_ECM_CTLREG_MAX] = {
/* Skip ECMERRCTLR0 setting */
/* Skip ECMERRCTLR1 setting */
/* Skip ECMERRCTLR2 setting */
/* Skip ECMERRCTLR3 setting */
/* Skip ECMERRCTLR4 setting */
/* Skip ECMERRCTLR5 setting */
/* Skip ECMERRCTLR6 setting */
/* Skip ECMERRCTLR7 setting */
/* Skip ECMERRCTLR8 setting */
/* Skip ECMERRCTLR9 setting */
/* Skip ECMERRCTLR10 setting */
/* Skip ECMERRCTLR11 setting */
/* Skip ECMERRCTLR12 setting */
/* Skip ECMERRCTLR13 setting */
/* Skip ECMERRCTLR14 setting */
/* Skip ECMERRCTLR15 setting */
[0] = {0xFD850040U, 0x3FFFC000U}, /* ECMERRCTLR16 */
/* Skip ECMERRCTLR17 setting */
/* Skip ECMERRCTLR18 setting */
/* Skip ECMERRCTLR19 setting */
/* Skip ECMERRCTLR20 setting */
/* Skip ECMERRCTLR21 setting */
/* Skip ECMERRCTLR22 setting */
/* Skip ECMERRCTLR23 setting */
/* Skip ECMERRCTLR24 setting */
/* Skip ECMERRCTLR25 setting */
/* Skip ECMERRCTLR26 setting */
/* Skip ECMERRCTLR27 setting */
/* Skip ECMERRCTLR28 setting */
/* Skip ECMERRCTLR29 setting */
/* Skip ECMERRCTLR30 setting */
/* Skip ECMERRCTLR31 setting */
/* Skip ECMERRCTLR32 setting */
/* Skip ECMERRCTLR33 setting */
/* Skip ECMERRCTLR34 setting */
/* Skip ECMERRCTLR35 setting */
/* Skip ECMERRCTLR36 setting */
/* Skip ECMERRCTLR37 setting */
/* Skip ECMERRCTLR38 setting */
/* Skip ECMERRCTLR39 setting */
/* Skip ECMERRCTLR40 setting */
/* Skip ECMERRCTLR41 setting */
/* Skip ECMERRCTLR42 setting */
};
const ECM_ERROR_TABLE ecmerrtgtr_type3_tbl[TYPE3_ECM_TGTREG_MAX] = {
[0] = {0xFD850200U, 0x80000000U}, /* ECMERRTGTR0 */
/* Skip ECMERRTGTR1 setting */
/* Skip ECMERRTGTR2 setting */
/* Skip ECMERRTGTR3 setting */
/* Skip ECMERRTGTR4 setting */
/* Skip ECMERRTGTR5 setting */
/* Skip ECMERRTGTR6 setting */
/* Skip ECMERRTGTR7 setting */
/* Skip ECMERRTGTR8 setting */
/* Skip ECMERRTGTR9 setting */
/* Skip ECMERRTGTR10 setting */
/* Skip ECMERRTGTR11 setting */
/* Skip ECMERRTGTR12 setting */
/* Skip ECMERRTGTR13 setting */
/* Skip ECMERRTGTR14 setting */
/* Skip ECMERRTGTR15 setting */
[1] = {0xFD850240U, 0x3FFFC000U}, /* ECMERRTGTR16 */
/* Skip ECMERRTGTR17 setting */
/* Skip ECMERRTGTR18 setting */
/* Skip ECMERRTGTR19 setting */
/* Skip ECMERRTGTR20 setting */
/* Skip ECMERRTGTR21 setting */
/* Skip ECMERRTGTR22 setting */
/* Skip ECMERRTGTR23 setting */
/* Skip ECMERRTGTR24 setting */
/* Skip ECMERRTGTR25 setting */
/* Skip ECMERRTGTR26 setting */
/* Skip ECMERRTGTR27 setting */
/* Skip ECMERRTGTR28 setting */
/* Skip ECMERRTGTR29 setting */
/* Skip ECMERRTGTR30 setting */
/* Skip ECMERRTGTR31 setting */
/* Skip ECMERRTGTR32 setting */
/* Skip ECMERRTGTR33 setting */
/* Skip ECMERRTGTR34 setting */
/* Skip ECMERRTGTR35 setting */
/* Skip ECMERRTGTR36 setting */
/* Skip ECMERRTGTR37 setting */
/* Skip ECMERRTGTR38 setting */
/* Skip ECMERRTGTR39 setting */
/* Skip ECMERRTGTR40 setting */
/* Skip ECMERRTGTR41 setting */
/* Skip ECMERRTGTR42 setting */
};
/* Unlock the write protect of ECM registers */
ecm_unlock();
NOTICE("ECMERRCTLR and ECMERRTGTR register initial setting.\n");
/* For the initial setting flow for Type-1, please refer to the following
* section in the "SAN(Safety Application Note)."
* Section 4.1.2.5 : (1)
* Section 4.1.4.5 : (1)
* Section 4.12.1.5 : (1)
* Section 4.13.1.5 : (1)
* Section 4.14.5 : (1)
* Section 4.16.5 : (1)
* Section 4.18.5 : (1)
* Section 4.2.7.5 : (1)
* Section 4.2.9.5 : (1)
* Section 4.23.5 : (1)
* Section 4.3.11.5 : (1)
* Section 4.3.12.5 : (1)
* Section 4.3.14.5 : (1)
* Section 4.3.19.5 : (1)
* Section 4.3.21.5 : (1)
* Section 4.4.14.5 : (1)
* Section 4.4.16.5 : (3)
* Section 4.4.18.5 : (1)
* Section 4.4.20.5 : (1)
* Section 4.4.3.5 : (1)
* Section 4.4.4.5 : (1)
* Section 4.4.6.5 : (1)
* Section 4.4.7.5 : (1)
* Section 4.4.9.5 : (1)
* Section 4.5.1.5 : (1)
* Section 4.7.1.5 : (1)
* Section 4.7.10.5 : (1)
* Section 4.7.3.5 : (1)
* Section 4.7.4.5 : (1)
* Section 4.7.7.5 : (1)
* Section 4.7.8.5 : (1)
* Section 5.6.5 : (1)
* Section 5.8.1.5 : (1)
*/
for (loop = 0U; loop < TYPE1_ECM_REG_MAX; loop++)
{
reg = mem_read32(ecmerrctlr_type1_tbl[loop].phys_addr);
reg |= (ecmerrctlr_type1_tbl[loop].value);
ecm_write(ecmerrctlr_type1_tbl[loop].phys_addr, reg);
INFO("[Type-1]ECMERRCTLR[\t%d]\t(0x%08x) =\t0x%08x \tsetting value = 0x%08x\n",
loop,
ecmerrctlr_type1_tbl[loop].phys_addr,
mem_read32(ecmerrctlr_type1_tbl[loop].phys_addr),
ecmerrctlr_type1_tbl[loop].value);
}
for (loop = 0U; loop < TYPE1_ECM_REG_MAX; loop++)
{
reg = mem_read32(ecmerrtgtr_type1_tbl[loop].phys_addr);
reg &= ~(ecmerrtgtr_type1_tbl[loop].value);
ecm_write(ecmerrtgtr_type1_tbl[loop].phys_addr, reg);
INFO("[Type-1]ECMERRTGTR[\t%d]\t(0x%08x) =\t0x%08x \tsetting value = 0x%08x\n",
loop,
ecmerrtgtr_type1_tbl[loop].phys_addr,
mem_read32(ecmerrtgtr_type1_tbl[loop].phys_addr),
ecmerrtgtr_type1_tbl[loop].value);
}
/* For the initial setting flow for Type-2, please refer to the following
* section in the "SAN(Safety Application Note)."
* Section 4.1.1.5 : (1)
* Section 4.12.2.5 : (1)
* Section 4.12.3.5 : (1)
* Section 4.15.5 : (1)
* Section 4.16.5 : (1)
* Section 4.2.1.5 : (1)
* Section 4.2.10.5 : (1)
* Section 4.2.12.5 : (1)
* Section 4.2.2.5 : (1)
* Section 4.2.4.5 : (1)
* Section 4.2.8.5 : (1)
* Section 4.3.1.5 : (1)
* Section 4.3.10.5 : (1)
* Section 4.3.11.5 : (1)
* Section 4.3.12.5 : (1)
* Section 4.3.13.5 : (1)
* Section 4.3.15.5 : (1)
* Section 4.3.16.5 : (1)
* Section 4.3.2.5 : (1)
* Section 4.3.5.5 : (1)
* Section 4.3.7.5 : (1)
* Section 4.3.8.5 : (1)
* Section 4.4.10.5 : (1)
* Section 4.4.12.5 : (8)
* Section 4.4.13.5 : (1)
* Section 4.4.15.5 : (1)
* Section 4.4.2.5 : (1)
* Section 4.5.3.5 : (1)
* Section 4.6.5 : (1)
* Section 4.7.2.5 : (1)
* Section 5.11.5 : (1)
* Section 5.12.5 : (1)
* Section 5.13.5 : (1)
* Section 5.4.5 : (1)
* Section 5.8.2.5 : (1)
*/
for (loop = 0U; loop < TYPE2_ECM_REG_MAX; loop++)
{
/* Initial Setting Type-2 for ECMERRCTLR registers */
reg = mem_read32(ecmerrctlr_type2_tbl[loop].phys_addr);
reg |= (ecmerrctlr_type2_tbl[loop].value);
ecm_write(ecmerrctlr_type2_tbl[loop].phys_addr, reg);
INFO("[Type-2]ECMERRCTLR[\t%d]\t(0x%08x) =\t0x%08x \tsetting value = 0x%08x\n",
loop,
ecmerrctlr_type2_tbl[loop].phys_addr,
mem_read32(ecmerrctlr_type2_tbl[loop].phys_addr),
ecmerrctlr_type2_tbl[loop].value);
}
for (loop = 0U; loop < TYPE2_ECM_REG_MAX; loop++)
{
/* Initial Setting Type-2 for ECMERRTGTR registers */
reg = mem_read32(ecmerrtgtr_type2_tbl[loop].phys_addr);
reg &= ~(ecmerrtgtr_type2_tbl[loop].value);
ecm_write(ecmerrtgtr_type2_tbl[loop].phys_addr, reg);
INFO("[Type-2]ECMERRTGTR[\t%d]\t(0x%08x) =\t0x%08x \tsetting value = 0x%08x\n",
loop,
ecmerrtgtr_type2_tbl[loop].phys_addr,
mem_read32(ecmerrtgtr_type2_tbl[loop].phys_addr),
ecmerrtgtr_type2_tbl[loop].value);
}
/* For the initial setting flow for Type-3, please refer to the following
* section in the "SAN(Safety Application Note)."
* Section 4.19.1.5 : (3)
* Section 6.2.5 : (12)
*/
for (loop = 0U; loop < TYPE3_ECM_CTLREG_MAX; loop++)
{
/* Initial Setting Type-3 for ECMERRCTLR registers */
reg = mem_read32(ecmerrctlr_type3_tbl[loop].phys_addr);
reg |= (ecmerrctlr_type3_tbl[loop].value);
ecm_write(ecmerrctlr_type3_tbl[loop].phys_addr, reg);
INFO("[Type-3]ECMERRCTLR[\t%d]\t(0x%08x) =\t0x%08x \tsetting value = 0x%08x\n",
loop,
ecmerrctlr_type3_tbl[loop].phys_addr,
mem_read32(ecmerrctlr_type3_tbl[loop].phys_addr),
ecmerrctlr_type3_tbl[loop].value);
}
for (loop = 0U; loop < TYPE3_ECM_TGTREG_MAX; loop++)
{
/* Initial Setting Type-3 for ECMERRTGTR registers */
reg = mem_read32(ecmerrtgtr_type3_tbl[loop].phys_addr);
reg &= ~(ecmerrtgtr_type3_tbl[loop].value);
ecm_write(ecmerrtgtr_type3_tbl[loop].phys_addr, reg);
INFO("[Type-3]ECMERRTGTR[\t%d]\t(0x%08x) =\t0x%08x \tsetting value = 0x%08x\n",
loop,
ecmerrtgtr_type3_tbl[loop].phys_addr,
mem_read32(ecmerrtgtr_type3_tbl[loop].phys_addr),
ecmerrtgtr_type3_tbl[loop].value);
}
/* Lock the ECM registers */
ecm_lock();
}
/* End of function ecm_init_setting(void) */
#endif /* ECM_ERROR_ENABLE == 1 */

View File

@@ -0,0 +1,42 @@
/*******************************************************************************
* 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 driver header
******************************************************************************/
#ifndef ECM_ENABLE_V4H
#define ECM_ENABLE_V4H
#if ((ECM_ERROR_ENABLE == 1) || (ECM_ENABLE == 1))
void ecm_unlock(void);
void ecm_write(uint32_t adr, uint32_t val);
void ecm_lock(void);
#endif /* (ECM_ERROR_ENABLE == 1) || (ECM_ENABLE == 1) */
#if (ECM_ERROR_ENABLE == 1)
void ecm_init_setting(void);
#endif /* ECM_ERROR_ENABLE == 1 */
#endif/* ECM_ENABLE_V4H */

View File

@@ -0,0 +1,302 @@
/*******************************************************************************
* Copyright (c) 2015-2022 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.
******************************************************************************/
#if defined(__RH850G3K__)
#include "remap_register.h"
#endif
#define RCAR_DDR_VERSION "rev.0.08rc7"
#define DRAM_CH_CNT 0x04
#define SLICE_CNT 0x02
#define CS_CNT 0x02
/* for pll setting */
#define CLK_DIV(a, diva, b, divb) (((a) * (divb)) / ((b) * (diva)))
#define CLK_MUL(a, diva, b, divb) (((a) * (b)) / ((diva) * (divb)))
/* for ddr density setting */
#define DBMEMCONF_REG(d3, row, BG, bank, col, dw) (((d3) << 30) | ((row) << 24) | ((BG) << 20) | ((bank) << 16) | ((col) << 8) | (dw))
#define DBMEMCONF_REGD(density) (DBMEMCONF_REG((density) % 2, ((density) + 1) / 2 + (28 - 2 - 2 - 10 - 1), 2, 2, 10, 1)) /* 16bit */
#define DBMEMCONF_VAL(ch,cs) (DBMEMCONF_REGD(DBMEMCONF_DENS(ch, cs)))
/* system registers : CPG */
#define CPG_FRQCRD_KICK_BIT (1U << 31)
#define CPG_PLL3CR0_KICK_BIT (1U << 31)
#define CPG_PLLECR_PLL3E_BIT (1U << 3)
#define CPG_PLLECR_PLL3ST_BIT (1U << 11)
#if defined(__RH850G3K__)
#define CPG_BASE (BASE_CPG_ADDR)
#else
#define CPG_BASE (0xE6150000U)
#endif
#define CPG_CPGWPR (CPG_BASE + 0x0000U)
#define CPG_CPGWPCR (CPG_BASE + 0x0004U)
#define CPG_FRQCRA (CPG_BASE + 0x0800U)
#define CPG_FRQCRB (CPG_BASE + 0x0804U)
#define CPG_FRQCRC (CPG_BASE + 0x0808U)
#define CPG_FRQCRD0 (CPG_BASE + 0x080CU)
#define CPG_PLLECR (CPG_BASE + 0x0820U)
#define CPG_PLL3CR0 (CPG_BASE + 0x083CU)
#define CPG_PLL3CR1 (CPG_BASE + 0x08C0U)
#define CPG_FSRCHKCLRR4 (CPG_BASE + 0x0590U)
#define CPG_FSRCHKSETR4 (CPG_BASE + 0x0510U)
#define CPG_FSRCHKRA4 (CPG_BASE + 0x0410U)
#define CPG_SRCR4 (CPG_BASE + 0x2C10U)
#define CPG_SRSTCLR4 (CPG_BASE + 0x2C90U)
#define CPG_PLL3FBCKMCSR (CPG_BASE + 0x0C60U)
#define CPG_PLL3FBCKMECR (CPG_BASE + 0x0C64U)
#define CPG_PLL3FBCKMLCH (CPG_BASE + 0x0C68U)
#define CPG_PLL3FBCKMLCL (CPG_BASE + 0x0C6CU)
#define CPG_PLL3FBCKMCNT (CPG_BASE + 0x0C70U)
#define CPG_PLL3FBCKMCNTE (CPG_BASE + 0x0C74U)
#if defined(__RH850G3K__)
#define RST_BASE (BASE_RESET_ADDR)
#else
#define RST_BASE (0xE6160000U)
#endif
#define RST_MODEMR0 (RST_BASE + 0x0000U)
#define RST_MODEMR1 (RST_BASE + 0x0004U)
/* Product Register */
#define PRR (0xFFF00044U)
#define PRR_PRODUCT_MASK (0x00007F00U)
#define PRR_CUT_MASK (0x000000FFU)
#define PRR_PRODUCT_V4H (0x00005C00U) /* R-Car V4H */
#define PRR_PRODUCT_10 (0x00000000U) /* ver 1.0 */
#define PRR_PRODUCT_20 (0x00000010U) /* ver 2.0 */
/* DBSC registers */
#if defined(__RH850G3K__)
#define DBSC_D_BASE (BASE_DBSC_ADDR + 0x14000U) /* forV4H DBSC0 clk_dbsc region DBSC1_D_BASE = 0xE67A8000U */
#define DBSC_A_BASE (BASE_DBSC_ADDR) /* forV4H DBSC0 clk_axim region DBSC1_A_BASE = 0xE6798000U */
#else
#define DBSC_D_BASE (0xE67A4000U) /* forV4H DBSC0 clk_dbsc region DBSC1_D_BASE = 0xE67A8000U */
#define DBSC_A_BASE (0xE6790000U) /* forV4H DBSC0 clk_axim region DBSC1_A_BASE = 0xE6798000U */
#endif
#define DBSC_DBSYSCONF0 (DBSC_A_BASE + 0x0000U)
#define DBSC_DBSYSCONF1 (DBSC_D_BASE + 0x0000U)
#define DBSC_DBSYSCONF1A (DBSC_A_BASE + 0x0004U)
#define DBSC_DBSYSCONF2 (DBSC_D_BASE + 0x0004U)
#define DBSC_DBPHYCONF0 (DBSC_D_BASE + 0x0008U)
#define DBSC_DBSYSCONF2A (DBSC_A_BASE + 0x0008U)
#define DBSC_DBMEMKIND (DBSC_D_BASE + 0x0020U)
#define DBSC_DBMEMKINDA (DBSC_A_BASE + 0x0020U)
#define DBSC_DBMEMCONF(ch,cs) (DBSC_D_BASE + 0x0030U + 0x10U * (ch) + 0x04U * (cs))
#define DBSC_DBMEMCONF_0_0 (DBSC_D_BASE + 0x0030U)
#define DBSC_DBMEMCONF_0_1 (DBSC_D_BASE + 0x0034U)
#define DBSC_DBMEMCONF_0_2 (DBSC_D_BASE + 0x0038U)
#define DBSC_DBMEMCONF_0_3 (DBSC_D_BASE + 0x003CU)
#define DBSC_DBMEMCONF_1_0 (DBSC_D_BASE + 0x0040U)
#define DBSC_DBMEMCONF_1_1 (DBSC_D_BASE + 0x0044U)
#define DBSC_DBMEMCONF_1_2 (DBSC_D_BASE + 0x0048U)
#define DBSC_DBMEMCONF_1_3 (DBSC_D_BASE + 0x004CU)
#define DBSC_DBMEMCONF_2_0 (DBSC_D_BASE + 0x0050U)
#define DBSC_DBMEMCONF_2_1 (DBSC_D_BASE + 0x0054U)
#define DBSC_DBMEMCONF_2_2 (DBSC_D_BASE + 0x0058U)
#define DBSC_DBMEMCONF_2_3 (DBSC_D_BASE + 0x005CU)
#define DBSC_DBMEMCONF_3_0 (DBSC_D_BASE + 0x0060U)
#define DBSC_DBMEMCONF_3_1 (DBSC_D_BASE + 0x0064U)
#define DBSC_DBMEMCONF_3_2 (DBSC_D_BASE + 0x0068U)
#define DBSC_DBMEMCONF_3_3 (DBSC_D_BASE + 0x006CU)
#define DBSC_DBMEMCONFA(ch,cs) (DBSC_A_BASE + 0x0030U + 0x10U * (ch) + 0x04U * (cs))
#define DBSC_DBMEMCONF_0_0A (DBSC_A_BASE + 0x0030U)
#define DBSC_DBMEMCONF_0_1A (DBSC_A_BASE + 0x0034U)
#define DBSC_DBMEMCONF_0_2A (DBSC_A_BASE + 0x0038U)
#define DBSC_DBMEMCONF_0_3A (DBSC_A_BASE + 0x003CU)
#define DBSC_DBMEMCONF_1_0A (DBSC_A_BASE + 0x0040U)
#define DBSC_DBMEMCONF_1_1A (DBSC_A_BASE + 0x0044U)
#define DBSC_DBMEMCONF_1_2A (DBSC_A_BASE + 0x0048U)
#define DBSC_DBMEMCONF_1_3A (DBSC_A_BASE + 0x004CU)
#define DBSC_DBMEMCONF_2_0A (DBSC_A_BASE + 0x0050U)
#define DBSC_DBMEMCONF_2_1A (DBSC_A_BASE + 0x0054U)
#define DBSC_DBMEMCONF_2_2A (DBSC_A_BASE + 0x0058U)
#define DBSC_DBMEMCONF_2_3A (DBSC_A_BASE + 0x005CU)
#define DBSC_DBMEMCONF_3_0A (DBSC_A_BASE + 0x0060U)
#define DBSC_DBMEMCONF_3_1A (DBSC_A_BASE + 0x0064U)
#define DBSC_DBMEMCONF_3_2A (DBSC_A_BASE + 0x0068U)
#define DBSC_DBMEMCONF_3_3A (DBSC_A_BASE + 0x006CU)
#define DBSC_DBSYSCNT0 (DBSC_D_BASE + 0x0100U)
#define DBSC_DBSYSCNT0A (DBSC_A_BASE + 0x0100U)
#define DBSC_DBACEN (DBSC_A_BASE + 0x0200U)
#define DBSC_DBRFEN (DBSC_D_BASE + 0x0204U)
#define DBSC_DBCMD (DBSC_D_BASE + 0x0208U)
#define DBSC_DBWAIT (DBSC_D_BASE + 0x0210U)
#define DBSC_DBTR(x) (DBSC_D_BASE + 0x0300U + 0x04U * (x))
#define DBSC_DBTR0 (DBSC_D_BASE + 0x0300U)
#define DBSC_DBTR1 (DBSC_D_BASE + 0x0304U)
#define DBSC_DBTR2 (DBSC_D_BASE + 0x0308U)
#define DBSC_DBTR3 (DBSC_D_BASE + 0x030CU)
#define DBSC_DBTR4 (DBSC_D_BASE + 0x0310U)
#define DBSC_DBTR5 (DBSC_D_BASE + 0x0314U)
#define DBSC_DBTR6 (DBSC_D_BASE + 0x0318U)
#define DBSC_DBTR7 (DBSC_D_BASE + 0x031CU)
#define DBSC_DBTR8 (DBSC_D_BASE + 0x0320U)
#define DBSC_DBTR9 (DBSC_D_BASE + 0x0324U)
#define DBSC_DBTR10 (DBSC_D_BASE + 0x0328U)
#define DBSC_DBTR11 (DBSC_D_BASE + 0x032CU)
#define DBSC_DBTR12 (DBSC_D_BASE + 0x0330U)
#define DBSC_DBTR13 (DBSC_D_BASE + 0x0334U)
#define DBSC_DBTR14 (DBSC_D_BASE + 0x0338U)
#define DBSC_DBTR15 (DBSC_D_BASE + 0x033CU)
#define DBSC_DBTR16 (DBSC_D_BASE + 0x0340U)
#define DBSC_DBTR17 (DBSC_D_BASE + 0x0344U)
#define DBSC_DBTR18 (DBSC_D_BASE + 0x0348U)
#define DBSC_DBTR19 (DBSC_D_BASE + 0x034CU)
#define DBSC_DBTR20 (DBSC_D_BASE + 0x0350U)
#define DBSC_DBTR21 (DBSC_D_BASE + 0x0354U)
#define DBSC_DBTR22 (DBSC_D_BASE + 0x0358U)
#define DBSC_DBTR23 (DBSC_D_BASE + 0x035CU)
#define DBSC_DBTR24 (DBSC_D_BASE + 0x0360U)
#define DBSC_DBTR25 (DBSC_D_BASE + 0x0364U)
#define DBSC_DBTR26 (DBSC_D_BASE + 0x0368U)
#define DBSC_DBTR27 (DBSC_D_BASE + 0x036CU)
#define DBSC_DBTR28 (DBSC_D_BASE + 0x0370U)
#define DBSC_DBTR29 (DBSC_D_BASE + 0x0374U)
#define DBSC_DBTR30 (DBSC_D_BASE + 0x0378U)
#define DBSC_DBTR31 (DBSC_D_BASE + 0x037CU)
#define DBSC_DBTR32 (DBSC_D_BASE + 0x0380U)
#define DBSC_DBTR33 (DBSC_D_BASE + 0x0384U)
#define DBSC_DBTR34 (DBSC_D_BASE + 0x0388U)
#define DBSC_DBTR35 (DBSC_D_BASE + 0x038CU)
#define DBSC_DBTR36 (DBSC_D_BASE + 0x0390U)
#define DBSC_DBTR37 (DBSC_D_BASE + 0x0394U)
#define DBSC_DBBL (DBSC_D_BASE + 0x0400U)
#define DBSC_DBBLA (DBSC_A_BASE + 0x0400U)
#define DBSC_DBRFCNF1 (DBSC_D_BASE + 0x0414U)
#define DBSC_DBRFCNF2 (DBSC_D_BASE + 0x0418U)
#define DBSC_DBCALCNF (DBSC_D_BASE + 0x0424U)
#define DBSC_DBRNK(x) (DBSC_D_BASE + 0x0430U + 0x04U * (x))
#define DBSC_DBRNK2 (DBSC_D_BASE + 0x0438U)
#define DBSC_DBRNK3 (DBSC_D_BASE + 0x043CU)
#define DBSC_DBRNK4 (DBSC_D_BASE + 0x0440U)
#define DBSC_DBRNK5 (DBSC_D_BASE + 0x0444U)
#define DBSC_DBDBICNT (DBSC_D_BASE + 0x0518U)
#define DBSC_DBDFIPMSTRCNF (DBSC_D_BASE + 0x0520U)
#define DBSC_DBDFICUPDCNF (DBSC_D_BASE + 0x0540U)
#define DBSC_DBDFISTAT(ch) (DBSC_D_BASE + 0x0600U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBDFISTAT_0 (DBSC_D_BASE + 0x0600U)
#define DBSC_DBDFISTAT_1 (DBSC_D_BASE + 0x0640U)
#define DBSC_DBDFISTAT_2 (DBSC_D_BASE + 0x0680U)
#define DBSC_DBDFISTAT_3 (DBSC_D_BASE + 0x06C0U)
#define DBSC_DBDFICNT(ch) (DBSC_D_BASE + 0x0604U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBDFICNT_0 (DBSC_D_BASE + 0x0604U)
#define DBSC_DBDFICNT_1 (DBSC_D_BASE + 0x0644U)
#define DBSC_DBDFICNT_2 (DBSC_D_BASE + 0x0684U)
#define DBSC_DBDFICNT_3 (DBSC_D_BASE + 0x06C4U)
#define DBSC_DBPDCNT0_0 (DBSC_D_BASE + 0x0610U)
#define DBSC_DBPDCNT0_1 (DBSC_D_BASE + 0x0614U)
#define DBSC_DBPDCNT0_2 (DBSC_D_BASE + 0x0618U)
#define DBSC_DBPDCNT0_3 (DBSC_D_BASE + 0x061CU)
#define DBSC_DBPDCNT1_0 (DBSC_D_BASE + 0x0650U)
#define DBSC_DBPDCNT1_1 (DBSC_D_BASE + 0x0654U)
#define DBSC_DBPDCNT1_2 (DBSC_D_BASE + 0x0658U)
#define DBSC_DBPDCNT1_3 (DBSC_D_BASE + 0x065CU)
#define DBSC_DBPDCNT2(ch) (DBSC_D_BASE + 0x0618U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBPDCNT2_0 (DBSC_D_BASE + 0x0690U)
#define DBSC_DBPDCNT2_1 (DBSC_D_BASE + 0x0694U)
#define DBSC_DBPDCNT2_2 (DBSC_D_BASE + 0x0698U)
#define DBSC_DBPDCNT2_3 (DBSC_D_BASE + 0x069CU)
#define DBSC_DBPDCNT3_0 (DBSC_D_BASE + 0x06D0U)
#define DBSC_DBPDCNT3_1 (DBSC_D_BASE + 0x06D4U)
#define DBSC_DBPDCNT3_2 (DBSC_D_BASE + 0x06D8U)
#define DBSC_DBPDCNT3_3 (DBSC_D_BASE + 0x06DCU)
#define DBSC_DBPDLK(ch) (DBSC_D_BASE + 0x0620U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBPDLK_0 (DBSC_D_BASE + 0x0620U)
#define DBSC_DBPDLK_1 (DBSC_D_BASE + 0x0660U)
#define DBSC_DBPDLK_2 (DBSC_D_BASE + 0x06a0U)
#define DBSC_DBPDLK_3 (DBSC_D_BASE + 0x06e0U)
#define DBSC_DBPDRGA(ch) (DBSC_D_BASE + 0x0624U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBPDRGA_0 (DBSC_D_BASE + 0x0624U)
#define DBSC_DBPDRGA_1 (DBSC_D_BASE + 0x0664U)
#define DBSC_DBPDRGA_2 (DBSC_D_BASE + 0x06A4U)
#define DBSC_DBPDRGA_3 (DBSC_D_BASE + 0x06E4U)
#define DBSC_DBPDRGD(ch) (DBSC_D_BASE + 0x0628U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBPDRGD_0 (DBSC_D_BASE + 0x0628U)
#define DBSC_DBPDRGD_1 (DBSC_D_BASE + 0x0668U)
#define DBSC_DBPDRGD_2 (DBSC_D_BASE + 0x06A8U)
#define DBSC_DBPDRGD_3 (DBSC_D_BASE + 0x06E8U)
#define DBSC_DBPDSTAT0(ch) (DBSC_D_BASE + 0x0630U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBPDSTAT0_0 (DBSC_D_BASE + 0x0630U)
#define DBSC_DBPDSTAT1_0 (DBSC_D_BASE + 0x0670U)
#define DBSC_DBPDSTAT1(ch) (DBSC_D_BASE + 0x0634U + 0x2000U * (ch & 0x02U) + 0x40U * (ch & 0x01U))
#define DBSC_DBPDSTAT0_1 (DBSC_D_BASE + 0x0634U)
#define DBSC_DBPDSTA1T_1 (DBSC_D_BASE + 0x0674U)
#define DBSC_DBCAM0CTRL0 (DBSC_A_BASE + 0x0940U)
#define DBSC_DBCAMSTAT0(x) (DBSC_A_BASE + 0x0980U + 0x4000U *(x & 0x02U) + 0x10U * (x & 0x01U))
#define DBSC_DBCAM0STAT0 (DBSC_A_BASE + 0x0980U)
#define DBSC_DBCAM1STAT0 (DBSC_A_BASE + 0x0990U)
#define DBSC_DBCAM2STAT0 (DBSC_A_BASE + 0x09A0U)
#define DBSC_DBCAM3STAT0 (DBSC_A_BASE + 0x09B0U)
#define DBSC_DBCAMSTAT1(x) (DBSC_A_BASE + 0x0984U + 0x4000U *(x & 0x02U) + 0x10U * (x & 0x01U))
#define DBSC_DBCAM0STAT1 (DBSC_A_BASE + 0x0984U)
#define DBSC_DBCAM1STAT1 (DBSC_A_BASE + 0x0994U)
#define DBSC_DBCAM2STAT1 (DBSC_A_BASE + 0x09A4U)
#define DBSC_DBCAM3STAT1 (DBSC_A_BASE + 0x09B4U)
#define DBSC_DBBCAMDIS (DBSC_A_BASE + 0x09FCU)
#define DBSC_DBSCHRW1 (DBSC_A_BASE + 0x1024U)
#define DBSC_DBSCHTR0 (DBSC_A_BASE + 0x1030U)
#define DBSC_DBSCHFCTST01(x) (DBSC_A_BASE + 0x1040U + 0x04U * (x))
#define DBSC_DBSCHFCTST0 (DBSC_A_BASE + 0x1040U)
#define DBSC_DBSCHFCTST1 (DBSC_A_BASE + 0x1044U)
#define DBSC_DBSCHQOS(x,y) (DBSC_A_BASE + 0x1100U + 0x10U * (x) + 0x04U * (y))

View File

@@ -0,0 +1,217 @@
/*******************************************************************************
* Copyright (c) 2023-2024 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 : ECC setting function
******************************************************************************/
/******************************************************************************
* @file ecc_enable_v4m.c
* - Version : 0.03
* @brief Enable setting process of ECC for DRAM.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 21.08.2023 0.01 First Release
* : 13.06.2024 0.02 Fix register setting for EDC_CFG, and revise
* : the ecm_lock()/ecm_unlock() process.
* : 07.04.2025 0.06 Remove unused functions.
*****************************************************************************/
#include <stdint.h>
#include <cnf_tbl.h>
#include <remap.h>
#include <wdt.h>
#if (ECM_ENABLE == 1)
#include "ecc_enable_v4m.h"
#include "v4m/lpddr5/boot_init_dram_regdef.h"
#include "ecm_enable_v4m.h"
#define AXI_SICREMAP_NUM (5U)
#define RGID_BASE1 (0xFE600000U)
#define RGID_BASE2 (0xE7A00000U)
#define RGID_BASE3 (0xEB800000U)
#define RGID_BASE4 (0xFD800000U)
#define RGID_BASE5 (0xFEA00000U)
#define FDT_COUNTER_MASK (0x0000FFFFU)
static void axi_timeout_setting(void);
void edc_axi_enable(void)
{
uint32_t edc_tmp;
/* Unlock the write protect of ECM registers */
ecm_unlock();
/* (1) Set the corresponding bits of the ECMERRTGTR and ECMERRCTLR registers
to inform the external device of the error via the ERROROUT# pin. */
/* Set bit 11 - bit 2 of ECMERRTGTR7 to all 0 and bit 11 - bit 2 of
ECMERRCTLR7 to 1. (Error of AXI-Bus ECM of each hierarchy) */
edc_tmp = mem_read32(ECMERRTGTR7);
edc_tmp &= ~(0x3FFU << 2U);
ecm_write(ECMERRTGTR7, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR7);
edc_tmp |= (0x3FFU << 2U);
ecm_write(ECMERRCTLR7, edc_tmp);
/* Set bit 28 - bit 16 of ECMERRTGTR39 to all 0 and bit 28 - bit 16 of
ECMERRCTLR39 to 1. (Error of AXI-Bus ECM of each hierarchy) */
edc_tmp = mem_read32(ECMERRTGTR39);
edc_tmp &= ~(0x1FFFU << 16U);
ecm_write(ECMERRTGTR39, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR39);
edc_tmp |= (0x1FFFU << 16U);
ecm_write(ECMERRCTLR39, edc_tmp);
/* Set bit 26 of ECMERRTGTR1 to 0 and bit 26 of
ECMERRCTLR1 to 1. (CCI bus EDC error) */
edc_tmp = mem_read32(ECMERRTGTR1);
edc_tmp &= ~(0x1U << 26U);
ecm_write(ECMERRTGTR1, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR1);
edc_tmp |= (0x1U << 26U);
ecm_write(ECMERRCTLR1, edc_tmp);
axi_timeout_setting();
/* Lock the ECM registers */
ecm_lock();
}
void edc_vram_enable(void)
{
uint32_t edc_tmp;
/* Unlock the write protect of ECM registers */
ecm_unlock();
/* (1) Set the corresponding bits of the ECMERRTGTR and ECMERRCTLR registers
to inform the external device of the error via the ERROROUT# pin. */
/* Set bit 30 of ECMERRTGTR7 to 0 and bit 30 of ECMERRCTLR7 to 1.
(RT-VRAM edc 1-bit error) */
edc_tmp = mem_read32(ECMERRTGTR7);
edc_tmp &= ~(0x1U << 30U);
ecm_write(ECMERRTGTR7, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR7);
edc_tmp |= (0x1U << 30U);
ecm_write(ECMERRCTLR7, edc_tmp);
/* Set bit 29 of ECMERRTGTR7 to 0 and bit 29 of ECMERRCTLR7 to 1.
(RT-VRAM edc multi-bit error) */
edc_tmp = mem_read32(ECMERRTGTR7);
edc_tmp &= ~(0x1U << 29U);
ecm_write(ECMERRTGTR7, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR7);
edc_tmp |= (0x1U << 29U);
ecm_write(ECMERRCTLR7, edc_tmp);
/* Set bit 19 of ECMERRTGTR17 to 0 and bit 19 of ECMERRCTLR17 to 1.
(RT-VRAM edc 1-bit error) */
edc_tmp = mem_read32(ECMERRTGTR17);
edc_tmp &= ~(0x1U << 19U);
ecm_write(ECMERRTGTR17, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR17);
edc_tmp |= (0x1U << 19U);
ecm_write(ECMERRCTLR17, edc_tmp);
/* Set bit 18 of ECMERRTGTR17 to 0 and bit 18 of ECMERRCTLR17 to 1.
(RT-VRAM edc multi-bit error) */
edc_tmp = mem_read32(ECMERRTGTR17);
edc_tmp &= ~(0x1U << 18U);
ecm_write(ECMERRTGTR17, edc_tmp);
edc_tmp = mem_read32(ECMERRCTLR17);
edc_tmp |= (0x1U << 18U);
ecm_write(ECMERRCTLR17, edc_tmp);
/* Set bit 0 of EDC_CFG to 1. (EDC Error Control) */
edc_tmp = mem_read32(EDC_CFG);
edc_tmp |= (0x1U << 0U);
mem_write32(EDC_CFG, edc_tmp);
/* Lock the ECM registers */
ecm_lock();
}
static void axi_timeout_setting(void)
{
uint32_t reg;
uint32_t loop;
REMAP_TABLE axi_remap_tbl[AXI_SICREMAP_NUM] = {
{RGID_BASE1, 0U},
{RGID_BASE2, 0U},
{RGID_BASE3, 0U},
{RGID_BASE4, 0U},
{RGID_BASE5, 0U},
};
/* Register of AXI Base */
for (loop = 0U; loop < AXI_SICREMAP_NUM; loop++)
{
remap_register(axi_remap_tbl[loop].base_addr, &axi_remap_tbl[loop].rmp_addr);
}
/* Set the COUNTER bits of the FDT_* registers for all safety-related modules to minimum value with 1ms or more. */
for (loop = 0U; loop < FDT_REG_MAX; loop++)
{
reg = mem_read32(g_fdt_tbl[loop].reg_addr);
reg &= ~(FDT_COUNTER_MASK);
reg |= g_fdt_tbl[loop].value;
mem_write32(g_fdt_tbl[loop].reg_addr, reg);
INFO("FDT[%d] =\t0x%08x \tsetting value = 0x%08x\n", loop, mem_read32(g_fdt_tbl[loop].reg_addr), g_fdt_tbl[loop].value);
}
for(loop = 0U; loop < INTEN_REG_MAX; loop++)
{
/* Set access protection setting value of Region ID (AXI bus of Region ID register) */
mem_write32(g_inten_tbl[loop].reg_addr, g_inten_tbl[loop].value);
INFO("INTEN[%d] =\t0x%08x \tsetting value = 0x%08x\n", loop, mem_read32(g_inten_tbl[loop].reg_addr), g_inten_tbl[loop].value);
}
/* Unregister of AXI Base */
for (loop = 0U; loop < AXI_SICREMAP_NUM; loop++)
{
remap_unregister(axi_remap_tbl[loop].rmp_addr);
}
wdt_restart();
}
#endif /* ECM_ENABLE == 1 */

View File

@@ -0,0 +1,123 @@
/*******************************************************************************
* Copyright (c) 2022-2024 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 : ECC driver header
******************************************************************************/
#ifndef ECC_PROTECT
#define ECC_PROTECT
#include "remap_register.h"
/* DBSC registers */
#if defined(__RH850G3K__)
#include "mem_io.h"
#include "log.h"
#define DBSC_D_BASE (BASE_DBSC_ADDR + 0x14000U) /* forV4H DBSC0 clk_dbsc region DBSC1_D_BASE = 0xE67A8000U */
#define DBSC_A_BASE (BASE_DBSC_ADDR) /* forV4H DBSC0 clk_axim region DBSC1_A_BASE = 0xE6798000U */
#define ECM_BASE (BASE_ECC_ADDR)
#else
#include <mmio.h>
#include <debug.h>
#define DBSC_D_BASE (0xE67A4000U) /* forV4H DBSC0 clk_dbsc region DBSC1_D_BASE = 0xE67A8000U */
#define DBSC_A_BASE (0xE6790000U) /* forV4H DBSC0 clk_axim region DBSC1_A_BASE = 0xE6798000U */
#define ECM_BASE (0xE6250000U)
#endif/* defined(__RH850G3K__) */
#define RTVRAM_REG_BASE (0xFFEC0000U)
void edc_axi_enable(void);
void edc_vram_enable(void);
#define DB0SYSCNT0 (DBSC_D_BASE + 0x0100U)
#define DB0SYSCNT0A (DBSC_A_BASE + 0x0100U)
#define DB1SYSCNT0 (DB0SYSCNT0 + 0x4000U)
#define DB1SYSCNT0A (DB0SYSCNT0A + 0x8000U)
#define DBSC_DBACEN0 (DBSC_A_BASE + 0x0200U)
#define DBSC_DBACEN1 (DBSC_DBACEN0 + 0x8000U)
#define ECMWACNTR (ECM_BASE + 0x0A04U)
#define ECMWPCNTR (ECM_BASE + 0x0A00U)
#define ECMERRTGTR0 (ECM_BASE + 0x0200U)
#define ECMERRCTLR0 (ECM_BASE + 0x0000U)
#define ECMERRTGTR1 (ECM_BASE + 0x0200U + 0x4U * 1U)
#define ECMERRCTLR1 (ECM_BASE + 0x0000U + 0x4U * 1U)
#define ECMERRTGTR7 (ECM_BASE + 0x0200U + 0x4U * 7U)
#define ECMERRCTLR7 (ECM_BASE + 0x0000U + 0x4U * 7U)
#define ECMERRTGTR17 (ECM_BASE + 0x0200U + 0x4U * 17U)
#define ECMERRCTLR17 (ECM_BASE + 0x0000U + 0x4U * 17U)
#define ECMERRTGTR39 (ECM_BASE + 0x0200U + 0x4U * 39U)
#define ECMERRCTLR39 (ECM_BASE + 0x0000U + 0x4U * 39U)
#define DB0FSCONF00A (DBSC_A_BASE + 0x7640U)
#define DB1FSCONF00A (DB0FSCONF00A + 0x8000U)
#define DB0FSCONF01A (DBSC_A_BASE + 0x7644U)
#define DB1FSCONF01A (DB0FSCONF01A + 0x8000U)
#define DB0FSCONF02A (DBSC_A_BASE + 0x7648U)
#define DB1FSCONF02A (DB0FSCONF02A + 0x8000U)
#define DB0FSCTRL01A (DBSC_A_BASE + 0x7604U)
#define DB1FSCTRL01A (DB0FSCTRL01A + 0x8000U)
#define DB0FSSTAT01A (DBSC_A_BASE + 0x7684U)
#define DB1FSSTAT01A (DB0FSSTAT01A + 0x8000U)
#define DB0FSSTAT00A (DBSC_A_BASE + 0x7680U)
#define DB1FSSTAT00A (DB0FSSTAT00A + 0x8000U)
#define DB0FSINTENB02A (DBSC_A_BASE + 0x7088U)
#define DB1FSINTENB02A (DB0FSINTENB02A + 0x8000U)
#define DB0FSINTENB04A (DBSC_A_BASE + 0x7090U)
#define DB1FSINTENB04A (DB0FSINTENB04A + 0x8000U)
#define DB0FSDRAMECCAREA0 (DBSC_A_BASE + 0x7450U)
#define DB0FSDRAMECCAREA1 (DBSC_A_BASE + 0x7454U)
#define DB1FSDRAMECCAREA0 (DB0FSDRAMECCAREA0 + 0x8000U)
#define DB1FSDRAMECCAREA1 (DB0FSDRAMECCAREA1 + 0x8000U)
#define DB0FSCONFAXI0 (DBSC_A_BASE + 0x7400U)
#define DB1FSCONFAXI0 (DB0FSCONFAXI0 + 0x8000U)
#define EDC_CFG (RTVRAM_REG_BASE + 0x4110U)
/********************* Set by the user *********************/
/* The row address of ECC Protection Area Size for memory rank 0/1 of DBSC0/1 */
#define ECC_PROT_SIZE00 (0x1000U)
#define ECC_PROT_SIZE01 (0x1000U)
#define ECC_PROT_SIZE10 (0x1000U)
#define ECC_PROT_SIZE11 (0x1000U)
/* Start and End row address of ECC Protection area for rank0 of DBSC0/1 */
#define START_ECC_INIT_AREA00 (0x00000000U)
#define START_ECC_INIT_AREA10 (0x00000000U)
#define END_ECC_INIT_AREA00 (0x00000FFFU)
#define END_ECC_INIT_AREA10 (0x00000FFFU)
/* Start and End row address of ECC Protection area for rank1 of DBSC0/1 */
#define START_ECC_INIT_AREA01 (0x00000000U)
#define START_ECC_INIT_AREA11 (0x00000000U)
#define END_ECC_INIT_AREA01 (0x00000FFFU)
#define END_ECC_INIT_AREA11 (0x00000FFFU)
/*********** Other settings cannot be changed ***************/
#endif/* ECC_PROTECT */

View File

@@ -0,0 +1,534 @@
/*******************************************************************************
* 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) || (ECM_ENABLE == 1))
#include "ecc_enable_v4m.h"
#include "mem_io.h"
#endif /* (ECM_ERROR_ENABLE == 1) || (ECM_ENABLE == 1) */
#if (ECM_ERROR_ENABLE == 1)
#define TYPE1_ECM_REG_MAX (14U)
#define TYPE2_ECM_REG_MAX (21U)
#define TYPE3_ECM_CTLREG_MAX (1U)
#define TYPE3_ECM_TGTREG_MAX (2U)
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) || (ECM_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) || (ECM_ENABLE == 1) */
#if (ECM_ERROR_ENABLE == 1)
void ecm_init_setting(void)
{
uint32_t reg;
uint32_t loop;
const ECM_ERROR_TABLE ecmerrctlr_type1_tbl[TYPE1_ECM_REG_MAX] = {
[0] = {0xFD850000U, 0x00381000U}, /* ECMERRCTLR0 */
[1] = {0xFD850004U, 0xA400C000U}, /* ECMERRCTLR1 */
/* Skip ECMERRCTLR2 setting */
/* Skip ECMERRCTLR3 setting */
/* Skip ECMERRCTLR4 setting */
/* Skip ECMERRCTLR5 setting */
[2] = {0xFD850018U, 0xCC000000U}, /* ECMERRCTLR6 */
[3] = {0xFD85001CU, 0x08000000U}, /* ECMERRCTLR7 */
/* Skip ECMERRCTLR8 setting */
/* Skip ECMERRCTLR9 setting */
/* Skip ECMERRCTLR10 setting */
/* Skip ECMERRCTLR11 setting */
/* Skip ECMERRCTLR12 setting */
/* Skip ECMERRCTLR13 setting */
/* Skip ECMERRCTLR14 setting */
/* Skip ECMERRCTLR15 setting */
/* Skip ECMERRCTLR16 setting */
[4] = {0xFD850044U, 0x2D001000U}, /* ECMERRCTLR17 */
[5] = {0xFD850048U, 0x0CC001FFU}, /* ECMERRCTLR18 */
[6] = {0xFD85004CU, 0xFFF80000U}, /* ECMERRCTLR19 */
[7] = {0xFD850050U, 0x0000001EU}, /* ECMERRCTLR20 */
[8] = {0xFD850054U, 0x9F000000U}, /* ECMERRCTLR21 */
/* Skip ECMERRCTLR22 setting */
/* Skip ECMERRCTLR23 setting */
/* Skip ECMERRCTLR24 setting */
/* Skip ECMERRCTLR25 setting */
/* Skip ECMERRCTLR26 setting */
/* Skip ECMERRCTLR27 setting */
/* Skip ECMERRCTLR28 setting */
/* Skip ECMERRCTLR29 setting */
/* Skip ECMERRCTLR30 setting */
/* Skip ECMERRCTLR31 setting */
[9] = {0xFD850080U, 0x10000000U}, /* ECMERRCTLR32 */
[10] = {0xFD850084U, 0x10000000U}, /* ECMERRCTLR33 */
/* Skip ECMERRCTLR34 setting */
[11] = {0xFD85008CU, 0x20002280U}, /* ECMERRCTLR35 */
/* Skip ECMERRCTLR36 setting */
/* Skip ECMERRCTLR37 setting */
[12] = {0xFD850098U, 0x33300054U}, /* ECMERRCTLR38 */
/* Skip ECMERRCTLR39 setting */
/* Skip ECMERRCTLR40 setting */
[13] = {0xFD8500A4U, 0x01000880U}, /* ECMERRCTLR41 */
/* Skip ECMERRCTLR42 setting */
};
const ECM_ERROR_TABLE ecmerrtgtr_type1_tbl[TYPE1_ECM_REG_MAX] = {
[0] = {0xFD850200U, 0x00381000U}, /* ECMERRTGTR0 */
[1] = {0xFD850204U, 0xA400C000U}, /* ECMERRTGTR1 */
/* Skip ECMERRTGTR2 setting */
/* Skip ECMERRTGTR3 setting */
/* Skip ECMERRTGTR4 setting */
/* Skip ECMERRTGTR5 setting */
[2] = {0xFD850218U, 0xCC000000U}, /* ECMERRTGTR6 */
[3] = {0xFD85021CU, 0x08000000U}, /* ECMERRTGTR7 */
/* Skip ECMERRTGTR8 setting */
/* Skip ECMERRTGTR9 setting */
/* Skip ECMERRTGTR10 setting */
/* Skip ECMERRTGTR11 setting */
/* Skip ECMERRTGTR12 setting */
/* Skip ECMERRTGTR13 setting */
/* Skip ECMERRTGTR14 setting */
/* Skip ECMERRTGTR15 setting */
/* Skip ECMERRTGTR16 setting */
[4] = {0xFD850244U, 0x2D001000U}, /* ECMERRTGTR17 */
[5] = {0xFD850248U, 0x0CC001FFU}, /* ECMERRTGTR18 */
[6] = {0xFD85024CU, 0xFFF80000U}, /* ECMERRTGTR19 */
[7] = {0xFD850250U, 0x0000001EU}, /* ECMERRTGTR20 */
[8] = {0xFD850254U, 0x9F000000U}, /* ECMERRTGTR21 */
/* Skip ECMERRTGTR22 setting */
/* Skip ECMERRTGTR23 setting */
/* Skip ECMERRTGTR24 setting */
/* Skip ECMERRTGTR25 setting */
/* Skip ECMERRTGTR26 setting */
/* Skip ECMERRTGTR27 setting */
/* Skip ECMERRTGTR28 setting */
/* Skip ECMERRTGTR29 setting */
/* Skip ECMERRTGTR30 setting */
/* Skip ECMERRTGTR31 setting */
[9] = {0xFD850280U, 0x10000000U}, /* ECMERRTGTR32 */
[10] = {0xFD850284U, 0x10000000U}, /* ECMERRTGTR33 */
/* Skip ECMERRTGTR34 setting */
[11] = {0xFD85028CU, 0x20002280U}, /* ECMERRTGTR35 */
/* Skip ECMERRTGTR36 setting */
/* Skip ECMERRTGTR37 setting */
[12] = {0xFD850298U, 0x33300054U}, /* ECMERRTGTR38 */
/* Skip ECMERRTGTR39 setting */
/* Skip ECMERRTGTR40 setting */
[13] = {0xFD8502A4U, 0x01000880U}, /* ECMERRTGTR41 */
/* Skip ECMERRTGTR42 setting */
};
const ECM_ERROR_TABLE ecmerrctlr_type2_tbl[TYPE2_ECM_REG_MAX] = {
[0] = {0xFD850000U, 0x40000003U}, /* ECMERRCTLR0 */
[1] = {0xFD850004U, 0x04004000U}, /* ECMERRCTLR1 */
[2] = {0xFD850008U, 0xFFFFFFFFU}, /* ECMERRCTLR2 */
[3] = {0xFD85000CU, 0xFFFFFFFFU}, /* ECMERRCTLR3 */
[4] = {0xFD850010U, 0xFFFFFFFFU}, /* ECMERRCTLR4 */
[5] = {0xFD850014U, 0x81FFFFFFU}, /* ECMERRCTLR5 */
[6] = {0xFD850018U, 0x15000A80U}, /* ECMERRCTLR6 */
[7] = {0xFD85001CU, 0x00801481U}, /* ECMERRCTLR7 */
/* Skip ECMERRCTLR8 setting */
/* Skip ECMERRCTLR9 setting */
/* Skip ECMERRCTLR10 setting */
/* Skip ECMERRCTLR11 setting */
/* Skip ECMERRCTLR12 setting */
/* Skip ECMERRCTLR13 setting */
/* Skip ECMERRCTLR14 setting */
/* Skip ECMERRCTLR15 setting */
[8] = {0xFD850040U, 0x00003E9FU}, /* ECMERRCTLR16 */
[9] = {0xFD850044U, 0x00938060U}, /* ECMERRCTLR17 */
[10] = {0xFD850048U, 0x00341600U}, /* ECMERRCTLR18 */
[11] = {0xFD85004CU, 0x0007FF30U}, /* ECMERRCTLR19 */
[12] = {0xFD850050U, 0x02200220U}, /* ECMERRCTLR20 */
[13] = {0xFD850054U, 0x0061820FU}, /* ECMERRCTLR21 */
/* Skip ECMERRCTLR22 setting */
/* Skip ECMERRCTLR23 setting */
/* Skip ECMERRCTLR24 setting */
/* Skip ECMERRCTLR25 setting */
/* Skip ECMERRCTLR26 setting */
/* Skip ECMERRCTLR27 setting */
/* Skip ECMERRCTLR28 setting */
/* Skip ECMERRCTLR29 setting */
/* Skip ECMERRCTLR30 setting */
/* Skip ECMERRCTLR31 setting */
[14] = {0xFD850080U, 0x03E9043BU}, /* ECMERRCTLR32 */
[15] = {0xFD850084U, 0x03E9043BU}, /* ECMERRCTLR33 */
/* Skip ECMERRCTLR34 setting */
[16] = {0xFD85008CU, 0x83B00800U}, /* ECMERRCTLR35 */
[17] = {0xFD850090U, 0xFFFFFFFFU}, /* ECMERRCTLR36 */
/* Skip ECMERRCTLR37 setting */
[18] = {0xFD850098U, 0x00000002U}, /* ECMERRCTLR38 */
/* Skip ECMERRCTLR39 setting */
[19] = {0xFD8500A0U, 0x0000601EU}, /* ECMERRCTLR40 */
[20] = {0xFD8500A4U, 0x20010000U}, /* ECMERRCTLR41 */
/* Skip ECMERRCTLR42 setting */
};
const ECM_ERROR_TABLE ecmerrtgtr_type2_tbl[TYPE2_ECM_REG_MAX] = {
[0] = {0xFD850200U, 0x40000003U}, /* ECMERRTGTR0 */
[1] = {0xFD850204U, 0x04004000U}, /* ECMERRTGTR1 */
[2] = {0xFD850208U, 0xFFFFFFFFU}, /* ECMERRTGTR2 */
[3] = {0xFD85020CU, 0xFFFFFFFFU}, /* ECMERRTGTR3 */
[4] = {0xFD850210U, 0xFFFFFFFFU}, /* ECMERRTGTR4 */
[5] = {0xFD850214U, 0x81FFFFFFU}, /* ECMERRTGTR5 */
[6] = {0xFD850218U, 0x15000A80U}, /* ECMERRTGTR6 */
[7] = {0xFD85021CU, 0x00801481U}, /* ECMERRTGTR7 */
/* Skip ECMERRTGTR8 setting */
/* Skip ECMERRTGTR9 setting */
/* Skip ECMERRTGTR10 setting */
/* Skip ECMERRTGTR11 setting */
/* Skip ECMERRTGTR12 setting */
/* Skip ECMERRTGTR13 setting */
/* Skip ECMERRTGTR14 setting */
/* Skip ECMERRTGTR15 setting */
[8] = {0xFD850240U, 0x00003E9FU}, /* ECMERRTGTR16 */
[9] = {0xFD850244U, 0x00938060U}, /* ECMERRTGTR17 */
[10] = {0xFD850248U, 0x00341600U}, /* ECMERRTGTR18 */
[11] = {0xFD85024CU, 0x0007FF30U}, /* ECMERRTGTR19 */
[12] = {0xFD850250U, 0x02200220U}, /* ECMERRTGTR20 */
[13] = {0xFD850254U, 0x0061820FU}, /* ECMERRTGTR21 */
/* Skip ECMERRTGTR22 setting */
/* Skip ECMERRTGTR23 setting */
/* Skip ECMERRTGTR24 setting */
/* Skip ECMERRTGTR25 setting */
/* Skip ECMERRTGTR26 setting */
/* Skip ECMERRTGTR27 setting */
/* Skip ECMERRTGTR28 setting */
/* Skip ECMERRTGTR29 setting */
/* Skip ECMERRTGTR30 setting */
/* Skip ECMERRTGTR31 setting */
[14] = {0xFD850280U, 0x03E9043BU}, /* ECMERRTGTR32 */
[15] = {0xFD850284U, 0x03E9043BU}, /* ECMERRTGTR33 */
/* Skip ECMERRTGTR34 setting */
[16] = {0xFD85028CU, 0x83B00800U}, /* ECMERRTGTR35 */
[17] = {0xFD850290U, 0xFFFFFFFFU}, /* ECMERRTGTR36 */
/* Skip ECMERRTGTR37 setting */
[18] = {0xFD850298U, 0x00000002U}, /* ECMERRTGTR38 */
/* Skip ECMERRTGTR39 setting */
[19] = {0xFD8502A0U, 0x0000601EU}, /* ECMERRTGTR40 */
[20] = {0xFD8502A4U, 0x20010000U}, /* ECMERRTGTR41 */
/* Skip ECMERRTGTR42 setting */
};
const ECM_ERROR_TABLE ecmerrctlr_type3_tbl[TYPE3_ECM_CTLREG_MAX] = {
/* Skip ECMERRCTLR0 setting */
/* Skip ECMERRCTLR1 setting */
/* Skip ECMERRCTLR2 setting */
/* Skip ECMERRCTLR3 setting */
/* Skip ECMERRCTLR4 setting */
/* Skip ECMERRCTLR5 setting */
/* Skip ECMERRCTLR6 setting */
/* Skip ECMERRCTLR7 setting */
/* Skip ECMERRCTLR8 setting */
/* Skip ECMERRCTLR9 setting */
/* Skip ECMERRCTLR10 setting */
/* Skip ECMERRCTLR11 setting */
/* Skip ECMERRCTLR12 setting */
/* Skip ECMERRCTLR13 setting */
/* Skip ECMERRCTLR14 setting */
/* Skip ECMERRCTLR15 setting */
[0] = {0xFD850040U, 0x33F00000U}, /* ECMERRCTLR16 */
/* Skip ECMERRCTLR17 setting */
/* Skip ECMERRCTLR18 setting */
/* Skip ECMERRCTLR19 setting */
/* Skip ECMERRCTLR20 setting */
/* Skip ECMERRCTLR21 setting */
/* Skip ECMERRCTLR22 setting */
/* Skip ECMERRCTLR23 setting */
/* Skip ECMERRCTLR24 setting */
/* Skip ECMERRCTLR25 setting */
/* Skip ECMERRCTLR26 setting */
/* Skip ECMERRCTLR27 setting */
/* Skip ECMERRCTLR28 setting */
/* Skip ECMERRCTLR29 setting */
/* Skip ECMERRCTLR30 setting */
/* Skip ECMERRCTLR31 setting */
/* Skip ECMERRCTLR32 setting */
/* Skip ECMERRCTLR33 setting */
/* Skip ECMERRCTLR34 setting */
/* Skip ECMERRCTLR35 setting */
/* Skip ECMERRCTLR36 setting */
/* Skip ECMERRCTLR37 setting */
/* Skip ECMERRCTLR38 setting */
/* Skip ECMERRCTLR39 setting */
/* Skip ECMERRCTLR40 setting */
/* Skip ECMERRCTLR41 setting */
/* Skip ECMERRCTLR42 setting */
};
const ECM_ERROR_TABLE ecmerrtgtr_type3_tbl[TYPE3_ECM_TGTREG_MAX] = {
[0] = {0xFD850200U, 0x80000000U}, /* ECMERRTGTR0 */
/* Skip ECMERRTGTR1 setting */
/* Skip ECMERRTGTR2 setting */
/* Skip ECMERRTGTR3 setting */
/* Skip ECMERRTGTR4 setting */
/* Skip ECMERRTGTR5 setting */
/* Skip ECMERRTGTR6 setting */
/* Skip ECMERRTGTR7 setting */
/* Skip ECMERRTGTR8 setting */
/* Skip ECMERRTGTR9 setting */
/* Skip ECMERRTGTR10 setting */
/* Skip ECMERRTGTR11 setting */
/* Skip ECMERRTGTR12 setting */
/* Skip ECMERRTGTR13 setting */
/* Skip ECMERRTGTR14 setting */
/* Skip ECMERRTGTR15 setting */
[1] = {0xFD850240U, 0x33F00000U}, /* ECMERRTGTR16 */
/* Skip ECMERRTGTR17 setting */
/* Skip ECMERRTGTR18 setting */
/* Skip ECMERRTGTR19 setting */
/* Skip ECMERRTGTR20 setting */
/* Skip ECMERRTGTR21 setting */
/* Skip ECMERRTGTR22 setting */
/* Skip ECMERRTGTR23 setting */
/* Skip ECMERRTGTR24 setting */
/* Skip ECMERRTGTR25 setting */
/* Skip ECMERRTGTR26 setting */
/* Skip ECMERRTGTR27 setting */
/* Skip ECMERRTGTR28 setting */
/* Skip ECMERRTGTR29 setting */
/* Skip ECMERRTGTR30 setting */
/* Skip ECMERRTGTR31 setting */
/* Skip ECMERRTGTR32 setting */
/* Skip ECMERRTGTR33 setting */
/* Skip ECMERRTGTR34 setting */
/* Skip ECMERRTGTR35 setting */
/* Skip ECMERRTGTR36 setting */
/* Skip ECMERRTGTR37 setting */
/* Skip ECMERRTGTR38 setting */
/* Skip ECMERRTGTR39 setting */
/* Skip ECMERRTGTR40 setting */
/* Skip ECMERRTGTR41 setting */
/* Skip ECMERRTGTR42 setting */
};
/* Unlock the write protect of ECM registers */
ecm_unlock();
NOTICE("ECMERRCTLR and ECMERRTGTR register initial setting.\n");
/* For the initial setting flow for Type-1, please refer to the following
* section in the "SAN(Safety Application Note)."
* Section 4.1.2.5 : (1)
* Section 4.1.4.5 : (1)
* Section 4.12.1.5 : (1)
* Section 4.14.5 : (1)
* Section 4.2.7.5 : (1)
* Section 4.2.9.5 : (1)
* Section 4.23.5 : (1)
* Section 4.25.5 : (1)
* Section 4.3.14.5 : (1)
* Section 4.3.19.5 : (1)
* Section 4.3.21.5 : (1)
* Section 4.4.16.5 : (1)
* Section 4.4.18.5 : (1)
* Section 4.4.20.5 : (1)
* Section 4.4.3.5 : (1)
* Section 4.4.4.5 : (1)
* Section 4.4.6.5 : (1)
* Section 4.4.7.5 : (1)
* Section 4.4.9.5 : (1)
* Section 4.5.1.5 : (1)
* Section 4.7.1.5 : (1)
* Section 4.7.10.5 : (1)
* Section 4.7.3.5 : (1)
* Section 4.7.4.5 : (1)
* Section 4.7.7.5 : (1)
* Section 4.7.8.5 : (1)
* Section 5.8.1.5 : (1)
*/
for (loop = 0U; loop < TYPE1_ECM_REG_MAX; loop++)
{
/* Initial Setting Type-1 for ECMERRCTLR registers */
reg = mem_read32(ecmerrctlr_type1_tbl[loop].phys_addr);
reg |= (ecmerrctlr_type1_tbl[loop].value);
ecm_write(ecmerrctlr_type1_tbl[loop].phys_addr, reg);
INFO("[Type-1]ECMERRCTLR[\t%d]\t(0x%x) =\t0x%x \tsetting value = 0x%x\n",
loop,
ecmerrctlr_type1_tbl[loop].phys_addr,
mem_read32(ecmerrctlr_type1_tbl[loop].phys_addr),
ecmerrctlr_type1_tbl[loop].value);
}
for (loop = 0U; loop < TYPE1_ECM_REG_MAX; loop++)
{
/* Initial Setting Type-1 for ECMERRTGTR registers */
reg = mem_read32(ecmerrtgtr_type1_tbl[loop].phys_addr);
reg &= ~(ecmerrtgtr_type1_tbl[loop].value);
ecm_write(ecmerrtgtr_type1_tbl[loop].phys_addr, reg);
INFO("[Type-1]ECMERRTGTR[\t%d]\t(0x%x) =\t0x%x \tsetting value = 0x%x\n",
loop,
ecmerrtgtr_type1_tbl[loop].phys_addr,
mem_read32(ecmerrtgtr_type1_tbl[loop].phys_addr),
ecmerrtgtr_type1_tbl[loop].value);
}
/* For the initial setting flow for Type-2, please refer to the following
* section in the "SAN(Safety Application Note)."
* Section 4.1.1.5 : (1)
* Section 4.12.2.5 : (1)
* Section 4.12.3.5 : (1)
* Section 4.15.5 : (1)
* Section 4.16.5 : (1)
* Section 4.18.5 : (1)
* Section 4.2.1.5 : (1)
* Section 4.2.10.5 : (1)
* Section 4.2.12.5 : (1)
* Section 4.2.2.5 : (1)
* Section 4.2.4.5 : (1)
* Section 4.2.8.5 : (1)
* Section 4.3.1.5 : (1)
* Section 4.3.10.5 : (1)
* Section 4.3.11.5 : (1)
* Section 4.3.12.5 : (1)
* Section 4.3.13.5 : (1)
* Section 4.3.15.5 : (1)
* Section 4.3.16.5 : (1)
* Section 4.3.2.5 : (1)
* Section 4.3.5.5 : (1)
* Section 4.3.7.5 : (1)
* Section 4.3.8.5 : (1)
* Section 4.4.10.5 : (1)
* Section 4.4.12.5 : (6)
* Section 4.4.13.5 : (1)
* Section 4.4.14.5 : (1)
* Section 4.4.15.5 : (1)
* Section 4.4.2.5 : (1)
* Section 4.5.3.5 : (1)
* Section 4.6.5 : (1)
* Section 4.7.2.5 : (1)
* Section 5.11.5 : (1)
* Section 5.12.5 : (1)
* Section 5.13.5 : (1)
* Section 5.4.5 : (1)
* Section 5.6.5 : (1)
* Section 5.8.2.5 : (1)
*/
for (loop = 0U; loop < TYPE2_ECM_REG_MAX; loop++)
{
/* Initial Setting Type-2 for ECMERRCTLR registers */
reg = mem_read32(ecmerrctlr_type2_tbl[loop].phys_addr);
reg |= (ecmerrctlr_type2_tbl[loop].value);
ecm_write(ecmerrctlr_type2_tbl[loop].phys_addr, reg);
INFO("[Type-2]ECMERRCTLR[\t%d]\t(0x%x) =\t0x%x \tsetting value = 0x%x\n",
loop,
ecmerrctlr_type2_tbl[loop].phys_addr,
mem_read32(ecmerrctlr_type2_tbl[loop].phys_addr),
ecmerrctlr_type2_tbl[loop].value);
}
for (loop = 0U; loop < TYPE2_ECM_REG_MAX; loop++)
{
/* Initial Setting Type-2 for ECMERRTGTR registers */
reg = mem_read32(ecmerrtgtr_type2_tbl[loop].phys_addr);
reg &= ~(ecmerrtgtr_type2_tbl[loop].value);
ecm_write(ecmerrtgtr_type2_tbl[loop].phys_addr, reg);
INFO("[Type-2]ECMERRTGTR[\t%d]\t(0x%x) =\t0x%x \tsetting value = 0x%x\n",
loop,
ecmerrtgtr_type2_tbl[loop].phys_addr,
mem_read32(ecmerrtgtr_type2_tbl[loop].phys_addr),
ecmerrtgtr_type2_tbl[loop].value);
}
/* For the initial setting flow for Type-3, please refer to the following
* section in the "SAN(Safety Application Note)."
* Section 4.19.1.5 : (3)
* Section 6.2.5 : (12)
*/
for (loop = 0U; loop < TYPE3_ECM_CTLREG_MAX; loop++)
{
/* Initial Setting Type-3 for ECMERRCTLR registers */
reg = mem_read32(ecmerrctlr_type3_tbl[loop].phys_addr);
reg |= (ecmerrctlr_type3_tbl[loop].value);
ecm_write(ecmerrctlr_type3_tbl[loop].phys_addr, reg);
INFO("[Type-3]ECMERRCTLR[\t%d]\t(0x%x) =\t0x%x \tsetting value = 0x%x\n",
loop,
ecmerrctlr_type3_tbl[loop].phys_addr,
mem_read32(ecmerrctlr_type3_tbl[loop].phys_addr),
ecmerrctlr_type3_tbl[loop].value);
}
for (loop = 0U; loop < TYPE3_ECM_TGTREG_MAX; loop++)
{
/* Initial Setting Type-3 for ECMERRTGTR registers */
reg = mem_read32(ecmerrtgtr_type3_tbl[loop].phys_addr);
reg &= ~(ecmerrtgtr_type3_tbl[loop].value);
ecm_write(ecmerrtgtr_type3_tbl[loop].phys_addr, reg);
INFO("[Type-3]ECMERRTGTR[\t%d]\t(0x%x) =\t0x%x \tsetting value = 0x%x\n",
loop,
ecmerrtgtr_type3_tbl[loop].phys_addr,
mem_read32(ecmerrtgtr_type3_tbl[loop].phys_addr),
ecmerrtgtr_type3_tbl[loop].value);
}
/* Lock the ECM registers */
ecm_lock();
}
/* End of function ecm_init_setting(void) */
#endif /* ECM_ERROR_ENABLE == 1 */

View File

@@ -0,0 +1,47 @@
/*******************************************************************************
* 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 driver header
******************************************************************************/
#ifndef ECM_ENABLE_V4M
#define ECM_ENABLE_V4M
#if ((ECM_ERROR_ENABLE == 1) || (ECM_ENABLE == 1))
void ecm_unlock(void);
void ecm_write(uint32_t adr, uint32_t val);
void ecm_lock(void);
#endif /* (ECM_ERROR_ENABLE == 1) || (ECM_ENABLE == 1) */
#if (ECM_ERROR_ENABLE == 1)
void ecm_init_setting(void);
#endif /* ECM_ERROR_ENABLE == 1 */
#endif/* ECM_ENABLE_V4M */

View File

@@ -0,0 +1,182 @@
/*******************************************************************************
* 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 2021-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : DMA driver
******************************************************************************/
/******************************************************************************
* @file dma.c
* - Version : 0.07
* @brief DMA driver.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 28.07.2021 0.01 First Release
* : 30.09.2021 0.02 Change function name load_start and
* load_end function.
* : 15.10.2021 0.03 modified to not use CHCLR.
* : 06.01.2022 0.04 Add exception handling for ICUMX_WDTA.
* : 02.02.2022 0.05 Add MFIS Lock/Unlock.
* : 22.06.2022 0.06 Replace address align check to function.
* : Remove some defines.
* : 20.12.2022 0.07 Add mask when writing to TCR register.
*****************************************************************************/
#include <stdint.h>
#include <mem_io.h>
#include <dma.h>
#include <rpc.h>
#include <log.h>
#include <wdt.h>
#include <mfis.h>
#define DMOR_INIT (uint16_t)(0x0301U)
#define DMOR_HW_INIT (uint16_t)(0x0000U)
#define TCR_CNT_SHIFT (6U)
#define TCR_UPPER8BIT_MASK (0x00FFFFFFU)
#define CHCR_TRN_MODE (0x00105409U)
#define CHCR_TE_BIT (0x00000002U)
#define TE_FLAG (0x00000000U)
#define CHCR_CAE_BIT (0x80000000U)
#define CHCR_CAE_BIT_NOERROR (0x00000000U)
#define CHCR_CAIE_BIT (0x40000000U)
#define CHCR_DPM_BIT (0x30000000U)
#define CHCR_RPT_BIT (0x0F000000U)
#define CHCR_WAIT_BIT (0x00800000U)
#define CHCR_DPB_BIT (0x00400000U)
#define CHCR_DSE_BIT (0x00080000U)
#define CHCR_DSIE_BIT (0x00040000U)
#define CHCR_DM_BIT (0x0000C000U)
#define CHCR_SM_BIT (0x00003000U)
#define CHCR_RS_BIT (0x00000F00U)
#define CHCR_TS_BIT (0x00300018U)
#define CHCR_IE_BIT (0x00000004U)
#define CHCR_TE_BIT (0x00000002U)
#define CHCR_DE_BIT (0x00000001U)
#define CHCR_CONF_MASK (CHCR_TS_BIT | CHCR_DM_BIT | CHCR_SM_BIT | CHCR_RS_BIT | CHCR_DE_BIT)
#define CHCR_DESCRIPTOR_CONF_MASK (CHCR_DPM_BIT | CHCR_RPT_BIT | CHCR_WAIT_BIT | CHCR_DPB_BIT)
#define CHCR_INTERRUPT_MASK (CHCR_CAIE_BIT | CHCR_DSIE_BIT | CHCR_IE_BIT)
#define CHCR_FLAG_MASK (CHCR_CAE_BIT | CHCR_DSE_BIT | CHCR_TE_BIT)
#define CHCR_ALL_BIT_MASK (CHCR_CONF_MASK | CHCR_DESCRIPTOR_CONF_MASK | CHCR_INTERRUPT_MASK | CHCR_FLAG_MASK)
#define DAR_HW_INIT (0x00000000U)
#define SAR_HW_INIT (0x00000000U)
#define TCR_HW_INIT (0x00000000U)
/* fraction mask for 256-byte units */
#define FRACTION_MASK_256_BYTE (0x000000FFU)
void dma_init(void)
{
uint32_t reg;
/* DMA operation */
mem_write16(RTDMA_DMOR, DMOR_INIT);
/* DMA secure control register */
reg = mem_read32(RTDMA_DMSEC);
reg |= ((uint32_t)1U << DMACH);
mem_write32(RTDMA_DMSEC, reg);
reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH));
reg &= ~(CHCR_ALL_BIT_MASK);
mem_write32(dma_get_rtdma_chcr_addr(DMACH), reg);
}
/* End of function dma_init(void) */
void dma_trans_start(uint32_t dst, uint32_t src, uint32_t len)
{
uint32_t reg;
/* dst and src must be 64-byte boundary. */
dma_address_align_check(dst, src);
/* round up 256 byte alignment */
len += FRACTION_MASK_256_BYTE;
len &= (~(uint32_t)(FRACTION_MASK_256_BYTE));
/* DMA destination address */
mem_write32(dma_get_rtdma_dar_addr(DMACH), dst);
/* DMA source address */
mem_write32(dma_get_rtdma_sar_addr(DMACH), src);
/* DMA 64bytes-unit transfer count */
mem_write32(dma_get_rtdma_tcr_addr(DMACH), ((len >> TCR_CNT_SHIFT) & TCR_UPPER8BIT_MASK));
/* Lock to avoid conflict with RPC */
mfis_lock();
/* DMA channel control */
reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH));
reg |= CHCR_TRN_MODE;
mem_write32(dma_get_rtdma_chcr_addr(DMACH), reg);
}
/* End of function dma_trans_start(uint32_t dst, uint32_t src, uint32_t len) */
void dma_trans_end_check(void)
{
uint32_t reg;
/* Check end of DMA transfer. */
do
{
wdt_restart();
reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH));
/* Check error of DMA transfer */
if ((reg & CHCR_CAE_BIT) != CHCR_CAE_BIT_NOERROR)
{
ERROR("DMA - Channel Address Error\n");
panic;
}
} while ((reg & CHCR_TE_BIT) == TE_FLAG);
reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH));
reg &= ~(CHCR_ALL_BIT_MASK);
mem_write32(dma_get_rtdma_chcr_addr(DMACH), reg);
rpc_end_state_check();
/* Unlock to avoid conflict with RPC */
mfis_unlock();
}
/* End of function dma_trans_end_check(void) */
void dma_release(void)
{
uint32_t reg;
/* DMA channel control */
reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH));
reg &= ~(CHCR_ALL_BIT_MASK);
mem_write32(dma_get_rtdma_chcr_addr(DMACH), reg);
/* DMA destination address */
mem_write32(dma_get_rtdma_dar_addr(DMACH), DAR_HW_INIT);
/* DMA source address */
mem_write32(dma_get_rtdma_sar_addr(DMACH), SAR_HW_INIT);
/* DMA 64bytes-unit transfer count */
mem_write32(dma_get_rtdma_tcr_addr(DMACH), TCR_HW_INIT);
reg = mem_read32(RTDMA_DMSEC);
reg &= (~((uint32_t)1U << DMACH));
mem_write32(RTDMA_DMSEC, reg);
/* DMA operation */
mem_write16(RTDMA_DMOR, DMOR_HW_INIT);
}
/* End of function dma_release(void) */

View File

@@ -0,0 +1,249 @@
/*******************************************************************************
* 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 2021-2024 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : eMMC boot
******************************************************************************/
/******************************************************************************
* @file emmc_boot.c
* - Version : 0.07
* @brief eMMC initialze interface.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 30.09.2021 0.01 First Release
* : 22.10.2021 0.02 Remove unnecessary code
* : 22.12.2021 0.03 Support static analysis
* : 06.01.2022 0.04 Add WWDT timer reset function
* : 06.04.2022 0.05 Fix Set SDCLK to 200MHz
* : 23.05.2022 0.06 Integration of S4 and V4H
* : 24.06.2024 0.07 Add process that set SDHI_D1.8/3.3V to 1.8V.
*****************************************************************************/
#include "emmc_boot.h"
#include "mem_io.h"
#include "log.h"
#include "rom_api.h"
#include "image_load_emmc.h"
#include "emmc_hal.h"
#include "emmc_std.h"
#include "emmc_multiboot.h"
#include "emmc_def.h"
#include "emmc_config.h"
#if (RCAR_LSI == RCAR_V4M) /* Gray Hawk */
#include "i2c.h"
#include "remap.h"
#endif /* (RCAR_LSI == RCAR_V4M) */
/************************************************************************************************/
/* Definitions */
/************************************************************************************************/
/************************************************************************************************/
/* Unions */
/************************************************************************************************/
/************************************************************************************************/
/* Structs */
/************************************************************************************************/
/************************************************************************************************/
/* Globals */
/************************************************************************************************/
/************************************************************************************************/
/* Macros */
/************************************************************************************************/
/************************************************************************************************/
/* Prototypes */
/************************************************************************************************/
static void power_on_mmc(void);
static void set_sd_clock(void);
static void init_mmc_pin_function(void);
#if (RCAR_LSI == RCAR_V4M) /* Gray Hawk */
static void sdhi_random_address_read_pmic(uint32_t sl_add, uint32_t access_add, uint32_t *rd_buf);
static void sdhi_page_write_pmic(uint32_t sl_add, uint32_t access_add, uint32_t *wr_buf);
static void pmic_set_sdhi_vdd18(void);
#endif /* (RCAR_LSI == RCAR_V4M) */
void emmc_initialize( void )
{
#if (RCAR_LSI == RCAR_V4M) /* Gray Hawk */
/* Register I2C base address(physical:0xE6600000) to SIC REMAP14 for V4M. */
set_sicremap_fcpr();
pmic_set_sdhi_vdd18();
#endif /* (RCAR_LSI == RCAR_V4M) */
/*****************************************************************
PFC setting
*****************************************************************/
init_mmc_pin_function();
/*****************************************************************
CPG setting
*****************************************************************/
power_on_mmc();
set_sd_clock();
#if (RCAR_SA9_TYPE == EMMC_BOOT)
EMMC_ERROR_CODE result;
/* eMMC driver initialize */
(void)emmc_init(); /* Normal clock mode */
/* Card power on */
(void)emmc_memcard_power(TRUE);
/* Card mount */
result = emmc_mount();
if (result != EMMC_SUCCESS)
{
NOTICE("eMMC initialize error!!\n");
panic;
}
#endif /* (RCAR_SA9_TYPE == EMMC_BOOT) */
} /* End of function emmc_initialize( void ) */
/************************************************************************************************/
/* Func power_on_mmc */
/************************************************************************************************/
static void power_on_mmc(void)
{
uint32_t reg;
uint32_t tmp_val;
tmp_val = CPG_MSTPCR_SDHI;
reg = mem_read32(CPG_MSTPCR7D0);
if ((reg & tmp_val) != 0x0U)
{
reg &= ~(tmp_val);
cpg_reg_write(CPG_MSTPCR7D0, CPG_MSTPSR7D0, reg);
}
do
{
reg = mem_read32(CPG_MSTPCR7D0);
}
while ((reg & tmp_val) != 0x0U); /* wait tmp_val=0 */
} /* End of function power_on_mmc(void) */
/************************************************************************************************/
/* Func set_sd_clock */
/************************************************************************************************/
static void set_sd_clock(void)
{
uint32_t reg;
reg = mem_read32(CPG_SD0CKCR0);
reg &= (~(CPG_SD0CKCR0_STP0HCK | CPG_SD0CKCR0_SDSRCFC_MASK | CPG_SD0CKCR0_SD0FC_MASK));
reg |= CPG_SD0CKCR0_200MHZ;
cpg_reg_write(CPG_SD0CKCR0, CPG_SD0CKCR0, reg); /* Stop SDnH clock & SDn=200MHz */
} /* End of function set_sd_clock(void) */
/************************************************************************************************/
/* Func init_mmc_pin_function */
/************************************************************************************************/
static void init_mmc_pin_function(void)
{
uint32_t reg;
reg = mem_read32(PFC_POC_MMC_RW);
reg &= (~(PFC_POC_MMC_MASK));
reg |= PFC_POC_MMC_VAL;
pfc_reg_write(PFC_POC_MMC_RW, reg);
} /* End of function init_mmc_pin_function(void) */
#if (RCAR_LSI == RCAR_V4M) /* Gray Hawk */
static void sdhi_random_address_read_pmic(uint32_t sl_add, uint32_t access_add, uint32_t *rd_buf)
{
uint32_t data;
/* for PMIC_RAA271005 */
data = (access_add & 0x300U) >> 8U;
i2c3_write(sl_add, 0x00U, data); /* Bank Set */
i2c3_read(sl_add, (access_add & 0x0FFU), rd_buf);
}
/* End of function sdhi_random_address_read_pmic(uint32_t sl_add, uint32_t access_add, uint32_t *rd_buf) */
static void sdhi_page_write_pmic(uint32_t sl_add, uint32_t access_add, uint32_t *wr_buf)
{
uint32_t data;
/* for PMIC_RAA271005 */
data = (access_add & 0x300U) >> 8U;
i2c3_write(sl_add, 0x00U, data); /* Bank Set */
i2c3_read(sl_add, (access_add & 0x0FFU), wr_buf);
}
/* End of function sdhi_page_write_pmic(uint32_t sl_add, uint32_t access_add, uint32_t *wr_buf) */
static void pmic_set_sdhi_vdd18(void)
{
/* In case of Gray Hawk board, change SDHI_18/33 voltage. */
uint32_t slv_addr = 0xA8U; /* for PMIC-RAA271005: "reg 0xA8 0xA9 prot 0xAA 0xAB" */
uint32_t data;
/* Init I2C */
i2c3_init();
/* Setting 1.8V to SDHI_D1.8/3.3V(VDDQ18_33_SDHI) on PMIC-RAA271005 */
data = 0x1U;
i2c3_write(slv_addr, 0x00U, data); /* Write IO_PAGE. Chenge BANK1 */
i2c3_read(slv_addr, 0x3BU, &data);
if ((data & 0x0CU) != 0x0U)
{
data &= ~(0x0CU);
i2c3_write(slv_addr, 0x3BU, data);
}
sdhi_random_address_read_pmic(slv_addr, 0x02U, &data);
if ((data & 0xF0U) == 0xB0U)
{
// RAA271005 rev.B only
data = 0x1U;
sdhi_page_write_pmic(slv_addr, 0x00U, &data); /* Write IO_PAGE. Chenge BANK1 */
sdhi_random_address_read_pmic(slv_addr, 0x3BU, &data); /* Read FLT_CTRL1 */
data &= 0xF3U; /* LDO1 Fault remove */
sdhi_page_write_pmic(slv_addr, 0x3BU, &data); /* Write FLT_CTRL1 */
data = 0x0U;
sdhi_page_write_pmic(slv_addr, 0x00U, &data); /* Write IO_PAGE. Chenge BANK0 */
}
data = 0x75U; /* LDO voltage 1.8V Value */
i2c3_write(slv_addr, 0xBAU, data);
sdhi_random_address_read_pmic(slv_addr, 0xBAU, &data);
}
/* End of function pmic_set_sdhi_vdd18(void) */
#endif /* (RCAR_LSI == RCAR_V4M) */

View File

@@ -0,0 +1,580 @@
/*******************************************************************************
* 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 2021-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : eMMC CMD driver
******************************************************************************/
/******************************************************************************
* @file emmc_cmd.c
* - Version : 0.04
* @brief control of CMD in SDHI.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 22.02.2022 0.01 First Release
* : 22.10.2021 0.02 Remove unnecessary code
* : 22.12.2021 0.03 Support static analysis
* : 06.01.2022 0.04 Modify SDHI access from DMA to PIO.
*****************************************************************************/
#include "emmc_config.h"
#include "emmc_hal.h"
#include "emmc_std.h"
#include "emmc_registers.h"
#include "emmc_def.h"
#include "micro_wait.h"
#include "log.h"
/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */
/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */
/* ********************** DECLARATION OF EXTERNAL DATA ********************* */
/* ************************** FUNCTION PROTOTYPES ************************** */
static void emmc_read_response(uint32_t *response);
static void emmc_little_to_big(uint8_t *p, uint32_t value);
static void emmc_data_transfer_dma(void);
static EMMC_ERROR_CODE emmc_response_check(const uint32_t *response, uint32_t error_mask);
static void emmc_softreset(void);
static void emmc_WaitCmd2Cmd_8Cycle(void);
/* ********************************* CODE ********************************** */
/* execute MMC command.
*
* - Pre-conditions:<BR>
* * Clock to memory card IF is enabled.
* - Post-conditions:<BR>
* Requested command is executed successfully
*
* param[in] error_mask Errors to be checked (error values; HAL_MEMCARD_ERRORS)
* param[in,out] *response Response from the card (virtual address)
* return eMMC error code.
*/
EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response)
{
EMMC_ERROR_CODE rtn_code = EMMC_ERR;
HAL_MEMCARD_RESPONSE_TYPE response_type;
HAL_MEMCARD_COMMAND_TYPE cmd_type;
EMMC_INT_STATE state;
/* parameter check */
if (response == NULL) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* state check */
if (mmc_drv_obj.clock_enable != TRUE) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
if (mmc_drv_obj.state_machine_blocking == TRUE) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR);
return EMMC_ERR;
}
state = ESTATE_BEGIN;
response_type = (HAL_MEMCARD_RESPONSE_TYPE)(uintptr_t)((uint32_t)(mmc_drv_obj.cmd_info.cmd) & (uint32_t)HAL_MEMCARD_RESPONSE_TYPE_MASK);
cmd_type = (HAL_MEMCARD_COMMAND_TYPE)(uintptr_t)((uint32_t)(mmc_drv_obj.cmd_info.cmd) & (uint32_t)HAL_MEMCARD_COMMAND_TYPE_MASK);
/* state machine */
while ((mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END)) {
/* The interrupt factor flag is observed. */
(void)emmc_interrupt();
/* wait interrupt */
if (mmc_drv_obj.state_machine_blocking == TRUE) {
continue;
}
switch (state) {
case ESTATE_BEGIN:
/* Busy check */
if ((mmc_drv_obj.error_info.info2 & SD_INFO2_CBSY) != 0U) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_CARD_BUSY);
return EMMC_ERR_CARD_BUSY;
}
/* clear register */
mem_write32(SD_INFO1, 0x00000000U);
mem_write32(SD_INFO2, SD_INFO2_CLEAR);
mem_write32(SD_INFO1_MASK, SD_INFO1_INFO0);
mem_write32(SD_INFO2_MASK, ( SD_INFO2_ALL_ERR | SD_INFO2_CLEAR ));
/* fallthrough */
case ESTATE_ISSUE_CMD:
/* ARG */
mem_write32(SD_ARG, mmc_drv_obj.cmd_info.arg);
/* issue cmd */
mem_write32(SD_CMD, mmc_drv_obj.cmd_info.hw);
/* Set driver flag */
mmc_drv_obj.state_machine_blocking = TRUE;
if (response_type == HAL_MEMCARD_RESPONSE_NONE) {
state = ESTATE_NON_RESP_CMD;
} else {
state = ESTATE_RCV_RESP;
}
break;
case ESTATE_NON_RESP_CMD:
/* interrupt disable */
mem_write32(SD_INFO1_MASK, 0x00000000U);
mem_write32(SD_INFO2_MASK, SD_INFO2_CLEAR);
/* check interrupt */
if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0U) {
/* error interrupt */
rtn_code = EMMC_ERR_INFO2;
state = ESTATE_ERROR;
} else if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO0) == 0U) {
/* not receive expected interrupt */
rtn_code = EMMC_ERR_RESPONSE;
state = ESTATE_ERROR;
} else {
emmc_WaitCmd2Cmd_8Cycle();
state = ESTATE_END;
}
break;
case ESTATE_RCV_RESP:
/* interrupt disable */
mem_write32(SD_INFO1_MASK, 0x00000000U);
mem_write32(SD_INFO2_MASK, SD_INFO2_CLEAR);
/* check interrupt */
if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0U) {
/* error interrupt */
rtn_code = EMMC_ERR_INFO2;
state = ESTATE_ERROR;
break;
} else if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO0) == 0U) {
/* not receive expected interrupt */
rtn_code = EMMC_ERR_RESPONSE;
state = ESTATE_ERROR;
break;
} else {
/* nop */
}
/* read response */
emmc_read_response(response);
/* check response */
rtn_code = emmc_response_check(response, error_mask);
if (rtn_code != EMMC_SUCCESS) {
state = ESTATE_ERROR;
break;
}
if (response_type == HAL_MEMCARD_RESPONSE_R1b) {
/* R1b */
mem_write32(SD_INFO2_MASK, ( SD_INFO2_ALL_ERR | SD_INFO2_CLEAR ));
state = ESTATE_RCV_RESPONSE_BUSY;
} else {
state = ESTATE_CHECK_RESPONSE_COMPLETE;
}
break;
case ESTATE_RCV_RESPONSE_BUSY:
/* check interrupt */
if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0U) {
/* error interrupt */
rtn_code = EMMC_ERR_INFO2;
state = ESTATE_ERROR;
break;
}
/* DAT0 not Busy */
if ((SD_INFO2_DAT0 & mmc_drv_obj.error_info.info2) != 0U) {
state = ESTATE_CHECK_RESPONSE_COMPLETE;
break;
}
break;
case ESTATE_CHECK_RESPONSE_COMPLETE:
if (cmd_type >= HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE) {
state = ESTATE_DATA_TRANSFER;
} else {
emmc_WaitCmd2Cmd_8Cycle();
state = ESTATE_END;
}
break;
case ESTATE_DATA_TRANSFER:
/* ADTC command */
mmc_drv_obj.during_transfer = TRUE;
mmc_drv_obj.state_machine_blocking = TRUE;
if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) {
/* DMA */
emmc_data_transfer_dma();
} else {
/* PIO */
/* interrupt enable (FIFO read/write enable) */
if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) {
mem_write32(SD_INFO2_MASK, ( SD_INFO2_BWE | SD_INFO2_ALL_ERR | SD_INFO2_CLEAR ));
} else {
mem_write32(SD_INFO2_MASK, ( SD_INFO2_BRE | SD_INFO2_ALL_ERR | SD_INFO2_CLEAR ));
}
}
state = ESTATE_DATA_TRANSFER_COMPLETE;
break;
case ESTATE_DATA_TRANSFER_COMPLETE:
/* check interrupt */
if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0U) {
/* error interrupt */
rtn_code = EMMC_ERR_INFO2;
state = ESTATE_TRANSFER_ERROR;
break;
} else {
/* success. nothing to do. */
}
/* DMAC error ? */
if (mmc_drv_obj.dma_error_flag == TRUE) {
/* Error occurred in DMAC driver. */
rtn_code = EMMC_ERR_FROM_DMAC_TRANSFER;
state = ESTATE_TRANSFER_ERROR;
} else if (mmc_drv_obj.during_dma_transfer == TRUE) {
/* DMAC not finished. unknown error */
rtn_code = EMMC_ERR;
state = ESTATE_TRANSFER_ERROR;
} else {
mem_write32(SD_INFO1_MASK, SD_INFO1_INFO2);
mem_write32(SD_INFO2_MASK, ( SD_INFO2_ALL_ERR | SD_INFO2_CLEAR ));
mmc_drv_obj.state_machine_blocking = TRUE;
state = ESTATE_ACCESS_END;
}
break;
case ESTATE_ACCESS_END:
/* clear flag */
if (HAL_MEMCARD_DMA == mmc_drv_obj.transfer_mode) {
mem_write32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */
mem_write32(SD_STOP, 0x00000000U);
mmc_drv_obj.during_dma_transfer = FALSE;
}
mem_write32(SD_INFO1_MASK, 0x00000000U);
mem_write32(SD_INFO2_MASK, SD_INFO2_CLEAR);
mem_write32(SD_INFO1, 0x00000000U);
mem_write32(SD_INFO2, SD_INFO2_CLEAR);
if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO2) != 0U) {
emmc_WaitCmd2Cmd_8Cycle();
state = ESTATE_END;
} else {
state = ESTATE_ERROR;
}
break;
case ESTATE_TRANSFER_ERROR:
/* The error occurred in the Data transfer. */
if (HAL_MEMCARD_DMA == mmc_drv_obj.transfer_mode) {
mem_write32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */
mem_write32(SD_STOP, 0x00000000U);
mmc_drv_obj.during_dma_transfer = FALSE;
}
/* fallthrough */
case ESTATE_ERROR:
emmc_softreset();
ERROR("%s:0x%08x\n",__func__,rtn_code);
return rtn_code;
default:
state = ESTATE_END;
break;
} /* switch (state) */
} /* while ( (mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END) ) */
/* force terminate */
if (mmc_drv_obj.force_terminate == TRUE) {
/* timeout timer is expired. Or, PIO data transfer error. */
/* Timeout occurred in the DMA transfer. */
if (mmc_drv_obj.during_dma_transfer == TRUE) {
mmc_drv_obj.during_dma_transfer = FALSE;
}
emmc_softreset();
return EMMC_ERR_FORCE_TERMINATE; /* error information has already been written. */
}
/* success */
mmc_drv_obj.during_transfer = FALSE;
return EMMC_SUCCESS;
}
/** host controller softrest.
*
* - Pre-conditions:<BR>
* .
* - Post-conditions:<BR>
* .
*
* param None.
* return None.
*/
static void emmc_softreset(void)
{
int32_t loop = 10000;
int32_t retry = 1000;
/* flag clear */
mmc_drv_obj.during_transfer = FALSE;
mmc_drv_obj.during_dma_transfer = FALSE;
mmc_drv_obj.state_machine_blocking = FALSE;
mmc_drv_obj.force_terminate = FALSE;
mmc_drv_obj.dma_error_flag = FALSE;
/* during operation ? */
if ((mem_read32(SD_INFO2) & SD_INFO2_CBSY) != 0U) {
/* wait CMDSEQ = 0 */
while (loop > 0) {
if ((mem_read32(SD_INFO2) & SD_INFO2_CBSY) == 0U) {
break; /* ready */
}
loop--;
if ((loop == 0) && (retry > 0)) {
micro_wait(1000U); /* wait 1ms */
loop = 10000;
retry--;
}
}
}
/* reset */
mem_write32(SOFT_RST, ( mem_read32(SOFT_RST) & (~SOFT_RST_SDRST) )); /* Soft reset */
mem_write32(SOFT_RST, ( mem_read32(SOFT_RST) | SOFT_RST_SDRST )); /* Soft reset released */
/* initialize */
mem_write32(SD_INFO1, 0x00000000U);
mem_write32(SD_INFO2, SD_INFO2_CLEAR);
mem_write32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */
mem_write32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */
}
/** read response
*
* - Pre-conditions:<BR>
* Called from emmc_exec_cmd().
* - Post-conditions:<BR>
* .
*
* param[in,out] *response Response from the card
* return None.
*/
static void emmc_read_response(uint32_t *response)
{
uint8_t *p = NULL;
if (response == NULL) {
return;
}
/* read response */
if (mmc_drv_obj.response_length == EMMC_MAX_RESPONSE_LENGTH) {
/* CSD or CID */
p = (uint8_t *)(response);
emmc_little_to_big(p, ((mem_read32(SD_RSP76) << 8U) | (mem_read32(SD_RSP54) >> 24U))); /* [127:96] */
emmc_little_to_big(p + 4U, ((mem_read32(SD_RSP54) << 8U) | (mem_read32(SD_RSP32) >> 24U))); /* [95:64] */
emmc_little_to_big(p + 8U, ((mem_read32(SD_RSP32) << 8U) | (mem_read32(SD_RSP10) >> 24U))); /* [63:32] */
emmc_little_to_big(p + 12U, (mem_read32(SD_RSP10) << 8U)); /* [31:0] */
} else {
*response = mem_read32(SD_RSP10); /* [39:8] */
}
}
/** response check
*
* - Pre-conditions:<BR>
* Called from emmc_exec_cmd().
* - Post-conditions:<BR>
* .
*
* param[in] *response Response from the card
* param[in] error_mask Errors to be checked (for R1/R1b response)
* return error code.
*/
static EMMC_ERROR_CODE emmc_response_check(const uint32_t *response, uint32_t error_mask)
{
HAL_MEMCARD_RESPONSE_TYPE response_type = (HAL_MEMCARD_RESPONSE_TYPE)(uintptr_t)((uint32_t)(mmc_drv_obj.cmd_info.cmd)
& (uint32_t)HAL_MEMCARD_RESPONSE_TYPE_MASK);
if (response == NULL) {
return EMMC_ERR_PARAM;
}
if (response_type == HAL_MEMCARD_RESPONSE_NONE) {
return EMMC_SUCCESS;
}
/* response check */
if (response_type <= HAL_MEMCARD_RESPONSE_R1b) {
/* R1 or R1b */
mmc_drv_obj.current_state = (EMMC_R1_STATE)((*response & EMMC_R1_STATE_MASK) >> EMMC_R1_STATE_SHIFT);
if ((*response & error_mask) != 0U) {
return EMMC_ERR_CARD_STATUS_BIT;
}
} else if (response_type == HAL_MEMCARD_RESPONSE_R4) {
/* R4 */
if ((*response & EMMC_R4_STATUS) != 0U) {
return EMMC_ERR_CARD_STATUS_BIT;
}
} else {
; /* nothing to do. other type does not have status bit */
}
return EMMC_SUCCESS;
}
/** brief converts endian from little to big
*
* - Pre-conditions:<BR>
* .
* - Post-conditions:<BR>
* .
*
* param[in,out] p destination buffer address.
* param[in] value convert data.(little)
* return None.
*/
static void emmc_little_to_big(uint8_t *p, uint32_t value)
{
if (p == NULL) {
return;
}
p[0] = (uint8_t)(value >> 24U);
p[1] = (uint8_t)(value >> 16U);
p[2] = (uint8_t)(value >> 8U);
p[3] = (uint8_t)value;
}
/** data transfer with DMA.
*
* - Pre-conditions:<BR>
* Called from emmc_exec_cmd().
* - Post-conditions:<BR>
* .
*
* return error code.
*/
static void emmc_data_transfer_dma(void)
{
mmc_drv_obj.during_dma_transfer = TRUE;
mmc_drv_obj.dma_error_flag = FALSE;
mem_write32(SD_INFO1_MASK, 0x00000000U);
mem_write32(SD_INFO2_MASK, ( SD_INFO2_ALL_ERR | SD_INFO2_CLEAR ));
/* DMAC setting */
if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) {
/* transfer complete interrupt enable */
mem_write32(DM_CM_INFO1_MASK, ( DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH0_ENABLE ));
mem_write32(DM_CM_INFO2_MASK, ( DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH0_ENABLE ));
/* BUFF --> FIFO */
mem_write32(DM_CM_DTRAN_MODE, ( DM_CM_DTRAN_MODE_CH0 | DM_CM_DTRAN_MODE_BIT_WIDTH )); /* CH0(downstream), 64-bit width */
} else {
/* transfer complete interrupt enable */
mem_write32(DM_CM_INFO1_MASK, ( DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH1_ENABLE ));
mem_write32(DM_CM_INFO2_MASK, ( DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH1_ENABLE ));
/* FIFO --> BUFF */
mem_write32(DM_CM_DTRAN_MODE, ( DM_CM_DTRAN_MODE_CH1 | DM_CM_DTRAN_MODE_BIT_WIDTH )); /* CH0(downstream), 64-bit width */
}
mem_write32(DM_DTRAN_ADDR, ( ( (uintptr_t)mmc_drv_obj.buff_address_virtual & DM_DTRAN_ADDR_WRITE_MASK ) )); /* Set address */
mem_write32(DM_CM_DTRAN_CTRL, DM_CM_DTRAN_CTRL_START); /* DMAC Start */
}
/** wait cmd-cmd 8cycle
*
* - Pre-conditions:<BR>
*
* - Post-conditions:<BR>
* .
*
* return None.
*/
static void emmc_WaitCmd2Cmd_8Cycle(void)
{
uint32_t dataL, wait = 0U;
dataL = mem_read32(SD_CLK_CTRL);
dataL &= 0x000000FFU;
switch (dataL) {
case 0xFFU: /* 1/1 10 us wait ( 1/200MHz)*8= 0.04 us(min) */
wait = 10U;
break;
case 0x00U: /* 1/2 10 us wait ( 2/200MHz)*8= 0.08 us(min) */
wait = 10U;
break;
case 0x01U: /* 1/4 10 us wait ( 4/200MHz)*8= 0.16 us(min) */
wait = 10U;
break;
case 0x02U: /* 1/8 10 us wait ( 8/200MHz)*8= 0.32 us(min) */
wait = 10U;
break;
case 0x04U: /* 1/16 10 us wait ( 16/200MHz)*8= 0.64 us(min) */
wait = 10U;
break;
case 0x08U: /* 1/32 10 us wait ( 32/200MHz)*8= 1.28 us(min) */
wait = 10U;
break;
case 0x10U: /* 1/64 10 us wait ( 64/200MHz)*8= 2.56 us(min) */
wait = 10U;
break;
case 0x20U: /* 1/128 10 us wait (128/200MHz)*8= 5.12 us(min) */
wait = 10U;
break;
case 0x40U: /* 1/256 20 us wait (256/200MHz)*8= 10.24 us(min) */
wait = 20U;
break;
case 0x80U: /* 1/512 30 us wait (512/200MHz)*8= 20.48 us(min) */
wait = 30U;
break;
default:
/* nop */
break;
}
micro_wait(wait);
}
/* ******************************** END ************************************ */

View File

@@ -0,0 +1,311 @@
/*******************************************************************************
* 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 2021-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : eMMC initialze
******************************************************************************/
/******************************************************************************
* @file emmc_init.c
* - Version : 0.05
* @brief initialize of SDHI driver.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 22.02.2022 0.01 First Release
* : 22.10.2021 0.02 Remove unnecessary code
* : 22.12.2021 0.03 Support static analysis
* : 06.01.2022 0.04 Modify SDHI access from DMA to PIO.
* : 06.04/2022 0.05 Del SDnH clock & SDn=200MHz(Duplicate settings)
*****************************************************************************/
/* ************************ HEADER (INCLUDE) SECTION *********************** */
#include "emmc_config.h"
#include "emmc_hal.h"
#include "emmc_std.h"
#include "emmc_registers.h"
#include "emmc_def.h"
/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */
/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */
/* ********************** DECLARATION OF EXTERNAL DATA ********************* */
st_mmc_base mmc_drv_obj;
/* ************************** FUNCTION PROTOTYPES ************************** */
static void emmc_drv_init(void);
static EMMC_ERROR_CODE emmc_dev_init(void);
static EMMC_ERROR_CODE emmc_dev_finalize(void);
static void emmc_memset(void *buff, uint8_t data, uint32_t cnt);
static EMMC_ERROR_CODE emmc_reset_controller(void);
static void emmc_driver_config(void);
static void emmc_set_data_timeout(uint32_t data_timeout);
/* ********************************* CODE ********************************** */
/** brief eMMC initialize.
*
* - Pre-conditions:<BR>
* .
* - Post-conditions:<BR>
* .
*
* retval EMMC_SUCCESS successful.
* retval EMMC_ERR error from interrupt API.
*/
EMMC_ERROR_CODE emmc_init(void)
{
/* initialize H/W */
(void)emmc_reset_controller();
/* Configuration */
emmc_driver_config();
return EMMC_SUCCESS;
}
/** terminate emmc driver
*
* EMMC H/W and S/W resource is released.
*
* - Pre-conditions:<BR>
* .
* - Post-conditions:<BR>
* .
*
* return None.
*/
EMMC_ERROR_CODE emmc_terminate(void)
{
EMMC_ERROR_CODE result = EMMC_ERR;
/* H/W finalize */
result = emmc_dev_finalize();
/* driver finalize */
emmc_memset((uint8_t *)(&mmc_drv_obj), 0U, sizeof(st_mmc_base)); /* clear global variable */
return result;
}
/** Function executes full reset to MMC host controller without taking power out from the memory card.
*
* - Pre-conditions:<BR>
* .
* - Post-conditions:<BR>
* Reset MMC host controller without taking power out from the memory card.
* Memory card preserves its state.
*
* return None
*/
static EMMC_ERROR_CODE emmc_reset_controller(void)
{
EMMC_ERROR_CODE result = EMMC_ERR;
/* initialize mmc driver */
emmc_drv_init();
mmc_drv_obj.base_address = MMC0_SD_BASE;
/* initialize H/W */
result = emmc_dev_init();
mmc_drv_obj.initialize = TRUE;
return result;
}
/** Configuration eMMC driver
*
* - Pre-conditions:<BR>
* initialized eMMC driver.
* - Post-conditions:<BR>
* .
*
* return None
*/
static void emmc_driver_config(void)
{
/* Read/Write data timeout */
emmc_set_data_timeout(EMMC_RW_DATA_TIMEOUT);
}
/** Sets data timeout
*
* Sets the data timeout value for read and write operations.
*
* - Pre-conditions:<BR>
* initialized eMMC driver.
*
* - Post-conditions:<BR>
* After this function is called, the timeout value is set according to argument.
*
* param[in] time_out The desired timeout value in milliseconds.
* return None
*/
static void emmc_set_data_timeout(uint32_t data_timeout)
{
mmc_drv_obj.data_timeout = data_timeout;
}
/** eMMC driver initialize. (software)
*
* - Pre-conditions:<BR>
* .
* - Post-conditions:<BR>
* .
*
* return None.
*/
static void emmc_drv_init(void)
{
/* initialize */
emmc_memset((uint8_t *)(&mmc_drv_obj), 0U, sizeof(st_mmc_base));
mmc_drv_obj.data_timeout = EMMC_RW_DATA_TIMEOUT;
mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT;
}
/** eMMC driver initialize. (H/W)
*
* - Pre-conditions:<BR>
* .
* - Post-conditions:<BR>
* .
*
* return None.
*/
static EMMC_ERROR_CODE emmc_dev_init(void)
{
/* MMCIF initialize */
mem_write32(SD_INFO1, 0x00000000U); /* all interrupt clear */
mem_write32(SD_INFO2, SD_INFO2_CLEAR); /* all interrupt clear */
mem_write32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */
mem_write32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */
mem_write32(HOST_MODE, 0x00000000U); /* SD_BUF access width = 64-bit */
mem_write32(SD_OPTION, 0x0000C0EEU); /* Bus width = 1bit, timeout=MAX */
mem_write32(SD_CLK_CTRL, 0x00000000U); /* Automatic Control=Disable, Clock Output=Disable */
return EMMC_SUCCESS;
}
/** EMMC H/W finalize
*
* EMMC Host and Card hardware resource is released.
*
* - Pre-conditions:<BR>
* .
*
* - Post-conditions:<BR>
* .
* return None.
*/
static EMMC_ERROR_CODE emmc_dev_finalize(void)
{
EMMC_ERROR_CODE result = EMMC_ERR;
/* MMC power off
* the power supply of eMMC device is always turning on.
* RST_n : Hi --> Low level.
*/
result = emmc_memcard_power(FALSE);
mem_write32(SD_INFO1, 0x00000000U);
mem_write32(SD_INFO2, 0x00000800U);
mem_write32(DM_CM_INFO1, 0x00000000U);
mem_write32(DM_CM_INFO2, 0x00000000U);
mem_write32(SD_CLK_CTRL, 0x00000020U);
mem_write32(CC_EXT_MODE, 0x00000000U);
mem_write32(SD_STOP, 0x00000000U);
mem_write32(SD_SECCNT, 0x00000000U);
mem_write32(DM_CM_DTRAN_MODE, 0x00000000U);
mem_write32(DM_DTRAN_ADDR, 0x00000000U);
mem_write32(SD_OPTION, 0x00000000U);
mem_write32(DM_CM_DTRAN_CTRL, 0x00000000U);
return result;
}
/** Set power to memory card IF.
* This function control Vcc and Vccq and RST_n.
*
* attention
* CPU cannot control Vcc&Vccq.
* The power supply of eMMC device is always turning on.
*
* param[in] mode TRUE = power on, FALSE = power off
*
* retval EMMC_SUCCESS powering succeeded
* retval EMMC_ERR_CARD_POWER powering failed
*/
EMMC_ERROR_CODE emmc_memcard_power(uint32_t mode)
{
if (mode == TRUE) {
/* power on (Vcc&Vccq is always power on) */
mmc_drv_obj.card_power_enable = TRUE;
} else {
/* power off (Vcc&Vccq is always power on) */
mmc_drv_obj.card_power_enable = FALSE;
mmc_drv_obj.mount = FALSE;
mmc_drv_obj.selected = FALSE;
}
return EMMC_SUCCESS;
}
/** memset(). no use C standard library.
*
* - Pre-conditions:<BR>
* .
* - Post-conditions:<BR>
* .
*
* param[in,out] buff pointer to buffer (virtual)
* param[in] data fill data.
* param[in] cnt fill size (number of bytes)
* return None.
*/
static void emmc_memset(void *buff, uint8_t data, uint32_t cnt)
{
uint8_t *tmp = NULL;
tmp = (uint8_t *)buff;
if (buff == NULL) {
return;
}
while (cnt > 0U) {
*tmp = data;
tmp++;
cnt--;
}
}
/* ******************************** END ************************************ */

View File

@@ -0,0 +1,227 @@
/*******************************************************************************
* 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 2021-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : eMMC interrupt
******************************************************************************/
/******************************************************************************
* @file emmc_interrupt.c
* - Version : 0.04
* @brief state check of SDHI.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 22.02.2022 0.01 First Release
* : 22.10.2021 0.02 Remove unnecessary code
* : 22.12.2021 0.03 Support static analysis
* : 06.01.2022 0.04 Modify SDHI access from DMA to PIO.
*****************************************************************************/
#include "emmc_config.h"
#include "emmc_hal.h"
#include "emmc_std.h"
#include "emmc_registers.h"
#include "emmc_def.h"
#include "log.h"
#include <stdint.h>
/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */
/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */
/* ********************** DECLARATION OF EXTERNAL DATA ********************* */
/* ************************** FUNCTION PROTOTYPES ************************** */
static EMMC_ERROR_CODE emmc_trans_sector(uint32_t *buff_address_virtual);
/* ********************************* CODE ********************************** */
/** emmc driver interrupt service routine.
*
* - Pre-conditions:<BR>
* Must be block emmc driver state machine.
* - Post-conditions:<BR>
* unblocking emmc driver state machine.
*
* retval INT_SUCCESS
*/
uint32_t emmc_interrupt(void)
{
EMMC_ERROR_CODE result = EMMC_ERR;
/* SD_INFO */
mmc_drv_obj.error_info.info1 = mem_read32(SD_INFO1);
mmc_drv_obj.error_info.info2 = mem_read32(SD_INFO2);
/* SD_INFO EVENT */
mmc_drv_obj.int_event1 = mmc_drv_obj.error_info.info1 & mem_read32(SD_INFO1_MASK);
mmc_drv_obj.int_event2 = mmc_drv_obj.error_info.info2 & mem_read32(SD_INFO2_MASK);
/* ERR_STS */
mmc_drv_obj.error_info.status1 = mem_read32(SD_ERR_STS1);
mmc_drv_obj.error_info.status2 = mem_read32(SD_ERR_STS2);
/* DM_CM_INFO */
mmc_drv_obj.error_info.dm_info1 = mem_read32(DM_CM_INFO1);
mmc_drv_obj.error_info.dm_info2 = mem_read32(DM_CM_INFO2);
/* DM_CM_INFO EVENT */
mmc_drv_obj.dm_event1 = mmc_drv_obj.error_info.dm_info1 & mem_read32(DM_CM_INFO1_MASK);
mmc_drv_obj.dm_event2 = mmc_drv_obj.error_info.dm_info2 & mem_read32(DM_CM_INFO2_MASK);
/* ERR SD_INFO2 */
if ((SD_INFO2_ALL_ERR & mmc_drv_obj.int_event2) != 0U) {
mem_write32(SD_INFO1_MASK, 0x00000000U); /* interrupt disable */
mem_write32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* interrupt disable */
mem_write32(SD_INFO1, 0x00000000U); /* interrupt clear */
mem_write32(SD_INFO2, SD_INFO2_CLEAR); /* interrupt clear */
mmc_drv_obj.state_machine_blocking = FALSE;
}
/* PIO Transfer */
/* BWE/BRE */
else if ((( SD_INFO2_BWE | SD_INFO2_BRE) & mmc_drv_obj.int_event2) != 0U) {
/* BWE */
if (( SD_INFO2_BWE & mmc_drv_obj.int_event2) != 0U) {
mem_write32(SD_INFO2, (mem_read32(SD_INFO2) & ~SD_INFO2_BWE)); /* interrupt clear */
}
/* BRE */
else {
mem_write32(SD_INFO2, (mem_read32(SD_INFO2) & ~SD_INFO2_BRE)); /* interrupt clear */
}
result = emmc_trans_sector((uint32_t *)mmc_drv_obj.buff_address_virtual); /* sector R/W */
mmc_drv_obj.buff_address_virtual += EMMC_BLOCK_LENGTH;
mmc_drv_obj.remain_size -= EMMC_BLOCK_LENGTH;
if (result != EMMC_SUCCESS) {
/* data transfer error */
ERROR("%s:0x%08x\n",__func__, result);
/* Panic */
mem_write32(SD_INFO1_MASK, 0x00000000U); /* interrupt disable */
mem_write32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* interrupt disable */
mem_write32(SD_INFO1, 0x00000000U); /* interrupt clear */
mem_write32(SD_INFO2, SD_INFO2_CLEAR); /* interrupt clear */
mmc_drv_obj.force_terminate = TRUE;
} else {
mmc_drv_obj.during_transfer = FALSE;
}
mmc_drv_obj.state_machine_blocking = FALSE;
}
/* DMA_TRANSFER */
/* DM_CM_INFO1: DMA-ch0 transfer complete or error occured */
else if ((DM_CM_INFO_DTRANEND0 & mmc_drv_obj.dm_event1) != 0U) {
mem_write32(DM_CM_INFO1, 0x00000000U);
mem_write32(DM_CM_INFO2, 0x00000000U);
mem_write32(SD_INFO2, (mem_read32(SD_INFO2) & ~SD_INFO2_BWE)); /* interrupt clear */
/* DM_CM_INFO2: DMA-ch0 error occured */
if (( DM_CM_INFO_DTRANEND0 & mmc_drv_obj.dm_event2) != 0U) {
mmc_drv_obj.dma_error_flag = TRUE;
} else {
mmc_drv_obj.during_dma_transfer = FALSE;
mmc_drv_obj.during_transfer = FALSE;
}
mmc_drv_obj.state_machine_blocking = FALSE; /* wait next interrupt */
}
/* DM_CM_INFO1: DMA-ch1 transfer complete or error occured */
else if ((DM_CM_INFO_DTRANEND1 & mmc_drv_obj.dm_event1) != 0U) {
mem_write32(DM_CM_INFO1, 0x00000000U);
mem_write32(DM_CM_INFO2, 0x00000000U);
mem_write32(SD_INFO2, (mem_read32(SD_INFO2) & ~SD_INFO2_BRE)); /* interrupt clear */
/* DM_CM_INFO2: DMA-ch1 error occured */
if (( DM_CM_INFO_DTRANEND1 & mmc_drv_obj.dm_event2) != 0U) {
mmc_drv_obj.dma_error_flag = TRUE;
} else {
mmc_drv_obj.during_dma_transfer = FALSE;
mmc_drv_obj.during_transfer = FALSE;
}
mmc_drv_obj.state_machine_blocking = FALSE; /* wait next interrupt */
}
/* Response end */
else if ((SD_INFO1_INFO0 & mmc_drv_obj.int_event1) != 0U) {
mem_write32(SD_INFO1, (mem_read32(SD_INFO1) & ~SD_INFO1_INFO0)); /* interrupt clear */
mmc_drv_obj.state_machine_blocking = FALSE;
}
/* Access end */
else if ((SD_INFO1_INFO2 & mmc_drv_obj.int_event1) != 0U) {
mem_write32(SD_INFO1, (mem_read32(SD_INFO1) & ~SD_INFO1_INFO2)); /* interrupt clear */
mmc_drv_obj.state_machine_blocking = FALSE;
} else {
/* nothing to do. */
}
return 0U;
}
/** Data transfer function with PIO (Single sector).
*
* - Pre-conditions:<BR>
* Called from interrupt service.
* - Post-conditions:<BR>
* .
*
* param[in,out] buff_address_virtual Dest/Src buffer address(virtual).
* retval EMMC_SUCCESS successful.
* retval EMMC_ERR_PARAM parameter error.
* retval EMMC_ERR_STATE state error.
*/
static EMMC_ERROR_CODE emmc_trans_sector(uint32_t *buff_address_virtual)
{
uint32_t length, i;
uint64_t *bufPtrLL;
if (buff_address_virtual == NULL) {
return EMMC_ERR_PARAM;
}
if ((mmc_drv_obj.during_transfer != TRUE) || (mmc_drv_obj.remain_size == 0U)) {
return EMMC_ERR_STATE;
}
bufPtrLL = (uint64_t*)buff_address_virtual;
length = mmc_drv_obj.remain_size;
/* data transefer */
for (i = 0U; i < (length >> 3U); i++) {
/* Write */
if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) {
mem_write64(SD_BUF0, *bufPtrLL); /* buffer --> FIFO */
}
/* Read */
else {
*bufPtrLL = mem_read64(SD_BUF0); /* FIFO --> buffer */
}
bufPtrLL++;
}
return EMMC_SUCCESS;
}
/* ******************************** END ************************************ */

View File

@@ -0,0 +1,767 @@
/*******************************************************************************
* 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 2021-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : eMMC Mount
******************************************************************************/
/******************************************************************************
* @file emmc_mount.c
* - Version : 0.04
* @brief initialize of condition.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 22.02.2022 0.01 First Release
* : 22.10.2021 0.02 Remove unnecessary code
* : 22.12.2021 0.03 Support static analysis
* : 06.01.2022 0.04 Modify SDHI access from DMA to PIO.
*****************************************************************************/
/* ************************ HEADER (INCLUDE) SECTION *********************** */
#include "emmc_config.h"
#include "emmc_hal.h"
#include "emmc_std.h"
#include "emmc_registers.h"
#include "emmc_def.h"
#include <stdint.h>
#include "micro_wait.h"
#include "remap.h"
#include "log.h"
/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */
/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */
/* ********************** DECLARATION OF EXTERNAL DATA ********************* */
/* ************************** FUNCTION PROTOTYPES ************************** */
static EMMC_ERROR_CODE emmc_clock_ctrl(uint32_t mode);
static EMMC_ERROR_CODE emmc_card_init(void);
static EMMC_ERROR_CODE emmc_high_speed(void);
static EMMC_ERROR_CODE emmc_bus_width(uint32_t width);
static uint32_t emmc_set_timeout_register_value(uint32_t freq);
static void set_sd_clk(uint32_t clkDiv);
static uint32_t emmc_calc_tran_speed(uint32_t* freq);
/* ********************************* CODE ********************************** */
/** eMMC mount operation.
*
* Sequence is the following.
* 1) Bus initialization (emmc_card_init())
* 2) Switching to high speed mode. (emmc_high_speed())
* 3) Changing the data bus width. (emmc_bus_width())
*
* - Pre-conditions:<BR>
* eMMC driver is initialized. The power supply of MMC IF must be turning on.
* - Post-conditions:<BR>
* MMC card state changes to transfer state.
*
* return eMMC error code.
*/
EMMC_ERROR_CODE emmc_mount(void)
{
EMMC_ERROR_CODE result = EMMC_ERR;
/* state check */
if ((mmc_drv_obj.initialize != TRUE) || (mmc_drv_obj.card_power_enable != TRUE)
|| ((mem_read32(SD_INFO2) & SD_INFO2_CBSY) != 0U)) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* initialize card (IDLE state --> Transfer state) */
result = emmc_card_init();
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
(void)emmc_clock_ctrl(FALSE);
return result;
}
/* Switching high speed mode */
result = emmc_high_speed();
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
(void)emmc_clock_ctrl(FALSE);
return result;
}
/* Changing the data bus width */
result = emmc_bus_width(8U);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
(void)emmc_clock_ctrl(FALSE);
return result;
}
/* mount complete */
mmc_drv_obj.mount = TRUE;
return EMMC_SUCCESS;
}
/** Bus initialization function
*
* - Pre-conditions:<BR>
* eMMC driver is initialized. The power supply of MMC IF must be turning on.
* - Post-conditions:<BR>
* MMC card state changes to transfer state.
*
* retval EMMC_SUCCESS successful.
* return eMMC error code.
* attention upper layer must be check pre-conditions.
*/
static EMMC_ERROR_CODE emmc_card_init(void)
{
int32_t retry;
uint32_t freq = MMC_400KHZ; /* 390KHz */
EMMC_ERROR_CODE result = EMMC_ERR;
uint32_t resultCalc = 0U;
/* state check */
if ((mmc_drv_obj.initialize != TRUE) || (mmc_drv_obj.card_power_enable != TRUE)
|| ((mem_read32(SD_INFO2) & SD_INFO2_CBSY) != 0U)) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* clock on (force change) */
mmc_drv_obj.current_freq = 0U;
mmc_drv_obj.max_freq = MMC_20MHZ; /* MMC_20MHZ = MMC_12MHZ = 12.187MHz */
result = emmc_set_request_mmc_clock(&freq);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
return EMMC_ERR;
}
micro_wait(1000U); /* wait 1ms */
/* CMD0, arg=0x00000000 */
result = emmc_send_idle_cmd (0x00000000U);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
return result;
}
micro_wait(200U); /* wait 74clock 390kHz(189.74us)*/
/* CMD1 */
emmc_make_nontrans_cmd(CMD1_SEND_OP_COND, EMMC_HOST_OCR_VALUE);
for (retry = 300; retry > 0; retry--) {
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
return result;
}
if ((mmc_drv_obj.r3_ocr & EMMC_OCR_STATUS_BIT) != 0U) {
break; /* card is ready. exit loop */
}
micro_wait(1000U); /* wait 1ms */
}
if (retry == 0) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_TIMEOUT);
return EMMC_ERR_TIMEOUT;
}
if ((mmc_drv_obj.r3_ocr & EMMC_OCR_ACCESS_MODE_MASK) != EMMC_OCR_ACCESS_MODE_SECT) {
/* unknown value */
ERROR("%s:0x%08x\n",__func__,EMMC_ERR);
return EMMC_ERR;
}
/* CMD2 */
emmc_make_nontrans_cmd(CMD2_ALL_SEND_CID_MMC, 0x00000000U);
mmc_drv_obj.response = (uint32_t *)(&mmc_drv_obj.cid_data[0U]); /* use CID special buffer */
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
return result;
}
/* CMD3 */
emmc_make_nontrans_cmd(CMD3_SET_RELATIVE_ADDR, EMMC_RCA << 16U);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
return result;
}
/* CMD9 : CSD */
emmc_make_nontrans_cmd(CMD9_SEND_CSD, EMMC_RCA << 16U);
mmc_drv_obj.response = (uint32_t *)(&mmc_drv_obj.csd_data[0U]); /* use CSD special buffer */
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
return result;
}
/* card version check */
if (EMMC_CSD_SPEC_VARS() < 4U) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_ILLEGAL_CARD);
return EMMC_ERR_ILLEGAL_CARD;
}
/* CMD7 (select card) */
emmc_make_nontrans_cmd(CMD7_SELECT_CARD, EMMC_RCA << 16U);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
return result;
}
mmc_drv_obj.selected = TRUE;
/* card speed check */
resultCalc = emmc_calc_tran_speed(&freq); /* Card spec is calculated from TRAN_SPEED(CSD). */
if (resultCalc == 0U) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_ILLEGAL_CARD);
return EMMC_ERR_ILLEGAL_CARD;
}
mmc_drv_obj.max_freq = freq; /* max frequency (card spec) */
result = emmc_set_request_mmc_clock(&freq);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
return EMMC_ERR;
}
/* set read/write timeout */
mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq);
mem_write32(SD_OPTION, ((mem_read32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) | mmc_drv_obj.data_timeout));
/* SET_BLOCKLEN:512byte */
/* CMD16 */
emmc_make_nontrans_cmd(CMD16_SET_BLOCKLEN, EMMC_BLOCK_LENGTH);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
return result;
}
/* Transfer Data Length */
mem_write32(SD_SIZE, EMMC_BLOCK_LENGTH);
/* CMD8 : EXT_CSD */
emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000U, (uint32_t *)(&mmc_drv_obj.ext_csd_data[0U]),
EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ, HAL_MEMCARD_NOT_DMA);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
/* CMD12 is not send.
* If BUS initialization is failed, user must be execute Bus initialization again.
* Bus initialization is start CMD0(soft reset command).
*/
ERROR("%s\n",__func__);
return result;
}
return EMMC_SUCCESS;
}
/** Switching to high-speed mode
*
* - Pre-conditions:<BR>
* Executing Bus initializatin by emmc_card_init().
* EXT_CSD data must be stored in mmc_drv_obj.ext_csd_data[].
*
* - Post-conditions:<BR>
* Change the clock frequency to 26MHz or 52MHz.
*
* retval EMMC_SUCCESS successful or aleady switching.
* retval EMMC_ERR_STATE state error.
* retval EMMC_ERR unknown error.
* return emmc error code.
*/
static EMMC_ERROR_CODE emmc_high_speed(void)
{
uint32_t freq; /**< High speed mode clock frequency */
EMMC_ERROR_CODE result = EMMC_ERR;
uint8_t cardType;
/* state check */
if (mmc_drv_obj.selected != TRUE) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* max frequency */
cardType = (uint8_t)mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_CARD_TYPE];
if ((cardType & EMMC_EXT_CSD_CARD_TYPE_52MHZ) != 0U) {
freq = MMC_52MHZ;
} else if ((cardType & EMMC_EXT_CSD_CARD_TYPE_26MHZ) != 0U) {
freq = MMC_26MHZ;
} else {
freq = MMC_20MHZ;
}
/* Hi-Speed-mode selction */
if (( MMC_52MHZ == freq) || ( MMC_26MHZ == freq)) {
/* CMD6 */
emmc_make_nontrans_cmd(CMD6_SWITCH, EMMC_SWITCH_HS_TIMING);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
return result;
}
}
/* set mmc clock */
mmc_drv_obj.max_freq = freq;
result = emmc_set_request_mmc_clock(&freq);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
return EMMC_ERR;
}
/* set read/write timeout */
mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq);
mem_write32(SD_OPTION, ((mem_read32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) | mmc_drv_obj.data_timeout));
/* CMD13 */
emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16U);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK_WITHOUT_CRC, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
ERROR("%s\n",__func__);
return result;
}
return EMMC_SUCCESS;
}
/** Changing the data bus width
*
* if chinging the data bus width failed, card is reset by CMD0.
* Please do Bus initialization over again.
*
* - Pre-conditions:<BR>
* Executing Bus initializatin by emmc_card_init().
*
* - Post-conditions:<BR>
* Change the data bus width to 8bit or 4bit.
* mmc_drv_obj.ext_csd_data is updated.
*
* param[in] width bus width (8 or 4)
* retval EMMC_SUCCESS successful.
* retval EMMC_ERR_PARAM parameter error
* retval EMMC_ERR_STATE state error.
*
*/
static EMMC_ERROR_CODE emmc_bus_width(uint32_t width)
{
EMMC_ERROR_CODE result = EMMC_ERR;
/* parameter check */
if ((width != 8U) && (width != 4U) && (width != 1U)) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* state check */
if (mmc_drv_obj.selected != TRUE) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
mmc_drv_obj.bus_width = (HAL_MEMCARD_DATA_WIDTH)(width >> 2U); /* 2 = 8bit, 1 = 4bit, 0 =1bit */
/* CMD6 */
emmc_make_nontrans_cmd(CMD6_SWITCH, ( EMMC_SWITCH_BUS_WIDTH_1 | ((uint32_t)(mmc_drv_obj.bus_width) << 8U)));
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
/* occurred error */
mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT;
goto EXIT;
}
switch (mmc_drv_obj.bus_width) {
case HAL_MEMCARD_DATA_WIDTH_1_BIT:
mem_write32(SD_OPTION, ((mem_read32(SD_OPTION) & ~(SD_OPTION_WIDTH|SD_OPTION_WIDTH8)) | SD_OPTION_WIDTH ));
break;
case HAL_MEMCARD_DATA_WIDTH_4_BIT:
mem_write32(SD_OPTION, (mem_read32(SD_OPTION) & ~(SD_OPTION_WIDTH|SD_OPTION_WIDTH8)));
break;
case HAL_MEMCARD_DATA_WIDTH_8_BIT:
default:
mem_write32(SD_OPTION, ((mem_read32(SD_OPTION) & ~(SD_OPTION_WIDTH|SD_OPTION_WIDTH8)) | SD_OPTION_WIDTH8 ));
break;
}
/* CMD13 */
emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16U);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
goto EXIT;
}
/* CMD8 : EXT_CSD */
emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000U, (uint32_t *)(&mmc_drv_obj.ext_csd_data[0U]),
EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ, HAL_MEMCARD_NOT_DMA);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
goto EXIT;
}
return EMMC_SUCCESS;
EXIT:
ERROR("%s:0x%08x\n",__func__,result);
return result;
}
/** select access partition
*
* This function write the EXT_CSD register(PARTITION_ACCESS: PARTITION_CONFIG[2:0]).
*
* - Pre-conditions:<BR>
* MMC card is mounted.
*
* - Post-conditions:<BR>
* selected partition can access.
*
* param[in] id user selects partitions to access.
* retval EMMC_SUCCESS successful.
* retval EMMC_ERR_STATE state error.
* retval EMMC_ERR_PARAM parameter error.
* return emmc error code.
*/
EMMC_ERROR_CODE emmc_select_partition(EMMC_PARTITION_ID id)
{
EMMC_ERROR_CODE result = EMMC_ERR;
uint32_t partition;
uint32_t partition_config;
/* state check */
if (mmc_drv_obj.mount != TRUE) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* id has PARTITION_ACCESS(Bit[2:0]) */
if ((uint32_t)((uint32_t)id & ~(uint32_t)PARTITION_ID_MASK) != 0U) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* EXT_CSD[179] value */
partition_config = (uint32_t)mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_PARTITION_CONFIG];
if ((partition_config & (uint32_t)PARTITION_ID_MASK) == (uint32_t)id) {
result = EMMC_SUCCESS;
} else {
partition_config = ((partition_config & (~(uint32_t)PARTITION_ID_MASK)) | (uint32_t)id);
partition = EMMC_SWITCH_PARTITION_CONFIG | (partition_config << 8U);
result = emmc_set_ext_csd(partition);
}
return result;
}
/** set EXT CSD data
*
* - Pre-conditions:<BR>
* MMC card is mounted.
*
* - Post-conditions:<BR>
* mmc_drv_obj.ext_csd_data[] is updated.
*
* param[in] arg argument of CMD6
* return emmc error code.
*/
EMMC_ERROR_CODE emmc_set_ext_csd(uint32_t arg)
{
EMMC_ERROR_CODE result = EMMC_ERR;
/* CMD6 */
emmc_make_nontrans_cmd(CMD6_SWITCH, arg);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
/* CMD13 */
emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16U);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
/* CMD8 : EXT_CSD */
emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000, (uint32_t *)(&mmc_drv_obj.ext_csd_data[0U]),
EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ, HAL_MEMCARD_NOT_DMA);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
return EMMC_SUCCESS;
}
/** set request MMC clock frequency.
*
* Function returns EMMC_SUCCESS if clock is already running in the desired frequency.
* EMMC_ERR is returned if the HW doesn't support requested clock frequency.
* If matching frequence cannot be set the closest frequence below should be selected.
* For example if 50MHz is requested, but HW supports only 48MHz then 48MHz should be returned in the freq parameter.
*
* - Pre-conditions:<BR>
* initialized eMMC driver with emmc_init().
* Memory card and MMCSDIO host controller needs to be powered up beforehand.
*
* - Post-conditions:<BR>
* Desired clock frequency is set to memory card IF.
*
* param[in] freq frequency [Hz]
* retval EMMC_SUCCESS successful.
* retval EMMC_ERR_STATE state error.
* retval EMMC_ERR busy
*/
EMMC_ERROR_CODE emmc_set_request_mmc_clock(const uint32_t *freq)
{
/* parameter check */
if (freq == NULL) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* state check */
if ((mmc_drv_obj.initialize != TRUE) || (mmc_drv_obj.card_power_enable != TRUE)) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* clock is already running in the desired frequency. */
if ((mmc_drv_obj.clock_enable == TRUE) && (mmc_drv_obj.current_freq == *freq)) {
return EMMC_SUCCESS;
}
/* busy check */
if ((mem_read32(SD_INFO2) & SD_INFO2_CBSY) != 0U) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_CARD_BUSY);
return EMMC_ERR;
}
set_sd_clk(*freq);
mmc_drv_obj.clock_enable = FALSE;
return emmc_clock_ctrl(TRUE); /* clock on */
}
/** set sd clock.
*
* - Pre-conditions:<BR>
* CSD data must be stored in mmc_drv_obj.csd_data[].
*
* - Post-conditions:<BR>
* set mmc clock.
*
* param[in] clkDiv request freq
* return None.
*/
static void set_sd_clk(uint32_t clkDiv)
{
uint32_t dataL;
dataL = (mem_read32(SD_CLK_CTRL) & (~SD_CLK_CTRL_CLKDIV_MASK));
switch (clkDiv) {
case 1U: /* 1/1 */
dataL |= 0x000000FFU;
break;
case 2U: /* 1/2 */
dataL |= 0x00000000U;
break;
case 4U: /* 1/4 */
dataL |= 0x00000001U;
break;
case 8U: /* 1/8 */
dataL |= 0x00000002U;
break;
case 16U: /* 1/16 */
dataL |= 0x00000004U;
break;
case 32U:/* 1/32 */
dataL |= 0x00000008U;
break;
case 64U:/* 1/64 */
dataL |= 0x00000010U;
break;
case 128U:/* 1/128 */
dataL |= 0x00000020U;
break;
case 256U: /* 1/256 */
dataL |= 0x00000040U;
break;
case 512U:/* 1/512 */
dataL |= 0x00000080U;
break;
default:
/* nop */
break;
}
mem_write32(SD_CLK_CTRL, dataL);
mmc_drv_obj.current_freq = (uint32_t)clkDiv;
}
/** Enable/Disable MMC clock
*
* - Pre-conditions:<BR>
* Before enabling the clock for the first time the desired clock frequency must be set with
* emmc_set_clock_freq().
* Berore setting mmc_drv_obj.data_timeout with emmc_set_data_timeout().
*
* - Post-conditions:<BR>
* After this function is called, clock to memory card IF is on/off.
*
* param[in] mode TRUE = clock on, FALSE = clock off
* retval EMMC_SUCCESS succeeded
* retval EMMC_ERR Busy
*/
static EMMC_ERROR_CODE emmc_clock_ctrl(uint32_t mode)
{
uint32_t value;
/* busy check */
if ((mem_read32(SD_INFO2) & SD_INFO2_CBSY) != 0U) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_CARD_BUSY);
return EMMC_ERR;
}
if (mode == TRUE) {
/* clock ON */
value = ((mem_read32(SD_CLK_CTRL) | MMC_SD_CLK_START) & SD_CLK_WRITE_MASK);
mem_write32(SD_CLK_CTRL, value); /* on */
mmc_drv_obj.clock_enable = TRUE;
} else {
/* clock OFF */
value = ((mem_read32(SD_CLK_CTRL) & MMC_SD_CLK_STOP) & SD_CLK_WRITE_MASK);
mem_write32(SD_CLK_CTRL, value); /* off */
mmc_drv_obj.clock_enable = FALSE;
}
return EMMC_SUCCESS;
}
/** Calculate Card support frequency.
* TRAN_SPEED defines the clock frequency when not in high speed mode.
*
* - Pre-conditions:<BR>
* CSD data must be stored in mmc_drv_obj.csd_data[].
*
* - Post-conditions:<BR>
* None.
* return Frquency[Hz]
*/
static uint32_t emmc_calc_tran_speed(uint32_t* freq)
{
const uint32_t unit[8U] = {10000U, 100000U, 1000000U, 10000000U, 0U, 0U, 0U, 0U}; /**< frequency unit (1/10) */
const uint32_t mult[16U] = {0U, 10U, 12U, 13U, 15U, 20U, 26U, 30U, 35U, 40U, 45U, 52U, 55U, 60U, 70U, 80U}; /**< multiple factor (x10) */
uint32_t maxFreq = 0U;
uint32_t result = 0U;
uint32_t tran_speed = EMMC_CSD_TRAN_SPEED();
/* tran_speed = 0x32
* unit[tran_speed&0x7] = uint[0x2] = 1000000
* mult[(tran_speed&0x78)>>3] = mult[0x30>>3] = mult[6] = 26
* 1000000 * 26 = 26000000 (26MHz)
*/
maxFreq = unit[tran_speed & EMMC_TRANSPEED_FREQ_UNIT_MASK]
* mult[(tran_speed & EMMC_TRANSPEED_MULT_MASK) >> EMMC_TRANSPEED_MULT_SHIFT];
if (maxFreq == 0U) {
result = 0U;
} else if ( MMC_FREQ_52MHZ <= maxFreq) {
*freq = MMC_52MHZ;
result = 1U;
} else if ( MMC_FREQ_26MHZ <= maxFreq) {
*freq = MMC_26MHZ;
result = 1U;
} else if ( MMC_FREQ_20MHZ <= maxFreq) {
*freq = MMC_20MHZ;
result = 1U;
} else {
*freq = MMC_400KHZ;
result = 1U;
}
return result;
}
/** Calculate read/write timeout.
*
* - Pre-conditions:<BR>
* CSD data must be stored in mmc_drv_obj.csd_data[].
*
* - Post-conditions:<BR>
* set mmc clock.
*
* param[in] freq Base clock Div
* return SD_OPTION Timeout Counter
*/
static uint32_t emmc_set_timeout_register_value(uint32_t freq)
{
uint32_t timeoutCnt = 0U; /* SD_OPTION - Timeout Counter */
switch (freq) {
case 1U:/* SDCLK * 2^27 */
timeoutCnt = 0xE0U;
break;
case 2U:/* SDCLK * 2^27 */
timeoutCnt = 0xE0U;
break;
case 4U:/* SDCLK * 2^26 */
timeoutCnt = 0xD0U;
break;
case 8U:/* SDCLK * 2^25 */
timeoutCnt = 0xC0U;
break;
case 16U:/* SDCLK * 2^24 */
timeoutCnt = 0xB0U;
break;
case 32U:/* SDCLK * 2^23 */
timeoutCnt = 0xA0U;
break;
case 64U:/* SDCLK * 2^22 */
timeoutCnt = 0x90U;
break;
case 128U:/* SDCLK * 2^21 */
timeoutCnt = 0x80U;
break;
case 256U:/* SDCLK * 2^20 */
timeoutCnt = 0x70U;
break;
case 512U:/* SDCLK * 2^19 */
timeoutCnt = 0x60U;
break;
default:
/* nop */
break;
}
return timeoutCnt;
}

View File

@@ -0,0 +1,95 @@
/*******************************************************************************
* 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 2021-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : eMMC multi boot
******************************************************************************/
/******************************************************************************
* @file emmc_multiboot.c
* - Version : 0.04
* @brief data access interface to emmc.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 22.02.2022 0.01 First Release
* : 22.10.2021 0.02 Remove unnecessary code
* : 22.12.2021 0.03 Support static analysis
* : 06.01.2022 0.04 Modify SDHI access from DMA to PIO.
*****************************************************************************/
/* ************************ HEADER (INCLUDE) SECTION *********************** */
#include "emmc_config.h"
#include "emmc_hal.h"
#include "emmc_std.h"
#include "emmc_def.h"
#include "emmc_multiboot.h"
#include "rom_api.h"
#include "types.h"
/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */
/* ********************** DECLARATION OF EXTERNAL DATA ********************* */
/* ************************** FUNCTION PROTOTYPES ************************** */
uint32_t emmc_check_result(uint32_t result);
/* ********************************* CODE ********************************** */
#if defined(__RH850__)
uint32_t emmc_trans_data(uint32_t next_bootPartition, uintptr_t sourceSct, uintptr_t targetAd, uint32_t sectorSize)
{
EMMC_ERROR_CODE result;
uint32_t rtn_val = EMMC_DEV_ERR;
/* Partition select */
result = emmc_select_partition((EMMC_PARTITION_ID)next_bootPartition);
if (result == EMMC_SUCCESS) {
result = emmc_read_sector((uint32_t *)targetAd, sourceSct, sectorSize, LOADIMAGE_FLAGS_DMA_ENABLE);
}
/* EMMC_ERROR_CODE -> ROM_XX */
rtn_val = emmc_check_result((uint32_t)result);
return rtn_val;
}
#endif /* #if defined(__RH850__) */
uint32_t emmc_check_result(uint32_t result)
{
uint32_t ret = EMMC_DEV_ERR_FAULT_INJECTION;
if (result == EMMC_SUCCESS) {
ret = EMMC_DEV_OK;
} else if (result == EMMC_ERR) {
ret = EMMC_DEV_ERR;
} else { /* other */
ret = EMMC_DEV_ERR_HW;
}
return ret;
}
/* ******************************** END ************************************ */

View File

@@ -0,0 +1,204 @@
/*******************************************************************************
* 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 2021-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : eMMC Read data access driver
******************************************************************************/
/******************************************************************************
* @file emmc_read.c
* - Version : 0.04
* @brief read data access function to emmc.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 22.02.2022 0.01 First Release
* : 22.10.2021 0.02 Remove unnecessary code
* : 22.12.2021 0.03 Support static analysis
* : 06.01.2022 0.04 Modify SDHI access from DMA to PIO.
*****************************************************************************/
/* ************************ HEADER (INCLUDE) SECTION *********************** */
#include "emmc_config.h"
#include "emmc_hal.h"
#include "emmc_std.h"
#include "emmc_registers.h"
#include "emmc_def.h"
#include "log.h"
#include <wdt.h>
/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */
#define EMMC_RW_SECTOR_COUNT_MAX 0x0000ffffUL
/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */
/* ********************** DECLARATION OF EXTERNAL DATA ********************* */
/* ************************** FUNCTION PROTOTYPES ************************** */
static EMMC_ERROR_CODE emmc_multiple_block_read (uint32_t *buff_address_virtual, uint32_t sector_number, uint32_t count, HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode);
static inline uint32_t get_min_value(uint32_t a, uint32_t b)
{
uint32_t ret = a;
if(b < a)
{
ret = b;
}
return ret;
}
/* ********************************* CODE ********************************** */
/** function of read sector
*
* This function always use block read.
* Single block read is not used.
*
* - Pre-conditions:<BR>
* MMC card is mounted.
*
* - Post-conditions:<BR>
* .
*
* param[in,out] buff_address_virtual virtual address of read data buffer.
* param[in] sector_number data address for MMC device (sector number).
* param[in] count number of sector.
* param[in] transfermode Mode of data transfer, DMA or not DMA.
*/
EMMC_ERROR_CODE emmc_read_sector(uint32_t *buff_address_virtual, uint32_t sector_number, uint32_t count,
uint32_t feature_flags)
{
uint32_t trans_count;
uint32_t remain;
EMMC_ERROR_CODE result = EMMC_ERR;
HAL_MEMCARD_DATA_TRANSFER_MODE transfermode;
/* parameter check */
if (count == 0U) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* state check */
if (mmc_drv_obj.mount != TRUE) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* DMA? */
if ((feature_flags & LOADIMAGE_FLAGS_DMA_ENABLE) != 0U) {
transfermode = HAL_MEMCARD_DMA;
} else {
transfermode = HAL_MEMCARD_NOT_DMA;
}
remain = count;
while (remain != 0U) {
trans_count = get_min_value(remain, EMMC_RW_SECTOR_COUNT_MAX);
result = emmc_multiple_block_read(buff_address_virtual, sector_number, trans_count, transfermode);
if (result != EMMC_SUCCESS) {
return result;
}
buff_address_virtual += (EMMC_BLOCK_LENGTH_DW * trans_count);
sector_number += trans_count;
remain -= trans_count;
wdt_restart();
}
return EMMC_SUCCESS;
}
/** multiple block read
*
* Multiple block read with pre-defined block count.
*
* - Pre-conditions:<BR>
* MMC card is mounted.
*
* - Post-conditions:<BR>
* .
*
* param[in,out] buff_address_virtual virtual address of read data buffer.
* param[in] sector_number data address for MMC device (sector number).
* param[in] count number of sector. (0x1 - 0xffff)
* param[in] transfer_mode Mode of data transfer, DMA or not DMA.
*/
static EMMC_ERROR_CODE emmc_multiple_block_read(uint32_t *buff_address_virtual, uint32_t sector_number, uint32_t count,
HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode)
{
EMMC_ERROR_CODE result = EMMC_ERR;
/* parameter check */
if ((count > EMMC_RW_SECTOR_COUNT_MAX) || (count == 0U)
|| ((transfer_mode != HAL_MEMCARD_DMA) && (transfer_mode != HAL_MEMCARD_NOT_DMA))) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* CMD23 */
emmc_make_nontrans_cmd(CMD23_SET_BLOCK_COUNT, count);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
mem_write32(SD_SECCNT, count);
mem_write32(SD_STOP, 0x00000100U);
mem_write32(CC_EXT_MODE, (CC_EXT_MODE_CLEAR | CC_EXT_MODE_DMASDRW_ENABLE)); /* SD_BUF Read/Write DMA Transfer enable */
/* CMD18 */
emmc_make_trans_cmd(CMD18_READ_MULTIPLE_BLOCK, sector_number, buff_address_virtual, count << EMMC_SECTOR_SIZE_SHIFT,
HAL_MEMCARD_READ, transfer_mode);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result; /* CMD18 error code */
}
/* CMD13 */
emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16U);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
/* ready status check */
if ((mmc_drv_obj.r1_card_status & EMMC_R1_READY) == 0U) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_CARD_BUSY);
return EMMC_ERR_CARD_BUSY;
}
/* state check */
if (mmc_drv_obj.current_state != EMMC_R1_STATE_TRAN) {
ERROR("%s:0x%08x\n",__func__,EMMC_ERR_CARD_STATE);
return EMMC_ERR_CARD_STATE;
}
return EMMC_SUCCESS;
}
/* ******************************** END ************************************ */

View File

@@ -0,0 +1,301 @@
/*******************************************************************************
* 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 2021-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : eMMC Utility
******************************************************************************/
/******************************************************************************
* @file emmc_utility.c
* - Version : 0.04
* @brief Analysis of SDHI data.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 22.02.2022 0.01 First Release
* : 22.10.2021 0.02 Remove unnecessary code
* : 22.12.2021 0.03 Support static analysis
* : 06.01.2022 0.04 Modify SDHI access from DMA to PIO.
*****************************************************************************/
/* ************************ HEADER (INCLUDE) SECTION *********************** */
#include "emmc_config.h"
#include "emmc_hal.h"
#include "emmc_std.h"
#include "emmc_registers.h"
#include "emmc_def.h"
/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */
#define BUSY_SIGNAL (1U << 10U)
static const uint32_t cmd_reg_hw[EMMC_CMD_MAX + 1U] = {
0x00000000U, /* CMD0 */
0x00000701U, /* CMD1 */
0x00000002U, /* CMD2 */
0x00000003U, /* CMD3 */
0x00000004U, /* CMD4 */
0x00000505U, /* CMD5 */
0x00000406U, /* CMD6 */
0x00000007U, /* CMD7 */
0x00001C08U, /* CMD8 */
0x00000009U, /* CMD9 */
0x0000000AU, /* CMD10 */
0x00000000U, /* reserved */
0x0000000CU, /* CMD12 */
0x0000000DU, /* CMD13 */
0x00001C0EU, /* CMD14 */
0x0000000FU, /* CMD15 */
0x00000010U, /* CMD16 */
0x00000011U, /* CMD17 */
0x00007C12U, /* CMD18 */
0x00000C13U, /* CMD19 */
0x00000000U,
0x00001C15U, /* CMD21 */
0x00000000U,
0x00000017U, /* CMD23 */
0x00000018U, /* CMD24 */
0x00006C19U, /* CMD25 */
0x00000C1AU, /* CMD26 */
0x0000001BU, /* CMD27 */
0x0000001CU, /* CMD28 */
0x0000001DU, /* CMD29 */
0x0000001EU, /* CMD30 */
0x00001C1FU, /* CMD31 */
0x00000000U,
0x00000000U,
0x00000000U,
0x00000423U, /* CMD35 */
0x00000424U, /* CMD36 */
0x00000000U,
0x00000026U, /* CMD38 */
0x00000427U, /* CMD39 */
0x00000428U, /* CMD40 : send cmd */
0x00000000U,
0x0000002AU, /* CMD42 */
0x00000000U,
0x00000000U,
0x00000000U,
0x00000000U,
0x00000000U,
0x00000000U,
0x00000C31U,
0x00000000U,
0x00000000U,
0x00000000U,
0x00007C35U,
0x00006C36U,
0x00000037U, /* CMD55 */
0x00000038U, /* CMD56 : Read */
0x00000000U,
0x00000000U,
0x00000000U,
0x00000000U
};
/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */
/* ********************** DECLARATION OF EXTERNAL DATA ********************* */
/* ************************** FUNCTION PROTOTYPES ************************** */
/* ********************************* CODE ********************************** */
/** make non-transfer command data
*
* Response data buffer is automatically selected.
*
* - Pre-conditions:<BR>
* Clock to memory card IF is enabled.
*
* - Post-conditions:<BR>
* After this function is called, command can be executed.
*
* param[in] cmd command information.
* param[in] arg command argument
* return None.
*/
void emmc_make_nontrans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg)
{
/* command information */
mmc_drv_obj.cmd_info.cmd = cmd;
mmc_drv_obj.cmd_info.arg = arg;
mmc_drv_obj.cmd_info.dir = HAL_MEMCARD_READ;
mmc_drv_obj.cmd_info.hw = cmd_reg_hw[(uint32_t)cmd & HAL_MEMCARD_COMMAND_INDEX_MASK];
/* clear data transfer information */
mmc_drv_obj.trans_size = 0U;
mmc_drv_obj.remain_size = 0U;
mmc_drv_obj.buff_address_virtual = NULL;
mmc_drv_obj.buff_address_physical = NULL;
/* response information */
mmc_drv_obj.response_length = 6U;
switch ((HAL_MEMCARD_RESPONSE_TYPE)((uint32_t)(mmc_drv_obj.cmd_info.cmd) & (uint32_t)HAL_MEMCARD_RESPONSE_TYPE_MASK)) {
case HAL_MEMCARD_RESPONSE_NONE:
mmc_drv_obj.response = (uint32_t *)mmc_drv_obj.response_data;
mmc_drv_obj.response_length = 0U;
break;
case HAL_MEMCARD_RESPONSE_R1:
mmc_drv_obj.response = &mmc_drv_obj.r1_card_status;
break;
case HAL_MEMCARD_RESPONSE_R1b:
mmc_drv_obj.cmd_info.hw |= BUSY_SIGNAL; /* bit10 = R1 busy bit */
mmc_drv_obj.response = &mmc_drv_obj.r1_card_status;
break;
case HAL_MEMCARD_RESPONSE_R2:
mmc_drv_obj.response = (uint32_t *)mmc_drv_obj.response_data;
mmc_drv_obj.response_length = 17U;
break;
case HAL_MEMCARD_RESPONSE_R3:
mmc_drv_obj.response = &mmc_drv_obj.r3_ocr;
break;
case HAL_MEMCARD_RESPONSE_R4:
mmc_drv_obj.response = &mmc_drv_obj.r4_resp;
break;
case HAL_MEMCARD_RESPONSE_R5:
mmc_drv_obj.response = &mmc_drv_obj.r5_resp;
break;
default:
mmc_drv_obj.response = (uint32_t *)mmc_drv_obj.response_data;
break;
}
}
/** Making command information for data transfer command.
*
* - Pre-conditions:<BR>
* None.
*
* - Post-conditions:<BR>
* After this function is called, command can be executed.
*
* param[in] cmd command
* param[in] arg command argument
* param[in] buff_address_virtual Pointer to buffer where data is/will be stored. (virtual address)
* Client is responsible of allocation and deallocation of the buffer.
* param[in] len transfer length in bytes
* param[in] dir direction
* param[in] transfer_mode Mode of data transfer, DMA or not DMA.
* return None.
*/
void emmc_make_trans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg, uint32_t *buff_address_virtual, /* virtual address */
uint32_t len, HAL_MEMCARD_OPERATION dir, HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode)
{
emmc_make_nontrans_cmd(cmd, arg); /* update common information */
/* for data transfer command */
mmc_drv_obj.cmd_info.dir = dir;
mmc_drv_obj.buff_address_virtual = buff_address_virtual;
mmc_drv_obj.buff_address_physical = buff_address_virtual;
mmc_drv_obj.trans_size = len;
mmc_drv_obj.remain_size = len;
mmc_drv_obj.transfer_mode = transfer_mode;
}
/** Send idle command.
* Function execute CMD0.
*
* - Pre-conditions:<BR>
* Clock to MMC I/F enabled.
*
* - Post-conditions:<BR>
* Card reset to idle or pre-idle state.
*
* param[in] arg CMD0 argument.
* return error code
*/
EMMC_ERROR_CODE emmc_send_idle_cmd(uint32_t arg)
{
EMMC_ERROR_CODE result = EMMC_ERR;
uint32_t freq;
/* initialize state */
mmc_drv_obj.mount = FALSE;
mmc_drv_obj.selected = FALSE;
mmc_drv_obj.during_transfer = FALSE;
mmc_drv_obj.during_dma_transfer = FALSE;
mmc_drv_obj.dma_error_flag = FALSE;
mmc_drv_obj.force_terminate = FALSE;
mmc_drv_obj.state_machine_blocking = FALSE;
mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT;
mmc_drv_obj.max_freq = MMC_20MHZ; /* 20MHz */
mmc_drv_obj.current_state = EMMC_R1_STATE_IDLE;
/* CMD0 (MMC clock is current frequency. if Data transfer mode, 20MHz or higher.) */
emmc_make_nontrans_cmd(CMD0_GO_IDLE_STATE, arg); /* CMD0 */
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
/* change MMC clock(400KHz) */
freq = MMC_400KHZ;
result = emmc_set_request_mmc_clock(&freq);
if (result != EMMC_SUCCESS) {
return result;
}
return EMMC_SUCCESS;
}
/** get bit field data for 16bytes data(CSD register).
*
* - Pre-conditions:<BR>
* .
* - Post-conditions:<BR>
* .
*
* param[in] data 16bytes data.
* param[in] top bit number(top). 128>top
* param[in] bottom bit number(bottom). (0<=bottom<=top)
* return bit field.
*/
uint32_t emmc_bit_field(const uint8_t *data, uint32_t top, uint32_t bottom)
{
uint32_t value;
uint32_t index_top = (uint32_t)(15U - (top >> 3U));
uint32_t index_bottom = (uint32_t)(15U - (bottom >> 3U));
if (index_top == index_bottom) {
value = data[index_top];
} else if ((index_top + 1U) == index_bottom) {
value = (uint32_t)(((uint32_t)data[index_top] << 8U) | data[index_bottom]);
} else if ((index_top + 2U) == index_bottom) {
value = (uint32_t)(
((uint32_t)data[index_top] << 16U) | ((uint32_t)data[index_top + 1U] << 8U) | data[index_top + 2U]);
} else {
value = (uint32_t)(
((uint32_t)data[index_top] << 24U) | ((uint32_t)data[index_top + 1U] << 16U)
| ((uint32_t)data[index_top + 2U] << 8U) | data[index_top + 3U]);
}
value = ((value >> (bottom & 0x07U)) & ((1U << ((top - bottom) + 1U)) - 1U));
return value;
}
/* ******************************** END ************************************ */

View File

@@ -0,0 +1,79 @@
/*******************************************************************************
* 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 2023 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : FCPR initialize
******************************************************************************/
/******************************************************************************
* @file fcpr.c
* - Version : 0.04
* @brief Initial setting process of FCPR.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 28.10.2022 0.01 First Release
* : 22.11.2022 0.02 Defenition Remap address
* : 14.06.2023 0.03 Update the setting process for FCPR.
* : 21.08.2023 0.04 Add support for V4M.
*****************************************************************************/
#include <stdint.h>
#include <types.h>
#include <cpg.h>
#include <fcpr.h>
#include <remap.h>
#define CPG_MSTPCR_FCPR (((uint32_t)1U) << 17U)
void fcpr_init(void)
{
/* Register FPCR base address to SIC REMAP14 for V4M. */
/* There are no problems for V4H because same value had set for V4H in BootROM. */
set_sicremap_fcpr();
#if (SET_FCPR_PARAM == FCPR_ENABLE)
uint32_t reg;
/* Enables supply of the clock signal */
reg = mem_read32(CPG_MSTPCR28D0);
/* If supply of clock to FCPR is stopped */
if (FALSE != (CPG_MSTPCR_FCPR & reg))
{
/* Supply of clock to FCPR is start */
reg &= ~(CPG_MSTPCR_FCPR);
mem_write32(CPG_MSTPCR28D0, reg);
}
/* Set value to FCPR_CMP_CTRL */
mem_write32(FCPR_CMP_CTRL, COMPRESSION_ENABLE);
/* Set value to FCPR_CMP_SPACE */
mem_write32(FCPR_CMP_SPACE, 0x00000000U);
/* Set value to FCPR_CMP_STADR */
mem_write32(FCPR_CMP_STADR, COMPRESSION_START_ADDR);
/* Set value to FCPR_CMP_EDADR */
mem_write32(FCPR_CMP_EDADR, COMPRESSION_END_ADDR);
#endif /* SET_FCPR_PARAM == FCPR_ENABLE */
}
/* End of function fcpr_init(void) */

View File

@@ -0,0 +1,102 @@
/*******************************************************************************
* DESCRIPTION : GPIO Control function
******************************************************************************/
/******************************************************************************
* @file gpio.c
* - Version : 0.01
* @brief
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 18.11.2024 0.01 First Release
*****************************************************************************/
#if defined(__CX_IPL__) /* V4H_Cx_Loader */
#include "mem_io.h"
#include "rcar_def.h"
#include "rcar_register.h"
#include "gic.h"
#include "ip_control.h"
#include "timer.h"
#define GP0_8_BASE (BASE_PFC0_ADDR + 0x0180U)
#define GP1_24_BASE (PFC_GP1_BASE + 0x0180U)
#else /* Gen4_ICUMX_Loader */
#include <stdint.h>
#include <types.h>
#include <cpg.h>
#include <pfc.h>
#include <mem_io.h>
#include <micro_wait.h>
#include <rst_register.h>
#define GPIO_BASE (PFC_BASE + PFC_PORT_GRP0)
#define GP0_8_BASE (PFC_BASE + PFC_PORT_GRP0 + 0x0180)
#define GP1_24_BASE (PFC_BASE + PFC_PORT_GRP1 + 0x0180)
#endif
#define GP1_23_BASE GP1_24_BASE
#define GPIO_IOINTSEL 0x00 /* General IO/Interrupt Switching Register */
#define GPIO_INOUTSEL 0x04 /* General Input/Output Switching Register */
#define GPIO_OUTDT 0x08 /* General Output Register */
#define GPIO_INDT 0x0c /* General Input Register */
#define GPIO_INTDT 0x10 /* Interrupt Display Register */
#define GPIO_INTCLR 0x14 /* Interrupt Clear Register */
#define GPIO_INTMSK 0x18 /* Interrupt Mask Register */
#define GPIO_MSKCLR 0x1c /* Interrupt Mask Clear Register */
#define GPIO_POSNEG 0x20 /* Positive/Negative Logic Select Register */
#define GPIO_EDGLEVEL 0x24 /* Edge/level Select Register */
#define GPIO_FILONOFF 0x28 /* Chattering Prevention On/Off Register */
#define GPIO_BOTHEDGE 0x4c /* One Edge/Both Edge Select Register */
#define GPIO_INEN 0x50 /* General Input Enable Register */
#define BIT(nr) (1 << (nr))
void gpio_output_clr_set(uintptr_t regs, int offset, int set)
{
if (set)
mem_bitclrset32(regs + GPIO_OUTDT, 0x0, BIT(offset)); /* set */
else
mem_bitclrset32(regs + GPIO_OUTDT, BIT(offset), 0x0); /* clear */
mem_bitclrset32(regs + GPIO_POSNEG, BIT(offset), 0x0);
mem_bitclrset32(regs + GPIO_INEN, BIT(offset), 0x0);
mem_bitclrset32(regs + GPIO_IOINTSEL, BIT(offset), 0x0);
mem_bitclrset32(regs + GPIO_INOUTSEL, 0x0, BIT(offset)); /* set output */
}
/* End of function gpio_output_clr_set(uintptr_t regs, int offset, int set) */
#if (BOOT_TIME_CHECK != 0)
void gpio_N1307(int set) {
if (set == 2) {
gpio_output_clr_set(GP0_8_BASE, 8, 0);
gpio_output_clr_set(GP0_8_BASE, 8, 1);
micro_wait(10U);
gpio_output_clr_set(GP0_8_BASE, 8, 0);
} else if (set)
gpio_output_clr_set(GP0_8_BASE, 8, 1);
else
gpio_output_clr_set(GP0_8_BASE, 8, 0);
}
void gpio_N1305(int set) {
if (set == 2) {
gpio_output_clr_set(GP1_24_BASE, 24, 0);
micro_wait(10U);
gpio_output_clr_set(GP1_24_BASE, 24, 1);
micro_wait(10U);
// gpio_output_clr_set(GP1_24_BASE, 24, 0);
} else if (set)
gpio_output_clr_set(GP1_24_BASE, 24, 1);
else
gpio_output_clr_set(GP1_24_BASE, 24, 0);
}
#endif
void gpio_V4H_SERDES_1V8_en(int set) {
if (set) {
gpio_output_clr_set(GP1_23_BASE, 23, 1);
} else {
gpio_output_clr_set(GP1_23_BASE, 23, 0);
}
}

View File

@@ -0,0 +1,408 @@
/*******************************************************************************
* 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 2023-2024 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : I2C driver
******************************************************************************/
/******************************************************************************
* @file i2c.c
* - Version : 0.02
* @brief I2C driver.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 16.11.2023 0.01 First Release
* : 24.06.2024 0.02 Remove pre-process branch of i2c3_read().
*****************************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <cpg.h>
#include <cpg_register.h>
#include <i2c.h>
#include <i2c_register.h>
#include <log.h>
#include <mem_io.h>
#include <pfc.h>
#include <pfc_register.h>
/* Setting value for PFC */
#define IP0SR4_SDA3 (0xF0000000U) /* bit[31:28] */
#define IP0SR4_SCL3 (0x0F000000U) /* bit[27:24] */
#define GPSR4_SDA3 (0x00000080U) /* bit7 */
#define GPSR4_SCL3 (0x00000040U) /* bit6 */
#define MODSEL4_SDA3 (0x00000080U) /* bit7 */
#define MODSEL4_SCL3 (0x00000040U) /* bit6 */
#define PUEN4_SDA3 (0x00000080U) /* bit7 */
#define PUEN4_SCL3 (0x00000040U) /* bit6 */
static void i2c3_init_pin_function(void);
void i2c3_init(void)
{
/*
* Module Standby setting for I2C3 is not nessesary
* because H/W initial value is 'Enables supply of the clock signal'.
*/
/* PFC setting for I2C3. */
i2c3_init_pin_function();
/* CDFD=0, HLSE=0, SME=0 */
mem_write32((uintptr_t)I2C3_ICCCR2, 0x00000000U);
/* SCGD=H'3, CDF=H'6 */
mem_write32((uintptr_t)I2C3_ICCCR, (SET_SCGD | SET_CDF));
mem_write32((uintptr_t)I2C3_ICSCR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSSR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSIER, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSAR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMIER, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMAR, 0x00000000U);
}
/* End of function i2c3_init(void) */
static void i2c3_init_pin_function(void)
{
uint32_t data;
/* SDA3, SCL3 -> 0 */
data = mem_read32((uintptr_t)PFC_IP0SR4_RW);
data &= ~(IP0SR4_SDA3 | IP0SR4_SCL3);
pfc_reg_write(PFC_IP0SR4_RW, data);
/* SDA3, SCL3 -> 1 */
data = mem_read32((uintptr_t)PFC_GPSR4_RW);
data |= (GPSR4_SDA3 | GPSR4_SCL3);
pfc_reg_write(PFC_GPSR4_RW, data);
/* Select SDA3 and SCL3 to I2C mode */
data = mem_read32((uintptr_t)PFC_MODSEL4_RW);
data |= (MODSEL4_SDA3 | MODSEL4_SCL3);
pfc_reg_write(PFC_MODSEL4_RW, data);
/* SDA3, SCL3 -> 0 */
data = mem_read32((uintptr_t)PFC_PUEN4_RW);
data &= ~(PUEN4_SDA3 | PUEN4_SCL3);
pfc_reg_write(PFC_PUEN4_RW, data);
}
/* End of function i2c3_init_pin_function(void) */
void i2c3_write(uint32_t slaveAdd, uint32_t regAdd, uint32_t setData)
{
uint32_t data;
uint32_t err_count = 0U;
uint32_t status;
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMCR);
data &= (FLAG_FSCL | FLAG_FSDA);
if(data == FLAG_FSCL)
{
break;
}
}
status = I2C_NG;
while(I2C_NG == status)
{
/* Set MDBS and MIE (initialize) */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
/* Set slave address */
slaveAdd &= ~FLG_RW; /* write mode */
mem_write32((uintptr_t)I2C3_ICMAR, slaveAdd);
/* Set register address */
mem_write32((uintptr_t)I2C3_ICTXD, regAdd);
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMCR);
data &= (FLAG_FSCL | FLAG_FSDA);
if(data == FLAG_FSCL)
{
break;
}
}
/* Set MDBS, MIE and ESG */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_ESG)); /* start condition */
/* MDE(master data empty) & MAT(master address transmitted */
status = i2c3_err_check(FLAG_MDE, FLAG_MAT, (FLAG_MNR|FLAG_MAL));
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("1:I2C data write error\n");
panic;
}
}
}
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
status = I2C_NG;
while(I2C_NG == status)
{
/* MDE and MAT clear */
data = mem_read32((uintptr_t)I2C3_ICMSR);
data &= (FLAG_MNR | FLAG_MAL | FLAG_MST | FLAG_MDT | FLAG_MDR);
mem_write32((uintptr_t)I2C3_ICMSR, data);
/* MDE(master data empty) & MDT(master data transmitted) */
status = i2c3_err_check(FLAG_MDE, FLAG_MDT, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("2:I2C data write error\n");
panic;
}
}
}
status = I2C_NG;
while(I2C_NG == status)
{
/* send voltage */
mem_write32((uintptr_t)I2C3_ICTXD, setData);
/* MDE and MAT clear */
data = mem_read32((uintptr_t)I2C3_ICMSR);
data &= (FLAG_MNR | FLAG_MAL | FLAG_MST | FLAG_MDR | FLAG_MAT);
mem_write32((uintptr_t)I2C3_ICMSR, data);
/* MDE(master data empty) & MDT(master data transmitted) */
status = i2c3_err_check(FLAG_MDE, FLAG_MDT, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("3:I2C data write error\n");
panic;
}
}
}
/* Set MDBS, MIE and FSB */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_FSB)); /* stop condition */
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U); /* MST(master stop transmitted) clear */
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMSR);
if((data & FLAG_MST) != 0U) /* MST(master stop transmitted) */
{
break;
}
}
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
}
/* End of function i2c3_write(uint32_t slaveAdd, uint32_t regAdd, uint32_t setData) */
void i2c3_read(uint32_t slaveAdd, uint32_t regAdd, uint32_t *revData)
{
uint32_t data;
uint32_t err_count = 0;
uint32_t status;
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMCR);
data &= (FLAG_FSCL | FLAG_FSDA);
if(data == FLAG_FSCL)
{
break;
}
}
status = I2C_NG;
while(I2C_NG == status)
{
/* Set MDBS and MIE (initialize) */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
/* Set slave address */
slaveAdd &= ~FLG_RW; /* write mode */
mem_write32((uintptr_t)I2C3_ICMAR, slaveAdd);
/* Set register address */
mem_write32((uintptr_t)I2C3_ICTXD, regAdd);
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMCR);
data &= (FLAG_FSCL | FLAG_FSDA);
if(data == FLAG_FSCL)
{
break;
}
}
/* Set MDBS, MIE and ESG */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_ESG)); /* start condition */
/* MDE(master data empty) & MAT(master address transmitted */
status = i2c3_err_check(FLAG_MDE, FLAG_MAT, (FLAG_MNR|FLAG_MAL));
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("1:I2C data read error\n");
panic;
}
}
}
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
status = I2C_NG;
while(I2C_NG == status)
{
/* MDE and MAT clear */
data = mem_read32((uintptr_t)I2C3_ICMSR);
data &= 0x000000F6U;
mem_write32((uintptr_t)I2C3_ICMSR, data);
/* MDE(master data empty) */
status = i2c3_err_check(FLAG_MDE, FLAG_NONE, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("2:I2C data read error\n");
panic;
}
}
}
status = I2C_NG;
while(I2C_NG == status)
{
/* Set slave address */
slaveAdd |= FLG_RW; /* read mode */
mem_write32((uintptr_t)I2C3_ICMAR, slaveAdd);
/* Set MDBS, MIE and ESG */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_ESG)); /* start condition */
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U);
/* MDR(master data recieved) & MAT(master address transmitted) */
status = i2c3_err_check(FLAG_MDR, FLAG_MAT, (FLAG_MNR|FLAG_MAL));
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("3:I2C data read error\n");
panic;
}
}
}
status = I2C_NG;
while(I2C_NG == status)
{
/* Set MDBS, MIE and FSB */
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_FSB)); /* stop condition */
/* MDE and MAT clear */
data = mem_read32((uintptr_t)I2C3_ICMSR);
data &= 0x000000FCU;
mem_write32((uintptr_t)I2C3_ICMSR, data);
status = i2c3_err_check(FLAG_MDR, FLAG_NONE, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("4:I2C data read error\n");
panic;
}
}
if(I2C_OK == status)
{
*revData = mem_read32((uintptr_t)I2C3_ICRXD) & 0x000000FFU;
}
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U); /* MST(master stop transmitted) clear */
}
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMSR);
if((data & FLAG_MST) != 0U)
{
break;
}
}
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMCR, (FLAG_MDBS | FLAG_MIE));
}
/* End of function i2c3_read(uint32_t slaveAdd, uint32_t regAdd, uint32_t *revData) */
uint32_t i2c3_err_check(uint32_t first, uint32_t second, uint32_t error)
{
uint32_t data;
uint32_t status = I2C_OK;
while(true)
{
data = mem_read32((uintptr_t)I2C3_ICMSR);
if((data & first) != 0U)
{
if((second == FLAG_NONE) || ((data & second) != 0U))
{
status = I2C_OK;
break;
}
}
if((data & error) != 0U)
{
mem_write32((uintptr_t)I2C3_ICMSR, ~error);
status = I2C_NG;
break;
}
}
return status;
}
/* End of function i2c3_err_check(uint32_t first, uint32_t second, uint32_t error) */
void i2c3_release(void)
{
mem_write32((uintptr_t)I2C3_ICCCR2, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICCCR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSCR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSSR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSIER, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICSAR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMCR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMSR, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMIER, 0x00000000U);
mem_write32((uintptr_t)I2C3_ICMAR, 0x00000000U);
}
/* End of function i2c3_release(void) */

View File

@@ -0,0 +1,468 @@
/*******************************************************************************
* 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 2023-2024 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : I2C driver
******************************************************************************/
/******************************************************************************
* @file i2c.c
* - Version : 0.02
* @brief I2C driver.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 16.11.2023 0.01 First Release
* : 24.06.2024 0.02 Remove pre-process branch of i2c5_read().
*****************************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <types.h>
#include <cpg.h>
#include <cpg_register.h>
#include <i2c.h>
#include <i2c_register.h>
#include <log.h>
#include <mem_io.h>
#include <pfc.h>
#include <pfc_register.h>
/* Setting value for PFC */
#define IP1SR8_SDA5_MASK (0x0000F000U) /* bit[15:12] */
#define IP1SR8_SCL5_MASK (0x00000F00U) /* bit[11:8] */
#define IP1SR8_SDA5 (0x00000000U) /* bit[15:12] */
#define IP1SR8_SCL5 (0x00000000U) /* bit[11:8] */
#define GPSR8_SDA5 (0x00000800U) /* bit11 */
#define GPSR8_SCL5 (0x00000400U) /* bit10 */
#define MODSEL8_SDA5 (0x00000800U) /* bit11 */
#define MODSEL8_SCL5 (0x00000400U) /* bit10 */
#define PUEN8_SDA5 (0x00000800U) /* bit11 */
#define PUEN8_SCL5 (0x00000400U) /* bit10 */
#define CPG_MSTPCR_I2C5 (((uint32_t)1U) << 23U)
static void i2c5_init_pin_function(void);
void i2c5_init(void)
{
uint32_t reg;
/*
* Module Standby setting for I2C5
*/
reg = mem_read32(CPG_MSTPSR5D0);
/* If supply of clock to I2C5 is stopped */
if (FALSE != (CPG_MSTPCR_I2C5 & reg))
{
/* Supply of clock to I2C5 is start */
reg &= ~(CPG_MSTPCR_I2C5);
cpg_reg_write(CPG_MSTPCR5D0, CPG_MSTPSR5D0, reg);
}
/* PFC setting for I2C5. */
i2c5_init_pin_function();
/* clock init */
/* CDFD=1, HLSE=1, SME=1, FMPE=1 */
mem_write32((uintptr_t)I2C5_ICCCR2, 0x7U | (1 << 7));
//Clock to filter glitches = 133.3/(1 + 6) = 19Mhz
mem_write32((uintptr_t)I2C5_ICCCR, 0x6);
mem_write32((uintptr_t)I2C5_ICMPR, 21);
mem_write32((uintptr_t)I2C5_ICHPR, 133);
mem_write32((uintptr_t)I2C5_ICLPR, 150);
/* 1st bit setup cycle */
mem_write32((uintptr_t)I2C5_ICFBSCR, 0x07);
/* reset slave interface */
mem_write32((uintptr_t)I2C5_ICSIER, 0U);
mem_write32((uintptr_t)I2C5_ICSCR, FLAG_SDBS);
mem_write32((uintptr_t)I2C5_ICSAR, 0U);
mem_write32((uintptr_t)I2C5_ICSSR, 0U);
/* reset master interface */
mem_write32((uintptr_t)I2C5_ICMIER, 0U);
mem_write32((uintptr_t)I2C5_ICMCR, FLAG_MDBS);
mem_write32((uintptr_t)I2C5_ICMAR, 0U);
mem_write32((uintptr_t)I2C5_ICMSR, 0U);
}
/* End of function i2c5_init(void) */
static void i2c5_init_pin_function(void)
{
uint32_t data;
/* SDA5(GP8_11), SCL5(GP8_10) -> 0 */
data = mem_read32((uintptr_t)PFC_IP1SR8_RW);
data &= ~(IP1SR8_SDA5_MASK | IP1SR8_SCL5_MASK);
// data |= (IP1SR8_SDA5 | IP1SR8_SCL5); /* useless */
pfc_reg_write(PFC_IP1SR8_RW, data);
/* SDA5, SCL5 -> 1 */
data = mem_read32((uintptr_t)PFC_GPSR8_RW);
data |= (GPSR8_SDA5 | GPSR8_SCL5);
pfc_reg_write(PFC_GPSR8_RW, data);
/* Select SDA5 and SCL5 to I2C mode */
data = mem_read32((uintptr_t)PFC_MODSEL8_RW);
data |= (MODSEL8_SDA5 | MODSEL8_SCL5);
pfc_reg_write(PFC_MODSEL8_RW, data);
/* SDA5, SCL5 -> 0 */
data = mem_read32((uintptr_t)PFC_PUEN8_RW);
data &= ~(PUEN8_SDA5 | PUEN8_SCL5);
pfc_reg_write(PFC_PUEN8_RW, data);
}
/* End of function i2c5_init_pin_function(void) */
static void i2c5_set_address_reg(uint32_t slaveAdd, uint32_t regAdd)
{
uint32_t data;
uint32_t err_count = 0U;
uint32_t status;
while(true)
{
data = mem_read32((uintptr_t)I2C5_ICMCR);
data &= (FLAG_FSCL | FLAG_FSDA);
if(data == FLAG_FSCL)
{
break;
}
}
/* 107.3.10.1. Master Transmitter
(b) set value for the master control registers, first data byte, and address */
status = I2C_NG;
while(I2C_NG == status)
{
/* Clear all ICMSR */
mem_write32((uintptr_t)I2C5_ICMSR, 0U);
/* Set slave address */
slaveAdd &= ~FLG_RW; /* write mode */
mem_write32((uintptr_t)I2C5_ICMAR, slaveAdd);
/* Set register address */
mem_write32((uintptr_t)I2C5_ICTXD, regAdd);
while(true)
{
data = mem_read32((uintptr_t)I2C5_ICMCR);
data &= (FLAG_FSCL | FLAG_FSDA);
if(data == FLAG_FSCL)
{
break;
}
}
/* 5. set the Master Control register (ICMCR) = H'89 */
/* Set MDBS, MIE and ESG */
mem_write32((uintptr_t)I2C5_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_ESG)); /* start condition */
/* (c) waiting for outputting address
1. wait for master event (ICMSR.MAT and ICMSR.MDE) */
/* MDE(master data empty) & MAT(master address transmitted) */
status = i2c5_err_check(FLAG_MDE, FLAG_MAT, (FLAG_MNR|FLAG_MAL));
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("1:I2C data write error\n");
panic;
}
}
}
}
static void __i2c5_write(uint32_t slaveAdd, uint32_t regAdd, uint32_t setData)
{
uint32_t data;
uint32_t err_count = 0U;
uint32_t status;
/* 107.3.10.1. Master Transmitter */
i2c5_set_address_reg(slaveAdd, regAdd);
/* 2. set ICMCR to H'88 */
mem_write32((uintptr_t)I2C5_ICMCR, (FLAG_MDBS | FLAG_MIE));
status = I2C_NG;
while(I2C_NG == status)
{
/* 3. Clear the ICMSR.MAT and ICMSR.MDE bits. */
data = mem_read32((uintptr_t)I2C5_ICMSR);
data &= __INV(FLAG_MAT | FLAG_MDE);
mem_write32((uintptr_t)I2C5_ICMSR, data);
/* (d). Monitoring transmission of data
1. wait for master event ICMSR.MDE(master data empty) */
status = i2c5_err_check(FLAG_MDE, FLAG_NONE, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("2:I2C data write error\n");
panic;
}
}
}
/* 2. ICTXD = data */
mem_write32((uintptr_t)I2C5_ICTXD, setData);
/* 3. clear the ICMSR.MDE bit
Clear ICMSR.MDE after setting the last byte to be transmitted.
After the last byte data is loaded into the shift register,
ICMSR.MDE is generated. Before clearning ICMSR.MDE, you must
set ICMCR to H'8A (set the force stop control bit). */
status = I2C_NG;
while(I2C_NG == status)
{
data = mem_read32((uintptr_t)I2C5_ICMSR);
data &= __INV(FLAG_MDE);
mem_write32((uintptr_t)I2C5_ICMSR, data);
status = i2c5_err_check(FLAG_MDE, FLAG_NONE, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("3:I2C data write error\n");
panic;
}
}
}
/* Before clearning ICMSR.MDE, you must
set ICMCR to H'8A (set the force stop control bit). */
mem_write32((uintptr_t)I2C5_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_FSB));
status = I2C_NG;
while(I2C_NG == status)
{
data = mem_read32((uintptr_t)I2C5_ICMSR);
data &= __INV(FLAG_MDE);
mem_write32((uintptr_t)I2C5_ICMSR, data);
/* (e) wait for end of transmission
1. wait for the master event, ICMSR.MST */
status = i2c5_err_check(FLAG_MST, FLAG_NONE, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("3:I2C data write error\n");
panic;
}
}
}
/* 2. clear the ICMSR.MST bit */
data = mem_read32((uintptr_t)I2C5_ICMSR);
data &= __INV(FLAG_MST);
mem_write32((uintptr_t)I2C5_ICMSR, data);
}
/* End of function i2c5_write(uint32_t slaveAdd, uint32_t regAdd, uint32_t setData) */
static void __i2c5_read(uint32_t slaveAdd, uint32_t regAdd, uint32_t *revData)
{
uint32_t data;
uint32_t err_count = 0;
uint32_t status;
/* 107.3.10.3. Master Transmitter - repeated START - Master receiver */
i2c5_set_address_reg(slaveAdd, regAdd);
status = I2C_NG;
while(I2C_NG == status)
{
/* 2. set ICMAR to address of slave ... (read mode: 1) */
/* Set slave address */
slaveAdd |= FLG_RW; /* read mode */
mem_write32((uintptr_t)I2C5_ICMAR, slaveAdd);
/* Set MDBS, MIE and ESG */
mem_write32((uintptr_t)I2C5_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_ESG)); /* start condition */
/* 3. Clear the ICMSR.MAT and ICMSR.MDE bits. */
data = mem_read32((uintptr_t)I2C5_ICMSR);
data &= __INV(FLAG_MAT | FLAG_MDE);
mem_write32((uintptr_t)I2C5_ICMSR, data);
/* (d). Monitor transmission of data.
1. wait for master event, ICMSR.MDE */
/* MDE(master data empty) */
status = i2c5_err_check(FLAG_MDE, FLAG_NONE, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("2:I2C data read error\n");
panic;
}
}
}
status = I2C_NG;
while(I2C_NG == status)
{
/* 2. set ICMCR = H'89 (MDBS = 1, MIE = 1, ESG = 1) */
mem_write32((uintptr_t)I2C5_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_ESG)); /* start condition */
/* 3. clear the MDE bit. */
data = mem_read32((uintptr_t)I2C5_ICMSR);
data &= __INV(FLAG_MDE);
mem_write32((uintptr_t)I2C5_ICMSR, data);
/* (e) wait for outputting slave-address of master reception
1. wait for master event (ICMSR.MAT and ICMSR.MDR bits.) */
status = i2c5_err_check(FLAG_MDR, FLAG_MAT, (FLAG_MNR|FLAG_MAL));
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("3:I2C data read error\n");
panic;
}
}
}
status = I2C_NG;
while(I2C_NG == status)
{
/* 2. set ICMCR to H'88(MDBS, MIE) */
mem_write32((uintptr_t)I2C5_ICMCR, (FLAG_MDBS | FLAG_MIE));
/* 3. clear the ICMSR.MAT and ICMSR.MDR bits. */
data = mem_read32((uintptr_t)I2C5_ICMSR);
data &= __INV(FLAG_MAT | FLAG_MDR);
mem_write32((uintptr_t)I2C5_ICMSR, data);
/* (f) Monitor reception of data
3. set ICMR.FSB to 1 before the last byte data transfer is started */
mem_write32((uintptr_t)I2C5_ICMCR, (FLAG_MDBS | FLAG_MIE | FLAG_FSB)); /* stop condition */
/* (g) Monitor reception of data
1. handle the receive interrupt(ICMSR.MDR) in the last byte:
that is, read the data and clear the ICMSR.MDR. */
status = i2c5_err_check(FLAG_MDR, FLAG_NONE, FLAG_MNR);
if(I2C_NG == status)
{
err_count++;
if(err_count > ERR_MAX)
{
ERROR("4:I2C data read error\n");
panic;
}
}
if(I2C_OK == status)
{
*revData = mem_read32((uintptr_t)I2C5_ICRXD) & 0x000000FFU;
}
/* clear ICMSR.MDR */
data = mem_read32((uintptr_t)I2C5_ICMSR);
data &= __INV(FLAG_MDR);
mem_write32((uintptr_t)I2C5_ICMSR, data);
}
/* 2. wait for master event, ICMSR.MST */
while(true)
{
data = mem_read32((uintptr_t)I2C5_ICMSR);
if((data & FLAG_MST) != 0U)
{
break;
}
}
/* 3. clear the ICMSR.MST(master stop transmitted) bit */
data = mem_read32((uintptr_t)I2C5_ICMSR);
data &= __INV(FLAG_MST);
mem_write32((uintptr_t)I2C5_ICMSR, data);
}
/* End of function i2c5_read(uint32_t slaveAdd, uint32_t regAdd, uint32_t *revData) */
uint32_t i2c5_err_check(uint32_t first, uint32_t second, uint32_t error)
{
uint32_t data;
uint32_t status = I2C_OK;
while(true)
{
data = mem_read32((uintptr_t)I2C5_ICMSR);
if((data & first) != 0U)
{
if((second == FLAG_NONE) || ((data & second) != 0U))
{
status = I2C_OK;
break;
}
}
if((data & error) != 0U)
{
mem_write32((uintptr_t)I2C5_ICMSR, ~error);
status = I2C_NG;
break;
}
}
return status;
}
/* End of function i2c5_err_check(uint32_t first, uint32_t second, uint32_t error) */
void i2c5_release(void)
{
mem_write32((uintptr_t)I2C5_ICCCR2, 0x00000000U);
mem_write32((uintptr_t)I2C5_ICCCR, 0x00000000U);
mem_write32((uintptr_t)I2C5_ICSCR, 0x00000000U);
mem_write32((uintptr_t)I2C5_ICSSR, 0x00000000U);
mem_write32((uintptr_t)I2C5_ICSIER, 0x00000000U);
mem_write32((uintptr_t)I2C5_ICSAR, 0x00000000U);
mem_write32((uintptr_t)I2C5_ICMCR, 0x00000000U);
mem_write32((uintptr_t)I2C5_ICMSR, 0x00000000U);
mem_write32((uintptr_t)I2C5_ICMIER, 0x00000000U);
mem_write32((uintptr_t)I2C5_ICMAR, 0x00000000U);
}
/* End of function i2c5_release(void) */
static uint32_t cur_page = 0x00;
static inline void i2c5_page_change(uint32_t slaveAdd, uint32_t new_page) {
if (cur_page != new_page) {
__i2c5_write(slaveAdd, 0x00, new_page);
__i2c5_write(slaveAdd, 0x00, new_page);
__i2c5_read(slaveAdd, 0x00, &cur_page);
if (cur_page != new_page) {
ERROR("I2C5: page change error (0x%x:0x%x)\n", cur_page, new_page);
panic;
}
}
}
void i2c5_write(uint32_t slaveAdd, uint32_t regAdd, uint32_t revData) {
i2c5_page_change(slaveAdd, (regAdd & 0xFF00) >> 8);
__i2c5_write(slaveAdd, regAdd & 0xFF, revData);
}
void i2c5_read(uint32_t slaveAdd, uint32_t regAdd, uint32_t *revData) {
i2c5_page_change(slaveAdd, (regAdd & 0xFF00) >> 8);
__i2c5_read(slaveAdd, regAdd & 0xFF, revData);
}

View File

@@ -0,0 +1,122 @@
/*******************************************************************************
* 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 2021-2023 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : IP's control function
******************************************************************************/
/******************************************************************************
* @file ip_control.c
* - Version : 0.08
* @brief Initial setting controller.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 28.07.2021 0.01 First Release
* : 30.09.2021 0.02 Support of eMMC boot.
* : 15.10.2021 0.03 modify include of flash /eMMC.
* : 03.12.2021 0.04 CA IPL boot support (workaround)
* : 06.01.2022 0.05 Add exception handling for ICUMX_WDTA.
* : 02.02.2022 0.06 Add MFIS Lock/Unlock.
* : 23.05.2022 0.07 Integration of S4 and V4H
* : 23.08.2023 0.08 Add support for V4M.
* : 13.10.2023 0.09 Add calling of sysc_c4_power_on function.
*****************************************************************************/
#include <cpg.h>
#include <scif.h>
#include <emmc_boot.h>
#if (RCAR_SA9_TYPE == FLASH_BOOT)
#include <dma.h>
#include <rpc.h>
#include <mfis.h>
#elif (RCAR_SA9_TYPE == EMMC_BOOT)
#include <emmc_def.h>
#else
/* no process */
#endif
#include <i2c.h>
#include <wdt.h>
#include <vect_set.h>
#include <ip_control.h>
#if ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
#include <fcpr.h>
#endif
#if (RCAR_LSI == RCAR_V4M)
#include <sysc.h>
#endif
void ip_init(void)
{
scif_init();
set_vect_table();
wdt_init();
cpg_init();
#if (RCAR_SA9_TYPE == FLASH_BOOT)
dma_init();
rpc_init();
mfis_init();
#if (CA_LOAD_TYPE == CA_IPL)
emmc_initialize(); /* workaround */
#endif /* (CA_LOAD_TYPE == CA_IPL) */
#elif (RCAR_SA9_TYPE == EMMC_BOOT) /* (RCAR_SA9_TYPE == FLASH_BOOT) */
emmc_initialize();
#else /* (RCAR_SA9_TYPE == FLASH_BOOT) */
/* No process */
#endif /* (RCAR_SA9_TYPE == FLASH_BOOT) */
#if ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
fcpr_init();
#endif /* ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M)) */
#if (RCAR_LSI == RCAR_V4M)
/*
* For accessing Region ID registers by ICUMX,
* and starting Cortex-A76 by CR52 2nd IPL.
*/
sysc_c4_power_on();
#endif /* RCAR_LSI == RCAR_V4M */
#if (SAN_ENABLE == 1)
i2c5_init();
#endif
}
/* End of function ip_init(void) */
void ip_release(void)
{
#if (SAN_ENABLE == 1)
i2c5_release();
#endif
#if (RCAR_SA9_TYPE == FLASH_BOOT)
rpc_release();
dma_release();
#elif (RCAR_SA9_TYPE == EMMC_BOOT)
emmc_terminate();
#else
/* No process */
#endif
wdt_restart();
}
/* End of function ip_release(void) */

View File

@@ -0,0 +1,82 @@
/*******************************************************************************
* 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 2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : MFIS driver
******************************************************************************/
/******************************************************************************
* @file mfis.c
* - Version : 0.01
* @brief Initial setting process of MFIS.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 02.04.2022 0.01 First Release
*****************************************************************************/
#include <stdint.h>
#include <mem_io.h>
#include <micro_wait.h>
#include <mfis.h>
#include <mfis_register.h>
#define MFIS_CODE_VALID (0xACCE0000U)
#define MFISWPCNTR_ENABLE (0U) /* 1' b0: Enable write protection */
#define MFISLCKR_LCK_BIT ((uint32_t)1U << 0U)
#define MFISLCKR_UNLOCK (0U)
void mfis_init(void)
{
/* Write Protection Control Register */
/* Enable write protection setting */
mem_write32(MFIS_WPCNTR, (uint32_t)(MFIS_CODE_VALID + MFISWPCNTR_ENABLE));
/* IPL considers the situation that mutex of MFIS is not released, release it. */
mfis_unlock();
}
/* End of function mfis_init(void) */
void mfis_lock(void)
{
/* MFIS Lock Register [j] (MFISLCKR[j]) */
/* bit in LCK != 0? */
while((mem_read32(MFIS_LCKR) & MFISLCKR_LCK_BIT) != MFISLCKR_UNLOCK)
{
micro_wait(10U); /* 10us */
}
/* this bit is automatically set to "1" */
}
/* End of function mfis_lock(void) */
void mfis_unlock(void)
{
/* Write Access Control Register */
/* MFISLCKR[j] Register address setting */
mem_write32(MFIS_WACNTR, (uint32_t)(MFIS_CODE_VALID + MFISLCKR_ADDRESS));
/* MFIS Lock Register [j] (MFISLCKR[j]) */
mem_write32(MFIS_LCKR, (uint32_t)MFISLCKR_UNLOCK);
}
/* End of function mfis_unlock(void) */

View File

@@ -0,0 +1,413 @@
/*******************************************************************************
* 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 2021-2023 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : QoS initialize function
******************************************************************************/
/******************************************************************************
* @file qos.c
* - Version : 0.04
* @brief Initial setting process of QoS.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 28.07.2021 0.01 First Release
* : 23.05.2022 0.02 Integration of S4 and V4H
* Update QoS setting rev.0.02 (for S4)
* Update QoS setting rev.0.03 (for V4H)
* : 20.01.2023 0.03 Add DBSC W/A 1,2,3 (OTLINT-5579)
* : 21.08.2023 0.04 Add support for V4M.
*****************************************************************************/
#include <stdint.h>
#if defined(__RH850G3K__)
#include <log.h>
#include <remap_register.h>
#include <remap.h>
#else
#include <debug.h>
#endif
#include <qos.h>
#include <mem_io.h>
#include <cnf_tbl.h>
#if (RCAR_LSI == RCAR_S4)
#define RCAR_QOS_VERSION "base_v6.1"
#elif ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
#define RCAR_QOS_VERSION "base_v6.1"
#endif /* RCAR_LSI == RCAR_S4 */
#define RCAR_DRAM_SPLIT_DISABLE (0U)
#define RCAR_DRAM_SPLIT_ENABLE (1U)
#define RCAR_REWT_TRAINING_DISABLE (0U)
#define RCAR_REWT_TRAINING_ENABLE (1U)
#if defined(__RH850G3K__)
#define AXMM_BASE (BASE_AXMM_ADDR)
#else
#define AXMM_BASE (0xE6780000U)
#endif
#define AXMM_MMCR (AXMM_BASE + 0x4300U)
#define AXMM_ADSPLCR0 (AXMM_BASE + 0x4008U)
#define AXMM_ADSPLCR1 (AXMM_BASE + 0x400CU)
#define AXMM_ADSPLCR2 (AXMM_BASE + 0x4010U)
#define AXMM_ADSPLCR3 (AXMM_BASE + 0x4014U)
#if (RCAR_LSI == RCAR_S4)
#if defined(__RH850G3K__)
#define DBSC_BASE (BASE_DBSC_ADDR)
#else
#define DBSC_BASE (0xE6790000U)
#endif
#define DBSC_CH_NUM (1U) /* Number of DBSCx */
#define DBSC_A_CH_OFFSET (0U) /* 1ch only (for S4)*/
#define DBSC_D_CH_OFFSET (0U) /* 1ch only (for S4)*/
#define DBSC_SYSCNT0 (DBSC_BASE + 0x0100U)
#define DBSC_SYSCNT0A (DBSC_BASE + 0x0108U)
#define DBSC_DBBUS0CNF2 (DBSC_BASE + 0x0808U)
#define DBSC_DBCAM0CNF1 (DBSC_BASE + 0x0904U)
#define DBSC_DBCAM0CNF2 (DBSC_BASE + 0x0908U)
#define DBSC_DBCAM0CNF3 (DBSC_BASE + 0x090CU)
#define DBSC_DBCAMDIS (DBSC_BASE + 0x09FCU)
#define DBSC_DBSCHCNT0 (DBSC_BASE + 0x1000U)
#define DBSC_DBSCHSZ0 (DBSC_BASE + 0x1010U)
#define DBSC_DBSCHRW0 (DBSC_BASE + 0x1020U)
#define DBSC_DBSCHQOS_0_0 (DBSC_BASE + 0x1030U)
#define DBSC_DBSCHQOS_0_1 (DBSC_BASE + 0x1034U)
#define DBSC_DBSCHQOS_0_2 (DBSC_BASE + 0x1038U)
#define DBSC_DBSCHQOS_0_3 (DBSC_BASE + 0x103CU)
#define DBSC_DBSCHQOS_4_0 (DBSC_BASE + 0x1070U)
#define DBSC_DBSCHQOS_4_1 (DBSC_BASE + 0x1074U)
#define DBSC_DBSCHQOS_4_2 (DBSC_BASE + 0x1078U)
#define DBSC_DBSCHQOS_4_3 (DBSC_BASE + 0x107CU)
#define DBSC_DBSCHQOS_9_0 (DBSC_BASE + 0x10C0U)
#define DBSC_DBSCHQOS_9_1 (DBSC_BASE + 0x10C4U)
#define DBSC_DBSCHQOS_9_2 (DBSC_BASE + 0x10C8U)
#define DBSC_DBSCHQOS_9_3 (DBSC_BASE + 0x10CCU)
#define DBSC_DBSCHQOS_12_0 (DBSC_BASE + 0x10F0U)
#define DBSC_DBSCHQOS_12_1 (DBSC_BASE + 0x10F4U)
#define DBSC_DBSCHQOS_12_2 (DBSC_BASE + 0x10F8U)
#define DBSC_DBSCHQOS_12_3 (DBSC_BASE + 0x10FCU)
#define DBSC_DBSCHQOS_13_0 (DBSC_BASE + 0x1100U)
#define DBSC_DBSCHQOS_13_1 (DBSC_BASE + 0x1104U)
#define DBSC_DBSCHQOS_13_2 (DBSC_BASE + 0x1108U)
#define DBSC_DBSCHQOS_13_3 (DBSC_BASE + 0x110CU)
#define DBSC_DBSCHQOS_14_0 (DBSC_BASE + 0x1110U)
#define DBSC_DBSCHQOS_14_1 (DBSC_BASE + 0x1114U)
#define DBSC_DBSCHQOS_14_2 (DBSC_BASE + 0x1118U)
#define DBSC_DBSCHQOS_14_3 (DBSC_BASE + 0x111CU)
#define DBSC_DBSCHQOS_15_0 (DBSC_BASE + 0x1120U)
#define DBSC_DBSCHQOS_15_1 (DBSC_BASE + 0x1124U)
#define DBSC_DBSCHQOS_15_2 (DBSC_BASE + 0x1128U)
#define DBSC_DBSCHQOS_15_3 (DBSC_BASE + 0x112CU)
#define DBSC_SCFCTST2 (DBSC_BASE + 0x170CU)
#elif ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
#if defined(__RH850G3K__)
#define DBSC_D_BASE (BASE_DBSC_ADDR + 0x14000U)
#define DBSC_A_BASE (BASE_DBSC_ADDR)
#else
#define DBSC_D_BASE (0xE67A4000U)
#define DBSC_A_BASE (0xE6790000U)
#endif
#define DBSC_CH_NUM (2U) /* ch number of DBSCx */
#define DBSC_A_CH_OFFSET (0x8000U)
#define DBSC_D_CH_OFFSET (0x4000U)
#define DBSC_SYSCNT0 (DBSC_D_BASE + 0x0100U)
#define DBSC_SYSCNT0A (DBSC_A_BASE + 0x0100U)
#define DBSC_DBBUS0CNF2 (DBSC_A_BASE + 0x0808U)
#define DBSC_DBCAM0CNF1 (DBSC_A_BASE + 0x0904U)
#define DBSC_DBCAM0CNF2 (DBSC_A_BASE + 0x0908U)
#define DBSC_DBCAMDIS (DBSC_A_BASE + 0x09FCU)
#define DBSC_DBCAM0CNF3 (DBSC_A_BASE + 0x090CU)
#define DBSC_DBSCHCNT0 (DBSC_A_BASE + 0x1000U)
#define DBSC_DBSCHSZ0 (DBSC_A_BASE + 0x1010U)
#define DBSC_DBSCHRW0 (DBSC_A_BASE + 0x1020U)
#define DBSC_DBSCHQOS_0_0 (DBSC_A_BASE + 0x1100U)
#define DBSC_DBSCHQOS_0_1 (DBSC_A_BASE + 0x1104U)
#define DBSC_DBSCHQOS_0_2 (DBSC_A_BASE + 0x1108U)
#define DBSC_DBSCHQOS_0_3 (DBSC_A_BASE + 0x110CU)
#define DBSC_DBSCHQOS_4_0 (DBSC_A_BASE + 0x1140U)
#define DBSC_DBSCHQOS_4_1 (DBSC_A_BASE + 0x1144U)
#define DBSC_DBSCHQOS_4_2 (DBSC_A_BASE + 0x1148U)
#define DBSC_DBSCHQOS_4_3 (DBSC_A_BASE + 0x114CU)
#define DBSC_DBSCHQOS_9_0 (DBSC_A_BASE + 0x1190U)
#define DBSC_DBSCHQOS_9_1 (DBSC_A_BASE + 0x1194U)
#define DBSC_DBSCHQOS_9_2 (DBSC_A_BASE + 0x1198U)
#define DBSC_DBSCHQOS_9_3 (DBSC_A_BASE + 0x119CU)
#define DBSC_DBSCHQOS_12_0 (DBSC_A_BASE + 0x11C0U)
#define DBSC_DBSCHQOS_12_1 (DBSC_A_BASE + 0x11C4U)
#define DBSC_DBSCHQOS_12_2 (DBSC_A_BASE + 0x11C8U)
#define DBSC_DBSCHQOS_12_3 (DBSC_A_BASE + 0x11CCU)
#define DBSC_DBSCHQOS_13_0 (DBSC_A_BASE + 0x11D0U)
#define DBSC_DBSCHQOS_13_1 (DBSC_A_BASE + 0x11D4U)
#define DBSC_DBSCHQOS_13_2 (DBSC_A_BASE + 0x11D8U)
#define DBSC_DBSCHQOS_13_3 (DBSC_A_BASE + 0x11DCU)
#define DBSC_DBSCHQOS_14_0 (DBSC_A_BASE + 0x11E0U)
#define DBSC_DBSCHQOS_14_1 (DBSC_A_BASE + 0x11E4U)
#define DBSC_DBSCHQOS_14_2 (DBSC_A_BASE + 0x11E8U)
#define DBSC_DBSCHQOS_14_3 (DBSC_A_BASE + 0x11ECU)
#define DBSC_DBSCHQOS_15_0 (DBSC_A_BASE + 0x11F0U)
#define DBSC_DBSCHQOS_15_1 (DBSC_A_BASE + 0x11F4U)
#define DBSC_DBSCHQOS_15_2 (DBSC_A_BASE + 0x11F8U)
#define DBSC_DBSCHQOS_15_3 (DBSC_A_BASE + 0x11FCU)
#define DBSC_SCFCTST2 (DBSC_A_BASE + 0x1048U)
#endif /* RCAR_LSI == RCAR_S4 */
#if defined(__RH850G3K__)
#define QOS_BASE (BASE_QOS_ADDR)
#else
#define QOS_BASE (0xE67E0000U)
#endif
#define QOS_FIX_QOS_BANK0 (QOS_BASE + 0x00000000U)
#define QOS_FIX_QOS_BANK1 (QOS_BASE + 0x00001000U)
#define QOS_BE_QOS_BANK0 (QOS_BASE + 0x00002000U)
#define QOS_BE_QOS_BANK1 (QOS_BASE + 0x00003000U)
#define QOS_SL_INIT (QOS_BASE + 0x00008000U)
#define QOS_REF_ARS (QOS_BASE + 0x00008004U)
#define QOS_STATQC (QOS_BASE + 0x00008008U)
#define QOS_REF_ENBL (QOS_BASE + 0x00008044U)
#define QOS_BWG (QOS_BASE + 0x0000804CU)
#if RCAR_PERIODIC_WRITE_TRAINING != RCAR_REWT_TRAINING_DISABLE
#define QOSWT_FIX_QOS_BANK0 (QOS_BASE + 0x00000800U)
#define QOSWT_FIX_QOS_BANK1 (QOS_BASE + 0x00001800U)
#define QOSWT_BE_QOS_BANK0 (QOS_BASE + 0x00002800U)
#define QOSWT_BE_QOS_BANK1 (QOS_BASE + 0x00003800U)
#define QOSWT_WTEN (QOS_BASE + 0x00008030U)
#define QOSWT_WTREF (QOS_BASE + 0x00008034U)
#define QOSWT_WTSET0 (QOS_BASE + 0x00008038U)
#define QOSWT_WTSET1 (QOS_BASE + 0x0000803CU)
#endif /* RCAR_PERIODIC_WRITE_TRAINING != RCAR_REWT_TRAINING_DISABLE */
#define QOS_RAS (QOS_BASE + 0x00010000U)
#define QOS_RAEN (QOS_BASE + 0x00010018U)
#define QOS_DANN_LOW (QOS_BASE + 0x00010030U)
#define QOS_DANN_HIGH (QOS_BASE + 0x00010034U)
#define QOS_DANT (QOS_BASE + 0x00010038U)
#define QOS_EMS_LOW (QOS_BASE + 0x00010040U)
#define QOS_EMS_HIGH (QOS_BASE + 0x00010044U)
#define QOS_FSS (QOS_BASE + 0x00010048U)
#define QOS_INSFC (QOS_BASE + 0x00010050U)
#define QOS_EARLYR (QOS_BASE + 0x00010060U)
#define QOS_RACNT0 (QOS_BASE + 0x00010080U)
#define QOS_STATGEN0 (QOS_BASE + 0x00010088U)
#define CCI_BASE (BASE_CCI_ADDR)
#define CCIQOS00 (CCI_BASE + 0xC020U)
#define CCIQOS01 (CCI_BASE + 0xC024U)
#define CCIQOS10 (CCI_BASE + 0xD000U)
#define CCIQOS11 (CCI_BASE + 0xD004U)
#if (RCAR_LSI == RCAR_S4)
#define CCIQOS12 (CCI_BASE + 0xD008U)
#define CCIQOS13 (CCI_BASE + 0xD00CU)
#endif
static void dbsc_setting(void)
{
for(uint32_t loop = 0; loop < DBSC_CH_NUM; loop++)
{
/* DBSC CAM, Scheduling Setting */
mem_write32((DBSC_SYSCNT0 + (DBSC_D_CH_OFFSET * loop)), 0x00001234U);
mem_write32((DBSC_SYSCNT0A + (DBSC_A_CH_OFFSET * loop)), 0x00001234U);
mem_write32((DBSC_DBCAM0CNF1 + (DBSC_A_CH_OFFSET * loop)), 0x00104214U); /* dbcam0cnf1 */
mem_write32((DBSC_DBCAM0CNF2 + (DBSC_A_CH_OFFSET * loop)), 0x000001C4U); /* dbcam0cnf2 */
mem_write32((DBSC_DBCAM0CNF3 + (DBSC_A_CH_OFFSET * loop)), 0x00000003U); /* dbcam0cnf3 */
#if (RCAR_LSI == RCAR_S4)
#if (WA_OTLINT5579 == 1 && ECC_ENABLE == 1)
mem_write32((DBSC_DBCAMDIS + (DBSC_A_CH_OFFSET * loop)), 0x00000002U); /* OTLINT-5579: V4H DBSC W/A-1,2 */
#else
mem_write32((DBSC_DBCAMDIS + (DBSC_A_CH_OFFSET * loop)), 0x00000000U);
#endif
#elif ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
#if (WA_OTLINT5579 == 1 && ECC_ENABLE == 1)
mem_write32((DBSC_DBCAMDIS + (DBSC_A_CH_OFFSET * loop)), 0x00000013U); /* OTLINT-5579: V4H DBSC W/A-1,2,3 */
#elif (WA_OTLINT5579 == 1 && ECC_ENABLE == 0)
mem_write32((DBSC_DBCAMDIS + (DBSC_A_CH_OFFSET * loop)), 0x00000011U); /* OTLINT-5579: V4H DBSC W/A-3 */
#else
mem_write32((DBSC_DBCAMDIS + (DBSC_A_CH_OFFSET * loop)), 0x00000010U);
#endif
#endif
mem_write32((DBSC_DBSCHCNT0 + (DBSC_A_CH_OFFSET * loop)), 0x000F0037U); /* dbschcnt0 */
mem_write32((DBSC_DBSCHSZ0 + (DBSC_A_CH_OFFSET * loop)), 0x00000001U); /* dbschsz0 */
mem_write32((DBSC_DBSCHRW0 + (DBSC_A_CH_OFFSET * loop)), 0xF7311111U); /* dbschrw0 */
mem_write32((DBSC_SCFCTST2 + (DBSC_A_CH_OFFSET * loop)), 0x111F1FFFU);
#if (((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M)) && WA_OTLINT5579 == 1)
mem_write32((DBSC_DBBUS0CNF2 + (DBSC_A_CH_OFFSET * loop)), 0x00000007U); /* OTLINT-5579: V4H DBSC WA3 */
#else
mem_write32((DBSC_DBBUS0CNF2 + (DBSC_A_CH_OFFSET * loop)), 0x00000003U); /* S4, V4H w/o DBSC WA3 */
#endif
/* DBSC QoS Setting */
mem_write32((DBSC_DBSCHQOS_0_0 + (DBSC_A_CH_OFFSET * loop)), 0x0000FFFFU);
mem_write32((DBSC_DBSCHQOS_0_1 + (DBSC_A_CH_OFFSET * loop)), 0x00000480U);
mem_write32((DBSC_DBSCHQOS_0_2 + (DBSC_A_CH_OFFSET * loop)), 0x00000300U);
mem_write32((DBSC_DBSCHQOS_0_3 + (DBSC_A_CH_OFFSET * loop)), 0x00000180U);
mem_write32((DBSC_DBSCHQOS_4_0 + (DBSC_A_CH_OFFSET * loop)), 0x00000600U);
mem_write32((DBSC_DBSCHQOS_4_1 + (DBSC_A_CH_OFFSET * loop)), 0x00000480U);
mem_write32((DBSC_DBSCHQOS_4_2 + (DBSC_A_CH_OFFSET * loop)), 0x00000300U);
mem_write32((DBSC_DBSCHQOS_4_3 + (DBSC_A_CH_OFFSET * loop)), 0x00000180U);
mem_write32((DBSC_DBSCHQOS_9_0 + (DBSC_A_CH_OFFSET * loop)), 0x00000400U);
mem_write32((DBSC_DBSCHQOS_9_1 + (DBSC_A_CH_OFFSET * loop)), 0x00000300U);
mem_write32((DBSC_DBSCHQOS_9_2 + (DBSC_A_CH_OFFSET * loop)), 0x00000200U);
mem_write32((DBSC_DBSCHQOS_9_3 + (DBSC_A_CH_OFFSET * loop)), 0x00000100U);
mem_write32((DBSC_DBSCHQOS_12_0 + (DBSC_A_CH_OFFSET * loop)), 0x00000040U);
mem_write32((DBSC_DBSCHQOS_12_1 + (DBSC_A_CH_OFFSET * loop)), 0x00000030U);
mem_write32((DBSC_DBSCHQOS_12_2 + (DBSC_A_CH_OFFSET * loop)), 0x00000020U);
mem_write32((DBSC_DBSCHQOS_12_3 + (DBSC_A_CH_OFFSET * loop)), 0x00000010U);
mem_write32((DBSC_DBSCHQOS_13_0 + (DBSC_A_CH_OFFSET * loop)), 0x00000300U);
mem_write32((DBSC_DBSCHQOS_13_1 + (DBSC_A_CH_OFFSET * loop)), 0x00000240U);
mem_write32((DBSC_DBSCHQOS_13_2 + (DBSC_A_CH_OFFSET * loop)), 0x00000180U);
mem_write32((DBSC_DBSCHQOS_13_3 + (DBSC_A_CH_OFFSET * loop)), 0x000000C0U);
mem_write32((DBSC_DBSCHQOS_14_0 + (DBSC_A_CH_OFFSET * loop)), 0x00000200U);
mem_write32((DBSC_DBSCHQOS_14_1 + (DBSC_A_CH_OFFSET * loop)), 0x00000180U);
mem_write32((DBSC_DBSCHQOS_14_2 + (DBSC_A_CH_OFFSET * loop)), 0x00000100U);
mem_write32((DBSC_DBSCHQOS_14_3 + (DBSC_A_CH_OFFSET * loop)), 0x00000080U);
mem_write32((DBSC_DBSCHQOS_15_0 + (DBSC_A_CH_OFFSET * loop)), 0x00000100U);
mem_write32((DBSC_DBSCHQOS_15_1 + (DBSC_A_CH_OFFSET * loop)), 0x000000C0U);
mem_write32((DBSC_DBSCHQOS_15_2 + (DBSC_A_CH_OFFSET * loop)), 0x00000080U);
mem_write32((DBSC_DBSCHQOS_15_3 + (DBSC_A_CH_OFFSET * loop)), 0x00000040U);
mem_write32((DBSC_SYSCNT0 + (DBSC_D_CH_OFFSET * loop)), 0x00000000U);
mem_write32((DBSC_SYSCNT0A + (DBSC_A_CH_OFFSET * loop)), 0x00000000U);
}
}
/* End of function dbsc_setting(void) */
void qos_init(void)
{
uint32_t i;
/* Setting the register of DBSC4 for QoS initialize */
dbsc_setting();
NOTICE("QoS setting(%s)\n", RCAR_QOS_VERSION);
NOTICE("DRAM refresh interval 1.91 usec\n");
#if RCAR_PERIODIC_WRITE_TRAINING != RCAR_REWT_TRAINING_DISABLE
NOTICE("Periodic Write DQ Training\n");
#endif /* RCAR_PERIODIC_WRITE_TRAINING != RCAR_REWT_TRAINING_DISABLE */
#if (RCAR_LSI == RCAR_S4)
/* Resource Alloc setting */
mem_write32(QOS_RAS, 0x00000028U);
mem_write32(QOS_DANN_LOW, 0x02020201U);
mem_write32(QOS_DANN_HIGH, 0x04040200U);
mem_write32(QOS_DANT, 0x00181004U);
mem_write32(QOS_EMS_LOW, 0x00000000U);
mem_write32(QOS_EMS_HIGH, 0x00000000U);
mem_write32(QOS_FSS, 0x0000000AU);
mem_write32(QOS_INSFC, 0x030F0001U);
mem_write32(QOS_EARLYR, 0x00000000U);
mem_write32(QOS_RACNT0, 0x00050003U);
mem_write32(QOS_STATGEN0, 0x00000000U);
/* QoS MSTAT setting */
mem_write32(QOS_SL_INIT, 0x00050100U);
mem_write32(QOS_REF_ARS, 0x00FB0000U);
mem_write32(QOS_REF_ENBL, 0x00000012U);
mem_write32(QOS_BWG, 0x00000002U);
mem_write32(AXMM_MMCR, 0x00010000U);
mem_write32(CCIQOS00, 0x08000000);
mem_write32(CCIQOS01, 0x08000000);
mem_write32(CCIQOS10, 0x00000001);
mem_write32(CCIQOS11, 0x00000001);
mem_write32(CCIQOS12, 0x00000001);
mem_write32(CCIQOS13, 0x00000001);
#elif ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
#if (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_ENABLE)
/* Address Split 2ch */
mem_write32(AXMM_ADSPLCR0, 0x00000000U);
mem_write32(AXMM_ADSPLCR1, 0x00FF1B0CU);
mem_write32(AXMM_ADSPLCR2, 0x00000000U);
mem_write32(AXMM_ADSPLCR3, 0x00000000U);
#endif
mem_write32(CCIQOS00, 0x08000000);
mem_write32(CCIQOS01, 0x08000000);
mem_write32(CCIQOS10, 0x00000000);
mem_write32(CCIQOS11, 0x00000000);
/* Resource Alloc setting */
mem_write32(QOS_RAS, 0x00000040U);
mem_write32(QOS_DANN_LOW, 0x02020201U);
mem_write32(QOS_DANN_HIGH, 0x04040200U);
mem_write32(QOS_DANT, 0x00181008U);
mem_write32(QOS_EMS_LOW, 0x00000000U);
mem_write32(QOS_EMS_HIGH, 0x00000000U);
mem_write32(QOS_FSS, 0x0000000AU);
mem_write32(QOS_INSFC, 0x030F0001U);
mem_write32(QOS_EARLYR, 0x00000000U);
mem_write32(QOS_RACNT0, 0x00050003U);
mem_write32(QOS_STATGEN0, 0x00000000U);
/* QoS MSTAT setting */
mem_write32(QOS_SL_INIT, 0x00050100U);
mem_write32(QOS_REF_ARS, 0x00FB0000U);
mem_write32(QOS_REF_ENBL, 0x00000012U);
mem_write32(QOS_BWG, 0x00000004U);
#if (((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M)) && WA_OTLINT5579 == 1)
mem_write32(AXMM_MMCR, 0x00000000U); /* OTLINT-5579: V4H DBSC WA3 */
#else
mem_write32(AXMM_MMCR, 0x00010000U);
#endif
#endif /* RCAR_LSI == RCAR_S4 */
for (i = 0U; i < QOS_TBL_MAX; i++)
{
mem_write64((QOS_FIX_QOS_BANK0 + (i * 8U)), g_qosbw_tbl[i].fix);
mem_write64((QOS_FIX_QOS_BANK1 + (i * 8U)), g_qosbw_tbl[i].fix);
mem_write64((QOS_BE_QOS_BANK0 + (i * 8U)), g_qosbw_tbl[i].be);
mem_write64((QOS_BE_QOS_BANK1 + (i * 8U)), g_qosbw_tbl[i].be);
}
#if RCAR_PERIODIC_WRITE_TRAINING != RCAR_REWT_TRAINING_DISABLE
for (i = 0U; i < QOS_TBL_MAX; i++)
{
mem_write64((QOSWT_FIX_QOS_BANK0 + (i * 8U)), g_qoswt_tbl[i].fix);
mem_write64((QOSWT_FIX_QOS_BANK1 + (i * 8U)), g_qoswt_tbl[i].fix);
mem_write64((QOSWT_BE_QOS_BANK0 + (i * 8U)), g_qoswt_tbl[i].be);
mem_write64((QOSWT_BE_QOS_BANK1 + (i * 8U)), g_qoswt_tbl[i].be);
}
#endif /* RCAR_PERIODIC_WRITE_TRAINING != RCAR_REWT_TRAINING_DISABLE */
/* QoS SRAM setting */
mem_write32(QOS_RAEN, 0x00000001U);
#if RCAR_PERIODIC_WRITE_TRAINING != RCAR_REWT_TRAINING_DISABLE
mem_write32(QOSWT_WTREF, 0x02080208U);
mem_write32(QOSWT_WTSET0, 0x14A6050BU);
mem_write32(QOSWT_WTSET1, 0x14A6050BU);
mem_write32(QOSWT_WTEN, 0x00000001U);
#endif /* RCAR_PERIODIC_WRITE_TRAINING != RCAR_REWT_TRAINING_DISABLE */
mem_write32(QOS_STATQC, 0x00000101U);
}
/* End of function qos_init(void) */

View File

@@ -0,0 +1,218 @@
/*******************************************************************************
* 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 2015-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : DMA driver
******************************************************************************/
/******************************************************************************
* @file dma.c
* - Version : 0.05
* @brief RT-DMAC driver.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 15.10.2021 0.01 First Release
* : 10.02.2022 0.02 Add dma_start_xbyte function.
* : 18.03.2022 0.03 Modify to read modify write when write to
* : register.
* : 29.03.2022 0.04 Modify magic number to definition.
* : 09.11.2022 0.05 License notation change.
*****************************************************************************/
#include <stdint.h>
#include <stddef.h>
#include <mem_io.h>
#include <rpc_register.h>
#include <cpg_register.h>
#include <rpc.h>
#include <wdt.h>
#include <log.h>
/*
* from flash_writer's reg_rcar.h
*/
/* RT-DMA Control */
#define RTDMACTL_BASE (BASE_RTDMACTL_ADDR)
#define RTDMAC_RDMOR (RTDMACTL_BASE + 0x0060U) /* R/W 16 DMA operation register (for channels 0 to 15) */
/* RT-DMAC0(for RPC) */
#define RTDMAC_BASE (BASE_RTDMA0_ADDR)
#define RTDMAC_RDMSEC (RTDMAC_BASE + 0x00B0U) /* R/W 32 DMA secure control register (for channels 0 to 15) */
#define RTDMAC_RDMSAR(x) (RTDMAC_BASE + 0x0000U + (0x80U * (x))) /* R/W 32 DMA source address register_0 */
#define RTDMAC_RDMDAR(x) (RTDMAC_BASE + 0x0004U + (0x80U * (x))) /* R/W 32 DMA destination address register_0 */
#define RTDMAC_RDMTCR(x) (RTDMAC_BASE + 0x0008U + (0x80U * (x))) /* R/W 32 DMA transfer count register_0 */
#define RTDMAC_RDMCHCR(x) (RTDMAC_BASE + 0x000CU + (0x80U * (x))) /* R/W 32 DMA channel control register_0 */
#include "dma2.h"
#define RDMOR_INITIAL (0x0301U)
#define DMACH (0U)
#define RDMTCR_CNT_SHIFT (6U)
#define RDMCHCR_TRN_MODE (0x00105409U)
#define RDMCHCR_TRN_MODE_SRC_FIX (0x00104409U)
#define RDMCHCR_TRN_MODE_1BYTE (0x00005401U)
#define RDMCHCR_TE_BIT (0x00000002U)
#define TE_FLAG (0x00000000U)
#define RDMCHCR_CAE_BIT (0x80000000U)
#define RDMCHCR_CAE_BIT_NOERROR (0x00000000U)
#define RDMCHCR_CAIE_BIT (0x40000000U)
#define RDMCHCR_DPM_BIT (0x30000000U)
#define RDMCHCR_RPT_BIT (0x0F000000U)
#define RDMCHCR_WAIT_BIT (0x00800000U)
#define RDMCHCR_DPB_BIT (0x00400000U)
#define RDMCHCR_DSE_BIT (0x00080000U)
#define RDMCHCR_DSIE_BIT (0x00040000U)
#define RDMCHCR_DM_BIT (0x0000C000U)
#define RDMCHCR_SM_BIT (0x00003000U)
#define RDMCHCR_RS_BIT (0x00000F00U)
#define RDMCHCR_TS_BIT (0x00300018U)
#define RDMCHCR_IE_BIT (0x00000004U)
#define RDMCHCR_TE_BIT (0x00000002U)
#define RDMCHCR_DE_BIT (0x00000001U)
#define RDMCHCR_CONF_MASK (RDMCHCR_TS_BIT | RDMCHCR_DM_BIT | RDMCHCR_SM_BIT \
| RDMCHCR_RS_BIT | RDMCHCR_DE_BIT)
#define RDMCHCR_DESCRIPTOR_CONF_MASK (RDMCHCR_DPM_BIT | RDMCHCR_RPT_BIT | RDMCHCR_WAIT_BIT | RDMCHCR_DPB_BIT)
#define RDMCHCR_INTERRUPT_MASK (RDMCHCR_CAIE_BIT | RDMCHCR_DSIE_BIT | RDMCHCR_IE_BIT)
#define RDMCHCR_FLAG_MASK (RDMCHCR_CAE_BIT | RDMCHCR_DSE_BIT | RDMCHCR_TE_BIT)
#define RDMCHCR_ALL_BIT_MASK (RDMCHCR_CONF_MASK | RDMCHCR_DESCRIPTOR_CONF_MASK \
| RDMCHCR_INTERRUPT_MASK | RDMCHCR_FLAG_MASK)
#define CMNSR_TEND (0x00000001U)
#define RDMTCR_UPPER_MASK (0xFF000000U)
/* fraction mask for 64-byte units */
#define FRACTION_MASK_64_BYTE (0x0000003FU)
/* fraction mask for 256-byte units */
#define FRACTION_MASK_256_BYTE (0x000000FFU)
void dma2_init(void)
{
uint32_t reg;
/* DMA transfer disabled */
reg = mem_read32(RTDMAC_RDMCHCR(DMACH));
reg &= ~(RDMCHCR_ALL_BIT_MASK);
mem_write32(RTDMAC_RDMCHCR(DMACH), reg);
/* DMA operation */
mem_write16(RTDMAC_RDMOR, RDMOR_INITIAL);
/* DMA secure control register */
reg = mem_read32(RTDMAC_RDMSEC);
reg |= ((uint32_t)1U << DMACH);
mem_write32(RTDMAC_RDMSEC, reg);
}
/* End of function dma_init */
void dma2_start(uint32_t dst, uint32_t src, uint32_t len, uint32_t mode)
{
uint32_t reg;
if (((dst & FRACTION_MASK_64_BYTE) != 0U) || ((src & FRACTION_MASK_64_BYTE) != 0U))
{
/* dst or src are not 64-bit alignment. */
ERROR("not 64-bit alignment in DMA(2) transfer\n");
while(1)
{
; /* panic */
}
}
/* round up 256 byte alignment */
len += FRACTION_MASK_256_BYTE;
len &= (~(uint32_t)(FRACTION_MASK_256_BYTE));
/* DMA destination address */
mem_write32(RTDMAC_RDMDAR(DMACH), dst);
/* DMA source address */
mem_write32(RTDMAC_RDMSAR(DMACH), src);
/* DMA 64bytes-unit transfer count */
mem_write32(RTDMAC_RDMTCR(DMACH), ((len >> RDMTCR_CNT_SHIFT) & (~RDMTCR_UPPER_MASK)));
/* DMA channel control */
reg = mem_read32(RTDMAC_RDMCHCR(DMACH));
if (mode == DMA_MODE_SRC_FIX)
{
reg |= RDMCHCR_TRN_MODE_SRC_FIX;
mem_write32(RTDMAC_RDMCHCR(DMACH), reg);
}
else
{
reg |= RDMCHCR_TRN_MODE;
mem_write32(RTDMAC_RDMCHCR(DMACH), reg);
}
}
/* End of function dma_start */
void dma2_start_xbyte(uint32_t dst, uint32_t src, uint32_t len, uint32_t trns_unit)
{
uint32_t reg;
/* DMA destination address */
mem_write32(RTDMAC_RDMDAR(DMACH), dst);
/* DMA source address */
mem_write32(RTDMAC_RDMSAR(DMACH), src);
/* DMA transfer count */
mem_write32(RTDMAC_RDMTCR(DMACH), ((len >> trns_unit) & (~RDMTCR_UPPER_MASK)));
/* DMA channel control */
reg = mem_read32(RTDMAC_RDMCHCR(DMACH));
if (trns_unit == TRANS_UNIT_1BYTE)
{
/* DMA channel control (transfer unit is 1 byte)*/
reg |= RDMCHCR_TRN_MODE_1BYTE;
mem_write32(RTDMAC_RDMCHCR(DMACH), reg);
}
if (trns_unit == TRANS_UNIT_64BYTES)
{
/* DMA channel control (transfer unit is 64 bytes) */
reg |= RDMCHCR_TRN_MODE;
mem_write32(RTDMAC_RDMCHCR(DMACH), reg);
}
}
/* End of function dma_start_byte */
void dma2_end(void)
{
uint32_t reg;
/* Check end of DMA transfer. */
do
{
wdt_restart();
/* Check error of DMA transfer */
if ((mem_read32(RTDMAC_RDMCHCR(DMACH)) & RDMCHCR_CAE_BIT) != RDMCHCR_CAE_BIT_NOERROR)
{
ERROR("DMA(2) - Channel Address Error\n");
while(1)
{
; /* panic */
}
}
}
while ((mem_read32(RTDMAC_RDMCHCR(DMACH)) & RDMCHCR_TE_BIT) == TE_FLAG);
/* DMA transfer disabled */
reg = mem_read32(RTDMAC_RDMCHCR(DMACH));
reg &= ~(RDMCHCR_ALL_BIT_MASK);
mem_write32(RTDMAC_RDMCHCR(DMACH), reg);
rpc_end_state_check();
}
/* End of function dma_end */

View File

@@ -0,0 +1,56 @@
/*******************************************************************************
* 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 2015-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : DMA driver header
******************************************************************************/
/******************************************************************************
* @file dma.h
* - Version : 0.03
* @brief DMA driver header
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 16.02.2022 0.01 First Release
* : 01.04.2022 0.02 Add definitions.
* : 09.11.2022 0.03 License notation change.
*****************************************************************************/
#ifndef DMA2_H_
#define DMA2_H_
#define TRANS_UNIT_1BYTE (0x0)
#define TRANS_UNIT_64BYTES (0x6)
#define DMA_MODE_SRC_INC (0x0U)
#define DMA_MODE_SRC_FIX (0x1U)
#define TRANS_SIZE_1BYTE (0x1U)
#define TRANS_SIZE_64BYTE (0x40U)
void dma2_init(void);
void dma2_start(uint32_t dst, uint32_t src, uint32_t len, uint32_t mode);
void dma2_start_xbyte(uint32_t dst, uint32_t src, uint32_t len, uint32_t trns_unit);
void dma2_end(void);
#endif /* DMA2_H_ */

View File

@@ -0,0 +1,367 @@
/*******************************************************************************
* 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 2021-2024 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : RPC driver
******************************************************************************/
/******************************************************************************
* @file rpc.c
* - Version : 0.08
* @brief Initial setting process of RPC.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 28.07.2021 0.01 First Release
* : 03.09.2021 0.02 Add rpc_release function.
* : 27.07.2022 0.03 Add QSPI Flash vendor ID check and QSPI Flash
* : command initialization.
* : 22.08.2022 0.04 Add DDR mode for QSPI Flash.
* : 21.09.2022 0.05 Fix comparison of test data
* : in adjust_strobe_timing function.
* : 12.01.2023 0.06 Add PFC setting to qspi_ddr_transfer_mode()
* : function.
* : 04.04.2023 0.07 Removed stdio.h.
* : 17.06.2024 0.08 Fix PUEN register setting when QSPI DDR mode.
*****************************************************************************/
#include <stdint.h>
#include <stddef.h>
#include <rpc.h>
#include <rpc_register.h>
#include <mem_io.h>
#include <rst_register.h>
#include <image_load_flash.h>
#include <cpg_register.h>
#include <cpg.h>
#include <remap.h>
#include <log.h>
#include <pfc.h>
#include <bit.h>
#include <rpcqspidrv.h>
#define RPC_PHYCNT_DDRCAL ((uint32_t)1U << 19U)
#define RPC_PHYCNT_PHYMEM_SPI_DDR ((uint32_t)1U << 0U)
#define RPC_PHYCNT_PHYMEM_MASK (0x00000003U)
#define RPC_DRCR_RCF ((uint32_t)1U << 9U)
#define RPC_DRCR_SSLN_NEGATE (0x01000000U)
#define RPC_DRCR_RBE_RBURST_MASK (0x001F0000U)
#define RPC_DRCR_RBE_RBURST_1DATA (0x00000000U) /* Smallest data unit (8byte) */
#define RPC_DRCR_RBE_RBURST_32DATA (0x001F0000U) /* biggest data unit (256byte) */
#define RPC_DRCR_RBE_ENABLE (0x00000100U)
#define RPC_DRCMR_CMD_SHIFT (16U)
#define RPC_DRCMR_CMD_MASK ((uint32_t)0xFFU << RPC_DRCMR_CMD_SHIFT)
#define RPC_DRCMR_OCMD_MASK ((uint32_t)0xFFU << 0U)
#define RPC_DRCMR_HW_INIT (0x00030000U)
#define RPC_DREAR_EAV_MASK ((uint32_t)0xFFU << 16U)
#define RPC_DREAR_EAC_MASK ((uint32_t)0x7U << 0U)
#define RPC_DREAR_EAC_EXT_ADDR_25BIT ((uint32_t)0x1U << 0U)
#define RPC_DREAR_HW_INIT (0x00000000U)
#define RPC_DRENR_CDB_MASK (0xC0000000U)
#define RPC_DRENR_CDB_1BIT (0x00000000U)
#define RPC_DRENR_ADB_MASK (0x03000000U)
#define RPC_DRENR_ADB_4BIT (0x02000000U)
#define RPC_DRENR_DRDB_MASK (0x00030000U)
#define RPC_DRENR_DRDB_4BIT (0x00020000U)
#define RPC_DRENR_DME_MASK (0x00008000U)
#define RPC_DRENR_DME_ENABLE (0x00008000U)
#define RPC_DRENR_CDE_ENABLE ((uint32_t)0x1U << 14U)
#define RPC_DRENR_ADE_MASK (0x00000F00U)
#define RPC_DRENR_ADE_32BIT_ADDR ((uint32_t)0xFU << 8U)
#define RPC_DRENR_HW_INIT (0x00004700U)
#define RPC_DRENR_TRANS_DISABLE (0x00000000U)
#define RPC_SMCMR_CMD_SHIFT (16U)
#define RPC_SMCMR_CMD_MASK (0x00FF0000U)
#define RPC_SMCMR_OCMD_MASK (0x000000FFU)
#define RPC_SMDRENR_HYPE_MASK (0x00007000U)
#define RPC_SMDRENR_ADDRE (0x00000100U)
#define RPC_SMDRENR_OPDRE (0x00000010U)
#define RPC_SMDRENR_SPIDRE (0x00000001U)
#define RPC_SMENR_CDB_MASK (0xC0000000U)
#define RPC_SMENR_OCDB_MASK (0x30000000U)
#define RPC_SMENR_ADB_MASK (0x03000000U)
#define RPC_SMENR_OPDB_MASK (0x00300000U)
#define RPC_SMENR_SPIDB_MASK (0x00030000U)
#define RPC_SMENR_DME_EN (0x00008000U)
#define RPC_SMENR_CDE_EN (0x00004000U)
#define RPC_SMENR_OCDE_EN (0x00001000U)
#define RPC_SMENR_ADE_MASK (0x00000F00U)
#define RPC_SMENR_OPDE_MASK (0x000000F0U)
#define RPC_SMENR_SPIDE_MASK (0x0000000FU)
#define RPC_SMENR_SPIDE_SPI_32 (0x0000000FU)
#define RPC_SMCR_SSLKP (0x00000100U)
#define RPC_SMCR_SPIRE (0x00000004U)
#define RPC_SMCR_SPIWE (0x00000002U)
#define RPC_SMCR_SPIE (0x00000001U)
#define RPC_CMNCR_MD (0x80000000U) /* bit[31]:Operating Mode Switch -> Manual mode */
#define RPC_CMNCR_MOIIO_MASK (0x00FF0000U)
#define RPC_CMNCR_MOIIO3_HI_Z (0x00C00000U)
#define RPC_CMNCR_MOIIO2_HI_Z (0x00300000U)
#define RPC_CMNCR_MOIIO1_HI_Z (0x000C0000U)
#define RPC_CMNCR_MOIIO0_HI_Z (0x00030000U)
#define RPC_CMNCR_BSZ_MASK (0x00000003U)
#define RPC_DRDRENR_DRDRE (0x00000001U)
#define RPC_DRDRENR_ADDRE (0x00000100U)
#define RPC_PHYOFFSET1_DDRTMG_MSK (0x30000000U)
#define RPC_PHYOFFSET1_DDRTMG_DDR (0x20000000U)
#define STRTIM_SMALLEST (0x0000000FU)
#define STRTIM_MASK_3 (0x00000008U)
#define STRTIM_MASK (0x00000007U)
#define STRTIM_MATCH_ERROR (0xFFFFFFFFU)
/* For PFC register */
#define PFC_PUEN3_QSPI0_IO3 (0x00010000U) /* bit16 */
#define PFC_PUEN3_QSPI0_IO2 (0x00020000U) /* bit17 */
/* verification data for strobe timing adjustment */
#define QSPI_TESTDATA (0x5A5AA5A5U)
#define QSPI_TESTDATA_OFFSET (0x00000400U)
#define QSPI_TESTDATA_FLASH_ADDR (FLASH_CONTENT_CERT_ADDR + QSPI_TESTDATA_OFFSET) /* Offset 0x00240400 */
static inline void set_strtim(uint32_t strobe_timing);
#if (QSPI_DDR_MODE==1)
static void adjust_strobe_timing(void);
#endif
#if (QSPI_DDR_MODE==0)
void qspi_sdr_transfer_mode(uint32_t command)
{
uint32_t reg;
/* check the transfer end flag */
rpc_end_state_check();
/* For the initial setting flow of RPC, see Figure 112.12 in */
/* "R-Car Series, S4 Series User's Manual" and */
/* "R-Car Series, V4H Series User's Manual". */
/* This RPC setting is for S25FS512S device */
/* A register that does not set a value expects */
/* the initial value of HW. */
/* PHY calibration */
set_strtim(STRTIM_SMALLEST);
reg = mem_read32(RPC_PHYCNT);
reg |= RPC_PHYCNT_CAL;
mem_write32(RPC_PHYCNT, reg);
/* External Address Space Read Mode */
reg = mem_read32(RPC_CMNCR);
reg &= ~(RPC_CMNCR_MD);
mem_write32(RPC_CMNCR, reg);
/* Read cache Flash */
reg = mem_read32(RPC_DRCR);
mem_write32(RPC_DRCR, (reg | RPC_DRCR_RCF));
/* 32bit address read command*/
reg = mem_read32(RPC_DRCMR);
reg &= ~(RPC_DRCMR_CMD_MASK | RPC_DRCMR_OCMD_MASK);
reg |= (command << RPC_SMCMR_CMD_SHIFT);
mem_write32(RPC_DRCMR, reg);
/* Extended external address valid range is [25:0]*/
reg = mem_read32(RPC_DREAR);
reg &= ~(RPC_DREAR_EAV_MASK | RPC_DREAR_EAC_MASK);
reg |= RPC_DREAR_EAC_EXT_ADDR_25BIT;
mem_write32(RPC_DREAR, reg);
/* output command is 32bit width */
reg = mem_read32(RPC_DRENR);
reg &= ~(RPC_DRENR_CDE_ENABLE | RPC_DRENR_ADE_MASK);
reg |= (RPC_DRENR_CDE_ENABLE | RPC_DRENR_ADE_32BIT_ADDR);
mem_write32(RPC_DRENR, reg);
}
/* End of function rpc_init(void) */
#else
void qspi_ddr_transfer_mode(uint32_t command)
{
uint32_t reg;
/* check the transfer end flag */
rpc_end_state_check();
cpg_reg_write(CPG_RPCCKCR, CPG_RPCCKCR, RPC_CLK_160MHZ); /* RPCD2 = 80MHz */
/* Disable pull-up/down function of QSPI0_IO2/QSPI0_IO3 when QSPI DDR transfer mode. */
reg = mem_read32(PFC_PUEN3_RW);
reg &= ~(PFC_PUEN3_QSPI0_IO3 | PFC_PUEN3_QSPI0_IO2);
pfc_reg_write(PFC_PUEN3_RW, reg);
/* For the initial setting flow of RPC, see Figure 112.12 in */
/* "R-Car Series, S4 Series User's Manual" and */
/* "R-Car Series, V4H Series User's Manual". */
/* This RPC setting is for S25FS512S device */
/* A register that does not set a value expects */
/* the initial value of HW. */
/* PHY calibration */
set_strtim(STRTIM_SMALLEST);
reg = mem_read32(RPC_PHYCNT);
reg |= RPC_PHYCNT_DDRCAL;
reg |= RPC_PHYCNT_PHYMEM_SPI_DDR;
mem_write32(RPC_PHYCNT, reg);
/* External Address Space Read Mode */
reg = mem_read32(RPC_CMNCR);
reg &= ~(RPC_CMNCR_MD | RPC_CMNCR_MOIIO_MASK | RPC_CMNCR_BSZ_MASK);
reg |= (RPC_CMNCR_MOIIO0_HI_Z | RPC_CMNCR_MOIIO1_HI_Z | RPC_CMNCR_MOIIO2_HI_Z | RPC_CMNCR_MOIIO3_HI_Z);
mem_write32(RPC_CMNCR, reg);
/* Read cache Flash */
reg = mem_read32(RPC_DRCR);
reg &= ~(RPC_DRCR_RBE_RBURST_MASK);
reg |= (RPC_DRCR_SSLN_NEGATE | RPC_DRCR_RBE_RBURST_1DATA | RPC_DRCR_RCF | RPC_DRCR_RBE_ENABLE);
mem_write32(RPC_DRCR, (reg | RPC_DRCR_RCF));
/* 32bit address read command*/
reg = mem_read32(RPC_DRCMR);
reg &= ~(RPC_DRCMR_CMD_MASK | RPC_DRCMR_OCMD_MASK);
reg |= (command << RPC_SMCMR_CMD_SHIFT);
mem_write32(RPC_DRCMR, reg);
/* Extended external address valid range is [25:0]*/
reg = mem_read32(RPC_DREAR);
reg &= ~(RPC_DREAR_EAV_MASK | RPC_DREAR_EAC_MASK);
reg |= RPC_DREAR_EAC_EXT_ADDR_25BIT;
mem_write32(RPC_DREAR, reg);
/* output command is 32bit width */
reg = mem_read32(RPC_DRENR);
reg &= ~(RPC_DRENR_CDB_MASK | RPC_DRENR_ADB_MASK | RPC_DRENR_DRDB_MASK
| RPC_DRENR_DME_MASK | RPC_DRENR_CDE_ENABLE | RPC_DRENR_ADE_MASK);
reg |= (RPC_DRENR_CDB_1BIT | RPC_DRENR_ADB_4BIT | RPC_DRENR_DRDB_4BIT
| RPC_DRENR_DME_ENABLE | RPC_DRENR_CDE_ENABLE | RPC_DRENR_ADE_32BIT_ADDR);
mem_write32(RPC_DRENR, reg);
/* Set Dummy Cycle */
mem_write32(RPC_DRDMCR, (uint32_t)RCAR_QSPI_DDR_DUMMY_CYCLE - 1U);
/* Specifies DDR transfer of the data read. */
reg = mem_read32(RPC_DRDRENR);
reg |= RPC_DRDRENR_DRDRE | RPC_DRDRENR_ADDRE;
mem_write32(RPC_DRDRENR, reg);
/* timing adjustment in DDR read operation. */
reg = mem_read32(RPC_PHYOFFSET1);
reg &= ~(RPC_PHYOFFSET1_DDRTMG_MSK);
reg |= RPC_PHYOFFSET1_DDRTMG_DDR;
mem_write32(RPC_PHYOFFSET1, reg);
/* Change PHYCNT.DDRCAL */
reg = mem_read32(RPC_PHYCNT);
reg |= RPC_PHYCNT_PHYMEM_SPI_DDR;
reg &= ~RPC_PHYCNT_CAL;
reg |= RPC_PHYCNT_DDRCAL;
mem_write32(RPC_PHYCNT, reg);
adjust_strobe_timing();
/* Set data burst length to 256 byte */
reg = mem_read32(RPC_DRCR);
reg |= RPC_DRCR_RBE_RBURST_32DATA;
mem_write32(RPC_DRCR, reg);
}
static void adjust_strobe_timing(void)
{
uint32_t reg;
uint32_t flash_data;
uint32_t remap_flash_addr;
uint32_t strobe_timing = STRTIM_SMALLEST;
uint32_t first_match = STRTIM_MATCH_ERROR;
uint32_t match_count = 0U;
uint32_t loop;
/* Convert verification data to logical addresses. */
remap_register(QSPI_TESTDATA_FLASH_ADDR, &remap_flash_addr);
INFO("Adjust strobe timing\n");
INFO("QSPI_TESTDATA_FLASH_ADDR = 0x%08x\n",remap_flash_addr);
for(loop = 0U; loop <= STRTIM_SMALLEST; loop++)
{
/* RPC Transfer Disable */
mem_write32(RPC_DRENR, RPC_DRENR_TRANS_DISABLE);
/* Read cache Flash */
reg = mem_read32(RPC_DRCR);
mem_write32(RPC_DRCR, (reg | RPC_DRCR_RCF));
/* set strobe timing */
set_strtim(strobe_timing);
/* RPC Transfer Enable */
reg = mem_read32(RPC_DRENR);
reg &= ~(RPC_DRENR_CDB_MASK | RPC_DRENR_ADB_MASK | RPC_DRENR_DRDB_MASK
| RPC_DRENR_DME_MASK | RPC_DRENR_CDE_ENABLE | RPC_DRENR_ADE_MASK);
reg |= (RPC_DRENR_CDB_1BIT | RPC_DRENR_ADB_4BIT | RPC_DRENR_DRDB_4BIT
| RPC_DRENR_DME_ENABLE | RPC_DRENR_CDE_ENABLE | RPC_DRENR_ADE_32BIT_ADDR);
mem_write32(RPC_DRENR, reg);
/* Read verification Data on QSPIFlash */
flash_data = mem_read32(remap_flash_addr);
/* check the transfer end flag */
rpc_end_state_check();
INFO("strobe timing:0x%x\tflash_data:0x%x\ttest_data:0x%x\n", strobe_timing, flash_data, QSPI_TESTDATA);
/* Comparison of Verification Data */
if(flash_data == QSPI_TESTDATA)
{
/* First match of validation data. */
if(first_match == STRTIM_MATCH_ERROR)
{
first_match = strobe_timing;
}
match_count++;
}
else
{
/* If out of timing to match */
if(first_match != STRTIM_MATCH_ERROR)
{
/* Terminate the exploration of Strobe timing. */
break;
}
}
strobe_timing--;
}
/* Verification Data is not matched */
if(first_match == STRTIM_MATCH_ERROR)
{
ERROR("Failed Strobe timing adjustment of DDR transfer mode.\n");
panic;
}
INFO("first_match:0x%x\tmatch_count:0x%x\n", first_match, match_count);
remap_unregister(remap_flash_addr);
/* strobe timing value adjustment */
strobe_timing = first_match - (match_count / 2U);
/* set strobe timing */
set_strtim(strobe_timing);
INFO("RPC_PHYCNT\t = 0x%08x\n",mem_read32(RPC_PHYCNT));
}
#endif
static inline void set_strtim(uint32_t strobe_timing)
{
uint32_t reg;
reg = mem_read32(RPC_PHYCNT);
reg &= ~((STRTIM_MASK_3 << 24U) | (STRTIM_MASK << 15U));
reg |= ((strobe_timing & STRTIM_MASK_3) << 24U); /* bit[27] */
reg |= ((strobe_timing & STRTIM_MASK) << 15U); /* bit[17:15] */
mem_write32(RPC_PHYCNT, reg);
}

View File

@@ -0,0 +1,280 @@
/*******************************************************************************
* 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 2021-2024 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : RPC driver
******************************************************************************/
/******************************************************************************
* @file rpc.c
* - Version : 0.08
* @brief Initial setting process of RPC.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 28.07.2021 0.01 First Release
* : 03.09.2021 0.02 Add rpc_release function.
* : 27.07.2022 0.03 Add QSPI Flash vendor ID check and QSPI Flash
* : command initialization.
* : 22.08.2022 0.04 Add DDR mode for QSPI Flash.
* : 21.09.2022 0.05 Fix comparison of test data
* : in adjust_strobe_timing function.
* : 12.01.2023 0.06 Add PFC setting to qspi_ddr_transfer_mode()
* : function.
* : 04.04.2023 0.07 Removed stdio.h.
* : 17.06.2024 0.08 Fix PUEN register setting when QSPI DDR mode.
*****************************************************************************/
#include <stdint.h>
#include <stddef.h>
#include <remap.h>
#include <mem_io.h>
#include <rst_register.h>
#include <cpg_register.h>
#include <cpg.h>
#include <rpc_register.h>
#include <rpcqspidrv.h>
#include <rpc.h>
#include <image_load_flash.h>
#include <pfc.h>
#include <log.h>
#define RST_MODEMR0_BOOTMODE (0xFU << 1U)
#define BOOTMODE_QSPI_SINGLE_40MHZ (0x4U)
#define BOOTMODE_QSPI_DMA (0x6U)
typedef struct{
uint32_t reg_addr; /* registers address. */
uint32_t value; /* setting value. */
} st_register_table_t;
#define RPC_TBL_MAX (13U)
static st_register_table_t g_rpc_reg_hwinit_val_tbl[RPC_TBL_MAX];
/* The number of Flash vendor */
#if USER_ADDED_QSPI == 0
#define VENDOR_NUM (1U)
#endif /* USER_ADDED_QSPI == 0 */
/* Command for S25FS512S */
#define MT25QU01GB_READ_FAST (0x0CU) /* 4FAST_READ, read_fast */
#define MT25QU01GB_SEC_ER_4BYTE_ADDR (0xDCU) /* 4SE, sector_erase_4byte_addr */
#define MT25QU01GB_PARA_4KBYTE_ER (0x21U) /* 4P4E, parameter_4kbyte_erase */
#define MT25QU01GB_PP_4BYTE_ADDR (0x12U) /* 4PP, pp_4byte_addr */
#define MT25QU01GB_READ_ANY_REG (0x05U) /* READ STATUS, read_any_register */
#define MT25QU01GB_READ_STATUS (0x70U) /* READ FLAG STATUS, read_stts_register */
#define MT25QU01GB_WRITE_ENABLE (0x06U) /* WREN, write_enable */
#define S25FS512S_READ_32BIT_ADDR (0x13U) /* read 32bit address */
#define S25FS512S_DDR_QUAD_IO_READ_32BIT_ADDR (0xEEU) /* DDR quad I/O read 32bit address */
#if USER_ADDED_QSPI == 1
/* User can customize for another vendor's QSPI Flash. */
#define VENDOR_NUM (2U)
/* Command for XXXXXXXXX */
#define XXXXXXXXX_READ_FAST (0x0CU) /* 4-byte read_fast */
#define XXXXXXXXX_SEC_ER_4BYTE_ADDR (0xDCU) /* sector_erase_4byte_addr */
#define XXXXXXXXX_PARA_4KBYTE_ER (0x21U) /* parameter_4kbyte_erase */
#define XXXXXXXXX_PP_4BYTE_ADDR (0x12U) /* page_program_4byte_addr */
#define XXXXXXXXX_READ_ANY_REG (0x05U) /* READ STATUS, read_any_register */
#define XXXXXXXXX_READ_STATUS (0x2BU) /* RDSCUR, read_stts_register */
#define XXXXXXXXX_WRITE_ENABLE (0x06U) /* WREN, write_enable */
#define XXXXXXXXX_READ_32BIT_ADDR (0x13U) /* read 32bit address */
#define XXXXXXXXX_DDR_QUAD_IO_READ_32BIT_ADDR (0xEEU) /* DDR quad I/O read 32bit address */
#endif /* USER_ADDED_QSPI == 1 */
static const st_qspi_cmd_tbl_t qspi_cmd_tbls[VENDOR_NUM] =
{
/* Command table for MT25QU01GB */
{
MT25QU01GB_READ_FAST, /* read_fast */
MT25QU01GB_SEC_ER_4BYTE_ADDR, /* sector_erase_4byte_addr */
MT25QU01GB_PARA_4KBYTE_ER, /* parameter_4kbyte_erase */
MT25QU01GB_PP_4BYTE_ADDR, /* pp_4byte_addr */
MT25QU01GB_READ_ANY_REG, /* read_any_register */
MT25QU01GB_READ_STATUS, /* read_status */
MT25QU01GB_WRITE_ENABLE, /* write_enable */
S25FS512S_READ_32BIT_ADDR, /* read 32bit address */
S25FS512S_DDR_QUAD_IO_READ_32BIT_ADDR /* DDR quad I/O read 32bit address */
},
#if USER_ADDED_QSPI == 1
/* Command table for XXXXXXXXX */
/* User can customize for another vendor's QSPI Flash. */
{
XXXXXXXXX_READ_FAST, /* read_fast */
XXXXXXXXX_SEC_ER_4BYTE_ADDR, /* sector_erase_4byte_addr */
XXXXXXXXX_PARA_4KBYTE_ER, /* parameter_4kbyte_erase */
XXXXXXXXX_PP_4BYTE_ADDR, /* pp_4byte_addr */
XXXXXXXXX_READ_ANY_REG, /* read_any_register */
XXXXXXXXX_READ_STATUS, /* read_status */
XXXXXXXXX_WRITE_ENABLE, /* write_enable */
XXXXXXXXX_READ_32BIT_ADDR, /* read 32bit address */
XXXXXXXXX_DDR_QUAD_IO_READ_32BIT_ADDR /* DDR quad I/O read 32bit address */
}
#endif /* USER_ADDED_QSPI == 1 */
};
static const uint32_t dev_id_index[VENDOR_NUM] =
{
/* QSPI Flash device ID */
DEVID_MT25QU01GB, /* MT25QU01GB */
#if USER_ADDED_QSPI == 1
/* User can customize for another vendor's QSPI Flash. */
DEVID_XXXXXXXXX
#endif /* USER_ADDED_QSPI == 1 */
};
const st_qspi_cmd_tbl_t* gp_qspi_cmd_tbl;
static void rpc_save_hw_init_val(void);
static uint32_t init_qspi_cmd(uint32_t device_id);
void rpc_init(void)
{
/* Save HW initial value of RPC registers */
rpc_save_hw_init_val();
}
void qspi_flash_rw_init(void)
{
uint32_t reg;
uint32_t qspi_flash_id;
uint32_t rtn_val;
static bool qspi_flash_id_checked = false;
if (qspi_flash_id_checked == true)
{
NOTICE("QSPI Flash ID has been checked.\n");
return;
}
qspi_flash_id_checked = true;
/* judge boot device */
reg = (mem_read32(RST_MODEMR0) & RST_MODEMR0_BOOTMODE) >> 1U;
if ((reg == BOOTMODE_QSPI_SINGLE_40MHZ) ||
(reg == BOOTMODE_QSPI_DMA))
{
/* check the transfer end flag */
rpc_end_state_check();
/* Initialize command for QSPI Flash. */
read_qspi_flash_id(&qspi_flash_id);
qspi_flash_id = (qspi_flash_id & DEVICE_ID_MASK);
NOTICE("QSPI Flash ID = 0x%08x\n", qspi_flash_id);
rtn_val = init_qspi_cmd(qspi_flash_id);
if(rtn_val != QSPI_CMD_INIT_SUCCESS)
{
/* unknown QSPI Flash ID */
ERROR("QSPI Flash command initialization error!!\n");
panic;
}
#if (QSPI_DDR_MODE==1)
/* Initialize for QSPI DDR transfer mode */
qspi_ddr_transfer_mode(gp_qspi_cmd_tbl->ddr_quad_io_read_32bit_addr);
#else
/* Initialize for QSPI SDR transfer mode */
qspi_sdr_transfer_mode(gp_qspi_cmd_tbl->read_32bit_addr);
#endif
}
}
/* End of function rpc_init(void) */
void rpc_release(void)
{
uint32_t loop;
/* Set HW initial value to RPC registers */
for(loop = 0; loop < RPC_TBL_MAX; loop++)
{
mem_write32(g_rpc_reg_hwinit_val_tbl[loop].reg_addr, g_rpc_reg_hwinit_val_tbl[loop].value);
}
}
/* End of function rpc_release(void) */
void rpc_end_state_check(void)
{
/* Wait until RPC data transfer is completed */
while ((mem_read32(RPC_CMNSR) & CMNSR_TEND) != 1U)
{
;
}
}
/* End of function rpc_end_state_check(void) */
static void rpc_save_hw_init_val(void)
{
uint32_t loop;
g_rpc_reg_hwinit_val_tbl[0].reg_addr = RPC_CMNCR;
g_rpc_reg_hwinit_val_tbl[1].reg_addr = RPC_DRCR;
g_rpc_reg_hwinit_val_tbl[2].reg_addr = RPC_DRCMR;
g_rpc_reg_hwinit_val_tbl[3].reg_addr = RPC_DREAR;
g_rpc_reg_hwinit_val_tbl[4].reg_addr = RPC_DRENR;
g_rpc_reg_hwinit_val_tbl[5].reg_addr = RPC_SMCR;
g_rpc_reg_hwinit_val_tbl[6].reg_addr = RPC_SMCMR;
g_rpc_reg_hwinit_val_tbl[7].reg_addr = RPC_SMENR;
/* RPC_SMRDR0 is Read only */
/* RPC_CMNSR is Read only */
g_rpc_reg_hwinit_val_tbl[8].reg_addr = RPC_DRDMCR;
g_rpc_reg_hwinit_val_tbl[9].reg_addr = RPC_DRDRENR;
g_rpc_reg_hwinit_val_tbl[10].reg_addr = RPC_SMDRENR;
g_rpc_reg_hwinit_val_tbl[11].reg_addr = RPC_PHYCNT;
g_rpc_reg_hwinit_val_tbl[12].reg_addr = RPC_PHYOFFSET1;
/* Save RPC register initial value */
for(loop = 0; loop < RPC_TBL_MAX; loop++)
{
g_rpc_reg_hwinit_val_tbl[loop].value = mem_read32(g_rpc_reg_hwinit_val_tbl[loop].reg_addr);
}
}
uint8_t prk3_rev = 3;
static uint32_t init_qspi_cmd(uint32_t device_id)
{
uint32_t i = 0U;
uint32_t rtn_val = QSPI_CMD_INIT_ERROR;
gp_qspi_cmd_tbl = NULL;
for (i = 0U; i < VENDOR_NUM; i++)
{
if (device_id == dev_id_index[i])
{
gp_qspi_cmd_tbl = &qspi_cmd_tbls[i];
if (device_id == DEVID_XXXXXXXXX)
prk3_rev = 4;
rtn_val = QSPI_CMD_INIT_SUCCESS;
break;
}
}
return rtn_val;
}
int check_Erase_Fail(uint32_t status) {
if (prk3_rev <= 3)
return (status & BIT5);
return (status & BIT6);
}
/* End of function init_qspi_cmd(uint32_t device_id) */

View File

@@ -0,0 +1,809 @@
/*******************************************************************************
* 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 2015-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : RPC driver for QSPI Flash
******************************************************************************/
/******************************************************************************
* @file rpcqspidrv.c
* - Version : 0.07
* @brief RPC driver for QSPI Flash.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 15.10.2021 0.01 First Release
* : 16.02.2022 0.02 Modify how to write to RPC_WRBUF register.
* : 15.03.2022 0.03 Modify to use inline function in mem_io.h
* : when access to register.
* : 18.03.2022 0.04 Modify to read modify write when write to
* : register.
* : 23.03.2022 0.05 Modify command for QSPI Flash to refer to
* : command table.
* : 01.04.2022 0.06 Modify magic number to definition.
* : 09.11.2022 0.07 License notation change.
*****************************************************************************/
#include <stdint.h>
#include <stddef.h>
#include <remap.h>
#include <mem_io.h>
#include <micro_wait.h>
#include <cpg_register.h>
#include <rpc_register.h>
#include <rpcqspidrv.h>
#include <rpc.h>
#include <wdt.h>
#include <log.h>
#include "dma2.h"
static uint32_t read_register_qspi_flash(uint32_t cmd, uint32_t *readData);
void init_rpc_qspi_flash_4fastread_ext_mode(void)
{
uint32_t reg;
reg = mem_read32(RPC_PHYCNT);
reg |= (RPC_PHYCNT_STRTIM3
| RPC_PHYCNT_STRTIM2
| RPC_PHYCNT_STRTIM1
| RPC_PHYCNT_STRTIM0);
reg &= ~(RPC_PHYCNT_HS
| RPC_PHYCNT_WBUF2
| RPC_PHYCNT_WBUF
| RPC_PHYCNT_PHYMEM_HYP);
mem_write32(RPC_PHYCNT, reg);
reg |= RPC_PHYCNT_CAL;
mem_write32(RPC_PHYCNT, reg);
reg = mem_read32(RPC_CMNCR);
reg &= ~(CMNCR_MD_MANUAL /* External address space read mode */
| CMNCR_BSZ_MASK); /* Data Bus Size: Serial flash memory x 1*/
reg |= (CMNCR_MOIIO3_HIZ
| CMNCR_MOIIO2_HIZ
| CMNCR_MOIIO1_HIZ
| CMNCR_MOIIO0_HIZ
| CMNCR_IO0FV_HIZ);
mem_write32(RPC_CMNCR, reg);
/* bit31 MD = 0 : External address space read mode */
/* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */
reg = mem_read32(RPC_DRCR);
reg &= ~(DRCR_SSLN
| DRCR_RCF
| DRCR_SSLE);
reg |= (DRCR_RBURST_32UNITS
| DRCR_RBE_BURST);
mem_write32(RPC_DRCR, reg);
/* bit20-16 RBURST[4:0] = 11111 : 32 continuous data unit */
/* bit8 RBE = 1 : Burst read */
reg = mem_read32(RPC_DRCMR);
reg &= ~(DRCMR_CMD_MASK
| DRCMR_OCMD_MASK);
reg |= ((gp_qspi_cmd_tbl -> read_fast) << DRCMR_SMCMR_CMD_SHIFT);
mem_write32(RPC_DRCMR, reg);
/* bit23-16 CMD[7:0] = 0x0C : 4FAST_READ 0Ch Command 4-byte address command */
reg = mem_read32(RPC_DREAR);
reg &= ~(DREAR_EAV_MASK
| DREAR_EAC_MASK);
reg |= DREAR_EAC_26BITS;
mem_write32(RPC_DREAR, reg);
/* bit23-16 EAV[7:0] = 0 : ADR[32:26] output set0 */
/* bit2-0 EAC[2:0] = 001 : ADR[25:0 ] Enable */
reg = mem_read32(RPC_DRENR);
reg &= ~(DRENR_CDB_MASK
| DRENR_OCDB_MASK
| DRENR_ADB_MASK
| DRENR_OPDB_MASK
| DRENR_DRDB_MASK
| DRENR_OCDE_EN
| DRENR_ADE_MASK
| DRENR_OPDE_MASK);
reg |= (DRENR_DME_EN
| DRENR_CDE_EN
| DRENR_ADE_ONE_SERIAL);
mem_write32(RPC_DRENR, reg);
/* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */
/* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */
/* bit17-16 DRDB[1:0] = 00 : 1bit width transfer data (QSPI0_IO0) */
/* bit15 DME = 1 : dummy cycle enable */
/* bit14 CDE = 1 : Command enable */
/* bit11-8 ADE[3:0] = 1111 : ADR[31:0] output (32 Bit Address) */
reg = mem_read32(RPC_DRDMCR);
reg &= ~(DRDMCR_DMCYC_MASK);
reg |= DRDMCR_DMCYC_8;
mem_write32(RPC_DRDMCR, reg);
/* bit2-0 DMCYC[2:0] = 111 : 8 cycle dummy wait */
reg = mem_read32(RPC_DRDRENR);
reg &= ~(DRDRENR_HYPE_MASK
| DRDRENR_ADDRE
| DRDRENR_OPDRE
| DRDRENR_DRDRE);
mem_write32(RPC_DRDRENR, reg);
/* bit8 ADDRE = 0 : Address SDR transfer */
/* bit0 DRDRE = 0 : DATA SDR transfer */
}
/* End of function init_rpc_qspi_flash_4fastread_ext_mode */
void init_rpc_qspi_flash(void)
{
uint32_t reg;
power_on_rpc();
set_rpc_clock_mode(RPC_CLK_80M);
reset_rpc();
set_rpc_ssl_delay();
reg = mem_read32(RPC_OFFSET1);
reg &= ~(PHYOFFSET1_MASK);
reg |= PHYOFFSET1_DMA_QSPI;
mem_write32(RPC_OFFSET1, reg);
}
/* End of function init_rpc_qspi_flash */
/* 4SE DCh 4-byte address */
void sector_erase_4byte_qspi_flash(uint32_t sector_addr)
{
uint32_t reg;
reg = mem_read32(RPC_PHYCNT);
reg |= (RPC_PHYCNT_CAL
| RPC_PHYCNT_STRTIM3
| RPC_PHYCNT_STRTIM2
| RPC_PHYCNT_STRTIM1
| RPC_PHYCNT_STRTIM0);
reg &= ~(RPC_PHYCNT_HS
| RPC_PHYCNT_WBUF2
| RPC_PHYCNT_WBUF
| RPC_PHYCNT_PHYMEM_HYP);
mem_write32(RPC_PHYCNT, reg);
/* bit31 CAL = 1 : PHY calibration */
/* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */
reg = mem_read32(RPC_CMNCR);
reg &= ~(CMNCR_BSZ_MASK);
reg |= (CMNCR_MD_MANUAL
| CMNCR_MOIIO3_HIZ
| CMNCR_MOIIO2_HIZ
| CMNCR_MOIIO1_HIZ
| CMNCR_MOIIO0_HIZ
| CMNCR_IO0FV_HIZ);
mem_write32(RPC_CMNCR, reg);
/* bit31 MD = 1 : Manual mode */
/* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */
reg = mem_read32(RPC_SMCMR);
reg &= ~(SMCMR_CMD_MASK
| SMCMR_OCMD_MASK);
reg |= ((gp_qspi_cmd_tbl -> sector_erase_4byte_addr) << DRCMR_SMCMR_CMD_SHIFT);
mem_write32(RPC_SMCMR, reg);
/* bit23-16 CMD[7:0] = 0xDC : Sector Erase 4-byte address command */
mem_write32(RPC_SMADR, sector_addr);
reg = mem_read32(RPC_SMDRENR);
reg &= ~(SMDRENR_HYPE_MASK
| SMDRENR_ADDRE
| SMDRENR_OPDRE
| SMDRENR_SPIDRE);
mem_write32(RPC_SMDRENR, reg);
/* bit8 ADDRE = 0 : Address SDR transfer */
/* bit0 SPIDRE = 0 : DATA SDR transfer */
reg = mem_read32(RPC_SMENR);
reg &= ~(SMENR_CDB_MASK
| SMENR_OCDB_MASK
| SMENR_ADB_MASK
| SMENR_OPDB_MASK
| SMENR_SPIDB_MASK
| SMENR_DME_EN
| SMENR_OCDE_EN
| SMENR_ADE_MASK
| SMENR_OPDE_MASK
| SMENR_SPIDE_MASK);
reg |= (SMENR_CDE_EN
| SMENR_ADE_SERIAL_31);
mem_write32(RPC_SMENR, reg);
/* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */
/* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */
/* bit17-16 SPIDB[1:0] = 00 : 1bit width transfer data (QSPI0_MISO) */
/* bit15 DME = 0 : No dummy cycle */
/* bit14 CDE = 1 : Command enable */
/* bit11-8 ADE[3:0] = 1111 : ADR[31:0] output (32 Bit Address) */
/* bit3-0 SPIDE[3:0] = 0000 : No transfer */
reg = mem_read32(RPC_SMCR);
reg &= ~(SMCR_SSLKP
| SMCR_SPIRE
| SMCR_SPIWE);
reg |= SMCR_SPIE;
mem_write32(RPC_SMCR, reg);
/* bit2 SPIRE = 0 : Data read disable */
/* bit1 SPIWE = 0 : Data write disable */
/* bit0 SPIE = 1 : SPI transfer start */
wait_rpc_tx_end();
}
/* End of function sector_erase_4byte_qspi_flash */
/* 4P4E 21h 4-byte address */
void parameter_sector_erase_4kb_qspi_flash(uint32_t sector_addr)
{
uint32_t reg;
reg = mem_read32(RPC_PHYCNT);
reg |= (RPC_PHYCNT_CAL
| RPC_PHYCNT_STRTIM3
| RPC_PHYCNT_STRTIM2
| RPC_PHYCNT_STRTIM1
| RPC_PHYCNT_STRTIM0);
reg &= ~(RPC_PHYCNT_HS
| RPC_PHYCNT_WBUF2
| RPC_PHYCNT_WBUF
| RPC_PHYCNT_PHYMEM_HYP);
mem_write32(RPC_PHYCNT, reg);
/* bit31 CAL = 1 : PHY calibration */
/* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */
reg = mem_read32(RPC_CMNCR);
reg &= ~(CMNCR_BSZ_MASK);
reg |= (CMNCR_MD_MANUAL
| CMNCR_MOIIO3_HIZ
| CMNCR_MOIIO2_HIZ
| CMNCR_MOIIO1_HIZ
| CMNCR_MOIIO0_HIZ
| CMNCR_IO0FV_HIZ);
mem_write32(RPC_CMNCR, reg);
/* bit31 MD = 1 : Manual mode */
/* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */
reg = mem_read32(RPC_SMCMR);
reg &= ~(SMCMR_CMD_MASK
| SMCMR_OCMD_MASK);
reg |= ((gp_qspi_cmd_tbl -> parameter_4kbyte_erase) << DRCMR_SMCMR_CMD_SHIFT);
mem_write32(RPC_SMCMR, reg);
/* bit23-16 CMD[7:0] = 0x21 : Parameter 4-kB Sector Erasecommand */
mem_write32(RPC_SMADR, sector_addr);
reg = mem_read32(RPC_SMDRENR);
reg &= ~(SMDRENR_HYPE_MASK
| SMDRENR_ADDRE
| SMDRENR_OPDRE
| SMDRENR_SPIDRE);
mem_write32(RPC_SMDRENR, reg);
/* bit8 ADDRE = 0 : Address SDR transfer */
/* bit0 SPIDRE = 0 : DATA SDR transfer */
reg = mem_read32(RPC_SMENR);
reg &= ~(SMENR_CDB_MASK
| SMENR_OCDB_MASK
| SMENR_ADB_MASK
| SMENR_OPDB_MASK
| SMENR_SPIDB_MASK
| SMENR_DME_EN
| SMENR_OCDE_EN
| SMENR_ADE_MASK
| SMENR_OPDE_MASK
| SMENR_SPIDE_MASK);
reg |= (SMENR_CDE_EN
| SMENR_ADE_SERIAL_31);
mem_write32(RPC_SMENR, reg);
/* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */
/* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */
/* bit17-16 SPIDB[1:0] = 00 : 1bit width transfer data (QSPI0_MISO) */
/* bit15 DME = 0 : No dummy cycle */
/* bit14 CDE = 1 : Command enable */
/* bit11-8 ADE[3:0] = 1111 : ADR[31:0] output (32 Bit Address) */
/* bit3-0 SPIDE[3:0] = 0000 : No transfer */
reg = mem_read32(RPC_SMCR);
reg &= ~(SMCR_SSLKP
| SMCR_SPIRE
| SMCR_SPIWE);
reg |= SMCR_SPIE;
mem_write32(RPC_SMCR, reg);
/* bit2 SPIRE = 0 : Data read disable */
/* bit1 SPIWE = 0 : Data write disable */
/* bit0 SPIE = 1 : SPI transfer start */
wait_rpc_tx_end();
}
/* End of function parameter_sector_erase_4kb_qspi_flash */
/* Page Program (4PP:12h) 4-byte address */
void write_data_4pp_with_buf_qspi_flash(uint32_t addr, uint32_t source_addr)
{
uintptr_t i=0;
uint32_t reg;
reg = mem_read32(RPC_DRCR);
reg |= (DRCR_SSLN
| DRCR_RBURST_32UNITS
| DRCR_RCF
| DRCR_RBE_BURST
| DRCR_SSLE);
mem_write32(RPC_DRCR, reg);
/* bit9 RCF = 1 : Read Cache Clear */
reg = mem_read32(RPC_PHYCNT);
reg |= (RPC_PHYCNT_CAL
| RPC_PHYCNT_STRTIM3
| RPC_PHYCNT_STRTIM2
| RPC_PHYCNT_STRTIM1
| RPC_PHYCNT_STRTIM0
| RPC_PHYCNT_WBUF2
| RPC_PHYCNT_WBUF);
reg &= ~(RPC_PHYCNT_HS
| RPC_PHYCNT_PHYMEM_HYP);
mem_write32(RPC_PHYCNT, reg);
/* bit31 CAL = 1 : PHY calibration */
/* bit2 WBUF = 1 : Write Buffer Enable */
/* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */
for(i = 0; i < RPC_WRITE_BUF_SIZE; i = i + TRANS_SIZE_64BYTE)
{
dma2_start_xbyte(RPC_WRBUF_PHYS+i, source_addr+i, TRANS_SIZE_64BYTE, TRANS_UNIT_64BYTES);
dma2_end();
// dma_trans_start(RPC_WRBUF_PHYS+i, source_addr+i, TRANS_SIZE_64BYTE);
// dma_trans_end_check();
}
reg = mem_read32(RPC_CMNCR);
reg &= ~(CMNCR_BSZ_MASK);
reg |= (CMNCR_MD_MANUAL
| CMNCR_MOIIO3_HIZ
| CMNCR_MOIIO2_HIZ
| CMNCR_MOIIO1_HIZ
| CMNCR_MOIIO0_HIZ
| CMNCR_IO0FV_HIZ);
mem_write32(RPC_CMNCR, reg);
/* bit31 MD = 1 : Manual mode */
/* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */
reg = mem_read32(RPC_SMCMR);
reg &= ~(SMCMR_CMD_MASK
| SMCMR_OCMD_MASK);
reg |= ((gp_qspi_cmd_tbl -> pp_4byte_addr) << DRCMR_SMCMR_CMD_SHIFT);
mem_write32(RPC_SMCMR, reg);
/* bit23-16 CMD[7:0] = 0x12 : Page Program 4-byte address */
mem_write32(RPC_SMADR, addr);
reg = mem_read32(RPC_SMDRENR);
reg &= ~(SMDRENR_HYPE_MASK
| SMDRENR_ADDRE
| SMDRENR_OPDRE
| SMDRENR_SPIDRE);
mem_write32(RPC_SMDRENR, reg);
/* bit8 ADDRE = 0 : Address SDR transfer */
/* bit0 SPIDRE = 0 : DATA SDR transfer */
reg = mem_read32(RPC_SMENR);
reg &= ~(SMENR_CDB_MASK
| SMENR_OCDB_MASK
| SMENR_ADB_MASK
| SMENR_OPDB_MASK
| SMENR_SPIDB_MASK
| SMENR_DME_EN
| SMENR_OCDE_EN
| SMENR_ADE_MASK
| SMENR_OPDE_MASK
| SMENR_SPIDE_MASK);
reg |= (SMENR_CDE_EN
| SMENR_ADE_SERIAL_31
| SMENR_SPIDE_SPI_32);
mem_write32(RPC_SMENR, reg);
/* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */
/* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */
/* bit17-16 SPIDB[1:0] = 00 : 1bit width transfer data (QSPI0_MISO) */
/* bit15 DME = 0 : No dummy cycle */
/* bit14 CDE = 1 : Command enable */
/* bit11-8 ADE[3:0] = 1111 : ADR[31:0] is output */
/* bit3-0 SPIDE[3:0] = 1111 : 32bit transfer */
reg = mem_read32(RPC_SMCR);
reg &= ~(SMCR_SSLKP
| SMCR_SPIRE);
reg |= (SMCR_SPIWE
| SMCR_SPIE);
mem_write32(RPC_SMCR, reg);
/* bit2 SPIRE = 0 : Data read disable */
/* bit1 SPIWE = 1 : Data write enable */
/* bit0 SPIE = 1 : SPI transfer start */
wait_rpc_tx_end();
reg = mem_read32(RPC_PHYCNT);
reg |= (RPC_PHYCNT_STRTIM3
| RPC_PHYCNT_STRTIM2
| RPC_PHYCNT_STRTIM1
| RPC_PHYCNT_STRTIM0
| RPC_PHYCNT_WBUF2);
reg &= ~(RPC_PHYCNT_HS
| RPC_PHYCNT_WBUF
| RPC_PHYCNT_PHYMEM_HYP);
mem_write32(RPC_PHYCNT, reg);
/* bit31 CAL = 0 : No PHY calibration */
/* bit2 WBUF = 0 : Write Buffer Disable */
/* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */
reg = mem_read32(RPC_DRCR);
reg |= (DRCR_SSLN
| DRCR_RBURST_32UNITS
| DRCR_RCF
| DRCR_RBE_BURST
| DRCR_SSLE);
mem_write32(RPC_DRCR, reg);
/* bit9 RCF = 1 : Read Cache Clear */
}
/* End of function write_data_4pp_with_buf_qspi_flash */
/* OnBoard QspiFlash(MT25QU01GB) */
uint32_t read_wip_status_register(uint32_t *readData) /* for QSPIx1ch */
{
return read_register_qspi_flash(gp_qspi_cmd_tbl -> read_any_register, readData);
}
#define RDCR_cmd 0x15
uint32_t read_configuration_register(uint32_t *readData) /* for QSPIx1ch */
{
return read_register_qspi_flash(RDCR_cmd, readData);
}
#define WRSR_cmd 0x01
void write_status_register(uint16_t stat_conf)
{
uint32_t reg;
reg = mem_read32(RPC_PHYCNT);
reg |= (RPC_PHYCNT_CAL
| RPC_PHYCNT_STRTIM3
| RPC_PHYCNT_STRTIM2
| RPC_PHYCNT_STRTIM1
| RPC_PHYCNT_STRTIM0);
reg &= ~(RPC_PHYCNT_HS
| RPC_PHYCNT_WBUF2
| RPC_PHYCNT_WBUF
| RPC_PHYCNT_PHYMEM_HYP);
mem_write32(RPC_PHYCNT, reg);
/* bit31 CAL = 1 : PHY calibration */
/* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */
reg = mem_read32(RPC_CMNCR);
reg &= ~(CMNCR_BSZ_MASK);
reg |= (CMNCR_MD_MANUAL
| CMNCR_MOIIO3_HIZ
| CMNCR_MOIIO2_HIZ
| CMNCR_MOIIO1_HIZ
| CMNCR_MOIIO0_HIZ
| CMNCR_IO0FV_HIZ);
mem_write32(RPC_CMNCR, reg);
/* bit31 MD = 1 : Manual mode */
/* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */
reg = mem_read32(RPC_SMCMR);
reg &= ~(SMCMR_CMD_MASK
| SMCMR_OCMD_MASK);
reg |= ((WRSR_cmd) << DRCMR_SMCMR_CMD_SHIFT);
mem_write32(RPC_SMCMR, reg);
/* bit23-16 CMD[7:0] = 0x01 : write status/configuration register command */
reg = mem_read32(RPC_SMENR);
reg &= ~(SMENR_CDB_MASK
| SMENR_OCDB_MASK
| SMENR_ADB_MASK
| SMENR_OPDB_MASK
| SMENR_SPIDB_MASK
| SMENR_DME_EN
| SMENR_OCDE_EN
| SMENR_ADE_MASK
| SMENR_OPDE_MASK
| SMENR_SPIDE_MASK);
reg |= (SMENR_CDE_EN
| SMENR_SPIDE_SPI_16);
mem_write32(RPC_SMENR, reg);
/* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */
/* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */
/* bit17-16 SPIDB[1:0] = 00 : 1bit width transfer data (QSPI0_MISO) */
/* bit15 DME = 0 : No dummy cycle */
/* bit14 CDE = 1 : Command enable */
/* bit11-8 ADE[3:0] = 0000 : Address output disable */
/* bit3-0 SPIDE[3:0] = 1100 : 16bit transfer */
mem_write16(RPC_SMWDR0, stat_conf);
reg = mem_read32(RPC_SMCR);
reg &= ~(SMCR_SSLKP
| SMCR_SPIRE);
reg |= (SMCR_SPIWE
| SMCR_SPIE);
mem_write32(RPC_SMCR, reg);
/* bit2 SPIRE = 0 : Data read disable */
/* bit1 SPIWE = 1 : Data write enable */
/* bit0 SPIE = 1 : SPI transfer start */
wait_rpc_tx_end();
}
void set_rpc_clock_mode(uint32_t mode)
{
uint32_t dataL=0;
uint32_t reg;
if(mode == RPC_CLK_160M){
dataL = RPCCKCR_RPCFC_160M; /* RPC clock 160MHz */
}else if(mode == RPC_CLK_80M){
dataL = RPCCKCR_RPCFC_80M; /* RPC clock 80MHz */
}else{
dataL = RPCCKCR_RPCFC_40M; /* RPC clock 40MHz */
}
reg = mem_read32(CPG_RPCCKCR);
reg &= ~(RPCCKCR_RPCFC_MASK);
dataL |= reg;
mem_write32(CPG_CPGWPR, ~dataL);
mem_write32(CPG_RPCCKCR, dataL);
(void)mem_read32(CPG_RPCCKCR); /* dummy read */
}
/* End of function set_rpc_clock_mode */
void wait_rpc_tx_end(void)
{
uint32_t dataL=0;
while(1)
{
wdt_restart();
dataL = mem_read32(RPC_CMNSR);
if(dataL & BIT0) break;
/* Wait for TEND = 1 */
}
}
/* End of function wait_rpc_tx_end */
void reset_rpc(void)
{
mem_write32(CPG_CPGWPR, ~BIT29);
mem_write32(CPG_SRCR6, BIT29);
/* wait: tRLRH Reset# low pulse width 10us */
micro_wait(20); /* wait 20us */
mem_write32(CPG_CPGWPR, ~BIT29);
mem_write32(CPG_SRSTCLR6, BIT29);
/* wait: tREADY1(35us) - tRHSL(10us) = 25us */
micro_wait(40); /* wait 40us */
}
/* End of function reset_rpc */
void set_rpc_ssl_delay(void)
{
uint32_t reg;
reg = mem_read32(RPC_SSLDR);
reg |= SSLDR_SLNDL;
mem_write32(RPC_SSLDR, reg);
/* bit10-8 SLNDL[2:0] = 100 : 5.5 cycles of QSPIn_SPCLK */
}
/* End of function set_rpc_ssl_delay */
void power_on_rpc(void)
{
uint32_t dataL=0;
dataL = mem_read32(CPG_MSTPSR6);
if(dataL & BIT29){ /* case RPC(QSPI) Standby */
dataL &= ~BIT29;
mem_write32(CPG_CPGWPR, ~dataL);
mem_write32(CPG_MSTPCR6, dataL);
while( BIT29 & mem_read32(CPG_MSTPSR6) ); /* wait bit=0 */
}
}
/* End of function power_on_rpc */
uint32_t read_qspi_flash_id(uint32_t *readData) /* for QSPIx1ch */
{
return read_register_qspi_flash(FLASH_CMD_READ_ID, readData);
}
uint32_t read_status_qspi_flash(uint32_t *readData) {
return read_register_qspi_flash(gp_qspi_cmd_tbl -> read_stts_register, readData);
}
static uint32_t read_register_qspi_flash(uint32_t cmd, uint32_t *readData) /* for QSPIx1ch */
{
uint32_t reg;
reg = mem_read32(RPC_PHYCNT);
reg |= (RPC_PHYCNT_STRTIM3
| RPC_PHYCNT_STRTIM2
| RPC_PHYCNT_STRTIM1
| RPC_PHYCNT_STRTIM0);
reg &= ~(RPC_PHYCNT_HS
| RPC_PHYCNT_WBUF2
| RPC_PHYCNT_WBUF
| RPC_PHYCNT_PHYMEM_HYP);
mem_write32(RPC_PHYCNT, reg);
reg |= RPC_PHYCNT_CAL;
mem_write32(RPC_PHYCNT, reg);
/* bit31 CAL = 1 : PHY calibration */
/* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */
reg = mem_read32(RPC_CMNCR);
reg &= ~(CMNCR_BSZ_MASK);
reg |= (CMNCR_MD_MANUAL
| CMNCR_MOIIO3_HIZ
| CMNCR_MOIIO2_HIZ
| CMNCR_MOIIO1_HIZ
| CMNCR_MOIIO0_HIZ
| CMNCR_IO0FV_HIZ);
mem_write32(RPC_CMNCR, reg);
/* bit31 MD = 1 : Manual mode */
/* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */
reg = mem_read32(RPC_SMCMR);
reg &= ~(SMCMR_CMD_MASK
| SMCMR_OCMD_MASK);
reg |= ((cmd) << DRCMR_SMCMR_CMD_SHIFT);
mem_write32(RPC_SMCMR, reg);
/* bit23-16 CMD[7:0] = 0x05 : Status Read command (for Palladium QSPI model) */
reg = mem_read32(RPC_SMDRENR);
reg &= ~(SMDRENR_HYPE_MASK
| SMDRENR_ADDRE
| SMDRENR_OPDRE
| SMDRENR_SPIDRE);
mem_write32(RPC_SMDRENR, reg);
/* bit8 ADDRE = 0 : Address SDR transfer */
/* bit0 SPIDRE = 0 : DATA SDR transfer */
reg = mem_read32(RPC_SMENR);
reg &= ~(SMENR_CDB_MASK
| SMENR_OCDB_MASK
| SMENR_ADB_MASK
| SMENR_OPDB_MASK
| SMENR_SPIDB_MASK
| SMENR_DME_EN
| SMENR_OCDE_EN
| SMENR_ADE_MASK
| SMENR_OPDE_MASK
| SMENR_SPIDE_MASK);
reg |= (SMENR_CDE_EN
| SMENR_SPIDE_SPI_32);
mem_write32(RPC_SMENR, reg);
/* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */
/* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */
/* bit17-16 SPIDB[1:0] = 00 : 1bit width transfer data (QSPI0_MISO) */
/* bit15 DME = 0 : No dummy cycle */
/* bit14 CDE = 1 : Command enable */
/* bit11-8 ADE[3:0] = 0000 : Address output disable */
/* bit3-0 SPIDE[3:0] = 1111 : 32bit transfer */
reg = mem_read32(RPC_SMCR);
reg &= ~(SMCR_SSLKP
| SMCR_SPIWE);
reg |= (SMCR_SPIRE
| SMCR_SPIE);
mem_write32(RPC_SMCR, reg);
/* bit2 SPIRE = 1 : Data read enable */
/* bit1 SPIWE = 0 : Data write disable */
/* bit0 SPIE = 1 : SPI transfer start */
wait_rpc_tx_end();
readData[0] = mem_read32(RPC_SMRDR0); /* read data[31:0] */
return(readData[0]);
}
/* End of function read_register_qspi_flash */
void write_command_qspi_flash(uint32_t command) /* for QSPIx1ch */
{
uint32_t reg;
reg = mem_read32(RPC_PHYCNT);
reg |= (RPC_PHYCNT_CAL
| RPC_PHYCNT_STRTIM3
| RPC_PHYCNT_STRTIM2
| RPC_PHYCNT_STRTIM1
| RPC_PHYCNT_STRTIM0);
reg &= ~(RPC_PHYCNT_HS
| RPC_PHYCNT_WBUF2
| RPC_PHYCNT_WBUF
| RPC_PHYCNT_PHYMEM_HYP);
mem_write32(RPC_PHYCNT, reg);
/* bit31 CAL = 1 : PHY calibration */
/* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */
reg = mem_read32(RPC_CMNCR);
reg &= ~(CMNCR_BSZ_MASK);
reg |= (CMNCR_MD_MANUAL
| CMNCR_MOIIO3_HIZ
| CMNCR_MOIIO2_HIZ
| CMNCR_MOIIO1_HIZ
| CMNCR_MOIIO0_HIZ
| CMNCR_IO0FV_HIZ);
mem_write32(RPC_CMNCR, reg);
/* bit31 MD = 1 : Manual mode */
/* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */
reg = mem_read32(RPC_SMCMR);
reg &= ~(SMCMR_CMD_MASK
| SMCMR_OCMD_MASK);
reg |= (command & (SMCMR_CMD_MASK | SMCMR_OCMD_MASK));
mem_write32(RPC_SMCMR, reg);
/* bit23-16 CMD[7:0] : command */
reg = mem_read32(RPC_SMDRENR);
reg &= ~(SMDRENR_HYPE_MASK
| SMDRENR_ADDRE
| SMDRENR_OPDRE
| SMDRENR_SPIDRE);
mem_write32(RPC_SMDRENR, reg);
/* bit8 ADDRE = 0 : Address SDR transfer */
/* bit0 SPIDRE = 0 : DATA SDR transfer */
reg = mem_read32(RPC_SMENR);
reg &= ~(SMENR_CDB_MASK
| SMENR_OCDB_MASK
| SMENR_ADB_MASK
| SMENR_OPDB_MASK
| SMENR_SPIDB_MASK
| SMENR_DME_EN
| SMENR_OCDE_EN
| SMENR_ADE_MASK
| SMENR_ADE_MASK
| SMENR_OPDE_MASK
| SMENR_SPIDE_MASK);
reg |= SMENR_CDE_EN;
mem_write32(RPC_SMENR, reg);
/* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */
/* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */
/* bit17-16 SPIDB[1:0] = 00 : 1bit width transfer data (QSPI0_MISO) */
/* bit15 DME = 0 : No dummy cycle */
/* bit14 CDE = 1 : Command enable */
/* bit11-8 ADE[3:0] = 0000 : Address output disable */
/* bit3-0 SPIDE[3:0] = 0000 : No transfer */
reg = mem_read32(RPC_SMCR);
reg &= ~(SMCR_SSLKP
| SMCR_SPIRE
| SMCR_SPIWE);
reg |= SMCR_SPIE;
mem_write32(RPC_SMCR, reg);
/* bit2 SPIRE = 0 : Data read disable */
/* bit1 SPIWE = 0 : Data write disable */
/* bit0 SPIE = 1 : SPI transfer start */
wait_rpc_tx_end();
}
/* End of function write_command_qspi_flash */

View File

@@ -0,0 +1,213 @@
/*******************************************************************************
* 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 2020-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : QSPI Flash driver for S25FS512S
******************************************************************************/
/******************************************************************************
* @file spiflash2drv.c
* - Version : 0.04
* @brief QSPI Flash driver for S25FS512S.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 15.10.2021 0.01 First Release
* : 23.03.2022 0.02 Modify command for QSPI Flash to refer to
* : command table.
* : 01.04.2022 0.03 Modify magic number to definition.
* : 09.11.2022 0.04 License notation change.
*****************************************************************************/
#include <stdint.h>
#include <stddef.h>
#include <spiflash2drv.h>
#include <rpcqspidrv.h>
#include <rpc.h>
#include <log.h>
#include "dma2.h"
#define QSPI_PARAM_SEC_SIZE (0x1000U)
#define QSPI_PARAM_SEC_MASK (0xFFFFF000U)
void fast_rd_qspi_flash(uint32_t sourceSpiAdd, uint32_t destinationAdd, uint32_t byteCount)
{
uint32_t sourceAdd;
init_rpc_qspi_flash_4fastread_ext_mode();
sourceAdd = SPI_IOADDRESS_TOP + sourceSpiAdd;
// dma_trans_start(destinationAdd, sourceAdd, byteCount);
// dma_trans_end_check();
// dma2_init();
dma2_start(destinationAdd, sourceAdd, byteCount, DMA_MODE_SRC_INC);
dma2_end();
}
/* End of function fast_rd_qspi_flash */
/* Qspi:Sector Erase */
/* 4SE DCh */
void sector_erase_NNNkb_qspi_flash_s25s512s(uint32_t addr)
{
uint32_t status;
/* WRITE ENABLE */
write_command_qspi_flash((gp_qspi_cmd_tbl -> write_enable) << DRCMR_SMCMR_CMD_SHIFT);
sector_erase_4byte_qspi_flash(addr);
while(1)
{
read_status_qspi_flash(&status);
if( check_Erase_Fail(status) )
{
// put_str("Erase Error", CRLF_OFF);
ERROR("Erase Error!!\n");
break;
}
read_wip_status_register(&status);
if( !(status & BIT0) )
{
break;
}
}
}
/* End of function sector_erase_NNNkb_qspi_flash_s25s512s */
/* Qspi:Parameter 4-kB Sector Erase */
/* 4P4E 21h */
void parameter_sector_erase_4kb_qspi_flash_s25s512s(uint32_t addr)
{
uint32_t status;
/* WRITE ENABLE */
write_command_qspi_flash((gp_qspi_cmd_tbl -> write_enable) << DRCMR_SMCMR_CMD_SHIFT);
parameter_sector_erase_4kb_qspi_flash(addr);
while(1)
{
read_status_qspi_flash(&status);
if( check_Erase_Fail(status) )
{
ERROR("Erase Error!!\n");
break;
}
read_wip_status_register(&status);
if( !(status & BIT0) )
{
break;
}
}
}
/* End of function parameter_sector_erase_4kb_qspi_flash_s25s512s */
/* Qspi:Page Program (4PP:12h) */
void page_program_with_buf_qspi_flash_s25s512s(uint32_t addr, uint32_t source_addr)
{
uint32_t status;
/* WRITE ENABLE */
write_command_qspi_flash((gp_qspi_cmd_tbl -> write_enable) << DRCMR_SMCMR_CMD_SHIFT);
write_data_4pp_with_buf_qspi_flash(addr,source_addr); /* 4PP */
/* Add */
while(1)
{
read_wip_status_register(&status);
if( !(status & BIT0) )
{
break;
}
}
}
/* End of function page_program_with_buf_qspi_flash_s25s512s */
/* Qspi:Clear Block Protection of SR1V */
void clear_bp_qspi_flash(void)
{
uint32_t statusReg;
while(1)
{
read_wip_status_register(&statusReg);
if( !(statusReg & BIT0) )
{
break;
}
}
}
/* End of function clear_bp_qspi_flash */
void save_data_with_buf_qspi_flash(uint32_t srcAdd,uint32_t svFlashAdd,uint32_t svSize)
{
uint32_t flashAdd;
uint32_t writeDataAdd;
/* WRITE ENABLE */
write_command_qspi_flash((gp_qspi_cmd_tbl -> write_enable) << DRCMR_SMCMR_CMD_SHIFT);
writeDataAdd = srcAdd;
for(flashAdd=svFlashAdd; flashAdd<(svFlashAdd+svSize); flashAdd += RPC_WRITE_BUF_SIZE)
{ /* 256byte:RPC Write Buffer size */
page_program_with_buf_qspi_flash_s25s512s(flashAdd, writeDataAdd);
writeDataAdd = writeDataAdd + RPC_WRITE_BUF_SIZE;
}
}
/* End of function save_data_with_buf_qspi_flash */
void sector_erase_qspi_flash(uint32_t EraseStatAdd,uint32_t EraseEndAdd)
{
uint32_t sectorAd;
uint32_t SectorStatTopAdd;
uint32_t SectorEndTopAdd;
SectorStatTopAdd = EraseStatAdd & FLASH_SECTOR_MASK;
SectorEndTopAdd = EraseEndAdd & FLASH_SECTOR_MASK;
for(sectorAd = SectorStatTopAdd; sectorAd <= SectorEndTopAdd; sectorAd += FLASH_SECTOR_SIZE)
{
sector_erase_NNNkb_qspi_flash_s25s512s(sectorAd);
}
}
/* End of function sector_erase_qspi_flash_s25s512s */
void parameter_sector_erase_qspi_flash(uint32_t EraseStatAdd,uint32_t EraseEndAdd)
{
uint32_t sectorAd;
uint32_t SectorStatTopAdd;
uint32_t SectorEndTopAdd;
SectorStatTopAdd = EraseStatAdd & QSPI_PARAM_SEC_MASK;
SectorEndTopAdd = EraseEndAdd & QSPI_PARAM_SEC_MASK;
for(sectorAd = SectorStatTopAdd; sectorAd <= SectorEndTopAdd; sectorAd += QSPI_PARAM_SEC_SIZE)
{
parameter_sector_erase_4kb_qspi_flash_s25s512s(sectorAd);
}
}
/* End of function parameter_sector_erase_qspi_flash */

View File

@@ -0,0 +1,77 @@
/*******************************************************************************
* 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 2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : RT-VRAM driver
******************************************************************************/
/******************************************************************************
* @file RTVRAM.c
* - Version : 0.03
* @brief RT-VRAM driver.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 17.11.2021 0.01 First Release
* : 03.12.2021 0.02 remove Cache flush.
* : 06.01.2022 0.03 Static analysis support
*****************************************************************************/
#include <ram_def.h>
#include <rtvram.h>
#include <mem_io.h>
#include <log.h>
#include <inline_asm.h>
#define RTVRAM_VBUF_CFG_CACHE_MODE_8WAY (1U << 8U)
#define RTVRAM_VBUF_CFG_VBUF_SIZE_28M (6U << 0U)
#define RTVRAM_EXT_MODE_EXT (1U << 0U)
#define RTVRAM_VBUF_NUM (7U)
#define RTVRAM_EXTEND_ENABLE (1U)
void rtvram_extendmode(void)
{
#if (RTVRAM_EXTEND == RTVRAM_EXTEND_ENABLE)
uint32_t reg;
uint32_t loop;
/* Set each 4MB from the top of SDRAM as the buffer area of RT-VRAM. */
for(loop = 0; loop < RTVRAM_VBUF_NUM; loop++)
{
mem_write32(get_vbuf_baddr_addr(loop), (uint32_t)((SDRAM_40BIT_ADDR_TOP + (RTVRAM_VBUF_AREA_SIZE * loop)) >> 16U));
}
reg = mem_read32(RTVRAM_VBUF_CFG);
reg |= (RTVRAM_VBUF_CFG_CACHE_MODE_8WAY | RTVRAM_VBUF_CFG_VBUF_SIZE_28M); /* Cache Mode: 8-way, VBF size: 28M */
mem_write32(RTVRAM_VBUF_CFG, reg);
/* Set at the end */
mem_write32(RTVRAM_EXT_MODE, RTVRAM_EXT_MODE_EXT); /* Change from Compatible Mode to Extended Mode */
syncm();
#endif
}
/* End of function rtvram_extendmode(void) */

View File

@@ -0,0 +1,458 @@
/*******************************************************************************
* 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 2023-2024 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : I2C driver
******************************************************************************/
/******************************************************************************
* @file i2c.c
* - Version : 0.02
* @brief I2C driver.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 16.11.2023 0.01 First Release
* : 24.06.2024 0.02 Remove pre-process branch of i2c5_read().
*****************************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <cpg.h>
#include <cpg_register.h>
#include <i2c.h>
#include <i2c_register.h>
#include <log.h>
#include <mem_io.h>
#include <pfc.h>
#include <pfc_register.h>
#include <micro_wait.h>
/* Setting value for PFC */
#define GPSR4_TSN0_MDIO (0x00000001U) /* bit0 */
#define PMIC_ADDR ((0x54) << 1) /* regulation register */
#define PMIC_ADDR_P ((0x55) << 1) /* protection register */
#define PMIC_ADDR_OTP ((0x64) << 1) /* OTP register ? */
void PMIC_SM_27A(void) {
/*
// PRESET -> PRESETOUT Check
// Set SDI and EN High, and Presetout low
MCU_VMONOUT0 = B_PIN_STATE_HIGH;
MCU_VMONOUT1 = B_PIN_STATE_HIGH;
MCU_SDI4 = B_PIN_STATE_HIGH;
MCU_ERROROUT_M = B_PIN_STATE_HIGH;
MCU_PRESET_OUT = B_PIN_STATE_LOW;
MCU_EN_PIN = B_PIN_STATE_HIGH;
delay_1ms(20); // Set delay to wait for LBIST to finish
while (PMIC_GLOBAL_PGOOD != B_PIN_STATE_HIGH){} // Wait for PGOOD to go high
while (PMIC_PRESETB != B_PIN_STATE_HIGH) {} // Wait for PRESET to go high
delay_1ms(6); // Set delay to pass 25% of TIMEOUT_PRESET_CHK_TOUT
MCU_PRESET_OUT = B_PIN_STATE_HIGH; // Set PRESETOUT High
*/
// from RAA271005_SAN.pdf page 91
// PRESET# Check is executed by the PMIC automatically
// // PGOOD_PMIC(TSN0_MDIO, GP4_00)
// /* Set GPSR to GPIO */
// data = mem_read32((uintptr_t)PFC_GPSR4_RW);
// data &= ~(GPSR4_TSN0_MDIO);
// pfc_reg_write(PFC_GPSR4_RW, data);
// /* PUEN disable */
// data = mem_read32((uintptr_t)PFC_PUEN4_RW);
// data &= ~(GPSR4_TSN0_MDIO);
// pfc_reg_write(PFC_PUEN4_RW, data);
// /* skip POSNEG
// data = mem_read32((uintptr_t)PFC_PUEN4_RW);
// data |= (GPSR4_TSN0_MDIO);
// mem_write32((uintptr_t)PFC_PUEN4_RW, data);
// */
// /* skip INOUTSEL
// data = mem_read32((uintptr_t)PFC_INOUTSEL4_RW);
// data &= ~(GPSR4_TSN0_MDIO);
// mem_write32((uintptr_t)PFC_INOUTSEL4_RW, data);
// */
// /* INEN */
// data = mem_read32((uintptr_t)PFC_INEN4_RW);
// data |= (GPSR4_TSN0_MDIO);
// mem_write32((uintptr_t)PFC_INEN4_RW, data);
// /* INDT */
// do {
// data = mem_read32((uintptr_t)PFC_INDT4_R);
// } while ((data & GPSR4_TSN0_MDIO) != 0);
}
#define D_SINT_CODE 0x2A
#define FUSA_CTRL_2 (0x09)
#define FUSA_CTRL_3 (0x0A)
#define FUSA_SOC_CHK_1 (0x15)
// SINT Check
void PMIC_SM_27B(void) {
uint32_t data = D_SINT_CODE;
i2c5_write(PMIC_ADDR_P, FUSA_CTRL_2, data);
i2c5_read(PMIC_ADDR_P, FUSA_SOC_CHK_1, &data);
NOTICE("SINT Check = 0x%x\n", data);
i2c5_write(PMIC_ADDR_P, FUSA_CTRL_3, data);
}
#define FUSA_CTRL_4 (0x0B)
#define EXT_PIN_CHK_EN (1U << 5)
#define EXT_PIN_CHK_SD1 (1U << 4)
#define EXT_PIN_CHK_SD2 (1U << 2)
#define EXT_PIN_CHK_SD3 (1U << 1)
#define EXT_PIN_CHK_SD4 (1U << 0)
/* To read/write an adress after 0x100,
it is necessary to write a value to IO_PAGE and
access the target address after changing the page.
*/
#define FUSA_CTRL_D (0x11D)
// EXT PINCHECK2
void PMIC_SM_27C(void) {
/*
// SDI1 Test
pmic_rtn_code_tmp = r_pmic_i2c_write(D_PMIC_I2C_PROT_ADDRESS, 0x0B, 0xFF); // Tell the PMIC to look for all SDIs to be high, to do this we set all bits (0xFF)
delay_1us(1);
MCU_ERROROUT_M = B_PIN_STATE_LOW; // Set SDI1 LOW
pmic_rtn_code_tmp = r_pmic_i2c_write(D_PMIC_I2C_PROT_ADDRESS, 0x0B, 0xEF); // Check for the SDI1 to be low
delay_1us(1);
MCU_ERROROUT_M = B_PIN_STATE_HIGH; // Set SDI1 HIGH
// SDI2 Test
pmic_rtn_code_tmp = r_pmic_i2c_write(D_PMIC_I2C_PROT_ADDRESS, 0x0B, 0xFF); // Tell the PMIC to look for all SDIs to be high, to do this we set all bits (0xFF)
delay_1us(1);
MCU_VMONOUT0 = B_PIN_STATE_LOW; // Set SDI2 LOW
pmic_rtn_code_tmp = r_pmic_i2c_write(D_PMIC_I2C_PROT_ADDRESS, 0x0B, 0xFB); // Check for the SDI2 to be low
delay_1us(1);
MCU_VMONOUT0 = B_PIN_STATE_HIGH; // Set SDI2 HIGH
// SDI3 Test
pmic_rtn_code_tmp = r_pmic_i2c_write(D_PMIC_I2C_PROT_ADDRESS, 0x0B, 0xFF); // Tell the PMIC to look for all SDIs to be high, to do this we set all bits (0xFF)
delay_1us(1);
MCU_VMONOUT1 = B_PIN_STATE_LOW; // Set SDI3 LOW
pmic_rtn_code_tmp = r_pmic_i2c_write(D_PMIC_I2C_PROT_ADDRESS, 0x0B, 0xFC); // Check for the SDI3 to be low
delay_1us(1);
MCU_VMONOUT1 = B_PIN_STATE_HIGH; // Set SDI3 HIGH
// SDI4 Test
pmic_rtn_code_tmp = r_pmic_i2c_write(D_PMIC_I2C_PROT_ADDRESS, 0x0B, 0xFF); // Tell the PMIC to look for all SDIs to be high, to do this we set all bits (0xFF)
delay_1us(1);
MCU_SDI4 = B_PIN_STATE_LOW; // Set SDI4 LOW
pmic_rtn_code_tmp = r_pmic_i2c_write(D_PMIC_I2C_PROT_ADDRESS, 0x0B, 0xFE); // Check for the SDI4 to be low
delay_1us(1);
MCU_SDI4 = B_PIN_STATE_HIGH; // Set SDI4 HIGH
comms_rtrncode_tmp = r_pmic_i2c_write(D_PMIC_I2C_PROT_ADDRESS, 0x0B, 0x00); // Must clear out 0x0B after external pin check 2 complete
*/
uint32_t data = 0xFF;
NOTICE("EXT PINCHECK2\n");
// SDI1,2,3,4 Test
// Tell the PMIC to look for all SDIs to be high, to do this we set all bits (0xFF)
i2c5_write(PMIC_ADDR_P, FUSA_CTRL_4, data);
micro_wait(1U);
// Must clear out 0x0B after external pin check 2 complete
i2c5_write(PMIC_ADDR_P, FUSA_CTRL_4, 0x0);
}
#define D_LENGTH_FUSA_CTRL_CVM 4 // Based on how many CVM slots is enabled
#define FUSA_CHK_CVM1 (0x0D)
#define CVM_TEST_START (1U << 0)
#define CVM_TEST_DONE (1U << 7)
#define FUSA_STATUS_CVM1 (0x0E)
#define CVM_TEST_FAIL_3 (0x3U << 6)
#define CVM_TEST_FAIL_2 (0x3U << 4)
#define CVM_TEST_FAIL_1 (0x3U << 2)
#define FUSA_STATUS_CVM2 (0x0F)
#define CVM_TEST_FAIL_6 (0x3U << 4)
#define CVM_TEST_FAIL_5 (0x3U << 2)
#define CVM_TEST_FAIL_4 (0x3U << 0)
#define FUSA_CHK_CVM2H (0x10D)
#define FUSA_CHK_CVM2L (0x10E)
#define FUSA_CHK_CVM3H (0x10F)
#define FUSA_CHK_CVM3L (0x110)
#define FUSA_CHK_CVM4H (0x111)
#define FUSA_CHK_CVM4L (0x112)
#define FUSA_CHK_CVM5H (0x113)
#define FUSA_CHK_CVM5L (0x114)
#define FUSA_CTRL_CVM1 (0x125)
#define FUSA_CTRL_CVM2 (0x126)
#define FUSA_CTRL_CVM3 (0x127)
#define FUSA_CTRL_CVM4 (0x128)
#define FUSA_CTRL_CVM5 (0x129)
#define FUSA_CTRL_CVM6 (0x12A)
#define ADCMON_MASK_ExtINPs (0x133)
#define FaultMask_EXT_0_Prot (1U << 0)
#define FaultMask_EXT_1_Prot (1U << 0)
// CVM Test
void PMIC_SM_27D(void) {
/*
//Array that holds the 8bit dac information ADC1
uint8_t g_ary_cvm_vthref[4] = {
0x0F, //2
0x3A, //3
0x60, //4
0x3A //3
};
//Array that holds the 12bit dac information ADC2
uint8_t g_ary_cvm_vthsense[8] = {
0x03, 0xE1,
0x00, 0xD3,
0x00, 0xD3,
0x03, 0xE1
};
D_LENGTH_FUSA_CTRL_CVM = 4; // Based on how many CVM slots is enabled
comms_rtn_code_tmp = r_pmic_i2c_write(D_PMIC_I2C_PROT_ADDRESS, 0x0D, 0x01); // Start CVM Test
delay_1ms(1);
for(idx = 0; idx <D_LENGTH_FUSA_CTRL_CVM; idx++){
write_data_buffer[0] = g_ary_cvm_vthsense[idx2];
write_data_buffer[1] = g_ary_cvm_vthsense[idx2+1];
dac8_value_tmp = g_ary_cvm_vthref[idx];
dac_i2c_tmp = R_IICA0_Master_Send(0x60 << 1, (uint8_t * )write_data_buffer , 2, 50); // Write to external DAC (ADC2)
delay_1ms(1);
idx2 += 2;
R_DAC0_Set_ConversionValue(dac8_value_tmp); // Write to internal DAC (ADC1)
g_ary_fusa_chk_cvm_status[idx] = r_pmic_i2c_read(D_PMIC_I2C_PROT_ADDRESS, 0x0D);
comms_rtn_code_tmp = r_pmic_i2c_write(D_PMIC_I2C_PROT_ADDRESS, 0x0D, 0x01); // Start next slot test
delay_1ms(2);
}
// Check to see if CVM passed
pmic_data_tmp = r_pmic_i2c_read(D_PMIC_I2C_PROT_ADDRESS, 0x0D);
while(pmic_data_tmp != 0x80 ){
pmic_data_tmp = r_pmic_i2c_read(D_PMIC_I2C_PROT_ADDRESS, 0x0D);
pmic_data_tmp &= 0x80;
}
R_DAC0_Set_ConversionValue(26U); // Set ADC1 value back to be within protection limits
write_data_buffer[0] = 0x03;
write_data_buffer[1] = 0xF0;
dac_i2c_tmp = R_IICA0_Master_Send(0x60 << 1, (uint8_t * )write_data_buffer , 2, 200); // Set ADC2 value back to be within protection limits
*/
uint32_t data, data2;
i2c5_write(PMIC_ADDR_P, FUSA_CHK_CVM1, CVM_TEST_START);
for(int i = 0; i < D_LENGTH_FUSA_CTRL_CVM; i++) {
micro_wait(2U);
i2c5_write(PMIC_ADDR_P, FUSA_CHK_CVM1, CVM_TEST_START);
}
do {
i2c5_read(PMIC_ADDR_P, FUSA_CHK_CVM1, &data);
} while ((data & CVM_TEST_DONE) == 0);
i2c5_read(PMIC_ADDR_P, FUSA_STATUS_CVM1, &data);
i2c5_read(PMIC_ADDR_P, FUSA_STATUS_CVM2, &data2);
NOTICE("CVM Test: 0x%x, 0x%x\n", data, data2);
}
#define FUSA_STATUS_1 (0x10)
#define SOC_ACTIVATED (1U << 4)
#define SCS_POWER_OFF (0x0 << 5)
#define SCS_SELF_DIAG (0x1 << 5)
#define SCS_POWER_UP (0x2 << 5)
#define SCS_SOC_ACTIV (0x3 << 5)
#define SCS_ACTIVE (0x4 << 5)
#define SCS_RESET (0x5 << 5)
#define SCS_ERROR (0x6 << 5)
#define SCS_LOCK (0x7 << 5)
#define SAS_IDLE (0x0)
#define SAS_EXT_PIN_CHK_1 (0x4)
#define SAS_SINT_CHK (0x5)
#define SAS_EXT_PIN_CHK_2 (0x6)
#define SAS_START_WDT (0x7)
void check_SoC_Activation(void) {
#if LOG_LEVEL >= LOG_NOTICE
uint32_t data = 0xFF;
char *str, *str2, *str3;
i2c5_read(PMIC_ADDR_P, FUSA_STATUS_1, &data);
if ((data & SOC_ACTIVATED) != 0)
str = "PASSED";
else
str = "FAILED";
switch (data & (0x7 << 5)) {
case SCS_POWER_OFF: str2 = "power off"; break;
case SCS_SELF_DIAG: str2 = "self diagnosis"; break;
case SCS_POWER_UP : str2 = "power up sequence"; break;
case SCS_SOC_ACTIV: str2 = "SoC activation"; break;
case SCS_ACTIVE: str2 = "ACTIVE"; break;
case SCS_RESET: str2 = "RESET"; break;
case SCS_ERROR: str2 = "ERROR"; break;
case SCS_LOCK: str2 = "LOCK"; break;
default:
str2 = "unknown";
break;
}
switch (data & 0x7) {
case SAS_IDLE: str3 = "idle"; break;
case SAS_EXT_PIN_CHK_1: str3 = "EXT PIN check(1)"; break;
case SAS_SINT_CHK: str3 = "SINT check"; break;
case SAS_EXT_PIN_CHK_2: str3 = "EXT PIN check(2)"; break;
case SAS_START_WDT: str3 = "start WDT"; break;
default:
str3 = "unknown";
break;
}
NOTICE("SoC Activation: %s(%s), %s, 0x%x\n", str, str3, str2, data);
#endif
}
#define WDT_KICK_REG (0x95)
#define WDT_LFSR (0x96)
#define WDT_CFG0 (0x107)
#define WDT_CFG0_QNA (0x1 << 2)
#define WDT_CFG0_16QNA (0x1 << 1)
#define WDT_CFG0_EN (0x1 << 0)
#define WDT_CFG3 (0x10A)
void PMIC_SM_12_wdt(void) {
uint32_t tmp, question, answer0;
i2c5_read(PMIC_ADDR_P, WDT_CFG0, &tmp);
if ((tmp & WDT_CFG0_EN) == 0) {
NOTICE("WDT is disabled\n");
i2c5_read(PMIC_ADDR_P, 0x01, &tmp); /* set PAGE to 0x00 */
return;
}
i2c5_read(PMIC_ADDR_P, WDT_LFSR, &question); // Read the question
if ((tmp & WDT_CFG0_16QNA) == 0) {
// Grab only the first two bits to figure out what to do
tmp = question >> 6;
answer0 = question & 0x3F;
micro_wait(4U);
if (tmp == 0x1) {
answer0 = (answer0 << 1) | (tmp << 6);
} else if (tmp == 0x2) {
answer0 = (answer0 >> 1) | (tmp << 6);
} else if (tmp == 0x3) {
answer0 = (~answer0) | (tmp << 6);
} /* else if (tmp == 0x0) {
// answer0 = (answer0) | (tmp << 6);
} */
i2c5_write(PMIC_ADDR_P, WDT_KICK_REG, answer0);
NOTICE("4Q&A: DONE\n");
} else {
static uint8_t g_ary_wdt_answer[] = {
0x00, 0x4F, 0x16, 0x59,
0x8a, 0xc5, 0x9c, 0xd3,
0x2d, 0x62, 0x3b, 0x74,
0xa7, 0xe8, 0xb1, 0xfe,
};
uint32_t err_cnt = 0;
// Grab the upper nibble to respond to, logic shift the lower nibble away
tmp = question >> 4;
answer0 = g_ary_wdt_answer[tmp];
i2c5_write(PMIC_ADDR_P, WDT_KICK_REG, answer0);
i2c5_read(PMIC_ADDR_P, WDT_CFG3, &question);
err_cnt |= (question & 0xFF) << 24; // Check WDT Error counter
micro_wait(4U);
// For the second answer, take the first answer and flip the upper nibble
i2c5_write(PMIC_ADDR_P, WDT_KICK_REG, (answer0 ^ 0xF0) & 0xFF);
i2c5_read(PMIC_ADDR_P, WDT_CFG3, &question);
err_cnt |= (question & 0xFF) << 16; // Check WDT Error counter
micro_wait(4U);
// For the third answer, take the first answer and flip the lower nibble
i2c5_write(PMIC_ADDR_P, WDT_KICK_REG, (answer0 ^ 0x0F) & 0xFF);
i2c5_read(PMIC_ADDR_P, WDT_CFG3, &question);
err_cnt |= (question & 0xFF) << 8; // Check WDT Error counter
micro_wait(4U);
// For the fourth answer, take the first answer and invert the whole byte
i2c5_write(PMIC_ADDR_P, WDT_KICK_REG, (answer0 ^ 0xFF) & 0xFF);
i2c5_read(PMIC_ADDR_P, WDT_CFG3, &question);
err_cnt |= (question & 0xFF) << 0; // Check WDT Error counter
if (err_cnt) {
NOTICE("16Q&A: Error 0x%x\n", err_cnt);
} else {
NOTICE("16Q&A: DONE\n");
}
i2c5_read(PMIC_ADDR_P, 0x01, &tmp); /* set PAGE to 0x00 */
}
}
// External Pin Check for ECM
void SM_6_3_1(void) {}
// External Pin Check for RST
void SM_6_3_2(void) {}
// initial Toggle Test
void SM_5_3_6(void) {}
// check POST result of other than "stop" type hierachies
void SM_5_1(void) {}
// read Back Test for Integrity Check
void SM_6_23(void) {}
// self test for AES-ACC
void SM_4_21(void) {}
// self check for Field BIST
void SM_5_1_6(void) {}
// self check for Field BIST
void SM_5_2_6(void) {}
// write access protection check at start-up
void SM_6_2(void) {}
// timeout monitoring for confirmation of PHY start
void SM_6_11(void) {}
// initial loopback test using PWM
void SM_6_14_6(void) {}
// integrity check for Program Code
void SM_6_22(void) {}
// start-up test for THS
void SM_6_24_2(void) {}
// start-up test for CVM
void SM_6_24_3(void) {}
// Power isolation Cell Error Detector Test at start-up
void SM_6_29(void) {}
// clock monitor test at start-up
void SM_6_30(void) {}

View File

@@ -0,0 +1,109 @@
/*******************************************************************************
* 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 2023-2024 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : System Controller function
******************************************************************************/
/******************************************************************************
* @file sysc.c
* - Version : 0.04
* @brief
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 29.09.2023 0.01 First Release
* : 13.11.2023 0.02 Add software reset
* : 16.11.2023 0.03 Add APSREG initialization process.
* : 22.10.2024 0.04 Update the C4 power domain setting process.
*****************************************************************************/
#include "mem_io.h"
#include "sysc.h"
#include "cpg_register.h"
#include "log.h"
#include "cpu_on.h"
#include "ap_system_core_register.h"
/*
* V4M turns on C4 power before starting CA
* V4M HWM:SYSC:Operation:Power Control of Non Arm CPU Modules
*/
#if (RCAR_LSI == RCAR_V4M)
void sysc_c4_power_on(void)
{
uint32_t reg;
/*
* Need to execute APSREG initialization before C4 power on according to
* R-Car V4M Series User's Manual '5.4.3 Register Initialization Before C4 power on'.
*/
reg = mem_read32(ap_core_get_ap_cluster_n_aux0_addr(0U));
reg |= AP_CORE_APSREG_AP_CLUSTER_N_AUX0_INIT;
mem_write32(ap_core_get_ap_cluster_n_aux0_addr(0U), reg);
reg = mem_read32(AP_CORE_APSREG_CCI500_AUX);
reg |= AP_CORE_APSREG_CCI500_AUX_ACTDIS;
mem_write32(AP_CORE_APSREG_CCI500_AUX, reg);
/* 1.Write the set value in SYSCIER0 and SYSCIMR0 */
reg = mem_read32(SYSC_SYSCIER0);
mem_write32(SYSC_SYSCIER0, reg | SYSCIER0_PDR31);
reg = mem_read32(SYSC_SYSCIMR0);
mem_write32(SYSC_SYSCIMR0, reg | SYSCIMR0_PDR31);
/* 2.Confirm that SYSCSR.BUSY[1] becomes 1.*/
while (true)
{
reg = mem_read32(SYSC_SYSCSR);
if (SYSCSR_BUSY1 == (reg & SYSCSR_BUSY1))
{
break;
}
}
/* 3.Write the reset value in SRCR11 and SESTCLR11 */
reg = mem_read32(CPG_SRCR11);
mem_write32(CPG_SRCR11, reg | CPGSRCR_PDR11);
mem_write32(CPG_SRSTCLR11, CPGSRCR_PDR11);
/* 4.Write the set value in PDRONCR31 */
mem_write32(SYSC_PDRONCR31, PDRONCR31_PWRON);
/* 5.Confirm that SYSCISCR0.PDR[31] becomes 1.*/
while (true)
{
reg = mem_read32(SYSC_SYSCISCR0);
if (SYSCISCR0_PDR31 == (reg & SYSCISCR0_PDR31))
{
break;
}
}
/* 6.Clear the bit31(PDR[31]) in SYSCISCR0 to 0. */
mem_write32(SYSC_SYSCISCR0, SYSCISCR0_PDR31);
}
/* End of function sysc_c4_power_on(void) */
#endif /* RCAR_LSI == RCAR_V4M */

View File

@@ -0,0 +1,101 @@
/*******************************************************************************
* DESCRIPTION : RCLK watchdog timer driver
******************************************************************************/
/******************************************************************************
* @file rwdt.c
* - Version : 0.014
* @brief RCLK Watchdog Timer driver
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 29.04.2025 0.01 First Release
*****************************************************************************/
#include <stdint.h>
#include <wdt.h>
#include <wdt_register.h>
#include <mem_io.h>
#include <intc.h>
#include <intc_id.h>
#include <log.h>
/* Initialization RCLK Watchdog Timer, see 154.1.3 Operation of h/w manual */
void rwdt_init(int start)
{
uint8_t wdta_val;
wdta_val = mem_read8(RWDT_RWTCSRA);
if (((wdta_val & RWTCSRA_TME) != 0) && start) {
wdta_val &= ~(RWTCSRA_TME);
mem_write32(RWDT_RWTCSRA, RWTCSRA_UPPER | wdta_val);
mem_write32(RWDT_RWTCNT, RWTCNT_UPPER | 0x0U);
wdta_val = mem_read8(RWDT_RWTCSRA);
wdta_val &= ~(RWTCSRA_WOVF);
mem_write32(RWDT_RWTCSRA, RWTCSRA_UPPER | wdta_val);
/* skip set CKS0, CKS1 */
}
do {
wdta_val = mem_read8(RWDT_RWTCSRA);
} while ((wdta_val & RWTCSRA_WRFLG) != 0);
/* start the counting by setting the TME bit in RWTCSRA to 1 */
/*
if (start) {
wdta_val |= RWTCSRA_TME;
mem_write32(RWDT_RWTCSRA, RWTCSRA_UPPER | wdta_val);
}
*/
}
/*
void rwdt_update(void)
{
mem_write32(RWDT_RWTCNT, RWTCNT_UPPER | 0U);
}
// RWTCNT overflow
void rwdt_handler(void)
{
uint8_t wdta_val;
wdta_val = mem_read8(RWDT_RWTCSRA);
if ((wdta_val & RWTCSRA_WOVF) != 0) {
// it's overflowed.
}
// RWTCNT, RWTCSRA, RWTCSRB are initialized.
// should we run rwdt_init() again?
}
*/
/* Initialization System Watchdog Timer */
void swdt_init(int start)
{
uint8_t wdta_val;
wdta_val = mem_read8(SWDT_SWTCSRA);
if (((wdta_val & RWTCSRA_TME) != 0) && start) {
wdta_val &= ~(RWTCSRA_TME);
mem_write32(SWDT_SWTCSRA, RWTCSRA_UPPER | wdta_val);
mem_write32(SWDT_SWTCNT, RWTCNT_UPPER | 0x0U);
wdta_val = mem_read8(SWDT_SWTCSRA);
wdta_val &= ~(RWTCSRA_WOVF);
mem_write32(SWDT_SWTCSRA, RWTCSRA_UPPER | wdta_val);
/* skip set CKS0, CKS1 */
}
do {
wdta_val = mem_read8(SWDT_SWTCSRA);
} while ((wdta_val & RWTCSRA_WRFLG) != 0);
/* start the counting by setting the TME bit in SWTCSRA to 1 */
/* do nothing */
}

View File

@@ -0,0 +1,148 @@
/*******************************************************************************
* 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 2022-2023 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : window watchdog timer driver
******************************************************************************/
/******************************************************************************
* @file wdt.c
* - Version : 0.04
* @brief Window Watchdog Timer driver
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 28.07.2021 0.01 First Release
* : 06.01.2022 0.02 Add exception handling for ICUMX_WDTA.
* : 20.01.2022 0.03 Add ICUMX name unification.
* : 11.01.2023 0.04 Modify activation code writing to
* : ICUMX_WDTA0EVAC register.
*****************************************************************************/
#include <stdint.h>
#include <wdt.h>
#include <mem_io.h>
#include <intc.h>
#include <intc_id.h>
#include <log.h>
#define ICUMX_WDTA0_BASE (0xFFFEE080U) /* Watchdog Timer base */
#define ICUMX_WDTA0WDTE (ICUMX_WDTA0_BASE)
#define ICUMX_WDTA0EVAC (ICUMX_WDTA0_BASE+0x0004U)
#define ICUMX_WDTA0REF (ICUMX_WDTA0_BASE+0x0008U)
#define ICUMX_WDTA0MD (ICUMX_WDTA0_BASE+0x000CU)
#define WDTA0MD_WDTA0WIE (1U<<3) /* Enables the 75% interrupt request INTWDTA0 */
#define WDTA0MD_WDTA0ERM (1U<<2) /* 0:NMI request mode 1:Reset mode */
#define WDTA0MD_WDTA0WS10 (3U) /* 11B: window-open period is 100% */
/* overflow time setting */
#define WDT_11MS (0x0U)
#define WDT_23MS (0x1U)
#define WDT_46MS (0x2U)
#define WDT_93MS (0x3U)
#define WDT_187MS (0x4U)
#define WDT_374MS (0x5U)
#define WDT_749MS (0x6U)
#define WDT_1498MS (0x7U)
/* Activation code */
#define WDT_ACT_CODE (0xACU)
/* ICUMX Configuration Register */
#define ICUMX_CFG4 (0xFFFEE270U)
/* Bit definition for Configuration Register */
#define ICUMX_CFG4_ICUMOPWDVAC (0x00000020U)
/* Initialization Window Watchdog Timer */
void wdt_init(void)
{
uint8_t wdta_val;
/* This API is executed before copying a part of Loader to Local RAM. */
/* Therefore, this API can not use the Memory mapped I/O API. */
/* When reading or writing memory, execute the same processing as */
/* Memory mapped I/O API in this function. */
wdta_val = WDTA0MD_WDTA0ERM; /* NMI request mode */
wdta_val |= WDTA0MD_WDTA0WIE; /* Enables the 75% interrupt request INTWDTA0 */
wdta_val |= WDTA0MD_WDTA0WS10;
wdta_val |= (WDT_1498MS << 4U); /* overflow interval time */
mem_write8(ICUMX_WDTA0MD, wdta_val);
/* set watchdog timer handler */
intc_set_interrupt(WDT0_INT, 7U, (INT_HANDLER)wdt_handler);
/* watchdog timer restart */
wdt_restart();
}
/* End of function wdt_init(uint32_t overflow_time) */
void wdt_restart(void)
{
uint8_t reg8;
uint32_t reg32;
reg32 = mem_read32(ICUMX_CFG4);
if((reg32 & ICUMX_CFG4_ICUMOPWDVAC) != 0U)
{
reg8 = mem_read8(ICUMX_WDTA0REF);
reg8 = WDT_ACT_CODE - reg8;
/* Watchdog Timer restart. */
/* Subtract ICUMX_WDTA0REF from activation code when VAC(Variable Activation Code) is enabled. */
mem_write8(ICUMX_WDTA0EVAC, reg8);
}
else
{
/* Watchdog Timer restart. */
mem_write8(ICUMX_WDTA0EVAC, WDT_ACT_CODE);
}
}
/* End of function wdt_restart(void) */
#include <micro_wait.h>
#include <rst_register.h>
#define RST_SRESCR0 (RST_BASE + 0x18)
#define RST_SPRES 0x5AA58000UL
/* Interrupt handling function */
void wdt_handler(void)
{
intc_disable_interrupt(WDT0_INT);
ERROR("\n");
ERROR("ICUMX: System WDT overflow\n");
#ifdef WDT_RESET
micro_wait(11*1000U); /* wait 11 miliseconds */
/* try to reset */
mem_write32(RST_SRESCR0, RST_SPRES);
#else
#warning "WDT_RESET is not defined. System will not reset."
/* If WDT_RESET is not defined, the system will not reset. */
/* This is useful for debugging purposes, but in production, */
/* it is recommended to define WDT_RESET to ensure the system resets on WDT overflow. */
#endif
panic;
}
/* End of function wdt_handler(void) */