ram: Add BL808 PSRAM driver

Signed-off-by: Samuel Holland <samuel@sholland.org>
This commit is contained in:
Samuel Holland 2022-11-12 16:19:45 -06:00
parent 7060875727
commit ce3a98ed92
17 changed files with 7580 additions and 0 deletions

View File

@ -108,6 +108,7 @@ config IMXRT_SDRAM
This driver is for the sdram memory interface with the SEMC.
source "drivers/ram/aspeed/Kconfig"
source "drivers/ram/bflb/Kconfig"
source "drivers/ram/rockchip/Kconfig"
source "drivers/ram/sifive/Kconfig"
source "drivers/ram/stm32mp1/Kconfig"

View File

@ -8,6 +8,7 @@ obj-$(CONFIG_MPC83XX_SDRAM) += mpc83xx_sdram.o
obj-$(CONFIG_SANDBOX) += sandbox_ram.o
obj-$(CONFIG_STM32MP1_DDR) += stm32mp1/
obj-$(CONFIG_STM32_SDRAM) += stm32_sdram.o
obj-$(CONFIG_RAM_BFLB) += bflb/
obj-$(CONFIG_ARCH_BMIPS) += bmips_ram.o
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/

6
drivers/ram/bflb/Kconfig Normal file
View File

@ -0,0 +1,6 @@
config RAM_BFLB
bool "Ram drivers support for Bouffalo Lab SoCs"
depends on RAM && TARGET_BOUFFALO_BL808
default y
help
This enables support for RAM drivers on Bouffalo Lab SoCs.

View File

@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0+
obj-y += bl808_ef_cfg.o
obj-y += bl808_ef_ctrl.o
obj-y += bl808_glb.o
obj-y += bl808_psram_uhs.o
obj-y += bl808_uhs_phy.o
obj-y += psram.o

171
drivers/ram/bflb/bl808.h Normal file
View File

