1 /* $NetBSD: via_map.c,v 1.2 2018/08/27 04:58:37 riastradh Exp $ */ 2 3 /* 4 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. 5 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sub license, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 * DEALINGS IN THE SOFTWARE. 25 */ 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: via_map.c,v 1.2 2018/08/27 04:58:37 riastradh Exp $"); 28 29 #include <drm/drmP.h> 30 #include <drm/via_drm.h> 31 #include "via_drv.h" 32 33 static int via_do_init_map(struct drm_device *dev, drm_via_init_t *init) 34 { 35 drm_via_private_t *dev_priv = dev->dev_private; 36 37 DRM_DEBUG("\n"); 38 39 dev_priv->sarea = drm_legacy_getsarea(dev); 40 if (!dev_priv->sarea) { 41 DRM_ERROR("could not find sarea!\n"); 42 dev->dev_private = (void *)dev_priv; 43 via_do_cleanup_map(dev); 44 return -EINVAL; 45 } 46 47 dev_priv->fb = drm_legacy_findmap(dev, init->fb_offset); 48 if (!dev_priv->fb) { 49 DRM_ERROR("could not find framebuffer!\n"); 50 dev->dev_private = (void *)dev_priv; 51 via_do_cleanup_map(dev); 52 return -EINVAL; 53 } 54 dev_priv->mmio = drm_legacy_findmap(dev, init->mmio_offset); 55 if (!dev_priv->mmio) { 56 DRM_ERROR("could not find mmio region!\n"); 57 dev->dev_private = (void *)dev_priv; 58 via_do_cleanup_map(dev); 59 return -EINVAL; 60 } 61 62 dev_priv->sarea_priv = 63 (drm_via_sarea_t *) ((u8 *) dev_priv->sarea->handle + 64 init->sarea_priv_offset); 65 66 dev_priv->agpAddr = init->agpAddr; 67 68 via_init_futex(dev_priv); 69 70 via_init_dmablit(dev); 71 72 dev->dev_private = (void *)dev_priv; 73 return 0; 74 } 75 76 int via_do_cleanup_map(struct drm_device *dev) 77 { 78 via_dma_cleanup(dev); 79 80 return 0; 81 } 82 83 int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv) 84 { 85 drm_via_init_t *init = data; 86 87 DRM_DEBUG("\n"); 88 89 switch (init->func) { 90 case VIA_INIT_MAP: 91 return via_do_init_map(dev, init); 92 case VIA_CLEANUP_MAP: 93 return via_do_cleanup_map(dev); 94 } 95 96 return -EINVAL; 97 } 98 99 int via_driver_load(struct drm_device *dev, unsigned long chipset) 100 { 101 drm_via_private_t *dev_priv; 102 int ret = 0; 103 104 dev_priv = kzalloc(sizeof(drm_via_private_t), GFP_KERNEL); 105 if (dev_priv == NULL) 106 return -ENOMEM; 107 108 idr_init(&dev_priv->object_idr); 109 dev->dev_private = (void *)dev_priv; 110 111 dev_priv->chipset = chipset; 112 113 pci_set_master(dev->pdev); 114 115 ret = drm_vblank_init(dev, 1); 116 if (ret) { 117 kfree(dev_priv); 118 return ret; 119 } 120 121 return 0; 122 } 123 124 int via_driver_unload(struct drm_device *dev) 125 { 126 drm_via_private_t *dev_priv = dev->dev_private; 127 128 idr_destroy(&dev_priv->object_idr); 129 130 kfree(dev_priv); 131 132 return 0; 133 } 134