diff options
-rw-r--r-- | src/smi501_crtc.c | 50 | ||||
-rw-r--r-- | src/smi501_output.c | 67 | ||||
-rw-r--r-- | src/smi_501.c | 94 | ||||
-rw-r--r-- | src/smi_501.h | 10 | ||||
-rw-r--r-- | src/smi_driver.c | 37 |
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); } |