File u_vesa-Add-VBEDPMSGetCapabilities-VBEDPMSGet.patch of Package xorg-x11-server
From: Egbert Eich <eich@suse.de>
Date: Thu Sep 24 12:38:13 2015 +0200
Subject: [PATCH]vesa: Add VBEDPMSGetCapabilities & VBEDPMSGet()
Patch-mainline: to be upstreamed
References: bnc#947356
Signed-off-by: Egbert Eich <eich@suse.com>
Signed-off-by: Egbert Eich <eich@suse.de>
---
hw/xfree86/vbe/vbe.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++-
hw/xfree86/vbe/vbe.h | 3 ++
2 files changed, 149 insertions(+), 1 deletion(-)
diff --git a/hw/xfree86/vbe/vbe.c b/hw/xfree86/vbe/vbe.c
index 39f0cef..179d4c6 100644
--- a/hw/xfree86/vbe/vbe.c
+++ b/hw/xfree86/vbe/vbe.c
@@ -20,6 +20,28 @@
#include "vbe.h"
#include <X11/extensions/dpmsconst.h>
+#ifdef DEBUG
+#define LOG_RESULT(x) { \
+ xf86DrvMsg(x->pInt10->pScrn->scrnIndex, X_INFO, "%s () = %s\n", \
+ __FUNCTION__, \
+ R16(x->pInt10->ax) == 0x4f ? "success" : "failure"); }
+
+#define LOG_SUCCESS(x) { \
+ xf86DrvMsg(x->pInt10->pScrn->scrnIndex, X_INFO, "%s () = success\n", \
+ __FUNCTION__); }
+#define LOG_FAILURE(x) { \
+ xf86DrvMsg(x->pInt10->pScrn->scrnIndex, X_INFO, "%s () = failure\n", \
+ __FUNCTION__); }
+#define LOG_VBE(x,fmt, args...) { \
+ xf86DrvMsg(x->pInt10->pScrn->scrnIndex, X_INFO, "%s " fmt, __FUNCTION__, \
+ ##args); }
+#else
+#define LOG_RESULT(x) {}
+#define LOG_SUCCESS(x) {}
+#define LOG_FAILURE(x) {}
+#define LOG_VBE(x,fmt, args...) {}
+#endif
+
#define VERSION(x) VBE_VERSION_MAJOR(x),VBE_VERSION_MINOR(x)
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
@@ -187,6 +209,7 @@ vbeProbeDDC(vbeInfoPtr pVbe)
if (pVbe->ddc != DDC_UNCHECKED)
return TRUE;
+ LOG_VBE(pVbe,"()\n");
pVbe->pInt10->ax = 0x4F15;
pVbe->pInt10->bx = 0;
pVbe->pInt10->cx = 0;
@@ -195,6 +218,7 @@ vbeProbeDDC(vbeInfoPtr pVbe)
pVbe->pInt10->num = 0x10;
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
xf86DrvMsgVerb(screen, X_INFO, 3, "VESA VBE DDC not supported\n");
@@ -285,6 +309,7 @@ vbeReadEDID(vbeInfoPtr pVbe)
memset(page, 0, sizeof(vbeInfoPtr));
strcpy(page, vbeVersionString);
+ LOG_VBE(pVbe, "()\n");
pVbe->pInt10->ax = 0x4F15;
pVbe->pInt10->bx = 0x01;
pVbe->pInt10->cx = 0;
@@ -294,6 +319,7 @@ vbeReadEDID(vbeInfoPtr pVbe)
pVbe->pInt10->num = 0x10;
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
xf86DrvMsgVerb(screen, X_INFO, 3, "VESA VBE DDC invalid\n");
@@ -365,11 +391,13 @@ VBEGetVBEInfo(vbeInfoPtr pVbe)
((char *) pVbe->memory)[2] = 'E';
((char *) pVbe->memory)[3] = '2';
+ LOG_VBE(pVbe, "()\n");
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f00;
pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if (R16(pVbe->pInt10->ax) != 0x4f)
return NULL;
@@ -458,6 +486,7 @@ VBESetVBEMode(vbeInfoPtr pVbe, int mode, VbeCRTCInfoBlock * block)
Output: AX = Status
(All other registers are preserved)
*/
+ LOG_VBE(pVbe, "(mode=0x%x)\n", mode);
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f02;
pVbe->pInt10->bx = mode;
@@ -471,6 +500,7 @@ VBESetVBEMode(vbeInfoPtr pVbe, int mode, VbeCRTCInfoBlock * block)
pVbe->pInt10->bx &= ~(1 << 11);
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
return (R16(pVbe->pInt10->ax) == 0x4f);
}
@@ -488,10 +518,12 @@ VBEGetVBEMode(vbeInfoPtr pVbe, int *mode)
BX := Current video mode
(All other registers are preserved)
*/
+ LOG_VBE(pVbe, "()\n");
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f03;
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if (R16(pVbe->pInt10->ax) == 0x4f) {
*mode = R16(pVbe->pInt10->bx);
@@ -521,12 +553,14 @@ VBEGetModeInfo(vbeInfoPtr pVbe, int mode)
AX := status
(All other registers are preserved)
*/
+ LOG_VBE(pVbe, "(mode = 0x%x)\n",mode);
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f01;
pVbe->pInt10->cx = mode;
pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if (R16(pVbe->pInt10->ax) != 0x4f)
return NULL;
@@ -586,6 +620,7 @@ VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function,
(All other registers are preserved)
*/
+ LOG_VBE(pVbe, "(function = %d)", function);
if ((pVbe->version & 0xff00) > 0x100) {
int screen = pVbe->pInt10->pScrn->scrnIndex;
@@ -597,9 +632,9 @@ VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function,
pVbe->pInt10->dx = 0;
pVbe->pInt10->cx = 0x000f;
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if (R16(pVbe->pInt10->ax) != 0x4f)
return FALSE;
-
if (function == MODE_SAVE) {
int npages = (R16(pVbe->pInt10->bx) * 64) / 4096 + 1;
@@ -618,6 +653,7 @@ VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function,
if (!*memory)
return FALSE;
+
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f04;
switch (function) {
@@ -635,6 +671,7 @@ VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function,
pVbe->pInt10->es = SEG_ADDR(*real_mode_pages);
pVbe->pInt10->bx = SEG_OFF(*real_mode_pages);
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
return (R16(pVbe->pInt10->ax) == 0x4f);
}
@@ -652,11 +689,13 @@ VBEBankSwitch(vbeInfoPtr pVbe, unsigned int iBank, int window)
Output:
*/
+ LOG_VBE(pVbe, "(bank = %d window = %d)\n", iBank, window);
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f05;
pVbe->pInt10->bx = window;
pVbe->pInt10->dx = iBank;
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if (R16(pVbe->pInt10->ax) != 0x4f)
return FALSE;
@@ -690,12 +729,14 @@ VBESetGetLogicalScanlineLength(vbeInfoPtr pVbe, vbeScanwidthCommand command,
DX := Maximum Number of Scan Lines
*/
+ LOG_VBE(pVbe,"(width = %i)\n",width);
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f06;
pVbe->pInt10->bx = command;
if (command == SCANWID_SET || command == SCANWID_SET_BYTES)
pVbe->pInt10->cx = width;
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if (R16(pVbe->pInt10->ax) != 0x4f)
return FALSE;
@@ -715,12 +756,15 @@ VBESetGetLogicalScanlineLength(vbeInfoPtr pVbe, vbeScanwidthCommand command,
Bool
VBESetDisplayStart(vbeInfoPtr pVbe, int x, int y, Bool wait_retrace)
{
+ LOG_VBE(pVbe, "(x = %i y = %i wait_retrace = %s)\n",
+ x, y, wait_retrace ? "y" : "n");
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f07;
pVbe->pInt10->bx = wait_retrace ? 0x80 : 0x00;
pVbe->pInt10->cx = x;
pVbe->pInt10->dx = y;
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if (R16(pVbe->pInt10->ax) != 0x4f)
return FALSE;
@@ -731,10 +775,12 @@ VBESetDisplayStart(vbeInfoPtr pVbe, int x, int y, Bool wait_retrace)
Bool
VBEGetDisplayStart(vbeInfoPtr pVbe, int *x, int *y)
{
+ LOG_VBE(pVbe, "()\n");
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f07;
pVbe->pInt10->bx = 0x01;
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if (R16(pVbe->pInt10->ax) != 0x4f)
return FALSE;
@@ -761,6 +807,7 @@ VBESetGetDACPaletteFormat(vbeInfoPtr pVbe, int bits)
BH := Current number of bits of color per primary
*/
+ LOG_VBE(pVbe, "(bits = %d)\n", bits);
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f08;
if (!bits)
@@ -768,6 +815,7 @@ VBESetGetDACPaletteFormat(vbeInfoPtr pVbe, int bits)
else
pVbe->pInt10->bx = (bits & 0x00ff) << 8;
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if (R16(pVbe->pInt10->ax) != 0x4f)
return 0;
@@ -805,6 +853,8 @@ VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num,
DS := Selector for memory mapped registers
*/
+ LOG_VBE(pVbe,"(%s first = %i num = %i wait_retrace = %s)\n",
+ set ? "set" : "get", first, num, wait_retrace ? "y" : "n");
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f09;
if (!secondary)
@@ -818,6 +868,7 @@ VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num,
if (set)
memcpy(pVbe->memory, data, num * sizeof(CARD32));
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if (R16(pVbe->pInt10->ax) != 0x4f)
return NULL;
@@ -850,11 +901,13 @@ VBEGetVBEpmi(vbeInfoPtr pVbe)
(All other registers are preserved)
*/
+ LOG_VBE(pVbe, "()\n");
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f0a;
pVbe->pInt10->bx = 0;
pVbe->pInt10->di = 0;
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if (R16(pVbe->pInt10->ax) != 0x4f)
return NULL;
@@ -967,6 +1020,7 @@ VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int clock)
AX := VBE Return Status
ECX := Closest pixel clock
*/
+ LOG_VBE(pVbe,"(mode = 0x%x clock = %d)\n", mode, clock);
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f0b;
@@ -974,6 +1028,7 @@ VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int clock)
pVbe->pInt10->cx = clock;
pVbe->pInt10->dx = mode;
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if (R16(pVbe->pInt10->ax) != 0x4f)
return 0;
@@ -981,6 +1036,92 @@ VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int clock)
return pVbe->pInt10->cx;
}
+int
+VBEDPMSGetCapabilities(vbeInfoPtr pVbe, int *cap)
+{
+ /*
+ Input:
+ AX := 4F10h DPMS
+ BL := 00h Get VBE/PM Capabilities
+ CX := 00h
+ ES:DI := 0
+
+ Output:
+ AX := Status
+ BH := Power Saving State 1=supported, 0=unsupported
+ Bit 0: stand by, Bit 1: suspend, Bit 2: off Bit 3: reduced
+ */
+ LOG_VBE(pVbe, "()\n");
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f10;
+ pVbe->pInt10->bx = 0x0;
+ pVbe->pInt10->cx = 0x0;
+ pVbe->pInt10->es = pVbe->pInt10->di = 0;
+ xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
+
+ if ((R16(pVbe->pInt10->ax) != 0x4f))
+ return FALSE;
+
+ xf86DrvMsgVerb(pVbe->pInt10->pScrn->scrnIndex, X_INFO, 7,
+ "DPMSGetCapabilities: 0x%x\n,",
+ pVbe->pInt10->bx);
+ *cap = 1 << DPMSModeOn; /* always supported */
+ if (pVbe->pInt10->bx & 0x100)
+ *cap |= 1 << DPMSModeStandby;
+ if (pVbe->pInt10->bx & 0x200)
+ *cap |= 1 << DPMSModeSuspend;
+ if (pVbe->pInt10->bx & 0x200)
+ *cap |= 1 << DPMSModeOff;
+
+ return TRUE;
+}
+
+int
+VBEDPMSGet(vbeInfoPtr pVbe, int *mode)
+{
+ /*
+ Input:
+ AX := 4F10h DPMS
+ BL := 02h Get Display Power State
+ CX := 00h
+
+ Output:
+ AX := VBE Return Status
+ BH := Power State currently set
+ */
+ LOG_VBE(pVbe, "()\n");
+ pVbe->pInt10->ax = 0x4f10;
+ pVbe->pInt10->bx = 0x2;
+ pVbe->pInt10->cx = 0x0;
+ xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
+ if ((R16(pVbe->pInt10->ax) != 0x4f))
+ return FALSE;
+
+ xf86DrvMsgVerb(pVbe->pInt10->pScrn->scrnIndex, X_INFO, 7,
+ "DPMSGetState: 0x%x\n,",
+ pVbe->pInt10->bx);
+ switch (pVbe->pInt10->bx >> 4) {
+ case 0:
+ *mode = DPMSModeOn;
+ break;
+ case 1:
+ *mode = DPMSModeStandby;
+ break;
+ case 2:
+ *mode = DPMSModeSuspend;
+ break;
+ case 4:
+ *mode = DPMSModeOff;
+ break;
+ case 8:
+ *mode = DPMSModeOn;
+ break;
+ }
+ return TRUE;
+}
+
Bool
VBEDPMSSet(vbeInfoPtr pVbe, int mode)
{
@@ -994,6 +1135,7 @@ VBEDPMSSet(vbeInfoPtr pVbe, int mode)
AX := VBE Return Status
*/
+ LOG_VBE(pVbe, "(mode = %d)\n", mode);
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x4f10;
pVbe->pInt10->bx = 0x01;
@@ -1011,6 +1153,7 @@ VBEDPMSSet(vbeInfoPtr pVbe, int mode)
break;
}
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
return (R16(pVbe->pInt10->ax) == 0x4f);
}
@@ -1059,6 +1202,7 @@ VBEReadPanelID(vbeInfoPtr pVbe)
void *tmp = NULL;
int screen = pVbe->pInt10->pScrn->scrnIndex;
+ LOG_VBE(pVbe, "()\n");
pVbe->pInt10->ax = 0x4F11;
pVbe->pInt10->bx = 0x01;
pVbe->pInt10->cx = 0;
@@ -1068,6 +1212,7 @@ VBEReadPanelID(vbeInfoPtr pVbe)
pVbe->pInt10->num = 0x10;
xf86ExecX86int10(pVbe->pInt10);
+ LOG_RESULT(pVbe);
if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
xf86DrvMsgVerb(screen, X_INFO, 3, "VESA VBE PanelID invalid\n");
diff --git a/hw/xfree86/vbe/vbe.h b/hw/xfree86/vbe/vbe.h
index 3907c53..9b37f46 100644
--- a/hw/xfree86/vbe/vbe.h
+++ b/hw/xfree86/vbe/vbe.h
@@ -336,6 +336,9 @@ VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeSaveRestorePtr vbe_sr,
extern _X_EXPORT int VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int Clock);
extern _X_EXPORT Bool VBEDPMSSet(vbeInfoPtr pVbe, int mode);
+#define VBE_HAVE_DPMS_GET_CAPABILITIES
+extern _X_EXPORT Bool VBEDPMSGetCapabilities(vbeInfoPtr pVbe, int *cap);
+extern _X_EXPORT Bool VBEDPMSGet(vbeInfoPtr pVbe, int *mode);
struct vbePanelID {
short hsize;