507 lines
10 KiB
C
507 lines
10 KiB
C
|
|
//
|
||
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
//
|
||
|
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
// See the License for the specific language governing permissions and
|
||
|
|
// limitations under the License.
|
||
|
|
|
||
|
|
|
||
|
|
#include <common/bk_include.h>
|
||
|
|
#include <driver/psram_types.h>
|
||
|
|
#include "psram_hal.h"
|
||
|
|
#include "psram_ll_macro_def.h"
|
||
|
|
#include "bk_pm_internal_api.h"
|
||
|
|
#include "sys_driver.h"
|
||
|
|
#include "aon_pmu_ll.h"
|
||
|
|
#include <driver/psram.h>
|
||
|
|
#include <modules/chip_support.h>
|
||
|
|
|
||
|
|
extern void delay_us(uint32_t us);
|
||
|
|
|
||
|
|
static void psram_delay(volatile uint32_t times)
|
||
|
|
{
|
||
|
|
while(times--);
|
||
|
|
}
|
||
|
|
|
||
|
|
void psram_hal_set_sf_reset(uint32_t value)
|
||
|
|
{
|
||
|
|
psram_ll_set_sf_reset_value(value);
|
||
|
|
}
|
||
|
|
|
||
|
|
void psram_hal_set_cmd_reset(void)
|
||
|
|
{
|
||
|
|
psram_ll_set_reg8_value(0x4);
|
||
|
|
}
|
||
|
|
|
||
|
|
void psram_hal_cmd_write(uint32_t addr, uint32_t value)
|
||
|
|
{
|
||
|
|
psram_ll_set_write_address(addr);
|
||
|
|
psram_ll_set_write_data(value);
|
||
|
|
psram_ll_set_reg8_value(0x1);
|
||
|
|
while(psram_ll_get_reg8_value() & 0x1);
|
||
|
|
}
|
||
|
|
|
||
|
|
uint32_t psram_hal_cmd_read(uint32_t addr)
|
||
|
|
{
|
||
|
|
uint8_t m = 10, i = 5;
|
||
|
|
|
||
|
|
for (i = 5; i > 0; i--)
|
||
|
|
{
|
||
|
|
psram_ll_set_write_address(addr);
|
||
|
|
psram_ll_set_reg8_value(0x2);
|
||
|
|
|
||
|
|
m = 10;
|
||
|
|
|
||
|
|
while(psram_ll_get_reg8_value() & 0x2)
|
||
|
|
{
|
||
|
|
for (int j = 0; j < 5000; j++) {}
|
||
|
|
|
||
|
|
m--;
|
||
|
|
|
||
|
|
if (m == 0)
|
||
|
|
break;
|
||
|
|
};
|
||
|
|
|
||
|
|
if (m != 0)
|
||
|
|
{
|
||
|
|
return psram_ll_get_regb_value();
|
||
|
|
}
|
||
|
|
|
||
|
|
psram_hal_set_sf_reset(0);
|
||
|
|
psram_hal_set_sf_reset(1);
|
||
|
|
psram_hal_set_cmd_reset();
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
void psram_hal_set_clk(psram_clk_t clk)
|
||
|
|
{
|
||
|
|
switch (clk)
|
||
|
|
{
|
||
|
|
case PSRAM_240M:
|
||
|
|
sys_drv_psram_clk_sel(1); // clk sel: 0-320 1-480
|
||
|
|
sys_drv_psram_set_clkdiv(0); //frq: F/(2 + (1+div))
|
||
|
|
break;
|
||
|
|
case PSRAM_160M:
|
||
|
|
sys_drv_psram_clk_sel(0); // clk sel: 0-320 1-480
|
||
|
|
sys_drv_psram_set_clkdiv(0); //frq: F/(2 + (1+div))
|
||
|
|
break;
|
||
|
|
case PSRAM_120M:
|
||
|
|
sys_drv_psram_clk_sel(1); // clk sel: 0-320 1-480
|
||
|
|
sys_drv_psram_set_clkdiv(1); //frq: F/(2 + (1+div))
|
||
|
|
break;
|
||
|
|
case PSRAM_80M:
|
||
|
|
sys_drv_psram_clk_sel(0); // clk sel: 0-320 1-480
|
||
|
|
sys_drv_psram_set_clkdiv(1); //frq: F/(2 + (1+div))
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void psram_hal_set_voltage(psram_voltage_t voltage)
|
||
|
|
{
|
||
|
|
#if (COINFG_SOC_BK7256XX)
|
||
|
|
switch (voltage)
|
||
|
|
{
|
||
|
|
case PSRAM_OUT_3_20V:
|
||
|
|
sys_drv_psram_psldo_vset(0, 1);
|
||
|
|
break;
|
||
|
|
case PSRAM_OUT_3_0V:
|
||
|
|
sys_drv_psram_psldo_vset(0, 0);
|
||
|
|
break;
|
||
|
|
case PSRAM_OUT_2_0V:
|
||
|
|
sys_drv_psram_psldo_vset(1, 1);
|
||
|
|
break;
|
||
|
|
case PSRAM_OUT_1_80V:
|
||
|
|
sys_drv_psram_psldo_vset(1, 0);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
#else
|
||
|
|
switch (voltage)
|
||
|
|
{
|
||
|
|
case PSRAM_OUT_3_0V:
|
||
|
|
sys_drv_psram_psldo_vset(0, 0);
|
||
|
|
break;
|
||
|
|
case PSRAM_OUT_1_95V:
|
||
|
|
sys_drv_psram_psldo_vset(1, 0);
|
||
|
|
break;
|
||
|
|
case PSRAM_OUT_1_90V:
|
||
|
|
sys_drv_psram_psldo_vset(1, 1);
|
||
|
|
break;
|
||
|
|
case PSRAM_OUT_1_85V:
|
||
|
|
sys_drv_psram_psldo_vset(1, 2);
|
||
|
|
break;
|
||
|
|
case PSRAM_OUT_1_80V:
|
||
|
|
sys_drv_psram_psldo_vset(1, 3);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
static inline bool is_psram_addr_out_of_range(uint32_t addr)
|
||
|
|
{
|
||
|
|
#if (CONFIG_PSRAM_WRITE_THROUGH)
|
||
|
|
return ((addr < SOC_PSRAM_DATA_BASE) || (addr > (SOC_PSRAM_DATA_BASE + SOC_PSRAM_DATA_SIZE)));
|
||
|
|
#else
|
||
|
|
return false;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
static inline bool is_32bytes_aligned(uint32_t addr)
|
||
|
|
{
|
||
|
|
return ((addr & 0x1f) == 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
int psram_hal_set_write_through(psram_write_through_area_t area, uint32_t enable, uint32_t start, uint32_t end)
|
||
|
|
{
|
||
|
|
#if (CONFIG_PSRAM_WRITE_THROUGH)
|
||
|
|
|
||
|
|
if (area > PSRAM_WRITE_THROUGH_AREA_COUNT) {
|
||
|
|
return BK_ERR_PSRAM_AREA;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (enable) {
|
||
|
|
if (start >= end) {
|
||
|
|
return BK_ERR_PSRAM_ADDR_RELATION;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (is_psram_addr_out_of_range(start) || is_psram_addr_out_of_range(end)) {
|
||
|
|
return BK_ERR_PSRAM_ADDR_OUT_OF_RANGE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((!is_32bytes_aligned(start)) || (!is_32bytes_aligned(end))) {
|
||
|
|
return BK_ERR_PSRAM_ADDR_ALIGN;
|
||
|
|
}
|
||
|
|
psram_ll_set_cover_start(area, start >> 5);
|
||
|
|
psram_ll_set_cover_stop_enable(area, BIT(31) | (end >> 5));
|
||
|
|
} else {
|
||
|
|
psram_ll_set_cover_stop_enable(area, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
return BK_OK;
|
||
|
|
#else
|
||
|
|
return BK_FAIL;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
void psram_hal_set_transfer_mode(uint32_t value)
|
||
|
|
{
|
||
|
|
psram_ll_set_reg4_wrap_config(value);
|
||
|
|
}
|
||
|
|
|
||
|
|
static int psram_hal_APS6408L_init(uint32_t *id)
|
||
|
|
{
|
||
|
|
uint32_t val = 0;
|
||
|
|
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
uint32_t chip_id = bk_get_hardware_chip_id_version();
|
||
|
|
|
||
|
|
if (chip_id == CHIP_VERSION_C)
|
||
|
|
psram_hal_set_mode_value(PSRAM_MODE1);
|
||
|
|
else
|
||
|
|
psram_hal_set_mode_value(PSRAM_MODE3);
|
||
|
|
#else
|
||
|
|
psram_hal_set_mode_value(PSRAM_MODE6);//PSRAM_MODE2
|
||
|
|
//psram_hal_set_reg5_value(0x282);
|
||
|
|
psram_hal_set_reg5_value(0x380);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
psram_hal_set_cmd_reset();
|
||
|
|
|
||
|
|
psram_delay(500);
|
||
|
|
|
||
|
|
val = psram_hal_cmd_read(0x00000000);//1 0001 10001101
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
// 8 line
|
||
|
|
val = ((val >> 8) & 0xFF) | ((val & 0xFF) << 8);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
if (val == 0 || val != *id)
|
||
|
|
{
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
*id = val;
|
||
|
|
}
|
||
|
|
|
||
|
|
val = psram_hal_get_regb_value();
|
||
|
|
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
val = (val & ~(0x1F << 8)) | (0x4 << 10) | (0x3 << 8);
|
||
|
|
#else
|
||
|
|
val = (val & ~(0x1F)) | (0x4 << 2) | 0x3;
|
||
|
|
#endif
|
||
|
|
psram_hal_cmd_write(0x00000000, val);
|
||
|
|
|
||
|
|
psram_hal_cmd_read(0x00000000);//1 0001 10001101
|
||
|
|
psram_hal_cmd_read(0x00000004);
|
||
|
|
|
||
|
|
val = psram_hal_get_regb_value();
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
val = (val & ~(0x7 << 13)) | (0x6 << 13);//write latency 110 166Mhz
|
||
|
|
#else
|
||
|
|
val = (val & ~(0x7 << 5)) | (0x6 << 5);
|
||
|
|
#endif
|
||
|
|
psram_hal_cmd_write(0x00000004, val);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static int psram_hal_W955D8MKY_5J_init(uint32_t *id)
|
||
|
|
{
|
||
|
|
uint32_t val = 0;
|
||
|
|
uint32_t io_drv = 0; /*range [0, 3]*/
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
psram_hal_set_mode_value(PSRAM_MODE4);// mode 4
|
||
|
|
#elif (CONFIG_SOC_BK7236XX)
|
||
|
|
psram_hal_set_mode_value(PSRAM_MODE8);// mode 8
|
||
|
|
#endif
|
||
|
|
#if (!CONFIG_SOC_BK7256XX)
|
||
|
|
psram_hal_set_reg5_value(0x292);
|
||
|
|
//psram_hal_set_reg5_value(0x380); //NOTES:APS PSRAM drive stength needs changed.This type PSRAM needs to be verified.
|
||
|
|
#endif
|
||
|
|
|
||
|
|
psram_hal_set_cmd_reset();
|
||
|
|
psram_delay(500);
|
||
|
|
|
||
|
|
val = psram_hal_cmd_read(0x01000000);
|
||
|
|
(VOID *)val;
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
// 8 line
|
||
|
|
val = ((val >> 8) & 0xFF) | ((val & 0xFF) << 8);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
val = 0x8F1C | (io_drv << 12);
|
||
|
|
#else
|
||
|
|
val = 0x1C8F | (io_drv << 4);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
psram_hal_cmd_write(0x01000000, val);
|
||
|
|
#elif (CONFIG_SOC_BK7236XX)
|
||
|
|
psram_hal_cmd_write(0x01000000, 0x1c8f);
|
||
|
|
#endif
|
||
|
|
psram_hal_cmd_read(0x01000000);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static int psram_hal_APS128XXO_OB9_init(uint32_t *id)
|
||
|
|
{
|
||
|
|
uint32_t val = 0;
|
||
|
|
psram_hal_set_mode_value(PSRAM_MODE7);
|
||
|
|
#if (!CONFIG_SOC_BK7256XX)
|
||
|
|
//psram_hal_set_reg5_value(0x292);
|
||
|
|
psram_hal_set_reg5_value(0x380);
|
||
|
|
#endif
|
||
|
|
psram_hal_set_cmd_reset();
|
||
|
|
|
||
|
|
psram_delay(500);
|
||
|
|
|
||
|
|
val = psram_hal_cmd_read(0x00000000);//1 0001 10001101
|
||
|
|
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
// 8 line
|
||
|
|
val = ((val >> 8) & 0xFF) | ((val & 0xFF) << 8);
|
||
|
|
#endif
|
||
|
|
if (val == 0 || val != *id)
|
||
|
|
{
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
*id = val;
|
||
|
|
}
|
||
|
|
|
||
|
|
val = psram_hal_get_regb_value();
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
val = (val & ~(0x7 << 10)) | (0x4 << 10);
|
||
|
|
#else
|
||
|
|
val = (val & ~(0x7 << 2)) | (0x4 << 2);
|
||
|
|
#endif
|
||
|
|
psram_hal_cmd_write(0x00000000, val);
|
||
|
|
|
||
|
|
psram_hal_cmd_read(0x00000004);
|
||
|
|
val = psram_hal_get_regb_value();
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
val = (val & ~(0x7 << 13)) | (0x6 << 13);
|
||
|
|
#else
|
||
|
|
val = (val & ~(0x7 << 5)) | (0x6 << 5);
|
||
|
|
#endif
|
||
|
|
psram_hal_cmd_write(0x00000004, val);
|
||
|
|
|
||
|
|
psram_hal_cmd_read(0x00000008);//1 0001 10001101
|
||
|
|
val = psram_hal_get_regb_value();
|
||
|
|
val |= 0x40;
|
||
|
|
psram_hal_cmd_write(0x00000008,val);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
uint32_t psram_hal_config_init(uint32_t id)
|
||
|
|
{
|
||
|
|
int ret = 0;
|
||
|
|
uint32_t val = 0;
|
||
|
|
uint32_t type = id;
|
||
|
|
|
||
|
|
psram_hal_set_sf_reset(1);
|
||
|
|
|
||
|
|
/* set psram bypass */
|
||
|
|
val = psram_hal_get_reg2_value();
|
||
|
|
val |= (0x1 << 1);
|
||
|
|
psram_hal_set_reg2_value(val);
|
||
|
|
|
||
|
|
if (id != 0)
|
||
|
|
{
|
||
|
|
if (id == PSRAM_APS6408L_ID)
|
||
|
|
{
|
||
|
|
psram_hal_APS6408L_init(&type);
|
||
|
|
return type;
|
||
|
|
}
|
||
|
|
else if (id == PSRAM_APS128XXO_OB9_ID)
|
||
|
|
{
|
||
|
|
psram_hal_APS128XXO_OB9_init(&type);
|
||
|
|
return type;
|
||
|
|
}
|
||
|
|
else //id == PSRAM_W955D8MKY_5J_ID
|
||
|
|
{
|
||
|
|
psram_hal_W955D8MKY_5J_init(&type);
|
||
|
|
return type;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
type = PSRAM_APS6408L_ID;
|
||
|
|
ret = psram_hal_APS6408L_init(&type);
|
||
|
|
if (ret == 0)
|
||
|
|
{
|
||
|
|
return type;
|
||
|
|
}
|
||
|
|
|
||
|
|
type = PSRAM_APS128XXO_OB9_ID;
|
||
|
|
ret = psram_hal_APS128XXO_OB9_init(&type);
|
||
|
|
if (ret == 0)
|
||
|
|
{
|
||
|
|
return type;
|
||
|
|
}
|
||
|
|
|
||
|
|
type = PSRAM_W955D8MKY_5J_ID;
|
||
|
|
ret = psram_hal_W955D8MKY_5J_init(&type);
|
||
|
|
|
||
|
|
return type;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// config 1: psram power and clk config, need wait clk stable
|
||
|
|
void psram_hal_power_clk_enable(uint8_t enable)
|
||
|
|
{
|
||
|
|
if (enable)
|
||
|
|
{
|
||
|
|
psram_delay(500);
|
||
|
|
|
||
|
|
sys_drv_psram_ldo_enable(1);
|
||
|
|
delay_us(1000);
|
||
|
|
|
||
|
|
bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_AHBP_PSRAM, PM_POWER_MODULE_STATE_ON);
|
||
|
|
|
||
|
|
// psram bus clk always open
|
||
|
|
sys_drv_psram_psram_disckg(1);
|
||
|
|
|
||
|
|
//psram 80M
|
||
|
|
psram_hal_set_clk(PSRAM_80M);
|
||
|
|
|
||
|
|
sys_drv_dev_clk_pwr_up(CLK_PWR_ID_PSRAM, CLK_PWR_CTRL_PWR_UP);//psram_clk_enable bit19=1
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
bk_psram_heap_init_flag_set(false);
|
||
|
|
|
||
|
|
bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_AHBP_PSRAM, PM_POWER_MODULE_STATE_OFF);
|
||
|
|
psram_hal_set_sf_reset(0);
|
||
|
|
|
||
|
|
sys_drv_dev_clk_pwr_up(CLK_PWR_ID_PSRAM, CLK_PWR_CTRL_PWR_DOWN);//psram_clk_disable
|
||
|
|
|
||
|
|
// power down
|
||
|
|
sys_drv_psram_ldo_enable(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
psram_delay(3000);
|
||
|
|
}
|
||
|
|
|
||
|
|
// config 2: reset psram and wait psram ready
|
||
|
|
void psram_hal_reset(void)
|
||
|
|
{
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
psram_hal_set_sf_reset(1);
|
||
|
|
|
||
|
|
#if (CONFIG_PSRAM_APS6408L_O)
|
||
|
|
|
||
|
|
int chip_id = bk_get_hardware_chip_id_version();
|
||
|
|
|
||
|
|
if (chip_id == CHIP_VERSION_C)
|
||
|
|
psram_hal_set_mode_value(PSRAM_MODE1);
|
||
|
|
else
|
||
|
|
psram_hal_set_mode_value(PSRAM_MODE3);
|
||
|
|
#else
|
||
|
|
//psram_hal_set_mode_value(PSRAM_MODE5);// mode 5
|
||
|
|
psram_hal_set_mode_value(PSRAM_MODE4);// mode 4
|
||
|
|
#endif
|
||
|
|
psram_hal_set_cmd_reset();
|
||
|
|
#endif //CONFIG_SOC_BK7256XX
|
||
|
|
}
|
||
|
|
|
||
|
|
// config 3: psram config
|
||
|
|
void psram_hal_config(void)
|
||
|
|
{
|
||
|
|
#if (CONFIG_SOC_BK7256XX)
|
||
|
|
uint32_t val = 0;
|
||
|
|
|
||
|
|
#if (CONFIG_PSRAM_APS6408L_O)
|
||
|
|
|
||
|
|
psram_hal_cmd_read(0x00000000);//1 0001 10001101
|
||
|
|
|
||
|
|
val = psram_hal_get_regb_value();
|
||
|
|
|
||
|
|
val = (val & ~(0x1F << 8)) | (0x4 << 10) | (0x3 << 8);
|
||
|
|
|
||
|
|
psram_hal_cmd_write(0x00000000, val);
|
||
|
|
|
||
|
|
psram_hal_cmd_read(0x00000000);//1 0001 10001101
|
||
|
|
|
||
|
|
psram_hal_cmd_read(0x00000004);
|
||
|
|
|
||
|
|
val = psram_hal_get_regb_value();
|
||
|
|
val = (val & ~(0x7 << 13)) | (0x6 << 13);//write latency 110 166Mhz
|
||
|
|
|
||
|
|
psram_hal_cmd_write(0x00000004, val);
|
||
|
|
#else
|
||
|
|
uint32_t io_drv = 0; /*range [0, 3]*/
|
||
|
|
|
||
|
|
val = psram_hal_cmd_read(0x01000000);
|
||
|
|
|
||
|
|
//val = 0x8F1F | (io_drv << 12);// mode 5
|
||
|
|
val = 0x8F1C | (io_drv << 12);// mode 4
|
||
|
|
|
||
|
|
psram_hal_cmd_write(0x01000000, val);
|
||
|
|
|
||
|
|
psram_hal_cmd_read(0x01000000);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#endif //CONFIG_SOC_BK7256XX
|
||
|
|
}
|
||
|
|
|
||
|
|
|