diff options
Diffstat (limited to 'modules/hardware/t100ha/drm.patch')
-rw-r--r-- | modules/hardware/t100ha/drm.patch | 733 |
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__ */ |