Files
base/drivers/source/clk/sdrv_fs24m_hw_access.c
2025-11-07 09:57:14 +08:00

106 lines
2.7 KiB
C

/**
* @file sdrv_fs24m_hw_access.c
* @brief taishan fs24m hw access source file.
*
* @copyright Copyright (c) 2022 Semidrive Semiconductor.
* All rights reserved.
*/
#include <bits.h>
#include "sdrv_fs24m_hw_access.h"
#include "sdrv_ckgen_common.h"
#define FS24M_WAIT_TIME 500000u
void sdrv_fs24m_xtal_sel(uint32_t base, uint8_t src)
{
RMWREG32(base + FS24M_GLB_CTL, FS24M_GLB_CTL_XTAL_SRC_SEL, 1u, src);
}
void sdrv_fs24m_fs_sel(uint32_t base, uint8_t src)
{
RMWREG32(base + FS24M_GLB_CTL, FS24M_GLB_CTL_FS_SRC_SEL, 1u, src);
}
uint32_t sdrv_fs24m_fs_sel_get(uint32_t base)
{
if (BIT(readl(base + FS24M_GLB_CTL), FS24M_GLB_CTL_XTAL_ACTIVE)) {
return FS24M_FS_SEL_XTAL;
}
else {
return FS24M_FS_SEL_RC;
}
}
int sdrv_fs24m_wait_active(uint32_t base, uint8_t src, uint32_t count)
{
uint32_t reg = base + FS24M_GLB_CTL;
uint32_t offset;
if (src == FS24M_FS_SEL_RC) {
offset = FS24M_GLB_CTL_RC_ACTIVE;
}
else {
offset = FS24M_GLB_CTL_XTAL_ACTIVE;
}
return sdrv_ckgen_wait(reg, offset, 1u, count);
}
int sdrv_fs24m_wait_ready(uint32_t base, uint8_t src, uint32_t count)
{
uint32_t reg = base + FS24M_GLB_CTL;
uint32_t offset;
if (src == FS24M_FS_SEL_RC) {
offset = FS24M_GLB_CTL_RC_RDY;
}
else {
offset = FS24M_GLB_CTL_XTAL_RDY;
}
/* timeout value 1 second */
return sdrv_ckgen_wait_timeout(reg, offset, 1u, 1000000u);
}
void sdrv_fs24m_xtal_fs_enable(uint32_t base, bool enable)
{
RMWREG32(base + FS24M_GLB_CTL, FS24M_GLB_CTL_FS_XTAL_EN, 1u, enable);
}
void sdrv_fs24m_rc_fs_enable(uint32_t base, bool enable)
{
RMWREG32(base + FS24M_GLB_CTL, FS24M_GLB_CTL_FS_OSC_EN, 1u, enable);
}
void sdrv_fs24m_xtal_enable(uint32_t base, bool enable)
{
RMWREG32(base + FS24M_XTAL_CTRL, FS24M_XTAL_CTRL_XTAL_ENABLE, 1u, enable);
}
void sdrv_fs24m_xtal_test_enable(uint32_t base, bool enable)
{
RMWREG32(base + FS24M_XTAL_CTRL, FS24M_XTAL_CTRL_XTAL_TEST_ENABLE, 1u, enable);
}
uint32_t sdrv_fs24m_get_32k_frequency_counter(uint32_t base)
{
uint32_t addr = base + FS24M_RC32K_CHK_CTL;
bool ret;
RMWREG32(addr, FS24M_RC32K_CHK_CTL_MON_EN_LSB, 1, 0);
sdrv_ckgen_wait(addr, FS24M_RC32K_CHK_CTL_MON_EN_STA_LSB, 0, FS24M_WAIT_TIME);
RMWREG32(addr, FS24M_RC32K_CHK_CTL_MON_EN_LSB, 1, 1);
ret = sdrv_ckgen_wait(addr, FS24M_RC32K_CHK_CTL_MON_EN_STA_LSB, 1, FS24M_WAIT_TIME);
if (ret) {
return ((readl(addr) >> FS24M_RC32K_CHK_CTL_FREQ_CNT_STA_LSB)
& FS24M_RC32K_CHK_CTL_FREQ_CNT_STA_MASK);
}
else {
return 0;
}
}