aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-02 18:24:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-02 18:24:45 -0400
commitada7339efeb94690a7ad15de69a3af186b9a55b5 (patch)
tree4e7c7ecf36704ca29eccc27d0db4c02a6d8723c1
parent4277e6b9fd44a42d13f1c47fb403167718e9bed4 (diff)
parent012cfaced00b7a9498227504c4d37a1c4619403d (diff)
Merge tag 'drm-fixes-for-v4.17-rc8' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "A few final fixes: i915: - fix for potential Spectre vector in the new query uAPI - fix NULL pointer deref (FDO #106559) - DMI fix to hide LVDS for Radiant P845 (FDO #105468) amdgpu: - suspend/resume DC regression fix - underscan flicker fix on fiji - gamma setting fix after dpms omap: - fix oops regression core: - fix PSR timing dw-hdmi: - fix oops regression" * tag 'drm-fixes-for-v4.17-rc8' of git://people.freedesktop.org/~airlied/linux: drm/amd/display: Update color props when modeset is required drm/amd/display: Make atomic-check validate underscan changes drm/bridge/synopsys: dw-hdmi: fix dw_hdmi_setup_rx_sense drm/amd/display: Fix BUG_ON during CRTC atomic check update drm/i915/query: nospec expects no more than an unsigned long drm/i915/query: Protect tainted function pointer lookup drm/i915/lvds: Move acpi lid notification registration to registration phase drm/i915: Disable LVDS on Radiant P845 drm/omap: fix NULL deref crash with SDI displays drm/psr: Fix missed entry in PSR setup time table.
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c44
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c15
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c1
-rw-r--r--drivers/gpu/drm/i915/i915_query.c15
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c51
-rw-r--r--drivers/gpu/drm/meson/meson_dw_hdmi.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/sdi.c5
-rw-r--r--include/drm/bridge/dw_hdmi.h2
8 files changed, 91 insertions, 44 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1dd1142246c2..27579443cdc5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4555,8 +4555,8 @@ static int dm_update_crtcs_state(struct dc *dc,
4555 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { 4555 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
4556 struct amdgpu_crtc *acrtc = NULL; 4556 struct amdgpu_crtc *acrtc = NULL;
4557 struct amdgpu_dm_connector *aconnector = NULL; 4557 struct amdgpu_dm_connector *aconnector = NULL;
4558 struct drm_connector_state *new_con_state = NULL; 4558 struct drm_connector_state *drm_new_conn_state = NULL, *drm_old_conn_state = NULL;
4559 struct dm_connector_state *dm_conn_state = NULL; 4559 struct dm_connector_state *dm_new_conn_state = NULL, *dm_old_conn_state = NULL;
4560 struct drm_plane_state *new_plane_state = NULL; 4560 struct drm_plane_state *new_plane_state = NULL;
4561 4561
4562 new_stream = NULL; 4562 new_stream = NULL;
@@ -4577,19 +4577,23 @@ static int dm_update_crtcs_state(struct dc *dc,
4577 /* TODO This hack should go away */ 4577 /* TODO This hack should go away */
4578 if (aconnector && enable) { 4578 if (aconnector && enable) {
4579 // Make sure fake sink is created in plug-in scenario 4579 // Make sure fake sink is created in plug-in scenario
4580 new_con_state = drm_atomic_get_connector_state(state, 4580 drm_new_conn_state = drm_atomic_get_new_connector_state(state,
4581 &aconnector->base); 4581 &aconnector->base);
4582 drm_old_conn_state = drm_atomic_get_old_connector_state(state,
4583 &aconnector->base);
4582 4584
4583 if (IS_ERR(new_con_state)) { 4585
4584 ret = PTR_ERR_OR_ZERO(new_con_state); 4586 if (IS_ERR(drm_new_conn_state)) {
4587 ret = PTR_ERR_OR_ZERO(drm_new_conn_state);
4585 break; 4588 break;
4586 } 4589 }
4587 4590
4588 dm_conn_state = to_dm_connector_state(new_con_state); 4591 dm_new_conn_state = to_dm_connector_state(drm_new_conn_state);
4592 dm_old_conn_state = to_dm_connector_state(drm_old_conn_state);
4589 4593
4590 new_stream = create_stream_for_sink(aconnector, 4594 new_stream = create_stream_for_sink(aconnector,
4591 &new_crtc_state->mode, 4595 &new_crtc_state->mode,
4592 dm_conn_state); 4596 dm_new_conn_state);
4593 4597
4594 /* 4598 /*
4595 * we can have no stream on ACTION_SET if a display 4599 * we can have no stream on ACTION_SET if a display
@@ -4695,20 +4699,30 @@ next_crtc:
4695 * We want to do dc stream updates that do not require a 4699 * We want to do dc stream updates that do not require a
4696 * full modeset below. 4700 * full modeset below.
4697 */ 4701 */
4698 if (!enable || !aconnector || modereset_required(new_crtc_state)) 4702 if (!(enable && aconnector && new_crtc_state->enable &&
4703 new_crtc_state->active))
4699 continue; 4704 continue;
4700 /* 4705 /*
4701 * Given above conditions, the dc state cannot be NULL because: 4706 * Given above conditions, the dc state cannot be NULL because:
4702 * 1. We're attempting to enable a CRTC. Which has a... 4707 * 1. We're in the process of enabling CRTCs (just been added
4703 * 2. Valid connector attached, and 4708 * to the dc context, or already is on the context)
4704 * 3. User does not want to reset it (disable or mark inactive, 4709 * 2. Has a valid connector attached, and
4705 * which can happen on a CRTC that's already disabled). 4710 * 3. Is currently active and enabled.
4706 * => It currently exists. 4711 * => The dc stream state currently exists.
4707 */ 4712 */
4708 BUG_ON(dm_new_crtc_state->stream == NULL); 4713 BUG_ON(dm_new_crtc_state->stream == NULL);
4709 4714
4710 /* Color managment settings */ 4715 /* Scaling or underscan settings */
4711 if (dm_new_crtc_state->base.color_mgmt_changed) { 4716 if (is_scaling_state_different(dm_old_conn_state, dm_new_conn_state))
4717 update_stream_scaling_settings(
4718 &new_crtc_state->mode, dm_new_conn_state, dm_new_crtc_state->stream);
4719
4720 /*
4721 * Color management settings. We also update color properties
4722 * when a modeset is needed, to ensure it gets reprogrammed.
4723 */
4724 if (dm_new_crtc_state->base.color_mgmt_changed ||
4725 drm_atomic_crtc_needs_modeset(new_crtc_state)) {
4712 ret = amdgpu_dm_set_regamma_lut(dm_new_crtc_state); 4726 ret = amdgpu_dm_set_regamma_lut(dm_new_crtc_state);
4713 if (ret) 4727 if (ret)
4714 goto fail; 4728 goto fail;
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index ec8d0006ef7c..3c136f2b954f 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2077,7 +2077,7 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
2077 return ret; 2077 return ret;
2078} 2078}
2079 2079
2080void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense) 2080void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
2081{ 2081{
2082 mutex_lock(&hdmi->mutex); 2082 mutex_lock(&hdmi->mutex);
2083 2083
@@ -2103,13 +2103,6 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
2103 } 2103 }
2104 mutex_unlock(&hdmi->mutex); 2104 mutex_unlock(&hdmi->mutex);
2105} 2105}
2106
2107void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense)
2108{
2109 struct dw_hdmi *hdmi = dev_get_drvdata(dev);
2110
2111 __dw_hdmi_setup_rx_sense(hdmi, hpd, rx_sense);
2112}
2113EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense); 2106EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
2114 2107
2115static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) 2108static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
@@ -2145,9 +2138,9 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
2145 */ 2138 */
2146 if (intr_stat & 2139 if (intr_stat &
2147 (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) { 2140 (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
2148 __dw_hdmi_setup_rx_sense(hdmi, 2141 dw_hdmi_setup_rx_sense(hdmi,
2149 phy_stat & HDMI_PHY_HPD, 2142 phy_stat & HDMI_PHY_HPD,
2150 phy_stat & HDMI_PHY_RX_SENSE); 2143 phy_stat & HDMI_PHY_RX_SENSE);
2151 2144
2152 if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) 2145 if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
2153 cec_notifier_set_phys_addr(hdmi->cec_notifier, 2146 cec_notifier_set_phys_addr(hdmi->cec_notifier,
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index ffe14ec3e7f2..70ae1f232331 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1145,6 +1145,7 @@ int drm_dp_psr_setup_time(const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE])
1145 static const u16 psr_setup_time_us[] = { 1145 static const u16 psr_setup_time_us[] = {
1146 PSR_SETUP_TIME(330), 1146 PSR_SETUP_TIME(330),
1147 PSR_SETUP_TIME(275), 1147 PSR_SETUP_TIME(275),
1148 PSR_SETUP_TIME(220),
1148 PSR_SETUP_TIME(165), 1149 PSR_SETUP_TIME(165),
1149 PSR_SETUP_TIME(110), 1150 PSR_SETUP_TIME(110),
1150 PSR_SETUP_TIME(55), 1151 PSR_SETUP_TIME(55),
diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c
index 3ace929dd90f..3f502eef2431 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -4,6 +4,8 @@
4 * Copyright © 2018 Intel Corporation 4 * Copyright © 2018 Intel Corporation
5 */ 5 */
6 6
7#include <linux/nospec.h>
8
7#include "i915_drv.h" 9#include "i915_drv.h"
8#include "i915_query.h" 10#include "i915_query.h"
9#include <uapi/drm/i915_drm.h> 11#include <uapi/drm/i915_drm.h>
@@ -100,7 +102,7 @@ int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
100 102
101 for (i = 0; i < args->num_items; i++, user_item_ptr++) { 103 for (i = 0; i < args->num_items; i++, user_item_ptr++) {
102 struct drm_i915_query_item item; 104 struct drm_i915_query_item item;
103 u64 func_idx; 105 unsigned long func_idx;
104 int ret; 106 int ret;
105 107
106 if (copy_from_user(&item, user_item_ptr, sizeof(item))) 108 if (copy_from_user(&item, user_item_ptr, sizeof(item)))
@@ -109,12 +111,17 @@ int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
109 if (item.query_id == 0) 111 if (item.query_id == 0)
110 return -EINVAL; 112 return -EINVAL;
111 113
114 if (overflows_type(item.query_id - 1, unsigned long))
115 return -EINVAL;
116
112 func_idx = item.query_id - 1; 117 func_idx = item.query_id - 1;
113 118
114 if (func_idx < ARRAY_SIZE(i915_query_funcs)) 119 ret = -EINVAL;
120 if (func_idx < ARRAY_SIZE(i915_query_funcs)) {
121 func_idx = array_index_nospec(func_idx,
122 ARRAY_SIZE(i915_query_funcs));
115 ret = i915_query_funcs[func_idx](dev_priv, &item); 123 ret = i915_query_funcs[func_idx](dev_priv, &item);
116 else 124 }
117 ret = -EINVAL;
118 125
119 /* Only write the length back to userspace if they differ. */ 126 /* Only write the length back to userspace if they differ. */
120 if (ret != item.length && put_user(ret, &user_item_ptr->length)) 127 if (ret != item.length && put_user(ret, &user_item_ptr->length))
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 8691c86f579c..e125d16a1aa7 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -574,6 +574,36 @@ exit:
574 return NOTIFY_OK; 574 return NOTIFY_OK;
575} 575}
576 576
577static int
578intel_lvds_connector_register(struct drm_connector *connector)
579{
580 struct intel_lvds_connector *lvds = to_lvds_connector(connector);
581 int ret;
582
583 ret = intel_connector_register(connector);
584 if (ret)
585 return ret;
586
587 lvds->lid_notifier.notifier_call = intel_lid_notify;
588 if (acpi_lid_notifier_register(&lvds->lid_notifier)) {
589 DRM_DEBUG_KMS("lid notifier registration failed\n");
590 lvds->lid_notifier.notifier_call = NULL;
591 }
592
593 return 0;
594}
595
596static void
597intel_lvds_connector_unregister(struct drm_connector *connector)
598{
599 struct intel_lvds_connector *lvds = to_lvds_connector(connector);
600
601 if (lvds->lid_notifier.notifier_call)
602 acpi_lid_notifier_unregister(&lvds->lid_notifier);
603
604 intel_connector_unregister(connector);
605}
606
577/** 607/**
578 * intel_lvds_destroy - unregister and free LVDS structures 608 * intel_lvds_destroy - unregister and free LVDS structures
579 * @connector: connector to free 609 * @connector: connector to free
@@ -586,9 +616,6 @@ static void intel_lvds_destroy(struct drm_connector *connector)
586 struct intel_lvds_connector *lvds_connector = 616 struct intel_lvds_connector *lvds_connector =
587 to_lvds_connector(connector); 617 to_lvds_connector(connector);
588 618
589 if (lvds_connector->lid_notifier.notifier_call)
590 acpi_lid_notifier_unregister(&lvds_connector->lid_notifier);
591
592 if (!IS_ERR_OR_NULL(lvds_connector->base.edid)) 619 if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
593 kfree(lvds_connector->base.edid); 620 kfree(lvds_connector->base.edid);
594 621
@@ -609,8 +636,8 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
609 .fill_modes = drm_helper_probe_single_connector_modes, 636 .fill_modes = drm_helper_probe_single_connector_modes,
610 .atomic_get_property = intel_digital_connector_atomic_get_property, 637 .atomic_get_property = intel_digital_connector_atomic_get_property,
611 .atomic_set_property = intel_digital_connector_atomic_set_property, 638 .atomic_set_property = intel_digital_connector_atomic_set_property,
612 .late_register = intel_connector_register, 639 .late_register = intel_lvds_connector_register,
613 .early_unregister = intel_connector_unregister, 640 .early_unregister = intel_lvds_connector_unregister,
614 .destroy = intel_lvds_destroy, 641 .destroy = intel_lvds_destroy,
615 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 642 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
616 .atomic_duplicate_state = intel_digital_connector_duplicate_state, 643 .atomic_duplicate_state = intel_digital_connector_duplicate_state,
@@ -827,6 +854,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
827 DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"), 854 DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
828 }, 855 },
829 }, 856 },
857 {
858 .callback = intel_no_lvds_dmi_callback,
859 .ident = "Radiant P845",
860 .matches = {
861 DMI_MATCH(DMI_SYS_VENDOR, "Radiant Systems Inc"),
862 DMI_MATCH(DMI_PRODUCT_NAME, "P845"),
863 },
864 },
830 865
831 { } /* terminating entry */ 866 { } /* terminating entry */
832}; 867};
@@ -1150,12 +1185,6 @@ out:
1150 1185
1151 lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK; 1186 lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK;
1152 1187
1153 lvds_connector->lid_notifier.notifier_call = intel_lid_notify;
1154 if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) {
1155 DRM_DEBUG_KMS("lid notifier registration failed\n");
1156 lvds_connector->lid_notifier.notifier_call = NULL;
1157 }
1158
1159 return; 1188 return;
1160 1189
1161failed: 1190failed:
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index a393095aac1a..c9ad45686e7a 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -529,7 +529,7 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
529 if (stat & HDMITX_TOP_INTR_HPD_RISE) 529 if (stat & HDMITX_TOP_INTR_HPD_RISE)
530 hpd_connected = true; 530 hpd_connected = true;
531 531
532 dw_hdmi_setup_rx_sense(dw_hdmi->dev, hpd_connected, 532 dw_hdmi_setup_rx_sense(dw_hdmi->hdmi, hpd_connected,
533 hpd_connected); 533 hpd_connected);
534 534
535 drm_helper_hpd_irq_event(dw_hdmi->encoder.dev); 535 drm_helper_hpd_irq_event(dw_hdmi->encoder.dev);
diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c
index 68a40ae26f5b..1e2c931f6acf 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -82,7 +82,7 @@ static int sdi_calc_clock_div(struct sdi_device *sdi, unsigned long pclk,
82 struct dispc_clock_info *dispc_cinfo) 82 struct dispc_clock_info *dispc_cinfo)
83{ 83{
84 int i; 84 int i;
85 struct sdi_clk_calc_ctx ctx = { .sdi = sdi }; 85 struct sdi_clk_calc_ctx ctx;
86 86
87 /* 87 /*
88 * DSS fclk gives us very few possibilities, so finding a good pixel 88 * DSS fclk gives us very few possibilities, so finding a good pixel
@@ -95,6 +95,9 @@ static int sdi_calc_clock_div(struct sdi_device *sdi, unsigned long pclk,
95 bool ok; 95 bool ok;
96 96
97 memset(&ctx, 0, sizeof(ctx)); 97 memset(&ctx, 0, sizeof(ctx));
98
99 ctx.sdi = sdi;
100
98 if (pclk > 1000 * i * i * i) 101 if (pclk > 1000 * i * i * i)
99 ctx.pck_min = max(pclk - 1000 * i * i * i, 0lu); 102 ctx.pck_min = max(pclk - 1000 * i * i * i, 0lu);
100 else 103 else
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index dd2a8cf7d20b..ccb5aa8468e0 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -151,7 +151,7 @@ struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
151 struct drm_encoder *encoder, 151 struct drm_encoder *encoder,
152 const struct dw_hdmi_plat_data *plat_data); 152 const struct dw_hdmi_plat_data *plat_data);
153 153
154void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense); 154void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense);
155 155
156void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate); 156void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
157void dw_hdmi_audio_enable(struct dw_hdmi *hdmi); 157void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);