}
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;
}
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 {