regulator: cpr3: support LDO handling for different LDO types
An LDO300 regulator is used by the GPU rail on msmfalcon. This LDO is CPR managed and uses a different configuration/control scheme compared to Kryo LDO. Add support for this LDO in the CPR3 framework. CRs-Fixed: 1068294 Change-Id: Ia45152fe211f2ece1028c5cb978beebda86faba3 Signed-off-by: Tirupathi Reddy <tirupath@codeaurora.org>
This commit is contained in:
parent
a80e267a8c
commit
23603a7dc4
5 changed files with 234 additions and 65 deletions
|
@ -32,7 +32,7 @@
|
||||||
#include <linux/regulator/driver.h>
|
#include <linux/regulator/driver.h>
|
||||||
#include <linux/regulator/machine.h>
|
#include <linux/regulator/machine.h>
|
||||||
#include <linux/regulator/of_regulator.h>
|
#include <linux/regulator/of_regulator.h>
|
||||||
#include <linux/regulator/kryo-regulator.h>
|
#include <linux/regulator/msm-ldo-regulator.h>
|
||||||
|
|
||||||
#include "cpr3-regulator.h"
|
#include "cpr3-regulator.h"
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <linux/regulator/driver.h>
|
#include <linux/regulator/driver.h>
|
||||||
#include <linux/regulator/machine.h>
|
#include <linux/regulator/machine.h>
|
||||||
#include <linux/regulator/of_regulator.h>
|
#include <linux/regulator/of_regulator.h>
|
||||||
#include <linux/regulator/kryo-regulator.h>
|
#include <linux/regulator/msm-ldo-regulator.h>
|
||||||
|
|
||||||
#include <soc/qcom/spm.h>
|
#include <soc/qcom/spm.h>
|
||||||
|
|
||||||
|
@ -1761,7 +1761,12 @@ static int cpr3_regulator_config_ldo_retention(struct cpr3_regulator *vreg,
|
||||||
{
|
{
|
||||||
struct regulator *ldo_ret_reg = vreg->ldo_ret_regulator;
|
struct regulator *ldo_ret_reg = vreg->ldo_ret_regulator;
|
||||||
int retention_volt, rc;
|
int retention_volt, rc;
|
||||||
enum kryo_supply_mode mode;
|
enum msm_ldo_supply_mode mode;
|
||||||
|
|
||||||
|
if (!ldo_ret_reg) {
|
||||||
|
/* LDO retention regulator is not defined */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
retention_volt = regulator_get_voltage(ldo_ret_reg);
|
retention_volt = regulator_get_voltage(ldo_ret_reg);
|
||||||
if (retention_volt < 0) {
|
if (retention_volt < 0) {
|
||||||
|
@ -1783,8 +1788,8 @@ static int cpr3_regulator_config_ldo_retention(struct cpr3_regulator *vreg,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpr3_regulator_config_ldo_mem_acc() - configure the mem-acc regulator
|
* cpr3_regulator_config_kryo_ldo_mem_acc() - configure the mem-acc regulator
|
||||||
* corner based upon a future LDO regulator voltage setpoint
|
* corner based upon a future Kryo LDO regulator voltage setpoint
|
||||||
* @vreg: Pointer to the CPR3 regulator
|
* @vreg: Pointer to the CPR3 regulator
|
||||||
* @new_volt: New voltage in microvolts that the LDO regulator needs
|
* @new_volt: New voltage in microvolts that the LDO regulator needs
|
||||||
* to end up at
|
* to end up at
|
||||||
|
@ -1796,7 +1801,7 @@ static int cpr3_regulator_config_ldo_retention(struct cpr3_regulator *vreg,
|
||||||
*
|
*
|
||||||
* Return: 0 on success, errno on failure
|
* Return: 0 on success, errno on failure
|
||||||
*/
|
*/
|
||||||
static int cpr3_regulator_config_ldo_mem_acc(struct cpr3_regulator *vreg,
|
static int cpr3_regulator_config_kryo_ldo_mem_acc(struct cpr3_regulator *vreg,
|
||||||
int new_volt)
|
int new_volt)
|
||||||
{
|
{
|
||||||
struct cpr3_controller *ctrl = vreg->thread->ctrl;
|
struct cpr3_controller *ctrl = vreg->thread->ctrl;
|
||||||
|
@ -1857,6 +1862,51 @@ static int cpr3_regulator_config_ldo_mem_acc(struct cpr3_regulator *vreg,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cpr3_regulator_kryo_bhs_prepare() - configure the Kryo LDO regulator
|
||||||
|
* associated with a CPR3 regulator in preparation for BHS
|
||||||
|
* mode switch.
|
||||||
|
* @vreg: Pointer to the CPR3 regulator
|
||||||
|
* @vdd_volt: Last known settled voltage in microvolts for the VDD
|
||||||
|
* supply
|
||||||
|
* @vdd_ceiling_volt: Last known aggregated ceiling voltage in microvolts for
|
||||||
|
* the VDD supply
|
||||||
|
*
|
||||||
|
* This function performs the necessary steps prior to switching a Kryo LDO
|
||||||
|
* regulator to BHS mode (LDO bypassed mode).
|
||||||
|
*
|
||||||
|
* Return: 0 on success, errno on failure
|
||||||
|
*/
|
||||||
|
static int cpr3_regulator_kryo_bhs_prepare(struct cpr3_regulator *vreg,
|
||||||
|
int vdd_volt, int vdd_ceiling_volt)
|
||||||
|
{
|
||||||
|
struct regulator *ldo_reg = vreg->ldo_regulator;
|
||||||
|
int bhs_volt, rc;
|
||||||
|
|
||||||
|
bhs_volt = vdd_volt - vreg->ldo_min_headroom_volt;
|
||||||
|
if (bhs_volt > vreg->ldo_max_volt) {
|
||||||
|
cpr3_debug(vreg, "limited to LDO output of %d uV when switching to BHS mode\n",
|
||||||
|
vreg->ldo_max_volt);
|
||||||
|
bhs_volt = vreg->ldo_max_volt;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = cpr3_regulator_config_kryo_ldo_mem_acc(vreg, bhs_volt);
|
||||||
|
if (rc) {
|
||||||
|
cpr3_err(vreg, "failed to configure mem-acc settings\n");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = regulator_set_voltage(ldo_reg, bhs_volt, min(vdd_ceiling_volt,
|
||||||
|
vreg->ldo_max_volt));
|
||||||
|
if (rc) {
|
||||||
|
cpr3_err(vreg, "regulator_set_voltage(ldo) == %d failed, rc=%d\n",
|
||||||
|
bhs_volt, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpr3_regulator_set_bhs_mode() - configure the LDO regulator associated with
|
* cpr3_regulator_set_bhs_mode() - configure the LDO regulator associated with
|
||||||
* a CPR3 regulator to BHS mode
|
* a CPR3 regulator to BHS mode
|
||||||
|
@ -1873,32 +1923,21 @@ static int cpr3_regulator_set_bhs_mode(struct cpr3_regulator *vreg,
|
||||||
int vdd_volt, int vdd_ceiling_volt)
|
int vdd_volt, int vdd_ceiling_volt)
|
||||||
{
|
{
|
||||||
struct regulator *ldo_reg = vreg->ldo_regulator;
|
struct regulator *ldo_reg = vreg->ldo_regulator;
|
||||||
int bhs_volt, rc;
|
int rc;
|
||||||
|
|
||||||
bhs_volt = vdd_volt - vreg->ldo_min_headroom_volt;
|
if (vreg->ldo_type == CPR3_LDO_KRYO) {
|
||||||
if (bhs_volt > vreg->ldo_max_volt) {
|
rc = cpr3_regulator_kryo_bhs_prepare(vreg, vdd_volt,
|
||||||
cpr3_debug(vreg, "limited to LDO output of %d uV when switching to BHS mode\n",
|
vdd_ceiling_volt);
|
||||||
vreg->ldo_max_volt);
|
if (rc) {
|
||||||
bhs_volt = vreg->ldo_max_volt;
|
cpr3_err(vreg, "cpr3 regulator bhs mode prepare failed, rc=%d\n",
|
||||||
}
|
rc);
|
||||||
|
return rc;
|
||||||
rc = cpr3_regulator_config_ldo_mem_acc(vreg, bhs_volt);
|
}
|
||||||
if (rc) {
|
|
||||||
cpr3_err(vreg, "failed to configure mem-acc settings\n");
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = regulator_set_voltage(ldo_reg, bhs_volt, min(vdd_ceiling_volt,
|
|
||||||
vreg->ldo_max_volt));
|
|
||||||
if (rc) {
|
|
||||||
cpr3_err(vreg, "regulator_set_voltage(ldo) == %d failed, rc=%d\n",
|
|
||||||
bhs_volt, rc);
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = regulator_allow_bypass(ldo_reg, BHS_MODE);
|
rc = regulator_allow_bypass(ldo_reg, BHS_MODE);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
cpr3_err(vreg, "regulator_allow_bypass(ldo) == %s failed, rc=%d\n",
|
cpr3_err(vreg, "regulator_allow_bypass(bhs) == %s failed, rc=%d\n",
|
||||||
BHS_MODE ? "true" : "false", rc);
|
BHS_MODE ? "true" : "false", rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -2009,44 +2048,34 @@ static int cpr3_regulator_ldo_apm_prepare(struct cpr3_controller *ctrl,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpr3_regulator_config_vreg_ldo() - configure the voltage and bypass state for
|
* cpr3_regulator_config_vreg_kryo_ldo() - configure the voltage and bypass
|
||||||
* the LDO regulator associated with a single CPR3 regulator.
|
* state for the Kryo LDO regulator associated with a single CPR3
|
||||||
|
* regulator.
|
||||||
*
|
*
|
||||||
* @vreg: Pointer to the CPR3 regulator
|
* @vreg: Pointer to the CPR3 regulator
|
||||||
* @vdd_floor_volt: Last known aggregated floor voltage in microvolts for
|
* @vdd_floor_volt: Last known aggregated floor voltage in microvolts for
|
||||||
* the VDD supply
|
* the VDD supply
|
||||||
* @vdd_ceiling_volt: Last known aggregated ceiling voltage in microvolts for
|
* @vdd_ceiling_volt: Last known aggregated ceiling voltage in microvolts for
|
||||||
* the VDD supply
|
* the VDD supply
|
||||||
* @new_volt: New voltage in microvolts that VDD supply needs to
|
* @ref_volt: Reference voltage in microvolts corresponds either to
|
||||||
* end up at
|
* the aggregated floor voltage or the next VDD supply
|
||||||
|
* setpoint.
|
||||||
* @last_volt: Last known voltage in microvolts for the VDD supply
|
* @last_volt: Last known voltage in microvolts for the VDD supply
|
||||||
*
|
*
|
||||||
* This function performs all relevant LDO or BHS configurations if an LDO
|
* This function performs all relevant LDO or BHS configurations if a Kryo LDO
|
||||||
* regulator is specified.
|
* regulator is specified.
|
||||||
*
|
*
|
||||||
* Return: 0 on success, errno on failure
|
* Return: 0 on success, errno on failure
|
||||||
*/
|
*/
|
||||||
static int cpr3_regulator_config_vreg_ldo(struct cpr3_regulator *vreg,
|
static int cpr3_regulator_config_vreg_kryo_ldo(struct cpr3_regulator *vreg,
|
||||||
int vdd_floor_volt, int vdd_ceiling_volt,
|
int vdd_floor_volt, int vdd_ceiling_volt,
|
||||||
int new_volt, int last_volt)
|
int ref_volt, int last_volt)
|
||||||
{
|
{
|
||||||
struct cpr3_controller *ctrl = vreg->thread->ctrl;
|
struct cpr3_controller *ctrl = vreg->thread->ctrl;
|
||||||
struct regulator *ldo_reg = vreg->ldo_regulator;
|
struct regulator *ldo_reg = vreg->ldo_regulator;
|
||||||
struct cpr3_corner *current_corner;
|
struct cpr3_corner *current_corner;
|
||||||
enum msm_apm_supply apm_mode;
|
enum msm_apm_supply apm_mode;
|
||||||
int rc, ldo_volt, final_ldo_volt, bhs_volt, max_volt, safe_volt;
|
int rc, ldo_volt, final_ldo_volt, bhs_volt, max_volt, safe_volt;
|
||||||
int ref_volt;
|
|
||||||
|
|
||||||
ref_volt = ctrl->use_hw_closed_loop ? vdd_floor_volt :
|
|
||||||
new_volt;
|
|
||||||
|
|
||||||
rc = cpr3_regulator_config_ldo_retention(vreg, ref_volt);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
if (!vreg->vreg_enabled || vreg->current_corner
|
|
||||||
== CPR3_REGULATOR_CORNER_INVALID)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
current_corner = &vreg->corner[vreg->current_corner];
|
current_corner = &vreg->corner[vreg->current_corner];
|
||||||
ldo_volt = current_corner->open_loop_volt
|
ldo_volt = current_corner->open_loop_volt
|
||||||
|
@ -2087,7 +2116,7 @@ static int cpr3_regulator_config_vreg_ldo(struct cpr3_regulator *vreg,
|
||||||
bhs_volt),
|
bhs_volt),
|
||||||
vreg->ldo_max_volt);
|
vreg->ldo_max_volt);
|
||||||
|
|
||||||
rc = cpr3_regulator_config_ldo_mem_acc(vreg,
|
rc = cpr3_regulator_config_kryo_ldo_mem_acc(vreg,
|
||||||
safe_volt);
|
safe_volt);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
cpr3_err(vreg, "failed to configure mem-acc settings\n");
|
cpr3_err(vreg, "failed to configure mem-acc settings\n");
|
||||||
|
@ -2119,7 +2148,7 @@ static int cpr3_regulator_config_vreg_ldo(struct cpr3_regulator *vreg,
|
||||||
else
|
else
|
||||||
final_ldo_volt = ldo_volt;
|
final_ldo_volt = ldo_volt;
|
||||||
|
|
||||||
rc = cpr3_regulator_config_ldo_mem_acc(vreg,
|
rc = cpr3_regulator_config_kryo_ldo_mem_acc(vreg,
|
||||||
final_ldo_volt);
|
final_ldo_volt);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
cpr3_err(vreg, "failed to configure mem-acc settings\n");
|
cpr3_err(vreg, "failed to configure mem-acc settings\n");
|
||||||
|
@ -2145,6 +2174,115 @@ static int cpr3_regulator_config_vreg_ldo(struct cpr3_regulator *vreg,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cpr3_regulator_config_vreg_ldo300() - configure the voltage and bypass state
|
||||||
|
* for the LDO300 regulator associated with a single CPR3
|
||||||
|
* regulator.
|
||||||
|
*
|
||||||
|
* @vreg: Pointer to the CPR3 regulator
|
||||||
|
* @new_volt: New voltage in microvolts that VDD supply needs to
|
||||||
|
* end up at
|
||||||
|
* @vdd_ceiling_volt: Last known aggregated ceiling voltage in microvolts for
|
||||||
|
* the VDD supply
|
||||||
|
*
|
||||||
|
* This function performs all relevant LDO or BHS configurations for an LDO300
|
||||||
|
* type regulator.
|
||||||
|
*
|
||||||
|
* Return: 0 on success, errno on failure
|
||||||
|
*/
|
||||||
|
static int cpr3_regulator_config_vreg_ldo300(struct cpr3_regulator *vreg,
|
||||||
|
int new_volt, int vdd_ceiling_volt)
|
||||||
|
{
|
||||||
|
struct regulator *ldo_reg = vreg->ldo_regulator;
|
||||||
|
struct cpr3_corner *corner;
|
||||||
|
bool mode;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
corner = &vreg->corner[vreg->current_corner];
|
||||||
|
mode = corner->ldo_mode_allowed ? LDO_MODE : BHS_MODE;
|
||||||
|
|
||||||
|
if (mode == LDO_MODE) {
|
||||||
|
rc = regulator_set_voltage(ldo_reg, new_volt, vdd_ceiling_volt);
|
||||||
|
if (rc) {
|
||||||
|
cpr3_err(vreg, "regulator_set_voltage(ldo) == %d failed, rc=%d\n",
|
||||||
|
new_volt, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vreg->ldo_regulator_bypass != mode) {
|
||||||
|
rc = regulator_allow_bypass(ldo_reg, mode);
|
||||||
|
if (rc) {
|
||||||
|
cpr3_err(vreg, "regulator_allow_bypass(%s) is failed, rc=%d\n",
|
||||||
|
mode == LDO_MODE ? "ldo" : "bhs", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
vreg->ldo_regulator_bypass = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cpr3_regulator_config_vreg_ldo() - configure the voltage and bypass state for
|
||||||
|
* the LDO regulator associated with a single CPR3 regulator.
|
||||||
|
*
|
||||||
|
* @vreg: Pointer to the CPR3 regulator
|
||||||
|
* @vdd_floor_volt: Last known aggregated floor voltage in microvolts for
|
||||||
|
* the VDD supply
|
||||||
|
* @vdd_ceiling_volt: Last known aggregated ceiling voltage in microvolts for
|
||||||
|
* the VDD supply
|
||||||
|
* @new_volt: New voltage in microvolts that VDD supply needs to
|
||||||
|
* end up at
|
||||||
|
* @last_volt: Last known voltage in microvolts for the VDD supply
|
||||||
|
*
|
||||||
|
* This function identifies the type of LDO regulator associated with a CPR3
|
||||||
|
* regulator and invokes the LDO specific configuration functions.
|
||||||
|
*
|
||||||
|
* Return: 0 on success, errno on failure
|
||||||
|
*/
|
||||||
|
static int cpr3_regulator_config_vreg_ldo(struct cpr3_regulator *vreg,
|
||||||
|
int vdd_floor_volt, int vdd_ceiling_volt,
|
||||||
|
int new_volt, int last_volt)
|
||||||
|
{
|
||||||
|
struct cpr3_controller *ctrl = vreg->thread->ctrl;
|
||||||
|
int ref_volt, rc;
|
||||||
|
|
||||||
|
ref_volt = ctrl->use_hw_closed_loop ? vdd_floor_volt :
|
||||||
|
new_volt;
|
||||||
|
|
||||||
|
rc = cpr3_regulator_config_ldo_retention(vreg, ref_volt);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if (!vreg->vreg_enabled ||
|
||||||
|
vreg->current_corner == CPR3_REGULATOR_CORNER_INVALID)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (vreg->ldo_type) {
|
||||||
|
case CPR3_LDO_KRYO:
|
||||||
|
rc = cpr3_regulator_config_vreg_kryo_ldo(vreg, vdd_floor_volt,
|
||||||
|
vdd_ceiling_volt, ref_volt, last_volt);
|
||||||
|
if (rc)
|
||||||
|
cpr3_err(vreg, "kryo ldo regulator config failed, rc=%d\n",
|
||||||
|
rc);
|
||||||
|
break;
|
||||||
|
case CPR3_LDO300:
|
||||||
|
rc = cpr3_regulator_config_vreg_ldo300(vreg, new_volt,
|
||||||
|
vdd_ceiling_volt);
|
||||||
|
if (rc)
|
||||||
|
cpr3_err(vreg, "ldo300 regulator config failed, rc=%d\n",
|
||||||
|
rc);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cpr3_err(vreg, "invalid ldo regulator type = %d\n",
|
||||||
|
vreg->ldo_type);
|
||||||
|
rc = -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpr3_regulator_config_ldo() - configure the voltage and bypass state for the
|
* cpr3_regulator_config_ldo() - configure the voltage and bypass state for the
|
||||||
* LDO regulator associated with each CPR3 regulator of a CPR3
|
* LDO regulator associated with each CPR3 regulator of a CPR3
|
||||||
|
@ -2529,6 +2667,12 @@ static int cpr3_regulator_scale_vdd_voltage(struct cpr3_controller *ctrl,
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (new_volt < last_volt) {
|
if (new_volt < last_volt) {
|
||||||
|
if (ctrl->support_ldo300_vreg) {
|
||||||
|
rc = cpr3_regulator_config_mem_acc(ctrl, aggr_corner);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/* Decreasing VDD voltage */
|
/* Decreasing VDD voltage */
|
||||||
rc = cpr3_regulator_config_ldo(ctrl, aggr_corner->floor_volt,
|
rc = cpr3_regulator_config_ldo(ctrl, aggr_corner->floor_volt,
|
||||||
ctrl->aggr_corner.ceiling_volt,
|
ctrl->aggr_corner.ceiling_volt,
|
||||||
|
@ -2539,10 +2683,11 @@ static int cpr3_regulator_scale_vdd_voltage(struct cpr3_controller *ctrl,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = cpr3_regulator_config_mem_acc(ctrl, aggr_corner);
|
if (!ctrl->support_ldo300_vreg) {
|
||||||
if (rc)
|
rc = cpr3_regulator_config_mem_acc(ctrl, aggr_corner);
|
||||||
return rc;
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Increasing VDD voltage */
|
/* Increasing VDD voltage */
|
||||||
if (ctrl->system_regulator) {
|
if (ctrl->system_regulator) {
|
||||||
|
@ -2903,6 +3048,8 @@ static void cpr3_regulator_aggregate_corners(struct cpr3_corner *aggr_corner,
|
||||||
aggr_corner->mem_acc_volt
|
aggr_corner->mem_acc_volt
|
||||||
= max(aggr_corner->mem_acc_volt, corner->mem_acc_volt);
|
= max(aggr_corner->mem_acc_volt, corner->mem_acc_volt);
|
||||||
aggr_corner->irq_en |= corner->irq_en;
|
aggr_corner->irq_en |= corner->irq_en;
|
||||||
|
aggr_corner->use_open_loop |= corner->use_open_loop;
|
||||||
|
aggr_corner->ldo_mode_allowed |= corner->ldo_mode_allowed;
|
||||||
|
|
||||||
if (aggr_quot) {
|
if (aggr_quot) {
|
||||||
aggr_corner->ro_mask &= corner->ro_mask;
|
aggr_corner->ro_mask &= corner->ro_mask;
|
||||||
|
@ -3281,7 +3428,8 @@ static int _cpr3_regulator_update_ctrl_state(struct cpr3_controller *ctrl)
|
||||||
* Only enable the CPR controller if it is possible to set more than
|
* Only enable the CPR controller if it is possible to set more than
|
||||||
* one vdd-supply voltage.
|
* one vdd-supply voltage.
|
||||||
*/
|
*/
|
||||||
if (aggr_corner.ceiling_volt > aggr_corner.floor_volt)
|
if (aggr_corner.ceiling_volt > aggr_corner.floor_volt &&
|
||||||
|
!aggr_corner.use_open_loop)
|
||||||
cpr3_ctrl_loop_enable(ctrl);
|
cpr3_ctrl_loop_enable(ctrl);
|
||||||
|
|
||||||
ctrl->last_corner_was_closed_loop = ctrl->cpr_enabled;
|
ctrl->last_corner_was_closed_loop = ctrl->cpr_enabled;
|
||||||
|
|
|
@ -141,6 +141,9 @@ struct cpr4_sdelta {
|
||||||
* @use_open_loop: Boolean indicating that open-loop (i.e CPR disabled) as
|
* @use_open_loop: Boolean indicating that open-loop (i.e CPR disabled) as
|
||||||
* opposed to closed-loop operation must be used for this
|
* opposed to closed-loop operation must be used for this
|
||||||
* corner on CPRh controllers.
|
* corner on CPRh controllers.
|
||||||
|
* @ldo_mode_allowed: Boolean which indicates if LDO mode is allowed for this
|
||||||
|
* corner. This field is applicable for CPR4 controllers
|
||||||
|
* that manage LDO300 supply regulator.
|
||||||
* @sdelta: The CPR4 controller specific data for this corner. This
|
* @sdelta: The CPR4 controller specific data for this corner. This
|
||||||
* field is applicable for CPR4 controllers.
|
* field is applicable for CPR4 controllers.
|
||||||
*
|
*
|
||||||
|
@ -174,6 +177,7 @@ struct cpr3_corner {
|
||||||
u32 irq_en;
|
u32 irq_en;
|
||||||
int aging_derate;
|
int aging_derate;
|
||||||
bool use_open_loop;
|
bool use_open_loop;
|
||||||
|
bool ldo_mode_allowed;
|
||||||
struct cpr4_sdelta *sdelta;
|
struct cpr4_sdelta *sdelta;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -192,6 +196,18 @@ struct cprh_corner_band {
|
||||||
struct cpr4_sdelta *sdelta;
|
struct cpr4_sdelta *sdelta;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum cpr3_ldo_type - Constants which define the LDO supply regulator
|
||||||
|
* types used to manage the subsystem component rail voltage.
|
||||||
|
* %CPR3_LDO_KRYO: Kryo LDO regulator used to sub-regulate the HMSS
|
||||||
|
* per-cluster voltage.
|
||||||
|
* %CPR3_LDO300: LDO regulator used to sub-regulate the GFX voltage.
|
||||||
|
*/
|
||||||
|
enum cpr3_ldo_type {
|
||||||
|
CPR3_LDO_KRYO = 0,
|
||||||
|
CPR3_LDO300 = 1,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct cpr3_regulator - CPR3 logical regulator instance associated with a
|
* struct cpr3_regulator - CPR3 logical regulator instance associated with a
|
||||||
* given CPR3 hardware thread
|
* given CPR3 hardware thread
|
||||||
|
@ -275,6 +291,7 @@ struct cprh_corner_band {
|
||||||
* participated in the last aggregation event
|
* participated in the last aggregation event
|
||||||
* @debug_corner: Index identifying voltage corner used for displaying
|
* @debug_corner: Index identifying voltage corner used for displaying
|
||||||
* corner configuration values in debugfs
|
* corner configuration values in debugfs
|
||||||
|
* @ldo_type: LDO regulator type.
|
||||||
* @ldo_min_headroom_volt: Minimum voltage difference in microvolts required
|
* @ldo_min_headroom_volt: Minimum voltage difference in microvolts required
|
||||||
* between the VDD supply voltage and the LDO output in
|
* between the VDD supply voltage and the LDO output in
|
||||||
* order for the LDO operate
|
* order for the LDO operate
|
||||||
|
@ -358,6 +375,7 @@ struct cpr3_regulator {
|
||||||
int last_closed_loop_corner;
|
int last_closed_loop_corner;
|
||||||
bool aggregated;
|
bool aggregated;
|
||||||
int debug_corner;
|
int debug_corner;
|
||||||
|
enum cpr3_ldo_type ldo_type;
|
||||||
int ldo_min_headroom_volt;
|
int ldo_min_headroom_volt;
|
||||||
int ldo_max_headroom_volt;
|
int ldo_max_headroom_volt;
|
||||||
int ldo_adjust_volt;
|
int ldo_adjust_volt;
|
||||||
|
@ -715,6 +733,8 @@ struct cpr3_panic_regs_info {
|
||||||
* @panic_regs_info: Array of panic registers information which provides the
|
* @panic_regs_info: Array of panic registers information which provides the
|
||||||
* list of registers to dump when the device crashes.
|
* list of registers to dump when the device crashes.
|
||||||
* @panic_notifier: Notifier block registered to global panic notifier list.
|
* @panic_notifier: Notifier block registered to global panic notifier list.
|
||||||
|
* @support_ldo300_vreg: Boolean value which indicates that this CPR controller
|
||||||
|
* manages an underlying LDO regulator of type LDO300.
|
||||||
*
|
*
|
||||||
* This structure contains both configuration and runtime state data. The
|
* This structure contains both configuration and runtime state data. The
|
||||||
* elements cpr_allowed_sw, use_hw_closed_loop, aggr_corner, cpr_enabled,
|
* elements cpr_allowed_sw, use_hw_closed_loop, aggr_corner, cpr_enabled,
|
||||||
|
@ -815,6 +835,7 @@ struct cpr3_controller {
|
||||||
u32 voltage_settling_time;
|
u32 voltage_settling_time;
|
||||||
struct cpr3_panic_regs_info *panic_regs_info;
|
struct cpr3_panic_regs_info *panic_regs_info;
|
||||||
struct notifier_block panic_notifier;
|
struct notifier_block panic_notifier;
|
||||||
|
bool support_ldo300_vreg;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Used for rounding voltages to the closest physically available set point. */
|
/* Used for rounding voltages to the closest physically available set point. */
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <linux/regulator/driver.h>
|
#include <linux/regulator/driver.h>
|
||||||
#include <linux/regulator/machine.h>
|
#include <linux/regulator/machine.h>
|
||||||
#include <linux/regulator/of_regulator.h>
|
#include <linux/regulator/of_regulator.h>
|
||||||
#include <linux/regulator/kryo-regulator.h>
|
#include <linux/regulator/msm-ldo-regulator.h>
|
||||||
|
|
||||||
#include <soc/qcom/spm.h>
|
#include <soc/qcom/spm.h>
|
||||||
|
|
||||||
|
@ -89,9 +89,9 @@ struct kryo_regulator {
|
||||||
struct regulator_dev *retention_rdev;
|
struct regulator_dev *retention_rdev;
|
||||||
struct regulator_desc retention_desc;
|
struct regulator_desc retention_desc;
|
||||||
const char *name;
|
const char *name;
|
||||||
enum kryo_supply_mode mode;
|
enum msm_ldo_supply_mode mode;
|
||||||
enum kryo_supply_mode retention_mode;
|
enum msm_ldo_supply_mode retention_mode;
|
||||||
enum kryo_supply_mode pre_lpm_state_mode;
|
enum msm_ldo_supply_mode pre_lpm_state_mode;
|
||||||
void __iomem *reg_base;
|
void __iomem *reg_base;
|
||||||
void __iomem *pm_apcc_base;
|
void __iomem *pm_apcc_base;
|
||||||
struct dentry *debugfs;
|
struct dentry *debugfs;
|
||||||
|
@ -248,7 +248,7 @@ static int kryo_set_ldo_volt(struct kryo_regulator *kvreg, int volt)
|
||||||
|
|
||||||
/* Locks must be held by the caller */
|
/* Locks must be held by the caller */
|
||||||
static int kryo_configure_mode(struct kryo_regulator *kvreg,
|
static int kryo_configure_mode(struct kryo_regulator *kvreg,
|
||||||
enum kryo_supply_mode mode)
|
enum msm_ldo_supply_mode mode)
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
int timeout = PWR_GATE_SWITCH_TIMEOUT_US;
|
int timeout = PWR_GATE_SWITCH_TIMEOUT_US;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -11,22 +11,22 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __KRYO_REGULATOR_H__
|
#ifndef __MSM_LDO_REGULATOR_H__
|
||||||
#define __KRYO_REGULATOR_H__
|
#define __MSM_LDO_REGULATOR_H__
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum kryo_supply_mode - supported operating modes by this regulator type.
|
* enum msm_ldo_supply_mode - supported operating modes by this regulator type.
|
||||||
* Use negative logic to ensure BHS mode is treated as the safe default by the
|
* Use negative logic to ensure BHS mode is treated as the safe default by the
|
||||||
* the regulator framework. This is necessary since LDO mode can only be enabled
|
* the regulator framework. This is necessary since LDO mode can only be enabled
|
||||||
* when several constraints are satisfied. Consumers of this regulator are
|
* when several constraints are satisfied. Consumers of this regulator are
|
||||||
* expected to request changes in operating modes through the use of
|
* expected to request changes in operating modes through the use of
|
||||||
* regulator_allow_bypass() passing in the desired Kryo supply mode.
|
* regulator_allow_bypass() passing in the desired LDO supply mode.
|
||||||
* %BHS_MODE: to select BHS as operating mode
|
* %BHS_MODE: to select BHS as operating mode
|
||||||
* %LDO_MODE: to select LDO as operating mode
|
* %LDO_MODE: to select LDO as operating mode
|
||||||
*/
|
*/
|
||||||
enum kryo_supply_mode {
|
enum msm_ldo_supply_mode {
|
||||||
BHS_MODE = false,
|
BHS_MODE = false,
|
||||||
LDO_MODE = true,
|
LDO_MODE = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __KRYO_REGULATOR_H__ */
|
#endif /* __MSM_LDO_REGULATOR_H__ */
|
Loading…
Add table
Reference in a new issue