platform: correct the sequence for enabling DSI pixel clock
In the current implementation, the M,N,D values for DSI pixel clock is
set after setting the update RCG bit in DSI_PCLK_CMD_RCGR register.
This causes the dirty bits for M,N,D to be set in PCLK_CMD_RCGR causing
issues during handoff in kernel for DSI pixel clock. Update the sequence
to take care of this for multiple targets.
Change-Id: Ifcc53ca1787b710cd1a154738a7c1ccd472d22c7
diff --git a/platform/msm8909/acpuclock.c b/platform/msm8909/acpuclock.c
index b8e0df4..ed2cbfc 100644
--- a/platform/msm8909/acpuclock.c
+++ b/platform/msm8909/acpuclock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -37,6 +37,8 @@
#include <platform/clock.h>
#include <blsp_qup.h>
+#define MAX_LOOPS 500
+
void hsusb_clock_init(void)
{
int ret;
@@ -358,6 +360,34 @@
}
}
+static void rcg_update_config(uint32_t reg)
+{
+ int i;
+
+ for (i = 0; i < MAX_LOOPS; i++) {
+ if (!(readl(reg) & BIT(0)))
+ return;
+ udelay(1);
+ }
+
+ dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
+ ASSERT(0);
+}
+
+static void branch_clk_halt_check(uint32_t reg)
+{
+ int i;
+
+ for (i = 0; i < MAX_LOOPS; i++) {
+ if (!(readl(reg) & BIT(31)))
+ return;
+ udelay(1);
+ }
+
+ dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
+ ASSERT(0);
+}
+
/* Disable all the branch clocks needed by the DSI controller */
void gcc_dsi_clocks_disable(void)
{
@@ -371,20 +401,32 @@
{
int ret;
- /* Configure Byte clock -autopll- This will not change becasue
- byte clock does not need any divider*/
+ /*
+ * Configure Byte clock -autopll- This will not change becasue
+ * byte clock does not need any divider
+ */
+ /* Set the source for DSI0 byte RCG */
writel(0x100, DSI_BYTE0_CFG_RCGR);
+ /* Set the update RCG bit */
writel(0x1, DSI_BYTE0_CMD_RCGR);
+ rcg_update_config(DSI_BYTE0_CMD_RCGR);
+ /* Enable the branch clock */
writel(0x1, DSI_BYTE0_CBCR);
+ branch_clk_halt_check(DSI_BYTE0_CBCR);
/* Configure Pixel clock */
+ /* Set the source for DSI0 pixel RCG */
writel(0x100, DSI_PIXEL0_CFG_RCGR);
- writel(0x1, DSI_PIXEL0_CMD_RCGR);
- writel(0x1, DSI_PIXEL0_CBCR);
-
+ /* Set the MND for DSI0 pixel clock */
writel(pclk0_m, DSI_PIXEL0_M);
writel(pclk0_n, DSI_PIXEL0_N);
writel(pclk0_d, DSI_PIXEL0_D);
+ /* Set the update RCG bit */
+ writel(0x1, DSI_PIXEL0_CMD_RCGR);
+ rcg_update_config(DSI_PIXEL0_CMD_RCGR);
+ /* Enable the branch clock */
+ writel(0x1, DSI_PIXEL0_CBCR);
+ branch_clk_halt_check(DSI_PIXEL0_CBCR);
/* Configure ESC clock */
ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);