@ -0,0 +1,171 @@
#ifndef __BL808_H__
#define __BL808_H__
#include <linux/delay.h>
#include <linux/types.h>
#define ARCH_RISCV
#define CPU_M0
#define __ASM asm
#define __NOP barrier
#define arch_delay_us(x) udelay(x)
#define readl(a) readl((const volatile void __iomem *)a)
#define writel(v, a) writel(v, (volatile void __iomem *)a)
/**
* @brief BL808 Memory Map Definitions
*/
#define BL808_OCRAM_BASE (0x22020000)
#define BL808_OCRAM_END (0x22020000 + 64 * 1024)
#define BL808_OCRAM_CACHEABLE_BASE (0x62020000)
#define BL808_OCRAM_CACHEABLE_END (0x62020000 + 64 * 1024)
#define BL808_WRAM_BASE (0x22030000)
#define BL808_WRAM_END (0x22030000 + 160 * 1024)
#define BL808_WRAM_CACHEABLE_BASE (0x62030000)
#define BL808_WRAM_CACHEABLE_END (0x62030000 + 160 * 1024)
#define BL808_MCU_ALLRAM_BASE (0x22020000)
#define BL808_MCU_ALLRAM_END (0x22020000 + 64 * 1024 + 160 * 1024)
#define BL808_MCU_ALLRAM_CACHEABLE_BASE (0x62020000)
#define BL808_MCU_ALLRAM_CACHEABLE_END (0x62020000 + 64 * 1024 + 160 * 1024)
#define BL808_DRAM_BASE (0x3EF80000)
#define BL808_DRAM_END (0x3EF80000 + 512 * 1024)
#define BL808_DRAM_CACHEABLE_BASE (0x7EF80000)
#define BL808_DRAM_CACHEABLE_END (0x7EF80000 + 512 * 1024)
#define BL808_VRAM_BASE (0x3F000000)
#define BL808_VRAM_END (0x3F000000 + 32 * 1024)
#define BL808_VRAM_CACHEABLE_BASE (0x7F000000)
#define BL808_VRAM_CACHEABLE_END (0x7F000000 + 32 * 1024)
#define BL808_MM_ALLRAM_BASE (0x3EF80000)
#define BL808_MM_ALLRAM_END (0x3EF80000 + 512 * 1024 + 32 * 1024)
#define BL808_MM_ALLRAM_CACHEABLE_BASE (0x7EF80000)
#define BL808_MM_ALLRAM_CACHEABLE_END (0x7EF80000 + 512 * 1024 + 32 * 1024)
#define BL808_FLASH_XIP_BASE (0x58000000)
#define BL808_FLASH_XIP_END (0x58000000 + 64 * 1024 * 1024)
#define BL808_FLASH2_XIP_BASE (0x5C000000)
#define BL808_FLASH2_XIP_END (0x5C000000 + 64 * 1024 * 1024)
#define BL808_FLASH_XIP_REMAP0_BASE (0xD8000000)
#define BL808_FLASH_XIP_REMAP0_END (0xD8000000 + 64 * 1024 * 1024)
#define BL808_FLASH2_XIP_REMAP0_BASE (0xDC000000)
#define BL808_FLASH2_XIP_REMAP0_END (0xDC000000 + 64 * 1024 * 1024)
#define BL808_MM_WHOLERAM_BASE (0x3EF80000)
#define BL808_MM_WHOLERAM_END (0x3EF80000 + 512 * 1024 + 96 * 1024)
#define BL808_MM_WHOLERAM_CACHEABLE_BASE (0x7EF80000)
#define BL808_MM_WHOLERAM_CACHEABLE_END (0x7EF80000 + 512 * 1024 + 96 * 1024)
/*@} end of group Memory_Map_Section */
/* BL808 peripherals base address */
/* WLSYS */
#define GLB_BASE ((uint32_t)0x20000000)
#define MIX_BASE ((uint32_t)0x20001000)
#define GPIP_BASE ((uint32_t)0x20002000)
#define PHY_BASE ((uint32_t)0x20002800)
#define AGC_BASE ((uint32_t)0x20002c00)
#define SEC_DBG_BASE ((uint32_t)0x20003000)
#define SEC_ENG_BASE ((uint32_t)0x20004000)
#define TZ1_BASE ((uint32_t)0x20005000)
#define TZC_SEC_BASE ((uint32_t)0x20005000)
#define TZ2_BASE ((uint32_t)0x20006000)
#define TZC_NSEC_BASE ((uint32_t)0x20006000)
#define EFUSE_BASE ((uint32_t)0x20056000)
#define EF_DATA_BASE ((uint32_t)0x20056000)
#define EF_CTRL_BASE ((uint32_t)0x20056000)
#define CCI_BASE ((uint32_t)0x20008000)
#define MCU_MISC_BASE ((uint32_t)0x20009000)
#define L1C_BASE ((uint32_t)0x20009000)
#define UART0_BASE ((uint32_t)0x2000a000)
#define UART1_BASE ((uint32_t)0x2000a100)
#define SPI0_BASE ((uint32_t)0x2000a200)
#define I2C0_BASE ((uint32_t)0x2000a300)
#define PWM_BASE ((uint32_t)0x2000a400)
#define TIMER0_BASE ((uint32_t)0x2000a500)
#define IR_BASE ((uint32_t)0x2000a600)
#define CKS_BASE ((uint32_t)0x2000a700)
#define IPC0_BASE ((uint32_t)0x2000a800)
#define IPC1_BASE ((uint32_t)0x2000a840)
#define I2C1_BASE ((uint32_t)0x2000a900)
#define UART2_BASE ((uint32_t)0x2000aa00)
#define ISO11898_BASE ((uint32_t)0x2000aa00)
#define I2S_BASE ((uint32_t)0x2000ab00)
#define PDM0_BASE ((uint32_t)0x2000a000)
#define LZ4D_BASE ((uint32_t)0x2000ad00)
#define QSPI_BASE ((uint32_t)0x2000b000)
#define SF_CTRL_BASE ((uint32_t)0x2000b000)
#define SF_CTRL_BUF_BASE ((uint32_t)0x2000b600)
#define DMA0_BASE ((uint32_t)0x2000c000)
#define PDS_BASE ((uint32_t)0x2000e000)
#define HBN_BASE ((uint32_t)0x2000f000)
#define AON_BASE ((uint32_t)0x2000f000)
#define EMI_MISC_BASE ((uint32_t)0x20050000)
#define PSRAM_CTRL_BASE ((uint32_t)0x20052000)
#define USB_BASE ((uint32_t)0x20072000)
#define AUDIO_BASE ((uint32_t)0x20055000)
#define SDH_BASE ((uint32_t)0x20060000)
#define EMAC_BASE ((uint32_t)0x20070000)
#define DMA1_BASE ((uint32_t)0x20071000)
/* MMSYS */
#define MM_MISC_BASE ((uint32_t)0x30000000)
#define DMA2_BASE ((uint32_t)0x30001000)
#define UART3_BASE ((uint32_t)0x30002000)
#define I2C2_BASE ((uint32_t)0x30003000)
#define I2C3_BASE ((uint32_t)0x30004000)
#define IPC2_BASE ((uint32_t)0x30005000)
#define DMA2D_BASE ((uint32_t)0x30006000)
#define CLKRST_CTRL_BASE ((uint32_t)0x30007000)
#define MM_GLB_BASE ((uint32_t)0x30007000)
#define SPI1_BASE ((uint32_t)0x30008000)
#define TIMER1_BASE ((uint32_t)0x30009000)
#define PSRAM_UHS_BASE ((uint32_t)0x3000f000)
/* SUBSYS */
#define SUB_MISC_BASE ((uint32_t)0x30010000)
#define SUB_BASE ((uint32_t)0x30011000)
#define DVP0_BASE ((uint32_t)0x30012000)
#define DVP1_BASE ((uint32_t)0x30012100)
#define DVP2_BASE ((uint32_t)0x30012200)
#define DVP3_BASE ((uint32_t)0x30012300)
#define DVP4_BASE ((uint32_t)0x30012400)
#define DVP5_BASE ((uint32_t)0x30012500)
#define DVP6_BASE ((uint32_t)0x30012600)
#define DVP7_BASE ((uint32_t)0x30012700)
#define DVP_TSRC0_BASE ((uint32_t)0x30012800)
#define DVP_TSRC1_BASE ((uint32_t)0x30012900)
#define AXI_CTRL_NR3D_BASE ((uint32_t)0x30012a00)
#define OSD_PROBE_BASE ((uint32_t)0x30012b00)
#define OSD_A_BASE ((uint32_t)0x30013000)
#define OSD_B_BASE ((uint32_t)0x30014000)
#define OSD_DP_BASE ((uint32_t)0x30015000)
#define OSD_BLEND0_OFFSET (0x000)
#define OSD_BLEND1_OFFSET (0x100)
#define OSD_BLEND2_OFFSET (0x200)
#define OSD_BLEND3_OFFSET (0x300)
#define OSD_DRAW_LOW_OFFSET (0x400)
#define OSD_DRAW_HIGH_OFFSET (0x504)
#define MIPI_BASE ((uint32_t)0x3001a000)
#define DBI_BASE ((uint32_t)0x3001b000)
#define DSI_BASE ((uint32_t)0x3001a100)
#define CSI_BASE ((uint32_t)0x3001a000)
/* CODEC_SUBSYS */
#define CODEC_MISC_BASE ((uint32_t)0x30020000)
#define MJPEG_BASE ((uint32_t)0x30021000)
#define VIDEO_BASE ((uint32_t)0x30022000)
#define MJPEG_DEC_BASE ((uint32_t)0x30023000)
#define BL_CNN_BASE ((uint32_t)0x30024000)
#define HBN_RAM_BASE ((uint32_t)0x20010000)
#define RF_BASE ((uint32_t)0x20001000)
#endif

View File

