blob: 28933d97e74f082455f8c9a7015cceb9b36ec311 [file] [log] [blame]
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT nxp_s32k3_pmc
#include <zephyr/kernel.h>
#include <zephyr/init.h>
/* Low Voltage Status and Control Register */
#define PMC_LVSC 0x0
#define PMC_LVSC_HVDAF_MASK BIT(0)
#define PMC_LVSC_HVDAF(v) FIELD_PREP(PMC_LVSC_HVDAF_MASK, (v))
#define PMC_LVSC_HVDBF_MASK BIT(1)
#define PMC_LVSC_HVDBF(v) FIELD_PREP(PMC_LVSC_HVDBF_MASK, (v))
#define PMC_LVSC_HVD25F_MASK BIT(2)
#define PMC_LVSC_HVD25F(v) FIELD_PREP(PMC_LVSC_HVD25F_MASK, (v))
#define PMC_LVSC_HVD11F_MASK BIT(3)
#define PMC_LVSC_HVD11F(v) FIELD_PREP(PMC_LVSC_HVD11F_MASK, (v))
#define PMC_LVSC_LVD5AF_MASK BIT(4)
#define PMC_LVSC_LVD5AF(v) FIELD_PREP(PMC_LVSC_LVD5AF_MASK, (v))
#define PMC_LVSC_LVD15F_MASK BIT(5)
#define PMC_LVSC_LVD15F(v) FIELD_PREP(PMC_LVSC_LVD15F_MASK, (v))
#define PMC_LVSC_HVDAS_MASK BIT(8)
#define PMC_LVSC_HVDAS(v) FIELD_PREP(PMC_LVSC_HVDAS_MASK, (v))
#define PMC_LVSC_HVDBS_MASK BIT(9)
#define PMC_LVSC_HVDBS(v) FIELD_PREP(PMC_LVSC_HVDBS_MASK, (v))
#define PMC_LVSC_HVD25S_MASK BIT(10)
#define PMC_LVSC_HVD25S(v) FIELD_PREP(PMC_LVSC_HVD25S_MASK, (v))
#define PMC_LVSC_HVD11S_MASK BIT(11)
#define PMC_LVSC_HVD11S(v) FIELD_PREP(PMC_LVSC_HVD11S_MASK, (v))
#define PMC_LVSC_LVD5AS_MASK BIT(12)
#define PMC_LVSC_LVD5AS(v) FIELD_PREP(PMC_LVSC_LVD5AS_MASK, (v))
#define PMC_LVSC_LVD15S_MASK BIT(13)
#define PMC_LVSC_LVD15S(v) FIELD_PREP(PMC_LVSC_LVD15S_MASK, (v))
#define PMC_LVSC_LVRAF_MASK BIT(16)
#define PMC_LVSC_LVRAF(v) FIELD_PREP(PMC_LVSC_LVRAF_MASK, (v))
#define PMC_LVSC_LVRALPF_MASK BIT(17)
#define PMC_LVSC_LVRALPF(v) FIELD_PREP(PMC_LVSC_LVRALPF_MASK, (v))
#define PMC_LVSC_LVRBF_MASK BIT(18)
#define PMC_LVSC_LVRBF(v) FIELD_PREP(PMC_LVSC_LVRBF_MASK, (v))
#define PMC_LVSC_LVRBLPF_MASK BIT(19)
#define PMC_LVSC_LVRBLPF(v) FIELD_PREP(PMC_LVSC_LVRBLPF_MASK, (v))
#define PMC_LVSC_LVR25F_MASK BIT(20)
#define PMC_LVSC_LVR25F(v) FIELD_PREP(PMC_LVSC_LVR25F_MASK, (v))
#define PMC_LVSC_LVR25LPF_MASK BIT(21)
#define PMC_LVSC_LVR25LPF(v) FIELD_PREP(PMC_LVSC_LVR25LPF_MASK, (v))
#define PMC_LVSC_LVR11F_MASK BIT(22)
#define PMC_LVSC_LVR11F(v) FIELD_PREP(PMC_LVSC_LVR11F_MASK, (v))
#define PMC_LVSC_LVR11LPF_MASK BIT(23)
#define PMC_LVSC_LVR11LPF(v) FIELD_PREP(PMC_LVSC_LVR11LPF_MASK, (v))
#define PMC_LVSC_GNG25OSCF_MASK BIT(24)
#define PMC_LVSC_GNG25OSCF(v) FIELD_PREP(PMC_LVSC_GNG25OSCF_MASK, (v))
#define PMC_LVSC_GNG11OSCF_MASK BIT(25)
#define PMC_LVSC_GNG11OSCF(v) FIELD_PREP(PMC_LVSC_GNG11OSCF_MASK, (v))
#define PMC_LVSC_PORF_MASK BIT(31)
#define PMC_LVSC_PORF(v) FIELD_PREP(PMC_LVSC_PORF_MASK, (v))
/* PMC Configuration Register */
#define PMC_CONFIG 0x4
#define PMC_CONFIG_LMEN_MASK BIT(0)
#define PMC_CONFIG_LMEN(v) FIELD_PREP(PMC_CONFIG_LMEN_MASK, (v))
#define PMC_CONFIG_LMBCTLEN_MASK BIT(1)
#define PMC_CONFIG_LMBCTLEN(v) FIELD_PREP(PMC_CONFIG_LMBCTLEN_MASK, (v))
#define PMC_CONFIG_FASTREC_MASK BIT(2)
#define PMC_CONFIG_FASTREC(v) FIELD_PREP(PMC_CONFIG_FASTREC_MASK, (v))
#define PMC_CONFIG_LPM25EN_MASK BIT(3)
#define PMC_CONFIG_LPM25EN(v) FIELD_PREP(PMC_CONFIG_LPM25EN_MASK, (v))
#define PMC_CONFIG_LVRBLPEN_MASK BIT(4)
#define PMC_CONFIG_LVRBLPEN(v) FIELD_PREP(PMC_CONFIG_LVRBLPEN_MASK, (v))
#define PMC_CONFIG_HVDIE_MASK BIT(8)
#define PMC_CONFIG_HVDIE(v) FIELD_PREP(PMC_CONFIG_HVDIE_MASK, (v))
#define PMC_CONFIG_LVDIE_MASK BIT(9)
#define PMC_CONFIG_LVDIE(v) FIELD_PREP(PMC_CONFIG_LVDIE_MASK, (v))
#define PMC_CONFIG_LMAUTOEN_MASK BIT(16)
#define PMC_CONFIG_LMAUTOEN(v) FIELD_PREP(PMC_CONFIG_LMAUTOEN_MASK, (v))
#define PMC_CONFIG_LMSTAT_MASK BIT(17)
#define PMC_CONFIG_LMSTAT(v) FIELD_PREP(PMC_CONFIG_LMSTAT_MASK, (v))
/* Version ID register */
#define PMC_VERID 0xc
#define PMC_VERID_LMFEAT_MASK BIT(0)
#define PMC_VERID_LMFEAT(v) FIELD_PREP(PMC_VERID_LMFEAT_MASK, (v))
#define PMC_VERID_MINOR_MASK GENMASK(23, 16)
#define PMC_VERID_MINOR(v) FIELD_PREP(PMC_VERID_MINOR_MASK, (v))
#define PMC_VERID_MAJOR_MASK GENMASK(31, 24)
#define PMC_VERID_MAJOR(v) FIELD_PREP(PMC_VERID_MAJOR_MASK, (v))
/* Handy accessors */
#define REG_READ(r) sys_read32((mem_addr_t)(DT_INST_REG_ADDR(0) + (r)))
#define REG_WRITE(r, v) sys_write32((v), (mem_addr_t)(DT_INST_REG_ADDR(0) + (r)))
#define PMC_TIMEOUT_US 10000U
static int pmc_init(const struct device *dev)
{
uint32_t reg_val;
ARG_UNUSED(dev);
/* Clear Low Voltage Status flags after initial power ramp-up */
REG_WRITE(PMC_LVSC, 0xffffffffU);
/* Last Mile regulator initialization */
reg_val = PMC_CONFIG_LMEN(DT_INST_PROP(0, lm_reg)) |
PMC_CONFIG_LMAUTOEN(DT_INST_PROP(0, lm_reg_auto)) |
PMC_CONFIG_LMBCTLEN(DT_INST_PROP(0, lm_reg_base_control));
if (DT_INST_PROP(0, lm_reg)) {
REG_WRITE(PMC_CONFIG, reg_val & ~PMC_CONFIG_LMEN_MASK);
/*
* If external BJT is using on the PCB board, wait for the LVD15 to go above
* low-voltage detect threshold before enabling LMEN
*/
if (DT_INST_PROP(0, lm_reg_base_control)) {
if (!WAIT_FOR(FIELD_GET(PMC_LVSC_LVD15S_MASK, REG_READ(PMC_LVSC)) == 0U,
PMC_TIMEOUT_US, k_busy_wait(10U))) {
return -ETIMEDOUT;
}
}
REG_WRITE(PMC_CONFIG, REG_READ(PMC_CONFIG) | PMC_CONFIG_LMEN(1U));
} else {
REG_WRITE(PMC_CONFIG, reg_val);
if (DT_INST_PROP(0, lm_reg_auto)) {
/* Wait for Last Mile regulator to be turned on */
if (!WAIT_FOR(FIELD_GET(PMC_CONFIG_LMSTAT_MASK, REG_READ(PMC_CONFIG)) == 1U,
PMC_TIMEOUT_US, k_busy_wait(10U))) {
return -ETIMEDOUT;
}
}
}
return 0;
}
DEVICE_DT_INST_DEFINE(0, pmc_init, NULL, NULL, 0, PRE_KERNEL_1, 1, NULL);