vga_pci.c revision 254883
1/*-
2 * Copyright (c) 2005 John Baldwin <jhb@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the names of any co-contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/pci/vga_pci.c 254883 2013-08-25 18:23:15Z dumbbell $");
32
33/*
34 * Simple driver for PCI VGA display devices.  Drivers such as agp(4) and
35 * drm(4) should attach as children of this device.
36 *
37 * XXX: The vgapci name is a hack until we somehow merge the isa vga driver
38 * in or rename it.
39 */
40
41#include <sys/param.h>
42#include <sys/bus.h>
43#include <sys/kernel.h>
44#include <sys/module.h>
45#include <sys/rman.h>
46#include <sys/sysctl.h>
47#include <sys/systm.h>
48
49#if defined(__amd64__) || defined(__i386__) || defined(__ia64__)
50#include <vm/vm.h>
51#include <vm/pmap.h>
52#endif
53
54#include <dev/pci/pcireg.h>
55#include <dev/pci/pcivar.h>
56
57struct vga_resource {
58	struct resource	*vr_res;
59	int	vr_refs;
60};
61
62struct vga_pci_softc {
63	device_t	vga_msi_child;	/* Child driver using MSI. */
64	struct vga_resource vga_bars[PCIR_MAX_BAR_0 + 1];
65	struct vga_resource vga_bios;
66};
67
68SYSCTL_DECL(_hw_pci);
69
70int vga_pci_default_unit = -1;
71TUNABLE_INT("hw.pci.default_vgapci_unit", &vga_pci_default_unit);
72SYSCTL_INT(_hw_pci, OID_AUTO, default_vgapci_unit, CTLFLAG_RDTUN,
73    &vga_pci_default_unit, -1, "Default VGA-compatible display");
74
75int
76vga_pci_is_boot_display(device_t dev)
77{
78
79	/*
80	 * Return true if the given device is the default display used
81	 * at boot time.
82	 */
83
84	return (
85	    (pci_get_class(dev) == PCIC_DISPLAY ||
86	     (pci_get_class(dev) == PCIC_OLD &&
87	      pci_get_subclass(dev) == PCIS_OLD_VGA)) &&
88	    device_get_unit(dev) == vga_pci_default_unit);
89}
90
91void *
92vga_pci_map_bios(device_t dev, size_t *size)
93{
94	int rid;
95	struct resource *res;
96
97#if defined(__amd64__) || defined(__i386__) || defined(__ia64__)
98	if (vga_pci_is_boot_display(dev)) {
99		/*
100		 * On x86, the System BIOS copy the default display
101		 * device's Video BIOS at a fixed location in system
102		 * memory (0xC0000, 128 kBytes long) at boot time.
103		 *
104		 * We use this copy for the default boot device, because
105		 * the original ROM may not be valid after boot.
106		 */
107
108		*size = VGA_PCI_BIOS_SHADOW_SIZE;
109		return (pmap_mapbios(VGA_PCI_BIOS_SHADOW_ADDR, *size));
110	}
111#endif
112
113	rid = PCIR_BIOS;
114	res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
115	if (res == NULL) {
116		return (NULL);
117	}
118
119	*size = rman_get_size(res);
120	return (rman_get_virtual(res));
121}
122
123void
124vga_pci_unmap_bios(device_t dev, void *bios)
125{
126	int rid;
127	struct resource *res;
128
129	if (bios == NULL) {
130		return;
131	}
132
133#if defined(__amd64__) || defined(__i386__) || defined(__ia64__)
134	if (vga_pci_is_boot_display(dev)) {
135		/* We mapped the BIOS shadow copy located at 0xC0000. */
136		pmap_unmapdev((vm_offset_t)bios, VGA_PCI_BIOS_SHADOW_SIZE);
137
138		return;
139	}
140#endif
141
142	/*
143	 * FIXME: We returned only the virtual address of the resource
144	 * to the caller. Now, to get the resource struct back, we
145	 * allocate it again: the struct exists once in memory in
146	 * device softc. Therefore, we release twice now to release the
147	 * reference we just obtained to get the structure back and the
148	 * caller's reference.
149	 */
150
151	rid = PCIR_BIOS;
152	res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
153
154	KASSERT(res != NULL,
155	    ("%s: Can't get BIOS resource back", __func__));
156	KASSERT(bios == rman_get_virtual(res),
157	    ("%s: Given BIOS address doesn't match "
158	     "resource virtual address", __func__));
159
160	bus_release_resource(dev, SYS_RES_MEMORY, rid, bios);
161	bus_release_resource(dev, SYS_RES_MEMORY, rid, bios);
162}
163
164static int
165vga_pci_probe(device_t dev)
166{
167	device_t bdev;
168	int unit;
169	uint16_t bctl;
170
171	switch (pci_get_class(dev)) {
172	case PCIC_DISPLAY:
173		break;
174	case PCIC_OLD:
175		if (pci_get_subclass(dev) != PCIS_OLD_VGA)
176			return (ENXIO);
177		break;
178	default:
179		return (ENXIO);
180	}
181
182	/* Probe default display. */
183	unit = device_get_unit(dev);
184	bdev = device_get_parent(device_get_parent(dev));
185	bctl = pci_read_config(bdev, PCIR_BRIDGECTL_1, 2);
186	if (vga_pci_default_unit < 0 && (bctl & PCIB_BCR_VGA_ENABLE) != 0)
187		vga_pci_default_unit = unit;
188	if (vga_pci_default_unit == unit)
189		device_set_flags(dev, 1);
190
191	device_set_desc(dev, "VGA-compatible display");
192	return (BUS_PROBE_GENERIC);
193}
194
195static int
196vga_pci_attach(device_t dev)
197{
198
199	bus_generic_probe(dev);
200
201	/* Always create a drm child for now to make it easier on drm. */
202	device_add_child(dev, "drm", -1);
203	device_add_child(dev, "drmn", -1);
204	bus_generic_attach(dev);
205	return (0);
206}
207
208static int
209vga_pci_suspend(device_t dev)
210{
211
212	return (bus_generic_suspend(dev));
213}
214
215static int
216vga_pci_resume(device_t dev)
217{
218
219	return (bus_generic_resume(dev));
220}
221
222/* Bus interface. */
223
224static int
225vga_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
226{
227
228	return (BUS_READ_IVAR(device_get_parent(dev), dev, which, result));
229}
230
231static int
232vga_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
233{
234
235	return (EINVAL);
236}
237
238static int
239vga_pci_setup_intr(device_t dev, device_t child, struct resource *irq,
240    int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg,
241    void **cookiep)
242{
243	return (BUS_SETUP_INTR(device_get_parent(dev), dev, irq, flags,
244	    filter, intr, arg, cookiep));
245}
246
247static int
248vga_pci_teardown_intr(device_t dev, device_t child, struct resource *irq,
249    void *cookie)
250{
251	return (BUS_TEARDOWN_INTR(device_get_parent(dev), dev, irq, cookie));
252}
253
254static struct vga_resource *
255lookup_res(struct vga_pci_softc *sc, int rid)
256{
257	int bar;
258
259	if (rid == PCIR_BIOS)
260		return (&sc->vga_bios);
261	bar = PCI_RID2BAR(rid);
262	if (bar >= 0 && bar <= PCIR_MAX_BAR_0)
263		return (&sc->vga_bars[bar]);
264	return (NULL);
265}
266
267static struct resource *
268vga_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
269    u_long start, u_long end, u_long count, u_int flags)
270{
271	struct vga_resource *vr;
272
273	switch (type) {
274	case SYS_RES_MEMORY:
275	case SYS_RES_IOPORT:
276		/*
277		 * For BARs, we cache the resource so that we only allocate it
278		 * from the PCI bus once.
279		 */
280		vr = lookup_res(device_get_softc(dev), *rid);
281		if (vr == NULL)
282			return (NULL);
283		if (vr->vr_res == NULL)
284			vr->vr_res = bus_alloc_resource(dev, type, rid, start,
285			    end, count, flags);
286		if (vr->vr_res != NULL)
287			vr->vr_refs++;
288		return (vr->vr_res);
289	}
290	return (bus_alloc_resource(dev, type, rid, start, end, count, flags));
291}
292
293static int
294vga_pci_release_resource(device_t dev, device_t child, int type, int rid,
295    struct resource *r)
296{
297	struct vga_resource *vr;
298	int error;
299
300	switch (type) {
301	case SYS_RES_MEMORY:
302	case SYS_RES_IOPORT:
303		/*
304		 * For BARs, we release the resource from the PCI bus
305		 * when the last child reference goes away.
306		 */
307		vr = lookup_res(device_get_softc(dev), rid);
308		if (vr == NULL)
309			return (EINVAL);
310		if (vr->vr_res == NULL)
311			return (EINVAL);
312		KASSERT(vr->vr_res == r, ("vga_pci resource mismatch"));
313		if (vr->vr_refs > 1) {
314			vr->vr_refs--;
315			return (0);
316		}
317		KASSERT(vr->vr_refs > 0,
318		    ("vga_pci resource reference count underflow"));
319		error = bus_release_resource(dev, type, rid, r);
320		if (error == 0) {
321			vr->vr_res = NULL;
322			vr->vr_refs = 0;
323		}
324		return (error);
325	}
326
327	return (bus_release_resource(dev, type, rid, r));
328}
329
330/* PCI interface. */
331
332static uint32_t
333vga_pci_read_config(device_t dev, device_t child, int reg, int width)
334{
335
336	return (pci_read_config(dev, reg, width));
337}
338
339static void
340vga_pci_write_config(device_t dev, device_t child, int reg,
341    uint32_t val, int width)
342{
343
344	pci_write_config(dev, reg, val, width);
345}
346
347static int
348vga_pci_enable_busmaster(device_t dev, device_t child)
349{
350
351	return (pci_enable_busmaster(dev));
352}
353
354static int
355vga_pci_disable_busmaster(device_t dev, device_t child)
356{
357
358	return (pci_disable_busmaster(dev));
359}
360
361static int
362vga_pci_enable_io(device_t dev, device_t child, int space)
363{
364
365	device_printf(dev, "child %s requested pci_enable_io\n",
366	    device_get_nameunit(child));
367	return (pci_enable_io(dev, space));
368}
369
370static int
371vga_pci_disable_io(device_t dev, device_t child, int space)
372{
373
374	device_printf(dev, "child %s requested pci_disable_io\n",
375	    device_get_nameunit(child));
376	return (pci_disable_io(dev, space));
377}
378
379static int
380vga_pci_get_vpd_ident(device_t dev, device_t child, const char **identptr)
381{
382
383	return (pci_get_vpd_ident(dev, identptr));
384}
385
386static int
387vga_pci_get_vpd_readonly(device_t dev, device_t child, const char *kw,
388    const char **vptr)
389{
390
391	return (pci_get_vpd_readonly(dev, kw, vptr));
392}
393
394static int
395vga_pci_set_powerstate(device_t dev, device_t child, int state)
396{
397
398	device_printf(dev, "child %s requested pci_set_powerstate\n",
399	    device_get_nameunit(child));
400	return (pci_set_powerstate(dev, state));
401}
402
403static int
404vga_pci_get_powerstate(device_t dev, device_t child)
405{
406
407	device_printf(dev, "child %s requested pci_get_powerstate\n",
408	    device_get_nameunit(child));
409	return (pci_get_powerstate(dev));
410}
411
412static int
413vga_pci_assign_interrupt(device_t dev, device_t child)
414{
415
416	device_printf(dev, "child %s requested pci_assign_interrupt\n",
417	    device_get_nameunit(child));
418	return (PCI_ASSIGN_INTERRUPT(device_get_parent(dev), dev));
419}
420
421static int
422vga_pci_find_cap(device_t dev, device_t child, int capability,
423    int *capreg)
424{
425
426	return (pci_find_cap(dev, capability, capreg));
427}
428
429static int
430vga_pci_find_extcap(device_t dev, device_t child, int capability,
431    int *capreg)
432{
433
434	return (pci_find_extcap(dev, capability, capreg));
435}
436
437static int
438vga_pci_find_htcap(device_t dev, device_t child, int capability,
439    int *capreg)
440{
441
442	return (pci_find_htcap(dev, capability, capreg));
443}
444
445static int
446vga_pci_alloc_msi(device_t dev, device_t child, int *count)
447{
448	struct vga_pci_softc *sc;
449	int error;
450
451	sc = device_get_softc(dev);
452	if (sc->vga_msi_child != NULL)
453		return (EBUSY);
454	error = pci_alloc_msi(dev, count);
455	if (error == 0)
456		sc->vga_msi_child = child;
457	return (error);
458}
459
460static int
461vga_pci_alloc_msix(device_t dev, device_t child, int *count)
462{
463	struct vga_pci_softc *sc;
464	int error;
465
466	sc = device_get_softc(dev);
467	if (sc->vga_msi_child != NULL)
468		return (EBUSY);
469	error = pci_alloc_msix(dev, count);
470	if (error == 0)
471		sc->vga_msi_child = child;
472	return (error);
473}
474
475static int
476vga_pci_remap_msix(device_t dev, device_t child, int count,
477    const u_int *vectors)
478{
479	struct vga_pci_softc *sc;
480
481	sc = device_get_softc(dev);
482	if (sc->vga_msi_child != child)
483		return (ENXIO);
484	return (pci_remap_msix(dev, count, vectors));
485}
486
487static int
488vga_pci_release_msi(device_t dev, device_t child)
489{
490	struct vga_pci_softc *sc;
491	int error;
492
493	sc = device_get_softc(dev);
494	if (sc->vga_msi_child != child)
495		return (ENXIO);
496	error = pci_release_msi(dev);
497	if (error == 0)
498		sc->vga_msi_child = NULL;
499	return (error);
500}
501
502static int
503vga_pci_msi_count(device_t dev, device_t child)
504{
505
506	return (pci_msi_count(dev));
507}
508
509static int
510vga_pci_msix_count(device_t dev, device_t child)
511{
512
513	return (pci_msix_count(dev));
514}
515
516static bus_dma_tag_t
517vga_pci_get_dma_tag(device_t bus, device_t child)
518{
519
520	return (bus_get_dma_tag(bus));
521}
522
523static device_method_t vga_pci_methods[] = {
524	/* Device interface */
525	DEVMETHOD(device_probe,		vga_pci_probe),
526	DEVMETHOD(device_attach,	vga_pci_attach),
527	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
528	DEVMETHOD(device_suspend,	vga_pci_suspend),
529	DEVMETHOD(device_resume,	vga_pci_resume),
530
531	/* Bus interface */
532	DEVMETHOD(bus_read_ivar,	vga_pci_read_ivar),
533	DEVMETHOD(bus_write_ivar,	vga_pci_write_ivar),
534	DEVMETHOD(bus_setup_intr,	vga_pci_setup_intr),
535	DEVMETHOD(bus_teardown_intr,	vga_pci_teardown_intr),
536	DEVMETHOD(bus_alloc_resource,	vga_pci_alloc_resource),
537	DEVMETHOD(bus_release_resource,	vga_pci_release_resource),
538	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
539	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
540	DEVMETHOD(bus_get_dma_tag,	vga_pci_get_dma_tag),
541
542	/* PCI interface */
543	DEVMETHOD(pci_read_config,	vga_pci_read_config),
544	DEVMETHOD(pci_write_config,	vga_pci_write_config),
545	DEVMETHOD(pci_enable_busmaster,	vga_pci_enable_busmaster),
546	DEVMETHOD(pci_disable_busmaster, vga_pci_disable_busmaster),
547	DEVMETHOD(pci_enable_io,	vga_pci_enable_io),
548	DEVMETHOD(pci_disable_io,	vga_pci_disable_io),
549	DEVMETHOD(pci_get_vpd_ident,	vga_pci_get_vpd_ident),
550	DEVMETHOD(pci_get_vpd_readonly,	vga_pci_get_vpd_readonly),
551	DEVMETHOD(pci_get_powerstate,	vga_pci_get_powerstate),
552	DEVMETHOD(pci_set_powerstate,	vga_pci_set_powerstate),
553	DEVMETHOD(pci_assign_interrupt,	vga_pci_assign_interrupt),
554	DEVMETHOD(pci_find_cap,		vga_pci_find_cap),
555	DEVMETHOD(pci_find_extcap,	vga_pci_find_extcap),
556	DEVMETHOD(pci_find_htcap,	vga_pci_find_htcap),
557	DEVMETHOD(pci_alloc_msi,	vga_pci_alloc_msi),
558	DEVMETHOD(pci_alloc_msix,	vga_pci_alloc_msix),
559	DEVMETHOD(pci_remap_msix,	vga_pci_remap_msix),
560	DEVMETHOD(pci_release_msi,	vga_pci_release_msi),
561	DEVMETHOD(pci_msi_count,	vga_pci_msi_count),
562	DEVMETHOD(pci_msix_count,	vga_pci_msix_count),
563
564	{ 0, 0 }
565};
566
567static driver_t vga_pci_driver = {
568	"vgapci",
569	vga_pci_methods,
570	sizeof(struct vga_pci_softc),
571};
572
573static devclass_t vga_devclass;
574
575DRIVER_MODULE(vgapci, pci, vga_pci_driver, vga_devclass, 0, 0);
576