Remove viadrm(4), superseded by viadrmums.

Aside from viadrm using older drm code, it's also dysfunctional right now.
See PR port-i386/53364.
This commit is contained in:
maya 2018-07-10 17:01:42 +00:00
parent 305c0f0c67
commit 952ab4fc36
34 changed files with 23 additions and 6449 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1595 2018/06/29 12:34:14 roy Exp $
# $NetBSD: mi,v 1.1596 2018/07/10 17:01:42 maya Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -1959,7 +1959,7 @@
./usr/share/man/cat4/verifiedexec.0 man-obsolete obsolete
./usr/share/man/cat4/vga.0 man-sys-catman .cat
./usr/share/man/cat4/vge.0 man-sys-catman .cat
./usr/share/man/cat4/viadrm.0 man-sys-catman .cat
./usr/share/man/cat4/viadrm.0 man-obsolete obsolete
./usr/share/man/cat4/viaenv.0 man-sys-catman .cat
./usr/share/man/cat4/viaide.0 man-sys-catman .cat
./usr/share/man/cat4/viapm.0 man-obsolete obsolete
@ -5026,7 +5026,7 @@
./usr/share/man/html4/veriexec.html man-sys-htmlman html
./usr/share/man/html4/vga.html man-sys-htmlman html
./usr/share/man/html4/vge.html man-sys-htmlman html
./usr/share/man/html4/viadrm.html man-sys-htmlman html
./usr/share/man/html4/viadrm.html man-obsolete obsolete
./usr/share/man/html4/viaenv.html man-sys-htmlman html
./usr/share/man/html4/viaide.html man-sys-htmlman html
./usr/share/man/html4/video.html man-sys-htmlman html
@ -8021,7 +8021,7 @@
./usr/share/man/man4/verifiedexec.4 man-obsolete obsolete
./usr/share/man/man4/vga.4 man-sys-man .man
./usr/share/man/man4/vge.4 man-sys-man .man
./usr/share/man/man4/viadrm.4 man-sys-man .man
./usr/share/man/man4/viadrm.4 man-obsolete obsolete
./usr/share/man/man4/viaenv.4 man-sys-man .man
./usr/share/man/man4/viaide.4 man-sys-man .man
./usr/share/man/man4/viapm.4 man-obsolete obsolete

View File

@ -1,4 +1,4 @@
# $NetBSD: md.i386,v 1.78 2018/02/26 07:30:17 pgoyette Exp $
# $NetBSD: md.i386,v 1.79 2018/07/10 17:01:42 maya Exp $
#
# NOTE that there are three sets of files here:
# @MODULEDIR@, i386-xen, and i386pae-xen
@ -182,8 +182,8 @@
./@MODULEDIR@/ubsec/ubsec.kmod base-kernel-modules kmod
./@MODULEDIR@/viac7temp base-kernel-modules kmod
./@MODULEDIR@/viac7temp/viac7temp.kmod base-kernel-modules kmod
./@MODULEDIR@/viadrm base-kernel-modules kmod
./@MODULEDIR@/viadrm/viadrm.kmod base-kernel-modules kmod
./@MODULEDIR@/viadrm base-obsolete obsolete
./@MODULEDIR@/viadrm/viadrm.kmod base-obsolete obsolete
./@MODULEDIR@/viadrmums base-kernel-modules kmod
./@MODULEDIR@/viadrmums/viadrmums.kmod base-kernel-modules kmod
./@MODULEDIR@/vmt base-kernel-modules kmod

View File

@ -1,4 +1,4 @@
# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.2406 $>
# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.2407 $>
#
#
# [Note: This file does not mention every change made to the NetBSD source tree.
@ -169,3 +169,4 @@ Changes from NetBSD 8.0 to NetBSD 9.0:
[msaitoh 20180626]
gcc: add lsan the Leak Sanitizer [christos 20180626]
aarch64: Add support for SMP. [ryo 20180709]
viadrm(4): Removed, superseded by viadrmums. [maya 20180710]

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.656 2018/06/13 03:28:36 ozaki-r Exp $
# $NetBSD: Makefile,v 1.657 2018/07/10 17:01:43 maya Exp $
# @(#)Makefile 8.1 (Berkeley) 6/18/93
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
@ -177,7 +177,6 @@ MLINKS+=drm.4 radeondrm.4
MLINKS+=drm.4 savagedrm.4
MLINKS+=drm.4 sisdrm.4
MLINKS+=drm.4 tdfxdrm.4
MLINKS+=drm.4 viadrm.4
MLINKS+=acpiec.4 acpiecdt.4
MLINKS+=acpivga.4 acpiout.4

View File

@ -1,4 +1,4 @@
.\" $NetBSD: drm.4,v 1.15 2013/06/04 07:47:54 wiz Exp $
.\" $NetBSD: drm.4,v 1.16 2018/07/10 17:01:43 maya Exp $
.\"
.\" Copyright (c) 2007, 2013 Thomas Klausner
.\" All rights reserved.
@ -23,7 +23,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd June 4, 2013
.Dd July 10, 2018
.Dt DRM 4
.Os
.Sh NAME
@ -38,7 +38,6 @@
.Cd savagedrm* at drm?
.Cd sisdrm* at drm?
.Cd tdfxdrm* at drm?
.Cd viadrm* at drm?
.Pp
.Cd options DRM_DEBUG
.Cd options DRM_NO_AGP

View File

@ -1,4 +1,4 @@
# $NetBSD: ALL,v 1.90 2018/06/16 15:04:29 jdolecek Exp $
# $NetBSD: ALL,v 1.91 2018/07/10 17:01:43 maya Exp $
# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
#
# ALL machine description file
@ -17,7 +17,7 @@ include "arch/amd64/conf/std.amd64"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "ALL-$Revision: 1.90 $"
#ident "ALL-$Revision: 1.91 $"
maxusers 64 # estimated number of users
@ -511,7 +511,6 @@ wcfb* at pci? dev ? function ?
#sisdrm* at drm? # SiS DRM driver
#tdfxdrm* at drm? # 3dfx (voodoo) DRM driver
#vboxdrm* at drm? # VirtualBox DRM driver
#viadrm* at drm? # VIA UniChrome DRM driver
# DRMKMS drivers
i915drmkms* at pci? dev ? function ?

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.493 2018/06/07 13:36:28 thorpej Exp $
# $NetBSD: GENERIC,v 1.494 2018/07/10 17:01:43 maya Exp $
#
# GENERIC machine description file
#
@ -22,7 +22,7 @@ include "arch/amd64/conf/std.amd64"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC-$Revision: 1.493 $"
#ident "GENERIC-$Revision: 1.494 $"
maxusers 64 # estimated number of users
@ -418,7 +418,6 @@ sysbeep0 at pcppi?
#savagedrm* at drm? # S3 Savage DRM driver
#sisdrm* at drm? # SiS DRM driver
#tdfxdrm* at drm? # 3dfx (voodoo) DRM driver
#viadrm* at drm? # VIA DRM driver
# DRMKMS drivers
i915drmkms* at pci? dev ? function ?

View File

@ -1,4 +1,4 @@
# $NetBSD: ALL,v 1.440 2018/06/07 13:36:29 thorpej Exp $
# $NetBSD: ALL,v 1.441 2018/07/10 17:01:43 maya Exp $
# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
#
# ALL machine description file
@ -17,7 +17,7 @@ include "arch/i386/conf/std.i386"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "ALL-$Revision: 1.440 $"
#ident "ALL-$Revision: 1.441 $"
maxusers 64 # estimated number of users
@ -595,7 +595,6 @@ wsdisplay* at wsemuldisplaydev?
#sisdrm* at drm? # SiS DRM driver
#tdfxdrm* at drm? # 3dfx (voodoo) DRM driver
#vboxdrm* at drm? # VirtualBox DRM driver
#viadrm* at drm? # VIA UniChrome DRM driver
# DRMKMS drivers
i915drmkms* at pci? dev ? function ?

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.1180 2018/06/07 13:36:29 thorpej Exp $
# $NetBSD: GENERIC,v 1.1181 2018/07/10 17:01:43 maya Exp $
#
# GENERIC machine description file
#
@ -22,7 +22,7 @@ include "arch/i386/conf/std.i386"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC-$Revision: 1.1180 $"
#ident "GENERIC-$Revision: 1.1181 $"
maxusers 64 # estimated number of users
@ -558,7 +558,6 @@ sysbeep0 at pcppi?
#savagedrm* at drm? # S3 Savage DRM driver
#sisdrm* at drm? # SiS DRM driver
#tdfxdrm* at drm? # 3dfx (voodoo) DRM driver
#viadrm* at drm? # VIA DRM driver
# DRMKMS drivers
i915drmkms* at pci? dev ? function ?

View File

@ -1,4 +1,4 @@
# $NetBSD: files.drm,v 1.7 2011/03/27 08:45:11 mlelstv Exp $
# $NetBSD: files.drm,v 1.8 2018/07/10 17:01:43 maya Exp $
# direct rendering modules
define drmbase
@ -117,15 +117,3 @@ file external/bsd/drm/dist/shared-core/sis_mm.c sisdrm
device tdfxdrm: drmbase, drmpci
attach tdfxdrm at drm
file external/bsd/drm/dist/bsd-core/tdfx_drv.c tdfxdrm
device viadrm: drmbase, drmpci
attach viadrm at drm
file external/bsd/drm/dist/bsd-core/via_drv.c viadrm
file external/bsd/drm/dist/bsd-core/via_dmablit.c viadrm
file external/bsd/drm/dist/shared-core/via_dma.c viadrm
file external/bsd/drm/dist/shared-core/via_ds.c viadrm
file external/bsd/drm/dist/shared-core/via_irq.c viadrm
file external/bsd/drm/dist/shared-core/via_map.c viadrm
file external/bsd/drm/dist/shared-core/via_mm.c viadrm
file external/bsd/drm/dist/shared-core/via_verifier.c viadrm
file external/bsd/drm/dist/shared-core/via_video.c viadrm

View File

@ -500,19 +500,6 @@
{0x121a, 0x000b, 0, "3dfx Voodoo4 4200"}, \
{0, 0, 0, NULL}
#define viadrv_PCI_IDS \
{0x1106, 0x3022, 0, "VIA CLE266 3022"}, \
{0x1106, 0x3118, VIA_PRO_GROUP_A, "VIA CN400 / PM8X0"}, \
{0x1106, 0x3122, 0, "VIA CLE266"}, \
{0x1106, 0x7205, 0, "VIA KM400"}, \
{0x1106, 0x3108, 0, "VIA K8M800"}, \
{0x1106, 0x3344, 0, "VIA CN700 / VM800 / P4M800Pro"}, \
{0x1106, 0x3343, 0, "VIA P4M890"}, \
{0x1106, 0x3230, VIA_DX9_0, "VIA K8M890"}, \
{0x1106, 0x3157, VIA_PRO_GROUP_A, "VIA CX700"}, \
{0x1106, 0x3371, VIA_DX9_0, "VIA P4M900 / VN896"}, \
{0, 0, 0, NULL}
#define i810_PCI_IDS \
{0x8086, 0x7121, 0, "Intel i810 GMCH"}, \
{0x8086, 0x7123, 0, "Intel i810-DC100 GMCH"}, \

View File

@ -1,24 +0,0 @@
# $FreeBSD$
.PATH: ${.CURDIR}/..
KMOD = via
NO_MAN = YES
SRCS = via_dma.c via_drv.c via_ds.c via_irq.c via_map.c via_mm.c \
via_verifier.c via_video.c
SRCS += device_if.h bus_if.h pci_if.h opt_drm.h
CFLAGS += ${DEBUG_FLAGS} -I. -I..
.if defined(DRM_DEBUG)
DRM_DEBUG_OPT= "\#define DRM_DEBUG 1"
.endif
.if !defined(DRM_NOLINUX)
DRM_LINUX_OPT= "\#define DRM_LINUX 1"
.endif
opt_drm.h:
touch opt_drm.h
echo $(DRM_DEBUG_OPT) >> opt_drm.h
echo $(DRM_LINUX_OPT) >> opt_drm.h
.include <bsd.kmod.mk>

View File

