/******************************************************************************* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #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) */