1*e419bc7fSGatien Chevallier // SPDX-License-Identifier: BSD-2-Clause 2*e419bc7fSGatien Chevallier /* 3*e419bc7fSGatien Chevallier * Copyright (C) 2018-2024, STMicroelectronics 4*e419bc7fSGatien Chevallier */ 5*e419bc7fSGatien Chevallier #include <assert.h> 6*e419bc7fSGatien Chevallier #include <drivers/clk.h> 7*e419bc7fSGatien Chevallier #include <drivers/clk_dt.h> 8*e419bc7fSGatien Chevallier #include <drivers/rtc.h> 9*e419bc7fSGatien Chevallier #include <drivers/stm32_rif.h> 10*e419bc7fSGatien Chevallier #include <io.h> 11*e419bc7fSGatien Chevallier #include <kernel/dt.h> 12*e419bc7fSGatien Chevallier #include <kernel/dt_driver.h> 13*e419bc7fSGatien Chevallier #include <kernel/panic.h> 14*e419bc7fSGatien Chevallier #include <libfdt.h> 15*e419bc7fSGatien Chevallier #include <mm/core_memprot.h> 16*e419bc7fSGatien Chevallier 17*e419bc7fSGatien Chevallier /* 18*e419bc7fSGatien Chevallier * Registers 19*e419bc7fSGatien Chevallier */ 20*e419bc7fSGatien Chevallier #define RTC_TR U(0x00) 21*e419bc7fSGatien Chevallier #define RTC_DR U(0x04) 22*e419bc7fSGatien Chevallier #define RTC_SSR U(0x08) 23*e419bc7fSGatien Chevallier #define RTC_ICSR U(0x0C) 24*e419bc7fSGatien Chevallier #define RTC_PRER U(0x10) 25*e419bc7fSGatien Chevallier #define RTC_WUTR U(0x14) 26*e419bc7fSGatien Chevallier #define RTC_CR U(0x18) 27*e419bc7fSGatien Chevallier #define RTC_PRIVCFGR U(0x1C) 28*e419bc7fSGatien Chevallier /* RTC_SMCR is linked to RTC3v1_2 */ 29*e419bc7fSGatien Chevallier #define RTC_SMCR U(0x20) 30*e419bc7fSGatien Chevallier /* RTC_SECCFGR is linked to RTC3v3_2 and above */ 31*e419bc7fSGatien Chevallier #define RTC_SECCFGR U(0x20) 32*e419bc7fSGatien Chevallier #define RTC_WPR U(0x24) 33*e419bc7fSGatien Chevallier #define RTC_CALR U(0x28) 34*e419bc7fSGatien Chevallier #define RTC_SHIFTR U(0x2C) 35*e419bc7fSGatien Chevallier #define RTC_TSTR U(0x30) 36*e419bc7fSGatien Chevallier #define RTC_TSDR U(0x34) 37*e419bc7fSGatien Chevallier #define RTC_TSSSR U(0x38) 38*e419bc7fSGatien Chevallier #define RTC_ALRMAR U(0x40) 39*e419bc7fSGatien Chevallier #define RTC_ALRMASSR U(0x44) 40*e419bc7fSGatien Chevallier #define RTC_ALRMBR U(0x48) 41*e419bc7fSGatien Chevallier #define RTC_ALRMBSSR U(0x4C) 42*e419bc7fSGatien Chevallier #define RTC_SR U(0x50) 43*e419bc7fSGatien Chevallier #define RTC_SCR U(0x5C) 44*e419bc7fSGatien Chevallier #define RTC_OR U(0x60) 45*e419bc7fSGatien Chevallier #define RTC_CIDCFGR(x) (U(0x80) + U(0x4) * (x)) 46*e419bc7fSGatien Chevallier 47*e419bc7fSGatien Chevallier #define RTC_TR_SU_MASK GENMASK_32(3, 0) 48*e419bc7fSGatien Chevallier #define RTC_TR_ST_MASK GENMASK_32(6, 4) 49*e419bc7fSGatien Chevallier #define RTC_TR_ST_SHIFT U(4) 50*e419bc7fSGatien Chevallier #define RTC_TR_MNU_MASK GENMASK_32(11, 8) 51*e419bc7fSGatien Chevallier #define RTC_TR_MNU_SHIFT U(8) 52*e419bc7fSGatien Chevallier #define RTC_TR_MNT_MASK GENMASK_32(14, 12) 53*e419bc7fSGatien Chevallier #define RTC_TR_MNT_SHIFT U(12) 54*e419bc7fSGatien Chevallier #define RTC_TR_HU_MASK GENMASK_32(19, 16) 55*e419bc7fSGatien Chevallier #define RTC_TR_HU_SHIFT U(16) 56*e419bc7fSGatien Chevallier #define RTC_TR_HT_MASK GENMASK_32(21, 20) 57*e419bc7fSGatien Chevallier #define RTC_TR_HT_SHIFT U(20) 58*e419bc7fSGatien Chevallier #define RTC_TR_PM BIT(22) 59*e419bc7fSGatien Chevallier 60*e419bc7fSGatien Chevallier #define RTC_DR_DU_MASK GENMASK_32(3, 0) 61*e419bc7fSGatien Chevallier #define RTC_DR_DT_MASK GENMASK_32(5, 4) 62*e419bc7fSGatien Chevallier #define RTC_DR_DT_SHIFT U(4) 63*e419bc7fSGatien Chevallier #define RTC_DR_MU_MASK GENMASK_32(11, 8) 64*e419bc7fSGatien Chevallier #define RTC_DR_MU_SHIFT U(8) 65*e419bc7fSGatien Chevallier #define RTC_DR_MT_MASK BIT(12) 66*e419bc7fSGatien Chevallier #define RTC_DR_MT_SHIFT U(12) 67*e419bc7fSGatien Chevallier #define RTC_DR_WDU_MASK GENMASK_32(15, 13) 68*e419bc7fSGatien Chevallier #define RTC_DR_WDU_SHIFT U(13) 69*e419bc7fSGatien Chevallier #define RTC_DR_YU_MASK GENMASK_32(19, 16) 70*e419bc7fSGatien Chevallier #define RTC_DR_YU_SHIFT U(16) 71*e419bc7fSGatien Chevallier #define RTC_DR_YT_MASK GENMASK_32(23, 20) 72*e419bc7fSGatien Chevallier #define RTC_DR_YT_SHIFT U(20) 73*e419bc7fSGatien Chevallier 74*e419bc7fSGatien Chevallier #define RTC_SSR_SS_MASK GENMASK_32(15, 0) 75*e419bc7fSGatien Chevallier 76*e419bc7fSGatien Chevallier #define RTC_ICSR_RSF BIT(5) 77*e419bc7fSGatien Chevallier #define RTC_ICSR_INITF BIT(6) 78*e419bc7fSGatien Chevallier #define RTC_ICSR_INIT BIT(7) 79*e419bc7fSGatien Chevallier 80*e419bc7fSGatien Chevallier #define RTC_PRER_PREDIV_S_MASK GENMASK_32(14, 0) 81*e419bc7fSGatien Chevallier 82*e419bc7fSGatien Chevallier #define RTC_CR_BYPSHAD BIT(5) 83*e419bc7fSGatien Chevallier #define RTC_CR_BYPSHAD_SHIFT U(5) 84*e419bc7fSGatien Chevallier #define RTC_CR_TAMPTS BIT(25) 85*e419bc7fSGatien Chevallier 86*e419bc7fSGatien Chevallier #define RTC_PRIVCFGR_VALUES GENMASK_32(3, 0) 87*e419bc7fSGatien Chevallier #define RTC_PRIVCFGR_VALUES_TO_SHIFT GENMASK_32(5, 4) 88*e419bc7fSGatien Chevallier #define RTC_PRIVCFGR_SHIFT U(9) 89*e419bc7fSGatien Chevallier #define RTC_PRIVCFGR_MASK (GENMASK_32(14, 13) | GENMASK_32(3, 0)) 90*e419bc7fSGatien Chevallier #define RTC_PRIVCFGR_FULL_PRIV BIT(15) 91*e419bc7fSGatien Chevallier 92*e419bc7fSGatien Chevallier #define RTC_SMCR_TS_DPROT BIT(3) 93*e419bc7fSGatien Chevallier 94*e419bc7fSGatien Chevallier #define RTC_SECCFGR_VALUES GENMASK_32(3, 0) 95*e419bc7fSGatien Chevallier #define RTC_SECCFGR_TS_SEC BIT(3) 96*e419bc7fSGatien Chevallier #define RTC_SECCFGR_VALUES_TO_SHIFT GENMASK_32(5, 4) 97*e419bc7fSGatien Chevallier #define RTC_SECCFGR_SHIFT U(9) 98*e419bc7fSGatien Chevallier #define RTC_SECCFGR_MASK (GENMASK_32(14, 13) | GENMASK_32(3, 0)) 99*e419bc7fSGatien Chevallier #define RTC_SECCFGR_FULL_SEC BIT(15) 100*e419bc7fSGatien Chevallier 101*e419bc7fSGatien Chevallier #define RTC_WPR_KEY1 U(0xCA) 102*e419bc7fSGatien Chevallier #define RTC_WPR_KEY2 U(0x53) 103*e419bc7fSGatien Chevallier #define RTC_WPR_KEY_LOCK U(0xFF) 104*e419bc7fSGatien Chevallier 105*e419bc7fSGatien Chevallier #define RTC_TSDR_MU_MASK GENMASK_32(11, 8) 106*e419bc7fSGatien Chevallier #define RTC_TSDR_MU_SHIFT U(8) 107*e419bc7fSGatien Chevallier #define RTC_TSDR_DT_MASK GENMASK_32(5, 4) 108*e419bc7fSGatien Chevallier #define RTC_TSDR_DT_SHIFT U(4) 109*e419bc7fSGatien Chevallier #define RTC_TSDR_DU_MASK GENMASK_32(3, 0) 110*e419bc7fSGatien Chevallier #define RTC_TSDR_DU_SHIFT U(0) 111*e419bc7fSGatien Chevallier 112*e419bc7fSGatien Chevallier #define RTC_SR_TSF BIT(3) 113*e419bc7fSGatien Chevallier #define RTC_SR_TSOVF BIT(4) 114*e419bc7fSGatien Chevallier 115*e419bc7fSGatien Chevallier #define RTC_SCR_CTSF BIT(3) 116*e419bc7fSGatien Chevallier #define RTC_SCR_CTSOVF BIT(4) 117*e419bc7fSGatien Chevallier 118*e419bc7fSGatien Chevallier #define RTC_CIDCFGR_SCID_MASK GENMASK_32(6, 4) 119*e419bc7fSGatien Chevallier #define RTC_CIDCFGR_SCID_MASK_SHIFT U(4) 120*e419bc7fSGatien Chevallier #define RTC_CIDCFGR_CONF_MASK (_CIDCFGR_CFEN | \ 121*e419bc7fSGatien Chevallier RTC_CIDCFGR_SCID_MASK) 122*e419bc7fSGatien Chevallier 123*e419bc7fSGatien Chevallier /* 124*e419bc7fSGatien Chevallier * RIF miscellaneous 125*e419bc7fSGatien Chevallier */ 126*e419bc7fSGatien Chevallier #define RTC_NB_RIF_RESOURCES U(6) 127*e419bc7fSGatien Chevallier 128*e419bc7fSGatien Chevallier #define RTC_RIF_FULL_PRIVILEGED U(0x3F) 129*e419bc7fSGatien Chevallier #define RTC_RIF_FULL_SECURED U(0x3F) 130*e419bc7fSGatien Chevallier 131*e419bc7fSGatien Chevallier #define RTC_NB_MAX_CID_SUPPORTED U(7) 132*e419bc7fSGatien Chevallier 133*e419bc7fSGatien Chevallier /* 134*e419bc7fSGatien Chevallier * Driver miscellaneous 135*e419bc7fSGatien Chevallier */ 136*e419bc7fSGatien Chevallier #define RTC_RES_TIMESTAMP U(3) 137*e419bc7fSGatien Chevallier #define RTC_RES_CALIBRATION U(4) 138*e419bc7fSGatien Chevallier #define RTC_RES_INITIALIZATION U(5) 139*e419bc7fSGatien Chevallier 140*e419bc7fSGatien Chevallier #define RTC_FLAGS_READ_TWICE BIT(0) 141*e419bc7fSGatien Chevallier 142*e419bc7fSGatien Chevallier #define TIMEOUT_US_RTC_SHADOW U(10000) 143*e419bc7fSGatien Chevallier #define TIMEOUT_US_RTC_GENERIC U(100000) 144*e419bc7fSGatien Chevallier 145*e419bc7fSGatien Chevallier #define YEAR_REF ULL(2000) 146*e419bc7fSGatien Chevallier #define YEAR_MAX (YEAR_REF + ULL(99)) 147*e419bc7fSGatien Chevallier 148*e419bc7fSGatien Chevallier struct rtc_compat { 149*e419bc7fSGatien Chevallier bool has_seccfgr; 150*e419bc7fSGatien Chevallier bool has_rif_support; 151*e419bc7fSGatien Chevallier }; 152*e419bc7fSGatien Chevallier 153*e419bc7fSGatien Chevallier /* 154*e419bc7fSGatien Chevallier * struct rtc_device - RTC device data 155*e419bc7fSGatien Chevallier * @base: RTC IOMEM base address 156*e419bc7fSGatien Chevallier * @compat: RTC compatible data 157*e419bc7fSGatien Chevallier * @pclk: RTC bus clock 158*e419bc7fSGatien Chevallier * @rtc_ck: RTC kernel clock 159*e419bc7fSGatien Chevallier * @conf_data: RTC RIF configuration data, when supported 160*e419bc7fSGatien Chevallier * @nb_res: Number of protectible RTC resources 161*e419bc7fSGatien Chevallier * @flags: RTC driver flags 162*e419bc7fSGatien Chevallier * @is_secured: True if the RTC is fully secured 163*e419bc7fSGatien Chevallier */ 164*e419bc7fSGatien Chevallier struct rtc_device { 165*e419bc7fSGatien Chevallier struct io_pa_va base; 166*e419bc7fSGatien Chevallier const struct rtc_compat *compat; 167*e419bc7fSGatien Chevallier struct clk *pclk; 168*e419bc7fSGatien Chevallier struct clk *rtc_ck; 169*e419bc7fSGatien Chevallier struct rif_conf_data *conf_data; 170*e419bc7fSGatien Chevallier unsigned int nb_res; 171*e419bc7fSGatien Chevallier uint8_t flags; 172*e419bc7fSGatien Chevallier bool is_secured; 173*e419bc7fSGatien Chevallier }; 174*e419bc7fSGatien Chevallier 175*e419bc7fSGatien Chevallier /* Expect a single RTC instance */ 176*e419bc7fSGatien Chevallier static struct rtc_device rtc_dev; 177*e419bc7fSGatien Chevallier 178*e419bc7fSGatien Chevallier static vaddr_t get_base(void) 179*e419bc7fSGatien Chevallier { 180*e419bc7fSGatien Chevallier assert(rtc_dev.base.pa); 181*e419bc7fSGatien Chevallier 182*e419bc7fSGatien Chevallier return io_pa_or_va(&rtc_dev.base, 1); 183*e419bc7fSGatien Chevallier } 184*e419bc7fSGatien Chevallier 185*e419bc7fSGatien Chevallier static void stm32_rtc_write_unprotect(void) 186*e419bc7fSGatien Chevallier { 187*e419bc7fSGatien Chevallier vaddr_t rtc_base = get_base(); 188*e419bc7fSGatien Chevallier 189*e419bc7fSGatien Chevallier io_write32(rtc_base + RTC_WPR, RTC_WPR_KEY1); 190*e419bc7fSGatien Chevallier io_write32(rtc_base + RTC_WPR, RTC_WPR_KEY2); 191*e419bc7fSGatien Chevallier } 192*e419bc7fSGatien Chevallier 193*e419bc7fSGatien Chevallier static void stm32_rtc_write_protect(void) 194*e419bc7fSGatien Chevallier { 195*e419bc7fSGatien Chevallier vaddr_t rtc_base = get_base(); 196*e419bc7fSGatien Chevallier 197*e419bc7fSGatien Chevallier io_write32(rtc_base + RTC_WPR, RTC_WPR_KEY_LOCK); 198*e419bc7fSGatien Chevallier } 199*e419bc7fSGatien Chevallier 200*e419bc7fSGatien Chevallier static bool stm32_rtc_get_bypshad(void) 201*e419bc7fSGatien Chevallier { 202*e419bc7fSGatien Chevallier return io_read32(get_base() + RTC_CR) & RTC_CR_BYPSHAD; 203*e419bc7fSGatien Chevallier } 204*e419bc7fSGatien Chevallier 205*e419bc7fSGatien Chevallier /* Get the subsecond value. */ 206*e419bc7fSGatien Chevallier static uint32_t stm32_rtc_get_subsecond(uint32_t ssr) 207*e419bc7fSGatien Chevallier { 208*e419bc7fSGatien Chevallier uint32_t prediv_s = io_read32(get_base() + RTC_PRER) & 209*e419bc7fSGatien Chevallier RTC_PRER_PREDIV_S_MASK; 210*e419bc7fSGatien Chevallier 211*e419bc7fSGatien Chevallier return prediv_s - ssr; 212*e419bc7fSGatien Chevallier } 213*e419bc7fSGatien Chevallier 214*e419bc7fSGatien Chevallier /* 215*e419bc7fSGatien Chevallier * Get the subsecond scale. 216*e419bc7fSGatien Chevallier * 217*e419bc7fSGatien Chevallier * Number of subseconds in a second is linked to RTC PREDIV_S value. 218*e419bc7fSGatien Chevallier * The higher PREDIV_S is, the more subsecond is precise. 219*e419bc7fSGatien Chevallier */ 220*e419bc7fSGatien Chevallier static uint32_t stm32_rtc_get_subsecond_scale(void) 221*e419bc7fSGatien Chevallier { 222*e419bc7fSGatien Chevallier return (io_read32(get_base() + RTC_PRER) & RTC_PRER_PREDIV_S_MASK) + 1; 223*e419bc7fSGatien Chevallier } 224*e419bc7fSGatien Chevallier 225*e419bc7fSGatien Chevallier static bool cid1_has_access(unsigned int resource) 226*e419bc7fSGatien Chevallier { 227*e419bc7fSGatien Chevallier uint32_t cidcfgr = io_read32(get_base() + RTC_CIDCFGR(resource)); 228*e419bc7fSGatien Chevallier 229*e419bc7fSGatien Chevallier return !(cidcfgr & _CIDCFGR_CFEN) || 230*e419bc7fSGatien Chevallier get_field_u32(cidcfgr, RTC_CIDCFGR_SCID_MASK) == RIF_CID1; 231*e419bc7fSGatien Chevallier } 232*e419bc7fSGatien Chevallier 233*e419bc7fSGatien Chevallier static TEE_Result check_rif_config(void) 234*e419bc7fSGatien Chevallier { 235*e419bc7fSGatien Chevallier if (!cid1_has_access(RTC_RES_TIMESTAMP) || 236*e419bc7fSGatien Chevallier !cid1_has_access(RTC_RES_CALIBRATION) || 237*e419bc7fSGatien Chevallier !cid1_has_access(RTC_RES_INITIALIZATION)) 238*e419bc7fSGatien Chevallier return TEE_ERROR_ACCESS_DENIED; 239*e419bc7fSGatien Chevallier 240*e419bc7fSGatien Chevallier return TEE_SUCCESS; 241*e419bc7fSGatien Chevallier } 242*e419bc7fSGatien Chevallier 243*e419bc7fSGatien Chevallier static void apply_rif_config(bool is_tdcid) 244*e419bc7fSGatien Chevallier { 245*e419bc7fSGatien Chevallier vaddr_t base = get_base(); 246*e419bc7fSGatien Chevallier unsigned int shifted_values = 0; 247*e419bc7fSGatien Chevallier uint32_t seccfgr = 0; 248*e419bc7fSGatien Chevallier uint32_t privcfgr = 0; 249*e419bc7fSGatien Chevallier uint32_t access_mask_reg = 0; 250*e419bc7fSGatien Chevallier unsigned int i = 0; 251*e419bc7fSGatien Chevallier 252*e419bc7fSGatien Chevallier if (!rtc_dev.conf_data) 253*e419bc7fSGatien Chevallier return; 254*e419bc7fSGatien Chevallier 255*e419bc7fSGatien Chevallier /* Build access mask for RTC_SECCFGR and RTC_PRIVCFGR */ 256*e419bc7fSGatien Chevallier for (i = 0; i < RTC_NB_RIF_RESOURCES; i++) { 257*e419bc7fSGatien Chevallier if (rtc_dev.conf_data->access_mask[0] & BIT(i)) { 258*e419bc7fSGatien Chevallier if (i <= RTC_RES_TIMESTAMP) 259*e419bc7fSGatien Chevallier access_mask_reg |= BIT(i); 260*e419bc7fSGatien Chevallier else 261*e419bc7fSGatien Chevallier access_mask_reg |= BIT(i) << RTC_SECCFGR_SHIFT; 262*e419bc7fSGatien Chevallier } 263*e419bc7fSGatien Chevallier } 264*e419bc7fSGatien Chevallier 265*e419bc7fSGatien Chevallier for (i = 0; i < RTC_NB_RIF_RESOURCES; i++) { 266*e419bc7fSGatien Chevallier if (!(BIT(i) & rtc_dev.conf_data->access_mask[0])) 267*e419bc7fSGatien Chevallier continue; 268*e419bc7fSGatien Chevallier 269*e419bc7fSGatien Chevallier /* 270*e419bc7fSGatien Chevallier * When TDCID, OP-TEE should be the one to set the CID filtering 271*e419bc7fSGatien Chevallier * configuration. Clearing previous configuration prevents 272*e419bc7fSGatien Chevallier * undesired events during the only legitimate configuration. 273*e419bc7fSGatien Chevallier */ 274*e419bc7fSGatien Chevallier if (is_tdcid) 275*e419bc7fSGatien Chevallier io_clrbits32(base + RTC_CIDCFGR(i), 276*e419bc7fSGatien Chevallier RTC_CIDCFGR_CONF_MASK); 277*e419bc7fSGatien Chevallier } 278*e419bc7fSGatien Chevallier 279*e419bc7fSGatien Chevallier /* Security RIF configuration */ 280*e419bc7fSGatien Chevallier seccfgr = rtc_dev.conf_data->sec_conf[0]; 281*e419bc7fSGatien Chevallier 282*e419bc7fSGatien Chevallier /* Check if all resources must be secured */ 283*e419bc7fSGatien Chevallier if (seccfgr == RTC_RIF_FULL_SECURED) { 284*e419bc7fSGatien Chevallier io_setbits32(base + RTC_SECCFGR, RTC_SECCFGR_FULL_SEC); 285*e419bc7fSGatien Chevallier rtc_dev.is_secured = true; 286*e419bc7fSGatien Chevallier 287*e419bc7fSGatien Chevallier if (!(io_read32(base + RTC_SECCFGR) & RTC_SECCFGR_FULL_SEC)) 288*e419bc7fSGatien Chevallier panic("Bad RTC seccfgr configuration"); 289*e419bc7fSGatien Chevallier } 290*e419bc7fSGatien Chevallier 291*e419bc7fSGatien Chevallier /* Shift some values to align with the register */ 292*e419bc7fSGatien Chevallier shifted_values = SHIFT_U32(seccfgr & RTC_SECCFGR_VALUES_TO_SHIFT, 293*e419bc7fSGatien Chevallier RTC_SECCFGR_SHIFT); 294*e419bc7fSGatien Chevallier seccfgr = (seccfgr & RTC_SECCFGR_VALUES) + shifted_values; 295*e419bc7fSGatien Chevallier 296*e419bc7fSGatien Chevallier io_clrsetbits32(base + RTC_SECCFGR, 297*e419bc7fSGatien Chevallier RTC_SECCFGR_MASK & access_mask_reg, seccfgr); 298*e419bc7fSGatien Chevallier 299*e419bc7fSGatien Chevallier /* Privilege RIF configuration */ 300*e419bc7fSGatien Chevallier privcfgr = rtc_dev.conf_data->priv_conf[0]; 301*e419bc7fSGatien Chevallier 302*e419bc7fSGatien Chevallier /* Check if all resources must be privileged */ 303*e419bc7fSGatien Chevallier if (privcfgr == RTC_RIF_FULL_PRIVILEGED) { 304*e419bc7fSGatien Chevallier io_setbits32(base + RTC_PRIVCFGR, RTC_PRIVCFGR_FULL_PRIV); 305*e419bc7fSGatien Chevallier 306*e419bc7fSGatien Chevallier if (!(io_read32(base + RTC_PRIVCFGR) & RTC_PRIVCFGR_FULL_PRIV)) 307*e419bc7fSGatien Chevallier panic("Bad RTC privcfgr configuration"); 308*e419bc7fSGatien Chevallier } 309*e419bc7fSGatien Chevallier 310*e419bc7fSGatien Chevallier /* Shift some values to align with the register */ 311*e419bc7fSGatien Chevallier shifted_values = SHIFT_U32(privcfgr & RTC_PRIVCFGR_VALUES_TO_SHIFT, 312*e419bc7fSGatien Chevallier RTC_PRIVCFGR_SHIFT); 313*e419bc7fSGatien Chevallier privcfgr = (privcfgr & RTC_PRIVCFGR_VALUES) + shifted_values; 314*e419bc7fSGatien Chevallier 315*e419bc7fSGatien Chevallier io_clrsetbits32(base + RTC_PRIVCFGR, 316*e419bc7fSGatien Chevallier RTC_PRIVCFGR_MASK & access_mask_reg, privcfgr); 317*e419bc7fSGatien Chevallier 318*e419bc7fSGatien Chevallier if (!is_tdcid) 319*e419bc7fSGatien Chevallier return; 320*e419bc7fSGatien Chevallier 321*e419bc7fSGatien Chevallier for (i = 0; i < RTC_NB_RIF_RESOURCES; i++) { 322*e419bc7fSGatien Chevallier if (!(BIT(i) & rtc_dev.conf_data->access_mask[0])) 323*e419bc7fSGatien Chevallier continue; 324*e419bc7fSGatien Chevallier /* 325*e419bc7fSGatien Chevallier * When at least one resource has CID filtering enabled, 326*e419bc7fSGatien Chevallier * the RTC_PRIVCFGR_FULL_PRIV and RTC_SECCFGR_FULL_SEC bits are 327*e419bc7fSGatien Chevallier * cleared. 328*e419bc7fSGatien Chevallier */ 329*e419bc7fSGatien Chevallier io_clrsetbits32(base + RTC_CIDCFGR(i), 330*e419bc7fSGatien Chevallier RTC_CIDCFGR_CONF_MASK, 331*e419bc7fSGatien Chevallier rtc_dev.conf_data->cid_confs[i]); 332*e419bc7fSGatien Chevallier } 333*e419bc7fSGatien Chevallier } 334*e419bc7fSGatien Chevallier 335*e419bc7fSGatien Chevallier static TEE_Result parse_dt(const void *fdt, int node) 336*e419bc7fSGatien Chevallier { 337*e419bc7fSGatien Chevallier TEE_Result res = TEE_ERROR_GENERIC; 338*e419bc7fSGatien Chevallier const fdt32_t *cuint = NULL; 339*e419bc7fSGatien Chevallier size_t reg_size = 0; 340*e419bc7fSGatien Chevallier unsigned int i = 0; 341*e419bc7fSGatien Chevallier int lenp = 0; 342*e419bc7fSGatien Chevallier 343*e419bc7fSGatien Chevallier if (fdt_reg_info(fdt, node, &rtc_dev.base.pa, ®_size)) 344*e419bc7fSGatien Chevallier panic(); 345*e419bc7fSGatien Chevallier 346*e419bc7fSGatien Chevallier io_pa_or_va(&rtc_dev.base, reg_size); 347*e419bc7fSGatien Chevallier assert(rtc_dev.base.va); 348*e419bc7fSGatien Chevallier 349*e419bc7fSGatien Chevallier res = clk_dt_get_by_name(fdt, node, "pclk", &rtc_dev.pclk); 350*e419bc7fSGatien Chevallier if (res) 351*e419bc7fSGatien Chevallier return res; 352*e419bc7fSGatien Chevallier 353*e419bc7fSGatien Chevallier res = clk_dt_get_by_name(fdt, node, "rtc_ck", &rtc_dev.rtc_ck); 354*e419bc7fSGatien Chevallier if (res) 355*e419bc7fSGatien Chevallier return res; 356*e419bc7fSGatien Chevallier 357*e419bc7fSGatien Chevallier if (!rtc_dev.compat->has_rif_support) 358*e419bc7fSGatien Chevallier return TEE_SUCCESS; 359*e419bc7fSGatien Chevallier 360*e419bc7fSGatien Chevallier cuint = fdt_getprop(fdt, node, "st,protreg", &lenp); 361*e419bc7fSGatien Chevallier if (!cuint) { 362*e419bc7fSGatien Chevallier DMSG("No RIF configuration available"); 363*e419bc7fSGatien Chevallier return TEE_SUCCESS; 364*e419bc7fSGatien Chevallier } 365*e419bc7fSGatien Chevallier 366*e419bc7fSGatien Chevallier rtc_dev.conf_data = calloc(1, sizeof(*rtc_dev.conf_data)); 367*e419bc7fSGatien Chevallier if (!rtc_dev.conf_data) 368*e419bc7fSGatien Chevallier panic(); 369*e419bc7fSGatien Chevallier 370*e419bc7fSGatien Chevallier rtc_dev.nb_res = (unsigned int)(lenp / sizeof(uint32_t)); 371*e419bc7fSGatien Chevallier assert(rtc_dev.nb_res <= RTC_NB_RIF_RESOURCES); 372*e419bc7fSGatien Chevallier 373*e419bc7fSGatien Chevallier rtc_dev.conf_data->cid_confs = calloc(RTC_NB_RIF_RESOURCES, 374*e419bc7fSGatien Chevallier sizeof(uint32_t)); 375*e419bc7fSGatien Chevallier rtc_dev.conf_data->sec_conf = calloc(1, sizeof(uint32_t)); 376*e419bc7fSGatien Chevallier rtc_dev.conf_data->priv_conf = calloc(1, sizeof(uint32_t)); 377*e419bc7fSGatien Chevallier rtc_dev.conf_data->access_mask = calloc(1, sizeof(uint32_t)); 378*e419bc7fSGatien Chevallier if (!rtc_dev.conf_data->cid_confs || !rtc_dev.conf_data->sec_conf || 379*e419bc7fSGatien Chevallier !rtc_dev.conf_data->priv_conf || !rtc_dev.conf_data->access_mask) 380*e419bc7fSGatien Chevallier panic("Not enough memory capacity for RTC RIF config"); 381*e419bc7fSGatien Chevallier 382*e419bc7fSGatien Chevallier for (i = 0; i < rtc_dev.nb_res; i++) 383*e419bc7fSGatien Chevallier stm32_rif_parse_cfg(fdt32_to_cpu(cuint[i]), rtc_dev.conf_data, 384*e419bc7fSGatien Chevallier RTC_NB_RIF_RESOURCES); 385*e419bc7fSGatien Chevallier 386*e419bc7fSGatien Chevallier return TEE_SUCCESS; 387*e419bc7fSGatien Chevallier } 388*e419bc7fSGatien Chevallier 389*e419bc7fSGatien Chevallier static TEE_Result stm32_rtc_enter_init_mode(void) 390*e419bc7fSGatien Chevallier { 391*e419bc7fSGatien Chevallier vaddr_t base = get_base(); 392*e419bc7fSGatien Chevallier uint32_t icsr = io_read32(base + RTC_ICSR); 393*e419bc7fSGatien Chevallier uint32_t value = 0; 394*e419bc7fSGatien Chevallier 395*e419bc7fSGatien Chevallier if (!(icsr & RTC_ICSR_INITF)) { 396*e419bc7fSGatien Chevallier icsr |= RTC_ICSR_INIT; 397*e419bc7fSGatien Chevallier io_write32(base + RTC_ICSR, icsr); 398*e419bc7fSGatien Chevallier 399*e419bc7fSGatien Chevallier if (IO_READ32_POLL_TIMEOUT(base + RTC_ICSR, value, 400*e419bc7fSGatien Chevallier value & RTC_ICSR_INITF, 401*e419bc7fSGatien Chevallier 10, TIMEOUT_US_RTC_GENERIC)) 402*e419bc7fSGatien Chevallier return TEE_ERROR_BUSY; 403*e419bc7fSGatien Chevallier } 404*e419bc7fSGatien Chevallier 405*e419bc7fSGatien Chevallier return TEE_SUCCESS; 406*e419bc7fSGatien Chevallier } 407*e419bc7fSGatien Chevallier 408*e419bc7fSGatien Chevallier static void stm32_rtc_exit_init_mode(void) 409*e419bc7fSGatien Chevallier { 410*e419bc7fSGatien Chevallier io_clrbits32(get_base() + RTC_ICSR, RTC_ICSR_INIT); 411*e419bc7fSGatien Chevallier dsb(); 412*e419bc7fSGatien Chevallier } 413*e419bc7fSGatien Chevallier 414*e419bc7fSGatien Chevallier static TEE_Result stm32_rtc_wait_sync(void) 415*e419bc7fSGatien Chevallier { 416*e419bc7fSGatien Chevallier vaddr_t base = get_base(); 417*e419bc7fSGatien Chevallier uint32_t value = 0; 418*e419bc7fSGatien Chevallier 419*e419bc7fSGatien Chevallier io_clrbits32(base + RTC_ICSR, RTC_ICSR_RSF); 420*e419bc7fSGatien Chevallier 421*e419bc7fSGatien Chevallier if (IO_READ32_POLL_TIMEOUT(base + RTC_ICSR, value, 422*e419bc7fSGatien Chevallier value & RTC_ICSR_RSF, 10, 423*e419bc7fSGatien Chevallier TIMEOUT_US_RTC_GENERIC)) 424*e419bc7fSGatien Chevallier return TEE_ERROR_BUSY; 425*e419bc7fSGatien Chevallier 426*e419bc7fSGatien Chevallier return TEE_SUCCESS; 427*e419bc7fSGatien Chevallier } 428*e419bc7fSGatien Chevallier 429*e419bc7fSGatien Chevallier static TEE_Result stm32_rtc_get_time(struct rtc *rtc __unused, 430*e419bc7fSGatien Chevallier struct optee_rtc_time *tm) 431*e419bc7fSGatien Chevallier { 432*e419bc7fSGatien Chevallier vaddr_t base = get_base(); 433*e419bc7fSGatien Chevallier uint32_t ssr = 0; 434*e419bc7fSGatien Chevallier uint32_t dr = 0; 435*e419bc7fSGatien Chevallier uint32_t tr = 0; 436*e419bc7fSGatien Chevallier 437*e419bc7fSGatien Chevallier if (!stm32_rtc_get_bypshad()) { 438*e419bc7fSGatien Chevallier uint32_t icsr = 0; 439*e419bc7fSGatien Chevallier 440*e419bc7fSGatien Chevallier /* Wait calendar registers are ready */ 441*e419bc7fSGatien Chevallier io_clrbits32(base + RTC_ICSR, RTC_ICSR_RSF); 442*e419bc7fSGatien Chevallier 443*e419bc7fSGatien Chevallier if (IO_READ32_POLL_TIMEOUT(base + RTC_ICSR, icsr, 444*e419bc7fSGatien Chevallier icsr & RTC_ICSR_RSF, 0, 445*e419bc7fSGatien Chevallier TIMEOUT_US_RTC_SHADOW)) 446*e419bc7fSGatien Chevallier panic(); 447*e419bc7fSGatien Chevallier } 448*e419bc7fSGatien Chevallier 449*e419bc7fSGatien Chevallier /* 450*e419bc7fSGatien Chevallier * In our RTC we start : 451*e419bc7fSGatien Chevallier * - year at 0 452*e419bc7fSGatien Chevallier * - month at 1 453*e419bc7fSGatien Chevallier * - day at 1 454*e419bc7fSGatien Chevallier * - weekday at Monday = 1 455*e419bc7fSGatien Chevallier * Change month value so it becomes 0=January, 1 = February, ... 456*e419bc7fSGatien Chevallier * Change week day value so it becomes 0=Sunday, 1 = Monday, ... 457*e419bc7fSGatien Chevallier */ 458*e419bc7fSGatien Chevallier 459*e419bc7fSGatien Chevallier ssr = io_read32(base + RTC_SSR); 460*e419bc7fSGatien Chevallier tr = io_read32(base + RTC_TR); 461*e419bc7fSGatien Chevallier dr = io_read32(base + RTC_DR); 462*e419bc7fSGatien Chevallier 463*e419bc7fSGatien Chevallier tm->tm_hour = ((tr & RTC_TR_HT_MASK) >> RTC_TR_HT_SHIFT) * 10 + 464*e419bc7fSGatien Chevallier ((tr & RTC_TR_HU_MASK) >> RTC_TR_HU_SHIFT); 465*e419bc7fSGatien Chevallier 466*e419bc7fSGatien Chevallier if (tr & RTC_TR_PM) 467*e419bc7fSGatien Chevallier tm->tm_hour += 12; 468*e419bc7fSGatien Chevallier 469*e419bc7fSGatien Chevallier tm->tm_ms = (stm32_rtc_get_subsecond(ssr) * MS_PER_SEC) / 470*e419bc7fSGatien Chevallier stm32_rtc_get_subsecond_scale(); 471*e419bc7fSGatien Chevallier 472*e419bc7fSGatien Chevallier tm->tm_sec = ((tr & RTC_TR_ST_MASK) >> RTC_TR_ST_SHIFT) * 10 + 473*e419bc7fSGatien Chevallier (tr & RTC_TR_SU_MASK); 474*e419bc7fSGatien Chevallier 475*e419bc7fSGatien Chevallier tm->tm_min = ((tr & RTC_TR_MNT_MASK) >> RTC_TR_MNT_SHIFT) * 10 + 476*e419bc7fSGatien Chevallier ((tr & RTC_TR_MNU_MASK) >> RTC_TR_MNU_SHIFT); 477*e419bc7fSGatien Chevallier 478*e419bc7fSGatien Chevallier tm->tm_wday = ((dr & RTC_DR_WDU_MASK) >> RTC_DR_WDU_SHIFT) % 7; 479*e419bc7fSGatien Chevallier 480*e419bc7fSGatien Chevallier tm->tm_mday = ((dr & RTC_DR_DT_MASK) >> RTC_DR_DT_SHIFT) * 10 + 481*e419bc7fSGatien Chevallier (dr & RTC_DR_DU_MASK); 482*e419bc7fSGatien Chevallier 483*e419bc7fSGatien Chevallier tm->tm_mon = ((dr & RTC_DR_MT_MASK) >> RTC_DR_MT_SHIFT) * 10 + 484*e419bc7fSGatien Chevallier ((dr & RTC_DR_MU_MASK) >> RTC_DR_MU_SHIFT) - 1; 485*e419bc7fSGatien Chevallier 486*e419bc7fSGatien Chevallier tm->tm_year = ((dr & RTC_DR_YT_MASK) >> RTC_DR_YT_SHIFT) * 10 + 487*e419bc7fSGatien Chevallier ((dr & RTC_DR_YU_MASK) >> RTC_DR_YU_SHIFT) + YEAR_REF; 488*e419bc7fSGatien Chevallier 489*e419bc7fSGatien Chevallier return TEE_SUCCESS; 490*e419bc7fSGatien Chevallier } 491*e419bc7fSGatien Chevallier 492*e419bc7fSGatien Chevallier static TEE_Result stm32_rtc_set_time(struct rtc *rtc, struct optee_rtc_time *tm) 493*e419bc7fSGatien Chevallier { 494*e419bc7fSGatien Chevallier TEE_Result res = TEE_ERROR_GENERIC; 495*e419bc7fSGatien Chevallier vaddr_t rtc_base = get_base(); 496*e419bc7fSGatien Chevallier uint32_t tr = 0; 497*e419bc7fSGatien Chevallier uint32_t dr = 0; 498*e419bc7fSGatien Chevallier 499*e419bc7fSGatien Chevallier /* 500*e419bc7fSGatien Chevallier * In our RTC we start : 501*e419bc7fSGatien Chevallier * - year at 0 502*e419bc7fSGatien Chevallier * - month at 1 503*e419bc7fSGatien Chevallier * - day at 1 504*e419bc7fSGatien Chevallier * - weekday at Monday = 1 505*e419bc7fSGatien Chevallier * Change month value so it becomes 1=January, 2 = February, ... 506*e419bc7fSGatien Chevallier * Change week day value so it becomes 7=Sunday, 1 = Monday, ... 507*e419bc7fSGatien Chevallier */ 508*e419bc7fSGatien Chevallier tr = ((tm->tm_sec % 10) & RTC_TR_SU_MASK) | 509*e419bc7fSGatien Chevallier (SHIFT_U32(tm->tm_sec / 10, RTC_TR_ST_SHIFT) & RTC_TR_ST_MASK) | 510*e419bc7fSGatien Chevallier (SHIFT_U32(tm->tm_min % 10, RTC_TR_MNU_SHIFT) & RTC_TR_MNU_MASK) | 511*e419bc7fSGatien Chevallier (SHIFT_U32(tm->tm_min / 10, RTC_TR_MNT_SHIFT) & RTC_TR_MNT_MASK) | 512*e419bc7fSGatien Chevallier (SHIFT_U32(tm->tm_hour % 10, RTC_TR_HU_SHIFT) & RTC_TR_HU_MASK) | 513*e419bc7fSGatien Chevallier (SHIFT_U32(tm->tm_hour / 10, RTC_TR_HT_SHIFT) & RTC_TR_HT_MASK); 514*e419bc7fSGatien Chevallier 515*e419bc7fSGatien Chevallier dr = ((tm->tm_mday % 10) & RTC_DR_DU_MASK) | 516*e419bc7fSGatien Chevallier (SHIFT_U32(tm->tm_mday / 10, RTC_DR_DT_SHIFT) & RTC_DR_DT_MASK) | 517*e419bc7fSGatien Chevallier (SHIFT_U32((tm->tm_mon + 1) % 10, RTC_DR_MU_SHIFT) & 518*e419bc7fSGatien Chevallier RTC_DR_MU_MASK) | 519*e419bc7fSGatien Chevallier (SHIFT_U32((tm->tm_mon + 1) / 10, RTC_DR_MT_SHIFT) & 520*e419bc7fSGatien Chevallier RTC_DR_MT_MASK) | 521*e419bc7fSGatien Chevallier (SHIFT_U32(tm->tm_wday ? tm->tm_wday : 7, RTC_DR_WDU_SHIFT) & 522*e419bc7fSGatien Chevallier RTC_DR_WDU_MASK) | 523*e419bc7fSGatien Chevallier (SHIFT_U32((tm->tm_year - rtc->range_min.tm_year) % 10, 524*e419bc7fSGatien Chevallier RTC_DR_YU_SHIFT) & RTC_DR_YU_MASK) | 525*e419bc7fSGatien Chevallier (SHIFT_U32((tm->tm_year - rtc->range_min.tm_year) / 10, 526*e419bc7fSGatien Chevallier RTC_DR_YT_SHIFT) & RTC_DR_YT_MASK); 527*e419bc7fSGatien Chevallier 528*e419bc7fSGatien Chevallier stm32_rtc_write_unprotect(); 529*e419bc7fSGatien Chevallier 530*e419bc7fSGatien Chevallier res = stm32_rtc_enter_init_mode(); 531*e419bc7fSGatien Chevallier if (res) 532*e419bc7fSGatien Chevallier goto end; 533*e419bc7fSGatien Chevallier 534*e419bc7fSGatien Chevallier io_write32(rtc_base + RTC_TR, tr); 535*e419bc7fSGatien Chevallier io_write32(rtc_base + RTC_DR, dr); 536*e419bc7fSGatien Chevallier 537*e419bc7fSGatien Chevallier stm32_rtc_exit_init_mode(); 538*e419bc7fSGatien Chevallier 539*e419bc7fSGatien Chevallier res = stm32_rtc_wait_sync(); 540*e419bc7fSGatien Chevallier end: 541*e419bc7fSGatien Chevallier stm32_rtc_write_protect(); 542*e419bc7fSGatien Chevallier 543*e419bc7fSGatien Chevallier return res; 544*e419bc7fSGatien Chevallier } 545*e419bc7fSGatien Chevallier 546*e419bc7fSGatien Chevallier static const struct rtc_ops stm32_rtc_ops = { 547*e419bc7fSGatien Chevallier .get_time = stm32_rtc_get_time, 548*e419bc7fSGatien Chevallier .set_time = stm32_rtc_set_time, 549*e419bc7fSGatien Chevallier }; 550*e419bc7fSGatien Chevallier 551*e419bc7fSGatien Chevallier static struct rtc stm32_rtc = { 552*e419bc7fSGatien Chevallier .ops = &stm32_rtc_ops, 553*e419bc7fSGatien Chevallier .range_min = RTC_TIME(YEAR_REF, 0, 1, 0, 0, 0, 0, 0), 554*e419bc7fSGatien Chevallier .range_max = RTC_TIME(YEAR_MAX, 11, 31, 4, 23, 59, 59, 999), 555*e419bc7fSGatien Chevallier }; 556*e419bc7fSGatien Chevallier 557*e419bc7fSGatien Chevallier static TEE_Result stm32_rtc_probe(const void *fdt, int node, 558*e419bc7fSGatien Chevallier const void *compat_data) 559*e419bc7fSGatien Chevallier { 560*e419bc7fSGatien Chevallier TEE_Result res = TEE_ERROR_GENERIC; 561*e419bc7fSGatien Chevallier bool is_tdcid = false; 562*e419bc7fSGatien Chevallier 563*e419bc7fSGatien Chevallier rtc_dev.compat = compat_data; 564*e419bc7fSGatien Chevallier 565*e419bc7fSGatien Chevallier if (rtc_dev.compat->has_rif_support) { 566*e419bc7fSGatien Chevallier res = stm32_rifsc_check_tdcid(&is_tdcid); 567*e419bc7fSGatien Chevallier if (res) 568*e419bc7fSGatien Chevallier return res; 569*e419bc7fSGatien Chevallier } 570*e419bc7fSGatien Chevallier 571*e419bc7fSGatien Chevallier res = parse_dt(fdt, node); 572*e419bc7fSGatien Chevallier if (res) { 573*e419bc7fSGatien Chevallier memset(&rtc_dev, 0, sizeof(rtc_dev)); 574*e419bc7fSGatien Chevallier return res; 575*e419bc7fSGatien Chevallier } 576*e419bc7fSGatien Chevallier 577*e419bc7fSGatien Chevallier /* Unbalanced clock enable to ensure RTC core clock is always on */ 578*e419bc7fSGatien Chevallier res = clk_enable(rtc_dev.rtc_ck); 579*e419bc7fSGatien Chevallier if (res) 580*e419bc7fSGatien Chevallier panic("Couldn't enable RTC clock"); 581*e419bc7fSGatien Chevallier 582*e419bc7fSGatien Chevallier if (clk_get_rate(rtc_dev.pclk) < (clk_get_rate(rtc_dev.rtc_ck) * 7)) 583*e419bc7fSGatien Chevallier rtc_dev.flags |= RTC_FLAGS_READ_TWICE; 584*e419bc7fSGatien Chevallier 585*e419bc7fSGatien Chevallier if (rtc_dev.compat->has_rif_support) { 586*e419bc7fSGatien Chevallier res = clk_enable(rtc_dev.pclk); 587*e419bc7fSGatien Chevallier if (res) 588*e419bc7fSGatien Chevallier panic("Could not enable RTC bus clock"); 589*e419bc7fSGatien Chevallier 590*e419bc7fSGatien Chevallier apply_rif_config(is_tdcid); 591*e419bc7fSGatien Chevallier 592*e419bc7fSGatien Chevallier /* 593*e419bc7fSGatien Chevallier * Verify if applied RIF config will not disable 594*e419bc7fSGatien Chevallier * other functionalities of this driver. 595*e419bc7fSGatien Chevallier */ 596*e419bc7fSGatien Chevallier res = check_rif_config(); 597*e419bc7fSGatien Chevallier if (res) 598*e419bc7fSGatien Chevallier panic("Incompatible RTC RIF configuration"); 599*e419bc7fSGatien Chevallier 600*e419bc7fSGatien Chevallier clk_disable(rtc_dev.pclk); 601*e419bc7fSGatien Chevallier } 602*e419bc7fSGatien Chevallier 603*e419bc7fSGatien Chevallier rtc_register(&stm32_rtc); 604*e419bc7fSGatien Chevallier 605*e419bc7fSGatien Chevallier return res; 606*e419bc7fSGatien Chevallier } 607*e419bc7fSGatien Chevallier 608*e419bc7fSGatien Chevallier static const struct rtc_compat mp25_compat = { 609*e419bc7fSGatien Chevallier .has_seccfgr = true, 610*e419bc7fSGatien Chevallier .has_rif_support = true, 611*e419bc7fSGatien Chevallier }; 612*e419bc7fSGatien Chevallier 613*e419bc7fSGatien Chevallier static const struct rtc_compat mp15_compat = { 614*e419bc7fSGatien Chevallier .has_seccfgr = false, 615*e419bc7fSGatien Chevallier .has_rif_support = false, 616*e419bc7fSGatien Chevallier }; 617*e419bc7fSGatien Chevallier 618*e419bc7fSGatien Chevallier static const struct rtc_compat mp13_compat = { 619*e419bc7fSGatien Chevallier .has_seccfgr = true, 620*e419bc7fSGatien Chevallier .has_rif_support = false, 621*e419bc7fSGatien Chevallier }; 622*e419bc7fSGatien Chevallier 623*e419bc7fSGatien Chevallier static const struct dt_device_match stm32_rtc_match_table[] = { 624*e419bc7fSGatien Chevallier { 625*e419bc7fSGatien Chevallier .compatible = "st,stm32mp25-rtc", 626*e419bc7fSGatien Chevallier .compat_data = &mp25_compat, 627*e419bc7fSGatien Chevallier }, 628*e419bc7fSGatien Chevallier { 629*e419bc7fSGatien Chevallier .compatible = "st,stm32mp1-rtc", 630*e419bc7fSGatien Chevallier .compat_data = &mp15_compat, 631*e419bc7fSGatien Chevallier }, 632*e419bc7fSGatien Chevallier { 633*e419bc7fSGatien Chevallier .compatible = "st,stm32mp13-rtc", 634*e419bc7fSGatien Chevallier .compat_data = &mp13_compat, 635*e419bc7fSGatien Chevallier }, 636*e419bc7fSGatien Chevallier { } 637*e419bc7fSGatien Chevallier }; 638*e419bc7fSGatien Chevallier 639*e419bc7fSGatien Chevallier DEFINE_DT_DRIVER(stm32_rtc_dt_driver) = { 640*e419bc7fSGatien Chevallier .name = "stm32-rtc", 641*e419bc7fSGatien Chevallier .match_table = stm32_rtc_match_table, 642*e419bc7fSGatien Chevallier .probe = stm32_rtc_probe, 643*e419bc7fSGatien Chevallier }; 644