drm/i915: Setup dummy atomic state for connectors (v3)
authorMatt Roper <matthew.d.roper@intel.com>
Fri, 23 Jan 2015 00:50:32 +0000 (16:50 -0800)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 27 Jan 2015 08:57:02 +0000 (09:57 +0100)
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: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_dp_mst.c
drivers/gpu/drm/i915/intel_dsi.c
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_tv.c

index bb55368960e8dd1a874a0ec9135ede9ff2183d9b..18ee41ef0f18a389bf9418c47ae061a7c33ff988 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
@@ -792,6 +793,7 @@ static const struct drm_connector_funcs intel_crt_connector_funcs = {
        .fill_modes = drm_helper_probe_single_connector_modes,
        .destroy = intel_crt_destroy,
        .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 = {
index 75b7ca1488e9add2d8cbabd66a28f205212abf5a..b461f90698e36a6d36ad8499a8908ae3599b4d43 100644 (file)
@@ -12439,6 +12439,7 @@ static void intel_setup_outputs(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_encoder *encoder;
+       struct drm_connector *connector;
        bool dpd_is_edp = false;
 
        intel_lvds_init(dev);
@@ -12569,6 +12570,37 @@ static void intel_setup_outputs(struct drm_device *dev)
        if (SUPPORTS_TV(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);
 
        for_each_intel_encoder(dev, encoder) {
index a2adfa36d83bd175df12b6a6209da1f6f1acd50a..8bdaaaff35f34a8a36484ee748c2868ce2a00bbe 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
@@ -4402,6 +4403,7 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = {
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = intel_dp_set_property,
        .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 = {
index 0091a84fdd2452f08c8facae5bedc0ef8eeaea2a..f86da0fad718ad5f36a0862efc7885a7c3fbb31e 100644 (file)
@@ -26,6 +26,7 @@
 #include <drm/drmP.h>
 #include "i915_drv.h"
 #include "intel_drv.h"
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 
@@ -314,6 +315,7 @@ static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = intel_dp_mst_set_property,
        .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)
index c56c4150fc13fb71ff63befac62a206a78bbd056..e20bb1f8879cc10a39dcba4e2385fc0ed0f78bb9 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
 #include <drm/i915_drm.h>
@@ -785,6 +786,7 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
        .detect = intel_dsi_detect,
        .destroy = intel_dsi_destroy,
        .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)
index 706ab99ff4b65e95f33c97ef364a82945b320933..1cf2e352ad1be476c0af0437f10817e3eeca8977 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include "intel_drv.h"
 #include <drm/i915_drm.h>
@@ -390,6 +391,7 @@ static const struct drm_connector_funcs intel_dvo_connector_funcs = {
        .detect = intel_dvo_detect,
        .destroy = intel_dvo_destroy,
        .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 = {
index 200a0e7f2a2dc260d100e6ce853515f1a478b231..b8fab8cb42bf195a513940ceddcaa85880d4fe7a 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/delay.h>
 #include <linux/hdmi.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
 #include "intel_drv.h"
@@ -1615,6 +1616,7 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = intel_hdmi_set_property,
        .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 = {
index c7c6414d9f8df5b57705e305821b7987af294e71..908bd42fac5da9a8841db16cf038d1fbf9886dd3 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
 #include "intel_drv.h"
@@ -532,6 +533,7 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = intel_lvds_set_property,
        .destroy = intel_lvds_destroy,
+       .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
index 5b8275b04b9a9a65bd55b48f8311e7dffdcfe378..ae00bf9ce07a85568e7339c4903655b03cc6df92 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/delay.h>
 #include <linux/export.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
 #include "intel_drv.h"
@@ -2191,6 +2192,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = intel_sdvo_set_property,
        .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 = {
index 10e7ebd79f5a2882b3ed91c43d24cf54677acf79..d450054584a926c955bec79ca6b13d02c9330ea4 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
 #include "intel_drv.h"
@@ -1513,6 +1514,7 @@ static const struct drm_connector_funcs intel_tv_connector_funcs = {
        .destroy = intel_tv_destroy,
        .set_property = intel_tv_set_property,
        .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 = {