@@ -39,6 +39,24 @@ void clk_enable_cbc(phys_addr_t cbcr)
;
}
+/* Global Distributed Switch Controller - these are
+ * breaker switches for entire peripherals like USB,
+ * they control power and clocks and must be turned on
+ * before configuring clocks or accessing the peripheral.
+ */
+void gdsc_enable(phys_addr_t gdscr)
+{
+ u32 count;
+
+ clrbits_le32(gdscr, GDSC_SW_COLLAPSE);
+ for (count = 0; count < 1500; count++) {
+ if (readl(gdscr) & GDSC_PWR_ON)
+ break;
+ udelay(1);
+ }
+ WARN(count == 1500, "WARNING: GDSC @ %#llx stuck at off\n", gdscr);
+}
+
void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0)
{
if (readl(base + gpll0->status) & gpll0->status_bit)
@@ -12,6 +12,9 @@
#define CFG_CLK_SRC_GPLL0_EVEN (6 << 8)
#define CFG_CLK_SRC_MASK (7 << 8)
+#define GDSC_PWR_ON BIT(31)
+#define GDSC_SW_COLLAPSE BIT(0)
+
#define RCG_CFG_REG 0x4
#define RCG_M_REG 0x8
#define RCG_N_REG 0xc
@@ -78,6 +81,7 @@ int qcom_cc_bind(struct udevice *parent);
void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0);
void clk_bcr_update(phys_addr_t apps_cmd_rgcr);
void clk_enable_cbc(phys_addr_t cbcr);
+void gdsc_enable(phys_addr_t gdscr);
void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk);
const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate);
void clk_rcg_set_rate_mnd(phys_addr_t base, uint32_t cmd_rcgr,
Global Distributed Switch Controllers are per-domain switches which are used to toggle power and clocks to an entire subsystem. They live under the GCC block and might need to be enabled before certain clocks, so handle them as part of the clock driver. Linux models these as power domains, however this additional complexity doesn't offer much benefit to us in U-Boot. For now they can be turned on as-needed when a relevant clock is enabled. In the future, we can add a power-domain driver to model these properly. Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org> --- drivers/clk/qcom/clock-qcom.c | 18 ++++++++++++++++++ drivers/clk/qcom/clock-qcom.h | 4 ++++ 2 files changed, 22 insertions(+)