Merge "clk: msm: clock-osm: update register initialization for msmcobalt v2"

This commit is contained in:
Linux Build Service Account 2016-09-09 11:53:18 -07:00 committed by Gerrit - the friendly Code Review server
commit 5ea20de3a5
4 changed files with 87 additions and 40 deletions

View file

@ -9,7 +9,8 @@ Properties:
- compatible - compatible
Usage: required Usage: required
Value type: <string> Value type: <string>
Definition: must be "qcom,cpu-clock-osm". Definition: must be "qcom,cpu-clock-osm-msmcobalt-v1" or
"qcom,cpu-clock-osm-msmcobalt-v2".
- reg - reg
Usage: required Usage: required
@ -299,7 +300,7 @@ Properties:
Example: Example:
clock_cpu: qcom,cpu-clock-cobalt@179c0000 { clock_cpu: qcom,cpu-clock-cobalt@179c0000 {
compatible = "qcom,cpu-clock-osm"; compatible = "qcom,cpu-clock-osm-msmcobalt-v1";
reg = <0x179C0000 0x4000>, reg = <0x179C0000 0x4000>,
<0x17916000 0x1000>, <0x17916000 0x1000>,
<0x17816000 0x1000>, <0x17816000 0x1000>,

View file

@ -24,6 +24,8 @@
}; };
&clock_cpu { &clock_cpu {
compatible = "qcom,cpu-clock-osm-msmcobalt-v2";
/delete-property/ qcom,llm-sw-overr;
qcom,pwrcl-speedbin0-v0 = qcom,pwrcl-speedbin0-v0 =
< 300000000 0x0004000f 0x01200020 0x1 >, < 300000000 0x0004000f 0x01200020 0x1 >,
< 364800000 0x05040013 0x01200020 0x1 >, < 364800000 0x05040013 0x01200020 0x1 >,

View file

@ -803,7 +803,7 @@
}; };
clock_cpu: qcom,cpu-clock-cobalt@179c0000 { clock_cpu: qcom,cpu-clock-cobalt@179c0000 {
compatible = "qcom,cpu-clock-osm"; compatible = "qcom,cpu-clock-osm-msmcobalt-v1";
reg = <0x179c0000 0x4000>, reg = <0x179c0000 0x4000>,
<0x17916000 0x1000>, <0x17916000 0x1000>,
<0x17816000 0x1000>, <0x17816000 0x1000>,

View file

@ -77,6 +77,7 @@ enum clk_osm_trace_packet_id {
#define MEM_ACC_SEQ_CONST(n) (n) #define MEM_ACC_SEQ_CONST(n) (n)
#define MEM_ACC_INSTR_COMP(n) (0x67 + ((n) * 0x40)) #define MEM_ACC_INSTR_COMP(n) (0x67 + ((n) * 0x40))
#define MEM_ACC_SEQ_REG_VAL_START(n) (SEQ_REG(60 + (n))) #define MEM_ACC_SEQ_REG_VAL_START(n) (SEQ_REG(60 + (n)))
#define SEQ_REG1_MSMCOBALT_V2 0x1048
#define OSM_TABLE_SIZE 40 #define OSM_TABLE_SIZE 40
#define MAX_CLUSTER_CNT 2 #define MAX_CLUSTER_CNT 2
@ -116,7 +117,7 @@ enum clk_osm_trace_packet_id {
#define PLL_TEST_CTL_HI 0x1C #define PLL_TEST_CTL_HI 0x1C
#define PLL_STATUS 0x2C #define PLL_STATUS 0x2C
#define PLL_LOCK_DET_MASK BIT(16) #define PLL_LOCK_DET_MASK BIT(16)
#define PLL_WAIT_LOCK_TIME_US 5 #define PLL_WAIT_LOCK_TIME_US 10
#define PLL_WAIT_LOCK_TIME_NS (PLL_WAIT_LOCK_TIME_US * 1000) #define PLL_WAIT_LOCK_TIME_NS (PLL_WAIT_LOCK_TIME_US * 1000)
#define PLL_MIN_LVAL 43 #define PLL_MIN_LVAL 43
@ -165,7 +166,8 @@ enum clk_osm_trace_packet_id {
#define DCVS_DROOP_EN_MASK BIT(5) #define DCVS_DROOP_EN_MASK BIT(5)
#define LMH_PS_EN_MASK BIT(6) #define LMH_PS_EN_MASK BIT(6)
#define IGNORE_PLL_LOCK_MASK BIT(15) #define IGNORE_PLL_LOCK_MASK BIT(15)
#define SAFE_FREQ_WAIT_NS 1000 #define SAFE_FREQ_WAIT_NS 5000
#define DEXT_DECREMENT_WAIT_NS 1000
#define DCVS_BOOST_TIMER_REG0 0x1084 #define DCVS_BOOST_TIMER_REG0 0x1084
#define DCVS_BOOST_TIMER_REG1 0x1088 #define DCVS_BOOST_TIMER_REG1 0x1088
#define DCVS_BOOST_TIMER_REG2 0x108C #define DCVS_BOOST_TIMER_REG2 0x108C
@ -174,7 +176,8 @@ enum clk_osm_trace_packet_id {
#define PS_BOOST_TIMER_REG2 0x109C #define PS_BOOST_TIMER_REG2 0x109C
#define BOOST_PROG_SYNC_DELAY_REG 0x10A0 #define BOOST_PROG_SYNC_DELAY_REG 0x10A0
#define DROOP_CTRL_REG 0x10A4 #define DROOP_CTRL_REG 0x10A4
#define DROOP_PROG_SYNC_DELAY_REG 0x10B8 #define DROOP_RELEASE_TIMER_CTRL 0x10A8
#define DROOP_PROG_SYNC_DELAY_REG 0x10BC
#define DROOP_UNSTALL_TIMER_CTRL_REG 0x10AC #define DROOP_UNSTALL_TIMER_CTRL_REG 0x10AC
#define DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG 0x10B0 #define DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG 0x10B0
#define DROOP_WAIT_TO_RELEASE_TIMER_CTRL1_REG 0x10B4 #define DROOP_WAIT_TO_RELEASE_TIMER_CTRL1_REG 0x10B4
@ -342,6 +345,9 @@ struct clk_osm {
bool trace_en; bool trace_en;
}; };
static bool msmcobalt_v1;
static bool msmcobalt_v2;
static inline void clk_osm_masked_write_reg(struct clk_osm *c, u32 val, static inline void clk_osm_masked_write_reg(struct clk_osm *c, u32 val,
u32 offset, u32 mask) u32 offset, u32 mask)
{ {
@ -1665,6 +1671,9 @@ static void clk_osm_setup_osm_was(struct clk_osm *c)
u32 cc_hyst; u32 cc_hyst;
u32 val; u32 val;
if (msmcobalt_v2)
return;
val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG);
val |= IGNORE_PLL_LOCK_MASK; val |= IGNORE_PLL_LOCK_MASK;
cc_hyst = clk_osm_read_reg(c, SPM_CC_HYSTERESIS); cc_hyst = clk_osm_read_reg(c, SPM_CC_HYSTERESIS);
@ -1756,19 +1765,19 @@ static void clk_osm_setup_fsms(struct clk_osm *c)
if (c->boost_fsm_en) { if (c->boost_fsm_en) {
val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG);
clk_osm_write_reg(c, val | CC_BOOST_EN_MASK, PDN_FSM_CTRL_REG); clk_osm_write_reg(c, val | CC_BOOST_EN_MASK, PDN_FSM_CTRL_REG);
val = clk_osm_read_reg(c, CC_BOOST_TIMER_REG0); val = clk_osm_read_reg(c, CC_BOOST_TIMER_REG0);
val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS));
val |= BVAL(31, 16, clk_osm_count_ns(c, val |= BVAL(31, 16, clk_osm_count_ns(c, SAFE_FREQ_WAIT_NS));
SAFE_FREQ_WAIT_NS));
clk_osm_write_reg(c, val, CC_BOOST_TIMER_REG0); clk_osm_write_reg(c, val, CC_BOOST_TIMER_REG0);
val = clk_osm_read_reg(c, CC_BOOST_TIMER_REG1); val = clk_osm_read_reg(c, CC_BOOST_TIMER_REG1);
val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS));
val |= BVAL(31, 16, clk_osm_count_ns(c, SAFE_FREQ_WAIT_NS)); val |= BVAL(31, 16, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS));
clk_osm_write_reg(c, val, CC_BOOST_TIMER_REG1); clk_osm_write_reg(c, val, CC_BOOST_TIMER_REG1);
val = clk_osm_read_reg(c, CC_BOOST_TIMER_REG2); val = clk_osm_read_reg(c, CC_BOOST_TIMER_REG2);
val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); val |= BVAL(15, 0, clk_osm_count_ns(c, DEXT_DECREMENT_WAIT_NS));
clk_osm_write_reg(c, val, CC_BOOST_TIMER_REG2); clk_osm_write_reg(c, val, CC_BOOST_TIMER_REG2);
} }
@ -1779,12 +1788,19 @@ static void clk_osm_setup_fsms(struct clk_osm *c)
PDN_FSM_CTRL_REG); PDN_FSM_CTRL_REG);
val = clk_osm_read_reg(c, DCVS_BOOST_TIMER_REG0); val = clk_osm_read_reg(c, DCVS_BOOST_TIMER_REG0);
val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS));
val |= BVAL(31, 16, clk_osm_count_ns(c, SAFE_FREQ_WAIT_NS)); val |= BVAL(31, 16, clk_osm_count_ns(c, SAFE_FREQ_WAIT_NS));
clk_osm_write_reg(c, val, DCVS_BOOST_TIMER_REG0); clk_osm_write_reg(c, val, DCVS_BOOST_TIMER_REG0);
val = clk_osm_read_reg(c, DCVS_BOOST_TIMER_REG1); val = clk_osm_read_reg(c, DCVS_BOOST_TIMER_REG1);
val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS));
val |= BVAL(31, 16, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS));
clk_osm_write_reg(c, val, DCVS_BOOST_TIMER_REG1); clk_osm_write_reg(c, val, DCVS_BOOST_TIMER_REG1);
val = clk_osm_read_reg(c, DCVS_BOOST_TIMER_REG2);
val |= BVAL(15, 0, clk_osm_count_ns(c, DEXT_DECREMENT_WAIT_NS));
clk_osm_write_reg(c, val, DCVS_BOOST_TIMER_REG2);
} }
/* PS FSM */ /* PS FSM */
@ -1792,13 +1808,19 @@ static void clk_osm_setup_fsms(struct clk_osm *c)
val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG);
clk_osm_write_reg(c, val | PS_BOOST_EN_MASK, PDN_FSM_CTRL_REG); clk_osm_write_reg(c, val | PS_BOOST_EN_MASK, PDN_FSM_CTRL_REG);
val = clk_osm_read_reg(c, PS_BOOST_TIMER_REG0) | val = clk_osm_read_reg(c, PS_BOOST_TIMER_REG0);
BVAL(31, 16, clk_osm_count_ns(c, 1000)); val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS));
val |= BVAL(31, 16, clk_osm_count_ns(c, SAFE_FREQ_WAIT_NS));
clk_osm_write_reg(c, val, PS_BOOST_TIMER_REG0); clk_osm_write_reg(c, val, PS_BOOST_TIMER_REG0);
val = clk_osm_read_reg(c, PS_BOOST_TIMER_REG1) | val = clk_osm_read_reg(c, PS_BOOST_TIMER_REG1);
clk_osm_count_ns(c, 1000); val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS));
val |= BVAL(31, 16, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS));
clk_osm_write_reg(c, val, PS_BOOST_TIMER_REG1); clk_osm_write_reg(c, val, PS_BOOST_TIMER_REG1);
val = clk_osm_read_reg(c, PS_BOOST_TIMER_REG2);
val |= BVAL(15, 0, clk_osm_count_ns(c, DEXT_DECREMENT_WAIT_NS));
clk_osm_write_reg(c, val, PS_BOOST_TIMER_REG2);
} }
/* PLL signal timing control */ /* PLL signal timing control */
@ -1811,13 +1833,13 @@ static void clk_osm_setup_fsms(struct clk_osm *c)
val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG);
clk_osm_write_reg(c, val | WFX_DROOP_EN_MASK, PDN_FSM_CTRL_REG); clk_osm_write_reg(c, val | WFX_DROOP_EN_MASK, PDN_FSM_CTRL_REG);
val = clk_osm_read_reg(c, DROOP_UNSTALL_TIMER_CTRL_REG) | val = clk_osm_read_reg(c, DROOP_UNSTALL_TIMER_CTRL_REG);
BVAL(31, 16, clk_osm_count_ns(c, 1000)); val |= BVAL(31, 16, clk_osm_count_ns(c, 500));
clk_osm_write_reg(c, val, DROOP_UNSTALL_TIMER_CTRL_REG); clk_osm_write_reg(c, val, DROOP_UNSTALL_TIMER_CTRL_REG);
val = clk_osm_read_reg(c, val = clk_osm_read_reg(c,
DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG) | DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG);
BVAL(31, 16, clk_osm_count_ns(c, 1000)); val |= BVAL(31, 16, clk_osm_count_ns(c, 500));
clk_osm_write_reg(c, val, clk_osm_write_reg(c, val,
DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG); DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG);
} }
@ -1828,9 +1850,15 @@ static void clk_osm_setup_fsms(struct clk_osm *c)
clk_osm_write_reg(c, val | PC_RET_EXIT_DROOP_EN_MASK, clk_osm_write_reg(c, val | PC_RET_EXIT_DROOP_EN_MASK,
PDN_FSM_CTRL_REG); PDN_FSM_CTRL_REG);
val = clk_osm_read_reg(c, DROOP_UNSTALL_TIMER_CTRL_REG) | val = clk_osm_read_reg(c, DROOP_UNSTALL_TIMER_CTRL_REG);
BVAL(15, 0, clk_osm_count_ns(c, 5000)); val |= BVAL(15, 0, clk_osm_count_ns(c, 500));
clk_osm_write_reg(c, val, DROOP_UNSTALL_TIMER_CTRL_REG); clk_osm_write_reg(c, val, DROOP_UNSTALL_TIMER_CTRL_REG);
val = clk_osm_read_reg(c,
DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG);
val |= BVAL(15, 0, clk_osm_count_ns(c, 500));
clk_osm_write_reg(c, val,
DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG);
} }
/* DCVS droop FSM - only if RCGwRC is not used for di/dt control */ /* DCVS droop FSM - only if RCGwRC is not used for di/dt control */
@ -1841,14 +1869,14 @@ static void clk_osm_setup_fsms(struct clk_osm *c)
} }
if (c->wfx_fsm_en || c->ps_fsm_en || c->droop_fsm_en) { if (c->wfx_fsm_en || c->ps_fsm_en || c->droop_fsm_en) {
val = clk_osm_read_reg(c,
DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG) |
BVAL(15, 0, clk_osm_count_ns(c, 1000));
clk_osm_write_reg(c, val,
DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG);
clk_osm_write_reg(c, 0x1, DROOP_PROG_SYNC_DELAY_REG); clk_osm_write_reg(c, 0x1, DROOP_PROG_SYNC_DELAY_REG);
val = clk_osm_read_reg(c, DROOP_CTRL_REG) | clk_osm_write_reg(c, clk_osm_count_ns(c, 250),
BVAL(22, 16, 0x2); DROOP_RELEASE_TIMER_CTRL);
clk_osm_write_reg(c, clk_osm_count_ns(c, 500),
DCVS_DROOP_TIMER_CTRL);
val = clk_osm_read_reg(c, DROOP_CTRL_REG);
val |= BIT(31) | BVAL(22, 16, 0x2) |
BVAL(6, 0, 0x8);
clk_osm_write_reg(c, val, DROOP_CTRL_REG); clk_osm_write_reg(c, val, DROOP_CTRL_REG);
} }
} }
@ -1886,6 +1914,9 @@ static void clk_osm_do_additional_setup(struct clk_osm *c,
clk_osm_write_reg(c, RCG_UPDATE_SUCCESS, SEQ_REG(84)); clk_osm_write_reg(c, RCG_UPDATE_SUCCESS, SEQ_REG(84));
clk_osm_write_reg(c, RCG_UPDATE, SEQ_REG(85)); clk_osm_write_reg(c, RCG_UPDATE, SEQ_REG(85));
/* ITM to OSM handoff */
clk_osm_setup_itm_to_osm_handoff();
pr_debug("seq_size: %lu, seqbr_size: %lu\n", ARRAY_SIZE(seq_instr), pr_debug("seq_size: %lu, seqbr_size: %lu\n", ARRAY_SIZE(seq_instr),
ARRAY_SIZE(seq_br_instr)); ARRAY_SIZE(seq_br_instr));
clk_osm_setup_sequencer(&pwrcl_clk); clk_osm_setup_sequencer(&pwrcl_clk);
@ -1918,18 +1949,22 @@ static void clk_osm_apm_vc_setup(struct clk_osm *c)
/* Ensure writes complete before returning */ /* Ensure writes complete before returning */
mb(); mb();
} else { } else {
if (msmcobalt_v1) {
scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(1), scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(1),
c->apm_threshold_vc); c->apm_threshold_vc);
scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(73),
0x3b | c->apm_threshold_vc << 6);
} else if (msmcobalt_v2) {
clk_osm_write_reg(c, c->apm_threshold_vc,
SEQ_REG1_MSMCOBALT_V2);
}
scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(72), scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(72),
c->apm_crossover_vc); c->apm_crossover_vc);
/* SEQ_REG(8) = address of SEQ_REG(1) init by TZ */
clk_osm_write_reg(c, c->apm_threshold_vc, clk_osm_write_reg(c, c->apm_threshold_vc,
SEQ_REG(15)); SEQ_REG(15));
scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(31), scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(31),
c->apm_threshold_vc != 0 ? c->apm_threshold_vc != 0 ?
c->apm_threshold_vc - 1 : 0xff); c->apm_threshold_vc - 1 : 0xff);
scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(73),
0x3b | c->apm_threshold_vc << 6);
scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(76), scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(76),
0x39 | c->apm_threshold_vc << 6); 0x39 | c->apm_threshold_vc << 6);
} }
@ -2533,6 +2568,14 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev)
.get_cpu_cycle_counter = clk_osm_get_cpu_cycle_counter, .get_cpu_cycle_counter = clk_osm_get_cpu_cycle_counter,
}; };
if (of_find_compatible_node(NULL, NULL,
"qcom,cpu-clock-osm-msmcobalt-v1")) {
msmcobalt_v1 = true;
} else if (of_find_compatible_node(NULL, NULL,
"qcom,cpu-clock-osm-msmcobalt-v2")) {
msmcobalt_v2 = true;
}
rc = clk_osm_resources_init(pdev); rc = clk_osm_resources_init(pdev);
if (rc) { if (rc) {
if (rc != -EPROBE_DEFER) if (rc != -EPROBE_DEFER)
@ -2547,6 +2590,12 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev)
return rc; return rc;
} }
if ((pwrcl_clk.secure_init || perfcl_clk.secure_init) &&
msmcobalt_v2) {
pr_err("unsupported configuration for msmcobalt v2\n");
return -EINVAL;
}
if (pwrcl_clk.vbases[EFUSE_BASE]) { if (pwrcl_clk.vbases[EFUSE_BASE]) {
/* Multiple speed-bins are supported */ /* Multiple speed-bins are supported */
pte_efuse = readl_relaxed(pwrcl_clk.vbases[EFUSE_BASE]); pte_efuse = readl_relaxed(pwrcl_clk.vbases[EFUSE_BASE]);
@ -2618,10 +2667,6 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev)
clk_osm_print_osm_table(&pwrcl_clk); clk_osm_print_osm_table(&pwrcl_clk);
clk_osm_print_osm_table(&perfcl_clk); clk_osm_print_osm_table(&perfcl_clk);
/* Program the minimum PLL frequency */
clk_osm_write_reg(&pwrcl_clk, PLL_MIN_LVAL, SEQ_REG(27));
clk_osm_write_reg(&perfcl_clk, PLL_MIN_LVAL, SEQ_REG(27));
rc = clk_osm_setup_hw_table(&pwrcl_clk); rc = clk_osm_setup_hw_table(&pwrcl_clk);
if (rc) { if (rc) {
dev_err(&pdev->dev, "failed to setup power cluster hardware table\n"); dev_err(&pdev->dev, "failed to setup power cluster hardware table\n");
@ -2640,8 +2685,6 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev)
goto exit; goto exit;
} }
clk_osm_setup_itm_to_osm_handoff();
/* LLM Freq Policy Tuning */ /* LLM Freq Policy Tuning */
rc = clk_osm_set_llm_freq_policy(pdev); rc = clk_osm_set_llm_freq_policy(pdev);
if (rc < 0) { if (rc < 0) {
@ -2775,7 +2818,8 @@ exit:
} }
static struct of_device_id match_table[] = { static struct of_device_id match_table[] = {
{ .compatible = "qcom,cpu-clock-osm" }, { .compatible = "qcom,cpu-clock-osm-msmcobalt-v1" },
{ .compatible = "qcom,cpu-clock-osm-msmcobalt-v2" },
{} {}
}; };