210 lines
4.9 KiB
C
210 lines
4.9 KiB
C
/**
|
|
* @file device_init.c
|
|
* @brief Semidrive device ealryinit.
|
|
*
|
|
* @copyright Copyright (c) 2022 Semidrive Semiconductor.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <sdrv_ckgen.h>
|
|
#include <sdrv_power.h>
|
|
#include <regs_base.h>
|
|
#include <reg.h>
|
|
#include <core_id.h>
|
|
#include <param.h>
|
|
|
|
#ifndef APB_IRAMC1_BASE
|
|
/* IRAM1 RAM Controller */
|
|
#define APB_IRAMC1_BASE (0xF0D20000ul)
|
|
#endif
|
|
|
|
#ifndef APB_IRAMC2_BASE
|
|
/* IRAM2 RAM Controller */
|
|
#define APB_IRAMC2_BASE (0xF0D30000ul)
|
|
#endif
|
|
|
|
#ifndef APB_IRAMC3_BASE
|
|
/* IRAM3 RAM Controller */
|
|
#define APB_IRAMC3_BASE (0xF0D40000ul)
|
|
#endif
|
|
|
|
#ifndef APB_IRAMC4_BASE
|
|
/* IRAM4 RAM Controller */
|
|
#define APB_IRAMC4_BASE (0xF2030000ul)
|
|
#endif
|
|
|
|
#define SAF_LP_CTL_OFF(n) (0x1008U + 8U * (n))
|
|
#define SAF_RAM_LP_CTL_OFF(n) (0x1060U + 4U * (n))
|
|
|
|
|
|
extern const sdrv_ckgen_node_t **g_ckgen_unused[];
|
|
|
|
static const sdrv_ckgen_xcg_set_t g_xcg_info[] = {
|
|
{APB_CKGEN_SF_BASE, CKGEN_PCG_TYPE, 334},
|
|
{APB_CKGEN_SF_BASE, CKGEN_BCG_TYPE, 15},
|
|
{APB_CKGEN_SF_BASE, CKGEN_CCG_TYPE, 5},
|
|
{APB_CKGEN_AP_BASE, CKGEN_PCG_TYPE, 60},
|
|
{APB_CKGEN_AP_BASE, CKGEN_BCG_TYPE, 7},
|
|
};
|
|
|
|
static const mcu_power_e g_unused_power[] = {
|
|
MCU_POWER_GAMA,
|
|
MCU_POWER_END
|
|
};
|
|
|
|
static void mcu_unused_power_register_set(uint32_t index)
|
|
{
|
|
uint32_t addr, ram_addr;
|
|
|
|
addr = APB_SMC_BASE + SAF_LP_CTL_OFF(index);
|
|
ram_addr = APB_SMC_BASE + SAF_RAM_LP_CTL_OFF(index);
|
|
|
|
RMWREG32(ram_addr, 0, 3, 0x7u);
|
|
RMWREG32(ram_addr, 3, 9, 0x1FFu);
|
|
RMWREG32(addr, 0, 4, 0xFu);
|
|
RMWREG32(addr, 4, 1, 0x1u);
|
|
}
|
|
|
|
static void mcu_unused_power_config(const mcu_power_e *powers)
|
|
{
|
|
uint32_t i = 0;
|
|
|
|
while (powers[i] != MCU_POWER_END) {
|
|
switch (powers[i]) {
|
|
case MCU_POWER_SF:
|
|
mcu_unused_power_register_set(0);
|
|
break;
|
|
|
|
case MCU_POWER_SP:
|
|
mcu_unused_power_register_set(1);
|
|
break;
|
|
|
|
case MCU_POWER_SX:
|
|
mcu_unused_power_register_set(2);
|
|
break;
|
|
|
|
case MCU_POWER_GAMA:
|
|
mcu_unused_power_register_set(3);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
static void mcu_unused_iramc_config(const mcu_power_e *powers)
|
|
{
|
|
uint32_t i = 0;
|
|
|
|
while (powers[i] != MCU_POWER_END) {
|
|
switch (powers[i]) {
|
|
case MCU_POWER_IRAM1:
|
|
RMWREG32(APB_IRAMC1_BASE + 0x4, 0, 3, 0x4u);
|
|
break;
|
|
|
|
case MCU_POWER_IRAM2:
|
|
RMWREG32(APB_IRAMC2_BASE + 0x4, 0, 3, 0x4u);
|
|
break;
|
|
|
|
case MCU_POWER_IRAM3:
|
|
RMWREG32(APB_IRAMC3_BASE + 0x4, 0, 3, 0x4u);
|
|
break;
|
|
|
|
case MCU_POWER_IRAM4:
|
|
RMWREG32(APB_IRAMC4_BASE + 0x4, 0, 3, 0x4u);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
static int mcu_unused_ip_cglist_mask(const sdrv_ckgen_node_t *ckgen_ip[], bool mask)
|
|
{
|
|
sdrv_ckgen_node_t *node;
|
|
uint32_t i = 0;
|
|
int ret = 0;
|
|
|
|
while (ckgen_ip[i] && !ret) {
|
|
node = (sdrv_ckgen_node_t *)ckgen_ip[i];
|
|
ret = sdrv_ckgen_cg_mask(node, mask);
|
|
i++;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int mcu_unused_ip_config(void)
|
|
{
|
|
uint32_t i = 0;
|
|
int ret = 0;
|
|
|
|
mcu_unused_iramc_config(g_unused_power);
|
|
|
|
while (g_ckgen_unused[i]) {
|
|
ret = sdrv_ckgen_ip_clock_enable(g_ckgen_unused[i], CKGEN_HIB_MODE, false);
|
|
ret = sdrv_ckgen_ip_clock_enable(g_ckgen_unused[i], CKGEN_SLP_MODE, false);
|
|
ret = sdrv_ckgen_ip_clock_enable(g_ckgen_unused[i], CKGEN_RUN_MODE, false);
|
|
ret = mcu_unused_ip_cglist_mask(g_ckgen_unused[i], true);
|
|
i++;
|
|
}
|
|
|
|
mcu_unused_power_config(g_unused_power);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void sdrv_port_pre_init(void)
|
|
{
|
|
volatile uint32_t val;
|
|
|
|
for (uint32_t i = 0; i < 5; i++) {
|
|
val = readl(APB_DISP_MUX_BASE + 0x1010 + 0x4 * i);
|
|
val &= ~(0x1U << 1);
|
|
val &= ~(0x3U << 6);
|
|
writel(val, APB_DISP_MUX_BASE + 0x1010 + 0x4 * i);
|
|
}
|
|
|
|
val = readl(APB_DISP_MUX_BASE + 0x1100);
|
|
val &= ~(0xFU << 1);
|
|
writel(val, APB_DISP_MUX_BASE + 0x1100);
|
|
}
|
|
|
|
static void sdrv_xcg_runmode_active(const sdrv_ckgen_xcg_set_t *infos, uint32_t size)
|
|
{
|
|
for (uint32_t i = 0; i < size; i++) {
|
|
sdrv_ckgen_xcg_type_set((sdrv_ckgen_xcg_set_t *)&infos[i], CKGEN_RUN_MODE, false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief initializes the device.
|
|
*
|
|
* This function initializes the device before call main function.
|
|
*/
|
|
void device_init(void)
|
|
{
|
|
if (get_core_id() == CORE_SF) {
|
|
if (IS_P0)
|
|
/* initializes LDO module. */
|
|
writel(0x0, APB_LDO_DIG_BASE + 0x10);
|
|
|
|
/* Set rtc_lbist bypass when do offline-bist */
|
|
RMWREG32(APB_PMU_CORE_BASE + 0x70U, 2, 1, 1);
|
|
RMWREG32(APB_PMU_CORE_BASE + 0x70U, 3, 1, 1);
|
|
|
|
sdrv_port_pre_init();
|
|
|
|
sdrv_xcg_runmode_active(g_xcg_info, ARRAY_SIZE(g_xcg_info));
|
|
|
|
mcu_unused_ip_config();
|
|
}
|
|
}
|