summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOsvaldo Banuelos <osvaldob@codeaurora.org>2016-04-26 17:48:47 -0700
committerJeevan Shriram <jshriram@codeaurora.org>2016-05-09 18:35:31 -0700
commitcf381d203a3084bff5c8453a6b3736b9de9c7122 (patch)
tree62efa429ffd35c65b68a077dce781d64fdc543a3
parent75f9319b67f01100c19da41553e2af9ee85f9d59 (diff)
clk: msm: osm: support programming LMh SW override values in set_rate()
To ensure stable operation, it is necessary to place LMh SW override votes when setting the new rate of the power and performance CPU clocks. Add support for parsing these values from Device Tree and programming them in clk_set_rate(). Change-Id: I60d90d546f155edb6c13c46e6c59c75e95848d6c CRs-Fixed: 1009097 Signed-off-by: Osvaldo Banuelos <osvaldob@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/arm/msm/qcom,osm.txt7
-rw-r--r--drivers/clk/msm/clock-osm.c31
2 files changed, 37 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
index 2577ee24dad4..2bd7653af5a3 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
@@ -196,6 +196,13 @@ Properties:
controller status register for each of the two clusters
managed by the OSM controller.
+- qcom,llm-sw-overr
+ Usage: optional
+ Value type: <prop-encoded-array>
+ Definition: Array of tuples which defines the three non-zero LLM SW
+ override values to write to the OSM controller for each
+ of the two clusters. Each tuple must contain three elements.
+
- qcom,pwrcl-apcs-mem-acc-cfg
Usage: required if qcom,osm-no-tz is specified
Value type: <prop-encoded-array>
diff --git a/drivers/clk/msm/clock-osm.c b/drivers/clk/msm/clock-osm.c
index dbb2d5f66bf4..142704fd8897 100644
--- a/drivers/clk/msm/clock-osm.c
+++ b/drivers/clk/msm/clock-osm.c
@@ -80,6 +80,7 @@ enum clk_osm_trace_packet_id {
#define OSM_TABLE_SIZE 40
#define MAX_CLUSTER_CNT 2
#define MAX_CONFIG 4
+#define LLM_SW_OVERRIDE_CNT 3
#define ENABLE_REG 0x1004
#define INDEX_REG 0x1150
@@ -142,6 +143,7 @@ enum clk_osm_trace_packet_id {
#define PLL_POST_DIV1 0x1F
#define PLL_POST_DIV2 0x11F
+#define LLM_SW_OVERRIDE_REG 0x1038
#define VMIN_REDUC_ENABLE_REG 0x103C
#define VMIN_REDUC_TIMER_REG 0x1040
#define PDN_FSM_CTRL_REG 0x1070
@@ -300,6 +302,7 @@ struct clk_osm {
u32 apcs_pll_user_ctl;
u32 apcs_mem_acc_cfg[MAX_MEM_ACC_VAL_PER_LEVEL];
u32 apcs_mem_acc_val[MAX_MEM_ACC_VALUES];
+ u32 llm_sw_overr[LLM_SW_OVERRIDE_CNT];
u32 apm_mode_ctl;
u32 apm_ctrl_status;
u32 osm_clk_rate;
@@ -413,9 +416,23 @@ static int clk_osm_set_rate(struct clk *c, unsigned long rate)
}
pr_debug("rate: %lu --> index %d\n", rate, index);
+ if (cpuclk->llm_sw_overr) {
+ clk_osm_write_reg(cpuclk, cpuclk->llm_sw_overr[0],
+ LLM_SW_OVERRIDE_REG);
+ clk_osm_write_reg(cpuclk, cpuclk->llm_sw_overr[1],
+ LLM_SW_OVERRIDE_REG);
+ udelay(1);
+ }
+
/* Choose index and send request to OSM hardware */
clk_osm_write_reg(cpuclk, index, DCVS_PERF_STATE_DESIRED_REG);
+ if (cpuclk->llm_sw_overr) {
+ udelay(1);
+ clk_osm_write_reg(cpuclk, cpuclk->llm_sw_overr[2],
+ LLM_SW_OVERRIDE_REG);
+ }
+
/* Make sure the write goes through before proceeding */
mb();
@@ -603,7 +620,7 @@ static int clk_osm_parse_dt_configs(struct platform_device *pdev)
{
struct device_node *of = pdev->dev.of_node;
u32 *array;
- int rc = 0;
+ int i, rc = 0;
array = devm_kzalloc(&pdev->dev, MAX_CLUSTER_CNT * sizeof(u32),
GFP_KERNEL);
@@ -687,6 +704,18 @@ static int clk_osm_parse_dt_configs(struct platform_device *pdev)
pwrcl_clk.apm_ctrl_status = array[pwrcl_clk.cluster_num];
perfcl_clk.apm_ctrl_status = array[perfcl_clk.cluster_num];
+ for (i = 0; i < LLM_SW_OVERRIDE_CNT; i++)
+ of_property_read_u32_index(of, "qcom,llm-sw-overr",
+ pwrcl_clk.cluster_num *
+ LLM_SW_OVERRIDE_CNT + i,
+ &pwrcl_clk.llm_sw_overr[i]);
+
+ for (i = 0; i < LLM_SW_OVERRIDE_CNT; i++)
+ of_property_read_u32_index(of, "qcom,llm-sw-overr",
+ perfcl_clk.cluster_num *
+ LLM_SW_OVERRIDE_CNT + i,
+ &perfcl_clk.llm_sw_overr[i]);
+
rc = of_property_read_u32(of, "qcom,xo-clk-rate",
&pwrcl_clk.xo_clk_rate);
if (rc) {