diff --git a/bsp/board/bl808dk/board.c b/bsp/board/bl808dk/board.c index 214856ad..06ab19b9 100644 --- a/bsp/board/bl808dk/board.c +++ b/bsp/board/bl808dk/board.c @@ -5,10 +5,10 @@ #include "bflb_rtc.h" #include "mmheap.h" #include "bl808_glb.h" -// #include "bl808_psram_uhs.h" -// #include "bl808_tzc_sec.h" -// #include "bl808_ef_cfg.h" -// #include "bl808_uhs_phy.h" +#include "bl808_psram_uhs.h" +#include "bl808_tzc_sec.h" +#include "bl808_ef_cfg.h" +#include "bl808_uhs_phy.h" #include "board.h" #ifdef CONFIG_BSP_SDH_SDCARD diff --git a/drivers/soc/bl808/CMakeLists.txt b/drivers/soc/bl808/CMakeLists.txt index 2e004d12..9fae19f4 100644 --- a/drivers/soc/bl808/CMakeLists.txt +++ b/drivers/soc/bl808/CMakeLists.txt @@ -15,11 +15,11 @@ sdk_library_add_sources(bl808_std/src/bl808_hbn.c) sdk_library_add_sources(bl808_std/src/bl808_pds.c) sdk_library_add_sources(bl808_std/src/bl808_sdh.c) -# sdk_library_add_sources(bl808_std/src/bl808_tzc_sec.c) -# sdk_library_add_sources(bl808_std/src/bl808_ef_ctrl.c) -# sdk_library_add_sources(bl808_std/src/bl808_ef_cfg.c) -# sdk_library_add_sources(bl808_std/src/bl808_psram_uhs.c) -# sdk_library_add_sources(bl808_std/src/bl808_uhs_phy.c) +sdk_library_add_sources(bl808_std/src/bl808_tzc_sec.c) +sdk_library_add_sources(bl808_std/src/bl808_ef_ctrl.c) +sdk_library_add_sources(bl808_std/src/bl808_ef_cfg.c) +sdk_library_add_sources(bl808_std/src/bl808_psram_uhs.c) +sdk_library_add_sources(bl808_std/src/bl808_uhs_phy.c) sdk_library_add_sources(port/bl808_clock.c) sdk_add_include_directories( diff --git a/drivers/soc/bl808/bl808_std/include/bl808_psram.h b/drivers/soc/bl808/bl808_std/include/bl808_psram.h new file mode 100644 index 00000000..f199d599 --- /dev/null +++ b/drivers/soc/bl808/bl808_std/include/bl808_psram.h @@ -0,0 +1,488 @@ +/** + ****************************************************************************** + * @file bl808_psram.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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. + * + ****************************************************************************** + */ +#ifndef __BL808_PSRAM_CTRL_H__ +#define __BL808_PSRAM_CTRL_H__ + +#include "psram_reg.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup PSRAM_CTRL + * @{ + */ + +/** @defgroup PSRAM_CTRL_Public_Types + * @{ + */ + +/** + * @brief PSRAM ID + */ +typedef enum { + PSRAM0_ID, /*!< PSRAM0 identifier */ +} PSRAM_ID_Type; + +/** + * @brief PSRAM Ctrl IO mode type definition + */ +typedef enum { + PSRAM_CTRL_X8_MODE, /*!< PSRAM X8 mode */ + PSRAM_CTRL_X16_MODE, /*!< PSRAM X16 mode */ +} PSRAM_Ctrl_Io_Mode_Type; + +/** + * @brief PSRAM Ctrl PSRAM vendor type definition + */ +typedef enum { + PSRAM_CTRL_VENDOR_WINBOND = 0x1, /*!< Winbond psram */ + PSRAM_CTRL_VENDOR_APMEM_EXCLUDE_4MB = 0x2, /*!< AP memory psram exclude 4MB size */ + PSRAM_CTRL_VENDOR_APMEM_4MB = 0x4, /*!< AP memory psram 4MB size */ +} PSRAM_Ctrl_Vendor_Type; + +/** + * @brief PSRAM SIZE + */ +typedef enum { + PSRAM_SIZE_4MB = 0x3, /*!< PSRAM size is 4MB */ + PSRAM_SIZE_8MB = 0x7, /*!< PSRAM size is 8MB */ + PSRAM_SIZE_16MB = 0xf, /*!< PSRAM size is 16MB */ + PSRAM_SIZE_32MB = 0x1f, /*!< PSRAM size is 32MB */ +} PSRAM_Ctrl_Size_Type; + +/** + * @brief Winbond PSRAM configuration register type definition + */ +typedef enum { + PSRAM_WINBOND_REG_ID0, /*!< Winbond register ID0 */ + PSRAM_WINBOND_REG_ID1, /*!< Winbond register ID1 */ + PSRAM_WINBOND_REG_CR0, /*!< Winbond register CR0 */ + PSRAM_WINBOND_REG_CR1, /*!< Winbond register CR1 */ + PSRAM_WINBOND_REG_CR2, /*!< Winbond register CR2 */ + PSRAM_WINBOND_REG_CR3, /*!< Winbond register CR3 */ + PSRAM_WINBOND_REG_CR4, /*!< Winbond register CR4 */ +} PSRAM_Ctrl_Winbond_Cfg_Reg_Type; + +/** + * @brief APMemory PSRAM configuration register type definition + */ +typedef enum { + PSRAM_APMEM_REG_0 = 0, /*!< APMemory register 0 */ + PSRAM_APMEM_REG_1, /*!< APMemory register 1 */ + PSRAM_APMEM_REG_2, /*!< APMemory register 2 */ + PSRAM_APMEM_REG_3, /*!< APMemory register 3 */ + PSRAM_APMEM_REG_4, /*!< APMemory register 4 */ + PSRAM_APMEM_REG_5, /*!< APMemory register 5 */ + PSRAM_APMEM_REG_6, /*!< APMemory register 6 */ + PSRAM_APMEM_REG_8, /*!< APMemory register 8 */ +} PSRAM_Ctrl_ApMem_Cfg_Reg_Type; + +/** + * @brief PSRAM Latency Counter type definition + */ +typedef enum { + PSRAM_WINBOND_5_CLOCKS_LATENCY, /*!< PSRAM 5 clocks latency 133MHZ */ + PSRAM_WINBOND_6_CLOCKS_LATENCY, /*!< PSRAM 6 clocks latency 166MHZ */ + PSRAM_WINBOND_7_CLOCKS_LATENCY, /*!< PSRAM 7 clocks latency 200MHZ */ + PSRAM_WINBOND_3_CLOCKS_LATENCY = 0xE, /*!< PSRAM 3 clocks latency 83MHZ */ + PSRAM_WINBOND_4_CLOCKS_LATENCY = 0xF, /*!< PSRAM 4 clocks latency 100MHZ */ + PSRAM_WINBOND_14_CLOCKS_LATENCY = 0x7, /*!< PSRAM 14 clocks latency only for Hyperbus3 400MHZ */ + PSRAM_WINBOND_19_CLOCKS_LATENCY = 0x9, /*!< PSRAM 19 clocks latency only for Hyperbus3 533MHZ */ +} PSRAM_Latency_Winbond_Type; + +/** + * @brief PSRAM Burst Type + */ +typedef enum { + PSRAM_HYBRID_BURST, /*!< PSRAM use hybrid brust */ + PSRAM_WRAPPED_BURST, /*!< PSRAM use warpped brust */ +} PSRAM_Burst_Type; + +/** + * @brief PSRAM Latency Counter type definition + */ +typedef enum { + PSRAM_APMEM_3_CLOCKS_LATENCY, /*!< PSRAM 3 clocks latency */ + PSRAM_APMEM_4_CLOCKS_LATENCY = 0x4, /*!< PSRAM 4 clocks latency */ + PSRAM_APMEM_5_CLOCKS_LATENCY = 0x2, /*!< PSRAM 5 clocks latency */ + PSRAM_APMEM_6_CLOCKS_LATENCY = 0x6, /*!< PSRAM 6 clocks latency */ + PSRAM_APMEM_7_CLOCKS_LATENCY = 0x1, /*!< PSRAM 7 clocks latency */ +} PSRAM_Latency_ApMem_Type; + +/** + * @brief PSRAM Drive Strength type definition for Winbon 4M + */ +typedef enum { + PSRAM_WINBOND_DRIVE_STRENGTH_50_OHMS_FOR_4M_34_OHMS_FOR_8M, /*!< drive strength 50 ohms for 4M size ,34 ohms for 8M size */ + PSRAM_WINBOND_DRIVE_STRENGTH_35_OHMS_FOR_4M_115_OHMS_FOR_8M, /*!< drive strength 35 ohms for 4M size ,115 ohms for 8M size */ + PSRAM_WINBOND_DRIVE_STRENGTH_100_OHMS_FOR_4M_67_OHMS_FOR_8M, /*!< drive strength 100 ohms for 4M size ,67 ohms for 8M size */ + PSRAM_WINBOND_DRIVE_STRENGTH_200_OHMS_FOR_4M_46_OHMS_FOR_8M, /*!< drive strength 200 ohms for 4M size ,46 ohms for 8M size */ + PSRAM_DRIVE_STRENGTH_34_OHMS_ONLY_FOR_8M, /*!< drive strength 34 ohms only for 8M size */ + PSRAM_DRIVE_STRENGTH_27_OHMS_ONLY_FOR_8M, /*!< drive strength 27 ohms only for 8M size */ + PSRAM_DRIVE_STRENGTH_22_OHMS_ONLY_FOR_8M, /*!< drive strength 22 ohms only for 8M size */ + PSRAM_DRIVE_STRENGTH_19_OHMS_ONLY_FOR_8M, /*!< drive strength 19 ohms only for 8M size */ +} PSRAM_Winbond_Drive_Strength; + +/** + * @brief PSRAM Drive Strength type definition for Winbon 8MB + */ +typedef enum { + PSRAM_APMEM_DRIVE_STRENGTH_25_OHMS, /*!< drive strength 25 ohms */ + PSRAM_APMEM_DRIVE_STRENGTH_50_OHMS, /*!< drive strength 50 ohms */ + PSRAM_APMEM_DRIVE_STRENGTH_100_OHMS, /*!< drive strength 100 ohms */ + PSRAM_APMEM_DRIVE_STRENGTH_200_OHMS, /*!< drive strength 200 ohms */ +} PSRAM_ApMem_Drive_Strength; + +/** + * @brief PSRAM Burst Length type definition + */ +typedef enum { + PSRAM_WINBOND_BURST_LENGTH_128_BYTES = 0x4, /*!< Burst Length 128 bytes */ + PSRAM_WINBOND_BURST_LENGTH_64_BYTES, /*!< Burst Length 64 bytes */ + PSRAM_WINBOND_BURST_LENGTH_16_BYTES, /*!< Burst Length 16 bytes */ + PSRAM_WINBOND_BURST_LENGTH_32_BYTES, /*!< Burst Length 32 bytes */ + PSRAM_WINBOND_BURST_LENGTH_512_BYTES, /*!< Burst Length 512 only for HyperBus3 */ +} PSRAM_Winbond_Burst_Length; + +/** + * @brief PSRAM Burst Length type definition + */ +typedef enum { + PSRAM_APMEM_BURST_LENGTH_16_BYTES, /*!< Burst Length 16 bytes */ + PSRAM_APMEM_BURST_LENGTH_32_BYTES, /*!< Burst Length 32 bytes */ + PSRAM_APMEM_BURST_LENGTH_64_BYTES, /*!< Burst Length 64 bytes */ + PSRAM_APMEM_BURST_LENGTH_1K_FOR_APS64_2K_FOR_APS256, /*!< Burst Length 1K bytes for APS6408L and 2Kbytes for APS256XXN */ +} PSRAM_ApMem_Burst_Length; + +/** + * @brief PSRAM Fixed Latency Enable type definition + */ +typedef enum { + PSRAM_VARIALBE_INITIAL_LATENCY, /*!< 1 or 2 times Initial Latency depending on RWDS during CA cycles */ + PSRAM_FIXED_2_TIMES_INITIAL_LATENCY, /*!< Fixed 2 times Initial Latency (default) */ +} PSRAM_Fixed_Latency_Enable; + +/** + * @brief PSRAM Deep Power Down Enable type definition + */ +typedef enum { + PSRAM_DPD_ENTER, /*!< Writing 0 to CR0[15] causes the device to enter Deep Power Down */ + PSRAM_DPD_NORMAL, /*!< Normal operation (default) */ +} PSRAM_Deep_Power_Down; + +/** + * @brief Partial Array Self Refresh definition + */ +typedef enum { + PSRAM_PARTIAL_REFRESH_FULL, /*!< PSRAM partial refresh full array (000000h - 1FFFFFh) */ + PSRAM_PARTIAL_REFRESH_BOTTOM_1TO2, /*!< PSRAM partial refresh Bottom 1/2 array (000000h - 0FFFFFh) */ + PSRAM_PARTIAL_REFRESH_BOTTOM_1TO4, /*!< PSRAM partial refresh Bottom 1/4 array (000000h - 07FFFFh) */ + PSRAM_PARTIAL_REFRESH_BOTTOM_1TO8, /*!< PSRAM partial refresh Bottom 1/8 array (000000h - 03FFFFh) */ + PSRAM_PARTIAL_REFRESH_NONE, /*!< PSRAM partial refresh None */ + PSRAM_PARTIAL_REFRESH_TOP_1TO2, /*!< PSRAM partial refresh Top 1/2 array (100000h - 1FFFFFh) */ + PSRAM_PARTIAL_REFRESH_TOP_1TO4, /*!< PSRAM partial refresh Top 1/4 array (180000h - 1FFFFFh) */ + PSRAM_PARTIAL_REFRESH_TOP_1TO8, /*!< PSRAM partial refresh Top 1/8 array (1C0000h - 1FFFFFh) */ +} PSRAM_Partial_Array_Refresh; + +/** + * @brief PSRAM ApMem self-fresh freq + */ +typedef enum { + PSRAM_APMEM_FAST_REFRESH, /*!< Fast Refresh (default) */ + PSRAM_APMEM_SLOW_REFRESH, /*!< Enables Slow Refresh when temperature allows */ +} PSRAM_ApMem_Refresh_Speed; + +/** + * @brief PSRAM Hybrid Sleep Mode type definition + */ +typedef enum { + PSRAM_HYBRID_SLEEP_DISABLE, /*!< not in Hybrid Sleep Mode */ + PSRAM_HYBRID_SLEEP_ENABLE, /*!< entering Hybrid Sleep Mode */ +} PSRAM_Hybrid_Sleep_Mode; + +/** + * @brief PSRAM Master Clock type definition + */ +typedef enum { + PSRAM_CLOCK_DIFF, /*!< PSRAM Master Clock is differential */ + PSRAM_CLOCK_SINGLE, /*!< PSRAM Master Clock is single end */ +} PSRAM_Clock_Type; + +/** + * @brief PSRAM delay chain configuration definition + */ +typedef struct +{ + PSRAM_Ctrl_Vendor_Type vendor; /*!< PSRAM Vendor */ + PSRAM_Ctrl_Io_Mode_Type ioMode; /*!< PSRAM interface mode */ + PSRAM_Ctrl_Size_Type size; /*!< PSRAM size */ + uint32_t dqs_delay; /*!< PSRAM dqs delay value */ +} PSRAM_Ctrl_Cfg_Type; + +/** + * @brief PSRAM Winbon configuration definition + */ +typedef struct +{ + BL_Fun_Type rst; /*!< Winbond pSRAM CR1 - Software Reset */ + PSRAM_Clock_Type clockType; /*!< Winbond pSRAM CR1 - Master Clock Type */ + BL_Fun_Type inputPowerDownMode; /*!< Winbond pSRAM CR1 - Input Power Down */ + BL_Fun_Type linear_dis; /*!< Winbond pSRAM linear burst disable */ + BL_Fun_Type hybridSleepMode; /*!< Winbond pSRAM CR1 - Hybrid Sleep Mode configuration */ + PSRAM_Partial_Array_Refresh PASR; /*!< Winbond pSRAM CR1 - Partial Array Refresh + Distributed Refresh Interval */ + BL_Fun_Type disDeepPowerDownMode; /*!< Winbond pSRAM CR0 - Deep Power-Down Disable configuration */ + BL_Fun_Type fixedLatency; /*!< Winbond pSRAM CR1 - Fix Latency configuration */ + PSRAM_Winbond_Burst_Length brustLen; /*!< Winbond pSRAM CR0 - Burst Length configuration */ + PSRAM_Burst_Type brustType; /*!< Winbond pSRAM CR0 - Hybrid Burst Enable */ + PSRAM_Winbond_Drive_Strength driveStrength; /*!< Winbond pSRAM CR0 - Drive Strength configuration */ + PSRAM_Latency_Winbond_Type latency; /*!< Winbond pSRAM CR0 - Latency Counter configuration */ +} PSRAM_Winbond_Cfg_Type; + +/** + * @brief PSRAM Winbon configuration definition + */ +typedef struct +{ + BL_Fun_Type rst; /*!< AP Memory pSRAM configure global reset enable */ + BL_Fun_Type fixedLatency; /*!< AP Memory pSRAM configure MR0 - read latency type */ + PSRAM_Latency_ApMem_Type readLatency; /*!< AP Memory pSRAM configure MR0 - read latency code */ + PSRAM_ApMem_Refresh_Speed refreshFreq; /*!< AP Memory pSRAM configure MR4 - refresh frequency */ + PSRAM_ApMem_Drive_Strength driveStrength; /*!< AP Memory pSRAM configure MR0 - drive strength */ + PSRAM_Latency_ApMem_Type writeLatency; /*!< AP Memory pSRAM configure MR4 - write latency code */ + PSRAM_Partial_Array_Refresh PASR; /*!< AP Memory pSRAM configure MR4 - partial array refresh */ + BL_Fun_Type halfSleepModeEnable; /*!< AP Memory pSRAM configure MR6 - Half Sleep enable */ + BL_Fun_Type deepPowerDownModeEnable; /*!< AP Memory pSRAM configure MR6 - Deep Power Down enable */ + BL_Fun_Type crossBoundaryEnable; /*!< AP Memory pSRAM configure MR8 - cross boundary enable 1'b0 - Read within 1K boundary 1'b1 - + Read cross 1K boundary */ + PSRAM_Burst_Type brustType; /*!< AP Memory pSRAM configure MR8 - burst type */ + PSRAM_ApMem_Burst_Length brustLen; /*!< AP Memory pSRAM configure MR8 - burst length */ +} PSRAM_APMemory_Cfg_Type; + +/*@} end of group PSRAM_CTRL_Public_Types */ + +/** @defgroup PSRAM_CTRL_Public_Constants + * @{ + */ + +/** @defgroup PSRAM_ID_TYPE + * @{ + */ +#define IS_PSRAM_ID_TYPE(type) (((type) == PSRAM0_ID) || \ + ((type) == PSRAM1_ID)) + +/** @defgroup PSRAM_CTRL_IO_MODE_TYPE + * @{ + */ +#define IS_PSRAM_CTRL_IO_MODE_TYPE(type) (((type) == PSRAM_CTRL_X8_MODE) || \ + ((type) == PSRAM_CTRL_X16_MODE)) + +/** @defgroup PSRAM_CTRL_VENDOR_TYPE + * @{ + */ +#define IS_PSRAM_CTRL_VENDOR_TYPE(type) (((type) == PSRAM_CTRL_VENDOR_WINBOND) || \ + ((type) == PSRAM_CTRL_VENDOR_APMEM_EXCLUDE_4MB) || \ + ((type) == PSRAM_CTRL_VENDOR_APMEM_4MB)) + +/** @defgroup PSRAM_CTRL_SIZE_TYPE + * @{ + */ +#define IS_PSRAM_CTRL_SIZE_TYPE(type) (((type) == PSRAM_SIZE_4MB) || \ + ((type) == PSRAM_SIZE_8MB) || \ + ((type) == PSRAM_SIZE_16MB) || \ + ((type) == PSRAM_SIZE_32MB)) + +/** @defgroup PSRAM_CTRL_WINBOND_CFG_REG_TYPE + * @{ + */ +#define IS_PSRAM_CTRL_WINBOND_CFG_REG_TYPE(type) (((type) == PSRAM_WINBOND_REG_ID0) || \ + ((type) == PSRAM_WINBOND_REG_ID1) || \ + ((type) == PSRAM_WINBOND_REG_CR0) || \ + ((type) == PSRAM_WINBOND_REG_CR1) || \ + ((type) == PSRAM_WINBOND_REG_CR2) || \ + ((type) == PSRAM_WINBOND_REG_CR3) || \ + ((type) == PSRAM_WINBOND_REG_CR4)) + +/** @defgroup PSRAM_CTRL_APMEM_CFG_REG_TYPE + * @{ + */ +#define IS_PSRAM_CTRL_APMEM_CFG_REG_TYPE(type) (((type) == PSRAM_APMEM_REG_0) || \ + ((type) == PSRAM_APMEM_REG_1) || \ + ((type) == PSRAM_APMEM_REG_2) || \ + ((type) == PSRAM_APMEM_REG_3) || \ + ((type) == PSRAM_APMEM_REG_4) || \ + ((type) == PSRAM_APMEM_REG_5) || \ + ((type) == PSRAM_APMEM_REG_6) || \ + ((type) == PSRAM_APMEM_REG_8)) + +/** @defgroup PSRAM_LATENCY_WINBOND_TYPE + * @{ + */ +#define IS_PSRAM_LATENCY_WINBOND_TYPE(type) (((type) == PSRAM_WINBOND_5_CLOCKS_LATENCY) || \ + ((type) == PSRAM_WINBOND_6_CLOCKS_LATENCY) || \ + ((type) == PSRAM_WINBOND_7_CLOCKS_LATENCY) || \ + ((type) == PSRAM_WINBOND_3_CLOCKS_LATENCY) || \ + ((type) == PSRAM_WINBOND_4_CLOCKS_LATENCY) || \ + ((type) == PSRAM_WINBOND_14_CLOCKS_LATENCY) || \ + ((type) == PSRAM_WINBOND_19_CLOCKS_LATENCY)) + +/** @defgroup PSRAM_BURST_TYPE + * @{ + */ +#define IS_PSRAM_BURST_TYPE(type) (((type) == PSRAM_HYBRID_BURST) || \ + ((type) == PSRAM_WRAPPED_BURST)) + +/** @defgroup PSRAM_LATENCY_APMEM_TYPE + * @{ + */ +#define IS_PSRAM_LATENCY_APMEM_TYPE(type) (((type) == PSRAM_APMEM_3_CLOCKS_LATENCY) || \ + ((type) == PSRAM_APMEM_4_CLOCKS_LATENCY) || \ + ((type) == PSRAM_APMEM_5_CLOCKS_LATENCY) || \ + ((type) == PSRAM_APMEM_6_CLOCKS_LATENCY) || \ + ((type) == PSRAM_APMEM_7_CLOCKS_LATENCY)) + +/** @defgroup PSRAM_WINBOND_DRIVE_STRENGTH + * @{ + */ +#define IS_PSRAM_WINBOND_DRIVE_STRENGTH(type) (((type) == PSRAM_WINBOND_DRIVE_STRENGTH_50_OHMS_FOR_4M_34_OHMS_FOR_8M) || \ + ((type) == PSRAM_WINBOND_DRIVE_STRENGTH_35_OHMS_FOR_4M_115_OHMS_FOR_8M) || \ + ((type) == PSRAM_WINBOND_DRIVE_STRENGTH_100_OHMS_FOR_4M_67_OHMS_FOR_8M) || \ + ((type) == PSRAM_WINBOND_DRIVE_STRENGTH_200_OHMS_FOR_4M_46_OHMS_FOR_8M) || \ + ((type) == PSRAM_DRIVE_STRENGTH_34_OHMS_ONLY_FOR_8M) || \ + ((type) == PSRAM_DRIVE_STRENGTH_27_OHMS_ONLY_FOR_8M) || \ + ((type) == PSRAM_DRIVE_STRENGTH_22_OHMS_ONLY_FOR_8M) || \ + ((type) == PSRAM_DRIVE_STRENGTH_19_OHMS_ONLY_FOR_8M)) + +/** @defgroup PSRAM_APMEM_DRIVE_STRENGTH + * @{ + */ +#define IS_PSRAM_APMEM_DRIVE_STRENGTH(type) (((type) == PSRAM_APMEM_DRIVE_STRENGTH_25_OHMS) || \ + ((type) == PSRAM_APMEM_DRIVE_STRENGTH_50_OHMS) || \ + ((type) == PSRAM_APMEM_DRIVE_STRENGTH_100_OHMS) || \ + ((type) == PSRAM_APMEM_DRIVE_STRENGTH_200_OHMS)) + +/** @defgroup PSRAM_WINBOND_BURST_LENGTH + * @{ + */ +#define IS_PSRAM_WINBOND_BURST_LENGTH(type) (((type) == PSRAM_WINBOND_BURST_LENGTH_128_BYTES) || \ + ((type) == PSRAM_WINBOND_BURST_LENGTH_64_BYTES) || \ + ((type) == PSRAM_WINBOND_BURST_LENGTH_16_BYTES) || \ + ((type) == PSRAM_WINBOND_BURST_LENGTH_32_BYTES) || \ + ((type) == PSRAM_WINBOND_BURST_LENGTH_512_BYTES)) + +/** @defgroup PSRAM_APMEM_BURST_LENGTH + * @{ + */ +#define IS_PSRAM_APMEM_BURST_LENGTH(type) (((type) == PSRAM_APMEM_BURST_LENGTH_16_BYTES) || \ + ((type) == PSRAM_APMEM_BURST_LENGTH_32_BYTES) || \ + ((type) == PSRAM_APMEM_BURST_LENGTH_64_BYTES) || \ + ((type) == PSRAM_APMEM_BURST_LENGTH_1K_FOR_APS64_2K_FOR_APS256)) + +/** @defgroup PSRAM_FIXED_LATENCY_ENABLE + * @{ + */ +#define IS_PSRAM_FIXED_LATENCY_ENABLE(type) (((type) == PSRAM_VARIALBE_INITIAL_LATENCY) || \ + ((type) == PSRAM_FIXED_2_TIMES_INITIAL_LATENCY)) + +/** @defgroup PSRAM_DEEP_POWER_DOWN + * @{ + */ +#define IS_PSRAM_DEEP_POWER_DOWN(type) (((type) == PSRAM_DPD_ENTER) || \ + ((type) == PSRAM_DPD_NORMAL)) + +/** @defgroup PSRAM_PARTIAL_ARRAY_REFRESH + * @{ + */ +#define IS_PSRAM_PARTIAL_ARRAY_REFRESH(type) (((type) == PSRAM_PARTIAL_REFRESH_FULL) || \ + ((type) == PSRAM_PARTIAL_REFRESH_BOTTOM_1TO2) || \ + ((type) == PSRAM_PARTIAL_REFRESH_BOTTOM_1TO4) || \ + ((type) == PSRAM_PARTIAL_REFRESH_BOTTOM_1TO8) || \ + ((type) == PSRAM_PARTIAL_REFRESH_NONE) || \ + ((type) == PSRAM_PARTIAL_REFRESH_TOP_1TO2) || \ + ((type) == PSRAM_PARTIAL_REFRESH_TOP_1TO4) || \ + ((type) == PSRAM_PARTIAL_REFRESH_TOP_1TO8)) + +/** @defgroup PSRAM_APMEM_REFRESH_SPEED + * @{ + */ +#define IS_PSRAM_APMEM_REFRESH_SPEED(type) (((type) == PSRAM_APMEM_FAST_REFRESH) || \ + ((type) == PSRAM_APMEM_SLOW_REFRESH)) + +/** @defgroup PSRAM_HYBRID_SLEEP_MODE + * @{ + */ +#define IS_PSRAM_HYBRID_SLEEP_MODE(type) (((type) == PSRAM_HYBRID_SLEEP_DISABLE) || \ + ((type) == PSRAM_HYBRID_SLEEP_ENABLE)) + +/** @defgroup PSRAM_CLOCK_TYPE + * @{ + */ +#define IS_PSRAM_CLOCK_TYPE(type) (((type) == PSRAM_CLOCK_DIFF) || \ + ((type) == PSRAM_CLOCK_SINGLE)) + +/*@} end of group PSRAM_CTRL_Public_Constants */ + +/** @defgroup PSRAM_CTRL_Public_Macros + * @{ + */ + +/*@} end of group PSRAM_CTRL_Public_Macros */ + +/** @defgroup PSRAM_CTRL_Public_Functions + * @{ + */ +void PSram_Ctrl_Init(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Cfg_Type *psramCtrlCfg); +BL_Err_Type PSram_Ctrl_Winbond_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_Reg_Type reg_addr, uint16_t *regVal); +BL_Err_Type PSram_Ctrl_Winbond_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_Reg_Type reg_addr, + PSRAM_Winbond_Cfg_Type *reg_cfg); +BL_Err_Type PSram_Ctrl_ApMem_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_Type reg_addr, uint16_t *regVal); +BL_Err_Type PSram_Ctrl_ApMem_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_Type reg_addr, + PSRAM_APMemory_Cfg_Type *reg_cfg); +void PSram_Ctrl_ApMem_Reset(PSRAM_ID_Type PSRAM_ID); +void PSram_Ctrl_CK_Sel(PSRAM_ID_Type PSRAM_ID, PSRAM_Clock_Type clkSel); +void PSram_Ctrl_Winbond_Reset(PSRAM_ID_Type PSRAM_ID); +uint8_t PSram_Ctrl_Get_Timeout_Flag(PSRAM_ID_Type PSRAM_ID); +void PSram_Ctrl_Clear_Timout_Flag(PSRAM_ID_Type PSRAM_ID); +void PSram_Ctrl_Debug_Timout(PSRAM_ID_Type PSRAM_ID, uint8_t enable, uint32_t timeoutThr); + +/*@} end of group PSRAM_CTRL_Public_Functions */ + +/*@} end of group PSRAM_CTRL */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_PSRAM_CTRL_H__ */ diff --git a/drivers/soc/bl808/bl808_std/include/bl808_psram_uhs.h b/drivers/soc/bl808/bl808_std/include/bl808_psram_uhs.h new file mode 100644 index 00000000..df369258 --- /dev/null +++ b/drivers/soc/bl808/bl808_std/include/bl808_psram_uhs.h @@ -0,0 +1,273 @@ +/** + ****************************************************************************** + * @file bl808_psram_uhs.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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. + * + ****************************************************************************** + */ +#ifndef __BL808_PSRAM_UHS_H__ +#define __BL808_PSRAM_UHS_H__ + +#include "psram_uhs_reg.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup PSRAM_UHS + * @{ + */ + +/** @defgroup PSRAM_UHS_Public_Types + * @{ + */ + +/** + * @brief Psram UHS Size + */ +typedef enum { + PSRAM_MEM_SIZE_4MB = 0x03, /*!< PSRAM Memory Size 4M */ + PSRAM_MEM_SIZE_8MB = 0x07, /*!< PSRAM Memory Size 8M */ + PSRAM_MEM_SIZE_16MB = 0x0f, /*!< PSRAM Memory Size 16M */ + PSRAM_MEM_SIZE_32MB = 0x1f, /*!< PSRAM Memory Size 32M */ + PSRAM_MEM_SIZE_64MB = 0x3f, /*!< PSRAM Memory Size 64M */ +} PSRAM_UHS_Mem_Size_Type; + +/** + * @brief Psram UHS Page Type + */ +typedef enum { + PSRAM_PAGE_SIZE_2KB = 0x0B, /*!< PSRAM Page Size 2KB */ + PSRAM_PAGE_SIZE_4KB = 0x16, /*!< PSRAM Page Size 4KB */ +} PSRAM_UHS_Page_Size_Type; + +/** + * @brief Psram UHS Burst Size + */ +typedef enum { + PSRAM_UHS_WARP_BURST_64, /*!< PSRAM Warp Burst Size 64 */ + PSRAM_UHS_WARP_BURST_32, /*!< PSRAM Warp Burst Size 32 */ + PSRAM_UHS_WARP_BURST_16, /*!< PSRAM Warp Burst Size 16 */ + PSRAM_UHS_WARP_BURST_NONE, /*!< PSRAM Warp Burst NONE */ + PSRAM_UHS_WARP_BURST_NO_CHANGE, /*!< Not change this value */ +} PSRAM_UHS_WARP_BURST_Type; + +/** + * @brief Psram UHS Driver Strength + */ +typedef enum { + PSRAM_UHS_DRIVER_ST_34P3_PDPU = 0x1, /*!< 34.3 PD/PU */ + PSRAM_UHS_DRIVER_ST_40_PDPU = 0x2, /*!< 40 PD/PU */ + PSRAM_UHS_DRIVER_ST_48_PDPU = 0x3, /*!< 48 PD/PU */ + PSRAM_UHS_DRIVER_ST_60_PDPU = 0x4, /*!< 60 PD/PU */ + PSRAM_UHS_DRIVER_ST_80_PDPU = 0x6, /*!< 80 PD/PU */ + PSRAM_UHS_DRIVER_ST_34P3_PD_40_PU = 0x9, /*!< 34.3 PD & 40 PU */ + PSRAM_UHS_DRIVER_ST_40_PD_48_PU = 0xa, /*!< 40 PD & 48 PU */ + PSRAM_UHS_DRIVER_ST_34P3_PD_48_PU = 0xb, /*!< 34.3 PD & 48 PU */ + PSRAM_UHS_DRIVER_ST_NO_CHANGE = 0xf, /*!< Not change this value */ +} PSRAM_UHS_DRIVER_ST_Type; + +/** + * @brief Psram UHS LATENCY + */ +typedef enum { + PSRAM_UHS_LATENCY_W10_R20_MAX_FRE_533_MHZ, /*!< MAX freq. = 533 MHz / Write LATENCY=10 / Read LATENCY=20 */ + PSRAM_UHS_LATENCY_W14_R29_MAX_FRE_800_MHZ, /*!< MAX freq. = 800 MHz / Write LATENCY=14 / Read LATENCY=29 */ + PSRAM_UHS_LATENCY_W16_R33_MAX_FRE_933_MHZ, /*!< MAX freq. = 933 MHz / Write LATENCY=16 / Read LATENCY=33 */ + PSRAM_UHS_LATENCY_W18_R37_MAX_FRE_1066_MHZ, /*!< MAX freq. = 1066 MHz / Write LATENCY=18 / Read LATENCY=37 */ + PSRAM_UHS_LATENCY_RESERVED, /*!< Reserved */ + PSRAM_UHS_LATENCY_W6_R16_MAX_FRE_400_MHZ, /*!< MAX freq. = 400 MHz / Write LATENCY=6 / Read LATENCY=16 */ + PSRAM_UHS_LATENCY_W5_R13_MAX_FRE_333_MHZ, /*!< MAX freq. = 333 MHz / Write LATENCY=5 / Read LATENCY=13 */ + PSRAM_UHS_LATENCY_W5_R9_MAX_FRE_200_MHZ, /*!< MAX freq. = 200 MHz / Write LATENCY=5 / Read LATENCY=9 */ + PSRAM_UHS_LATENCY_NO_CHANGE, /*!< Not change this value */ +} PSRAM_UHS_LATENCY_Type; + +/** + * @brief Psram UHS CMD Type + */ +typedef enum { + PSRAM_UHS_CMD_SELF_REFRESH_IN, /*!< pSRAM self-refresh in command */ + PSRAM_UHS_CMD_SELF_REFRESH_EXIT, /*!< pSRAM self-refresh exit command */ + PSRAM_UHS_CMD_GLOBAL_RESET, /*!< pSRAM global reset command */ + PSRAM_UHS_CMD_ZQ_CAL_LONG, /*! */ + PSRAM_UHS_CMD_ZQ_CAL_SHORT, /*!*/ + PSRAM_UHS_CMD_ZQ_CAL_RESET, /*!*/ +} PSRAM_UHS_CMD_Type; + +/** + * @brief PSRAM UHS Temperature + * + */ +typedef enum { + PSRAM_UHS_NORMAL_TEMP, + PSRAM_UHS_HIGH_TEMP, +} PSRAM_UHS_TEMP_Type; + +/** + * @brief PSRAM_UHS_Cfg_Type + */ +typedef struct { + uint32_t pck_freq; /*!< pck frequency unit is MHZ */ + PSRAM_UHS_Mem_Size_Type psramMemSize; /*!< psram uhm memory size */ + PSRAM_UHS_Page_Size_Type psramPageSize; /*!< psram uhm page size */ + PSRAM_UHS_TEMP_Type isHighTem; /*!< auto refresh work temperature */ +} PSRAM_UHS_Cfg_Type; + +/** + * @brief PSRAM_UHS_Phy_Latency_Pra_Type + */ +typedef struct { + uint8_t phy_rl_ana; /*!< phy_rl_ana */ + uint8_t phy_rl_dig; /*!< phy_rl_dig*/ + uint8_t phy_wl_ana; /*!< phy_wl_ana */ + uint8_t phy_wl_dig; /*!< phy_wl_dig*/ + uint8_t phy_wl_dq_ana; /*!< phy_wl_dq_ana */ + uint8_t phy_wl_dq_dig; /*!< phy_wl_dq_dig */ + + uint8_t reg_timer_array_read; /*!< reg_timer_array_read */ + uint8_t reg_timer_array_write; /*!< reg_timer_array_write */ + uint8_t reg_timer_dqs_array_stop; /*!< reg_timer_dqs_array_stop */ + uint8_t reg_timer_dqs_start; /*!< reg_timer_dqs_start */ + + uint8_t reg_timer_dqs_stop; /*!< reg_timer_dqs_stop */ + uint8_t reg_timer_reg_read; /*!< reg_timer_reg_read */ + uint8_t reg_timer_reg_write; /*!< reg_timer_reg_write */ + uint8_t reg_timer_auto_refresh; /*!< reg_timer_auto_refresh */ + + uint16_t reg_timer_global_rst; /*!< reg_timer_global_rst */ + uint8_t reg_timer_self_refresh1_in; /*!< reg_timer_self_refresh1_in */ + uint8_t reg_timer_self_refresh1_exit; /*!< reg_timer_self_refresh1_exit */ + + uint8_t reg_timer_reg_write_busy; /*!< reg_timer_reg_write_busy */ + uint8_t reg_timer_reg_read_busy; /*!< reg_timer_reg_read_busy */ + uint8_t reg_timer_arrary_write_busy; /*!< reg_timer_arrary_write_busy */ + uint8_t reg_timer_arrary_read_busy; /*!< reg_timer_arrary_read_busy */ + + uint8_t en_rx_fe_dly; /*!< en_rx_fe_dly */ + uint8_t odt_sel_dly; /*!< odt_sel_dly */ + + uint8_t reg_trc_cycle; /*!< reg_trc_cycle */ + uint8_t reg_trfc_cycle; /*!< reg_trfc_cycle */ + uint8_t reg_tcphr_cycle; /*!< reg_tcphr_cycle */ + uint8_t reg_tcphw_cycle; /*!< reg_tcphw_cycle */ + +} PSRAM_UHS_Phy_Latency_Pra_Type; + +/** + * @brief PSRAM_UHS_Write_Reg_Cfg_Type + */ +typedef struct { + PSRAM_UHS_DRIVER_ST_Type driver_st; /*!< driver strength */ + PSRAM_UHS_WARP_BURST_Type burst_size; /*!< burst size */ + PSRAM_UHS_LATENCY_Type lentency; /*!< lentency */ +} PSRAM_UHS_Write_Reg_Cfg_Type; + +/*@} end of group PSRAM_UHS_Public_Types */ + +/** @defgroup PSRAM_UHS_Public_Constants + * @{ + */ + +/** @defgroup PSRAM_UHS_MEM_SIZE_TYPE + * @{ + */ +#define IS_PSRAM_UHS_MEM_SIZE_TYPE(type) (((type) == PSRAM_MEM_SIZE_4MB) || \ + ((type) == PSRAM_MEM_SIZE_8MB) || \ + ((type) == PSRAM_MEM_SIZE_16MB) || \ + ((type) == PSRAM_MEM_SIZE_32MB)) + +/** @defgroup PSRAM_UHS_PAGE_SIZE_TYPE + * @{ + */ +#define IS_PSRAM_UHS_PAGE_SIZE_TYPE(type) (((type) == PSRAM_PAGE_SIZE_2KB) || \ + ((type) == PSRAM_PAGE_SIZE_4KB)) + +/** @defgroup PSRAM_UHS_WARP_BURST_TYPE + * @{ + */ +#define IS_PSRAM_UHS_WARP_BURST_TYPE(type) (((type) == PSRAM_UHS_WARP_BURST_64) || \ + ((type) == PSRAM_UHS_WARP_BURST_32) || \ + ((type) == PSRAM_UHS_WARP_BURST_16)) + +/** @defgroup PSRAM_UHS_DRIVER_ST_TYPE + * @{ + */ +#define IS_PSRAM_UHS_DRIVER_ST_TYPE(type) (((type) == PSRAM_UHS_DRIVER_ST_34P3_PUPU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_40_PUPU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_48_PUPU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_60_PUPU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_80_PUPU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_34P3_PD_40_PU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_40_PD_48_PU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_34P3_PD_48_PU)) + +/** @defgroup PSRAM_UHS_LATENCY_TYPE + * @{ + */ +#define IS_PSRAM_UHS_LATENCY_TYPE(type) (((type) == PSRAM_UHS_LATENCY_W10_R20_MAX_FRE_533_MHZ) || \ + ((type) == PSRAM_UHS_LATENCY_W14_R29_MAX_FRE_800_MHZ) || \ + ((type) == PSRAM_UHS_LATENCY_W16_R33_MAX_FRE_933_MHZ) || \ + ((type) == PSRAM_UHS_LATENCY_W18_R37_MAX_FRE_1066_MHZ) || \ + ((type) == PSRAM_UHS_LATENCY_W6_R16_MAX_FRE_400_MHZ) || \ + ((type) == PSRAM_UHS_LATENCY_W5_R13_MAX_FRE_333_MHZ) || \ + ((type) == PSRAM_UHS_LATENCY_W5_R9_MAX_FRE_200_MHZ)) +/** @defgroup PSRAM_UHS_CMD_Type + * @{ + */ +#define IS_PSRAM_UHS_CMD_TYPE(type) (((type) == PSRAM_UHS_CMD_SELF_REFRESH_IN) || \ + ((type) == PSRAM_UHS_CMD_SELF_REFRESH_EXIT) || \ + ((type) == PSRAM_UHS_CMD_GLOBAL_RESET) + +/*@} end of group PSRAM_UHS_Public_Constants */ + +/** @defgroup PSRAM_UHS_Public_Macros + * @{ + */ + +/*@} end of group PSRAM_UHS_Public_Macros */ + +/** @defgroup PSRAM_UHS_Public_Functions + * @{ + */ +void Psram_UHS_Init(PSRAM_UHS_Cfg_Type *cfg); +int PSram_UHS_Read_Reg(uint32_t reg_addr, uint8_t *regVal); +int PSram_UHS_Write_Reg(PSRAM_UHS_Write_Reg_Cfg_Type *regCfg); +int PSram_UHS_Construct_Cmd(PSRAM_UHS_CMD_Type cmd); +void Psram_UHS_x16_Init(uint32_t uhs_pll_clk); +void Psram_UHS_x16_Init_Override(PSRAM_UHS_Cfg_Type *cfg); +/*@} end of group PSRAM_UHS_Public_Functions */ + +/*@} end of group PSRAM_UHS */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_PSRAM_UHS_H__ */ diff --git a/drivers/soc/bl808/bl808_std/include/bl808_tzc_sec.h b/drivers/soc/bl808/bl808_std/include/bl808_tzc_sec.h new file mode 100644 index 00000000..34500811 --- /dev/null +++ b/drivers/soc/bl808/bl808_std/include/bl808_tzc_sec.h @@ -0,0 +1,295 @@ +/** + ****************************************************************************** + * @file bl808_tzc_sec.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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. + * + ****************************************************************************** + */ +#ifndef __BL808_TZC_SEC_H__ +#define __BL808_TZC_SEC_H__ + +#include "tzc_sec_reg.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup TZC_SEC + * @{ + */ + +/** @defgroup TZC_SEC_Public_Types + * @{ + */ + +/** + * @brief TZC_SEC master type definition + */ +typedef enum { + TZC_SEC_MASTER_LP, /*!< TZC Master:LP CPU */ + TZC_SEC_MASTER_MM_BUS, /*!< TZC Master:MM Bus */ + TZC_SEC_MASTER_USB, /*!< TZC Master:USB */ + TZC_SEC_MASTER_WIFI, /*!< TZC Master:WIFI */ + TZC_SEC_MASTER_CCI, /*!< TZC Master:CCI */ + TZC_SEC_MASTER_SDH, /*!< TZC Master:SDH */ + TZC_SEC_MASTER_EMAC, /*!< TZC Master:EMAC */ + TZC_SEC_MASTER_M0, /*!< TZC Master:M0 CPU */ + TZC_SEC_MASTER_DMA0, /*!< TZC Master:DMA0 */ + TZC_SEC_MASTER_DMA1, /*!< TZC Master:DMA1 */ + TZC_SEC_MASTER_LZ4, /*!< TZC Master:LZ4 */ + TZC_SEC_MASTER_D0, /*!< TZC Master:D0 */ + TZC_SEC_MASTER_BLAI, /*!< TZC Master:BLAI */ + TZC_SEC_MASTER_CODEC, /*!< TZC Master:CODEC */ + TZC_SEC_MASTER_ISP, /*!< TZC Master:ISP */ + TZC_SEC_MASTER_2DDMA, /*!< TZC Master:2D DMA */ + TZC_SEC_MASTER_DMA2, /*!< TZC Master:DMA2 */ + TZC_SEC_MASTER_MAX, /*!< TZC Master max */ +} TZC_SEC_Master_Type; + +/** + * @brief TZC_SEC slave type definition + */ +typedef enum { + TZC_SEC_SLAVE_GLB = 0, /*!< TZC Slave:GLB */ + TZC_SEC_SLAVE_MIX, /*!< TZC Slave:MIX */ + TZC_SEC_SLAVE_GPIP, /*!< TZC Slave:GPIP */ + TZC_SEC_SLAVE_DBG, /*!< TZC Slave:DBG */ + TZC_SEC_SLAVE_RSVD, /*!< TZC Slave:Reserved */ + TZC_SEC_SLAVE_TZC1, /*!< TZC Slave:TZC1 */ + TZC_SEC_SLAVE_TZC2, /*!< TZC Slave:TZC2 */ + TZC_SEC_SLAVE_RSVD2, /*!< TZC Slave:Reserved */ + TZC_SEC_SLAVE_CCI, /*!< TZC Slave:CCI */ + TZC_SEC_SLAVE_MCU_MISC, /*!< TZC Slave:MCU_MISC */ + TZC_SEC_SLAVE_PERIPHERAL, /*!< TZC Slave:Peripheral */ + TZC_SEC_SLAVE_EMI_MISC = 16, /*!< TZC Slave:emi misc */ + TZC_SEC_SLAVE_PSRAMA, /*!< TZC Slave:PSRAMA */ + TZC_SEC_SLAVE_PSRAMB, /*!< TZC Slave:PSRAMB */ + TZC_SEC_SLAVE_USB, /*!< TZC Slave:USB */ + TZC_SEC_SLAVE_RF2, /*!< TZC Slave:RF2 */ + TZC_SEC_SLAVE_AUDIO, /*!< TZC Slave:Audio */ + TZC_SEC_SLAVE_EF_CTRL, /*!< TZC Slave:efuse control*/ + + TZC_SEC_SLAVE_MM = 32, /*!< TZC Slave:MM */ + TZC_SEC_SLAVE_DMA0, /*!< TZC Slave:DMA0 */ + TZC_SEC_SLAVE_DMA1, /*!< TZC Slave:DMA1 */ + TZC_SEC_SLAVE_PWR, /*!< TZC Slave:Power */ + + TZC_SEC_SLAVE_MAX, /*!< TZC slave max*/ +} TZC_SEC_Slave_Type; + +/** + * @brief TZC_SEC MM slave type definition + */ +typedef enum { + TZC_SEC_MM_SLAVE_MISC, /*!< TZC MM Slave:MISC */ + TZC_SEC_MM_SLAVE_DMA, /*!< TZC MM Slave:DMA */ + TZC_SEC_MM_SLAVE_UART, /*!< TZC MM Slave:UART */ + TZC_SEC_MM_SLAVE_I2C0, /*!< TZC MM Slave:I2C0 */ + TZC_SEC_MM_SLAVE_I2C1, /*!< TZC MM Slave:I2C1 */ + TZC_SEC_MM_SLAVE_IPC, /*!< TZC MM Slave:IPC */ + TZC_SEC_MM_SLAVE_2DDMA, /*!< TZC MM Slave:2DDMA */ + TZC_SEC_MM_SLAVE_CLKRST, /*!< TZC MM Slave:Clock and reset */ + TZC_SEC_MM_SLAVE_SPI, /*!< TZC MM Slave:SPI */ + TZC_SEC_MM_SLAVE_TIMER, /*!< TZC MM Slave:Timer */ + TZC_SEC_MM_SLAVE_RSVD1, /*!< TZC MM Slave:reserved1 */ + TZC_SEC_MM_SLAVE_RSVD2, /*!< TZC MM Slave:reserved2 */ + TZC_SEC_MM_SLAVE_RSVD3, /*!< TZC MM Slave:reserved3 */ + TZC_SEC_MM_SLAVE_RSVD4, /*!< TZC MM Slave:reserved4 */ + TZC_SEC_MM_SLAVE_RSVD5, /*!< TZC MM Slave:reserved5 */ + TZC_SEC_MM_SLAVE_UHS_PSRAM, /*!< TZC MM Slave:uhs psram */ + + TZC_SEC_MM_SLAVE_ISP_MISC = 16, /*!< TZC MM Slave:ISP MISC */ + TZC_SEC_MM_SLAVE_ISP_TOP, /*!< TZC MM Slave:ISP TOP */ + TZC_SEC_MM_SLAVE_DVP_MISC, /*!< TZC MM Slave:DVP MISC */ + TZC_SEC_MM_SLAVE_OSD_A, /*!< TZC MM Slave:OSD_A */ + TZC_SEC_MM_SLAVE_OSD_B, /*!< TZC MM Slave:OSD_B */ + TZC_SEC_MM_SLAVE_OSD_DP, /*!< TZC MM Slave:OSD_DP */ + TZC_SEC_MM_SLAVE_AWB3_CORE, /*!< TZC MM Slave:AWB3 core */ + TZC_SEC_MM_SLAVE_AWB3_SRAM, /*!< TZC MM Slave:AWB3 SRAM */ + TZC_SEC_MM_SLAVE_RSVD6, /*!< TZC MM Slave:Reserved */ + TZC_SEC_MM_SLAVE_ISP_AE_SRAM, /*!< TZC MM Slave:ISP AE SRAM */ + TZC_SEC_MM_SLAVE_MIPI, /*!< TZC MM Slave:MIPI(DSI & CSI )*/ + TZC_SEC_MM_SLAVE_DBI, /*!< TZC MM Slave:DBI */ + TZC_SEC_MM_SLAVE_ISP_AWB_SRAM, /*!< TZC MM Slave:ISP AWB SRAM */ + + TZC_SEC_MM_SLAVE_CODEC_MISC = 32, /*!< TZC MM Slave:Codec misc */ + TZC_SEC_MM_SLAVE_MJPEG, /*!< TZC MM Slave:MJPEG */ + TZC_SEC_MM_SLAVE_VIDEO, /*!< TZC MM Slave:Video */ + TZC_SEC_MM_SLAVE_MJPEG_DEC, /*!< TZC MM Slave:MJPEG Decoder */ + TZC_SEC_MM_SLAVE_BLAI, /*!< TZC MM Slave:BLAI */ + + TZC_SEC_MM_SLAVE_MAX, /*!< TZC MM slave max*/ +} TZC_SEC_MM_Slave_Type; + +/** + * @brief TZC_SEC GLB Ctrl type definition + */ +typedef enum { + TZC_SEC_GLB_CTRL_POR_RESET, /*!< TZC GLB Ctrl: Power on reset */ + TZC_SEC_GLB_CTRL_CPU_RESET, /*!< TZC GLB Ctrl: CPU reset */ + TZC_SEC_GLB_CTRL_SYS_RESET, /*!< TZC GLB Ctrl: System reset */ + TZC_SEC_GLB_CTRL_CCPU_RESET, /*!< TZC GLB Ctrl: Coupled CPU reset */ + TZC_SEC_GLB_CTRL_MISC, /*!< TZC GLB Ctrl: MISC */ + TZC_SEC_GLB_CTRL_SRAM, /*!< TZC GLB Ctrl: SRAM */ + TZC_SEC_GLB_CTRL_SWRESET, /*!< TZC GLB Ctrl: Software reset */ + TZC_SEC_GLB_CTRL_BMX, /*!< TZC GLB Ctrl: BMX */ + TZC_SEC_GLB_CTRL_DBG, /*!< TZC GLB Ctrl: DBG */ + TZC_SEC_GLB_CTRL_MBIST, /*!< TZC GLB Ctrl: MBIST */ + TZC_SEC_GLB_CTRL_CLK, /*!< TZC GLB Ctrl: CLK */ + TZC_SEC_GLB_CTRL_INT, /*!< TZC GLB Ctrl: Interrupt */ + TZC_SEC_GLB_CTRL_PWR, /*!< TZC GLB Ctrl: Power */ + TZC_SEC_GLB_CTRL_MAX, +} TZC_SEC_GLB_Ctrl_Type; + +/** + * @brief TZC_SEC MM GLB Ctrl type definition + */ +typedef enum { + TZC_SEC_MM_GLB_CTRL_POR_RESET, /*!< TZC MM GLB Ctrl: Power on reset */ + TZC_SEC_MM_GLB_CTRL_CPU_RESET, /*!< TZC MM GLB Ctrl: CPU reset */ + TZC_SEC_MM_GLB_CTRL_SYS_RESET, /*!< TZC MM GLB Ctrl: System reset */ + TZC_SEC_MM_GLB_CTRL_CCPU_RESET, /*!< TZC MM GLB Ctrl: Coupled CPU reset */ + TZC_SEC_MM_GLB_CTRL_RSVD1, /*!< TZC MM GLB Ctrl: Reserved */ + TZC_SEC_MM_GLB_CTRL_SRAM, /*!< TZC MM GLB Ctrl: SRAM */ + TZC_SEC_MM_GLB_CTRL_SWRESET, /*!< TZC MM GLB Ctrl: Software reset */ + TZC_SEC_MM_GLB_CTRL_RSVD2, /*!< TZC MM GLB Ctrl: Reserved */ + TZC_SEC_MM_GLB_CTRL_RSVD3, /*!< TZC MM GLB Ctrl: Reserved */ + TZC_SEC_MM_GLB_CTRL_RSVD4, /*!< TZC MM GLB Ctrl: Reserved */ + TZC_SEC_MM_GLB_CTRL_CLK, /*!< TZC MM GLB Ctrl: CLK */ + TZC_SEC_MM_GLB_CTRL_MAX, +} TZC_SEC_MM_GLB_Ctrl_Type; + +/** + * @brief TZC_SEC SE Ctrl type definition + */ +typedef enum { + TZC_SEC_SE_CTRL_SHA, /*!< TZC SE Ctrl: SHA */ + TZC_SEC_SE_CTRL_AES, /*!< TZC SE Ctrl: AES */ + TZC_SEC_SE_CTRL_TRNG, /*!< TZC SE Ctrl: TRNG */ + TZC_SEC_SE_CTRL_PKA, /*!< TZC SE Ctrl: PKA */ + TZC_SEC_SE_CTRL_CDET, /*!< TZC SE Ctrl: CEDT */ + TZC_SEC_SE_CTRL_GMAC, /*!< TZC SE Ctrl: GMAC */ + TZC_SEC_SE_CTRL_MAX, +} TZC_SEC_SE_Ctrl_Type; + +/** + * @brief TZC_SEC SF Ctrl type definition + */ +typedef enum { + TZC_SEC_SF_CTRL_CR, /*!< TZC SF Ctrl: control register */ + TZC_SEC_SF_CTRL_SEC, /*!< TZC SF Ctrl: security register */ + TZC_SEC_SF_CTRL_MAX, +} TZC_SEC_SF_Ctrl_Type; + +/** + * @brief TZC_SEC SE Ctrl mode definition + */ +typedef enum { + TZC_SEC_SE_MODE_ARB, /*!< TZC SE Ctrl mode: cpus arbitrate */ + TZC_SEC_SE_MODE_TZC, /*!< TZC SE Ctrl: TZC control as group */ +} TZC_SEC_SE_Ctrl_Mode; + +/** + * @brief TZC_SEC SF Ctrl mode definition + */ +typedef enum { + TZC_SEC_SF_MODE_ARB, /*!< TZC SF Ctrl mode: cpus arbitrate */ + TZC_SEC_SF_MODE_TZC, /*!< TZC SF Ctrl: TZC control as group */ +} TZC_SEC_SF_Ctrl_Mode; + +/** + * @brief TZC_SEC Auth group + */ +typedef enum { + TZC_SEC_AUTH_GRP_0, /*!< TZC auth group 0 */ + TZC_SEC_AUTH_GRP_1, /*!< TZC auth group 1 */ +} TZC_SEC_Auth_Group; + +/** + * @brief TZC_SEC Advance Auth group + */ +typedef enum { + TZC_SEC_ADV_AUTH_GRP_0_IBUS = 0x01, /*!< TZC advance auth group 0 IBUS */ + TZC_SEC_ADV_AUTH_GRP_0_DBUS = 0x02, /*!< TZC advance auth group 0 DBUS */ + TZC_SEC_ADV_AUTH_GRP_1_IBUS = 0x04, /*!< TZC advance auth group 1 IBUS */ + TZC_SEC_ADV_AUTH_GRP_1_DBUS = 0x08, /*!< TZC advance auth group 1 DBUS */ +} TZC_SEC_Advance_Auth_Group; + +/*@} end of group TZC_SEC_Public_Types */ + +/** @defgroup TZC_SEC_Public_Constants + * @{ + */ + +/*@} end of group TZC_SEC_Public_Constants */ + +/** @defgroup TZC_SEC_Public_Macros + * @{ + */ + +#define TZC_SEC_MAX_AUTH_GRP 3 +/*@} end of group TZC_SEC_Public_Macros */ + +/** @defgroup TZC_SEC_Public_Functions + * @{ + */ +void Tzc_Sec_Set_Sboot_Done(void); +void Tzc_Sec_Set_Master_Group(TZC_SEC_Master_Type masterType, uint8_t group); +void Tzc_Sec_Set_CPU_Group(uint8_t cpu, uint8_t group); +void Tzc_Sec_Set_Slave_Group(TZC_SEC_Slave_Type slaveType, uint8_t group); +void Tzc_Sec_Set_Glb_Ctrl_Group(TZC_SEC_GLB_Ctrl_Type slaveType, uint8_t group); +void Tzc_Sec_ROM_Access_Set(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group); +void Tzc_Sec_OCRAM_Access_Set_Advance(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group); +void Tzc_Sec_OCRAM_Access_Set_Regionx(uint8_t group); +void Tzc_Sec_WRAM_Access_Set_Advance(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group); +void Tzc_Sec_WRAM_Access_Set_Regionx(uint8_t group); +void Tzc_Sec_Flash_Access_Set_Advance(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group); +void Tzc_Sec_Flash_Access_Set_Regionx(uint8_t group); +void Tzc_Sec_L2SRAM_Access_Set(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group); +void Tzc_Sec_VRAM_Access_Set(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group); +void Tzc_Sec_PSRAMA_Access_Set(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group); +void Tzc_Sec_PSRAMA_Access_Release(void); +void Tzc_Sec_PSRAMB_Access_Set(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group); +void Tzc_Sec_PSRAMB_Access_Release(void); +void Tzc_Sec_XRAM_Access_Set(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group); +void Tzc_Sec_Set_Se_Ctrl_Mode(TZC_SEC_SE_Ctrl_Mode mode); +void Tzc_Sec_Set_Sf_Ctrl_Mode(TZC_SEC_SE_Ctrl_Mode mode); +void Tzc_Sec_Set_Se_Group(TZC_SEC_SE_Ctrl_Type slaveType, uint8_t group); +void Tzc_Sec_Set_Sf_Group(TZC_SEC_SF_Ctrl_Type slaveType, uint8_t group); +void Tzc_Sec_Set_WTD_Rst_Delay(uint16_t delayValue); +/*@} end of group TZC_SEC_Public_Functions */ + +/*@} end of group TZC_SEC */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_TZC_SEC_H__ */ diff --git a/drivers/soc/bl808/bl808_std/include/bl808_uhs_phy.h b/drivers/soc/bl808/bl808_std/include/bl808_uhs_phy.h new file mode 100644 index 00000000..a2560b06 --- /dev/null +++ b/drivers/soc/bl808/bl808_std/include/bl808_uhs_phy.h @@ -0,0 +1,117 @@ +#ifndef __UHS_PHY_H__ +#define __UHS_PHY_H__ + +#include "bl808_common.h" +#include "bl808_psram_uhs.h" +#include "bl808_glb.h" + +#ifndef CAL_MODE +#define CAL_MODE (0) // 0 is for sw call, 1 is for phy test, 2 is for ate cal +#endif + +enum { + UHS_LATENCY_CODE_533 = 3, // "0" + UHS_LATENCY_CODE_800 = 3, // "1" + UHS_LATENCY_CODE_933 = 3, // "2" + UHS_LATENCY_CODE_1066 = 3, + UHS_LATENCY_CODE_RESERVED = 3, //"4" + UHS_LATENCY_CODE_400 = 3, //"5" + UHS_LATENCY_CODE_333 = 3, //"6" + UHS_LATENCY_CODE_200 = 3, //"7" +}; + +enum{ + UHS_REGR_GNT_ERR = 1, + UHS_REGR_DONE_ERR, + UHS_REGW_GNT_ERR, + UHS_REGW_DONE_ERR, + UHS_LATENCY_CODE_WRITE_ERR, + UHS_INIT_ARRAY_WRITE_ERR, + UHS_REG_READ_CAL_ERR, + UHS_REG_WRITE_CAL_ERR, + UHS_ARRAY_READ_LAT_ERR, + UHS_ARRAY_WRITE_CK_ERR, + UHS_ARRAY_READ_CAL_ERR, + UHS_ARRAY_WRITE_CAL_ERR, + UHS_CACHE_ENABLE_ERR, + UHS_CACHE_DISABLE_ERR, + UHS_CACHE_RECOVER_ERR, + UHS_REG_WRITE_2kM_ERR, + UHS_BAD_DIE_ERR, + UHS_DIAGONAL_TEST_ERR, + UHS_ALL_ADDR_TEST_ERR, +}; + +#if CAL_MODE != 2 +typedef struct +{ + uint8_t rl :6; + uint8_t rdqs :4; + uint8_t rdq :4; + uint8_t wl :5; + uint8_t wdqs :4; + uint8_t wdq :4; + uint8_t ck :4; + uint8_t err_type; + uint8_t err_sub_type; + uint8_t cal_mode; + uint16_t datarate; + uint8_t rwindow; + uint8_t rwindow_begin; + uint8_t rwindow_end; + uint8_t wwindow; + uint8_t wwindow_begin; + uint8_t wwindow_end; + uint8_t cal_done; + uint32_t crc_res; +} uhs_phy_cal_res_struct; +#else +typedef struct +{ + uint32_t rl; + uint32_t rdqs; + uint32_t rdq; + uint32_t wl; + uint32_t wdqs; + uint32_t wdq; + uint32_t ck; + uint32_t err_type; + uint32_t err_sub_type; + uint32_t cal_mode; + uint32_t datarate; + uint32_t rwindow; + uint32_t rwindow_begin; + uint32_t rwindow_end; + uint32_t wwindow; + uint32_t wwindow_begin; + uint32_t wwindow_end; + uint32_t cal_done; + uint32_t crc_res; +} uhs_phy_cal_res_struct; +#endif +extern uhs_phy_cal_res_struct* uhs_phy_cal_res; + +// function call +void uhs_phy_init(PSRAM_UHS_Cfg_Type *cfg); +void uhs_phy_pwr_down(void); +uint8_t mr_read_back(void); +void set_odt_en(void); +// for htol test api +uint8_t uhs_all_addr_test(void); + +// for test or debug in example main.c +void soft_reset(void); +void uhs_reset(uint8_t ma_rb); +void array_write_fix(uint32_t addr,uint32_t len,uint32_t data0,uint32_t data1); +uint8_t array_read_fix(uint32_t addr,uint32_t len,uint32_t data0,uint32_t data1); +BL_Err_Type ATTR_CLOCK_SECTION GLB_Config_UHS_PLL_Freq(GLB_XTAL_Type xtalType, uint32_t pllFreq); +// +void set_uhs_latency_r(uint32_t uhs_latency); +void set_uhs_latency_w(uint32_t uhs_latency); +void cfg_dq_drv(uint32_t dq); +void cfg_dqs_drv(uint32_t dqs); +void cfg_ck_cen_drv(uint8_t array_ck_dly_drv,uint8_t array_cen_dly_drv); +void cfg_dq_rx(uint8_t dq); +void cfg_dqs_rx(uint8_t dqs); + +#endif // __UHS_PHY_H__ \ No newline at end of file diff --git a/drivers/soc/bl808/bl808_std/src/bl808_ef_cfg.c b/drivers/soc/bl808/bl808_std/src/bl808_ef_cfg.c new file mode 100644 index 00000000..05c3efc1 --- /dev/null +++ b/drivers/soc/bl808/bl808_std/src/bl808_ef_cfg.c @@ -0,0 +1,610 @@ +/** + ****************************************************************************** + * @file bl808_ef_cfg.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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. + * + ****************************************************************************** + */ + +#include "string.h" +#include "bl808_ef_ctrl.h" +#include "bl808_ef_cfg.h" +#include "ef_data_0_reg.h" +#include "ef_data_1_reg.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup SEC_EF_CTRL + * @{ + */ + +/** @defgroup SEC_EF_CTRL_Private_Macros + * @{ + */ +#define EF_CTRL_LOAD_BEFORE_READ_R0 EF_Ctrl_Load_Efuse_R0() +#define EF_CTRL_LOAD_BEFORE_READ_R1 EF_Ctrl_Load_Efuse_R1() + +/*@} end of group SEC_EF_CTRL_Private_Macros */ + +/** @defgroup SEC_EF_CTRL_Private_Types + * @{ + */ + +/*@} end of group SEC_EF_CTRL_Private_Types */ + +/** @defgroup SEC_EF_CTRL_Private_Variables + * @{ + */ + +/*@} end of group SEC_EF_CTRL_Private_Variables */ + +/** @defgroup SEC_EF_CTRL_Global_Variables + * @{ + */ + +/*@} end of group SEC_EF_CTRL_Global_Variables */ + +/** @defgroup SEC_EF_CTRL_Private_Fun_Declaration + * @{ + */ + +/*@} end of group SEC_EF_CTRL_Private_Fun_Declaration */ + +/** @defgroup SEC_EF_CTRL_Private_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Efuse get zero bit count + * + * @param val: Value to count + * + * @return Zero bit count + * +*******************************************************************************/ +static uint32_t EF_Cfg_Get_Byte_Zero_Cnt(uint8_t val) +{ + uint32_t cnt = 0; + uint32_t i = 0; + + for (i = 0; i < 8; i++) { + if ((val & (1 << i)) == 0) { + cnt += 1; + } + } + + return cnt; +} + +/****************************************************************************/ /** + * @brief Efuse get chip info + * + * @param chipInfo: info pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Get_Chip_Info(Efuse_Chip_Info_Type *chipInfo) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH); + chipInfo->chipInfo = (tmpVal>>29)&0x7; + chipInfo->memoryInfo = (tmpVal>>27)&0x3; + chipInfo->psramInfo = (tmpVal>>25)&0x3; + chipInfo->deviceInfo = (tmpVal>>22)&0x7; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + chipInfo->psramInfo |= ((tmpVal>>20)&0x1) << 2; +} + +/****************************************************************************/ /** + * @brief Efuse read xtal trim rc32m configuration + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_LDO15RF_Vout_Sel(Efuse_Ana_LDO15RF_Vout_Sel_Type *trim) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_3); + trim->trimLDO15RFVoutAon = (tmpVal >> 27) & 0x07; + trim->trimLDO15RFVoutAonParity = (tmpVal >> 30) & 0x01; + trim->trimLDO15RFVoutAonEn = (tmpVal >> 31) & 0x01; +} + + +/****************************************************************************/ /** + * @brief Efuse read rcal iptat code configuration + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Rcal_Iptat_Code(Efuse_Ana_Rcal_Iptat_Code_Type *trim) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_3); + trim->trimRcalIptatCode = (tmpVal >> 22) & 0x1f; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W2); + trim->trimRcalIptatCodeParity = (tmpVal >> 30) & 0x01; + trim->trimRcalIptatCodeEn = (tmpVal >> 31) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse read rcal icx code configuration + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Rcal_Icx_Code(Efuse_Ana_Rcal_Icx_Code_Type *trim) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W2); + trim->trimRcalIcxCode = (tmpVal >> 22) & 0x3f; + trim->trimRcalIcxCodeParity = (tmpVal >> 28) & 0x01; + trim->trimRcalIcxCodeEn = (tmpVal >> 29) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse read LDO28CIS vout trim configuration + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_LDO28CIS_Vout_Trim(Efuse_Ana_LDO28CIS_Vout_Trim_Type *trim) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W3); + trim->trimLDO28CISVout = (tmpVal >> 8) & 0xf; + trim->trimLDO28CISVoutParity = (tmpVal >> 12) & 0x01; + trim->trimLDO28CISVoutEn = (tmpVal >> 13) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse read LDO15CIS vout trim configuration + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_LDO15CIS_Vout_Trim(Efuse_Ana_LDO15CIS_Vout_Trim_Type *trim) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W3); + trim->trimLDO15CISVout = (tmpVal >> 8) & 0xf; + trim->trimLDO15CISVoutParity = (tmpVal >> 12) & 0x01; + trim->trimLDO15CISVoutEn = (tmpVal >> 13) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse read LDO12UHS vout trim configuration + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_LDO12UHS_Vout_Trim(Efuse_Ana_LDO12UHS_Vout_Trim_Type *trim) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R1; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_KEY_SLOT_10_W3); + trim->trimLDO12UHSVout = (tmpVal >> 20) & 0xf; + trim->trimLDO12UHSVoutParity = (tmpVal >> 24) & 0x01; + trim->trimLDO12UHSVoutEn = (tmpVal >> 25) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse read xtal capcode 1 inout configuration + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Xtal_Capcode1_Inout(Efuse_Ana_Xtal_Capcode_1_Type *trim) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R1; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_KEY_SLOT_10_W3); + trim->trimXtalCapcode1 = (tmpVal >> 0) & 0x3f; + trim->trimXtalCapcode1Parity = (tmpVal >> 6) & 0x01; + trim->trimXtalCapcode1En = (tmpVal >> 7) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse read xtal capcode 2 inout configuration + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Xtal_Capcode2_Inout(Efuse_Ana_Xtal_Capcode_2_Type *trim) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R1; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_DAT_1_RSVD_1); + trim->trimXtalCapcode2 = (tmpVal >> 26) & 0x3f; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_DAT_1_RSVD_0); + trim->trimXtalCapcode2Parity = (tmpVal >> 30) & 0x01; + trim->trimXtalCapcode2En = (tmpVal >> 31) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse read xtal capcode 3 inout configuration + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Xtal_Capcode3_Inout(Efuse_Ana_Xtal_Capcode_3_Type *trim) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R1; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_DAT_1_RSVD_1); + trim->trimXtalCapcode3 = (tmpVal >> 20) & 0x3f; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_DAT_1_RSVD_0); + trim->trimXtalCapcode3Parity = (tmpVal >> 28) & 0x01; + trim->trimXtalCapcode3En = (tmpVal >> 29) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse read gauge vpack offset configuration + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Gauge_Vpack_Offset(Efuse_Ana_Gauge_Vpack_Offset_Type *trim) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R1; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_DAT_1_RSVD_1); + trim->trimGaugeVpackOffset = (tmpVal >> 2) & 0xffff; + trim->trimGaugeVpackOffsetParity = (tmpVal >> 18) & 0x01; + trim->trimGaugeVpackOffsetEn = (tmpVal >> 19) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse read gauge vtemp offset configuration + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Gauge_Vtemp_Offset(Efuse_Ana_Gauge_Vtemp_Offset_Type *trim) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R1; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_DAT_1_RSVD_2); + trim->trimGaugeVtempOffset = (tmpVal >> 16) & 0xffff; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_DAT_1_RSVD_1); + trim->trimGaugeVtempOffsetParity = (tmpVal >> 0) & 0x01; + trim->trimGaugeVtempOffsetEn = (tmpVal >> 1) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse read psram trim configuration + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Psram_Trim(Efuse_Psram_Trim_Type *trim) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R1; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_KEY_SLOT_10_W2); + trim->psramTrim = (tmpVal >> 0) & 0x7ff; + trim->psramTrimParity = (tmpVal >> 11) & 0x01; + trim->psramTrimEn = (tmpVal >> 12) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse write psram trim configuration + * + * @param trim: Trim data pointer + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_Psram_Trim(Efuse_Psram_Trim_Type *trim, uint8_t program) +{ + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_1(); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_KEY_SLOT_10_W2); + tmpVal |= (trim->psramTrim<<0); + tmpVal |= (trim->psramTrimParity<<11); + tmpVal |= (trim->psramTrimEn<<12); + BL_WR_REG(EF_DATA_BASE, EF_DATA_1_EF_KEY_SLOT_10_W2, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_1(); + } +} + +/****************************************************************************/ /** + * @brief Whether MAC address slot is empty + * + * @param slot: MAC address slot + * @param reload: whether reload to check + * + * @return 0 for all slots full,1 for others + * +*******************************************************************************/ +uint8_t EF_Ctrl_Is_MAC_Address_Slot_Empty(uint8_t slot, uint8_t reload) +{ + uint32_t tmp1 = 0xffffffff, tmp2 = 0xffffffff; + uint32_t part1Empty = 0, part2Empty = 0; + + if (slot == 0) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (reload) { + EF_CTRL_LOAD_BEFORE_READ_R0; + } + + tmp1 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_LOW); + tmp2 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH); + } else if (slot == 1) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (reload) { + EF_CTRL_LOAD_BEFORE_READ_R0; + } + + tmp1 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_2); + tmp2 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_3); + } else if (slot == 2) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (reload) { + EF_CTRL_LOAD_BEFORE_READ_R0; + } + + tmp1 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W1); + tmp2 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W2); + } + + part1Empty = (EF_Ctrl_Is_All_Bits_Zero(tmp1, 0, 32)); + part2Empty = (EF_Ctrl_Is_All_Bits_Zero(tmp2, 0, 22)); + + return (part1Empty && part2Empty); +} + +/****************************************************************************/ /** + * @brief Efuse write optional MAC address + * + * @param slot: MAC address slot + * @param mac[6]: MAC address buffer + * @param program: Whether program + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Write_MAC_Address_Opt(uint8_t slot, uint8_t mac[6], uint8_t program) +{ + uint8_t *maclow = (uint8_t *)mac; + uint8_t *machigh = (uint8_t *)(mac + 4); + uint32_t tmpVal; + uint32_t i = 0, cnt; + + if (slot >= 3) { + return ERROR; + } + + /* Change to local order */ + for (i = 0; i < 3; i++) { + tmpVal = mac[i]; + mac[i] = mac[5 - i]; + mac[5 - i] = tmpVal; + } + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + /* The low 32 bits */ + if (slot == 0) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_LOW, BL_RDWD_FRM_BYTEP(maclow)); + } else if (slot == 1) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_2, BL_RDWD_FRM_BYTEP(maclow)); + } else if (slot == 2) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W1, BL_RDWD_FRM_BYTEP(maclow)); + } + + /* The high 16 bits */ + tmpVal = machigh[0] + (machigh[1] << 8); + cnt = 0; + + for (i = 0; i < 6; i++) { + cnt += EF_Cfg_Get_Byte_Zero_Cnt(mac[i]); + } + + tmpVal |= ((cnt & 0x3f) << 16); + + if (slot == 0) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH, tmpVal); + } else if (slot == 1) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_3, tmpVal); + } else if (slot == 2) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W2, tmpVal); + } + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Efuse read optional MAC address + * + * @param slot: MAC address slot + * @param mac[6]: MAC address buffer + * @param reload: Whether reload + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Read_MAC_Address_Opt(uint8_t slot, uint8_t mac[6], uint8_t reload) +{ + uint8_t *maclow = (uint8_t *)mac; + uint8_t *machigh = (uint8_t *)(mac + 4); + uint32_t tmpVal = 0; + uint32_t i = 0; + uint32_t cnt = 0; + + if (slot >= 3) { + return ERROR; + } + + /* Trigger read data from efuse */ + if (reload) { + EF_CTRL_LOAD_BEFORE_READ_R0; + } + + if (slot == 0) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_LOW); + } else if (slot == 1) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_2); + } else if (slot == 2) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W1); + } + + BL_WRWD_TO_BYTEP(maclow, tmpVal); + + if (slot == 0) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH); + } else if (slot == 1) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_3); + } else if (slot == 2) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W2); + } + + machigh[0] = tmpVal & 0xff; + machigh[1] = (tmpVal >> 8) & 0xff; + + /* Check parity */ + for (i = 0; i < 6; i++) { + cnt += EF_Cfg_Get_Byte_Zero_Cnt(mac[i]); + } + + if ((cnt & 0x3f) == ((tmpVal >> 16) & 0x3f)) { + /* Change to network order */ + for (i = 0; i < 3; i++) { + tmpVal = mac[i]; + mac[i] = mac[5 - i]; + mac[5 - i] = tmpVal; + } + + return SUCCESS; + } else { + return ERROR; + } +} + +/*@} end of group SEC_EF_CTRL_Public_Functions */ + +/*@} end of group SEC_EF_CTRL */ + +/*@} end of group BL808_Peripheral_Driver */ diff --git a/drivers/soc/bl808/bl808_std/src/bl808_ef_ctrl.c b/drivers/soc/bl808/bl808_std/src/bl808_ef_ctrl.c new file mode 100644 index 00000000..7d9987d6 --- /dev/null +++ b/drivers/soc/bl808/bl808_std/src/bl808_ef_ctrl.c @@ -0,0 +1,1698 @@ +/** + ****************************************************************************** + * @file bl808_ef_ctrl.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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. + * + ****************************************************************************** + */ + +#include "string.h" +#include "bl808_ef_ctrl.h" +#include "ef_data_0_reg.h" +#include "ef_data_1_reg.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup SEC_EF_CTRL + * @{ + */ + +/** @defgroup SEC_EF_CTRL_Private_Macros + * @{ + */ +#define EF_CTRL_EFUSE_CYCLE_PROTECT (0xbf << 24) +#define EF_CTRL_EFUSE_CTRL_PROTECT (0xbf << 8) +#define EF_CTRL_DFT_TIMEOUT_VAL (320 * 1000) +#ifndef BOOTROM +#define EF_CTRL_LOAD_BEFORE_READ_R0 EF_Ctrl_Load_Efuse_R0() +#define EF_CTRL_LOAD_BEFORE_READ_R1 EF_Ctrl_Load_Efuse_R1() +#else +#define EF_CTRL_LOAD_BEFORE_READ_R0 +#define EF_CTRL_LOAD_BEFORE_READ_R1 +#endif +#define EF_CTRL_DATA0_CLEAR EF_Ctrl_Clear(0, 0, EF_CTRL_EFUSE_R0_SIZE / 4) +#define EF_CTRL_DATA1_CLEAR EF_Ctrl_Clear(1, 0, EF_CTRL_EFUSE_R1_SIZE / 4) + +/*@} end of group SEC_EF_CTRL_Private_Macros */ + +/** @defgroup SEC_EF_CTRL_Private_Types + * @{ + */ + +/*@} end of group SEC_EF_CTRL_Private_Types */ + +/** @defgroup SEC_EF_CTRL_Private_Variables + * @{ + */ + +/*@} end of group SEC_EF_CTRL_Private_Variables */ + +/** @defgroup SEC_EF_CTRL_Global_Variables + * @{ + */ + +/*@} end of group SEC_EF_CTRL_Global_Variables */ + +/** @defgroup SEC_EF_CTRL_Private_Fun_Declaration + * @{ + */ + +/*@} end of group SEC_EF_CTRL_Private_Fun_Declaration */ + +/** @defgroup SEC_EF_CTRL_Private_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief get custom USB PID VID + * + * @param PID + * + * @param VID + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION EF_Ctrl_Get_Customer_PIDVID(uint16_t pid[1], uint16_t vid[1]) +{ + uint32_t tmpVal; + + EF_Ctrl_Read_Sw_Usage(4, &tmpVal); + + pid[0] = (uint16_t)(tmpVal & 0xFFFF); + vid[0] = (uint16_t)(tmpVal >> 16); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Switch efuse region 0 control to AHB clock + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION EF_Ctrl_Sw_AHB_Clk_0(void) +{ + uint32_t tmpVal; + uint32_t timeout = EF_CTRL_DFT_TIMEOUT_VAL; + + while (EF_Ctrl_Busy() == SET) { + timeout--; + + if (timeout == 0) { + break; + } + } + + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Switch efuse region 1 control to AHB clock + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION EF_Ctrl_Sw_AHB_Clk_1(void) +{ + uint32_t tmpVal; + uint32_t timeout = EF_CTRL_DFT_TIMEOUT_VAL; + + while (EF_Ctrl_Busy() == SET) { + timeout--; + + if (timeout == 0) { + break; + } + } + + /* Note:ef_if_ctrl_1 has no EF_CTRL_EF_CLK_SAHB_DATA_SEL_POS bit as ef_if_ctrl_0, + so we select it(them) in ef_if_ctrl_0 */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_1_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_1_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_1_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_1_RW_POS) | + (0 << EF_CTRL_EF_IF_1_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_1, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Program efuse region 0 + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION EF_Ctrl_Program_Efuse_0(void) +{ + uint32_t tmpVal; + + /* Select auto mode and select ef clock */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + /* Program */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (1 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (1 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + /* Add delay for POR to be stable */ + arch_delay_us(4); + + /* Trigger */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (1 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (1 << EF_CTRL_EF_IF_0_RW_POS) | + (1 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Program efuse region 1 + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION EF_Ctrl_Program_Efuse_1(void) +{ + uint32_t tmpVal; + + /* Select auto mode and select ef clock */ + /* Note:ef_if_ctrl_1 has no EF_CTRL_EF_CLK_SAHB_DATA_SEL_POS bit as ef_if_ctrl_0, + so we select it(them) in ef_if_ctrl_0 */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_1_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_1_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_1_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_1_RW_POS) | + (0 << EF_CTRL_EF_IF_1_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_1, tmpVal); + + /* Program */ + /* Note:ef_if_ctrl_1 has no EF_CTRL_EF_CLK_SAHB_DATA_SEL_POS bit as ef_if_ctrl_0, + so we select it(them) in ef_if_ctrl_0 */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (1 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + /* Add delay for POR to be stable */ + arch_delay_us(4); + + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_1_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_1_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_1_INT_CLR_POS) | + (1 << EF_CTRL_EF_IF_1_RW_POS) | + (0 << EF_CTRL_EF_IF_1_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_1, tmpVal); + + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_1_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_1_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_1_INT_CLR_POS) | + (1 << EF_CTRL_EF_IF_1_RW_POS) | + (1 << EF_CTRL_EF_IF_1_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_1, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Load efuse region 0 + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION EF_Ctrl_Load_Efuse_R0(void) +{ + uint32_t tmpVal; + uint32_t timeout = EF_CTRL_DFT_TIMEOUT_VAL; + + EF_CTRL_DATA0_CLEAR; + + /* Trigger read */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (1 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + arch_delay_us(10); + + /* Wait for efuse control idle */ + do { + tmpVal = BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0); + timeout--; + + if (timeout == 0) { + break; + } + } while (BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_IF_0_BUSY) || + + (!BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_IF_0_AUTOLOAD_DONE))); + + /* Switch to AHB clock */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Load efuse region 1 + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void EF_Ctrl_Load_Efuse_R1(void) +{ + uint32_t tmpVal; + + EF_CTRL_DATA1_CLEAR; + + /* Trigger read */ + /* Note:ef_if_ctrl_1 has no EF_CTRL_EF_CLK_SAHB_DATA_SEL_POS bit as ef_if_ctrl_0, + so we select it(them) in ef_if_ctrl_0 */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_1_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_1_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_1_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_1_RW_POS) | + (0 << EF_CTRL_EF_IF_1_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_1, tmpVal); + + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_1_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_1_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_1_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_1_RW_POS) | + (1 << EF_CTRL_EF_IF_1_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_1, tmpVal); + + arch_delay_us(10); + + /* Wait for efuse control idle */ + do { + tmpVal = BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_1); + } while (BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_IF_1_BUSY)); + + do { + tmpVal = BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0); + } while (!BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_IF_0_AUTOLOAD_DONE)); + + /* Switch to AHB clock since often read efuse data after load */ + /* Note:ef_if_ctrl_1 has no EF_CTRL_EF_CLK_SAHB_DATA_SEL_POS bit as ef_if_ctrl_0, + so we select it(them) in ef_if_ctrl_0 */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_1_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_1_CYC_MODIFY_POS) | + (1 << EF_CTRL_EF_IF_1_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_1_RW_POS) | + (0 << EF_CTRL_EF_IF_1_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_1, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Check efuse busy status + * + * @param None + * + * @return SET or RESET + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Sts_Type ATTR_TCM_SECTION EF_Ctrl_Busy(void) +{ + if (BL_IS_REG_BIT_SET(BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0), EF_CTRL_EF_IF_0_BUSY) || + BL_IS_REG_BIT_SET(BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_1), EF_CTRL_EF_IF_1_BUSY)) { + return SET; + } + + return RESET; +} +#endif + +/****************************************************************************/ /** + * @brief Check efuse whether finish loading + * + * @param None + * + * @return SET or RESET + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Sts_Type ATTR_TCM_SECTION EF_Ctrl_AutoLoad_Done(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0); + + if (BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_IF_0_AUTOLOAD_DONE)) { + return SET; + } else { + return RESET; + } +} +#endif + +/****************************************************************************/ /** + * @brief Efuse write debug password + * + * @param slot: password slot0 or slot1 + * @param passWdLow: password low 32 bits + * @param passWdHigh: password high 32 bits + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_Dbg_Pwd(uint8_t slot, uint32_t passWdLow, uint32_t passWdHigh, uint8_t program) +{ + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (slot == 0) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_LOW, passWdLow); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_HIGH, passWdHigh); + } else if (slot == 1) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD2_LOW, passWdLow); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD2_HIGH, passWdHigh); + } + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse read debug password + * + * @param slot: password slot0 or slot1 + * @param passWdLow: password low 32 bits pointer to store value + * @param passWdHigh: password high 32 bits pointer to store value + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Dbg_Pwd(uint8_t slot, uint32_t *passWdLow, uint32_t *passWdHigh) +{ + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + if (slot == 0) { + *passWdLow = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_LOW); + *passWdHigh = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_HIGH); + } else if (slot == 1) { + *passWdLow = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD2_LOW); + *passWdHigh = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD2_HIGH); + } +} + +/****************************************************************************/ /** + * @brief Efuse lock reading for passwd + * + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Readlock_Dbg_Pwd(uint8_t program) +{ + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + tmpVal = BL_SET_REG_BIT(tmpVal, EF_DATA_0_RD_LOCK_DBG_PWD); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse lock writing for passwd + * + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Writelock_Dbg_Pwd(uint8_t program) +{ + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + tmpVal = BL_SET_REG_BIT(tmpVal, EF_DATA_0_WR_LOCK_DBG_PWD); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse read security configuration + * + * @param cfg: security configuration pointer + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_Secure_Cfg(EF_Ctrl_Sec_Param_Type *cfg, uint8_t program) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_DBG_MODE, cfg->ef_dbg_mode); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_DBG_JTAG_0_DIS, cfg->ef_dbg_jtag_0_dis); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_DBG_JTAG_1_DIS, cfg->ef_dbg_jtag_1_dis); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_SBOOT_EN, cfg->ef_sboot_en); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse read security configuration + * + * @param cfg: security configuration pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Secure_Cfg(EF_Ctrl_Sec_Param_Type *cfg) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + + cfg->ef_dbg_mode = (EF_Ctrl_Dbg_Mode_Type)BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_DBG_MODE); + cfg->ef_dbg_jtag_0_dis = BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_DBG_JTAG_0_DIS); + cfg->ef_dbg_jtag_1_dis = BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_DBG_JTAG_1_DIS); + cfg->ef_sboot_en = BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_SBOOT_EN); +} + +/****************************************************************************/ /** + * @brief Efuse write security boot configuration + * + * @param sign[1]: Sign configuration pointer + * @param aes[1]: AES configuration pointer + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_Secure_Boot(EF_Ctrl_Sign_Type sign[1], EF_Ctrl_SF_AES_Type aes[1], uint8_t program) +{ + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (aes[0] != EF_CTRL_SF_AES_NONE) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_SF_AES_MODE, aes[0]); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0, tmpVal); + } + + if (EF_CTRL_SIGN_NONE != sign[0]) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_SBOOT_SIGN_MODE, sign[0]); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_0, tmpVal); + } + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse write security boot configuration + * + * @param aes[2]: AES configuration pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Secure_Boot(EF_Ctrl_SF_AES_Type aes[2]) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + + aes[1] = aes[0] = (EF_Ctrl_SF_AES_Type)BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_SF_AES_MODE); +} + +/****************************************************************************/ /** + * @brief Efuse read xtal trim rc32m configuration + * + * @param forceNoTrim: force no trim + * @param noXtal: no xtal + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Xtal_Trim_RC32M(uint8_t *forceNoTrim, uint8_t *noXtal) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + + *forceNoTrim = BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_FORCE_NO_TRIM); + *noXtal = BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_NO_XTAL); +} + +/****************************************************************************/ /** + * @brief Efuse Set sf key re sel + * + * @param ef_sf_key_re_sel: Efuse sf key re sel + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Set_sf_key_re_sel(uint8_t ef_sf_key_re_sel) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_SF_KEY_RE_SEL, ef_sf_key_re_sel); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0, tmpVal); +} + +/****************************************************************************/ /** + * @brief Analog Trim parity calculate + * + * @param val: Value of efuse trim data + * @param len: Length of bit to calculate + * + * @return Parity bit value + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +uint8_t ATTR_CLOCK_SECTION EF_Ctrl_Get_Trim_Parity(uint32_t val, uint8_t len) +{ + uint8_t cnt = 0; + uint8_t i = 0; + + for (i = 0; i < len; i++) { + if (val & (1 << i)) { + cnt++; + } + } + + return cnt & 0x01; +} +#endif + +/****************************************************************************/ /** + * @brief Efuse read DCDC11 trim + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_CLOCK_SECTION EF_Ctrl_Read_DCDC11_Trim(Efuse_Ana_DCDC11_Trim_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W3); + trim->trimDcdc11VoutAon = (tmpVal >> 26) & 0x0f; + trim->trimDcdc11VoutAonParity = (tmpVal >> 30) & 0x01; + trim->trimDcdc11VoutAonEn = (tmpVal >> 31) & 0x01; +} +#endif + +/****************************************************************************/ /** + * @brief Efuse read DCDC18 trim + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_CLOCK_SECTION EF_Ctrl_Read_DCDC18_Trim(Efuse_Ana_DCDC18_Trim_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W3); + trim->trimDcdc18VoutAon = (tmpVal >> 20) & 0x0f; + trim->trimDcdc18VoutAonParity = (tmpVal >> 24) & 0x01; + trim->trimDcdc18VoutAonEn = (tmpVal >> 25) & 0x01; +} +#endif + +/****************************************************************************/ /** + * @brief Efuse read LDO18FLASH trim + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_CLOCK_SECTION EF_Ctrl_Read_LDO18FLASH_Trim(Efuse_Ana_LDO18FLASH_Trim_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R1; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_KEY_SLOT_10_W3); + trim->trimLdo18flashVoutAon = (tmpVal >> 26) & 0x0f; + trim->trimLdo18flashVoutAonParity = (tmpVal >> 30) & 0x01; + trim->trimLdo18flashVoutAonEn = (tmpVal >> 31) & 0x01; +} +#endif + +/****************************************************************************/ /** + * @brief Efuse read USB20RCAL trim + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_CLOCK_SECTION EF_Ctrl_Read_USB20RCAL_Trim(Efuse_Ana_USB20RCAL_Trim_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R1; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_DAT_1_RSVD_2); + trim->trimUsb20rcalAon = (tmpVal >> 8) & 0x3f; + trim->trimUsb20rcalAonParity = (tmpVal >> 14) & 0x01; + trim->trimUsb20rcalAonEn = (tmpVal >> 15) & 0x01; +} +#endif + +/****************************************************************************/ /** + * @brief Efuse read RC32M trim + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_CLOCK_SECTION EF_Ctrl_Read_RC32M_Trim(Efuse_Ana_RC32M_Trim_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + trim->trimRc32mCodeFrExt = (tmpVal >> 4) & 0xff; + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W3); + trim->trimRc32mCodeFrExtParity = (tmpVal >> 0) & 0x01; + trim->trimRc32mExtCodeEn = (tmpVal >> 1) & 0x01; +} +#endif + +/****************************************************************************/ /** + * @brief Efuse read RC32K trim + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_CLOCK_SECTION EF_Ctrl_Read_RC32K_Trim(Efuse_Ana_RC32K_Trim_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_1(); + + EF_CTRL_LOAD_BEFORE_READ_R1; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_KEY_SLOT_10_W3); + trim->trimRc32kCodeFrExt = (tmpVal >> 8) & 0x3ff; + trim->trimRc32kCodeFrExtParity = (tmpVal >> 18) & 0x01; + trim->trimRc32kExtCodeEn = (tmpVal >> 19) & 0x01; +} +#endif + +/****************************************************************************/ /** + * @brief + * + * @param + * + * @return + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_CLOCK_SECTION EF_Ctrl_Read_LDO18IO_Vout_Trim(Efuse_Ana_LDO18IO_VOUT_Trim_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W3); + trim->trimLdo18ioVoutVal = (tmpVal >> 14) & 0x0f; + trim->trimLdo18ioVoutParity = (tmpVal >> 18) & 0x01; + trim->trimLdo18ioVoutEn = (tmpVal >> 19) & 0x01; +} +#endif + +/****************************************************************************/ /** + * @brief Efuse read TSEN trim + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void ATTR_CLOCK_SECTION EF_Ctrl_Read_TSEN_Trim(Efuse_TSEN_Refcode_Corner_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_1(); + + EF_CTRL_LOAD_BEFORE_READ_R1; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_DAT_1_RSVD_0); + trim->tsenRefcodeCorner = (tmpVal >> 0) & 0xfff; + trim->tsenRefcodeCornerParity = (tmpVal >> 12) & 0x01; + trim->tsenRefcodeCornerEn = (tmpVal >> 13) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse read ADC Gain trim + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void ATTR_CLOCK_SECTION EF_Ctrl_Read_ADC_Gain_Trim(Efuse_ADC_Gain_Coeff_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_1(); + + EF_CTRL_LOAD_BEFORE_READ_R1; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_EF_DAT_1_RSVD_0); + trim->adcGainCoeff = (tmpVal >> 14) & 0xfff; + trim->adcGainCoeffParity = (tmpVal >> 26) & 0x01; + trim->adcGainCoeffEn = (tmpVal >> 27) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse write software usage + * + * @param index: index of software usage + * @param usage: usage value + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_Sw_Usage(uint32_t index, uint32_t usage, uint8_t program) +{ + /* switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + switch (index) { + case 0: + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_0, usage); + break; + + case 1: + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_1, usage); + break; + + case 2: + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_2, usage); + break; + + case 3: + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_3, usage); + break; + + case 4: + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W0, usage); + break; + + default: + break; + } + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse read software usage + * + * @param index: index of software usage + * @param usage: usage value + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Sw_Usage(uint32_t index, uint32_t *usage) +{ + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + switch (index) { + case 0: + *usage = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_0); + break; + + case 1: + *usage = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_1); + break; + + case 2: + *usage = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_2); + break; + + case 3: + *usage = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_3); + break; + + case 4: + *usage = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_11_W0); + break; + + default: + break; + } +} + +/****************************************************************************/ /** + * @brief Efuse read software usage + * + * @param index: index of software usage + * @param program: usage value + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Writelock_Sw_Usage(uint32_t index, uint8_t program) +{ + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + + if (index == 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, EF_DATA_0_WR_LOCK_SW_USAGE_0); + } else if (index == 1) { + tmpVal = BL_SET_REG_BIT(tmpVal, EF_DATA_0_WR_LOCK_SW_USAGE_1); + } else if (index == 2) { + tmpVal = BL_SET_REG_BIT(tmpVal, EF_DATA_0_WR_LOCK_SW_USAGE_2); + } else if (index == 3) { + tmpVal = BL_SET_REG_BIT(tmpVal, EF_DATA_0_WR_LOCK_SW_USAGE_3); + } + + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse write MAC address + * + * @param mac[6]: MAC address buffer + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_MAC_Address(uint8_t mac[6], uint8_t program) +{ + uint8_t *maclow = (uint8_t *)mac; + uint8_t *machigh = (uint8_t *)(mac + 4); + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + /* The low 32 bits */ + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_LOW, BL_RDWD_FRM_BYTEP(maclow)); + /* The high 16 bits */ + tmpVal = machigh[0] + (machigh[1] << 8); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse Ctrl get zero bit count + * + * @param val: Value to count + * + * @return Zero bit count + * +*******************************************************************************/ +static uint32_t EF_Ctrl_Get_Byte_Zero_Cnt(uint8_t val) +{ + uint32_t cnt = 0; + uint32_t i = 0; + + for (i = 0; i < 8; i++) { + if ((val & (1 << i)) == 0) { + cnt += 1; + } + } + + return cnt; +} + +/****************************************************************************/ /** + * @brief Efuse read MAC address + * + * @param mac[6]: MAC address buffer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Read_MAC_Address(uint8_t mac[6]) +{ + uint8_t *maclow = (uint8_t *)mac; + uint8_t *machigh = (uint8_t *)(mac + 4); + uint32_t tmpVal; + uint32_t i = 0; + uint32_t cnt = 0; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_LOW); + BL_WRWD_TO_BYTEP(maclow, tmpVal); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH); + machigh[0] = tmpVal & 0xff; + machigh[1] = (tmpVal >> 8) & 0xff; + + /* Check parity */ + for (i = 0; i < 6; i++) { + cnt += EF_Ctrl_Get_Byte_Zero_Cnt(mac[i]); + } + + if ((cnt & 0x3f) == ((tmpVal >> 16) & 0x3f)) { + /* Change to network order */ + for (i = 0; i < 3; i++) { + tmpVal = mac[i]; + mac[i] = mac[5 - i]; + mac[5 - i] = tmpVal; + } + + return SUCCESS; + } else { + return ERROR; + } +} + +/****************************************************************************/ /** + * @brief Efuse read MAC address + * + * @param mac[7]: MAC address buffer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Read_MAC_Address_Raw(uint8_t mac[7]) +{ + uint8_t *maclow = (uint8_t *)mac; + uint8_t *machigh = (uint8_t *)(mac + 4); + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_LOW); + BL_WRWD_TO_BYTEP(maclow, tmpVal); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH); + machigh[0] = tmpVal & 0xff; + machigh[1] = (tmpVal >> 8) & 0xff; + machigh[2] = (tmpVal >> 16) & 0xff; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Efuse lock writing for MAC address + * + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Writelock_MAC_Address(uint8_t program) +{ + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + tmpVal = BL_SET_REG_BIT(tmpVal, EF_DATA_0_WR_LOCK_WIFI_MAC); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Whether a value bits is all zero + * + * @param val: value to check + * @param start: start bit + * @param len: total length of bits to check + * + * @return 1 for all bits zero 0 for others + * +*******************************************************************************/ +uint8_t EF_Ctrl_Is_All_Bits_Zero(uint32_t val, uint8_t start, uint8_t len) +{ + uint32_t mask = 0; + + val = (val >> start); + + if (len >= 32) { + mask = 0xffffffff; + } else { + mask = (1 << len) - 1; + } + + if ((val & mask) == 0) { + return 1; + } else { + return 0; + } +} + +/****************************************************************************/ /** + * @brief Efuse read chip ID + * + * @param chipID[8]: Chip ID buffer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Read_Chip_ID(uint8_t chipID[8]) +{ + chipID[6] = 0; + chipID[7] = 0; + return EF_Ctrl_Read_MAC_Address_Raw(chipID); +} + +/****************************************************************************/ /** + * @brief Efuse write AES key + * + * @param keyRegion: efuse key region + * @param index: index of key slot + * @param keyData: key data buffer + * @param len: key data length in words + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_AES_Key(uint8_t index, uint32_t *keyData, uint32_t len, uint8_t program) +{ + uint32_t *pAESKeyStart0 = (uint32_t *)(EF_DATA_BASE + 0x1C); + uint32_t *pAESKeyStart1 = (uint32_t *)(EF_DATA_BASE + 0x80); + + /* slot_w0~slot_w3,slot_w11 in ef_data0 + slot_w4~slot_w10,in ef_data1 */ + + if ((index <= 3) || (index == 11)) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + index = ((index == 11) ? 5 : index); + + /* Every key is 4 words len*/ + + ARCH_MemCpy4(pAESKeyStart0 + index * 4, keyData, len); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } + } else if ((index < 11) && (index > 3)) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_1(); + + index = index - 4; + + /* Every key is 4 words len*/ + ARCH_MemCpy4(pAESKeyStart1 + index * 4, keyData, len); + + if (program) { + EF_Ctrl_Program_Efuse_1(); + } + } +} + +/****************************************************************************/ /** + * @brief Efuse read AES key from specified region and index + * + * @param keyRegion: efuse key region + * @param index: index of key slot + * @param keyData: key data buffer + * @param len: key data length in words + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_AES_Key(uint8_t index, uint32_t *keyData, uint32_t len) +{ + uint32_t *pAESKeyStart0 = (uint32_t *)(EF_DATA_BASE + 0x1C); + uint32_t *pAESKeyStart1 = (uint32_t *)(EF_DATA_BASE + 0x80); + + if ((index <= 3) || (index == 11)) { + /* Trigger read data from efuse*/ + EF_CTRL_LOAD_BEFORE_READ_R0; + + index = ((index == 11) ? 5 : index); + + /* Every key is 4 words len*/ + ARCH_MemCpy4(keyData, pAESKeyStart0 + index * 4, len); + } else if ((index < 11) && (index > 3)) { + /* Trigger read data from efuse*/ + EF_CTRL_LOAD_BEFORE_READ_R1; + index = index - 4; + /* Every key is 4 words len*/ + ARCH_MemCpy4(keyData, pAESKeyStart1 + index * 4, len); + } +} + +/****************************************************************************/ /** + * @brief Efuse lock writing for aes key + * + * @param keyRegion: efuse key region + * @param index: index of key slot + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Writelock_AES_Key(uint8_t index, uint8_t program) +{ + uint32_t tmpVal; + + if ((index <= 3) || (index == 11)) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + index = ((index == 11) ? 8 : index); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + tmpVal |= (1 << (index + 17)); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } + } else if ((index < 11) && (index > 3)) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_1(); + + index = index - 4; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_LOCK); + tmpVal |= (1 << (index + 15)); + BL_WR_REG(EF_DATA_BASE, EF_DATA_1_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_1(); + } + } +} + +/****************************************************************************/ /** + * @brief Efuse lock reading for aes key + * + * @param keyRegion: efuse key region + * @param index: index of key slot + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Readlock_AES_Key(uint8_t index, uint8_t program) +{ + uint32_t tmpVal; + + if ((index <= 3) || (index == 11)) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + index = ((index == 11) ? 4 : index); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + tmpVal |= (1 << (index + 27)); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } + } else if ((index < 11) && (index > 3)) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_1(); + + index = index - 4; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_1_LOCK); + tmpVal |= (1 << (index + 25)); + BL_WR_REG(EF_DATA_BASE, EF_DATA_1_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_1(); + } + } +} +/****************************************************************************/ /** + * @brief Program data to efuse + * + * @param offset: offset of efuse address to program + * @param pword: data pointer to buffer which is aligned to word + * @param count: count of data in words to program + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Program_Direct(uint32_t offset, uint32_t *pword, uint32_t count) +{ + uint32_t *pEfuseStart = (uint32_t *)(EF_DATA_BASE); + uint32_t region0_count = 0, region1_count = 0; + + if (offset > 0x100 || (offset + count * 4) > 0x100) { + return; + } + + if (offset < 0x80) { + if (offset + count * 4 <= 0x80) { + region0_count = count; + } else { + region0_count = (0x80 - offset) / 4; + region1_count = (offset + count * 4 - 0x80) / 4; + } + } else { + region1_count = count; + } + + if (region0_count > 0) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + /* Add delay for CLK to be stable */ + arch_delay_us(4); + + if (pword != NULL) { + ARCH_MemCpy4(pEfuseStart, pword, region0_count); + pEfuseStart += region0_count; + pword += region0_count; + } + + EF_Ctrl_Program_Efuse_0(); + arch_delay_us(100); + } + if (region1_count > 0) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_1(); + + /* Add delay for CLK to be stable */ + arch_delay_us(4); + + if (pword != NULL) { + ARCH_MemCpy4(pEfuseStart, pword, region1_count); + } + + EF_Ctrl_Program_Efuse_1(); + arch_delay_us(100); + } +} + +/****************************************************************************/ /** + * @brief Read data from efuse + * + * @param offset: offset of efuse address to read + * @param pword: data pointer to buffer which is aligned to word + * @param count: count of data in words to read + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Direct(uint32_t offset, uint32_t *pword, uint32_t count) +{ + uint32_t *pEfuseStart = (uint32_t *)(EF_DATA_BASE); + uint32_t region0_count = 0, region1_count = 0; + + if (offset > 0x100 || (offset + count * 4) > 0x100) { + return; + } + + if (offset < 0x80) { + if (offset + count * 4 <= 0x80) { + region0_count = count; + } else { + region0_count = (0x80 - offset) / 4; + region1_count = (offset + count * 4 - 0x80) / 4; + } + } else { + region1_count = count; + } + + if (region0_count > 0) { + EF_CTRL_LOAD_BEFORE_READ_R0; + ARCH_MemCpy4(pword, pEfuseStart, region0_count); + pword += region0_count; + pEfuseStart += region0_count; + } + if (region1_count > 0) { + EF_CTRL_LOAD_BEFORE_READ_R1; + ARCH_MemCpy4(pword, pEfuseStart, region0_count); + } +} + +/****************************************************************************/ /** + * @brief Clear efuse data register + * + * @param region: index efuse region + * @param index: index of efuse in word + * @param len: data length + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION EF_Ctrl_Clear(uint8_t region, uint32_t index, uint32_t len) +{ + uint32_t *pEfuseStart0 = (uint32_t *)(EF_DATA_BASE + 0x00); + uint32_t *pEfuseStart1 = (uint32_t *)(EF_DATA_BASE + 0x80); + uint32_t i = 0; + + if (region == 0) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + /* Clear data */ + for (i = 0; i < len; i++) { + pEfuseStart0[index + i] = 0; + } + } else if (region == 1) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_1(); + + /* Clear data */ + for (i = 0; i < len; i++) { + pEfuseStart1[index + i] = 0; + } + } +} +#endif + +/****************************************************************************/ /** + * @brief efuse ctrl crc enable + * + * @param None + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Crc_Enable(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_CRC_CTRL_0); + tmpVal = BL_SET_REG_BIT(tmpVal, EF_CTRL_EF_CRC_TRIG); + tmpVal = BL_CLR_REG_BIT(tmpVal, EF_CTRL_EF_CRC_MODE); + tmpVal = BL_SET_REG_BIT(tmpVal, EF_CTRL_EF_CRC_DOUT_INV_EN); + tmpVal = BL_CLR_REG_BIT(tmpVal, EF_CTRL_EF_CRC_DOUT_ENDIAN); + tmpVal = BL_CLR_REG_BIT(tmpVal, EF_CTRL_EF_CRC_DIN_ENDIAN); + tmpVal = BL_CLR_REG_BIT(tmpVal, EF_CTRL_EF_CRC_INT_CLR); + tmpVal = BL_CLR_REG_BIT(tmpVal, EF_CTRL_EF_CRC_INT_SET); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_CRC_CTRL_0, tmpVal); + + tmpVal = BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_CRC_CTRL_0); + tmpVal = BL_SET_REG_BIT(tmpVal, EF_CTRL_EF_CRC_EN); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_CRC_CTRL_0, tmpVal); +} + +/****************************************************************************/ /** + * @brief efuse ctrl get crc busy status + * + * @param None + * + * @return DISABLE or ENABLE + * +*******************************************************************************/ +BL_Sts_Type EF_Ctrl_Crc_Is_Busy(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_CRC_CTRL_0); + return (BL_Sts_Type)BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_CRC_BUSY); +} + +/****************************************************************************/ /** + * @brief efuse ctrl set golden value + * + * @param goldenValue: Crc golden value + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Crc_Set_Golden(uint32_t goldenValue) +{ + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_CRC_CTRL_4, goldenValue); +} + +/****************************************************************************/ /** + * @brief efuse ctrl get crc result + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Crc_Result(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_CRC_CTRL_0); + return (BL_Err_Type)BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_CRC_ERROR); +} + +/*@} end of group SEC_EF_CTRL_Public_Functions */ + +/*@} end of group SEC_EF_CTRL */ + +/*@} end of group BL808_Peripheral_Driver */ diff --git a/drivers/soc/bl808/bl808_std/src/bl808_tzc_sec.c b/drivers/soc/bl808/bl808_std/src/bl808_tzc_sec.c new file mode 100644 index 00000000..6ae89f3f --- /dev/null +++ b/drivers/soc/bl808/bl808_std/src/bl808_tzc_sec.c @@ -0,0 +1,898 @@ +/** + ****************************************************************************** + * @file bl808_tzc_sec.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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. + * + ****************************************************************************** + */ + +#include "string.h" +#include "bl808_tzc_sec.h" +#include "bl808_glb.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup TZC_ENG + * @{ + */ + +/** @defgroup TZC_ENG_Private_Macros + * @{ + */ + +/*@} end of group TZC_ENG_Private_Macros */ + +/** @defgroup TZC_ENG_Private_Types + * @{ + */ + +/*@} end of group TZC_ENG_Private_Types */ + +/** @defgroup TZC_ENG_Private_Variables + * @{ + */ + +/*@} end of group TZC_ENG_Private_Variables */ + +/** @defgroup TZC_ENG_Global_Variables + * @{ + */ + +/*@} end of group TZC_ENG_Global_Variables */ + +/** @defgroup TZC_ENG_Private_Fun_Declaration + * @{ + */ + +/*@} end of group TZC_ENG_Private_Fun_Declaration */ + +/** @defgroup TZC_ENG_Private_Functions + * @{ + */ + +/*@} end of group TZC_ENG_Private_Functions */ + +/** @defgroup TZC_ENG_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief None + * + * @param None + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_Set_Sboot_Done(void) +{ + uint32_t tmpVal; + /* Set Sboot done */ + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_ROM_TZSRG_CTRL); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TZC_SEC_TZC_SBOOT_DONE, 0xf); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_ROM_TZSRG_CTRL, tmpVal); +} + +void Tzc_Sec_Set_Master_Group(TZC_SEC_Master_Type masterType, uint8_t group) +{ + uint32_t tmpVal; + uint32_t tmpVal2; + + if (masterType < TZC_SEC_MASTER_D0) { + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_BMX_TZMID); + tmpVal2 = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_BMX_TZMID_LOCK); + + if (group == 0) { + tmpVal &= (~(1 << masterType)); + } else { + tmpVal |= (1 << masterType); + } + tmpVal |= (1 << (masterType + 16)); + tmpVal2 |= (1 << masterType); + + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_BMX_TZMID, tmpVal); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_BMX_TZMID_LOCK, tmpVal2); + } else { + masterType -= TZC_SEC_MASTER_D0; + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_TZMID); + tmpVal2 = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_TZMID_LOCK); + + if (group == 0) { + tmpVal &= (~(1 << masterType)); + } else { + tmpVal |= (1 << masterType); + } + tmpVal |= (1 << (masterType + 16)); + tmpVal2 |= (1 << masterType); + + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_TZMID, tmpVal); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_TZMID_LOCK, tmpVal2); + } +} + +void Tzc_Sec_Set_Slave_Group(TZC_SEC_Slave_Type slaveType, uint8_t group) +{ + uint32_t tmpVal; + + if (group > TZC_SEC_MAX_AUTH_GRP || slaveType >= TZC_SEC_SLAVE_MAX) { + return; + } + group = 1 << (group); + + if (slaveType >= TZC_SEC_SLAVE_MM) { + slaveType -= TZC_SEC_SLAVE_MM; + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_BMX_S0); + /* set group */ + tmpVal &= (~(3 << (slaveType * 2))); + tmpVal |= (group << (slaveType * 2)); + /* set lock*/ + tmpVal |= (1 << (slaveType + 16)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_BMX_S0, tmpVal); + } else if (slaveType < TZC_SEC_SLAVE_EMI_MISC) { + slaveType -= TZC_SEC_SLAVE_GLB; + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_BMX_S1); + /* set group */ + tmpVal &= (~(3 << (slaveType * 2))); + tmpVal |= (group << (slaveType * 2)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_BMX_S1, tmpVal); + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_BMX_S_LOCK); + /* set lock */ + tmpVal |= (1 << slaveType); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_BMX_S_LOCK, tmpVal); + } else { + slaveType -= TZC_SEC_SLAVE_EMI_MISC; + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_BMX_S2); + /* set group */ + tmpVal &= (~(3 << (slaveType * 2))); + tmpVal |= (group << (slaveType * 2)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_BMX_S2, tmpVal); + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_BMX_S_LOCK); + /* set lock */ + tmpVal |= (1 << (slaveType + TZC_SEC_SLAVE_EMI_MISC)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_BMX_S_LOCK, tmpVal); + } +} + +void Tzc_Sec_Set_MM_Slave_Group(TZC_SEC_MM_Slave_Type slaveType, uint8_t group) +{ + uint32_t tmpVal; + + if (group > TZC_SEC_MAX_AUTH_GRP || slaveType >= TZC_SEC_MM_SLAVE_MAX) { + return; + } + group = 1 << (group); + + if (slaveType < TZC_SEC_MM_SLAVE_ISP_MISC) { + /* set group */ + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_S0); + tmpVal &= (~(3 << (slaveType * 2))); + tmpVal |= (group << (slaveType * 2)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_S0, tmpVal); + + /* set lock */ + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_S_LOCK0); + tmpVal |= (1 << slaveType); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_S_LOCK0, tmpVal); + + } else if (slaveType < TZC_SEC_MM_SLAVE_CODEC_MISC) { + slaveType -= TZC_SEC_MM_SLAVE_ISP_MISC; + + /* set group */ + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_S1); + tmpVal &= (~(3 << (slaveType * 2))); + tmpVal |= (group << (slaveType * 2)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_S1, tmpVal); + + /* set lock */ + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_S_LOCK1); + tmpVal |= (1 << (slaveType + 16)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_S_LOCK1, tmpVal); + } else { + slaveType -= TZC_SEC_MM_SLAVE_CODEC_MISC; + + /* set group */ + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_S2); + tmpVal &= (~(3 << (slaveType * 2))); + tmpVal |= (group << (slaveType * 2)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_S2, tmpVal); + + /* set lock */ + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_S_LOCK1); + tmpVal |= (1 << slaveType); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_S_LOCK1, tmpVal); + } +} + +void Tzc_Sec_Set_Glb_Ctrl_Group(TZC_SEC_GLB_Ctrl_Type slaveType, uint8_t group) +{ + uint32_t tmpVal; + + if (slaveType >= TZC_SEC_GLB_CTRL_MAX || group > TZC_SEC_MAX_AUTH_GRP) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_GLB_CTRL_0); + /* set group */ + tmpVal &= (~(3 << (slaveType * 2))); + tmpVal |= (group << (slaveType * 2)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_GLB_CTRL_0, tmpVal); + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_GLB_CTRL_2); + /* set lock */ + tmpVal |= (1 << slaveType); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_GLB_CTRL_2, tmpVal); +} + +void Tzc_Sec_Set_MM_Glb_Ctrl_Group(TZC_SEC_MM_GLB_Ctrl_Type slaveType, uint8_t group) +{ + uint32_t tmpVal; + + if (slaveType >= TZC_SEC_MM_GLB_CTRL_MAX || group > TZC_SEC_MAX_AUTH_GRP) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_MM_CTRL_0); + /* set group */ + tmpVal &= (~(3 << (slaveType * 2))); + tmpVal |= (group << (slaveType * 2)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_MM_CTRL_0, tmpVal); + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_MM_CTRL_2); + /* set lock */ + tmpVal |= (1 << slaveType); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_MM_CTRL_2, tmpVal); +} + +void Tzc_Sec_Set_CPU_Group(uint8_t cpu, uint8_t group) +{ + uint32_t tmpVal; + uint32_t tmpVal2; + + if (cpu == GLB_CORE_ID_M0) { + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_BMX_TZMID); + tmpVal2 = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_BMX_TZMID_LOCK); + + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TZC_SEC_TZC_CPU_TZMID, group); + tmpVal2 = BL_SET_REG_BITS_VAL(tmpVal2, TZC_SEC_TZC_CPU_TZMID_LOCK, 1); + + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_BMX_TZMID, tmpVal); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_BMX_TZMID_LOCK, tmpVal2); + } else if (cpu == GLB_CORE_ID_D0) { + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_TZMID); + tmpVal2 = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_TZMID_LOCK); + + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TZC_SEC_TZC_MMCPU_TZMID, group); + tmpVal2 = BL_SET_REG_BITS_VAL(tmpVal2, TZC_SEC_TZC_MMCPU_TZMID, 1); + + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_TZMID, tmpVal); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_MM_BMX_TZMID_LOCK, tmpVal2); + + } else if (cpu == GLB_CORE_ID_LP) { + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_BMX_TZMID); + tmpVal2 = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_BMX_TZMID_LOCK); + + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TZC_SEC_TZC_PICO_TZMID, group); + tmpVal2 = BL_SET_REG_BITS_VAL(tmpVal2, TZC_SEC_TZC_PICO_TZMID_LOCK, 1); + + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_BMX_TZMID, tmpVal); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_BMX_TZMID_LOCK, tmpVal2); + } +} + +/****************************************************************************/ /** + * @brief TrustZone Security set ROM region access configuration + * + * @param region: ROM region index 0-2 + * @param startAddr: ROM region start address + * @param length: ROM region length + * @param group: ROM region auth group type + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_ROM_Access_Set(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group) +{ + uint32_t tmpVal = 0; + uint32_t alignEnd = (startAddr+length+1023)&~0x3FF; + + /* check the parameter */ + CHECK_PARAM(IS_TZC_SEC_GROUP_TYPE(group)); + if (region >= 3 || group > TZC_SEC_MAX_AUTH_GRP) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_ROM_TZSRG_CTRL); + tmpVal &= (~(3 << (region * 2))); + tmpVal |= (group << (region * 2)); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_ROM_TZSRG_CTRL, tmpVal); + + tmpVal = (((alignEnd >> 10) & 0xffff) - 1) | (((startAddr >> 10) & 0xffff) << 16); + BL_WR_WORD(TZC_SEC_BASE + TZC_SEC_TZC_ROM_TZSRG_R0_OFFSET + region * 4, tmpVal); + + /* set enable and lock */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_ROM_TZSRG_CTRL); + tmpVal |= 1 << (region + 16); + tmpVal |= 1 << (region + 24); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_ROM_TZSRG_CTRL, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set OCRAM region access configuration + * + * @param region: OCRAM region index 0-2 + * @param startAddr: OCRAM region start address + * @param length: OCRAM region length + * @param group: OCRAM region auth group type + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_OCRAM_Access_Set_Advance(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group) +{ + uint32_t tmpVal = 0; + uint32_t alignEnd = (startAddr+length+1023)&~0x3FF; + + /* check the parameter */ + CHECK_PARAM(IS_TZC_SEC_GROUP_TYPE(group)); + if (region >= 3) { + return; + } + group = group & 0xf; + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_OCRAM_TZSRG_CTRL); + tmpVal &= (~(0xf << (region * 4))); + tmpVal |= (group << (region * 4)); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_OCRAM_TZSRG_CTRL, tmpVal); + + tmpVal = (((alignEnd >> 10) & 0xffff) - 1) | (((startAddr >> 10) & 0xffff) << 16); + BL_WR_WORD(TZC_SEC_BASE + TZC_SEC_TZC_OCRAM_TZSRG_R0_OFFSET + region * 4, tmpVal); + + /* set enable and lock */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_OCRAM_TZSRG_CTRL); + tmpVal |= 1 << (region + 16); + tmpVal |= 1 << (region + 20); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_OCRAM_TZSRG_CTRL, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set OCRAM regionx access configuration + * + * @param group: OCRAM region auth group type + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_OCRAM_Access_Set_Regionx(uint8_t group) +{ + uint32_t tmpVal = 0; + uint8_t region = 3; + + /* check the parameter */ + CHECK_PARAM(IS_TZC_SEC_GROUP_TYPE(group)); + if (group > TZC_SEC_MAX_AUTH_GRP) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_OCRAM_TZSRG_CTRL); + tmpVal &= (~(3 << (region * 4))); + tmpVal |= (group << (region * 4)); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_OCRAM_TZSRG_CTRL, tmpVal); + + /* set enable and lock */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_OCRAM_TZSRG_CTRL); + tmpVal |= 1 << (region + 16); + tmpVal |= 1 << (region + 20); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_OCRAM_TZSRG_CTRL, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set WRAM region access configuration + * + * @param region: WRAM region index 0-2 + * @param startAddr: WRAM region start address + * @param length: WRAM region length + * @param group: WRAM region auth group type + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_WRAM_Access_Set_Advance(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group) +{ + uint32_t tmpVal = 0; + uint32_t alignEnd = (startAddr+length+1023)&~0x3FF; + + /* check the parameter */ + CHECK_PARAM(IS_TZC_SEC_GROUP_TYPE(group)); + if (region >= 3) { + return; + } + group = group & 0xf; + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_WRAM_TZSRG_CTRL); + tmpVal &= (~(0xf << (region * 4))); + tmpVal |= (group << (region * 4)); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_WRAM_TZSRG_CTRL, tmpVal); + + tmpVal = (((alignEnd >> 10) & 0xffff) - 1) | (((startAddr >> 10) & 0xffff) << 16); + BL_WR_WORD(TZC_SEC_BASE + TZC_SEC_TZC_WRAM_TZSRG_R0_OFFSET + region * 4, tmpVal); + + /* set enable and lock */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_WRAM_TZSRG_CTRL); + tmpVal |= 1 << (region + 16); + tmpVal |= 1 << (region + 20); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_WRAM_TZSRG_CTRL, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set WRAM regionx access configuration + * + * @param group: WRAM region auth group type + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_WRAM_Access_Set_Regionx(uint8_t group) +{ + uint32_t tmpVal = 0; + uint8_t region = 3; + + /* check the parameter */ + CHECK_PARAM(IS_TZC_SEC_GROUP_TYPE(group)); + if (group > TZC_SEC_MAX_AUTH_GRP) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_WRAM_TZSRG_CTRL); + tmpVal &= (~(3 << (region * 4))); + tmpVal |= (group << (region * 4)); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_WRAM_TZSRG_CTRL, tmpVal); + + /* set enable and lock */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_WRAM_TZSRG_CTRL); + tmpVal |= 1 << (region + 16); + tmpVal |= 1 << (region + 20); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_WRAM_TZSRG_CTRL, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set Flash region access configuration + * + * @param region: Flash region index 0-2 + * @param startAddr: Flash region start address + * @param length: Flash region length + * @param group: Flash region auth group type + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_Flash_Access_Set_Advance(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group) +{ + uint32_t tmpVal = 0; + uint32_t tmpVal2 = 0; + uint32_t alignEnd = (startAddr+length+1023)&~0x3FF; + + /* check the parameter */ + CHECK_PARAM(IS_TZC_SEC_GROUP_TYPE(group)); + if (region >= 4 || group > TZC_SEC_MAX_AUTH_GRP) { + return; + } + group = 0xf & (group); + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_SF_TZSRG_CTRL); + tmpVal &= (~(0xf << (region * 4))); + tmpVal |= (group << (region * 4)); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_SF_TZSRG_CTRL, tmpVal); + + /* Set range */ + tmpVal = (((alignEnd >> 10) & 0xffff) - 1) | (((startAddr >> 10) & 0xffff) << 16); + BL_WR_WORD(TZC_SEC_BASE + TZC_SEC_TZC_SF_TZSRG_R0_OFFSET + region * 4, tmpVal); + + /* Set range MSB */ + tmpVal = BL_RD_WORD(TZC_SEC_BASE + TZC_SEC_TZC_SF_TZSRG_MSB_OFFSET); + tmpVal = tmpVal & (0xff << (8 * region)); + tmpVal2 = ((alignEnd >> 26) & 0x7) | (((startAddr >> 26) & 0x7) << 3); + tmpVal2 = tmpVal2 << (8 * region); + BL_WR_WORD(TZC_SEC_BASE + TZC_SEC_TZC_SF_TZSRG_MSB_OFFSET, tmpVal | tmpVal2); + + /* set enable and lock */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_SF_TZSRG_CTRL); + tmpVal |= 1 << (region + 20); + tmpVal |= 1 << (region + 25); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_SF_TZSRG_CTRL, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set Flash regionx access configuration + * + * @param group: Flash region auth group type + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_Flash_Access_Set_Regionx(uint8_t group) +{ + uint32_t tmpVal = 0; + uint8_t region = 4; + + /* check the parameter */ + CHECK_PARAM(IS_TZC_SEC_GROUP_TYPE(group)); + if (group > TZC_SEC_MAX_AUTH_GRP) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_SF_TZSRG_CTRL); + tmpVal &= (~(3 << (region * 4))); + tmpVal |= (group << (region * 4)); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_SF_TZSRG_CTRL, tmpVal); + + /* set enable and lock */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_SF_TZSRG_CTRL); + tmpVal |= 1 << (region + 20); + tmpVal |= 1 << (region + 25); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_SF_TZSRG_CTRL, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set L2SRAM region access configuration + * + * @param region: L2SRAM region index 0-2 + * @param startAddr: L2SRAM region start address + * @param length: L2SRAM region length + * @param group: L2SRAM region auth group type + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_L2SRAM_Access_Set(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group) +{ + uint32_t tmpVal = 0; + uint32_t alignEnd = (startAddr+length+1023)&~0x3FF; + + /* check the parameter */ + CHECK_PARAM(IS_TZC_SEC_GROUP_TYPE(group)); + if (region >= 3 || group > TZC_SEC_MAX_AUTH_GRP) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_L2SRAM_TZSRG_CTRL); + tmpVal &= (~(3 << (region * 2))); + tmpVal |= (group << (region * 2)); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_L2SRAM_TZSRG_CTRL, tmpVal); + + tmpVal = (((alignEnd >> 10) & 0xffff) - 1) | (((startAddr >> 10) & 0xffff) << 16); + BL_WR_WORD(TZC_SEC_BASE + TZC_SEC_TZC_L2SRAM_TZSRG_R0_OFFSET + region * 4, tmpVal); + + /* set enable and lock */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_L2SRAM_TZSRG_CTRL); + tmpVal |= 1 << (region + 16); + tmpVal |= 1 << (region + 24); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_L2SRAM_TZSRG_CTRL, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set VRAM region access configuration + * + * @param region: VRAM region index 0-2 + * @param startAddr: VRAM region start address + * @param length: VRAM region length + * @param group: VRAM region auth group type + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_VRAM_Access_Set(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group) +{ + uint32_t tmpVal = 0; + uint32_t alignEnd = (startAddr+length+1023)&~0x3FF; + + /* check the parameter */ + CHECK_PARAM(IS_TZC_SEC_GROUP_TYPE(group)); + if (region >= 3 || group > TZC_SEC_MAX_AUTH_GRP) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_VRAM_TZSRG_CTRL); + tmpVal &= (~(3 << (region * 2))); + tmpVal |= (group << (region * 2)); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_VRAM_TZSRG_CTRL, tmpVal); + + tmpVal = (((alignEnd >> 10) & 0xffff) - 1) | (((startAddr >> 10) & 0xffff) << 16); + BL_WR_WORD(TZC_SEC_BASE + TZC_SEC_TZC_VRAM_TZSRG_R0_OFFSET + region * 4, tmpVal); + + /* set enable lock */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_VRAM_TZSRG_CTRL); + tmpVal |= 1 << (region + 16); + tmpVal |= 1 << (region + 24); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_VRAM_TZSRG_CTRL, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set PSRAMA region access configuration + * + * @param region: PSRAMA region index 0-2 + * @param startAddr: PSRAMA region start address + * @param length: PSRAMA region length + * @param group: PSRAMA region auth group type + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_PSRAMA_Access_Set(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group) +{ + uint32_t tmpVal = 0; + uint32_t alignEnd = (startAddr+length+1023)&~0x3FF; + + /* check the parameter */ + CHECK_PARAM(IS_TZC_SEC_GROUP_TYPE(group)); + if (region >= 3 || group > TZC_SEC_MAX_AUTH_GRP) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_PSRAMA_TZSRG_CTRL); + tmpVal &= (~(3 << (region * 2))); + tmpVal |= (group << (region * 2)); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_PSRAMA_TZSRG_CTRL, tmpVal); + + tmpVal = (((alignEnd >> 10) & 0xffff) - 1) | (((startAddr >> 10) & 0xffff) << 16); + BL_WR_WORD(TZC_SEC_BASE + TZC_SEC_TZC_PSRAMA_TZSRG_R0_OFFSET + region * 4, tmpVal); + + /* set enable and lock */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_PSRAMA_TZSRG_CTRL); + tmpVal |= 1 << (region + 16); + tmpVal |= 1 << (region + 24); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_PSRAMA_TZSRG_CTRL, tmpVal); +} + +/** + * @brief TrustZone Security set Release PSRAMA region access + * + */ +void Tzc_Sec_PSRAMA_Access_Release(void) +{ + uint32_t tmpVal = 0; + uint32_t region = 0; + /* set disable */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_PSRAMA_TZSRG_CTRL); + tmpVal &= (~(1 << (region + 16))); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_PSRAMA_TZSRG_CTRL, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set PSRAMB region access configuration + * + * @param region: PSRAMB region index 0-2 + * @param startAddr: PSRAMB region start address + * @param length: PSRAMB region length + * @param group: PSRAMB region auth group type + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_PSRAMB_Access_Set(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group) +{ + uint32_t tmpVal = 0; + uint32_t alignEnd = (startAddr+length+1023)&~0x3FF; + + /* check the parameter */ + CHECK_PARAM(IS_TZC_SEC_GROUP_TYPE(group)); + if (region >= 3 || group > TZC_SEC_MAX_AUTH_GRP) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_PSRAMB_TZSRG_CTRL); + tmpVal &= (~(3 << (region * 2))); + tmpVal |= (group << (region * 2)); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_PSRAMB_TZSRG_CTRL, tmpVal); + + tmpVal = (((alignEnd >> 10) & 0xffff) - 1) | (((startAddr >> 10) & 0xffff) << 16); + BL_WR_WORD(TZC_SEC_BASE + TZC_SEC_TZC_PSRAMB_TZSRG_R0_OFFSET + region * 4, tmpVal); + + /* set enable and lock */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_PSRAMB_TZSRG_CTRL); + tmpVal |= 1 << (region + 16); + tmpVal |= 1 << (region + 24); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_PSRAMB_TZSRG_CTRL, tmpVal); +} +/** + * @brief TrustZone Security set Release PSRAMB region access + * + */ +void Tzc_Sec_PSRAMB_Access_Release(void) +{ + uint32_t tmpVal = 0; + uint32_t region = 0; + /* set disable */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_PSRAMB_TZSRG_CTRL); + tmpVal &= (~(1 << (region + 16))); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_PSRAMB_TZSRG_CTRL, tmpVal); +} +/****************************************************************************/ /** + * @brief TrustZone Security set XRAM region access configuration + * + * @param region: XRAM region index 0-2 + * @param startAddr: XRAM region start address + * @param length: XRAM region length + * @param group: XRAM region auth group type + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_XRAM_Access_Set(uint8_t region, uint32_t startAddr, uint32_t length, uint8_t group) +{ + uint32_t tmpVal = 0; + uint32_t alignEnd = (startAddr+length+1023)&~0x3FF; + + /* check the parameter */ + CHECK_PARAM(IS_TZC_SEC_GROUP_TYPE(group)); + if (region >= 3 || group > TZC_SEC_MAX_AUTH_GRP) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_XRAM_TZSRG_CTRL); + tmpVal &= (~(3 << (region * 2))); + tmpVal |= (group << (region * 2)); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_XRAM_TZSRG_CTRL, tmpVal); + + tmpVal = (((alignEnd >> 10) & 0xffff) - 1) | (((startAddr >> 10) & 0xffff) << 16); + BL_WR_WORD(TZC_SEC_BASE + TZC_SEC_TZC_XRAM_TZSRG_R0_OFFSET + region * 4, tmpVal); + + /* set enable and lock */ + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_XRAM_TZSRG_CTRL); + tmpVal |= 1 << (region + 16); + tmpVal |= 1 << (region + 24); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_XRAM_TZSRG_CTRL, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set sec_eng module config + * + * @param mode: sec_eng control mode + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_Set_Se_Ctrl_Mode(TZC_SEC_SE_Ctrl_Mode mode) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_SE_CTRL_0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TZC_SEC_TZC_SE_TZSID_CRMD, mode); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_SE_CTRL_0, tmpVal); + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_SE_CTRL_2); + /* set lock */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TZC_SEC_TZC_SE_TZSID_CRMD_LOCK, 1); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_SE_CTRL_2, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set sf_ctrl module config + * + * @param mode: sf_ctrl control mode + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_Set_Sf_Ctrl_Mode(TZC_SEC_SE_Ctrl_Mode mode) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_SE_CTRL_1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TZC_SEC_TZC_SF_TZSID_CRMD, mode); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_SE_CTRL_1, tmpVal); + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_SE_CTRL_2); + /* set lock */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TZC_SEC_TZC_SF_TZSID_CRMD_LOCK, 1); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_SE_CTRL_2, tmpVal); +} + +void Tzc_Sec_Set_Se_Group(TZC_SEC_SE_Ctrl_Type slaveType, uint8_t group) +{ + uint32_t tmpVal; + + if (group > TZC_SEC_MAX_AUTH_GRP || slaveType >= TZC_SEC_SE_CTRL_MAX) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_SE_CTRL_0); + /* set group */ + tmpVal &= (~(3 << (slaveType * 2))); + tmpVal |= (group << (slaveType * 2)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_SE_CTRL_0, tmpVal); + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_SE_CTRL_2); + /* set lock */ + tmpVal |= (1 << (slaveType)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_SE_CTRL_2, tmpVal); +} + +void Tzc_Sec_Set_Sf_Group(TZC_SEC_SF_Ctrl_Type slaveType, uint8_t group) +{ + uint32_t tmpVal; + + if (group > TZC_SEC_MAX_AUTH_GRP || slaveType >= TZC_SEC_SF_CTRL_MAX) { + return; + } + group = 1 << (group); + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_SE_CTRL_1); + /* set group */ + tmpVal &= (~(3 << (slaveType * 2))); + tmpVal |= (group << (slaveType * 2)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_SE_CTRL_1, tmpVal); + + tmpVal = BL_RD_REG(TZ1_BASE, TZC_SEC_TZC_SE_CTRL_2); + /* set lock */ + tmpVal |= (1 << (slaveType + 16)); + BL_WR_REG(TZ1_BASE, TZC_SEC_TZC_SE_CTRL_2, tmpVal); +} + +/****************************************************************************/ /** + * @brief TrustZone Security set watchdog reset delay value + * + * @param mode: sec_eng control mode + * + * @return None + * +*******************************************************************************/ +void Tzc_Sec_Set_WTD_Rst_Delay(uint16_t delayValue) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(TZC_SEC_BASE, TZC_SEC_TZC_SE_CTRL_0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TZC_SEC_TZC_SE_WDT_DLY, delayValue); + BL_WR_REG(TZC_SEC_BASE, TZC_SEC_TZC_SE_CTRL_0, tmpVal); +} + +/*@} end of group TZC_ENG_Public_Functions */ + +/*@} end of group TZC_ENG */ + +/*@} end of group BL808_Peripheral_Driver */ diff --git a/drivers/soc/bl808/bl808_std/src/bl808_uhs_phy.c b/drivers/soc/bl808/bl808_std/src/bl808_uhs_phy.c new file mode 100644 index 00000000..849c183a --- /dev/null +++ b/drivers/soc/bl808/bl808_std/src/bl808_uhs_phy.c @@ -0,0 +1,2890 @@ +#include "bl808_uhs_phy.h" +#include +#include +#include +#include "psram_uhs_reg.h" +#include "glb_reg.h" +#include "pds_reg.h" + +#define bl808_DBG_RF (0) // 0 is for commit with only err log, 1 is for all debug log, 2 is for key debug log +#if bl808_DBG_RF == 1 + #define uhs_phy_printf_debug printf // debug mode + #define uhs_phy_printf printf + #define uhs_phy_printfe printf +#elif bl808_DBG_RF == 2 + #define uhs_phy_printf_debug(...) + #define uhs_phy_printf printf // commit it out in release version, use to collect data + // #define uhs_phy_printf(...) // used in release version + #define uhs_phy_printfe printf +#else + #define uhs_phy_printf_debug(...) + #define uhs_phy_printf(...) + #define uhs_phy_printfe printf +#endif + +#define ODT_EN (0) +// #define PSRAM_32MB (0) +#define CACHE_EN (0) // unused ! + +static uhs_phy_cal_res_struct cal_res; +uhs_phy_cal_res_struct* uhs_phy_cal_res = &cal_res; +static uint8_t err_flag = 0; +#define CHECK_ERR_FLAG(func,args) {\ + func args;\ + if(err_flag)return err_flag;\ +} + +static uint32_t cache_state = 0; +static uint8_t uhs_latency_code = 1; +static uint32_t dqs_dq_delta = 0; +static uint32_t dcache_original = 0; +static uint32_t dcache_current = 0; +static uint32_t dcache_end = 0; +static uint8_t regr_done_err = 0; +static uint8_t reg_read_err = 0; +static uint8_t reg_write_err = 0; +static uint8_t init_array_write_err = 0; +static uint8_t array_read_err = 0; +static uint32_t addr_dump = 0x3000F000; +// +static uint32_t addr_rarray = 0x50000000; +static uint32_t data0_rarray = 0x12345678; +static uint32_t data1_rarray = 0x87654321; +// uint32_t datarate_glb; +static uint32_t latency_wr[2] = {9,30}; +static PSRAM_UHS_Cfg_Type *cfg_glb; +// static uint32_t addr_sr[3] = {0x3000f014,0x3000f018,0x3000f020}; +// static uint32_t val_sr[3] = {0x0,0x0,0x0}; +static uint32_t latency_wr_2kM[2] = {13,41}; +static uint8_t cal_done_flag = 0; +static uint8_t print_flag = 0; +// static uint32_t latency_wr_2kM_init[2] = {13,36}; +static uint8_t flag_ck1 = 0; +static uint8_t flag_ck2 = 0; + +void set_uhs_latency_w(uint32_t uhs_latency); +void set_uhs_latency_r(uint32_t uhs_latency); +void uhs_reset(uint8_t ma_rb); +void uhs_phy_reg_dump(void); +void set_or_uhs(void); +uint8_t mr_read_back(void); +uint8_t uhs_phy_init_core(PSRAM_UHS_Cfg_Type *cfg); + +void uhs_phy_delay_us(uint32_t us) +{ + arch_delay_us(us); +} + +void uhs_phy_delay_ms(uint32_t ms) +{ + arch_delay_ms(ms); +} + +void uhs_phy_af_reg(uint32_t REG_PCK_T_DIV,uint32_t REG_WIN_CYCLE,uint32_t REG_WIN_REF_CNT,uint32_t REG_REFI_CYCLE,uint32_t REG_BUST_CYCLE) +{ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_MANUAL); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_PCK_T_DIV,REG_PCK_T_DIV); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_MANUAL,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_AUTO_FRESH_1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_WIN_CYCLE,REG_WIN_CYCLE); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_AUTO_FRESH_1,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_AUTO_FRESH_2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_WIN_REF_CNT,REG_WIN_REF_CNT); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_REFI_CYCLE,REG_REFI_CYCLE); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_AUTO_FRESH_2,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_AUTO_FRESH_4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_BUST_CYCLE,REG_BUST_CYCLE); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_AUTO_FRESH_4,tmpVal); + // tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_AF_EN,0x1); + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); +} + +void uhs_phy_af_onoff(uint8_t onoff){ + uint32_t tmpVal = 0; + + if(onoff){ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_AF_EN,0x1); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + uhs_phy_delay_us(50); + // tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_INIT_EN,0x1); + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + // uhs_phy_delay_us(50); + }else{ + // tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_INIT_EN,0x0); + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + // uhs_phy_delay_us(50); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_AF_EN,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + uhs_phy_delay_us(50); + } +} + +void uhs_phy_af_cfg(void) +{ + // uint32_t tmpVal = 0; + + uhs_phy_af_onoff(0); + + if(cfg_glb->psramMemSize == PSRAM_MEM_SIZE_64MB && cfg_glb->isHighTem == PSRAM_UHS_HIGH_TEMP){ + if(cfg_glb->pck_freq == 2000){ + uhs_phy_af_reg(0x4,0xF423F,0x2000,0x79,0x6); + } + else if(cfg_glb->pck_freq == 1900){ + uhs_phy_af_reg(0x4,0xE7EEF,0x2000,0x72,0x6); + } + else if(cfg_glb->pck_freq == 1800){ + uhs_phy_af_reg(0x4,0xDBB9F,0x2000,0x6C,0x6); + } + else if(cfg_glb->pck_freq == 1700){ + uhs_phy_af_reg(0x4,0xCF84F,0x2000,0x66,0x5); + } + else if(cfg_glb->pck_freq == 1600){ + uhs_phy_af_reg(0x4,0xC34FF,0x2000,0x60,0x5); + } + else if(cfg_glb->pck_freq == 1500){ + uhs_phy_af_reg(0x4,0xB71AF,0x2000,0x5A,0x5); + } + else if(cfg_glb->pck_freq == 1400){ + uhs_phy_af_reg(0x4,0xAAE5F,0x2000,0x54,0x4); + } + else if(cfg_glb->pck_freq == 1300){ + uhs_phy_af_reg(0x4,0x9EB0F,0x2000,0x4E,0x4); + } + else if(cfg_glb->pck_freq == 1200){ + uhs_phy_af_reg(0x4,0x927BF,0x2000,0x48,0x4); + } + else if(cfg_glb->pck_freq == 1100){ + uhs_phy_af_reg(0x4,0x8646F,0x2000,0x42,0x4); + } + else if(cfg_glb->pck_freq == 1000){ + uhs_phy_af_reg(0x4,0x7A11F,0x2000,0x3C,0x3); + } + else if(cfg_glb->pck_freq == 900){ + uhs_phy_af_reg(0x4,0x6DDCF,0x2000,0x35,0x3); + } + else{ + uhs_phy_af_reg(0x4,0x61A7F,0x2000,0x2F,0x3); + } + } + else if(cfg_glb->psramMemSize == PSRAM_MEM_SIZE_64MB){ + if(cfg_glb->pck_freq == 2000){ + uhs_phy_af_reg(0x4,0x1E847F,0x2000,0xF3,0x6); + } + else if(cfg_glb->pck_freq == 1900){ + uhs_phy_af_reg(0x4,0x1CFDDF,0x2000,0xE6,0x6); + } + else if(cfg_glb->pck_freq == 1800){ + uhs_phy_af_reg(0x4,0x1B773F,0x2000,0xDA,0x6); + } + else if(cfg_glb->pck_freq == 1700){ + uhs_phy_af_reg(0x4,0x19F09F,0x2000,0xCE,0x5); + } + else if(cfg_glb->pck_freq == 1600){ + uhs_phy_af_reg(0x4,0x1869FF,0x2000,0xC2,0x5); + } + else if(cfg_glb->pck_freq == 1500){ + uhs_phy_af_reg(0x4,0x16E35F,0x2000,0xB6,0x5); + } + else if(cfg_glb->pck_freq == 1400){ + uhs_phy_af_reg(0x4,0x155CBF,0x2000,0xA9,0x4); + } + else if(cfg_glb->pck_freq == 1300){ + uhs_phy_af_reg(0x4,0x13D61F,0x2000,0x9D,0x4); + } + else if(cfg_glb->pck_freq == 1200){ + uhs_phy_af_reg(0x4,0x124F7F,0x2000,0x91,0x4); + } + else if(cfg_glb->pck_freq == 1100){ + uhs_phy_af_reg(0x4,0x10C8DF,0x2000,0x85,0x4); + } + else if(cfg_glb->pck_freq == 1000){ + uhs_phy_af_reg(0x4,0xF423F,0x2000,0x79,0x3); + } + else if(cfg_glb->pck_freq == 900){ + uhs_phy_af_reg(0x4,0xDBB9F,0x2000,0x6C,0x3); + } + else{ + uhs_phy_af_reg(0x4,0xC34FF,0x2000,0x60,0x3); + } + } + else if(cfg_glb->psramMemSize == PSRAM_MEM_SIZE_32MB && cfg_glb->isHighTem == PSRAM_UHS_HIGH_TEMP){ + if(cfg_glb->pck_freq == 2000){ + uhs_phy_af_reg(0x4,0xF423F,0x1000,0xF3,0x6); + } + else if(cfg_glb->pck_freq == 1900){ + uhs_phy_af_reg(0x4,0xE7EEF,0x1000,0xE6,0x6); + } + else if(cfg_glb->pck_freq == 1800){ + uhs_phy_af_reg(0x4,0xDBB9F,0x1000,0xDA,0x6); + } + else if(cfg_glb->pck_freq == 1700){ + uhs_phy_af_reg(0x4,0xCF84F,0x1000,0xCE,0x5); + } + else if(cfg_glb->pck_freq == 1600){ + uhs_phy_af_reg(0x4,0xC34FF,0x1000,0xC2,0x5); + } + else if(cfg_glb->pck_freq == 1500){ + uhs_phy_af_reg(0x4,0xB71AF,0x1000,0xB6,0x5); + } + else if(cfg_glb->pck_freq == 1400){ + uhs_phy_af_reg(0x4,0xAAE5F,0x1000,0xA9,0x4); + } + else if(cfg_glb->pck_freq == 1300){ + uhs_phy_af_reg(0x4,0x9EB0F,0x1000,0x9D,0x4); + } + else if(cfg_glb->pck_freq == 1200){ + uhs_phy_af_reg(0x4,0x927BF,0x1000,0x91,0x4); + } + else if(cfg_glb->pck_freq == 1100){ + uhs_phy_af_reg(0x4,0x8646F,0x1000,0x85,0x4); + } + else if(cfg_glb->pck_freq == 1000){ + uhs_phy_af_reg(0x4,0x7A11F,0x1000,0x79,0x3); + } + else if(cfg_glb->pck_freq == 900){ + uhs_phy_af_reg(0x4,0x6DDCF,0x1000,0x6C,0x3); + } + else{ + uhs_phy_af_reg(0x4,0x61A7F,0x1000,0x60,0x3); + } + } + else{ + if(cfg_glb->pck_freq == 2000){ + uhs_phy_af_reg(0x4,0x1E847F,0x1000,0x1E7,0x6); + } + else if(cfg_glb->pck_freq == 1900){ + uhs_phy_af_reg(0x4,0x1CFDDF,0x1000,0x1CE,0x6); + } + else if(cfg_glb->pck_freq == 1800){ + uhs_phy_af_reg(0x4,0x1B773F,0x1000,0x1B6,0x6); + } + else if(cfg_glb->pck_freq == 1700){ + uhs_phy_af_reg(0x4,0x19F09F,0x1000,0x19E,0x5); + } + else if(cfg_glb->pck_freq == 1600){ + uhs_phy_af_reg(0x4,0x1869FF,0x1000,0x185,0x5); + } + else if(cfg_glb->pck_freq == 1500){ + uhs_phy_af_reg(0x4,0x16E35F,0x1000,0x16D,0x5); + } + else if(cfg_glb->pck_freq == 1400){ + uhs_phy_af_reg(0x4,0x155CBF,0x1000,0x154,0x4); + } + else if(cfg_glb->pck_freq == 1300){ + uhs_phy_af_reg(0x4,0x13D61F,0x1000,0x13C,0x4); + } + else if(cfg_glb->pck_freq == 1200){ + uhs_phy_af_reg(0x4,0x124F7F,0x1000,0x123,0x4); + } + else if(cfg_glb->pck_freq == 1100){ + uhs_phy_af_reg(0x4,0x10C8DF,0x1000,0x10B,0x4); + } + else if(cfg_glb->pck_freq == 1000){ + uhs_phy_af_reg(0x4,0xF423F,0x1000,0xF3,0x3); + } + else if(cfg_glb->pck_freq == 900){ + uhs_phy_af_reg(0x4,0xDBB9F,0x1000,0xDA,0x3); + } + else{ + uhs_phy_af_reg(0x4,0xC34FF,0x1000,0xC2,0x3); + } + } + + uhs_phy_af_onoff(1); +} + +void Psram_UHS_Init_Override(PSRAM_UHS_Cfg_Type *cfg){ + uint32_t tmpVal = 0; + + Psram_UHS_Init(cfg); + if (cfg_glb->psramMemSize == PSRAM_MEM_SIZE_32MB){ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_48); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PSRAM_TYPE,0x1); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_48,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_ADDRMB_MSK,0x1f); // 3F -> 512Mb psram, 1F -> 256Mb psram + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + }else if(cfg_glb->psramMemSize == PSRAM_MEM_SIZE_64MB){ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_48); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PSRAM_TYPE,0x2); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_48,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_ADDRMB_MSK,0x3f); // 3F -> 512Mb psram, 1F -> 256Mb psram + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + } + + #if CAL_MODE == 1 + uhs_phy_af_cfg(); + #endif + + set_or_uhs(); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_LDO12UHS); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_LDO12UHS_VOUT_SEL, 5); + BL_WR_REG(GLB_BASE, GLB_LDO12UHS, tmpVal); + uhs_phy_printf("GLB_LDO12UHS: %lx\r\n",tmpVal); + uhs_phy_delay_us(250); +} + +void power_up_mm(uint8_t off) +{ + uint32_t tmpVal = 0; + if (off == 0) + { + // power up MM domain + tmpVal = BL_RD_REG(PDS_BASE,PDS_CTL2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PDS_CR_PDS_FORCE_MM_PWR_OFF,off); + BL_WR_REG(PDS_BASE,PDS_CTL2,tmpVal); + uhs_phy_delay_us(150); + tmpVal = BL_RD_REG(PDS_BASE,PDS_CTL2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PDS_CR_PDS_FORCE_MM_ISO_EN,off); + BL_WR_REG(PDS_BASE,PDS_CTL2,tmpVal); + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PDS_BASE,PDS_CTL2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PDS_CR_PDS_FORCE_MM_GATE_CLK,off); + BL_WR_REG(PDS_BASE,PDS_CTL2,tmpVal); + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PDS_BASE,PDS_CTL2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PDS_CR_PDS_FORCE_MM_MEM_STBY,off); + BL_WR_REG(PDS_BASE,PDS_CTL2,tmpVal); + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PDS_BASE,PDS_CTL2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PDS_CR_PDS_FORCE_MM_PDS_RST,off); + BL_WR_REG(PDS_BASE,PDS_CTL2,tmpVal); + // uhs_phy_delay_us(10); + // uhs_phy_delay_ms(1); + } + else + { + tmpVal = BL_RD_REG(PDS_BASE,PDS_CTL2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PDS_CR_PDS_FORCE_MM_ISO_EN,off); + BL_WR_REG(PDS_BASE,PDS_CTL2,tmpVal); + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PDS_BASE,PDS_CTL2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PDS_CR_PDS_FORCE_MM_GATE_CLK,off); + BL_WR_REG(PDS_BASE,PDS_CTL2,tmpVal); + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PDS_BASE,PDS_CTL2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PDS_CR_PDS_FORCE_MM_MEM_STBY,off); + BL_WR_REG(PDS_BASE,PDS_CTL2,tmpVal); + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PDS_BASE,PDS_CTL2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PDS_CR_PDS_FORCE_MM_PDS_RST,off); + BL_WR_REG(PDS_BASE,PDS_CTL2,tmpVal); + uhs_phy_delay_us(150); + tmpVal = BL_RD_REG(PDS_BASE,PDS_CTL2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PDS_CR_PDS_FORCE_MM_PWR_OFF,off); + BL_WR_REG(PDS_BASE,PDS_CTL2,tmpVal); + } + uhs_phy_delay_us(100); +} + +void power_up_uhspll(void) +{ + // power_up_uhspll + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(GLB_BASE,GLB_UHS_PLL_CFG0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_PU_UHSPLL_SFREG,0x1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_PU_UHSPLL,0x1); + BL_WR_REG(GLB_BASE,GLB_UHS_PLL_CFG0,tmpVal); + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(GLB_BASE,GLB_UHS_PLL_CFG0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_UHSPLL_SDM_RSTB,0x0); + BL_WR_REG(GLB_BASE,GLB_UHS_PLL_CFG0,tmpVal); + uhs_phy_delay_us(50); + tmpVal = BL_RD_REG(GLB_BASE,GLB_UHS_PLL_CFG0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_UHSPLL_SDM_RSTB,0x1); + BL_WR_REG(GLB_BASE,GLB_UHS_PLL_CFG0,tmpVal); + uhs_phy_delay_us(50); + tmpVal = BL_RD_REG(GLB_BASE,GLB_UHS_PLL_CFG0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_UHSPLL_FBDV_RSTB,0x0); + BL_WR_REG(GLB_BASE,GLB_UHS_PLL_CFG0,tmpVal); + uhs_phy_delay_us(50); + tmpVal = BL_RD_REG(GLB_BASE,GLB_UHS_PLL_CFG0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_UHSPLL_FBDV_RSTB,0x1); + BL_WR_REG(GLB_BASE,GLB_UHS_PLL_CFG0,tmpVal); + uhs_phy_delay_us(50); +} + +void power_up_ldo12uhs(void) +{ + // use internal LDO + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(GLB_BASE,GLB_LDO12UHS); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_PU_LDO12UHS,0x1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_LDO12UHS_VOUT_SEL,0x5); + BL_WR_REG(GLB_BASE,GLB_LDO12UHS,tmpVal); + uhs_phy_delay_us(200); + // use external LDO + // tmpVal = BL_RD_REG(GLB_BASE,GLB_LDO12UHS); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_LDO12UHS_PULLDOWN,0x0); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_LDO12UHS_PULLDOWN_SEL,0x1); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_PU_LDO12UHS,0x0); + // BL_WR_REG(GLB_BASE,GLB_LDO12UHS,tmpVal); +} + +void set_cen_ck_ckn(void) +{ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ_OE_MID_N_REG,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ_OE_MID_P_REG,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_50,tmpVal); + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_40); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_DMY1,0xfc); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_DMY0,0x1); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_40,tmpVal); + uhs_phy_delay_us(10); +} + +void set_or_uhs(void) +{ + uint32_t tmpVal = 0; + + if (cfg_glb->psramMemSize == PSRAM_MEM_SIZE_32MB){ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_48); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PSRAM_TYPE,0x1); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_48,tmpVal); + }else if(cfg_glb->psramMemSize == PSRAM_MEM_SIZE_64MB){ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_48); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PSRAM_TYPE,0x2); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_48,tmpVal); + } + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_4C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_ODT_SEL_HW,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_4C,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_ODT_SEL,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_VREF_MODE,0x1); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_00); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_CEN_DLY_DRV,0x8); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_CK_DLY_DRV,0xB); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_00,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_04); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DM0_DLY_DRV,0x7); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DM1_DLY_DRV,0x7); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_04,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_24); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ15_DLY_DRV,0x7); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ14_DLY_DRV,0x7); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_24,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_20); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ13_DLY_DRV,0x7); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ12_DLY_DRV,0x7); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_20,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_1C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ11_DLY_DRV,0x7); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ10_DLY_DRV,0x7); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_1C,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_18); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ9_DLY_DRV,0x7); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ8_DLY_DRV,0x7); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_18,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_14); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ7_DLY_DRV,0x7); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ6_DLY_DRV,0x7); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_14,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_10); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ5_DLY_DRV,0x7); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ4_DLY_DRV,0x7); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_10,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_0C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ3_DLY_DRV,0x7); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ2_DLY_DRV,0x7); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_0C,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_08); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ1_DLY_DRV,0x7); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ0_DLY_DRV,0x7); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_08,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_28); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQS0_DLY_DRV,0x6); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_28,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_2C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQS1_DLY_DRV,0x6); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_2C,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_OE_TIMER,0x3); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_00); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_CEN_SR,0x2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_CK_SR,0x2); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_00,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_04); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DM1_SR,0x2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DM0_SR,0x2); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_04,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_24); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ15_SR,0x2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ14_SR,0x2); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_24,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_20); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ13_SR,0x2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ12_SR,0x2); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_20,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_1C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ11_SR,0x2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ10_SR,0x2); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_1C,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_18); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ9_SR,0x2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ8_SR,0x2); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_18,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_14); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ7_SR,0x2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ6_SR,0x2); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_14,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_10); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ5_SR,0x2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ4_SR,0x2); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_10,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_0C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ3_SR,0x2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ2_SR,0x2); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_0C,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_08); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ1_SR,0x2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ0_SR,0x2); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_08,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ_OE_DN_P_REG,0x3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ_OE_DN_N_REG,0x3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ_OE_UP_P_REG,0x3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ_OE_UP_N_REG,0x3); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_50,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_24); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ15_DLY_RX,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ14_DLY_RX,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_24,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_20); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ13_DLY_RX,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ12_DLY_RX,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_20,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_1C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ11_DLY_RX,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ10_DLY_RX,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_1C,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_18); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ9_DLY_RX,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ8_DLY_RX,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_18,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_14); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ7_DLY_RX,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ6_DLY_RX,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_14,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_10); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ5_DLY_RX,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ4_DLY_RX,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_10,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_0C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ3_DLY_RX,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ2_DLY_RX,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_0C,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_08); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ1_DLY_RX,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ0_DLY_RX,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_08,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_28); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQS0_DLY_RX,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQS0N_DLY_RX,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQS0_DIFF_DLY_RX,0x3); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_28,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_2C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQS1_DLY_RX,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQS1N_DLY_RX,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQS1_DIFF_DLY_RX,0x3); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_2C,tmpVal); + uhs_phy_delay_us(200); +} + +void switch_to_ldo12uhs(void) +{ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_40); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_DMY1,0xcc); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_40,tmpVal); + uhs_phy_delay_us(200); +} + +void release_cen_ck_ckn(void) +{ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_40); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_DMY1,0xcf); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_DMY0,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_40,tmpVal); + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ_OE_MID_P_REG,0x3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ_OE_MID_N_REG,0x3); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_50,tmpVal); + uhs_phy_delay_us(10); +} + +void uhs_phy_pwr_down(void) +{ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(GLB_BASE,GLB_LDO12UHS); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_LDO12UHS_PULLDOWN_SEL,0x0); + BL_WR_REG(GLB_BASE,GLB_LDO12UHS,tmpVal); + uhs_phy_delay_us(100); + tmpVal = BL_RD_REG(GLB_BASE,GLB_LDO12UHS); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_PU_LDO12UHS,0x0); + BL_WR_REG(GLB_BASE,GLB_LDO12UHS,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_40); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_DMY1,0xff); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_40,tmpVal); + uhs_phy_delay_us(100); + tmpVal = BL_RD_REG(GLB_BASE,GLB_LDO12UHS); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_PU_UHSPLL_SFREG,0x0); + BL_WR_REG(GLB_BASE,GLB_LDO12UHS,tmpVal); + uhs_phy_delay_us(100); +} + +void psram_init(void) +{ + uint8_t i; + uint32_t tmpVal = 0; + for (i = 0; i < 1; i++){ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + // if (cfg_glb->psramMemSize == PSRAM_MEM_SIZE_32MB){ + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_ADDRMB_MSK,0x1f); // 3F -> 512Mb psram, 1F -> 256Mb psram + // }else if(cfg_glb->psramMemSize == PSRAM_MEM_SIZE_64MB){ + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_ADDRMB_MSK,0x3f); // 3F -> 512Mb psram, 1F -> 256Mb psram + // } + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_LINEAR_BND_B,0xb); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_INIT_EN,0x1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_CONFIG_REQ,0x1); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_GLBR_PULSE,0x1); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD,tmpVal); + uhs_phy_delay_us(100); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_CONFIG_REQ,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + uhs_phy_delay_us(100); + } + + // // psram auto refresh at 2000Mbps + // tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_AUTO_FRESH_1); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_WIN_CYCLE,0x001E0C4); + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_AUTO_FRESH_1,tmpVal); + // tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_AUTO_FRESH_2); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_WIN_REF_CNT,0x1007); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_REFI_CYCLE,0x01d); + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_AUTO_FRESH_2,tmpVal); + // tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_AUTO_FRESH_4); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_BUST_CYCLE,0x1); + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_AUTO_FRESH_4,tmpVal); + // tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_MANUAL); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_PCK_T_DIV,0x40); + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_MANUAL,tmpVal); + // tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_AF_EN,0x1); + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + + // // psram cmd timing < 2000Mbps + // BL_WR_WORD(0x3000F030,0x18090610); +} + +void set_uhs_phy_init(void) +{ + // set phy & controller + uint32_t tmpVal = 0; + // default latency(800MHz) + // tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_RL_ANA,0x2); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_RL_DIG,0x7); + // // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_WL_ANA,0x0); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_WL_ANA,0x1); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_WL_DIG,0x2); + // // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_WL_DQ_ANA,0x1); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_WL_DQ_ANA,0x2); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_WL_DQ_DIG,0x2); + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_ODT_SEL,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_OE_CTRL_HW,0x1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_VREF_MODE,0x1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_OE_TIMER,0x3); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30,tmpVal); + if (cfg_glb->psramMemSize == PSRAM_MEM_SIZE_32MB){ + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_34,0x05000501); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_38,0x02080108); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_3C,0x03e90b0b); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_44,0x040b0308); + }else if(cfg_glb->psramMemSize == PSRAM_MEM_SIZE_64MB){ + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_34,0x09020303); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_38,0x040c0313); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_3C,0x07d11515); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_44,0x060f050c); + } + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_WL_CEN_ANA,0x1); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_50,tmpVal); + uhs_phy_delay_us(100); +} + +void set_uhs_phy(void) +{ + uint32_t tmpVal = 0; + // set phy & controller + // latency code=3 (1066MHz) + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30,0x0f0a1323); // if fail than use 0x0f391323 + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30,0x0f0a0313); // tDQSS -> -1 + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30,0x0f0a3233); // tDQSS -> 1 + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_ODT_SEL,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_OE_CTRL_HW,0x1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_VREF_MODE,0x1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_OE_TIMER,0x3); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30,tmpVal); + set_uhs_latency_w(latency_wr[0]); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_34,0x0b030404); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_38,0x050e0418); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_3C,0x0a6a1c1c); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_44,0x07110710); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_50,0x01333333); + + uhs_phy_delay_us(100); +} + +uint8_t uhs_err_handler(uint8_t err) +{ + err_flag = 1; + uhs_phy_cal_res->err_type = err; + switch (err) { + case UHS_REGR_GNT_ERR: + uhs_phy_printfe("UHS_REGR_GNT_ERR\r\n"); + break; + case UHS_REGR_DONE_ERR: + uhs_phy_printfe("UHS_REGR_DONE_ERR = %d\r\n",regr_done_err); + uhs_phy_cal_res->err_sub_type = regr_done_err; + break; + case UHS_REGW_GNT_ERR: + uhs_phy_printfe("UHS_REGW_GNT_ERR\r\n"); + break; + case UHS_REGW_DONE_ERR: + uhs_phy_printfe("UHS_REGW_DONE_ERR\r\n"); + break; + case UHS_LATENCY_CODE_WRITE_ERR: + uhs_phy_printfe("UHS_LATENCY_CODE_WRITE_ERR\r\n"); + break; + case UHS_INIT_ARRAY_WRITE_ERR: + uhs_phy_printfe("UHS_INIT_ARRAY_WRITE_ERR = %d\r\n",init_array_write_err); + uhs_phy_cal_res->err_sub_type = init_array_write_err; + break; + case UHS_REG_READ_CAL_ERR: + uhs_phy_printfe("UHS_REG_READ_CAL_ERR = %d\r\n",reg_read_err); + uhs_phy_cal_res->err_sub_type = reg_read_err; + break; + case UHS_REG_WRITE_CAL_ERR: + uhs_phy_printfe("UHS_REG_WRITE_CAL_ERR = %d\r\n",reg_write_err); + uhs_phy_cal_res->err_sub_type = reg_write_err; + break; + case UHS_ARRAY_READ_LAT_ERR: + uhs_phy_printfe("UHS_ARRAY_READ_LAT_ERR = %d\r\n",array_read_err); + uhs_phy_cal_res->err_sub_type = array_read_err; + break; + case UHS_ARRAY_WRITE_CK_ERR: + uhs_phy_printfe("UHS_ARRAY_WRITE_CK_ERR\r\n"); + break; + case UHS_ARRAY_READ_CAL_ERR: + uhs_phy_printfe("UHS_ARRAY_READ_CAL_ERR\r\n"); + break; + case UHS_ARRAY_WRITE_CAL_ERR: + uhs_phy_printfe("UHS_ARRAY_WRITE_CAL_ERR\r\n"); + break; + case UHS_CACHE_ENABLE_ERR: + uhs_phy_printfe("UHS_CACHE_ENABLE_ERR\r\n"); + break; + case UHS_CACHE_DISABLE_ERR: + uhs_phy_printfe("UHS_CACHE_DISABLE_ERR\r\n"); + break; + case UHS_CACHE_RECOVER_ERR: + uhs_phy_printfe("UHS_CACHE_RECOVER_ERR\r\n"); + break; + case UHS_REG_WRITE_2kM_ERR: + uhs_phy_printfe("UHS_REG_WRITE_2kM_ERR\r\n"); + break; + case UHS_BAD_DIE_ERR: + uhs_phy_printfe("UHS_BAD_DIE_ERR\r\n"); + break; + case UHS_DIAGONAL_TEST_ERR: + uhs_phy_printfe("UHS_DIAGONAL_TEST_ERR\r\n"); + break; + case UHS_ALL_ADDR_TEST_ERR: + uhs_phy_printfe("UHS_ALL_ADDR_TEST_ERR\r\n"); + break; + default: + break; + } + uhs_phy_printfe("ERR_AT %ldMbps\r\n",cfg_glb->pck_freq); + uhs_phy_reg_dump(); + #if CAL_MODE == 0 || CAL_MODE == 1 + while(1){ + uhs_phy_printfe("%d",err); + uhs_phy_delay_ms(10000); + }; + #endif + return err_flag; +} + +void uhs_phy_reg_dump(void){ + uint32_t len = 0x150; + uint32_t i = 0; + + // uhs_phy_printf_debug("UHS_PHY_REG_DUMP_START\r\n"); + // for(i = 0;i <= len;i = i+4){ + // uhs_phy_printf_debug("0x%lx,0x%lx\r\n",(addr_dump + i),*((volatile uint32_t*)(addr_dump + i))); + // } + // uhs_phy_printf_debug("UHS_PHY_REG_DUMP_END\r\n"); + uhs_phy_printfe("UHS_PHY_REG_DUMP_START\r\n"); + for(i = 0;i <= len;i = i+4){ + uhs_phy_printfe("0x%lx,0x%lx\r\n",(addr_dump + i),*((volatile uint32_t*)(addr_dump + i))); + } + uhs_phy_printfe("UHS_PHY_REG_DUMP_END\r\n"); +} + +uint8_t uhs_reg_w(uint32_t uhs_latency,uint32_t uhs_drive,uint32_t ma,uint32_t BL_32) +{ + uint32_t tmpVal = 0; + uint32_t count = 0; + if(ma == 0) + { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_PSRAM_CONFIGURE); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_LATENCY,uhs_latency); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_DRIVE_ST,uhs_drive); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_PSRAM_CONFIGURE,tmpVal); + } + else if(ma == 2) + { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_PSRAM_CONFIGURE); + if (BL_32 == 1){ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_BL_64,0x1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_BL_32,0x1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_BL_16,0x0); + }else if (BL_32 == 2){ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_BL_64,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_BL_32,0x1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_BL_16,0x1); + }else{ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_BL_64,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_BL_32,0x0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_UHS_BL_16,0x0); + } + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_PSRAM_CONFIGURE,tmpVal); + } + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_MODE_REG,ma); //reg_mode_reg + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_CONFIG_REQ,0x1); //reg_config_req + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + // uhs_phy_printf_debug("reg_w GNT while\r\n"); + while (1) + { + if (count == 100000){ + return uhs_err_handler(UHS_REGW_GNT_ERR); + } + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_GET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_CONFIG_GNT); + if (tmpVal == 1) + { + uhs_phy_printf_debug("reg_w GNT pass\r\n"); + break; + } + count ++; + } + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_REGW_PULSE,0x1); //reg_regw_pulse + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD,tmpVal); + + count = 0; + while (1) + { + if (count == 100000){ + return uhs_err_handler(UHS_REGW_DONE_ERR); + } + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD); + tmpVal = BL_GET_REG_BITS_VAL(tmpVal,PSRAM_UHS_STS_REGW_DONE); //regw_done + if (tmpVal == 1) + { + uhs_phy_printf_debug("reg_w DONE pass\r\n"); + break; + } + count ++; + } + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_CONFIG_REQ,0x0); //reg_config_req + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + uhs_phy_delay_us(10); + + return 0; +} + +uint8_t uhs_reg_r(uint32_t ma,uint8_t flag) +{ + uint32_t tmpVal = 0; + // uint32_t tmpInd = 0; + uint32_t count = 0; + uint8_t opc = 1; + + if (flag == 1){ + uhs_phy_af_onoff(0); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_48); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_FORCE_FSM,0x1); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_48,tmpVal); + uhs_phy_delay_us(50); + } + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_MODE_REG,ma); //reg_mode_reg + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_CONFIG_REQ,0x1); //reg_config_req + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + + while (1) + { + if (count == 100000){ + return uhs_err_handler(UHS_REGR_GNT_ERR); + } + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_GET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_CONFIG_GNT); + if (tmpVal == 1) + { + uhs_phy_printf_debug("reg_r GNT pass\r\n"); + break; + } + count ++; + } + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_REGR_PULSE,0x1); //reg_regr_pulse + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD,tmpVal); + + count = 0; + while (1) + { + if (flag == 1){ + if (count == 100){ + regr_done_err = 2; + return uhs_err_handler(UHS_REGR_DONE_ERR); + } + uhs_phy_delay_us(20); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD); + tmpVal = BL_GET_REG_BITS_VAL(tmpVal,PSRAM_UHS_STS_REGR_DONE); //regr_done + if (tmpVal == 1){ + uhs_phy_printf_debug("reg_r DONE pass\r\n"); + break; + } + count ++; + + // if (tmpVal == 1){ + // uhs_phy_printf_debug("reg_r DONE pass\r\n"); + // opc = 1; + // }else{ + // uhs_phy_printf_debug("reg_r DONE fail\r\n"); + // opc = 0; + // } + // break; + } + else{ + if (count == 100000){ + regr_done_err = 1; + return uhs_err_handler(UHS_REGR_DONE_ERR); + } + uhs_phy_delay_us(10); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD); + tmpVal = BL_GET_REG_BITS_VAL(tmpVal,PSRAM_UHS_STS_REGR_DONE); //regr_done + if (tmpVal == 1){ + uhs_phy_printf_debug("reg_r DONE pass\r\n"); + break; + } + count ++; + } + } + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_CONFIG_REQ,0x0); //reg_config_req + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + + if (opc == 0){ + uhs_reset(0); + } + + if (flag == 1){ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_48); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_FORCE_FSM,0x0); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_48,tmpVal); + uhs_phy_delay_us(50); + + uhs_phy_af_onoff(1); + } + + uhs_phy_delay_us(10); + return opc; +} + + +void cfg_dq_rx(uint8_t dq){ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_24); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ15_DLY_RX,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ14_DLY_RX,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_24,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_20); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ13_DLY_RX,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ12_DLY_RX,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_20,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_1C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ11_DLY_RX,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ10_DLY_RX,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_1C,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_18); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ9_DLY_RX,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ8_DLY_RX,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_18,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_14); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ7_DLY_RX,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ6_DLY_RX,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_14,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_10); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ5_DLY_RX,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ4_DLY_RX,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_10,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_0C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ3_DLY_RX,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ2_DLY_RX,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_0C,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_08); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ1_DLY_RX,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ0_DLY_RX,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_08,tmpVal); + uhs_phy_delay_us(10); +} + +void cfg_dqs_rx(uint8_t dqs){ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_28); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQS0_DIFF_DLY_RX,dqs); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_28,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_2C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQS1_DIFF_DLY_RX,dqs); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_2C,tmpVal); + uhs_phy_delay_us(10); +} + +void cfg_ck_cen_drv(uint8_t array_ck_dly_drv,uint8_t array_cen_dly_drv){ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_00); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_CK_DLY_DRV,array_ck_dly_drv); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_CEN_DLY_DRV,array_cen_dly_drv); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_00,tmpVal); + uhs_phy_delay_us(50); +} + +void uhs_reset(uint8_t ma_rb) +{ + // uint32_t tmpVal = 0; + // uint32_t len = 0x150; + // uint32_t val_sr[len>>2]; + // int32_t i = 0; + + uhs_phy_printf("IN_UHS_RESET\r\n"); + + // for( i = len ; i >= 0 ; i = i-4 ){ + // if( i != 0x4 ){ + // val_sr[i>>2] = *((volatile uint32_t*)(addr_dump + i)); + // } + // } + + // tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_AF_EN,0); + // BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + // uhs_phy_delay_us(100); + + // tmpVal = BL_RD_WORD(0x30007044); + // tmpVal = tmpVal | 0x00008000; + // BL_WR_WORD(0x30007044,tmpVal); + // uhs_phy_delay_us(100); + // tmpVal = tmpVal & 0xFFFF7FFF; + // BL_WR_WORD(0x30007044,tmpVal); + // uhs_phy_delay_us(200); + + // BL_WR_WORD(0x3000F030,0x18090610); + + // #if PSRAM_32MB + // PSRAM_UHS_Cfg_Type psramCfg = { + // datarate, + // PSRAM_MEM_SIZE_32MB, + // PSRAM_PAGE_SIZE_2KB, + // 0, + // }; + // #else + // PSRAM_UHS_Cfg_Type psramCfg = { + // datarate, + // PSRAM_MEM_SIZE_64MB, + // PSRAM_PAGE_SIZE_2KB, + // 0, + // }; + // #endif + // Psram_UHS_Init_Override(cfg_glb); //controller init + + // set_or_uhs(); + // set_uhs_phy(); + + // for( i = len ; i >= 0 ; i = i-4 ){ + // if( i != 0x4 ){ + // *((volatile uint32_t*)(addr_dump + i)) = val_sr[i>>2]; + // } + // } + // uhs_phy_delay_us(400); + + if (ma_rb){ + mr_read_back(); + }else{ + power_up_mm(1); + uhs_phy_pwr_down(); + latency_wr_2kM[1] --; + uhs_phy_init_core(cfg_glb); + } + + uhs_phy_printf("OUT_UHS_RESET\r\n"); +} + +void set_uhs_latency_r(uint32_t uhs_latency) +{ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_RL_ANA,uhs_latency%4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_RL_DIG,uhs_latency/4); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30,tmpVal); + uhs_phy_delay_us(50); +} + +void set_uhs_latency_w(uint32_t uhs_latency) +{ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_WL_ANA,uhs_latency%4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_WL_DIG,uhs_latency/4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_WL_DQ_ANA,(uhs_latency+1)%4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_PHY_WL_DQ_DIG,(uhs_latency+1)/4); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30,tmpVal); + uhs_phy_delay_us(50); +} + +uint8_t mr_read_back(void) +{ + uint8_t cnt1; + uint32_t tmpVal; + for (cnt1=0;cnt1<=4;cnt1++){ + if(cnt1 != 3){ + CHECK_ERR_FLAG(uhs_reg_r,(cnt1,0)); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + uhs_phy_printf("MA%d = 0x%lx\r\n",cnt1,tmpVal); + } + } + return 0; +} + +uint8_t reg_read_cal(void) +{ + uint32_t tmpVal = 0; + uint32_t tmpVal_1 = 1; + uint32_t uhs_latency = 42; + int32_t i = 0; + uint8_t dqs_dq_flag = 0; + uint32_t reg_dqs = 0; + uint32_t reg_dq = 0; + + // for(uhs_latency = 41; uhs_latency > 0; uhs_latency --) + for(uhs_latency = latency_wr_2kM[1]; uhs_latency > 0; uhs_latency --) + { + if(uhs_latency == 34) + { + reg_read_err = 1; + return uhs_err_handler(UHS_REG_READ_CAL_ERR); + } + uhs_phy_printf_debug("reg read cal 1st by latency= %ld\r\n",uhs_latency); + set_uhs_latency_r(uhs_latency); + + // sweep dqs + cfg_dq_rx(0); + for(i = 15; i >= 0; i --) + { + cfg_dqs_rx(i); + // tmpVal_1 = uhs_reg_r(0,1); + CHECK_ERR_FLAG(uhs_reg_r,(0,1)); + if (cal_done_flag == 1) + return 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + uhs_phy_printf_debug("PSRAM_UHS_UHS_CMD>>24 1st dqs--, 0x%lx\r\n",tmpVal); + if(tmpVal == ((2<<3)+uhs_latency_code) && (tmpVal_1 == 1)){ + uhs_phy_printf_debug("reg read pass by dqs= %ld\r\n",i); + // reg_dqs = i; + dqs_dq_flag = 1; + break; + } + else{ + uhs_phy_printf_debug("reg read fail by dqs= %ld\r\n",i); + } + // if(tmpVal_1 == 0){ + // uhs_phy_printf_debug("read done not found!!!\r\n"); + // // uhs_reset(datarate); + // set_uhs_latency_r(uhs_latency); + // cfg_dq_rx(0); + // } + } + + // sweep dq + cfg_dqs_rx(0); + for(i = 15; i >=0; i --) + { + cfg_dq_rx(i); + // tmpVal_1 = uhs_reg_r(0,1); + CHECK_ERR_FLAG(uhs_reg_r,(0,1)); + if (cal_done_flag == 1) + return 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + uhs_phy_printf_debug("PSRAM_UHS_UHS_CMD>>24 1st dq--, 0x%lx\r\n",tmpVal); + if(tmpVal == ((2<<3)+uhs_latency_code) && (tmpVal_1 == 1)){ + uhs_phy_printf_debug("reg read pass by dq= %ld\r\n",i); + // reg_dq = i; + dqs_dq_flag = 1; + break; + } + else{ + uhs_phy_printf_debug("reg read fail by dq= %ld\r\n",i); + } + // if(tmpVal_1 == 0){ + // uhs_phy_printf_debug("read done not found!!!\r\n"); + // // uhs_reset(datarate); + // set_uhs_latency_r(uhs_latency); + // cfg_dqs_rx(0); + // } + } + if (dqs_dq_flag == 1){ + dqs_dq_flag = 0; + + uhs_latency = uhs_latency - 2; + uhs_phy_printf_debug("reg read cal 2nd by latency= %ld\r\n",uhs_latency); + set_uhs_latency_r(uhs_latency); //got a good robust uhs_latency + latency_wr[1] = uhs_latency; + //******verify the uhs_latency and get dqs/dq timing + //sweep dqs + cfg_dq_rx(0); + for(i = 15; i >= 0; i --) + { + cfg_dqs_rx(i); + CHECK_ERR_FLAG(uhs_reg_r,(0,0)); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + uhs_phy_printf_debug("PSRAM_UHS_UHS_CMD>>24 2nd dqs--, 0x%lx\r\n",tmpVal); + if(tmpVal == ((2<<3)+uhs_latency_code)) + { + uhs_phy_printf("reg read pass by --dqs= %ld\r\n",i); + reg_dqs += i; + dqs_dq_flag = 1; + break; + } + else{ + uhs_phy_printf_debug("reg read fail by dqs= %ld\r\n",i); + } + } + for(i = 0; i <= 15; i ++) + { + cfg_dqs_rx(i); + CHECK_ERR_FLAG(uhs_reg_r,(0,0)); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + uhs_phy_printf_debug("PSRAM_UHS_UHS_CMD>>24 2nd dqs++, 0x%lx\r\n",tmpVal); + if(tmpVal == ((2<<3)+uhs_latency_code)) + { + uhs_phy_printf("reg read pass by ++dqs= %ld\r\n",i); + reg_dqs += i; + dqs_dq_flag = 1; + break; + } + else{ + uhs_phy_printf_debug("reg read fail by dqs= %ld\r\n",i); + } + } + // sweep dq + cfg_dqs_rx(0); + for(i = 15; i >= 0; i --) + { + cfg_dq_rx(i); + CHECK_ERR_FLAG(uhs_reg_r,(0,0)); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + uhs_phy_printf_debug("PSRAM_UHS_UHS_CMD>>24 2nd dq--, 0x%lx\r\n",tmpVal); + if(tmpVal == ((2<<3)+uhs_latency_code)) + { + uhs_phy_printf("reg read pass by --dq= %ld\r\n",i); + reg_dq += i; + dqs_dq_flag = 1; + break; + } + else{ + uhs_phy_printf_debug("reg read fail by dq= %ld\r\n",i); + } + } + for(i = 0; i <= 15; i ++) + { + cfg_dq_rx(i); + CHECK_ERR_FLAG(uhs_reg_r,(0,0)); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + uhs_phy_printf_debug("PSRAM_UHS_UHS_CMD>>24 2nd dq++, 0x%lx\r\n",tmpVal); + if(tmpVal == ((2<<3)+uhs_latency_code)) + { + uhs_phy_printf("reg read pass by ++dq= %ld\r\n",i); + reg_dq += i; + dqs_dq_flag = 1; + break; + } + else{ + uhs_phy_printf_debug("reg read fail by dq= %ld\r\n",i); + } + } + + if(dqs_dq_flag == 0) + { + reg_read_err = 2; + return uhs_err_handler(UHS_REG_READ_CAL_ERR); + } + + if(reg_dqs >= reg_dq) + { + reg_dqs = (reg_dqs-reg_dq)/2; + reg_dq = 0; + } + else + { + reg_dq = (reg_dq-reg_dqs)/2; + reg_dqs = 0; + } + + // set dqs & dq by register read calibration result + cfg_dqs_rx(reg_dqs); + cfg_dq_rx(reg_dq); + CHECK_ERR_FLAG(mr_read_back,()); + uhs_phy_printf("reg_read_cal pass, latency= %ld, dqs= %ld, dq= %ld\r\n",uhs_latency,reg_dqs,reg_dq); + break; + } + } + + return 0; +} + +void cfg_dq_drv(uint32_t dq){ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_04); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DM0_DLY_DRV,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DM1_DLY_DRV,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_04,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_24); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ15_DLY_DRV,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ14_DLY_DRV,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_24,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_20); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ13_DLY_DRV,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ12_DLY_DRV,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_20,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_1C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ11_DLY_DRV,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ10_DLY_DRV,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_1C,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_18); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ9_DLY_DRV,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ8_DLY_DRV,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_18,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_14); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ7_DLY_DRV,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ6_DLY_DRV,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_14,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_10); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ5_DLY_DRV,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ4_DLY_DRV,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_10,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_0C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ3_DLY_DRV,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ2_DLY_DRV,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_0C,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_08); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ1_DLY_DRV,dq); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ0_DLY_DRV,dq); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_08,tmpVal); + // uhs_phy_delay_us(10); +} + +void cfg_dqs_drv(uint32_t dqs){ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_28); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQS0_DLY_DRV,dqs); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_28,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_2C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQS1_DLY_DRV,dqs); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_2C,tmpVal); + uhs_phy_delay_us(10); +} + +uint8_t reg_write_cal(void) //only need sweep dqs +{ + uint32_t tmpVal = 0; + // uint32_t tmpVal_1 = 0; + int32_t i = 0; + uint32_t reg_dqs; + uint32_t reg_dq = 0; + uint32_t reg_dqs1 = 0; + uint32_t reg_dqs2 = 0; + uint8_t dqs_dq_flag1 = 0; + uint8_t dqs_dq_flag2 = 0; + // reg_write_err = 0; + + // sweep1 dqs + for(i = 15; i >=0; i --) + { + cfg_dqs_drv(i); + CHECK_ERR_FLAG(uhs_reg_w,(uhs_latency_code,2,2,1)); //uhs_latency_code==3,uhs_drive==2,ma==2,BL_32==1 + CHECK_ERR_FLAG(uhs_reg_r,(2,0)); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + if(tmpVal == (16 + 32)) + { + uhs_phy_printf("reg write pass by -- dqs1= %ld\r\n",i); + reg_dqs1 = i; + dqs_dq_flag1 = 1; + break; + } + else{ + uhs_phy_printf_debug("reg write fail by -- dqs1= %ld\r\n",i); + } + } + // sweep2 dqs + for(i = 0; i <=15; i ++) + { + cfg_dqs_drv(i); + CHECK_ERR_FLAG(uhs_reg_w,(uhs_latency_code,2,2,2)); //uhs_latency_code==3,uhs_drive==2,ma==2,BL_32==0,BL_64==1 + CHECK_ERR_FLAG(uhs_reg_r,(2,0)); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + if(tmpVal == (8 + 16)) + { + uhs_phy_printf("reg write pass by ++ dqs2= %ld\r\n",i); + reg_dqs2 = i; + dqs_dq_flag2 = 1; + break; + } + else{ + uhs_phy_printf_debug("reg write fail by ++ dqs2= %ld\r\n",i); + } + } + + if(dqs_dq_flag1 == 1 && dqs_dq_flag2 == 1){ + reg_dqs = (reg_dqs1 + reg_dqs2) / 2 ; + }else if(dqs_dq_flag1 == 1 && dqs_dq_flag2 == 0){ + reg_dqs = reg_dqs1; + }else if(dqs_dq_flag1 == 0 && dqs_dq_flag2 == 1){ + reg_dqs = reg_dqs2; + } + else{ + reg_write_err = 1; + return uhs_err_handler(UHS_REG_WRITE_CAL_ERR); + } + + // if ck_dly_drv = 4, fix reg_dqs to 0 + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_00); + tmpVal = (tmpVal >> 16) & 0xF; + if(tmpVal == 4){ + reg_dqs = 0; + } + // set dqs by register write cal result + cfg_dqs_drv(reg_dqs); + CHECK_ERR_FLAG(uhs_reg_w,(uhs_latency_code,2,2,0)); //uhs_latency_code==3,uhs_drive==2,ma==2,BL_32==1 + CHECK_ERR_FLAG(uhs_reg_r,(2,0)); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + if(tmpVal == 0){ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_08); + reg_dq = BL_GET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ0_DLY_DRV); + uhs_phy_printf("reg write cal pass dqs= %ld, dq= %ld\r\n",reg_dqs,reg_dq); + } + else{ + reg_write_err = 2; + return uhs_err_handler(UHS_REG_WRITE_CAL_ERR); + } + + dqs_dq_delta = 16 + reg_dqs - reg_dq; + uhs_phy_printf("reg_write_cal return dqs_dq_delta= %ld\r\n",dqs_dq_delta); + + return 0; +} + +void array_write_fix(uint32_t addr,uint32_t len,uint32_t data0,uint32_t data1) +{ + uint32_t addr_tmp = addr; + uint32_t data = data0; + uint32_t i = 0; + + if (print_flag){ + uhs_phy_printf("IN_ARRAY_WRITE_FIX\r\n"); + } + for(i = 0; i < (len>>2); i ++) + { + addr_tmp = (i << 2) + addr; + if((i % 2) == 0) + data = data0 + i; + else + data = data1 + i; + + BL_WR_WORD(addr_tmp,data); + } + if (print_flag){ + uhs_phy_printf("BEFORE CACHE FUCNTION\r\n"); + } + if (cache_state){ + // #if CACHE_EN + __DSB(); + __ISB(); + L1C_DCache_Clean_Invalid_All(); + __DSB(); + __ISB(); + // #endif + } + uhs_phy_delay_us(10); + if (print_flag){ + uhs_phy_printf("OUT_ARRAY_WRITE_FIX\r\n"); + } +} + +uint8_t array_read_fix(uint32_t addr,uint32_t len,uint32_t data0,uint32_t data1) +{ + uint8_t array_read_pass = 1; + uint32_t addr_tmp = addr; + uint32_t data = data0; + uint32_t data_read = 0; + uint32_t i = 0; + + if (print_flag){ + uhs_phy_printf("IN_ARRAY_READ_FIX\r\n"); + } + for(i = 0; i < (len>>2); i ++) + { + // data_read = 0; + // data_read += *((volatile uint8_t *)(addr+(i<<2)+3)); + // data_read <<= 8; + // data_read += *((volatile uint8_t *)(addr+(i<<2)+2)); + // data_read <<= 8; + // data_read += *((volatile uint8_t *)(addr+(i<<2)+1)); + // data_read <<= 8; + // data_read += *((volatile uint8_t *)(addr+(i<<2)+0)); + + addr_tmp = (i << 2) + addr; + data_read = BL_RD_WORD(addr_tmp); + if((i % 2) == 0) + data = data0 + i; + else + data = data1 + i; + + if (print_flag && i == 0){ + uhs_phy_printf("addr 0x%lx, write_val 0x%lx, read_val 0x%lx\r\n",addr_tmp,data,data_read); + } + if(data_read != data){ + array_read_pass = 0; + uhs_phy_printf("addr 0x%lx, write_val 0x%lx, read_val error 0x%lx\r\n",addr_tmp,data,data_read); + break; + } + } + if (print_flag){ + uhs_phy_printf("BEFORE CACHE FUCNTION\r\n"); + } + if (cache_state){ + // #if CACHE_EN + __DSB(); + __ISB(); + L1C_DCache_Clean_Invalid_All(); + __DSB(); + __ISB(); + // #endif + } + uhs_phy_delay_us(10); + if (print_flag){ + uhs_phy_printf("OUT_ARRAY_READ_FIX\r\n"); + } + return array_read_pass; +} + +void set_ck_dly_drv(uint32_t array_ck_dly_drv) +{ + uint32_t array_dqx_dly_drv = 0; + uint32_t array_dqsx_dly_drv = 0; + uint32_t array_cen_dly_drv = 0; + + uhs_phy_delay_us(10); // ck modify need time + + array_dqx_dly_drv = (array_ck_dly_drv >=4) ? (array_ck_dly_drv-4) : 0; + array_cen_dly_drv = array_dqx_dly_drv + 1; + array_dqx_dly_drv = (array_dqx_dly_drv > 15) ? 15 : array_dqx_dly_drv; + array_cen_dly_drv = (array_cen_dly_drv > 15) ? 15 : array_cen_dly_drv; + array_dqsx_dly_drv = (array_dqsx_dly_drv > 15) ? 15 : array_dqsx_dly_drv; + + cfg_dq_drv(array_dqx_dly_drv); + // cfg_dqs_drv(array_dqsx_dly_drv); + cfg_ck_cen_drv(array_ck_dly_drv,array_cen_dly_drv); + // uhs_phy_printf_debug("array_dqx_dly_drv= %ld,array_dqsx_dly_drv= %ld,array_ck_dly_drv= %ld,array_cen_dly_drv= %ld\r\n",array_dqx_dly_drv,array_dqsx_dly_drv,array_ck_dly_drv,array_cen_dly_drv); //debug + // uhs_phy_delay_us(50); // ck modify need time +} + +uint8_t array_read_latency_cal(void) +{ + // uint32_t tmpVal = 0; + uint32_t uhs_latency = 42; + // uint8_t array_ck_dly_drv_val[3] = {15,4,9}; + uint8_t array_ck_dly_drv_val[3] = {4,9,15}; + uint8_t ck_i; + uint32_t array_ck_dly_drv = 0; + int32_t i = 0; + uint32_t array_dqs = 0; + uint32_t array_dq = 0; + uint32_t dqs_flag; + uint32_t dq_flag; + uint32_t len = 128; + uint8_t rwindow = 0; + + for(uhs_latency = latency_wr[1]; uhs_latency > 0; uhs_latency --) + { + if(uhs_latency == 34) + { + array_read_err = 1; + return uhs_err_handler(UHS_ARRAY_READ_LAT_ERR); + } + + uhs_phy_printf_debug("array read cal by latency= %ld\r\n",uhs_latency); + set_uhs_latency_r(uhs_latency); + + for (ck_i = 0; ck_i < (sizeof(array_ck_dly_drv_val)/sizeof(array_ck_dly_drv_val[0])); ck_i++){ + array_ck_dly_drv = array_ck_dly_drv_val[ck_i]; + set_ck_dly_drv(array_ck_dly_drv); + uhs_phy_printf_debug("array read cal by ck= %ld\r\n",array_ck_dly_drv); + + rwindow = 0; + + // sweep dqs + cfg_dq_rx(0); + for(i = 15; i >= 0; i --) + { + cfg_dqs_rx(i); + dqs_flag = array_read_fix(addr_rarray,len,data0_rarray,data1_rarray); + if(dqs_flag == 1) + { + uhs_phy_printf("array_read_dqs_dq_cal pass by --dqs= %ld\r\n",i); + array_dqs += i; + rwindow += i; + uhs_phy_cal_res->rwindow_end = i; + break; + } + } + for(i = 0; i <= 15; i ++) + { + cfg_dqs_rx(i); + dqs_flag = array_read_fix(addr_rarray,len,data0_rarray,data1_rarray); + if(dqs_flag == 1) + { + uhs_phy_printf("array_read_dqs_dq_cal pass by ++dqs= %ld\r\n",i); + array_dqs += i; + rwindow = (i > 0) ? (rwindow - i) : (rwindow + 1); + uhs_phy_cal_res->rwindow_begin = i; + break; + } + } + // sweep dq + cfg_dqs_rx(0); + for(i = 15; i >= 0; i --) + { + cfg_dq_rx(i); + dq_flag = array_read_fix(addr_rarray,len,data0_rarray,data1_rarray); + if(dq_flag == 1) + { + uhs_phy_printf("array_read_dqs_dq_cal pass by --dq= %ld\r\n",i); + array_dq += i; + rwindow += i; + break; + } + } + for(i = 0; i <= 15; i ++) + { + cfg_dq_rx(i); + dq_flag = array_read_fix(addr_rarray,len,data0_rarray,data1_rarray); + if(dq_flag == 1) + { + uhs_phy_printf("array_read_dqs_dq_cal pass by ++dq= %ld\r\n",i); + array_dq += i; + rwindow -= i; + break; + } + } + + if(dqs_flag == 1 || dq_flag == 1){ + if(array_dqs >= array_dq) + { + array_dqs = (array_dqs-array_dq)/2; + array_dq = 0; + } + else + { + #if CAL_MODE == 2 + array_read_err = 2; + return uhs_err_handler(UHS_ARRAY_READ_LAT_ERR); + #endif + array_dq = (array_dq-array_dqs)/2; + array_dqs = 0; + } + cfg_dq_rx(array_dq); + cfg_dqs_rx(array_dqs); + uhs_phy_printf("array_read_dqs_dq_cal valid code number= %d\r\n",rwindow); + uhs_phy_cal_res->rwindow = rwindow; + uhs_phy_cal_res->rdqs = array_dqs; + uhs_phy_cal_res->rdq = array_dq; + uhs_phy_printf("array_read_dqs_dq_cal pass by array_dqs= %ld, array_dq= %ld\r\n",array_dqs,array_dq); + break; + } + } + if(dqs_flag == 1 || dq_flag == 1){ + uhs_phy_cal_res->rl = uhs_latency; + uhs_phy_printf("array_read_latency_cal pass, latency= %ld, ck= %ld\r\n",uhs_latency,array_ck_dly_drv); + break; + } + } + + return 0; +} + +uint8_t array_write_ck_cal(void) +{ + uint32_t array_ck_dly_drv = 0; + uint32_t array_ck_dly_drv1 = 15; + uint32_t array_ck_dly_drv2 = 4; + uint32_t flag_1 = 0; + uint32_t flag_2 = 0; + uint32_t len = 1024<<4; + + for(array_ck_dly_drv = 4; array_ck_dly_drv <= 15; array_ck_dly_drv ++) + { + set_ck_dly_drv(array_ck_dly_drv); + flag_2 = array_read_fix(addr_rarray,len,data0_rarray,data1_rarray); + if (flag_2 == 0){ + uhs_phy_printf("array_write_ck_cal ck++ = %ld, flag_2 = %ld\r\n",array_ck_dly_drv,flag_2); + } + if(flag_2 == 0 && flag_ck2 == 0){ + flag_ck2 = 1; + uhs_phy_printf("array_write_ck_cal fail by ++ck= %ld\r\n",array_ck_dly_drv); + array_ck_dly_drv2 = array_ck_dly_drv; + // break; + } + } + if (flag_ck2 == 1) + flag_2 = 0; + for(array_ck_dly_drv = 15; array_ck_dly_drv >= 4; array_ck_dly_drv --) + { + set_ck_dly_drv(array_ck_dly_drv); + flag_1 = array_read_fix(addr_rarray,len,data0_rarray,data1_rarray); + if (flag_1 == 0){ + uhs_phy_printf("array_write_ck_cal ck-- = %ld, flag_1 = %ld\r\n",array_ck_dly_drv,flag_1); + } + if(flag_1 == 0 && flag_ck1 == 0){ + flag_ck1 = 1; + uhs_phy_printf("array_write_ck_cal fail by --ck= %ld\r\n",array_ck_dly_drv); + array_ck_dly_drv1 = array_ck_dly_drv; + // break; + } + } + if (flag_ck1 == 1) + flag_1 = 0; + + if (flag_1 == 0 && flag_2 == 0){ + if(array_ck_dly_drv1 == 15 && array_ck_dly_drv2 == 4) + { + return uhs_err_handler(UHS_ARRAY_WRITE_CK_ERR); + } + else if ((15 - array_ck_dly_drv1) >= (array_ck_dly_drv2 - 4)){ + array_ck_dly_drv = 15; + } + else{ + array_ck_dly_drv = 4; + } + } + else if (flag_1 == 0 && flag_2 == 1){ + array_ck_dly_drv = (array_ck_dly_drv1 > 9) ? 4 : 15; + }else if (flag_1 == 1 && flag_2 == 0){ + array_ck_dly_drv = (array_ck_dly_drv2 > 9) ? 4 : 15; + } + else { + array_ck_dly_drv = (15 + 4) / 2; + } + + set_ck_dly_drv(array_ck_dly_drv); + uhs_phy_cal_res->ck = array_ck_dly_drv; + uhs_phy_printf("array_write_ck_cal pass, ck= %ld\r\n",array_ck_dly_drv); + + return 0; +} + +uint8_t array_read_dqs_dq_cal(void) +{ + int32_t i = 0; + uint32_t array_dqs = 0; + uint32_t array_dq = 0; + uint32_t dqs_flag; + uint32_t dq_flag; + uint32_t len = 128; + + // sweep dqs + cfg_dq_rx(0); + + for(i = 15; i >= 0; i --) + { + cfg_dqs_rx(i); + dqs_flag = array_read_fix(addr_rarray,len,data0_rarray,data1_rarray); + if(dqs_flag == 1) + { + uhs_phy_printf("array_read_dqs_dq_cal pass by dqs= %ld\r\n",i); + array_dqs = i; + break; + } + } + // sweep dq + cfg_dqs_rx(0); + for(i = 15; i >=0; i --) + { + cfg_dq_rx(i); + dq_flag = array_read_fix(addr_rarray,len,data0_rarray,data1_rarray); + if(dq_flag == 1) + { + uhs_phy_printf("array_read_dqs_dq_cal pass by dq= %ld\r\n",i); + array_dq = i; + break; + } + } + if(dqs_flag == 0 && dq_flag == 0) + { + return uhs_err_handler(UHS_ARRAY_READ_CAL_ERR); + } + if(array_dqs > array_dq) + { + array_dqs = (array_dqs-array_dq)/2; + array_dq = 0; + } + else + { + array_dq = (array_dq-array_dqs)/2; + array_dqs = 0; + } + cfg_dq_rx(array_dq); + cfg_dqs_rx(array_dqs); + uhs_phy_printf("array_read_dqs_dq_cal pass by array_dqs= %ld, array_dq= %ld\r\n",array_dqs,array_dq); + + return 0; +} + +uint8_t array_write_dqs_dq_cal(void) +{ + uint32_t tmpVal = 0; + int32_t i = 0; + uint32_t dqs_flag1 = 0; + uint32_t dqs_flag2 = 0; + uint32_t array_dqs_dly_drv = 0; + uint32_t array_dqs_dly_drv1 = 0; + uint32_t array_dqs_dly_drv2 = 0; + + uint32_t addr = 0x50000000; + uint32_t len = 128; + uint32_t data0 = 0x23456789; + uint32_t data1 = 0x98765432; + + uint8_t wwindow = 0; + + for(i = 15; i >= 0; i --) + { + cfg_dqs_drv(i); + array_write_fix(addr,len,data0,data1); + dqs_flag1 = array_read_fix(addr,len,data0,data1); + if(dqs_flag1 == 1) + { + uhs_phy_printf("array_write_dqs_dq_cal pass by -- dqs1= %ld\r\n",i); + array_dqs_dly_drv1 = i; + uhs_phy_cal_res->wwindow_end = i; + break; + } + else + { + uhs_phy_printf_debug("array_write_dqs_dq_cal fail by -- dqs1= %ld\r\n",i); + } + } + for(i = 0; i <= 15; i ++) + { + cfg_dqs_drv(i); + array_write_fix(addr,len,data1,data0); + dqs_flag2 = array_read_fix(addr,len,data1,data0); + if(dqs_flag2 == 1) + { + uhs_phy_printf("array_write_dqs_dq_cal pass by ++ dqs2= %ld\r\n",i); + array_dqs_dly_drv2 = i; + uhs_phy_cal_res->wwindow_begin = i; + break; + } + else + { + uhs_phy_printf_debug("array_write_dqs_dq_cal fail by ++ dqs2= %ld\r\n",i); + } + } + + if(dqs_flag1 == 1 && dqs_flag2 == 1) + { + array_dqs_dly_drv = (array_dqs_dly_drv1 + array_dqs_dly_drv2) / 2 ; + } + else if(dqs_flag1 == 1 && dqs_flag2 == 0){ + array_dqs_dly_drv = array_dqs_dly_drv1; + }else if(dqs_flag1 == 0 && dqs_flag2 == 1){ + array_dqs_dly_drv = array_dqs_dly_drv2; + }else{ + return uhs_err_handler(UHS_ARRAY_WRITE_CAL_ERR); + } + + //debug + // array_dqs_dly_drv = 4; + + // if ck_dly_drv = 4, fix dqsx_dly_drv to 0 + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_00); + tmpVal = (tmpVal >> 16) & 0xF; + if(tmpVal == 4){ + array_dqs_dly_drv = 0; + uhs_phy_cal_res->wwindow_begin = 0; + } + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_08); + tmpVal = BL_GET_REG_BITS_VAL(tmpVal,PSRAM_UHS_DQ0_DLY_DRV); + + wwindow = (array_dqs_dly_drv > 0) ? (array_dqs_dly_drv1 - array_dqs_dly_drv2 + 1) : (array_dqs_dly_drv1 - 0 + 1); + uhs_phy_printf("array_write_dqs_dq_cal valid code number= %d\r\n",wwindow); + uhs_phy_cal_res->wwindow = wwindow; + uhs_phy_cal_res->wdqs = array_dqs_dly_drv; + uhs_phy_cal_res->wdq = tmpVal; + uhs_phy_printf("array_write_dqs_dq_cal pass by array_dqs_dly_drv= %ld,array_dq_dly_drv= %ld\r\n",array_dqs_dly_drv,tmpVal); + // set dqs by register write cal result + cfg_dqs_drv(array_dqs_dly_drv); + + return 0; +} + +BL_Err_Type ATTR_CLOCK_SECTION GLB_Config_UHS_PLL_Freq(GLB_XTAL_Type xtalType, uint32_t pllFreq) +{ + uint32_t xtalFreq = 0; + uint32_t factor = 0; + GLB_MU_PLL_CFG_BASIC_Type uhsPllMCfg = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 7, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 2100/50, /*!< pll_even_div_ratio */ + }; + GLB_MU_PLL_Cfg_Type uhsPllCfg[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &uhsPllMCfg, 0x0 }, /*!< XTAL is 24M */ + { &uhsPllMCfg, 0x0 }, /*!< XTAL is 32M */ + { &uhsPllMCfg, 0x0 }, /*!< XTAL is 38.4M */ + { &uhsPllMCfg, 0x0 }, /*!< XTAL is 40M */ + { &uhsPllMCfg, 0x0 }, /*!< XTAL is 26M */ + { &uhsPllMCfg, 0x0 }, /*!< XTAL is RC32M */ + }; + GLB_PLL_REF_CLK_Type refClk; + + /* calc clkpllRefdivRatio */ + switch(xtalType){ + case GLB_XTAL_NONE: + return ERROR; + case GLB_XTAL_24M: + xtalFreq = 240; + uhsPllMCfg.clkpllRefdivRatio = 1; + break; + case GLB_XTAL_32M: + xtalFreq = 320; + uhsPllMCfg.clkpllRefdivRatio = 2; + break; + case GLB_XTAL_38P4M: + xtalFreq = 384; + uhsPllMCfg.clkpllRefdivRatio = 2; + break; + case GLB_XTAL_40M: + xtalFreq = 400; + uhsPllMCfg.clkpllRefdivRatio = 2; + break; + case GLB_XTAL_26M: + xtalFreq = 260; + uhsPllMCfg.clkpllRefdivRatio = 1; + break; + case GLB_XTAL_RC32M: + xtalFreq = 320; + uhsPllMCfg.clkpllRefdivRatio = 2; + break; + default : + break; + } + /* calc clkpllSelSampleClk */ + factor = pllFreq*20480/(xtalFreq/uhsPllMCfg.clkpllRefdivRatio); + if(factor<32*2048){ + uhsPllMCfg.clkpllSelSampleClk = 0; + }else if(factor<64*2048){ + uhsPllMCfg.clkpllSelSampleClk = 1; + }else if(factor<128*2048){ + uhsPllMCfg.clkpllSelSampleClk = 2; + }else{ + uhsPllMCfg.clkpllSelSampleClk = 2; + } + /* calc clkpllVcoSpeed */ + if(pllFreq<800){ + uhsPllMCfg.clkpllVcoSpeed = 1; + }else if(pllFreq<1000){ + uhsPllMCfg.clkpllVcoSpeed = 2; + }else if(pllFreq<1200){ + uhsPllMCfg.clkpllVcoSpeed = 3; + }else if(pllFreq<1500){ + uhsPllMCfg.clkpllVcoSpeed = 4; + }else if(pllFreq<1700){ + uhsPllMCfg.clkpllVcoSpeed = 5; + }else if(pllFreq<1900){ + uhsPllMCfg.clkpllVcoSpeed = 6; + }else if(pllFreq<2200){ + uhsPllMCfg.clkpllVcoSpeed = 7; + }else{ + uhsPllMCfg.clkpllVcoSpeed = 8; + } + /* calc clkpllEvenDivRatio */ + uhsPllMCfg.clkpllEvenDivRatio = pllFreq/50; + /* calc clkpllSdmin */ + uhsPllCfg[GLB_XTAL_24M].clkpllSdmin = factor; + uhsPllCfg[GLB_XTAL_32M].clkpllSdmin = factor; + uhsPllCfg[GLB_XTAL_38P4M].clkpllSdmin = factor; + uhsPllCfg[GLB_XTAL_40M].clkpllSdmin = factor; + uhsPllCfg[GLB_XTAL_26M].clkpllSdmin = factor; + uhsPllCfg[GLB_XTAL_RC32M].clkpllSdmin = factor; + + if (xtalType == GLB_XTAL_RC32M) { + refClk = GLB_PLL_REFCLK_RC32M; + } else { + refClk = GLB_PLL_REFCLK_XTAL; + } + + // GLB_Power_Off_MU_PLL(GLB_MU_PLL_UHSPLL); + GLB_MU_PLL_Ref_Clk_Sel(GLB_MU_PLL_UHSPLL, refClk); + GLB_Power_On_MU_PLL(GLB_MU_PLL_UHSPLL, &(uhsPllCfg[xtalType]), 1); + + return SUCCESS; +} + +uint8_t init_reg_write(void){ + uint32_t tmpVal = 0; + uint8_t wl_i; + uint32_t wl; + uint32_t wdqs; + // uint8_t wdq_val[3] = {0,11,5}; + uint8_t wdq_val[3] = {0,5,11}; + uint8_t wdq_i; + uint32_t wdq; + uint32_t rl; + uint32_t rdqs; + uint32_t rdq; + uint8_t rl_i; + uint8_t wl_val_32[6] = {1,0,2,3,4,5}; + uint8_t rl_val_32[5] = {36,37,38,39,40}; + uint8_t wl_val_64[6] = {9,8,10,7,11,6}; + uint8_t rl_val_64[5] = {36,37,38,39,40}; + uint8_t wl_val[6]; + uint8_t rl_val[5]; + + if (cfg_glb->psramMemSize == PSRAM_MEM_SIZE_32MB){ + for (wl_i = 0; wl_i < (sizeof(wl_val)/sizeof(wl_val[0])); wl_i++){ + wl_val[wl_i] = wl_val_32[wl_i]; + } + for (rl_i = 0; rl_i < (sizeof(rl_val)/sizeof(rl_val[0])); rl_i++){ + rl_val[rl_i] = rl_val_32[rl_i]; + } + }else if(cfg_glb->psramMemSize == PSRAM_MEM_SIZE_64MB){ + for (wl_i = 0; wl_i < (sizeof(wl_val)/sizeof(wl_val[0])); wl_i++){ + wl_val[wl_i] = wl_val_64[wl_i]; + } + for (rl_i = 0; rl_i < (sizeof(rl_val)/sizeof(rl_val[0])); rl_i++){ + rl_val[rl_i] = rl_val_64[rl_i]; + } + } + + // set to 2000Mbps + for (rl_i = 0; rl_i < (sizeof(rl_val)/sizeof(rl_val[0])); rl_i++){ + rl = rl_val[rl_i]; + set_uhs_latency_r(rl); + for (wl_i = 0; wl_i < (sizeof(wl_val)/sizeof(wl_val[0])); wl_i++){ + wl = wl_val[wl_i]; + latency_wr[0] = wl; + set_uhs_latency_w(wl); + for (wdq_i = 0; wdq_i < (sizeof(wdq_val)/sizeof(wdq_val[0])); wdq_i++){ + wdq = wdq_val[wdq_i]; + cfg_dq_drv(wdq); + cfg_ck_cen_drv(wdq + 4,wdq + 1); + for (wdqs = 0; wdqs <= 15; wdqs++){ + cfg_dqs_drv(wdqs); + set_uhs_phy_init(); + CHECK_ERR_FLAG(uhs_reg_w,(uhs_latency_code,2,0,0)); //uhs_latency_code==3,uhs_drive==2,ma==0,BL_32==0 + set_uhs_phy(); + rdq = 0; + cfg_dq_rx(rdq); + for (rdqs = 0; rdqs <= 15; rdqs++){ + cfg_dqs_rx(rdqs); + CHECK_ERR_FLAG(uhs_reg_r,(0,1)); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + uhs_phy_printf_debug("PSRAM_UHS_UHS_CMD>>24 = 0x%lx, rdqs++\r\n",tmpVal); + if(tmpVal == ((2<<3)+uhs_latency_code)){ + uhs_phy_printf("LATENCY_CODE_WRITE_SUCCESS, wl = %ld, wdqs = %ld, wdq = %ld, rl = %ld, rdqs = %ld, rdq = %ld\r\n",wl,wdqs,wdq,rl,rdqs,rdq); + return 0; + } + else{ + uhs_phy_printf_debug("LATENCY_CODE_WRITE_FAIL, wl = %ld, wdqs = %ld, wdq = %ld, rl = %ld, rdqs = %ld, rdq = %ld\r\n",wl,wdqs,wdq,rl,rdqs,rdq); + } + } + rdqs = 0; + cfg_dqs_rx(rdqs); + for (rdq = 0; rdq <= 15; rdq++){ + cfg_dq_rx(rdq); + CHECK_ERR_FLAG(uhs_reg_r,(0,1)); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + uhs_phy_printf_debug("PSRAM_UHS_UHS_CMD>>24 = 0x%lx, rdq++\r\n",tmpVal); + if(tmpVal == ((2<<3)+uhs_latency_code)){ + uhs_phy_printf("LATENCY_CODE_WRITE_SUCCESS, wl = %ld, wdqs = %ld, wdq = %ld, rl = %ld, rdqs = %ld, rdq = %ld\r\n",wl,wdqs,wdq,rl,rdqs,rdq); + return 0; + } + else{ + uhs_phy_printf_debug("LATENCY_CODE_WRITE_FAIL, wl = %ld, wdqs = %ld, wdq = %ld, rl = %ld, rdqs = %ld, rdq = %ld\r\n",wl,wdqs,wdq,rl,rdqs,rdq); + } + } + } + } + } + } + return uhs_err_handler(UHS_LATENCY_CODE_WRITE_ERR); +} + +uint8_t init_array_write(void){ + uint8_t wl_val[6] = {13,12,14,11,15,10}; + uint8_t wl_i; + uint32_t wl; + uint32_t wdqs; + // uint8_t wdq_val[3] = {0,11,5}; + uint8_t wdq_val[3] = {0,5,11}; + uint8_t wdq_i; + uint32_t wdq; + uint32_t rl; + uint32_t rdqs; + uint32_t rdq; + uint32_t len = 1024<<4; + uint32_t flag = 0; + print_flag = 1; + + for (wl_i = 0; wl_i < (sizeof(wl_val)/sizeof(wl_val[0])); wl_i++){ + wl = wl_val[wl_i]; + latency_wr[0] = wl; + set_uhs_latency_w(wl); + for (wdq_i = 0; wdq_i < (sizeof(wdq_val)/sizeof(wdq_val[0])); wdq_i++){ + wdq = wdq_val[wdq_i]; + cfg_dq_drv(wdq); + cfg_ck_cen_drv(wdq + 4,wdq + 1); + for (wdqs = 0; wdqs <= 15; wdqs++){ + cfg_dqs_drv(wdqs); + array_write_fix(addr_rarray,len,data0_rarray,data1_rarray); + for (rl = latency_wr[1]; rl >= 35; rl--){ + set_uhs_latency_r(rl); + rdq = 0; + cfg_dq_rx(rdq); + for (rdqs = 0; rdqs <= 15; rdqs++){ + cfg_dqs_rx(rdqs); + flag = array_read_fix(addr_rarray,len,data0_rarray,data1_rarray); + if(flag == 1){ + uhs_phy_printf("INIT_ARRAY_WRITE_SUCCESS, rdqs++, wl = %ld, wdqs = %ld, wdq = %ld, rl = %ld, rdqs = %ld, rdq = %ld\r\n",wl,wdqs,wdq,rl,rdqs,rdq); + print_flag = 0; + #if CAL_MODE == 2 + if(wl != 13){ + init_array_write_err = 2; + return uhs_err_handler(UHS_INIT_ARRAY_WRITE_ERR); + } + #endif + uhs_phy_cal_res->wl = wl; + return 0; + } + else{ + uhs_phy_printf_debug("INIT_ARRAY_WRITE_FAIL, rdqs++, wl = %ld, wdqs = %ld, wdq = %ld, rl = %ld, rdqs = %ld, rdq = %ld\r\n",wl,wdqs,wdq,rl,rdqs,rdq); + } + } + rdqs = 0; + cfg_dqs_rx(rdqs); + for (rdq = 0; rdq <= 15; rdq++){ + cfg_dq_rx(rdq); + flag = array_read_fix(addr_rarray,len,data0_rarray,data1_rarray); + if(flag == 1){ + uhs_phy_printf("INIT_ARRAY_WRITE_SUCCESS, rdq++, wl = %ld, wdqs = %ld, wdq = %ld, rl = %ld, rdqs = %ld, rdq = %ld\r\n",wl,wdqs,wdq,rl,rdqs,rdq); + print_flag = 0; + #if CAL_MODE == 2 + if(wl != 13){ + init_array_write_err = 2; + return uhs_err_handler(UHS_INIT_ARRAY_WRITE_ERR); + } + #endif + uhs_phy_cal_res->wl = wl; + return 0; + } + else{ + uhs_phy_printf_debug("INIT_ARRAY_WRITE_FAIL, rdq++, wl = %ld, wdqs = %ld, wdq = %ld, rl = %ld, rdqs = %ld, rdq = %ld\r\n",wl,wdqs,wdq,rl,rdqs,rdq); + } + } + } + } + } + } + init_array_write_err = 1; + return uhs_err_handler(UHS_INIT_ARRAY_WRITE_ERR); +} + +void set_odt_en(void){ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_RSVD_REG); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_MR2_2_0,0x3); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_RSVD_REG,tmpVal); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_MODE_REG,0x2); //reg_mode_reg + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_CONFIG_REQ,0x1); //reg_config_req + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + uhs_phy_delay_us(10); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_REGW_PULSE,0x1); //reg_regw_pulse + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD,tmpVal); + uhs_phy_delay_us(10); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_REG_CONFIG_REQ,0x0); //reg_config_req + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_BASIC,tmpVal); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_ODT_SEL,0xf); // odt_sel + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_30,tmpVal); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_4C); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_ODT_SEL_HW,0x1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,PSRAM_UHS_ODT_SEL_DLY,0x3); + BL_WR_REG(PSRAM_UHS_BASE,PSRAM_UHS_PHY_CFG_4C,tmpVal); +} + +uint8_t init_reg_write_2kM(void){ + uint32_t tmpVal = 0; + uint8_t wl_val[6] = {13,12,14,11,15,10}; + uint8_t wl_i; + uint32_t wl; + uint32_t wdqs; + // uint8_t wdq_val[3] = {0,11,5}; + uint8_t wdq_val[3] = {0,5,11}; + uint8_t wdq_i; + uint32_t wdq; + + // set to 2000Mbps + for (wl_i = 0; wl_i < (sizeof(wl_val)/sizeof(wl_val[0])); wl_i++){ + wl = wl_val[wl_i]; + latency_wr[0] = wl; + set_uhs_latency_w(wl); + for (wdq_i = 0; wdq_i < (sizeof(wdq_val)/sizeof(wdq_val[0])); wdq_i++){ + wdq = wdq_val[wdq_i]; + cfg_dq_drv(wdq); + cfg_ck_cen_drv(wdq + 4,wdq + 1); + for (wdqs = 0; wdqs <= 15; wdqs++){ + cfg_dqs_drv(wdqs); + set_odt_en(); + CHECK_ERR_FLAG(uhs_reg_r,(2,0)); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + uhs_phy_printf_debug("MA2 = 0x%lx\r\n",tmpVal); + if(tmpVal == 3){ + uhs_phy_printf("2kM_REG_WRITE_SUCCESS, wl = %ld, wdqs = %ld, wdq = %ld\r\n",wl,wdqs,wdq); + return 0; + } + else{ + uhs_phy_printf_debug("2kM_REG_WRITE_FAIL, wl = %ld, wdqs = %ld, wdq = %ld\r\n",wl,wdqs,wdq); + } + } + } + } + return uhs_err_handler(UHS_REG_WRITE_2kM_ERR); +} + +uint8_t self_cal() +{ + uint32_t tmpVal = 0; + uint32_t datarate; + datarate = cfg_glb->pck_freq; + + if (datarate >= 933*2){ + uhs_latency_code = UHS_LATENCY_CODE_1066; + }else if(datarate >= 800*2){ + uhs_latency_code = UHS_LATENCY_CODE_933; + }else if(datarate >= 533*2){ + uhs_latency_code = UHS_LATENCY_CODE_800; + }else if(datarate >= 400*2){ + uhs_latency_code = UHS_LATENCY_CODE_533; + }else if(datarate >= 333*2){ + uhs_latency_code = UHS_LATENCY_CODE_400; + }else if(datarate >= 200*2){ + uhs_latency_code = UHS_LATENCY_CODE_333; + }else{ + uhs_latency_code = UHS_LATENCY_CODE_200; + } + // #if PSRAM_32MB + // PSRAM_UHS_Cfg_Type psramCfg = { + // datarate, + // PSRAM_MEM_SIZE_32MB, + // PSRAM_PAGE_SIZE_2KB, + // 0, + // }; + // #else + // PSRAM_UHS_Cfg_Type psramCfg = { + // datarate, + // PSRAM_MEM_SIZE_64MB, + // PSRAM_PAGE_SIZE_2KB, + // 0, + // }; + // #endif + + uhs_phy_printf("********** INIT_REG_WRITE **********\r\n"); + CHECK_ERR_FLAG(init_reg_write,()); //write latency code + // uhs_phy_printf("START_CAL_AT %ldMbps\r\n",datarate); + // datarate_glb = datarate; + // ramsize_glb = cfg->psramMemSize; + GLB_Config_UHS_PLL_Freq(GLB_XTAL_40M,datarate); + Psram_UHS_Init_Override(cfg_glb); //controller init + set_uhs_phy(); + + #if CAL_MODE == 0 + return 0; + // then load efuse, to set uhs phy regs + // call set_odt_en(), to set psram odt MR if need + // call mr_read_back() + #endif + + uhs_phy_printf("********** REG_READ_CAL **********\r\n"); + // uhs_phy_reg_dump(); + // ******register read latency & dqs & dq calibration + CHECK_ERR_FLAG(reg_read_cal,()); + if (cal_done_flag == 1) + return 0; + // if (datarate >= 1800){ + // latency_wr[1] = 39; + // }else if(datarate >= 1600){ + // latency_wr[1] = 38; + // }else if(datarate >= 1100){ + // latency_wr[1] = 37; + // }else{ + // latency_wr[1] = 36; + // } + + CHECK_ERR_FLAG(uhs_reg_r,(1,0)); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + if (cfg_glb->psramMemSize == PSRAM_MEM_SIZE_32MB){ + tmpVal &= 0x10; + }else if (cfg_glb->psramMemSize == PSRAM_MEM_SIZE_64MB){ + tmpVal &= 0x20; + } + if (tmpVal != 0){ + return uhs_err_handler(UHS_BAD_DIE_ERR); + } + + uhs_phy_printf("UHS_PHY_CAL, ODT_EN = %d\r\n",ODT_EN); + #if ODT_EN + uhs_phy_printf("********** INIT_REG_WRITE_2kM **********\r\n"); + CHECK_ERR_FLAG(init_reg_write_2kM,()); + #endif + + uhs_phy_printf("********** INIT_ARRAY_WRITE **********\r\n"); + #if bl808_DBG_RF == 2 + uhs_phy_reg_dump(); + #endif + // reg_write_cal(); + CHECK_ERR_FLAG(init_array_write,()); + uhs_phy_printf("********** ARRAY_READ_CAL **********\r\n"); + // uhs_phy_reg_dump(); + // ******array read latency & dqs & dq calibration + CHECK_ERR_FLAG(array_read_latency_cal,()); + uhs_phy_printf("********** ARRAY_WRITE_CK_CAL **********\r\n"); + // uhs_phy_reg_dump(); + flag_ck1 = 0; + flag_ck2 = 0; + CHECK_ERR_FLAG(array_write_ck_cal,()); + uhs_phy_printf("********** ARRAY_WRITE_CAL **********\r\n"); + // uhs_phy_reg_dump(); + // array_read_dqs_dq_cal(); //calibrated in array_read_latency_cal + CHECK_ERR_FLAG(array_write_dqs_dq_cal,()); + // uhs_phy_reg_dump(); + + return 0; +} + +void soft_reset(void) +{ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(GLB_BASE,GLB_SWRST_CFG2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_REG_CTRL_PWRON_RST,0x1); // soft power on reset + BL_WR_REG(GLB_BASE,GLB_SWRST_CFG2,tmpVal); + uhs_phy_delay_ms(1); +} + +uint8_t uhs_diagonal_test(uint32_t data0,uint32_t data1) +{ + uint32_t RA = 0x0; //X_address + uint32_t CA = 0x0; //Y_address + uint32_t CA_init = 0x0; + uint32_t dataTmp; + uint32_t STRESS_TEST_BASE = 0x50000000; + uint32_t RowAddr = 0x3fff; //256Mb X_address + + if (cfg_glb->psramMemSize == PSRAM_MEM_SIZE_32MB){ + RowAddr = 0x3fff; + }else if (cfg_glb->psramMemSize == PSRAM_MEM_SIZE_64MB){ + RowAddr = 0x7fff; + } + + // data0 + for (RA = 0x0; RA <= RowAddr; RA++){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFC0007FF; + STRESS_TEST_BASE = STRESS_TEST_BASE | (RA<<11); // STRESS_TEST_BASE[25:11] = RA[14:0] + CA_init = (RA & 0x7f) << 3; + for (CA = CA_init; CA <= CA_init + 0x7; CA = CA + 2){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFFFFF800; + STRESS_TEST_BASE = STRESS_TEST_BASE | (CA<<1); // STRESS_TEST_BASE[10:2] = CA[9:1], STRESS_TEST_BASE[1:0] = 0; + *((volatile uint32_t*)(STRESS_TEST_BASE)) = data0; + } + } + for (RA = 0x0; RA <= RowAddr; RA++){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFC0007FF; + STRESS_TEST_BASE = STRESS_TEST_BASE | (RA<<11); // STRESS_TEST_BASE[25:11] = RA[14:0] + CA_init = (RA & 0x7f) << 3; + for (CA = CA_init; CA <= CA_init + 0x7; CA = CA + 2){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFFFFF800; + STRESS_TEST_BASE = STRESS_TEST_BASE | (CA<<1); // STRESS_TEST_BASE[10:2] = CA[9:1], STRESS_TEST_BASE[1:0] = 0; + dataTmp = *((volatile uint32_t*)(STRESS_TEST_BASE)); + if(dataTmp != data0){ + uhs_phy_printfe("addr: 0x%lx\r\n", STRESS_TEST_BASE); + uhs_phy_printfe("data_w data0: 0x%lx\r\n", data0); + uhs_phy_printfe("addr_r data0: 0x%lx\r\n", dataTmp); + return uhs_err_handler(UHS_DIAGONAL_TEST_ERR); + } + } + } + // data1 + for (RA = 0x0; RA <= RowAddr; RA++){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFC0007FF; + STRESS_TEST_BASE = STRESS_TEST_BASE | (RA<<11); // STRESS_TEST_BASE[25:11] = RA[14:0] + CA_init = (RA & 0x7f) << 3; + for (CA = CA_init; CA <= CA_init + 0x7; CA = CA + 2){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFFFFF800; + STRESS_TEST_BASE = STRESS_TEST_BASE | (CA<<1); // STRESS_TEST_BASE[10:2] = CA[9:1], STRESS_TEST_BASE[1:0] = 0; + *((volatile uint32_t*)(STRESS_TEST_BASE)) = data1; + } + } + for (RA = 0x0; RA <= RowAddr; RA++){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFC0007FF; + STRESS_TEST_BASE = STRESS_TEST_BASE | (RA<<11); // STRESS_TEST_BASE[25:11] = RA[14:0] + CA_init = (RA & 0x7f) << 3; + for (CA = CA_init; CA <= CA_init + 0x7; CA = CA + 2){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFFFFF800; + STRESS_TEST_BASE = STRESS_TEST_BASE | (CA<<1); // STRESS_TEST_BASE[10:2] = CA[9:1], STRESS_TEST_BASE[1:0] = 0; + dataTmp = *((volatile uint32_t*)(STRESS_TEST_BASE)); + if(dataTmp != data1){ + uhs_phy_printfe("addr: 0x%lx\r\n", STRESS_TEST_BASE); + uhs_phy_printfe("data_w data1: 0x%lx\r\n", data1); + uhs_phy_printfe("addr_r data1: 0x%lx\r\n", dataTmp); + return uhs_err_handler(UHS_DIAGONAL_TEST_ERR); + } + } + } + + uhs_phy_printf("uhs_diagonal_test success\r\n"); + return 0; +} + +uint8_t uhs_all_addr_test(void) +{ + int32_t RA = 0x0; //X_address + int32_t CA = 0x0; //Y_address + uint32_t dataTmp; + uint32_t STRESS_TEST_BASE = 0x50000000; + uint32_t RowAddr = 0x3fff; //256Mb X_address + uint32_t data0 = 0xffffffff; + uint32_t data1 = 0x00000000; + + if (cfg_glb->psramMemSize == PSRAM_MEM_SIZE_32MB){ + RowAddr = 0x3fff; + }else if (cfg_glb->psramMemSize == PSRAM_MEM_SIZE_64MB){ + RowAddr = 0x7fff; + } + + // ****** Y_address -> X_address + //data0 + for (RA = 0x0; RA <= RowAddr; RA++){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFC0007FF; + STRESS_TEST_BASE = STRESS_TEST_BASE | (RA<<11); // STRESS_TEST_BASE[25:11] = RA[14:0] + for (CA = 0x0; CA <= 0x3ff; CA = CA + 2){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFFFFF800; + STRESS_TEST_BASE = STRESS_TEST_BASE | (CA<<1); // STRESS_TEST_BASE[10:2] = CA[9:1], STRESS_TEST_BASE[1:0] = 0; + *((volatile uint32_t*)(STRESS_TEST_BASE)) = data0; + } + } + for (RA = 0x0; RA <= RowAddr; RA++){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFC0007FF; + STRESS_TEST_BASE = STRESS_TEST_BASE | (RA<<11); // STRESS_TEST_BASE[25:11] = RA[14:0] + for(CA = 0x0; CA <= 0x3ff; CA = CA + 2){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFFFFF800; + STRESS_TEST_BASE = STRESS_TEST_BASE | (CA<<1); // STRESS_TEST_BASE[10:2] = CA[9:1], STRESS_TEST_BASE[1:0] = 0; + dataTmp = *((volatile uint32_t*)(STRESS_TEST_BASE)); + if(dataTmp != data0){ + uhs_phy_printfe("addr: 0x%lx\r\n", STRESS_TEST_BASE); + uhs_phy_printfe("data_w data0 first: 0x%lx\r\n", data0); + uhs_phy_printfe("addr_r data0 first: 0x%lx\r\n", dataTmp); + return uhs_err_handler(UHS_ALL_ADDR_TEST_ERR); + } + } + } + // data1 + for (RA = 0x0; RA <= RowAddr; RA++){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFC0007FF; + STRESS_TEST_BASE = STRESS_TEST_BASE | (RA<<11); // STRESS_TEST_BASE[25:11] = RA[14:0] + for (CA = 0x0; CA <= 0x3ff; CA = CA + 2){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFFFFF800; + STRESS_TEST_BASE = STRESS_TEST_BASE | (CA<<1); // STRESS_TEST_BASE[10:2] = CA[9:1], STRESS_TEST_BASE[1:0] = 0; + *((volatile uint32_t*)(STRESS_TEST_BASE)) = data1; + } + } + // ****** X_address -> Y_address + // data1 + for (RA = RowAddr; RA >= 0x0; RA--){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFC0007FF; + STRESS_TEST_BASE = STRESS_TEST_BASE | (RA<<11); // STRESS_TEST_BASE[25:11] = RA[14:0] + for(CA = 0x3ff - 1; CA >= 0x0; CA = CA - 2){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFFFFF800; + STRESS_TEST_BASE = STRESS_TEST_BASE | (CA<<1); // STRESS_TEST_BASE[10:2] = CA[9:1], STRESS_TEST_BASE[1:0] = 0; + dataTmp = *((volatile uint32_t*)(STRESS_TEST_BASE)); + if(dataTmp != data1){ + uhs_phy_printfe("addr: 0x%lx\r\n", STRESS_TEST_BASE); + uhs_phy_printfe("data_w data1: 0x%lx\r\n", data1); + uhs_phy_printfe("addr_r data1: 0x%lx\r\n", dataTmp); + return uhs_err_handler(UHS_ALL_ADDR_TEST_ERR); + } + } + } + //data0 + for (RA = RowAddr; RA >= 0x0; RA--){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFC0007FF; + STRESS_TEST_BASE = STRESS_TEST_BASE | (RA<<11); // STRESS_TEST_BASE[25:11] = RA[14:0] + for (CA = 0x3ff - 1; CA >= 0x0; CA = CA - 2){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFFFFF800; + STRESS_TEST_BASE = STRESS_TEST_BASE | (CA<<1); // STRESS_TEST_BASE[10:2] = CA[9:1], STRESS_TEST_BASE[1:0] = 0; + *((volatile uint32_t*)(STRESS_TEST_BASE)) = data0; + } + } + for (RA = RowAddr; RA >= 0x0; RA--){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFC0007FF; + STRESS_TEST_BASE = STRESS_TEST_BASE | (RA<<11); // STRESS_TEST_BASE[25:11] = RA[14:0] + for(CA = 0x3ff - 1; CA >= 0x0; CA = CA - 2){ + STRESS_TEST_BASE = STRESS_TEST_BASE & 0xFFFFF800; + STRESS_TEST_BASE = STRESS_TEST_BASE | (CA<<1); // STRESS_TEST_BASE[10:2] = CA[9:1], STRESS_TEST_BASE[1:0] = 0; + dataTmp = *((volatile uint32_t*)(STRESS_TEST_BASE)); + if(dataTmp != data0){ + uhs_phy_printfe("addr: 0x%lx\r\n", STRESS_TEST_BASE); + uhs_phy_printfe("data_w data0 second: 0x%lx\r\n", data0); + uhs_phy_printfe("addr_r data0 second: 0x%lx\r\n", dataTmp); + return uhs_err_handler(UHS_ALL_ADDR_TEST_ERR); + } + } + } + uhs_phy_printf("uhs_all_addr_test success\r\n"); + return 0; +} + + +void dump_uhs_phy_cal_res(void) +{ + #if CAL_MODE != 2 + // dump uhs_phy_cal_res + uhs_phy_printf("uhs_phy_cal_res->cal_mode = %d\r\n",uhs_phy_cal_res->cal_mode); + uhs_phy_printf("uhs_phy_cal_res->err_type = %d\r\n",uhs_phy_cal_res->err_type); + uhs_phy_printf("uhs_phy_cal_res->err_sub_type = %d\r\n",uhs_phy_cal_res->err_sub_type); + uhs_phy_printf("uhs_phy_cal_res->datarate = %d\r\n",uhs_phy_cal_res->datarate); + uhs_phy_printf("uhs_phy_cal_res->rl = %d\r\n",uhs_phy_cal_res->rl); + uhs_phy_printf("uhs_phy_cal_res->rdqs = %d\r\n",uhs_phy_cal_res->rdqs); + uhs_phy_printf("uhs_phy_cal_res->rdq = %d\r\n",uhs_phy_cal_res->rdq); + uhs_phy_printf("uhs_phy_cal_res->rwindow = %d\r\n",uhs_phy_cal_res->rwindow); + uhs_phy_printf("uhs_phy_cal_res->rwindow_begin = %d\r\n",uhs_phy_cal_res->rwindow_begin); + uhs_phy_printf("uhs_phy_cal_res->rwindow_end = %d\r\n",uhs_phy_cal_res->rwindow_end); + uhs_phy_printf("uhs_phy_cal_res->ck = %d\r\n",uhs_phy_cal_res->ck); + uhs_phy_printf("uhs_phy_cal_res->wl = %d\r\n",uhs_phy_cal_res->wl); + uhs_phy_printf("uhs_phy_cal_res->wdqs = %d\r\n",uhs_phy_cal_res->wdqs); + uhs_phy_printf("uhs_phy_cal_res->wdq = %d\r\n",uhs_phy_cal_res->wdq); + uhs_phy_printf("uhs_phy_cal_res->wwindow = %d\r\n",uhs_phy_cal_res->wwindow); + uhs_phy_printf("uhs_phy_cal_res->wwindow_begin = %d\r\n",uhs_phy_cal_res->wwindow_begin); + uhs_phy_printf("uhs_phy_cal_res->wwindow_end = %d\r\n",uhs_phy_cal_res->wwindow_end); + uhs_phy_printf("uhs_phy_cal_res->cal_done = %d\r\n",uhs_phy_cal_res->cal_done); + uhs_phy_printf("uhs_phy_cal_res->crc_res = %lx\r\n",uhs_phy_cal_res->crc_res); + #else + // dump uhs_phy_cal_res + uhs_phy_printf("uhs_phy_cal_res->cal_mode = %ld\r\n",uhs_phy_cal_res->cal_mode); + uhs_phy_printf("uhs_phy_cal_res->err_type = %lx\r\n",uhs_phy_cal_res->err_type); + uhs_phy_printf("uhs_phy_cal_res->err_sub_type = %ld\r\n",uhs_phy_cal_res->err_sub_type); + uhs_phy_printf("uhs_phy_cal_res->datarate = %ld\r\n",uhs_phy_cal_res->datarate); + uhs_phy_printf("uhs_phy_cal_res->rl = %ld\r\n",uhs_phy_cal_res->rl); + uhs_phy_printf("uhs_phy_cal_res->rdqs = %ld\r\n",uhs_phy_cal_res->rdqs); + uhs_phy_printf("uhs_phy_cal_res->rdq = %ld\r\n",uhs_phy_cal_res->rdq); + uhs_phy_printf("uhs_phy_cal_res->rwindow = %ld\r\n",uhs_phy_cal_res->rwindow); + uhs_phy_printf("uhs_phy_cal_res->rwindow_begin = %ld\r\n",uhs_phy_cal_res->rwindow_begin); + uhs_phy_printf("uhs_phy_cal_res->rwindow_end = %ld\r\n",uhs_phy_cal_res->rwindow_end); + uhs_phy_printf("uhs_phy_cal_res->ck = %ld\r\n",uhs_phy_cal_res->ck); + uhs_phy_printf("uhs_phy_cal_res->wl = %ld\r\n",uhs_phy_cal_res->wl); + uhs_phy_printf("uhs_phy_cal_res->wdqs = %ld\r\n",uhs_phy_cal_res->wdqs); + uhs_phy_printf("uhs_phy_cal_res->wdq = %ld\r\n",uhs_phy_cal_res->wdq); + uhs_phy_printf("uhs_phy_cal_res->wwindow = %ld\r\n",uhs_phy_cal_res->wwindow); + uhs_phy_printf("uhs_phy_cal_res->wwindow_begin = %ld\r\n",uhs_phy_cal_res->wwindow_begin); + uhs_phy_printf("uhs_phy_cal_res->wwindow_end = %ld\r\n",uhs_phy_cal_res->wwindow_end); + uhs_phy_printf("uhs_phy_cal_res->cal_done = %lx\r\n",uhs_phy_cal_res->cal_done); + uhs_phy_printf("uhs_phy_cal_res->crc_res = %lx\r\n",uhs_phy_cal_res->crc_res); + #endif +} + +void uhs_phy_init(PSRAM_UHS_Cfg_Type *cfg) +{ + memset((void*)uhs_phy_cal_res, 0, sizeof(uhs_phy_cal_res_struct)); + uhs_phy_cal_res->cal_mode = CAL_MODE; + uhs_phy_cal_res->datarate = cfg->pck_freq; + + err_flag = 0; + + __DSB(); + __ISB(); + cache_state = __get_MHCR(); + cache_state &= (0x1<<1); + __DSB(); + __ISB(); + + cfg_glb = cfg; + latency_wr_2kM[1] = 41; + uhs_phy_init_core(cfg); +} + +extern uint32_t ATTR_TCM_SECTION BFLB_Soft_CRC32(void *dataIn, uint32_t len); +uint8_t uhs_phy_init_core(PSRAM_UHS_Cfg_Type *cfg) +{ + cal_done_flag = 0; + if(latency_wr_2kM[1] == 34) + { + reg_read_err = 3; + return uhs_err_handler(UHS_REG_READ_CAL_ERR); + } + + uint32_t pck_freq_temp; + + uhs_phy_printf_debug("uhs phy init\r\n"); + if (cfg->psramMemSize == PSRAM_MEM_SIZE_32MB){ + uhs_phy_printf("\r\n########## START_CAL_AT %ldMbps, PSRAM_MEM_SIZE_32MB, CACHE_EN = %ld ##########\r\n",cfg->pck_freq,cache_state); + }else if(cfg->psramMemSize == PSRAM_MEM_SIZE_64MB){ + uhs_phy_printf("\r\n########## START_CAL_AT %ldMbps, PSRAM_MEM_SIZE_64MB, CACHE_EN = %ld ##########\r\n",cfg->pck_freq,cache_state); + } + #if CAL_MODE != 2 + uhs_phy_printf("CAL_MODE = %d\r\n",uhs_phy_cal_res->cal_mode); + #else + uhs_phy_printf("CAL_MODE = %ld\r\n",uhs_phy_cal_res->cal_mode); + #endif + + power_up_mm(0); + power_up_uhspll(); + + power_up_ldo12uhs(); + set_cen_ck_ckn(); + + set_or_uhs(); + switch_to_ldo12uhs(); + release_cen_ck_ckn(); + + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(GLB_BASE,GLB_UHS_PLL_CFG9); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal,GLB_UHSPLL_SSC_EN,0x0); // uhspll_ssc_en + BL_WR_REG(GLB_BASE,GLB_UHS_PLL_CFG9,tmpVal); + pck_freq_temp = cfg->pck_freq; + if (cfg->psramMemSize == PSRAM_MEM_SIZE_32MB){ + cfg->pck_freq = 800; + // PSRAM_UHS_Cfg_Type psramCfg = { + // 800, + // PSRAM_MEM_SIZE_32MB, + // PSRAM_PAGE_SIZE_2KB, + // 0, + // }; + + GLB_Config_UHS_PLL_Freq(GLB_XTAL_40M,800); //stuck + Psram_UHS_Init_Override(cfg); // controller init + set_uhs_phy_init(); // phy init + set_uhs_latency_w(1); + set_uhs_latency_r(17); + psram_init(); // psram init after set freq & set_phy + + // uhs_reg_r(0,1); + // tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + // uhs_phy_printf_debug("readout MA0 = 0x%lx\r\n",tmpVal); + // if(tmpVal == ((2<<3)+5)) // 700M --> default uhs_latency_code == 5 + // { + // uhs_phy_printf_debug("register read pass at 700Mbps\r\n"); + // } + // else{ + // uhs_phy_printf_debug("register read fail at 700Mbps\r\n"); + // } + } + else if(cfg->psramMemSize == PSRAM_MEM_SIZE_64MB){ + cfg->pck_freq = 1400; + // PSRAM_UHS_Cfg_Type psramCfg = { + // 1400, + // PSRAM_MEM_SIZE_64MB, + // PSRAM_PAGE_SIZE_2KB, + // 0, + // }; + + GLB_Config_UHS_PLL_Freq(GLB_XTAL_40M,1400); //stuck + Psram_UHS_Init_Override(cfg); // controller init + set_uhs_phy_init(); // phy init + set_uhs_latency_w(9); + set_uhs_latency_r(30); + psram_init(); // psram init after set freq & set_phy + + // uhs_reg_r(0,1); + // tmpVal = BL_RD_REG(PSRAM_UHS_BASE,PSRAM_UHS_UHS_CMD)>>24; + // if(tmpVal == ((2<<3)+1)) // 1400M --> default uhs_latency_code == 1 + // { + // uhs_phy_printf_debug("register read pass at 1400Mbps\r\n"); + // } + // else{ + // uhs_phy_printf_debug("register read fail at 1400Mbps\r\n"); + // } + } + + cfg->pck_freq = pck_freq_temp; + self_cal(); + uhs_phy_delay_ms(1); + cal_done_flag = 1; + #if CAL_MODE == 2 + if(err_flag == 0){ + uhs_phy_printf("********** UHS_DIAGONAL_TEST **********\r\n"); + uhs_diagonal_test(0x5555aaaa,0xaaaa5555); + // uhs_phy_printf("********** UHS_ALL_ADDR_TEST **********\r\n"); + // uhs_all_addr_test(); + } + // uhs_phy_printfe("!!!!!!!!!! uhs_phy_cal_res->err_type = %d !!!!!!!!!!\r\n",uhs_phy_cal_res->err_type);l + uint32_t magic_os = 0x89abcdef; + uhs_phy_cal_res->err_type += magic_os; + uhs_phy_cal_res->cal_done = magic_os; + uhs_phy_cal_res->crc_res = BFLB_Soft_CRC32(uhs_phy_cal_res, sizeof(uhs_phy_cal_res_struct)-4); + #elif CAL_MODE == 1 + uhs_phy_cal_res->cal_done = 1; + uhs_phy_cal_res->crc_res = BFLB_Soft_CRC32(uhs_phy_cal_res, sizeof(uhs_phy_cal_res_struct)-4); + #endif + + #if CAL_MODE != 2 + uhs_phy_printf("!!!!!!!!!! uhs_phy_cal_res->err_type = %d !!!!!!!!!!\r\n",uhs_phy_cal_res->err_type); + #else + uhs_phy_printf("!!!!!!!!!! uhs_phy_cal_res->err_type = %lx !!!!!!!!!!\r\n",uhs_phy_cal_res->err_type); + #endif + + dump_uhs_phy_cal_res(); + return uhs_phy_cal_res->err_type; + + //get dcache original state + __DSB(); + __ISB(); + dcache_original = __get_MHCR(); + dcache_original &= (0x1<<1); + __DSB(); + __ISB(); + uhs_phy_printf_debug("dcache_original= 0x%lx\r\n",dcache_original); + + uhs_phy_printf("UHS_PHY_CAL, CACHE_EN = %d\r\n",CACHE_EN); + #if CACHE_EN + csi_dcache_enable(); + #else + csi_dcache_disable(); + #endif + + //get dcache current state + __DSB(); + __ISB(); + dcache_current = __get_MHCR(); + dcache_current &= (0x1<<1); + __DSB(); + __ISB(); + uhs_phy_printf_debug("dcache_current= 0x%lx\r\n",dcache_current); + + cfg->pck_freq = pck_freq_temp; + #if CACHE_EN + if(dcache_current == (0x1<<1)) + { + self_cal(); + } + else + { + uhs_phy_printf_debug("dcache enable fail\r\n"); + return uhs_err_handler(UHS_CACHE_ENABLE_ERR); + } + if (dcache_original == 0) + { + csi_dcache_disable(); + } + #else + if(dcache_current == 0x0) + { + self_cal(); + } + else + { + uhs_phy_printf_debug("dcache disable fail\r\n"); + return uhs_err_handler(UHS_CACHE_DISABLE_ERR); + } + if (dcache_original == (0x1<<1)) + { + csi_dcache_enable(); + } + #endif + + //get dcache end state + __DSB(); + __ISB(); + dcache_end = __get_MHCR(); + dcache_end &= (0x1<<1); + __DSB(); + __ISB(); + if(dcache_end == dcache_original) + { + uhs_phy_printf_debug("dcache state right , dcache_state= 0x%lx\r\n",dcache_end); + } + else + { + uhs_phy_printf_debug("dcache state error\r\n"); + return uhs_err_handler(UHS_CACHE_RECOVER_ERR); + } + + uhs_phy_delay_ms(1); + + if (cfg->psramMemSize == PSRAM_MEM_SIZE_32MB){ + uhs_phy_printf("########## END_CAL_AT %ldMbps, PSRAM_MEM_SIZE_32MB ##########\r\n",cfg->pck_freq); + }else if(cfg->psramMemSize == PSRAM_MEM_SIZE_64MB){ + uhs_phy_printf("########## END_CAL_AT %ldMbps, PSRAM_MEM_SIZE_64MB ##########\r\n",cfg->pck_freq); + } +} \ No newline at end of file