For LVDS displays with pre-configured PLL clock, bypass the clock
divider calculation by setting ATMEL_XLCDC_CLKBYP flag.
For non-LVDS displays, retain existing clock divider calculation logic
to determine appropriate clock scaling based on display requirements.

Signed-off-by: Manikandan Muralidharan <[email protected]>
---
changes in v3:
- Introduce ATMEL_XLCDC_CLKBYP to this series
---
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c    | 65 ++++++++++---------
 include/linux/mfd/atmel-hlcdc.h               |  1 +
 2 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index 26c9fbdfd871..73ac5ebbe121 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -127,39 +127,44 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct 
drm_crtc *c)
                     (adj->crtc_hdisplay - 1) |
                     ((adj->crtc_vdisplay - 1) << 16));
 
-       prate = clk_get_rate(crtc->dc->hlcdc->sys_clk);
-       mode_rate = adj->crtc_clock * 1000;
-       if (!crtc->dc->desc->fixed_clksrc) {
-               prate *= 2;
-               cfg |= ATMEL_HLCDC_CLKSEL;
-               mask |= ATMEL_HLCDC_CLKSEL;
-       }
+       if (crtc->dc->hlcdc->lvds_pll_clk) {
+               cfg |= ATMEL_XLCDC_CLKBYP;
+               mask |= ATMEL_XLCDC_CLKBYP;
+       } else {
+               prate = clk_get_rate(crtc->dc->hlcdc->sys_clk);
+               mode_rate = adj->crtc_clock * 1000;
+               if (!crtc->dc->desc->fixed_clksrc) {
+                       prate *= 2;
+                       cfg |= ATMEL_HLCDC_CLKSEL;
+                       mask |= ATMEL_HLCDC_CLKSEL;
+               }
 
-       div = DIV_ROUND_UP(prate, mode_rate);
-       if (div < 2) {
-               div = 2;
-       } else if (ATMEL_HLCDC_CLKDIV(div) & ~ATMEL_HLCDC_CLKDIV_MASK) {
-               /* The divider ended up too big, try a lower base rate. */
-               cfg &= ~ATMEL_HLCDC_CLKSEL;
-               prate /= 2;
                div = DIV_ROUND_UP(prate, mode_rate);
-               if (ATMEL_HLCDC_CLKDIV(div) & ~ATMEL_HLCDC_CLKDIV_MASK)
-                       div = ATMEL_HLCDC_CLKDIV_MASK;
-       } else {
-               int div_low = prate / mode_rate;
-
-               if (div_low >= 2 &&
-                   (10 * (prate / div_low - mode_rate) <
-                    (mode_rate - prate / div)))
-                       /*
-                        * At least 10 times better when using a higher
-                        * frequency than requested, instead of a lower.
-                        * So, go with that.
-                        */
-                       div = div_low;
-       }
+               if (div < 2) {
+                       div = 2;
+               } else if (ATMEL_HLCDC_CLKDIV(div) & ~ATMEL_HLCDC_CLKDIV_MASK) {
+                       /* The divider ended up too big, try a lower base rate. 
*/
+                       cfg &= ~ATMEL_HLCDC_CLKSEL;
+                       prate /= 2;
+                       div = DIV_ROUND_UP(prate, mode_rate);
+                       if (ATMEL_HLCDC_CLKDIV(div) & ~ATMEL_HLCDC_CLKDIV_MASK)
+                               div = ATMEL_HLCDC_CLKDIV_MASK;
+               } else {
+                       int div_low = prate / mode_rate;
+
+                       if (div_low >= 2 &&
+                           (10 * (prate / div_low - mode_rate) <
+                            (mode_rate - prate / div)))
+                               /*
+                                * At least 10 times better when using a higher
+                                * frequency than requested, instead of a lower.
+                                * So, go with that.
+                                */
+                               div = div_low;
+               }
 
-       cfg |= ATMEL_HLCDC_CLKDIV(div);
+               cfg |= ATMEL_HLCDC_CLKDIV(div);
+       }
 
        if (connector &&
            connector->display_info.bus_flags & 
DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
diff --git a/include/linux/mfd/atmel-hlcdc.h b/include/linux/mfd/atmel-hlcdc.h
index 07c2081867fd..19504d3ea12c 100644
--- a/include/linux/mfd/atmel-hlcdc.h
+++ b/include/linux/mfd/atmel-hlcdc.h
@@ -44,6 +44,7 @@
 #define ATMEL_XLCDC_HEO_UPDATE         BIT(3)
 
 #define ATMEL_HLCDC_CLKPOL             BIT(0)
+#define ATMEL_XLCDC_CLKBYP             BIT(1)
 #define ATMEL_HLCDC_CLKSEL             BIT(2)
 #define ATMEL_HLCDC_CLKPWMSEL          BIT(3)
 #define ATMEL_HLCDC_CGDIS(i)           BIT(8 + (i))
-- 
2.25.1

Reply via email to