172 lines
4.8 KiB
C
172 lines
4.8 KiB
C
/*
|
|
* Kneron System driver
|
|
*
|
|
* Copyright (C) 2019 Kneron, Inc. All rights reserved.
|
|
*
|
|
*/
|
|
|
|
|
|
#include "kdrv_system.h"
|
|
#ifndef NON_OS
|
|
#include "cmsis_os2.h"
|
|
#endif
|
|
#include "kdrv_scu.h"
|
|
#include "kdrv_scu_ext.h"
|
|
#include "kdrv_power.h"
|
|
#include "kdrv_clock.h"
|
|
#include "kdrv_ddr.h"
|
|
|
|
uint32_t bootup_status;
|
|
uint32_t warm_boot;
|
|
uint32_t __sys_int_flag;
|
|
|
|
#define BOOTUP_STATUS_WARM (SCU_REG_BTUP_STS_SMR | SCU_REG_BTUP_STS_PMR2)
|
|
|
|
void kdrv_system_reset(int32_t subsystem)
|
|
{
|
|
switch (subsystem) {
|
|
case SUBSYS_NPU:
|
|
SCU_EXTREG_SWRST_SET_NPU_resetn(1);
|
|
break;
|
|
case SUBSYS_PD_NPU:
|
|
SCU_EXTREG_SWRST_SET_PD_NPU_resetn(1);
|
|
break;
|
|
case SUBSYS_LCDC:
|
|
SCU_EXTREG_SWRST_SET_LCDC_resetn(1);
|
|
break;
|
|
case SUBSYS_NCPU:
|
|
SCU_EXTREG_CM4_NCPU_CTRL_SET_wakeup(0);
|
|
SCU_EXTREG_CM4_NCPU_CTRL_SET_wakeup(1);
|
|
}
|
|
}
|
|
|
|
void system_isr(void)
|
|
{
|
|
outw(SCU_REG_INT_STS, 0xffffffff); //clear sleep wakeup interrupt
|
|
|
|
__sys_int_flag = 0x1;
|
|
}
|
|
|
|
static void reset_handler(void)
|
|
{
|
|
bootup_status = inw(SCU_REG_BTUP_STS);
|
|
outw(SCU_REG_BTUP_STS, 0xffffffff); // clear boot-up status
|
|
outw(SCU_REG_BTUP_CTRL, SCU_REG_BTUP_CTRL_RTC_BU_EN | // RTC wakeup allowed
|
|
SCU_REG_BTUP_CTRL_PWRBTN_EN | // send power button output signal
|
|
SCU_REG_BTUP_CTRL_GPO_1_OUT |
|
|
SCU_REG_BTUP_CTRL_GPO_OUT);
|
|
|
|
NVIC_ClearPendingIRQ((IRQn_Type)SYS_SYSTEM_IRQ);
|
|
NVIC_EnableIRQ((IRQn_Type)SYS_SYSTEM_IRQ);
|
|
|
|
outw(SCU_REG_INT_STS, 0xffffffff); // clear all interrupt status
|
|
outw(SCU_REG_INT_EN, 0xffffffff); // enable all interrupts during boot
|
|
|
|
//can't directly write to the PLL control pins, it needs to use the
|
|
//FCS or PLL_UPDATE command that contained he power-ode register
|
|
kdrv_clock_mgr_set_scuclkin(scuclkin_pll0div3, true);
|
|
kdrv_delay_us(2000);
|
|
|
|
kdrv_power_ops(POWER_OPS_FCS);
|
|
__WFI();
|
|
do{
|
|
}while((__sys_int_flag)!= 0x1);
|
|
|
|
// kdrv_clock_mgr_set_muxsel(CLOCK_MUXSEL_NCPU_TRACECLK_DEFAULT |
|
|
// CLOCK_MUXSEL_SCPU_TRACECLK_SRC_PLL0DIV3 |
|
|
// CLOCK_MUXSEL_CSIRX1_CLK_PLL5 |
|
|
// CLOCK_MUXSEL_NPU_CLK_PLL0 | /* CLOCK_MUXSEL_NPU_CLK_PLL4 | */
|
|
// CLOCK_MUXSEL_PLL4_FREF_PLL0DIV |
|
|
// CLOCK_MUXSEL_UART_0_IRDA_UCLK_UART);
|
|
kdrv_delay_us(1000);
|
|
}
|
|
|
|
void kdrv_system_init(void)
|
|
{
|
|
NVIC_SetVector((IRQn_Type)SYS_SYSTEM_IRQ, (uint32_t)system_isr);
|
|
|
|
reset_handler();
|
|
|
|
if ((bootup_status & BOOTUP_STATUS_WARM) == BOOTUP_STATUS_WARM)
|
|
warm_boot = 1;
|
|
else
|
|
warm_boot = 0;
|
|
|
|
kdrv_clock_mgr_init();
|
|
|
|
/* Default power domain is already on */
|
|
{
|
|
//kdrv_clock_mgr_open_pll4(); // npu
|
|
kdrv_delay_us(10 * 10);
|
|
kdrv_clock_enable(CLK_PLL4_FREF_PLL0);
|
|
kdrv_delay_us(30 * 10);
|
|
kdrv_clock_enable(CLK_PLL4);
|
|
kdrv_delay_us(30 * 10);
|
|
kdrv_clock_enable(CLK_PLL4_OUT);
|
|
}
|
|
|
|
/* Turn on NPU power domain */
|
|
kdrv_power_set_domain(POWER_DOMAIN_NPU, 1);
|
|
if (warm_boot) {
|
|
/* TODO: reload ncpu fw to NiRAM */
|
|
}
|
|
|
|
{
|
|
/* Turn on DDR power domain for cold boot */
|
|
kdrv_power_set_domain(POWER_DOMAIN_DDRCK, 1);
|
|
|
|
kdrv_clock_enable(CLK_PLL1);
|
|
kdrv_delay_us(10 * 10);
|
|
kdrv_clock_enable(CLK_PLL1_OUT);
|
|
kdrv_delay_us(30 * 10);
|
|
|
|
kdrv_clock_enable(CLK_PLL2);
|
|
kdrv_delay_us(10 * 10);
|
|
kdrv_clock_enable(CLK_PLL2_OUT);
|
|
}
|
|
|
|
{ // PLL5
|
|
kdrv_clock_mgr_change_pll5_clock(1, 0x63, 2);
|
|
|
|
// Set I2C PCLKs disabled by default
|
|
uint32_t mask = SCU_REG_APBCLKG_PCLK_EN_I2C0_PCLK |
|
|
SCU_REG_APBCLKG_PCLK_EN_I2C1_PCLK |
|
|
SCU_REG_APBCLKG_PCLK_EN_I2C2_PCLK |
|
|
SCU_REG_APBCLKG_PCLK_EN_I2C3_PCLK;
|
|
masked_outw(SCU_REG_APBCLKG, 0, mask);
|
|
}
|
|
|
|
//fcs
|
|
{
|
|
kdrv_delay_us(10 * 10);
|
|
kdrv_clock_enable(CLK_PLL4_FREF_PLL0);
|
|
kdrv_delay_us(30 * 10);
|
|
kdrv_clock_enable(CLK_PLL4);
|
|
kdrv_delay_us(30 * 10);
|
|
kdrv_clock_enable(CLK_PLL4_OUT);
|
|
|
|
NVIC_ClearPendingIRQ((IRQn_Type)SYS_SYSTEM_IRQ);
|
|
NVIC_EnableIRQ((IRQn_Type)SYS_SYSTEM_IRQ);
|
|
|
|
outw(SCU_REG_INT_STS, 0xffffffff); // clear all interrupt status
|
|
|
|
kdrv_clock_enable(CLK_FCS_PLL2);
|
|
kdrv_clock_enable(CLK_FCS_DLL);
|
|
kdrv_clock_mgr_set_scuclkin(scuclkin_pll0div3, false);
|
|
kdrv_power_ops(POWER_OPS_FCS);
|
|
|
|
__WFI();
|
|
do {
|
|
} while((__sys_int_flag)!= 0x1);
|
|
}
|
|
}
|
|
|
|
void kdrv_system_init_ncpu(void)
|
|
{
|
|
kdrv_clock_enable(CLK_SCPU_TRACE);
|
|
kdrv_clock_enable(CLK_NCPU);
|
|
kdrv_clock_enable(CLK_NPU);
|
|
kdrv_system_reset(SUBSYS_PD_NPU);
|
|
kdrv_system_reset(SUBSYS_NPU);
|
|
}
|