soc: cpu_pwr_ctl: Add 8976 cpu retention ldo configure support
Add support to configure the performance cluster cpu retention ldo voltage. This value needs to be configured when a core is coldbooted. The core will then be able to enter retention at the programmed retention voltage. Change-Id: Idf46c31edfb2be7ce364070baea5550048301a14 Signed-off-by: Srinivas Rao L <lsrao@codeaurora.org>
This commit is contained in:
parent
5e453077d2
commit
11f4d90145
|
@ -0,0 +1,21 @@
|
|||
*8976 Perf-CPU LDO Retention Voltage Configuration
|
||||
|
||||
This device is used to program the appropriate LDO voltage for 8976 Performance cluster CPU's from the pre-programmed register.
|
||||
|
||||
Required properties:
|
||||
- compatible:
|
||||
Must be "qcom,8976-cpu-ldo-vref"
|
||||
- reg:
|
||||
The register holds the base address to LDO_BHS. Use this
|
||||
register base to configure the LDO for all the cpus.
|
||||
- qcom,ldo-vref-ret:
|
||||
Value to which the ldo voltage reference needs to be
|
||||
programmed.
|
||||
Value to be used is encoded. 0x9 = 0.5V and 0x10 = 0.55V
|
||||
|
||||
Example:
|
||||
ldo0:ldo-vref@b086000 {
|
||||
compatible = "qcom,8976-cpu-ldo-vref";
|
||||
reg = <0xb086000 0x40>,
|
||||
qcom,ldo-vref-ret = <0x9>;
|
||||
};
|
|
@ -126,6 +126,20 @@ static int __init msm_cpu_prepare(unsigned int cpu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init msm8976_cpu_prepare(unsigned int cpu)
|
||||
{
|
||||
int ret;
|
||||
u32 mpidr = cpu_logical_map(cpu);
|
||||
|
||||
if ((per_cpu(cold_boot_done, 0) == false)
|
||||
&& MPIDR_AFFINITY_LEVEL(mpidr, 1)) {
|
||||
ret = msm8976_cpu_ldo_config(0);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return msm_cpu_prepare(cpu);
|
||||
}
|
||||
|
||||
static int __init msm8994_cpu_prepare(unsigned int cpu)
|
||||
{
|
||||
|
@ -162,6 +176,7 @@ static int msm_cpu_boot(unsigned int cpu)
|
|||
static int msm8976_cpu_boot(unsigned int cpu)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 mpidr = cpu_logical_map(cpu);
|
||||
|
||||
if (per_cpu(cold_boot_done, cpu) == false) {
|
||||
if (of_board_is_sim()) {
|
||||
|
@ -173,6 +188,11 @@ static int msm8976_cpu_boot(unsigned int cpu)
|
|||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (MPIDR_AFFINITY_LEVEL(mpidr, 1)) {
|
||||
ret = msm8976_cpu_ldo_config(cpu);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
per_cpu(cold_boot_done, cpu) = true;
|
||||
}
|
||||
return secondary_pen_release(cpu);
|
||||
|
@ -266,7 +286,7 @@ CPU_METHOD_OF_DECLARE(msm8994_cortex_a_ops, &msm8994_cortex_a_ops);
|
|||
static const struct cpu_operations msm8976_cortex_a_ops = {
|
||||
.name = "qcom,8976-arm-cortex-acc",
|
||||
.cpu_init = msm_cpu_init,
|
||||
.cpu_prepare = msm_cpu_prepare,
|
||||
.cpu_prepare = msm8976_cpu_prepare,
|
||||
.cpu_boot = msm8976_cpu_boot,
|
||||
.cpu_postboot = msm_cpu_postboot,
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#define APC_LDO_CFG2 0x10
|
||||
#define APC_LDO_VREF_CFG 0x4
|
||||
#define APC_LDO_BHS_PWR_CTL 0x28
|
||||
#define APC_LDO_RDAC_CTL 0x34
|
||||
|
||||
/*
|
||||
* struct msm_l2ccc_of_info: represents of data for l2 cache clock controller.
|
||||
|
@ -571,6 +572,81 @@ out_acc:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int msm8976_cpu_ldo_config(unsigned int cpu)
|
||||
{
|
||||
struct device_node *cpu_node, *ldo_node;
|
||||
void __iomem *ldo_bhs_reg_base;
|
||||
u32 ldo_vref_ret = 0;
|
||||
u32 ref_val = 0;
|
||||
int ret = 0;
|
||||
u32 val;
|
||||
|
||||
cpu_node = of_get_cpu_node(cpu, NULL);
|
||||
if (!cpu_node)
|
||||
return -ENODEV;
|
||||
|
||||
ldo_node = of_parse_phandle(cpu_node, "qcom,ldo", 0);
|
||||
if (!ldo_node) {
|
||||
pr_debug("LDO is not configured to enable retention\n");
|
||||
goto exit_cpu_node;
|
||||
}
|
||||
|
||||
ldo_bhs_reg_base = of_iomap(ldo_node, 0);
|
||||
if (!ldo_bhs_reg_base) {
|
||||
pr_err("LDO configuration failed due to iomap failure\n");
|
||||
ret = -ENOMEM;
|
||||
goto exit_cpu_node;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(ldo_node, "qcom,ldo-vref-ret", &ref_val);
|
||||
if (ret) {
|
||||
pr_err("Failed to get LDO Reference voltage for CPU%u\n",
|
||||
cpu);
|
||||
ret = -ENOENT;
|
||||
goto exit_cpu_node;
|
||||
}
|
||||
|
||||
/* Bring LDO out of reset */
|
||||
ldo_vref_ret = readl_relaxed(ldo_bhs_reg_base + APC_LDO_VREF_CFG);
|
||||
ldo_vref_ret &= ~BIT(16);
|
||||
writel_relaxed(ldo_vref_ret, ldo_bhs_reg_base + APC_LDO_VREF_CFG);
|
||||
|
||||
val = readl_relaxed(ldo_bhs_reg_base + APC_LDO_CFG1);
|
||||
val = (val & 0xffffff00) | 0x90;
|
||||
writel_relaxed(val, ldo_bhs_reg_base + APC_LDO_CFG1);
|
||||
val = readl_relaxed(ldo_bhs_reg_base + APC_LDO_RDAC_CTL);
|
||||
val = (val & 0xffffff00) | 0x60;
|
||||
writel_relaxed(val, ldo_bhs_reg_base + APC_LDO_RDAC_CTL);
|
||||
|
||||
/* Program the retention voltage */
|
||||
ldo_vref_ret = readl_relaxed(ldo_bhs_reg_base + APC_LDO_VREF_CFG);
|
||||
ldo_vref_ret = (ldo_vref_ret & 0xffff80ff) | (ref_val << 8);
|
||||
writel_relaxed(ldo_vref_ret, ldo_bhs_reg_base + APC_LDO_VREF_CFG);
|
||||
|
||||
/* Write the sequence to latch on the LDO voltage */
|
||||
writel_relaxed(0x0, ldo_bhs_reg_base);
|
||||
writel_relaxed(0x1, ldo_bhs_reg_base);
|
||||
/* After writing 1 to the UPDATE register, '1 xo clk cycle' delay
|
||||
* is required for the update to take effect. This delay needs to
|
||||
* start after the reg write is complete. Make sure that the reg
|
||||
* write is complete using a memory barrier */
|
||||
mb();
|
||||
usleep(1);
|
||||
writel_relaxed(0x0, ldo_bhs_reg_base);
|
||||
/* Use a memory barrier to make sure the reg write is complete before
|
||||
* the node is unmapped. */
|
||||
mb();
|
||||
|
||||
of_node_put(ldo_node);
|
||||
|
||||
iounmap(ldo_bhs_reg_base);
|
||||
|
||||
exit_cpu_node:
|
||||
of_node_put(cpu_node);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void msm8976_unclamp_perf_cluster_cpu(void __iomem *reg)
|
||||
{
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ int msm_unclamp_secondary_arm_cpu(unsigned int cpu);
|
|||
int msm8994_unclamp_secondary_arm_cpu(unsigned int cpu);
|
||||
int msm8976_unclamp_secondary_arm_cpu(unsigned int cpu);
|
||||
int msm8994_cpu_ldo_config(unsigned int cpu);
|
||||
int msm8976_cpu_ldo_config(unsigned int cpu);
|
||||
#else
|
||||
static inline int msm_unclamp_secondary_arm_cpu_sim(unsigned int cpu)
|
||||
{
|
||||
|
@ -40,5 +41,9 @@ static inline int msm8994_cpu_ldo_config(unsigned int cpu)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int msm8976_cpu_ldo_config(unsigned int cpu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /*MSM_CPU_SUBSYS_H_*/
|
||||
|
|
Loading…
Reference in New Issue