FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Ubuntu > Ubuntu Kernel Team

 
 
LinkBack Thread Tools
 
Old 12-24-2008, 01:48 AM
 
Default DRM / VIA_CHROME9 - C code

To whom it may concern:
This patch contains the modification on the .C files for the VIA
Chrome9 DRM kernel module based on kernel 2.6.28-RC9. The c files
includes
1. via_chrome9_dma.c
2. via_chrome9_drm.c
3. via_chrome9_drv.c
4. via_chrome9_mm.c
5. via_chrome9_verifier.c

Thanks and Best Regards
Bruce C. Chang

Signed-off-by: Bruce Chang <BruceChang@via.com.tw>
diff -Nur ./drivers/gpu/drm/via_chrome9/via_chrome9_dma.c
./drivers/gpu/drm/via_chrome9/via_chrome9_dma.c
--- ./drivers/gpu/drm/via_chrome9/via_chrome9_dma.c 1970-01-01
08:00:00.000000000 +0800
+++ ./drivers/gpu/drm/via_chrome9/via_chrome9_dma.c 2009-02-11
00:32:53.000000000 +0800
@@ -0,0 +1,1281 @@
+/*
+ * 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
+protect_size_value(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;
+}
+
+void via_chrome9_dma_init_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;
+
+ 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 |= protect_size_value(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);
+
+ if (dev_priv->drm_agp_type != DRM_AGP_DISABLED) {
+ 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)
+ set_agp_double_cmd_inv(dev);
+ else if (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER)
+ set_agp_ring_cmd_inv(dev);
+
+ return ;
+}
+
+static unsigned int
+init_pcie_gart(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 |=
protect_size_value(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 *
+alloc_bind_pcie_memory(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
+set_agp_double_cmd_inv(struct drm_device *dev)
+{
+ /* we now don't use double buffer */
+ return;
+}
+
+void
+set_agp_ring_cmd_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
",
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;
+ /* 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!
");
+ 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
");
+
+ if (dev_priv->chip_sub_index == CHIP_H6S2) {
+ dev_priv->pcie_vmalloc_nocache = 0;
+ if (dev_priv->pagetable_map.pagetable_size)
+ retval = init_pcie_gart(dev_priv);
+
+ if (retval && dev_priv->drm_agp_type !=
DRM_AGP_DISABLED) {
+ addrlinear =
+ alloc_bind_pcie_memory(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);
+ /* 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;
+ set_agp_double_cmd_inv(dev);
+ if (dev_priv->chip_sub_index == CHIP_H6S2) {
+ DRM_INFO("DMA buffer initialized finished. ");
+ DRM_INFO("Use PCIE Double Buffer type!
");
+ DRM_INFO("Total PCIE DMA buffer size = %8d
bytes.
",
+ lpcmdmamanager->dmasize << 2);
+ } else {
+ DRM_INFO("DMA buffer initialized finished. ");
+ DRM_INFO("Use AGP Double Buffer type!
");
+ DRM_INFO("Total AGP DMA buffer size = %8d bytes.

",
+ 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;
+ set_agp_ring_cmd_inv(dev);
+ if (dev_priv->chip_sub_index == CHIP_H6S2) {
+ DRM_INFO("DMA buffer initialized finished.
");
+ DRM_INFO("Use PCIE Ring Buffer type!");
+ DRM_INFO("Total PCIE DMA buffer size = %8d
bytes.
",
+ lpcmdmamanager->dmasize << 2);
+ } else {
+ DRM_INFO("DMA buffer initialized finished. ");
+ DRM_INFO("Use AGP Ring Buffer type!
");
+ DRM_INFO("Total AGP DMA buffer size = %8d bytes.

",
+ 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
");
+ else
+ DRM_INFO("AGP init failed! Use PCI
");
+ }
+ return 0;
+}
+
+static void
+kickoff_bci_inv(struct drm_device *dev,
+ struct drm_via_chrome9_flush *dma_info)
+{
+ u32 hdtype, dwqwcount, i, dwcount, add1, addr2, swpointer,
+ swpointerend;
+ unsigned long *pcmddata;
+ int result;
+
+ struct drm_via_chrome9_private *dev_priv =
+ (struct drm_via_chrome9_private *) dev->dev_private;
+ /*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);
+ if (result) {
+ DRM_ERROR("In function kickoff_bci_inv,
+ copy_from_user is fault.
");
+ return ;
+ }
+ result = via_chrome9_verify_command_stream(
+ (const uint32_t *)pcmddata, dma_info->cmd_size << 2,
+ dev, dev_priv->chip_sub_index == CHIP_H6S2 ? 0 : 1);
+ if (result) {
+ DRM_ERROR("The command has the security issue
");
+ return ;
+ }
+ 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];
+ add1 = 0x0;
+ swpointer += 4; /* skip 128-bit. */
+
+ for (; dwcount > 0; dwcount--, swpointer++,
+ add1 += 4) {
+
setmmioregister(dev_priv->hostBlt->handle,
+ add1,
pcmddata[swpointer]);
+ }
+ break;
+
+ case INV_AGPHeader4:
+ dwcount = pcmddata[swpointer + 1];
+ add1 = pcmddata[swpointer] & 0x0000FFFF;
+ swpointer += 4; /* skip 128-bit. */
+
+ for (; dwcount > 0; dwcount--, swpointer++)
+ setmmioregister(dev_priv->mmio->handle,
add1,
+ pcmddata[swpointer]);
+ break;
+
+ case INV_AGPHeader2:
+ add1 = pcmddata[swpointer + 1] & 0xFFFF;
+ addr2 = pcmddata[swpointer] & 0xFFFF;
+
+ /* Write first data (either ParaType or
whatever) to
+ add1 */
+ setmmioregister(dev_priv->mmio->handle, add1,
+ pcmddata[swpointer + 2]);
+ swpointer += 4;
+
+ /* The following data are all written to addr2,
+ until another header is met */
+ while (!is_agp_header(pcmddata[swpointer])
+ && (swpointer < swpointerend)) {
+ setmmioregister(dev_priv->mmio->handle,
addr2,
+ pcmddata[swpointer]);
+ swpointer++;
+ }
+ break;
+
+ case INV_AGPHeader3:
+ add1 = pcmddata[swpointer] & 0xFFFF;
+ addr2 = add1 + 4;
+ dwcount = pcmddata[swpointer + 1];
+
+ /* Write first data (either ParaType or
whatever) to
+ add1 */
+ setmmioregister(dev_priv->mmio->handle, add1,
+ 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!!!
");
+ 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
+rewind_ring_agp_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!!!
");
+ 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);
+ }
+ rewind_ring_agp_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);
+ }
+ rewind_ring_agp_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->chip_sub_index == CHIP_H6S2) &&
+ (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;
+ 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!!!
");
+ return 0;
+ }
+
+ kickoff_bci_inv(dev, 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->chip_sub_index == CHIP_H6S2) &&
+ (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER))
+ getspace.dwRequestSize += (NULLCOMMANDNUMBER +
4);
+ /* 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);
+ if (result) {
+ DRM_ERROR("In function
via_chrome9_ioctl_flush,
+ copy_from_user is fault.
");
+ return -EINVAL;
+ }
+
+ result = via_chrome9_verify_command_stream(
+ (const uint32_t *)pcmddata, dma_info->cmd_size
<< 2,
+ dev, dev_priv->chip_sub_index == CHIP_H6S2 ? 0 :
1);
+ if (result) {
+ DRM_ERROR("The user command has security
issue.
");
+ return -EINVAL;
+ }
+
+ 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;
+}

diff -Nur ./drivers/gpu/drm/via_chrome9/via_chrome9_drm.c
./drivers/gpu/drm/via_chrome9/via_chrome9_drm.c
--- ./drivers/gpu/drm/via_chrome9/via_chrome9_drm.c 1970-01-01
08:00:00.000000000 +0800
+++ ./drivers/gpu/drm/via_chrome9/via_chrome9_drm.c 2009-02-11
00:32:53.000000000 +0800
@@ -0,0 +1,945 @@
+/*
+ * 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_chrome9_dev_v4l;
+void *via_chrome9_filepriv_v4l;
+
+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++) {
+ 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++) {
+ 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));
+ for (i = 0 ; i <= 0x30 ; i++) {
+
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));
+ for (i = 0 ; i <= 0x36 ; i++) {
+
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;
+
+ if (!dev_priv->initialized)
+ return 0;
+
+ 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 i;
+ /* Here restore SR66~SR6F SR79~SR7B */
+ for (i = 0; i < 10; i++) {
+ setmmioregisteru8(dev_priv->mmio->handle,
+ 0x83c4, 0x66 + i);
+ setmmioregisteru8(dev_priv->mmio->handle,
+ 0x83c5, dev_priv->gti_backup[i]);
+ }
+
+ for (i = 0; i < 3; i++) {
+ setmmioregisteru8(dev_priv->mmio->handle,
+ 0x83c4, 0x79 + i);
+ setmmioregisteru8(dev_priv->mmio->handle,
+ 0x83c5, dev_priv->gti_backup[10 + i]);
+ }
+ }
+
+ via_chrome9_dma_init_inv(dev);
+
+ return 0;
+}
+
+int via_chrome9_drm_suspend(struct pci_dev *pci,
+ pm_message_t state)
+{
+ int i;
+ 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;
+
+ if (!dev_priv->initialized)
+ return 0;
+
+ if (dev_priv->chip_sub_index != CHIP_H6S2)
+ return 0;
+
+ /* Save registers from SR66~SR6F */
+ for (i = 0; i < 10; i++) {
+ setmmioregisteru8(dev_priv->mmio->handle, 0x83c4, 0x66 +
i);
+ dev_priv->gti_backup[i] =
+ getmmioregisteru8(dev_priv->mmio->handle,
0x83c5);
+ }
+
+ /* Save registers from SR79~SR7B */
+ for (i = 0; i < 3; i++) {
+ setmmioregisteru8(dev_priv->mmio->handle, 0x83c4, 0x79 +
i);
+ dev_priv->gti_backup[10 + i] =
+ getmmioregisteru8(dev_priv->mmio->handle,
0x83c5);
+ }
+
+ 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;
+
+ 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_chro
 

Thread Tools




All times are GMT. The time now is 04:23 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org