1 /*
2 * Copyright 2024 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT nxp_s32k3_pmc
8
9 #include <zephyr/kernel.h>
10 #include <zephyr/init.h>
11
12 /* Low Voltage Status and Control Register */
13 #define PMC_LVSC 0x0
14 #define PMC_LVSC_HVDAF_MASK BIT(0)
15 #define PMC_LVSC_HVDAF(v) FIELD_PREP(PMC_LVSC_HVDAF_MASK, (v))
16 #define PMC_LVSC_HVDBF_MASK BIT(1)
17 #define PMC_LVSC_HVDBF(v) FIELD_PREP(PMC_LVSC_HVDBF_MASK, (v))
18 #define PMC_LVSC_HVD25F_MASK BIT(2)
19 #define PMC_LVSC_HVD25F(v) FIELD_PREP(PMC_LVSC_HVD25F_MASK, (v))
20 #define PMC_LVSC_HVD11F_MASK BIT(3)
21 #define PMC_LVSC_HVD11F(v) FIELD_PREP(PMC_LVSC_HVD11F_MASK, (v))
22 #define PMC_LVSC_LVD5AF_MASK BIT(4)
23 #define PMC_LVSC_LVD5AF(v) FIELD_PREP(PMC_LVSC_LVD5AF_MASK, (v))
24 #define PMC_LVSC_LVD15F_MASK BIT(5)
25 #define PMC_LVSC_LVD15F(v) FIELD_PREP(PMC_LVSC_LVD15F_MASK, (v))
26 #define PMC_LVSC_HVDAS_MASK BIT(8)
27 #define PMC_LVSC_HVDAS(v) FIELD_PREP(PMC_LVSC_HVDAS_MASK, (v))
28 #define PMC_LVSC_HVDBS_MASK BIT(9)
29 #define PMC_LVSC_HVDBS(v) FIELD_PREP(PMC_LVSC_HVDBS_MASK, (v))
30 #define PMC_LVSC_HVD25S_MASK BIT(10)
31 #define PMC_LVSC_HVD25S(v) FIELD_PREP(PMC_LVSC_HVD25S_MASK, (v))
32 #define PMC_LVSC_HVD11S_MASK BIT(11)
33 #define PMC_LVSC_HVD11S(v) FIELD_PREP(PMC_LVSC_HVD11S_MASK, (v))
34 #define PMC_LVSC_LVD5AS_MASK BIT(12)
35 #define PMC_LVSC_LVD5AS(v) FIELD_PREP(PMC_LVSC_LVD5AS_MASK, (v))
36 #define PMC_LVSC_LVD15S_MASK BIT(13)
37 #define PMC_LVSC_LVD15S(v) FIELD_PREP(PMC_LVSC_LVD15S_MASK, (v))
38 #define PMC_LVSC_LVRAF_MASK BIT(16)
39 #define PMC_LVSC_LVRAF(v) FIELD_PREP(PMC_LVSC_LVRAF_MASK, (v))
40 #define PMC_LVSC_LVRALPF_MASK BIT(17)
41 #define PMC_LVSC_LVRALPF(v) FIELD_PREP(PMC_LVSC_LVRALPF_MASK, (v))
42 #define PMC_LVSC_LVRBF_MASK BIT(18)
43 #define PMC_LVSC_LVRBF(v) FIELD_PREP(PMC_LVSC_LVRBF_MASK, (v))
44 #define PMC_LVSC_LVRBLPF_MASK BIT(19)
45 #define PMC_LVSC_LVRBLPF(v) FIELD_PREP(PMC_LVSC_LVRBLPF_MASK, (v))
46 #define PMC_LVSC_LVR25F_MASK BIT(20)
47 #define PMC_LVSC_LVR25F(v) FIELD_PREP(PMC_LVSC_LVR25F_MASK, (v))
48 #define PMC_LVSC_LVR25LPF_MASK BIT(21)
49 #define PMC_LVSC_LVR25LPF(v) FIELD_PREP(PMC_LVSC_LVR25LPF_MASK, (v))
50 #define PMC_LVSC_LVR11F_MASK BIT(22)
51 #define PMC_LVSC_LVR11F(v) FIELD_PREP(PMC_LVSC_LVR11F_MASK, (v))
52 #define PMC_LVSC_LVR11LPF_MASK BIT(23)
53 #define PMC_LVSC_LVR11LPF(v) FIELD_PREP(PMC_LVSC_LVR11LPF_MASK, (v))
54 #define PMC_LVSC_GNG25OSCF_MASK BIT(24)
55 #define PMC_LVSC_GNG25OSCF(v) FIELD_PREP(PMC_LVSC_GNG25OSCF_MASK, (v))
56 #define PMC_LVSC_GNG11OSCF_MASK BIT(25)
57 #define PMC_LVSC_GNG11OSCF(v) FIELD_PREP(PMC_LVSC_GNG11OSCF_MASK, (v))
58 #define PMC_LVSC_PORF_MASK BIT(31)
59 #define PMC_LVSC_PORF(v) FIELD_PREP(PMC_LVSC_PORF_MASK, (v))
60 /* PMC Configuration Register */
61 #define PMC_CONFIG 0x4
62 #define PMC_CONFIG_LMEN_MASK BIT(0)
63 #define PMC_CONFIG_LMEN(v) FIELD_PREP(PMC_CONFIG_LMEN_MASK, (v))
64 #define PMC_CONFIG_LMBCTLEN_MASK BIT(1)
65 #define PMC_CONFIG_LMBCTLEN(v) FIELD_PREP(PMC_CONFIG_LMBCTLEN_MASK, (v))
66 #define PMC_CONFIG_FASTREC_MASK BIT(2)
67 #define PMC_CONFIG_FASTREC(v) FIELD_PREP(PMC_CONFIG_FASTREC_MASK, (v))
68 #define PMC_CONFIG_LPM25EN_MASK BIT(3)
69 #define PMC_CONFIG_LPM25EN(v) FIELD_PREP(PMC_CONFIG_LPM25EN_MASK, (v))
70 #define PMC_CONFIG_LVRBLPEN_MASK BIT(4)
71 #define PMC_CONFIG_LVRBLPEN(v) FIELD_PREP(PMC_CONFIG_LVRBLPEN_MASK, (v))
72 #define PMC_CONFIG_HVDIE_MASK BIT(8)
73 #define PMC_CONFIG_HVDIE(v) FIELD_PREP(PMC_CONFIG_HVDIE_MASK, (v))
74 #define PMC_CONFIG_LVDIE_MASK BIT(9)
75 #define PMC_CONFIG_LVDIE(v) FIELD_PREP(PMC_CONFIG_LVDIE_MASK, (v))
76 #define PMC_CONFIG_LMAUTOEN_MASK BIT(16)
77 #define PMC_CONFIG_LMAUTOEN(v) FIELD_PREP(PMC_CONFIG_LMAUTOEN_MASK, (v))
78 #define PMC_CONFIG_LMSTAT_MASK BIT(17)
79 #define PMC_CONFIG_LMSTAT(v) FIELD_PREP(PMC_CONFIG_LMSTAT_MASK, (v))
80 /* Version ID register */
81 #define PMC_VERID 0xc
82 #define PMC_VERID_LMFEAT_MASK BIT(0)
83 #define PMC_VERID_LMFEAT(v) FIELD_PREP(PMC_VERID_LMFEAT_MASK, (v))
84 #define PMC_VERID_MINOR_MASK GENMASK(23, 16)
85 #define PMC_VERID_MINOR(v) FIELD_PREP(PMC_VERID_MINOR_MASK, (v))
86 #define PMC_VERID_MAJOR_MASK GENMASK(31, 24)
87 #define PMC_VERID_MAJOR(v) FIELD_PREP(PMC_VERID_MAJOR_MASK, (v))
88
89 /* Handy accessors */
90 #define REG_READ(r) sys_read32((mem_addr_t)(DT_INST_REG_ADDR(0) + (r)))
91 #define REG_WRITE(r, v) sys_write32((v), (mem_addr_t)(DT_INST_REG_ADDR(0) + (r)))
92
93 #define PMC_TIMEOUT_US 10000U
94
pmc_init(const struct device * dev)95 static int pmc_init(const struct device *dev)
96 {
97 uint32_t reg_val;
98
99 ARG_UNUSED(dev);
100
101 /* Clear Low Voltage Status flags after initial power ramp-up */
102 REG_WRITE(PMC_LVSC, 0xffffffffU);
103
104 /* Last Mile regulator initialization */
105 reg_val = PMC_CONFIG_LMEN(DT_INST_PROP(0, lm_reg)) |
106 PMC_CONFIG_LMAUTOEN(DT_INST_PROP(0, lm_reg_auto)) |
107 PMC_CONFIG_LMBCTLEN(DT_INST_PROP(0, lm_reg_base_control));
108
109 if (DT_INST_PROP(0, lm_reg)) {
110 REG_WRITE(PMC_CONFIG, reg_val & ~PMC_CONFIG_LMEN_MASK);
111 /*
112 * If external BJT is using on the PCB board, wait for the LVD15 to go above
113 * low-voltage detect threshold before enabling LMEN
114 */
115 if (DT_INST_PROP(0, lm_reg_base_control)) {
116 if (!WAIT_FOR(FIELD_GET(PMC_LVSC_LVD15S_MASK, REG_READ(PMC_LVSC)) == 0U,
117 PMC_TIMEOUT_US, k_busy_wait(10U))) {
118 return -ETIMEDOUT;
119 }
120 }
121 REG_WRITE(PMC_CONFIG, REG_READ(PMC_CONFIG) | PMC_CONFIG_LMEN(1U));
122 } else {
123 REG_WRITE(PMC_CONFIG, reg_val);
124 if (DT_INST_PROP(0, lm_reg_auto)) {
125 /* Wait for Last Mile regulator to be turned on */
126 if (!WAIT_FOR(FIELD_GET(PMC_CONFIG_LMSTAT_MASK, REG_READ(PMC_CONFIG)) == 1U,
127 PMC_TIMEOUT_US, k_busy_wait(10U))) {
128 return -ETIMEDOUT;
129 }
130 }
131 }
132
133 return 0;
134 }
135
136 DEVICE_DT_INST_DEFINE(0, pmc_init, NULL, NULL, 0, PRE_KERNEL_1, 1, NULL);
137