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,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 */