aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fb.c')
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c82
1 files changed, 34 insertions, 48 deletions
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index b61966c126d3..ec49bae73382 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -44,13 +44,6 @@
44#include "i915_drm.h" 44#include "i915_drm.h"
45#include "i915_drv.h" 45#include "i915_drv.h"
46 46
47struct intel_fbdev {
48 struct drm_fb_helper helper;
49 struct intel_framebuffer ifb;
50 struct list_head fbdev_list;
51 struct drm_display_mode *our_mode;
52};
53
54static struct fb_ops intelfb_ops = { 47static struct fb_ops intelfb_ops = {
55 .owner = THIS_MODULE, 48 .owner = THIS_MODULE,
56 .fb_check_var = drm_fb_helper_check_var, 49 .fb_check_var = drm_fb_helper_check_var,
@@ -69,13 +62,13 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
69 struct drm_fb_helper_surface_size *sizes) 62 struct drm_fb_helper_surface_size *sizes)
70{ 63{
71 struct drm_device *dev = ifbdev->helper.dev; 64 struct drm_device *dev = ifbdev->helper.dev;
65 struct drm_i915_private *dev_priv = dev->dev_private;
72 struct fb_info *info; 66 struct fb_info *info;
73 struct drm_framebuffer *fb; 67 struct drm_framebuffer *fb;
74 struct drm_mode_fb_cmd mode_cmd; 68 struct drm_mode_fb_cmd mode_cmd;
75 struct drm_gem_object *fbo = NULL; 69 struct drm_i915_gem_object *obj;
76 struct drm_i915_gem_object *obj_priv;
77 struct device *device = &dev->pdev->dev; 70 struct device *device = &dev->pdev->dev;
78 int size, ret, mmio_bar = IS_I9XX(dev) ? 0 : 1; 71 int size, ret;
79 72
80 /* we don't do packed 24bpp */ 73 /* we don't do packed 24bpp */
81 if (sizes->surface_bpp == 24) 74 if (sizes->surface_bpp == 24)
@@ -85,34 +78,27 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
85 mode_cmd.height = sizes->surface_height; 78 mode_cmd.height = sizes->surface_height;
86 79
87 mode_cmd.bpp = sizes->surface_bpp; 80 mode_cmd.bpp = sizes->surface_bpp;
88 mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64); 81 mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64);
89 mode_cmd.depth = sizes->surface_depth; 82 mode_cmd.depth = sizes->surface_depth;
90 83
91 size = mode_cmd.pitch * mode_cmd.height; 84 size = mode_cmd.pitch * mode_cmd.height;
92 size = ALIGN(size, PAGE_SIZE); 85 size = ALIGN(size, PAGE_SIZE);
93 fbo = i915_gem_alloc_object(dev, size); 86 obj = i915_gem_alloc_object(dev, size);
94 if (!fbo) { 87 if (!obj) {
95 DRM_ERROR("failed to allocate framebuffer\n"); 88 DRM_ERROR("failed to allocate framebuffer\n");
96 ret = -ENOMEM; 89 ret = -ENOMEM;
97 goto out; 90 goto out;
98 } 91 }
99 obj_priv = to_intel_bo(fbo);
100 92
101 mutex_lock(&dev->struct_mutex); 93 mutex_lock(&dev->struct_mutex);
102 94
103 ret = intel_pin_and_fence_fb_obj(dev, fbo); 95 /* Flush everything out, we'll be doing GTT only from now on */
96 ret = intel_pin_and_fence_fb_obj(dev, obj, false);
104 if (ret) { 97 if (ret) {
105 DRM_ERROR("failed to pin fb: %d\n", ret); 98 DRM_ERROR("failed to pin fb: %d\n", ret);
106 goto out_unref; 99 goto out_unref;
107 } 100 }
108 101
109 /* Flush everything out, we'll be doing GTT only from now on */
110 ret = i915_gem_object_set_to_gtt_domain(fbo, 1);
111 if (ret) {
112 DRM_ERROR("failed to bind fb: %d.\n", ret);
113 goto out_unpin;
114 }
115
116 info = framebuffer_alloc(0, device); 102 info = framebuffer_alloc(0, device);
117 if (!info) { 103 if (!info) {
118 ret = -ENOMEM; 104 ret = -ENOMEM;
@@ -121,7 +107,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
121 107
122 info->par = ifbdev; 108 info->par = ifbdev;
123 109
124 ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, fbo); 110 ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj);
125 if (ret) 111 if (ret)
126 goto out_unpin; 112 goto out_unpin;
127 113
@@ -135,6 +121,11 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
135 info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; 121 info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
136 info->fbops = &intelfb_ops; 122 info->fbops = &intelfb_ops;
137 123
124 ret = fb_alloc_cmap(&info->cmap, 256, 0);
125 if (ret) {
126 ret = -ENOMEM;
127 goto out_unpin;
128 }
138 /* setup aperture base/size for vesafb takeover */ 129 /* setup aperture base/size for vesafb takeover */
139 info->apertures = alloc_apertures(1); 130 info->apertures = alloc_apertures(1);
140 if (!info->apertures) { 131 if (!info->apertures) {
@@ -142,26 +133,17 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
142 goto out_unpin; 133 goto out_unpin;
143 } 134 }
144 info->apertures->ranges[0].base = dev->mode_config.fb_base; 135 info->apertures->ranges[0].base = dev->mode_config.fb_base;
145 if (IS_I9XX(dev)) 136 info->apertures->ranges[0].size =
146 info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 2); 137 dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
147 else
148 info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0);
149 138
150 info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset; 139 info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset;
151 info->fix.smem_len = size; 140 info->fix.smem_len = size;
152 141
153 info->screen_base = ioremap_wc(dev->agp->base + obj_priv->gtt_offset, 142 info->screen_base = ioremap_wc(dev->agp->base + obj->gtt_offset, size);
154 size);
155 if (!info->screen_base) { 143 if (!info->screen_base) {
156 ret = -ENOSPC; 144 ret = -ENOSPC;
157 goto out_unpin; 145 goto out_unpin;
158 } 146 }
159
160 ret = fb_alloc_cmap(&info->cmap, 256, 0);
161 if (ret) {
162 ret = -ENOMEM;
163 goto out_unpin;
164 }
165 info->screen_size = size; 147 info->screen_size = size;
166 148
167// memset(info->screen_base, 0, size); 149// memset(info->screen_base, 0, size);
@@ -169,10 +151,6 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
169 drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); 151 drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
170 drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); 152 drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
171 153
172 /* FIXME: we really shouldn't expose mmio space at all */
173 info->fix.mmio_start = pci_resource_start(dev->pdev, mmio_bar);
174 info->fix.mmio_len = pci_resource_len(dev->pdev, mmio_bar);
175
176 info->pixmap.size = 64*1024; 154 info->pixmap.size = 64*1024;
177 info->pixmap.buf_align = 8; 155 info->pixmap.buf_align = 8;
178 info->pixmap.access_align = 32; 156 info->pixmap.access_align = 32;
@@ -181,7 +159,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
181 159
182 DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", 160 DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n",
183 fb->width, fb->height, 161 fb->width, fb->height,
184 obj_priv->gtt_offset, fbo); 162 obj->gtt_offset, obj);
185 163
186 164
187 mutex_unlock(&dev->struct_mutex); 165 mutex_unlock(&dev->struct_mutex);
@@ -189,9 +167,9 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
189 return 0; 167 return 0;
190 168
191out_unpin: 169out_unpin:
192 i915_gem_object_unpin(fbo); 170 i915_gem_object_unpin(obj);
193out_unref: 171out_unref:
194 drm_gem_object_unreference(fbo); 172 drm_gem_object_unreference(&obj->base);
195 mutex_unlock(&dev->struct_mutex); 173 mutex_unlock(&dev->struct_mutex);
196out: 174out:
197 return ret; 175 return ret;
@@ -219,8 +197,8 @@ static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
219 .fb_probe = intel_fb_find_or_create_single, 197 .fb_probe = intel_fb_find_or_create_single,
220}; 198};
221 199
222int intel_fbdev_destroy(struct drm_device *dev, 200static void intel_fbdev_destroy(struct drm_device *dev,
223 struct intel_fbdev *ifbdev) 201 struct intel_fbdev *ifbdev)
224{ 202{
225 struct fb_info *info; 203 struct fb_info *info;
226 struct intel_framebuffer *ifb = &ifbdev->ifb; 204 struct intel_framebuffer *ifb = &ifbdev->ifb;
@@ -238,11 +216,9 @@ int intel_fbdev_destroy(struct drm_device *dev,
238 216
239 drm_framebuffer_cleanup(&ifb->base); 217 drm_framebuffer_cleanup(&ifb->base);
240 if (ifb->obj) { 218 if (ifb->obj) {
241 drm_gem_object_unreference(ifb->obj); 219 drm_gem_object_unreference_unlocked(&ifb->obj->base);
242 ifb->obj = NULL; 220 ifb->obj = NULL;
243 } 221 }
244
245 return 0;
246} 222}
247 223
248int intel_fbdev_init(struct drm_device *dev) 224int intel_fbdev_init(struct drm_device *dev)
@@ -288,3 +264,13 @@ void intel_fb_output_poll_changed(struct drm_device *dev)
288 drm_i915_private_t *dev_priv = dev->dev_private; 264 drm_i915_private_t *dev_priv = dev->dev_private;
289 drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); 265 drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
290} 266}
267
268void intel_fb_restore_mode(struct drm_device *dev)
269{
270 int ret;
271 drm_i915_private_t *dev_priv = dev->dev_private;
272
273 ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
274 if (ret)
275 DRM_DEBUG("failed to restore crtc mode\n");
276}