#define DPLL_CFGCR1(id)        _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR1, _DPLL2_CFGCR1)
 #define DPLL_CFGCR2(id)        _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR2, _DPLL2_CFGCR2)
 
+/*
+ * CNL Clocks
+ */
+#define DPCLKA_CFGCR0                          _MMIO(0x6C200)
+#define  DPCLKA_CFGCR0_DDI_CLK_OFF(port)       (1 << ((port)+10))
+#define  DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port)  (3 << ((port)*2))
+#define  DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port) ((port)*2)
+#define  DPCLKA_CFGCR0_DDI_CLK_SEL(pll, port)  ((pll) << ((port)*2))
+
 /* BXT display engine PLL */
 #define BXT_DE_PLL_CTL                 _MMIO(0x6d000)
 #define   BXT_DE_PLL_RATIO(x)          (x)     /* {60,65,100} * 19.2MHz */
 
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        enum port port = intel_ddi_get_encoder_port(encoder);
+       uint32_t val;
 
        if (WARN_ON(!pll))
                return;
 
-       if (IS_GEN9_BC(dev_priv)) {
-               uint32_t val;
+       if (IS_CANNONLAKE(dev_priv)) {
+               /* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */
+               val = I915_READ(DPCLKA_CFGCR0);
+               val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->id, port);
+               I915_WRITE(DPCLKA_CFGCR0, val);
 
+               /*
+                * Configure DPCLKA_CFGCR0 to turn on the clock for the DDI.
+                * This step and the step before must be done with separate
+                * register writes.
+                */
+               val = I915_READ(DPCLKA_CFGCR0);
+               val &= ~(DPCLKA_CFGCR0_DDI_CLK_OFF(port) |
+                        DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port));
+               I915_WRITE(DPCLKA_CFGCR0, val);
+       } else if (IS_GEN9_BC(dev_priv)) {
                /* DDI -> PLL mapping  */
                val = I915_READ(DPLL_CTRL2);
 
        if (dig_port)
                intel_display_power_put(dev_priv, dig_port->ddi_io_power_domain);
 
-       if (IS_GEN9_BC(dev_priv))
+       if (IS_CANNONLAKE(dev_priv))
+               I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) |
+                          DPCLKA_CFGCR0_DDI_CLK_OFF(port));
+       else if (IS_GEN9_BC(dev_priv))
                I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
                                        DPLL_CTRL2_DDI_CLK_OFF(port)));
        else if (INTEL_GEN(dev_priv) < 9)