amdgpu, i915, omap, dw-hdmi fixes
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJbEvsXAAoJEAx081l5xIa+LncP/355OijfiJxjbze+eJVlz+1r CIlZsZBMc9aqsGU2HyVCTx3dqglrx0UbXZWRyI5WgPuqgi8x/rgbrTk+RyWr3eKw QQD+oHMN6vXn07ss3VYyHgW+5tkEZ/bbkTaTVRagag/wCZ9eOFgtww1VllYEw1ZG QI+tOWKhBpcU1dnoL+Bxu1W4JckPXK5FPlcFF/zkt/bIOSedoj+3MZl5Db7c1NSz quw0mR8C/luf5H2Ump5WIgqKRD8j3xM/EDnY0gdIg9HMmm3k0xIhNLcU/rwNi5ns qvurOPGK9Fteu94QnmmIbKj1E/ms/KRDA+71UoqmW2YYKJJAYHYr6t8Q4HXlKFcC MGq1pDGzaZrTbOtqHPJv6iLcnA28GgjDGQ0nQuNWp7mhjmb+fbqLftFQjLeHNPUc lu3pmmE8FZWI4lSTiqj5ojM1ceZFgGFN2l52PS+17wVHAHln+WpIMbFpaqkxlFRz zwMr09d70w8qQiW/0b5Pf8n7hq7ud3SZEOhzaAjQ6ggPNXRQ1czj1s8QUsUNt+3b o+uYC9kSpS67PxUs4QTPFyicMueZaGB+WT5Y+Cr5d4OJIwenzkmRhlAuR05W755T P5vbe4SJxih+FqcxfAWFJBFoRIRC49YxB/UXYpCIK4iSXpWVVNYearwzjJxywvzA QppQU+Y9IfvVPNHQtzxX =MK3/ -----END PGP SIGNATURE----- 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.
This commit is contained in:
commit
ada7339efe
@ -4555,8 +4555,8 @@ static int dm_update_crtcs_state(struct dc *dc,
|
|||||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||||
struct amdgpu_crtc *acrtc = NULL;
|
struct amdgpu_crtc *acrtc = NULL;
|
||||||
struct amdgpu_dm_connector *aconnector = NULL;
|
struct amdgpu_dm_connector *aconnector = NULL;
|
||||||
struct drm_connector_state *new_con_state = NULL;
|
struct drm_connector_state *drm_new_conn_state = NULL, *drm_old_conn_state = NULL;
|
||||||
struct dm_connector_state *dm_conn_state = NULL;
|
struct dm_connector_state *dm_new_conn_state = NULL, *dm_old_conn_state = NULL;
|
||||||
struct drm_plane_state *new_plane_state = NULL;
|
struct drm_plane_state *new_plane_state = NULL;
|
||||||
|
|
||||||
new_stream = NULL;
|
new_stream = NULL;
|
||||||
@ -4577,19 +4577,23 @@ static int dm_update_crtcs_state(struct dc *dc,
|
|||||||
/* TODO This hack should go away */
|
/* TODO This hack should go away */
|
||||||
if (aconnector && enable) {
|
if (aconnector && enable) {
|
||||||
// Make sure fake sink is created in plug-in scenario
|
// Make sure fake sink is created in plug-in scenario
|
||||||
new_con_state = drm_atomic_get_connector_state(state,
|
drm_new_conn_state = drm_atomic_get_new_connector_state(state,
|
||||||
&aconnector->base);
|
&aconnector->base);
|
||||||
|
drm_old_conn_state = drm_atomic_get_old_connector_state(state,
|
||||||
|
&aconnector->base);
|
||||||
|
|
||||||
if (IS_ERR(new_con_state)) {
|
|
||||||
ret = PTR_ERR_OR_ZERO(new_con_state);
|
if (IS_ERR(drm_new_conn_state)) {
|
||||||
|
ret = PTR_ERR_OR_ZERO(drm_new_conn_state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dm_conn_state = to_dm_connector_state(new_con_state);
|
dm_new_conn_state = to_dm_connector_state(drm_new_conn_state);
|
||||||
|
dm_old_conn_state = to_dm_connector_state(drm_old_conn_state);
|
||||||
|
|
||||||
new_stream = create_stream_for_sink(aconnector,
|
new_stream = create_stream_for_sink(aconnector,
|
||||||
&new_crtc_state->mode,
|
&new_crtc_state->mode,
|
||||||
dm_conn_state);
|
dm_new_conn_state);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we can have no stream on ACTION_SET if a display
|
* we can have no stream on ACTION_SET if a display
|
||||||
@ -4695,20 +4699,30 @@ static int dm_update_crtcs_state(struct dc *dc,
|
|||||||
* We want to do dc stream updates that do not require a
|
* We want to do dc stream updates that do not require a
|
||||||
* full modeset below.
|
* full modeset below.
|
||||||
*/
|
*/
|
||||||
if (!enable || !aconnector || modereset_required(new_crtc_state))
|
if (!(enable && aconnector && new_crtc_state->enable &&
|
||||||
|
new_crtc_state->active))
|
||||||
continue;
|
continue;
|
||||||
/*
|
/*
|
||||||
* Given above conditions, the dc state cannot be NULL because:
|
* Given above conditions, the dc state cannot be NULL because:
|
||||||
* 1. We're attempting to enable a CRTC. Which has a...
|
* 1. We're in the process of enabling CRTCs (just been added
|
||||||
* 2. Valid connector attached, and
|
* to the dc context, or already is on the context)
|
||||||
* 3. User does not want to reset it (disable or mark inactive,
|
* 2. Has a valid connector attached, and
|
||||||
* which can happen on a CRTC that's already disabled).
|
* 3. Is currently active and enabled.
|
||||||
* => It currently exists.
|
* => The dc stream state currently exists.
|
||||||
*/
|
*/
|
||||||
BUG_ON(dm_new_crtc_state->stream == NULL);
|
BUG_ON(dm_new_crtc_state->stream == NULL);
|
||||||
|
|
||||||
/* Color managment settings */
|
/* Scaling or underscan settings */
|
||||||
if (dm_new_crtc_state->base.color_mgmt_changed) {
|
if (is_scaling_state_different(dm_old_conn_state, dm_new_conn_state))
|
||||||
|
update_stream_scaling_settings(
|
||||||
|
&new_crtc_state->mode, dm_new_conn_state, dm_new_crtc_state->stream);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Color management settings. We also update color properties
|
||||||
|
* when a modeset is needed, to ensure it gets reprogrammed.
|
||||||
|
*/
|
||||||
|
if (dm_new_crtc_state->base.color_mgmt_changed ||
|
||||||
|
drm_atomic_crtc_needs_modeset(new_crtc_state)) {
|
||||||
ret = amdgpu_dm_set_regamma_lut(dm_new_crtc_state);
|
ret = amdgpu_dm_set_regamma_lut(dm_new_crtc_state);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -2077,7 +2077,7 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
|
void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
|
||||||
{
|
{
|
||||||
mutex_lock(&hdmi->mutex);
|
mutex_lock(&hdmi->mutex);
|
||||||
|
|
||||||
@ -2103,13 +2103,6 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
|
|||||||
}
|
}
|
||||||
mutex_unlock(&hdmi->mutex);
|
mutex_unlock(&hdmi->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense)
|
|
||||||
{
|
|
||||||
struct dw_hdmi *hdmi = dev_get_drvdata(dev);
|
|
||||||
|
|
||||||
__dw_hdmi_setup_rx_sense(hdmi, hpd, rx_sense);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
|
EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
|
||||||
|
|
||||||
static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
|
static 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)
|
|||||||
*/
|
*/
|
||||||
if (intr_stat &
|
if (intr_stat &
|
||||||
(HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
|
(HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
|
||||||
__dw_hdmi_setup_rx_sense(hdmi,
|
dw_hdmi_setup_rx_sense(hdmi,
|
||||||
phy_stat & HDMI_PHY_HPD,
|
phy_stat & HDMI_PHY_HPD,
|
||||||
phy_stat & HDMI_PHY_RX_SENSE);
|
phy_stat & HDMI_PHY_RX_SENSE);
|
||||||
|
|
||||||
if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
|
if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
|
||||||
cec_notifier_set_phys_addr(hdmi->cec_notifier,
|
cec_notifier_set_phys_addr(hdmi->cec_notifier,
|
||||||
|
@ -1145,6 +1145,7 @@ int drm_dp_psr_setup_time(const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE])
|
|||||||
static const u16 psr_setup_time_us[] = {
|
static const u16 psr_setup_time_us[] = {
|
||||||
PSR_SETUP_TIME(330),
|
PSR_SETUP_TIME(330),
|
||||||
PSR_SETUP_TIME(275),
|
PSR_SETUP_TIME(275),
|
||||||
|
PSR_SETUP_TIME(220),
|
||||||
PSR_SETUP_TIME(165),
|
PSR_SETUP_TIME(165),
|
||||||
PSR_SETUP_TIME(110),
|
PSR_SETUP_TIME(110),
|
||||||
PSR_SETUP_TIME(55),
|
PSR_SETUP_TIME(55),
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
* Copyright © 2018 Intel Corporation
|
* Copyright © 2018 Intel Corporation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/nospec.h>
|
||||||
|
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
#include "i915_query.h"
|
#include "i915_query.h"
|
||||||
#include <uapi/drm/i915_drm.h>
|
#include <uapi/drm/i915_drm.h>
|
||||||
@ -100,7 +102,7 @@ int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||||||
|
|
||||||
for (i = 0; i < args->num_items; i++, user_item_ptr++) {
|
for (i = 0; i < args->num_items; i++, user_item_ptr++) {
|
||||||
struct drm_i915_query_item item;
|
struct drm_i915_query_item item;
|
||||||
u64 func_idx;
|
unsigned long func_idx;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (copy_from_user(&item, user_item_ptr, sizeof(item)))
|
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)
|
|||||||
if (item.query_id == 0)
|
if (item.query_id == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (overflows_type(item.query_id - 1, unsigned long))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
func_idx = item.query_id - 1;
|
func_idx = item.query_id - 1;
|
||||||
|
|
||||||
if (func_idx < ARRAY_SIZE(i915_query_funcs))
|
ret = -EINVAL;
|
||||||
|
if (func_idx < ARRAY_SIZE(i915_query_funcs)) {
|
||||||
|
func_idx = array_index_nospec(func_idx,
|
||||||
|
ARRAY_SIZE(i915_query_funcs));
|
||||||
ret = i915_query_funcs[func_idx](dev_priv, &item);
|
ret = i915_query_funcs[func_idx](dev_priv, &item);
|
||||||
else
|
}
|
||||||
ret = -EINVAL;
|
|
||||||
|
|
||||||
/* Only write the length back to userspace if they differ. */
|
/* Only write the length back to userspace if they differ. */
|
||||||
if (ret != item.length && put_user(ret, &user_item_ptr->length))
|
if (ret != item.length && put_user(ret, &user_item_ptr->length))
|
||||||
|
@ -574,6 +574,36 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
|
|||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
intel_lvds_connector_register(struct drm_connector *connector)
|
||||||
|
{
|
||||||
|
struct intel_lvds_connector *lvds = to_lvds_connector(connector);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = intel_connector_register(connector);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
lvds->lid_notifier.notifier_call = intel_lid_notify;
|
||||||
|
if (acpi_lid_notifier_register(&lvds->lid_notifier)) {
|
||||||
|
DRM_DEBUG_KMS("lid notifier registration failed\n");
|
||||||
|
lvds->lid_notifier.notifier_call = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
intel_lvds_connector_unregister(struct drm_connector *connector)
|
||||||
|
{
|
||||||
|
struct intel_lvds_connector *lvds = to_lvds_connector(connector);
|
||||||
|
|
||||||
|
if (lvds->lid_notifier.notifier_call)
|
||||||
|
acpi_lid_notifier_unregister(&lvds->lid_notifier);
|
||||||
|
|
||||||
|
intel_connector_unregister(connector);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* intel_lvds_destroy - unregister and free LVDS structures
|
* intel_lvds_destroy - unregister and free LVDS structures
|
||||||
* @connector: connector to free
|
* @connector: connector to free
|
||||||
@ -586,9 +616,6 @@ static void intel_lvds_destroy(struct drm_connector *connector)
|
|||||||
struct intel_lvds_connector *lvds_connector =
|
struct intel_lvds_connector *lvds_connector =
|
||||||
to_lvds_connector(connector);
|
to_lvds_connector(connector);
|
||||||
|
|
||||||
if (lvds_connector->lid_notifier.notifier_call)
|
|
||||||
acpi_lid_notifier_unregister(&lvds_connector->lid_notifier);
|
|
||||||
|
|
||||||
if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
|
if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
|
||||||
kfree(lvds_connector->base.edid);
|
kfree(lvds_connector->base.edid);
|
||||||
|
|
||||||
@ -609,8 +636,8 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
|
|||||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||||
.atomic_get_property = intel_digital_connector_atomic_get_property,
|
.atomic_get_property = intel_digital_connector_atomic_get_property,
|
||||||
.atomic_set_property = intel_digital_connector_atomic_set_property,
|
.atomic_set_property = intel_digital_connector_atomic_set_property,
|
||||||
.late_register = intel_connector_register,
|
.late_register = intel_lvds_connector_register,
|
||||||
.early_unregister = intel_connector_unregister,
|
.early_unregister = intel_lvds_connector_unregister,
|
||||||
.destroy = intel_lvds_destroy,
|
.destroy = intel_lvds_destroy,
|
||||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||||
.atomic_duplicate_state = intel_digital_connector_duplicate_state,
|
.atomic_duplicate_state = intel_digital_connector_duplicate_state,
|
||||||
@ -827,6 +854,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
|
|||||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
|
DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.callback = intel_no_lvds_dmi_callback,
|
||||||
|
.ident = "Radiant P845",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Radiant Systems Inc"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "P845"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
{ } /* terminating entry */
|
{ } /* terminating entry */
|
||||||
};
|
};
|
||||||
@ -1150,12 +1185,6 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
|
|||||||
|
|
||||||
lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK;
|
lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK;
|
||||||
|
|
||||||
lvds_connector->lid_notifier.notifier_call = intel_lid_notify;
|
|
||||||
if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) {
|
|
||||||
DRM_DEBUG_KMS("lid notifier registration failed\n");
|
|
||||||
lvds_connector->lid_notifier.notifier_call = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
|
@ -529,7 +529,7 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
|
|||||||
if (stat & HDMITX_TOP_INTR_HPD_RISE)
|
if (stat & HDMITX_TOP_INTR_HPD_RISE)
|
||||||
hpd_connected = true;
|
hpd_connected = true;
|
||||||
|
|
||||||
dw_hdmi_setup_rx_sense(dw_hdmi->dev, hpd_connected,
|
dw_hdmi_setup_rx_sense(dw_hdmi->hdmi, hpd_connected,
|
||||||
hpd_connected);
|
hpd_connected);
|
||||||
|
|
||||||
drm_helper_hpd_irq_event(dw_hdmi->encoder.dev);
|
drm_helper_hpd_irq_event(dw_hdmi->encoder.dev);
|
||||||
|
@ -82,7 +82,7 @@ static int sdi_calc_clock_div(struct sdi_device *sdi, unsigned long pclk,
|
|||||||
struct dispc_clock_info *dispc_cinfo)
|
struct dispc_clock_info *dispc_cinfo)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct sdi_clk_calc_ctx ctx = { .sdi = sdi };
|
struct sdi_clk_calc_ctx ctx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DSS fclk gives us very few possibilities, so finding a good pixel
|
* 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,
|
|||||||
bool ok;
|
bool ok;
|
||||||
|
|
||||||
memset(&ctx, 0, sizeof(ctx));
|
memset(&ctx, 0, sizeof(ctx));
|
||||||
|
|
||||||
|
ctx.sdi = sdi;
|
||||||
|
|
||||||
if (pclk > 1000 * i * i * i)
|
if (pclk > 1000 * i * i * i)
|
||||||
ctx.pck_min = max(pclk - 1000 * i * i * i, 0lu);
|
ctx.pck_min = max(pclk - 1000 * i * i * i, 0lu);
|
||||||
else
|
else
|
||||||
|
@ -151,7 +151,7 @@ struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
|
|||||||
struct drm_encoder *encoder,
|
struct drm_encoder *encoder,
|
||||||
const struct dw_hdmi_plat_data *plat_data);
|
const struct dw_hdmi_plat_data *plat_data);
|
||||||
|
|
||||||
void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense);
|
void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense);
|
||||||
|
|
||||||
void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
|
void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
|
||||||
void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
|
void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
|
||||||
|
Loading…
Reference in New Issue
Block a user