diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2008-05-30 17:42:32 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-05-30 17:42:32 -0700 |
| commit | 2ba6d8f6124b3ed806183c78903491610698e104 (patch) | |
| tree | 13e27ef5e55652d99e1e5562aecbce52ce20f8ad | |
| parent | 2ecddb867c1a51b33287bde7c4e54914dcdc6734 (diff) | |
| download | patches-2ba6d8f6124b3ed806183c78903491610698e104.tar.gz | |
add via patches
| -rw-r--r-- | ldp/via-agp.patch | 28 | ||||
| -rw-r--r-- | ldp/via-chrome9-drm.patch | 3873 | ||||
| -rw-r--r-- | ldp/via-unichrome-drm.patch | 3389 | ||||
| -rw-r--r-- | series | 4 |
4 files changed, 7294 insertions, 0 deletions
diff --git a/ldp/via-agp.patch b/ldp/via-agp.patch new file mode 100644 index 00000000000000..5b099135a039a2 --- /dev/null +++ b/ldp/via-agp.patch @@ -0,0 +1,28 @@ +--- + drivers/char/agp/via-agp.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +--- a/drivers/char/agp/via-agp.c ++++ b/drivers/char/agp/via-agp.c +@@ -389,11 +389,6 @@ static struct agp_device_ids via_agp_dev + .device_id = PCI_DEVICE_ID_VIA_VT3324, + .chipset_name = "CX700", + }, +- /* VT3336 */ +- { +- .device_id = PCI_DEVICE_ID_VIA_VT3336, +- .chipset_name = "VT3336", +- }, + /* P4M890 */ + { + .device_id = PCI_DEVICE_ID_VIA_P4M890, +@@ -546,8 +541,8 @@ static const struct pci_device_id agp_vi + ID(PCI_DEVICE_ID_VIA_3296_0), + ID(PCI_DEVICE_ID_VIA_P4M800CE), + ID(PCI_DEVICE_ID_VIA_VT3324), +- ID(PCI_DEVICE_ID_VIA_VT3336), + ID(PCI_DEVICE_ID_VIA_P4M890), ++ ID(PCI_DEVICE_ID_VIA_VT3364), + { } + }; + diff --git a/ldp/via-chrome9-drm.patch b/ldp/via-chrome9-drm.patch new file mode 100644 index 00000000000000..f9050c246e520d --- /dev/null +++ b/ldp/via-chrome9-drm.patch @@ -0,0 +1,3873 @@ +--- + 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 ++ diff --git a/ldp/via-unichrome-drm.patch b/ldp/via-unichrome-drm.patch new file mode 100644 index 00000000000000..728c36a5c7e3d6 --- /dev/null +++ b/ldp/via-unichrome-drm.patch @@ -0,0 +1,3389 @@ +--- + drivers/char/drm/via_3d_reg.h | 12 - + drivers/char/drm/via_dma.c | 353 +++++++++++++++++++++++++++------------- + drivers/char/drm/via_dmablit.c | 325 +++++++++++++++++++++--------------- + drivers/char/drm/via_dmablit.h | 22 +- + drivers/char/drm/via_drm.h | 142 ++++++++++------ + drivers/char/drm/via_drv.c | 13 + + drivers/char/drm/via_drv.h | 93 ++++++---- + drivers/char/drm/via_irq.c | 66 ++++--- + drivers/char/drm/via_map.c | 75 +++++++- + drivers/char/drm/via_mm.c | 249 ++++++++++++++++++++++------ + drivers/char/drm/via_verifier.c | 269 +++++++++++++++--------------- + drivers/char/drm/via_verifier.h | 64 +++---- + drivers/char/drm/via_video.c | 70 ++++--- + 13 files changed, 1111 insertions(+), 642 deletions(-) + +--- a/drivers/char/drm/via_3d_reg.h ++++ b/drivers/char/drm/via_3d_reg.h +@@ -1605,18 +1605,18 @@ + #define HC_ACMD_H4COUNT_MASK 0x01fffe00 + #define HC_ACMD_H4COUNT_SHIFT 9 + +-/******************************************************************************** ++/****************************************************************************** + ** Define Header +-********************************************************************************/ ++*******************************************************************************/ + #define HC_HEADER2 0xF210F110 + +-/******************************************************************************** ++/****************************************************************************** + ** Define Dummy Value +-********************************************************************************/ ++*******************************************************************************/ + #define HC_DUMMY 0xCCCCCCCC +-/******************************************************************************** ++/****************************************************************************** + ** Define for DMA use +-********************************************************************************/ ++*******************************************************************************/ + #define HALCYON_HEADER2 0XF210F110 + #define HALCYON_FIRECMD 0XEE100000 + #define HALCYON_FIREMASK 0XFFF00000 +--- a/drivers/char/drm/via_dmablit.c ++++ b/drivers/char/drm/via_dmablit.c +@@ -30,8 +30,8 @@ + /* + * Unmaps the DMA mappings. + * FIXME: Is this a NoOp on x86? Also +- * FIXME: What happens if this one is called and a pending blit has previously done +- * the same DMA mappings? ++ * FIXME: What happens if this one is called and a pending ++ * blit has previously done the same DMA mappings? + */ + + #include "drmP.h" +@@ -45,12 +45,12 @@ + #define VIA_PGOFF(x) (((unsigned long)(x)) & ~PAGE_MASK) + #define VIA_PFN(x) ((unsigned long)(x) >> PAGE_SHIFT) + +-typedef struct _drm_via_descriptor { ++struct drm_via_descriptor { + uint32_t mem_addr; + uint32_t dev_addr; + uint32_t size; + uint32_t next; +-} drm_via_descriptor_t; ++} ; + + + /* +@@ -60,24 +60,26 @@ typedef struct _drm_via_descriptor { + + + static void +-via_unmap_blit_from_device(struct pci_dev *pdev, drm_via_sg_info_t *vsg) ++via_unmap_blit_from_device(struct pci_dev *pdev, struct drm_via_sg_info *vsg) + { + int num_desc = vsg->num_desc; + unsigned cur_descriptor_page = num_desc / vsg->descriptors_per_page; + unsigned descriptor_this_page = num_desc % vsg->descriptors_per_page; +- drm_via_descriptor_t *desc_ptr = vsg->desc_pages[cur_descriptor_page] + +- descriptor_this_page; ++ struct drm_via_descriptor *desc_ptr = ++ vsg->desc_pages[cur_descriptor_page] + descriptor_this_page; + dma_addr_t next = vsg->chain_start; + +- while(num_desc--) { ++ while (num_desc--) { + if (descriptor_this_page-- == 0) { + cur_descriptor_page--; + descriptor_this_page = vsg->descriptors_per_page - 1; + desc_ptr = vsg->desc_pages[cur_descriptor_page] + + descriptor_this_page; + } +- dma_unmap_single(&pdev->dev, next, sizeof(*desc_ptr), DMA_TO_DEVICE); +- dma_unmap_page(&pdev->dev, desc_ptr->mem_addr, desc_ptr->size, vsg->direction); ++ dma_unmap_single(&pdev->dev, next, sizeof(*desc_ptr), ++ DMA_TO_DEVICE); ++ dma_unmap_page(&pdev->dev, desc_ptr->mem_addr, desc_ptr->size, ++ vsg->direction); + next = (dma_addr_t) desc_ptr->next; + desc_ptr--; + } +@@ -85,15 +87,16 @@ via_unmap_blit_from_device(struct pci_de + + /* + * If mode = 0, count how many descriptors are needed. +- * If mode = 1, Map the DMA pages for the device, put together and map also the descriptors. +- * Descriptors are run in reverse order by the hardware because we are not allowed to update the +- * 'next' field without syncing calls when the descriptor is already mapped. ++ * If mode = 1, Map the DMA pages for the device, put together and ++ * map also the descriptors. Descriptors are run in reverse order ++ * by the hardware because we are not allowed to update the 'next' ++ * field without syncing calls when the descriptor is already mapped. + */ + + static void + via_map_blit_for_device(struct pci_dev *pdev, +- const drm_via_dmablit_t *xfer, +- drm_via_sg_info_t *vsg, ++ const struct drm_via_dmablit *xfer, ++ struct drm_via_sg_info *vsg, + int mode) + { + unsigned cur_descriptor_page = 0; +@@ -108,7 +111,7 @@ via_map_blit_for_device(struct pci_dev * + int num_desc = 0; + int cur_line; + dma_addr_t next = 0 | VIA_DMA_DPR_EC; +- drm_via_descriptor_t *desc_ptr = NULL; ++ struct drm_via_descriptor *desc_ptr = NULL; + + if (mode == 1) + desc_ptr = vsg->desc_pages[cur_descriptor_page]; +@@ -121,26 +124,29 @@ via_map_blit_for_device(struct pci_dev * + + while (line_len > 0) { + +- remaining_len = min(PAGE_SIZE-VIA_PGOFF(cur_mem), line_len); ++ remaining_len = min(PAGE_SIZE-VIA_PGOFF(cur_mem), ++ line_len); + line_len -= remaining_len; + + if (mode == 1) { + desc_ptr->mem_addr = + dma_map_page(&pdev->dev, +- vsg->pages[VIA_PFN(cur_mem) - +- VIA_PFN(first_addr)], +- VIA_PGOFF(cur_mem), remaining_len, +- vsg->direction); ++ vsg->pages[VIA_PFN(cur_mem) - ++ VIA_PFN(first_addr)], ++ VIA_PGOFF(cur_mem), remaining_len, ++ vsg->direction); + desc_ptr->dev_addr = cur_fb; + + desc_ptr->size = remaining_len; + desc_ptr->next = (uint32_t) next; +- next = dma_map_single(&pdev->dev, desc_ptr, sizeof(*desc_ptr), +- DMA_TO_DEVICE); ++ next = dma_map_single(&pdev->dev, desc_ptr, ++ sizeof(*desc_ptr), DMA_TO_DEVICE); + desc_ptr++; +- if (++num_descriptors_this_page >= vsg->descriptors_per_page) { ++ if (++num_descriptors_this_page >= ++ vsg->descriptors_per_page) { + num_descriptors_this_page = 0; +- desc_ptr = vsg->desc_pages[++cur_descriptor_page]; ++ desc_ptr = ++ vsg->desc_pages[++cur_descriptor_page]; + } + } + +@@ -162,30 +168,31 @@ via_map_blit_for_device(struct pci_dev * + + /* + * Function that frees up all resources for a blit. It is usable even if the +- * blit info has only been partially built as long as the status enum is consistent +- * with the actual status of the used resources. ++ * blit info has only been partially built as long as the status enum is ++ * consistent with the actual status of the used resources. + */ + +- + static void +-via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg) ++via_free_sg_info(struct pci_dev *pdev, struct drm_via_sg_info *vsg) + { + struct page *page; + int i; + +- switch(vsg->state) { ++ switch (vsg->state) { + case dr_via_device_mapped: + via_unmap_blit_from_device(pdev, vsg); + case dr_via_desc_pages_alloc: +- for (i=0; i<vsg->num_desc_pages; ++i) { ++ for (i = 0; i < vsg->num_desc_pages; ++i) { + if (vsg->desc_pages[i] != NULL) + free_page((unsigned long)vsg->desc_pages[i]); + } + kfree(vsg->desc_pages); + case dr_via_pages_locked: +- for (i=0; i<vsg->num_pages; ++i) { +- if ( NULL != (page = vsg->pages[i])) { +- if (! PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction)) ++ for (i = 0; i < vsg->num_pages; ++i) { ++ page = vsg->pages[i]; ++ if (NULL != page) { ++ if (!PageReserved(page) && ++ (DMA_FROM_DEVICE == vsg->direction)) + SetPageDirty(page); + page_cache_release(page); + } +@@ -207,36 +214,44 @@ via_free_sg_info(struct pci_dev *pdev, d + */ + + static void +-via_fire_dmablit(struct drm_device *dev, drm_via_sg_info_t *vsg, int engine) ++via_fire_dmablit(struct drm_device *dev, struct drm_via_sg_info *vsg, ++ int engine) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *)dev->dev_private; + + VIA_WRITE(VIA_PCI_DMA_MAR0 + engine*0x10, 0); + VIA_WRITE(VIA_PCI_DMA_DAR0 + engine*0x10, 0); +- VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DD | VIA_DMA_CSR_TD | +- VIA_DMA_CSR_DE); +- VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE); ++ VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, ++ VIA_DMA_CSR_DD | VIA_DMA_CSR_TD | VIA_DMA_CSR_DE); ++ VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, ++ VIA_DMA_MR_CM | VIA_DMA_MR_TDIE); + VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0); + VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start); + DRM_WRITEMEMORYBARRIER(); +- VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS); ++ VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, ++ VIA_DMA_CSR_DE | VIA_DMA_CSR_TS); + VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04); + } + + /* +- * Obtain a page pointer array and lock all pages into system memory. A segmentation violation will +- * occur here if the calling user does not have access to the submitted address. ++ * Obtain a page pointer array and lock all pages into system memory. ++ * A segmentation violation will occur here if the calling user ++ * does not have access to the submitted address. + */ + + static int +-via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) ++via_lock_all_dma_pages(struct drm_via_sg_info *vsg, ++ struct drm_via_dmablit *xfer) + { + int ret; + unsigned long first_pfn = VIA_PFN(xfer->mem_addr); +- vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride -1)) - ++ vsg->num_pages = VIA_PFN(xfer->mem_addr + ++ (xfer->num_lines * xfer->mem_stride - 1)) - + first_pfn + 1; +- +- if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages))) ++ vsg->pages = vmalloc(sizeof(struct page *) * ++ vsg->num_pages); ++ if (NULL == vsg->pages) + return -ENOMEM; + memset(vsg->pages, 0, sizeof(struct page *) * vsg->num_pages); + down_read(¤t->mm->mmap_sem); +@@ -259,38 +274,42 @@ via_lock_all_dma_pages(drm_via_sg_info_t + } + + /* +- * Allocate DMA capable memory for the blit descriptor chain, and an array that keeps track of the +- * pages we allocate. We don't want to use kmalloc for the descriptor chain because it may be +- * quite large for some blits, and pages don't need to be contingous. ++ * Allocate DMA capable memory for the blit descriptor chain, and an ++ * array that keeps track of the pages we allocate. We don't want ++ * to use kmalloc for the descriptor chain because it may be + */ + + static int +-via_alloc_desc_pages(drm_via_sg_info_t *vsg) ++via_alloc_desc_pages(struct drm_via_sg_info *vsg) + { + int i; + +- vsg->descriptors_per_page = PAGE_SIZE / sizeof( drm_via_descriptor_t); ++ vsg->descriptors_per_page = PAGE_SIZE / ++ sizeof(struct drm_via_descriptor); + vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) / + vsg->descriptors_per_page; +- +- if (NULL == (vsg->desc_pages = kcalloc(vsg->num_desc_pages, sizeof(void *), GFP_KERNEL))) ++ vsg->desc_pages = kcalloc(vsg->num_desc_pages, ++ sizeof(void *), GFP_KERNEL); ++ if (NULL == vsg->desc_pages) + return -ENOMEM; + + vsg->state = dr_via_desc_pages_alloc; +- for (i=0; i<vsg->num_desc_pages; ++i) { +- if (NULL == (vsg->desc_pages[i] = +- (drm_via_descriptor_t *) __get_free_page(GFP_KERNEL))) ++ for (i = 0; i < vsg->num_desc_pages; ++i) { ++ vsg->desc_pages[i] = ++ (struct drm_via_descriptor *) __get_free_page(GFP_KERNEL); ++ if (NULL == vsg->desc_pages[i]) + return -ENOMEM; + } +- DRM_DEBUG("Allocated %d pages for %d descriptors.\n", vsg->num_desc_pages, +- vsg->num_desc); ++ DRM_DEBUG("Allocated %d pages for %d descriptors.\n", \ ++ vsg->num_desc_pages, vsg->num_desc); + return 0; + } + + static void + via_abort_dmablit(struct drm_device *dev, int engine) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *)dev->dev_private; + + VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TA); + } +@@ -298,32 +317,36 @@ via_abort_dmablit(struct drm_device *dev + static void + via_dmablit_engine_off(struct drm_device *dev, int engine) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *)dev->dev_private; + +- VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD | VIA_DMA_CSR_DD); ++ VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, ++ VIA_DMA_CSR_TD | VIA_DMA_CSR_DD); + } + + + + /* +- * The dmablit part of the IRQ handler. Trying to do only reasonably fast things here. +- * The rest, like unmapping and freeing memory for done blits is done in a separate workqueue +- * task. Basically the task of the interrupt handler is to submit a new blit to the engine, while ++ * The dmablit part of the IRQ handler. Trying to do only reasonably ++ * fast things here. The rest, like unmapping and freeing memory for ++ * done blits is done in a separate workqueue task. Basically the ++ * task of the interrupt handler is to submit a new blit to the engine, while + * the workqueue task takes care of processing associated with the old blit. + */ + + void + via_dmablit_handler(struct drm_device *dev, int engine, int from_irq) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; +- drm_via_blitq_t *blitq = dev_priv->blit_queues + engine; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *)dev->dev_private; ++ struct drm_via_blitq *blitq = dev_priv->blit_queues + engine; + int cur; + int done_transfer; +- unsigned long irqsave=0; ++ unsigned long irqsave = 0; + uint32_t status = 0; + +- DRM_DEBUG("DMA blit handler called. engine = %d, from_irq = %d, blitq = 0x%lx\n", +- engine, from_irq, (unsigned long) blitq); ++ DRM_DEBUG("DMA blit handler called. engine = %d, from_irq = %d, " ++ "blitq = 0x%lx\n", engine, from_irq, (unsigned long) blitq); + + if (from_irq) { + spin_lock(&blitq->blit_lock); +@@ -332,8 +355,10 @@ via_dmablit_handler(struct drm_device *d + } + + done_transfer = blitq->is_active && +- (( status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD); +- done_transfer = done_transfer || ( blitq->aborting && !(status & VIA_DMA_CSR_DE)); ++ ((status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & ++ VIA_DMA_CSR_TD); ++ done_transfer = done_transfer || (blitq->aborting && ++ !(status & VIA_DMA_CSR_DE)); + + cur = blitq->cur; + if (done_transfer) { +@@ -357,7 +382,8 @@ via_dmablit_handler(struct drm_device *d + blitq->aborting = 0; + schedule_work(&blitq->wq); + +- } else if (blitq->is_active && time_after_eq(jiffies, blitq->end)) { ++ } else if (blitq->is_active && ++ time_after_eq(jiffies, blitq->end)) { + + /* + * Abort transfer after one second. +@@ -378,9 +404,8 @@ via_dmablit_handler(struct drm_device *d + if (!timer_pending(&blitq->poll_timer)) + mod_timer(&blitq->poll_timer, jiffies + 1); + } else { +- if (timer_pending(&blitq->poll_timer)) { ++ if (timer_pending(&blitq->poll_timer)) + del_timer(&blitq->poll_timer); +- } + via_dmablit_engine_off(dev, engine); + } + } +@@ -399,7 +424,8 @@ via_dmablit_handler(struct drm_device *d + */ + + static int +-via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, wait_queue_head_t **queue) ++via_dmablit_active(struct drm_via_blitq *blitq, int engine, uint32_t handle, ++wait_queue_head_t **queue) + { + unsigned long irqsave; + uint32_t slot; +@@ -415,10 +441,10 @@ via_dmablit_active(drm_via_blitq_t *blit + ((blitq->cur_blit_handle - handle) <= (1 << 23)); + + if (queue && active) { +- slot = handle - blitq->done_blit_handle + blitq->cur -1; +- if (slot >= VIA_NUM_BLIT_SLOTS) { ++ slot = handle - blitq->done_blit_handle + blitq->cur - 1; ++ if (slot >= VIA_NUM_BLIT_SLOTS) + slot -= VIA_NUM_BLIT_SLOTS; +- } ++ + *queue = blitq->blit_queue + slot; + } + +@@ -435,28 +461,32 @@ static int + via_dmablit_sync(struct drm_device *dev, uint32_t handle, int engine) + { + +- drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; +- drm_via_blitq_t *blitq = dev_priv->blit_queues + engine; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *)dev->dev_private; ++ struct drm_via_blitq *blitq = dev_priv->blit_queues + engine; + wait_queue_head_t *queue; + int ret = 0; + + if (via_dmablit_active(blitq, engine, handle, &queue)) { + DRM_WAIT_ON(ret, *queue, 3 * DRM_HZ, +- !via_dmablit_active(blitq, engine, handle, NULL)); ++ !via_dmablit_active(blitq, engine, handle, NULL)); + } +- DRM_DEBUG("DMA blit sync handle 0x%x engine %d returned %d\n", +- handle, engine, ret); ++ DRM_DEBUG("DMA blit sync handle 0x%x engine %d returned %d\n", \ ++ handle, engine, ret); + + return ret; + } + + + /* +- * A timer that regularly polls the blit engine in cases where we don't have interrupts: +- * a) Broken hardware (typically those that don't have any video capture facility). +- * b) Blit abort. The hardware doesn't send an interrupt when a blit is aborted. +- * The timer and hardware IRQ's can and do work in parallel. If the hardware has +- * irqs, it will shorten the latency somewhat. ++ * A timer that regularly polls the blit engine in cases where ++ * we don't have interrupts: ++ * a) Broken hardware (typically those that don't have any ++ * video capture facility). ++ * b) Blit abort. The hardware doesn't send an interrupt ++ * when a blit is aborted. ++ * The timer and hardware IRQ's can and do work in parallel. ++ * If the hardware has irqs, it will shorten the latency somewhat. + */ + + +@@ -464,10 +494,10 @@ via_dmablit_sync(struct drm_device *dev, + static void + via_dmablit_timer(unsigned long data) + { +- drm_via_blitq_t *blitq = (drm_via_blitq_t *) data; ++ struct drm_via_blitq *blitq = (struct drm_via_blitq *) data; + struct drm_device *dev = blitq->dev; + int engine = (int) +- (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues); ++ (blitq - ((struct drm_via_private *)dev->dev_private)->blit_queues); + + DRM_DEBUG("Polling timer called for engine %d, jiffies %lu\n", engine, + (unsigned long) jiffies); +@@ -482,7 +512,7 @@ via_dmablit_timer(unsigned long data) + * to shorten abort latency. This is a little nasty. + */ + +- via_dmablit_handler(dev, engine, 0); ++ via_dmablit_handler(dev, engine, 0); + + } + } +@@ -500,19 +530,21 @@ via_dmablit_timer(unsigned long data) + static void + via_dmablit_workqueue(struct work_struct *work) + { +- drm_via_blitq_t *blitq = container_of(work, drm_via_blitq_t, wq); ++ struct drm_via_blitq *blitq = ++ container_of(work, struct drm_via_blitq, wq); + struct drm_device *dev = blitq->dev; + unsigned long irqsave; +- drm_via_sg_info_t *cur_sg; ++ struct drm_via_sg_info *cur_sg; + int cur_released; + + +- DRM_DEBUG("Workqueue task called for blit engine %ld\n",(unsigned long) +- (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues)); ++ DRM_DEBUG("Workqueue task called for blit engine %ld\n", ++ (unsigned long)(blitq - ++ ((struct drm_via_private *)dev->dev_private)->blit_queues)); + + spin_lock_irqsave(&blitq->blit_lock, irqsave); + +- while(blitq->serviced != blitq->cur) { ++ while (blitq->serviced != blitq->cur) { + + cur_released = blitq->serviced++; + +@@ -546,13 +578,14 @@ via_dmablit_workqueue(struct work_struct + void + via_init_dmablit(struct drm_device *dev) + { +- int i,j; +- drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; +- drm_via_blitq_t *blitq; ++ int i, j; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *)dev->dev_private; ++ struct drm_via_blitq *blitq; + + pci_set_master(dev->pdev); + +- for (i=0; i< VIA_NUM_BLIT_ENGINES; ++i) { ++ for (i = 0; i < VIA_NUM_BLIT_ENGINES; ++i) { + blitq = dev_priv->blit_queues + i; + blitq->dev = dev; + blitq->cur_blit_handle = 0; +@@ -565,9 +598,9 @@ via_init_dmablit(struct drm_device *dev) + blitq->is_active = 0; + blitq->aborting = 0; + spin_lock_init(&blitq->blit_lock); +- for (j=0; j<VIA_NUM_BLIT_SLOTS; ++j) { ++ for (j = 0; j < VIA_NUM_BLIT_SLOTS; ++j) + DRM_INIT_WAITQUEUE(blitq->blit_queue + j); +- } ++ + DRM_INIT_WAITQUEUE(&blitq->busy_queue); + INIT_WORK(&blitq->wq, via_dmablit_workqueue); + setup_timer(&blitq->poll_timer, via_dmablit_timer, +@@ -581,7 +614,8 @@ via_init_dmablit(struct drm_device *dev) + + + static int +-via_build_sg_info(struct drm_device *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) ++via_build_sg_info(struct drm_device *dev, struct drm_via_sg_info *vsg, ++ struct drm_via_dmablit *xfer) + { + int draw = xfer->to_fb; + int ret = 0; +@@ -622,7 +656,8 @@ via_build_sg_info(struct drm_device *dev + * DOS security hole. + */ + +- if (xfer->num_lines > 2048 || (xfer->num_lines*xfer->mem_stride > (2048*2048*4))) { ++ if (xfer->num_lines > 2048 || ++ (xfer->num_lines*xfer->mem_stride > (2048*2048*4))) { + DRM_ERROR("Too large PCI DMA bitblt.\n"); + return -EINVAL; + } +@@ -639,14 +674,17 @@ via_build_sg_info(struct drm_device *dev + } + + /* +- * A hardware bug seems to be worked around if system memory addresses start on +- * 16 byte boundaries. This seems a bit restrictive however. VIA is contacted +- * about this. Meanwhile, impose the following restrictions: ++ * A hardware bug seems to be worked around if system memory ++ * addresses start on 16 byte boundaries. This seems a bit ++ * restrictive however. VIA is contacted about this. ++ * Meanwhile, impose the following restrictions: + */ + + #ifdef VIA_BUGFREE +- if ((((unsigned long)xfer->mem_addr & 3) != ((unsigned long)xfer->fb_addr & 3)) || +- ((xfer->num_lines > 1) && ((xfer->mem_stride & 3) != (xfer->fb_stride & 3)))) { ++ if ((((unsigned long)xfer->mem_addr & 3) != ++ ((unsigned long)xfer->fb_addr & 3)) || ++ ((xfer->num_lines > 1) && ((xfer->mem_stride & 3) != ++ (xfer->fb_stride & 3)))) { + DRM_ERROR("Invalid DRM bitblt alignment.\n"); + return -EINVAL; + } +@@ -654,20 +692,21 @@ via_build_sg_info(struct drm_device *dev + if ((((unsigned long)xfer->mem_addr & 15) || + ((unsigned long)xfer->fb_addr & 3)) || + ((xfer->num_lines > 1) && +- ((xfer->mem_stride & 15) || (xfer->fb_stride & 3)))) { ++ ((xfer->mem_stride & 15) || (xfer->fb_stride & 3)))) { + DRM_ERROR("Invalid DRM bitblt alignment.\n"); + return -EINVAL; + } + #endif +- +- if (0 != (ret = via_lock_all_dma_pages(vsg, xfer))) { ++ ret = via_lock_all_dma_pages(vsg, xfer); ++ if (0 != ret) { + DRM_ERROR("Could not lock DMA pages.\n"); + via_free_sg_info(dev->pdev, vsg); + return ret; + } + + via_map_blit_for_device(dev->pdev, xfer, vsg, 0); +- if (0 != (ret = via_alloc_desc_pages(vsg))) { ++ ret = via_alloc_desc_pages(vsg); ++ if (0 != ret) { + DRM_ERROR("Could not allocate DMA descriptor pages.\n"); + via_free_sg_info(dev->pdev, vsg); + return ret; +@@ -684,20 +723,21 @@ via_build_sg_info(struct drm_device *dev + */ + + static int +-via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine) ++via_dmablit_grab_slot(struct drm_via_blitq *blitq, int engine) + { +- int ret=0; ++ int ret = 0; + unsigned long irqsave; + + DRM_DEBUG("Num free is %d\n", blitq->num_free); + spin_lock_irqsave(&blitq->blit_lock, irqsave); ++ while (blitq->num_free == 0) { + while(blitq->num_free == 0) { + spin_unlock_irqrestore(&blitq->blit_lock, irqsave); + +- DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0); +- if (ret) { ++ DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, ++ blitq->num_free > 0); ++ if (ret) + return (-EINTR == ret) ? -EAGAIN : ret; +- } + + spin_lock_irqsave(&blitq->blit_lock, irqsave); + } +@@ -713,14 +753,14 @@ via_dmablit_grab_slot(drm_via_blitq_t *b + */ + + static void +-via_dmablit_release_slot(drm_via_blitq_t *blitq) ++via_dmablit_release_slot(struct drm_via_blitq *blitq) + { + unsigned long irqsave; + + spin_lock_irqsave(&blitq->blit_lock, irqsave); + blitq->num_free++; + spin_unlock_irqrestore(&blitq->blit_lock, irqsave); +- DRM_WAKEUP( &blitq->busy_queue ); ++ DRM_WAKEUP(&blitq->busy_queue); + } + + /* +@@ -729,11 +769,12 @@ via_dmablit_release_slot(drm_via_blitq_t + + + static int +-via_dmablit(struct drm_device *dev, drm_via_dmablit_t *xfer) ++via_dmablit(struct drm_device *dev, struct drm_via_dmablit *xfer) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; +- drm_via_sg_info_t *vsg; +- drm_via_blitq_t *blitq; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *)dev->dev_private; ++ struct drm_via_sg_info *vsg; ++ struct drm_via_blitq *blitq; + int ret; + int engine; + unsigned long irqsave; +@@ -745,14 +786,16 @@ via_dmablit(struct drm_device *dev, drm_ + + engine = (xfer->to_fb) ? 0 : 1; + blitq = dev_priv->blit_queues + engine; +- if (0 != (ret = via_dmablit_grab_slot(blitq, engine))) { ++ ret = via_dmablit_grab_slot(blitq, engine); ++ if (0 != ret) + return ret; +- } +- if (NULL == (vsg = kmalloc(sizeof(*vsg), GFP_KERNEL))) { ++ vsg = kmalloc(sizeof(*vsg), GFP_KERNEL); ++ if (NULL == vsg) { + via_dmablit_release_slot(blitq); + return -ENOMEM; + } +- if (0 != (ret = via_build_sg_info(dev, vsg, xfer))) { ++ ret = via_build_sg_info(dev, vsg, xfer); ++ if (0 != ret) { + via_dmablit_release_slot(blitq); + kfree(vsg); + return ret; +@@ -774,16 +817,19 @@ via_dmablit(struct drm_device *dev, drm_ + } + + /* +- * Sync on a previously submitted blit. Note that the X server use signals extensively, and +- * that there is a very big probability that this IOCTL will be interrupted by a signal. In that +- * case it returns with -EAGAIN for the signal to be delivered. +- * The caller should then reissue the IOCTL. This is similar to what is being done for drmGetLock(). ++ * Sync on a previously submitted blit. Note that the X ++ * server use signals extensively, and that there is a very ++ * big probability that this IOCTL will be interrupted by a signal. ++ * In that case it returns with -EAGAIN for the signal to be delivered. ++ * The caller should then reissue the IOCTL. This is similar to ++ * what is being done for drmGetLock(). + */ + + int +-via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv ) ++via_dma_blit_sync(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) + { +- drm_via_blitsync_t *sync = data; ++ struct drm_via_blitsync *sync = data; + int err; + + if (sync->engine >= VIA_NUM_BLIT_ENGINES) +@@ -799,15 +845,16 @@ via_dma_blit_sync( struct drm_device *de + + + /* +- * Queue a blit and hand back a handle to be used for sync. This IOCTL may be interrupted by a signal +- * while waiting for a free slot in the blit queue. In that case it returns with -EAGAIN and should +- * be reissued. See the above IOCTL code. ++ * Queue a blit and hand back a handle to be used for sync. ++ * This IOCTL may be interrupted by a signal while waiting for ++ * a free slot in the blit queue. In that case it returns with ++ * -EAGAIN and should be reissued. See the above IOCTL code. + */ + + int +-via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv ) ++via_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv) + { +- drm_via_dmablit_t *xfer = data; ++ struct drm_via_dmablit *xfer = data; + int err; + + err = via_dmablit(dev, xfer); +--- a/drivers/char/drm/via_dmablit.h ++++ b/drivers/char/drm/via_dmablit.h +@@ -35,30 +35,30 @@ + #define VIA_NUM_BLIT_ENGINES 2 + #define VIA_NUM_BLIT_SLOTS 8 + +-struct _drm_via_descriptor; ++struct drm_via_descriptor; + +-typedef struct _drm_via_sg_info { ++struct drm_via_sg_info { + struct page **pages; + unsigned long num_pages; +- struct _drm_via_descriptor **desc_pages; ++ struct drm_via_descriptor **desc_pages; + int num_desc_pages; + int num_desc; + enum dma_data_direction direction; + unsigned char *bounce_buffer; +- dma_addr_t chain_start; ++ dma_addr_t chain_start; + uint32_t free_on_sequence; +- unsigned int descriptors_per_page; ++ unsigned int descriptors_per_page; + int aborted; + enum { +- dr_via_device_mapped, ++ dr_via_device_mapped, + dr_via_desc_pages_alloc, + dr_via_pages_locked, + dr_via_pages_alloc, + dr_via_sg_init + } state; +-} drm_via_sg_info_t; ++}; + +-typedef struct _drm_via_blitq { ++struct drm_via_blitq { + struct drm_device *dev; + uint32_t cur_blit_handle; + uint32_t done_blit_handle; +@@ -68,15 +68,15 @@ typedef struct _drm_via_blitq { + unsigned num_free; + unsigned num_outstanding; + unsigned long end; +- int aborting; ++ int aborting; + int is_active; +- drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS]; ++ struct drm_via_sg_info *blits[VIA_NUM_BLIT_SLOTS]; + spinlock_t blit_lock; + wait_queue_head_t blit_queue[VIA_NUM_BLIT_SLOTS]; + wait_queue_head_t busy_queue; + struct work_struct wq; + struct timer_list poll_timer; +-} drm_via_blitq_t; ++}; + + + /* +--- a/drivers/char/drm/via_dma.c ++++ b/drivers/char/drm/via_dma.c +@@ -58,28 +58,31 @@ + *((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1; \ + *((uint32_t *)(vb) + 1) = (nData); \ + vb = ((uint32_t *)vb) + 2; \ +- dev_priv->dma_low +=8; \ ++ dev_priv->dma_low += 8; \ + } + + #define via_flush_write_combine() DRM_MEMORYBARRIER() + + #define VIA_OUT_RING_QW(w1,w2) \ ++ do { \ + *vb++ = (w1); \ + *vb++ = (w2); \ +- dev_priv->dma_low += 8; ++ dev_priv->dma_low += 8; \ ++ } while (0); ++ ++static void via_cmdbuf_start(struct drm_via_private *dev_priv); ++static void via_cmdbuf_pause(struct drm_via_private *dev_priv); ++static void via_cmdbuf_reset(struct drm_via_private *dev_priv); ++static void via_cmdbuf_rewind(struct drm_via_private *dev_priv); ++static int via_wait_idle(struct drm_via_private *dev_priv); ++static void via_pad_cache(struct drm_via_private *dev_priv, int qwords); + +-static void via_cmdbuf_start(drm_via_private_t * dev_priv); +-static void via_cmdbuf_pause(drm_via_private_t * dev_priv); +-static void via_cmdbuf_reset(drm_via_private_t * dev_priv); +-static void via_cmdbuf_rewind(drm_via_private_t * dev_priv); +-static int via_wait_idle(drm_via_private_t * dev_priv); +-static void via_pad_cache(drm_via_private_t * dev_priv, int qwords); + + /* + * Free space in command buffer. + */ + +-static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv) ++static uint32_t via_cmdbuf_space(struct drm_via_private *dev_priv) + { + uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; + uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base; +@@ -93,7 +96,7 @@ static uint32_t via_cmdbuf_space(drm_via + * How much does the command regulator lag behind? + */ + +-static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv) ++static uint32_t via_cmdbuf_lag(struct drm_via_private *dev_priv) + { + uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; + uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base; +@@ -108,7 +111,7 @@ static uint32_t via_cmdbuf_lag(drm_via_p + */ + + static inline int +-via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size) ++via_cmdbuf_wait(struct drm_via_private *dev_priv, unsigned int size) + { + uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; + uint32_t cur_addr, hw_addr, next_addr; +@@ -122,7 +125,7 @@ via_cmdbuf_wait(drm_via_private_t * dev_ + hw_addr = *hw_addr_ptr - agp_base; + if (count-- == 0) { + DRM_ERROR +- ("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n", ++ ("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n", + hw_addr, cur_addr, next_addr); + return -1; + } +@@ -139,25 +142,25 @@ via_cmdbuf_wait(drm_via_private_t * dev_ + * Returns virtual pointer to ring buffer. + */ + +-static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv, ++static inline uint32_t *via_check_dma(struct drm_via_private *dev_priv, + unsigned int size) + { + if ((dev_priv->dma_low + size + 4 * CMDBUF_ALIGNMENT_SIZE) > +- dev_priv->dma_high) { ++ dev_priv->dma_high) + via_cmdbuf_rewind(dev_priv); +- } +- if (via_cmdbuf_wait(dev_priv, size) != 0) { ++ ++ if (via_cmdbuf_wait(dev_priv, size) != 0) + return NULL; +- } ++ + + return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low); + } + +-int via_dma_cleanup(struct drm_device * dev) ++int via_dma_cleanup(struct drm_device *dev) + { + if (dev->dev_private) { +- drm_via_private_t *dev_priv = +- (drm_via_private_t *) dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + + if (dev_priv->ring.virtual_start) { + via_cmdbuf_reset(dev_priv); +@@ -171,9 +174,9 @@ int via_dma_cleanup(struct drm_device * + return 0; + } + +-static int via_initialize(struct drm_device * dev, +- drm_via_private_t * dev_priv, +- drm_via_dma_init_t * init) ++static int via_initialize(struct drm_device *dev, ++ struct drm_via_private *dev_priv, ++ struct drm_via_dma_init *init) + { + if (!dev_priv || !dev_priv->mmio) { + DRM_ERROR("via_dma_init called before via_map_init\n"); +@@ -227,10 +230,12 @@ static int via_initialize(struct drm_dev + return 0; + } + +-static int via_dma_init(struct drm_device *dev, void *data, struct drm_file *file_priv) ++static int via_dma_init(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; +- drm_via_dma_init_t *init = data; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; ++ struct drm_via_dma_init *init = data; + int retcode = 0; + + switch (init->func) { +@@ -258,44 +263,26 @@ static int via_dma_init(struct drm_devic + return retcode; + } + +-static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * cmd) ++static int via_dispatch_cmdbuffer(struct drm_device *dev, ++ struct drm_via_cmdbuffer *cmd) + { +- drm_via_private_t *dev_priv; ++ struct drm_via_private *dev_priv; + uint32_t *vb; +- int ret; + +- dev_priv = (drm_via_private_t *) dev->dev_private; ++ dev_priv = (struct drm_via_private *) dev->dev_private; + + if (dev_priv->ring.virtual_start == NULL) { + DRM_ERROR("called without initializing AGP ring buffer.\n"); + return -EFAULT; + } + +- if (cmd->size > VIA_PCI_BUF_SIZE) { +- return -ENOMEM; +- } +- +- if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) +- return -EFAULT; +- +- /* +- * Running this function on AGP memory is dead slow. Therefore +- * we run it on a temporary cacheable system memory buffer and +- * copy it to AGP memory when ready. +- */ +- +- if ((ret = +- via_verify_command_stream((uint32_t *) dev_priv->pci_buf, +- cmd->size, dev, 1))) { +- return ret; +- } +- + vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size); +- if (vb == NULL) { ++ if (vb == NULL) + return -EAGAIN; +- } + +- memcpy(vb, dev_priv->pci_buf, cmd->size); ++ ++ if (DRM_COPY_FROM_USER(vb, cmd->buf, cmd->size)) ++ return -EFAULT; + + dev_priv->dma_low += cmd->size; + +@@ -311,17 +298,18 @@ static int via_dispatch_cmdbuffer(struct + return 0; + } + +-int via_driver_dma_quiescent(struct drm_device * dev) ++int via_driver_dma_quiescent(struct drm_device *dev) + { +- drm_via_private_t *dev_priv = dev->dev_private; ++ struct drm_via_private *dev_priv = dev->dev_private; + +- if (!via_wait_idle(dev_priv)) { ++ if (!via_wait_idle(dev_priv)) + return -EBUSY; +- } ++ + return 0; + } + +-static int via_flush_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) ++static int via_flush_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) + { + + LOCK_TEST_WITH_RETURN(dev, file_priv); +@@ -329,9 +317,10 @@ static int via_flush_ioctl(struct drm_de + return via_driver_dma_quiescent(dev); + } + +-static int via_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) ++static int via_cmdbuffer(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) + { +- drm_via_cmdbuffer_t *cmdbuf = data; ++ struct drm_via_cmdbuffer *cmdbuf = data; + int ret; + + LOCK_TEST_WITH_RETURN(dev, file_priv); +@@ -339,30 +328,31 @@ static int via_cmdbuffer(struct drm_devi + DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size); + + ret = via_dispatch_cmdbuffer(dev, cmdbuf); +- if (ret) { ++ if (ret) + return ret; +- } ++ + + return 0; + } + +-static int via_dispatch_pci_cmdbuffer(struct drm_device * dev, +- drm_via_cmdbuffer_t * cmd) ++static int via_dispatch_pci_cmdbuffer(struct drm_device *dev, ++ struct drm_via_cmdbuffer *cmd) + { +- drm_via_private_t *dev_priv = dev->dev_private; ++ struct drm_via_private *dev_priv = dev->dev_private; + int ret; + +- if (cmd->size > VIA_PCI_BUF_SIZE) { ++ if (cmd->size > VIA_PCI_BUF_SIZE) + return -ENOMEM; +- } ++ + if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) + return -EFAULT; +- +- if ((ret = ++ ret = + via_verify_command_stream((uint32_t *) dev_priv->pci_buf, +- cmd->size, dev, 0))) { ++ cmd->size, dev, 0); ++ ++ if (ret) + return ret; +- } ++ + + ret = + via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf, +@@ -370,9 +360,10 @@ static int via_dispatch_pci_cmdbuffer(st + return ret; + } + +-static int via_pci_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) ++static int via_pci_cmdbuffer(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) + { +- drm_via_cmdbuffer_t *cmdbuf = data; ++ struct drm_via_cmdbuffer *cmdbuf = data; + int ret; + + LOCK_TEST_WITH_RETURN(dev, file_priv); +@@ -380,19 +371,19 @@ static int via_pci_cmdbuffer(struct drm_ + DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size); + + ret = via_dispatch_pci_cmdbuffer(dev, cmdbuf); +- if (ret) { ++ if (ret) + return ret; +- } ++ + + return 0; + } + +-static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv, +- uint32_t * vb, int qw_count) ++static inline uint32_t *via_align_buffer(struct drm_via_private *dev_priv, ++ uint32_t *vb, int qw_count) + { +- for (; qw_count > 0; --qw_count) { ++ for (; qw_count > 0; --qw_count) + VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY); +- } ++ + return vb; + } + +@@ -401,7 +392,7 @@ static inline uint32_t *via_align_buffer + * + * Returns virtual pointer to ring buffer. + */ +-static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv) ++static inline uint32_t *via_get_dma(struct drm_via_private *dev_priv) + { + return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low); + } +@@ -411,18 +402,18 @@ static inline uint32_t *via_get_dma(drm_ + * modifying the pause address stored in the buffer itself. If + * the regulator has already paused, restart it. + */ +-static int via_hook_segment(drm_via_private_t * dev_priv, ++static int via_hook_segment(struct drm_via_private *dev_priv, + uint32_t pause_addr_hi, uint32_t pause_addr_lo, + int no_pci_fire) + { + int paused, count; + volatile uint32_t *paused_at = dev_priv->last_pause_ptr; +- uint32_t reader,ptr; ++ uint32_t reader, ptr; + uint32_t diff; + + paused = 0; + via_flush_write_combine(); +- (void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1); ++ (void) *(volatile uint32_t *)(via_get_dma(dev_priv) - 1); + + *paused_at = pause_addr_lo; + via_flush_write_combine(); +@@ -443,7 +434,7 @@ static int via_hook_segment(drm_via_priv + + diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff; + count = 10000000; +- while(diff == 0 && count--) { ++ while (diff == 0 && count--) { + paused = (VIA_READ(0x41c) & 0x80000000); + if (paused) + break; +@@ -463,9 +454,9 @@ static int via_hook_segment(drm_via_priv + ptr, reader, dev_priv->dma_diff); + } else if (diff == 0) { + /* +- * There is a concern that these writes may stall the PCI bus +- * if the GPU is not idle. However, idling the GPU first +- * doesn't make a difference. ++ * There is a concern that these writes may stall ++ * the PCI bus if the GPU is not idle. However, ++ * idling the GPU first doesn't make a difference. + */ + + VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); +@@ -477,7 +468,7 @@ static int via_hook_segment(drm_via_priv + return paused; + } + +-static int via_wait_idle(drm_via_private_t * dev_priv) ++static int via_wait_idle(struct drm_via_private *dev_priv) + { + int count = 10000000; + +@@ -489,9 +480,9 @@ static int via_wait_idle(drm_via_private + return count; + } + +-static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type, +- uint32_t addr, uint32_t * cmd_addr_hi, +- uint32_t * cmd_addr_lo, int skip_wait) ++static uint32_t *via_align_cmd(struct drm_via_private *dev_priv, ++ uint32_t cmd_type, uint32_t addr, uint32_t *cmd_addr_hi, ++ uint32_t *cmd_addr_lo, int skip_wait) + { + uint32_t agp_base; + uint32_t cmd_addr, addr_lo, addr_hi; +@@ -519,7 +510,7 @@ static uint32_t *via_align_cmd(drm_via_p + return vb; + } + +-static void via_cmdbuf_start(drm_via_private_t * dev_priv) ++static void via_cmdbuf_start(struct drm_via_private *dev_priv) + { + uint32_t pause_addr_lo, pause_addr_hi; + uint32_t start_addr, start_addr_lo; +@@ -578,7 +569,7 @@ static void via_cmdbuf_start(drm_via_pri + dev_priv->dma_diff = ptr - reader; + } + +-static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) ++static void via_pad_cache(struct drm_via_private *dev_priv, int qwords) + { + uint32_t *vb; + +@@ -588,7 +579,7 @@ static void via_pad_cache(drm_via_privat + via_align_buffer(dev_priv, vb, qwords); + } + +-static inline void via_dummy_bitblt(drm_via_private_t * dev_priv) ++static inline void via_dummy_bitblt(struct drm_via_private *dev_priv) + { + uint32_t *vb = via_get_dma(dev_priv); + SetReg2DAGP(0x0C, (0 | (0 << 16))); +@@ -596,7 +587,7 @@ static inline void via_dummy_bitblt(drm_ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000); + } + +-static void via_cmdbuf_jump(drm_via_private_t * dev_priv) ++static void via_cmdbuf_jump(struct drm_via_private *dev_priv) + { + uint32_t agp_base; + uint32_t pause_addr_lo, pause_addr_hi; +@@ -615,9 +606,9 @@ static void via_cmdbuf_jump(drm_via_priv + */ + + dev_priv->dma_low = 0; +- if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0) { ++ if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0) + DRM_ERROR("via_cmdbuf_jump failed\n"); +- } ++ + + via_dummy_bitblt(dev_priv); + via_dummy_bitblt(dev_priv); +@@ -655,12 +646,13 @@ static void via_cmdbuf_jump(drm_via_priv + } + + +-static void via_cmdbuf_rewind(drm_via_private_t * dev_priv) ++static void via_cmdbuf_rewind(struct drm_via_private *dev_priv) + { + via_cmdbuf_jump(dev_priv); + } + +-static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type) ++static void via_cmdbuf_flush(struct drm_via_private *dev_priv, ++ uint32_t cmd_type) + { + uint32_t pause_addr_lo, pause_addr_hi; + +@@ -668,12 +660,12 @@ static void via_cmdbuf_flush(drm_via_pri + via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0); + } + +-static void via_cmdbuf_pause(drm_via_private_t * dev_priv) ++static void via_cmdbuf_pause(struct drm_via_private *dev_priv) + { + via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE); + } + +-static void via_cmdbuf_reset(drm_via_private_t * dev_priv) ++static void via_cmdbuf_reset(struct drm_via_private *dev_priv) + { + via_cmdbuf_flush(dev_priv, HC_HAGPBpID_STOP); + via_wait_idle(dev_priv); +@@ -683,17 +675,18 @@ static void via_cmdbuf_reset(drm_via_pri + * User interface to the space and lag functions. + */ + +-static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *file_priv) ++static int via_cmdbuf_size(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) + { +- drm_via_cmdbuf_size_t *d_siz = data; ++ struct drm_via_cmdbuf_size *d_siz = data; + int ret = 0; + uint32_t tmp_size, count; +- drm_via_private_t *dev_priv; ++ struct drm_via_private *dev_priv; + +- DRM_DEBUG("\n"); ++ DRM_DEBUG("via cmdbuf_size\n"); + LOCK_TEST_WITH_RETURN(dev, file_priv); + +- dev_priv = (drm_via_private_t *) dev->dev_private; ++ dev_priv = (struct drm_via_private *) dev->dev_private; + + if (dev_priv->ring.virtual_start == NULL) { + DRM_ERROR("called without initializing AGP ring buffer.\n"); +@@ -706,9 +699,9 @@ static int via_cmdbuf_size(struct drm_de + case VIA_CMDBUF_SPACE: + while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size) + && count--) { +- if (!d_siz->wait) { ++ if (!d_siz->wait) + break; +- } ++ + } + if (!count) { + DRM_ERROR("VIA_CMDBUF_SPACE timed out.\n"); +@@ -718,9 +711,9 @@ static int via_cmdbuf_size(struct drm_de + case VIA_CMDBUF_LAG: + while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size) + && count--) { +- if (!d_siz->wait) { ++ if (!d_siz->wait) + break; +- } ++ + } + if (!count) { + DRM_ERROR("VIA_CMDBUF_LAG timed out.\n"); +@@ -735,6 +728,144 @@ static int via_cmdbuf_size(struct drm_de + return ret; + } + ++/*The following functions are for ACPI*/ ++ ++static void initialize3Dengine(struct drm_via_private *dev_priv) ++{ ++ int i = 0; ++ ++ VIA_WRITE(0x43C, 0x00010000); ++ ++ for (i = 0; i <= 0x7D; i++) ++ VIA_WRITE(0x440, (unsigned long) i << 24); ++ ++ ++ VIA_WRITE(0x43C, 0x00020000); ++ ++ for (i = 0; i <= 0x94; i++) ++ VIA_WRITE(0x440, (unsigned long) i << 24); ++ ++ ++ VIA_WRITE(0x440, 0x82400000); ++ VIA_WRITE(0x43C, 0x01020000); ++ ++ ++ for (i = 0; i <= 0x94; i++) ++ VIA_WRITE(0x440, (unsigned long) i << 24); ++ ++ ++ VIA_WRITE(0x440, 0x82400000); ++ VIA_WRITE(0x43C, 0xfe020000); ++ ++ for (i = 0; i <= 0x03; i++) ++ VIA_WRITE(0x440, (unsigned long) i << 24); ++ ++ ++ VIA_WRITE(0x43C, 0x00030000); ++ ++ for (i = 0; i <= 0xff; i++) ++ VIA_WRITE(0x440, 0); ++ ++ VIA_WRITE(0x43C, 0x00100000); ++ VIA_WRITE(0x440, 0x00333004); ++ VIA_WRITE(0x440, 0x10000002); ++ VIA_WRITE(0x440, 0x60000000); ++ VIA_WRITE(0x440, 0x61000000); ++ VIA_WRITE(0x440, 0x62000000); ++ VIA_WRITE(0x440, 0x63000000); ++ VIA_WRITE(0x440, 0x64000000); ++ ++ VIA_WRITE(0x43C, 0x00fe0000); ++ VIA_WRITE(0x440, 0x40008c0f); ++ VIA_WRITE(0x440, 0x44000000); ++ VIA_WRITE(0x440, 0x45080C04); ++ VIA_WRITE(0x440, 0x46800408); ++ VIA_WRITE(0x440, 0x50000000); ++ VIA_WRITE(0x440, 0x51000000); ++ VIA_WRITE(0x440, 0x52000000); ++ VIA_WRITE(0x440, 0x53000000); ++ ++ ++ VIA_WRITE(0x43C, 0x00fe0000); ++ VIA_WRITE(0x440, 0x08000001); ++ VIA_WRITE(0x440, 0x0A000183); ++ VIA_WRITE(0x440, 0x0B00019F); ++ VIA_WRITE(0x440, 0x0C00018B); ++ VIA_WRITE(0x440, 0x0D00019B); ++ VIA_WRITE(0x440, 0x0E000000); ++ VIA_WRITE(0x440, 0x0F000000); ++ VIA_WRITE(0x440, 0x10000000); ++ VIA_WRITE(0x440, 0x11000000); ++ VIA_WRITE(0x440, 0x20000000); ++} ++ ++ ++/* For acpi case, when system resume from suspend or hibernate, ++ * need to re-initialize dma info into HW ++ */ ++int via_drm_resume(struct pci_dev *pci) ++{ ++ struct drm_device *dev = (struct drm_device *)pci_get_drvdata(pci); ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; ++ struct drm_via_video_save_head *pnode = 0; ++ ++ /* when resume, initialize 3d registers */ ++ initialize3Dengine(dev_priv); ++ ++ /* here we need to restore some video memory content */ ++ for (pnode = via_video_save_head; pnode; pnode = pnode->next) ++ memcpy(pnode->pvideomem, pnode->psystemmem, pnode->size); ++ ++ ++ /* if pci path, return */ ++ if (!dev_priv->ring.virtual_start) ++ return 0; ++ ++ dev_priv->dma_ptr = dev_priv->ring.virtual_start; ++ dev_priv->dma_low = 0; ++ dev_priv->dma_high = 0x1000000; ++ dev_priv->dma_wrap = 0x1000000; ++ dev_priv->dma_offset = 0x0; ++ dev_priv->last_pause_ptr = NULL; ++ dev_priv->hw_addr_ptr = dev_priv->mmio->handle + 0x418; ++ ++ via_cmdbuf_start(dev_priv); ++ ++ return 0; ++} ++ ++int via_drm_suspend(struct pci_dev *pci, pm_message_t state) ++{ ++ struct drm_device *dev = (struct drm_device *)pci_get_drvdata(pci); ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; ++ ++ struct drm_via_video_save_head *pnode = 0; ++ ++ /*here we need to save some video mem information into system memory, ++ to keep the system consistent between suspend *before* and *after* ++ 1.save only necessary */ ++ for (pnode = via_video_save_head; pnode; pnode = ++ (struct drm_via_video_save_head *)pnode->next) ++ memcpy(pnode->psystemmem, pnode->pvideomem, pnode->size); ++ ++ ++ /* Only agp path need to flush the cmd */ ++ if (dev_priv->ring.virtual_start) ++ via_cmdbuf_reset(dev_priv); ++ ++ ++ return 0; ++} ++ ++int via_drm_authmagic(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return 0; ++} ++ ++ + struct drm_ioctl_desc via_ioctls[] = { + DRM_IOCTL_DEF(DRM_VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_FREEMEM, via_mem_free, DRM_AUTH), +@@ -742,6 +873,7 @@ struct drm_ioctl_desc via_ioctls[] = { + DRM_IOCTL_DEF(DRM_VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER), + DRM_IOCTL_DEF(DRM_VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER), + DRM_IOCTL_DEF(DRM_VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_VIA_GET_INFO, via_get_drm_info, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_DMA_INIT, via_dma_init, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_FLUSH, via_flush_ioctl, DRM_AUTH), +@@ -749,7 +881,8 @@ struct drm_ioctl_desc via_ioctls[] = { + DRM_IOCTL_DEF(DRM_VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_DMA_BLIT, via_dma_blit, DRM_AUTH), +- DRM_IOCTL_DEF(DRM_VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH) ++ DRM_IOCTL_DEF(DRM_VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_VIA_AUTH_MAGIC, via_drm_authmagic, 0) + }; + + int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls); +--- a/drivers/char/drm/via_drm.h ++++ b/drivers/char/drm/via_drm.h +@@ -40,7 +40,8 @@ + #define VIA_NR_XVMC_LOCKS 5 + #define VIA_MAX_CACHELINE_SIZE 64 + #define XVMCLOCKPTR(saPriv,lockNo) \ +- ((volatile struct drm_hw_lock *)(((((unsigned long) (saPriv)->XvMCLockArea) + \ ++ ((volatile struct drm_hw_lock *)(((((unsigned long) \ ++ (saPriv)->XvMCLockArea) + \ + (VIA_MAX_CACHELINE_SIZE - 1)) & \ + ~(VIA_MAX_CACHELINE_SIZE - 1)) + \ + VIA_MAX_CACHELINE_SIZE*(lockNo))) +@@ -51,6 +52,13 @@ + #define VIA_LOG_MIN_TEX_REGION_SIZE 16 + #endif + ++struct drm_via_info{ ++ unsigned long AgpHandle; ++ unsigned long AgpSize; ++ unsigned long RegHandle; ++ unsigned long RegSize; ++}; ++ + #define VIA_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */ + #define VIA_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */ + #define VIA_UPLOAD_CTX 0x4 +@@ -67,7 +75,7 @@ + #define DRM_VIA_FB_INIT 0x03 + #define DRM_VIA_MAP_INIT 0x04 + #define DRM_VIA_DEC_FUTEX 0x05 +-#define NOT_USED ++#define DRM_VIA_GET_INFO 0x06 + #define DRM_VIA_DMA_INIT 0x07 + #define DRM_VIA_CMDBUFFER 0x08 + #define DRM_VIA_FLUSH 0x09 +@@ -77,22 +85,39 @@ + #define DRM_VIA_WAIT_IRQ 0x0d + #define DRM_VIA_DMA_BLIT 0x0e + #define DRM_VIA_BLIT_SYNC 0x0f ++#define DRM_VIA_AUTH_MAGIC 0x11 + +-#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t) +-#define DRM_IOCTL_VIA_FREEMEM DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t) +-#define DRM_IOCTL_VIA_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_AGP_INIT, drm_via_agp_t) +-#define DRM_IOCTL_VIA_FB_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_FB_INIT, drm_via_fb_t) +-#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_MAP_INIT, drm_via_init_t) +-#define DRM_IOCTL_VIA_DEC_FUTEX DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_DEC_FUTEX, drm_via_futex_t) +-#define DRM_IOCTL_VIA_DMA_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_DMA_INIT, drm_via_dma_init_t) +-#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_CMDBUFFER, drm_via_cmdbuffer_t) +-#define DRM_IOCTL_VIA_FLUSH DRM_IO( DRM_COMMAND_BASE + DRM_VIA_FLUSH) +-#define DRM_IOCTL_VIA_PCICMD DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_PCICMD, drm_via_cmdbuffer_t) +-#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \ +- drm_via_cmdbuf_size_t) +-#define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t) +-#define DRM_IOCTL_VIA_DMA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DMA_BLIT, drm_via_dmablit_t) +-#define DRM_IOCTL_VIA_BLIT_SYNC DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_BLIT_SYNC, drm_via_blitsync_t) ++#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + \ ++ DRM_VIA_ALLOCMEM, struct drm_via_mem) ++#define DRM_IOCTL_VIA_FREEMEM DRM_IOW(DRM_COMMAND_BASE + \ ++ DRM_VIA_FREEMEM, struct drm_via_mem) ++#define DRM_IOCTL_VIA_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + \ ++ DRM_VIA_AGP_INIT, struct drm_via_agp) ++#define DRM_IOCTL_VIA_FB_INIT DRM_IOWR(DRM_COMMAND_BASE + \ ++ DRM_VIA_FB_INIT, struct drm_via_fb) ++#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(DRM_COMMAND_BASE + \ ++ DRM_VIA_MAP_INIT, struct drm_via_init) ++#define DRM_IOCTL_VIA_DEC_FUTEX DRM_IOW(DRM_COMMAND_BASE + \ ++ DRM_VIA_DEC_FUTEX, struct drm_via_futex) ++#define DRM_IOCTL_VIA_GET_INFO DRM_IOW(DRM_COMMAND_BASE + \ ++ DRM_VIA_GET_INFO, struct drm_via_info) ++#define DRM_IOCTL_VIA_DMA_INIT DRM_IOWR(DRM_COMMAND_BASE + \ ++ DRM_VIA_DMA_INIT, struct drm_via_dma_init) ++#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOW(DRM_COMMAND_BASE + \ ++ DRM_VIA_CMDBUFFER, struct drm_via_cmdbuffer) ++#define DRM_IOCTL_VIA_FLUSH DRM_IO(DRM_COMMAND_BASE + DRM_VIA_FLUSH) ++#define DRM_IOCTL_VIA_PCICMD DRM_IOW(DRM_COMMAND_BASE + \ ++ DRM_VIA_PCICMD, struct drm_via_cmdbuffer) ++#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR(DRM_COMMAND_BASE + \ ++ DRM_VIA_CMDBUF_SIZE, struct drm_via_cmdbuf_size) ++#define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR(DRM_COMMAND_BASE + \ ++ DRM_VIA_WAIT_IRQ, union drm_via_irqwait) ++#define DRM_IOCTL_VIA_DMA_BLIT DRM_IOW(DRM_COMMAND_BASE + \ ++ DRM_VIA_DMA_BLIT, struct drm_via_dmablit) ++#define DRM_IOCTL_VIA_BLIT_SYNC DRM_IOW(DRM_COMMAND_BASE + \ ++ DRM_VIA_BLIT_SYNC, struct drm_via_blitsync) ++#define DRM_IOCTL_VIA_AUTH_MAGIC DRM_IOW(DRM_COMMAND_BASE + \ ++ DRM_VIA_AUTH_MAGIC, struct drm_auth) + + /* 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, +@@ -113,25 +138,33 @@ + #define VIA_MEM_MIXED 3 + #define VIA_MEM_UNKNOWN 4 + +-typedef struct { ++#define VIA_MEM_VIDEO_SAVE 2 /*For video memory need to be saved in ACPI */ ++ ++enum drm_agp_type { ++ AGP_RING_BUFFER, ++ AGP_DOUBLE_BUFFER, ++ DISABLED ++}; ++ ++struct drm_via_agp { + uint32_t offset; + uint32_t size; +-} drm_via_agp_t; ++}; + +-typedef struct { ++struct drm_via_fb { + uint32_t offset; + uint32_t size; +-} drm_via_fb_t; ++}; + +-typedef struct { ++struct drm_via_mem { + uint32_t context; + uint32_t type; + uint32_t size; + unsigned long index; + unsigned long offset; +-} drm_via_mem_t; ++}; + +-typedef struct _drm_via_init { ++struct drm_via_init { + enum { + VIA_INIT_MAP = 0x01, + VIA_CLEANUP_MAP = 0x02 +@@ -141,9 +174,11 @@ typedef struct _drm_via_init { + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long agpAddr; +-} drm_via_init_t; ++ unsigned long agp_offset; ++ enum drm_agp_type agp_type; ++}; + +-typedef struct _drm_via_futex { ++struct drm_via_futex { + enum { + VIA_FUTEX_WAIT = 0x00, + VIA_FUTEX_WAKE = 0X01 +@@ -151,9 +186,9 @@ typedef struct _drm_via_futex { + uint32_t ms; + uint32_t lock; + uint32_t val; +-} drm_via_futex_t; ++}; + +-typedef struct _drm_via_dma_init { ++struct drm_via_dma_init { + enum { + VIA_INIT_DMA = 0x01, + VIA_CLEANUP_DMA = 0x02, +@@ -163,27 +198,27 @@ typedef struct _drm_via_dma_init { + unsigned long offset; + unsigned long size; + unsigned long reg_pause_addr; +-} drm_via_dma_init_t; ++}; + +-typedef struct _drm_via_cmdbuffer { ++struct drm_via_cmdbuffer { + char __user *buf; + unsigned long size; +-} drm_via_cmdbuffer_t; ++}; + + /* Warning: If you change the SAREA structure you must change the Xserver + * structure as well */ + +-typedef struct _drm_via_tex_region { ++struct drm_via_tex_region { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char inUse; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +-} drm_via_tex_region_t; ++}; + +-typedef struct _drm_via_sarea { ++struct drm_via_sarea { + unsigned int dirty; + unsigned int nbox; + struct drm_clip_rect boxes[VIA_NR_SAREA_CLIPRECTS]; +- drm_via_tex_region_t texList[VIA_NR_TEX_REGIONS + 1]; ++ struct drm_via_tex_region texList[VIA_NR_TEX_REGIONS + 1]; + int texAge; /* last time texture was uploaded */ + int ctxOwner; /* last context to upload state */ + int vertexPrim; +@@ -203,23 +238,23 @@ typedef struct _drm_via_sarea { + /* Used by the 3d driver only at this point, for pageflipping: + */ + unsigned int pfCurrentOffset; +-} drm_via_sarea_t; ++}; + +-typedef struct _drm_via_cmdbuf_size { ++struct drm_via_cmdbuf_size { + enum { + VIA_CMDBUF_SPACE = 0x01, + VIA_CMDBUF_LAG = 0x02 + } func; + int wait; + uint32_t size; +-} drm_via_cmdbuf_size_t; ++}; + +-typedef enum { ++enum via_irq_seq_type { + VIA_IRQ_ABSOLUTE = 0x0, + VIA_IRQ_RELATIVE = 0x1, + VIA_IRQ_SIGNAL = 0x10000000, + VIA_IRQ_FORCE_SEQUENCE = 0x20000000 +-} via_irq_seq_type_t; ++}; + + #define VIA_IRQ_FLAGS_MASK 0xF0000000 + +@@ -235,20 +270,20 @@ enum drm_via_irqs { + + struct drm_via_wait_irq_request { + unsigned irq; +- via_irq_seq_type_t type; ++ enum via_irq_seq_type type; + uint32_t sequence; + uint32_t signal; + }; + +-typedef union drm_via_irqwait { ++union drm_via_irqwait { + struct drm_via_wait_irq_request request; + struct drm_wait_vblank_reply reply; +-} drm_via_irqwait_t; ++}; + +-typedef struct drm_via_blitsync { ++struct drm_via_blitsync { + uint32_t sync_handle; + unsigned engine; +-} drm_via_blitsync_t; ++}; + + /* - * Below,"flags" is currently unused but will be used for possible future + * extensions like kernel space bounce buffers for bad alignments and +@@ -256,7 +291,7 @@ typedef struct drm_via_blitsync { + * interrupts. + */ + +-typedef struct drm_via_dmablit { ++struct drm_via_dmablit { + uint32_t num_lines; + uint32_t line_length; + +@@ -269,7 +304,18 @@ typedef struct drm_via_dmablit { + uint32_t flags; + int to_fb; + +- drm_via_blitsync_t sync; +-} drm_via_dmablit_t; ++ struct drm_via_blitsync sync; ++}; ++ ++struct drm_via_video_save_head { ++ void *pvideomem; ++ void *psystemmem; ++ int size; ++ /* token used to identify this video memory */ ++ unsigned long token; ++ void *next; ++}; ++ ++extern struct drm_via_video_save_head *via_video_save_head; + + #endif /* _VIA_DRM_H_ */ +--- a/drivers/char/drm/via_drv.c ++++ b/drivers/char/drm/via_drv.c +@@ -37,10 +37,17 @@ static struct pci_device_id pciidlist[] + viadrv_PCI_IDS + }; + ++int via_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_USE_MTRR | DRIVER_HAVE_IRQ | + DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, ++ .open = via_driver_open, + .load = via_driver_load, + .unload = via_driver_unload, + .context_dtor = via_final_context, +@@ -68,8 +75,10 @@ static struct drm_driver driver = { + .fasync = drm_fasync, + }, + .pci_driver = { +- .name = DRIVER_NAME, +- .id_table = pciidlist, ++ .name = DRIVER_NAME, ++ .id_table = pciidlist, ++ .suspend = via_drm_suspend, ++ .resume = via_drm_resume, + }, + + .name = DRIVER_NAME, +--- a/drivers/char/drm/via_drv.h ++++ b/drivers/char/drm/via_drv.h +@@ -43,25 +43,29 @@ + #define VIA_FIRE_BUF_SIZE 1024 + #define VIA_NUM_IRQS 4 + +-typedef struct drm_via_ring_buffer { ++struct drm_via_ring_buffer { + drm_local_map_t map; + char *virtual_start; +-} drm_via_ring_buffer_t; ++}; + + typedef uint32_t maskarray_t[5]; + +-typedef struct drm_via_irq { ++struct drm_via_irq { + atomic_t irq_received; + uint32_t pending_mask; + uint32_t enable_mask; + wait_queue_head_t irq_queue; +-} drm_via_irq_t; ++}; + +-typedef struct drm_via_private { +- drm_via_sarea_t *sarea_priv; ++struct drm_via_private { ++ struct drm_via_sarea *sarea_priv; + drm_local_map_t *sarea; + drm_local_map_t *fb; + drm_local_map_t *mmio; ++ /* support managing agp in our own prev data structure */ ++ drm_local_map_t *agp; ++ enum drm_agp_type agptype; ++ /* end */ + unsigned long agpAddr; + wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS]; + char *dma_ptr; +@@ -71,16 +75,16 @@ typedef struct drm_via_private { + uint32_t dma_wrap; + volatile uint32_t *last_pause_ptr; + volatile uint32_t *hw_addr_ptr; +- drm_via_ring_buffer_t ring; ++ struct drm_via_ring_buffer ring; + struct timeval last_vblank; + int last_vblank_valid; + unsigned usec_per_vblank; +- drm_via_state_t hc_state; ++ struct drm_via_state hc_state; + char pci_buf[VIA_PCI_BUF_SIZE]; + const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; + uint32_t num_fire_offsets; + int chipset; +- drm_via_irq_t via_irqs[VIA_NUM_IRQS]; ++ struct drm_via_irq via_irqs[VIA_NUM_IRQS]; + unsigned num_irqs; + maskarray_t *irq_masks; + uint32_t irq_enable_mask; +@@ -92,9 +96,9 @@ typedef struct drm_via_private { + int agp_initialized; + unsigned long vram_offset; + unsigned long agp_offset; +- drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES]; ++ struct drm_via_blitq blit_queues[VIA_NUM_BLIT_ENGINES]; + uint32_t dma_diff; +-} drm_via_private_t; ++}; + + enum via_family { + VIA_OTHER = 0, /* Baseline */ +@@ -106,48 +110,65 @@ enum via_family { + #define VIA_BASE ((dev_priv->mmio)) + + #define VIA_READ(reg) DRM_READ32(VIA_BASE, reg) +-#define VIA_WRITE(reg,val) DRM_WRITE32(VIA_BASE, reg, val) ++#define VIA_WRITE(reg, val) DRM_WRITE32(VIA_BASE, reg, val) + #define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg) +-#define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val) ++#define VIA_WRITE8(reg, val) DRM_WRITE8(VIA_BASE, reg, val) + + extern struct drm_ioctl_desc via_ioctls[]; + extern int via_max_ioctl; + +-extern int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv); +-extern int via_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); +-extern int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv); +-extern int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv); +-extern int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv); +-extern int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv); +-extern int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv); +-extern int via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv ); +-extern int via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv ); ++extern int via_fb_init(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int via_mem_alloc(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int via_mem_free(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int via_agp_init(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int via_map_init(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int via_decoder_futex(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int via_get_drm_info(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int via_wait_irq(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int via_dma_blit_sync(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int via_dma_blit(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); + + extern int via_driver_load(struct drm_device *dev, unsigned long chipset); + extern int via_driver_unload(struct drm_device *dev); + +-extern int via_init_context(struct drm_device * dev, int context); +-extern int via_final_context(struct drm_device * dev, int context); ++extern int via_init_context(struct drm_device *dev, int context); ++extern int via_final_context(struct drm_device *dev, int context); + +-extern int via_do_cleanup_map(struct drm_device * dev); +-extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); ++extern int via_do_cleanup_map(struct drm_device *dev); ++extern int via_driver_vblank_wait(struct drm_device *dev, ++ unsigned int *sequence); + + extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); +-extern void via_driver_irq_preinstall(struct drm_device * dev); +-extern void via_driver_irq_postinstall(struct drm_device * dev); +-extern void via_driver_irq_uninstall(struct drm_device * dev); ++extern void via_driver_irq_preinstall(struct drm_device *dev); ++extern void via_driver_irq_postinstall(struct drm_device *dev); ++extern void via_driver_irq_uninstall(struct drm_device *dev); + +-extern int via_dma_cleanup(struct drm_device * dev); ++extern int via_dma_cleanup(struct drm_device *dev); + extern void via_init_command_verifier(void); +-extern int via_driver_dma_quiescent(struct drm_device * dev); +-extern void via_init_futex(drm_via_private_t * dev_priv); +-extern void via_cleanup_futex(drm_via_private_t * dev_priv); +-extern void via_release_futex(drm_via_private_t * dev_priv, int context); ++extern int via_driver_dma_quiescent(struct drm_device *dev); ++extern void via_init_futex(struct drm_via_private *dev_priv); ++extern void via_cleanup_futex(struct drm_via_private *dev_priv); ++extern void via_release_futex(struct drm_via_private *dev_priv, int context); + +-extern void via_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv); ++extern void via_reclaim_buffers_locked(struct drm_device *dev, ++ struct drm_file *file_priv); + extern void via_lastclose(struct drm_device *dev); + +-extern void via_dmablit_handler(struct drm_device *dev, int engine, int from_irq); ++extern void via_dmablit_handler(struct drm_device *dev, int engine, ++ int from_irq); + extern void via_init_dmablit(struct drm_device *dev); + ++extern int via_drm_resume(struct pci_dev *dev); ++extern int via_drm_suspend(struct pci_dev *dev, pm_message_t state); ++ + #endif +--- a/drivers/char/drm/via_irq.c ++++ b/drivers/char/drm/via_irq.c +@@ -30,9 +30,10 @@ + * Keith Whitwell <keith@tungstengraphics.com> + * Thomas Hellstrom <unichrome@shipmail.org> + * +- * This code provides standard DRM access to the Via Unichrome / Pro Vertical blank +- * interrupt, as well as an infrastructure to handle other interrupts of the chip. +- * The refresh rate is also calculated for video playback sync purposes. ++ * This code provides standard DRM access to the Via Unichrome ++ * / Pro Vertical blank interrupt, as well as an infrastructure ++ * to handle other interrupts of the chip. The refresh rate is ++ * also calculated for video playback sync purposes. + */ + + #include "drmP.h" +@@ -99,11 +100,12 @@ static unsigned time_diff(struct timeval + irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) + { + struct drm_device *dev = (struct drm_device *) arg; +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + u32 status; + int handled = 0; + struct timeval cur_vblank; +- drm_via_irq_t *cur_irq = dev_priv->via_irqs; ++ struct drm_via_irq *cur_irq = dev_priv->via_irqs; + int i; + + status = VIA_READ(VIA_REG_INTERRUPT); +@@ -133,11 +135,12 @@ irqreturn_t via_driver_irq_handler(DRM_I + atomic_inc(&cur_irq->irq_received); + DRM_WAKEUP(&cur_irq->irq_queue); + handled = 1; +- if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) { ++ if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) + via_dmablit_handler(dev, 0, 1); +- } else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) { ++ else if (dev_priv->irq_map[drm_via_irq_dma1_td] == ++ i) + via_dmablit_handler(dev, 1, 1); +- } ++ + } + cur_irq++; + } +@@ -151,7 +154,8 @@ irqreturn_t via_driver_irq_handler(DRM_I + return IRQ_NONE; + } + +-static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) ++static inline void ++viadrv_acknowledge_irqs(struct drm_via_private *dev_priv) + { + u32 status; + +@@ -163,9 +167,10 @@ static __inline__ void viadrv_acknowledg + } + } + +-int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) ++int via_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + unsigned int cur_vblank; + int ret = 0; + +@@ -191,12 +196,13 @@ int via_driver_vblank_wait(struct drm_de + } + + static int +-via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequence, +- unsigned int *sequence) ++via_driver_irq_wait(struct drm_device *dev, unsigned int irq, ++ int force_sequence, unsigned int *sequence) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + unsigned int cur_irq_sequence; +- drm_via_irq_t *cur_irq; ++ struct drm_via_irq *cur_irq; + int ret = 0; + maskarray_t *masks; + int real_irq; +@@ -243,11 +249,12 @@ via_driver_irq_wait(struct drm_device * + * drm_dma.h hooks + */ + +-void via_driver_irq_preinstall(struct drm_device * dev) ++void via_driver_irq_preinstall(struct drm_device *dev) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + u32 status; +- drm_via_irq_t *cur_irq; ++ struct drm_via_irq *cur_irq; + int i; + + DRM_DEBUG("dev_priv: %p\n", dev_priv); +@@ -292,9 +299,10 @@ void via_driver_irq_preinstall(struct dr + } + } + +-void via_driver_irq_postinstall(struct drm_device * dev) ++void via_driver_irq_postinstall(struct drm_device *dev) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + u32 status; + + DRM_DEBUG("\n"); +@@ -311,9 +319,10 @@ void via_driver_irq_postinstall(struct d + } + } + +-void via_driver_irq_uninstall(struct drm_device * dev) ++void via_driver_irq_uninstall(struct drm_device *dev) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + u32 status; + + DRM_DEBUG("\n"); +@@ -330,13 +339,15 @@ void via_driver_irq_uninstall(struct drm + } + } + +-int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv) ++int via_wait_irq(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) + { +- drm_via_irqwait_t *irqwait = data; ++ union drm_via_irqwait *irqwait = data; + struct timeval now; + int ret = 0; +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; +- drm_via_irq_t *cur_irq = dev_priv->via_irqs; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; ++ struct drm_via_irq *cur_irq = dev_priv->via_irqs; + int force_sequence; + + if (!dev->irq) +@@ -352,7 +363,8 @@ int via_wait_irq(struct drm_device *dev, + + switch (irqwait->request.type & ~VIA_IRQ_FLAGS_MASK) { + case VIA_IRQ_RELATIVE: +- irqwait->request.sequence += atomic_read(&cur_irq->irq_received); ++ irqwait->request.sequence += ++ atomic_read(&cur_irq->irq_received); + irqwait->request.type &= ~_DRM_VBLANK_RELATIVE; + case VIA_IRQ_ABSOLUTE: + break; +--- a/drivers/char/drm/via_map.c ++++ b/drivers/char/drm/via_map.c +@@ -25,9 +25,11 @@ + #include "via_drm.h" + #include "via_drv.h" + +-static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init) ++static int associate; ++ ++static int via_do_init_map(struct drm_device *dev, struct drm_via_init *init) + { +- drm_via_private_t *dev_priv = dev->dev_private; ++ struct drm_via_private *dev_priv = dev->dev_private; + + DRM_DEBUG("\n"); + +@@ -55,7 +57,7 @@ static int via_do_init_map(struct drm_de + } + + dev_priv->sarea_priv = +- (drm_via_sarea_t *) ((u8 *) dev_priv->sarea->handle + ++ (struct drm_via_sarea *) ((u8 *) dev_priv->sarea->handle + + init->sarea_priv_offset); + + dev_priv->agpAddr = init->agpAddr; +@@ -65,19 +67,43 @@ static int via_do_init_map(struct drm_de + via_init_dmablit(dev); + + dev->dev_private = (void *)dev_priv; ++ ++ /* from doing this, we has the stuff ++ *in prev data structure to manage agp ++ */ ++ if (init->agp_type != DISABLED) { ++ dev_priv->agp = drm_core_findmap(dev, init->agp_offset); ++ ++ if (!dev_priv->agp) { ++ DRM_ERROR("failed to find dma buffer region!\n"); ++ return -EINVAL; ++ } ++ ++ if (init->agp_type == AGP_DOUBLE_BUFFER) ++ dev_priv->agptype = AGP_DOUBLE_BUFFER; ++ ++ if (init->agp_type == AGP_RING_BUFFER) ++ dev_priv->agptype = AGP_RING_BUFFER; ++ } else { ++ dev_priv->agptype = DISABLED; ++ dev_priv->agp = 0; ++ } ++ /* end */ ++ + return 0; + } + +-int via_do_cleanup_map(struct drm_device * dev) ++int via_do_cleanup_map(struct drm_device *dev) + { + via_dma_cleanup(dev); + + return 0; + } + +-int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv) ++int via_map_init(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) + { +- drm_via_init_t *init = data; ++ struct drm_via_init *init = data; + + DRM_DEBUG("\n"); + +@@ -93,10 +119,17 @@ int via_map_init(struct drm_device *dev, + + int via_driver_load(struct drm_device *dev, unsigned long chipset) + { +- drm_via_private_t *dev_priv; ++ struct drm_via_private *dev_priv; + int ret = 0; + +- dev_priv = drm_calloc(1, sizeof(drm_via_private_t), DRM_MEM_DRIVER); ++ if (!associate) { ++ pci_set_drvdata(dev->pdev, dev); ++ dev->pdev->driver = &dev->driver->pci_driver; ++ associate = 1; ++ } ++ ++ dev_priv = drm_calloc(1, ++ sizeof(struct drm_via_private), DRM_MEM_DRIVER); + if (dev_priv == NULL) + return -ENOMEM; + +@@ -105,19 +138,37 @@ int via_driver_load(struct drm_device *d + dev_priv->chipset = chipset; + + ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); +- if (ret) { ++ if (ret) + drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); +- } ++ + return ret; + } + + int via_driver_unload(struct drm_device *dev) + { +- drm_via_private_t *dev_priv = dev->dev_private; ++ struct drm_via_private *dev_priv = dev->dev_private; + + drm_sman_takedown(&dev_priv->sman); + +- drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER); ++ drm_free(dev_priv, sizeof(struct drm_via_private), DRM_MEM_DRIVER); ++ ++ return 0; ++} + ++int via_get_drm_info(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *)dev->dev_private; ++ struct drm_via_info info; ++ ++ if (copy_from_user(&info, data, sizeof(info))) ++ return -EFAULT; ++ info.RegSize = dev_priv->mmio->size; ++ info.AgpSize = dev_priv->agp->size; ++ info.RegHandle = dev_priv->mmio->offset; ++ info.AgpHandle = dev_priv->agp->offset; ++ if (copy_to_user((struct drm_via_info *)data, &info, sizeof(info))) ++ return -EFAULT; + return 0; + } +--- a/drivers/char/drm/via_mm.c ++++ b/drivers/char/drm/via_mm.c +@@ -1,42 +1,47 @@ + /* +- * Copyright 2006 Tungsten Graphics Inc., Bismarck, ND., USA. +- * All rights reserved. +- * +- * Permission is hereby granted, free of charge, to any person obtaining a +- * copy of this software and associated documentation files (the "Software"), +- * to deal in the Software without restriction, including without limitation +- * the rights to use, copy, modify, merge, publish, distribute, sub license, +- * and/or sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice (including the +- * next paragraph) shall be included in all copies or substantial portions +- * of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +- * THE AUTHORS OR COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +- * DEALINGS IN THE SOFTWARE. +- */ ++* Copyright 2006 Tungsten Graphics Inc., Bismarck, ND., USA. ++* All rights reserved. ++* ++* Permission is hereby granted, free of charge, to any person obtaining a ++* copy of this software and associated documentation files (the "Software"), ++* to deal in the Software without restriction, including without limitation ++* the rights to use, copy, modify, merge, publish, distribute, sub license, ++* and/or sell copies of the Software, and to permit persons to whom the ++* Software is furnished to do so, subject to the following conditions: ++* ++* The above copyright notice and this permission notice (including the ++* next paragraph) shall be included in all copies or substantial portions ++* of the Software. ++* ++* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++* THE AUTHORS OR COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY ++* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ++* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR ++* THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++*/ ++ + /* +- * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com> +- */ ++* Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com> ++*/ + + #include "drmP.h" + #include "via_drm.h" + #include "via_drv.h" + #include "drm_sman.h" + ++struct drm_via_video_save_head *via_video_save_head; ++ + #define VIA_MM_ALIGN_SHIFT 4 +-#define VIA_MM_ALIGN_MASK ( (1 << VIA_MM_ALIGN_SHIFT) - 1) ++#define VIA_MM_ALIGN_MASK ((1 << VIA_MM_ALIGN_SHIFT) - 1) + +-int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) ++int via_agp_init(struct drm_device *dev, void *data, ++struct drm_file *file_priv) + { +- drm_via_agp_t *agp = data; +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; ++ struct drm_via_agp *agp = data; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + int ret; + + mutex_lock(&dev->struct_mutex); +@@ -57,10 +62,16 @@ int via_agp_init(struct drm_device *dev, + return 0; + } + ++/*Henry:For via_fb_alloc/free used by video*/ ++static void *global_dev; ++static void *global_file_priv; ++/*Henry:End*/ ++ + int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv) + { +- drm_via_fb_t *fb = data; +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; ++ struct drm_via_fb *fb = data; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + int ret; + + mutex_lock(&dev->struct_mutex); +@@ -79,13 +90,19 @@ int via_fb_init(struct drm_device *dev, + mutex_unlock(&dev->struct_mutex); + DRM_DEBUG("offset = %u, size = %u\n", fb->offset, fb->size); + ++ /*Henry:For via_fb_alloc/free used by video*/ ++ global_dev = dev; ++ global_file_priv = file_priv; ++ /*Henry:End*/ ++ + return 0; + + } + + int via_final_context(struct drm_device *dev, int context) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + + via_release_futex(dev_priv, context); + +@@ -103,7 +120,8 @@ int via_final_context(struct drm_device + + void via_lastclose(struct drm_device *dev) + { +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + + if (!dev_priv) + return; +@@ -115,38 +133,134 @@ void via_lastclose(struct drm_device *de + mutex_unlock(&dev->struct_mutex); + } + ++static int via_videomem_presave_ok(struct drm_via_private *dev_priv, ++ struct drm_via_mem *mem) ++{ ++ void *pvideomem = 0, *psystemmem = 0; ++ struct drm_via_video_save_head *pnode = 0; ++ ++ if (!mem || !mem->size || (mem->type != VIA_MEM_VIDEO_SAVE)) ++ return 0; ++ ++ /* here the mem->offset is the absolute address, ++ *not the offset within videomem ++ */ ++ pvideomem = ++ (void *)ioremap(dev_priv->fb->offset+mem->offset, mem->size); ++ if (!pvideomem) ++ return 0; ++ psystemmem = kmalloc(mem->size, GFP_KERNEL); ++ if (!psystemmem) { ++ iounmap(pvideomem); ++ return 0; ++ } ++ ++ /* map success, then save this information into ++ * a data structure for later saving usage ++ */ ++ pnode = kmalloc(sizeof(struct drm_via_video_save_head), GFP_KERNEL); ++ ++ if (!pnode) { ++ iounmap(pvideomem); ++ kfree(psystemmem); ++ return 0; ++ } ++ ++ pnode->next = 0; ++ pnode->psystemmem = psystemmem; ++ pnode->pvideomem = pvideomem; ++ pnode->size = mem->size; ++ pnode->token = mem->offset; ++ ++ /* insert this node into list */ ++ if (!via_video_save_head) ++ via_video_save_head = pnode; ++ else { ++ pnode->next = via_video_save_head; ++ via_video_save_head = pnode; ++ } ++ ++ return 1; ++ ++} ++ ++static int via_videomem_housekeep_ok(struct drm_via_mem *mem) ++{ ++ struct drm_via_video_save_head **ppnode = 0; ++ struct drm_via_video_save_head *tmpnode = 0; ++ ++ /* if this mem's token match with one node of the list */ ++ ++ for (ppnode = &via_video_save_head; *ppnode; ++ ppnode = (struct drm_via_video_save_head **) ++ (&((*ppnode)->next))) { ++ if ((*ppnode)->token == mem->offset) ++ break; ++ ++ } ++ ++ if (*ppnode == 0) ++ ++ /* not found, the user may specify the wrong mem node to free */ ++ return 0; ++ ++ /* delete this node from the list and then free ++ * all the mem to avoid memory leak ++ */ ++ tmpnode = *ppnode; ++ *ppnode = (*ppnode)->next; ++ iounmap(tmpnode->pvideomem); ++ kfree(tmpnode->psystemmem); ++ kfree(tmpnode); ++ ++ return 1; ++} ++ + int via_mem_alloc(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { +- drm_via_mem_t *mem = data; ++ struct drm_via_mem *mem = data; + int retval = 0; + struct drm_memblock_item *item; +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + unsigned long tmpSize; + +- if (mem->type > VIA_MEM_AGP) { ++ if (mem->type > VIA_MEM_VIDEO_SAVE) { + DRM_ERROR("Unknown memory type allocation\n"); + return -EINVAL; + } + mutex_lock(&dev->struct_mutex); +- if (0 == ((mem->type == VIA_MEM_VIDEO) ? dev_priv->vram_initialized : +- dev_priv->agp_initialized)) { +- DRM_ERROR +- ("Attempt to allocate from uninitialized memory manager.\n"); ++ if (0 == ++ ((mem->type == VIA_MEM_VIDEO || mem->type == VIA_MEM_VIDEO_SAVE) ? ++ 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_MM_ALIGN_MASK) >> VIA_MM_ALIGN_SHIFT; +- item = drm_sman_alloc(&dev_priv->sman, mem->type, tmpSize, 0, +- (unsigned long)file_priv); ++ item = drm_sman_alloc(&dev_priv->sman, ++ (mem->type == VIA_MEM_VIDEO_SAVE?VIA_MEM_VIDEO:mem->type), ++ tmpSize, 0, (unsigned long)file_priv); + mutex_unlock(&dev->struct_mutex); + if (item) { +- mem->offset = ((mem->type == VIA_MEM_VIDEO) ? +- dev_priv->vram_offset : dev_priv->agp_offset) + +- (item->mm-> +- offset(item->mm, item->mm_info) << VIA_MM_ALIGN_SHIFT); ++ mem->offset = ++ ((mem->type == VIA_MEM_VIDEO || ++ mem->type == VIA_MEM_VIDEO_SAVE) ? ++ dev_priv->vram_offset : dev_priv->agp_offset) + ++ (item->mm->offset(item->mm, item->mm_info) << ++ VIA_MM_ALIGN_SHIFT); + mem->index = item->user_hash.key; ++ if (mem->type == VIA_MEM_VIDEO_SAVE) { ++ if (!via_videomem_presave_ok(dev_priv, mem)) { ++ mutex_lock(&dev->struct_mutex); ++ drm_sman_free_key(&dev_priv->sman, mem->index); ++ mutex_unlock(&dev->struct_mutex); ++ retval = -ENOMEM; ++ } ++ } + } else { + mem->offset = 0; + mem->size = 0; +@@ -158,14 +272,20 @@ int via_mem_alloc(struct drm_device *dev + return retval; + } + +-int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv) ++int via_mem_free(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) + { +- drm_via_private_t *dev_priv = dev->dev_private; +- drm_via_mem_t *mem = data; ++ struct drm_via_private *dev_priv = dev->dev_private; ++ struct drm_via_mem *mem = data; + int ret; + + mutex_lock(&dev->struct_mutex); + ret = drm_sman_free_key(&dev_priv->sman, mem->index); ++ if (mem->type == VIA_MEM_VIDEO_SAVE) { ++ if (!via_videomem_housekeep_ok(mem)) ++ ret = -EINVAL; ++ } ++ + mutex_unlock(&dev->struct_mutex); + DRM_DEBUG("free = 0x%lx\n", mem->index); + +@@ -173,10 +293,10 @@ int via_mem_free(struct drm_device *dev, + } + + +-void via_reclaim_buffers_locked(struct drm_device * dev, ++void via_reclaim_buffers_locked(struct drm_device *dev, + struct drm_file *file_priv) + { +- drm_via_private_t *dev_priv = dev->dev_private; ++ struct drm_via_private *dev_priv = dev->dev_private; + + mutex_lock(&dev->struct_mutex); + if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)file_priv)) { +@@ -184,11 +304,36 @@ void via_reclaim_buffers_locked(struct d + return; + } + +- if (dev->driver->dma_quiescent) { ++ if (dev->driver->dma_quiescent) + dev->driver->dma_quiescent(dev); +- } ++ + + drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv); + mutex_unlock(&dev->struct_mutex); + return; + } ++ ++/*Henry:For via_fb_alloc/free used by video*/ ++static int via_fb_alloc(struct drm_via_mem *mem) ++{ ++ struct drm_device *dev = global_dev; ++ struct drm_file *file_priv = global_file_priv; ++ ++ if (dev && file_priv) ++ return via_mem_alloc(dev, mem, file_priv); ++ else ++ return -EINVAL; ++} ++EXPORT_SYMBOL(via_fb_alloc); ++ ++static int via_fb_free(struct drm_via_mem *mem) ++{ ++ struct drm_device *dev = global_dev; ++ struct drm_file *file_priv = global_file_priv; ++ ++ if (dev && file_priv) ++ return via_mem_free(dev, mem, file_priv); ++ else ++ return -EINVAL; ++} ++EXPORT_SYMBOL(via_fb_free); +--- a/drivers/char/drm/via_verifier.c ++++ b/drivers/char/drm/via_verifier.c +@@ -1,32 +1,32 @@ + /* +- * Copyright 2004 The Unichrome Project. All Rights Reserved. +- * Copyright 2005 Thomas Hellstrom. All Rights Reserved. +- * +- * Permission is hereby granted, free of charge, to any person obtaining a +- * copy of this software and associated documentation files (the "Software"), +- * to deal in the Software without restriction, including without limitation +- * the rights to use, copy, modify, merge, publish, distribute, sub license, +- * and/or sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice (including the +- * next paragraph) shall be included in all copies or substantial portions +- * of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +- * THE AUTHOR(S), AND/OR THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +- * DEALINGS IN THE SOFTWARE. +- * +- * Author: Thomas Hellstrom 2004, 2005. +- * This code was written using docs obtained under NDA from VIA Inc. +- * +- * Don't run this code directly on an AGP buffer. Due to cache problems it will +- * be very slow. +- */ ++* Copyright 2004 The Unichrome Project. All Rights Reserved. ++* Copyright 2005 Thomas Hellstrom. All Rights Reserved. ++* ++* Permission is hereby granted, free of charge, to any person obtaining a ++* copy of this software and associated documentation files (the "Software"), ++* to deal in the Software without restriction, including without limitation ++* the rights to use, copy, modify, merge, publish, distribute, sub license, ++* and/or sell copies of the Software, and to permit persons to whom the ++* Software is furnished to do so, subject to the following conditions: ++* ++* The above copyright notice and this permission notice (including the ++* next paragraph) shall be included in all copies or substantial portions ++* of the Software. ++* ++* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++* THE AUTHOR(S), AND/OR THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES ++* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++* DEALINGS IN THE SOFTWARE. ++* ++* Author: Thomas Hellstrom 2004, 2005. ++* This code was written using docs obtained under NDA from VIA Inc. ++* ++* Don't run this code directly on an AGP buffer. Due to cache problems it will ++* be very slow. ++*/ + + #include "via_3d_reg.h" + #include "drmP.h" +@@ -35,16 +35,16 @@ + #include "via_verifier.h" + #include "via_drv.h" + +-typedef enum { ++enum verifier_state { + state_command, + state_header2, + state_header1, + state_vheader5, + state_vheader6, + state_error +-} verifier_state_t; ++}; + +-typedef enum { ++enum hazard { + no_check = 0, + check_for_header2, + check_for_header1, +@@ -72,7 +72,7 @@ typedef enum { + check_for_vertex_count, + check_number_texunits, + forbidden_command +-} hazard_t; ++}; + + /* + * Associates each hazard above with a possible multi-command +@@ -81,7 +81,7 @@ typedef enum { + * that does not include any part of the address. + */ + +-static drm_via_sequence_t seqs[] = { ++static enum drm_via_sequence seqs[] = { + no_sequence, + no_sequence, + no_sequence, +@@ -109,12 +109,12 @@ static drm_via_sequence_t seqs[] = { + no_sequence + }; + +-typedef struct { ++struct hz_init { + unsigned int code; +- hazard_t hz; +-} hz_init_t; ++ enum hazard hz; ++}; + +-static hz_init_t init_table1[] = { ++static struct hz_init init_table1[] = { + {0xf2, check_for_header2_err}, + {0xf0, check_for_header1_err}, + {0xee, check_for_fire}, +@@ -165,7 +165,7 @@ static hz_init_t init_table1[] = { + {0x7D, check_for_vertex_count} + }; + +-static hz_init_t init_table2[] = { ++static struct hz_init init_table2[] = { + {0xf2, check_for_header2_err}, + {0xf0, check_for_header1_err}, + {0xee, check_for_fire}, +@@ -223,19 +223,19 @@ static hz_init_t init_table2[] = { + {0x93, no_check} + }; + +-static hz_init_t init_table3[] = { ++static struct hz_init init_table3[] = { + {0xf2, check_for_header2_err}, + {0xf0, check_for_header1_err}, + {0xcc, check_for_dummy}, + {0x00, check_number_texunits} + }; + +-static hazard_t table1[256]; +-static hazard_t table2[256]; +-static hazard_t table3[256]; ++static enum hazard table1[256]; ++static enum hazard table2[256]; ++static enum hazard table3[256]; + +-static __inline__ int +-eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) ++static inline int ++eat_words(const uint32_t **buf, const uint32_t *buf_end, unsigned num_words) + { + if ((buf_end - *buf) >= num_words) { + *buf += num_words; +@@ -249,18 +249,16 @@ eat_words(const uint32_t ** buf, const u + * Partially stolen from drm_memory.h + */ + +-static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq, +- unsigned long offset, +- unsigned long size, +- struct drm_device * dev) ++static inline drm_local_map_t *via_drm_lookup_agp_map( ++struct drm_via_state *seq, unsigned long offset, unsigned long size, ++struct drm_device *dev) + { + struct drm_map_list *r_list; + drm_local_map_t *map = seq->map_cache; + + if (map && map->offset <= offset +- && (offset + size) <= (map->offset + map->size)) { +- return map; +- } ++ && (offset + size) <= (map->offset + map->size)) ++ return map; + + list_for_each_entry(r_list, &dev->maplist, head) { + map = r_list->map; +@@ -286,7 +284,7 @@ static __inline__ drm_local_map_t *via_d + * very little CPU time. + */ + +-static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq) ++static inline int finish_current_sequence(struct drm_via_state *cur_seq) + { + switch (cur_seq->unfinished) { + case z_address: +@@ -343,14 +341,14 @@ static __inline__ int finish_current_seq + return 0; + } + +-static __inline__ int +-investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq) ++static inline int ++investigate_hazard(uint32_t cmd, enum hazard hz, struct drm_via_state *cur_seq) + { + register uint32_t tmp, *tmp_addr; + + if (cur_seq->unfinished && (cur_seq->unfinished != seqs[hz])) { +- int ret; +- if ((ret = finish_current_sequence(cur_seq))) ++ int ret = finish_current_sequence(cur_seq); ++ if (ret) + return ret; + } + +@@ -453,11 +451,11 @@ investigate_hazard(uint32_t cmd, hazard_ + cur_seq->tex_npot[cur_seq->texture] = 1; + } else { + cur_seq->pitch[cur_seq->texture][tmp] = +- (cmd & HC_HTXnLnPitE_MASK) >> HC_HTXnLnPitE_SHIFT; ++ (cmd & HC_HTXnLnPitE_MASK) >> HC_HTXnLnPitE_SHIFT; + cur_seq->tex_npot[cur_seq->texture] = 0; + if (cmd & 0x000FFFFF) { + DRM_ERROR +- ("Unimplemented texture level 0 pitch mode.\n"); ++ ("Unimplemented texture level 0 pitch mode.\n"); + return 2; + } + } +@@ -494,7 +492,8 @@ investigate_hazard(uint32_t cmd, hazard_ + return 0; + case check_texture_addr_mode: + cur_seq->unfinished = tex_address; +- if (2 == (tmp = cmd & 0x00000003)) { ++ tmp = cmd & 0x00000003; ++ if (2 == tmp) { + DRM_ERROR + ("Attempt to fetch texture from system memory.\n"); + return 2; +@@ -516,12 +515,12 @@ investigate_hazard(uint32_t cmd, hazard_ + return 2; + } + +-static __inline__ int +-via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end, +- drm_via_state_t * cur_seq) ++static inline int ++via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end, ++ struct drm_via_state *cur_seq) + { +- drm_via_private_t *dev_priv = +- (drm_via_private_t *) cur_seq->dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) cur_seq->dev->dev_private; + uint32_t a_fire, bcmd, dw_count; + int ret = 0; + int have_fire; +@@ -596,12 +595,13 @@ via_check_prim_list(uint32_t const **buf + if ((*buf == HALCYON_HEADER2) || + ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) { + DRM_ERROR("Missing Vertex Fire command, " +- "Stray Vertex Fire command or verifier " ++ "Stray Vertex Fire command or verifier " + "lost sync.\n"); + ret = 1; + break; + } +- if ((ret = eat_words(&buf, buf_end, dw_count))) ++ ret = eat_words(&buf, buf_end, dw_count); ++ if (ret) + break; + } + if (buf >= buf_end && !have_fire) { +@@ -620,15 +620,15 @@ via_check_prim_list(uint32_t const **buf + return ret; + } + +-static __inline__ verifier_state_t +-via_check_header2(uint32_t const **buffer, const uint32_t * buf_end, +- drm_via_state_t * hc_state) ++static inline enum verifier_state ++via_check_header2(uint32_t const **buffer, const uint32_t *buf_end, ++ struct drm_via_state *hc_state) + { + uint32_t cmd; + int hz_mode; +- hazard_t hz; ++ enum hazard hz; + const uint32_t *buf = *buffer; +- const hazard_t *hz_table; ++ const enum hazard *hz_table; + + if ((buf_end - buf) < 2) { + DRM_ERROR +@@ -693,8 +693,10 @@ via_check_header2(uint32_t const **buffe + + while (buf < buf_end) { + cmd = *buf++; +- if ((hz = hz_table[cmd >> 24])) { +- if ((hz_mode = investigate_hazard(cmd, hz, hc_state))) { ++ hz = hz_table[cmd >> 24]; ++ if (hz) { ++ hz_mode = investigate_hazard(cmd, hz, hc_state); ++ if (hz_mode) { + if (hz_mode == 1) { + buf--; + break; +@@ -702,20 +704,19 @@ via_check_header2(uint32_t const **buffe + return state_error; + } + } else if (hc_state->unfinished && +- finish_current_sequence(hc_state)) { ++ finish_current_sequence(hc_state)) + return state_error; +- } ++ + } +- if (hc_state->unfinished && finish_current_sequence(hc_state)) { ++ if (hc_state->unfinished && finish_current_sequence(hc_state)) + return state_error; +- } + *buffer = buf; + return state_command; + } + +-static __inline__ verifier_state_t +-via_parse_header2(drm_via_private_t * dev_priv, uint32_t const **buffer, +- const uint32_t * buf_end, int *fire_count) ++static inline enum verifier_state ++via_parse_header2(struct drm_via_private *dev_priv, uint32_t const **buffer, ++ const uint32_t *buf_end, int *fire_count) + { + uint32_t cmd; + const uint32_t *buf = *buffer; +@@ -762,7 +763,7 @@ via_parse_header2(drm_via_private_t * de + return state_command; + } + +-static __inline__ int verify_mmio_address(uint32_t address) ++static inline int verify_mmio_address(uint32_t address) + { + if ((address > 0x3FF) && (address < 0xC00)) { + DRM_ERROR("Invalid VIDEO DMA command. " +@@ -780,8 +781,8 @@ static __inline__ int verify_mmio_addres + return 0; + } + +-static __inline__ int +-verify_video_tail(uint32_t const **buffer, const uint32_t * buf_end, ++static inline int ++verify_video_tail(uint32_t const **buffer, const uint32_t *buf_end, + uint32_t dwords) + { + const uint32_t *buf = *buffer; +@@ -800,12 +801,12 @@ verify_video_tail(uint32_t const **buffe + return 0; + } + +-static __inline__ verifier_state_t +-via_check_header1(uint32_t const **buffer, const uint32_t * buf_end) ++static inline enum verifier_state ++via_check_header1(uint32_t const **buffer, const uint32_t *buf_end) + { + uint32_t cmd; + const uint32_t *buf = *buffer; +- verifier_state_t ret = state_command; ++ enum verifier_state ret = state_command; + + while (buf < buf_end) { + cmd = *buf; +@@ -813,14 +814,15 @@ via_check_header1(uint32_t const **buffe + (cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) { + if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) + break; +- DRM_ERROR("Invalid HALCYON_HEADER1 command. " +- "Attempt to access 3D- or command burst area.\n"); ++ DRM_ERROR("Invalid HALCYON_HEADER1 command. " \ ++ "Attempt to access 3D- or command burst \ ++ area.\n"); + ret = state_error; + break; + } else if (cmd > ((0xCFF >> 2) | HALCYON_HEADER1)) { + if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) + break; +- DRM_ERROR("Invalid HALCYON_HEADER1 command. " ++ DRM_ERROR("Invalid HALCYON_HEADER1 command. " \ + "Attempt to access VGA registers.\n"); + ret = state_error; + break; +@@ -832,9 +834,9 @@ via_check_header1(uint32_t const **buffe + return ret; + } + +-static __inline__ verifier_state_t +-via_parse_header1(drm_via_private_t * dev_priv, uint32_t const **buffer, +- const uint32_t * buf_end) ++static inline enum verifier_state ++via_parse_header1(struct drm_via_private *dev_priv, uint32_t const **buffer, ++ const uint32_t *buf_end) + { + register uint32_t cmd; + const uint32_t *buf = *buffer; +@@ -850,8 +852,8 @@ via_parse_header1(drm_via_private_t * de + return state_command; + } + +-static __inline__ verifier_state_t +-via_check_vheader5(uint32_t const **buffer, const uint32_t * buf_end) ++static inline enum verifier_state ++via_check_vheader5(uint32_t const **buffer, const uint32_t *buf_end) + { + uint32_t data; + const uint32_t *buf = *buffer; +@@ -883,9 +885,9 @@ via_check_vheader5(uint32_t const **buff + + } + +-static __inline__ verifier_state_t +-via_parse_vheader5(drm_via_private_t * dev_priv, uint32_t const **buffer, +- const uint32_t * buf_end) ++static inline enum verifier_state ++via_parse_vheader5(struct drm_via_private *dev_priv, ++ uint32_t const **buffer, const uint32_t *buf_end) + { + uint32_t addr, count, i; + const uint32_t *buf = *buffer; +@@ -893,17 +895,17 @@ via_parse_vheader5(drm_via_private_t * d + addr = *buf++ & ~VIA_VIDEOMASK; + i = count = *buf; + buf += 3; +- while (i--) { ++ while (i--) + VIA_WRITE(addr, *buf++); +- } ++ + if (count & 3) + buf += 4 - (count & 3); + *buffer = buf; + return state_command; + } + +-static __inline__ verifier_state_t +-via_check_vheader6(uint32_t const **buffer, const uint32_t * buf_end) ++static inline enum verifier_state ++via_check_vheader6(uint32_t const **buffer, const uint32_t *buf_end) + { + uint32_t data; + const uint32_t *buf = *buffer; +@@ -939,9 +941,9 @@ via_check_vheader6(uint32_t const **buff + return state_command; + } + +-static __inline__ verifier_state_t +-via_parse_vheader6(drm_via_private_t * dev_priv, uint32_t const **buffer, +- const uint32_t * buf_end) ++static inline enum verifier_state ++via_parse_vheader6(struct drm_via_private *dev_priv, ++ uint32_t const **buffer, const uint32_t *buf_end) + { + + uint32_t addr, count, i; +@@ -961,16 +963,17 @@ via_parse_vheader6(drm_via_private_t * d + } + + int +-via_verify_command_stream(const uint32_t * buf, unsigned int size, +- struct drm_device * dev, int agp) ++via_verify_command_stream(const uint32_t *buf, unsigned int size, ++ struct drm_device *dev, int agp) + { + +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; +- drm_via_state_t *hc_state = &dev_priv->hc_state; +- drm_via_state_t saved_state = *hc_state; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; ++ struct drm_via_state *hc_state = &dev_priv->hc_state; ++ struct drm_via_state saved_state = *hc_state; + uint32_t cmd; + const uint32_t *buf_end = buf + (size >> 2); +- verifier_state_t state = state_command; ++ enum verifier_state state = state_command; + int cme_video; + int supported_3d; + +@@ -1002,8 +1005,8 @@ via_verify_command_stream(const uint32_t + state = via_check_vheader6(&buf, buf_end); + break; + case state_command: +- if ((HALCYON_HEADER2 == (cmd = *buf)) && +- supported_3d) ++ cmd = *buf; ++ if ((HALCYON_HEADER2 == cmd) && supported_3d) + state = state_header2; + else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) + state = state_header1; +@@ -1014,12 +1017,12 @@ via_verify_command_stream(const uint32_t + && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) + state = state_vheader6; + else if ((cmd == HALCYON_HEADER2) && !supported_3d) { +- DRM_ERROR("Accelerated 3D is not supported on this chipset yet.\n"); ++ DRM_ERROR("Accelerated 3D is not \ ++ supported on this chipset yet.\n"); + state = state_error; + } else { +- DRM_ERROR +- ("Invalid / Unimplemented DMA HEADER command. 0x%x\n", +- cmd); ++ DRM_ERROR("Invalid / Unimplemented DMA \ ++ HEADER command. 0x%x\n", cmd); + state = state_error; + } + break; +@@ -1037,14 +1040,15 @@ via_verify_command_stream(const uint32_t + } + + int +-via_parse_command_stream(struct drm_device * dev, const uint32_t * buf, ++via_parse_command_stream(struct drm_device *dev, const uint32_t *buf, + unsigned int size) + { + +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; + uint32_t cmd; + const uint32_t *buf_end = buf + (size >> 2); +- verifier_state_t state = state_command; ++ enum verifier_state state = state_command; + int fire_count = 0; + + while (buf < buf_end) { +@@ -1065,7 +1069,8 @@ via_parse_command_stream(struct drm_devi + state = via_parse_vheader6(dev_priv, &buf, buf_end); + break; + case state_command: +- if (HALCYON_HEADER2 == (cmd = *buf)) ++ cmd = *buf; ++ if (HALCYON_HEADER2 == cmd) + state = state_header2; + else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) + state = state_header1; +@@ -1074,9 +1079,8 @@ via_parse_command_stream(struct drm_devi + else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) + state = state_vheader6; + else { +- DRM_ERROR +- ("Invalid / Unimplemented DMA HEADER command. 0x%x\n", +- cmd); ++ DRM_ERROR("Invalid / Unimplemented DMA \ ++ HEADER command. 0x%x\n", cmd); + state = state_error; + } + break; +@@ -1085,32 +1089,31 @@ via_parse_command_stream(struct drm_devi + return -EINVAL; + } + } +- if (state == state_error) { ++ if (state == state_error) + return -EINVAL; +- } ++ + return 0; + } + + static void +-setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size) ++setup_hazard_table(struct hz_init init_table[], enum hazard table[], int size) + { + int i; + +- for (i = 0; i < 256; ++i) { ++ for (i = 0; i < 256; ++i) + table[i] = forbidden_command; +- } + +- for (i = 0; i < size; ++i) { ++ for (i = 0; i < size; ++i) + table[init_table[i].code] = init_table[i].hz; +- } ++ + } + + void via_init_command_verifier(void) + { + setup_hazard_table(init_table1, table1, +- sizeof(init_table1) / sizeof(hz_init_t)); ++ sizeof(init_table1) / sizeof(struct hz_init)); + setup_hazard_table(init_table2, table2, +- sizeof(init_table2) / sizeof(hz_init_t)); ++ sizeof(init_table2) / sizeof(struct hz_init)); + setup_hazard_table(init_table3, table3, +- sizeof(init_table3) / sizeof(hz_init_t)); ++ sizeof(init_table3) / sizeof(struct hz_init)); + } +--- a/drivers/char/drm/via_verifier.h ++++ b/drivers/char/drm/via_verifier.h +@@ -1,39 +1,39 @@ + /* +- * Copyright 2004 The Unichrome Project. All Rights Reserved. +- * +- * Permission is hereby granted, free of charge, to any person obtaining a +- * copy of this software and associated documentation files (the "Software"), +- * to deal in the Software without restriction, including without limitation +- * the rights to use, copy, modify, merge, publish, distribute, sub license, +- * and/or sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice (including the +- * next paragraph) shall be included in all copies or substantial portions +- * of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +- * THE UNICHROME PROJECT, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +- * DEALINGS IN THE SOFTWARE. +- * +- * Author: Thomas Hellström 2004. +- */ ++* Copyright 2004 The Unichrome Project. All Rights Reserved. ++* ++* Permission is hereby granted, free of charge, to any person obtaining a ++* copy of this software and associated documentation files (the "Software"), ++* to deal in the Software without restriction, including without limitation ++* the rights to use, copy, modify, merge, publish, distribute, sub license, ++* and/or sell copies of the Software, and to permit persons to whom the ++* Software is furnished to do so, subject to the following conditions: ++* ++* The above copyright notice and this permission notice (including the ++* next paragraph) shall be included in all copies or substantial portions ++* of the Software. ++* ++* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++* THE UNICHROME PROJECT, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR ++* THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++* ++* Author: Thomas Hellström 2004. ++*/ + + #ifndef _VIA_VERIFIER_H_ + #define _VIA_VERIFIER_H_ + +-typedef enum { ++enum drm_via_sequence { + no_sequence = 0, + z_address, + dest_address, + tex_address +-} drm_via_sequence_t; ++}; + +-typedef struct { ++struct drm_via_state { + unsigned texture; + uint32_t z_addr; + uint32_t d_addr; +@@ -44,7 +44,7 @@ typedef struct { + uint32_t tex_level_hi[2]; + uint32_t tex_palette_size[2]; + uint32_t tex_npot[2]; +- drm_via_sequence_t unfinished; ++ enum drm_via_sequence unfinished; + int agp_texture; + int multitex; + struct drm_device *dev; +@@ -52,11 +52,11 @@ typedef struct { + uint32_t vertex_count; + int agp; + const uint32_t *buf_start; +-} drm_via_state_t; ++}; + +-extern int via_verify_command_stream(const uint32_t * buf, unsigned int size, +- struct drm_device * dev, int agp); +-extern int via_parse_command_stream(struct drm_device *dev, const uint32_t *buf, +- unsigned int size); ++extern int via_verify_command_stream(const uint32_t *buf, ++ unsigned int size, struct drm_device *dev, int agp); ++extern int via_parse_command_stream(struct drm_device *dev, ++ const uint32_t *buf, unsigned int size); + + #endif +--- a/drivers/char/drm/via_video.c ++++ b/drivers/char/drm/via_video.c +@@ -1,35 +1,35 @@ + /* +- * Copyright 2005 Thomas Hellstrom. All Rights Reserved. +- * +- * Permission is hereby granted, free of charge, to any person obtaining a +- * copy of this software and associated documentation files (the "Software"), +- * to deal in the Software without restriction, including without limitation +- * the rights to use, copy, modify, merge, publish, distribute, sub license, +- * and/or sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice (including the +- * next paragraph) shall be included in all copies or substantial portions +- * of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +- * THE AUTHOR(S), AND/OR THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +- * DEALINGS IN THE SOFTWARE. +- * +- * Author: Thomas Hellstrom 2005. +- * +- * Video and XvMC related functions. +- */ ++* Copyright 2005 Thomas Hellstrom. All Rights Reserved. ++* ++* Permission is hereby granted, free of charge, to any person obtaining a ++* copy of this software and associated documentation files (the "Software"), ++* to deal in the Software without restriction, including without limitation ++* the rights to use, copy, modify, merge, publish, distribute, sub license, ++* and/or sell copies of the Software, and to permit persons to whom the ++* Software is furnished to do so, subject to the following conditions: ++* ++* The above copyright notice and this permission notice (including the ++* next paragraph) shall be included in all copies or substantial portions ++* of the Software. ++* ++* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++* THE AUTHOR(S), AND/OR THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES ++* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++* DEALINGS IN THE SOFTWARE. ++* ++* Author: Thomas Hellstrom 2005. ++* ++* Video and XvMC related functions. ++*/ + + #include "drmP.h" + #include "via_drm.h" + #include "via_drv.h" + +-void via_init_futex(drm_via_private_t * dev_priv) ++void via_init_futex(struct drm_via_private *dev_priv) + { + unsigned int i; + +@@ -41,11 +41,11 @@ void via_init_futex(drm_via_private_t * + } + } + +-void via_cleanup_futex(drm_via_private_t * dev_priv) ++void via_cleanup_futex(struct drm_via_private *dev_priv) + { + } + +-void via_release_futex(drm_via_private_t * dev_priv, int context) ++void via_release_futex(struct drm_via_private *dev_priv, int context) + { + unsigned int i; + volatile int *lock; +@@ -57,20 +57,22 @@ void via_release_futex(drm_via_private_t + lock = (volatile int *)XVMCLOCKPTR(dev_priv->sarea_priv, i); + if ((_DRM_LOCKING_CONTEXT(*lock) == context)) { + if (_DRM_LOCK_IS_HELD(*lock) +- && (*lock & _DRM_LOCK_CONT)) { ++ && (*lock & _DRM_LOCK_CONT)) + DRM_WAKEUP(&(dev_priv->decoder_queue[i])); +- } ++ + *lock = 0; + } + } + } + +-int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv) ++int via_decoder_futex(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) + { +- drm_via_futex_t *fx = data; ++ struct drm_via_futex *fx = data; + volatile int *lock; +- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; +- drm_via_sarea_t *sAPriv = dev_priv->sarea_priv; ++ struct drm_via_private *dev_priv = ++ (struct drm_via_private *) dev->dev_private; ++ struct drm_via_sarea *sAPriv = dev_priv->sarea_priv; + int ret = 0; + + DRM_DEBUG("\n"); @@ -231,6 +231,9 @@ ldp/aectc-add-the-aectc-driver.patch ldp/net-add-et131x-driver.patch ldp/framebuffer-add-the-via-framebuffer-driver.patch ldp/oms-add-oms-maxp-driver.patch +ldp/via-agp.patch +ldp/via-chrome9-drm.patch +ldp/via-unichrome-drm.patch # not quite working yet... @@ -247,3 +250,4 @@ ldp/oms-add-oms-maxp-driver.patch #kill-bus_id.patch + |
