/** * @file sdrv_fs24m_hw_access.c * @brief taishan fs24m hw access source file. * * @copyright Copyright (c) 2022 Semidrive Semiconductor. * All rights reserved. */ #include #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; } }