Commit c6f95f27 authored by Matt Roper's avatar Matt Roper Committed by Daniel Vetter

drm/i915: Setup dummy atomic state for connectors (v3)

We want to enable/test plane updates via the atomic interface, but as
soon as we flip DRIVER_ATOMIC on, the DRM core will take some atomic
codepaths to lookup properties during drmModeGetConnector() and some of
those codepaths unconditionally dereference connector->state
(specifically when looking up the CRTC ID property in
drm_atomic_connector_get_property()).  Create a dummy connector state
for each connector at init time to ensure the DRM core doesn't try to
dereference a NULL connector->state.  The actual connector properties
will never be updated or contain useful information, but since we're
doing this specifically for testing/debug of the plane operations (and
only when a specific kernel module option is given), that shouldn't
really matter.

Once we start creating connector states, the DRM core will want to be
able to clean them up for us.  We also need to hook up the destruction
entrypoint to the core's helper.

v2: Squash in the patch to set the state destruction hook (Ander & Bob)

v3: Only create dummy connector states when we're actually faking
    atomic support.  (Ander)
Signed-off-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Reviewed-by: default avatarAnder Conselvan de Oliveira <conselvan2@gmail.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 5ee67f1c
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
...@@ -792,6 +793,7 @@ static const struct drm_connector_funcs intel_crt_connector_funcs = { ...@@ -792,6 +793,7 @@ static const struct drm_connector_funcs intel_crt_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = intel_crt_destroy, .destroy = intel_crt_destroy,
.set_property = intel_crt_set_property, .set_property = intel_crt_set_property,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
}; };
static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = { static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = {
......
...@@ -12439,6 +12439,7 @@ static void intel_setup_outputs(struct drm_device *dev) ...@@ -12439,6 +12439,7 @@ static void intel_setup_outputs(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *encoder; struct intel_encoder *encoder;
struct drm_connector *connector;
bool dpd_is_edp = false; bool dpd_is_edp = false;
intel_lvds_init(dev); intel_lvds_init(dev);
...@@ -12569,6 +12570,37 @@ static void intel_setup_outputs(struct drm_device *dev) ...@@ -12569,6 +12570,37 @@ static void intel_setup_outputs(struct drm_device *dev)
if (SUPPORTS_TV(dev)) if (SUPPORTS_TV(dev))
intel_tv_init(dev); intel_tv_init(dev);
/*
* FIXME: We don't have full atomic support yet, but we want to be
* able to enable/test plane updates via the atomic interface in the
* meantime. However as soon as we flip DRIVER_ATOMIC on, the DRM core
* will take some atomic codepaths to lookup properties during
* drmModeGetConnector() that unconditionally dereference
* connector->state.
*
* We create a dummy connector state here for each connector to ensure
* the DRM core doesn't try to dereference a NULL connector->state.
* The actual connector properties will never be updated or contain
* useful information, but since we're doing this specifically for
* testing/debug of the plane operations (and only when a specific
* kernel module option is given), that shouldn't really matter.
*
* Once atomic support for crtc's + connectors lands, this loop should
* be removed since we'll be setting up real connector state, which
* will contain Intel-specific properties.
*/
if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
list_for_each_entry(connector,
&dev->mode_config.connector_list,
head) {
if (!WARN_ON(connector->state)) {
connector->state =
kzalloc(sizeof(*connector->state),
GFP_KERNEL);
}
}
}
intel_psr_init(dev); intel_psr_init(dev);
for_each_intel_encoder(dev, encoder) { for_each_intel_encoder(dev, encoder) {
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
...@@ -4402,6 +4403,7 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = { ...@@ -4402,6 +4403,7 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_dp_set_property, .set_property = intel_dp_set_property,
.destroy = intel_dp_connector_destroy, .destroy = intel_dp_connector_destroy,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
}; };
static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = {
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_drv.h" #include "intel_drv.h"
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
...@@ -314,6 +315,7 @@ static const struct drm_connector_funcs intel_dp_mst_connector_funcs = { ...@@ -314,6 +315,7 @@ static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_dp_mst_set_property, .set_property = intel_dp_mst_set_property,
.destroy = intel_dp_mst_connector_destroy, .destroy = intel_dp_mst_connector_destroy,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
}; };
static int intel_dp_mst_get_modes(struct drm_connector *connector) static int intel_dp_mst_get_modes(struct drm_connector *connector)
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
*/ */
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
#include <drm/i915_drm.h> #include <drm/i915_drm.h>
...@@ -785,6 +786,7 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = { ...@@ -785,6 +786,7 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
.detect = intel_dsi_detect, .detect = intel_dsi_detect,
.destroy = intel_dsi_destroy, .destroy = intel_dsi_destroy,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
}; };
void intel_dsi_init(struct drm_device *dev) void intel_dsi_init(struct drm_device *dev)
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include "intel_drv.h" #include "intel_drv.h"
#include <drm/i915_drm.h> #include <drm/i915_drm.h>
...@@ -390,6 +391,7 @@ static const struct drm_connector_funcs intel_dvo_connector_funcs = { ...@@ -390,6 +391,7 @@ static const struct drm_connector_funcs intel_dvo_connector_funcs = {
.detect = intel_dvo_detect, .detect = intel_dvo_detect,
.destroy = intel_dvo_destroy, .destroy = intel_dvo_destroy,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
}; };
static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = { static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = {
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/hdmi.h> #include <linux/hdmi.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
#include "intel_drv.h" #include "intel_drv.h"
...@@ -1615,6 +1616,7 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = { ...@@ -1615,6 +1616,7 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_hdmi_set_property, .set_property = intel_hdmi_set_property,
.destroy = intel_hdmi_destroy, .destroy = intel_hdmi_destroy,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
}; };
static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = { static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = {
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
#include "intel_drv.h" #include "intel_drv.h"
...@@ -532,6 +533,7 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = { ...@@ -532,6 +533,7 @@ 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,
.set_property = intel_lvds_set_property, .set_property = intel_lvds_set_property,
.destroy = intel_lvds_destroy, .destroy = intel_lvds_destroy,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
}; };
static const struct drm_encoder_funcs intel_lvds_enc_funcs = { static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/export.h> #include <linux/export.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
#include "intel_drv.h" #include "intel_drv.h"
...@@ -2191,6 +2192,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = { ...@@ -2191,6 +2192,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_sdvo_set_property, .set_property = intel_sdvo_set_property,
.destroy = intel_sdvo_destroy, .destroy = intel_sdvo_destroy,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
}; };
static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = { static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
*/ */
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
#include "intel_drv.h" #include "intel_drv.h"
...@@ -1513,6 +1514,7 @@ static const struct drm_connector_funcs intel_tv_connector_funcs = { ...@@ -1513,6 +1514,7 @@ static const struct drm_connector_funcs intel_tv_connector_funcs = {
.destroy = intel_tv_destroy, .destroy = intel_tv_destroy,
.set_property = intel_tv_set_property, .set_property = intel_tv_set_property,
.fill_modes = drm_helper_probe_single_connector_modes, .fill_modes = drm_helper_probe_single_connector_modes,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
}; };
static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = { static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment