diff --git a/drivers/gpu/drm/i915/display/intel_dsi.h b/drivers/gpu/drm/i915/display/intel_dsi.h
index b15be5814599..6ff1b59b0f6f 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi.h
+++ b/drivers/gpu/drm/i915/display/intel_dsi.h
@@ -45,8 +45,9 @@ struct intel_dsi {
 	struct intel_dsi_host *dsi_hosts[I915_MAX_PORTS];
 	intel_wakeref_t io_wakeref[I915_MAX_PORTS];
 
-	/* GPIO Desc for CRC based Panel control */
+	/* GPIO Desc for panel and backlight control */
 	struct gpio_desc *gpio_panel;
+	struct gpio_desc *gpio_backlight;
 
 	struct intel_connector *attached_connector;
 
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
index fc63e2f6a511..bd081a3bb54b 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -24,6 +24,7 @@
  */
 
 #include <linux/gpio/consumer.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/slab.h>
 
 #include <drm/drm_atomic_helper.h>
@@ -797,7 +798,7 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder,
 	if (!IS_GEMINILAKE(dev_priv))
 		intel_dsi_prepare(encoder, pipe_config);
 
-	/* Power on, try both CRC pmic gpio and VBT */
+	/* Power on, try both the panel-enable GPIO and the MIPI seq. */
 	if (intel_dsi->gpio_panel)
 		gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1);
 	intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
@@ -843,6 +844,9 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder,
 	}
 
 	intel_panel_enable_backlight(pipe_config, conn_state);
+	/* Backlight on, try both the backlight-enable GPIO and the MIPI seq. */
+	if (intel_dsi->gpio_backlight)
+		gpiod_set_value_cansleep(intel_dsi->gpio_backlight, 1);
 	intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON);
 }
 
@@ -859,7 +863,10 @@ static void intel_dsi_disable(struct intel_encoder *encoder,
 
 	DRM_DEBUG_KMS("\n");
 
+	/* Backlight off, try both the enable GPIO and the MIPI seq. */
 	intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF);
+	if (intel_dsi->gpio_backlight)
+		gpiod_set_value_cansleep(intel_dsi->gpio_backlight, 0);
 	intel_panel_disable_backlight(old_conn_state);
 
 	/*
@@ -943,7 +950,7 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder,
 	/* Assert reset */
 	intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_ASSERT_RESET);
 
-	/* Power off, try both CRC pmic gpio and VBT */
+	/* Power off, try both the panel-enable GPIO and the MIPI seq. */
 	intel_dsi_msleep(intel_dsi, intel_dsi->panel_off_delay);
 	intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_OFF);
 	if (intel_dsi->gpio_panel)
@@ -1542,6 +1549,8 @@ static void intel_dsi_encoder_destroy(struct drm_encoder *encoder)
 	/* dispose of the gpios */
 	if (intel_dsi->gpio_panel)
 		gpiod_put(intel_dsi->gpio_panel);
+	if (intel_dsi->gpio_backlight)
+		gpiod_put(intel_dsi->gpio_backlight);
 
 	intel_encoder_destroy(encoder);
 }
@@ -1821,6 +1830,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
 	struct intel_connector *intel_connector;
 	struct drm_connector *connector;
 	struct drm_display_mode *current_mode, *fixed_mode;
+	struct pinctrl *pinctrl;
 	enum port port;
 
 	DRM_DEBUG_KMS("\n");
@@ -1921,7 +1931,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
 	vlv_dphy_param_init(intel_dsi);
 
 	/*
-	 * In case of BYT with CRC PMIC, we need to use GPIO for
+	 * In case of BYT or CHT with CRC PMIC, we need to use GPIO for
 	 * Panel control.
 	 */
 	if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
@@ -1934,6 +1944,34 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
 			intel_dsi->gpio_panel = NULL;
 		}
 	}
+	/*
+	 * In case of BYT (and only BYT) and using the SoC for PWM, we need
+	 * to use the SoC's GPIOs for panel and backlight enable. When the
+	 * GOP did not initialize the panel (HDMI inserted) we may need to
+	 * also change the pinmux for the SoC's PWM0 pin from GPIO to PWM.
+	 */
+	if (IS_VALLEYVIEW(dev_priv) &&
+	    dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_SOC) {
+		intel_dsi->gpio_panel = gpiod_get(dev->dev,
+						  "soc_panel_enable",
+						  GPIOD_OUT_HIGH);
+		if (IS_ERR(intel_dsi->gpio_panel)) {
+			DRM_ERROR("Failed to own gpio for panel control\n");
+			intel_dsi->gpio_panel = NULL;
+		}
+
+		intel_dsi->gpio_backlight = gpiod_get(dev->dev,
+						      "soc_backlight_enable",
+						      GPIOD_OUT_HIGH);
+		if (IS_ERR(intel_dsi->gpio_backlight)) {
+			DRM_ERROR("Failed to own gpio for backlight control\n");
+			intel_dsi->gpio_backlight = NULL;
+		}
+
+		pinctrl = devm_pinctrl_get_select(dev->dev, "soc_pwm0");
+		if (IS_ERR(pinctrl))
+			DRM_ERROR("Failed to set pinmux to PWM\n");
+	}
 
 	drm_connector_init(dev, connector, &intel_dsi_connector_funcs,
 			   DRM_MODE_CONNECTOR_DSI);