@ -1,794 +0,0 @@
/* via_dmablit.c -- PCI DMA BitBlt support for the VIA Unichrome/Pro
*
* Copyright (C) 2005 Thomas Hellstrom, All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Thomas Hellstrom.
* Partially based on code obtained from Digeo Inc.
*/
/* $FreeBSD: src/sys/dev/drm/via_dmablit.c,v 1.6 2010/12/25 21:26:56 alc Exp $ */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: via_dmablit.c,v 1.2 2013/10/17 21:15:18 christos Exp $");
/*
* Unmaps the DMA mappings.
* FIXME: Is this a NoOp on x86? Also
* FIXME: What happens if this one is called and a pending blit has previously done
* the same DMA mappings?
*/
#include "drmP.h"
#include "via_drm.h"
#include "via_drv.h"
#include "via_dmablit.h"
#define VIA_PGDN(x) (((unsigned long)(x)) & ~PAGE_MASK)
#define VIA_PGOFF(x) (((unsigned long)(x)) & PAGE_MASK)
#define VIA_PFN(x) ((unsigned long)(x) >> PAGE_SHIFT)
typedef struct _drm_via_descriptor {
uint32_t mem_addr;
uint32_t dev_addr;
uint32_t size;
uint32_t next;
} drm_via_descriptor_t;
static void via_dmablit_timer(void *arg);
/*
* Unmap a DMA mapping.
*/
static void
via_unmap_blit_from_device(drm_via_sg_info_t *vsg)
{
int num_desc = vsg->num_desc;
unsigned cur_descriptor_page = num_desc / vsg->descriptors_per_page;
unsigned descriptor_this_page = num_desc % vsg->descriptors_per_page;
drm_via_descriptor_t *desc_ptr = vsg->desc_pages[cur_descriptor_page] +
descriptor_this_page;
while(num_desc--) {
if (descriptor_this_page-- == 0) {
cur_descriptor_page--;
descriptor_this_page = vsg->descriptors_per_page - 1;
desc_ptr = vsg->desc_pages[cur_descriptor_page] +
descriptor_this_page;
}
desc_ptr--;
}
}
/*
* If mode = 0, count how many descriptors are needed.
* If mode = 1, Map the DMA pages for the device, put together and map also the descriptors.
* Descriptors are run in reverse order by the hardware because we are not allowed to update the
* 'next' field without syncing calls when the descriptor is already mapped.
*/
static void
via_map_blit_for_device(const drm_via_dmablit_t *xfer,
drm_via_sg_info_t *vsg, int mode)
{
unsigned cur_descriptor_page = 0;
unsigned num_descriptors_this_page = 0;
unsigned char *mem_addr = xfer->mem_addr;
unsigned char *cur_mem;
unsigned char *first_addr = (unsigned char *)VIA_PGDN(mem_addr);
uint32_t fb_addr = xfer->fb_addr;
uint32_t cur_fb;
unsigned long line_len;
unsigned remaining_len;
int num_desc = 0;
int cur_line;
dma_addr_t next = 0 | VIA_DMA_DPR_EC;
drm_via_descriptor_t *desc_ptr = NULL;
if (mode == 1)
desc_ptr = vsg->desc_pages[cur_descriptor_page];
for (cur_line = 0; cur_line < xfer->num_lines; ++cur_line) {
line_len = xfer->line_length;
cur_fb = fb_addr;
cur_mem = mem_addr;
while (line_len > 0) {
remaining_len = min(PAGE_SIZE - VIA_PGOFF(cur_mem),
line_len);
line_len -= remaining_len;
if (mode == 1) {
desc_ptr->mem_addr =
VM_PAGE_TO_PHYS(
vsg->pages[VIA_PFN(cur_mem) -
VIA_PFN(first_addr)]) + VIA_PGOFF(cur_mem);
desc_ptr->dev_addr = cur_fb;
desc_ptr->size = remaining_len;
desc_ptr->next = (uint32_t) next;
next = vtophys((vaddr_t)desc_ptr);
desc_ptr++;
if (++num_descriptors_this_page >= vsg->descriptors_per_page) {
num_descriptors_this_page = 0;
desc_ptr = vsg->desc_pages[++cur_descriptor_page];
}
}
num_desc++;
cur_mem += remaining_len;
cur_fb += remaining_len;
}
mem_addr += xfer->mem_stride;
fb_addr += xfer->fb_stride;
}
if (mode == 1) {
vsg->chain_start = next;
vsg->state = dr_via_device_mapped;
}
vsg->num_desc = num_desc;
}
/*
* Function that frees up all resources for a blit. It is usable even if the
* blit info has only been partially built as long as the status enum is consistent
* with the actual status of the used resources.
*/
static void
via_free_sg_info(drm_via_sg_info_t *vsg)
{
int i;
switch(vsg->state) {
case dr_via_device_mapped:
via_unmap_blit_from_device(vsg);
case dr_via_desc_pages_alloc:
for (i=0; i<vsg->num_desc_pages; ++i) {
if (vsg->desc_pages[i] != NULL)
free(vsg->desc_pages[i], DRM_MEM_PAGES);
}
free(vsg->desc_pages, DRM_MEM_DRIVER);
case dr_via_pages_locked:
uvm_vsunlock(vsg->vmspace, vsg->mem_addr,
vsg->num_pages * PAGE_SIZE);
case dr_via_pages_alloc:
if (vsg->pages)
free(vsg->pages, DRM_MEM_DRIVER);
default:
vsg->state = dr_via_sg_init;
}
if (vsg->bounce_buffer)
free(vsg->bounce_buffer, DRM_MEM_DRIVER);
vsg->bounce_buffer = NULL;
vsg->free_on_sequence = 0;
}
/*
* Fire a blit engine.
*/
static void
via_fire_dmablit(struct drm_device *dev, drm_via_sg_info_t *vsg, int engine)
{
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
VIA_WRITE(VIA_PCI_DMA_MAR0 + engine*0x10, 0);
VIA_WRITE(VIA_PCI_DMA_DAR0 + engine*0x10, 0);
VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DD | VIA_DMA_CSR_TD |
VIA_DMA_CSR_DE);
VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE);
VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0);
VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start);
DRM_WRITEMEMORYBARRIER();
VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS);
VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04);
}
/*
* Obtain a page pointer array and lock all pages into system memory. A segmentation violation will
* occur here if the calling user does not have access to the submitted address.
*/
static int
via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
{
unsigned long first_pfn = VIA_PFN(xfer->mem_addr);
paddr_t pa;
int i;
vsg->num_pages = VIA_PFN(xfer->mem_addr +
(xfer->num_lines * xfer->mem_stride -1)) - first_pfn + 1;
if (NULL == (vsg->pages = malloc(sizeof(vm_page_t) * vsg->num_pages,
DRM_MEM_DRIVER, M_NOWAIT|M_ZERO)))
return -ENOMEM;
vsg->state = dr_via_pages_alloc;
vsg->mem_addr = xfer->mem_addr;
vsg->vmspace = curproc->p_vmspace;
if (uvm_vslock(curproc->p_vmspace, xfer->mem_addr,
vsg->num_pages * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE) != 0)
return -EACCES;
for (i = 0; i < vsg->num_pages; i++) {
pmap_extract(vm_map_pmap(&curproc->p_vmspace->vm_map),
(vaddr_t)xfer->mem_addr + (i * PAGE_SIZE), &pa);
vsg->pages[i] = PHYS_TO_VM_PAGE(pa);
if (vsg->pages[i] == NULL)
break;
}
vsg->state = dr_via_pages_locked;
if (i != vsg->num_pages)
return -EINVAL;
DRM_DEBUG("DMA pages locked\n");
return 0;
}
/*
* Allocate DMA capable memory for the blit descriptor chain, and an array that keeps track of the
* pages we allocate. We don't want to use kmalloc for the descriptor chain because it may be
* quite large for some blits, and pages don't need to be contingous.
*/
static int
via_alloc_desc_pages(drm_via_sg_info_t *vsg)
{
int i;
vsg->descriptors_per_page = PAGE_SIZE / sizeof(drm_via_descriptor_t);
vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) /
vsg->descriptors_per_page;
if (NULL == (vsg->desc_pages = malloc(vsg->num_desc_pages *
sizeof(void *), DRM_MEM_DRIVER, M_NOWAIT | M_ZERO)))
return -ENOMEM;
vsg->state = dr_via_desc_pages_alloc;
for (i = 0; i < vsg->num_desc_pages; ++i) {
if (NULL == (vsg->desc_pages[i] =
(drm_via_descriptor_t *)malloc(PAGE_SIZE, DRM_MEM_PAGES,
M_NOWAIT | M_ZERO)))
return -ENOMEM;
}
DRM_DEBUG("Allocated %d pages for %d descriptors.\n",
vsg->num_desc_pages, vsg->num_desc);
return 0;
}
static void
via_abort_dmablit(struct drm_device *dev, int engine)
{
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TA);
}
static void
via_dmablit_engine_off(struct drm_device *dev, int engine)
{
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD | VIA_DMA_CSR_DD);
}
/*
* The dmablit part of the IRQ handler. Trying to do only reasonably fast things here.
* The rest, like unmapping and freeing memory for done blits is done in a separate workqueue
* task. Basically the task of the interrupt handler is to submit a new blit to the engine, while
* the workqueue task takes care of processing associated with the old blit.
*/
void
via_dmablit_handler(struct drm_device *dev, int engine, int from_irq)
{
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
drm_via_blitq_t *blitq = dev_priv->blit_queues + engine;
int cur;
int done_transfer;
uint32_t status = 0;
DRM_DEBUG("DMA blit handler called. engine = %d, from_irq = %d, blitq = 0x%lx\n",
engine, from_irq, (unsigned long) blitq);
mutex_enter(&blitq->blit_lock);
done_transfer = blitq->is_active &&
(( status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD);
done_transfer = done_transfer || ( blitq->aborting && !(status & VIA_DMA_CSR_DE));
cur = blitq->cur;
if (done_transfer) {
blitq->blits[cur]->aborted = blitq->aborting;
blitq->done_blit_handle++;
DRM_WAKEUP(&blitq->blit_queue[cur]);
cur++;
if (cur >= VIA_NUM_BLIT_SLOTS)
cur = 0;
blitq->cur = cur;
/*
* Clear transfer done flag.
*/
VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD);
blitq->is_active = 0;
blitq->aborting = 0;
workqueue_enqueue(blitq->wq, &blitq->work, NULL);
} else if (blitq->is_active && (hardclock_ticks >= blitq->end)) {
/*
* Abort transfer after one second.
*/
via_abort_dmablit(dev, engine);
blitq->aborting = 1;
blitq->end = hardclock_ticks + DRM_HZ;
}
if (!blitq->is_active) {
if (blitq->num_outstanding) {
via_fire_dmablit(dev, blitq->blits[cur], engine);
blitq->is_active = 1;
blitq->cur = cur;
blitq->num_outstanding--;
blitq->end = hardclock_ticks + DRM_HZ;
if (!callout_pending(&blitq->poll_timer))
callout_reset(&blitq->poll_timer,
1, via_dmablit_timer,
(void *)blitq);
} else {
if (callout_pending(&blitq->poll_timer)) {
callout_stop(&blitq->poll_timer);
}
via_dmablit_engine_off(dev, engine);
}
}
mutex_exit(&blitq->blit_lock);
}
/*
* Check whether this blit is still active, performing necessary locking.
*/
static int
via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, wait_queue_head_t **queue)
{
uint32_t slot;
int active;
mutex_enter(&blitq->blit_lock);
/*
* Allow for handle wraparounds.
*/
active = ((blitq->done_blit_handle - handle) > (1 << 23)) &&
((blitq->cur_blit_handle - handle) <= (1 << 23));
if (queue && active) {
slot = handle - blitq->done_blit_handle + blitq->cur -1;
if (slot >= VIA_NUM_BLIT_SLOTS) {
slot -= VIA_NUM_BLIT_SLOTS;
}
*queue = blitq->blit_queue + slot;
}
mutex_exit(&blitq->blit_lock);
return active;
}
/*
* Sync. Wait for at least three seconds for the blit to be performed.
*/
static int
via_dmablit_sync(struct drm_device *dev, uint32_t handle, int engine)
{
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
drm_via_blitq_t *blitq = dev_priv->blit_queues + engine;
wait_queue_head_t *queue;
int ret = 0;
if (via_dmablit_active(blitq, engine, handle, &queue)) {
DRM_WAIT_ON(ret, *queue, 3 * DRM_HZ,
!via_dmablit_active(blitq, engine, handle, NULL));
}
DRM_DEBUG("DMA blit sync handle 0x%x engine %d returned %d\n",
handle, engine, ret);
return ret;
}
/*
* A timer that regularly polls the blit engine in cases where we don't have interrupts:
* a) Broken hardware (typically those that don't have any video capture facility).
* b) Blit abort. The hardware doesn't send an interrupt when a blit is aborted.
* The timer and hardware IRQ's can and do work in parallel. If the hardware has
* irqs, it will shorten the latency somewhat.
*/
static void
via_dmablit_timer(void *arg)
{
drm_via_blitq_t *blitq = (drm_via_blitq_t *)arg;
struct drm_device *dev = blitq->dev;
int engine = (int)
(blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues);
DRM_DEBUG("Polling timer called for engine %d, jiffies %lu\n", engine,
(unsigned long) jiffies);
via_dmablit_handler(dev, engine, 0);
if (!callout_pending(&blitq->poll_timer)) {
callout_schedule(&blitq->poll_timer, 1);
/*
* Rerun handler to delete timer if engines are off, and
* to shorten abort latency. This is a little nasty.
*/
via_dmablit_handler(dev, engine, 0);
}
}
/*
* Workqueue task that frees data and mappings associated with a blit.
* Also wakes up waiting processes. Each of these tasks handles one
* blit engine only and may not be called on each interrupt.
*/
static void
via_dmablit_workqueue(struct work *wk, void *arg)
{
drm_via_blitq_t *blitq = (drm_via_blitq_t *)arg;
struct drm_device *dev = blitq->dev;
drm_via_sg_info_t *cur_sg;
int cur_released;
DRM_DEBUG("task called for blit engine %ld\n",(unsigned long)
(blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues));
mutex_enter(&blitq->blit_lock);
while(blitq->serviced != blitq->cur) {
cur_released = blitq->serviced++;
DRM_DEBUG("Releasing blit slot %d\n", cur_released);
if (blitq->serviced >= VIA_NUM_BLIT_SLOTS)
blitq->serviced = 0;
cur_sg = blitq->blits[cur_released];
blitq->num_free++;
mutex_exit(&blitq->blit_lock);
DRM_WAKEUP(&blitq->busy_queue);
via_free_sg_info(cur_sg);
free(cur_sg, DRM_MEM_DRIVER);
mutex_enter(&blitq->blit_lock);
}
mutex_exit(&blitq->blit_lock);
}
/*
* Init all blit engines. Currently we use two, but some hardware have 4.
*/
void
via_init_dmablit(struct drm_device *dev)
{
int i,j;
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
drm_via_blitq_t *blitq;
for (i=0; i< VIA_NUM_BLIT_ENGINES; ++i) {
blitq = dev_priv->blit_queues + i;
blitq->dev = dev;
blitq->cur_blit_handle = 0;
blitq->done_blit_handle = 0;
blitq->head = 0;
blitq->cur = 0;
blitq->serviced = 0;
blitq->num_free = VIA_NUM_BLIT_SLOTS - 1;
blitq->num_outstanding = 0;
blitq->is_active = 0;
blitq->aborting = 0;
mutex_init(&blitq->blit_lock, MUTEX_DEFAULT, IPL_NONE);
for (j=0; j<VIA_NUM_BLIT_SLOTS; ++j) {
DRM_INIT_WAITQUEUE(blitq->blit_queue + j);
}
DRM_INIT_WAITQUEUE(&blitq->busy_queue);
workqueue_create(&blitq->wq, "viadmablit",
via_dmablit_workqueue, blitq, PRI_KTHREAD, IPL_NONE,
WQ_MPSAFE);
callout_init(&blitq->poll_timer, 0);
}
}
/*
* Build all info and do all mappings required for a blit.
*/
static int
via_build_sg_info(struct drm_device *dev, drm_via_sg_info_t *vsg,
drm_via_dmablit_t *xfer)
{
int ret = 0;
vsg->bounce_buffer = NULL;
vsg->state = dr_via_sg_init;
if (xfer->num_lines <= 0 || xfer->line_length <= 0) {
DRM_ERROR("Zero size bitblt.\n");
return -EINVAL;
}
/*
* Below check is a driver limitation, not a hardware one. We
* don't want to lock unused pages, and don't want to incoporate the
* extra logic of avoiding them. Make sure there are no.
* (Not a big limitation anyway.)
*/
if ((xfer->mem_stride - xfer->line_length) > 2 * PAGE_SIZE) {
DRM_ERROR("Too large system memory stride. Stride: %d, "
"Length: %d\n", xfer->mem_stride, xfer->line_length);
return -EINVAL;
}
if ((xfer->mem_stride == xfer->line_length) &&
(xfer->fb_stride == xfer->line_length)) {
xfer->mem_stride *= xfer->num_lines;
xfer->line_length = xfer->mem_stride;
xfer->fb_stride = xfer->mem_stride;
xfer->num_lines = 1;
}
/*
* Don't lock an arbitrary large number of pages, since that causes a
* DOS security hole.
*/
if (xfer->num_lines > 2048 ||
(xfer->num_lines*xfer->mem_stride > (2048*2048*4))) {
DRM_ERROR("Too large PCI DMA bitblt.\n");
return -EINVAL;
}
/*
* we allow a negative fb stride to allow flipping of images in
* transfer.
*/
if (xfer->mem_stride < xfer->line_length ||
abs(xfer->fb_stride) < xfer->line_length) {
DRM_ERROR("Invalid frame-buffer / memory stride.\n");
return -EINVAL;
}
/*
* A hardware bug seems to be worked around if system memory addresses
* start on 16 byte boundaries. This seems a bit restrictive however.
* VIA is contacted about this. Meanwhile, impose the following
* restrictions:
*/
#ifdef VIA_BUGFREE
if ((((unsigned long)xfer->mem_addr & 3) !=
((unsigned long)xfer->fb_addr & 3)) ||
((xfer->num_lines > 1) && ((xfer->mem_stride & 3) !=
(xfer->fb_stride & 3)))) {
DRM_ERROR("Invalid DRM bitblt alignment.\n");
return -EINVAL;
}
#else
if ((((unsigned long)xfer->mem_addr & 15) ||
((unsigned long)xfer->fb_addr & 3)) ||
((xfer->num_lines > 1) &&
((xfer->mem_stride & 15) || (xfer->fb_stride & 3)))) {
DRM_ERROR("Invalid DRM bitblt alignment.\n");
return -EINVAL;
}
#endif
if (0 != (ret = via_lock_all_dma_pages(vsg, xfer))) {
DRM_ERROR("Could not lock DMA pages.\n");
via_free_sg_info(vsg);
return ret;
}
via_map_blit_for_device(xfer, vsg, 0);
if (0 != (ret = via_alloc_desc_pages(vsg))) {
DRM_ERROR("Could not allocate DMA descriptor pages.\n");
via_free_sg_info(vsg);
return ret;
}
via_map_blit_for_device(xfer, vsg, 1);
return 0;
}
/*
* Reserve one free slot in the blit queue. Will wait for one second for one
* to become available. Otherwise -EBUSY is returned.
*/
static int
via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine)
{
struct drm_device *dev = blitq->dev;
int ret=0;
DRM_DEBUG("Num free is %d\n", blitq->num_free);
mutex_enter(&blitq->blit_lock);
while(blitq->num_free == 0) {
mutex_exit(&blitq->blit_lock);
DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ,
blitq->num_free > 0);
if (ret) {
return (-EINTR == ret) ? -EAGAIN : ret;
}
mutex_enter(&blitq->blit_lock);
}
blitq->num_free--;
mutex_exit(&blitq->blit_lock);
return 0;
}
/*
* Hand back a free slot if we changed our mind.
*/
static void
via_dmablit_release_slot(drm_via_blitq_t *blitq)
{
mutex_enter(&blitq->blit_lock);
blitq->num_free++;
mutex_exit(&blitq->blit_lock);
DRM_WAKEUP( &blitq->busy_queue );
}
/*
* Grab a free slot. Build blit info and queue a blit.
*/
static int
via_dmablit(struct drm_device *dev, drm_via_dmablit_t *xfer)
{
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
drm_via_sg_info_t *vsg;
drm_via_blitq_t *blitq;
int ret;
int engine;
if (dev_priv == NULL) {
DRM_ERROR("Called without initialization.\n");
return -EINVAL;
}
engine = (xfer->to_fb) ? 0 : 1;
blitq = dev_priv->blit_queues + engine;
if (0 != (ret = via_dmablit_grab_slot(blitq, engine))) {
return ret;
}
if (NULL == (vsg = malloc(sizeof(*vsg), DRM_MEM_DRIVER,
M_NOWAIT | M_ZERO))) {
via_dmablit_release_slot(blitq);
return -ENOMEM;
}
if (0 != (ret = via_build_sg_info(dev, vsg, xfer))) {
via_dmablit_release_slot(blitq);
free(vsg, DRM_MEM_DRIVER);
return ret;
}
mutex_enter(&blitq->blit_lock);
blitq->blits[blitq->head++] = vsg;
if (blitq->head >= VIA_NUM_BLIT_SLOTS)
blitq->head = 0;
blitq->num_outstanding++;
xfer->sync.sync_handle = ++blitq->cur_blit_handle;
mutex_exit(&blitq->blit_lock);
xfer->sync.engine = engine;
via_dmablit_handler(dev, engine, 0);
return 0;
}
/*
* Sync on a previously submitted blit. Note that the X server use signals
* extensively, and that there is a very big probability that this IOCTL will
* be interrupted by a signal. In that case it returns with -EAGAIN for the
* signal to be delivered. The caller should then reissue the IOCTL. This is
* similar to what is being done for drmGetLock().
*/
int
via_dma_blit_sync( struct drm_device *dev, void *data,
struct drm_file *file_priv )
{
drm_via_blitsync_t *sync = data;
int err;
if (sync->engine >= VIA_NUM_BLIT_ENGINES)
return -EINVAL;
err = via_dmablit_sync(dev, sync->sync_handle, sync->engine);
if (-EINTR == err)
err = -EAGAIN;
return err;
}
/*
* Queue a blit and hand back a handle to be used for sync. This IOCTL may be
* interrupted by a signal while waiting for a free slot in the blit queue.
* In that case it returns with -EAGAIN and should be reissued. See the above
* IOCTL code.
*/
int
via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv )
{
drm_via_dmablit_t *xfer = data;
int err;
err = via_dmablit(dev, xfer);
return err;
}

