1 /* 2 * Copyright (c) 2025, Mediatek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <errno.h> 8 9 #include <common/debug.h> 10 #include <drivers/pmic/pmic_psc.h> 11 #include <drivers/spmi_api.h> 12 #include <lib/mtk_init/mtk_init.h> 13 14 #include "registers.h" 15 16 static struct spmi_device *sdev; 17 18 static const struct pmic_psc_reg mt6363_psc_regs[] = { 19 PMIC_PSC_REG(RG_PWRHOLD, MT6363_PPCCTL0, 0), 20 PMIC_PSC_REG(RG_CRST, MT6363_PPCCTL1, 0), 21 PMIC_PSC_REG(RG_SMART_RST_SDN_EN, MT6363_STRUP_CON12, 1), 22 PMIC_PSC_REG(RG_SMART_RST_MODE, MT6363_STRUP_CON12, 2), 23 }; 24 25 static int mt6363_psc_read_field(uint32_t reg, uint32_t *val, uint32_t mask, uint32_t shift) 26 { 27 uint8_t rdata = 0; 28 int ret = 0; 29 30 if (!val) 31 return -EINVAL; 32 if (!sdev) 33 return -ENODEV; 34 ret = spmi_ext_register_readl(sdev, reg, &rdata, 1); 35 if (ret < 0) 36 return ret; 37 38 rdata &= (mask << shift); 39 *val = (rdata >> shift); 40 41 return 0; 42 } 43 44 static int mt6363_psc_write_field(uint32_t reg, uint32_t val, uint32_t mask, uint32_t shift) 45 { 46 uint8_t org = 0; 47 int ret = 0; 48 49 if (!sdev) 50 return -ENODEV; 51 ret = spmi_ext_register_readl(sdev, reg, &org, 1); 52 if (ret < 0) 53 return ret; 54 55 org &= ~(mask << shift); 56 org |= (val << shift); 57 58 ret = spmi_ext_register_writel(sdev, reg, &org, 1); 59 return ret; 60 } 61 62 static const struct pmic_psc_config mt6363_psc_config = { 63 .read_field = mt6363_psc_read_field, 64 .write_field = mt6363_psc_write_field, 65 .regs = mt6363_psc_regs, 66 .reg_size = ARRAY_SIZE(mt6363_psc_regs), 67 }; 68 69 static int mt6363_psc_init(void) 70 { 71 sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4); 72 if (!sdev) 73 ERROR("%s: get spmi device fail\n", __func__); 74 return pmic_psc_register(&mt6363_psc_config); 75 } 76 77 MTK_PLAT_SETUP_0_INIT(mt6363_psc_init); 78 79 #ifdef CONFIG_MTK_PMIC_SPT_SUPPORT 80 static int mt6363_spt_enable(void) 81 { 82 /* Enable PMIC Self-Protection Timer(SPT) */ 83 return mt6363_psc_write_field(MT6363_RG_SELFWDT_EN_ADDR, MT6363_RG_SELFWDT_EN_MASK, 84 MT6363_RG_SELFWDT_EN_MASK, 0); 85 } 86 87 MTK_PLAT_RUNTIME_INIT(mt6363_spt_enable); 88 #endif 89