mirror of
https://github.com/LineageOS/android_kernel_samsung_msm8226.git
synced 2026-09-29 00:00:25 +02:00
Merge "msm: krait-regulator: use phase management for v2"
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
commit
ca403ce99c
@@ -1,5 +1,20 @@
|
||||
Krait Voltage regulators
|
||||
|
||||
The cpus are powered using a single supply powered by PMIC ganged regulators operating in
|
||||
different phases. Individual kraits further can draw power from the single supply via
|
||||
a LDO or a head switch (BHS). The first level node represents the PMIC ganged regulator
|
||||
and its properties and encompasses second level nodes that represent the individual
|
||||
krait LDO/BHS control regulator.
|
||||
|
||||
[First Level Nodes]
|
||||
Required properties:
|
||||
- compatible: Must be "qcom,krait-pdn"
|
||||
|
||||
Optional properties:
|
||||
- qcom,use-phase-switching indicates whether the driver should add/shed phases on the PMIC
|
||||
ganged regulator as cpus are hotplugged.
|
||||
|
||||
[Second Level Nodes]
|
||||
Required properties:
|
||||
- compatible: Must be "qcom,krait-regulator"
|
||||
- reg: Specifies the address and size for this regulator device,
|
||||
@@ -27,19 +42,26 @@ Any property defined as part of the core regulator
|
||||
binding, defined in regulator.txt, can also be used.
|
||||
|
||||
Example:
|
||||
krait0_vreg: regulator@f9088000 {
|
||||
compatible = "qcom,krait-regulator";
|
||||
regulator-name = "krait0";
|
||||
reg = <0xf9088000 0x1000>, /* APCS_ALIAS0_KPSS_ACS */
|
||||
<0xf908a800 0x1000>; /* APCS_ALIAS0_KPSS_MDD */
|
||||
reg-names = "acs", "mdd";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
qcom,headroom-voltage = <150000>;
|
||||
qcom,retention-voltage = <745000>;
|
||||
qcom,ldo-default-voltage = <745000>;
|
||||
qcom,ldo-threshold-voltage = <750000>;
|
||||
qcom,ldo-delta-voltage = <50000>;
|
||||
qcom,cpu-num = 0;
|
||||
};
|
||||
krait_pdn: krait-pdn {
|
||||
compatible = "qcom,krait-pdn";
|
||||
qcom,use-phase-switching;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
krait0_vreg: regulator@f9088000 {
|
||||
compatible = "qcom,krait-regulator";
|
||||
regulator-name = "krait0";
|
||||
reg = <0xf9088000 0x1000>, /* APCS_ALIAS0_KPSS_ACS */
|
||||
<0xf908a800 0x1000>; /* APCS_ALIAS0_KPSS_MDD */
|
||||
reg-names = "acs", "mdd";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
qcom,headroom-voltage = <150000>;
|
||||
qcom,retention-voltage = <675000>;
|
||||
qcom,ldo-default-voltage = <750000>;
|
||||
qcom,ldo-threshold-voltage = <850000>;
|
||||
qcom,ldo-delta-voltage = <50000>;
|
||||
qcom,cpu-num = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -423,68 +423,75 @@
|
||||
};
|
||||
|
||||
/ {
|
||||
krait0_vreg: regulator@f9088000 {
|
||||
compatible = "qcom,krait-regulator";
|
||||
regulator-name = "krait0";
|
||||
reg = <0xf9088000 0x1000>, /* APCS_ALIAS0_KPSS_ACS */
|
||||
<0xf908a800 0x1000>; /* APCS_ALIAS0_KPSS_MDD */
|
||||
reg-names = "acs", "mdd";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
qcom,headroom-voltage = <150000>;
|
||||
qcom,retention-voltage = <675000>;
|
||||
qcom,ldo-default-voltage = <750000>;
|
||||
qcom,ldo-threshold-voltage = <850000>;
|
||||
qcom,ldo-delta-voltage = <50000>;
|
||||
qcom,cpu-num = <0>;
|
||||
};
|
||||
krait_pdn: krait-pdn {
|
||||
compatible = "qcom,krait-pdn";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
krait1_vreg: regulator@f9098000 {
|
||||
compatible = "qcom,krait-regulator";
|
||||
regulator-name = "krait1";
|
||||
reg = <0xf9098000 0x1000>, /* APCS_ALIAS1_KPSS_ACS */
|
||||
<0xf909a800 0x1000>; /* APCS_ALIAS1_KPSS_MDD */
|
||||
reg-names = "acs", "mdd";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
qcom,headroom-voltage = <150000>;
|
||||
qcom,retention-voltage = <675000>;
|
||||
qcom,ldo-default-voltage = <750000>;
|
||||
qcom,ldo-threshold-voltage = <850000>;
|
||||
qcom,ldo-delta-voltage = <50000>;
|
||||
qcom,cpu-num = <1>;
|
||||
};
|
||||
krait0_vreg: regulator@f9088000 {
|
||||
compatible = "qcom,krait-regulator";
|
||||
regulator-name = "krait0";
|
||||
reg = <0xf9088000 0x1000>, /* APCS_ALIAS0_KPSS_ACS */
|
||||
<0xf908a800 0x1000>; /* APCS_ALIAS0_KPSS_MDD */
|
||||
reg-names = "acs", "mdd";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
qcom,headroom-voltage = <150000>;
|
||||
qcom,retention-voltage = <675000>;
|
||||
qcom,ldo-default-voltage = <750000>;
|
||||
qcom,ldo-threshold-voltage = <850000>;
|
||||
qcom,ldo-delta-voltage = <50000>;
|
||||
qcom,cpu-num = <0>;
|
||||
};
|
||||
|
||||
krait2_vreg: regulator@f90a8000 {
|
||||
compatible = "qcom,krait-regulator";
|
||||
regulator-name = "krait2";
|
||||
reg = <0xf90a8000 0x1000>, /* APCS_ALIAS2_KPSS_ACS */
|
||||
<0xf90aa800 0x1000>; /* APCS_ALIAS2_KPSS_MDD */
|
||||
reg-names = "acs", "mdd";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
qcom,headroom-voltage = <150000>;
|
||||
qcom,retention-voltage = <675000>;
|
||||
qcom,ldo-default-voltage = <750000>;
|
||||
qcom,ldo-threshold-voltage = <850000>;
|
||||
qcom,ldo-delta-voltage = <50000>;
|
||||
qcom,cpu-num = <2>;
|
||||
};
|
||||
krait1_vreg: regulator@f9098000 {
|
||||
compatible = "qcom,krait-regulator";
|
||||
regulator-name = "krait1";
|
||||
reg = <0xf9098000 0x1000>, /* APCS_ALIAS1_KPSS_ACS */
|
||||
<0xf909a800 0x1000>; /* APCS_ALIAS1_KPSS_MDD */
|
||||
reg-names = "acs", "mdd";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
qcom,headroom-voltage = <150000>;
|
||||
qcom,retention-voltage = <675000>;
|
||||
qcom,ldo-default-voltage = <750000>;
|
||||
qcom,ldo-threshold-voltage = <850000>;
|
||||
qcom,ldo-delta-voltage = <50000>;
|
||||
qcom,cpu-num = <1>;
|
||||
};
|
||||
|
||||
krait3_vreg: regulator@f90b8000 {
|
||||
compatible = "qcom,krait-regulator";
|
||||
regulator-name = "krait3";
|
||||
reg = <0xf90b8000 0x1000>, /* APCS_ALIAS3_KPSS_ACS */
|
||||
<0xf90ba800 0x1000>; /* APCS_ALIAS3_KPSS_MDD */
|
||||
reg-names = "acs", "mdd";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
qcom,headroom-voltage = <150000>;
|
||||
qcom,retention-voltage = <675000>;
|
||||
qcom,ldo-default-voltage = <750000>;
|
||||
qcom,ldo-threshold-voltage = <850000>;
|
||||
qcom,ldo-delta-voltage = <50000>;
|
||||
qcom,cpu-num = <3>;
|
||||
krait2_vreg: regulator@f90a8000 {
|
||||
compatible = "qcom,krait-regulator";
|
||||
regulator-name = "krait2";
|
||||
reg = <0xf90a8000 0x1000>, /* APCS_ALIAS2_KPSS_ACS */
|
||||
<0xf90aa800 0x1000>; /* APCS_ALIAS2_KPSS_MDD */
|
||||
reg-names = "acs", "mdd";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
qcom,headroom-voltage = <150000>;
|
||||
qcom,retention-voltage = <675000>;
|
||||
qcom,ldo-default-voltage = <750000>;
|
||||
qcom,ldo-threshold-voltage = <850000>;
|
||||
qcom,ldo-delta-voltage = <50000>;
|
||||
qcom,cpu-num = <2>;
|
||||
};
|
||||
|
||||
krait3_vreg: regulator@f90b8000 {
|
||||
compatible = "qcom,krait-regulator";
|
||||
regulator-name = "krait3";
|
||||
reg = <0xf90b8000 0x1000>, /* APCS_ALIAS3_KPSS_ACS */
|
||||
<0xf90ba800 0x1000>; /* APCS_ALIAS3_KPSS_MDD */
|
||||
reg-names = "acs", "mdd";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
qcom,headroom-voltage = <150000>;
|
||||
qcom,retention-voltage = <675000>;
|
||||
qcom,ldo-default-voltage = <750000>;
|
||||
qcom,ldo-threshold-voltage = <850000>;
|
||||
qcom,ldo-delta-voltage = <50000>;
|
||||
qcom,cpu-num = <3>;
|
||||
};
|
||||
};
|
||||
|
||||
spi_eth_vreg: spi_eth_phy_vreg {
|
||||
|
||||
@@ -111,3 +111,7 @@
|
||||
<2024000 1212000>,
|
||||
<2132000 1279000>;
|
||||
};
|
||||
|
||||
&krait_pdn {
|
||||
qcom,use-phase-switching;
|
||||
};
|
||||
|
||||
@@ -155,6 +155,7 @@ struct pmic_gang_vreg {
|
||||
bool pfm_mode;
|
||||
int pmic_min_uV_for_retention;
|
||||
bool retention_enabled;
|
||||
bool use_phase_switching;
|
||||
};
|
||||
|
||||
static struct pmic_gang_vreg *the_gang;
|
||||
@@ -390,13 +391,17 @@ static int switch_to_using_ldo(struct krait_power_vreg *kvreg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_pmic_gang_phases(int phase_count)
|
||||
static int set_pmic_gang_phases(struct pmic_gang_vreg *pvreg, int phase_count)
|
||||
{
|
||||
/*
|
||||
* TODO : spm writes for phase control,
|
||||
* pmic phase control is not working yet
|
||||
*/
|
||||
return 0;
|
||||
pr_debug("programming phase_count = %d\n", phase_count);
|
||||
if (pvreg->use_phase_switching)
|
||||
/*
|
||||
* note the PMIC sets the phase count to one more than
|
||||
* the value in the register - hence subtract 1 from it
|
||||
*/
|
||||
return msm_spm_apcs_set_phase(phase_count - 1);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_pmic_gang_voltage(struct pmic_gang_vreg *pvreg, int uV)
|
||||
@@ -547,14 +552,19 @@ static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
|
||||
int load_uA)
|
||||
{
|
||||
struct pmic_gang_vreg *pvreg = from->pvreg;
|
||||
int phase_count = DIV_ROUND_UP(load_uA, LOAD_PER_PHASE) - 1;
|
||||
int phase_count = DIV_ROUND_UP(load_uA, LOAD_PER_PHASE);
|
||||
int rc = 0;
|
||||
|
||||
if (phase_count < 0)
|
||||
phase_count = 0;
|
||||
if (phase_count <= 0)
|
||||
phase_count = 1;
|
||||
|
||||
/* Increase phases if it is less than the number of cpus online */
|
||||
if (phase_count < num_online_cpus()) {
|
||||
phase_count = num_online_cpus();
|
||||
}
|
||||
|
||||
if (phase_count != pvreg->pmic_phase_count) {
|
||||
rc = set_pmic_gang_phases(phase_count);
|
||||
rc = set_pmic_gang_phases(pvreg, phase_count);
|
||||
if (rc < 0) {
|
||||
dev_err(&from->rdev->dev,
|
||||
"%s failed set phase %d rc = %d\n",
|
||||
@@ -577,32 +587,6 @@ static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __devinit pvreg_init(struct platform_device *pdev)
|
||||
{
|
||||
struct pmic_gang_vreg *pvreg;
|
||||
|
||||
pvreg = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct pmic_gang_vreg), GFP_KERNEL);
|
||||
if (!pvreg) {
|
||||
pr_err("kzalloc failed.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pvreg->name = "pmic_gang";
|
||||
pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
|
||||
pvreg->pmic_phase_count = 1;
|
||||
pvreg->retention_enabled = true;
|
||||
pvreg->pmic_min_uV_for_retention = INT_MAX;
|
||||
|
||||
mutex_init(&pvreg->krait_power_vregs_lock);
|
||||
INIT_LIST_HEAD(&pvreg->krait_power_vregs);
|
||||
the_gang = pvreg;
|
||||
|
||||
pr_debug("name=%s inited\n", pvreg->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int krait_power_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
|
||||
@@ -925,24 +909,6 @@ static int __devinit krait_power_probe(struct platform_device *pdev)
|
||||
int ldo_delta_uV;
|
||||
int cpu_num;
|
||||
|
||||
/* Initialize the pmic gang if it hasn't been initialized already */
|
||||
if (the_gang == NULL) {
|
||||
rc = pvreg_init(pdev);
|
||||
if (rc < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to init pmic gang rc = %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
/* global initializtion */
|
||||
glb_init(pdev);
|
||||
}
|
||||
|
||||
if (dent == NULL) {
|
||||
dent = debugfs_create_dir(KRAIT_REGULATOR_DRIVER_NAME, NULL);
|
||||
debugfs_create_file("retention_uV",
|
||||
0644, dent, the_gang, &retention_fops);
|
||||
}
|
||||
|
||||
if (pdev->dev.of_node) {
|
||||
/* Get init_data from device tree. */
|
||||
init_data = of_get_regulator_init_data(&pdev->dev,
|
||||
@@ -1139,14 +1105,93 @@ static struct platform_driver krait_power_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct of_device_id krait_pdn_match_table[] = {
|
||||
{ .compatible = "qcom,krait-pdn", },
|
||||
{}
|
||||
};
|
||||
|
||||
static int __devinit krait_pdn_probe(struct platform_device *pdev)
|
||||
{
|
||||
int rc;
|
||||
bool use_phase_switching = false;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct pmic_gang_vreg *pvreg;
|
||||
|
||||
if (!dev->of_node) {
|
||||
dev_err(dev, "device tree information missing\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
use_phase_switching = of_property_read_bool(node,
|
||||
"qcom,use-phase-switching");
|
||||
pvreg = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct pmic_gang_vreg), GFP_KERNEL);
|
||||
if (!pvreg) {
|
||||
pr_err("kzalloc failed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pvreg->name = "pmic_gang";
|
||||
pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
|
||||
pvreg->pmic_phase_count = -EINVAL;
|
||||
pvreg->retention_enabled = true;
|
||||
pvreg->pmic_min_uV_for_retention = INT_MAX;
|
||||
pvreg->use_phase_switching = use_phase_switching;
|
||||
|
||||
mutex_init(&pvreg->krait_power_vregs_lock);
|
||||
INIT_LIST_HEAD(&pvreg->krait_power_vregs);
|
||||
the_gang = pvreg;
|
||||
|
||||
pr_debug("name=%s inited\n", pvreg->name);
|
||||
|
||||
/* global initializtion */
|
||||
glb_init(pdev);
|
||||
|
||||
rc = of_platform_populate(node, NULL, NULL, dev);
|
||||
if (rc) {
|
||||
dev_err(dev, "failed to add child nodes, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
dent = debugfs_create_dir(KRAIT_REGULATOR_DRIVER_NAME, NULL);
|
||||
debugfs_create_file("retention_uV",
|
||||
0644, dent, the_gang, &retention_fops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit krait_pdn_remove(struct platform_device *pdev)
|
||||
{
|
||||
the_gang = NULL;
|
||||
debugfs_remove_recursive(dent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver krait_pdn_driver = {
|
||||
.probe = krait_pdn_probe,
|
||||
.remove = __devexit_p(krait_pdn_remove),
|
||||
.driver = {
|
||||
.name = KRAIT_PDN_DRIVER_NAME,
|
||||
.of_match_table = krait_pdn_match_table,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int __init krait_power_init(void)
|
||||
{
|
||||
return platform_driver_register(&krait_power_driver);
|
||||
int rc = platform_driver_register(&krait_power_driver);
|
||||
if (rc) {
|
||||
pr_err("failed to add %s driver rc = %d\n",
|
||||
KRAIT_REGULATOR_DRIVER_NAME, rc);
|
||||
return rc;
|
||||
}
|
||||
return platform_driver_register(&krait_pdn_driver);
|
||||
}
|
||||
|
||||
static void __exit krait_power_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&krait_power_driver);
|
||||
platform_driver_unregister(&krait_pdn_driver);
|
||||
}
|
||||
module_exit(krait_power_exit);
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#ifndef __KRAIT_REGULATOR_H__
|
||||
#define __KRAIT_REGULATOR_H__
|
||||
|
||||
#define KRAIT_REGULATOR_DRIVER_NAME "krait-power-regulator"
|
||||
#define KRAIT_REGULATOR_DRIVER_NAME "krait-power-regulator"
|
||||
#define KRAIT_PDN_DRIVER_NAME "krait-pdn"
|
||||
|
||||
/**
|
||||
* krait_power_init - driver initialization function
|
||||
|
||||
Reference in New Issue
Block a user