View File

@ -1,144 +0,0 @@
/* via_dmablit.h -- PCI DMA BitBlt support for the VIA Unichrome/Pro
*
* Copyright 2005 Thomas Hellstrom.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Thomas Hellstrom.
* Register info from Digeo Inc.
*/
/* $FreeBSD: src/sys/dev/drm/via_dmablit.h,v 1.1 2010/01/31 14:30:39 rnoland Exp $ */
#ifndef _VIA_DMABLIT_H
#define _VIA_DMABLIT_H
#define VIA_NUM_BLIT_ENGINES 2
#define VIA_NUM_BLIT_SLOTS 8
typedef struct vm_page * vm_page_t;
struct _drm_via_descriptor;
typedef struct _drm_via_sg_info {
vm_page_t *pages;
unsigned long num_pages;
unsigned char *mem_addr;
struct vmspace *vmspace;
struct _drm_via_descriptor **desc_pages;
int num_desc_pages;
int num_desc;
unsigned char *bounce_buffer;
dma_addr_t chain_start;
uint32_t free_on_sequence;
unsigned int descriptors_per_page;
int aborted;
enum {
dr_via_device_mapped,
dr_via_desc_pages_alloc,
dr_via_pages_locked,
dr_via_pages_alloc,
dr_via_sg_init
} state;
} drm_via_sg_info_t;
typedef struct _drm_via_blitq {
struct drm_device *dev;
uint32_t cur_blit_handle;
uint32_t done_blit_handle;
unsigned serviced;
unsigned head;
unsigned cur;
unsigned num_free;
unsigned num_outstanding;
unsigned long end;
int aborting;
int is_active;
drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS];
kmutex_t blit_lock;
wait_queue_head_t blit_queue[VIA_NUM_BLIT_SLOTS];
wait_queue_head_t busy_queue;
struct workqueue *wq;
struct work work;
callout_t poll_timer;
} drm_via_blitq_t;
/*
* PCI DMA Registers
* Channels 2 & 3 don't seem to be implemented in hardware.
*/
#define VIA_PCI_DMA_MAR0 0xE40 /* Memory Address Register of Channel 0 */
#define VIA_PCI_DMA_DAR0 0xE44 /* Device Address Register of Channel 0 */
#define VIA_PCI_DMA_BCR0 0xE48 /* Byte Count Register of Channel 0 */
#define VIA_PCI_DMA_DPR0 0xE4C /* Descriptor Pointer Register of Channel 0 */
#define VIA_PCI_DMA_MAR1 0xE50 /* Memory Address Register of Channel 1 */
#define VIA_PCI_DMA_DAR1 0xE54 /* Device Address Register of Channel 1 */
#define VIA_PCI_DMA_BCR1 0xE58 /* Byte Count Register of Channel 1 */
#define VIA_PCI_DMA_DPR1 0xE5C /* Descriptor Pointer Register of Channel 1 */
#define VIA_PCI_DMA_MAR2 0xE60 /* Memory Address Register of Channel 2 */
#define VIA_PCI_DMA_DAR2 0xE64 /* Device Address Register of Channel 2 */
#define VIA_PCI_DMA_BCR2 0xE68 /* Byte Count Register of Channel 2 */
#define VIA_PCI_DMA_DPR2 0xE6C /* Descriptor Pointer Register of Channel 2 */
#define VIA_PCI_DMA_MAR3 0xE70 /* Memory Address Register of Channel 3 */
#define VIA_PCI_DMA_DAR3 0xE74 /* Device Address Register of Channel 3 */
#define VIA_PCI_DMA_BCR3 0xE78 /* Byte Count Register of Channel 3 */
#define VIA_PCI_DMA_DPR3 0xE7C /* Descriptor Pointer Register of Channel 3 */
#define VIA_PCI_DMA_MR0 0xE80 /* Mode Register of Channel 0 */
#define VIA_PCI_DMA_MR1 0xE84 /* Mode Register of Channel 1 */
#define VIA_PCI_DMA_MR2 0xE88 /* Mode Register of Channel 2 */
#define VIA_PCI_DMA_MR3 0xE8C /* Mode Register of Channel 3 */
#define VIA_PCI_DMA_CSR0 0xE90 /* Command/Status Register of Channel 0 */
#define VIA_PCI_DMA_CSR1 0xE94 /* Command/Status Register of Channel 1 */
#define VIA_PCI_DMA_CSR2 0xE98 /* Command/Status Register of Channel 2 */
#define VIA_PCI_DMA_CSR3 0xE9C /* Command/Status Register of Channel 3 */
#define VIA_PCI_DMA_PTR 0xEA0 /* Priority Type Register */
/* Define for DMA engine */
/* DPR */
#define VIA_DMA_DPR_EC (1<<1) /* end of chain */
#define VIA_DMA_DPR_DDIE (1<<2) /* descriptor done interrupt enable */
#define VIA_DMA_DPR_DT (1<<3) /* direction of transfer (RO) */
/* MR */
#define VIA_DMA_MR_CM (1<<0) /* chaining mode */
#define VIA_DMA_MR_TDIE (1<<1) /* transfer done interrupt enable */
#define VIA_DMA_MR_HENDMACMD (1<<7) /* ? */
/* CSR */
#define VIA_DMA_CSR_DE (1<<0) /* DMA enable */
#define VIA_DMA_CSR_TS (1<<1) /* transfer start */
#define VIA_DMA_CSR_TA (1<<2) /* transfer abort */
#define VIA_DMA_CSR_TD (1<<3) /* transfer done */
#define VIA_DMA_CSR_DD (1<<4) /* descriptor done */
#define VIA_DMA_DPR_EC (1<<1) /* end of chain */
#endif

