From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org
Subject: Re: via agp patches
Date: Fri, 30 May 2008 17:33:54 -0700 [thread overview]
Message-ID: <20080531003354.GC6208@suse.de> (raw)
In-Reply-To: <20080531003214.GA6208@suse.de>
This looks like the meatiest patch, with lots of support for new
hardware. Gotta love the StudlyCaps...
---
drivers/char/drm/Kconfig | 7
drivers/char/drm/Makefile | 2
drivers/char/drm/drm_pciids.h | 9
drivers/char/drm/via_chrome9_3d_reg.h | 395 +++++++++++
drivers/char/drm/via_chrome9_dma.c | 1147 ++++++++++++++++++++++++++++++++++
drivers/char/drm/via_chrome9_dma.h | 68 ++
drivers/char/drm/via_chrome9_drm.c | 993 +++++++++++++++++++++++++++++
drivers/char/drm/via_chrome9_drm.h | 423 ++++++++++++
drivers/char/drm/via_chrome9_drv.c | 153 ++++
drivers/char/drm/via_chrome9_drv.h | 145 ++++
drivers/char/drm/via_chrome9_mm.c | 388 +++++++++++
drivers/char/drm/via_chrome9_mm.h | 67 +
12 files changed, 3796 insertions(+), 1 deletion(-)
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -339,10 +339,17 @@
{0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
- {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
{0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
{0, 0, 0}
+
+#define via_chrome9DRV_PCI_IDS \
+ {0x1106, 0x3225, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_CHROME9_DX9_0}, \
+ {0x1106, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x1106, 0x1122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_CHROME9_PCIE_GROUP},\
+ {0, 0, 0}
+
#define i810_PCI_IDS \
{0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -99,6 +99,13 @@ config DRM_VIA
Choose this option if you have a Via unichrome or compatible video
chipset. If M is selected the module will be called via.
+config DRM_VIA_CHROME9
+ tristate "Via unichrome9 video cards"
+ depends on DRM
+ help
+ Choose this option if you have a Via unichrome9 or compatible video
+ chipset. If M is selected the module will be called via_chrome9.
+
config DRM_SAVAGE
tristate "Savage video cards"
depends on DRM
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -18,6 +18,7 @@ radeon-objs := radeon_drv.o radeon_cp.o
sis-objs := sis_drv.o sis_mm.o
savage-objs := savage_drv.o savage_bci.o savage_state.o
via-objs := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o
+via_chrome9-objs := via_chrome9_drv.o via_chrome9_drm.o via_chrome9_mm.o via_chrome9_dma.o
ifeq ($(CONFIG_COMPAT),y)
drm-objs += drm_ioc32.o
@@ -38,3 +39,4 @@ obj-$(CONFIG_DRM_I915) += i915.o
obj-$(CONFIG_DRM_SIS) += sis.o
obj-$(CONFIG_DRM_SAVAGE)+= savage.o
obj-$(CONFIG_DRM_VIA) +=via.o
+obj-$(CONFIG_DRM_VIA_CHROME9) += via_chrome9.o
--- /dev/null
+++ b/drivers/char/drm/via_chrome9_3d_reg.h
@@ -0,0 +1,395 @@
+/*
+ * 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_CHROME9_3D_REG_H
+#define VIA_CHROME9_3D_REG_H
+#define GetMMIORegister(base, offset) \
+ (*(volatile unsigned int *)(void *)(((unsigned char *)(base)) + \
+ (offset)))
+#define SetMMIORegister(base, offset, val) \
+ (*(volatile unsigned int *)(void *)(((unsigned char *)(base)) + \
+ (offset)) = (val))
+
+#define GetMMIORegisterU8(base, offset) \
+ (*(volatile unsigned char *)(void *)(((unsigned char *)(base)) + \
+ (offset)))
+#define SetMMIORegisterU8(base, offset, val) \
+ (*(volatile unsigned char *)(void *)(((unsigned char *)(base)) + \
+ (offset)) = (val))
+
+#define BCI_SEND(bci, value) (*(bci)++ = (unsigned long)(value))
+#define BCI_SET_STREAM_REGISTER(bci_base, bci_index, reg_value) \
+do { \
+ unsigned long cmd; \
+ \
+ cmd = (0x90000000 \
+ | (1<<16) /* stream processor register */ \
+ | (bci_index & 0x3FFC)); /* MMIO register address */ \
+ BCI_SEND(bci_base, cmd); \
+ BCI_SEND(bci_base, reg_value); \
+ } while (0)
+
+/* Command Header Type */
+
+#define INV_AGPHeader0 0xFE000000
+#define INV_AGPHeader1 0xFE010000
+#define INV_AGPHeader2 0xFE020000
+#define INV_AGPHeader3 0xFE030000
+#define INV_AGPHeader4 0xFE040000
+#define INV_AGPHeader5 0xFE050000
+#define INV_AGPHeader6 0xFE060000
+#define INV_AGPHeader7 0xFE070000
+#define INV_AGPHeader82 0xFE820000
+#define INV_AGPHeader_MASK 0xFFFF0000
+
+/*send pause address of AGP ring command buffer via_chrome9 this IO port*/
+#define INV_REG_PCIPAUSE 0x294
+#define INV_REG_PCIPAUSE_ENABLE 0x4
+
+#define INV_CMDBUF_THRESHOLD (8)
+#define INV_QW_PAUSE_ALIGN 0x40
+
+/* Transmission IO Space*/
+#define INV_REG_CR_TRANS 0x041C
+#define INV_REG_CR_BEGIN 0x0420
+#define INV_REG_CR_END 0x0438
+
+#define INV_REG_3D_TRANS 0x043C
+#define INV_REG_3D_BEGIN 0x0440
+#define INV_REG_3D_END 0x06FC
+#define INV_REG_23D_WAIT 0x326C
+/*3D / 2D ID Control (Only For Group A)*/
+#define INV_REG_2D3D_ID_CTRL 0x060
+
+
+/* Engine Status */
+
+#define INV_RB_ENG_STATUS 0x0400
+#define INV_ENG_BUSY_HQV0 0x00040000
+#define INV_ENG_BUSY_HQV1 0x00020000
+#define INV_ENG_BUSY_CR 0x00000010
+#define INV_ENG_BUSY_MPEG 0x00000008
+#define INV_ENG_BUSY_VQ 0x00000004
+#define INV_ENG_BUSY_2D 0x00000002
+#define INV_ENG_BUSY_3D 0x00001FE1
+#define INV_ENG_BUSY_ALL \
+ (INV_ENG_BUSY_2D | INV_ENG_BUSY_3D | INV_ENG_BUSY_CR)
+
+/* Command Queue Status*/
+#define INV_RB_VQ_STATUS 0x0448
+#define INV_VQ_FULL 0x40000000
+
+/* AGP command buffer pointer current position*/
+#define INV_RB_AGPCMD_CURRADDR 0x043C
+
+/* AGP command buffer status*/
+#define INV_RB_AGPCMD_STATUS 0x0444
+#define INV_AGPCMD_InPause 0x80000000
+
+/*AGP command buffer pause address*/
+#define INV_RB_AGPCMD_PAUSEADDR 0x045C
+
+/*AGP command buffer jump address*/
+#define INV_RB_AGPCMD_JUMPADDR 0x0460
+
+/*AGP command buffer start address*/
+#define INV_RB_AGPCMD_STARTADDR 0x0464
+
+
+/* Constants */
+#define NUMBER_OF_EVENT_TAGS 1024
+#define NUMBER_OF_APERTURES_CLB 16
+
+/* Register definition */
+#define HW_SHADOW_ADDR 0x8520
+#define HW_GARTTABLE_ADDR 0x8540
+
+#define INV_HSWFlag_DBGMASK 0x00000FFF
+#define INV_HSWFlag_ENCODEMASK 0x007FFFF0
+#define INV_HSWFlag_ADDRSHFT 8
+#define INV_HSWFlag_DECODEMASK \
+ (INV_HSWFlag_ENCODEMASK << INV_HSWFlag_ADDRSHFT)
+#define INV_HSWFlag_ADDR_ENCODE(x) 0xCC000000
+#define INV_HSWFlag_ADDR_DECODE(x) \
+ (((unsigned int)x & INV_HSWFlag_DECODEMASK) >> INV_HSWFlag_ADDRSHFT)
+
+
+#define INV_SubA_HAGPBstL 0x60000000
+#define INV_SubA_HAGPBstH 0x61000000
+#define INV_SubA_HAGPBendL 0x62000000
+#define INV_SubA_HAGPBendH 0x63000000
+#define INV_SubA_HAGPBpL 0x64000000
+#define INV_SubA_HAGPBpID 0x65000000
+#define INV_HAGPBpID_PAUSE 0x00000000
+#define INV_HAGPBpID_JUMP 0x00000100
+#define INV_HAGPBpID_STOP 0x00000200
+
+#define INV_HAGPBpH_MASK 0x000000FF
+#define INV_HAGPBpH_SHFT 0
+
+#define INV_SubA_HAGPBjumpL 0x66000000
+#define INV_SubA_HAGPBjumpH 0x67000000
+#define INV_HAGPBjumpH_MASK 0x000000FF
+#define INV_HAGPBjumpH_SHFT 0
+
+#define INV_SubA_HFthRCM 0x68000000
+#define INV_HFthRCM_MASK 0x003F0000
+#define INV_HFthRCM_SHFT 16
+#define INV_HFthRCM_8 0x00080000
+#define INV_HFthRCM_10 0x000A0000
+#define INV_HFthRCM_18 0x00120000
+#define INV_HFthRCM_24 0x00180000
+#define INV_HFthRCM_32 0x00200000
+
+#define INV_HAGPBClear 0x00000008
+
+#define INV_HRSTTrig_RestoreAGP 0x00000004
+#define INV_HRSTTrig_RestoreAll 0x00000002
+#define INV_HAGPBTrig 0x00000001
+
+#define INV_ParaSubType_MASK 0xff000000
+#define INV_ParaType_MASK 0x00ff0000
+#define INV_ParaOS_MASK 0x0000ff00
+#define INV_ParaAdr_MASK 0x000000ff
+#define INV_ParaSubType_SHIFT 24
+#define INV_ParaType_SHIFT 16
+#define INV_ParaOS_SHIFT 8
+#define INV_ParaAdr_SHIFT 0
+
+#define INV_ParaType_Vdata 0x00000000
+#define INV_ParaType_Attr 0x00010000
+#define INV_ParaType_Tex 0x00020000
+#define INV_ParaType_Pal 0x00030000
+#define INV_ParaType_FVF 0x00040000
+#define INV_ParaType_PreCR 0x00100000
+#define INV_ParaType_CR 0x00110000
+#define INV_ParaType_Cfg 0x00fe0000
+#define INV_ParaType_Dummy 0x00300000
+
+#define INV_HWBasL_MASK 0x00FFFFFF
+#define INV_HWBasH_MASK 0xFF000000
+#define INV_HWBasH_SHFT 24
+#define INV_HWBasL(x) ((unsigned int)(x) & INV_HWBasL_MASK)
+#define INV_HWBasH(x) ((unsigned int)(x) >> INV_HWBasH_SHFT)
+#define INV_HWBas256(x) ((unsigned int)(x) >> 8)
+#define INV_HWPit32(x) ((unsigned int)(x) >> 5)
+
+/* Read Back Register Setting */
+#define INV_SubA_HSetRBGID 0x02000000
+#define INV_HSetRBGID_CR 0x00000000
+#define INV_HSetRBGID_FE 0x00000001
+#define INV_HSetRBGID_PE 0x00000002
+#define INV_HSetRBGID_RC 0x00000003
+#define INV_HSetRBGID_PS 0x00000004
+#define INV_HSetRBGID_XE 0x00000005
+#define INV_HSetRBGID_BE 0x00000006
+
+
+struct drm_clb_event_tag_info {
+ unsigned int *linear_address;
+ unsigned int *event_tag_linear_address;
+ int usage[NUMBER_OF_EVENT_TAGS];
+ unsigned int pid[NUMBER_OF_EVENT_TAGS];
+};
+
+static inline int IS_AGPHEADER_INV(unsigned int data)
+{
+ switch (data & INV_AGPHeader_MASK) {
+ case INV_AGPHeader0:
+ case INV_AGPHeader1:
+ case INV_AGPHeader2:
+ case INV_AGPHeader3:
+ case INV_AGPHeader4:
+ case INV_AGPHeader5:
+ case INV_AGPHeader6:
+ case INV_AGPHeader7:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+/* Header0: 2D */
+#define ADDCmdHeader0_INVI(pCmd, dwCount) \
+{ \
+ /* 4 unsigned int align, insert NULL Command for padding */ \
+ while (((unsigned long *)(pCmd)) & 0xF) { \
+ *(pCmd)++ = 0xCC000000; \
+ } \
+ *(pCmd)++ = INV_AGPHeader0; \
+ *(pCmd)++ = (dwCount); \
+ *(pCmd)++ = 0; \
+ *(pCmd)++ = (unsigned int)INV_HSWFlag_ADDR_ENCODE(pCmd); \
+}
+
+/* Header1: 2D */
+#define ADDCmdHeader1_INVI(pCmd, dwAddr, dwCount) \
+{ \
+ /* 4 unsigned int align, insert NULL Command for padding */ \
+ while (((unsigned long *)(pCmd)) & 0xF) { \
+ *(pCmd)++ = 0xCC000000; \
+ } \
+ *(pCmd)++ = INV_AGPHeader1 | (dwAddr); \
+ *(pCmd)++ = (dwCount); \
+ *(pCmd)++ = 0; \
+ *(pCmd)++ = (unsigned int)INV_HSWFlag_ADDR_ENCODE(pCmd); \
+}
+
+/* Header2: CR/3D */
+#define ADDCmdHeader2_INVI(pCmd, dwAddr, dwType) \
+{ \
+ /* 4 unsigned int align, insert NULL Command for padding */ \
+ while (((unsigned int)(pCmd)) & 0xF) { \
+ *(pCmd)++ = 0xCC000000; \
+ } \
+ *(pCmd)++ = INV_AGPHeader2 | ((dwAddr)+4); \
+ *(pCmd)++ = (dwAddr); \
+ *(pCmd)++ = (dwType); \
+ *(pCmd)++ = (unsigned int)INV_HSWFlag_ADDR_ENCODE(pCmd); \
+}
+
+/* Header2: CR/3D with SW Flag */
+#define ADDCmdHeader2_SWFlag_INVI(pCmd, dwAddr, dwType, dwSWFlag) \
+{ \
+ /* 4 unsigned int align, insert NULL Command for padding */ \
+ while (((unsigned long *)(pCmd)) & 0xF) { \
+ *(pCmd)++ = 0xCC000000; \
+ } \
+ *(pCmd)++ = INV_AGPHeader2 | ((dwAddr)+4); \
+ *(pCmd)++ = (dwAddr); \
+ *(pCmd)++ = (dwType); \
+ *(pCmd)++ = (dwSWFlag); \
+}
+
+
+/* Header3: 3D */
+#define ADDCmdHeader3_INVI(pCmd, dwType, dwStart, dwCount) \
+{ \
+ /* 4 unsigned int align, insert NULL Command for padding */ \
+ while (((unsigned long *)(pCmd)) & 0xF) { \
+ *(pCmd)++ = 0xCC000000; \
+ } \
+ *(pCmd)++ = INV_AGPHeader3 | INV_REG_3D_TRANS; \
+ *(pCmd)++ = (dwCount); \
+ *(pCmd)++ = (dwType) | ((dwStart) & 0xFFFF); \
+ *(pCmd)++ = (unsigned int)INV_HSWFlag_ADDR_ENCODE(pCmd); \
+}
+
+/* Header3: 3D with SW Flag */
+#define ADDCmdHeader3_SWFlag_INVI(pCmd, dwType, dwStart, dwSWFlag, dwCount) \
+{ \
+ /* 4 unsigned int align, insert NULL Command for padding */ \
+ while (((unsigned long *)(pCmd)) & 0xF) { \
+ *(pCmd)++ = 0xCC000000; \
+ } \
+ *(pCmd)++ = INV_AGPHeader3 | INV_REG_3D_TRANS; \
+ *(pCmd)++ = (dwCount); \
+ *(pCmd)++ = (dwType) | ((dwStart) & 0xFFFF); \
+ *(pCmd)++ = (dwSWFlag); \
+}
+
+/* Header4: DVD */
+#define ADDCmdHeader4_INVI(pCmd, dwAddr, dwCount, id) \
+{ \
+ /* 4 unsigned int align, insert NULL Command for padding */ \
+ while (((unsigned long *)(pCmd)) & 0xF) { \
+ *(pCmd)++ = 0xCC000000; \
+ } \
+ *(pCmd)++ = INV_AGPHeader4 | (dwAddr); \
+ *(pCmd)++ = (dwCount); \
+ *(pCmd)++ = (id); \
+ *(pCmd)++ = 0; \
+}
+
+/* Header5: DVD */
+#define ADDCmdHeader5_INVI(pCmd, dwQWcount, id) \
+{ \
+ /* 4 unsigned int align, insert NULL Command for padding */ \
+ while (((unsigned long *)(pCmd)) & 0xF) { \
+ *(pCmd)++ = 0xCC000000; \
+ } \
+ *(pCmd)++ = INV_AGPHeader5; \
+ *(pCmd)++ = (dwQWcount); \
+ *(pCmd)++ = (id); \
+ *(pCmd)++ = 0; \
+}
+
+/* Header6: DEBUG */
+#define ADDCmdHeader6_INVI(pCmd) \
+{ \
+ /* 4 unsigned int align, insert NULL Command for padding */ \
+ while (((unsigned long *)(pCmd)) & 0xF) { \
+ *(pCmd)++ = 0xCC000000; \
+ } \
+ *(pCmd)++ = INV_AGPHeader6; \
+ *(pCmd)++ = 0; \
+ *(pCmd)++ = 0; \
+ *(pCmd)++ = 0; \
+}
+
+/* Header7: DMA */
+#define ADDCmdHeader7_INVI(pCmd, dwQWcount, id) \
+{ \
+ /* 4 unsigned int align, insert NULL Command for padding */ \
+ while (((unsigned long *)(pCmd)) & 0xF) { \
+ *(pCmd)++ = 0xCC000000; \
+ } \
+ *(pCmd)++ = INV_AGPHeader7; \
+ *(pCmd)++ = (dwQWcount); \
+ *(pCmd)++ = (id); \
+ *(pCmd)++ = 0; \
+}
+
+/* Header82: Branch buffer */
+#define ADDCmdHeader82_INVI(pCmd, dwAddr, dwType); \
+{ \
+ /* 4 unsigned int align, insert NULL Command for padding */ \
+ while (((unsigned long *)(pCmd)) & 0xF) { \
+ *(pCmd)++ = 0xCC000000; \
+ } \
+ *(pCmd)++ = INV_AGPHeader82 | ((dwAddr)+4); \
+ *(pCmd)++ = (dwAddr); \
+ *(pCmd)++ = (dwType); \
+ *(pCmd)++ = 0xCC000000; \
+}
+
+
+#define ADD2DCmd_INVI(pCmd, dwAddr, dwCmd) \
+{ \
+ *(pCmd)++ = (dwAddr); \
+ *(pCmd)++ = (dwCmd); \
+}
+
+#define ADDCmdData_INVI(pCmd, dwCmd) *(pCmd)++ = (dwCmd)
+
+#define ADDCmdDataStream_INVI(pCmdBuf, pCmd, dwCount) \
+{ \
+ memcpy((pCmdBuf), (pCmd), ((dwCount)<<2)); \
+ (pCmdBuf) += (dwCount); \
+}
+
+#endif
--- /dev/null
+++ b/drivers/char/drm/via_chrome9_dma.c
@@ -0,0 +1,1147 @@
+/*
+ * 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 "drmP.h"
+#include "drm.h"
+#include "via_chrome9_drm.h"
+#include "via_chrome9_drv.h"
+#include "via_chrome9_3d_reg.h"
+#include "via_chrome9_dma.h"
+
+#define NULLCOMMANDNUMBER 256
+unsigned int NULL_COMMAND_INV[4] =
+ { 0xCC000000, 0xCD000000, 0xCE000000, 0xCF000000 };
+
+void
+via_chrome9ke_assert(int a)
+{
+}
+
+unsigned int
+ProtectSizeValue(unsigned int size)
+{
+ unsigned int i;
+ for (i = 0; i < 8; i++)
+ if ((size > (1 << (i + 12)))
+ && (size <= (1 << (i + 13))))
+ return (i + 1);
+ return 0;
+}
+
+static unsigned int
+InitPCIEGART(struct drm_via_chrome9_private *dev_priv)
+{
+ unsigned int *pGARTTable;
+ unsigned int i, entries, GARTOffset;
+ unsigned char sr6a, sr6b, sr6c, sr6f, sr7b;
+
+ if (!dev_priv->pagetable_map.pagetable_size)
+ return 0;
+
+ entries = dev_priv->pagetable_map.pagetable_size / sizeof(unsigned int);
+
+ pGARTTable =
+ ioremap_nocache(dev_priv->fb_base_address +
+ dev_priv->pagetable_map.pagetable_offset,
+ dev_priv->pagetable_map.pagetable_size);
+ if (pGARTTable)
+ dev_priv->pagetable_map.pagetable_handle = pGARTTable;
+ else
+ return 0;
+
+ /*set gart table base */
+ GARTOffset = dev_priv->pagetable_map.pagetable_offset;
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c);
+ sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ sr6c &= (~0x80);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c);
+
+ sr6a = (unsigned char) ((GARTOffset & 0xff000) >> 12);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6a);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6a);
+
+ sr6b = (unsigned char) ((GARTOffset & 0xff00000) >> 20);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6b);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6b);
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c);
+ sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ sr6c |= ((unsigned char) ((GARTOffset >> 28) & 0x01));
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c);
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x7b);
+ sr7b = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ sr7b &= (~0x0f);
+ sr7b |= ProtectSizeValue(dev_priv->pagetable_map.pagetable_size);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr7b);
+
+ for (i = 0; i < entries; i++)
+ writel(0x80000000, pGARTTable + i);
+ /*flush */
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6f);
+ do {
+ sr6f = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ }
+ while (sr6f & 0x80)
+ ;
+
+ sr6f |= 0x80;
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6f);
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c);
+ sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ sr6c |= 0x80;
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c);
+
+ return 1;
+}
+
+
+static unsigned int *
+AllocAndBindPCIEMemory(struct drm_via_chrome9_private *dev_priv,
+ unsigned int size, unsigned int offset)
+{
+ unsigned int *addrlinear;
+ unsigned int *pGARTTable;
+ unsigned int entries, alignedoffset, i;
+ unsigned char sr6c, sr6f;
+
+ if (!size)
+ return NULL;
+
+ entries = (size + PAGE_SIZE - 1) / PAGE_SIZE;
+ alignedoffset = (offset + PAGE_SIZE - 1) / PAGE_SIZE;
+
+ if ((entries + alignedoffset) >
+ (dev_priv->pagetable_map.pagetable_size / sizeof(unsigned int)))
+ return NULL;
+
+ addrlinear =
+ __vmalloc(entries * PAGE_SIZE, GFP_KERNEL | __GFP_HIGHMEM,
+ PAGE_KERNEL_NOCACHE);
+
+ if (!addrlinear)
+ return NULL;
+
+ pGARTTable = dev_priv->pagetable_map.pagetable_handle;
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c);
+ sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ sr6c &= (~0x80);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c);
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6f);
+ do {
+ sr6f = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ }
+ while (sr6f & 0x80)
+ ;
+
+ for (i = 0; i < entries; i++)
+ writel(page_to_pfn
+ (vmalloc_to_page((void *) addrlinear + PAGE_SIZE * i)) &
+ 0x3fffffff, pGARTTable + i + alignedoffset);
+
+ sr6f |= 0x80;
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6f);
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c);
+ sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ sr6c |= 0x80;
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c);
+
+ return addrlinear;
+
+}
+
+void
+SetAGPDoubleCmd_inv(struct drm_device *dev)
+{
+ /* we now don't use double buffer */
+ return;
+}
+
+void
+SetAGPRingCmdRegs_inv(struct drm_device *dev)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ struct drm_via_chrome9_DMA_manager *lpcmDMAManager =
+ (struct drm_via_chrome9_DMA_manager *) dev_priv->dma_manager;
+ unsigned int AGPBufLinearBase = 0, AGPBufPhysicalBase = 0;
+ unsigned long *pFree;
+ unsigned int dwStart, dwEnd, dwPause, AGPCurrAddr, AGPCurStat, CurrAGP;
+ unsigned int dwReg60, dwReg61, dwReg62, dwReg63,
+ dwReg64, dwReg65, dwJump;
+
+ lpcmDMAManager->pFree = lpcmDMAManager->pBeg;
+
+ AGPBufLinearBase = (unsigned int) lpcmDMAManager->addr_linear;
+ AGPBufPhysicalBase =
+ (dev_priv->chip_agp ==
+ CHIP_PCIE) ? 0 : (unsigned int) dev->agp->base +
+ lpcmDMAManager->pPhysical;
+ /*add shadow offset */
+
+ CurrAGP =
+ GetMMIORegister(dev_priv->mmio->handle, INV_RB_AGPCMD_CURRADDR);
+ AGPCurStat =
+ GetMMIORegister(dev_priv->mmio->handle, INV_RB_AGPCMD_STATUS);
+
+ if (AGPCurStat & INV_AGPCMD_InPause) {
+ AGPCurrAddr =
+ GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ pFree = (unsigned long *) (AGPBufLinearBase + AGPCurrAddr -
+ AGPBufPhysicalBase);
+ ADDCmdHeader2_INVI(pFree, INV_REG_CR_TRANS, INV_ParaType_Dummy);
+ if (dev_priv->chip_sub_index == CHIP_H6S2)
+ do {
+ ADDCmdData_INVI(pFree, 0xCCCCCCC0);
+ ADDCmdData_INVI(pFree, 0xDDD00000);
+ }
+ while ((u32)((unsigned int) pFree) & 0x7f)
+ ;
+ /*for 8*128bit aligned */
+ else
+ do {
+ ADDCmdData_INVI(pFree, 0xCCCCCCC0);
+ ADDCmdData_INVI(pFree, 0xDDD00000);
+ }
+ while ((u32) ((unsigned int) pFree) & 0x1f)
+ ;
+ /*for 256bit aligned */
+ dwPause =
+ (u32) (((unsigned int) pFree) - AGPBufLinearBase +
+ AGPBufPhysicalBase - 16);
+
+ dwReg64 = INV_SubA_HAGPBpL | INV_HWBasL(dwPause);
+ dwReg65 =
+ INV_SubA_HAGPBpID | INV_HWBasH(dwPause) |
+ INV_HAGPBpID_STOP;
+
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS,
+ INV_ParaType_PreCR);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ dwReg64);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ dwReg65);
+
+ while ((GetMMIORegister
+ (dev_priv->mmio->handle,
+ INV_RB_ENG_STATUS) & INV_ENG_BUSY_ALL));
+ }
+ dwStart =
+ (u32) ((unsigned int) lpcmDMAManager->pBeg - AGPBufLinearBase +
+ AGPBufPhysicalBase);
+ dwEnd = (u32) ((unsigned int) lpcmDMAManager->pEnd - AGPBufLinearBase +
+ AGPBufPhysicalBase);
+
+ lpcmDMAManager->pFree = lpcmDMAManager->pBeg;
+ if (dev_priv->chip_sub_index == CHIP_H6S2) {
+ ADDCmdHeader2_INVI(lpcmDMAManager->pFree, INV_REG_CR_TRANS,
+ INV_ParaType_Dummy);
+ do {
+ ADDCmdData_INVI(lpcmDMAManager->pFree, 0xCCCCCCC0);
+ ADDCmdData_INVI(lpcmDMAManager->pFree, 0xDDD00000);
+ }
+ while ((u32)((unsigned long *) lpcmDMAManager->pFree) & 0x7f)
+ ;
+ }
+ dwJump = 0xFFFFFFF0;
+ dwPause =
+ (u32)(((unsigned int) lpcmDMAManager->pFree) -
+ 16 - AGPBufLinearBase + AGPBufPhysicalBase);
+
+ DRM_DEBUG("dwStart = %08x, dwEnd = %08x, dwPause = %08x\n", dwStart,
+ dwEnd, dwPause);
+
+ dwReg60 = INV_SubA_HAGPBstL | INV_HWBasL(dwStart);
+ dwReg61 = INV_SubA_HAGPBstH | INV_HWBasH(dwStart);
+ dwReg62 = INV_SubA_HAGPBendL | INV_HWBasL(dwEnd);
+ dwReg63 = INV_SubA_HAGPBendH | INV_HWBasH(dwEnd);
+ dwReg64 = INV_SubA_HAGPBpL | INV_HWBasL(dwPause);
+ dwReg65 = INV_SubA_HAGPBpID | INV_HWBasH(dwPause) | INV_HAGPBpID_PAUSE;
+
+ if (dev_priv->chip_sub_index == CHIP_H6S2)
+ dwReg60 |= 0x01;
+
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS,
+ INV_ParaType_PreCR);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg60);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg61);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg62);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg63);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg64);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg65);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ INV_SubA_HAGPBjumpL | INV_HWBasL(dwJump));
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ INV_SubA_HAGPBjumpH | INV_HWBasH(dwJump));
+
+ /* Trigger AGP cycle */
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ INV_SubA_HFthRCM | INV_HFthRCM_10 | INV_HAGPBTrig);
+
+ /*for debug */
+ CurrAGP =
+ GetMMIORegister(dev_priv->mmio->handle, INV_RB_AGPCMD_CURRADDR);
+
+ lpcmDMAManager->pInUseBySW = lpcmDMAManager->pFree;
+}
+
+/* Do hw intialization and determine whether to use dma or mmio to
+talk with hw */
+int
+via_chrome9_hw_init(struct drm_device *dev,
+ struct drm_via_chrome9_init *init)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ unsigned retval = 0;
+ unsigned int *pGARTTable, *addrlinear = NULL;
+ int pages;
+ struct drm_clb_event_tag_info *event_tag_info;
+ struct drm_via_chrome9_DMA_manager *lpcmDMAManager = NULL;
+
+ if (init->chip_agp == CHIP_PCIE) {
+ dev_priv->pagetable_map.pagetable_offset =
+ init->garttable_offset;
+ dev_priv->pagetable_map.pagetable_size = init->garttable_size;
+ dev_priv->agp_size = init->agp_tex_size;
+ /*Henry :prepare for PCIE texture buffer */
+ } else {
+ dev_priv->pagetable_map.pagetable_offset = 0;
+ dev_priv->pagetable_map.pagetable_size = 0;
+ }
+
+ dev_priv->dma_manager =
+ kmalloc(sizeof(struct drm_via_chrome9_DMA_manager), GFP_KERNEL);
+ if (!dev_priv->dma_manager) {
+ DRM_ERROR("could not allocate system for dma_manager!\n");
+ return -ENOMEM;
+ }
+
+ lpcmDMAManager =
+ (struct drm_via_chrome9_DMA_manager *) dev_priv->dma_manager;
+ ((struct drm_via_chrome9_DMA_manager *)
+ dev_priv->dma_manager)->DMASize = init->DMA_size;
+ ((struct drm_via_chrome9_DMA_manager *)
+ dev_priv->dma_manager)->pPhysical = init->DMA_phys_address;
+
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS, 0x00110000);
+ if (dev_priv->chip_sub_index == CHIP_H6S2) {
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ 0x06000000);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ 0x07100000);
+ } else {
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ 0x02000000);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ 0x03100000);
+ }
+
+ /* Specify fence command read back ID */
+ /* Default the read back ID is CR */
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS,
+ INV_ParaType_PreCR);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ INV_SubA_HSetRBGID | INV_HSetRBGID_CR);
+
+ DRM_DEBUG("begin to init\n");
+
+ if (dev_priv->chip_sub_index == CHIP_H6S2) {
+ dev_priv->pcie_vmalloc_nocache = 0;
+ if (dev_priv->pagetable_map.pagetable_size)
+ retval = InitPCIEGART(dev_priv);
+
+ if (retval && dev_priv->drm_agp_type != DRM_AGP_DISABLED) {
+ addrlinear =
+ AllocAndBindPCIEMemory(dev_priv,
+ lpcmDMAManager->DMASize +
+ dev_priv->agp_size, 0);
+ if (addrlinear) {
+ dev_priv->pcie_vmalloc_nocache = (unsigned long)
+ addrlinear;
+ } else {
+ dev_priv->bci_buffer =
+ vmalloc(MAX_BCI_BUFFER_SIZE);
+ dev_priv->drm_agp_type = DRM_AGP_DISABLED;
+ }
+ } else {
+ dev_priv->bci_buffer = vmalloc(MAX_BCI_BUFFER_SIZE);
+ dev_priv->drm_agp_type = DRM_AGP_DISABLED;
+ }
+ } else {
+ if (dev_priv->drm_agp_type != DRM_AGP_DISABLED) {
+ pGARTTable = NULL;
+ addrlinear = (unsigned int *)
+ ioremap(dev->agp->base +
+ lpcmDMAManager->pPhysical,
+ lpcmDMAManager->DMASize);
+ dev_priv->bci_buffer = NULL;
+ } else {
+ dev_priv->bci_buffer = vmalloc(MAX_BCI_BUFFER_SIZE);
+ /*Homer, BCI path always use this block of memory8 */
+ }
+ }
+
+ /*till here we have known whether support dma or not */
+ pages = dev->sg->pages;
+ event_tag_info = vmalloc(sizeof(struct drm_clb_event_tag_info));
+ memset(event_tag_info, 0, sizeof(struct drm_clb_event_tag_info));
+ if (!event_tag_info)
+ return DRM_ERROR(" event_tag_info allocate error!");
+
+ /* aligned to 16k alignment */
+ event_tag_info->linear_address =
+ (int
+ *) (((unsigned int) dev_priv->shadow_map.shadow_handle +
+ 0x3fff) & 0xffffc000);
+ event_tag_info->event_tag_linear_address =
+ event_tag_info->linear_address + 3;
+ dev_priv->event_tag_info = (void *) event_tag_info;
+ dev_priv->max_apertures = NUMBER_OF_APERTURES_CLB;
+
+ /* Initialize DMA data structure */
+ lpcmDMAManager->DMASize /= sizeof(unsigned int);
+ lpcmDMAManager->pBeg = addrlinear;
+ lpcmDMAManager->pFree = lpcmDMAManager->pBeg;
+ lpcmDMAManager->pInUseBySW = lpcmDMAManager->pBeg;
+ lpcmDMAManager->pInUseByHW = lpcmDMAManager->pBeg;
+ lpcmDMAManager->LastIssuedEventTag = (unsigned int) (unsigned long *)
+ lpcmDMAManager->pBeg;
+ lpcmDMAManager->ppInUseByHW =
+ (unsigned int **) ((char *) (dev_priv->mmio->handle) +
+ INV_RB_AGPCMD_CURRADDR);
+ lpcmDMAManager->bDMAAgp = dev_priv->chip_agp;
+ lpcmDMAManager->addr_linear = (unsigned int *) addrlinear;
+
+ if (dev_priv->drm_agp_type == DRM_AGP_DOUBLE_BUFFER) {
+ lpcmDMAManager->MaxKickoffSize = lpcmDMAManager->DMASize >> 1;
+ lpcmDMAManager->pEnd =
+ lpcmDMAManager->addr_linear +
+ (lpcmDMAManager->DMASize >> 1) - 1;
+ SetAGPDoubleCmd_inv(dev);
+ if (dev_priv->chip_sub_index == CHIP_H6S2) {
+ DRM_INFO("DMA buffer initialized finished. ");
+ DRM_INFO("Use PCIE Double Buffer type!\n");
+ DRM_INFO("Total PCIE DMA buffer size = %8d bytes. \n",
+ lpcmDMAManager->DMASize << 2);
+ } else {
+ DRM_INFO("DMA buffer initialized finished. ");
+ DRM_INFO("Use AGP Double Buffer type!\n");
+ DRM_INFO("Total AGP DMA buffer size = %8d bytes. \n",
+ lpcmDMAManager->DMASize << 2);
+ }
+ } else if (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER) {
+ lpcmDMAManager->MaxKickoffSize = lpcmDMAManager->DMASize;
+ lpcmDMAManager->pEnd =
+ lpcmDMAManager->addr_linear + lpcmDMAManager->DMASize;
+ SetAGPRingCmdRegs_inv(dev);
+ if (dev_priv->chip_sub_index == CHIP_H6S2) {
+ DRM_INFO("DMA buffer initialized finished. \n");
+ DRM_INFO("Use PCIE Ring Buffer type!");
+ DRM_INFO("Total PCIE DMA buffer size = %8d bytes. \n",
+ lpcmDMAManager->DMASize << 2);
+ } else {
+ DRM_INFO("DMA buffer initialized finished. ");
+ DRM_INFO("Use AGP Ring Buffer type!\n");
+ DRM_INFO("Total AGP DMA buffer size = %8d bytes. \n",
+ lpcmDMAManager->DMASize << 2);
+ }
+ } else if (dev_priv->drm_agp_type == DRM_AGP_DISABLED) {
+ lpcmDMAManager->MaxKickoffSize = 0x0;
+ if (dev_priv->chip_sub_index == CHIP_H6S2)
+ DRM_INFO("PCIE init failed! Use PCI\n");
+ else
+ DRM_INFO("AGP init failed! Use PCI\n");
+ }
+ return 0;
+}
+
+static void
+kickoff_bci_inv(struct drm_via_chrome9_private *dev_priv,
+ struct drm_via_chrome9_flush *dma_info)
+{
+ u32 HdType, dwQWCount, i, dwCount, Addr1, Addr2, SWPointer,
+ SWPointerEnd;
+ unsigned long *pCmdData;
+ int result;
+
+ /*pCmdData = __s3gke_vmalloc(dma_info->cmd_size<<2); */
+ pCmdData = dev_priv->bci_buffer;
+
+ if (!pCmdData)
+ return;
+
+ result = copy_from_user((int *) pCmdData, dma_info->usermode_dma_buf,
+ dma_info->cmd_size << 2);
+
+ SWPointer = 0;
+ SWPointerEnd = (u32) dma_info->cmd_size;
+ while (SWPointer < SWPointerEnd) {
+ HdType = pCmdData[SWPointer] & INV_AGPHeader_MASK;
+ switch (HdType) {
+ case INV_AGPHeader0:
+ case INV_AGPHeader5:
+ dwQWCount = pCmdData[SWPointer + 1];
+ SWPointer += 4;
+
+ for (i = 0; i < dwQWCount; i++) {
+ SetMMIORegister(dev_priv->mmio->handle,
+ pCmdData[SWPointer],
+ pCmdData[SWPointer + 1]);
+ SWPointer += 2;
+ }
+ break;
+
+ case INV_AGPHeader1:
+ dwCount = pCmdData[SWPointer + 1];
+ Addr1 = 0x0;
+ SWPointer += 4; /* skip 128-bit. */
+
+ for (; dwCount > 0; dwCount--, SWPointer++,
+ Addr1 += 4) {
+ SetMMIORegister(dev_priv->hostBlt->handle,
+ Addr1, pCmdData[SWPointer]);
+ }
+ break;
+
+ case INV_AGPHeader4:
+ dwCount = pCmdData[SWPointer + 1];
+ Addr1 = pCmdData[SWPointer] & 0x0000FFFF;
+ SWPointer += 4; /* skip 128-bit. */
+
+ for (; dwCount > 0; dwCount--, SWPointer++)
+ SetMMIORegister(dev_priv->mmio->handle, Addr1,
+ pCmdData[SWPointer]);
+ break;
+
+ case INV_AGPHeader2:
+ Addr1 = pCmdData[SWPointer + 1] & 0xFFFF;
+ Addr2 = pCmdData[SWPointer] & 0xFFFF;
+
+ /* Write first data (either ParaType or whatever) to
+ Addr1 */
+ SetMMIORegister(dev_priv->mmio->handle, Addr1,
+ pCmdData[SWPointer + 2]);
+ SWPointer += 4;
+
+ /* The following data are all written to Addr2,
+ until another header is met */
+ while (!IS_AGPHEADER_INV(pCmdData[SWPointer])
+ && (SWPointer < SWPointerEnd)) {
+ SetMMIORegister(dev_priv->mmio->handle, Addr2,
+ pCmdData[SWPointer]);
+ SWPointer++;
+ }
+ break;
+
+ case INV_AGPHeader3:
+ Addr1 = pCmdData[SWPointer] & 0xFFFF;
+ Addr2 = Addr1 + 4;
+ dwCount = pCmdData[SWPointer + 1];
+
+ /* Write first data (either ParaType or whatever) to
+ Addr1 */
+ SetMMIORegister(dev_priv->mmio->handle, Addr1,
+ pCmdData[SWPointer + 2]);
+ SWPointer += 4;
+
+ for (i = 0; i < dwCount; i++) {
+ SetMMIORegister(dev_priv->mmio->handle, Addr2,
+ pCmdData[SWPointer]);
+ SWPointer++;
+ }
+ break;
+
+ case INV_AGPHeader6:
+ break;
+
+ case INV_AGPHeader7:
+ break;
+
+ default:
+ SWPointer += 4; /* Advance to next header */
+ }
+
+ SWPointer = (SWPointer + 3) & ~3;
+ }
+}
+
+void
+kickoff_dma_db_inv(struct drm_device *dev)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ struct drm_via_chrome9_DMA_manager *lpcmDMAManager =
+ dev_priv->dma_manager;
+
+ u32 BufferSize = (u32) (lpcmDMAManager->pFree - lpcmDMAManager->pBeg);
+
+ unsigned int AGPBufLinearBase =
+ (unsigned int) lpcmDMAManager->addr_linear;
+ unsigned int AGPBufPhysicalBase =
+ (unsigned int) dev->agp->base + lpcmDMAManager->pPhysical;
+ /*add shadow offset */
+
+ unsigned int dwStart, dwEnd, dwPause;
+ unsigned int dwReg60, dwReg61, dwReg62, dwReg63, dwReg64, dwReg65;
+ unsigned int CR_Status;
+
+ if (BufferSize == 0)
+ return;
+
+ /* 256-bit alignment of AGP pause address */
+ if ((u32) ((unsigned long *) lpcmDMAManager->pFree) & 0x1f) {
+ ADDCmdHeader2_INVI(lpcmDMAManager->pFree, INV_REG_CR_TRANS,
+ INV_ParaType_Dummy);
+ do {
+ ADDCmdData_INVI(lpcmDMAManager->pFree, 0xCCCCCCC0);
+ ADDCmdData_INVI(lpcmDMAManager->pFree, 0xDDD00000);
+ }
+ while (((unsigned int) lpcmDMAManager->pFree) & 0x1f)
+ ;
+ }
+
+ dwStart =
+ (u32) (unsigned long *)lpcmDMAManager->pBeg -
+ AGPBufLinearBase + AGPBufPhysicalBase;
+ dwEnd = (u32) (unsigned long *)lpcmDMAManager->pEnd -
+ AGPBufLinearBase + AGPBufPhysicalBase;
+ dwPause =
+ (u32)(unsigned long *)lpcmDMAManager->pFree -
+ AGPBufLinearBase + AGPBufPhysicalBase - 4;
+
+ dwReg60 = INV_SubA_HAGPBstL | INV_HWBasL(dwStart);
+ dwReg61 = INV_SubA_HAGPBstH | INV_HWBasH(dwStart);
+ dwReg62 = INV_SubA_HAGPBendL | INV_HWBasL(dwEnd);
+ dwReg63 = INV_SubA_HAGPBendH | INV_HWBasH(dwEnd);
+ dwReg64 = INV_SubA_HAGPBpL | INV_HWBasL(dwPause);
+ dwReg65 = INV_SubA_HAGPBpID | INV_HWBasH(dwPause) | INV_HAGPBpID_STOP;
+
+ /* wait CR idle */
+ CR_Status = GetMMIORegister(dev_priv->mmio->handle, INV_RB_ENG_STATUS);
+ while (CR_Status & INV_ENG_BUSY_CR)
+ CR_Status =
+ GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_ENG_STATUS);
+
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS,
+ INV_ParaType_PreCR);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg60);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg61);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg62);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg63);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg64);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg65);
+
+ /* Trigger AGP cycle */
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ INV_SubA_HFthRCM | INV_HFthRCM_10 | INV_HAGPBTrig);
+
+ if (lpcmDMAManager->pBeg == lpcmDMAManager->addr_linear) {
+ /* The second AGP command buffer */
+ lpcmDMAManager->pBeg =
+ lpcmDMAManager->addr_linear +
+ (lpcmDMAManager->DMASize >> 2);
+ lpcmDMAManager->pEnd =
+ lpcmDMAManager->addr_linear + lpcmDMAManager->DMASize;
+ lpcmDMAManager->pFree = lpcmDMAManager->pBeg;
+ } else {
+ /* The first AGP command buffer */
+ lpcmDMAManager->pBeg = lpcmDMAManager->addr_linear;
+ lpcmDMAManager->pEnd =
+ lpcmDMAManager->addr_linear +
+ (lpcmDMAManager->DMASize / 2) - 1;
+ lpcmDMAManager->pFree = lpcmDMAManager->pBeg;
+ }
+ CR_Status = GetMMIORegister(dev_priv->mmio->handle, INV_RB_ENG_STATUS);
+}
+
+
+void
+kickoff_dma_ring_inv(struct drm_device *dev)
+{
+ unsigned int dwPause, dwReg64, dwReg65;
+
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ struct drm_via_chrome9_DMA_manager *lpcmDMAManager =
+ dev_priv->dma_manager;
+
+ unsigned int AGPBufLinearBase =
+ (unsigned int) lpcmDMAManager->addr_linear;
+ unsigned int AGPBufPhysicalBase =
+ (dev_priv->chip_agp ==
+ CHIP_PCIE) ? 0 : (unsigned int) dev->agp->base +
+ lpcmDMAManager->pPhysical;
+ /*add shadow offset */
+
+ /* 256-bit alignment of AGP pause address */
+ if (dev_priv->chip_sub_index == CHIP_H6S2) {
+ if ((u32)
+ ((unsigned long *) lpcmDMAManager->pFree) & 0x7f) {
+ ADDCmdHeader2_INVI(lpcmDMAManager->pFree,
+ INV_REG_CR_TRANS,
+ INV_ParaType_Dummy);
+ do {
+ ADDCmdData_INVI(lpcmDMAManager->pFree,
+ 0xCCCCCCC0);
+ ADDCmdData_INVI(lpcmDMAManager->pFree,
+ 0xDDD00000);
+ }
+ while ((u32)((unsigned long *) lpcmDMAManager->pFree) &
+ 0x7f)
+ ;
+ }
+ } else {
+ if ((u32)
+ ((unsigned long *) lpcmDMAManager->pFree) & 0x1f) {
+ ADDCmdHeader2_INVI(lpcmDMAManager->pFree,
+ INV_REG_CR_TRANS,
+ INV_ParaType_Dummy);
+ do {
+ ADDCmdData_INVI(lpcmDMAManager->pFree,
+ 0xCCCCCCC0);
+ ADDCmdData_INVI(lpcmDMAManager->pFree,
+ 0xDDD00000);
+ }
+ while ((u32)((unsigned long *) lpcmDMAManager->pFree) &
+ 0x1f)
+ ;
+ }
+ }
+
+
+ dwPause = (u32) ((unsigned long *) lpcmDMAManager->pFree)
+ - AGPBufLinearBase + AGPBufPhysicalBase - 16;
+
+ dwReg64 = INV_SubA_HAGPBpL | INV_HWBasL(dwPause);
+ dwReg65 = INV_SubA_HAGPBpID | INV_HWBasH(dwPause) | INV_HAGPBpID_PAUSE;
+
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS,
+ INV_ParaType_PreCR);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg64);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg65);
+
+ lpcmDMAManager->pInUseBySW = lpcmDMAManager->pFree;
+}
+
+static int
+waitchipidle_inv(struct drm_via_chrome9_private *dev_priv)
+{
+ unsigned int count = 50000;
+ unsigned int eng_status;
+ unsigned int engine_busy;
+
+ do {
+ eng_status =
+ GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_ENG_STATUS);
+ engine_busy = eng_status & INV_ENG_BUSY_ALL;
+ count--;
+ }
+ while (engine_busy && count)
+ ;
+ if (count && engine_busy == 0)
+ return 0;
+ return -1;
+}
+
+void
+get_space_db_inv(struct drm_device *dev,
+ struct cmd_get_space *lpcmGetSpaceData)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ struct drm_via_chrome9_DMA_manager *lpcmDMAManager =
+ dev_priv->dma_manager;
+
+ unsigned int dwRequestSize = lpcmGetSpaceData->dwRequestSize;
+ if (dwRequestSize > lpcmDMAManager->MaxKickoffSize) {
+ DRM_INFO("too big DMA buffer request!!!\n");
+ via_chrome9ke_assert(0);
+ *lpcmGetSpaceData->pCmdData = (unsigned int) NULL;
+ return;
+ }
+
+ if ((lpcmDMAManager->pFree + dwRequestSize) >
+ (lpcmDMAManager->pEnd - INV_CMDBUF_THRESHOLD * 2))
+ kickoff_dma_db_inv(dev);
+
+ *lpcmGetSpaceData->pCmdData = (unsigned int) lpcmDMAManager->pFree;
+}
+
+void
+RewindRingAGP_inv(struct drm_device *dev)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ struct drm_via_chrome9_DMA_manager *lpcmDMAManager =
+ dev_priv->dma_manager;
+
+ unsigned int AGPBufLinearBase =
+ (unsigned int) lpcmDMAManager->addr_linear;
+ unsigned int AGPBufPhysicalBase =
+ (dev_priv->chip_agp ==
+ CHIP_PCIE) ? 0 : (unsigned int) dev->agp->base +
+ lpcmDMAManager->pPhysical;
+ /*add shadow offset */
+
+ unsigned int dwPause, dwJump;
+ unsigned int dwReg66, dwReg67;
+ unsigned int dwReg64, dwReg65;
+
+ ADDCmdHeader2_INVI(lpcmDMAManager->pFree, INV_REG_CR_TRANS,
+ INV_ParaType_Dummy);
+ ADDCmdData_INVI(lpcmDMAManager->pFree, 0xCCCCCCC7);
+ if (dev_priv->chip_sub_index == CHIP_H6S2)
+ while ((unsigned int) lpcmDMAManager->pFree & 0x7F)
+ ADDCmdData_INVI(lpcmDMAManager->pFree, 0xCCCCCCC7);
+ else
+ while ((unsigned int) lpcmDMAManager->pFree & 0x1F)
+ ADDCmdData_INVI(lpcmDMAManager->pFree, 0xCCCCCCC7);
+ dwJump = ((u32) ((unsigned long *) lpcmDMAManager->pFree))
+ - AGPBufLinearBase + AGPBufPhysicalBase - 16;
+
+ lpcmDMAManager->pFree = lpcmDMAManager->pBeg;
+
+ dwPause = ((u32) ((unsigned long *) lpcmDMAManager->pFree))
+ - AGPBufLinearBase + AGPBufPhysicalBase - 16;
+
+ dwReg64 = INV_SubA_HAGPBpL | INV_HWBasL(dwPause);
+ dwReg65 = INV_SubA_HAGPBpID | INV_HWBasH(dwPause) | INV_HAGPBpID_PAUSE;
+
+ dwReg66 = INV_SubA_HAGPBjumpL | INV_HWBasL(dwJump);
+ dwReg67 = INV_SubA_HAGPBjumpH | INV_HWBasH(dwJump);
+
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS,
+ INV_ParaType_PreCR);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg66);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg67);
+
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg64);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg65);
+ lpcmDMAManager->pInUseBySW = lpcmDMAManager->pFree;
+}
+
+
+void
+get_space_ring_inv(struct drm_device *dev,
+ struct cmd_get_space *lpcmGetSpaceData)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ struct drm_via_chrome9_DMA_manager *lpcmDMAManager =
+ dev_priv->dma_manager;
+ unsigned int dwUnFlushed;
+ unsigned int dwRequestSize = lpcmGetSpaceData->dwRequestSize;
+
+ unsigned int AGPBufLinearBase =
+ (unsigned int) lpcmDMAManager->addr_linear;
+ unsigned int AGPBufPhysicalBase =
+ (dev_priv->chip_agp ==
+ CHIP_PCIE) ? 0 : (unsigned int) dev->agp->base +
+ lpcmDMAManager->pPhysical;
+ /*add shadow offset */
+ u32 BufStart, BufEnd, CurSW, CurHW, NextSW, BoundaryCheck;
+
+ dwUnFlushed =
+ (unsigned int) (lpcmDMAManager->pFree - lpcmDMAManager->pBeg);
+ /*default bEnableModuleSwitch is on for metro,is off for rest */
+ /*cmHW_Module_Switch is context-wide variable which is enough for 2d/3d
+ switch in a context. */
+ /*But we must keep the dma buffer being wrapped head and tail by 3d cmds
+ when it is kicked off to kernel mode. */
+ /*Get DMA Space (If requested, or no BCI space and BCI not forced. */
+
+ if (dwRequestSize > lpcmDMAManager->MaxKickoffSize) {
+ DRM_INFO("too big DMA buffer request!!!\n");
+ via_chrome9ke_assert(0);
+ *lpcmGetSpaceData->pCmdData = 0;
+ return;
+ }
+
+ if (dwUnFlushed + dwRequestSize > lpcmDMAManager->MaxKickoffSize)
+ kickoff_dma_ring_inv(dev);
+
+ BufStart =
+ (u32)((unsigned int) lpcmDMAManager->pBeg) - AGPBufLinearBase +
+ AGPBufPhysicalBase;
+ BufEnd = (u32)((unsigned int) lpcmDMAManager->pEnd) - AGPBufLinearBase +
+ AGPBufPhysicalBase;
+ dwRequestSize = lpcmGetSpaceData->dwRequestSize << 2;
+ NextSW = (u32) ((unsigned int) lpcmDMAManager->pFree) + dwRequestSize +
+ INV_CMDBUF_THRESHOLD * 8 - AGPBufLinearBase +
+ AGPBufPhysicalBase;
+
+ CurSW = (u32)((unsigned int) lpcmDMAManager->pFree) - AGPBufLinearBase +
+ AGPBufPhysicalBase;
+ CurHW = GetMMIORegister(dev_priv->mmio->handle, INV_RB_AGPCMD_CURRADDR);
+
+ if (NextSW >= BufEnd) {
+ kickoff_dma_ring_inv(dev);
+ CurSW = (u32) ((unsigned int) lpcmDMAManager->pFree) -
+ AGPBufLinearBase + AGPBufPhysicalBase;
+ /* make sure the last rewind is completed */
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ while (CurHW > CurSW)
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ /* Sometime the value read from HW is unreliable,
+ so need double confirm. */
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ while (CurHW > CurSW)
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ BoundaryCheck =
+ BufStart + dwRequestSize + INV_QW_PAUSE_ALIGN * 16;
+ if (BoundaryCheck >= BufEnd)
+ /* If an empty command buffer can't hold
+ the request data. */
+ via_chrome9ke_assert(0);
+ else {
+ /* We need to guarntee the new commands have no chance
+ to override the unexected commands or wait until there
+ is no unexecuted commands in agp buffer */
+ if (CurSW <= BoundaryCheck) {
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ while (CurHW < CurSW)
+ CurHW = GetMMIORegister(
+ dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ /*Sometime the value read from HW is unreliable,
+ so need double confirm. */
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ while (CurHW < CurSW) {
+ CurHW = GetMMIORegister(
+ dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ }
+ RewindRingAGP_inv(dev);
+ CurSW = (u32) ((unsigned long *)
+ lpcmDMAManager->pFree) -
+ AGPBufLinearBase + AGPBufPhysicalBase;
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ /* Waiting until hw pointer jump to start
+ and hw pointer will */
+ /* equal to sw pointer */
+ while (CurHW != CurSW) {
+ CurHW = GetMMIORegister(
+ dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ }
+ } else {
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+
+ while (CurHW <= BoundaryCheck) {
+ CurHW = GetMMIORegister(
+ dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ }
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ /* Sometime the value read from HW is
+ unreliable, so need double confirm. */
+ while (CurHW <= BoundaryCheck) {
+ CurHW = GetMMIORegister(
+ dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ }
+ RewindRingAGP_inv(dev);
+ }
+ }
+ } else {
+ /* no need to rewind Ensure unexecuted agp commands will
+ not be override by new
+ agp commands */
+ CurSW = (u32) ((unsigned int) lpcmDMAManager->pFree) -
+ AGPBufLinearBase + AGPBufPhysicalBase;
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+
+ while ((CurHW > CurSW) && (CurHW <= NextSW))
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+
+ /* Sometime the value read from HW is unreliable,
+ so need double confirm. */
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ while ((CurHW > CurSW) && (CurHW <= NextSW))
+ CurHW = GetMMIORegister(dev_priv->mmio->handle,
+ INV_RB_AGPCMD_CURRADDR);
+ }
+ /*return the space handle */
+ *lpcmGetSpaceData->pCmdData = (unsigned int) lpcmDMAManager->pFree;
+}
+
+void
+release_space_inv(struct drm_device *dev,
+ struct cmd_release_space *lpcmReleaseSpaceData)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ struct drm_via_chrome9_DMA_manager *lpcmDMAManager =
+ dev_priv->dma_manager;
+ unsigned int dwReleaseSize = lpcmReleaseSpaceData->dwReleaseSize;
+ int i = 0;
+
+ lpcmDMAManager->pFree += dwReleaseSize;
+
+ /* aligned address */
+ while (((unsigned int) lpcmDMAManager->pFree) & 0xF) {
+ /* not in 4 unsigned ints (16 Bytes) align address,
+ insert NULL Commands */
+ *lpcmDMAManager->pFree++ = NULL_COMMAND_INV[i & 0x3];
+ i++;
+ }
+
+ if ((dev_priv->chip_sub_index == CHIP_H5)
+ && (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER)) {
+ ADDCmdHeader2_INVI(lpcmDMAManager->pFree, INV_REG_CR_TRANS,
+ INV_ParaType_Dummy);
+ for (i = 0; i < NULLCOMMANDNUMBER; i++)
+ ADDCmdData_INVI(lpcmDMAManager->pFree, 0xCC000000);
+ }
+}
+
+int
+via_chrome9_ioctl_flush(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_via_chrome9_flush *dma_info = data;
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ int ret = 0;
+ int result = 0;
+ struct cmd_get_space getspace;
+ struct cmd_release_space releasespace;
+ volatile unsigned long *pCmdData = NULL;
+
+ switch (dma_info->dma_cmd_type) {
+ /* Copy DMA buffer to BCI command buffer */
+ case flush_bci:
+ case flush_bci_and_wait:
+ if (dma_info->cmd_size <= 0)
+ return 0;
+ if (dma_info->cmd_size > MAX_BCI_BUFFER_SIZE) {
+ DRM_INFO("too big BCI space request!!!\n");
+ return 0;
+ }
+
+ kickoff_bci_inv(dev_priv, dma_info);
+ waitchipidle_inv(dev_priv);
+ break;
+ /* Use DRM DMA buffer manager to kick off DMA directly */
+ case dma_kickoff:
+ break;
+
+ /* Copy user mode DMA buffer to kernel DMA buffer,
+ then kick off DMA */
+ case flush_dma_buffer:
+ case flush_dma_and_wait:
+ if (dma_info->cmd_size <= 0)
+ return 0;
+
+ getspace.dwRequestSize = dma_info->cmd_size;
+ if ((dev_priv->chip_sub_index == CHIP_H5)
+ && (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER))
+ getspace.dwRequestSize += (NULLCOMMANDNUMBER + 4);
+ /*henry:Patch for VT3293 agp ring buffer stability */
+ getspace.pCmdData = (unsigned int *) &pCmdData;
+
+ if (dev_priv->drm_agp_type == DRM_AGP_DOUBLE_BUFFER)
+ get_space_db_inv(dev, &getspace);
+ else if (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER)
+ get_space_ring_inv(dev, &getspace);
+
+ if (pCmdData) {
+ /*copy data from userspace to kernel-dma-agp buffer */
+ result = copy_from_user((int *)
+ pCmdData,
+ dma_info->usermode_dma_buf,
+ dma_info->cmd_size << 2);
+ releasespace.dwReleaseSize = dma_info->cmd_size;
+ release_space_inv(dev, &releasespace);
+
+ if (dev_priv->drm_agp_type == DRM_AGP_DOUBLE_BUFFER)
+ kickoff_dma_db_inv(dev);
+ else if (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER)
+ kickoff_dma_ring_inv(dev);
+
+ if (dma_info->dma_cmd_type == flush_dma_and_wait)
+ waitchipidle_inv(dev_priv);
+ } else {
+ DRM_INFO("No enough DMA space");
+ ret = -ENOMEM;
+ }
+ break;
+
+ default:
+ DRM_INFO("Invalid DMA buffer type");
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+int
+via_chrome9_ioctl_free(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ return 0;
+}
+
+int
+via_chrome9_ioctl_wait_chip_idle(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+
+ waitchipidle_inv(dev_priv);
+ /* maybe_bug here, do we always return 0 */
+ return 0;
+}
+
+int
+via_chrome9_ioctl_flush_cache(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ return 0;
+}
--- /dev/null
+++ b/drivers/char/drm/via_chrome9_dma.h
@@ -0,0 +1,68 @@
+/*
+ * 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_CHROME9_DMA_H_
+#define _VIA_CHROME9_DMA_H_
+
+#define MAX_BCI_BUFFER_SIZE 16*1024*1024
+
+enum cmd_request_type {
+ CM_REQUEST_BCI,
+ CM_REQUEST_DMA,
+ CM_REQUEST_RB,
+ CM_REQUEST_RB_FORCED_DMA,
+ CM_REQUEST_NOTAVAILABLE
+};
+
+struct cmd_get_space {
+ unsigned int dwRequestSize;
+ enum cmd_request_type hint;
+ volatile unsigned int *pCmdData;
+};
+
+struct cmd_release_space {
+ unsigned int dwReleaseSize;
+};
+
+extern int via_chrome9_hw_init(struct drm_device *dev,
+ struct drm_via_chrome9_init *init);
+extern int via_chrome9_ioctl_flush(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int via_chrome9_ioctl_free(struct drm_device *dev, void *data,
+ struct drm_file *file_prev);
+extern int via_chrome9_ioctl_wait_chip_idle(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_flush_cache(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_flush(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int via_chrome9_ioctl_free(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern unsigned int ProtectSizeValue(unsigned int size);
+extern void SetAGPDoubleCmd_inv(struct drm_device *dev);
+extern void SetAGPRingCmdRegs_inv(struct drm_device *dev);
+
+#endif
--- /dev/null
+++ b/drivers/char/drm/via_chrome9_drm.c
@@ -0,0 +1,993 @@
+/*
+ * 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 "drmP.h"
+#include "via_chrome9_drm.h"
+#include "via_chrome9_drv.h"
+#include "via_chrome9_mm.h"
+#include "via_chrome9_dma.h"
+#include "via_chrome9_3d_reg.h"
+
+#define VIA_CHROME9DRM_VIDEO_STARTADDRESS_ALIGNMENT 10
+
+
+void __via_chrome9ke_udelay(unsigned long usecs)
+{
+ unsigned long start;
+ unsigned long stop;
+ unsigned long period;
+ unsigned long wait_period;
+ struct timespec tval;
+
+#ifdef NDELAY_LIMIT
+#define UDELAY_LIMIT (NDELAY_LIMIT/1000) /* supposed to be 10 msec */
+#else
+#define UDELAY_LIMIT (10000) /* 10 msec */
+#endif
+
+ if (usecs > UDELAY_LIMIT) {
+ start = jiffies;
+ tval.tv_sec = usecs / 1000000;
+ tval.tv_nsec = (usecs - tval.tv_sec * 1000000) * 1000;
+ wait_period = timespec_to_jiffies(&tval);
+ do {
+ stop = jiffies;
+
+ if (stop < start)
+ period = ((unsigned long)-1 - start) + stop + 1;
+ else
+ period = stop - start;
+
+ } while (period < wait_period);
+ } else
+ udelay(usecs); /* delay value might get checked once again */
+}
+
+int via_chrome9_ioctl_process_exit(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ return 0;
+}
+
+int via_chrome9_ioctl_restore_primary(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ return 0;
+}
+
+void Initialize3DEngine(struct drm_via_chrome9_private *dev_priv)
+{
+ int i;
+ unsigned int StageOfTexture;
+
+ if (dev_priv->chip_sub_index == CHIP_H5 ||
+ dev_priv->chip_sub_index == CHIP_H5S1) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ 0x00010000);
+
+ for (i = 0; i <= 0x8A; i++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (unsigned int) i << 24);
+ }
+
+ /* Initial Texture Stage Setting*/
+ for (StageOfTexture = 0; StageOfTexture < 0xf;
+ StageOfTexture++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00020000 | 0x00000000 |
+ (StageOfTexture & 0xf)<<24));
+ /* *((unsigned int volatile*)(pMapIOPort+HC_REG_TRANS_SET)) =
+ (0x00020000 | HC_ParaSubType_Tex0 | (StageOfTexture &
+ 0xf)<<24);*/
+ for (i = 0 ; i <= 0x30 ; i++) {
+ /* *((unsigned int volatile*)(pMapIOPort+
+ HC_REG_Hpara0)) = ((unsigned int) i << 24);*/
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (unsigned int) i << 24);
+ }
+ }
+
+ /* Initial Texture Sampler Setting*/
+ for (StageOfTexture = 0; StageOfTexture < 0xf;
+ StageOfTexture++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00020000 | 0x00020000 |
+ (StageOfTexture & 0xf)<<24));
+ /* *((unsigned int volatile*)(pMapIOPort+
+ HC_REG_TRANS_SET)) = (0x00020000 | 0x00020000 |
+ ( StageOfTexture & 0xf)<<24);*/
+ for (i = 0 ; i <= 0x30 ; i++) {
+ /* *((unsigned int volatile*)(pMapIOPort+
+ HC_REG_Hpara0)) = ((unsigned int) i << 24);*/
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (unsigned int) i << 24);
+ }
+ }
+
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00020000 | 0xfe000000));
+ /* *((unsigned int volatile*)(pMapIOPort+HC_REG_TRANS_SET)) =
+ (0x00020000 | HC_ParaSubType_TexGen);*/
+ for (i = 0 ; i <= 0x13 ; i++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (unsigned int) i << 24);
+ /* *((unsigned int volatile*)(pMapIOPort+
+ HC_REG_Hpara0)) = ((unsigned int) i << 24);*/
+ }
+
+ /* Initial Gamma Table Setting*/
+ /* Initial Gamma Table Setting*/
+ /* 5 + 4 = 9 (12) dwords*/
+ /* sRGB texture is not directly support by H3 hardware.
+ We have to set the deGamma table for texture sampling.*/
+
+ /* degamma table*/
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00030000 | 0x15000000));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (0x40000000 | (30 << 20) | (15 << 10) | (5)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((119 << 20) | (81 << 10) | (52)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((283 << 20) | (219 << 10) | (165)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((535 << 20) | (441 << 10) | (357)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((119 << 20) | (884 << 20) | (757 << 10) |
+ (640)));
+
+ /* gamma table*/
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00030000 | 0x17000000));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (0x40000000 | (13 << 20) | (13 << 10) | (13)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (0x40000000 | (26 << 20) | (26 << 10) | (26)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (0x40000000 | (39 << 20) | (39 << 10) | (39)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((51 << 20) | (51 << 10) | (51)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((71 << 20) | (71 << 10) | (71)));
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (87 << 20) | (87 << 10) | (87));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (113 << 20) | (113 << 10) | (113));
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (135 << 20) | (135 << 10) | (135));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (170 << 20) | (170 << 10) | (170));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (199 << 20) | (199 << 10) | (199));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (246 << 20) | (246 << 10) | (246));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (284 << 20) | (284 << 10) | (284));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (317 << 20) | (317 << 10) | (317));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (347 << 20) | (347 << 10) | (347));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (373 << 20) | (373 << 10) | (373));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (398 << 20) | (398 << 10) | (398));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (442 << 20) | (442 << 10) | (442));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (481 << 20) | (481 << 10) | (481));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (517 << 20) | (517 << 10) | (517));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (550 << 20) | (550 << 10) | (550));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (609 << 20) | (609 << 10) | (609));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (662 << 20) | (662 << 10) | (662));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (709 << 20) | (709 << 10) | (709));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (753 << 20) | (753 << 10) | (753));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (794 << 20) | (794 << 10) | (794));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (832 << 20) | (832 << 10) | (832));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (868 << 20) | (868 << 10) | (868));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (902 << 20) | (902 << 10) | (902));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (934 << 20) | (934 << 10) | (934));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (966 << 20) | (966 << 10) | (966));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (996 << 20) | (996 << 10) | (996));
+
+
+ /*
+ For Interrupt Restore only All types of write through
+ regsiters should be write header data to hardware at
+ least before it can restore. H/W will automatically
+ record the header to write through state buffer for
+ resture usage.
+ By Jaren:
+ HParaType = 8'h03, HParaSubType = 8'h00
+ 8'h11
+ 8'h12
+ 8'h14
+ 8'h15
+ 8'h17
+ HParaSubType 8'h12, 8'h15 is initialized.
+ [HWLimit]
+ 1. All these write through registers can't be partial
+ update.
+ 2. All these write through must be AGP command
+ 16 entries : 4 128-bit data */
+
+ /* Initialize INV_ParaSubType_TexPal */
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00030000 | 0x00000000));
+ for (i = 0; i < 16; i++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x00000000);
+ }
+
+ /* Initialize INV_ParaSubType_4X4Cof */
+ /* 32 entries : 8 128-bit data */
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00030000 | 0x11000000));
+ for (i = 0; i < 32; i++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x00000000);
+ }
+
+ /* Initialize INV_ParaSubType_StipPal */
+ /* 5 entries : 2 128-bit data */
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00030000 | 0x14000000));
+ for (i = 0; i < (5+3); i++) {
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, 0x00000000);
+ }
+
+ /* primitive setting & vertex format*/
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00040000 | 0x14000000));
+ for (i = 0; i < 52; i++) {
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, ((unsigned int) i << 24));
+ }
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ 0x00fe0000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x4000840f);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x47000400);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x44000000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x46000000);
+
+ /* setting Misconfig*/
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ 0x00fe0000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x00001004);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x0800004b);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x0a000049);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x0b0000fb);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x0c000001);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x0d0000cb);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x0e000009);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x10000000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x110000ff);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x12000000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x130000db);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x14000000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x15000000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x16000000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x17000000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x18000000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x19000000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x20000000);
+ } else if (dev_priv->chip_sub_index == CHIP_H6S2) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ 0x00010000);
+ for (i = 0; i <= 0x9A; i++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (unsigned int) i << 24);
+ }
+
+ /* Initial Texture Stage Setting*/
+ for (StageOfTexture = 0; StageOfTexture <= 0xf;
+ StageOfTexture++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00020000 | 0x00000000 |
+ (StageOfTexture & 0xf)<<24));
+ /* *((unsigned int volatile*)(pMapIOPort+
+ HC_REG_TRANS_SET)) =
+ (0x00020000 | HC_ParaSubType_Tex0 |
+ (StageOfTexture & 0xf)<<24);*/
+ for (i = 0 ; i <= 0x30 ; i++) {
+ /* *((unsigned int volatile*)(pMapIOPort+
+ HC_REG_Hpara0)) =((unsigned int) i << 24);*/
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (unsigned int) i << 24);
+ }
+ }
+
+ /* Initial Texture Sampler Setting*/
+ for (StageOfTexture = 0; StageOfTexture <= 0xf;
+ StageOfTexture++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00020000 | 0x20000000 |
+ (StageOfTexture & 0xf)<<24));
+ /* *((unsigned int volatile*)(pMapIOPort+
+ HC_REG_TRANS_SET)) =(0x00020000 | 0x00020000 |
+ ( StageOfTexture & 0xf)<<24);*/
+ for (i = 0 ; i <= 0x36 ; i++) {
+ /* *((unsigned int volatile*)(pMapIOPort+
+ HC_REG_Hpara0)) =((unsigned int) i << 24);*/
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (unsigned int) i << 24);
+ }
+ }
+
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00020000 | 0xfe000000));
+ for (i = 0 ; i <= 0x13 ; i++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (unsigned int) i << 24);
+ /* *((unsigned int volatile*)(pMapIOPort+
+ HC_REG_Hpara0)) =((unsigned int) i << 24);*/
+ }
+
+ /* Initial Gamma Table Setting*/
+ /* Initial Gamma Table Setting*/
+ /* 5 + 4 = 9 (12) dwords*/
+ /* sRGB texture is not directly support by
+ H3 hardware.*/
+ /* We have to set the deGamma table for texture
+ sampling.*/
+
+ /* degamma table*/
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00030000 | 0x15000000));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (0x40000000 | (30 << 20) | (15 << 10) | (5)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((119 << 20) | (81 << 10) | (52)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((283 << 20) | (219 << 10) | (165)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((535 << 20) | (441 << 10) | (357)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((119 << 20) | (884 << 20) | (757 << 10)
+ | (640)));
+
+ /* gamma table*/
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00030000 | 0x17000000));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (0x40000000 | (13 << 20) | (13 << 10) | (13)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (0x40000000 | (26 << 20) | (26 << 10) | (26)));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (0x40000000 | (39 << 20) | (39 << 10) | (39)));
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, ((51 << 20) | (51 << 10) | (51)));
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, ((71 << 20) | (71 << 10) | (71)));
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (87 << 20) | (87 << 10) | (87));
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (113 << 20) | (113 << 10) | (113));
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (135 << 20) | (135 << 10) | (135));
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (170 << 20) | (170 << 10) | (170));
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (199 << 20) | (199 << 10) | (199));
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (246 << 20) | (246 << 10) | (246));
+ SetMMIORegister(dev_priv->mmio->handle,
+ 0x440, (284 << 20) | (284 << 10) | (284));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (317 << 20) | (317 << 10) | (317));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (347 << 20) | (347 << 10) | (347));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (373 << 20) | (373 << 10) | (373));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (398 << 20) | (398 << 10) | (398));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (442 << 20) | (442 << 10) | (442));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (481 << 20) | (481 << 10) | (481));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (517 << 20) | (517 << 10) | (517));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (550 << 20) | (550 << 10) | (550));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (609 << 20) | (609 << 10) | (609));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (662 << 20) | (662 << 10) | (662));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (709 << 20) | (709 << 10) | (709));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (753 << 20) | (753 << 10) | (753));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (794 << 20) | (794 << 10) | (794));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (832 << 20) | (832 << 10) | (832));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (868 << 20) | (868 << 10) | (868));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (902 << 20) | (902 << 10) | (902));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (934 << 20) | (934 << 10) | (934));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (966 << 20) | (966 << 10) | (966));
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ (996 << 20) | (996 << 10) | (996));
+
+
+ /* For Interrupt Restore only
+ All types of write through regsiters should be write
+ header data to hardware at least before it can restore.
+ H/W will automatically record the header to write
+ through state buffer for restureusage.
+ By Jaren:
+ HParaType = 8'h03, HParaSubType = 8'h00
+ 8'h11
+ 8'h12
+ 8'h14
+ 8'h15
+ 8'h17
+ HParaSubType 8'h12, 8'h15 is initialized.
+ [HWLimit]
+ 1. All these write through registers can't be partial
+ update.
+ 2. All these write through must be AGP command
+ 16 entries : 4 128-bit data */
+
+ /* Initialize INV_ParaSubType_TexPal */
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00030000 | 0x00000000));
+ for (i = 0; i < 16; i++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x00000000);
+ }
+
+ /* Initialize INV_ParaSubType_4X4Cof */
+ /* 32 entries : 8 128-bit data */
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00030000 | 0x11000000));
+ for (i = 0; i < 32; i++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x00000000);
+ }
+
+ /* Initialize INV_ParaSubType_StipPal */
+ /* 5 entries : 2 128-bit data */
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00030000 | 0x14000000));
+ for (i = 0; i < (5+3); i++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x00000000);
+ }
+
+ /* primitive setting & vertex format*/
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00040000));
+ for (i = 0; i <= 0x62; i++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((unsigned int) i << 24));
+ }
+
+ /*ParaType 0xFE - Configure and Misc Setting*/
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00fe0000));
+ for (i = 0; i <= 0x47; i++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((unsigned int) i << 24));
+ }
+ /*ParaType 0x11 - Frame Buffer Auto-Swapping and
+ Command Regulator Misc*/
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ (0x00110000));
+ for (i = 0; i <= 0x20; i++) {
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ ((unsigned int) i << 24));
+ }
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ 0x00fe0000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x4000840f);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x47000404);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x44000000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x46000005);
+
+ /* setting Misconfig*/
+ SetMMIORegister(dev_priv->mmio->handle, 0x43C,
+ 0x00fe0000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x00001004);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x08000249);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x0a0002c9);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x0b0002fb);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x0c000000);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x0d0002cb);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x0e000009);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x10000049);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x110002ff);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x12000008);
+ SetMMIORegister(dev_priv->mmio->handle, 0x440,
+ 0x130002db);
+ }
+}
+
+int via_chrome9_drm_resume(struct pci_dev *pci)
+{
+ struct drm_device *dev = (struct drm_device *)pci_get_drvdata(pci);
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *)dev->dev_private;
+ struct drm_via_chrome9_DMA_manager *lpcmDMAManager =
+ dev_priv->dma_manager;
+
+ Initialize3DEngine(dev_priv);
+
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS, 0x00110000);
+ if (dev_priv->chip_sub_index == CHIP_H6S2) {
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ 0x06000000);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ 0x07100000);
+ } else{
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ 0x02000000);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ 0x03100000);
+ }
+
+
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS,
+ INV_ParaType_PreCR);
+ SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN,
+ INV_SubA_HSetRBGID | INV_HSetRBGID_CR);
+
+ if (dev_priv->chip_sub_index == CHIP_H6S2) {
+ unsigned int *pGARTTable;
+ unsigned int i, entries, GARTOffset;
+ unsigned char sr6a, sr6b, sr6c, sr6f, sr7b;
+ unsigned int *addrlinear;
+ unsigned int size, alignedoffset;
+
+ entries = dev_priv->pagetable_map.pagetable_size /
+ sizeof(unsigned int);
+ pGARTTable = dev_priv->pagetable_map.pagetable_handle;
+
+ GARTOffset = dev_priv->pagetable_map.pagetable_offset;
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c);
+ sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ sr6c &= (~0x80);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c);
+
+ sr6a = (unsigned char)((GARTOffset & 0xff000) >> 12);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6a);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6a);
+
+ sr6b = (unsigned char)((GARTOffset & 0xff00000) >> 20);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6b);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6b);
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c);
+ sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ sr6c |= ((unsigned char)((GARTOffset >> 28) & 0x01));
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c);
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x7b);
+ sr7b = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ sr7b &= (~0x0f);
+ sr7b |= ProtectSizeValue(dev_priv->
+ pagetable_map.pagetable_size);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr7b);
+
+ for (i = 0; i < entries; i++)
+ writel(0x80000000, pGARTTable+i);
+
+ /*flush*/
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6f);
+ do {
+ sr6f = GetMMIORegisterU8(dev_priv->mmio->handle,
+ 0x83c5);
+ } while (sr6f & 0x80);
+
+ sr6f |= 0x80;
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6f);
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c);
+ sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ sr6c |= 0x80;
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c);
+
+ size = lpcmDMAManager->DMASize * sizeof(unsigned int) +
+ dev_priv->agp_size;
+ alignedoffset = 0;
+ entries = (size + PAGE_SIZE - 1) / PAGE_SIZE;
+ addrlinear = (unsigned int *)dev_priv->pcie_vmalloc_nocache;
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c);
+ sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ sr6c &= (~0x80);
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c);
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6f);
+ do {
+ sr6f = GetMMIORegisterU8(dev_priv->mmio->handle,
+ 0x83c5);
+ } while (sr6f & 0x80);
+
+ for (i = 0; i < entries; i++)
+ writel(page_to_pfn(vmalloc_to_page((void *)addrlinear +
+ PAGE_SIZE * i)) & 0x3fffffff, pGARTTable+
+ i+alignedoffset);
+
+ sr6f |= 0x80;
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6f);
+
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c);
+ sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5);
+ sr6c |= 0x80;
+ SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c);
+
+ }
+
+ if (dev_priv->drm_agp_type == DRM_AGP_DOUBLE_BUFFER)
+ SetAGPDoubleCmd_inv(dev);
+ else if (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER)
+ SetAGPRingCmdRegs_inv(dev);
+ return 0;
+}
+
+int via_chrome9_drm_suspend(struct pci_dev *dev,
+ pm_message_t state)
+{
+ return 0;
+}
+
+int via_chrome9_driver_load(struct drm_device *dev,
+ unsigned long chipset)
+{
+ struct drm_via_chrome9_private *dev_priv;
+ int ret = 0;
+ static int associate;
+
+ if (!associate) {
+ pci_set_drvdata(dev->pdev, dev);
+ dev->pdev->driver = &dev->driver->pci_driver;
+ associate = 1;
+ }
+
+ dev->counters += 4;
+ dev->types[6] = _DRM_STAT_IRQ;
+ dev->types[7] = _DRM_STAT_PRIMARY;
+ dev->types[8] = _DRM_STAT_SECONDARY;
+ dev->types[9] = _DRM_STAT_DMA;
+
+ dev_priv = drm_calloc(1, sizeof(struct drm_via_chrome9_private),
+ DRM_MEM_DRIVER);
+ if (dev_priv == NULL)
+ return -ENOMEM;
+
+ /* Clear */
+ memset(dev_priv, 0, sizeof(struct drm_via_chrome9_private));
+
+ dev_priv->dev = dev;
+ dev->dev_private = (void *)dev_priv;
+
+ dev_priv->chip_index = chipset;
+
+ ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
+ if (ret)
+ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+ return ret;
+}
+
+int via_chrome9_driver_unload(struct drm_device *dev)
+{
+ struct drm_via_chrome9_private *dev_priv = dev->dev_private;
+
+ drm_sman_takedown(&dev_priv->sman);
+
+ drm_free(dev_priv, sizeof(struct drm_via_chrome9_private),
+ DRM_MEM_DRIVER);
+
+ return 0;
+}
+
+static int via_chrome9_initialize(struct drm_device *dev,
+ struct drm_via_chrome9_init *init)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *)dev->dev_private;
+
+ dev_priv->chip_agp = init->chip_agp;
+ dev_priv->chip_index = init->chip_index;
+ dev_priv->chip_sub_index = init->chip_sub_index;
+
+ dev_priv->usec_timeout = init->usec_timeout;
+ dev_priv->front_offset = init->front_offset;
+ dev_priv->back_offset = init->back_offset >>
+ VIA_CHROME9DRM_VIDEO_STARTADDRESS_ALIGNMENT <<
+ VIA_CHROME9DRM_VIDEO_STARTADDRESS_ALIGNMENT;
+ dev_priv->available_fb_size = init->available_fb_size -
+ (init->available_fb_size %
+ (1 << VIA_CHROME9DRM_VIDEO_STARTADDRESS_ALIGNMENT));
+ dev_priv->depth_offset = init->depth_offset;
+
+ /* Find all the map added first, doing this is necessary to
+ intialize hw */
+ if (via_chrome9_map_init(dev, init)) {
+ DRM_ERROR("function via_chrome9_map_init ERROR !\n");
+ goto error;
+ }
+
+ /* Necessary information has been gathered for initialize hw */
+ if (via_chrome9_hw_init(dev, init)) {
+ DRM_ERROR("function via_chrome9_hw_init ERROR !\n");
+ goto error;
+ }
+
+ /* After hw intialization, we have kown whether to use agp
+ or to use pcie for texture */
+ if (via_chrome9_heap_management_init(dev, init)) {
+ DRM_ERROR("function \
+ via_chrome9_heap_management_init ERROR !\n");
+ goto error;
+ }
+
+ return 0;
+
+error:
+ /* all the error recover has been processed in relevant function,
+ so here just return error */
+ return -EINVAL;
+}
+
+static void via_chrome9_cleanup(struct drm_device *dev,
+ struct drm_via_chrome9_init *init)
+{
+ struct drm_via_chrome9_DMA_manager *lpcmDMAManager = NULL;
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *)dev->dev_private;
+ DRM_DEBUG("function via_chrome9_cleanup run!\n");
+
+ if (!dev_priv)
+ return ;
+
+ lpcmDMAManager =
+ (struct drm_via_chrome9_DMA_manager *)dev_priv->dma_manager;
+ if (dev_priv->pcie_vmalloc_nocache) {
+ vfree((void *)dev_priv->pcie_vmalloc_nocache);
+ dev_priv->pcie_vmalloc_nocache = 0;
+ if (lpcmDMAManager)
+ lpcmDMAManager->addr_linear = NULL;
+ }
+
+ if (dev_priv->pagetable_map.pagetable_handle) {
+ iounmap(dev_priv->pagetable_map.pagetable_handle);
+ dev_priv->pagetable_map.pagetable_handle = NULL;
+ }
+
+ if (lpcmDMAManager && lpcmDMAManager->addr_linear) {
+ iounmap(lpcmDMAManager->addr_linear);
+ lpcmDMAManager->addr_linear = NULL;
+ }
+
+ kfree(lpcmDMAManager);
+ dev_priv->dma_manager = NULL;
+
+ if (dev_priv->event_tag_info) {
+ vfree(dev_priv->event_tag_info);
+ dev_priv->event_tag_info = NULL;
+ }
+
+ if (dev_priv->bci_buffer) {
+ vfree(dev_priv->bci_buffer);
+ dev_priv->bci_buffer = NULL;
+ }
+
+ via_chrome9_memory_destroy_heap(dev, dev_priv);
+}
+
+/*
+Do almost everything intialize here,include:
+1.intialize all addmaps in private data structure
+2.intialize memory heap management for video agp/pcie
+3.intialize hw for dma(pcie/agp) function
+
+Note:all this function will dispatch into relevant function
+*/
+int via_chrome9_ioctl_init(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_via_chrome9_init *init = (struct drm_via_chrome9_init *)data;
+
+ switch (init->func) {
+ case VIA_CHROME9_INIT:
+ if (via_chrome9_initialize(dev, init)) {
+ DRM_ERROR("function via_chrome9_initialize error\n");
+ return -1;
+ }
+ break;
+
+ case VIA_CHROME9_CLEANUP:
+ via_chrome9_cleanup(dev, init);
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int via_chrome9_ioctl_allocate_event_tag(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_via_chrome9_event_tag *event_tag = data;
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *)dev->dev_private;
+ struct drm_clb_event_tag_info *event_tag_info =
+ dev_priv->event_tag_info;
+ unsigned int *event_addr = 0, i = 0;
+
+ for (i = 0; i < NUMBER_OF_EVENT_TAGS; i++) {
+ if (!event_tag_info->usage[i])
+ break;
+ }
+
+ if (i < NUMBER_OF_EVENT_TAGS) {
+ event_tag_info->usage[i] = 1;
+ event_tag->event_offset = i;
+ event_tag->last_sent_event_value.event_low = 0;
+ event_tag->current_event_value.event_low = 0;
+ event_addr = event_tag_info->linear_address +
+ event_tag->event_offset * 4;
+ *event_addr = 0;
+ return 0;
+ } else {
+ return -7;
+ }
+
+ return 0;
+}
+
+int via_chrome9_ioctl_free_event_tag(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *)dev->dev_private;
+ struct drm_clb_event_tag_info *event_tag_info =
+ dev_priv->event_tag_info;
+ struct drm_via_chrome9_event_tag *event_tag = data;
+
+ event_tag_info->usage[event_tag->event_offset] = 0;
+ return 0;
+}
+
+void via_chrome9_lastclose(struct drm_device *dev)
+{
+ via_chrome9_cleanup(dev, 0);
+ return ;
+}
+
+static int via_chrome9_do_wait_vblank(struct drm_via_chrome9_private
+ *dev_priv)
+{
+ int i;
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ VIA_CHROME9_WRITE8(0x83d4, 0x34);
+ if ((VIA_CHROME9_READ8(0x83d5)) & 0x8)
+ return 0;
+ __via_chrome9ke_udelay(1);
+ }
+
+ return (-1);
+}
+
+void via_chrome9_preclose(struct drm_device *dev, struct drm_file *file_priv)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ struct drm_via_chrome9_sarea *sarea_priv = NULL;
+
+ if (!dev_priv)
+ return ;
+
+ sarea_priv = dev_priv->sarea_priv;
+ if (!sarea_priv)
+ return ;
+
+ if ((sarea_priv->page_flip == 1) &&
+ (sarea_priv->current_page != VIA_CHROME9_FRONT)) {
+ volatile unsigned long *bci_base;
+ if (via_chrome9_do_wait_vblank(dev_priv))
+ return;
+
+ bci_base = (volatile unsigned long *)(dev_priv->bci);
+
+ BCI_SET_STREAM_REGISTER(bci_base, 0x81c4, 0xc0000000);
+ BCI_SET_STREAM_REGISTER(bci_base, 0x81c0,
+ dev_priv->front_offset);
+ BCI_SEND(bci_base, 0x64000000);/* wait vsync */
+
+ sarea_priv->current_page = VIA_CHROME9_FRONT;
+ }
+}
+
+int via_chrome9_is_agp(struct drm_device *dev)
+{
+ /* filter out pcie group which has no AGP device */
+ if (dev->pci_device == 0x1122) {
+ dev->driver->driver_features &=
+ ~(DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_REQUIRE_AGP);
+ return 0;
+ }
+ return 1;
+}
+
--- /dev/null
+++ b/drivers/char/drm/via_chrome9_drm.h
@@ -0,0 +1,423 @@
+/*
+ * 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_CHROME9_DRM_H_
+#define _VIA_CHROME9_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_CHROME9_DEFINES_
+#define _VIA_CHROME9_DEFINES_
+
+#ifndef __KERNEL__
+#include "via_drmclient.h"
+#endif
+
+#define VIA_CHROME9_NR_SAREA_CLIPRECTS 8
+#define VIA_CHROME9_NR_XVMC_PORTS 10
+#define VIA_CHROME9_NR_XVMC_LOCKS 5
+#define VIA_CHROME9_MAX_CACHELINE_SIZE 64
+#define XVMCLOCKPTR(saPriv,lockNo) \
+ ((volatile struct drm_hw_lock *) \
+ (((((unsigned long) (saPriv)->XvMCLockArea) + \
+ (VIA_CHROME9_MAX_CACHELINE_SIZE - 1)) & \
+ ~(VIA_CHROME9_MAX_CACHELINE_SIZE - 1)) + \
+ VIA_CHROME9_MAX_CACHELINE_SIZE*(lockNo)))
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+#define VIA_CHROME9_NR_TEX_REGIONS 64
+#define VIA_CHROME9_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+#define VIA_CHROME9_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
+#define VIA_CHROME9_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
+#define VIA_CHROME9_UPLOAD_CTX 0x4
+#define VIA_CHROME9_UPLOAD_BUFFERS 0x8
+#define VIA_CHROME9_UPLOAD_TEX0 0x10
+#define VIA_CHROME9_UPLOAD_TEX1 0x20
+#define VIA_CHROME9_UPLOAD_CLIPRECTS 0x40
+#define VIA_CHROME9_UPLOAD_ALL 0xff
+
+/* VIA_CHROME9 specific ioctls */
+#define DRM_VIA_CHROME9_ALLOCMEM 0x00
+#define DRM_VIA_CHROME9_FREEMEM 0x01
+#define DRM_VIA_CHROME9_FREE 0x02
+#define DRM_VIA_CHROME9_ALLOCATE_EVENT_TAG 0x03
+#define DRM_VIA_CHROME9_FREE_EVENT_TAG 0x04
+#define DRM_VIA_CHROME9_ALLOCATE_APERTURE 0x05
+#define DRM_VIA_CHROME9_FREE_APERTURE 0x06
+#define DRM_VIA_CHROME9_ALLOCATE_VIDEO_MEM 0x07
+#define DRM_VIA_CHROME9_FREE_VIDEO_MEM 0x08
+#define DRM_VIA_CHROME9_WAIT_CHIP_IDLE 0x09
+#define DRM_VIA_CHROME9_PROCESS_EXIT 0x0A
+#define DRM_VIA_CHROME9_RESTORE_PRIMARY 0x0B
+#define DRM_VIA_CHROME9_FLUSH_CACHE 0x0C
+#define DRM_VIA_CHROME9_INIT 0x0D
+#define DRM_VIA_CHROME9_FLUSH 0x0E
+#define DRM_VIA_CHROME9_CHECKVIDMEMSIZE 0x0F
+#define DRM_VIA_CHROME9_PCIEMEMCTRL 0x10
+#define DRM_VIA_CHROME9_AUTH_MAGIC 0x11
+
+#define DRM_IOCTL_VIA_CHROME9_INIT \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_INIT, \
+ struct drm_via_chrome9_init)
+#define DRM_IOCTL_VIA_CHROME9_FLUSH \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FLUSH, \
+ struct drm_via_chrome9_flush)
+#define DRM_IOCTL_VIA_CHROME9_FREE \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FREE, int)
+#define DRM_IOCTL_VIA_CHROME9_ALLOCATE_EVENT_TAG \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_ALLOCATE_EVENT_TAG, \
+ struct drm_event_via_chrome9_tag)
+#define DRM_IOCTL_VIA_CHROME9_FREE_EVENT_TAG \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FREE_EVENT_TAG, \
+ struct drm_event_via_chrome9_tag)
+#define DRM_IOCTL_VIA_CHROME9_ALLOCATE_APERTURE \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_ALLOCATE_APERTURE, \
+ struct drm_via_chrome9_aperture)
+#define DRM_IOCTL_VIA_CHROME9_FREE_APERTURE \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FREE_APERTURE, \
+ struct drm_via_chrome9_aperture)
+#define DRM_IOCTL_VIA_CHROME9_ALLOCATE_VIDEO_MEM \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_ALLOCATE_VIDEO_MEM, \
+ struct drm_via_chrome9_memory_alloc)
+#define DRM_IOCTL_VIA_CHROME9_FREE_VIDEO_MEM \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FREE_VIDEO_MEM, \
+ struct drm_via_chrome9_memory_alloc)
+#define DRM_IOCTL_VIA_CHROME9_WAIT_CHIP_IDLE \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_WAIT_CHIP_IDLE, int)
+#define DRM_IOCTL_VIA_CHROME9_PROCESS_EXIT \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_PROCESS_EXIT, int)
+#define DRM_IOCTL_VIA_CHROME9_RESTORE_PRIMARY \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_RESTORE_PRIMARY, int)
+#define DRM_IOCTL_VIA_CHROME9_FLUSH_CACHE \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FLUSH_CACHE, int)
+#define DRM_IOCTL_VIA_CHROME9_ALLOCMEM \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_ALLOCMEM, int)
+#define DRM_IOCTL_VIA_CHROME9_FREEMEM \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FREEMEM, int)
+#define DRM_IOCTL_VIA_CHROME9_CHECK_VIDMEM_SIZE \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_CHECKVIDMEMSIZE, \
+ struct drm_via_chrome9_memory_alloc)
+#define DRM_IOCTL_VIA_CHROME9_PCIEMEMCTRL \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_PCIEMEMCTRL,\
+ drm_via_chrome9_pciemem_ctrl_t)
+#define DRM_IOCTL_VIA_CHROME9_AUTH_MAGIC \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_AUTH_MAGIC, drm_auth_t)
+
+enum S3GCHIPIDS {
+ CHIP_UNKNOWN = -1,
+ CHIP_CMODEL, /*Model for any chip. */
+ CHIP_CLB, /*Columbia */
+ CHIP_DST, /*Destination */
+ CHIP_CSR, /*Castlerock */
+ CHIP_INV, /*Innovation (H3) */
+ CHIP_H5, /*Innovation (H5) */
+ CHIP_H5S1, /*Innovation (H5S1) */
+ CHIP_H6S2, /*Innovation (H6S2) */
+ CHIP_CMS, /*Columbia MS */
+ CHIP_METRO, /*Metropolis */
+ CHIP_MANHATTAN, /*manhattan */
+ CHIP_MATRIX, /*matrix */
+ CHIP_EVO, /*change for GCC 4.1 -add- 07.02.12*/
+ CHIP_H6S1, /*Innovation (H6S1)*/
+ CHIP_DST2, /*Destination-2 */
+ CHIP_LAST /*Maximum number of chips supported. */
+};
+
+enum VIA_CHROME9CHIPBUS {
+ CHIP_PCI,
+ CHIP_AGP,
+ CHIP_PCIE
+};
+
+struct drm_via_chrome9_init {
+ enum {
+ VIA_CHROME9_INIT = 0x01,
+ VIA_CHROME9_CLEANUP = 0x02
+ } func;
+ int chip_agp;
+ int chip_index;
+ int chip_sub_index;
+ int usec_timeout;
+ unsigned int sarea_priv_offset;
+ unsigned int fb_cpp;
+ unsigned int front_offset;
+ unsigned int back_offset;
+ unsigned int depth_offset;
+ unsigned int mmio_handle;
+ unsigned int dma_handle;
+ unsigned int fb_handle;
+ unsigned int front_handle;
+ unsigned int back_handle;
+ unsigned int depth_handle;
+
+ unsigned int fb_tex_offset;
+ unsigned int fb_tex_size;
+
+ unsigned int agp_tex_size;
+ unsigned int agp_tex_handle;
+ unsigned int shadow_size;
+ unsigned int shadow_handle;
+ unsigned int garttable_size;
+ unsigned int garttable_offset;
+ unsigned long available_fb_size;
+ unsigned long fb_base_address;
+ unsigned int DMA_size;
+ unsigned long DMA_phys_address;
+ enum {
+ AGP_RING_BUFFER,
+ AGP_DOUBLE_BUFFER,
+ AGP_DISABLED
+ } agp_type;
+ unsigned int hostBlt_handle;
+};
+
+enum dma_cmd_type {
+ flush_bci = 0,
+ flush_bci_and_wait,
+ dma_kickoff,
+ flush_dma_buffer,
+ flush_dma_and_wait
+};
+
+struct drm_via_chrome9_flush {
+ enum dma_cmd_type dma_cmd_type;
+ /* command buffer index */
+ int cmd_idx;
+ /* command buffer offset */
+ int cmd_offset;
+ /* command dword size,command always from beginning */
+ int cmd_size;
+ /* if use dma kick off,it is dma kick off command */
+ unsigned long dma_kickoff[2];
+ /* user mode DMA buffer pointer */
+ unsigned int *usermode_dma_buf;
+};
+
+struct event_value {
+ int event_low;
+ int event_high;
+};
+
+struct drm_via_chrome9_event_tag {
+ unsigned int event_size; /* event tag size */
+ int event_offset; /* event tag id */
+ struct event_value last_sent_event_value;
+ struct event_value current_event_value;
+ int query_mask0;
+ int query_mask1;
+ int query_Id1;
+};
+
+/* 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_CHROME9_TEX_SETUP_SIZE 8
+
+/* Flags for clear ioctl
+ */
+#define VIA_CHROME9_FRONT 0x1
+#define VIA_CHROME9_BACK 0x2
+#define VIA_CHROME9_DEPTH 0x4
+#define VIA_CHROME9_STENCIL 0x8
+#define VIA_CHROME9_MEM_VIDEO 0 /* matches drm constant */
+#define VIA_CHROME9_MEM_AGP 1 /* matches drm constant */
+#define VIA_CHROME9_MEM_SYSTEM 2
+#define VIA_CHROME9_MEM_MIXED 3
+#define VIA_CHROME9_MEM_UNKNOWN 4
+
+struct drm_via_chrome9_agp {
+ uint32_t offset;
+ uint32_t size;
+};
+
+struct drm_via_chrome9_fb {
+ uint32_t offset;
+ uint32_t size;
+};
+
+struct drm_via_chrome9_mem {
+ uint32_t context;
+ uint32_t type;
+ uint32_t size;
+ unsigned long index;
+ unsigned long offset;
+};
+
+struct drm_via_chrome9_aperture {
+ /*IN: The frame buffer offset of the surface. */
+ int surface_offset;
+ /*IN: Surface pitch in byte, */
+ int pitch;
+ /*IN: Surface width in pixel */
+ int width;
+ /*IN: Surface height in pixel */
+ int height;
+ /*IN: Surface color format, Columbia has more color formats */
+ int color_format;
+ /*IN: Rotation degrees, only for Columbia */
+ int rotation_degree;
+ /*IN Is the PCIE Video, for MATRIX support NONLOCAL Aperture */
+ int isPCIEVIDEO;
+ /*IN: Is the surface tilled, only for Columbia */
+ int is_tiled;
+ /*IN: Only allocate apertur, not hardware setup. */
+ int allocate_only;
+ /* OUT: linear address for aperture */
+ unsigned int *aperture_linear_address;
+ /*OUT: The pitch of the aperture,for CPU write not for GE */
+ int aperture_pitch;
+ /*OUT: The index of the aperture */
+ int aperture_handle;
+ int apertureID;
+ /* always =0xAAAAAAAA */
+ /* Aligned surface's width(in pixel) */
+ int width_aligned;
+ /* Aligned surface's height(in pixel) */
+ int height_aligned;
+};
+
+/*
+ Some fileds of this data structure has no meaning now since
+ we have managed heap based on mechanism provided by DRM
+ Remain what it was to keep consistent with 3D driver interface.
+*/
+struct drm_via_chrome9_memory_alloc {
+ enum {
+ memory_heap_video = 0,
+ memory_heap_agp,
+ memory_heap_pcie_video,
+ memory_heap_pcie,
+ max_memory_heaps
+ } heap_type;
+ struct {
+ void *lpL1Node;
+ unsigned int alcL1Tag;
+ unsigned int usageCount;
+ unsigned int dwVersion;
+ unsigned int dwResHandle;
+ unsigned int dwProcessID;
+ } heap_info;
+ unsigned int flags;
+ unsigned int size;
+ unsigned int physaddress;
+ unsigned int offset;
+ unsigned int align;
+ void *linearaddress;
+};
+
+struct drm_via_chrome9_dma_init {
+ enum {
+ VIA_CHROME9_INIT_DMA = 0x01,
+ VIA_CHROME9_CLEANUP_DMA = 0x02,
+ VIA_CHROME9_DMA_INITIALIZED = 0x03
+ } func;
+
+ unsigned long offset;
+ unsigned long size;
+ unsigned long reg_pause_addr;
+};
+
+struct drm_via_chrome9_cmdbuffer {
+ char __user *buf;
+ unsigned long size;
+};
+
+/* Warning: If you change the SAREA structure you must change the Xserver
+ * structure as well */
+
+struct drm_via_chrome9_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 */
+};
+
+struct drm_via_chrome9_sarea {
+ int page_flip;
+ int current_page;
+ unsigned int req_drawable;/* the X drawable id */
+ unsigned int req_draw_buffer;/* VIA_CHROME9_FRONT or VIA_CHROME9_BACK */
+ /* Last context that uploaded state */
+ int ctx_owner;
+};
+
+struct drm_via_chrome9_cmdbuf_size {
+ enum {
+ VIA_CHROME9_CMDBUF_SPACE = 0x01,
+ VIA_CHROME9_CMDBUF_LAG = 0x02
+ } func;
+ int wait;
+ uint32_t size;
+};
+
+struct drm_via_chrome9_DMA_manager {
+ unsigned int *addr_linear;
+ unsigned int DMASize;
+ unsigned int bDMAAgp;
+ unsigned int LastIssuedEventTag;
+ unsigned int *pBeg;
+ unsigned int *pInUseByHW;
+ unsigned int **ppInUseByHW;
+ unsigned int *pInUseBySW;
+ unsigned int *pFree;
+ unsigned int *pEnd;
+
+ unsigned long pPhysical;
+ unsigned int MaxKickoffSize;
+};
+
+extern int via_chrome9_ioctl_wait_chip_idle(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_init(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_allocate_event_tag(struct drm_device
+ *dev, void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_free_event_tag(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+extern int via_chrome9_driver_load(struct drm_device *dev,
+ unsigned long chipset);
+extern int via_chrome9_driver_unload(struct drm_device *dev);
+extern int via_chrome9_ioctl_process_exit(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_restore_primary(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+extern int via_chrome9_drm_resume(struct pci_dev *dev);
+extern int via_chrome9_drm_suspend(struct pci_dev *dev,
+ pm_message_t state);
+extern void __via_chrome9ke_udelay(unsigned long usecs);
+extern void via_chrome9_lastclose(struct drm_device *dev);
+extern void via_chrome9_preclose(struct drm_device *dev,
+ struct drm_file *file_priv);
+extern int via_chrome9_is_agp(struct drm_device *dev);
+
+
+#endif /* _VIA_CHROME9_DRM_H_ */
--- /dev/null
+++ b/drivers/char/drm/via_chrome9_drv.c
@@ -0,0 +1,153 @@
+/*
+ * 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 "drmP.h"
+#include "via_chrome9_drm.h"
+#include "via_chrome9_drv.h"
+#include "via_chrome9_dma.h"
+#include "via_chrome9_mm.h"
+
+#include "drm_pciids.h"
+
+static int dri_library_name(struct drm_device *dev, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "via_chrome9");
+}
+
+int via_chrome9_drm_authmagic(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ return 0;
+}
+
+struct drm_ioctl_desc via_chrome9_ioctls[] = {
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_INIT, via_chrome9_ioctl_init,
+ DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),/* via_chrome9_map.c*/
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_FLUSH, via_chrome9_ioctl_flush, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_FREE, via_chrome9_ioctl_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_ALLOCATE_EVENT_TAG,
+ via_chrome9_ioctl_allocate_event_tag, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_FREE_EVENT_TAG,
+ via_chrome9_ioctl_free_event_tag, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_ALLOCATE_APERTURE,
+ via_chrome9_ioctl_allocate_aperture, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_FREE_APERTURE,
+ via_chrome9_ioctl_free_aperture, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_ALLOCATE_VIDEO_MEM,
+ via_chrome9_ioctl_allocate_mem_wrapper, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_FREE_VIDEO_MEM,
+ via_chrome9_ioctl_free_mem_wrapper, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_WAIT_CHIP_IDLE,
+ via_chrome9_ioctl_wait_chip_idle, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_PROCESS_EXIT,
+ via_chrome9_ioctl_process_exit, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_RESTORE_PRIMARY,
+ via_chrome9_ioctl_restore_primary, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_FLUSH_CACHE,
+ via_chrome9_ioctl_flush_cache, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_ALLOCMEM,
+ via_chrome9_ioctl_allocate_mem_base, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_FREEMEM,
+ via_chrome9_ioctl_freemem_base, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_CHECKVIDMEMSIZE,
+ via_chrome9_ioctl_check_vidmem_size, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_PCIEMEMCTRL,
+ via_chrome9_ioctl_pciemem_ctrl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_VIA_CHROME9_AUTH_MAGIC, via_chrome9_drm_authmagic, 0)
+};
+
+int via_chrome9_max_ioctl = DRM_ARRAY_SIZE(via_chrome9_ioctls);
+
+static struct pci_device_id pciidlist[] = {
+ via_chrome9DRV_PCI_IDS
+};
+
+int via_chrome9_driver_open(struct drm_device *dev,
+ struct drm_file *priv)
+{
+ priv->authenticated = 1;
+ return 0;
+}
+
+static struct drm_driver driver = {
+ .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
+ DRIVER_HAVE_DMA | DRIVER_FB_DMA | DRIVER_USE_MTRR,
+ .open = via_chrome9_driver_open,
+ .load = via_chrome9_driver_load,
+ .unload = via_chrome9_driver_unload,
+ .device_is_agp = via_chrome9_is_agp,
+ .dri_library_name = dri_library_name,
+ .reclaim_buffers = drm_core_reclaim_buffers,
+ .reclaim_buffers_locked = NULL,
+ .reclaim_buffers_idlelocked = via_chrome9_reclaim_buffers_locked,
+ .lastclose = via_chrome9_lastclose,
+ .preclose = via_chrome9_preclose,
+ .get_map_ofs = drm_core_get_map_ofs,
+ .get_reg_ofs = drm_core_get_reg_ofs,
+ .ioctls = via_chrome9_ioctls,
+ .fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ },
+ .pci_driver = {
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ .resume = via_chrome9_drm_resume,
+ .suspend = via_chrome9_drm_suspend,
+ },
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
+};
+
+static int __init via_chrome9_init(void)
+{
+ driver.num_ioctls = via_chrome9_max_ioctl;
+ driver.dev_priv_size = sizeof(struct drm_via_chrome9_private);
+ return drm_init(&driver);
+}
+
+static void __exit via_chrome9_exit(void)
+{
+ drm_exit(&driver);
+}
+
+module_init(via_chrome9_init);
+module_exit(via_chrome9_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
--- /dev/null
+++ b/drivers/char/drm/via_chrome9_drv.h
@@ -0,0 +1,145 @@
+/*
+ * 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_CHROME9_DRV_H_
+#define _VIA_CHROME9_DRV_H_
+
+#include "drm_sman.h"
+#define DRIVER_AUTHOR "Various"
+
+#define DRIVER_NAME "via_chrome9_chrome9"
+#define DRIVER_DESC "VIA_CHROME9 Unichrome / Pro"
+#define DRIVER_DATE "20080415"
+
+#define DRIVER_MAJOR 2
+#define DRIVER_MINOR 11
+#define DRIVER_PATCHLEVEL 1
+
+#define via_chrome9_PCI_BUF_SIZE 60000
+#define via_chrome9_FIRE_BUF_SIZE 1024
+#define via_chrome9_NUM_IRQS 4
+
+#define MAX_MEMORY_HEAPS 4
+#define NUMBER_OF_APERTURES 32
+
+/*typedef struct drm_via_chrome9_shadow_map drm_via_chrome9_shadow_map_t;*/
+struct drm_via_chrome9_shadow_map {
+ struct drm_map *shadow;
+ unsigned int shadow_size;
+ unsigned int *shadow_handle;
+};
+
+/*typedef struct drm_via_chrome9_pagetable_map
+ *drm_via_chrome9_pagetable_map_t;
+ */
+struct drm_via_chrome9_pagetable_map {
+ unsigned int pagetable_offset;
+ unsigned int pagetable_size;
+ unsigned int *pagetable_handle;
+ unsigned int mmt_register;
+};
+
+/*typedef struct drm_via_chrome9_private drm_via_chrome9_private_t;*/
+struct drm_via_chrome9_private {
+ int chip_agp;
+ int chip_index;
+ int chip_sub_index;
+
+ unsigned long front_offset;
+ unsigned long back_offset;
+ unsigned long depth_offset;
+ unsigned long fb_base_address;
+ unsigned long available_fb_size;
+ int usec_timeout;
+ int max_apertures;
+ struct drm_sman sman;
+ unsigned int alignment;
+ /* bit[31]:0:indicate no alignment needed,1:indicate
+ alignment needed and size is bit[0:30]*/
+
+ struct drm_map *sarea;
+ struct drm_via_chrome9_sarea *sarea_priv;
+
+ struct drm_map *mmio;
+ struct drm_map *hostBlt;
+ struct drm_map *fb;
+ struct drm_map *front;
+ struct drm_map *back;
+ struct drm_map *depth;
+ struct drm_map *agp_tex;
+ unsigned int agp_size;
+ unsigned int agp_offset;
+
+ struct semaphore *drm_s3g_sem;
+
+ struct drm_via_chrome9_shadow_map shadow_map;
+ struct drm_via_chrome9_pagetable_map pagetable_map;
+
+ char *bci;
+
+ int aperture_usage[NUMBER_OF_APERTURES];
+ void *event_tag_info;
+
+ /* DMA buffer manager */
+ void *dma_manager;
+ /* Indicate agp/pcie heap initialization flag */
+ int agp_initialized;
+ /* Indicate video heap initialization flag */
+ int vram_initialized;
+
+ unsigned long pcie_vmalloc_addr;
+
+ /* pointer to device information */
+ void *dev;
+ /* if agp init fail, go ahead and force dri use PCI*/
+ enum {
+ DRM_AGP_RING_BUFFER,
+ DRM_AGP_DOUBLE_BUFFER,
+ DRM_AGP_DISABLED
+ } drm_agp_type;
+ /*end*/
+
+ unsigned long *bci_buffer;
+ unsigned long pcie_vmalloc_nocache;
+};
+
+
+enum via_chrome9_family {
+ VIA_CHROME9_OTHER = 0, /* Baseline */
+ VIA_CHROME9_PRO_GROUP_A,/* Another video engine and DMA commands */
+ VIA_CHROME9_DX9_0,
+ VIA_CHROME9_PCIE_GROUP
+};
+
+/* VIA_CHROME9 MMIO register access */
+#define VIA_CHROME9_BASE ((dev_priv->mmio))
+
+#define VIA_CHROME9_READ(reg) DRM_READ32(VIA_CHROME9_BASE, reg)
+#define VIA_CHROME9_WRITE(reg, val) DRM_WRITE32(VIA_CHROME9_BASE, reg, val)
+#define VIA_CHROME9_READ8(reg) DRM_READ8(VIA_CHROME9_BASE, reg)
+#define VIA_CHROME9_WRITE8(reg, val) DRM_WRITE8(VIA_CHROME9_BASE, reg, val)
+
+#endif
--- /dev/null
+++ b/drivers/char/drm/via_chrome9_mm.c
@@ -0,0 +1,388 @@
+/*
+ * 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 "drmP.h"
+#include "via_chrome9_drm.h"
+#include "via_chrome9_drv.h"
+#include "drm_sman.h"
+#include "via_chrome9_mm.h"
+
+#define VIA_CHROME9_MM_GRANULARITY 4
+#define VIA_CHROME9_MM_GRANULARITY_MASK ((1 << VIA_CHROME9_MM_GRANULARITY) - 1)
+
+
+int via_chrome9_map_init(struct drm_device *dev,
+ struct drm_via_chrome9_init *init)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *)dev->dev_private;
+
+ dev_priv->sarea = drm_getsarea(dev);
+ if (!dev_priv->sarea) {
+ DRM_ERROR("could not find sarea!\n");
+ goto error;
+ }
+ dev_priv->sarea_priv =
+ (struct drm_via_chrome9_sarea *)((unsigned char *)dev_priv->
+ sarea->handle + init->sarea_priv_offset);
+
+ dev_priv->fb = drm_core_findmap(dev, init->fb_handle);
+ if (!dev_priv->fb) {
+ DRM_ERROR("could not find framebuffer!\n");
+ goto error;
+ }
+ /* Frame buffer physical base address */
+ dev_priv->fb_base_address = init->fb_base_address;
+
+ if (init->shadow_size) {
+ /* find apg shadow region mappings */
+ dev_priv->shadow_map.shadow = drm_core_findmap(dev, init->
+ shadow_handle);
+ if (!dev_priv->shadow_map.shadow) {
+ DRM_ERROR("could not shadow map!\n");
+ goto error;
+ }
+ dev_priv->shadow_map.shadow_size = init->shadow_size;
+ dev_priv->shadow_map.shadow_handle = (unsigned int *)dev_priv->
+ shadow_map.shadow->handle;
+ init->shadow_handle = dev_priv->shadow_map.shadow->offset;
+ }
+ if (init->agp_tex_size && init->chip_agp != CHIP_PCIE) {
+ /* find apg texture buffer mappings */
+ dev_priv->agp_tex = drm_core_findmap(dev, init->agp_tex_handle);
+ dev_priv->agp_size = init->agp_tex_size;
+ dev_priv->agp_offset = init->agp_tex_handle;
+ if (!dev_priv->agp_tex) {
+ DRM_ERROR("could not find agp texture map !\n");
+ goto error;
+ }
+ }
+ /* find mmio/dma mappings */
+ dev_priv->mmio = drm_core_findmap(dev, init->mmio_handle);
+ if (!dev_priv->mmio) {
+ DRM_ERROR("failed to find mmio region!\n");
+ goto error;
+ }
+
+ dev_priv->hostBlt = drm_core_findmap(dev, init->hostBlt_handle);
+ if (!dev_priv->hostBlt) {
+ DRM_ERROR("failed to find host bitblt region!\n");
+ goto error;
+ }
+
+ dev_priv->drm_agp_type = init->agp_type;
+ if (init->agp_type != AGP_DISABLED && init->chip_agp != CHIP_PCIE) {
+ dev->agp_buffer_map = drm_core_findmap(dev, init->dma_handle);
+ if (!dev->agp_buffer_map) {
+ DRM_ERROR("failed to find dma buffer region!\n");
+ goto error;
+ }
+ }
+
+ dev_priv->bci = (char *)dev_priv->mmio->handle + 0x10000;
+
+ return 0;
+
+error:
+ /* do cleanup here, refine_later */
+ return (-EINVAL);
+}
+
+int via_chrome9_heap_management_init(struct drm_device *dev,
+ struct drm_via_chrome9_init *init)
+{
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ int ret = 0;
+
+ /* video memory management. range: 0 ---- video_whole_size */
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_sman_set_range(&dev_priv->sman, VIA_CHROME9_MEM_VIDEO,
+ 0, dev_priv->available_fb_size >> VIA_CHROME9_MM_GRANULARITY);
+ if (ret) {
+ DRM_ERROR("VRAM memory manager initialization ******ERROR\
+ !******\n");
+ mutex_unlock(&dev->struct_mutex);
+ goto error;
+ }
+ dev_priv->vram_initialized = 1;
+ /* agp/pcie heap management.
+ note:because agp is contradict with pcie, so only one is enough
+ for managing both of them.*/
+ init->agp_type = dev_priv->drm_agp_type;
+ if (init->agp_type != AGP_DISABLED && dev_priv->agp_size) {
+ ret = drm_sman_set_range(&dev_priv->sman, VIA_CHROME9_MEM_AGP,
+ 0, dev_priv->agp_size >> VIA_CHROME9_MM_GRANULARITY);
+ if (ret) {
+ DRM_ERROR("AGP/PCIE memory manager initialization ******ERROR\
+ !******\n");
+ mutex_unlock(&dev->struct_mutex);
+ goto error;
+ }
+ dev_priv->agp_initialized = 1;
+ }
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+
+error:
+ /* Do error recover here, refine_later */
+ return -EINVAL;
+}
+
+
+void via_chrome9_memory_destroy_heap(struct drm_device *dev,
+ struct drm_via_chrome9_private *dev_priv)
+{
+ mutex_lock(&dev->struct_mutex);
+ drm_sman_cleanup(&dev_priv->sman);
+ dev_priv->vram_initialized = 0;
+ dev_priv->agp_initialized = 0;
+ mutex_unlock(&dev->struct_mutex);
+}
+
+void via_chrome9_reclaim_buffers_locked(struct drm_device *dev,
+ struct drm_file *file_priv)
+{
+ return;
+}
+
+int via_chrome9_ioctl_allocate_aperture(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ return 0;
+}
+
+int via_chrome9_ioctl_free_aperture(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ return 0;
+}
+
+
+/* Allocate memory from DRM module for video playing */
+int via_chrome9_ioctl_allocate_mem_base(struct drm_device *dev,
+void *data, struct drm_file *file_priv)
+{
+ struct drm_via_chrome9_mem *mem = data;
+ struct drm_memblock_item *item;
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ unsigned long tmpSize = 0, offset = 0, alignment = 0;
+ /* modify heap_type to agp for pcie, since we treat pcie/agp heap
+ no difference in heap management */
+ if (mem->type == memory_heap_pcie) {
+ if (dev_priv->chip_agp != CHIP_PCIE) {
+ DRM_ERROR(
+ "User want to alloc memory from pcie heap but via_chrome9.ko\
+ has no this heap exist.******ERROR******\n");
+ return -EINVAL;
+ }
+ mem->type = memory_heap_agp;
+ }
+
+ if (mem->type > VIA_CHROME9_MEM_AGP) {
+ DRM_ERROR("Unknown memory type allocation\n");
+ return -EINVAL;
+ }
+ mutex_lock(&dev->struct_mutex);
+ if (0 == ((mem->type == VIA_CHROME9_MEM_VIDEO) ?
+ dev_priv->vram_initialized : dev_priv->agp_initialized)) {
+ DRM_ERROR("Attempt to allocate from uninitialized\
+ memory manager.\n");
+ mutex_unlock(&dev->struct_mutex);
+ return -EINVAL;
+ }
+ tmpSize = (mem->size + VIA_CHROME9_MM_GRANULARITY_MASK) >>
+ VIA_CHROME9_MM_GRANULARITY;
+ mem->size = tmpSize << VIA_CHROME9_MM_GRANULARITY;
+ alignment = (dev_priv->alignment & 0x80000000) ? dev_priv->
+ alignment & 0x7FFFFFFF:0;
+ alignment /= (1 << VIA_CHROME9_MM_GRANULARITY);
+ item = drm_sman_alloc(&dev_priv->sman, mem->type, tmpSize, alignment,
+ (unsigned long)file_priv);
+ mutex_unlock(&dev->struct_mutex);
+ /* alloc failed */
+ if (!item) {
+ DRM_ERROR("Allocate memory failed ******ERROR******.\n");
+ return -ENOMEM;
+ }
+ /* Till here every thing is ok, we check the memory type allocated
+ and return appropriate value to user mode Here the value return to
+ user is very difficult to operate. BE CAREFULLY!!! */
+ /* offset is used by user mode ap to calculate the virtual address
+ which is used to access the memory allocated */
+ mem->index = item->user_hash.key;
+ offset = item->mm->offset(item->mm, item->mm_info) <<
+ VIA_CHROME9_MM_GRANULARITY;
+ switch (mem->type) {
+ case VIA_CHROME9_MEM_VIDEO:
+ mem->offset = offset + dev_priv->back_offset;
+ break;
+ case VIA_CHROME9_MEM_AGP:
+ /* return different value to user according to the chip type */
+ if (dev_priv->chip_agp == CHIP_PCIE) {
+ mem->offset = offset +
+ ((struct drm_via_chrome9_DMA_manager *)dev_priv->
+ dma_manager)->DMASize * sizeof(unsigned long);
+ } else {
+ mem->offset = offset;
+ }
+ break;
+ default:
+ /* Strange thing happen! Faint. Code bug! */
+ DRM_ERROR("Enter here is impossible ******\
+ ERROR******.\n");
+ return -EINVAL;
+ }
+ /*DONE. Need we call function copy_to_user ?NO. We can't even
+ touch user's space.But we are lucky, since kernel drm:drm_ioctl
+ will to the job for us. */
+ return 0;
+}
+
+/* Allocate video/AGP/PCIE memory from heap management */
+int via_chrome9_ioctl_allocate_mem_wrapper(struct drm_device
+ *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_via_chrome9_memory_alloc *memory_alloc =
+ (struct drm_via_chrome9_memory_alloc *)data;
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ struct drm_via_chrome9_mem mem;
+
+ mem.size = memory_alloc->size;
+ mem.type = memory_alloc->heap_type;
+ dev_priv->alignment = memory_alloc->align | 0x80000000;
+ if (via_chrome9_ioctl_allocate_mem_base(dev, &mem, file_priv)) {
+ DRM_ERROR("Allocate memory error!.\n");
+ return -ENOMEM;
+ }
+ dev_priv->alignment = 0;
+ /* Till here every thing is ok, we check the memory type allocated and
+ return appropriate value to user mode Here the value return to user is
+ very difficult to operate. BE CAREFULLY!!!*/
+ /* offset is used by user mode ap to calculate the virtual address
+ which is used to access the memory allocated */
+ memory_alloc->offset = mem.offset;
+ memory_alloc->heap_info.lpL1Node = (void *)mem.index;
+ memory_alloc->size = mem.size;
+ switch (memory_alloc->heap_type) {
+ case VIA_CHROME9_MEM_VIDEO:
+ memory_alloc->physaddress = memory_alloc->offset +
+ dev_priv->fb_base_address;
+ memory_alloc->linearaddress = (void *)memory_alloc->physaddress;
+ break;
+ case VIA_CHROME9_MEM_AGP:
+ /* return different value to user according to the chip type */
+ if (dev_priv->chip_agp == CHIP_PCIE) {
+ memory_alloc->physaddress = memory_alloc->offset;
+ memory_alloc->linearaddress = (void *)memory_alloc->
+ physaddress;
+ } else {
+ memory_alloc->physaddress = dev->agp->base +
+ memory_alloc->offset +
+ ((struct drm_via_chrome9_DMA_manager *)
+ dev_priv->dma_manager)->DMASize * sizeof(unsigned long);
+ memory_alloc->linearaddress =
+ (void *)memory_alloc->physaddress;
+ }
+ break;
+ default:
+ /* Strange thing happen! Faint. Code bug! */
+ DRM_ERROR("Enter here is impossible ******ERROR******.\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int via_chrome9_ioctl_free_mem_wrapper(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_via_chrome9_memory_alloc *memory_alloc = data;
+ struct drm_via_chrome9_mem mem;
+
+ mem.index = (unsigned long)memory_alloc->heap_info.lpL1Node;
+ if (via_chrome9_ioctl_freemem_base(dev, &mem, file_priv)) {
+ DRM_ERROR("function free_mem_wrapper error.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int via_chrome9_ioctl_freemem_base(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_via_chrome9_private *dev_priv = dev->dev_private;
+ struct drm_via_chrome9_mem *mem = data;
+ int ret;
+
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_sman_free_key(&dev_priv->sman, mem->index);
+ mutex_unlock(&dev->struct_mutex);
+ DRM_DEBUG("free = 0x%lx\n", mem->index);
+
+ return ret;
+}
+
+int via_chrome9_ioctl_check_vidmem_size(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ return 0;
+}
+
+int via_chrome9_ioctl_pciemem_ctrl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ int result = 0;
+ struct drm_via_chrome9_private *dev_priv = dev->dev_private;
+ struct drm_via_chrome9_pciemem_ctrl *pcie_memory_ctrl = data;
+ switch (pcie_memory_ctrl->ctrl_type) {
+ case pciemem_copy_from_user:
+ result = copy_from_user((void *)(
+ dev_priv->pcie_vmalloc_nocache+
+ pcie_memory_ctrl->pcieoffset),
+ pcie_memory_ctrl->usermode_data,
+ pcie_memory_ctrl->size);
+ break;
+ case pciemem_copy_to_user:
+ result = copy_to_user(pcie_memory_ctrl->usermode_data,
+ (void *)(dev_priv->pcie_vmalloc_nocache+
+ pcie_memory_ctrl->pcieoffset),
+ pcie_memory_ctrl->size);
+ break;
+ case pciemem_memset:
+ memset((void *)(dev_priv->pcie_vmalloc_nocache +
+ pcie_memory_ctrl->pcieoffset),
+ pcie_memory_ctrl->memsetdata,
+ pcie_memory_ctrl->size);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
--- /dev/null
+++ b/drivers/char/drm/via_chrome9_mm.h
@@ -0,0 +1,67 @@
+/*
+ * 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_CHROME9_MM_H_
+#define _VIA_CHROME9_MM_H_
+struct drm_via_chrome9_pciemem_ctrl {
+ enum {
+ pciemem_copy_from_user = 0,
+ pciemem_copy_to_user,
+ pciemem_memset,
+ } ctrl_type;
+ unsigned int pcieoffset;
+ unsigned int size;/*in Byte*/
+ unsigned char memsetdata;/*for memset*/
+ void *usermode_data;/*user mode data pointer*/
+};
+
+extern int via_chrome9_map_init(struct drm_device *dev,
+ struct drm_via_chrome9_init *init);
+extern int via_chrome9_heap_management_init(struct drm_device
+ *dev, struct drm_via_chrome9_init *init);
+extern void via_chrome9_memory_destroy_heap(struct drm_device
+ *dev, struct drm_via_chrome9_private *dev_priv);
+extern int via_chrome9_ioctl_check_vidmem_size(struct drm_device
+ *dev, void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_pciemem_ctrl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_allocate_aperture(struct drm_device
+ *dev, void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_free_aperture(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_allocate_mem_base(struct drm_device
+ *dev, void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_allocate_mem_wrapper(
+ struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_freemem_base(struct drm_device
+ *dev, void *data, struct drm_file *file_priv);
+extern int via_chrome9_ioctl_free_mem_wrapper(struct drm_device
+ *dev, void *data, struct drm_file *file_priv);
+extern void via_chrome9_reclaim_buffers_locked(struct drm_device
+ *dev, struct drm_file *file_priv);
+
+#endif
+
next prev parent reply other threads:[~2008-05-31 0:36 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-31 0:32 via agp patches Greg KH
2008-05-31 0:32 ` Greg KH
2008-05-31 14:47 ` Dave Jones
2008-05-31 17:41 ` Greg KH
2008-06-05 17:45 ` Dave Jones
2008-06-06 1:45 ` Greg KH
2008-05-31 0:33 ` Greg KH [this message]
2008-05-31 12:25 ` Alan Cox
2008-05-31 16:48 ` Jason L Tibbitts III
2008-05-31 17:43 ` Greg KH
2008-05-31 19:44 ` Alan Cox
2008-05-31 0:34 ` Greg KH
2008-05-31 22:50 ` Dave Airlie
2008-06-06 1:44 ` Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080531003354.GC6208@suse.de \
--to=gregkh@suse.de \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.