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/i915/intel_display.c | |
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/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 92 |
1 files changed, 92 insertions, 0 deletions
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 |