View File

@ -1,134 +0,0 @@
/* via_drv.c -- VIA unichrome driver -*- linux-c -*-
* Created: Fri Aug 12 2005 by anholt@FreeBSD.org
*/
/*-
* Copyright 2005 Eric Anholt
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Eric Anholt <anholt@FreeBSD.org>
*
*/
#include "drmP.h"
#include "drm.h"
#include "via_drm.h"
#include "via_drv.h"
#include "drm_pciids.h"
/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
static drm_pci_id_list_t via_pciidlist[] = {
viadrv_PCI_IDS
};
static void
via_configure(struct drm_device *dev)
{
dev->driver->driver_features =
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ;
dev->driver->buf_priv_size = sizeof(drm_via_private_t);
dev->driver->load = via_driver_load;
dev->driver->unload = via_driver_unload;
dev->driver->lastclose = via_lastclose;
dev->driver->get_vblank_counter = via_get_vblank_counter;
dev->driver->enable_vblank = via_enable_vblank;
dev->driver->disable_vblank = via_disable_vblank;
dev->driver->irq_preinstall = via_driver_irq_preinstall;
dev->driver->irq_postinstall = via_driver_irq_postinstall;
dev->driver->irq_uninstall = via_driver_irq_uninstall;
dev->driver->irq_handler = via_driver_irq_handler;
dev->driver->dma_quiescent = via_driver_dma_quiescent;
dev->driver->ioctls = via_ioctls;
dev->driver->max_ioctl = via_max_ioctl;
dev->driver->name = DRIVER_NAME;
dev->driver->desc = DRIVER_DESC;
dev->driver->date = DRIVER_DATE;
dev->driver->major = DRIVER_MAJOR;
dev->driver->minor = DRIVER_MINOR;
dev->driver->patchlevel = DRIVER_PATCHLEVEL;
}
static int
viadrm_probe(device_t parent, cfdata_t match, void *aux)
{
struct pci_attach_args *pa = aux;
return drm_probe(pa, via_pciidlist);
}
static void
viadrm_attach(device_t parent, device_t self, void *aux)
{
struct pci_attach_args *pa = aux;
struct drm_device *dev = device_private(self);
if (!pmf_device_register(self, NULL, NULL))
aprint_error_dev(self, "couldn't establish power handler\n");
dev->driver = malloc(sizeof(struct drm_driver_info), DRM_MEM_DRIVER,
M_WAITOK | M_ZERO);
via_configure(dev);
drm_attach(self, pa, via_pciidlist);
}
static int
viadrm_detach(device_t self, int flags)
{
pmf_device_deregister(self);
return drm_detach(self, flags);
}
CFATTACH_DECL_NEW(viadrm, sizeof(struct drm_device),
viadrm_probe, viadrm_attach, viadrm_detach, NULL);
MODULE(MODULE_CLASS_DRIVER, viadrm, "drm");
#ifdef _MODULE
#include "ioconf.c"
#endif
static int
viadrm_modcmd(modcmd_t cmd, void *arg)
{
int err = 0;
switch (cmd) {
case MODULE_CMD_INIT:
#ifdef _MODULE
err = config_init_component(cfdriver_ioconf_viadrm,
cfattach_ioconf_viadrm, cfdata_ioconf_viadrm);
#endif
return err;
case MODULE_CMD_FINI:
#ifdef _MODULE
err = config_fini_component(cfdriver_ioconf_viadrm,
cfattach_ioconf_viadrm, cfdata_ioconf_viadrm);
#endif
return err;
default:
return ENOTTY;
}
}

View File

@ -31,7 +31,6 @@ cp linux-core/Kconfig $OUTDIR/.tmp
cd $OUTDIR
rm -rf .tmp
rm via_ds.[ch]
rm sis_ds.[ch]
cd -

View File

