diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2014-03-07 11:57:48 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-03-08 05:31:29 -0500 |
commit | 46f297fb83d4f9a6f6891964beb184664341a28b (patch) | |
tree | 01e3b56de203fdce2619bcb46d2907522eb65b79 /drivers/gpu/drm | |
parent | c2831a94b5e77a407db0708816949d4a87416a8e (diff) |
drm/i915: add plane_config fetching infrastructure v2
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 <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 92 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 9 |
3 files changed, 104 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7b6dfdfb2d8d..bfb537942dbe 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -406,6 +406,7 @@ struct drm_i915_error_state { | |||
406 | 406 | ||
407 | struct intel_connector; | 407 | struct intel_connector; |
408 | struct intel_crtc_config; | 408 | struct intel_crtc_config; |
409 | struct intel_plane_config; | ||
409 | struct intel_crtc; | 410 | struct intel_crtc; |
410 | struct intel_limit; | 411 | struct intel_limit; |
411 | struct dpll; | 412 | struct dpll; |
@@ -444,6 +445,8 @@ struct drm_i915_display_funcs { | |||
444 | * fills out the pipe-config with the hw state. */ | 445 | * fills out the pipe-config with the hw state. */ |
445 | bool (*get_pipe_config)(struct intel_crtc *, | 446 | bool (*get_pipe_config)(struct intel_crtc *, |
446 | struct intel_crtc_config *); | 447 | struct intel_crtc_config *); |
448 | void (*get_plane_config)(struct intel_crtc *, | ||
449 | struct intel_plane_config *); | ||
447 | int (*crtc_mode_set)(struct drm_crtc *crtc, | 450 | int (*crtc_mode_set)(struct drm_crtc *crtc, |
448 | int x, int y, | 451 | int x, int y, |
449 | struct drm_framebuffer *old_fb); | 452 | struct drm_framebuffer *old_fb); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 56edc8409856..482b8d4bd94a 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, | |||
2047 | } | 2047 | } |
2048 | } | 2048 | } |
2049 | 2049 | ||
2050 | int intel_format_to_fourcc(int format) | ||
2051 | { | ||
2052 | switch (format) { | ||
2053 | case DISPPLANE_8BPP: | ||
2054 | return DRM_FORMAT_C8; | ||
2055 | case DISPPLANE_BGRX555: | ||
2056 | return DRM_FORMAT_XRGB1555; | ||
2057 | case DISPPLANE_BGRX565: | ||
2058 | return DRM_FORMAT_RGB565; | ||
2059 | default: | ||
2060 | case DISPPLANE_BGRX888: | ||
2061 | return DRM_FORMAT_XRGB8888; | ||
2062 | case DISPPLANE_RGBX888: | ||
2063 | return DRM_FORMAT_XBGR8888; | ||
2064 | case DISPPLANE_BGRX101010: | ||
2065 | return DRM_FORMAT_XRGB2101010; | ||
2066 | case DISPPLANE_RGBX101010: | ||
2067 | return DRM_FORMAT_XBGR2101010; | ||
2068 | } | ||
2069 | } | ||
2070 | |||
2071 | static void intel_alloc_plane_obj(struct intel_crtc *crtc, | ||
2072 | struct intel_plane_config *plane_config) | ||
2073 | { | ||
2074 | struct drm_device *dev = crtc->base.dev; | ||
2075 | struct drm_i915_gem_object *obj = NULL; | ||
2076 | struct drm_mode_fb_cmd2 mode_cmd = { 0 }; | ||
2077 | u32 base = plane_config->base; | ||
2078 | |||
2079 | if (!plane_config->fb) | ||
2080 | return; | ||
2081 | |||
2082 | obj = i915_gem_object_create_stolen_for_preallocated(dev, base, base, | ||
2083 | plane_config->size); | ||
2084 | if (!obj) | ||
2085 | return; | ||
2086 | |||
2087 | if (plane_config->tiled) { | ||
2088 | obj->tiling_mode = I915_TILING_X; | ||
2089 | obj->stride = plane_config->fb->base.pitches[0]; | ||
2090 | } | ||
2091 | |||
2092 | mode_cmd.pixel_format = plane_config->fb->base.pixel_format; | ||
2093 | mode_cmd.width = plane_config->fb->base.width; | ||
2094 | mode_cmd.height = plane_config->fb->base.height; | ||
2095 | mode_cmd.pitches[0] = plane_config->fb->base.pitches[0]; | ||
2096 | |||
2097 | mutex_lock(&dev->struct_mutex); | ||
2098 | |||
2099 | if (intel_framebuffer_init(dev, plane_config->fb, &mode_cmd, obj)) { | ||
2100 | DRM_DEBUG_KMS("intel fb init failed\n"); | ||
2101 | goto out_unref_obj; | ||
2102 | } | ||
2103 | |||
2104 | mutex_unlock(&dev->struct_mutex); | ||
2105 | DRM_DEBUG_KMS("plane fb obj %p\n", plane_config->fb->obj); | ||
2106 | return; | ||
2107 | |||
2108 | out_unref_obj: | ||
2109 | drm_gem_object_unreference(&obj->base); | ||
2110 | mutex_unlock(&dev->struct_mutex); | ||
2111 | |||
2112 | } | ||
2113 | |||
2050 | static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, | 2114 | static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
2051 | int x, int y) | 2115 | int x, int y) |
2052 | { | 2116 | { |
@@ -11033,6 +11097,7 @@ void intel_modeset_init(struct drm_device *dev) | |||
11033 | struct drm_i915_private *dev_priv = dev->dev_private; | 11097 | struct drm_i915_private *dev_priv = dev->dev_private; |
11034 | int sprite, ret; | 11098 | int sprite, ret; |
11035 | enum pipe pipe; | 11099 | enum pipe pipe; |
11100 | struct intel_crtc *crtc; | ||
11036 | 11101 | ||
11037 | drm_mode_config_init(dev); | 11102 | drm_mode_config_init(dev); |
11038 | 11103 | ||
@@ -11095,6 +11160,33 @@ void intel_modeset_init(struct drm_device *dev) | |||
11095 | mutex_lock(&dev->mode_config.mutex); | 11160 | mutex_lock(&dev->mode_config.mutex); |
11096 | intel_modeset_setup_hw_state(dev, false); | 11161 | intel_modeset_setup_hw_state(dev, false); |
11097 | mutex_unlock(&dev->mode_config.mutex); | 11162 | mutex_unlock(&dev->mode_config.mutex); |
11163 | |||
11164 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, | ||
11165 | base.head) { | ||
11166 | if (!crtc->active) | ||
11167 | continue; | ||
11168 | |||
11169 | #if IS_ENABLED(CONFIG_FB) | ||
11170 | /* | ||
11171 | * We don't have a good way of freeing the buffer w/o the FB | ||
11172 | * layer owning it... | ||
11173 | * Note that reserving the BIOS fb up front prevents us | ||
11174 | * from stuffing other stolen allocations like the ring | ||
11175 | * on top. This prevents some ugliness at boot time, and | ||
11176 | * can even allow for smooth boot transitions if the BIOS | ||
11177 | * fb is large enough for the active pipe configuration. | ||
11178 | */ | ||
11179 | if (dev_priv->display.get_plane_config) { | ||
11180 | dev_priv->display.get_plane_config(crtc, | ||
11181 | &crtc->plane_config); | ||
11182 | /* | ||
11183 | * If the fb is shared between multiple heads, we'll | ||
11184 | * just get the first one. | ||
11185 | */ | ||
11186 | intel_alloc_plane_obj(crtc, &crtc->plane_config); | ||
11187 | } | ||
11188 | #endif | ||
11189 | } | ||
11098 | } | 11190 | } |
11099 | 11191 | ||
11100 | static void | 11192 | static void |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9c7090590776..48af57bbc73d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -218,6 +218,13 @@ typedef struct dpll { | |||
218 | int p; | 218 | int p; |
219 | } intel_clock_t; | 219 | } intel_clock_t; |
220 | 220 | ||
221 | struct intel_plane_config { | ||
222 | struct intel_framebuffer *fb; /* ends up managed by intel_fbdev.c */ | ||
223 | bool tiled; | ||
224 | int size; | ||
225 | u32 base; | ||
226 | }; | ||
227 | |||
221 | struct intel_crtc_config { | 228 | struct intel_crtc_config { |
222 | /** | 229 | /** |
223 | * quirks - bitfield with hw state readout quirks | 230 | * quirks - bitfield with hw state readout quirks |
@@ -366,6 +373,7 @@ struct intel_crtc { | |||
366 | int16_t cursor_width, cursor_height; | 373 | int16_t cursor_width, cursor_height; |
367 | bool cursor_visible; | 374 | bool cursor_visible; |
368 | 375 | ||
376 | struct intel_plane_config plane_config; | ||
369 | struct intel_crtc_config config; | 377 | struct intel_crtc_config config; |
370 | struct intel_crtc_config *new_config; | 378 | struct intel_crtc_config *new_config; |
371 | bool new_enabled; | 379 | bool new_enabled; |
@@ -740,6 +748,7 @@ intel_display_port_power_domain(struct intel_encoder *intel_encoder); | |||
740 | int valleyview_get_vco(struct drm_i915_private *dev_priv); | 748 | int valleyview_get_vco(struct drm_i915_private *dev_priv); |
741 | void intel_mode_from_pipe_config(struct drm_display_mode *mode, | 749 | void intel_mode_from_pipe_config(struct drm_display_mode *mode, |
742 | struct intel_crtc_config *pipe_config); | 750 | struct intel_crtc_config *pipe_config); |
751 | int intel_format_to_fourcc(int format); | ||
743 | 752 | ||
744 | /* intel_dp.c */ | 753 | /* intel_dp.c */ |
745 | void intel_dp_init(struct drm_device *dev, int output_reg, enum port port); | 754 | void intel_dp_init(struct drm_device *dev, int output_reg, enum port port); |