1 /* radeon_drv.c -- ATI Radeon driver -*- linux-c -*-
2 * Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com
3 */
4 /*-
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Gareth Hughes <gareth@valinux.com>
29 *
30 */
31
32 #include "drmP.h"
33 #include "drm.h"
34 #include "radeon_drm.h"
35 #include "radeon_drv.h"
36 #include "drm_pciids.h"
37
38 int radeon_no_wb;
39
40 /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
41 static drm_pci_id_list_t radeon_pciidlist[] = {
42 radeon_PCI_IDS
43 };
44
radeon_configure(struct drm_device * dev)45 static void radeon_configure(struct drm_device *dev)
46 {
47 dev->driver->driver_features =
48 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA |
49 DRIVER_SG | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ;
50
51 dev->driver->buf_priv_size = sizeof(drm_radeon_buf_priv_t);
52 dev->driver->load = radeon_driver_load;
53 dev->driver->unload = radeon_driver_unload;
54 dev->driver->firstopen = radeon_driver_firstopen;
55 dev->driver->open = radeon_driver_open;
56 dev->driver->preclose = radeon_driver_preclose;
57 dev->driver->postclose = radeon_driver_postclose;
58 dev->driver->lastclose = radeon_driver_lastclose;
59 dev->driver->get_vblank_counter = radeon_get_vblank_counter;
60 dev->driver->enable_vblank = radeon_enable_vblank;
61 dev->driver->disable_vblank = radeon_disable_vblank;
62 dev->driver->irq_preinstall = radeon_driver_irq_preinstall;
63 dev->driver->irq_postinstall = radeon_driver_irq_postinstall;
64 dev->driver->irq_uninstall = radeon_driver_irq_uninstall;
65 dev->driver->irq_handler = radeon_driver_irq_handler;
66 dev->driver->dma_ioctl = radeon_cp_buffers;
67
68 dev->driver->ioctls = radeon_ioctls;
69 dev->driver->max_ioctl = radeon_max_ioctl;
70
71 dev->driver->name = DRIVER_NAME;
72 dev->driver->desc = DRIVER_DESC;
73 dev->driver->date = DRIVER_DATE;
74 dev->driver->major = DRIVER_MAJOR;
75 dev->driver->minor = DRIVER_MINOR;
76 dev->driver->patchlevel = DRIVER_PATCHLEVEL;
77 }
78
79 #if defined(__FreeBSD__)
80 static int
radeon_probe(device_t kdev)81 radeon_probe(device_t kdev)
82 {
83 return drm_probe(kdev, radeon_pciidlist);
84 }
85
86 static int
radeon_attach(device_t kdev)87 radeon_attach(device_t kdev)
88 {
89 struct drm_device *dev = device_get_softc(kdev);
90
91 dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER,
92 M_WAITOK | M_ZERO);
93
94 radeon_configure(dev);
95
96 return drm_attach(kdev, radeon_pciidlist);
97 }
98
99 static int
radeon_detach(device_t kdev)100 radeon_detach(device_t kdev)
101 {
102 struct drm_device *dev = device_get_softc(kdev);
103 int ret;
104
105 ret = drm_detach(kdev);
106
107 free(dev->driver, DRM_MEM_DRIVER);
108
109 return ret;
110 }
111
112 static device_method_t radeon_methods[] = {
113 /* Device interface */
114 DEVMETHOD(device_probe, radeon_probe),
115 DEVMETHOD(device_attach, radeon_attach),
116 DEVMETHOD(device_detach, radeon_detach),
117
118 { 0, 0 }
119 };
120
121 static driver_t radeon_driver = {
122 "drm",
123 radeon_methods,
124 sizeof(struct drm_device)
125 };
126
127 extern devclass_t drm_devclass;
128 #if __FreeBSD_version >= 700010
129 DRIVER_MODULE(radeon, vgapci, radeon_driver, drm_devclass, 0, 0);
130 #else
131 DRIVER_MODULE(radeon, pci, radeon_driver, drm_devclass, 0, 0);
132 #endif
133 MODULE_DEPEND(radeon, drm, 1, 1, 1);
134
135 #elif defined(__NetBSD__)
136
137 static bool
radeondrm_suspend(device_t self,const pmf_qual_t * qual)138 radeondrm_suspend(device_t self, const pmf_qual_t *qual)
139 {
140 struct drm_device *dev = device_private(self);
141 drm_radeon_cp_stop_t stop_args;
142 bool rv = true;
143
144 stop_args.flush = stop_args.idle = 0;
145 DRM_LOCK();
146 if (drm_find_file_by_proc(dev, curlwp->l_proc) &&
147 radeon_cp_stop(dev, &stop_args, dev->lock.file_priv) != 0)
148 rv = false;
149 DRM_UNLOCK();
150
151 return rv;
152 }
153
154 static bool
radeondrm_resume(device_t self,const pmf_qual_t * qual)155 radeondrm_resume(device_t self, const pmf_qual_t *qual)
156 {
157 struct drm_device *dev = device_private(self);
158 bool rv = true;
159
160 DRM_LOCK();
161 if (drm_find_file_by_proc(dev, curlwp->l_proc) &&
162 radeon_cp_resume(dev, NULL, NULL) != 0)
163 rv = false;
164 DRM_UNLOCK();
165
166 return rv;
167 }
168
169 static int
radeondrm_probe(device_t parent,cfdata_t match,void * aux)170 radeondrm_probe(device_t parent, cfdata_t match, void *aux)
171 {
172 struct pci_attach_args *pa = aux;
173 return drm_probe(pa, radeon_pciidlist);
174 }
175
176 static void
radeondrm_attach(device_t parent,device_t self,void * aux)177 radeondrm_attach(device_t parent, device_t self, void *aux)
178 {
179 struct pci_attach_args *pa = aux;
180 struct drm_device *dev = device_private(self);
181
182 dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER,
183 M_WAITOK | M_ZERO);
184
185 radeon_configure(dev);
186
187 if (!pmf_device_register(self, radeondrm_suspend, radeondrm_resume))
188 aprint_error_dev(self, "couldn't establish power handler\n");
189
190 drm_attach(self, pa, radeon_pciidlist);
191 }
192
193 static int
radeondrm_detach(device_t self,int flags)194 radeondrm_detach(device_t self, int flags)
195 {
196 pmf_device_deregister(self);
197
198 return drm_detach(self, flags);
199 }
200
201 CFATTACH_DECL_NEW(radeondrm, sizeof(struct drm_device),
202 radeondrm_probe, radeondrm_attach, radeondrm_detach, NULL);
203
204 MODULE(MODULE_CLASS_DRIVER, radeondrm, "drm,ati_pcigart");
205
206 #ifdef _MODULE
207 #include "ioconf.c"
208 #endif
209
210 static int
radeondrm_modcmd(modcmd_t cmd,void * arg)211 radeondrm_modcmd(modcmd_t cmd, void *arg)
212 {
213 int error = 0;
214
215 switch (cmd) {
216 case MODULE_CMD_INIT:
217 #ifdef _MODULE
218 error = config_init_component(cfdriver_ioconf_radeondrm,
219 cfattach_ioconf_radeondrm, cfdata_ioconf_radeondrm);
220 #endif
221 break;
222 case MODULE_CMD_FINI:
223 #ifdef _MODULE
224 error = config_fini_component(cfdriver_ioconf_radeondrm,
225 cfattach_ioconf_radeondrm, cfdata_ioconf_radeondrm);
226 #endif
227 break;
228 default:
229 return ENOTTY;
230 }
231
232 return error;
233 }
234
235 #include <dev/firmload.h>
236
radeon_load_a_microcode(const char * fmt,const char * chip_name,void ** codep,size_t * sizep)237 int radeon_load_a_microcode(const char *fmt, const char *chip_name, void **codep, size_t *sizep)
238 {
239 firmware_handle_t fh;
240 char fw_name[30];
241 int error;
242
243 snprintf(fw_name, sizeof(fw_name), fmt, chip_name);
244 if ((error = firmware_open("radeon", fw_name, &fh)) != 0) {
245 DRM_ERROR("Cannot open radeon/%s firmware: %d\n", fw_name, error);
246 return error;
247 }
248 *sizep = firmware_get_size(fh);
249 if ((*codep = firmware_malloc(*sizep)) == NULL) {
250 DRM_ERROR("Cannot alloc memory for radeon/%s firmware\n", chip_name);
251 firmware_close(fh);
252 return ENOMEM;
253 }
254 if ((error = firmware_read(fh, 0, *codep, *sizep)) != 0) {
255 DRM_ERROR("Cannot read radeon/%s firmware: %d\n", chip_name, error);
256 firmware_free(*codep, *sizep);
257 }
258 firmware_close(fh);
259
260 return error;
261 }
262
radeon_free_a_microcode(void * code,size_t size)263 void radeon_free_a_microcode(void *code, size_t size)
264 {
265 firmware_free(code, size);
266 }
267
268 #endif
269