intelfb.c revision 1.7 1 1.7 jmcneill /* $NetBSD: intelfb.c,v 1.7 2014/08/06 22:16:38 jmcneill Exp $ */
2 1.1 riastrad
3 1.1 riastrad /*-
4 1.1 riastrad * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 1.1 riastrad * All rights reserved.
6 1.1 riastrad *
7 1.1 riastrad * This code is derived from software contributed to The NetBSD Foundation
8 1.1 riastrad * by Taylor R. Campbell.
9 1.1 riastrad *
10 1.1 riastrad * Redistribution and use in source and binary forms, with or without
11 1.1 riastrad * modification, are permitted provided that the following conditions
12 1.1 riastrad * are met:
13 1.1 riastrad * 1. Redistributions of source code must retain the above copyright
14 1.1 riastrad * notice, this list of conditions and the following disclaimer.
15 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 riastrad * notice, this list of conditions and the following disclaimer in the
17 1.1 riastrad * documentation and/or other materials provided with the distribution.
18 1.1 riastrad *
19 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 riastrad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 riastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 riastrad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 riastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 riastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 riastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 riastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 riastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 riastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 riastrad * POSSIBILITY OF SUCH DAMAGE.
30 1.1 riastrad */
31 1.1 riastrad
32 1.1 riastrad #include <sys/cdefs.h>
33 1.7 jmcneill __KERNEL_RCSID(0, "$NetBSD: intelfb.c,v 1.7 2014/08/06 22:16:38 jmcneill Exp $");
34 1.1 riastrad
35 1.1 riastrad #ifdef _KERNEL_OPT
36 1.1 riastrad #include "vga.h"
37 1.1 riastrad #endif
38 1.1 riastrad
39 1.1 riastrad #include <sys/types.h>
40 1.1 riastrad #include <sys/bus.h>
41 1.1 riastrad #include <sys/device.h>
42 1.1 riastrad
43 1.1 riastrad #include <dev/pci/pciio.h>
44 1.1 riastrad #include <dev/pci/pcireg.h>
45 1.1 riastrad #include <dev/pci/pcivar.h>
46 1.1 riastrad
47 1.1 riastrad #include <dev/pci/wsdisplay_pci.h>
48 1.1 riastrad #include <dev/wsfb/genfbvar.h>
49 1.1 riastrad
50 1.1 riastrad #if NVGA > 0
51 1.1 riastrad /*
52 1.1 riastrad * XXX All we really need is vga_is_console from vgavar.h, but the
53 1.1 riastrad * header files are missing their own dependencies, so we need to
54 1.1 riastrad * explicitly drag in the other crap.
55 1.1 riastrad */
56 1.1 riastrad #include <dev/ic/mc6845reg.h>
57 1.1 riastrad #include <dev/ic/pcdisplayvar.h>
58 1.1 riastrad #include <dev/ic/vgareg.h>
59 1.1 riastrad #include <dev/ic/vgavar.h>
60 1.1 riastrad #endif
61 1.1 riastrad
62 1.1 riastrad #include <drm/drmP.h>
63 1.1 riastrad #include <drm/drm_fb_helper.h>
64 1.1 riastrad
65 1.1 riastrad #include "i915_drv.h"
66 1.1 riastrad #include "i915_pci.h"
67 1.1 riastrad #include "intelfb.h"
68 1.1 riastrad
69 1.1 riastrad struct intelfb_softc {
70 1.1 riastrad /* XXX genfb requires the genfb_softc to be first. */
71 1.1 riastrad struct genfb_softc sc_genfb;
72 1.1 riastrad device_t sc_dev;
73 1.1 riastrad struct intelfb_attach_args sc_ifa;
74 1.1 riastrad bus_space_handle_t sc_fb_bsh;
75 1.1 riastrad struct i915drmkms_task sc_setconfig_task;
76 1.1 riastrad bool sc_mapped:1;
77 1.1 riastrad bool sc_scheduled:1;
78 1.1 riastrad bool sc_attached:1;
79 1.1 riastrad };
80 1.1 riastrad
81 1.1 riastrad static int intelfb_match(device_t, cfdata_t, void *);
82 1.1 riastrad static void intelfb_attach(device_t, device_t, void *);
83 1.1 riastrad static int intelfb_detach(device_t, int);
84 1.1 riastrad
85 1.1 riastrad static void intelfb_setconfig_task(struct i915drmkms_task *);
86 1.1 riastrad
87 1.1 riastrad static int intelfb_genfb_dpms(struct drm_device *, int);
88 1.1 riastrad static int intelfb_genfb_ioctl(void *, void *, unsigned long, void *,
89 1.1 riastrad int, struct lwp *);
90 1.1 riastrad static paddr_t intelfb_genfb_mmap(void *, void *, off_t, int);
91 1.1 riastrad static int intelfb_genfb_enable_polling(void *);
92 1.1 riastrad static int intelfb_genfb_disable_polling(void *);
93 1.7 jmcneill static bool intelfb_genfb_setmode(struct genfb_softc *, int);
94 1.7 jmcneill
95 1.7 jmcneill static const struct genfb_mode_callback intelfb_genfb_mode_callback = {
96 1.7 jmcneill .gmc_setmode = intelfb_genfb_setmode,
97 1.7 jmcneill };
98 1.1 riastrad
99 1.1 riastrad CFATTACH_DECL_NEW(intelfb, sizeof(struct intelfb_softc),
100 1.1 riastrad intelfb_match, intelfb_attach, intelfb_detach, NULL);
101 1.1 riastrad
102 1.1 riastrad static int
103 1.1 riastrad intelfb_match(device_t parent, cfdata_t match, void *aux)
104 1.1 riastrad {
105 1.1 riastrad
106 1.1 riastrad return 1;
107 1.1 riastrad }
108 1.1 riastrad
109 1.1 riastrad static void
110 1.1 riastrad intelfb_attach(device_t parent, device_t self, void *aux)
111 1.1 riastrad {
112 1.1 riastrad struct intelfb_softc *const sc = device_private(self);
113 1.1 riastrad const struct intelfb_attach_args *const ifa = aux;
114 1.1 riastrad int error;
115 1.1 riastrad
116 1.1 riastrad sc->sc_dev = self;
117 1.1 riastrad sc->sc_ifa = *ifa;
118 1.1 riastrad sc->sc_mapped = false;
119 1.1 riastrad sc->sc_scheduled = false;
120 1.1 riastrad sc->sc_attached = false;
121 1.1 riastrad
122 1.5 riastrad aprint_naive("\n");
123 1.5 riastrad aprint_normal("\n");
124 1.5 riastrad
125 1.1 riastrad /* XXX Defer this too? */
126 1.1 riastrad error = bus_space_map(ifa->ifa_fb_bst, ifa->ifa_fb_addr,
127 1.1 riastrad ifa->ifa_fb_size,
128 1.1 riastrad (BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE),
129 1.1 riastrad &sc->sc_fb_bsh);
130 1.1 riastrad if (error) {
131 1.1 riastrad aprint_error_dev(self, "unable to map framebuffer: %d\n",
132 1.1 riastrad error);
133 1.1 riastrad goto fail0;
134 1.1 riastrad }
135 1.1 riastrad sc->sc_mapped = true;
136 1.1 riastrad
137 1.1 riastrad i915drmkms_task_init(&sc->sc_setconfig_task, &intelfb_setconfig_task);
138 1.1 riastrad error = i915drmkms_task_schedule(parent, &sc->sc_setconfig_task);
139 1.1 riastrad if (error) {
140 1.1 riastrad aprint_error_dev(self, "failed to schedule mode set: %d\n",
141 1.1 riastrad error);
142 1.1 riastrad goto fail1;
143 1.1 riastrad }
144 1.1 riastrad sc->sc_scheduled = true;
145 1.1 riastrad
146 1.1 riastrad /* Success! */
147 1.1 riastrad return;
148 1.1 riastrad
149 1.1 riastrad fail1: bus_space_unmap(ifa->ifa_fb_bst, sc->sc_fb_bsh, ifa->ifa_fb_size);
150 1.1 riastrad sc->sc_mapped = false;
151 1.1 riastrad fail0: return;
152 1.1 riastrad }
153 1.1 riastrad
154 1.1 riastrad static int
155 1.1 riastrad intelfb_detach(device_t self, int flags)
156 1.1 riastrad {
157 1.1 riastrad struct intelfb_softc *const sc = device_private(self);
158 1.1 riastrad
159 1.1 riastrad if (sc->sc_scheduled)
160 1.1 riastrad return EBUSY;
161 1.1 riastrad
162 1.1 riastrad if (sc->sc_attached) {
163 1.1 riastrad /* XXX genfb detach? Help? */
164 1.1 riastrad sc->sc_attached = false;
165 1.1 riastrad }
166 1.1 riastrad
167 1.1 riastrad if (sc->sc_mapped) {
168 1.1 riastrad bus_space_unmap(sc->sc_ifa.ifa_fb_bst, sc->sc_fb_bsh,
169 1.1 riastrad sc->sc_ifa.ifa_fb_size);
170 1.1 riastrad sc->sc_mapped = false;
171 1.1 riastrad }
172 1.1 riastrad
173 1.1 riastrad return 0;
174 1.1 riastrad }
175 1.1 riastrad
176 1.1 riastrad static void
177 1.1 riastrad intelfb_setconfig_task(struct i915drmkms_task *task)
178 1.1 riastrad {
179 1.1 riastrad struct intelfb_softc *const sc = container_of(task,
180 1.1 riastrad struct intelfb_softc, sc_setconfig_task);
181 1.1 riastrad const prop_dictionary_t dict = device_properties(sc->sc_dev);
182 1.1 riastrad const struct intelfb_attach_args *const ifa = &sc->sc_ifa;
183 1.1 riastrad const struct drm_fb_helper_surface_size *const sizes =
184 1.1 riastrad &ifa->ifa_fb_sizes;
185 1.1 riastrad #if NVGA > 0 /* XXX no workie for modules */
186 1.1 riastrad struct drm_device *const dev = sc->sc_ifa.ifa_drm_dev;
187 1.1 riastrad #endif
188 1.1 riastrad enum { CONS_VGA, CONS_GENFB, CONS_NONE } what_was_cons;
189 1.1 riastrad static const struct genfb_ops zero_genfb_ops;
190 1.1 riastrad struct genfb_ops genfb_ops = zero_genfb_ops;
191 1.1 riastrad int error;
192 1.1 riastrad
193 1.1 riastrad KASSERT(sc->sc_scheduled);
194 1.1 riastrad
195 1.1 riastrad if (ifa->ifa_fb_zero)
196 1.1 riastrad bus_space_set_region_1(sc->sc_ifa.ifa_fb_bst, sc->sc_fb_bsh, 0,
197 1.1 riastrad 0, sc->sc_ifa.ifa_fb_size);
198 1.1 riastrad
199 1.1 riastrad /* XXX Ugh... Pass these parameters some other way! */
200 1.6 riastrad prop_dictionary_set_uint32(dict, "width", sizes->surface_width);
201 1.6 riastrad prop_dictionary_set_uint32(dict, "height", sizes->surface_height);
202 1.1 riastrad prop_dictionary_set_uint8(dict, "depth", sizes->surface_bpp);
203 1.1 riastrad prop_dictionary_set_uint16(dict, "linebytes",
204 1.6 riastrad roundup2((sizes->surface_width * howmany(sizes->surface_bpp, 8)),
205 1.6 riastrad 64));
206 1.1 riastrad prop_dictionary_set_uint32(dict, "address", 0); /* XXX >32-bit */
207 1.1 riastrad CTASSERT(sizeof(uintptr_t) <= sizeof(uint64_t));
208 1.1 riastrad prop_dictionary_set_uint64(dict, "virtual_address",
209 1.1 riastrad (uint64_t)(uintptr_t)bus_space_vaddr(sc->sc_ifa.ifa_fb_bst,
210 1.1 riastrad sc->sc_fb_bsh));
211 1.1 riastrad
212 1.7 jmcneill prop_dictionary_set_uint64(dict, "mode_callback",
213 1.7 jmcneill (uint64_t)(uintptr_t)&intelfb_genfb_mode_callback);
214 1.7 jmcneill
215 1.1 riastrad /* XXX Whattakludge! */
216 1.1 riastrad #if NVGA > 0
217 1.1 riastrad if (vga_is_console(dev->pdev->pd_pa.pa_iot, -1)) {
218 1.1 riastrad what_was_cons = CONS_VGA;
219 1.1 riastrad prop_dictionary_set_bool(dict, "is_console", true);
220 1.1 riastrad i915_disable_vga(dev);
221 1.1 riastrad vga_cndetach();
222 1.1 riastrad } else
223 1.1 riastrad #endif
224 1.1 riastrad if (genfb_is_console() && genfb_is_enabled()) {
225 1.1 riastrad what_was_cons = CONS_GENFB;
226 1.1 riastrad prop_dictionary_set_bool(dict, "is_console", true);
227 1.1 riastrad } else {
228 1.1 riastrad what_was_cons = CONS_NONE;
229 1.1 riastrad prop_dictionary_set_bool(dict, "is_console", false);
230 1.1 riastrad }
231 1.1 riastrad
232 1.1 riastrad sc->sc_genfb.sc_dev = sc->sc_dev;
233 1.1 riastrad genfb_init(&sc->sc_genfb);
234 1.1 riastrad genfb_ops.genfb_ioctl = intelfb_genfb_ioctl;
235 1.1 riastrad genfb_ops.genfb_mmap = intelfb_genfb_mmap;
236 1.1 riastrad genfb_ops.genfb_enable_polling = intelfb_genfb_enable_polling;
237 1.1 riastrad genfb_ops.genfb_disable_polling = intelfb_genfb_disable_polling;
238 1.1 riastrad
239 1.1 riastrad error = genfb_attach(&sc->sc_genfb, &genfb_ops);
240 1.1 riastrad if (error) {
241 1.1 riastrad aprint_error_dev(sc->sc_dev, "failed to attach genfb: %d\n",
242 1.1 riastrad error);
243 1.1 riastrad goto fail0;
244 1.1 riastrad }
245 1.1 riastrad sc->sc_attached = true;
246 1.1 riastrad
247 1.1 riastrad drm_fb_helper_set_config(sc->sc_ifa.ifa_fb_helper);
248 1.1 riastrad
249 1.1 riastrad /* Success! */
250 1.1 riastrad sc->sc_scheduled = false;
251 1.1 riastrad return;
252 1.1 riastrad
253 1.1 riastrad fail0: /* XXX Restore console... */
254 1.1 riastrad switch (what_was_cons) {
255 1.1 riastrad case CONS_VGA:
256 1.1 riastrad break;
257 1.1 riastrad case CONS_GENFB:
258 1.1 riastrad break;
259 1.1 riastrad case CONS_NONE:
260 1.1 riastrad break;
261 1.1 riastrad default:
262 1.1 riastrad break;
263 1.1 riastrad }
264 1.1 riastrad }
265 1.1 riastrad
266 1.1 riastrad static int
267 1.1 riastrad intelfb_genfb_dpms(struct drm_device *dev, int dpms_mode)
268 1.1 riastrad {
269 1.1 riastrad struct drm_i915_private *const dev_priv = dev->dev_private;
270 1.1 riastrad /* XXX What guarantees dev_priv->fbdev stays around? */
271 1.1 riastrad struct drm_fb_helper *const fb_helper = &dev_priv->fbdev->helper;
272 1.1 riastrad unsigned i;
273 1.1 riastrad
274 1.1 riastrad drm_modeset_lock_all(dev);
275 1.1 riastrad for (i = 0; i < fb_helper->connector_count; i++) {
276 1.1 riastrad struct drm_connector *const connector =
277 1.1 riastrad fb_helper->connector_info[i]->connector;
278 1.1 riastrad (*connector->funcs->dpms)(connector, dpms_mode);
279 1.1 riastrad drm_object_property_set_value(&connector->base,
280 1.1 riastrad dev->mode_config.dpms_property, dpms_mode);
281 1.1 riastrad }
282 1.1 riastrad drm_modeset_unlock_all(dev);
283 1.1 riastrad
284 1.1 riastrad return 0;
285 1.1 riastrad }
286 1.1 riastrad
287 1.1 riastrad static int
288 1.1 riastrad intelfb_genfb_ioctl(void *v, void *vs, unsigned long cmd, void *data, int flag,
289 1.1 riastrad struct lwp *l)
290 1.1 riastrad {
291 1.1 riastrad struct genfb_softc *const genfb = v;
292 1.1 riastrad struct intelfb_softc *const sc = container_of(genfb,
293 1.1 riastrad struct intelfb_softc, sc_genfb);
294 1.1 riastrad struct drm_device *const dev = sc->sc_ifa.ifa_fb_helper->dev;
295 1.1 riastrad const struct pci_attach_args *const pa = &dev->pdev->pd_pa;
296 1.1 riastrad
297 1.1 riastrad switch (cmd) {
298 1.1 riastrad case WSDISPLAYIO_GTYPE:
299 1.1 riastrad *(unsigned int *)data = WSDISPLAY_TYPE_PCIVGA;
300 1.1 riastrad return 0;
301 1.1 riastrad
302 1.1 riastrad /* PCI config read/write passthrough. */
303 1.1 riastrad case PCI_IOC_CFGREAD:
304 1.1 riastrad case PCI_IOC_CFGWRITE:
305 1.1 riastrad return pci_devioctl(pa->pa_pc, pa->pa_tag, cmd, data, flag, l);
306 1.1 riastrad
307 1.1 riastrad case WSDISPLAYIO_GET_BUSID:
308 1.2 riastrad return wsdisplayio_busid_pci(dev->dev, pa->pa_pc, pa->pa_tag,
309 1.2 riastrad data);
310 1.1 riastrad
311 1.1 riastrad /*
312 1.1 riastrad * Screen blanking ioctls. Not to be confused with backlight
313 1.1 riastrad * (can be disabled while stuff is still drawn on the screen),
314 1.1 riastrad * brightness, or contrast (which we don't support). Backlight
315 1.1 riastrad * and brightness are done through WSDISPLAYIO_{GET,SET}PARAM.
316 1.1 riastrad * This toggles between DPMS ON and DPMS OFF; backlight toggles
317 1.1 riastrad * between DPMS ON and DPMS SUSPEND.
318 1.1 riastrad */
319 1.1 riastrad case WSDISPLAYIO_GVIDEO: {
320 1.1 riastrad int *onp = (int *)data;
321 1.1 riastrad
322 1.1 riastrad /* XXX Can't really determine a single answer here. */
323 1.1 riastrad *onp = 1;
324 1.1 riastrad return 0;
325 1.1 riastrad }
326 1.1 riastrad
327 1.1 riastrad case WSDISPLAYIO_SVIDEO: {
328 1.1 riastrad const int on = *(const int *)data;
329 1.1 riastrad
330 1.1 riastrad return intelfb_genfb_dpms(dev,
331 1.1 riastrad on? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF);
332 1.1 riastrad }
333 1.1 riastrad
334 1.1 riastrad default:
335 1.1 riastrad return EPASSTHROUGH;
336 1.1 riastrad }
337 1.1 riastrad }
338 1.1 riastrad
339 1.1 riastrad static paddr_t
340 1.1 riastrad intelfb_genfb_mmap(void *v, void *vs, off_t offset, int prot)
341 1.1 riastrad {
342 1.1 riastrad struct genfb_softc *const genfb = v;
343 1.1 riastrad struct intelfb_softc *const sc = container_of(genfb,
344 1.1 riastrad struct intelfb_softc, sc_genfb);
345 1.1 riastrad struct drm_fb_helper *const helper = sc->sc_ifa.ifa_fb_helper;
346 1.1 riastrad struct intel_fbdev *const fbdev = container_of(helper,
347 1.1 riastrad struct intel_fbdev, helper);
348 1.1 riastrad struct drm_device *const dev = helper->dev;
349 1.1 riastrad struct drm_i915_private *const dev_priv = dev->dev_private;
350 1.1 riastrad const struct pci_attach_args *const pa = &dev->pdev->pd_pa;
351 1.1 riastrad unsigned int i;
352 1.1 riastrad
353 1.1 riastrad if (offset < 0)
354 1.1 riastrad return -1;
355 1.1 riastrad
356 1.1 riastrad /* Treat low memory as the framebuffer itself. */
357 1.1 riastrad if (offset < genfb->sc_fbsize)
358 1.1 riastrad return bus_space_mmap(dev->bst,
359 1.1 riastrad (dev_priv->gtt.mappable_base +
360 1.1 riastrad i915_gem_obj_ggtt_offset(fbdev->fb->obj)),
361 1.1 riastrad offset, prot,
362 1.1 riastrad (BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE));
363 1.1 riastrad
364 1.1 riastrad /* XXX Cargo-culted from genfb_pci. */
365 1.1 riastrad if (kauth_authorize_machdep(kauth_cred_get(),
366 1.1 riastrad KAUTH_MACHDEP_UNMANAGEDMEM, NULL, NULL, NULL, NULL) != 0) {
367 1.1 riastrad aprint_normal_dev(dev->dev, "mmap at %"PRIxMAX" rejected\n",
368 1.1 riastrad (uintmax_t)offset);
369 1.1 riastrad return -1;
370 1.1 riastrad }
371 1.1 riastrad
372 1.1 riastrad for (i = 0; PCI_BAR(i) <= PCI_MAPREG_ROM; i++) {
373 1.1 riastrad pcireg_t type;
374 1.1 riastrad bus_addr_t addr;
375 1.1 riastrad bus_size_t size;
376 1.1 riastrad int flags;
377 1.1 riastrad
378 1.1 riastrad /* Interrogate the BAR. */
379 1.1 riastrad if (!pci_mapreg_probe(pa->pa_pc, pa->pa_tag, PCI_BAR(i),
380 1.1 riastrad &type))
381 1.1 riastrad continue;
382 1.1 riastrad if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM)
383 1.1 riastrad continue;
384 1.1 riastrad if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, PCI_BAR(i), type,
385 1.1 riastrad &addr, &size, &flags))
386 1.1 riastrad continue;
387 1.1 riastrad
388 1.1 riastrad /* Try to map it if it's in range. */
389 1.1 riastrad if ((addr <= offset) && (offset < (addr + size)))
390 1.1 riastrad return bus_space_mmap(pa->pa_memt, addr,
391 1.1 riastrad (offset - addr), prot, flags);
392 1.1 riastrad
393 1.1 riastrad /* Skip a slot if this was a 64-bit BAR. */
394 1.1 riastrad if ((PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_MEM) &&
395 1.1 riastrad (PCI_MAPREG_MEM_TYPE(type) == PCI_MAPREG_MEM_TYPE_64BIT))
396 1.1 riastrad i += 1;
397 1.1 riastrad }
398 1.1 riastrad
399 1.1 riastrad /* Failure! */
400 1.1 riastrad return -1;
401 1.1 riastrad }
402 1.1 riastrad
403 1.1 riastrad static int
404 1.1 riastrad intelfb_genfb_enable_polling(void *cookie)
405 1.1 riastrad {
406 1.1 riastrad struct genfb_softc *const genfb = cookie;
407 1.1 riastrad struct intelfb_softc *const sc = container_of(genfb,
408 1.1 riastrad struct intelfb_softc, sc_genfb);
409 1.1 riastrad
410 1.1 riastrad return drm_fb_helper_debug_enter_fb(sc->sc_ifa.ifa_fb_helper);
411 1.1 riastrad }
412 1.1 riastrad
413 1.1 riastrad static int
414 1.1 riastrad intelfb_genfb_disable_polling(void *cookie)
415 1.1 riastrad {
416 1.1 riastrad struct genfb_softc *const genfb = cookie;
417 1.1 riastrad struct intelfb_softc *const sc = container_of(genfb,
418 1.1 riastrad struct intelfb_softc, sc_genfb);
419 1.1 riastrad
420 1.1 riastrad return drm_fb_helper_debug_leave_fb(sc->sc_ifa.ifa_fb_helper);
421 1.1 riastrad }
422 1.7 jmcneill
423 1.7 jmcneill static bool
424 1.7 jmcneill intelfb_genfb_setmode(struct genfb_softc *genfb, int mode)
425 1.7 jmcneill {
426 1.7 jmcneill struct intelfb_softc *sc = (struct intelfb_softc *)genfb;
427 1.7 jmcneill
428 1.7 jmcneill if (mode == WSDISPLAYIO_MODE_EMUL) {
429 1.7 jmcneill drm_fb_helper_set_config(sc->sc_ifa.ifa_fb_helper);
430 1.7 jmcneill }
431 1.7 jmcneill
432 1.7 jmcneill return true;
433 1.7 jmcneill }
434