@ -0,0 +1,66 @@
#ifndef __BL808_COMMON_H__
#define __BL808_COMMON_H__
#include "bl808.h"
/**
* @brief Memory access macro
*/
#define BL_RD_WORD(addr) (*((volatile uint32_t *)(uintptr_t)(addr)))
#define BL_WR_WORD(addr, val) ((*(volatile uint32_t *)(uintptr_t)(addr)) = (val))
#define BL_RD_SHORT(addr) (*((volatile uint16_t *)(uintptr_t)(addr)))
#define BL_WR_SHORT(addr, val) ((*(volatile uint16_t *)(uintptr_t)(addr)) = (val))
#define BL_RD_BYTE(addr) (*((volatile uint8_t *)(uintptr_t)(addr)))
#define BL_WR_BYTE(addr, val) ((*(volatile uint8_t *)(uintptr_t)(addr)) = (val))
/**
* @brief Register access macro
*/
#define BL_RD_REG16(addr, regname) BL_RD_SHORT(addr + regname##_OFFSET)
#define BL_WR_REG16(addr, regname, val) BL_WR_SHORT(addr + regname##_OFFSET, val)
#define BL_RD_REG(addr, regname) BL_RD_WORD(addr + regname##_OFFSET)
#define BL_WR_REG(addr, regname, val) BL_WR_WORD(addr + regname##_OFFSET, val)
#define BL_SET_REG_BIT(val, bitname) ((val) | (1U << bitname##_POS))
#define BL_CLR_REG_BIT(val, bitname) ((val)&bitname##_UMSK)
#define BL_GET_REG_BITS_VAL(val, bitname) (((val)&bitname##_MSK) >> bitname##_POS)
#define BL_SET_REG_BITS_VAL(val, bitname, bitval) (((val)&bitname##_UMSK) | ((uint32_t)(bitval) << bitname##_POS))
#define BL_IS_REG_BIT_SET(val, bitname) (((val) & (1U << (bitname##_POS))) != 0)
/**
* @brief Error type definition
*/
typedef enum {
SUCCESS = 0,
ERROR = 1,
TIMEOUT = 2,
INVALID = 3, /* invalid arguments */
NORESC = 4 /* no resource or resource temperary unavailable */
} BL_Err_Type;
/**
* @brief Functional type definition
*/
typedef enum {
DISABLE = 0,
ENABLE = 1,
} BL_Fun_Type;
/**
* @brief Status type definition
*/
typedef enum {
RESET = 0,
SET = 1,
} BL_Sts_Type;
/**
* @brief Mask type definition
*/
typedef enum {
UNMASK = 0,
MASK = 1
} BL_Mask_Type;
#define CHECK_PARAM(expr) ((void)0)
#endif /* __BL808_COMMON_H__ */

View File

@ -0,0 +1,90 @@
/**
******************************************************************************
* @file bl808_ef_cfg.c
* @version V1.0
* @date
* @brief This file is the standard driver c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
*
* 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 <bl808/ef_data_0_reg.h>
#include <bl808/ef_data_1_reg.h>
#define EF_CTRL_LOAD_BEFORE_READ_R0 EF_Ctrl_Load_Efuse_R0()
#define EF_CTRL_LOAD_BEFORE_READ_R1 EF_Ctrl_Load_Efuse_R1()
/****************************************************************************/ /**
* @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 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;
}

View File

@ -0,0 +1,67 @@
/**
******************************************************************************
* @file bl808_ef_ctrl.h
* @version V1.0
* @date
* @brief This file is the standard driver header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
*
* 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_EF_CFG_H__
#define __BL808_EF_CFG_H__
#include <bl808/ef_ctrl_reg.h>
#include "bl808_common.h"
/**
* @brief Efuse analog device info type definition
*/
typedef struct
{
uint8_t chipInfo; /*!< Efuse chip revision */
uint8_t memoryInfo; /*!< Efuse memory info 0:no memory, 8:1MB flash */
uint8_t psramInfo; /*!< Efuse psram info 0:no psram, 1:WB 4MB, 2:UHS 32MB, 3:UHS 64MB, 4:WB 32MB */
uint8_t deviceInfo; /*!< Efuse device information */
} Efuse_Chip_Info_Type;
/**
* @brief Efuse psram trim type definition
*/
typedef struct
{
uint32_t psramTrim : 11; /*!< Efuse analog trim:psram trim date */
uint32_t psramTrimParity : 1; /*!< Efuse analog trim:psram trim_parity */
uint32_t psramTrimEn : 1; /*!< Efuse analog trim:psram trim_en */
uint32_t reserved : 19; /*!< Efuse analog trim:reserved */
} Efuse_Psram_Trim_Type;
void EF_Ctrl_Get_Chip_Info(Efuse_Chip_Info_Type *chipInfo);
void EF_Ctrl_Read_Psram_Trim(Efuse_Psram_Trim_Type *trim);
#endif /* __BL808_EF_CFG_H__ */

View File

@ -0,0 +1,372 @@
/**
******************************************************************************
* @file bl808_ef_ctrl.c
* @version V1.0
* @date
* @brief This file is the standard driver c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
*
* 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_data_0_reg.h>
#include <bl808/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 Switch efuse region 0 control to AHB clock
*
* @param None
*
* @return None
*
*******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
void 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
void 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 Load efuse region 0
*
* @param None
*
* @return None
*
*******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
void 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
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
BL_Sts_Type 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 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
void 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

View File

@ -0,0 +1,80 @@
/**
******************************************************************************
* @file bl808_ef_ctrl.h
* @version V1.0
* @date
* @brief This file is the standard driver header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
*
* 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_EF_CTRL_H__
#define __BL808_EF_CTRL_H__
#include <bl808/ef_ctrl_reg.h>
#include "bl808_common.h"
/**
* @brief Efuse Ctrl clock type definition
*/
typedef enum {
EF_CTRL_PARA_DFT, /*!< Select default cyc parameter */
EF_CTRL_PARA_MANUAL, /*!< Select manual cyc parameter */
} EF_Ctrl_CYC_PARA_Type;
/**
* @brief Efuse Ctrl clock type definition
*/
typedef enum {
EF_CTRL_OP_MODE_AUTO, /*!< Select efuse program auto mode */
EF_CTRL_OP_MODE_MANUAL, /*!< Select efuse program manual mode */
} EF_Ctrl_OP_MODE_Type;
/**
* @brief Efuse analog device info type definition
*/
typedef struct
{
uint32_t rsvd : 22; /*!< Reserved */
uint32_t deviceInfo : 3; /*!< Efuse device information */
uint32_t psramInfo : 2; /*!< Efuse psram info 0:no psram, 1:BW 4MB, 2:UHS 64MB */
uint32_t memoryInfo : 2; /*!< Efuse memory info 0:no memory, 8:1MB flash */
uint32_t chipInfo : 3; /*!< Efuse chip revision */
} Efuse_Device_Info_Type;
#define EF_CTRL_EFUSE_R0_SIZE 128
#define EF_CTRL_EFUSE_R1_SIZE 128
void EF_Ctrl_Load_Efuse_R0(void);
void EF_Ctrl_Load_Efuse_R1(void);
BL_Sts_Type EF_Ctrl_Busy(void);
void EF_Ctrl_Clear(uint8_t region, uint32_t index, uint32_t len);
void EF_Ctrl_Sw_AHB_Clk_0(void);
void EF_Ctrl_Sw_AHB_Clk_1(void);
#endif /* __BL808_EF_CTRL_H__ */

View File

