Files
2026-08-24 10:03:24 +08:00

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");
}