forked from pool/xorg-x11-server
Stefan Dirsch
d1a7e7ee12
* Linux kernel v6.9 has changed the symlink to point to the parent device. This breaks fbdev_open() detection logic. Change it to use the subsystem symlink instead which will remain stable (gitlab xserver issue#1714) OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xorg-x11-server?expand=0&rev=889
433 lines
13 KiB
Diff
433 lines
13 KiB
Diff
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/in10/vbe.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++-
|
|
hw/xfree86/in10/vbe.h | 3 ++
|
|
2 files changed, 149 insertions(+), 1 deletion(-)
|
|
|
|
Index: xorg-server-21.1.0/hw/xfree86/int10/vbe.c
|
|
===================================================================
|
|
--- xorg-server-21.1.0.orig/hw/xfree86/int10/vbe.c
|
|
+++ xorg-server-21.1.0/hw/xfree86/int10/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,
|
|
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,
|
|
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, vbeSaveR
|
|
(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, vbeSaveR
|
|
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, vbeSaveR
|
|
|
|
if (!*memory)
|
|
return FALSE;
|
|
+
|
|
pVbe->pInt10->num = 0x10;
|
|
pVbe->pInt10->ax = 0x4f04;
|
|
switch (function) {
|
|
@@ -635,6 +671,7 @@ VBESaveRestore(vbeInfoPtr pVbe, vbeSaveR
|
|
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
|
|
|
|
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(vbeInfoPt
|
|
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(vbeInfoPt
|
|
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
|
|
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 pVb
|
|
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 pVb
|
|
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, Bo
|
|
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, Bo
|
|
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 mo
|
|
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 mo
|
|
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 mo
|
|
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");
|
|
Index: xorg-server-21.1.0/hw/xfree86/int10/vbe.h
|
|
===================================================================
|
|
--- xorg-server-21.1.0.orig/hw/xfree86/int10/vbe.h
|
|
+++ xorg-server-21.1.0/hw/xfree86/int10/vbe.h
|
|
@@ -335,6 +335,9 @@ VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeS
|
|
|
|
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;
|