Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6760c1ae authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: spm-v2: Use proper register offsets for SAW2_v3.0"

parents 05160c3b b5c502a2
Loading
Loading
Loading
Loading
+76 −97
Original line number Diff line number Diff line
@@ -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,
@@ -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,
@@ -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,
@@ -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)
{
@@ -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,
@@ -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(
@@ -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)
@@ -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 */
@@ -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;

@@ -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;
@@ -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
@@ -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 =
+1 −0
Original line number Diff line number Diff line
@@ -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,