summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-11-06 16:35:15 -0200
committerPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-11-06 16:35:15 -0200
commit98969b1b96244085ff5b0c76d2a463c1e436bcfa (patch)
treefae6caa2919481717cdcd922011a41677369d68c
parent87a3cc0652666c1796fd56f00810834193f3eca0 (diff)
Use the CRT Monitor Detect MSOC register.
Probably I misunderstood the usage of this register, as it will always show the same value, regardless of having a crt connected to the "vga" port or not. Only difference is that while the detect bit is set, the crt will be blank. This patch should be more of a placeholder for a possible correction, but it should not cause any side effects, unless the data field can be zero on a valid situation. In my test computer, this field, in base 2 is always 1000000010000100, what doesn't really look like data in rgb 8:8:8...
-rw-r--r--src/smi501_output.c27
-rw-r--r--src/smi_501.c3
-rw-r--r--src/smi_501.h24
3 files changed, 51 insertions, 3 deletions
diff --git a/src/smi501_output.c b/src/smi501_output.c
index 7a22955..4652344 100644
--- a/src/smi501_output.c
+++ b/src/smi501_output.c
@@ -97,9 +97,33 @@ SMI501_OutputDPMS_crt(xf86OutputPtr output, int dpms)
static xf86OutputStatus
SMI501_OutputDetect_crt(xf86OutputPtr output)
{
+ ScrnInfoPtr pScrn = output->scrn;
+ SMIPtr pSmi = SMIPTR(pScrn);
+ MSOCRegPtr mode = pSmi->mode;
+ xf86OutputStatus status;
+
ENTER();
- RETURN(XF86OutputStatusDisconnected);
+ mode->crt_detect.value = READ_SCR(pSmi, CRT_DETECT);
+ mode->crt_detect.f.enable = 1;
+ WRITE_SCR(pSmi, CRT_DETECT, mode->crt_detect.value);
+ SMI501_WaitVSync(pSmi, 1);
+
+ mode->crt_detect.value = READ_SCR(pSmi, CRT_DETECT);
+
+ /* FIXME This appears to have a fixed value, whatever I do, and
+ * the binary pattern is 1000000010000100
+ * regardless of crt being connected or not, so maybe this is
+ * just telling there is a VGA output?
+ */
+ status = mode->crt_detect.f.data ?
+ XF86OutputStatusConnected : XF86OutputStatusUnknown;
+
+ mode->crt_detect.f.enable = 0;
+ WRITE_SCR(pSmi, CRT_DETECT, mode->crt_detect.value);
+ SMI501_WaitVSync(pSmi, 1);
+
+ RETURN(status);
}
static xf86OutputFuncsRec SMI501_Output0Funcs;
@@ -133,6 +157,7 @@ SMI501_OutputPreInit(ScrnInfoPtr pScrn)
SMI_OutputFuncsInit_base(&SMI501_Output1Funcs);
SMI501_Output1Funcs.dpms = SMI501_OutputDPMS_crt;
SMI501_Output1Funcs.get_modes = SMI_OutputGetModes_native;
+ SMI501_Output1Funcs.detect = SMI501_OutputDetect_crt;
output1 = xf86OutputCreate(pScrn, &SMI501_Output1Funcs, "VGA");
if (!output1)
diff --git a/src/smi_501.c b/src/smi_501.c
index 555dfd8..2f993ca 100644
--- a/src/smi_501.c
+++ b/src/smi_501.c
@@ -50,7 +50,6 @@ authorization from The XFree86 Project or Silicon Motion.
static char *format_integer_base2(int32_t word);
static void SMI501_SetClock(SMIPtr pSmi, int32_t port,
int32_t pll, int32_t value);
-static void SMI501_WaitVSync(SMIPtr pSmi, int vsync_count);
/*
@@ -517,7 +516,7 @@ SMI501_PrintRegs(ScrnInfoPtr pScrn)
format_integer_base2(READ_SCR(pSmi, i)));
}
-static void
+void
SMI501_WaitVSync(SMIPtr pSmi, int vsync_count)
{
int32_t status, timeout;
diff --git a/src/smi_501.h b/src/smi_501.h
index ddee5c5..a9c9436 100644
--- a/src/smi_501.h
+++ b/src/smi_501.h
@@ -788,8 +788,31 @@ typedef struct _MSOCRegRec {
} f;
int32_t value;
} crt_vsync;
+
+#define CRT_DETECT 0x080224
+ /* CRT MONITOR DETECT
+ * Read/Write MMIO_base + 0x080224
+ * Power-on Default Undefined
+ *
+ * 0:23 Monitor Detect Data in RGB 8:8:8. This field is read-only.
+ * 24:24 Monitor Detect Enable.
+ * 0: Disable.
+ * 1: Enable.
+ * 25:25 Monitor Detect Read Back.
+ * 1: All R, G, and B voltages are greater than 0.325 V.
+ * 0: All R, G, and B voltages are less than or equal to 0.325 V.
+ */
+ union {
+ struct {
+ int32_t data : bits( 0, 23);
+ int32_t enable : bits(24, 24);
+ int32_t voltage : bits(25, 25);
+ } f;
+ int32_t value;
+ } crt_detect;
} MSOCRegRec, *MSOCRegPtr;
+
#define PANEL_PALETTE 0x080400
#define CRT_PALETTE 0x080c00
@@ -806,6 +829,7 @@ double SMI501_FindClock(double clock, int max_divider, Bool has1xclck,
int32_t *x2_divider, int32_t *x2_shift);
double SMI501_FindPLLClock(double clock, int32_t *m, int32_t *n,
int32_t *xclck);
+void SMI501_WaitVSync(SMIPtr pSmi, int vsync_count);
/* Initialize the CRTC-independent hardware registers */
Bool SMI501_HWInit(ScrnInfoPtr pScrn);