msm: cpr: Enable CPR support for 8625

CPR (Core Power Reduction) helps save CPU power by
reducing the chip voltage whenever possible

Change-Id: Ifa32967046b4bb7f5b4f756feb9cefabe8f5bea4
Signed-off-by: Kaushal Kumar <kaushalk@codeaurora.org>
(cherry picked from commit c0e5d6768038efbe5fb98fcd935f01c8ce611e08)

Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
(cherry picked from commit 7c8192db2ee5a7edbf8ac9707e3d044efd213da3)
This commit is contained in:
Kaushal Kumar 2012-07-31 16:07:49 +05:30 committed by Stephen Boyd
parent b2c67334b8
commit b80e0d6446
3 changed files with 190 additions and 1 deletions

View file

@ -39,6 +39,8 @@
#include "mpm-8625.h"
#include "irq.h"
#include "pm.h"
#include "msm_cpr.h"
#include "msm_smem_iface.h"
/* Address of GSBI blocks */
#define MSM_GSBI0_PHYS 0xA1200000
@ -48,6 +50,12 @@
#define MSM_GSBI0_QUP_PHYS (MSM_GSBI0_PHYS + 0x80000)
#define MSM_GSBI1_QUP_PHYS (MSM_GSBI1_PHYS + 0x80000)
#define A11S_TEST_BUS_SEL_ADDR (MSM_CSR_BASE + 0x518)
#define RBCPR_CLK_MUX_SEL (1 << 13)
/* Reset Address of RBCPR (Active Low)*/
#define RBCPR_SW_RESET_N (MSM_CSR_BASE + 0x64)
static struct resource gsbi0_qup_i2c_resources[] = {
{
.name = "qup_phys_addr",
@ -1592,6 +1600,176 @@ struct platform_device msm8625_kgsl_3d0 = {
},
};
static struct resource cpr_resources[] = {
{
.start = MSM8625_INT_CPR_IRQ0,
.flags = IORESOURCE_IRQ,
},
{
.start = MSM8625_CPR_PHYS,
.end = MSM8625_CPR_PHYS + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
};
/**
* These are various Vdd levels supported by PMIC
*/
static uint32_t msm_c2_pmic_mv[] __initdata = {
1300, 12875 / 10, 1275, 12625 / 10, 1250,
12375 / 10, 1225, 12125 / 10, 1200, 11875 / 10,
1175, 11625 / 10, 1150, 11375 / 10, 1125,
11125 / 10, 1100, 10875 / 10, 1075, 10625 / 10,
1050, 10375 / 10, 1025, 10125 / 10, 0, 0, 0, 0,
0, 0, 0, 1000,
};
/**
* This data will be based on CPR mode of operation
*/
static struct msm_cpr_mode msm_cpr_mode_data[] = {
[NORMAL_MODE] = {
.ring_osc_data = {
{0, },
{0, },
{0, },
{0, },
{0, },
{0, },
{0, },
{0, },
},
.ring_osc = 0,
.step_quot = ~0,
.tgt_volt_offset = 1,
.Vmax = 1200,
.Vmin = 1000,
.calibrated_mV = 1100,
},
[TURBO_MODE] = {
.ring_osc_data = {
{0, },
{0, },
{0, },
{0, },
{0, },
{0, },
{0, },
{0, },
},
.ring_osc = 0,
.step_quot = ~0,
.tgt_volt_offset = 1,
.Vmax = 1350,
.Vmin = 1250,
.calibrated_mV = 1300,
},
};
struct msm_cpr_vp_data vp_data = {
.min_volt = 1000,
.max_volt = 1350,
.default_volt = 1300,
.step_size = (12500 / 1000),
};
static struct msm_cpr_config msm_cpr_pdata = {
.ref_clk_khz = 19200,
.delay_us = 10000,
.irq_line = 0,
.cpr_mode_data = msm_cpr_mode_data,
.tgt_count_div_N = 1,
.floor = 0,
.ceiling = 40,
.sw_vlevel = 20,
.up_threshold = 1,
.dn_threshold = 2,
.up_margin = 0,
.dn_margin = 0,
.nom_freq_limit = 1008000,
.vp_data = &vp_data,
};
static struct platform_device msm8625_device_cpr = {
.name = "msm-cpr",
.id = -1,
.num_resources = ARRAY_SIZE(cpr_resources),
.resource = cpr_resources,
.dev = {
.platform_data = &msm_cpr_pdata,
},
};
static struct platform_device msm8625_vp_device = {
.name = "vp-regulator",
.id = -1,
};
static void __init msm_cpr_init(void)
{
struct cpr_info_type *cpr_info = NULL;
uint8_t ring_osc = 0;
uint32_t reg_val;
cpr_info = kzalloc(sizeof(struct cpr_info_type), GFP_KERNEL);
if (!cpr_info) {
pr_err("%s: Out of memory %d\n", __func__, -ENOMEM);
return;
}
msm_smem_get_cpr_info(cpr_info);
/**
* Set the ring_osc based on efuse BIT(0)
* CPR_fuse[0] = 0 selects 2nd RO (010)
* CPR_fuse[0] = 1 select 3rd RO (011)
*/
if (cpr_info->ring_osc == 0x0)
ring_osc = 0x2;
else if (cpr_info->ring_osc == 0x1)
ring_osc = 0x3;
msm_cpr_mode_data[TURBO_MODE].ring_osc = ring_osc;
msm_cpr_mode_data[NORMAL_MODE].ring_osc = ring_osc;
/* GCNT = 1000 nsec/52nsec (@TCX0=19.2Mhz) = 19.2 */
msm_cpr_mode_data[TURBO_MODE].ring_osc_data[ring_osc].gcnt = 19;
msm_cpr_mode_data[NORMAL_MODE].ring_osc_data[ring_osc].gcnt = 19;
/* The multiplier and offset are as per PTE data */
msm_cpr_mode_data[TURBO_MODE].ring_osc_data[ring_osc].target_count =
cpr_info->turbo_quot * 10 + 440;
msm_cpr_mode_data[NORMAL_MODE].ring_osc_data[ring_osc].target_count =
cpr_info->turbo_quot / msm_cpr_pdata.tgt_count_div_N;
/**
* Bits 4:0 of pvs_fuse provide mapping to the safe boot up voltage.
* Boot up mode is by default Turbo.
*/
msm_cpr_mode_data[TURBO_MODE].calibrated_mV =
msm_c2_pmic_mv[cpr_info->pvs_fuse & 0x1F];
/* TODO: Store the tgt_volt_offset values for the modes from PTE */
pr_debug("%s: cpr: ring_osc: 0x%x\n", __func__,
msm_cpr_mode_data[TURBO_MODE].ring_osc);
pr_debug("%s: cpr: turbo_quot: 0x%x\n", __func__, cpr_info->turbo_quot);
pr_debug("%s: cpr: pvs_fuse: 0x%x\n", __func__, cpr_info->pvs_fuse);
kfree(cpr_info);
/* Select TCXO (19.2MHz) as clock source */
reg_val = readl_relaxed(A11S_TEST_BUS_SEL_ADDR);
reg_val |= RBCPR_CLK_MUX_SEL;
writel_relaxed(reg_val, A11S_TEST_BUS_SEL_ADDR);
/* Get CPR out of reset */
writel_relaxed(0x1, RBCPR_SW_RESET_N);
platform_device_register(&msm8625_vp_device);
platform_device_register(&msm8625_device_cpr);
}
static struct clk_lookup msm_clock_8625_dummy[] = {
CLK_DUMMY("core_clk", adm_clk.c, "msm_dmov", 0),
CLK_DUMMY("adsp_clk", adsp_clk.c, NULL, 0),
@ -1658,7 +1836,6 @@ struct clock_init_data msm8625_dummy_clock_init_data __initdata = {
.table = msm_clock_8625_dummy,
.size = ARRAY_SIZE(msm_clock_8625_dummy),
};
enum {
MSM8625,
MSM8625A,
@ -1704,6 +1881,7 @@ int __init msm7x2x_misc_init(void)
{
if (machine_is_msm8625_rumi3()) {
msm_clock_init(&msm8625_dummy_clock_init_data);
msm_cpr_init();
return 0;
}
@ -1720,6 +1898,11 @@ int __init msm7x2x_misc_init(void)
} else {
platform_device_register(&msm7x27a_device_acpuclk);
}
if (cpu_is_msm8625() &&
(SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2))
msm_cpr_init();
return 0;
}

View file

@ -84,6 +84,9 @@
#define MSM8625_INT_L2CC_EM (GIC_SPI_START + 32 + 22)
#define MSM8625_INT_L2CC_INTR (GIC_SPI_START + 32 + 23)
#define MSM8625_INT_CE_IRQ (GIC_SPI_START + 32 + 24)
#define MSM8625_INT_CPR_IRQ0 (GIC_SPI_START + 32 + 25)
#define MSM8625_INT_CPR_IRQ1 (GIC_SPI_START + 32 + 26)
#define MSM8625_INT_CPR_IRQ2 (GIC_SPI_START + 32 + 27)
#define MSM8625_INT_ADSP_A11_SMSM MSM8625_INT_ADSP_A11
#endif

View file

@ -57,4 +57,7 @@
#define MSM8625_CFG_CTL_PHYS 0xA9800000
#define MSM8625_CFG_CTL_SIZE SZ_4K
#define MSM8625_CPR_PHYS 0xC0900000
#define MSM8625_CPR_SIZE SZ_4K
#endif