@ -35,12 +35,11 @@ mv $DRMDIR/*_drm.h $HDRDIR
cd $DRMDIR
rm -rf .tmp
rm via_ds.[ch]
rm sis_ds.[ch]
rm amd*.[ch]
rm radeon_ms*.[ch]
for i in radeon mach64 r128 mga i915 i810 via savage sis xgi nouveau tdfx ffb imagine
for i in radeon mach64 r128 mga i915 i810 savage sis xgi nouveau tdfx ffb imagine
do
mkdir ./$i
mv $i*.[ch] $i/

View File

@ -439,18 +439,6 @@
0x121a 0x0009 0 "3dfx Voodoo5 5500"
0x121a 0x000b 0 "3dfx Voodoo4 4200"
[viadrv]
0x1106 0x3022 0 "VIA CLE266 3022"
0x1106 0x3118 VIA_PRO_GROUP_A "VIA CN400 / PM8X0"
0x1106 0x3122 0 "VIA CLE266"
0x1106 0x7205 0 "VIA KM400"
0x1106 0x3108 0 "VIA K8M800"
0x1106 0x3344 0 "VIA CN700 / VM800 / P4M800Pro"
0x1106 0x3343 0 "VIA P4M890"
0x1106 0x3230 VIA_DX9_0 "VIA K8M890"
0x1106 0x3157 VIA_PRO_GROUP_A "VIA CX700"
0x1106 0x3371 VIA_DX9_0 "VIA P4M900 / VN896"
[i810]
0x8086 0x7121 0 "Intel i810 GMCH"
0x8086 0x7123 0 "Intel i810-DC100 GMCH"

File diff suppressed because it is too large Load Diff

View File

@ -1,765 +0,0 @@
/* via_dma.c -- DMA support for the VIA Unichrome/Pro
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Copyright 2004 Digeo, Inc., Palo Alto, CA, U.S.A.
* All Rights Reserved.
*
* Copyright 2004 The Unichrome project.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Tungsten Graphics,
* Erdi Chen,
* Thomas Hellstrom.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: via_dma.c,v 1.4 2013/10/17 21:15:18 christos Exp $");
#include "drmP.h"
#include "drm.h"
#include "via_drm.h"
#include "via_drv.h"
#include "via_3d_reg.h"
#define CMDBUF_ALIGNMENT_SIZE (0x100)
#define CMDBUF_ALIGNMENT_MASK (0x0ff)
/* defines for VIA 3D registers */
#define VIA_REG_STATUS 0x400
#define VIA_REG_TRANSET 0x43C
#define VIA_REG_TRANSPACE 0x440
/* VIA_REG_STATUS(0x400): Engine Status */
#define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */
#define VIA_2D_ENG_BUSY 0x00000001 /* 2D Engine is busy */
#define VIA_3D_ENG_BUSY 0x00000002 /* 3D Engine is busy */
#define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */
#define SetReg2DAGP(nReg, nData) { \
*((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1; \
*((uint32_t *)(vb) + 1) = (nData); \
vb = ((uint32_t *)vb) + 2; \
dev_priv->dma_low +=8; \
}
#define via_flush_write_combine() DRM_MEMORYBARRIER()
#define VIA_OUT_RING_QW(w1,w2) \
*vb++ = (w1); \
*vb++ = (w2); \
dev_priv->dma_low += 8;
static void via_cmdbuf_start(drm_via_private_t * dev_priv);
static void via_cmdbuf_pause(drm_via_private_t * dev_priv);
static void via_cmdbuf_reset(drm_via_private_t * dev_priv);
static void via_cmdbuf_rewind(drm_via_private_t * dev_priv);
static int via_wait_idle(drm_via_private_t * dev_priv);
static void via_pad_cache(drm_via_private_t * dev_priv, int qwords);
/*
* Free space in command buffer.
*/
static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv)
{
uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
return ((hw_addr <= dev_priv->dma_low) ?
(dev_priv->dma_high + hw_addr - dev_priv->dma_low) :
(hw_addr - dev_priv->dma_low));
}
/*
* How much does the command regulator lag behind?
*/
static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv)
{
uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
return ((hw_addr <= dev_priv->dma_low) ?
(dev_priv->dma_low - hw_addr) :
(dev_priv->dma_wrap + dev_priv->dma_low - hw_addr));
}
/*
* Check that the given size fits in the buffer, otherwise wait.
*/
static inline int
via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
{
uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
uint32_t cur_addr, hw_addr, next_addr;
volatile uint32_t *hw_addr_ptr;
uint32_t count;
hw_addr_ptr = dev_priv->hw_addr_ptr;
cur_addr = dev_priv->dma_low;
next_addr = cur_addr + size + 512 * 1024;
count = 1000000;
do {
hw_addr = *hw_addr_ptr - agp_base;
if (count-- == 0) {
DRM_ERROR
("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n",
hw_addr, cur_addr, next_addr);
return -1;
}
if ((cur_addr < hw_addr) && (next_addr >= hw_addr))
delay(1000);
} while ((cur_addr < hw_addr) && (next_addr >= hw_addr));
return 0;
}
/*
* Checks whether buffer head has reach the end. Rewind the ring buffer
* when necessary.
*
* Returns virtual pointer to ring buffer.
*/
static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv,
unsigned int size)
{
if ((dev_priv->dma_low + size + 4 * CMDBUF_ALIGNMENT_SIZE) >
dev_priv->dma_high) {
via_cmdbuf_rewind(dev_priv);
}
if (via_cmdbuf_wait(dev_priv, size) != 0) {
return NULL;
}
return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low);
}
int via_dma_cleanup(struct drm_device * dev)
{
drm_via_blitq_t *blitq;
int i;
if (dev->dev_private) {
drm_via_private_t *dev_priv =
(drm_via_private_t *) dev->dev_private;
if (dev_priv->ring.virtual_start) {
via_cmdbuf_reset(dev_priv);
drm_core_ioremapfree(&dev_priv->ring.map, dev);
dev_priv->ring.virtual_start = NULL;
}
for (i=0; i< VIA_NUM_BLIT_ENGINES; ++i) {
blitq = dev_priv->blit_queues + i;
mutex_destroy(&blitq->blit_lock);
}
}
return 0;
}
static int via_initialize(struct drm_device * dev,
drm_via_private_t * dev_priv,
drm_via_dma_init_t * init)
{
if (!dev_priv || !dev_priv->mmio) {
DRM_ERROR("via_dma_init called before via_map_init\n");
return -EFAULT;
}
if (dev_priv->ring.virtual_start != NULL) {
DRM_ERROR("called again without calling cleanup\n");
return -EFAULT;
}
if (!dev->agp || !dev->agp->base) {
DRM_ERROR("called with no agp memory available\n");
return -EFAULT;
}
if (dev_priv->chipset == VIA_DX9_0) {
DRM_ERROR("AGP DMA is not supported on this chip\n");
return -EINVAL;
}
dev_priv->ring.map.offset = dev->agp->base + init->offset;
dev_priv->ring.map.size = init->size;
dev_priv->ring.map.type = 0;
dev_priv->ring.map.flags = 0;
dev_priv->ring.map.mtrr = 0;
drm_core_ioremap_wc(&dev_priv->ring.map, dev);
if (dev_priv->ring.map.handle == NULL) {
via_dma_cleanup(dev);
DRM_ERROR("can not ioremap virtual address for"
" ring buffer\n");
return -ENOMEM;
}
dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
dev_priv->dma_ptr = dev_priv->ring.virtual_start;
dev_priv->dma_low = 0;
dev_priv->dma_high = init->size;
dev_priv->dma_wrap = init->size;
dev_priv->dma_offset = init->offset;
dev_priv->last_pause_ptr = NULL;
dev_priv->hw_addr_ptr =
(volatile uint32_t *)((char *)dev_priv->mmio->handle +
init->reg_pause_addr);
via_cmdbuf_start(dev_priv);
return 0;
}
static int via_dma_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
drm_via_dma_init_t *init = data;
int retcode = 0;
switch (init->func) {
case VIA_INIT_DMA:
if (!DRM_SUSER(DRM_CURPROC))
retcode = -EPERM;
else
retcode = via_initialize(dev, dev_priv, init);
break;
case VIA_CLEANUP_DMA:
if (!DRM_SUSER(DRM_CURPROC))
retcode = -EPERM;
else
retcode = via_dma_cleanup(dev);
break;
case VIA_DMA_INITIALIZED:
retcode = (dev_priv->ring.virtual_start != NULL) ?
0 : -EFAULT;
break;
default:
retcode = -EINVAL;
break;
}
return retcode;
}
static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * cmd)
{
drm_via_private_t *dev_priv;
uint32_t *vb;
int ret;
dev_priv = (drm_via_private_t *) dev->dev_private;
if (dev_priv->ring.virtual_start == NULL) {
DRM_ERROR("called without initializing AGP ring buffer.\n");
return -EFAULT;
}
if (cmd->size > VIA_PCI_BUF_SIZE) {
return -ENOMEM;
}
if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
return -EFAULT;
/*
* Running this function on AGP memory is dead slow. Therefore
* we run it on a temporary cacheable system memory buffer and
* copy it to AGP memory when ready.
*/
if ((ret =
via_verify_command_stream((uint32_t *) dev_priv->pci_buf,
cmd->size, dev, 1))) {
return ret;
}
vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size);
if (vb == NULL) {
return -EAGAIN;
}
memcpy(vb, dev_priv->pci_buf, cmd->size);
dev_priv->dma_low += cmd->size;
/*
* Small submissions somehow stalls the CPU. (AGP cache effects?)
* pad to greater size.
*/
if (cmd->size < 0x100)
via_pad_cache(dev_priv, (0x100 - cmd->size) >> 3);
via_cmdbuf_pause(dev_priv);
return 0;
}
int via_driver_dma_quiescent(struct drm_device * dev)
{
drm_via_private_t *dev_priv = dev->dev_private;
if (!via_wait_idle(dev_priv)) {
return -EBUSY;
}
return 0;
}
static int via_flush_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
LOCK_TEST_WITH_RETURN(dev, file_priv);
return via_driver_dma_quiescent(dev);
}
static int via_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_cmdbuffer_t *cmdbuf = data;
int ret;
LOCK_TEST_WITH_RETURN(dev, file_priv);
DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size);
ret = via_dispatch_cmdbuffer(dev, cmdbuf);
if (ret) {
return ret;
}
return 0;
}
static int via_dispatch_pci_cmdbuffer(struct drm_device * dev,
drm_via_cmdbuffer_t * cmd)
{
drm_via_private_t *dev_priv = dev->dev_private;
int ret;
if (cmd->size > VIA_PCI_BUF_SIZE) {
return -ENOMEM;
}
if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
return -EFAULT;
if ((ret =
via_verify_command_stream((uint32_t *) dev_priv->pci_buf,
cmd->size, dev, 0))) {
return ret;
}
ret =
via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf,
cmd->size);
return ret;
}
static int via_pci_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_cmdbuffer_t *cmdbuf = data;
int ret;
LOCK_TEST_WITH_RETURN(dev, file_priv);
DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size);
ret = via_dispatch_pci_cmdbuffer(dev, cmdbuf);
if (ret) {
return ret;
}
return 0;
}
static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv,
uint32_t * vb, int qw_count)
{
for (; qw_count > 0; --qw_count) {
VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY);
}
return vb;
}
/*
* This function is used internally by ring buffer management code.
*
* Returns virtual pointer to ring buffer.
*/
static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv)
{
return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low);
}
/*
* Hooks a segment of data into the tail of the ring-buffer by
* modifying the pause address stored in the buffer itself. If
* the regulator has already paused, restart it.
*/
static int via_hook_segment(drm_via_private_t * dev_priv,
uint32_t pause_addr_hi, uint32_t pause_addr_lo,
int no_pci_fire)
{
int paused, count;
volatile uint32_t *paused_at = dev_priv->last_pause_ptr;
uint32_t reader,ptr;
uint32_t diff;
paused = 0;
via_flush_write_combine();
(void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1);
*paused_at = pause_addr_lo;
via_flush_write_combine();
(void) *paused_at;
reader = *(dev_priv->hw_addr_ptr);
ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) +
dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
/*
* If there is a possibility that the command reader will
* miss the new pause address and pause on the old one,
* In that case we need to program the new start address
* using PCI.
*/
diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
count = 10000000;
while(diff == 0 && count--) {
paused = (VIA_READ(0x41c) & 0x80000000);
if (paused)
break;
reader = *(dev_priv->hw_addr_ptr);
diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
}
paused = VIA_READ(0x41c) & 0x80000000;
if (paused && !no_pci_fire) {
reader = *(dev_priv->hw_addr_ptr);
diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
diff &= (dev_priv->dma_high - 1);
if (diff != 0 && diff < (dev_priv->dma_high >> 1)) {
DRM_ERROR("Paused at incorrect address. "
"0x%08x, 0x%08x 0x%08x\n",
ptr, reader, dev_priv->dma_diff);
} else if (diff == 0) {
/*
* There is a concern that these writes may stall the PCI bus
* if the GPU is not idle. However, idling the GPU first
* doesn't make a difference.
*/
VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
VIA_READ(VIA_REG_TRANSPACE);
}
}
return paused;
}
static int via_wait_idle(drm_via_private_t * dev_priv)
{
int count = 10000000;
while (!(VIA_READ(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && --count)
;
while (count && (VIA_READ(VIA_REG_STATUS) &
(VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY |
VIA_3D_ENG_BUSY)))
--count;
return count;
}
static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
uint32_t addr, uint32_t * cmd_addr_hi,
uint32_t * cmd_addr_lo, int skip_wait)
{
uint32_t agp_base;
uint32_t cmd_addr, addr_lo, addr_hi;
uint32_t *vb;
uint32_t qw_pad_count;
if (!skip_wait)
via_cmdbuf_wait(dev_priv, 2 * CMDBUF_ALIGNMENT_SIZE);
vb = via_get_dma(dev_priv);
VIA_OUT_RING_QW(HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
(VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16);
agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
qw_pad_count = (CMDBUF_ALIGNMENT_SIZE >> 3) -
((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3);
cmd_addr = (addr) ? addr :
agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3);
addr_lo = ((HC_SubA_HAGPBpL << 24) | (cmd_type & HC_HAGPBpID_MASK) |
(cmd_addr & HC_HAGPBpL_MASK));
addr_hi = ((HC_SubA_HAGPBpH << 24) | (cmd_addr >> 24));
vb = via_align_buffer(dev_priv, vb, qw_pad_count - 1);
VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi, *cmd_addr_lo = addr_lo);
return vb;
}
static void via_cmdbuf_start(drm_via_private_t * dev_priv)
{
uint32_t pause_addr_lo, pause_addr_hi;
uint32_t start_addr, start_addr_lo;
uint32_t end_addr, end_addr_lo;
uint32_t command;
uint32_t agp_base;
uint32_t ptr;
uint32_t reader;
int count;
dev_priv->dma_low = 0;
agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
start_addr = agp_base;
end_addr = agp_base + dev_priv->dma_high;
start_addr_lo = ((HC_SubA_HAGPBstL << 24) | (start_addr & 0xFFFFFF));
end_addr_lo = ((HC_SubA_HAGPBendL << 24) | (end_addr & 0xFFFFFF));
command = ((HC_SubA_HAGPCMNT << 24) | (start_addr >> 24) |
((end_addr & 0xff000000) >> 16));
dev_priv->last_pause_ptr =
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0,
&pause_addr_hi, &pause_addr_lo, 1) - 1;
via_flush_write_combine();
(void) *(volatile uint32_t *)dev_priv->last_pause_ptr;
VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
VIA_WRITE(VIA_REG_TRANSPACE, command);
VIA_WRITE(VIA_REG_TRANSPACE, start_addr_lo);
VIA_WRITE(VIA_REG_TRANSPACE, end_addr_lo);
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
DRM_WRITEMEMORYBARRIER();
VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK);
VIA_READ(VIA_REG_TRANSPACE);
dev_priv->dma_diff = 0;
count = 10000000;
while (!(VIA_READ(0x41c) & 0x80000000) && count--);
reader = *(dev_priv->hw_addr_ptr);
ptr = ((volatile char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) +
dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
/*
* This is the difference between where we tell the
* command reader to pause and where it actually pauses.
* This differs between hw implementation so we need to
* detect it.
*/
dev_priv->dma_diff = ptr - reader;
}
static void via_pad_cache(drm_via_private_t * dev_priv, int qwords)
{
uint32_t *vb;
via_cmdbuf_wait(dev_priv, qwords + 2);
vb = via_get_dma(dev_priv);
VIA_OUT_RING_QW(HC_HEADER2, HC_ParaType_NotTex << 16);
via_align_buffer(dev_priv, vb, qwords);
}
static inline void via_dummy_bitblt(drm_via_private_t * dev_priv)
{
uint32_t *vb = via_get_dma(dev_priv);
SetReg2DAGP(0x0C, (0 | (0 << 16)));
SetReg2DAGP(0x10, 0 | (0 << 16));
SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000);
}
static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
{
uint32_t pause_addr_lo, pause_addr_hi;
uint32_t jump_addr_lo, jump_addr_hi;
volatile uint32_t *last_pause_ptr;
uint32_t dma_low_save1, dma_low_save2;
via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
&jump_addr_lo, 0);
dev_priv->dma_wrap = dev_priv->dma_low;
/*
* Wrap command buffer to the beginning.
*/
dev_priv->dma_low = 0;
if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0) {
DRM_ERROR("via_cmdbuf_jump failed\n");
}
via_dummy_bitblt(dev_priv);
via_dummy_bitblt(dev_priv);
last_pause_ptr =
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
&pause_addr_lo, 0) - 1;
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
&pause_addr_lo, 0);
*last_pause_ptr = pause_addr_lo;
dma_low_save1 = dev_priv->dma_low;
/*
* Now, set a trap that will pause the regulator if it tries to rerun the old
* command buffer. (Which may happen if via_hook_segment detecs a command regulator pause
* and reissues the jump command over PCI, while the regulator has already taken the jump
* and actually paused at the current buffer end).
* There appears to be no other way to detect this condition, since the hw_addr_pointer
* does not seem to get updated immediately when a jump occurs.
*/
last_pause_ptr =
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
&pause_addr_lo, 0) - 1;
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
&pause_addr_lo, 0);
*last_pause_ptr = pause_addr_lo;
dma_low_save2 = dev_priv->dma_low;
dev_priv->dma_low = dma_low_save1;
via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0);
dev_priv->dma_low = dma_low_save2;
via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
}
static void via_cmdbuf_rewind(drm_via_private_t * dev_priv)
{
via_cmdbuf_jump(dev_priv);
}
static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type)
{
uint32_t pause_addr_lo, pause_addr_hi;
via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &pause_addr_lo, 0);
via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
}
static void via_cmdbuf_pause(drm_via_private_t * dev_priv)
{
via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE);
}
static void via_cmdbuf_reset(drm_via_private_t * dev_priv)
{
via_cmdbuf_flush(dev_priv, HC_HAGPBpID_STOP);
via_wait_idle(dev_priv);
}
/*
* User interface to the space and lag functions.
*/
static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_cmdbuf_size_t *d_siz = data;
int ret = 0;
uint32_t tmp_size, count;
drm_via_private_t *dev_priv;
DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
dev_priv = (drm_via_private_t *) dev->dev_private;
if (dev_priv->ring.virtual_start == NULL) {
DRM_ERROR("called without initializing AGP ring buffer.\n");
return -EFAULT;
}
count = 1000000;
tmp_size = d_siz->size;
switch (d_siz->func) {
case VIA_CMDBUF_SPACE:
while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size)
&& --count) {
if (!d_siz->wait) {
break;
}
}
if (!count) {
DRM_ERROR("VIA_CMDBUF_SPACE timed out.\n");
ret = -EAGAIN;
}
break;
case VIA_CMDBUF_LAG:
while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size)
&& --count) {
if (!d_siz->wait) {
break;
}
}
if (!count) {
DRM_ERROR("VIA_CMDBUF_LAG timed out.\n");
ret = -EAGAIN;
}
break;
default:
ret = -EFAULT;
}
d_siz->size = tmp_size;
return ret;
}
struct drm_ioctl_desc via_ioctls[] = {
DRM_IOCTL_DEF(DRM_VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH),
DRM_IOCTL_DEF(DRM_VIA_FREEMEM, via_mem_free, DRM_AUTH),
DRM_IOCTL_DEF(DRM_VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER),
DRM_IOCTL_DEF(DRM_VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER),
DRM_IOCTL_DEF(DRM_VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER),
DRM_IOCTL_DEF(DRM_VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH),
DRM_IOCTL_DEF(DRM_VIA_DMA_INIT, via_dma_init, DRM_AUTH),
DRM_IOCTL_DEF(DRM_VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH),
DRM_IOCTL_DEF(DRM_VIA_FLUSH, via_flush_ioctl, DRM_AUTH),
DRM_IOCTL_DEF(DRM_VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH),
DRM_IOCTL_DEF(DRM_VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH),
DRM_IOCTL_DEF(DRM_VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH),
DRM_IOCTL_DEF(DRM_VIA_DMA_BLIT, via_dma_blit, DRM_AUTH),
DRM_IOCTL_DEF(DRM_VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH)
};
int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls);

View File

