about summary refs log tree commit diff
path: root/modules/hardware/t100ha/drm.patch
diff options
context:
space:
mode:
Diffstat (limited to 'modules/hardware/t100ha/drm.patch')
-rw-r--r--modules/hardware/t100ha/drm.patch733
1 files changed, 0 insertions, 733 deletions
diff --git a/modules/hardware/t100ha/drm.patch b/modules/hardware/t100ha/drm.patch
deleted file mode 100644
index 167be86d..00000000
--- a/modules/hardware/t100ha/drm.patch
+++ /dev/null
@@ -1,733 +0,0 @@
-diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
-index 8405b5a367d7..7e3545f65257 100644
---- a/drivers/gpu/drm/i915/intel_bios.h
-+++ b/drivers/gpu/drm/i915/intel_bios.h
-@@ -46,14 +46,20 @@ struct edp_power_seq {
- 	u16 t11_t12;
- } __packed;
- 
--/* MIPI Sequence Block definitions */
-+/*
-+ * MIPI Sequence Block definitions
-+ *
-+ * Note the VBT spec has AssertReset / DeassertReset swapped from their
-+ * usual naming, we use the proper names here to avoid confusion when
-+ * reading the code.
-+ */
- enum mipi_seq {
- 	MIPI_SEQ_END = 0,
--	MIPI_SEQ_ASSERT_RESET,
-+	MIPI_SEQ_DEASSERT_RESET,	/* Spec says MipiAssertResetPin */
- 	MIPI_SEQ_INIT_OTP,
- 	MIPI_SEQ_DISPLAY_ON,
- 	MIPI_SEQ_DISPLAY_OFF,
--	MIPI_SEQ_DEASSERT_RESET,
-+	MIPI_SEQ_ASSERT_RESET,		/* Spec says MipiDeassertResetPin */
- 	MIPI_SEQ_BACKLIGHT_ON,		/* sequence block v2+ */
- 	MIPI_SEQ_BACKLIGHT_OFF,		/* sequence block v2+ */
- 	MIPI_SEQ_TEAR_ON,		/* sequence block v2+ */
-diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
-index c9e83f39ec0a..6a6ae51996d0 100644
---- a/drivers/gpu/drm/i915/intel_display.c
-+++ b/drivers/gpu/drm/i915/intel_display.c
-@@ -13764,6 +13764,13 @@ static void update_scanline_offset(struct intel_crtc *crtc)
- 	 * type. For DP ports it behaves like most other platforms, but on HDMI
- 	 * there's an extra 1 line difference. So we need to add two instead of
- 	 * one to the value.
-+	 *
-+	 * On VLV/CHV DSI the scanline counter would appear to increment
-+	 * approx. 1/3 of a scanline before start of vblank. Unfortunately
-+	 * that we can't tell whether we're in vblank or not while we're
-+	 * on that particular line. We must set scanline_offset to 1 so
-+	 * that the vblank timestamps come out correct when we query
-+	 * the scanline counter from the vblank interrupt handler.
- 	 */
- 	if (IS_GEN2(dev)) {
- 		const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
-diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
-index b2e3d3a334f7..c07ef5e9de95 100644
---- a/drivers/gpu/drm/i915/intel_dsi.c
-+++ b/drivers/gpu/drm/i915/intel_dsi.c
-@@ -80,7 +80,7 @@ enum mipi_dsi_pixel_format pixel_format_from_register_bits(u32 fmt)
- 	}
- }
- 
--static void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi, enum port port)
-+void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi, enum port port)
- {
- 	struct drm_encoder *encoder = &intel_dsi->base.base;
- 	struct drm_device *dev = encoder->dev;
-@@ -505,37 +505,83 @@ static void intel_dsi_port_disable(struct intel_encoder *encoder)
- 	}
- }
- 
--static void intel_dsi_enable(struct intel_encoder *encoder)
--{
--	struct drm_device *dev = encoder->base.dev;
--	struct drm_i915_private *dev_priv = to_i915(dev);
--	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
--	enum port port;
--
--	DRM_DEBUG_KMS("\n");
--
--	if (is_cmd_mode(intel_dsi)) {
--		for_each_dsi_port(port, intel_dsi->ports)
--			I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(port), 8 * 4);
--	} else {
--		msleep(20); /* XXX */
--		for_each_dsi_port(port, intel_dsi->ports)
--			dpi_send_cmd(intel_dsi, TURN_ON, false, port);
--		msleep(100);
--
--		drm_panel_enable(intel_dsi->panel);
-+static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
-+			      struct intel_crtc_state *pipe_config);
- 
--		for_each_dsi_port(port, intel_dsi->ports)
--			wait_for_dsi_fifo_empty(intel_dsi, port);
-+static void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec)
-+{
-+	struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
- 
--		intel_dsi_port_enable(encoder);
--	}
-+	/* For v3 VBTs in vid-mode the delays are part of the VBT sequences */
-+	if (is_vid_mode(intel_dsi) && dev_priv->vbt.dsi.seq_version >= 3)
-+		return;
- 
--	intel_panel_enable_backlight(intel_dsi->attached_connector);
-+	msleep(msec);
- }
- 
--static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
--			      struct intel_crtc_state *pipe_config);
-+/*
-+ * Panel enable/disable sequences from the spec:
-+ *
-+ * v2 sequence for video mode:
-+ * - power on
-+ * - wait t1+t2
-+ * - MIPIDeassertResetPin
-+ * - clk/data lines to lp-11
-+ * - MIPISendInitialDcsCmds
-+ * - turn on DPI
-+ * - MIPIDisplayOn
-+ * - wait t5
-+ * - backlight on
-+ * ...
-+ * - backlight off
-+ * - wait t6
-+ * - MIPIDisplayOff
-+ * - turn off DPI
-+ * - clk/data lines to lp-00
-+ * - MIPIAssertResetPin
-+ * - wait t3
-+ * - power off
-+ * - wait t4
-+ *
-+ * v3 sequence for video mode:
-+ * - MIPIPanelPowerOn
-+ * - MIPIDeassertResetPin
-+ * - set clk/data lines to lp-11
-+ * - MIPISendInitialDcsCmds (LP)
-+ * - turn on DPI
-+ * - MIPITearOn (command mode only) + MIPIDisplayOn (LP and HS)
-+ * - MIPIBacklightOn
-+ * ...
-+ * - MIPIBacklightOff
-+ * - turn off DPI
-+ * - MIPITearOff + MIPIDisplayOff (LP)
-+ * - clk/data lines to lp-00
-+ * - MIPIAssertResetPin
-+ * - MIPIPanelPowerOff
-+ *
-+ * sequence for command mode:
-+ * - power on
-+ * - wait t1+t2
-+ * - MIPIDeassertResetPin
-+ * - clk/data lines to lp-11
-+ * - MIPISendInitialDcsCmds
-+ * - MIPITearOn
-+ * - MIPIDisplayOn
-+ * - set pipe to dsr mode
-+ * - wait t5
-+ * - backlight on
-+ * ... issue write_mem_start/write_mem_continue commands ...
-+ * - backlight off
-+ * - wait t6
-+ * - disable pipe dsr mode
-+ * - MIPITearOff
-+ * - MIPIDisplayOff
-+ * - clk/data lines to lp-00
-+ * - MIPIAssertResetPin
-+ * - wait t3
-+ * - power off
-+ * - wait t4
-+ */
- 
- static void intel_dsi_pre_enable(struct intel_encoder *encoder,
- 				 struct intel_crtc_state *pipe_config,
-@@ -554,14 +600,6 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder,
- 	intel_disable_dsi_pll(encoder);
- 	intel_enable_dsi_pll(encoder, pipe_config);
- 
--	intel_dsi_prepare(encoder, pipe_config);
--
--	/* Panel Enable over CRC PMIC */
--	if (intel_dsi->gpio_panel)
--		gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1);
--
--	msleep(intel_dsi->panel_on_delay);
--
- 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
- 		u32 val;
- 
-@@ -571,17 +609,44 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder,
- 		I915_WRITE(DSPCLK_GATE_D, val);
- 	}
- 
--	/* put device in ready state */
--	intel_dsi_device_ready(encoder);
-+	intel_dsi_prepare(encoder, pipe_config);
-+
-+	/* Power on, try both CRC pmic gpio and VBT */
-+	if (intel_dsi->gpio_panel)
-+		gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1);
-+	intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
-+	intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay);
- 
--	drm_panel_prepare(intel_dsi->panel);
-+	/* Deassert reset */
-+	intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET);
- 
--	for_each_dsi_port(port, intel_dsi->ports)
--		wait_for_dsi_fifo_empty(intel_dsi, port);
-+	/* Put device in ready state (LP-11) */
-+	intel_dsi_device_ready(encoder);
-+
-+	/* Send initialization commands in LP mode */
-+	intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_INIT_OTP);
- 
- 	/* Enable port in pre-enable phase itself because as per hw team
- 	 * recommendation, port should be enabled befor plane & pipe */
--	intel_dsi_enable(encoder);
-+	if (is_cmd_mode(intel_dsi)) {
-+		for_each_dsi_port(port, intel_dsi->ports)
-+			I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(port), 8 * 4);
-+		intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_TEAR_ON);
-+		intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);
-+	} else {
-+		msleep(20); /* XXX */
-+		for_each_dsi_port(port, intel_dsi->ports)
-+			dpi_send_cmd(intel_dsi, TURN_ON, false, port);
-+		intel_dsi_msleep(intel_dsi, 100);
-+
-+		intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);
-+
-+		intel_dsi_port_enable(encoder);
-+	}
-+
-+	/* Enable backlight, both pwm and VBT */
-+	intel_panel_enable_backlight(intel_dsi->attached_connector);
-+	intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON);
- }
- 
- static void intel_dsi_enable_nop(struct intel_encoder *encoder,
-@@ -605,8 +670,15 @@ static void intel_dsi_pre_disable(struct intel_encoder *encoder,
- 
- 	DRM_DEBUG_KMS("\n");
- 
-+	/* Disable backlight, both VBT and pwm */
-+	intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF);
- 	intel_panel_disable_backlight(intel_dsi->attached_connector);
- 
-+	/*
-+	 * XXX: According to the spec we should send SHUTDOWN before
-+	 * MIPI_SEQ_DISPLAY_OFF only for v3+ VBTs, but testing in the field
-+	 * has shown that we should do this for v2 VBTs too?
-+	 */
- 	if (is_vid_mode(intel_dsi)) {
- 		/* Send Shutdown command to the panel in LP mode */
- 		for_each_dsi_port(port, intel_dsi->ports)
-@@ -615,45 +687,6 @@ static void intel_dsi_pre_disable(struct intel_encoder *encoder,
- 	}
- }
- 
--static void intel_dsi_disable(struct intel_encoder *encoder)
--{
--	struct drm_device *dev = encoder->base.dev;
--	struct drm_i915_private *dev_priv = to_i915(dev);
--	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
--	enum port port;
--	u32 temp;
--
--	DRM_DEBUG_KMS("\n");
--
--	if (is_vid_mode(intel_dsi)) {
--		for_each_dsi_port(port, intel_dsi->ports)
--			wait_for_dsi_fifo_empty(intel_dsi, port);
--
--		intel_dsi_port_disable(encoder);
--		msleep(2);
--	}
--
--	for_each_dsi_port(port, intel_dsi->ports) {
--		/* Panel commands can be sent when clock is in LP11 */
--		I915_WRITE(MIPI_DEVICE_READY(port), 0x0);
--
--		intel_dsi_reset_clocks(encoder, port);
--		I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
--
--		temp = I915_READ(MIPI_DSI_FUNC_PRG(port));
--		temp &= ~VID_MODE_FORMAT_MASK;
--		I915_WRITE(MIPI_DSI_FUNC_PRG(port), temp);
--
--		I915_WRITE(MIPI_DEVICE_READY(port), 0x1);
--	}
--	/* if disable packets are sent before sending shutdown packet then in
--	 * some next enable sequence send turn on packet error is observed */
--	drm_panel_disable(intel_dsi->panel);
--
--	for_each_dsi_port(port, intel_dsi->ports)
--		wait_for_dsi_fifo_empty(intel_dsi, port);
--}
--
- static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
- {
- 	struct drm_device *dev = encoder->base.dev;
-@@ -696,8 +729,6 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
- 		I915_WRITE(MIPI_DEVICE_READY(port), 0x00);
- 		usleep_range(2000, 2500);
- 	}
--
--	intel_disable_dsi_pll(encoder);
- }
- 
- static void intel_dsi_post_disable(struct intel_encoder *encoder,
-@@ -706,13 +737,50 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder,
- {
- 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
-+	struct intel_connector *intel_connector = intel_dsi->attached_connector;
-+	enum port port;
-+	u32 temp;
- 
- 	DRM_DEBUG_KMS("\n");
- 
--	intel_dsi_disable(encoder);
-+	if (is_vid_mode(intel_dsi)) {
-+		for_each_dsi_port(port, intel_dsi->ports)
-+			wait_for_dsi_fifo_empty(intel_dsi, port);
-+
-+		intel_dsi_port_disable(encoder);
-+		usleep_range(2000, 5000);
-+	}
-+
-+	intel_panel_disable_backlight(intel_connector);
-+
-+	for_each_dsi_port(port, intel_dsi->ports) {
-+		/* Panel commands can be sent when clock is in LP11 */
-+		I915_WRITE(MIPI_DEVICE_READY(port), 0x0);
- 
-+		intel_dsi_reset_clocks(encoder, port);
-+		I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
-+
-+		temp = I915_READ(MIPI_DSI_FUNC_PRG(port));
-+		temp &= ~VID_MODE_FORMAT_MASK;
-+		I915_WRITE(MIPI_DSI_FUNC_PRG(port), temp);
-+
-+		I915_WRITE(MIPI_DEVICE_READY(port), 0x1);
-+	}
-+
-+	/*
-+	 * if disable packets are sent before sending shutdown packet then in
-+	 * some next enable sequence send turn on packet error is observed
-+	 * XXX spec specifies SHUTDOWN before MIPI_SEQ_DISPLAY_OFF for
-+	 * v3 VBTs, but not for v2 VBTs?
-+	 */
-+	intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_TEAR_OFF);
-+	intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_DISPLAY_OFF);
-+
-+	/* Transition to LP-00 */
- 	intel_dsi_clear_device_ready(encoder);
- 
-+	intel_disable_dsi_pll(encoder);
-+
- 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
- 		u32 val;
- 
-@@ -721,11 +789,12 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder,
- 		I915_WRITE(DSPCLK_GATE_D, val);
- 	}
- 
--	drm_panel_unprepare(intel_dsi->panel);
--
--	msleep(intel_dsi->panel_off_delay);
-+	/* Assert reset */
-+	intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_ASSERT_RESET);
- 
--	/* Panel Disable over CRC PMIC */
-+	/* Power off, try both CRC pmic gpio and VBT */
-+	intel_dsi_msleep(intel_dsi, intel_dsi->panel_off_delay);
-+	intel_dsi_exec_vbt_sequence(intel_dsi, MIPI_SEQ_POWER_OFF);
- 	if (intel_dsi->gpio_panel)
- 		gpiod_set_value_cansleep(intel_dsi->gpio_panel, 0);
- 
-@@ -733,7 +802,7 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder,
- 	 * FIXME As we do with eDP, just make a note of the time here
- 	 * and perform the wait before the next panel power on.
- 	 */
--	msleep(intel_dsi->panel_pwr_cycle_delay);
-+	intel_dsi_msleep(intel_dsi, intel_dsi->panel_pwr_cycle_delay);
- }
- 
- static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
-@@ -1376,6 +1445,7 @@ static void intel_dsi_connector_destroy(struct drm_connector *connector)
- 
- 	DRM_DEBUG_KMS("\n");
- 	intel_panel_fini(&intel_connector->panel);
-+	intel_panel_destroy_backlight(connector);
- 	drm_connector_cleanup(connector);
- 	kfree(connector);
- }
-diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
-index 5967ea6d6045..548649158abd 100644
---- a/drivers/gpu/drm/i915/intel_dsi.h
-+++ b/drivers/gpu/drm/i915/intel_dsi.h
-@@ -130,6 +130,11 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder)
- 	return container_of(encoder, struct intel_dsi, base.base);
- }
- 
-+void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi, enum port port);
-+
-+void intel_dsi_exec_vbt_sequence(struct intel_dsi *intel_dsi,
-+				 enum mipi_seq seq_id);
-+
- bool intel_dsi_pll_is_enabled(struct drm_i915_private *dev_priv);
- int intel_compute_dsi_pll(struct intel_encoder *encoder,
- 			  struct intel_crtc_state *config);
-diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
-index 34601574fc6e..a4e3c642b39a 100644
---- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
-+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
-@@ -189,6 +189,8 @@ static const u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi,
- 		break;
- 	}
- 
-+	wait_for_dsi_fifo_empty(intel_dsi, port);
-+
- out:
- 	data += len;
- 
-@@ -353,11 +355,11 @@ static const fn_mipi_elem_exec exec_elem[] = {
-  */
- 
- static const char * const seq_name[] = {
--	[MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET",
-+	[MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET",
- 	[MIPI_SEQ_INIT_OTP] = "MIPI_SEQ_INIT_OTP",
- 	[MIPI_SEQ_DISPLAY_ON] = "MIPI_SEQ_DISPLAY_ON",
- 	[MIPI_SEQ_DISPLAY_OFF]  = "MIPI_SEQ_DISPLAY_OFF",
--	[MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET",
-+	[MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET",
- 	[MIPI_SEQ_BACKLIGHT_ON] = "MIPI_SEQ_BACKLIGHT_ON",
- 	[MIPI_SEQ_BACKLIGHT_OFF] = "MIPI_SEQ_BACKLIGHT_OFF",
- 	[MIPI_SEQ_TEAR_ON] = "MIPI_SEQ_TEAR_ON",
-@@ -374,10 +376,9 @@ static const char *sequence_name(enum mipi_seq seq_id)
- 		return "(unknown)";
- }
- 
--static void generic_exec_sequence(struct drm_panel *panel, enum mipi_seq seq_id)
-+void intel_dsi_exec_vbt_sequence(struct intel_dsi *intel_dsi,
-+				 enum mipi_seq seq_id)
- {
--	struct vbt_panel *vbt_panel = to_vbt_panel(panel);
--	struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
- 	struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
- 	const u8 *data;
- 	fn_mipi_elem_exec mipi_elem_exec;
-@@ -436,35 +437,6 @@ static void generic_exec_sequence(struct drm_panel *panel, enum mipi_seq seq_id)
- 	}
- }
- 
--static int vbt_panel_prepare(struct drm_panel *panel)
--{
--	generic_exec_sequence(panel, MIPI_SEQ_ASSERT_RESET);
--	generic_exec_sequence(panel, MIPI_SEQ_INIT_OTP);
--
--	return 0;
--}
--
--static int vbt_panel_unprepare(struct drm_panel *panel)
--{
--	generic_exec_sequence(panel, MIPI_SEQ_DEASSERT_RESET);
--
--	return 0;
--}
--
--static int vbt_panel_enable(struct drm_panel *panel)
--{
--	generic_exec_sequence(panel, MIPI_SEQ_DISPLAY_ON);
--
--	return 0;
--}
--
--static int vbt_panel_disable(struct drm_panel *panel)
--{
--	generic_exec_sequence(panel, MIPI_SEQ_DISPLAY_OFF);
--
--	return 0;
--}
--
- static int vbt_panel_get_modes(struct drm_panel *panel)
- {
- 	struct vbt_panel *vbt_panel = to_vbt_panel(panel);
-@@ -488,10 +460,6 @@ static int vbt_panel_get_modes(struct drm_panel *panel)
- }
- 
- static const struct drm_panel_funcs vbt_panel_funcs = {
--	.disable = vbt_panel_disable,
--	.unprepare = vbt_panel_unprepare,
--	.prepare = vbt_panel_prepare,
--	.enable = vbt_panel_enable,
- 	.get_modes = vbt_panel_get_modes,
- };
- 
-diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
-index be4b4d546fd9..5aac10c3239f 100644
---- a/drivers/gpu/drm/i915/intel_panel.c
-+++ b/drivers/gpu/drm/i915/intel_panel.c
-@@ -32,6 +32,7 @@
- 
- #include <linux/kernel.h>
- #include <linux/moduleparam.h>
-+#include <linux/mfd/intel_soc_pmic.h>
- #include <linux/pwm.h>
- #include "intel_drv.h"
- 
-@@ -544,6 +545,11 @@ static u32 pwm_get_backlight(struct intel_connector *connector)
- 	return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS);
- }
- 
-+static u32 vlv_pmic_get_backlight(struct intel_connector *connector)
-+{
-+	return intel_soc_pmic_readb(0x4E);
-+}
-+
- static u32 intel_panel_get_backlight(struct intel_connector *connector)
- {
- 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-@@ -635,6 +641,11 @@ static void pwm_set_backlight(struct intel_connector *connector, u32 level)
- 	pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS);
- }
- 
-+static void vlv_pmic_set_backlight(struct intel_connector *connector, u32 level)
-+{
-+	intel_soc_pmic_writeb(0x4E, level);
-+}
-+
- static void
- intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
- {
-@@ -808,6 +819,14 @@ static void pwm_disable_backlight(struct intel_connector *connector)
- 	pwm_disable(panel->backlight.pwm);
- }
- 
-+static void vlv_pmic_disable_backlight(struct intel_connector *connector)
-+{
-+	intel_panel_actually_set_backlight(connector, 0);
-+
-+	intel_soc_pmic_writeb(0x51, 0x00);
-+	intel_soc_pmic_writeb(0x4B, 0x7F);
-+}
-+
- void intel_panel_disable_backlight(struct intel_connector *connector)
- {
- 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-@@ -1089,6 +1108,17 @@ static void pwm_enable_backlight(struct intel_connector *connector)
- 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
- }
- 
-+static void vlv_pmic_enable_backlight(struct intel_connector *connector)
-+{
-+	struct intel_panel *panel = &connector->panel;
-+
-+	intel_soc_pmic_writeb(0x4B, 0xFF);
-+	intel_soc_pmic_writeb(0x4E, 0xFF);
-+	intel_soc_pmic_writeb(0x51, 0x01);
-+
-+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
-+}
-+
- void intel_panel_enable_backlight(struct intel_connector *connector)
- {
- 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-@@ -1687,6 +1717,20 @@ static int pwm_setup_backlight(struct intel_connector *connector,
- 	return 0;
- }
- 
-+static int vlv_pmic_setup_backlight(struct intel_connector *connector,
-+		enum pipe unused)
-+{
-+	struct intel_panel *panel = &connector->panel;
-+
-+	panel->backlight.present = 1;
-+	panel->backlight.min = 0x00;
-+	panel->backlight.max = 0xFF;
-+	panel->backlight.level = 0x5A;
-+	panel->backlight.enabled = 1;
-+
-+	return 0;
-+}
-+
- int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
- {
- 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
-@@ -1694,6 +1738,8 @@ int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
- 	struct intel_panel *panel = &intel_connector->panel;
- 	int ret;
- 
-+	intel_backlight_device_register(intel_connector);
-+
- 	if (!dev_priv->vbt.backlight.present) {
- 		if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
- 			DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n");
-@@ -1783,18 +1829,17 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
- 		panel->backlight.hz_to_pwm = pch_hz_to_pwm;
- 	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
- 		if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) {
--			panel->backlight.setup = pwm_setup_backlight;
--			panel->backlight.enable = pwm_enable_backlight;
--			panel->backlight.disable = pwm_disable_backlight;
--			panel->backlight.set = pwm_set_backlight;
--			panel->backlight.get = pwm_get_backlight;
-+			panel->backlight.setup = vlv_pmic_setup_backlight;
-+			panel->backlight.enable = vlv_pmic_enable_backlight;
-+			panel->backlight.disable = vlv_pmic_disable_backlight;
-+			panel->backlight.set = vlv_pmic_set_backlight;
-+			panel->backlight.get = vlv_pmic_get_backlight;
- 		} else {
- 			panel->backlight.setup = vlv_setup_backlight;
- 			panel->backlight.enable = vlv_enable_backlight;
- 			panel->backlight.disable = vlv_disable_backlight;
- 			panel->backlight.set = vlv_set_backlight;
- 			panel->backlight.get = vlv_get_backlight;
--			panel->backlight.hz_to_pwm = vlv_hz_to_pwm;
- 		}
- 	} else if (IS_GEN4(dev_priv)) {
- 		panel->backlight.setup = i965_setup_backlight;
-diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
-index dbed12c484c9..a2f9a4671193 100644
---- a/drivers/gpu/drm/i915/intel_sprite.c
-+++ b/drivers/gpu/drm/i915/intel_sprite.c
-@@ -81,10 +81,13 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
-  */
- void intel_pipe_update_start(struct intel_crtc *crtc)
- {
-+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- 	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
- 	long timeout = msecs_to_jiffies_timeout(1);
- 	int scanline, min, max, vblank_start;
- 	wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
-+	bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
-+		intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DSI);
- 	DEFINE_WAIT(wait);
- 
- 	vblank_start = adjusted_mode->crtc_vblank_start;
-@@ -136,6 +139,25 @@ void intel_pipe_update_start(struct intel_crtc *crtc)
- 
- 	drm_crtc_vblank_put(&crtc->base);
- 
-+	/*
-+	 * On VLV/CHV DSI the scanline counter would appear to
-+	 * increment approx. 1/3 of a scanline before start of vblank.
-+	 * The registers still get latched at start of vblank however.
-+	 * This means we must not write any registers on the first
-+	 * line of vblank (since not the whole line is actually in
-+	 * vblank). And unfortunately we can't use the interrupt to
-+	 * wait here since it may have already fired before we check
-+	 * the scanline. We could use the frame start interrupt instead
-+	 * since it will fire after the critical scanline, but that would
-+	 * require more changes in the interrupt code. So for now we'll
-+	 * just do the nasty thing and poll for the bad scanline to
-+	 * pass us by.
-+	 *
-+	 * FIXME figure out if BXT+ DSI suffers from this as well
-+	 */
-+	while (need_vlv_dsi_wa && scanline == vblank_start)
-+		scanline = intel_get_crtc_scanline(crtc);
-+
- 	crtc->debug.scanline_start = scanline;
- 	crtc->debug.start_vbl_time = ktime_get();
- 	crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
-diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c
-index 12d6ebb4ae5d..8583e77deae0 100644
---- a/drivers/mfd/intel_soc_pmic_core.c
-+++ b/drivers/mfd/intel_soc_pmic_core.c
-@@ -44,6 +44,8 @@ static struct pwm_lookup crc_pwm_lookup[] = {
- 	PWM_LOOKUP("crystal_cove_pwm", 0, "0000:00:02.0", "pwm_backlight", 0, PWM_POLARITY_NORMAL),
- };
- 
-+static struct intel_soc_pmic *pmic_hack = NULL;
-+
- static int intel_soc_pmic_find_gpio_irq(struct device *dev)
- {
- 	struct gpio_desc *desc;
-@@ -77,6 +79,7 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c,
- 	config = (struct intel_soc_pmic_config *)id->driver_data;
- 
- 	pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
-+	pmic_hack = pmic;
- 	if (!pmic)
- 		return -ENOMEM;
- 
-@@ -168,6 +171,37 @@ static int intel_soc_pmic_resume(struct device *dev)
- }
- #endif
- 
-+int intel_soc_pmic_readb(int reg)
-+{
-+	int ret;
-+	unsigned int val;
-+
-+	if (!pmic_hack) {
-+		ret = -EIO;
-+	} else {
-+		ret = regmap_read(pmic_hack->regmap, reg, &val);
-+		if (!ret) {
-+			ret = val;
-+		}
-+	}
-+
-+	return ret;
-+}
-+EXPORT_SYMBOL(intel_soc_pmic_readb);
-+
-+int intel_soc_pmic_writeb(int reg, u8 val)
-+{
-+	int ret;
-+
-+	if (!pmic_hack) {
-+		ret = -EIO;
-+	} else {
-+		ret = regmap_write(pmic_hack->regmap, reg, val);
-+	}
-+	return ret;
-+}
-+EXPORT_SYMBOL(intel_soc_pmic_writeb);
-+
- static SIMPLE_DEV_PM_OPS(intel_soc_pmic_pm_ops, intel_soc_pmic_suspend,
- 			 intel_soc_pmic_resume);
- 
-diff --git a/include/linux/mfd/intel_soc_pmic.h b/include/linux/mfd/intel_soc_pmic.h
-index cf619dbeace2..52ad034f606a 100644
---- a/include/linux/mfd/intel_soc_pmic.h
-+++ b/include/linux/mfd/intel_soc_pmic.h
-@@ -29,4 +29,7 @@ struct intel_soc_pmic {
- 	struct device *dev;
- };
- 
-+int intel_soc_pmic_readb(int reg);
-+int intel_soc_pmic_writeb(int reg, u8 val);
-+
- #endif	/* __INTEL_SOC_PMIC_H__ */