Deleted Added
full compact
intel_fb.c (251961) intel_fb.c (259016)
1/*
2 * Copyright �� 2007 David Airlie
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * David Airlie
25 */
26
27#include <sys/cdefs.h>
1/*
2 * Copyright �� 2007 David Airlie
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * David Airlie
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/dev/drm2/i915/intel_fb.c 251961 2013-06-18 20:19:09Z kib $");
28__FBSDID("$FreeBSD: head/sys/dev/drm2/i915/intel_fb.c 259016 2013-12-05 22:38:53Z ray $");
29
30#include <dev/drm2/drmP.h>
31#include <dev/drm2/drm.h>
32#include <dev/drm2/drm_crtc.h>
33#include <dev/drm2/drm_fb_helper.h>
34#include <dev/drm2/i915/i915_drm.h>
35#include <dev/drm2/i915/i915_drv.h>
36#include <dev/drm2/i915/intel_drv.h>
37
38static int intelfb_create(struct intel_fbdev *ifbdev,
39 struct drm_fb_helper_surface_size *sizes)
40{
41 struct drm_device *dev = ifbdev->helper.dev;
42#if 0
43 struct drm_i915_private *dev_priv = dev->dev_private;
29
30#include <dev/drm2/drmP.h>
31#include <dev/drm2/drm.h>
32#include <dev/drm2/drm_crtc.h>
33#include <dev/drm2/drm_fb_helper.h>
34#include <dev/drm2/i915/i915_drm.h>
35#include <dev/drm2/i915/i915_drv.h>
36#include <dev/drm2/i915/intel_drv.h>
37
38static int intelfb_create(struct intel_fbdev *ifbdev,
39 struct drm_fb_helper_surface_size *sizes)
40{
41 struct drm_device *dev = ifbdev->helper.dev;
42#if 0
43 struct drm_i915_private *dev_priv = dev->dev_private;
44 struct fb_info *info;
45#endif
44#endif
45 struct fb_info *info;
46 struct drm_framebuffer *fb;
47 struct drm_mode_fb_cmd2 mode_cmd;
48 struct drm_i915_gem_object *obj;
49 int size, ret;
50
51 /* we don't do packed 24bpp */
52 if (sizes->surface_bpp == 24)
53 sizes->surface_bpp = 32;
54
55 mode_cmd.width = sizes->surface_width;
56 mode_cmd.height = sizes->surface_height;
57
58 mode_cmd.pitches[0] = roundup2(mode_cmd.width * ((sizes->surface_bpp + 7) /
59 8), 64);
60 mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
61 sizes->surface_depth);
62
63 size = mode_cmd.pitches[0] * mode_cmd.height;
64 size = roundup2(size, PAGE_SIZE);
65 obj = i915_gem_alloc_object(dev, size);
66 if (!obj) {
67 DRM_ERROR("failed to allocate framebuffer\n");
68 ret = -ENOMEM;
69 goto out;
70 }
71
72 DRM_LOCK(dev);
73
74 /* Flush everything out, we'll be doing GTT only from now on */
75 ret = intel_pin_and_fence_fb_obj(dev, obj, false);
76 if (ret) {
77 DRM_ERROR("failed to pin fb: %d\n", ret);
78 goto out_unref;
79 }
80
81#if 0
82 info = framebuffer_alloc(0, device);
83 if (!info) {
84 ret = -ENOMEM;
85 goto out_unpin;
86 }
87
88 info->par = ifbdev;
46 struct drm_framebuffer *fb;
47 struct drm_mode_fb_cmd2 mode_cmd;
48 struct drm_i915_gem_object *obj;
49 int size, ret;
50
51 /* we don't do packed 24bpp */
52 if (sizes->surface_bpp == 24)
53 sizes->surface_bpp = 32;
54
55 mode_cmd.width = sizes->surface_width;
56 mode_cmd.height = sizes->surface_height;
57
58 mode_cmd.pitches[0] = roundup2(mode_cmd.width * ((sizes->surface_bpp + 7) /
59 8), 64);
60 mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
61 sizes->surface_depth);
62
63 size = mode_cmd.pitches[0] * mode_cmd.height;
64 size = roundup2(size, PAGE_SIZE);
65 obj = i915_gem_alloc_object(dev, size);
66 if (!obj) {
67 DRM_ERROR("failed to allocate framebuffer\n");
68 ret = -ENOMEM;
69 goto out;
70 }
71
72 DRM_LOCK(dev);
73
74 /* Flush everything out, we'll be doing GTT only from now on */
75 ret = intel_pin_and_fence_fb_obj(dev, obj, false);
76 if (ret) {
77 DRM_ERROR("failed to pin fb: %d\n", ret);
78 goto out_unref;
79 }
80
81#if 0
82 info = framebuffer_alloc(0, device);
83 if (!info) {
84 ret = -ENOMEM;
85 goto out_unpin;
86 }
87
88 info->par = ifbdev;
89#else
90 info = malloc(sizeof(struct fb_info), DRM_MEM_KMS, M_WAITOK | M_ZERO);
91 info->fb_size = size;
92 info->fb_bpp = sizes->surface_bpp;
93 info->fb_width = sizes->fb_width;
94 info->fb_height = sizes->fb_height;
95 info->fb_pbase = dev->agp->base + obj->gtt_offset;
96 info->fb_vbase = (vm_offset_t)pmap_mapdev_attr(info->fb_pbase, size,
97 PAT_WRITE_COMBINING);
98
89#endif
90
91 ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj);
92 if (ret)
93 goto out_unpin;
94
95 fb = &ifbdev->ifb.base;
96
97 ifbdev->helper.fb = fb;
99#endif
100
101 ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj);
102 if (ret)
103 goto out_unpin;
104
105 fb = &ifbdev->ifb.base;
106
107 ifbdev->helper.fb = fb;
98#if 0
99 ifbdev->helper.fbdev = info;
108 ifbdev->helper.fbdev = info;
109#if 0
100
101 strcpy(info->fix.id, "inteldrmfb");
102
103 info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
104 info->fbops = &intelfb_ops;
105
106 ret = fb_alloc_cmap(&info->cmap, 256, 0);
107 if (ret) {
108 ret = -ENOMEM;
109 goto out_unpin;
110 }
111 /* setup aperture base/size for vesafb takeover */
112 info->apertures = alloc_apertures(1);
113 if (!info->apertures) {
114 ret = -ENOMEM;
115 goto out_unpin;
116 }
117 info->apertures->ranges[0].base = dev->mode_config.fb_base;
118 info->apertures->ranges[0].size =
119 dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
120
121 info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset;
122 info->fix.smem_len = size;
123
124 info->screen_base = ioremap_wc(dev->agp->base + obj->gtt_offset, size);
125 if (!info->screen_base) {
126 ret = -ENOSPC;
127 goto out_unpin;
128 }
129 info->screen_size = size;
130
131// memset(info->screen_base, 0, size);
132
133 drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
134 drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
135
136 /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
137#endif
110
111 strcpy(info->fix.id, "inteldrmfb");
112
113 info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
114 info->fbops = &intelfb_ops;
115
116 ret = fb_alloc_cmap(&info->cmap, 256, 0);
117 if (ret) {
118 ret = -ENOMEM;
119 goto out_unpin;
120 }
121 /* setup aperture base/size for vesafb takeover */
122 info->apertures = alloc_apertures(1);
123 if (!info->apertures) {
124 ret = -ENOMEM;
125 goto out_unpin;
126 }
127 info->apertures->ranges[0].base = dev->mode_config.fb_base;
128 info->apertures->ranges[0].size =
129 dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
130
131 info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset;
132 info->fix.smem_len = size;
133
134 info->screen_base = ioremap_wc(dev->agp->base + obj->gtt_offset, size);
135 if (!info->screen_base) {
136 ret = -ENOSPC;
137 goto out_unpin;
138 }
139 info->screen_size = size;
140
141// memset(info->screen_base, 0, size);
142
143 drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
144 drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
145
146 /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
147#endif
138
139 DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n",
140 fb->width, fb->height,
148 DRM_DEBUG_KMS("allocated %dx%d (s %dbits) fb: 0x%08x, bo %p\n",
149 fb->width, fb->height, fb->depth,
141 obj->gtt_offset, obj);
142
143 DRM_UNLOCK(dev);
144#if 1
145 KIB_NOTYET();
146#else
147 vga_switcheroo_client_fb_set(dev->pdev, info);
148#endif
149 return 0;
150
151out_unpin:
152 i915_gem_object_unpin(obj);
153out_unref:
154 drm_gem_object_unreference(&obj->base);
155 DRM_UNLOCK(dev);
156out:
157 return ret;
158}
159
160static int intel_fb_find_or_create_single(struct drm_fb_helper *helper,
161 struct drm_fb_helper_surface_size *sizes)
162{
163 struct intel_fbdev *ifbdev = (struct intel_fbdev *)helper;
164 int new_fb = 0;
165 int ret;
166
167 if (!helper->fb) {
168 ret = intelfb_create(ifbdev, sizes);
169 if (ret)
170 return ret;
171 new_fb = 1;
172 }
173 return new_fb;
174}
175
176static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
177 .gamma_set = intel_crtc_fb_gamma_set,
178 .gamma_get = intel_crtc_fb_gamma_get,
179 .fb_probe = intel_fb_find_or_create_single,
180};
181
182static void intel_fbdev_destroy(struct drm_device *dev,
183 struct intel_fbdev *ifbdev)
184{
185#if 0
186 struct fb_info *info;
187#endif
188 struct intel_framebuffer *ifb = &ifbdev->ifb;
189
190#if 0
191 if (ifbdev->helper.fbdev) {
192 info = ifbdev->helper.fbdev;
193 unregister_framebuffer(info);
194 iounmap(info->screen_base);
195 if (info->cmap.len)
196 fb_dealloc_cmap(&info->cmap);
197 framebuffer_release(info);
198 }
199#endif
200
201 drm_fb_helper_fini(&ifbdev->helper);
202
203 drm_framebuffer_cleanup(&ifb->base);
204 if (ifb->obj) {
205 drm_gem_object_unreference_unlocked(&ifb->obj->base);
206 ifb->obj = NULL;
207 }
208}
209
210extern int sc_txtmouse_no_retrace_wait;
211
212int intel_fbdev_init(struct drm_device *dev)
213{
214 struct intel_fbdev *ifbdev;
215 drm_i915_private_t *dev_priv = dev->dev_private;
216 int ret;
217
218 ifbdev = malloc(sizeof(struct intel_fbdev), DRM_MEM_KMS,
219 M_WAITOK | M_ZERO);
220
221 dev_priv->fbdev = ifbdev;
222 ifbdev->helper.funcs = &intel_fb_helper_funcs;
223
224 ret = drm_fb_helper_init(dev, &ifbdev->helper,
225 dev_priv->num_pipe,
226 INTELFB_CONN_LIMIT);
227 if (ret) {
228 free(ifbdev, DRM_MEM_KMS);
229 return ret;
230 }
231
232 drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
233 drm_fb_helper_initial_config(&ifbdev->helper, 32);
234 sc_txtmouse_no_retrace_wait = 1;
235 return 0;
236}
237
238void intel_fbdev_fini(struct drm_device *dev)
239{
240 drm_i915_private_t *dev_priv = dev->dev_private;
241 if (!dev_priv->fbdev)
242 return;
243
244 intel_fbdev_destroy(dev, dev_priv->fbdev);
245 free(dev_priv->fbdev, DRM_MEM_KMS);
246 dev_priv->fbdev = NULL;
247}
248
249void intel_fb_output_poll_changed(struct drm_device *dev)
250{
251 drm_i915_private_t *dev_priv = dev->dev_private;
252 drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
253}
254
255void intel_fb_restore_mode(struct drm_device *dev)
256{
257 int ret;
258 drm_i915_private_t *dev_priv = dev->dev_private;
259 struct drm_mode_config *config = &dev->mode_config;
260 struct drm_plane *plane;
261
262 sx_xlock(&dev->mode_config.mutex);
263
264 ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
265 if (ret)
266 DRM_DEBUG("failed to restore crtc mode\n");
267
268 /* Be sure to shut off any planes that may be active */
269 list_for_each_entry(plane, &config->plane_list, head)
270 plane->funcs->disable_plane(plane);
271
272 sx_xunlock(&dev->mode_config.mutex);
273}
150 obj->gtt_offset, obj);
151
152 DRM_UNLOCK(dev);
153#if 1
154 KIB_NOTYET();
155#else
156 vga_switcheroo_client_fb_set(dev->pdev, info);
157#endif
158 return 0;
159
160out_unpin:
161 i915_gem_object_unpin(obj);
162out_unref:
163 drm_gem_object_unreference(&obj->base);
164 DRM_UNLOCK(dev);
165out:
166 return ret;
167}
168
169static int intel_fb_find_or_create_single(struct drm_fb_helper *helper,
170 struct drm_fb_helper_surface_size *sizes)
171{
172 struct intel_fbdev *ifbdev = (struct intel_fbdev *)helper;
173 int new_fb = 0;
174 int ret;
175
176 if (!helper->fb) {
177 ret = intelfb_create(ifbdev, sizes);
178 if (ret)
179 return ret;
180 new_fb = 1;
181 }
182 return new_fb;
183}
184
185static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
186 .gamma_set = intel_crtc_fb_gamma_set,
187 .gamma_get = intel_crtc_fb_gamma_get,
188 .fb_probe = intel_fb_find_or_create_single,
189};
190
191static void intel_fbdev_destroy(struct drm_device *dev,
192 struct intel_fbdev *ifbdev)
193{
194#if 0
195 struct fb_info *info;
196#endif
197 struct intel_framebuffer *ifb = &ifbdev->ifb;
198
199#if 0
200 if (ifbdev->helper.fbdev) {
201 info = ifbdev->helper.fbdev;
202 unregister_framebuffer(info);
203 iounmap(info->screen_base);
204 if (info->cmap.len)
205 fb_dealloc_cmap(&info->cmap);
206 framebuffer_release(info);
207 }
208#endif
209
210 drm_fb_helper_fini(&ifbdev->helper);
211
212 drm_framebuffer_cleanup(&ifb->base);
213 if (ifb->obj) {
214 drm_gem_object_unreference_unlocked(&ifb->obj->base);
215 ifb->obj = NULL;
216 }
217}
218
219extern int sc_txtmouse_no_retrace_wait;
220
221int intel_fbdev_init(struct drm_device *dev)
222{
223 struct intel_fbdev *ifbdev;
224 drm_i915_private_t *dev_priv = dev->dev_private;
225 int ret;
226
227 ifbdev = malloc(sizeof(struct intel_fbdev), DRM_MEM_KMS,
228 M_WAITOK | M_ZERO);
229
230 dev_priv->fbdev = ifbdev;
231 ifbdev->helper.funcs = &intel_fb_helper_funcs;
232
233 ret = drm_fb_helper_init(dev, &ifbdev->helper,
234 dev_priv->num_pipe,
235 INTELFB_CONN_LIMIT);
236 if (ret) {
237 free(ifbdev, DRM_MEM_KMS);
238 return ret;
239 }
240
241 drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
242 drm_fb_helper_initial_config(&ifbdev->helper, 32);
243 sc_txtmouse_no_retrace_wait = 1;
244 return 0;
245}
246
247void intel_fbdev_fini(struct drm_device *dev)
248{
249 drm_i915_private_t *dev_priv = dev->dev_private;
250 if (!dev_priv->fbdev)
251 return;
252
253 intel_fbdev_destroy(dev, dev_priv->fbdev);
254 free(dev_priv->fbdev, DRM_MEM_KMS);
255 dev_priv->fbdev = NULL;
256}
257
258void intel_fb_output_poll_changed(struct drm_device *dev)
259{
260 drm_i915_private_t *dev_priv = dev->dev_private;
261 drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
262}
263
264void intel_fb_restore_mode(struct drm_device *dev)
265{
266 int ret;
267 drm_i915_private_t *dev_priv = dev->dev_private;
268 struct drm_mode_config *config = &dev->mode_config;
269 struct drm_plane *plane;
270
271 sx_xlock(&dev->mode_config.mutex);
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
277 /* Be sure to shut off any planes that may be active */
278 list_for_each_entry(plane, &config->plane_list, head)
279 plane->funcs->disable_plane(plane);
280
281 sx_xunlock(&dev->mode_config.mutex);
282}