mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-11 15:49:56 +00:00
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) {
|
||||
struct amdgpu_crtc *acrtc = NULL;
|
||||
struct amdgpu_dm_connector *aconnector = NULL;
|
||||
struct drm_connector_state *new_con_state = NULL;
|
||||
struct dm_connector_state *dm_conn_state = NULL;
|
||||
struct drm_connector_state *drm_new_conn_state = NULL, *drm_old_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;
|
||||
|
||||
new_stream = NULL;
|
||||
@ -4577,19 +4577,23 @@ static int dm_update_crtcs_state(struct dc *dc,
|
||||
/* TODO This hack should go away */
|
||||
if (aconnector && enable) {
|
||||
// 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);
|
||||
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;
|
||||
}
|
||||
|
||||
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_crtc_state->mode,
|
||||
dm_conn_state);
|
||||
dm_new_conn_state);
|
||||
|
||||
/*
|
||||
* we can have no stream on ACTION_SET if a display
|
||||
@ -4695,20 +4699,30 @@ next_crtc:
|
||||
* We want to do dc stream updates that do not require a
|
||||
* full modeset below.
|
||||
*/
|
||||
if (!enable || !aconnector || modereset_required(new_crtc_state))
|
||||
if (!(enable && aconnector && new_crtc_state->enable &&
|
||||
new_crtc_state->active))
|
||||
continue;
|
||||
/*
|
||||
* Given above conditions, the dc state cannot be NULL because:
|
||||
* 1. We're attempting to enable a CRTC. Which has a...
|
||||
* 2. Valid connector attached, and
|
||||
* 3. User does not want to reset it (disable or mark inactive,
|
||||
* which can happen on a CRTC that's already disabled).
|
||||
* => It currently exists.
|
||||
* 1. We're in the process of enabling CRTCs (just been added
|
||||
* to the dc context, or already is on the context)
|
||||
* 2. Has a valid connector attached, and
|
||||
* 3. Is currently active and enabled.
|
||||
* => The dc stream state currently exists.
|
||||
*/
|
||||
BUG_ON(dm_new_crtc_state->stream == NULL);
|
||||
|
||||
/* Color managment settings */
|
||||
if (dm_new_crtc_state->base.color_mgmt_changed) {
|
||||
/* Scaling or underscan settings */
|
||||
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);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
@ -2077,7 +2077,7 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
|
||||
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);
|
||||
|
||||
@ -2103,13 +2103,6 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
|
||||
}
|
||||
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);
|
||||
|
||||
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 &
|
||||
(HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
|
||||
__dw_hdmi_setup_rx_sense(hdmi,
|
||||
phy_stat & HDMI_PHY_HPD,
|
||||
phy_stat & HDMI_PHY_RX_SENSE);
|
||||
dw_hdmi_setup_rx_sense(hdmi,
|
||||
phy_stat & HDMI_PHY_HPD,
|
||||
phy_stat & HDMI_PHY_RX_SENSE);
|
||||
|
||||
if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
|
||||
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[] = {
|
||||
PSR_SETUP_TIME(330),
|
||||
PSR_SETUP_TIME(275),
|
||||
PSR_SETUP_TIME(220),
|
||||
PSR_SETUP_TIME(165),
|
||||
PSR_SETUP_TIME(110),
|
||||
PSR_SETUP_TIME(55),
|
||||
|
@ -4,6 +4,8 @@
|
||||
* Copyright © 2018 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/nospec.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_query.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++) {
|
||||
struct drm_i915_query_item item;
|
||||
u64 func_idx;
|
||||
unsigned long func_idx;
|
||||
int ret;
|
||||
|
||||
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)
|
||||
return -EINVAL;
|
||||
|
||||
if (overflows_type(item.query_id - 1, unsigned long))
|
||||
return -EINVAL;
|
||||
|
||||
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);
|
||||
else
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
/* Only write the length back to userspace if they differ. */
|
||||
if (ret != item.length && put_user(ret, &user_item_ptr->length))
|
||||
|
@ -574,6 +574,36 @@ exit:
|
||||
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
|
||||
* @connector: connector to free
|
||||
@ -586,9 +616,6 @@ static void intel_lvds_destroy(struct drm_connector *connector)
|
||||
struct intel_lvds_connector *lvds_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))
|
||||
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,
|
||||
.atomic_get_property = intel_digital_connector_atomic_get_property,
|
||||
.atomic_set_property = intel_digital_connector_atomic_set_property,
|
||||
.late_register = intel_connector_register,
|
||||
.early_unregister = intel_connector_unregister,
|
||||
.late_register = intel_lvds_connector_register,
|
||||
.early_unregister = intel_lvds_connector_unregister,
|
||||
.destroy = intel_lvds_destroy,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_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"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.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 */
|
||||
};
|
||||
@ -1150,12 +1185,6 @@ out:
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
@ -95,6 +95,9 @@ static int sdi_calc_clock_div(struct sdi_device *sdi, unsigned long pclk,
|
||||
bool ok;
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
|
||||
ctx.sdi = sdi;
|
||||
|
||||
if (pclk > 1000 * i * i * i)
|
||||
ctx.pck_min = max(pclk - 1000 * i * i * i, 0lu);
|
||||
else
|
||||
|
@ -151,7 +151,7 @@ struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
|
||||
struct drm_encoder *encoder,
|
||||
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_audio_enable(struct dw_hdmi *hdmi);
|
||||
|
Loading…
x
Reference in New Issue
Block a user