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

Commit 6239ce0a authored by Ke Liu's avatar Ke Liu
Browse files

msm: cpr-regulator: remove register save and restore for suspend and resume



As CPR hardware register values will be retained during XO shutdown with
VDD_CX minimization, there is no need to save and restore CPR hardware
register values during suspend and resume. Also, there is a race condition
between cpr_resume and cpr_regulator_set_voltage. The
cpr_regulator_set_voltage function might be called after cpr_suspend is
invoked and before cpr_resume is called, this will enable CPR during XO
shutdown.

Hence remove register save and restore operations from cpr_suspend and
cpr_resume functions and add a flag to indicate that CPR has been
suspended.

Change-Id: Ic7c0f639e7e5cedb096d2f2eaaa3e8433ccd44c7
CRs-Fixed: 616385
Signed-off-by: default avatarKe Liu <keliu@codeaurora.org>
parent 816351dd
Loading
Loading
Loading
Loading
+16 −43
Original line number Diff line number Diff line
@@ -125,7 +125,6 @@
#define CPR_INT_DEFAULT	(CPR_INT_UP | CPR_INT_DOWN)

#define CPR_NUM_RING_OSC	8
#define CPR_NUM_SAVE_REGS	10

/* RBCPR Clock Control Register */
#define RBCPR_CLK_SEL_MASK	BIT(0)
@@ -209,9 +208,6 @@ struct cpr_regulator {
	int		*save_ctl;
	int		*save_irq;

	u32		save_regs[CPR_NUM_SAVE_REGS];
	u32		save_reg_val[CPR_NUM_SAVE_REGS];

	/* Config parameters */
	bool		enable;
	u32		ref_clk_khz;
@@ -230,6 +226,8 @@ struct cpr_regulator {
	int		*corner_map;
	u32		num_corners;
	int		*quot_adjust;

	bool		is_cpr_suspended;
};

#define CPR_DEBUG_MASK_IRQ	BIT(0)
@@ -357,6 +355,9 @@ static void cpr_ctl_enable(struct cpr_regulator *cpr_vreg, int corner)
	u32 val;
	int fuse_corner = cpr_vreg->corner_map[corner];

	if (cpr_vreg->is_cpr_suspended)
		return;

	if (cpr_is_allowed(cpr_vreg) &&
	    (cpr_vreg->ceiling_volt[fuse_corner] >
		cpr_vreg->floor_volt[fuse_corner]))
@@ -368,31 +369,11 @@ static void cpr_ctl_enable(struct cpr_regulator *cpr_vreg, int corner)

static void cpr_ctl_disable(struct cpr_regulator *cpr_vreg)
{
	if (cpr_vreg->is_cpr_suspended)
		return;
	cpr_ctl_modify(cpr_vreg, RBCPR_CTL_LOOP_EN, 0);
}

static void cpr_regs_save(struct cpr_regulator *cpr_vreg)
{
	int i, offset;

	for (i = 0; i < CPR_NUM_SAVE_REGS; i++) {
		offset = cpr_vreg->save_regs[i];
		cpr_vreg->save_reg_val[i] = cpr_read(cpr_vreg, offset);
	}
}

static void cpr_regs_restore(struct cpr_regulator *cpr_vreg)
{
	int i, offset;
	u32 val;

	for (i = 0; i < CPR_NUM_SAVE_REGS; i++) {
		offset = cpr_vreg->save_regs[i];
		val = cpr_vreg->save_reg_val[i];
		cpr_write(cpr_vreg, offset, val);
	}
}

static void cpr_corner_save(struct cpr_regulator *cpr_vreg, int corner)
{
	cpr_vreg->save_ctl[corner] = cpr_read(cpr_vreg, REG_RBCPR_CTL);
@@ -899,12 +880,16 @@ static int cpr_suspend(struct cpr_regulator *cpr_vreg)
{
	cpr_debug("suspend\n");

	mutex_lock(&cpr_vreg->cpr_mutex);

	cpr_ctl_disable(cpr_vreg);
	disable_irq(cpr_vreg->cpr_irq);

	cpr_irq_clr(cpr_vreg);
	cpr_regs_save(cpr_vreg);

	cpr_vreg->is_cpr_suspended = true;

	mutex_unlock(&cpr_vreg->cpr_mutex);
	return 0;
}

@@ -913,12 +898,15 @@ static int cpr_resume(struct cpr_regulator *cpr_vreg)
{
	cpr_debug("resume\n");

	cpr_regs_restore(cpr_vreg);
	mutex_lock(&cpr_vreg->cpr_mutex);

	cpr_vreg->is_cpr_suspended = false;
	cpr_irq_clr(cpr_vreg);

	enable_irq(cpr_vreg->cpr_irq);
	cpr_ctl_enable(cpr_vreg, cpr_vreg->corner);

	mutex_unlock(&cpr_vreg->cpr_mutex);
	return 0;
}

@@ -1014,21 +1002,6 @@ static int cpr_config(struct cpr_regulator *cpr_vreg, struct device *dev)
	val |= RBCPR_CTL_SW_AUTO_CONT_ACK_EN;
	cpr_write(cpr_vreg, REG_RBCPR_CTL, val);

	/* Registers to save & restore for suspend */
	cpr_vreg->save_regs[0] = REG_RBCPR_TIMER_INTERVAL;
	cpr_vreg->save_regs[1] = REG_RBCPR_STEP_QUOT;
	cpr_vreg->save_regs[2] = REG_RBIF_TIMER_ADJUST;
	cpr_vreg->save_regs[3] = REG_RBIF_LIMIT;
	cpr_vreg->save_regs[4] = REG_RBIF_SW_VLEVEL;
	cpr_vreg->save_regs[5] = REG_RBIF_IRQ_EN(cpr_vreg->irq_line);
	cpr_vreg->save_regs[6] = REG_RBCPR_CTL;
	cpr_vreg->save_regs[7] = REG_RBCPR_GCNT_TARGET
		(cpr_vreg->cpr_fuse_ro_sel[CPR_FUSE_CORNER_SVS]);
	cpr_vreg->save_regs[8] = REG_RBCPR_GCNT_TARGET
		(cpr_vreg->cpr_fuse_ro_sel[CPR_FUSE_CORNER_NORMAL]);
	cpr_vreg->save_regs[9] = REG_RBCPR_GCNT_TARGET
		(cpr_vreg->cpr_fuse_ro_sel[CPR_FUSE_CORNER_TURBO]);

	cpr_irq_set(cpr_vreg, CPR_INT_DEFAULT);

	val = cpr_read(cpr_vreg, REG_RBCPR_VERSION);