summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/qcom/clock-qcom.c15
-rw-r--r--drivers/clk/qcom/clock-qcom.h11
2 files changed, 24 insertions, 2 deletions
diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index 7a259db7934..6b46d9db744 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -83,6 +83,21 @@ int qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id)
}
setbits_le32(priv->base + priv->data->clks[id].reg, priv->data->clks[id].en_val);
+ if (priv->data->clks[id].cbcr_reg) {
+ unsigned int count;
+ u32 val;
+
+ for (count = 0; count < 200; count++) {
+ val = readl(priv->base + priv->data->clks[id].cbcr_reg);
+ val &= BRANCH_CHECK_MASK;
+ if (val == BRANCH_ON_VAL || val == BRANCH_NOC_FSM_ON_VAL)
+ break;
+ udelay(1);
+ }
+ if (WARN(count == 200, "WARNING: Clock @ %#lx [%#010x] stuck at off\n",
+ priv->data->clks[id].cbcr_reg, val))
+ return -EBUSY;
+ }
return 0;
}
diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
index ee0347d9d86..1b60882dae4 100644
--- a/drivers/clk/qcom/clock-qcom.h
+++ b/drivers/clk/qcom/clock-qcom.h
@@ -52,13 +52,20 @@ struct freq_tbl {
struct gate_clk {
uintptr_t reg;
u32 en_val;
+ uintptr_t cbcr_reg;
const char *name;
};
+/*
+ * GATE_CLK() is deprecated: Use GATE_CLK_POLLED() instead to ensure the clock
+ * is running before we start making use of devices or registers.
+ */
#ifdef DEBUG
-#define GATE_CLK(clk, reg, val) [clk] = { reg, val, #clk }
+#define GATE_CLK(clk, reg, val) [clk] = { reg, val, 0, #clk }
+#define GATE_CLK_POLLED(clk, en_reg, val, cbcr_reg) [clk] = { en_reg, val, cbcr_reg, #clk }
#else
-#define GATE_CLK(clk, reg, val) [clk] = { reg, val, NULL }
+#define GATE_CLK(clk, reg, val) [clk] = { reg, val, 0, NULL }
+#define GATE_CLK_POLLED(clk, en_reg, val, cbcr_reg) [clk] = { en_reg, val, cbcr_reg, NULL }
#endif
struct qcom_reset_map {