@ -1,279 +0,0 @@
/*-
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: via_drm.h,v 1.2 2011/02/18 14:26:10 jmcneill Exp $");
#ifndef _VIA_DRM_H_
#define _VIA_DRM_H_
/* WARNING: These defines must be the same as what the Xserver uses.
* if you change them, you must change the defines in the Xserver.
*/
#ifndef _VIA_DEFINES_
#define _VIA_DEFINES_
#if !defined(__KERNEL__) && !defined(_KERNEL)
#include "via_drmclient.h"
#endif
#define VIA_NR_SAREA_CLIPRECTS 8
#define VIA_NR_XVMC_PORTS 10
#define VIA_NR_XVMC_LOCKS 5
#define VIA_MAX_CACHELINE_SIZE 64
#define XVMCLOCKPTR(saPriv,lockNo) \
((volatile struct drm_hw_lock *)(((((unsigned long) (saPriv)->XvMCLockArea) + \
(VIA_MAX_CACHELINE_SIZE - 1)) & \
~(VIA_MAX_CACHELINE_SIZE - 1)) + \
VIA_MAX_CACHELINE_SIZE*(lockNo)))
/* Each region is a minimum of 64k, and there are at most 64 of them.
*/
#define VIA_NR_TEX_REGIONS 64
#define VIA_LOG_MIN_TEX_REGION_SIZE 16
#endif
#define VIA_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
#define VIA_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
#define VIA_UPLOAD_CTX 0x4
#define VIA_UPLOAD_BUFFERS 0x8
#define VIA_UPLOAD_TEX0 0x10
#define VIA_UPLOAD_TEX1 0x20
#define VIA_UPLOAD_CLIPRECTS 0x40
#define VIA_UPLOAD_ALL 0xff
/* VIA specific ioctls */
#define DRM_VIA_ALLOCMEM 0x00
#define DRM_VIA_FREEMEM 0x01
#define DRM_VIA_AGP_INIT 0x02
#define DRM_VIA_FB_INIT 0x03
#define DRM_VIA_MAP_INIT 0x04
#define DRM_VIA_DEC_FUTEX 0x05
#define NOT_USED
#define DRM_VIA_DMA_INIT 0x07
#define DRM_VIA_CMDBUFFER 0x08
#define DRM_VIA_FLUSH 0x09
#define DRM_VIA_PCICMD 0x0a
#define DRM_VIA_CMDBUF_SIZE 0x0b
#define NOT_USED
#define DRM_VIA_WAIT_IRQ 0x0d
#define DRM_VIA_DMA_BLIT 0x0e
#define DRM_VIA_BLIT_SYNC 0x0f
#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t)
#define DRM_IOCTL_VIA_FREEMEM DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t)
#define DRM_IOCTL_VIA_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_AGP_INIT, drm_via_agp_t)
#define DRM_IOCTL_VIA_FB_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_FB_INIT, drm_via_fb_t)
#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_MAP_INIT, drm_via_init_t)
#define DRM_IOCTL_VIA_DEC_FUTEX DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_DEC_FUTEX, drm_via_futex_t)
#define DRM_IOCTL_VIA_DMA_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_DMA_INIT, drm_via_dma_init_t)
#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_CMDBUFFER, drm_via_cmdbuffer_t)
#define DRM_IOCTL_VIA_FLUSH DRM_IO( DRM_COMMAND_BASE + DRM_VIA_FLUSH)
#define DRM_IOCTL_VIA_PCICMD DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_PCICMD, drm_via_cmdbuffer_t)
#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \
drm_via_cmdbuf_size_t)
#define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t)
#define DRM_IOCTL_VIA_DMA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DMA_BLIT, drm_via_dmablit_t)
#define DRM_IOCTL_VIA_BLIT_SYNC DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_BLIT_SYNC, drm_via_blitsync_t)
/* Indices into buf.Setup where various bits of state are mirrored per
* context and per buffer. These can be fired at the card as a unit,
* or in a piecewise fashion as required.
*/
#define VIA_TEX_SETUP_SIZE 8
/* Flags for clear ioctl
*/
#define VIA_FRONT 0x1
#define VIA_BACK 0x2
#define VIA_DEPTH 0x4
#define VIA_STENCIL 0x8
#define VIA_MEM_VIDEO 0 /* matches drm constant */
#define VIA_MEM_AGP 1 /* matches drm constant */
#define VIA_MEM_SYSTEM 2
#define VIA_MEM_MIXED 3
#define VIA_MEM_UNKNOWN 4
typedef struct {
uint32_t offset;
uint32_t size;
} drm_via_agp_t;
typedef struct {
uint32_t offset;
uint32_t size;
} drm_via_fb_t;
typedef struct {
uint32_t context;
uint32_t type;
uint32_t size;
unsigned long index;
unsigned long offset;
} drm_via_mem_t;
typedef struct _drm_via_init {
enum {
VIA_INIT_MAP = 0x01,
VIA_CLEANUP_MAP = 0x02
} func;
unsigned long sarea_priv_offset;
unsigned long fb_offset;
unsigned long mmio_offset;
unsigned long agpAddr;
} drm_via_init_t;
typedef struct _drm_via_futex {
enum {
VIA_FUTEX_WAIT = 0x00,
VIA_FUTEX_WAKE = 0X01
} func;
uint32_t ms;
uint32_t lock;
uint32_t val;
} drm_via_futex_t;
typedef struct _drm_via_dma_init {
enum {
VIA_INIT_DMA = 0x01,
VIA_CLEANUP_DMA = 0x02,
VIA_DMA_INITIALIZED = 0x03
} func;
unsigned long offset;
unsigned long size;
unsigned long reg_pause_addr;
} drm_via_dma_init_t;
typedef struct _drm_via_cmdbuffer {
char __user *buf;
unsigned long size;
} drm_via_cmdbuffer_t;
/* Warning: If you change the SAREA structure you must change the Xserver
* structure as well */
typedef struct _drm_via_tex_region {
unsigned char next, prev; /* indices to form a circular LRU */
unsigned char inUse; /* owned by a client, or free? */
int age; /* tracked by clients to update local LRU's */
} drm_via_tex_region_t;
typedef struct _drm_via_sarea {
unsigned int dirty;
unsigned int nbox;
struct drm_clip_rect boxes[VIA_NR_SAREA_CLIPRECTS];
drm_via_tex_region_t texList[VIA_NR_TEX_REGIONS + 1];
int texAge; /* last time texture was uploaded */
int ctxOwner; /* last context to upload state */
int vertexPrim;
/*
* Below is for XvMC.
* We want the lock integers alone on, and aligned to, a cache line.
* Therefore this somewhat strange construct.
*/
char XvMCLockArea[VIA_MAX_CACHELINE_SIZE * (VIA_NR_XVMC_LOCKS + 1)];
unsigned int XvMCDisplaying[VIA_NR_XVMC_PORTS];
unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS];
unsigned int XvMCCtxNoGrabbed; /* Last context to hold decoder */
/* Used by the 3d driver only at this point, for pageflipping:
*/
unsigned int pfCurrentOffset;
} drm_via_sarea_t;
typedef struct _drm_via_cmdbuf_size {
enum {
VIA_CMDBUF_SPACE = 0x01,
VIA_CMDBUF_LAG = 0x02
} func;
int wait;
uint32_t size;
} drm_via_cmdbuf_size_t;
typedef enum {
VIA_IRQ_ABSOLUTE = 0x0,
VIA_IRQ_RELATIVE = 0x1,
VIA_IRQ_SIGNAL = 0x10000000,
VIA_IRQ_FORCE_SEQUENCE = 0x20000000
} via_irq_seq_type_t;
#define VIA_IRQ_FLAGS_MASK 0xF0000000
enum drm_via_irqs {
drm_via_irq_hqv0 = 0,
drm_via_irq_hqv1,
drm_via_irq_dma0_dd,
drm_via_irq_dma0_td,
drm_via_irq_dma1_dd,
drm_via_irq_dma1_td,
drm_via_irq_num
};
struct drm_via_wait_irq_request {
unsigned irq;
via_irq_seq_type_t type;
uint32_t sequence;
uint32_t signal;
};
typedef union drm_via_irqwait {
struct drm_via_wait_irq_request request;
struct drm_wait_vblank_reply reply;
} drm_via_irqwait_t;
typedef struct drm_via_blitsync {
uint32_t sync_handle;
unsigned engine;
} drm_via_blitsync_t;
/* - * Below,"flags" is currently unused but will be used for possible future
* extensions like kernel space bounce buffers for bad alignments and
* blit engine busy-wait polling for better latency in the absence of
* interrupts.
*/
typedef struct drm_via_dmablit {
uint32_t num_lines;
uint32_t line_length;
uint32_t fb_addr;
uint32_t fb_stride;
unsigned char *mem_addr;
uint32_t mem_stride;
uint32_t flags;
int to_fb;
drm_via_blitsync_t sync;
} drm_via_dmablit_t;
#endif /* _VIA_DRM_H_ */

View File

@ -1,158 +0,0 @@
/*-
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _VIA_DRV_H_
#define _VIA_DRV_H_
#include "drm_sman.h"
#define DRIVER_AUTHOR "Various"
#define DRIVER_NAME "via"
#define DRIVER_DESC "VIA Unichrome / Pro"
#define DRIVER_DATE "20070202"
#define DRIVER_MAJOR 2
#define DRIVER_MINOR 11
#define DRIVER_PATCHLEVEL 1
#include "via_verifier.h"
#include "via_dmablit.h"
#define VIA_PCI_BUF_SIZE 60000
#define VIA_FIRE_BUF_SIZE 1024
#define VIA_NUM_IRQS 4
typedef struct drm_via_ring_buffer {
drm_local_map_t map;
char *virtual_start;
} drm_via_ring_buffer_t;
typedef uint32_t maskarray_t[5];
typedef struct drm_via_irq {
atomic_t irq_received;
uint32_t pending_mask;
uint32_t enable_mask;
wait_queue_head_t irq_queue;
} drm_via_irq_t;
typedef struct drm_via_private {
drm_via_sarea_t *sarea_priv;
drm_local_map_t *sarea;
drm_local_map_t *fb;
drm_local_map_t *mmio;
unsigned long agpAddr;
wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS];
char *dma_ptr;
unsigned int dma_low;
unsigned int dma_high;
unsigned int dma_offset;
uint32_t dma_wrap;
volatile uint32_t *last_pause_ptr;
volatile uint32_t *hw_addr_ptr;
drm_via_ring_buffer_t ring;
struct timeval last_vblank;
int last_vblank_valid;
unsigned usec_per_vblank;
atomic_t vbl_received;
drm_via_state_t hc_state;
char pci_buf[VIA_PCI_BUF_SIZE];
const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
uint32_t num_fire_offsets;
int chipset;
drm_via_irq_t via_irqs[VIA_NUM_IRQS];
unsigned num_irqs;
maskarray_t *irq_masks;
uint32_t irq_enable_mask;
uint32_t irq_pending_mask;
int *irq_map;
unsigned int idle_fault;
struct drm_sman sman;
int vram_initialized;
int agp_initialized;
unsigned long vram_offset;
unsigned long agp_offset;
drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES];
uint32_t dma_diff;
} drm_via_private_t;
enum via_family {
VIA_OTHER = 0, /* Baseline */
VIA_PRO_GROUP_A, /* Another video engine and DMA commands */
VIA_DX9_0 /* Same video as pro_group_a, but 3D is unsupported */
};
/* VIA MMIO register access */
#define VIA_BASE ((dev_priv->mmio))
#define VIA_READ(reg) DRM_READ32(VIA_BASE, reg)
#define VIA_WRITE(reg,val) DRM_WRITE32(VIA_BASE, reg, val)
#define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg)
#define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val)
extern struct drm_ioctl_desc via_ioctls[];
extern int via_max_ioctl;
extern int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int via_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv );
extern int via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv );
extern int via_driver_load(struct drm_device *dev, unsigned long chipset);
extern int via_driver_unload(struct drm_device *dev);
extern int via_init_context(struct drm_device * dev, int context);
extern int via_final_context(struct drm_device * dev, int context);
extern int via_do_cleanup_map(struct drm_device * dev);
extern uint32_t via_get_vblank_counter(struct drm_device *dev, unsigned int crtc);
extern int via_enable_vblank(struct drm_device *dev, unsigned int crtc);
extern void via_disable_vblank(struct drm_device *dev, unsigned int crtc);
extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
extern void via_driver_irq_preinstall(struct drm_device * dev);
extern int via_driver_irq_postinstall(struct drm_device *dev);
extern void via_driver_irq_uninstall(struct drm_device * dev);
extern int via_dma_cleanup(struct drm_device * dev);
extern void via_init_command_verifier(void);
extern int via_driver_dma_quiescent(struct drm_device * dev);
extern void via_init_futex(drm_via_private_t *dev_priv);
extern void via_cleanup_futex(drm_via_private_t *dev_priv);
extern void via_release_futex(drm_via_private_t *dev_priv, int context);
extern void via_reclaim_buffers_locked(struct drm_device *dev,
struct drm_file *file_priv);
extern void via_lastclose(struct drm_device *dev);
extern void via_dmablit_handler(struct drm_device *dev, int engine, int from_irq);
extern void via_init_dmablit(struct drm_device *dev);
#endif

View File

