199 lines
4.3 KiB
C
199 lines
4.3 KiB
C
/*
|
|
* Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include "FreeRTOS.h"
|
|
#include <common.h>
|
|
#include "register.h"
|
|
#include "p_register.h"
|
|
#include "uart.h"
|
|
#include <task.h>
|
|
#include "soc.h"
|
|
#include "timer_source.h"
|
|
#include "clk.h"
|
|
#include "clk_util.h"
|
|
#include "vad_suspend.h"
|
|
#include "power_domain.h"
|
|
#include "mailbox-api.h"
|
|
#include "suspend.h"
|
|
#include "uart.h"
|
|
|
|
void set_time(uint32_t val)
|
|
{
|
|
#ifdef ARM_CPU
|
|
REG32(SYSCTRL_SEC_TIMERE) = 0x0;
|
|
#else
|
|
REG32(SYSCTRL_TIMERF) = val;
|
|
#endif
|
|
}
|
|
|
|
uint32_t get_time(void)
|
|
{
|
|
uint64_t timerE = 0;
|
|
|
|
#ifdef ARM_CPU
|
|
timerE = REG32(SYSCTRL_SEC_TIMERE);
|
|
#else
|
|
timerE = REG32(SYSCTRL_TIMERF);
|
|
#endif
|
|
return (timerE);
|
|
}
|
|
|
|
/*
|
|
* use_clk_src
|
|
* 0. osc_clk
|
|
* 1. sys_clk (rtc_pll) clk_div1
|
|
* 2. sys_clk (rtc_pll) clk_div2
|
|
* 3. rtc_clk
|
|
* Note:
|
|
* 1. If select sys_clk, tick clk of 1us/10us/100us/1ms/xtal3 are all same
|
|
* 2. If select rtc_clk, tick clk of 1us/10us/100us/1ms/xtal3 will actually
|
|
* be 1ms/10ms/100ms/1s/93.747us
|
|
*/
|
|
|
|
void alt_timebase(int use_clk_src)
|
|
{
|
|
uint32_t clk_div = 0;
|
|
|
|
if (use_clk_src == 0)
|
|
//select osc_clk
|
|
REG32(CLKCTRL_TIMEBASE_CTRL0) = 0x20018;
|
|
else if (use_clk_src == 1) {
|
|
//select sys_clk (rtc_pll) clk_div1
|
|
//if sys_clk is 11.171MHz
|
|
clk_div = 11;
|
|
REG32(CLKCTRL_TIMEBASE_CTRL0) = (clk_div << 19) | (0x2aa << 6);
|
|
} else if (use_clk_src == 2) {
|
|
//select sys_clk (rtc_pll) clk_div2 when sys_clk < 256MHz
|
|
//if sys_clk is 122.88MHz
|
|
clk_div = 123;
|
|
REG32(CLKCTRL_TIMEBASE_CTRL0) = (clk_div << 24) | (0x3ff << 6);
|
|
} else {
|
|
//select rtc clk
|
|
// 32k/32 = 1k
|
|
REG32(CLKCTRL_TIMEBASE_CTRL0) = 0x20020;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This is function for axi clk setting:
|
|
* Includes axi_clk(AKA cpu_axi_clk/ACLK), axi_matrix, axi_sram
|
|
*
|
|
*/
|
|
void set_axi_div_clk(int sel, int div)
|
|
{
|
|
uint32_t control;
|
|
uint32_t dyn_pre_mux;
|
|
uint32_t dyn_div;
|
|
|
|
// fclk_div4 = 500MHz
|
|
dyn_pre_mux = sel;
|
|
dyn_div = div; /* divide by 1 */
|
|
|
|
control = REG32(CLKCTRL_AXI_CLK_CTRL0);
|
|
if (control & (1 << 15)) { //default is preb, need use prea
|
|
control =
|
|
(control & ~(0x3fff)) | ((1 << 13) | (dyn_pre_mux << 10) | (dyn_div << 0));
|
|
REG32(CLKCTRL_AXI_CLK_CTRL0) = control;
|
|
control = control & ~(1 << 15);
|
|
REG32(CLKCTRL_AXI_CLK_CTRL0) = control;
|
|
udelay(25);
|
|
} else {
|
|
//preb
|
|
control = (control & ~((0x3fff) << 16)) |
|
|
((1 << 29) | (dyn_pre_mux << 26) | (dyn_div << 16));
|
|
REG32(CLKCTRL_AXI_CLK_CTRL0) = control;
|
|
control = control | (1 << 15);
|
|
REG32(CLKCTRL_AXI_CLK_CTRL0) = control;
|
|
udelay(25);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This is function for clk81 setting
|
|
*
|
|
*/
|
|
void set_sys_div_clk(int sel, int div)
|
|
{
|
|
uint32_t control;
|
|
uint32_t dyn_pre_mux;
|
|
uint32_t dyn_div;
|
|
|
|
printf("Set sys clock to 167Mhz\n");
|
|
|
|
// fclk_div4 = 500MHz
|
|
dyn_pre_mux = sel;
|
|
dyn_div = div; /* divide by 3 */
|
|
|
|
control = REG32(CLKCTRL_SYS_CLK_CTRL0);
|
|
|
|
if (control & (1 << 15)) { //default is preb, need use prea
|
|
control =
|
|
(control & ~(0x3fff)) | ((1 << 13) | (dyn_pre_mux << 10) | (dyn_div << 0));
|
|
REG32(CLKCTRL_SYS_CLK_CTRL0) = control;
|
|
control = control & ~(1 << 15);
|
|
REG32(CLKCTRL_SYS_CLK_CTRL0) = control;
|
|
udelay(25);
|
|
} else {
|
|
//preb
|
|
control = (control & ~((0x3fff) << 16)) |
|
|
((1 << 29) | (dyn_pre_mux << 26) | (dyn_div << 16));
|
|
REG32(CLKCTRL_SYS_CLK_CTRL0) = control;
|
|
control = control | (1 << 15);
|
|
REG32(CLKCTRL_SYS_CLK_CTRL0) = control;
|
|
udelay(25);
|
|
}
|
|
|
|
/* when bus switched from 24MHz to 166MHz,
|
|
* the clock tick used to generate OTP waveform
|
|
* needs 20us waiting time to switch to new clock tick
|
|
*/
|
|
udelay(25);
|
|
}
|
|
|
|
void disable_pll(int id)
|
|
{
|
|
switch (id) {
|
|
case PLL_SYS:
|
|
REG32(ANACTRL_SYSPLL_CTRL0) = (1 << 29);
|
|
break;
|
|
case PLL_GP0:
|
|
REG32(ANACTRL_GP0PLL_CTRL0) = (1 << 29);
|
|
break;
|
|
case PLL_GP1:
|
|
REG32(ANACTRL_GP1PLL_CTRL0) = (1 << 29);
|
|
break;
|
|
case PLL_FIX:
|
|
REG32(ANACTRL_FIXPLL_CTRL0) = (1 << 29);
|
|
break;
|
|
case PLL_HIFI:
|
|
REG32(ANACTRL_HIFIPLL_CTRL0) = (1 << 29);
|
|
break;
|
|
case PLL_RTC:
|
|
REG32(ANACTRL_RTCPLL_CTRL0) = (1 << 29);
|
|
break;
|
|
case PLL_DDR:
|
|
REG32(AM_DDR_PLL_CNTL0) = (1 << 29);
|
|
break;
|
|
default:
|
|
printf("Error: PLL is not in list\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
int oscin_ctrl_reg;
|
|
void vCLK_resume(uint32_t st_f)
|
|
{
|
|
(void)st_f;
|
|
// In a55 boot code
|
|
REG32(PWRCTRL_ACCESS_CTRL) = 0x0; // default access pwrctrl
|
|
}
|
|
|
|
void vCLK_suspend(uint32_t st_f)
|
|
{
|
|
(void)st_f;
|
|
printf("a5 enter vCLK_suspend\n");
|
|
}
|