summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-10-21 19:41:55 -0200
committerPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-10-21 19:41:55 -0200
commitdd083c26de400cee8c67977f46cf90d048b22ff9 (patch)
treeb7e93be6b35861bd2136734546780905693226e6
parent197b4231586b9ada1c590a01b8dd7a5fcda936e6 (diff)
Use existing "Dualhead" option in MSOC.
If Dualhead is set, it will attempt to use setups that allow different outputs with different contents, instead of crt always cloning panel. Still not fully functional.
-rw-r--r--src/smi501_crtc.c50
-rw-r--r--src/smi501_output.c67
-rw-r--r--src/smi_501.c94
-rw-r--r--src/smi_501.h10
-rw-r--r--src/smi_driver.c37
5 files changed, 165 insertions, 93 deletions
diff --git a/src/smi501_crtc.c b/src/smi501_crtc.c
index 9802ba9..f7e1551 100644
--- a/src/smi501_crtc.c
+++ b/src/smi501_crtc.c
@@ -122,11 +122,14 @@ SMI501_CrtcAdjustFrame(xf86CrtcPtr crtc, int x, int y)
Base = (Base + 15) & ~15;
- if(crtc == crtcConf->crtc[0]){
+ if (crtc == crtcConf->crtc[0]) {
mode->panel_fb_address.f.address = Base >> 4;
mode->panel_fb_address.f.pending = 1;
WRITE_SCR(pSmi, PANEL_FB_ADDRESS, mode->panel_fb_address.value);
- }else{
+ }
+ else {
+ mode->crt_display_ctl.f.pixel = ((x * pSmi->Bpp) & 15) / pSmi->Bpp;
+ WRITE_SCR(pSmi, CRT_DISPLAY_CTL, mode->crt_display_ctl.value);
mode->crt_fb_address.f.address = Base >> 4;
mode->crt_fb_address.f.pending = 1;
WRITE_SCR(pSmi, CRT_FB_ADDRESS, mode->crt_fb_address.value);
@@ -277,10 +280,11 @@ SMI501_CrtcModeSet_crt(xf86CrtcPtr crtc,
/* 0: select panel - 1: select crt */
mode->crt_display_ctl.f.select = 1;
mode->crt_display_ctl.f.enable = 1;
+ mode->crt_display_ctl.f.timing = 1;
+ /* 0: show pixels - 1: blank */
+ mode->crt_display_ctl.f.blank = 0;
mode->crt_fb_address.f.mextern = 0; /* local memory */
- mode->crt_fb_address.f.timing = 1;
- mode->crt_display_ctl.f.blank = 0;
/* 0 means pulse high */
mode->crt_display_ctl.f.hsync = !(xf86mode->Flags & V_PHSYNC);
@@ -335,34 +339,36 @@ static SMICrtcPrivateRec SMI501_Crtc1Priv;
Bool
SMI501_CrtcPreInit(ScrnInfoPtr pScrn)
{
- xf86CrtcPtr crtc0=NULL;
- xf86CrtcPtr crtc1=NULL;
+ SMIPtr pSmi = SMIPTR(pScrn);
+ xf86CrtcPtr crtc0, crtc1;
ENTER();
/* CRTC0 is LCD */
SMI_CrtcFuncsInit_base(&SMI501_Crtc0Funcs, &SMI501_Crtc0Priv);
- SMI501_Crtc0Funcs.mode_set = SMI501_CrtcModeSet_lcd;
- SMI501_Crtc0Priv.adjust_frame = SMI501_CrtcAdjustFrame;
- SMI501_Crtc0Priv.video_init = SMI501_CrtcVideoInit_lcd;
- SMI501_Crtc0Priv.load_lut = SMI501_CrtcLoadLUT;
+ SMI501_Crtc0Funcs.mode_set = SMI501_CrtcModeSet_lcd;
+ SMI501_Crtc0Priv.adjust_frame = SMI501_CrtcAdjustFrame;
+ SMI501_Crtc0Priv.video_init = SMI501_CrtcVideoInit_lcd;
+ SMI501_Crtc0Priv.load_lut = SMI501_CrtcLoadLUT;
- crtc0=xf86CrtcCreate(pScrn,&SMI501_Crtc0Funcs);
- if(!crtc0)
+ crtc0 = xf86CrtcCreate(pScrn, &SMI501_Crtc0Funcs);
+ if (!crtc0)
RETURN(FALSE);
crtc0->driver_private = &SMI501_Crtc0Priv;
/* CRTC1 is CRT */
- SMI_CrtcFuncsInit_base(&SMI501_Crtc1Funcs, &SMI501_Crtc1Priv);
- SMI501_Crtc1Funcs.mode_set = SMI501_CrtcModeSet_crt;
- SMI501_Crtc1Priv.adjust_frame = SMI501_CrtcAdjustFrame;
- SMI501_Crtc1Priv.video_init = SMI501_CrtcVideoInit_crt;
- SMI501_Crtc1Priv.load_lut = SMI501_CrtcLoadLUT;
-
- crtc1=xf86CrtcCreate(pScrn,&SMI501_Crtc1Funcs);
- if(!crtc1)
- RETURN(FALSE);
- crtc1->driver_private = &SMI501_Crtc1Priv;
+ if (pSmi->Dualhead) {
+ SMI_CrtcFuncsInit_base(&SMI501_Crtc1Funcs, &SMI501_Crtc1Priv);
+ SMI501_Crtc1Funcs.mode_set = SMI501_CrtcModeSet_crt;
+ SMI501_Crtc1Priv.adjust_frame = SMI501_CrtcAdjustFrame;
+ SMI501_Crtc1Priv.video_init = SMI501_CrtcVideoInit_crt;
+ SMI501_Crtc1Priv.load_lut = SMI501_CrtcLoadLUT;
+
+ crtc1 = xf86CrtcCreate(pScrn, &SMI501_Crtc1Funcs);
+ if (!crtc1)
+ RETURN(FALSE);
+ crtc1->driver_private = &SMI501_Crtc1Priv;
+ }
RETURN(TRUE);
}
diff --git a/src/smi501_output.c b/src/smi501_output.c
index a0fd6db..8bd3db9 100644
--- a/src/smi501_output.c
+++ b/src/smi501_output.c
@@ -47,6 +47,31 @@ SMI501_OutputDPMS_lcd(xf86OutputPtr output, int dpms)
}
static void
+SMI501_OutputDPMS_panel(xf86OutputPtr output, int dpms)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ SMIPtr pSmi = SMIPTR(pScrn);
+ MSOCRegPtr mode = pSmi->mode;
+
+ ENTER();
+
+ mode->system_ctl.value = READ_SCR(pSmi, SYSTEM_CTL);
+ switch (dpms) {
+ case DPMSModeOn:
+ SMI501_PowerPanel(pScrn, mode, TRUE);
+ case DPMSModeStandby:
+ break;
+ case DPMSModeSuspend:
+ break;
+ case DPMSModeOff:
+ SMI501_PowerPanel(pScrn, mode, FALSE);
+ break;
+ }
+
+ LEAVE();
+}
+
+static void
SMI501_OutputDPMS_crt(xf86OutputPtr output, int dpms)
{
ScrnInfoPtr pScrn = output->scrn;
@@ -93,19 +118,19 @@ static xf86OutputFuncsRec SMI501_Output1Funcs;
Bool
SMI501_OutputPreInit(ScrnInfoPtr pScrn)
{
- xf86OutputPtr output0=NULL;
- xf86OutputPtr output1=NULL;
+ SMIPtr pSmi = SMIPTR(pScrn);
+ xf86OutputPtr output0, output1;
ENTER();
/* CRTC0 is LCD */
SMI_OutputFuncsInit_base(&SMI501_Output0Funcs);
- SMI501_Output0Funcs.dpms=SMI501_OutputDPMS_lcd;
- SMI501_Output0Funcs.get_modes=SMI_OutputGetModes_native;
- SMI501_Output0Funcs.detect = SMI_OutputDetect_lcd;
+ SMI501_Output0Funcs.dpms = SMI501_OutputDPMS_lcd;
+ SMI501_Output0Funcs.get_modes = SMI_OutputGetModes_native;
+ SMI501_Output0Funcs.detect = SMI_OutputDetect_lcd;
- output0=xf86OutputCreate(pScrn,&SMI501_Output0Funcs,"LVDS");
- if(!output0)
+ output0 = xf86OutputCreate(pScrn, &SMI501_Output0Funcs, "LVDS");
+ if (!output0)
RETURN(FALSE);
output0->possible_crtcs = 1 << 0;
@@ -114,20 +139,20 @@ SMI501_OutputPreInit(ScrnInfoPtr pScrn)
output0->doubleScanAllowed = FALSE;
/* CRTC1 is CRT */
- 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)
- RETURN(FALSE);
-
- output1->possible_crtcs = 1 << 1;
- output1->possible_clones = 0;
- output1->interlaceAllowed = FALSE;
- output1->doubleScanAllowed = FALSE;
-
+ if (pSmi->Dualhead) {
+ SMI_OutputFuncsInit_base(&SMI501_Output1Funcs);
+ SMI501_Output1Funcs.dpms = SMI501_OutputDPMS_crt;
+ SMI501_Output1Funcs.get_modes = SMI_OutputGetModes_native;
+
+ output1 = xf86OutputCreate(pScrn, &SMI501_Output1Funcs, "VGA");
+ if (!output1)
+ RETURN(FALSE);
+
+ output1->possible_crtcs = 1 << 1;
+ output1->possible_clones = 0;
+ output1->interlaceAllowed = FALSE;
+ output1->doubleScanAllowed = FALSE;
+ }
RETURN(TRUE);
}
diff --git a/src/smi_501.c b/src/smi_501.c
index f973ed7..26c8798 100644
--- a/src/smi_501.c
+++ b/src/smi_501.c
@@ -206,12 +206,13 @@ SMI501_HWInit(ScrnInfoPtr pScrn)
break;
}
- /* By default, crt clones panel */
- mode->crt_display_ctl.f.enable = 1;
- /* 0: select panel - 1: select crt */
- mode->crt_display_ctl.f.select = 0;
- /* FIXME correct? */
- mode->crt_display_ctl.f.timing = 0;
+ if (!pSmi->Dualhead) {
+ /* By default, crt clones panel */
+ mode->crt_display_ctl.f.enable = 0;
+ /* 0: select panel - 1: select crt */
+ mode->crt_display_ctl.f.select = 0;
+ mode->crt_display_ctl.f.timing = 0;
+ }
SMI501_WriteMode_common(pScrn, mode);
@@ -255,7 +256,8 @@ SMI501_WriteMode_common(ScrnInfoPtr pScrn, MSOCRegPtr mode)
mode->system_ctl.f.retry = pSmi->PCIRetry != FALSE;
WRITE_SCR(pSmi, SYSTEM_CTL, mode->system_ctl.value);
- WRITE_SCR(pSmi, CRT_DISPLAY_CTL, mode->crt_display_ctl.value);
+ if (!pSmi->Dualhead)
+ WRITE_SCR(pSmi, CRT_DISPLAY_CTL, mode->crt_display_ctl.value);
}
void
@@ -293,26 +295,6 @@ SMI501_WriteMode_lcd(ScrnInfoPtr pScrn, MSOCRegPtr mode)
WRITE_SCR(pSmi, PANEL_VTOTAL, mode->panel_vtotal.value);
WRITE_SCR(pSmi, PANEL_VSYNC, mode->panel_vsync.value);
WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
-
- /* Power up sequence for panel */
- mode->panel_display_ctl.f.vdd = 1;
- WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
- SMI501_WaitVSync(pSmi, 4);
-
- mode->panel_display_ctl.f.signal = 1;
- WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
- SMI501_WaitVSync(pSmi, 4);
-
- mode->panel_display_ctl.f.bias = 1;
- WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
- SMI501_WaitVSync(pSmi, 4);
-
- mode->panel_display_ctl.f.fp = 1;
- WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
- SMI501_WaitVSync(pSmi, 4);
-
- /* Turn CRT on */
- SMI501_DisplayPowerManagementSet(pScrn, DPMSModeOn, 0);
}
void
@@ -340,6 +322,64 @@ SMI501_WriteMode_crt(ScrnInfoPtr pScrn, MSOCRegPtr mode)
WRITE_SCR(pSmi, CRT_DISPLAY_CTL, mode->crt_display_ctl.value);
}
+void
+SMI501_WriteMode(ScrnInfoPtr pScrn, MSOCRegPtr restore)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ SMI501_WriteMode_common(pScrn, restore);
+ SMI501_WriteMode_lcd(pScrn, restore);
+ if (pSmi->Dualhead)
+ SMI501_WriteMode_crt(pScrn, restore);
+}
+
+void
+SMI501_PowerPanel(ScrnInfoPtr pScrn, MSOCRegPtr mode, Bool on)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ if (on != FALSE) {
+ mode->panel_display_ctl.f.vdd = 1;
+ WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
+ SMI501_WaitVSync(pSmi, 4);
+
+ mode->panel_display_ctl.f.signal = 1;
+ WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
+ SMI501_WaitVSync(pSmi, 4);
+
+ mode->panel_display_ctl.f.bias = 1;
+ WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
+ SMI501_WaitVSync(pSmi, 4);
+
+ mode->panel_display_ctl.f.fp = 1;
+ WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
+ SMI501_WaitVSync(pSmi, 4);
+ }
+ else {
+ mode->panel_display_ctl.f.fp = 0;
+ WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
+ SMI501_WaitVSync(pSmi, 4);
+
+ mode->panel_display_ctl.f.bias = 0;
+ WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
+ SMI501_WaitVSync(pSmi, 4);
+
+ mode->panel_display_ctl.f.signal = 0;
+ WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
+ SMI501_WaitVSync(pSmi, 4);
+
+ mode->panel_display_ctl.f.vdd = 0;
+ WRITE_SCR(pSmi, PANEL_DISPLAY_CTL, mode->panel_display_ctl.value);
+ SMI501_WaitVSync(pSmi, 4);
+ }
+}
+
+void
+SMI501_PowerCrt(ScrnInfoPtr pScrn, MSOCRegPtr mode, Bool onoff)
+{
+ SMI501_DisplayPowerManagementSet(pScrn, onoff ? DPMSModeOn : DPMSModeOff, 0);
+}
+
static char *
format_integer_base2(int32_t word)
{
diff --git a/src/smi_501.h b/src/smi_501.h
index 1d68ebe..1050a3c 100644
--- a/src/smi_501.h
+++ b/src/smi_501.h
@@ -634,6 +634,11 @@ typedef struct _MSOCRegRec {
* 2:2 CRT Graphics Plane Enable.
* 0: Disable CRT Graphics plane.
* 1: Enable CRT Graphics plane.
+ * 3:3 Enable Gamma Control. Gamma control can be enabled
+ * only in RGB 5:6:5 and RGB 8:8:8 modes.
+ * 0: Disable gamma control.
+ * 1: Enable gamma control.
+ * 4:7 Starting Pixel Number for Smooth Pixel Panning.
* 8:8 Enable CRT Timing.
* 0: Disable CRT timing.
* 1: Enable CRT timing.
@@ -655,7 +660,8 @@ typedef struct _MSOCRegRec {
struct {
int32_t format : bits( 0, 1);
int32_t enable : bits( 2, 2);
- int32_t u0 : bits( 3, 7);
+ int32_t gamma : bits( 3, 3);
+ int32_t pixel : bits( 4, 7);
int32_t timing : bits( 8, 8);
int32_t select : bits( 9, 9);
int32_t blank : bits(10, 10);
@@ -807,6 +813,8 @@ Bool SMI501_HWInit(ScrnInfoPtr pScrn);
void SMI501_WriteMode_common(ScrnInfoPtr pScrn, MSOCRegPtr mode);
void SMI501_WriteMode_lcd(ScrnInfoPtr pScrn, MSOCRegPtr mode);
void SMI501_WriteMode_crt(ScrnInfoPtr pScrn, MSOCRegPtr mode);
+void SMI501_WriteMode(ScrnInfoPtr pScrn, MSOCRegPtr restore);
+void SMI501_PowerPanel(ScrnInfoPtr pScrn, MSOCRegPtr mode, Bool on);
/* smi501_crtc.c */
Bool SMI501_CrtcPreInit(ScrnInfoPtr pScrn);
diff --git a/src/smi_driver.c b/src/smi_driver.c
index 4c55f41..6b8eab7 100644
--- a/src/smi_driver.c
+++ b/src/smi_driver.c
@@ -190,7 +190,7 @@ static const OptionInfoRec SMIOptions[] =
/* end CZ */
{ OPTION_USEBIOS, "UseBIOS", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_ZOOMONLCD, "ZoomOnLCD", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_DUALHEAD, "Dualhead", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_DUALHEAD, "Dualhead", OPTV_BOOLEAN, {0}, TRUE },
{ OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE },
{ OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_USE_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE },
@@ -839,29 +839,15 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags)
pSmi->Dualhead = FALSE;
- if (IS_MSOC(pSmi)) {
- pSmi->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
+ from = X_DEFAULT;
+ if (xf86GetOptValBool(pSmi->Options, OPTION_DUALHEAD, &pSmi->Dualhead))
+ from = X_CONFIG;
- /* FIXME this assumes the first head is always lcd and second
- * always crt */
- pSmi->IsSecondary = FALSE;
+ if (IS_MSOC(pSmi)) {
pSmi->lcd = TRUE;
-
- if (xf86IsEntityShared(pSmi->pEnt->index)) {
- pSmi->Dualhead = TRUE;
- if (xf86IsPrimInitDone(pSmi->pEnt->index)) {
- pSmi->IsSecondary = TRUE;
- pSmi->lcd = FALSE;
- }
- else
- xf86SetPrimInitDone(pSmi->pEnt->index);
- }
+ pSmi->IsSecondary = FALSE;
}
- else {
- if (SMI_LYNXM_SERIES(pSmi->Chipset) &&
- xf86ReturnOptValBool(pSmi->Options, OPTION_DUALHEAD, FALSE))
- pSmi->Dualhead = TRUE;
-
+ else if (SMI_LYNXM_SERIES(pSmi->Chipset)) {
/* tweak options for dualhead */
if (pSmi->Dualhead) {
pSmi->useBIOS = FALSE;
@@ -883,6 +869,8 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags)
xf86ErrorFVerb(VERBLEV, "\tSMI_PreInit vgaCRIndex=%x, vgaIOBase=%x, "
"MMIOBase=%p\n", vgaCRIndex, vgaIOBase, hwp->MMIOBase);
}
+ xf86DrvMsg(pScrn->scrnIndex, from, "Dual head %sabled\n",
+ pSmi->PCIBurst ? "en" : "dis");
SMI_MapMmio(pScrn);
SMI_DetectMem(pScrn);
@@ -1097,8 +1085,11 @@ SMI_LeaveVT(int scrnIndex, int flags)
if (!IS_MSOC(pSmi)) {
vgaHWPtr hwp = VGAHWPTR(pScrn);
+
SMILynx_WriteMode(pScrn, &hwp->SavedReg, pSmi->save);
- }
+ }
+ else
+ SMI501_WriteMode(pScrn, pSmi->save);
SMI_UnmapMem(pScrn);
@@ -1831,6 +1822,8 @@ SMI_CloseScreen(int scrnIndex, ScreenPtr pScreen)
SMILynx_WriteMode(pScrn, &hwp->SavedReg, pSmi->save);
vgaHWLock(hwp);
}
+ else
+ SMI501_WriteMode(pScrn, pSmi->save);
SMI_UnmapMem(pScrn);
}