2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
7 * drm_memory.h -- Memory management wrappers for DRM -*- linux-c -*-
8 * Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
11 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
12 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
13 * Copyright (c) 2009, Intel Corporation.
14 * All Rights Reserved.
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
36 * Rickard E. (Rik) Faith <faith@valinux.com>
37 * Gareth Hughes <gareth@valinux.com>
43 /* Device memory access structure */
44 typedef struct drm_device_iomap
{
45 uint_t physical
; /* physical address */
46 uint_t size
; /* size of mapping */
47 uint_t drm_regnum
; /* register number */
48 caddr_t drm_base
; /* kernel virtual address */
49 ddi_acc_handle_t drm_handle
; /* data access handle */
64 drm_alloc(size_t size
, int area
)
66 return (kmem_zalloc(1 * size
, KM_NOSLEEP
));
71 drm_calloc(size_t nmemb
, size_t size
, int area
)
73 return (kmem_zalloc(size
* nmemb
, KM_NOSLEEP
));
78 drm_realloc(void *oldpt
, size_t oldsize
, size_t size
, int area
)
82 pt
= kmem_zalloc(1 * size
, KM_NOSLEEP
);
84 DRM_ERROR("pt is NULL strange");
87 if (oldpt
&& oldsize
) {
88 bcopy(pt
, oldpt
, oldsize
);
89 kmem_free(oldpt
, oldsize
);
96 drm_free(void *pt
, size_t size
, int area
)
103 drm_get_pci_index_reg(dev_info_t
*devi
, uint_t physical
, uint_t size
,
110 uint_t base
, regsize
;
114 if (ddi_dev_nregs(devi
, &n_reg
) == DDI_FAILURE
) {
115 DRM_ERROR("drm_get_pci_index_reg:ddi_dev_nregs failed\n");
120 if (ddi_getlongprop(DDI_DEV_T_ANY
, devi
, DDI_PROP_DONTPASS
,
121 "assigned-addresses", (caddr_t
)®s
, &length
) !=
123 DRM_ERROR("drm_get_pci_index_reg: ddi_getlongprop failed!\n");
127 for (i
= 0; i
< n_reg
; i
++) {
128 base
= (uint_t
)regs
[i
].pci_phys_low
;
129 regsize
= (uint_t
)regs
[i
].pci_size_low
;
130 if ((uint_t
)physical
>= base
&&
131 (uint_t
)physical
< (base
+ regsize
)) {
133 *off
= (off_t
)(physical
- base
);
138 kmem_free(regs
, (size_t)length
);
141 kmem_free(regs
, (size_t)length
);
145 /* data access attributes structure for register access */
146 static ddi_device_acc_attr_t dev_attr
= {
153 do_ioremap(dev_info_t
*devi
, drm_device_iomap_t
*iomap
)
159 regnum
= drm_get_pci_index_reg(devi
, iomap
->physical
,
160 iomap
->size
, &offset
);
162 DRM_ERROR("do_ioremap: can not find regster entry,"
163 " start=0x%x, size=0x%x", iomap
->physical
, iomap
->size
);
167 iomap
->drm_regnum
= regnum
;
169 ret
= ddi_regs_map_setup(devi
, iomap
->drm_regnum
,
170 (caddr_t
*)&(iomap
->drm_base
), (offset_t
)offset
,
171 (offset_t
)iomap
->size
, &dev_attr
, &iomap
->drm_handle
);
173 DRM_ERROR("do_ioremap: failed to map regs: regno=%d,"
174 " offset=0x%x", regnum
, offset
);
175 iomap
->drm_handle
= NULL
;
183 drm_ioremap(drm_device_t
*softstate
, drm_local_map_t
*map
)
185 drm_device_iomap_t iomap
;
188 DRM_DEBUG("drm_ioremap called\n");
190 bzero(&iomap
, sizeof (drm_device_iomap_t
));
191 iomap
.physical
= map
->offset
;
192 iomap
.size
= map
->size
;
193 ret
= do_ioremap(softstate
->dip
, &iomap
);
196 DRM_ERROR("drm_ioremap: failed, physaddr=0x%x, size=0x%x",
197 map
->offset
, map
->size
);
201 /* ddi_acc_handle_t */
202 map
->dev_handle
= iomap
.drm_handle
;
203 map
->handle
= (void *)iomap
.drm_base
;
204 map
->dev_addr
= iomap
.drm_base
;
207 "map->handle is %p map->dev_addr is %lx map->size %x",
208 (void *)map
->handle
, (unsigned long)map
->dev_addr
, map
->size
);
214 drm_ioremapfree(drm_local_map_t
*map
)
216 if (map
->dev_handle
== NULL
) {
217 DRM_ERROR("drm_ioremapfree: handle is NULL");
220 ddi_regs_map_free(&map
->dev_handle
);