summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}