2 * Copyright 2005 Stephane Marchesin
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
27 #include "drm_sarea.h"
28 #include "nouveau_drv.h"
30 /* here a client dies, release the stuff that was allocated for its filp */
31 void nouveau_preclose(drm_device_t * dev, DRMFILE filp)
33 drm_nouveau_private_t *dev_priv = dev->dev_private;
35 nouveau_mem_release(filp,dev_priv->fb_heap);
36 nouveau_mem_release(filp,dev_priv->agp_heap);
37 nouveau_object_cleanup(dev, filp);
38 nouveau_fifo_cleanup(dev, filp);
41 /* first module load, setup the mmio/fb mapping */
42 int nouveau_firstopen(struct drm_device *dev)
45 drm_nouveau_private_t *dev_priv = dev->dev_private;
47 /* resource 0 is mmio regs */
48 /* resource 1 is linear FB */
49 /* resource 2 is RAMIN (mmio regs + 0x1000000) */
50 /* resource 6 is bios */
52 /* map the mmio regs */
53 ret = drm_addmap(dev, drm_get_resource_start(dev, 0), drm_get_resource_len(dev, 0),
54 _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio);
57 DRM_INFO("regs mapped ok at 0x%lx\n",dev_priv->mmio->offset);
61 DRM_ERROR("Unable to initialize the mmio mapping. Please report your setup to " DRIVER_EMAIL "\n");
65 DRM_INFO("%lld MB of video ram detected\n",nouveau_mem_fb_amount(dev)>>20);
67 /* map larger RAMIN aperture on NV40 cards */
68 if (dev_priv->card_type >= NV_40) {
69 int ramin_resource = 2;
70 if (drm_get_resource_len(dev, ramin_resource) == 0)
73 ret = drm_addmap(dev, drm_get_resource_start(dev, ramin_resource),
74 drm_get_resource_len(dev, ramin_resource),
79 DRM_ERROR("Failed to init RAMIN mapping, "
80 "limited instance memory available\n");
81 dev_priv->ramin = NULL;
84 dev_priv->ramin = NULL;
87 * Determine locations for RAMHT/FC/RO
90 ret = nouveau_fifo_init(dev);
93 /* setup a mtrr over the FB */
94 dev_priv->fb_mtrr=drm_mtrr_add(drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC);
96 /* FIXME: doesn't belong here, and have no idea what it's for.. */
97 if (dev_priv->card_type >= NV_40)
99 else if (dev_priv->card_type >= NV_30) {
101 else if (dev_priv->card_type >= NV_20)
102 nv20_graph_init(dev);
103 else if (dev_priv->card_type >= NV_10)
104 nv10_graph_init(dev);
109 int nouveau_load(struct drm_device *dev, unsigned long flags)
111 drm_nouveau_private_t *dev_priv;
113 if (flags==NV_UNKNOWN)
114 return DRM_ERR(EINVAL);
116 dev_priv = drm_alloc(sizeof(drm_nouveau_private_t), DRM_MEM_DRIVER);
118 return DRM_ERR(ENOMEM);
120 memset(dev_priv, 0, sizeof(drm_nouveau_private_t));
121 dev_priv->card_type=flags&NOUVEAU_FAMILY;
122 dev_priv->flags=flags&NOUVEAU_FLAGS;
124 dev->dev_private = (void *)dev_priv;
129 void nouveau_lastclose(struct drm_device *dev)
131 drm_nouveau_private_t *dev_priv = dev->dev_private;
132 if(dev_priv->fb_mtrr>0)
134 drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC);
139 int nouveau_unload(struct drm_device *dev)
141 drm_free(dev->dev_private, sizeof(*dev->dev_private), DRM_MEM_DRIVER);
142 dev->dev_private = NULL;
146 int nouveau_ioctl_getparam(DRM_IOCTL_ARGS)
149 drm_nouveau_private_t *dev_priv = dev->dev_private;
150 drm_nouveau_getparam_t getparam;
152 DRM_COPY_FROM_USER_IOCTL(getparam, (drm_nouveau_getparam_t __user *)data,
155 switch (getparam.param) {
156 case NOUVEAU_GETPARAM_PCI_VENDOR:
157 getparam.value=dev->pci_vendor;
159 case NOUVEAU_GETPARAM_PCI_DEVICE:
160 getparam.value=dev->pci_device;
162 case NOUVEAU_GETPARAM_BUS_TYPE:
163 if (drm_device_is_agp(dev))
164 getparam.value=NV_AGP;
165 else if (drm_device_is_pcie(dev))
166 getparam.value=NV_PCIE;
168 getparam.value=NV_PCI;
170 case NOUVEAU_GETPARAM_FB_PHYSICAL:
171 getparam.value=dev_priv->fb_phys;
173 case NOUVEAU_GETPARAM_AGP_PHYSICAL:
174 getparam.value=dev_priv->agp_phys;
177 DRM_ERROR("unknown parameter %d\n", getparam.param);
178 return DRM_ERR(EINVAL);
181 DRM_COPY_TO_USER_IOCTL((drm_nouveau_getparam_t __user *)data, getparam,
186 int nouveau_ioctl_setparam(DRM_IOCTL_ARGS)
189 drm_nouveau_private_t *dev_priv = dev->dev_private;
190 drm_nouveau_setparam_t setparam;
192 DRM_COPY_FROM_USER_IOCTL(setparam, (drm_nouveau_setparam_t __user *)data,
195 switch (setparam.param) {
196 case NOUVEAU_SETPARAM_CMDBUF_LOCATION:
197 switch (setparam.value) {
198 case NOUVEAU_MEM_AGP:
202 DRM_ERROR("invalid CMDBUF_LOCATION value=%d\n", setparam.value);
203 return DRM_ERR(EINVAL);
205 dev_priv->config.cmdbuf.location = setparam.value;
207 case NOUVEAU_SETPARAM_CMDBUF_SIZE:
208 dev_priv->config.cmdbuf.size = setparam.value;
211 DRM_ERROR("unknown parameter %d\n", setparam.param);
212 return DRM_ERR(EINVAL);
219 void nouveau_wait_for_idle(struct drm_device *dev)
221 drm_nouveau_private_t *dev_priv=dev->dev_private;
222 switch(dev_priv->card_type)
225 while(NV_READ(NV03_PGRAPH_STATUS));
228 while(NV_READ(NV04_PGRAPH_STATUS));