@ -1,274 +0,0 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
* Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
#include "via_ds.h"
extern unsigned int VIA_DEBUG;
set_t *via_setInit(void)
{
int i;
set_t *set;
set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
for (i = 0; i < SET_SIZE; i++) {
set->list[i].free_next = i + 1;
set->list[i].alloc_next = -1;
}
set->list[SET_SIZE - 1].free_next = -1;
set->free = 0;
set->alloc = -1;
set->trace = -1;
return set;
}
int via_setAdd(set_t * set, ITEM_TYPE item)
{
int sfree = set->free;
if (sfree != -1) {
set->list[sfree].val = item;
set->free = set->list[sfree].free_next;
} else {
return 0;
}
set->list[sfree].alloc_next = set->alloc;
set->alloc = sfree;
set->list[sfree].free_next = -1;
return 1;
}
int via_setDel(set_t * set, ITEM_TYPE item)
{
int alloc = set->alloc;
int prev = -1;
while (alloc != -1) {
if (set->list[alloc].val == item) {
if (prev != -1)
set->list[prev].alloc_next =
set->list[alloc].alloc_next;
else
set->alloc = set->list[alloc].alloc_next;
break;
}
prev = alloc;
alloc = set->list[alloc].alloc_next;
}
if (alloc == -1)
return 0;
set->list[alloc].free_next = set->free;
set->free = alloc;
set->list[alloc].alloc_next = -1;
return 1;
}
/* setFirst -> setAdd -> setNext is wrong */
int via_setFirst(set_t * set, ITEM_TYPE * item)
{
if (set->alloc == -1)
return 0;
*item = set->list[set->alloc].val;
set->trace = set->list[set->alloc].alloc_next;
return 1;
}
int via_setNext(set_t * set, ITEM_TYPE * item)
{
if (set->trace == -1)
return 0;
*item = set->list[set->trace].val;
set->trace = set->list[set->trace].alloc_next;
return 1;
}
int via_setDestroy(set_t * set)
{
drm_free(set, sizeof(set_t), DRM_MEM_DRIVER);
return 1;
}
#define ISFREE(bptr) ((bptr)->free)
#define fprintf(fmt, arg...) do{}while(0)
memHeap_t *via_mmInit(int ofs, int size)
{
PMemBlock blocks;
if (size <= 0)
return NULL;
blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
if (blocks) {
blocks->ofs = ofs;
blocks->size = size;
blocks->free = 1;
return (memHeap_t *) blocks;
} else
return NULL;
}
static TMemBlock *SliceBlock(TMemBlock * p,
int startofs, int size,
int reserved, int alignment)
{
TMemBlock *newblock;
/* break left */
if (startofs > p->ofs) {
newblock =
(TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
DRM_MEM_DRIVER);
newblock->ofs = startofs;
newblock->size = p->size - (startofs - p->ofs);
newblock->free = 1;
newblock->next = p->next;
p->size -= newblock->size;
p->next = newblock;
p = newblock;
}
/* break right */
if (size < p->size) {
newblock =
(TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
DRM_MEM_DRIVER);
newblock->ofs = startofs + size;
newblock->size = p->size - size;
newblock->free = 1;
newblock->next = p->next;
p->size = size;
p->next = newblock;
}
/* p = middle block */
p->align = alignment;
p->free = 0;
p->reserved = reserved;
return p;
}
PMemBlock via_mmAllocMem(memHeap_t * heap, int size, int align2,
int startSearch)
{
int mask, startofs, endofs;
TMemBlock *p;
if (!heap || align2 < 0 || size <= 0)
return NULL;
mask = (1 << align2) - 1;
startofs = 0;
p = (TMemBlock *) heap;
while (p) {
if (ISFREE(p)) {
startofs = (p->ofs + mask) & ~mask;
if (startofs < startSearch)
startofs = startSearch;
endofs = startofs + size;
if (endofs <= (p->ofs + p->size))
break;
}
p = p->next;
}
if (!p)
return NULL;
p = SliceBlock(p, startofs, size, 0, mask + 1);
p->heap = heap;
return p;
}
static __inline__ int Join2Blocks(TMemBlock * p)
{
if (p->free && p->next && p->next->free) {
TMemBlock *q = p->next;
p->size += q->size;
p->next = q->next;
drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER);
return 1;
}
return 0;
}
int via_mmFreeMem(PMemBlock b)
{
TMemBlock *p, *prev;
if (!b)
return 0;
if (!b->heap) {
fprintf(stderr, "no heap\n");
return -1;
}
p = b->heap;
prev = NULL;
while (p && p != b) {
prev = p;
p = p->next;
}
if (!p || p->free || p->reserved) {
if (!p)
fprintf(stderr, "block not found in heap\n");
else if (p->free)
fprintf(stderr, "block already free\n");
else
fprintf(stderr, "block is reserved\n");
return -1;
}
p->free = 1;
Join2Blocks(p);
if (prev)
Join2Blocks(prev);
return 0;
}

View File

@ -1,104 +0,0 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
* Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _via_ds_h_
#define _via_ds_h_
#include "drmP.h"
/* Set Data Structure */
#define SET_SIZE 5000
typedef unsigned long ITEM_TYPE;
typedef struct {
ITEM_TYPE val;
int alloc_next, free_next;
} list_item_t;
typedef struct {
int alloc;
int free;
int trace;
list_item_t list[SET_SIZE];
} set_t;
set_t *via_setInit(void);
int via_setAdd(set_t * set, ITEM_TYPE item);
int via_setDel(set_t * set, ITEM_TYPE item);
int via_setFirst(set_t * set, ITEM_TYPE * item);
int via_setNext(set_t * set, ITEM_TYPE * item);
int via_setDestroy(set_t * set);
#endif
#ifndef MM_INC
#define MM_INC
struct mem_block_t {
struct mem_block_t *next;
struct mem_block_t *heap;
int ofs, size;
int align;
unsigned int free:1;
unsigned int reserved:1;
};
typedef struct mem_block_t TMemBlock;
typedef struct mem_block_t *PMemBlock;
/* a heap is just the first block in a chain */
typedef struct mem_block_t memHeap_t;
static __inline__ int mmBlockSize(PMemBlock b)
{
return b->size;
}
static __inline__ int mmOffset(PMemBlock b)
{
return b->ofs;
}
static __inline__ void mmMarkReserved(PMemBlock b)
{
b->reserved = 1;
}
/*
* input: total size in bytes
* return: a heap pointer if OK, NULL if error
*/
memHeap_t *via_mmInit(int ofs, int size);
PMemBlock via_mmAllocMem(memHeap_t * heap, int size, int align2,
int startSearch);
/*
* Free block starts at offset
* input: pointer to a block
* return: 0 if OK, -1 if error
*/
int via_mmFreeMem(PMemBlock b);
#endif

View File

@ -1,392 +0,0 @@
/* via_irq.c
*
* Copyright 2004 BEAM Ltd.
* Copyright 2002 Tungsten Graphics, Inc.
* Copyright 2005 Thomas Hellstrom.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BEAM LTD, TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Terry Barnaby <terry1@beam.ltd.uk>
* Keith Whitwell <keith@tungstengraphics.com>
* Thomas Hellstrom <unichrome@shipmail.org>
*
* This code provides standard DRM access to the Via Unichrome / Pro Vertical blank
* interrupt, as well as an infrastructure to handle other interrupts of the chip.
* The refresh rate is also calculated for video playback sync purposes.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: via_irq.c,v 1.4 2011/02/24 07:59:44 mrg Exp $");
#include "drmP.h"
#include "drm.h"
#include "via_drm.h"
#include "via_drv.h"
#define VIA_REG_INTERRUPT 0x200
/* VIA_REG_INTERRUPT */
#define VIA_IRQ_GLOBAL (1 << 31)
#define VIA_IRQ_VBLANK_ENABLE (1 << 19)
#define VIA_IRQ_VBLANK_PENDING (1 << 3)
#define VIA_IRQ_HQV0_ENABLE (1 << 11)
#define VIA_IRQ_HQV1_ENABLE (1 << 25)
#define VIA_IRQ_HQV0_PENDING (1 << 9)
#define VIA_IRQ_HQV1_PENDING (1 << 10)
#define VIA_IRQ_DMA0_DD_ENABLE (1 << 20)
#define VIA_IRQ_DMA0_TD_ENABLE (1 << 21)
#define VIA_IRQ_DMA1_DD_ENABLE (1 << 22)
#define VIA_IRQ_DMA1_TD_ENABLE (1 << 23)
#define VIA_IRQ_DMA0_DD_PENDING (1 << 4)
#define VIA_IRQ_DMA0_TD_PENDING (1 << 5)
#define VIA_IRQ_DMA1_DD_PENDING (1 << 6)
#define VIA_IRQ_DMA1_TD_PENDING (1 << 7)
/*
* Device-specific IRQs go here. This type might need to be extended with
* the register if there are multiple IRQ control registers.
* Currently we activate the HQV interrupts of Unichrome Pro group A.
*/
static maskarray_t via_pro_group_a_irqs[] = {
{VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010,
0x00000000 },
{VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010,
0x00000000 },
{VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0,
VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
{VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
};
static int via_num_pro_group_a = DRM_ARRAY_SIZE(via_pro_group_a_irqs);
static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3};
static maskarray_t via_unichrome_irqs[] = {
{VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0,
VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
{VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}
};
static int via_num_unichrome = DRM_ARRAY_SIZE(via_unichrome_irqs);
static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1};
static unsigned time_diff(struct timeval *now, struct timeval *then)
{
return (now->tv_usec >= then->tv_usec) ?
now->tv_usec - then->tv_usec :
1000000 - (then->tv_usec - now->tv_usec);
}
uint32_t via_get_vblank_counter(struct drm_device *dev, unsigned int crtc)
{
drm_via_private_t *dev_priv = dev->dev_private;
if (crtc != 0)
return 0;
return atomic_read(&dev_priv->vbl_received);
}
irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
uint32_t status;
int handled = 0;
struct timeval cur_vblank;
drm_via_irq_t *cur_irq = dev_priv->via_irqs;
int i;
status = VIA_READ(VIA_REG_INTERRUPT);
if (status & VIA_IRQ_VBLANK_PENDING) {
atomic_inc(&dev_priv->vbl_received);
if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) {
microtime(&cur_vblank);
if (dev_priv->last_vblank_valid) {
dev_priv->usec_per_vblank =
time_diff(&cur_vblank,
&dev_priv->last_vblank) >> 4;
}
dev_priv->last_vblank = cur_vblank;
dev_priv->last_vblank_valid = 1;
}
if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) {
DRM_DEBUG("US per vblank is: %u\n",
dev_priv->usec_per_vblank);
}
drm_handle_vblank(dev, 0);
handled = 1;
}
for (i = 0; i < dev_priv->num_irqs; ++i) {
if (status & cur_irq->pending_mask) {
atomic_inc(&cur_irq->irq_received);
DRM_WAKEUP(&cur_irq->irq_queue);
handled = 1;
if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) {
via_dmablit_handler(dev, 0, 1);
} else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) {
via_dmablit_handler(dev, 1, 1);
}
}
cur_irq++;
}
/* Acknowlege interrupts */
VIA_WRITE(VIA_REG_INTERRUPT, status);
if (handled)
return IRQ_HANDLED;
else
return IRQ_NONE;
}
static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
{
uint32_t status;
if (dev_priv) {
/* Acknowlege interrupts */
status = VIA_READ(VIA_REG_INTERRUPT);
VIA_WRITE(VIA_REG_INTERRUPT, status |
dev_priv->irq_pending_mask);
}
}
int via_enable_vblank(struct drm_device *dev, unsigned int crtc)
{
drm_via_private_t *dev_priv = dev->dev_private;
uint32_t status;
if (crtc != 0) {
DRM_ERROR("%s: bad crtc %d\n", __func__, crtc);
return -EINVAL;
}
status = VIA_READ(VIA_REG_INTERRUPT);
VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE);
VIA_WRITE8(0x83d4, 0x11);
VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
return 0;
}
void via_disable_vblank(struct drm_device *dev, unsigned int crtc)
{
drm_via_private_t *dev_priv = dev->dev_private;
VIA_WRITE8(0x83d4, 0x11);
VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
if (crtc != 0)
DRM_ERROR("%s: bad crtc %d\n", __func__, crtc);
}
static int
via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequence,
unsigned int *sequence)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
unsigned int cur_irq_sequence;
drm_via_irq_t *cur_irq;
int ret = 0;
maskarray_t *masks;
int real_irq;
DRM_DEBUG("\n");
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
if (irq >= drm_via_irq_num) {
DRM_ERROR("Trying to wait on unknown irq %d\n", irq);
return -EINVAL;
}
real_irq = dev_priv->irq_map[irq];
if (real_irq < 0) {
DRM_ERROR("Video IRQ %d not available on this hardware.\n",
irq);
return -EINVAL;
}
masks = dev_priv->irq_masks;
cur_irq = dev_priv->via_irqs + real_irq;
if (masks[real_irq][2] && !force_sequence) {
DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
((VIA_READ(masks[irq][2]) & masks[irq][3]) ==
masks[irq][4]));
cur_irq_sequence = atomic_read(&cur_irq->irq_received);
} else {
DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
(((cur_irq_sequence =
atomic_read(&cur_irq->irq_received)) -
*sequence) <= (1 << 23)));
}
*sequence = cur_irq_sequence;
return ret;
}
/*
* drm_dma.h hooks
*/
void via_driver_irq_preinstall(struct drm_device * dev)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
uint32_t status;
drm_via_irq_t *cur_irq;
int i;
DRM_DEBUG("dev_priv: %p\n", dev_priv);
if (dev_priv) {
cur_irq = dev_priv->via_irqs;
dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE;
dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING;
if (dev_priv->chipset == VIA_PRO_GROUP_A ||
dev_priv->chipset == VIA_DX9_0) {
dev_priv->irq_masks = via_pro_group_a_irqs;
dev_priv->num_irqs = via_num_pro_group_a;
dev_priv->irq_map = via_irqmap_pro_group_a;
} else {
dev_priv->irq_masks = via_unichrome_irqs;
dev_priv->num_irqs = via_num_unichrome;
dev_priv->irq_map = via_irqmap_unichrome;
}
for (i = 0; i < dev_priv->num_irqs; ++i) {
atomic_set(&cur_irq->irq_received, 0);
cur_irq->enable_mask = dev_priv->irq_masks[i][0];
cur_irq->pending_mask = dev_priv->irq_masks[i][1];
DRM_INIT_WAITQUEUE(&cur_irq->irq_queue);
dev_priv->irq_enable_mask |= cur_irq->enable_mask;
dev_priv->irq_pending_mask |= cur_irq->pending_mask;
cur_irq++;
DRM_DEBUG("Initializing IRQ %d\n", i);
}
dev_priv->last_vblank_valid = 0;
/* Clear VSync interrupt regs */
status = VIA_READ(VIA_REG_INTERRUPT);
VIA_WRITE(VIA_REG_INTERRUPT, status &
~(dev_priv->irq_enable_mask));
/* Clear bits if they're already high */
viadrv_acknowledge_irqs(dev_priv);
}
}
int via_driver_irq_postinstall(struct drm_device *dev)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
uint32_t status;
DRM_DEBUG("via_driver_irq_postinstall\n");
if (!dev_priv)
return -EINVAL;
status = VIA_READ(VIA_REG_INTERRUPT);
VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
| dev_priv->irq_enable_mask);
/* Some magic, oh for some data sheets ! */
VIA_WRITE8(0x83d4, 0x11);
VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
return 0;
}
void via_driver_irq_uninstall(struct drm_device * dev)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
uint32_t status;
DRM_DEBUG("\n");
if (dev_priv) {
/* Some more magic, oh for some data sheets ! */
VIA_WRITE8(0x83d4, 0x11);
VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
status = VIA_READ(VIA_REG_INTERRUPT);
VIA_WRITE(VIA_REG_INTERRUPT, status &
~(VIA_IRQ_VBLANK_ENABLE | dev_priv->irq_enable_mask));
}
}
int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_irqwait_t *irqwait = data;
struct timeval now;
int ret = 0;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
drm_via_irq_t *cur_irq = dev_priv->via_irqs;
int force_sequence;
if (irqwait->request.irq >= dev_priv->num_irqs) {
DRM_ERROR("Trying to wait on unknown irq %d\n",
irqwait->request.irq);
return -EINVAL;
}
cur_irq += irqwait->request.irq;
switch (irqwait->request.type & ~VIA_IRQ_FLAGS_MASK) {
case VIA_IRQ_RELATIVE:
irqwait->request.sequence +=
atomic_read(&cur_irq->irq_received);
irqwait->request.type &= ~_DRM_VBLANK_RELATIVE;
case VIA_IRQ_ABSOLUTE:
break;
default:
return -EINVAL;
}
if (irqwait->request.type & VIA_IRQ_SIGNAL) {
DRM_ERROR("Signals on Via IRQs not implemented yet.\n");
return -EINVAL;
}
force_sequence = (irqwait->request.type & VIA_IRQ_FORCE_SEQUENCE);
ret = via_driver_irq_wait(dev, irqwait->request.irq, force_sequence,
&irqwait->request.sequence);
microtime(&now);
irqwait->reply.tval_sec = now.tv_sec;
irqwait->reply.tval_usec = now.tv_usec;
return ret;
}

