summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2009-01-29 18:44:43 +0100
committerLuc Verhaegen <libv@skynet.be>2009-01-29 18:44:43 +0100
commite5e27810d41a603e5731746436936318f48b42a3 (patch)
treefbfa43f2a6830f5d9ff8b7a7cf980a908ef8c65a
parent4080a198207d6b2be8879993d14521f705f33d70 (diff)
Add DirectFB option.
The p4m800 boards bios doesn't set direct FB access. So now the option is added to enable this from the config. This at the same time makes it possible to force it off as well. Default is either depending on what the bios did, or true for k8m800 where it is just finding out where the physical ram lives.
-rw-r--r--man/unichrome.man5
-rw-r--r--src/via_accel.c2
-rw-r--r--src/via_driver.c13
-rw-r--r--src/via_driver.h5
-rw-r--r--src/via_host.c177
5 files changed, 152 insertions, 50 deletions
diff --git a/man/unichrome.man b/man/unichrome.man
index 178b889..d0ebb09 100644
--- a/man/unichrome.man
+++ b/man/unichrome.man
@@ -59,6 +59,11 @@ Disable the hardware cursor and use software cursor rendering instead.
Select any of \*qNone\*q, \*qShadowFB\*q or \*qXAA\*q as an Acceleration
Method. The default is \*qXAA\*q.
.TP
+.BI "Option \*qDirectFB\*q \*q" boolean \*q
+Force Direct FB access for the CPU on or off. Default for non-HyperTransport
+chipsets is whatever the BIOS set up. For K8M800 (VT3108), the default is
+on.
+.TP
.BI "Option \*qRotate\*q \*q" string \*q
Rotate the display either clockwise (\*qCW\*q) or counter clockwise (\*qCCW\*q).
Rotation is only supported unaccelerated.
diff --git a/src/via_accel.c b/src/via_accel.c
index 5083d99..58247fa 100644
--- a/src/via_accel.c
+++ b/src/via_accel.c
@@ -1193,7 +1193,7 @@ VIAXAAInit(ScrnInfoPtr pScrn, XAAInfoRecPtr xaaptr)
0;
/* It's faster to write directly into the FB than to use the PCI GXCopy */
- if (pVia->FBDirectCPUAccess)
+ if (pVia->FBDirect)
xaaptr->ImageWriteFlags |= NO_GXCOPY;
xaaptr->SetupForImageWrite = VIASetupForImageWrite;
diff --git a/src/via_driver.c b/src/via_driver.c
index 53a65cd..819f435 100644
--- a/src/via_driver.c
+++ b/src/via_driver.c
@@ -196,6 +196,7 @@ typedef enum {
OPTION_CRTC2SCALE,
OPTION_CRTC2HSCALE,
OPTION_CRTC2VSCALE,
+ OPTION_FBDIRECT,
OPTION_DISABLEVQ,
OPTION_DRIXINERAMA,
OPTION_DISABLEIRQ,
@@ -228,6 +229,7 @@ static OptionInfoRec VIAOptions[] =
{OPTION_CRTC2SCALE, "CRTC2Scale", OPTV_ANYSTR, {0}, FALSE},
{OPTION_CRTC2HSCALE, "CRTC2HScale", OPTV_ANYSTR, {0}, FALSE},
{OPTION_CRTC2VSCALE, "CRTC2VScale", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_FBDIRECT, "DirectFB", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_DISABLEVQ, "DisableVQ", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_DRIXINERAMA, "DRIXINERAMA", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_DISABLEIRQ, "DisableIRQ", OPTV_BOOLEAN, {0}, FALSE},
@@ -1324,6 +1326,10 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
pVia->ActiveDevice |= VIA_DEVICE_TV;
}
+ /* Do we set/force the Direct FB option? */
+ pVia->FBDirectOption = xf86GetOptValBool(VIAOptions, OPTION_FBDIRECT,
+ &pVia->FBDirect);
+
#ifdef XSERVER_LIBPCIACCESS
pVia->ChipId = pVia->PciInfo->vendor_id;
pScrn->chipset = (char *)xf86TokenToString(VIAChipsets, pVia->Chipset);
@@ -2008,13 +2014,6 @@ ViaMapFB(ScrnInfoPtr pScrn)
"mapping framebuffer @ 0x%lx with size 0x%lx\n",
pVia->FrameBufferBase, pVia->videoRambytes);
- if (pVia->FBDirectCPUAccess)
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Framebuffer: Direct CPU access enabled.\n");
- else
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Framebuffer: No Direct CPU access possible.\n");
-
#ifdef XSERVER_LIBPCIACCESS
if (pci_device_map_range(pVia->PciInfo, pVia->FrameBufferBase,
pVia->videoRambytes,
diff --git a/src/via_driver.h b/src/via_driver.h
index 7ec1da4..81934f0 100644
--- a/src/via_driver.h
+++ b/src/via_driver.h
@@ -169,7 +169,10 @@ typedef struct _VIA {
CARD8 MemType;
CARD32 Bandwidth; /* available memory bandwidth */
- Bool FBDirectCPUAccess;
+
+ /* Handle direct CPU->FB access */
+ Bool FBDirectOption; /* should we force something? */
+ Bool FBDirect; /* set or not? */
#ifndef X_USE_LINEARFB
/* memory "management" */
diff --git a/src/via_host.c b/src/via_host.c
index 4d42c5c..4fcd30f 100644
--- a/src/via_host.c
+++ b/src/via_host.c
@@ -74,6 +74,7 @@ pci_device_from_ids_first(CARD16 Vendor, CARD16 Device)
#define PCIREADBYTE(pcidev, offset, data) pci_device_cfg_read_u8((pcidev), (data), (offset))
#define PCIREADWORD(pcidev, offset, data) pci_device_cfg_read_u16((pcidev), (data), (offset))
+#define PCIWRITEWORD(pcidev, offset, data) pci_device_cfg_write_u16((pcidev), (data), (offset))
#else /* XSERVER_LIBPCIACCESS */
@@ -86,6 +87,7 @@ pci_device_from_ids_first(CARD16 Vendor, CARD16 Device)
#define PCIREADBYTE(pcidev, offset, data) *(data) = pciReadByte((pcidev), (offset))
#define PCIREADWORD(pcidev, offset, data) *(data) = pciReadWord((pcidev), (offset))
+#define PCIWRITEWORD(pcidev, offset, data) pciWriteWord((pcidev), (offset), (data))
#endif /* XSERVER_LIBPCIACCESS */
@@ -336,11 +338,8 @@ KM400RAMTypeGet(ScrnInfoPtr pScrn)
}
/*
- * TEST ME
- *
* Values are again from the BIOS, but here it was easy to see how things
* added up.
- *
*/
static CARD8
P4M800RAMTypeGet(ScrnInfoPtr pScrn)
@@ -812,38 +811,145 @@ ViaFBInit(ScrnInfoPtr pScrn)
* quite some latency and on-chip bandwidth. So on devices that are not using
* and AMD K8, we also get some advantage here.
*/
+
+/*
+ *
+ */
+static Bool
+CLE266FBDirectAccess(int scrnIndex, unsigned long *FBBase,
+ Bool Force, Bool ForceOn)
+{
+ PCIDEVVAR Dev = PCIDEVFROMPOS(0, 0, 0);
+ CARD16 tmp;
+
+ PCIREADWORD(Dev, 0xE0, &tmp);
+
+ if (Force) {
+ if (ForceOn) { /* We have to enable direct Access */
+ tmp &= ~0x0FFF;
+ tmp |= ((*FBBase) >> 20) | 0x01;
+ PCIWRITEWORD(Dev, 0xE0, tmp);
+
+ return TRUE;
+ } else { /* Disable */
+ tmp &= ~0x0001;
+ PCIWRITEWORD(Dev, 0xE0, tmp);
+
+ return FALSE;
+ }
+ } else {
+ if ((tmp & 0x0001) && (tmp & 0xFFE)) {
+ *FBBase = (((unsigned long) tmp) & 0xFFE) << 20;
+ return TRUE;
+ } else
+ return FALSE;
+ }
+}
+
+/*
+ *
+ */
+static Bool
+P4M800FBDirectAccess(int scrnIndex, unsigned long *FBBase,
+ Bool Force, Bool ForceOn)
+{
+ PCIDEVVAR Dev = PCIDEVFROMPOS(0, 0, 3);
+ CARD16 tmp;
+
+ PCIREADWORD(Dev, 0xA0, &tmp);
+
+ if (Force) {
+ if (ForceOn) { /* We have to enable direct Access */
+ tmp &= ~0x0FFF;
+ tmp |= ((*FBBase) >> 20) | 0x01;
+ PCIWRITEWORD(Dev, 0xA0, tmp);
+ /* if we don't kill the machine right here right now then we can
+ return :) */
+ return TRUE;
+ } else { /* Disable */
+ tmp &= ~0x0001;
+ PCIWRITEWORD(Dev, 0xA0, tmp);
+
+ return FALSE;
+ }
+ } else {
+ if ((tmp & 0x0001) && (tmp & 0xFFE)) {
+ *FBBase = (((unsigned long) tmp) & 0xFFE) << 20;
+ return TRUE;
+ } else
+ return FALSE;
+ }
+}
+
+/*
+ *
+ */
+static Bool
+K8M800FBDirectAccess(int scrnIndex, unsigned long *FBBase,
+ Bool Force, Bool ForceOn)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ PCIDEVVAR Dev;
+ unsigned long FBBaseNew;
+ CARD8 tmp;
+
+ if (Force && *FBBase) /* just don't touch the FBBase */
+ return FALSE;
+
+ Dev = PCIDEVFROMPOS(0, 0, 3);
+
+ PCIREADBYTE(PCIDEVFROMPOS(0, 0, 3), 0x47, &tmp);
+ FBBaseNew = (((unsigned long) tmp) & 0xFF) << 24;
+
+
+ if (FBBaseNew > (pScrn->videoRam << 10)) {
+ *FBBase = FBBaseNew - (pScrn->videoRam << 10);
+ return TRUE;
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "%s: RamController has crap data: 0:0.3 0x47: %08X",
+ __func__, tmp);
+ return FALSE;
+ }
+}
+
+/*
+ *
+ */
void
ViaFBBaseGet(ScrnInfoPtr pScrn)
{
VIAPtr pVia = VIAPTR(pScrn);
+ unsigned long FBBase;
VIAFUNC(pScrn->scrnIndex);
- pVia->FrameBufferBase = 0;
+ /* PCI BAR */
+#ifdef XSERVER_LIBPCIACCESS
+ FBBase = pVia->PciInfo->regions[0].base_addr;
+#else
+ FBBase = pVia->PciInfo->memBase[0];
+#endif
+
+ if (pVia->FBDirectOption) {
+ if (pVia->FBDirect)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Forcing Direct FB Access On.\n");
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Forcing Direct FB Access Off.\n");
+ }
/* See if we have some magic */
switch (pVia->Host) {
case VIA_HOST_CLE266:
case VIA_HOST_KM400:
- {
- CARD16 tmp;
-
- PCIREADWORD(PCIDEVFROMPOS(0, 0, 0), 0xE0, &tmp);
- if (tmp & 0x0001)
- pVia->FrameBufferBase = (((unsigned long) tmp) & 0xFFE) << 20;
- }
+ pVia->FBDirect = CLE266FBDirectAccess(pScrn->scrnIndex, &FBBase,
+ pVia->FBDirectOption,
+ pVia->FBDirect);
break;
case VIA_HOST_K8M800:
- {
- CARD8 tmp;
-
- PCIREADBYTE(PCIDEVFROMPOS(0, 0, 3), 0x47, &tmp);
- pVia->FrameBufferBase = (((unsigned long) tmp) & 0xFF) << 24;
- if (pVia->FrameBufferBase > (pScrn->videoRam << 10))
- pVia->FrameBufferBase -= (pScrn->videoRam << 10);
- else
- pVia->FrameBufferBase = 0;
- }
+ pVia->FBDirect = K8M800FBDirectAccess(pScrn->scrnIndex, &FBBase,
+ pVia->FBDirectOption,
+ pVia->FBDirect);
break;
case VIA_HOST_P4M800:
case VIA_HOST_CN400:
@@ -852,33 +958,22 @@ ViaFBBaseGet(ScrnInfoPtr pScrn)
case VIA_HOST_P4M890:
case VIA_HOST_P4M900:
case VIA_HOST_VX800:
- {
- CARD16 tmp;
-
- PCIREADWORD(PCIDEVFROMPOS(0, 0, 3), 0xA0, &tmp);
- if (tmp & 0x0001)
- pVia->FrameBufferBase = (((unsigned long) tmp) & 0xFFE) << 20;
- }
+ pVia->FBDirect = P4M800FBDirectAccess(pScrn->scrnIndex, &FBBase,
+ pVia->FBDirectOption,
+ pVia->FBDirect);
break;
case VIA_HOST_K8M890: /* i would need to get my hands on one first */
default:
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"%s: Unhandled HostBridge.\n", __func__);
+ pVia->FBDirect = FALSE;
break;
}
- if (!pVia->FrameBufferBase) {
- pVia->FBDirectCPUAccess = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "%s: Failed to find direct FB access area.\n", __func__);
+ pVia->FrameBufferBase = FBBase;
- /* PCI BAR */
-#ifdef XSERVER_LIBPCIACCESS
- pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr;
-#else
- pVia->FrameBufferBase = pVia->PciInfo->memBase[0];
-#endif
-
- } else
- pVia->FBDirectCPUAccess = TRUE;
+ if (pVia->FBDirect)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct FB Access Enabled.\n");
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct FB Access Disabled.\n");
}