xref: /dflybsd-src/sys/dev/drm/i915/intel_fbdev.c (revision 717f4a47b1c967e5249b3404279e0f118b1065c8)
1*717f4a47SSascha Wildner /*
2*717f4a47SSascha Wildner  * Copyright © 2007 David Airlie
3*717f4a47SSascha Wildner  *
4*717f4a47SSascha Wildner  * Permission is hereby granted, free of charge, to any person obtaining a
5*717f4a47SSascha Wildner  * copy of this software and associated documentation files (the "Software"),
6*717f4a47SSascha Wildner  * to deal in the Software without restriction, including without limitation
7*717f4a47SSascha Wildner  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*717f4a47SSascha Wildner  * and/or sell copies of the Software, and to permit persons to whom the
9*717f4a47SSascha Wildner  * Software is furnished to do so, subject to the following conditions:
10*717f4a47SSascha Wildner  *
11*717f4a47SSascha Wildner  * The above copyright notice and this permission notice (including the next
12*717f4a47SSascha Wildner  * paragraph) shall be included in all copies or substantial portions of the
13*717f4a47SSascha Wildner  * Software.
14*717f4a47SSascha Wildner  *
15*717f4a47SSascha Wildner  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*717f4a47SSascha Wildner  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*717f4a47SSascha Wildner  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*717f4a47SSascha Wildner  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*717f4a47SSascha Wildner  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*717f4a47SSascha Wildner  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*717f4a47SSascha Wildner  * DEALINGS IN THE SOFTWARE.
22*717f4a47SSascha Wildner  *
23*717f4a47SSascha Wildner  * Authors:
24*717f4a47SSascha Wildner  *     David Airlie
25*717f4a47SSascha Wildner  */
26*717f4a47SSascha Wildner 
27*717f4a47SSascha Wildner #include <drm/drmP.h>
28*717f4a47SSascha Wildner #include <linux/module.h>
29*717f4a47SSascha Wildner #include <linux/kernel.h>
30*717f4a47SSascha Wildner #include <linux/errno.h>
31*717f4a47SSascha Wildner #include <linux/string.h>
32*717f4a47SSascha Wildner #include <linux/mm.h>
33*717f4a47SSascha Wildner #include <linux/delay.h>
34*717f4a47SSascha Wildner #include <linux/fb.h>
35*717f4a47SSascha Wildner 
36*717f4a47SSascha Wildner #include <drm/drm_crtc.h>
37*717f4a47SSascha Wildner #include <drm/drm_fb_helper.h>
38*717f4a47SSascha Wildner #include "intel_drv.h"
39*717f4a47SSascha Wildner #include <drm/i915_drm.h>
40*717f4a47SSascha Wildner #include "i915_drv.h"
41*717f4a47SSascha Wildner 
42*717f4a47SSascha Wildner #if 0
43*717f4a47SSascha Wildner static struct fb_ops intelfb_ops = {
44*717f4a47SSascha Wildner 	.owner = THIS_MODULE,
45*717f4a47SSascha Wildner 	.fb_check_var = drm_fb_helper_check_var,
46*717f4a47SSascha Wildner 	.fb_set_par = drm_fb_helper_set_par,
47*717f4a47SSascha Wildner 	.fb_fillrect = cfb_fillrect,
48*717f4a47SSascha Wildner 	.fb_copyarea = cfb_copyarea,
49*717f4a47SSascha Wildner 	.fb_imageblit = cfb_imageblit,
50*717f4a47SSascha Wildner 	.fb_pan_display = drm_fb_helper_pan_display,
51*717f4a47SSascha Wildner 	.fb_blank = drm_fb_helper_blank,
52*717f4a47SSascha Wildner 	.fb_setcmap = drm_fb_helper_setcmap,
53*717f4a47SSascha Wildner 	.fb_debug_enter = drm_fb_helper_debug_enter,
54*717f4a47SSascha Wildner 	.fb_debug_leave = drm_fb_helper_debug_leave,
55*717f4a47SSascha Wildner };
56*717f4a47SSascha Wildner #endif
57*717f4a47SSascha Wildner 
58*717f4a47SSascha Wildner static int intelfb_alloc(struct drm_fb_helper *helper,
59*717f4a47SSascha Wildner 			 struct drm_fb_helper_surface_size *sizes)
60*717f4a47SSascha Wildner {
61*717f4a47SSascha Wildner 	struct intel_fbdev *ifbdev =
62*717f4a47SSascha Wildner 		container_of(helper, struct intel_fbdev, helper);
63*717f4a47SSascha Wildner 	struct drm_device *dev = helper->dev;
64*717f4a47SSascha Wildner 	struct drm_mode_fb_cmd2 mode_cmd = {};
65*717f4a47SSascha Wildner 	struct drm_i915_gem_object *obj;
66*717f4a47SSascha Wildner 	int size, ret;
67*717f4a47SSascha Wildner 
68*717f4a47SSascha Wildner 	/* we don't do packed 24bpp */
69*717f4a47SSascha Wildner 	if (sizes->surface_bpp == 24)
70*717f4a47SSascha Wildner 		sizes->surface_bpp = 32;
71*717f4a47SSascha Wildner 
72*717f4a47SSascha Wildner 	mode_cmd.width = sizes->surface_width;
73*717f4a47SSascha Wildner 	mode_cmd.height = sizes->surface_height;
74*717f4a47SSascha Wildner 
75*717f4a47SSascha Wildner 	mode_cmd.pitches[0] = ALIGN(mode_cmd.width *
76*717f4a47SSascha Wildner 				    DIV_ROUND_UP(sizes->surface_bpp, 8), 64);
77*717f4a47SSascha Wildner 	mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
78*717f4a47SSascha Wildner 							  sizes->surface_depth);
79*717f4a47SSascha Wildner 
80*717f4a47SSascha Wildner 	size = mode_cmd.pitches[0] * mode_cmd.height;
81*717f4a47SSascha Wildner 	size = ALIGN(size, PAGE_SIZE);
82*717f4a47SSascha Wildner 	obj = i915_gem_object_create_stolen(dev, size);
83*717f4a47SSascha Wildner 	if (obj == NULL)
84*717f4a47SSascha Wildner 		obj = i915_gem_alloc_object(dev, size);
85*717f4a47SSascha Wildner 	if (!obj) {
86*717f4a47SSascha Wildner 		DRM_ERROR("failed to allocate framebuffer\n");
87*717f4a47SSascha Wildner 		ret = -ENOMEM;
88*717f4a47SSascha Wildner 		goto out;
89*717f4a47SSascha Wildner 	}
90*717f4a47SSascha Wildner 
91*717f4a47SSascha Wildner 	/* Flush everything out, we'll be doing GTT only from now on */
92*717f4a47SSascha Wildner 	ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
93*717f4a47SSascha Wildner 	if (ret) {
94*717f4a47SSascha Wildner 		DRM_ERROR("failed to pin fb: %d\n", ret);
95*717f4a47SSascha Wildner 		goto out_unref;
96*717f4a47SSascha Wildner 	}
97*717f4a47SSascha Wildner 
98*717f4a47SSascha Wildner 	ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj);
99*717f4a47SSascha Wildner 	if (ret)
100*717f4a47SSascha Wildner 		goto out_unpin;
101*717f4a47SSascha Wildner 
102*717f4a47SSascha Wildner 	return 0;
103*717f4a47SSascha Wildner 
104*717f4a47SSascha Wildner out_unpin:
105*717f4a47SSascha Wildner 	i915_gem_object_unpin(obj);
106*717f4a47SSascha Wildner out_unref:
107*717f4a47SSascha Wildner 	drm_gem_object_unreference(&obj->base);
108*717f4a47SSascha Wildner out:
109*717f4a47SSascha Wildner 	return ret;
110*717f4a47SSascha Wildner }
111*717f4a47SSascha Wildner 
112*717f4a47SSascha Wildner static int intelfb_create(struct drm_fb_helper *helper,
113*717f4a47SSascha Wildner 			  struct drm_fb_helper_surface_size *sizes)
114*717f4a47SSascha Wildner {
115*717f4a47SSascha Wildner 	struct intel_fbdev *ifbdev =
116*717f4a47SSascha Wildner 		container_of(helper, struct intel_fbdev, helper);
117*717f4a47SSascha Wildner 	struct intel_framebuffer *intel_fb = &ifbdev->ifb;
118*717f4a47SSascha Wildner 	struct drm_device *dev = helper->dev;
119*717f4a47SSascha Wildner #if 0
120*717f4a47SSascha Wildner 	struct drm_i915_private *dev_priv = dev->dev_private;
121*717f4a47SSascha Wildner #endif
122*717f4a47SSascha Wildner 	struct fb_info *info;
123*717f4a47SSascha Wildner 	struct drm_framebuffer *fb;
124*717f4a47SSascha Wildner 	struct drm_i915_gem_object *obj;
125*717f4a47SSascha Wildner 	device_t vga_dev;
126*717f4a47SSascha Wildner 	int size, ret;
127*717f4a47SSascha Wildner 
128*717f4a47SSascha Wildner 	mutex_lock(&dev->struct_mutex);
129*717f4a47SSascha Wildner 
130*717f4a47SSascha Wildner 	if (!intel_fb->obj) {
131*717f4a47SSascha Wildner 		DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
132*717f4a47SSascha Wildner 		ret = intelfb_alloc(helper, sizes);
133*717f4a47SSascha Wildner 		if (ret)
134*717f4a47SSascha Wildner 			goto out_unlock;
135*717f4a47SSascha Wildner 	} else {
136*717f4a47SSascha Wildner 		DRM_DEBUG_KMS("re-using BIOS fb\n");
137*717f4a47SSascha Wildner 		sizes->fb_width = intel_fb->base.width;
138*717f4a47SSascha Wildner 		sizes->fb_height = intel_fb->base.height;
139*717f4a47SSascha Wildner 	}
140*717f4a47SSascha Wildner 
141*717f4a47SSascha Wildner 	obj = intel_fb->obj;
142*717f4a47SSascha Wildner 	size = obj->base.size;
143*717f4a47SSascha Wildner 
144*717f4a47SSascha Wildner #if 0
145*717f4a47SSascha Wildner 	info = framebuffer_alloc(0, &dev->pdev->dev);
146*717f4a47SSascha Wildner 	if (!info) {
147*717f4a47SSascha Wildner 		ret = -ENOMEM;
148*717f4a47SSascha Wildner 		goto out_unpin;
149*717f4a47SSascha Wildner 	}
150*717f4a47SSascha Wildner 
151*717f4a47SSascha Wildner 	info->par = helper;
152*717f4a47SSascha Wildner #endif
153*717f4a47SSascha Wildner 	vga_dev = device_get_parent(dev->dev);
154*717f4a47SSascha Wildner 	info = kmalloc(sizeof(struct fb_info), M_DRM, M_WAITOK | M_ZERO);
155*717f4a47SSascha Wildner 	info->width = sizes->fb_width;
156*717f4a47SSascha Wildner 	info->height = sizes->fb_height;
157*717f4a47SSascha Wildner 	info->stride =
158*717f4a47SSascha Wildner 	    ALIGN(sizes->surface_width * ((sizes->surface_bpp + 7) / 8), 64);
159*717f4a47SSascha Wildner 	info->depth = sizes->surface_bpp;
160*717f4a47SSascha Wildner 	info->paddr = dev->agp->base + i915_gem_obj_ggtt_offset(obj);
161*717f4a47SSascha Wildner 	info->is_vga_boot_display = vga_pci_is_boot_display(vga_dev);
162*717f4a47SSascha Wildner 	info->vaddr =
163*717f4a47SSascha Wildner 	    (vm_offset_t)pmap_mapdev_attr(info->paddr,
164*717f4a47SSascha Wildner 		sizes->surface_height * info->stride,
165*717f4a47SSascha Wildner 		VM_MEMATTR_WRITE_COMBINING);
166*717f4a47SSascha Wildner 
167*717f4a47SSascha Wildner 	fb = &ifbdev->ifb.base;
168*717f4a47SSascha Wildner 
169*717f4a47SSascha Wildner 	ifbdev->helper.fb = fb;
170*717f4a47SSascha Wildner 	ifbdev->helper.fbdev = info;
171*717f4a47SSascha Wildner 
172*717f4a47SSascha Wildner #if 0
173*717f4a47SSascha Wildner 	strcpy(info->fix.id, "inteldrmfb");
174*717f4a47SSascha Wildner 
175*717f4a47SSascha Wildner 	info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
176*717f4a47SSascha Wildner 	info->fbops = &intelfb_ops;
177*717f4a47SSascha Wildner 
178*717f4a47SSascha Wildner 	ret = fb_alloc_cmap(&info->cmap, 256, 0);
179*717f4a47SSascha Wildner 	if (ret) {
180*717f4a47SSascha Wildner 		ret = -ENOMEM;
181*717f4a47SSascha Wildner 		goto out_unpin;
182*717f4a47SSascha Wildner 	}
183*717f4a47SSascha Wildner 	/* setup aperture base/size for vesafb takeover */
184*717f4a47SSascha Wildner 	info->apertures = alloc_apertures(1);
185*717f4a47SSascha Wildner 	if (!info->apertures) {
186*717f4a47SSascha Wildner 		ret = -ENOMEM;
187*717f4a47SSascha Wildner 		goto out_unpin;
188*717f4a47SSascha Wildner 	}
189*717f4a47SSascha Wildner 	info->apertures->ranges[0].base = dev->mode_config.fb_base;
190*717f4a47SSascha Wildner 	info->apertures->ranges[0].size = dev_priv->gtt.mappable_end;
191*717f4a47SSascha Wildner 
192*717f4a47SSascha Wildner 	info->fix.smem_start = dev->mode_config.fb_base + i915_gem_obj_ggtt_offset(obj);
193*717f4a47SSascha Wildner 	info->fix.smem_len = size;
194*717f4a47SSascha Wildner 
195*717f4a47SSascha Wildner 	info->screen_base =
196*717f4a47SSascha Wildner 		ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
197*717f4a47SSascha Wildner 			   size);
198*717f4a47SSascha Wildner 	if (!info->screen_base) {
199*717f4a47SSascha Wildner 		ret = -ENOSPC;
200*717f4a47SSascha Wildner 		goto out_unpin;
201*717f4a47SSascha Wildner 	}
202*717f4a47SSascha Wildner 	info->screen_size = size;
203*717f4a47SSascha Wildner 
204*717f4a47SSascha Wildner 	/* This driver doesn't need a VT switch to restore the mode on resume */
205*717f4a47SSascha Wildner 	info->skip_vt_switch = true;
206*717f4a47SSascha Wildner 
207*717f4a47SSascha Wildner 	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
208*717f4a47SSascha Wildner 	drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
209*717f4a47SSascha Wildner 
210*717f4a47SSascha Wildner 	/* If the object is shmemfs backed, it will have given us zeroed pages.
211*717f4a47SSascha Wildner 	 * If the object is stolen however, it will be full of whatever
212*717f4a47SSascha Wildner 	 * garbage was left in there.
213*717f4a47SSascha Wildner 	 */
214*717f4a47SSascha Wildner 	if (ifbdev->ifb.obj->stolen)
215*717f4a47SSascha Wildner 		memset_io(info->screen_base, 0, info->screen_size);
216*717f4a47SSascha Wildner 
217*717f4a47SSascha Wildner 	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
218*717f4a47SSascha Wildner #endif
219*717f4a47SSascha Wildner 
220*717f4a47SSascha Wildner 	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08lx, bo %p\n",
221*717f4a47SSascha Wildner 		      fb->width, fb->height,
222*717f4a47SSascha Wildner 		      i915_gem_obj_ggtt_offset(obj), obj);
223*717f4a47SSascha Wildner 
224*717f4a47SSascha Wildner 	mutex_unlock(&dev->struct_mutex);
225*717f4a47SSascha Wildner #if 0
226*717f4a47SSascha Wildner 	vga_switcheroo_client_fb_set(dev->pdev, info);
227*717f4a47SSascha Wildner #endif
228*717f4a47SSascha Wildner 	return 0;
229*717f4a47SSascha Wildner 
230*717f4a47SSascha Wildner #if 0
231*717f4a47SSascha Wildner out_unpin:
232*717f4a47SSascha Wildner 	i915_gem_object_unpin(obj);
233*717f4a47SSascha Wildner 	drm_gem_object_unreference(&obj->base);
234*717f4a47SSascha Wildner #endif
235*717f4a47SSascha Wildner out_unlock:
236*717f4a47SSascha Wildner 	mutex_unlock(&dev->struct_mutex);
237*717f4a47SSascha Wildner 	return ret;
238*717f4a47SSascha Wildner }
239*717f4a47SSascha Wildner 
240*717f4a47SSascha Wildner /** Sets the color ramps on behalf of RandR */
241*717f4a47SSascha Wildner static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
242*717f4a47SSascha Wildner 				    u16 blue, int regno)
243*717f4a47SSascha Wildner {
244*717f4a47SSascha Wildner 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
245*717f4a47SSascha Wildner 
246*717f4a47SSascha Wildner 	intel_crtc->lut_r[regno] = red >> 8;
247*717f4a47SSascha Wildner 	intel_crtc->lut_g[regno] = green >> 8;
248*717f4a47SSascha Wildner 	intel_crtc->lut_b[regno] = blue >> 8;
249*717f4a47SSascha Wildner }
250*717f4a47SSascha Wildner 
251*717f4a47SSascha Wildner static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
252*717f4a47SSascha Wildner 				    u16 *blue, int regno)
253*717f4a47SSascha Wildner {
254*717f4a47SSascha Wildner 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
255*717f4a47SSascha Wildner 
256*717f4a47SSascha Wildner 	*red = intel_crtc->lut_r[regno] << 8;
257*717f4a47SSascha Wildner 	*green = intel_crtc->lut_g[regno] << 8;
258*717f4a47SSascha Wildner 	*blue = intel_crtc->lut_b[regno] << 8;
259*717f4a47SSascha Wildner }
260*717f4a47SSascha Wildner 
261*717f4a47SSascha Wildner static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
262*717f4a47SSascha Wildner 	.gamma_set = intel_crtc_fb_gamma_set,
263*717f4a47SSascha Wildner 	.gamma_get = intel_crtc_fb_gamma_get,
264*717f4a47SSascha Wildner 	.fb_probe = intelfb_create,
265*717f4a47SSascha Wildner };
266*717f4a47SSascha Wildner 
267*717f4a47SSascha Wildner static void intel_fbdev_destroy(struct drm_device *dev,
268*717f4a47SSascha Wildner 				struct intel_fbdev *ifbdev)
269*717f4a47SSascha Wildner {
270*717f4a47SSascha Wildner #if 0
271*717f4a47SSascha Wildner 	if (ifbdev->helper.fbdev) {
272*717f4a47SSascha Wildner 		struct fb_info *info = ifbdev->helper.fbdev;
273*717f4a47SSascha Wildner 
274*717f4a47SSascha Wildner 		unregister_framebuffer(info);
275*717f4a47SSascha Wildner 		iounmap(info->screen_base);
276*717f4a47SSascha Wildner 		if (info->cmap.len)
277*717f4a47SSascha Wildner 			fb_dealloc_cmap(&info->cmap);
278*717f4a47SSascha Wildner 
279*717f4a47SSascha Wildner 		framebuffer_release(info);
280*717f4a47SSascha Wildner 	}
281*717f4a47SSascha Wildner #endif
282*717f4a47SSascha Wildner 
283*717f4a47SSascha Wildner 	drm_fb_helper_fini(&ifbdev->helper);
284*717f4a47SSascha Wildner 
285*717f4a47SSascha Wildner 	drm_framebuffer_unregister_private(&ifbdev->ifb.base);
286*717f4a47SSascha Wildner 	intel_framebuffer_fini(&ifbdev->ifb);
287*717f4a47SSascha Wildner }
288*717f4a47SSascha Wildner 
289*717f4a47SSascha Wildner int intel_fbdev_init(struct drm_device *dev)
290*717f4a47SSascha Wildner {
291*717f4a47SSascha Wildner 	struct intel_fbdev *ifbdev;
292*717f4a47SSascha Wildner 	struct drm_i915_private *dev_priv = dev->dev_private;
293*717f4a47SSascha Wildner 	int ret;
294*717f4a47SSascha Wildner 
295*717f4a47SSascha Wildner 	ifbdev = kzalloc(sizeof(*ifbdev), GFP_KERNEL);
296*717f4a47SSascha Wildner 	if (!ifbdev)
297*717f4a47SSascha Wildner 		return -ENOMEM;
298*717f4a47SSascha Wildner 
299*717f4a47SSascha Wildner 	dev_priv->fbdev = ifbdev;
300*717f4a47SSascha Wildner 	ifbdev->helper.funcs = &intel_fb_helper_funcs;
301*717f4a47SSascha Wildner 
302*717f4a47SSascha Wildner 	ret = drm_fb_helper_init(dev, &ifbdev->helper,
303*717f4a47SSascha Wildner 				 INTEL_INFO(dev)->num_pipes,
304*717f4a47SSascha Wildner 				 4);
305*717f4a47SSascha Wildner 	if (ret) {
306*717f4a47SSascha Wildner 		kfree(ifbdev);
307*717f4a47SSascha Wildner 		return ret;
308*717f4a47SSascha Wildner 	}
309*717f4a47SSascha Wildner 
310*717f4a47SSascha Wildner 	drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
311*717f4a47SSascha Wildner 
312*717f4a47SSascha Wildner 	return 0;
313*717f4a47SSascha Wildner }
314*717f4a47SSascha Wildner 
315*717f4a47SSascha Wildner void intel_fbdev_initial_config(struct drm_device *dev)
316*717f4a47SSascha Wildner {
317*717f4a47SSascha Wildner 	struct drm_i915_private *dev_priv = dev->dev_private;
318*717f4a47SSascha Wildner 
319*717f4a47SSascha Wildner 	/* Due to peculiar init order wrt to hpd handling this is separate. */
320*717f4a47SSascha Wildner 	drm_fb_helper_initial_config(&dev_priv->fbdev->helper, 32);
321*717f4a47SSascha Wildner }
322*717f4a47SSascha Wildner 
323*717f4a47SSascha Wildner void intel_fbdev_fini(struct drm_device *dev)
324*717f4a47SSascha Wildner {
325*717f4a47SSascha Wildner 	struct drm_i915_private *dev_priv = dev->dev_private;
326*717f4a47SSascha Wildner 	if (!dev_priv->fbdev)
327*717f4a47SSascha Wildner 		return;
328*717f4a47SSascha Wildner 
329*717f4a47SSascha Wildner 	intel_fbdev_destroy(dev, dev_priv->fbdev);
330*717f4a47SSascha Wildner 	kfree(dev_priv->fbdev);
331*717f4a47SSascha Wildner 	dev_priv->fbdev = NULL;
332*717f4a47SSascha Wildner }
333*717f4a47SSascha Wildner 
334*717f4a47SSascha Wildner void intel_fbdev_set_suspend(struct drm_device *dev, int state)
335*717f4a47SSascha Wildner {
336*717f4a47SSascha Wildner #if 0
337*717f4a47SSascha Wildner 	struct drm_i915_private *dev_priv = dev->dev_private;
338*717f4a47SSascha Wildner 	struct intel_fbdev *ifbdev = dev_priv->fbdev;
339*717f4a47SSascha Wildner 	struct fb_info *info;
340*717f4a47SSascha Wildner 
341*717f4a47SSascha Wildner 	if (!ifbdev)
342*717f4a47SSascha Wildner 		return;
343*717f4a47SSascha Wildner 
344*717f4a47SSascha Wildner 	info = ifbdev->helper.fbdev;
345*717f4a47SSascha Wildner 
346*717f4a47SSascha Wildner 	/* On resume from hibernation: If the object is shmemfs backed, it has
347*717f4a47SSascha Wildner 	 * been restored from swap. If the object is stolen however, it will be
348*717f4a47SSascha Wildner 	 * full of whatever garbage was left in there.
349*717f4a47SSascha Wildner 	 */
350*717f4a47SSascha Wildner 	if (state == FBINFO_STATE_RUNNING && ifbdev->ifb.obj->stolen)
351*717f4a47SSascha Wildner 		memset_io(info->screen_base, 0, info->screen_size);
352*717f4a47SSascha Wildner 
353*717f4a47SSascha Wildner 	fb_set_suspend(info, state);
354*717f4a47SSascha Wildner #endif
355*717f4a47SSascha Wildner }
356*717f4a47SSascha Wildner 
357*717f4a47SSascha Wildner void intel_fbdev_output_poll_changed(struct drm_device *dev)
358*717f4a47SSascha Wildner {
359*717f4a47SSascha Wildner 	struct drm_i915_private *dev_priv = dev->dev_private;
360*717f4a47SSascha Wildner 	drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
361*717f4a47SSascha Wildner }
362*717f4a47SSascha Wildner 
363*717f4a47SSascha Wildner void intel_fbdev_restore_mode(struct drm_device *dev)
364*717f4a47SSascha Wildner {
365*717f4a47SSascha Wildner 	int ret;
366*717f4a47SSascha Wildner 	struct drm_i915_private *dev_priv = dev->dev_private;
367*717f4a47SSascha Wildner 
368*717f4a47SSascha Wildner 	if (INTEL_INFO(dev)->num_pipes == 0)
369*717f4a47SSascha Wildner 		return;
370*717f4a47SSascha Wildner 
371*717f4a47SSascha Wildner 	drm_modeset_lock_all(dev);
372*717f4a47SSascha Wildner 
373*717f4a47SSascha Wildner 	ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
374*717f4a47SSascha Wildner 	if (ret)
375*717f4a47SSascha Wildner 		DRM_DEBUG("failed to restore crtc mode\n");
376*717f4a47SSascha Wildner 
377*717f4a47SSascha Wildner 	drm_modeset_unlock_all(dev);
378*717f4a47SSascha Wildner }
379