@ -0,0 +1,299 @@
/**
******************************************************************************
* @file bl808_glb_pll.c
* @version V1.0
* @date
* @brief This file is the standard driver c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
*
* 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 <bl808/cci_reg.h>
#include "bl808_glb.h"
/* uhs PLL 2000 Config*/
const GLB_MU_PLL_CFG_BASIC_Type uhsPll2000BasicCfg_24M = {
.clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */
.clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */
.clkpllVcoSpeed = 7, /*!< pll_vco_speed */
.clkpllEvenDivEn = 1, /*!< pll_even_div_en */
.clkpllEvenDivRatio = 2000/50, /*!< pll_even_div_ratio */
};
const GLB_MU_PLL_CFG_BASIC_Type uhsPll2000BasicCfg_32M = {
.clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */
.clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */
.clkpllVcoSpeed = 7, /*!< pll_vco_speed */
.clkpllEvenDivEn = 1, /*!< pll_even_div_en */
.clkpllEvenDivRatio = 2000/50, /*!< pll_even_div_ratio */
};
const GLB_MU_PLL_CFG_BASIC_Type uhsPll2000BasicCfg_38P4M = {
.clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */
.clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */
.clkpllVcoSpeed = 7, /*!< pll_vco_speed */
.clkpllEvenDivEn = 1, /*!< pll_even_div_en */
.clkpllEvenDivRatio = 2000/50, /*!< pll_even_div_ratio */
};
const GLB_MU_PLL_CFG_BASIC_Type uhsPll2000BasicCfg_40M = {
.clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */
.clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */
.clkpllVcoSpeed = 7, /*!< pll_vco_speed */
.clkpllEvenDivEn = 1, /*!< pll_even_div_en */
.clkpllEvenDivRatio = 2000/50, /*!< pll_even_div_ratio */
};
const GLB_MU_PLL_CFG_BASIC_Type uhsPll2000BasicCfg_26M = {
.clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */
.clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */
.clkpllVcoSpeed = 7, /*!< pll_vco_speed */
.clkpllEvenDivEn = 1, /*!< pll_even_div_en */
.clkpllEvenDivRatio = 2000/50, /*!< pll_even_div_ratio */
};
const GLB_MU_PLL_Cfg_Type uhsPllCfg_2000M[GLB_XTAL_MAX] = {
{ NULL, 0x0 }, /*!< XTAL is None */
{ &uhsPll2000BasicCfg_24M, 0x29AAA }, /*!< XTAL is 24M */
{ &uhsPll2000BasicCfg_32M, 0x3E800 }, /*!< XTAL is 32M */
{ &uhsPll2000BasicCfg_38P4M, 0x34155 }, /*!< XTAL is 38.4M */
{ &uhsPll2000BasicCfg_40M, 0x32000 }, /*!< XTAL is 40M */
{ &uhsPll2000BasicCfg_26M, 0x26762 }, /*!< XTAL is 26M */
{ &uhsPll2000BasicCfg_32M, 0x3E800 }, /*!< XTAL is RC32M */
};
/****************************************************************************/ /**
* @brief GLB power off mipi uhs PLL
*
* @param pllType: PLL XTAL type
*
* @return SUCCESS or ERROR
*
*******************************************************************************/
BL_Err_Type GLB_Power_Off_MU_PLL(GLB_MU_PLL_Type pllType)
{
uint32_t REG_PLL_BASE_ADDRESS = 0;
uint32_t tmpVal = 0;
CHECK_PARAM(IS_GLB_Power_Off_MU_TYPE(pllType));
switch (pllType) {
case GLB_MU_PLL_MIPIPLL:
REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET;
break;
case GLB_MU_PLL_UHSPLL:
REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_UHS_PLL_CFG0_OFFSET;
break;
default:
REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET;
break;
}
/* cfg0 : pu_aupll=0 */
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_PU_AUPLL, 0);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal);
/* cfg0 : pu_aupll_sfreg=0 */
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_PU_AUPLL_SFREG, 0);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal);
return SUCCESS;
}
/****************************************************************************/ /**
* @brief GLB mipi uhs PLL ref clock select
*
* @param pllType: PLL XTAL type
* @param refClk: PLL ref clock select
*
* @return SUCCESS or ERROR
*
*******************************************************************************/
BL_Err_Type GLB_MU_PLL_Ref_Clk_Sel(GLB_MU_PLL_Type pllType, GLB_PLL_REF_CLK_Type refClk)
{
uint32_t REG_PLL_BASE_ADDRESS = 0;
uint32_t tmpVal = 0;
CHECK_PARAM(IS_GLB_WAC_PLL_TYPE(pllType));
CHECK_PARAM(IS_GLB_PLL_REF_CLK_TYPE(refClk));
switch (pllType) {
case GLB_MU_PLL_MIPIPLL:
REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET;
break;
case GLB_MU_PLL_UHSPLL:
REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_UHS_PLL_CFG0_OFFSET;
break;
default:
REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET;
break;
}
/* xxxpll_refclk_sel */
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 1);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_REFCLK_SEL, refClk);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 1, tmpVal);
return SUCCESS;
}
/****************************************************************************/ /**
* @brief GLB power on PLL
*
* @param pllType: PLL XTAL type
* @param cfg: GLB PLL configuration
* @param waitStable: wait PLL stable
*
* @return SUCCESS or ERROR
*
*******************************************************************************/
BL_Err_Type GLB_Power_On_MU_PLL(GLB_MU_PLL_Type pllType, const GLB_MU_PLL_Cfg_Type *const cfg, uint8_t waitStable)
{
uint32_t REG_PLL_BASE_ADDRESS = 0;
uint32_t tmpVal = 0;
/* unknown */
CHECK_PARAM(IS_GLB_WAC_PLL_TYPE(pllType));
switch (pllType) {
case GLB_MU_PLL_MIPIPLL:
REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET;
break;
case GLB_MU_PLL_UHSPLL:
REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_UHS_PLL_CFG0_OFFSET;
break;
default:
REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET;
break;
}
/* Step1:config parameter */
/* cfg1:Set aupll_refclk_sel and aupll_refdiv_ratio */
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 1);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_REFDIV_RATIO, cfg->basicCfg->clkpllRefdivRatio);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 1, tmpVal);
/* cfg4:Set aupll_sel_sample_clk */
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 4);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SEL_SAMPLE_CLK, cfg->basicCfg->clkpllSelSampleClk);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 4, tmpVal);
/* cfg5:Set aupll_vco_speed */
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 5);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_VCO_SPEED, cfg->basicCfg->clkpllVcoSpeed);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 5, tmpVal);
/* cfg1: uhspll_even_div_en and uhspll_even_div_ratio */
if (GLB_MU_PLL_UHSPLL == pllType) {
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 1);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_UHSPLL_EVEN_DIV_EN, cfg->basicCfg->clkpllEvenDivEn);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_UHSPLL_EVEN_DIV_RATIO, cfg->basicCfg->clkpllEvenDivRatio);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 1, tmpVal);
}
/* cfg6:Set aupll_sdm_bypass,aupll_sdmin */
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 6);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDMIN, cfg->clkpllSdmin);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 6, tmpVal);
/* Step2:config pu */
/* cfg0 : pu_aupll_sfreg=1 */
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_PU_AUPLL_SFREG, 1);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal);
/* delay > 2us */
arch_delay_us(3);
/* cfg0 : pu_wifipll=1 */
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_PU_AUPLL, 1);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal);
/* delay > 2us */
arch_delay_us(3);
/* toggle sdm_reset (pulse 0 > 1us) */
/* cfg0 : aupll_sdm_reset */
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDM_RSTB, 1);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal);
arch_delay_us(2);
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDM_RSTB, 0);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal);
arch_delay_us(2);
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDM_RSTB, 1);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal);
/* Step3:reset pll */
/* cfg0 : toggle aupll_reset_fbdv, pulse 0 > 1us */
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_FBDV_RSTB, 1);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal);
arch_delay_us(2);
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_FBDV_RSTB, 0);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal);
arch_delay_us(2);
tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_FBDV_RSTB, 1);
BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal);
if (waitStable) {
/* Wait 1.5*30us */
arch_delay_us(45);
}
return SUCCESS;
}
/****************************************************************************/ /**
* @brief reconfigure UHSPLL clock
*
* @param xtalType: XTAL frequency type
* @param pllCfg: PLL configuration
*
* @return SUCCESS or ERROR
*
*******************************************************************************/
BL_Err_Type GLB_Config_UHS_PLL(GLB_XTAL_Type xtalType, const GLB_MU_PLL_Cfg_Type * pllCfgList)
{
GLB_PLL_REF_CLK_Type refClk;
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, &(pllCfgList[xtalType]), 1);
return SUCCESS;
}

