Early at init time, we can try to read out the plane config structure
and try to preserve it if possible.

v2: alloc fb obj at init time after fetching plane config

Signed-off-by: Jesse Barnes <jbar...@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_drv.h      |  3 ++
 drivers/gpu/drm/i915/intel_display.c | 92 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h     |  9 ++++
 3 files changed, 104 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 29da39f..c9aad90 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -405,6 +405,7 @@ struct drm_i915_error_state {
 
 struct intel_connector;
 struct intel_crtc_config;
+struct intel_plane_config;
 struct intel_crtc;
 struct intel_limit;
 struct dpll;
@@ -443,6 +444,8 @@ struct drm_i915_display_funcs {
         * fills out the pipe-config with the hw state. */
        bool (*get_pipe_config)(struct intel_crtc *,
                                struct intel_crtc_config *);
+       void (*get_plane_config)(struct intel_crtc *,
+                                struct intel_plane_config *);
        int (*crtc_mode_set)(struct drm_crtc *crtc,
                             int x, int y,
                             struct drm_framebuffer *old_fb);
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 7e8bfd8..e793c2a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2047,6 +2047,70 @@ unsigned long intel_gen4_compute_page_offset(int *x, int 
*y,
        }
 }
 
+int intel_format_to_fourcc(int format)
+{
+       switch (format) {
+       case DISPPLANE_8BPP:
+               return DRM_FORMAT_C8;
+       case DISPPLANE_BGRX555:
+               return DRM_FORMAT_XRGB1555;
+       case DISPPLANE_BGRX565:
+               return DRM_FORMAT_RGB565;
+       default:
+       case DISPPLANE_BGRX888:
+               return DRM_FORMAT_XRGB8888;
+       case DISPPLANE_RGBX888:
+               return DRM_FORMAT_XBGR8888;
+       case DISPPLANE_BGRX101010:
+               return DRM_FORMAT_XRGB2101010;
+       case DISPPLANE_RGBX101010:
+               return DRM_FORMAT_XBGR2101010;
+       }
+}
+
+static void intel_alloc_plane_obj(struct intel_crtc *crtc,
+                                 struct intel_plane_config *plane_config)
+{
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_gem_object *obj = NULL;
+       struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+       u32 base = plane_config->base;
+
+       if (!plane_config->fb)
+               return;
+
+       obj = i915_gem_object_create_stolen_for_preallocated(dev, base, base,
+                                                            
plane_config->size);
+       if (!obj)
+               return;
+
+       if (plane_config->tiled) {
+               obj->tiling_mode = I915_TILING_X;
+               obj->stride = plane_config->fb->base.pitches[0];
+       }
+
+       mode_cmd.pixel_format = plane_config->fb->base.pixel_format;
+       mode_cmd.width = plane_config->fb->base.width;
+       mode_cmd.height = plane_config->fb->base.height;
+       mode_cmd.pitches[0] = plane_config->fb->base.pitches[0];
+
+       mutex_lock(&dev->struct_mutex);
+
+       if (intel_framebuffer_init(dev, plane_config->fb, &mode_cmd, obj)) {
+               DRM_DEBUG_KMS("intel fb init failed\n");
+               goto out_unref_obj;
+       }
+
+       mutex_unlock(&dev->struct_mutex);
+       DRM_DEBUG_KMS("plane fb obj %p\n", plane_config->fb->obj);
+       return;
+
+out_unref_obj:
+       drm_gem_object_unreference(&obj->base);
+       mutex_unlock(&dev->struct_mutex);
+
+}
+
 static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
                             int x, int y)
 {
@@ -10997,6 +11061,7 @@ void intel_modeset_init(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int sprite, ret;
        enum pipe pipe;
+       struct intel_crtc *crtc;
 
        drm_mode_config_init(dev);
 
@@ -11059,6 +11124,33 @@ void intel_modeset_init(struct drm_device *dev)
        mutex_lock(&dev->mode_config.mutex);
        intel_modeset_setup_hw_state(dev, false);
        mutex_unlock(&dev->mode_config.mutex);
+
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list,
+                           base.head) {
+               if (!crtc->active)
+                       continue;
+
+#if IS_ENABLED(CONFIG_FB)
+               /*
+                * We don't have a good way of freeing the buffer w/o the FB
+                * layer owning it...
+                * Note that reserving the BIOS fb up front prevents us
+                * from stuffing other stolen allocations like the ring
+                * on top.  This prevents some ugliness at boot time, and
+                * can even allow for smooth boot transitions if the BIOS
+                * fb is large enough for the active pipe configuration.
+                */
+               if (dev_priv->display.get_plane_config) {
+                       dev_priv->display.get_plane_config(crtc,
+                                                          &crtc->plane_config);
+                       /*
+                        * If the fb is shared between multiple heads, we'll
+                        * just get the first one.
+                        */
+                       intel_alloc_plane_obj(crtc, &crtc->plane_config);
+               }
+#endif
+       }
 }
 
 static void
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6042797..95dd15d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -218,6 +218,13 @@ typedef struct dpll {
        int     p;
 } intel_clock_t;
 
+struct intel_plane_config {
+       struct intel_framebuffer *fb; /* ends up managed by intel_fbdev.c */
+       bool tiled;
+       int size;
+       u32 base;
+};
+
 struct intel_crtc_config {
        /**
         * quirks - bitfield with hw state readout quirks
@@ -366,6 +373,7 @@ struct intel_crtc {
        int16_t cursor_width, cursor_height;
        bool cursor_visible;
 
+       struct intel_plane_config plane_config;
        struct intel_crtc_config config;
        struct intel_crtc_config *new_config;
        bool new_enabled;
@@ -736,6 +744,7 @@ void intel_display_set_init_power(struct drm_i915_private 
*dev, bool enable);
 int valleyview_get_vco(struct drm_i915_private *dev_priv);
 void intel_mode_from_pipe_config(struct drm_display_mode *mode,
                                 struct intel_crtc_config *pipe_config);
+int intel_format_to_fourcc(int format);
 
 /* intel_dp.c */
 void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
-- 
1.8.4.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to