vga_pci.c revision 153577
1153577Sjhb/*-
2153577Sjhb * Copyright (c) 2005 John Baldwin <jhb@FreeBSD.org>
3153577Sjhb * All rights reserved.
4153577Sjhb *
5153577Sjhb * Redistribution and use in source and binary forms, with or without
6153577Sjhb * modification, are permitted provided that the following conditions
7153577Sjhb * are met:
8153577Sjhb * 1. Redistributions of source code must retain the above copyright
9153577Sjhb *    notice, this list of conditions and the following disclaimer.
10153577Sjhb * 2. Redistributions in binary form must reproduce the above copyright
11153577Sjhb *    notice, this list of conditions and the following disclaimer in the
12153577Sjhb *    documentation and/or other materials provided with the distribution.
13153577Sjhb * 3. Neither the name of the author nor the names of any co-contributors
14153577Sjhb *    may be used to endorse or promote products derived from this software
15153577Sjhb *    without specific prior written permission.
16153577Sjhb *
17153577Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18153577Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19153577Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20153577Sjhb * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21153577Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22153577Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23153577Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24153577Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25153577Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26153577Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27153577Sjhb * SUCH DAMAGE.
28153577Sjhb */
29153577Sjhb
30153577Sjhb#include <sys/cdefs.h>
31153577Sjhb__FBSDID("$FreeBSD: head/sys/dev/pci/vga_pci.c 153577 2005-12-20 22:41:33Z jhb $");
32153577Sjhb
33153577Sjhb/*
34153577Sjhb * Simple driver for PCI VGA display devices.  Drivers such as agp(4) and
35153577Sjhb * drm(4) should attach as children of this device.
36153577Sjhb *
37153577Sjhb * XXX: The vgapci name is a hack until we somehow merge the isa vga driver
38153577Sjhb * in or rename it.
39153577Sjhb */
40153577Sjhb
41153577Sjhb#include <sys/param.h>
42153577Sjhb#include <sys/bus.h>
43153577Sjhb#include <sys/kernel.h>
44153577Sjhb#include <sys/module.h>
45153577Sjhb
46153577Sjhb#include <dev/pci/pcireg.h>
47153577Sjhb#include <dev/pci/pcivar.h>
48153577Sjhb
49153577Sjhbstatic int
50153577Sjhbvga_pci_probe(device_t dev)
51153577Sjhb{
52153577Sjhb
53153577Sjhb	switch (pci_get_class(dev)) {
54153577Sjhb	case PCIC_DISPLAY:
55153577Sjhb		break;
56153577Sjhb	case PCIC_OLD:
57153577Sjhb		if (pci_get_subclass(dev) != PCIS_OLD_VGA)
58153577Sjhb			return (ENXIO);
59153577Sjhb		break;
60153577Sjhb	default:
61153577Sjhb		return (ENXIO);
62153577Sjhb	}
63153577Sjhb	device_set_desc(dev, "VGA-compatible display");
64153577Sjhb	return (0);
65153577Sjhb}
66153577Sjhb
67153577Sjhbstatic int
68153577Sjhbvga_pci_attach(device_t dev)
69153577Sjhb{
70153577Sjhb
71153577Sjhb	bus_generic_probe(dev);
72153577Sjhb
73153577Sjhb	/*
74153577Sjhb	 * If AGP capabilities are present on this device, then create
75153577Sjhb	 * an AGP child.
76153577Sjhb	 */
77153577Sjhb	if (pci_find_extcap(dev, PCIY_AGP, NULL) == 0)
78153577Sjhb		device_add_child(dev, "agp", -1);
79153577Sjhb
80153577Sjhb	/* Always create a drm child for now to make it easier on drm. */
81153577Sjhb	device_add_child(dev, "drm", -1);
82153577Sjhb	bus_generic_attach(dev);
83153577Sjhb	return (0);
84153577Sjhb}
85153577Sjhb
86153577Sjhbstatic int
87153577Sjhbvga_pci_suspend(device_t dev)
88153577Sjhb{
89153577Sjhb
90153577Sjhb	return (bus_generic_suspend(dev));
91153577Sjhb}
92153577Sjhb
93153577Sjhbstatic int
94153577Sjhbvga_pci_resume(device_t dev)
95153577Sjhb{
96153577Sjhb
97153577Sjhb	return (bus_generic_resume(dev));
98153577Sjhb}
99153577Sjhb
100153577Sjhb/* Bus interface. */
101153577Sjhb
102153577Sjhbstatic int
103153577Sjhbvga_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
104153577Sjhb{
105153577Sjhb
106153577Sjhb	return (BUS_READ_IVAR(device_get_parent(dev), dev, which, result));
107153577Sjhb}
108153577Sjhb
109153577Sjhbstatic int
110153577Sjhbvga_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
111153577Sjhb{
112153577Sjhb
113153577Sjhb	return (EINVAL);
114153577Sjhb}
115153577Sjhb
116153577Sjhbstatic struct resource *
117153577Sjhbvga_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
118153577Sjhb    u_long start, u_long end, u_long count, u_int flags)
119153577Sjhb{
120153577Sjhb
121153577Sjhb	return (bus_alloc_resource(dev, type, rid, start, end, count, flags));
122153577Sjhb}
123153577Sjhb
124153577Sjhbstatic int
125153577Sjhbvga_pci_release_resource(device_t dev, device_t child, int type, int rid,
126153577Sjhb    struct resource *r)
127153577Sjhb{
128153577Sjhb
129153577Sjhb	return (bus_release_resource(dev, type, rid, r));
130153577Sjhb}
131153577Sjhb
132153577Sjhb/* PCI interface. */
133153577Sjhb
134153577Sjhbstatic uint32_t
135153577Sjhbvga_pci_read_config(device_t dev, device_t child, int reg, int width)
136153577Sjhb{
137153577Sjhb
138153577Sjhb	return (pci_read_config(dev, reg, width));
139153577Sjhb}
140153577Sjhb
141153577Sjhbstatic void
142153577Sjhbvga_pci_write_config(device_t dev, device_t child, int reg,
143153577Sjhb    uint32_t val, int width)
144153577Sjhb{
145153577Sjhb
146153577Sjhb	pci_write_config(dev, reg, val, width);
147153577Sjhb}
148153577Sjhb
149153577Sjhbstatic int
150153577Sjhbvga_pci_enable_busmaster(device_t dev, device_t child)
151153577Sjhb{
152153577Sjhb
153153577Sjhb	device_printf(dev, "child %s requested pci_enable_busmaster\n",
154153577Sjhb	    device_get_nameunit(child));
155153577Sjhb	return (pci_enable_busmaster(dev));
156153577Sjhb}
157153577Sjhb
158153577Sjhbstatic int
159153577Sjhbvga_pci_disable_busmaster(device_t dev, device_t child)
160153577Sjhb{
161153577Sjhb
162153577Sjhb	device_printf(dev, "child %s requested pci_disable_busmaster\n",
163153577Sjhb	    device_get_nameunit(child));
164153577Sjhb	return (pci_disable_busmaster(dev));
165153577Sjhb}
166153577Sjhb
167153577Sjhbstatic int
168153577Sjhbvga_pci_enable_io(device_t dev, device_t child, int space)
169153577Sjhb{
170153577Sjhb
171153577Sjhb	device_printf(dev, "child %s requested pci_enable_io\n",
172153577Sjhb	    device_get_nameunit(child));
173153577Sjhb	return (pci_enable_io(dev, space));
174153577Sjhb}
175153577Sjhb
176153577Sjhbstatic int
177153577Sjhbvga_pci_disable_io(device_t dev, device_t child, int space)
178153577Sjhb{
179153577Sjhb
180153577Sjhb	device_printf(dev, "child %s requested pci_disable_io\n",
181153577Sjhb	    device_get_nameunit(child));
182153577Sjhb	return (pci_disable_io(dev, space));
183153577Sjhb}
184153577Sjhb
185153577Sjhbstatic int
186153577Sjhbvga_pci_set_powerstate(device_t dev, device_t child, int state)
187153577Sjhb{
188153577Sjhb
189153577Sjhb	device_printf(dev, "child %s requested pci_set_powerstate\n",
190153577Sjhb	    device_get_nameunit(child));
191153577Sjhb	return (pci_set_powerstate(dev, state));
192153577Sjhb}
193153577Sjhb
194153577Sjhbstatic int
195153577Sjhbvga_pci_get_powerstate(device_t dev, device_t child)
196153577Sjhb{
197153577Sjhb
198153577Sjhb	device_printf(dev, "child %s requested pci_get_powerstate\n",
199153577Sjhb	    device_get_nameunit(child));
200153577Sjhb	return (pci_get_powerstate(dev));
201153577Sjhb}
202153577Sjhb
203153577Sjhbstatic int
204153577Sjhbvga_pci_assign_interrupt(device_t dev, device_t child)
205153577Sjhb{
206153577Sjhb
207153577Sjhb	device_printf(dev, "child %s requested pci_assign_interrupt\n",
208153577Sjhb	    device_get_nameunit(child));
209153577Sjhb	return (PCI_ASSIGN_INTERRUPT(device_get_parent(dev), dev));
210153577Sjhb}
211153577Sjhb
212153577Sjhbstatic int
213153577Sjhbvga_pci_find_extcap(device_t dev, device_t child, int capability,
214153577Sjhb    int *capreg)
215153577Sjhb{
216153577Sjhb
217153577Sjhb	return (pci_find_extcap(dev, capability, capreg));
218153577Sjhb}
219153577Sjhb
220153577Sjhbstatic device_method_t vga_pci_methods[] = {
221153577Sjhb	/* Device interface */
222153577Sjhb	DEVMETHOD(device_probe,		vga_pci_probe),
223153577Sjhb	DEVMETHOD(device_attach,	vga_pci_attach),
224153577Sjhb	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
225153577Sjhb	DEVMETHOD(device_suspend,	vga_pci_suspend),
226153577Sjhb	DEVMETHOD(device_resume,	vga_pci_resume),
227153577Sjhb
228153577Sjhb	/* Bus interface */
229153577Sjhb	DEVMETHOD(bus_read_ivar,	vga_pci_read_ivar),
230153577Sjhb	DEVMETHOD(bus_write_ivar,	vga_pci_write_ivar),
231153577Sjhb	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
232153577Sjhb	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
233153577Sjhb
234153577Sjhb	DEVMETHOD(bus_alloc_resource,	vga_pci_alloc_resource),
235153577Sjhb	DEVMETHOD(bus_release_resource,	vga_pci_release_resource),
236153577Sjhb	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
237153577Sjhb	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
238153577Sjhb
239153577Sjhb	/* PCI interface */
240153577Sjhb	DEVMETHOD(pci_read_config,	vga_pci_read_config),
241153577Sjhb	DEVMETHOD(pci_write_config,	vga_pci_write_config),
242153577Sjhb	DEVMETHOD(pci_enable_busmaster,	vga_pci_enable_busmaster),
243153577Sjhb	DEVMETHOD(pci_disable_busmaster, vga_pci_disable_busmaster),
244153577Sjhb	DEVMETHOD(pci_enable_io,	vga_pci_enable_io),
245153577Sjhb	DEVMETHOD(pci_disable_io,	vga_pci_disable_io),
246153577Sjhb	DEVMETHOD(pci_get_powerstate,	vga_pci_get_powerstate),
247153577Sjhb	DEVMETHOD(pci_set_powerstate,	vga_pci_set_powerstate),
248153577Sjhb	DEVMETHOD(pci_assign_interrupt,	vga_pci_assign_interrupt),
249153577Sjhb	DEVMETHOD(pci_find_extcap,	vga_pci_find_extcap),
250153577Sjhb
251153577Sjhb	{ 0, 0 }
252153577Sjhb};
253153577Sjhb
254153577Sjhbstatic driver_t vga_pci_driver = {
255153577Sjhb	"vgapci",
256153577Sjhb	vga_pci_methods,
257153577Sjhb	1,
258153577Sjhb};
259153577Sjhb
260153577Sjhbstatic devclass_t vga_devclass;
261153577Sjhb
262153577SjhbDRIVER_MODULE(vgapci, pci, vga_pci_driver, vga_devclass, 0, 0);
263