summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2005-11-16 16:00:28 +0000
committerLuc Verhaegen <libv@skynet.be>2005-11-16 16:00:28 +0000
commit379d8e4125262668f1678795c59ea78c02dffb1a (patch)
treea5550e45b5010af1d7565034830e56fbdbc0b150
parentb0b628e4b35791a04f56fa5509589d6da72d65fe (diff)
[devel-drmVersion]
- Fix build to build against old and new via_drm.h. - Get pVia->drmVersion early on, so it can be used for more than the ringbuffer. Relay DRM version in log. - Include drm/via_drm.h instead of plain via_drm.h when using modular.
-rw-r--r--src/via_driver.c4
-rw-r--r--src/via_driver.h8
-rw-r--r--src/via_memory.c6
-rw-r--r--src/via_video.c95
4 files changed, 106 insertions, 7 deletions
diff --git a/src/via_driver.c b/src/via_driver.c
index 533aeed..61cb879 100644
--- a/src/via_driver.c
+++ b/src/via_driver.c
@@ -150,7 +150,8 @@ typedef enum {
OPTION_INSECUREDRI,
OPTION_TVDEFLICKER,
OPTION_AGP_DMA,
- OPTION_2D_DMA
+ OPTION_2D_DMA,
+ OPTION_USEDMACOPY
} VIAOpts;
@@ -184,6 +185,7 @@ static OptionInfoRec VIAOptions[] =
{OPTION_DISABLEIRQ, "DisableIRQ", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_AGP_DMA, "EnableAGPDMA", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_2D_DMA, "NoAGPFor2D", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_USEDMACOPY, "UseDMACopy", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
diff --git a/src/via_driver.h b/src/via_driver.h
index b12ee77..9591c28 100644
--- a/src/via_driver.h
+++ b/src/via_driver.h
@@ -185,9 +185,9 @@ typedef struct _VIA {
ViaTwodContext td;
ViaCBuffer cBuf;
- /* BIOS Info Ptr */
- VIABIOSInfoPtr pBIOSInfo;
- struct ViaCardIdStruct* Id;
+ VIABIOSInfoPtr pBIOSInfo;
+ struct ViaCardIdStruct* Id;
+ CARD8 ActiveDevice; /* Option - actual devices -> pBIOSInfo */
/* Support for DGA */
int numDGAModes;
@@ -229,6 +229,7 @@ typedef struct _VIA {
Bool DRIIrqEnable;
Bool agpEnable;
Bool dma2d;
+ Bool UseDMACopy;
CARD8 ActiveDevice; /* Option */
@@ -249,7 +250,6 @@ typedef struct _VIA {
ViaSharedPtr sharedData;
#ifdef HAVE_DEBUG
- Bool DumpVGAROM;
Bool PrintVGARegs;
Bool PrintTVRegs;
Bool PrintSwovRegs;
diff --git a/src/via_memory.c b/src/via_memory.c
index 7dd5db0..a342f22 100644
--- a/src/via_memory.c
+++ b/src/via_memory.c
@@ -289,6 +289,12 @@ ViaMemFBAlloc(ScrnInfoPtr pScrn, unsigned long size, CARD8 alignment)
* DRM.
*
*/
+/* First some workarounds for the badly trackable drm changes.
+ * Plainly using VIDEO as a macro is a pretty bad initial choice
+ * though */
+#ifndef VIDEO
+#define VIDEO VIA_MEM_VIDEO
+#endif
/*
*
diff --git a/src/via_video.c b/src/via_video.c
index d15813f..ee92cfc 100644
--- a/src/via_video.c
+++ b/src/via_video.c
@@ -1689,12 +1689,103 @@ RegionsEqual(ScreenPtr pScreen, RegionPtr A, RegionPtr B)
#endif /* !REGION_EQUAL */
/*
+ * There is no via_drm.h versioning so we need to revert to this.
+ */
+#ifdef DRM_VIA_DMA_BLIT
+static Bool
+ViaSwovCopyDMA(VIAPtr pVia, struct ViaMem *Mem, unsigned char *buf)
+{
+ struct ViaXvPort *Port = pVia->Swov->Port;
+ unsigned char *aligned_buf, *new_buf = NULL;
+ drm_via_dmablit_t blit;
+ drm_via_blitsync_t *sync = &(blit.sync);
+ short width, height;
+ int error, i;
+
+ /* Here we have to work around implementational shortsightedness.
+ * The drm driver seems to lack the ability to just copy any given
+ * block of memory */
+ height = Port->Height;
+ width = Mem->Size / Port->Height;
+
+ /* reduce the amount of copies needed - work around unneccessary
+ * restrictions as best as possible*/
+ i = 4096 / width;
+ while (i > 1) {
+ if (!(height % i)) {
+ width *= i;
+ height /= i;
+ break;
+ }
+ i--;
+ }
+
+ /* Everything VIA requires memory to be 16byte aligned -- idiots */
+ if (((int) buf & 0x0F)) {
+ ViaDebug(pVia->scrnIndex, "%s: Buffer Misalignment!\n", __FUNCTION__);
+ new_buf = malloc(Mem->Size + 0x0F);
+ aligned_buf = (unsigned char *) (((int) new_buf + 0x0F) & ~0x0F);
+ xf86memcpy(aligned_buf, buf, Mem->Size);
+ } else
+ aligned_buf = buf;
+
+ /* Bleh; what was wrong with 2 addresses, a size and a direction ? */
+ blit.num_lines = height;
+ blit.line_length = width;
+ blit.fb_addr = Mem->Base;
+ blit.fb_stride = width;
+ blit.mem_addr = aligned_buf;
+ blit.mem_stride = width;
+ blit.bounce_buffer = 0; /* not implemented anyway */
+ blit.to_fb = 1;
+
+ /* shedule this copy */
+ error = -EAGAIN;
+ while (error == -EAGAIN)
+ error = drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, &blit,
+ sizeof(drm_via_dmablit_t));
+
+ if (error) {
+ xf86DrvMsg(pVia->scrnIndex, X_ERROR, "%s: DMA copy sheduling failed.\n",
+ __FUNCTION__);
+ if (new_buf)
+ xfree(new_buf);
+
+ return FALSE;
+ }
+
+ /* wait for this copy to complete */
+ error = -EAGAIN;
+ while (error == -EAGAIN)
+ error = drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC, sync,
+ sizeof(drm_via_blitsync_t));
+
+ if (new_buf)
+ xfree(new_buf);
+
+ if (error) {
+ xf86DrvMsg(pVia->scrnIndex, X_ERROR, "%s: DMA copy sync failed.\n",
+ __FUNCTION__);
+ return FALSE;
+ }
+ return TRUE;
+}
+#endif /* DRM_VIA_DMA_BLIT */
+
+/*
*
*/
-__inline__ static void
+static Bool
ViaSwovCopy(VIAPtr pVia, struct ViaMem *Mem, unsigned char *buf)
{
- xf86memcpy(pVia->FBBase + Mem->Base, buf, Mem->Size);
+#ifdef DRM_VIA_DMA_BLIT
+ if (pVia->UseDMACopy)
+ return ViaSwovCopyDMA(pVia, Mem, buf);
+ else
+#endif
+ xf86memcpy(pVia->FBBase + Mem->Base, buf, Mem->Size);
+
+ return TRUE;
}
/*