2321
drivers/ram/bflb/bl808_glb.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,835 @@
/**
******************************************************************************
* @file bl808_psram_uhs.c
* @version V1.0
* @date
* @brief This file is the standard driver c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
*
* 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 "bl808_psram_uhs.h"
#include "bl808_uhs_phy.h"
#include "bl808_common.h"
#include "bl808_glb.h"
#include <bl808/psram_uhs_reg.h>
/** @addtogroup BL808_Peripheral_Driver
* @{
*/
/** @addtogroup PSRAM_UHS
* @{
*/
/** @defgroup PSRAM_UHS_Private_Macros
* @{
*/
#define PSRAM_UHS_RW_TIMEOUT 0xffffffff
/*@} end of group PSRAM_UHS_Private_Macros */
/** @defgroup PSRAM_UHS_Private_Types
* @{
*/
/*@} end of group PSRAM_UHS_Private_Types */
/** @defgroup PSRAM_UHS_Private_Variables
* @{
*/
/*@} end of group PSRAM_UHS_Private_Variables */
/** @defgroup PSRAM_UHS_Global_Variables
* @{
*/
/*@} end of group PSRAM_UHS_Global_Variables */
/** @defgroup PSRAM_UHS_Private_Fun_Declaration
* @{
*/
/*@} end of group PSRAM_UHS_Private_Fun_Declaration */
/** @defgroup PSRAM_UHS_Private_Functions
* @{
*/
/*@} end of group PSRAM_UHS_Private_Functions */
/** @defgroup PSRAM_UHS_Public_Functions
* @{
*/
int config_uhs_phy(uint32_t datarate)
{
uint32_t tmpVal = 0;
if (datarate > 1866) {
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0x0F0A1323);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x0b030404);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x050e0419);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x0a6a1c1c);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x0711070e);
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, 1);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal);
} else if (datarate > 1600) {
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0x0F283203);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x0a020303);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x040d0416);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x091e1818);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x0710070d);
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, 3);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal);
} else if (datarate > 1066) {
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0x0F270212);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x09020303);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x040c0313);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x07d11515);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x060f060c);
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, 1);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal);
} else if (datarate > 800) {
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0x0F270212);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x06010202);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x0309020d);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x05360e0e);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x050c0509);
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, 1);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal);
} else if (datarate > 666) {
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0x0F041020);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x05000101);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x0208010a);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x03e90b0b);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x040b0408);
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, 0);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal);
} else if (datarate > 400) {
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0x0F130010);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x05000101);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x02080108);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x03420909);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x040b0408);
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, 0);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal);
} else {
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0x0F020010);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x04000101);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x02070106);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x01f50606);
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x040a0407);
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, 0);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal);
}
return 0;
}
static void power_up_ldo12uhs(void)
{
uint32_t tmpVal = 0;
tmpVal = BL_RD_REG(GLB_BASE, GLB_LDO12UHS);
#ifdef BL808D_REWORK
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_LDO12UHS_PULLDOWN, 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_LDO12UHS_PULLDOWN_SEL, 1);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_PU_LDO12UHS, 0);
#else
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_PU_LDO12UHS, 1);
BL_WR_REG(GLB_BASE, GLB_LDO12UHS, tmpVal);
arch_delay_us(300);
tmpVal = BL_RD_REG(GLB_BASE, GLB_LDO12UHS);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_LDO12UHS_VOUT_SEL, 6);
#endif
BL_WR_REG(GLB_BASE, GLB_LDO12UHS, tmpVal);
arch_delay_us(1);
}
static 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, 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_DQ_OE_MID_P_REG, 0);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal);
arch_delay_us(1);
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40);
tmpVal &= 0xFFFCFFFF;
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_DMY0, 1);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40, tmpVal);
arch_delay_us(1);
}
static int set_or_uhs(uint32_t datarate)
{
uint32_t tmpVal = 0;
uint32_t *uhs_phy_cfg_base_addr = (uint32_t *)(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_00_OFFSET);
// clang-format off
const static uint32_t uhs_phy_cfg_data[] ={
0x802b0200, 0x60206020, 0x70027002, 0x70027002,
0x70027002, 0x70027002, 0x70027002, 0x70027002,
0x70027002, 0x70027002, 0x26000000, 0x26000006,
};
// clang-format on
for (uint32_t i = 0; i < 12; i++) {
uhs_phy_cfg_base_addr[i] = uhs_phy_cfg_data[i];
}
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_30);
tmpVal &= 0x08ffffff;
tmpVal |= 0x07000000;
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_30, tmpVal);
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_48);
tmpVal &= 0xfffffcff;
tmpVal |= 0x00000200;
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 &= 0xffe0ffff;
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_4C, tmpVal);
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50);
tmpVal &= 0xff88ff88;
tmpVal |= 0x00330033;
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal);
arch_delay_us(1);
return 0;
}
static void switch_to_ldo12uhs(void)
{
uint32_t tmpVal = 0;
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40);
tmpVal &= 0xFFCFFFFF;
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40, tmpVal);
arch_delay_us(1);
}
static void release_cen_ck_ckn(void)
{
uint32_t tmpVal = 0;
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40);
tmpVal &= 0xFFFCFEFF;
#ifdef BL808D_REWORK
tmpVal |= 0x10000;
#else
tmpVal |= 0x30000;
#endif
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40, tmpVal);
arch_delay_us(1);
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, 3);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_DQ_OE_MID_P_REG, 3);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal);
arch_delay_us(1);
}
static void Psram_analog_init(uint32_t pck_freq)
{
/* power on ldo12 */
power_up_ldo12uhs();
/* set cen ck ckn */
set_cen_ck_ckn();
/*
* overwrite default register content
* only support 2000M and 1500MHZ
*/
set_or_uhs(pck_freq);
/* switch to ldo12 */
switch_to_ldo12uhs();
/* release cen ck */
release_cen_ck_ckn();
/* config phy paramater */
config_uhs_phy(pck_freq);
}
/****************************************************************************/ /**
* @brief Init Psram UHS ,set auto refresh cycle
*
* @param cfg: pck frequency unit is MHZ
*
* @return None
*
*******************************************************************************/
void Psram_UHS_Init(PSRAM_UHS_Cfg_Type *cfg)
{
uint32_t tmpVal = 0;
CHECK_PARAM(IS_PSRAM_UHS_MEM_SIZE_TYPE(cfg->psramMemSize));
CHECK_PARAM(IS_PSRAM_UHS_PAGE_SIZE_TYPE(cfg->psramPageSize));
if (cfg->pck_freq > 2300) {
/* max support 2300MHZ */
while (1)
;
} else if (cfg->pck_freq > 1600) {
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_UHS_TIMING_CTRL_OFFSET, 0x1a03000f);
} else {
BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_UHS_TIMING_CTRL_OFFSET, 0x1202000b);
}
Psram_analog_init(cfg->pck_freq);
/* Wait 150 us */
arch_delay_us(150);
/* set refresh paramater */
/* 1. auto refresh clock source is pck_t, Adjust pck_t_div so that the frequency is around ~50Mhz */
/* tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_MANUAL);
tmpVal &= 0x00ffffff;
if (cfg->pck_freq >= 2200) {
tmpVal |= 0x05000000;
} else if (cfg->pck_freq >= 2000) {
tmpVal |= 0x04000000;
} else if (cfg->pck_freq >= 1500) {
tmpVal |= 0x03000000;
} else if (cfg->pck_freq >= 1400) {
tmpVal |= 0x02000000;
} else if (cfg->pck_freq >= 666) {
tmpVal |= 0x01000000;
}
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_MANUAL, tmpVal); */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_MANUAL);
tmpVal &= 0x00ffffff;
if (cfg->pck_freq >= 2200) {
tmpVal |= 0x05000000;
} else if (cfg->pck_freq >= 1800) {
tmpVal |= 0x04000000;
} else if (cfg->pck_freq >= 1500) {
tmpVal |= 0x03000000;
} else if (cfg->pck_freq >= 1400) {
tmpVal |= 0x02000000;
} else if (cfg->pck_freq >= 666) {
tmpVal |= 0x01000000;
}
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_MANUAL, tmpVal);
/* 2. setting refresh windows cycle count
* reg_win_cycle = refresh_window / Tpck_y
*
* refresh_window unit is ms
* when refresh tempotory > 85
* refresh_window = 16
* elsee
* refresh_window = 32
*/
if (cfg->isHighTem == PSRAM_UHS_NORMAL_TEMP) {
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_AUTO_FRESH_1, 0x16e360);
} else {
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_AUTO_FRESH_1, 0xB71B0);
}
/* 3 & 4. setting refresh count in a windows fixed value 4096 in v0.2
* calculate Average cycle between two auto-refresh
* reg_refi_cycle = reg_win_cycle / reg_win_ref_cnt
* */
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, 0x1000);
if (cfg->isHighTem == PSRAM_UHS_NORMAL_TEMP) {
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_REFI_CYCLE, (370));
} else {
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_REFI_CYCLE, (190));
}
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_AUTO_FRESH_2, tmpVal);
/* 5 setting single auto refresh time */
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, (uint32_t)(90 / T_pck_t));
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_BUST_CYCLE, 5);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_AUTO_FRESH_4, tmpVal);
/* 6 auto-refesh enable */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_AF_EN);
/* 7&8 . set psram memory size and page size */
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_ADDRMB_MSK, cfg->psramMemSize);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_LINEAR_BND_B, cfg->psramPageSize);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
/* 9. psram enable initial */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_INIT_EN);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
}
/****************************************************************************/ /**
* @brief Read register for uhs
*
* @param reg_addr: read addr
* @param regVal: regVal
*
* @return success or not
*
*******************************************************************************/
int PSram_UHS_Read_Reg(uint32_t reg_addr, uint8_t *regVal)
{
uint32_t tmpVal = 0;
uint32_t cnt = 0;
/* 1 generate requeset and wait authorization*/
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
do {
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
cnt++;
if (cnt > PSRAM_UHS_RW_TIMEOUT)
return -1;
} while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_REG_CONFIG_GNT));
/* 2 set mode reg */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_MODE_REG, reg_addr);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
/* 3 enable controller Rx*/
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_REGR_PULSE);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD, tmpVal);
cnt = 0;
/* 4 wait read done */
do {
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
cnt++;
if (cnt > PSRAM_UHS_RW_TIMEOUT)
return -1;
} while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_REGR_DONE));
/* 5 steup up read data */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
*regVal = (uint8_t)(BL_GET_REG_BITS_VAL(tmpVal, PSRAM_UHS_STS_CONFIG_READ));
/* 6 cancel requeset singnal */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
return 0;
}
/****************************************************************************/ /**
* @brief write register for winbond PSRAM
*
* @param regCfg: wirte reg data
*
* @return None
*
*******************************************************************************/
int PSram_UHS_Write_Reg(PSRAM_UHS_Write_Reg_Cfg_Type *regCfg)
{
uint32_t tmpVal = 0;
uint32_t cnt = 0;
uint8_t regWriteList[] = { 0, 2 };
uint8_t i = 0;
CHECK_PARAM(IS_PSRAM_UHS_DRIVER_ST_TYPE(regCfg->driver_st));
CHECK_PARAM(IS_PSRAM_UHS_WARP_BURST_TYPE(regCfg->burst_size));
CHECK_PARAM(IS_PSRAM_UHS_LATENCY_TYPE(regCfg->lentency));
/* 1 congfi write reg*/
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_PSRAM_CONFIGURE);
switch (regCfg->burst_size) {
case PSRAM_UHS_WARP_BURST_64:
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_64);
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_32);
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_16);
break;
case PSRAM_UHS_WARP_BURST_32:
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_16);
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_32);
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_64);
break;
case PSRAM_UHS_WARP_BURST_16:
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_16);
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_32);
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_64);
break;
case PSRAM_UHS_WARP_BURST_NONE:
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_16);
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_32);
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_64);
break;
default:
return -1;
}
if (regCfg->driver_st != PSRAM_UHS_DRIVER_ST_NO_CHANGE) {
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_DRIVE_ST, regCfg->driver_st);
}
if (regCfg->lentency != PSRAM_UHS_LATENCY_NO_CHANGE) {
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_LATENCY, regCfg->lentency);
}
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_PSRAM_CONFIGURE, tmpVal);
/* 2 generate requeset and wait authorization */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
do {
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
cnt++;
if (cnt > PSRAM_UHS_RW_TIMEOUT)
return -1;
} while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_REG_CONFIG_GNT));
for (i = 0; i < sizeof(regWriteList) / sizeof(uint8_t); i++) {
/* 3 set mode reg */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_MODE_REG, regWriteList[i]);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
/* 4 enable controller */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_REGW_PULSE);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD, tmpVal);
cnt = 0;
/* 5 wait write done */
do {
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
cnt++;
if (cnt > PSRAM_UHS_RW_TIMEOUT)
return -1;
} while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_REGW_DONE));
}
/* 6 cancel requeset singnal */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
return 0;
}
/****************************************************************************/ /**
* @brief Timing Reset
*
* @param reg_addr: reg_addr
* @param regCfg: wirte reg data
*
* @return None
*
*******************************************************************************/
int PSram_UHS_Timing_Reset(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, 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_DMY0, 1);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40, tmpVal);
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, 0);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_DQ_OE_MID_P_REG, 0);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal);
arch_delay_us(1000);
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_DMY1, 3);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_DMY0, 0);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40, tmpVal);
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, 4);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_DQ_OE_MID_P_REG, 4);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal);
return 0;
}
/****************************************************************************/ /**
* @brief construct cmd wave for psram
*
* @param reg_addr: reg_addr
* @param regCfg: wirte reg data
*
* @return None
*
*******************************************************************************/
int PSram_UHS_Construct_Cmd(PSRAM_UHS_CMD_Type cmd)
{
uint32_t tmpVal = 0;
uint32_t cnt = 0;
CHECK_PARAM(IS_PSRAM_UHS_CMD_TYPE(cmd));
/* generate requeset and wait authorization*/
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
do {
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
cnt++;
if (cnt > PSRAM_UHS_RW_TIMEOUT)
goto exit;
} while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_REG_CONFIG_GNT));
/* enable cmd generate */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
switch (cmd) {
case PSRAM_UHS_CMD_SELF_REFRESH_IN:
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_SRFI_PULSE);
break;
case PSRAM_UHS_CMD_SELF_REFRESH_EXIT:
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_SRFO_PULSE);
break;
case PSRAM_UHS_CMD_GLOBAL_RESET:
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_GLBR_PULSE);
/* Wait 15 us for reset */
arch_delay_us(15);
break;
case PSRAM_UHS_CMD_ZQ_CAL_LONG:
/* 3 set mode reg */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_MODE_REG, 5);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
/* 4 enable controller */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_REGW_PULSE);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD, tmpVal);
cnt = 0;
/* 5 wait write done */
do {
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
cnt++;
if (cnt > PSRAM_UHS_RW_TIMEOUT)
goto exit;
} while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_REGW_DONE));
break;
case PSRAM_UHS_CMD_ZQ_CAL_SHORT:
/* 3 set mode reg */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_MODE_REG, 6);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
/* 4 enable controller */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_REGW_PULSE);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD, tmpVal);
cnt = 0;
/* 5 wait write done */
do {
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
cnt++;
if (cnt > PSRAM_UHS_RW_TIMEOUT)
goto exit;
} while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_REGW_DONE));
break;
case PSRAM_UHS_CMD_ZQ_CAL_RESET:
/* 3 set mode reg */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_MODE_REG, 7);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
/* 4 enable controller */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_REGW_PULSE);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD, tmpVal);
cnt = 0;
/* 5 wait write done */
do {
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
cnt++;
if (cnt > PSRAM_UHS_RW_TIMEOUT)
goto exit;
} while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_REGW_DONE));
break;
default:
goto exit;
break;
}
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD, tmpVal);
cnt = 0;
/* wait write done */
switch (cmd) {
case PSRAM_UHS_CMD_SELF_REFRESH_IN:
do {
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
cnt++;
if (cnt > PSRAM_UHS_RW_TIMEOUT)
goto exit;
} while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_SRFI_DONE));
break;
case PSRAM_UHS_CMD_SELF_REFRESH_EXIT:
do {
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
cnt++;
if (cnt > PSRAM_UHS_RW_TIMEOUT)
goto exit;
} while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_SRFO_DONE));
break;
case PSRAM_UHS_CMD_GLOBAL_RESET:
do {
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD);
cnt++;
if (cnt > PSRAM_UHS_RW_TIMEOUT)
goto exit;
} while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_GLBR_DONE));
break;
default:
goto exit;
}
/* 6 cancel requeset singnal */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
return 0;
exit:
/* 6 cancel requeset singnal */
tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC);
tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ);
BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal);
return -1;
}
/**
* @brief defualt init for 64MB x16 UHS PSRAM
* user should enable UHS PSRAM PLL before call this function
* @param uhs_pll_clk The uhs pll frequency used
*/
void Psram_UHS_x16_Init(uint32_t uhs_pll_clk)
{
PSRAM_UHS_Cfg_Type psramDefaultCfg = {
2000,
PSRAM_MEM_SIZE_64MB,
PSRAM_PAGE_SIZE_2KB,
PSRAM_UHS_NORMAL_TEMP,
};
PSRAM_UHS_Write_Reg_Cfg_Type writeReg = {
PSRAM_UHS_DRIVER_ST_40_PDPU,
PSRAM_UHS_WARP_BURST_NONE,
PSRAM_UHS_LATENCY_W18_R37_MAX_FRE_1066_MHZ,
};
psramDefaultCfg.pck_freq = uhs_pll_clk;
if ((uhs_pll_clk >= 2000) && (uhs_pll_clk <= 2300)) {
writeReg.lentency = PSRAM_UHS_LATENCY_W18_R37_MAX_FRE_1066_MHZ;
} else if ((uhs_pll_clk <= 1600) && (uhs_pll_clk > 1066)) {
writeReg.lentency = PSRAM_UHS_LATENCY_W14_R29_MAX_FRE_800_MHZ;
} else if ((uhs_pll_clk < 1067) && (uhs_pll_clk > 800)) {
writeReg.lentency = PSRAM_UHS_LATENCY_W10_R20_MAX_FRE_533_MHZ;
} else if ((uhs_pll_clk <= 800) && (uhs_pll_clk > 667)) {
writeReg.lentency = PSRAM_UHS_LATENCY_W6_R16_MAX_FRE_400_MHZ;
} else if ((uhs_pll_clk < 667) && (uhs_pll_clk > 400)) {
writeReg.lentency = PSRAM_UHS_LATENCY_W5_R13_MAX_FRE_333_MHZ;
} else if (uhs_pll_clk <= 400) {
writeReg.lentency = PSRAM_UHS_LATENCY_W5_R9_MAX_FRE_200_MHZ;
}
/* first initial psram controller*/
Psram_UHS_Init(&psramDefaultCfg);
/* reset psram device*/
PSram_UHS_Construct_Cmd(PSRAM_UHS_CMD_GLOBAL_RESET);
arch_delay_us(100);
/* write 1GHZ configuration to psram device */
PSram_UHS_Write_Reg(&writeReg);
}
void Psram_UHS_x16_Init_Override(PSRAM_UHS_Cfg_Type *cfg)
{
/* first initial psram controller*/
Psram_UHS_Init(cfg);
uhs_phy_init(cfg);
}
/*@} end of group PSRAM_UHS_Public_Functions */
/*@} end of group PSRAM_UHS */
/*@} end of group BL808_Peripheral_Driver */

