Loading arch/arm/mach-msm/spm-v2.c +76 −97 Original line number Diff line number Diff line Loading @@ -23,12 +23,6 @@ #define MSM_SPM_PMIC_STATE_IDLE 0 #define SAW2_V1_VER_REG 0x04 #define SAW2_V2_VER_REG 0xfd0 #define SAW2_MAJOR_2 2 enum { MSM_SPM_DEBUG_SHADOW = 1U << 0, MSM_SPM_DEBUG_VCTL = 1U << 1, Loading @@ -39,25 +33,41 @@ module_param_named( debug_mask, msm_spm_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP ); struct saw2_data { const char *ver_name; uint32_t major; uint32_t minor; uint32_t *spm_reg_offset_ptr; }; static uint32_t msm_spm_reg_offsets_v1[MSM_SPM_REG_NR] = { static uint32_t msm_spm_reg_offsets_saw2_v2_1[MSM_SPM_REG_NR] = { [MSM_SPM_REG_SAW2_SECURE] = 0x00, [MSM_SPM_REG_SAW2_ID] = 0x04, [MSM_SPM_REG_SAW2_CFG] = 0x08, [MSM_SPM_REG_SAW2_STS0] = 0x0C, [MSM_SPM_REG_SAW2_STS1] = 0x10, [MSM_SPM_REG_SAW2_VCTL] = 0x14, [MSM_SPM_REG_SAW2_AVS_CTL] = 0x18, [MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x1C, [MSM_SPM_REG_SAW2_SPM_CTL] = 0x20, [MSM_SPM_REG_SAW2_PMIC_DLY] = 0x24, [MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x28, [MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x2C, [MSM_SPM_REG_SAW2_RST] = 0x30, [MSM_SPM_REG_SAW2_SPM_STS] = 0x0C, [MSM_SPM_REG_SAW2_AVS_STS] = 0x10, [MSM_SPM_REG_SAW2_PMIC_STS] = 0x14, [MSM_SPM_REG_SAW2_RST] = 0x18, [MSM_SPM_REG_SAW2_VCTL] = 0x1C, [MSM_SPM_REG_SAW2_AVS_CTL] = 0x20, [MSM_SPM_REG_SAW2_AVS_LIMIT] = 0x24, [MSM_SPM_REG_SAW2_AVS_DLY] = 0x28, [MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x2C, [MSM_SPM_REG_SAW2_SPM_CTL] = 0x30, [MSM_SPM_REG_SAW2_SPM_DLY] = 0x34, [MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x40, [MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x44, [MSM_SPM_REG_SAW2_PMIC_DATA_2] = 0x48, [MSM_SPM_REG_SAW2_PMIC_DATA_3] = 0x4C, [MSM_SPM_REG_SAW2_PMIC_DATA_4] = 0x50, [MSM_SPM_REG_SAW2_PMIC_DATA_5] = 0x54, [MSM_SPM_REG_SAW2_PMIC_DATA_6] = 0x58, [MSM_SPM_REG_SAW2_PMIC_DATA_7] = 0x5C, [MSM_SPM_REG_SAW2_SEQ_ENTRY] = 0x80, [MSM_SPM_REG_SAW2_VERSION] = 0xFD0, }; static uint32_t msm_spm_reg_offsets_v2[MSM_SPM_REG_NR] = { static uint32_t msm_spm_reg_offsets_saw2_v3_0[MSM_SPM_REG_NR] = { [MSM_SPM_REG_SAW2_SECURE] = 0x00, [MSM_SPM_REG_SAW2_ID] = 0x04, [MSM_SPM_REG_SAW2_CFG] = 0x08, Loading @@ -72,6 +82,7 @@ static uint32_t msm_spm_reg_offsets_v2[MSM_SPM_REG_NR] = { [MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x2C, [MSM_SPM_REG_SAW2_SPM_CTL] = 0x30, [MSM_SPM_REG_SAW2_SPM_DLY] = 0x34, [MSM_SPM_REG_SAW2_STS2] = 0x38, [MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x40, [MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x44, [MSM_SPM_REG_SAW2_PMIC_DATA_2] = 0x48, Loading @@ -80,10 +91,25 @@ static uint32_t msm_spm_reg_offsets_v2[MSM_SPM_REG_NR] = { [MSM_SPM_REG_SAW2_PMIC_DATA_5] = 0x54, [MSM_SPM_REG_SAW2_PMIC_DATA_6] = 0x58, [MSM_SPM_REG_SAW2_PMIC_DATA_7] = 0x5C, [MSM_SPM_REG_SAW2_SEQ_ENTRY] = 0x80, [MSM_SPM_REG_SAW2_SEQ_ENTRY] = 0x400, [MSM_SPM_REG_SAW2_VERSION] = 0xFD0, }; static struct saw2_data saw2_info[] = { [0] = { "SAW2_v2.1", 0x2, 0x1, msm_spm_reg_offsets_saw2_v2_1, }, [1] = { "SAW2_v3.0", 0x3, 0x0, msm_spm_reg_offsets_saw2_v3_0, }, }; static inline uint32_t msm_spm_drv_get_num_spm_entry( struct msm_spm_driver_data *dev) { Loading Loading @@ -117,32 +143,7 @@ static inline void msm_spm_drv_set_start_addr( static inline bool msm_spm_pmic_arb_present(struct msm_spm_driver_data *dev) { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_ID); if (dev->major == SAW2_MAJOR_2) return (dev->reg_shadow[MSM_SPM_REG_SAW2_ID] >> 2) & 0x1; else return (dev->reg_shadow[MSM_SPM_REG_SAW2_ID] >> 18) & 0x1; } static inline void msm_spm_drv_set_vctl(struct msm_spm_driver_data *dev, uint32_t vlevel) { dev->reg_shadow[MSM_SPM_REG_SAW2_VCTL] &= ~0xFF; dev->reg_shadow[MSM_SPM_REG_SAW2_VCTL] |= vlevel; dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_DATA_0] &= ~0xFF; dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_DATA_0] |= vlevel; dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_DATA_1] &= ~0x3F; dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_DATA_1] |= (vlevel & 0x3F); dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_DATA_1] &= ~0x3F0000; dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_DATA_1] |= ((vlevel & 0x3F) << 16); msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_VCTL); msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_PMIC_DATA_0); msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_PMIC_DATA_1); } static inline void msm_spm_drv_set_vctl2(struct msm_spm_driver_data *dev, Loading @@ -169,60 +170,33 @@ static inline void msm_spm_drv_set_vctl2(struct msm_spm_driver_data *dev, msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_PMIC_DATA_3); } static inline void msm_spm_drv_apcs_set_vctl(struct msm_spm_driver_data *dev, unsigned int vlevel) { if (dev->major == SAW2_MAJOR_2) return msm_spm_drv_set_vctl2(dev, vlevel); else return msm_spm_drv_set_vctl(dev, vlevel); } static inline uint32_t msm_spm_drv_get_sts_pmic_state( struct msm_spm_driver_data *dev) { if (dev->major == SAW2_MAJOR_2) { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_PMIC_STS); return (dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_STS] >> 16) & 0x03; } else { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_STS0); return (dev->reg_shadow[MSM_SPM_REG_SAW2_STS0] >> 10) & 0x03; } } uint32_t msm_spm_drv_get_sts_curr_pmic_data( struct msm_spm_driver_data *dev) { if (dev->major == SAW2_MAJOR_2) { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_PMIC_STS); return dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_STS] & 0xFF; } else { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_STS1); return dev->reg_shadow[MSM_SPM_REG_SAW2_STS1] & 0xFF; } } static inline uint32_t msm_spm_drv_get_saw2_ver(struct msm_spm_driver_data *dev, static inline void msm_spm_drv_get_saw2_ver(struct msm_spm_driver_data *dev, uint32_t *major, uint32_t *minor) { int ret = -ENODEV; uint32_t val = 0; msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_VERSION); dev->reg_shadow[MSM_SPM_REG_SAW2_VERSION] = __raw_readl(dev->reg_base_addr + dev->ver_reg); val = dev->reg_shadow[MSM_SPM_REG_SAW2_VERSION]; if (dev->ver_reg == SAW2_V2_VER_REG) { *major = (val >> 28) & 0xF; *minor = (val >> 16) & 0xFFF; ret = 0; } else if (dev->ver_reg == SAW2_V1_VER_REG) { *major = (val >> 4) & 0xF; *minor = val & 0xF; ret = 0; } return ret; } inline int msm_spm_drv_set_spm_enable( Loading Loading @@ -322,10 +296,7 @@ int msm_spm_drv_set_low_power_mode(struct msm_spm_driver_data *dev, static bool msm_spm_drv_is_avs_enabled(struct msm_spm_driver_data *dev) { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_AVS_CTL); if (dev->major == SAW2_MAJOR_2) return dev->reg_shadow[MSM_SPM_REG_SAW2_AVS_CTL] & BIT(0); else return dev->reg_shadow[MSM_SPM_REG_SAW2_AVS_CTL] & BIT(27); } static void msm_spm_drv_disable_avs(struct msm_spm_driver_data *dev) Loading Loading @@ -388,7 +359,7 @@ int msm_spm_drv_set_vdd(struct msm_spm_driver_data *dev, unsigned int vlevel) dev->reg_shadow[MSM_SPM_REG_SAW2_RST] = 1; msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_RST); msm_spm_drv_apcs_set_vctl(dev, vlevel); msm_spm_drv_set_vctl2(dev, vlevel); timeout_us = dev->vctl_timeout_us; /* Confirm the voltage we set was what hardware sent */ Loading Loading @@ -453,9 +424,6 @@ int msm_spm_drv_set_pmic_data(struct msm_spm_driver_data *dev, unsigned int timeout_us = 0; int index = 0; if (dev->major != SAW2_MAJOR_2) return -ENODEV; if (!msm_spm_pmic_arb_present(dev)) return -ENOSYS; Loading Loading @@ -511,14 +479,10 @@ int msm_spm_drv_init(struct msm_spm_driver_data *dev, { int i; int num_spm_entry; bool found = false; BUG_ON(!dev || !data); if (dev->ver_reg == SAW2_V2_VER_REG) dev->reg_offsets = msm_spm_reg_offsets_v2; else dev->reg_offsets = msm_spm_reg_offsets_v1; dev->vctl_port = data->vctl_port; dev->phase_port = data->phase_port; dev->pfm_port = data->pfm_port; Loading @@ -528,6 +492,23 @@ int msm_spm_drv_init(struct msm_spm_driver_data *dev, dev->vctl_timeout_us = data->vctl_timeout_us; msm_spm_drv_get_saw2_ver(dev, &dev->major, &dev->minor); for (i = 0; i < ARRAY_SIZE(saw2_info); i++) if (dev->major == saw2_info[i].major && dev->minor == saw2_info[i].minor) { pr_debug("%s: Version found\n", saw2_info[i].ver_name); dev->reg_offsets = saw2_info[i].spm_reg_offset_ptr; found = true; break; } if (!found) { pr_err("%s: No SAW2 version found\n", __func__); BUG_ON(!found); } for (i = 0; i < MSM_SPM_REG_NR_INITIALIZE; i++) msm_spm_drv_flush_shadow(dev, i); /* barrier to ensure write completes before we update shadow Loading @@ -541,8 +522,6 @@ int msm_spm_drv_init(struct msm_spm_driver_data *dev, /* barrier to ensure read completes before we proceed further*/ mb(); msm_spm_drv_get_saw2_ver(dev, &dev->major, &dev->minor); num_spm_entry = msm_spm_drv_get_num_spm_entry(dev); dev->reg_seq_entry_shadow = Loading arch/arm/mach-msm/spm.h +1 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ enum { MSM_SPM_REG_SAW2_SECURE, MSM_SPM_REG_SAW2_STS0, MSM_SPM_REG_SAW2_STS1, MSM_SPM_REG_SAW2_STS2, MSM_SPM_REG_SAW2_VCTL, MSM_SPM_REG_SAW2_SEQ_ENTRY, MSM_SPM_REG_SAW2_SPM_STS, Loading Loading
arch/arm/mach-msm/spm-v2.c +76 −97 Original line number Diff line number Diff line Loading @@ -23,12 +23,6 @@ #define MSM_SPM_PMIC_STATE_IDLE 0 #define SAW2_V1_VER_REG 0x04 #define SAW2_V2_VER_REG 0xfd0 #define SAW2_MAJOR_2 2 enum { MSM_SPM_DEBUG_SHADOW = 1U << 0, MSM_SPM_DEBUG_VCTL = 1U << 1, Loading @@ -39,25 +33,41 @@ module_param_named( debug_mask, msm_spm_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP ); struct saw2_data { const char *ver_name; uint32_t major; uint32_t minor; uint32_t *spm_reg_offset_ptr; }; static uint32_t msm_spm_reg_offsets_v1[MSM_SPM_REG_NR] = { static uint32_t msm_spm_reg_offsets_saw2_v2_1[MSM_SPM_REG_NR] = { [MSM_SPM_REG_SAW2_SECURE] = 0x00, [MSM_SPM_REG_SAW2_ID] = 0x04, [MSM_SPM_REG_SAW2_CFG] = 0x08, [MSM_SPM_REG_SAW2_STS0] = 0x0C, [MSM_SPM_REG_SAW2_STS1] = 0x10, [MSM_SPM_REG_SAW2_VCTL] = 0x14, [MSM_SPM_REG_SAW2_AVS_CTL] = 0x18, [MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x1C, [MSM_SPM_REG_SAW2_SPM_CTL] = 0x20, [MSM_SPM_REG_SAW2_PMIC_DLY] = 0x24, [MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x28, [MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x2C, [MSM_SPM_REG_SAW2_RST] = 0x30, [MSM_SPM_REG_SAW2_SPM_STS] = 0x0C, [MSM_SPM_REG_SAW2_AVS_STS] = 0x10, [MSM_SPM_REG_SAW2_PMIC_STS] = 0x14, [MSM_SPM_REG_SAW2_RST] = 0x18, [MSM_SPM_REG_SAW2_VCTL] = 0x1C, [MSM_SPM_REG_SAW2_AVS_CTL] = 0x20, [MSM_SPM_REG_SAW2_AVS_LIMIT] = 0x24, [MSM_SPM_REG_SAW2_AVS_DLY] = 0x28, [MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x2C, [MSM_SPM_REG_SAW2_SPM_CTL] = 0x30, [MSM_SPM_REG_SAW2_SPM_DLY] = 0x34, [MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x40, [MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x44, [MSM_SPM_REG_SAW2_PMIC_DATA_2] = 0x48, [MSM_SPM_REG_SAW2_PMIC_DATA_3] = 0x4C, [MSM_SPM_REG_SAW2_PMIC_DATA_4] = 0x50, [MSM_SPM_REG_SAW2_PMIC_DATA_5] = 0x54, [MSM_SPM_REG_SAW2_PMIC_DATA_6] = 0x58, [MSM_SPM_REG_SAW2_PMIC_DATA_7] = 0x5C, [MSM_SPM_REG_SAW2_SEQ_ENTRY] = 0x80, [MSM_SPM_REG_SAW2_VERSION] = 0xFD0, }; static uint32_t msm_spm_reg_offsets_v2[MSM_SPM_REG_NR] = { static uint32_t msm_spm_reg_offsets_saw2_v3_0[MSM_SPM_REG_NR] = { [MSM_SPM_REG_SAW2_SECURE] = 0x00, [MSM_SPM_REG_SAW2_ID] = 0x04, [MSM_SPM_REG_SAW2_CFG] = 0x08, Loading @@ -72,6 +82,7 @@ static uint32_t msm_spm_reg_offsets_v2[MSM_SPM_REG_NR] = { [MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x2C, [MSM_SPM_REG_SAW2_SPM_CTL] = 0x30, [MSM_SPM_REG_SAW2_SPM_DLY] = 0x34, [MSM_SPM_REG_SAW2_STS2] = 0x38, [MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x40, [MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x44, [MSM_SPM_REG_SAW2_PMIC_DATA_2] = 0x48, Loading @@ -80,10 +91,25 @@ static uint32_t msm_spm_reg_offsets_v2[MSM_SPM_REG_NR] = { [MSM_SPM_REG_SAW2_PMIC_DATA_5] = 0x54, [MSM_SPM_REG_SAW2_PMIC_DATA_6] = 0x58, [MSM_SPM_REG_SAW2_PMIC_DATA_7] = 0x5C, [MSM_SPM_REG_SAW2_SEQ_ENTRY] = 0x80, [MSM_SPM_REG_SAW2_SEQ_ENTRY] = 0x400, [MSM_SPM_REG_SAW2_VERSION] = 0xFD0, }; static struct saw2_data saw2_info[] = { [0] = { "SAW2_v2.1", 0x2, 0x1, msm_spm_reg_offsets_saw2_v2_1, }, [1] = { "SAW2_v3.0", 0x3, 0x0, msm_spm_reg_offsets_saw2_v3_0, }, }; static inline uint32_t msm_spm_drv_get_num_spm_entry( struct msm_spm_driver_data *dev) { Loading Loading @@ -117,32 +143,7 @@ static inline void msm_spm_drv_set_start_addr( static inline bool msm_spm_pmic_arb_present(struct msm_spm_driver_data *dev) { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_ID); if (dev->major == SAW2_MAJOR_2) return (dev->reg_shadow[MSM_SPM_REG_SAW2_ID] >> 2) & 0x1; else return (dev->reg_shadow[MSM_SPM_REG_SAW2_ID] >> 18) & 0x1; } static inline void msm_spm_drv_set_vctl(struct msm_spm_driver_data *dev, uint32_t vlevel) { dev->reg_shadow[MSM_SPM_REG_SAW2_VCTL] &= ~0xFF; dev->reg_shadow[MSM_SPM_REG_SAW2_VCTL] |= vlevel; dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_DATA_0] &= ~0xFF; dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_DATA_0] |= vlevel; dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_DATA_1] &= ~0x3F; dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_DATA_1] |= (vlevel & 0x3F); dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_DATA_1] &= ~0x3F0000; dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_DATA_1] |= ((vlevel & 0x3F) << 16); msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_VCTL); msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_PMIC_DATA_0); msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_PMIC_DATA_1); } static inline void msm_spm_drv_set_vctl2(struct msm_spm_driver_data *dev, Loading @@ -169,60 +170,33 @@ static inline void msm_spm_drv_set_vctl2(struct msm_spm_driver_data *dev, msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_PMIC_DATA_3); } static inline void msm_spm_drv_apcs_set_vctl(struct msm_spm_driver_data *dev, unsigned int vlevel) { if (dev->major == SAW2_MAJOR_2) return msm_spm_drv_set_vctl2(dev, vlevel); else return msm_spm_drv_set_vctl(dev, vlevel); } static inline uint32_t msm_spm_drv_get_sts_pmic_state( struct msm_spm_driver_data *dev) { if (dev->major == SAW2_MAJOR_2) { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_PMIC_STS); return (dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_STS] >> 16) & 0x03; } else { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_STS0); return (dev->reg_shadow[MSM_SPM_REG_SAW2_STS0] >> 10) & 0x03; } } uint32_t msm_spm_drv_get_sts_curr_pmic_data( struct msm_spm_driver_data *dev) { if (dev->major == SAW2_MAJOR_2) { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_PMIC_STS); return dev->reg_shadow[MSM_SPM_REG_SAW2_PMIC_STS] & 0xFF; } else { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_STS1); return dev->reg_shadow[MSM_SPM_REG_SAW2_STS1] & 0xFF; } } static inline uint32_t msm_spm_drv_get_saw2_ver(struct msm_spm_driver_data *dev, static inline void msm_spm_drv_get_saw2_ver(struct msm_spm_driver_data *dev, uint32_t *major, uint32_t *minor) { int ret = -ENODEV; uint32_t val = 0; msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_VERSION); dev->reg_shadow[MSM_SPM_REG_SAW2_VERSION] = __raw_readl(dev->reg_base_addr + dev->ver_reg); val = dev->reg_shadow[MSM_SPM_REG_SAW2_VERSION]; if (dev->ver_reg == SAW2_V2_VER_REG) { *major = (val >> 28) & 0xF; *minor = (val >> 16) & 0xFFF; ret = 0; } else if (dev->ver_reg == SAW2_V1_VER_REG) { *major = (val >> 4) & 0xF; *minor = val & 0xF; ret = 0; } return ret; } inline int msm_spm_drv_set_spm_enable( Loading Loading @@ -322,10 +296,7 @@ int msm_spm_drv_set_low_power_mode(struct msm_spm_driver_data *dev, static bool msm_spm_drv_is_avs_enabled(struct msm_spm_driver_data *dev) { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_AVS_CTL); if (dev->major == SAW2_MAJOR_2) return dev->reg_shadow[MSM_SPM_REG_SAW2_AVS_CTL] & BIT(0); else return dev->reg_shadow[MSM_SPM_REG_SAW2_AVS_CTL] & BIT(27); } static void msm_spm_drv_disable_avs(struct msm_spm_driver_data *dev) Loading Loading @@ -388,7 +359,7 @@ int msm_spm_drv_set_vdd(struct msm_spm_driver_data *dev, unsigned int vlevel) dev->reg_shadow[MSM_SPM_REG_SAW2_RST] = 1; msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_RST); msm_spm_drv_apcs_set_vctl(dev, vlevel); msm_spm_drv_set_vctl2(dev, vlevel); timeout_us = dev->vctl_timeout_us; /* Confirm the voltage we set was what hardware sent */ Loading Loading @@ -453,9 +424,6 @@ int msm_spm_drv_set_pmic_data(struct msm_spm_driver_data *dev, unsigned int timeout_us = 0; int index = 0; if (dev->major != SAW2_MAJOR_2) return -ENODEV; if (!msm_spm_pmic_arb_present(dev)) return -ENOSYS; Loading Loading @@ -511,14 +479,10 @@ int msm_spm_drv_init(struct msm_spm_driver_data *dev, { int i; int num_spm_entry; bool found = false; BUG_ON(!dev || !data); if (dev->ver_reg == SAW2_V2_VER_REG) dev->reg_offsets = msm_spm_reg_offsets_v2; else dev->reg_offsets = msm_spm_reg_offsets_v1; dev->vctl_port = data->vctl_port; dev->phase_port = data->phase_port; dev->pfm_port = data->pfm_port; Loading @@ -528,6 +492,23 @@ int msm_spm_drv_init(struct msm_spm_driver_data *dev, dev->vctl_timeout_us = data->vctl_timeout_us; msm_spm_drv_get_saw2_ver(dev, &dev->major, &dev->minor); for (i = 0; i < ARRAY_SIZE(saw2_info); i++) if (dev->major == saw2_info[i].major && dev->minor == saw2_info[i].minor) { pr_debug("%s: Version found\n", saw2_info[i].ver_name); dev->reg_offsets = saw2_info[i].spm_reg_offset_ptr; found = true; break; } if (!found) { pr_err("%s: No SAW2 version found\n", __func__); BUG_ON(!found); } for (i = 0; i < MSM_SPM_REG_NR_INITIALIZE; i++) msm_spm_drv_flush_shadow(dev, i); /* barrier to ensure write completes before we update shadow Loading @@ -541,8 +522,6 @@ int msm_spm_drv_init(struct msm_spm_driver_data *dev, /* barrier to ensure read completes before we proceed further*/ mb(); msm_spm_drv_get_saw2_ver(dev, &dev->major, &dev->minor); num_spm_entry = msm_spm_drv_get_num_spm_entry(dev); dev->reg_seq_entry_shadow = Loading
arch/arm/mach-msm/spm.h +1 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ enum { MSM_SPM_REG_SAW2_SECURE, MSM_SPM_REG_SAW2_STS0, MSM_SPM_REG_SAW2_STS1, MSM_SPM_REG_SAW2_STS2, MSM_SPM_REG_SAW2_VCTL, MSM_SPM_REG_SAW2_SEQ_ENTRY, MSM_SPM_REG_SAW2_SPM_STS, Loading