1/* mach64_drv.c -- ATI Rage 128 driver -*- linux-c -*-
2 * Created: Mon Dec 13 09:47:27 1999 by faith@precisioninsight.com
3 */
4/*-
5 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
6 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
7 * All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 * OTHER DEALINGS IN THE SOFTWARE.
27 *
28 * Authors:
29 *    Rickard E. (Rik) Faith <faith@valinux.com>
30 *    Gareth Hughes <gareth@valinux.com>
31 */
32
33
34#include <sys/types.h>
35
36#include "drmP.h"
37#include "drm.h"
38#include "mach64_drm.h"
39#include "mach64_drv.h"
40#include "drm_pciids.h"
41
42/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
43static drm_pci_id_list_t mach64_pciidlist[] = {
44	mach64_PCI_IDS
45};
46
47int
48mach64_driver_load(struct drm_device * dev, unsigned long flags)
49{
50        return drm_vblank_init(dev, 1);
51}
52
53static void mach64_configure(struct drm_device *dev)
54{
55	dev->driver->driver_features =
56	    DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA |
57	    DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ;
58
59	dev->driver->buf_priv_size	= 1; /* No dev_priv */
60	dev->driver->load		= mach64_driver_load;
61	dev->driver->lastclose		= mach64_driver_lastclose;
62	dev->driver->get_vblank_counter	= mach64_get_vblank_counter;
63	dev->driver->enable_vblank	= mach64_enable_vblank;
64	dev->driver->disable_vblank	= mach64_disable_vblank;
65	dev->driver->irq_preinstall	= mach64_driver_irq_preinstall;
66	dev->driver->irq_postinstall	= mach64_driver_irq_postinstall;
67	dev->driver->irq_uninstall	= mach64_driver_irq_uninstall;
68	dev->driver->irq_handler	= mach64_driver_irq_handler;
69	dev->driver->dma_ioctl		= mach64_dma_buffers;
70
71	dev->driver->ioctls		= mach64_ioctls;
72	dev->driver->max_ioctl		= mach64_max_ioctl;
73
74	dev->driver->name		= DRIVER_NAME;
75	dev->driver->desc		= DRIVER_DESC;
76	dev->driver->date		= DRIVER_DATE;
77	dev->driver->major		= DRIVER_MAJOR;
78	dev->driver->minor		= DRIVER_MINOR;
79	dev->driver->patchlevel		= DRIVER_PATCHLEVEL;
80}
81
82#if defined(__FreeBSD__)
83
84static int
85mach64_probe(device_t kdev)
86{
87	return drm_probe(kdev, mach64_pciidlist);
88}
89
90static int
91mach64_attach(device_t kdev)
92{
93	struct drm_device *dev = device_get_softc(kdev);
94
95	dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER,
96	    M_WAITOK | M_ZERO);
97
98	mach64_configure(dev);
99
100	return drm_attach(kdev, mach64_pciidlist);
101}
102
103static int
104mach64_detach(device_t kdev)
105{
106	struct drm_device *dev = device_get_softc(kdev);
107	int ret;
108
109	ret = drm_detach(kdev);
110
111	free(dev->driver, DRM_MEM_DRIVER);
112
113	return ret;
114}
115
116static device_method_t mach64_methods[] = {
117	/* Device interface */
118	DEVMETHOD(device_probe,		mach64_probe),
119	DEVMETHOD(device_attach,	mach64_attach),
120	DEVMETHOD(device_detach,	mach64_detach),
121
122	{ 0, 0 }
123};
124
125static driver_t mach64_driver = {
126	"drm",
127	mach64_methods,
128	sizeof(struct drm_device)
129};
130
131extern devclass_t drm_devclass;
132#if __FreeBSD_version >= 700010
133DRIVER_MODULE(mach64, vgapci, mach64_driver, drm_devclass, 0, 0);
134#else
135DRIVER_MODULE(mach64, pci, mach64_driver, drm_devclass, 0, 0);
136#endif
137MODULE_DEPEND(mach64, drm, 1, 1, 1);
138
139#elif   defined(__NetBSD__)
140
141static int
142mach64drm_probe(device_t parent, cfdata_t match, void *aux)
143{
144	struct pci_attach_args *pa = aux;
145
146	return drm_probe(pa, mach64_pciidlist);
147}
148
149static void
150mach64drm_attach(device_t parent, device_t self, void *aux)
151{
152	struct pci_attach_args *pa = aux;
153	struct drm_device *dev = device_private(self);
154
155	dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER,
156	    M_WAITOK | M_ZERO);
157
158	mach64_configure(dev);
159
160	drm_attach(self, pa, mach64_pciidlist);
161}
162
163CFATTACH_DECL_NEW(mach64drm, sizeof(struct drm_device),
164    mach64drm_probe, mach64drm_attach, drm_detach, NULL);
165
166MODULE(MODULE_CLASS_DRIVER, mach64drm, "drm");
167
168#ifdef _MODULE
169#include "ioconf.c"
170#endif
171
172static int
173mach64drm_modcmd(modcmd_t cmd, void *arg)
174{
175	int error = 0;
176
177	switch (cmd) {
178	case MODULE_CMD_INIT:
179#ifdef _MODULE
180		error = config_init_component(cfdriver_ioconf_mach64drm,
181		    cfattach_ioconf_mach64drm, cfdata_ioconf_mach64drm);
182#endif
183		break;
184	case MODULE_CMD_FINI:
185#ifdef _MODULE
186		error = config_fini_component(cfdriver_ioconf_mach64drm,
187		    cfattach_ioconf_mach64drm, cfdata_ioconf_mach64drm);
188#endif
189		break;
190	default:
191		return ENOTTY;
192	}
193
194	return error;
195}
196
197#endif
198