View File

@ -0,0 +1,273 @@
/**
******************************************************************************
* @file bl808_psram_uhs.h
* @version V1.0
* @date
* @brief This file is the standard driver header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
*
* 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 <bl808/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, /*!<ZQ calibration, long> */
PSRAM_UHS_CMD_ZQ_CAL_SHORT, /*!<ZQ calibration, short>*/
PSRAM_UHS_CMD_ZQ_CAL_RESET, /*!<ZQ calibration,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__ */

File diff suppressed because it is too large Load Diff

View File

@ -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 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__

93
drivers/ram/bflb/psram.c Normal file
View File

@ -0,0 +1,93 @@
#include <dm.h>
#include <ram.h>
#include "bl808_ef_cfg.h"
#include "bl808_psram_uhs.h"
#include "bl808_uhs_phy.h"
#define WB_4MB_PSRAM (1)
#define UHS_32MB_PSRAM (2)
#define UHS_64MB_PSRAM (3)
#define WB_32MB_PSRAM (4)
#define NONE_UHS_PSRAM (-1)
static PSRAM_UHS_Cfg_Type psramDefaultCfg = {
2000,
PSRAM_MEM_SIZE_32MB,
PSRAM_PAGE_SIZE_2KB,
PSRAM_UHS_NORMAL_TEMP,
};
static int uhs_psram_init(void)
{
Efuse_Chip_Info_Type chip_info;
EF_Ctrl_Get_Chip_Info(&chip_info);
if (chip_info.psramInfo == UHS_32MB_PSRAM) {
psramDefaultCfg.psramMemSize = PSRAM_MEM_SIZE_32MB;
} else if (chip_info.psramInfo == UHS_64MB_PSRAM) {
psramDefaultCfg.psramMemSize = PSRAM_MEM_SIZE_64MB;
} else {
return -1;
}
Efuse_Psram_Trim_Type uhs_psram_trim;
EF_Ctrl_Read_Psram_Trim(&uhs_psram_trim);
//init uhs PLL; Must open uhs pll first, and then initialize uhs psram
GLB_Config_UHS_PLL(GLB_XTAL_40M, uhsPllCfg_2000M);
//init uhs psram ;
// Psram_UHS_x16_Init(Clock_Peripheral_Clock_Get(BL_PERIPHERAL_CLOCK_PSRAMA) / 1000000);
Psram_UHS_x16_Init_Override(&psramDefaultCfg);
// example: 2000Mbps typical cal values
uhs_phy_cal_res->rl = 39;
uhs_phy_cal_res->rdqs = 3;
uhs_phy_cal_res->rdq = 0;
uhs_phy_cal_res->wl = 13;
uhs_phy_cal_res->wdqs = 4;
uhs_phy_cal_res->wdq = 5;
uhs_phy_cal_res->ck = 9;
/* TODO: use uhs psram trim update */
set_uhs_latency_r(uhs_phy_cal_res->rl);
cfg_dqs_rx(uhs_phy_cal_res->rdqs);
cfg_dq_rx(uhs_phy_cal_res->rdq);
set_uhs_latency_w(uhs_phy_cal_res->wl);
cfg_dq_drv(uhs_phy_cal_res->wdq);
cfg_ck_cen_drv(uhs_phy_cal_res->wdq + 4, uhs_phy_cal_res->wdq + 1);
cfg_dqs_drv(uhs_phy_cal_res->wdqs);
// set_odt_en();
mr_read_back();
return 0;
}
static int bflb_psram_get_info(struct udevice *dev, struct ram_info *info)
{
info->base = 0x50000000;
info->size = (psramDefaultCfg.psramMemSize + 1) * 1024 * 1024;
return 0;
}
static const struct ram_ops bflb_psram_ops = {
.get_info = bflb_psram_get_info,
};
static int bflb_psram_probe(struct udevice *dev)
{
return uhs_psram_init();
}
static const struct udevice_id bflb_psram_ids[] = {
{ .compatible = "bflb,bl808-psram-uhs" },
{ }
};
U_BOOT_DRIVER(bflb_psram) = {
.name = "bflb_psram",
.id = UCLASS_RAM,
.of_match = bflb_psram_ids,
.probe = bflb_psram_probe,
.ops = &bflb_psram_ops,
.flags = DM_FLAG_PRE_RELOC,
};