1 /* 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 /* 6 * radeon_drv.c -- ATI Radeon driver -*- linux-c -*- 7 * Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com 8 */ 9 /* 10 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 11 * All Rights Reserved. 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining a 14 * copy of this software and associated documentation files (the "Software"), 15 * to deal in the Software without restriction, including without limitation 16 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 17 * and/or sell copies of the Software, and to permit persons to whom the 18 * Software is furnished to do so, subject to the following conditions: 19 * 20 * The above copyright notice and this permission notice (including the next 21 * paragraph) shall be included in all copies or substantial portions of the 22 * Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 27 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 28 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 29 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 30 * OTHER DEALINGS IN THE SOFTWARE. 31 * 32 * Authors: 33 * Gareth Hughes <gareth@valinux.com> 34 * 35 */ 36 37 #include "drmP.h" 38 #include "drm.h" 39 #include "radeon_drm.h" 40 #include "radeon_drv.h" 41 #include "drm_pciids.h" 42 43 int radeon_no_wb = 1; 44 45 /* 46 * cb_ops entrypoint 47 */ 48 extern struct cb_ops drm_cb_ops; 49 50 /* drv_PCI_IDs comes from drm_pciids.h */ 51 static drm_pci_id_list_t radeon_pciidlist[] = { 52 radeon_PCI_IDS 53 }; 54 55 /* 56 * module entrypoint 57 */ 58 static int radeon_info(dev_info_t *, ddi_info_cmd_t, void *, void **); 59 static int radeon_attach(dev_info_t *, ddi_attach_cmd_t); 60 static int radeon_detach(dev_info_t *, ddi_detach_cmd_t); 61 62 extern void radeon_init_ioctl_arrays(void); 63 extern uint_t radeon_driver_irq_handler(caddr_t); 64 extern int drm_get_pci_index_reg(dev_info_t *, uint_t, uint_t, off_t *); 65 66 /* 67 * Local routines 68 */ 69 static void radeon_configure(drm_driver_t *); 70 71 /* 72 * DRM driver 73 */ 74 static drm_driver_t radeon_driver = {0}; 75 76 static struct dev_ops radeon_dev_ops = { 77 DEVO_REV, /* devo_rev */ 78 0, /* devo_refcnt */ 79 radeon_info, /* devo_getinfo */ 80 nulldev, /* devo_identify */ 81 nulldev, /* devo_probe */ 82 radeon_attach, /* devo_attach */ 83 radeon_detach, /* devo_detach */ 84 nodev, /* devo_reset */ 85 &drm_cb_ops, /* devo_cb_ops */ 86 NULL, /* devo_bus_ops */ 87 NULL /* power */ 88 }; 89 90 static struct modldrv modldrv = { 91 &mod_driverops, /* drv_modops */ 92 "radeon DRM driver", /* drv_linkinfo */ 93 &radeon_dev_ops, /* drv_dev_ops */ 94 }; 95 96 static struct modlinkage modlinkage = { 97 MODREV_1, (void *) &modldrv, NULL 98 }; 99 100 101 /* 102 * softstate head 103 */ 104 static void *radeon_statep; 105 106 int 107 _init(void) 108 { 109 int error; 110 111 radeon_configure(&radeon_driver); 112 113 if ((error = ddi_soft_state_init(&radeon_statep, 114 sizeof (drm_device_t), DRM_MAX_INSTANCES)) != 0) 115 return (error); 116 117 if ((error = mod_install(&modlinkage)) != 0) { 118 ddi_soft_state_fini(&radeon_statep); 119 return (error); 120 } 121 122 return (error); 123 124 } /* _init() */ 125 126 int 127 _fini(void) 128 { 129 int error; 130 131 if ((error = mod_remove(&modlinkage)) != 0) 132 return (error); 133 134 (void) ddi_soft_state_fini(&radeon_statep); 135 136 return (0); 137 138 } /* _fini() */ 139 140 int 141 _info(struct modinfo *modinfop) 142 { 143 return (mod_info(&modlinkage, modinfop)); 144 145 } /* _info() */ 146 147 148 static int 149 radeon_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 150 { 151 drm_device_t *statep; 152 void *handle; 153 int unit; 154 155 if (cmd != DDI_ATTACH) { 156 DRM_ERROR("radeon_attach: only attach op supported"); 157 return (DDI_FAILURE); 158 } 159 160 unit = ddi_get_instance(dip); 161 if (ddi_soft_state_zalloc(radeon_statep, unit) != DDI_SUCCESS) { 162 cmn_err(CE_WARN, 163 "radeon_attach: alloc softstate failed unit=%d", unit); 164 return (DDI_FAILURE); 165 } 166 statep = ddi_get_soft_state(radeon_statep, unit); 167 statep->dip = dip; 168 statep->driver = &radeon_driver; 169 170 /* 171 * Call drm_supp_register to create minor nodes for us 172 */ 173 handle = drm_supp_register(dip, statep); 174 if (handle == NULL) { 175 DRM_ERROR("radeon_attach: drm_supp_register failed"); 176 goto err_exit1; 177 } 178 statep->drm_handle = handle; 179 180 /* 181 * After drm_supp_register, we can call drm_xxx routine 182 */ 183 statep->drm_supported = DRM_UNSUPPORT; 184 if (drm_probe(statep, radeon_pciidlist) != DDI_SUCCESS) { 185 DRM_ERROR("radeon_open: " 186 "DRM current don't support this graphics card"); 187 goto err_exit2; 188 } 189 statep->drm_supported = DRM_SUPPORT; 190 191 /* call common attach code */ 192 if (drm_attach(statep) != DDI_SUCCESS) { 193 DRM_ERROR("radeon_attach: drm_attach failed"); 194 goto err_exit2; 195 } 196 return (DDI_SUCCESS); 197 198 err_exit2: 199 (void) drm_supp_unregister(handle); 200 err_exit1: 201 (void) ddi_soft_state_free(radeon_statep, unit); 202 return (DDI_FAILURE); 203 204 } /* radeon_attach() */ 205 206 static int 207 radeon_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 208 { 209 drm_device_t *statep; 210 int unit; 211 212 if (cmd != DDI_DETACH) 213 return (DDI_FAILURE); 214 215 unit = ddi_get_instance(dip); 216 statep = ddi_get_soft_state(radeon_statep, unit); 217 if (statep == NULL) 218 return (DDI_FAILURE); 219 220 (void) drm_detach(statep); 221 (void) drm_supp_unregister(statep->drm_handle); 222 (void) ddi_soft_state_free(radeon_statep, unit); 223 224 return (DDI_SUCCESS); 225 226 } /* radeon_detach() */ 227 228 /*ARGSUSED*/ 229 static int 230 radeon_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 231 { 232 drm_device_t *statep; 233 int error = DDI_SUCCESS; 234 int unit; 235 236 unit = drm_dev_to_instance((dev_t)arg); 237 switch (infocmd) { 238 case DDI_INFO_DEVT2DEVINFO: 239 statep = ddi_get_soft_state(radeon_statep, unit); 240 if (statep == NULL || statep->dip == NULL) { 241 error = DDI_FAILURE; 242 } else { 243 *result = (void *) statep->dip; 244 error = DDI_SUCCESS; 245 } 246 break; 247 case DDI_INFO_DEVT2INSTANCE: 248 *result = (void *)(uintptr_t)unit; 249 error = DDI_SUCCESS; 250 break; 251 default: 252 error = DDI_FAILURE; 253 break; 254 } 255 return (error); 256 257 } /* radeon_info() */ 258 259 static void 260 radeon_configure(drm_driver_t *driver) 261 { 262 driver->buf_priv_size = sizeof (drm_radeon_buf_priv_t); 263 driver->load = radeon_driver_load; 264 driver->unload = radeon_driver_unload; 265 driver->firstopen = radeon_driver_firstopen; 266 driver->open = radeon_driver_open; 267 driver->preclose = radeon_driver_preclose; 268 driver->postclose = radeon_driver_postclose; 269 driver->lastclose = radeon_driver_lastclose; 270 driver->vblank_wait = radeon_driver_vblank_wait; 271 driver->vblank_wait2 = radeon_driver_vblank_wait2; 272 driver->irq_preinstall = radeon_driver_irq_preinstall; 273 driver->irq_postinstall = radeon_driver_irq_postinstall; 274 driver->irq_uninstall = radeon_driver_irq_uninstall; 275 driver->irq_handler = radeon_driver_irq_handler; 276 driver->dma_ioctl = radeon_cp_buffers; 277 278 driver->driver_ioctls = radeon_ioctls; 279 driver->max_driver_ioctl = radeon_max_ioctl; 280 281 driver->driver_name = DRIVER_NAME; 282 driver->driver_desc = DRIVER_DESC; 283 driver->driver_date = DRIVER_DATE; 284 driver->driver_major = DRIVER_MAJOR; 285 driver->driver_minor = DRIVER_MINOR; 286 driver->driver_patchlevel = DRIVER_PATCHLEVEL; 287 288 driver->use_agp = 1; 289 driver->use_mtrr = 1; 290 driver->use_pci_dma = 1; 291 driver->use_sg = 1; 292 driver->use_dma = 1; 293 driver->use_irq = 1; 294 driver->use_vbl_irq = 1; 295 driver->use_vbl_irq2 = 1; 296 297 } /* radeon_configure() */ 298