View File

@ -1,137 +0,0 @@
/*-
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: via_map.c,v 1.3 2011/02/18 14:26:10 jmcneill Exp $");
#include "drmP.h"
#include "via_drm.h"
#include "via_drv.h"
static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init)
{
drm_via_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("\n");
dev_priv->sarea = drm_getsarea(dev);
if (!dev_priv->sarea) {
DRM_ERROR("could not find sarea!\n");
dev->dev_private = (void *)dev_priv;
via_do_cleanup_map(dev);
return -EINVAL;
}
dev_priv->fb = drm_core_findmap(dev, init->fb_offset);
if (!dev_priv->fb) {
DRM_ERROR("could not find framebuffer!\n");
dev->dev_private = (void *)dev_priv;
via_do_cleanup_map(dev);
return -EINVAL;
}
dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
if (!dev_priv->mmio) {
DRM_ERROR("could not find mmio region!\n");
dev->dev_private = (void *)dev_priv;
via_do_cleanup_map(dev);
return -EINVAL;
}
dev_priv->sarea_priv =
(drm_via_sarea_t *) ((u8 *) dev_priv->sarea->handle +
init->sarea_priv_offset);
dev_priv->agpAddr = init->agpAddr;
via_init_futex(dev_priv);
via_init_dmablit(dev);
dev->dev_private = (void *)dev_priv;
return 0;
}
int via_do_cleanup_map(struct drm_device * dev)
{
via_dma_cleanup(dev);
return 0;
}
int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_init_t *init = data;
DRM_DEBUG("\n");
switch (init->func) {
case VIA_INIT_MAP:
return via_do_init_map(dev, init);
case VIA_CLEANUP_MAP:
return via_do_cleanup_map(dev);
}
return -EINVAL;
}
int via_driver_load(struct drm_device *dev, unsigned long chipset)
{
drm_via_private_t *dev_priv;
int ret = 0;
dev_priv = drm_alloc(sizeof(drm_via_private_t), DRM_MEM_DRIVER);
if (dev_priv == NULL)
return -ENOMEM;
dev->dev_private = (void *)dev_priv;
dev_priv->chipset = chipset;
ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
if (ret) {
drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
return ret;
}
ret = drm_vblank_init(dev, 1);
if (ret) {
drm_sman_takedown(&dev_priv->sman);
drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
return ret;
}
return 0;
}
int via_driver_unload(struct drm_device *dev)
{
drm_via_private_t *dev_priv = dev->dev_private;
drm_sman_takedown(&dev_priv->sman);
drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
dev->dev_private = NULL;
return 0;
}

View File

@ -1,180 +0,0 @@
/*-
* Copyright 2006 Tungsten Graphics Inc., Bismarck, ND., USA.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: via_mm.c,v 1.3 2011/02/18 14:26:10 jmcneill Exp $");
#include "drmP.h"
#include "via_drm.h"
#include "via_drv.h"
#include "drm_sman.h"
#define VIA_MM_ALIGN_SHIFT 4
#define VIA_MM_ALIGN_MASK ( (1 << VIA_MM_ALIGN_SHIFT) - 1)
int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_agp_t *agp = data;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
int ret;
ret = drm_sman_set_range(&dev_priv->sman, VIA_MEM_AGP, 0,
agp->size >> VIA_MM_ALIGN_SHIFT);
if (ret) {
DRM_ERROR("AGP memory manager initialisation error\n");
return ret;
}
dev_priv->agp_initialized = 1;
dev_priv->agp_offset = agp->offset;
DRM_DEBUG("offset = %u, size = %u\n", agp->offset, agp->size);
return 0;
}
int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_fb_t *fb = data;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
int ret;
ret = drm_sman_set_range(&dev_priv->sman, VIA_MEM_VIDEO, 0,
fb->size >> VIA_MM_ALIGN_SHIFT);
if (ret) {
DRM_ERROR("VRAM memory manager initialisation error\n");
return ret;
}
dev_priv->vram_initialized = 1;
dev_priv->vram_offset = fb->offset;
DRM_DEBUG("offset = %u, size = %u\n", fb->offset, fb->size);
return 0;
}
int via_final_context(struct drm_device *dev, int context)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
via_release_futex(dev_priv, context);
#ifdef __linux__
/* Linux specific until context tracking code gets ported to BSD */
/* Last context, perform cleanup */
if (dev->ctx_count == 1 && dev->dev_private) {
DRM_DEBUG("Last Context\n");
drm_irq_uninstall(dev);
via_cleanup_futex(dev_priv);
via_do_cleanup_map(dev);
}
#endif
return 1;
}
void via_lastclose(struct drm_device *dev)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
if (!dev_priv)
return;
drm_sman_cleanup(&dev_priv->sman);
dev_priv->vram_initialized = 0;
dev_priv->agp_initialized = 0;
}
int via_mem_alloc(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
drm_via_mem_t *mem = data;
int retval = 0;
struct drm_memblock_item *item;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
unsigned long tmpSize;
if (mem->type > VIA_MEM_AGP) {
DRM_ERROR("Unknown memory type allocation\n");
return -EINVAL;
}
if (0 == ((mem->type == VIA_MEM_VIDEO) ? dev_priv->vram_initialized :
dev_priv->agp_initialized)) {
DRM_ERROR
("Attempt to allocate from uninitialized memory manager.\n");
return -EINVAL;
}
tmpSize = (mem->size + VIA_MM_ALIGN_MASK) >> VIA_MM_ALIGN_SHIFT;
item = drm_sman_alloc(&dev_priv->sman, mem->type, tmpSize, 0,
(unsigned long)file_priv);
if (item) {
mem->offset = ((mem->type == VIA_MEM_VIDEO) ?
dev_priv->vram_offset : dev_priv->agp_offset) +
(item->mm->
offset(item->mm, item->mm_info) << VIA_MM_ALIGN_SHIFT);
mem->index = item->user_hash.key;
} else {
mem->offset = 0;
mem->size = 0;
mem->index = 0;
DRM_DEBUG("Video memory allocation failed\n");
retval = -ENOMEM;
}
return retval;
}
int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_private_t *dev_priv = dev->dev_private;
drm_via_mem_t *mem = data;
int ret;
ret = drm_sman_free_key(&dev_priv->sman, mem->index);
DRM_DEBUG("free = 0x%lx\n", mem->index);
return ret;
}
void via_reclaim_buffers_locked(struct drm_device * dev,
struct drm_file *file_priv)
{
drm_via_private_t *dev_priv = dev->dev_private;
if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)file_priv))
return;
if (dev->driver->dma_quiescent)
dev->driver->dma_quiescent(dev);
drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv);
return;
}

View File

@ -1,40 +0,0 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _via_drm_mm_h_
#define _via_drm_mm_h_
typedef struct {
unsigned int context;
unsigned int size;
unsigned long offset;
unsigned long free;
} drm_via_mm_t;
typedef struct {
unsigned int size;
unsigned long handle;
void *virtual;
} drm_via_dma_t;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,62 +0,0 @@
/*-
* Copyright 2004 The Unichrome Project. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE UNICHROME PROJECT, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Author: Thomas Hellström 2004.
*/
#ifndef _VIA_VERIFIER_H_
#define _VIA_VERIFIER_H_
typedef enum {
no_sequence = 0,
z_address,
dest_address,
tex_address
} drm_via_sequence_t;
typedef struct {
unsigned texture;
uint32_t z_addr;
uint32_t d_addr;
uint32_t t_addr[2][10];
uint32_t pitch[2][10];
uint32_t height[2][10];
uint32_t tex_level_lo[2];
uint32_t tex_level_hi[2];
uint32_t tex_palette_size[2];
uint32_t tex_npot[2];
drm_via_sequence_t unfinished;
int agp_texture;
int multitex;
struct drm_device *dev;
drm_local_map_t *map_cache;
uint32_t vertex_count;
int agp;
const uint32_t *buf_start;
} drm_via_state_t;
extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
struct drm_device * dev, int agp);
extern int via_parse_command_stream(struct drm_device *dev, const uint32_t *buf,
unsigned int size);
#endif

View File

@ -1,96 +0,0 @@
/*-
* Copyright 2005 Thomas Hellstrom. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S), AND/OR THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Author: Thomas Hellstrom 2005.
*
* Video and XvMC related functions.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: via_video.c,v 1.2 2011/02/18 14:26:10 jmcneill Exp $");
#include "drmP.h"
#include "via_drm.h"
#include "via_drv.h"
void via_init_futex(drm_via_private_t * dev_priv)
{
unsigned int i;
DRM_DEBUG("\n");
for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
DRM_INIT_WAITQUEUE(&(dev_priv->decoder_queue[i]));
XVMCLOCKPTR(dev_priv->sarea_priv, i)->lock = 0;
}
}
void via_cleanup_futex(drm_via_private_t * dev_priv)
{
}
void via_release_futex(drm_via_private_t * dev_priv, int context)
{
unsigned int i;
volatile int *lock;
if (!dev_priv->sarea_priv)
return;
for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
lock = (volatile int *)XVMCLOCKPTR(dev_priv->sarea_priv, i);
if ((_DRM_LOCKING_CONTEXT(*lock) == context)) {
if (_DRM_LOCK_IS_HELD(*lock)
&& (*lock & _DRM_LOCK_CONT)) {
DRM_WAKEUP(&(dev_priv->decoder_queue[i]));
}
*lock = 0;
}
}
}
int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_futex_t *fx = data;
volatile int *lock;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
drm_via_sarea_t *sAPriv = dev_priv->sarea_priv;
int ret = 0;
DRM_DEBUG("\n");
if (fx->lock >= VIA_NR_XVMC_LOCKS)
return -EFAULT;
lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx->lock);
switch (fx->func) {
case VIA_FUTEX_WAIT:
DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx->lock],
(fx->ms / 10) * (DRM_HZ / 100), *lock != fx->val);
return ret;
case VIA_FUTEX_WAKE:
DRM_WAKEUP(&(dev_priv->decoder_queue[fx->lock]));
return 0;
}
return 0;
}

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.205 2018/06/06 16:46:02 jakllsch Exp $
# $NetBSD: Makefile,v 1.206 2018/07/10 17:01:43 maya Exp $
.include <bsd.own.mk>
@ -284,7 +284,6 @@ SUBDIR+= savagedrm
SUBDIR+= sisdrm
SUBDIR+= tdfxdrm
SUBDIR+= viac7temp
SUBDIR+= viadrm
SUBDIR+= viadrmums
.endif

View File

@ -1,24 +0,0 @@
# $NetBSD: Makefile,v 1.3 2011/02/18 14:26:52 jmcneill Exp $
.include "../Makefile.inc"
.PATH: ${S}/external/bsd/drm/dist/bsd-core
.PATH: ${S}/external/bsd/drm/dist/shared-core
KMOD= viadrm
IOCONF= viadrm.ioconf
SRCS= via_drv.c
SRCS+= via_dma.c
SRCS+= via_dmablit.c
SRCS+= via_ds.c
SRCS+= via_irq.c
SRCS+= via_map.c
SRCS+= via_mm.c
SRCS+= via_verifier.c
SRCS+= via_video.c
CPPFLAGS+= -I${S}/external/bsd/drm/dist/bsd-core \
-I${S}/external/bsd/drm/dist/shared-core
.include <bsd.kmodule.mk>

View File

@ -1,9 +0,0 @@
# $NetBSD: viadrm.ioconf,v 1.1 2011/02/18 02:00:36 jmcneill Exp $
ioconf viadrm
include "conf/files"
pseudo-root drm*
viadrm* at drm?