summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@gmail.com>2008-12-21 19:37:14 +0100
committerPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-12-21 19:22:16 -0200
commit2b3fa385a6da4be5ad6719dd115834b96d1ea3e3 (patch)
tree30a66389828ff41db9e49070aa558deb7aeca656
parent75b1c309f1418d70e8cf112744ff95f372d4ef75 (diff)
Add a CRTC/Output implementation using BIOS for modesetting.
After the RandR1.2 implementation the "UseBIOS" option wasn't actually programming the hardware through VESA BIOS, this brings back that functionality.
-rw-r--r--src/smilynx_crtc.c98
-rw-r--r--src/smilynx_hw.c160
-rw-r--r--src/smilynx_output.c51
3 files changed, 220 insertions, 89 deletions
diff --git a/src/smilynx_crtc.c b/src/smilynx_crtc.c
index 08d798e..616cb81 100644
--- a/src/smilynx_crtc.c
+++ b/src/smilynx_crtc.c
@@ -524,6 +524,90 @@ SMILynx_CrtcModeSet_lcd(xf86CrtcPtr crtc,
}
static void
+SMILynx_CrtcModeSet_bios(xf86CrtcPtr crtc,
+ DisplayModePtr mode,
+ DisplayModePtr adjusted_mode,
+ int x, int y)
+{
+ ScrnInfoPtr pScrn=crtc->scrn;
+ SMIPtr pSmi = SMIPTR(pScrn);
+ SMIRegPtr reg = pSmi->mode;
+ int i;
+ CARD8 tmp;
+
+ ENTER();
+
+ /* Find the INT 10 mode number */
+ {
+ static struct {
+ int x, y, bpp;
+ CARD16 mode;
+ } modeTable[] =
+ {
+ { 640, 480, 8, 0x50 },
+ { 640, 480, 16, 0x52 },
+ { 640, 480, 24, 0x53 },
+ { 640, 480, 32, 0x54 },
+ { 800, 480, 8, 0x4A },
+ { 800, 480, 16, 0x4C },
+ { 800, 480, 24, 0x4D },
+ { 800, 600, 8, 0x55 },
+ { 800, 600, 16, 0x57 },
+ { 800, 600, 24, 0x58 },
+ { 800, 600, 32, 0x59 },
+ { 1024, 768, 8, 0x60 },
+ { 1024, 768, 16, 0x62 },
+ { 1024, 768, 24, 0x63 },
+ { 1024, 768, 32, 0x64 },
+ { 1280, 1024, 8, 0x65 },
+ { 1280, 1024, 16, 0x67 },
+ { 1280, 1024, 24, 0x68 },
+ { 1280, 1024, 32, 0x69 },
+ };
+
+ reg->mode = 0;
+ for (i = 0; i < sizeof(modeTable) / sizeof(modeTable[0]); i++) {
+ if ((modeTable[i].x == mode->HDisplay) &&
+ (modeTable[i].y == mode->VDisplay) &&
+ (modeTable[i].bpp == pScrn->bitsPerPixel)) {
+ reg->mode = modeTable[i].mode;
+ break;
+ }
+ }
+ }
+
+ if(!reg->mode){
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SMILynx_CrtcModeSet_bios: Not a known BIOS mode: "
+ "falling back to direct modesetting.\n");
+ SMILynx_CrtcModeSet_vga(crtc,mode,adjusted_mode,x,y);
+ LEAVE();
+ }
+
+ pSmi->pInt10->num = 0x10;
+ pSmi->pInt10->ax = reg->mode | 0x80;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%02X\n",
+ reg->mode);
+ xf86ExecX86int10(pSmi->pInt10);
+
+ /* Enable linear mode. */
+ outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18);
+ tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA);
+ outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp | 0x01);
+
+ /* Enable DPR/VPR registers. */
+ tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03);
+
+
+ /* Initialize Video Processor Registers */
+
+ SMICRTC(crtc)->video_init(crtc);
+ SMILynx_CrtcAdjustFrame(crtc, x,y);
+
+ LEAVE();
+}
+
+static void
SMILynx_CrtcLoadLUT_crt(xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
@@ -755,7 +839,12 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn)
functions. Has someone access to this hardware? */
SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv);
- crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga;
+
+ if(pSmi->useBIOS)
+ crtcFuncs->mode_set = SMILynx_CrtcModeSet_bios;
+ else
+ crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga;
+
crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame;
crtcPriv->video_init = SMI730_CrtcVideoInit;
crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt;
@@ -799,7 +888,12 @@ SMILynx_CrtcPreInit(ScrnInfoPtr pScrn)
/* CRTC0 is LCD, but in standard refresh mode
it is controlled through the primary VGA registers */
SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv);
- crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga;
+
+ if(pSmi->useBIOS)
+ crtcFuncs->mode_set = SMILynx_CrtcModeSet_bios;
+ else
+ crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga;
+
crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame;
crtcPriv->video_init = SMILynx_CrtcVideoInit_crt;
crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt;
diff --git a/src/smilynx_hw.c b/src/smilynx_hw.c
index 115a442..8d2c523 100644
--- a/src/smilynx_hw.c
+++ b/src/smilynx_hw.c
@@ -54,76 +54,78 @@ SMILynx_HWInit(ScrnInfoPtr pScrn)
mode->SR17 &= ~0x20;
}
- /* Disable DAC and LCD framebuffer r/w operation */
- mode->SR21 |= 0xB0;
+ /* Gamma correction */
+ if (pSmi->Chipset == SMI_LYNX3DM || pSmi->Chipset == SMI_COUGAR3DR) {
+ if(pScrn->bitsPerPixel == 8)
+ mode->SR66 = (mode->SR66 & 0x33) | 0x00; /* Both RAMLUT on, 6 bits-RAM */
+ else
+ mode->SR66 = (mode->SR66 & 0x33) | 0x04; /* Both RAMLUT on, Gamma correct ON */
+ }
- /* Power down mode is standby mode, VCLK and MCLK divided by 4 in standby mode */
- mode->SR20 = (mode->SR20 & ~0xB0) | 0x10;
+ /* Program MCLK */
+ if (pSmi->MCLK > 0)
+ SMI_CommonCalcClock(pScrn->scrnIndex, pSmi->MCLK,
+ 1, 1, 63, 0, 0,
+ pSmi->clockRange.minClock,
+ pSmi->clockRange.maxClock,
+ &mode->SR6A, &mode->SR6B);
- /* Set DPMS state to Off */
- mode->SR22 |= 0x30;
+ if(!pSmi->useBIOS) {
+ /* Disable DAC and LCD framebuffer r/w operation */
+ mode->SR21 |= 0xB0;
- /* VESA compliance power down mode */
- mode->SR24 &= ~0x01;
+ /* Power down mode is standby mode, VCLK and MCLK divided by 4 in standby mode */
+ mode->SR20 = (mode->SR20 & ~0xB0) | 0x10;
- if (pSmi->Chipset != SMI_COUGAR3DR) {
- /* Select no displays */
- mode->SR31 &= ~0x07;
+ /* Set DPMS state to Off */
+ mode->SR22 |= 0x30;
- /* Enable virtual refresh */
- if(pSmi->Dualhead){
- mode->SR31 |= 0x80;
- }else{
- mode->SR31 &= ~0x80;
- }
+ /* VESA compliance power down mode */
+ mode->SR24 &= ~0x01;
- /* Disable expansion */
- mode->SR32 &= ~0x03;
- /* Enable autocentering */
- if (SMI_LYNXM_SERIES(pSmi->Chipset))
- mode->SR32 |= 0x04;
- else
- mode->SR32 &= ~0x04;
+ if (pSmi->Chipset != SMI_COUGAR3DR) {
+ /* Select no displays */
+ mode->SR31 &= ~0x07;
- if (pSmi->lcd == 2) /* Panel is DSTN */
- mode->SR21 = 0x00;
+ /* Enable virtual refresh */
+ if(pSmi->Dualhead){
+ mode->SR31 |= 0x80;
+ }else{
+ mode->SR31 &= ~0x80;
+ }
- /* Enable HW LCD power sequencing */
- mode->SR34 |= 0x80;
- }
+ /* Disable expansion */
+ mode->SR32 &= ~0x03;
+ /* Enable autocentering */
+ if (SMI_LYNXM_SERIES(pSmi->Chipset))
+ mode->SR32 |= 0x04;
+ else
+ mode->SR32 &= ~0x04;
- /* Disable Vertical Expansion/Vertical Centering/Horizontal Centering */
- mode->CR90[0xE] &= ~0x7;
+ if (pSmi->lcd == 2) /* Panel is DSTN */
+ mode->SR21 = 0x00;
- /* Program MCLK */
- if (pSmi->MCLK > 0)
- SMI_CommonCalcClock(pScrn->scrnIndex, pSmi->MCLK,
- 1, 1, 63, 0, 0,
- pSmi->clockRange.minClock,
- pSmi->clockRange.maxClock,
- &mode->SR6A, &mode->SR6B);
+ /* Enable HW LCD power sequencing */
+ mode->SR34 |= 0x80;
+ }
- /* use vclk1 */
- mode->SR68 = 0x54;
+ /* Disable Vertical Expansion/Vertical Centering/Horizontal Centering */
+ mode->CR90[0xE] &= ~0x7;
- if(pSmi->Dualhead){
- /* set LCD to vclk2 */
- mode->SR69 = 0x04;
- }
+ /* use vclk1 */
+ mode->SR68 = 0x54;
- /* Gamma correction */
- if (pSmi->Chipset == SMI_LYNX3DM || pSmi->Chipset == SMI_COUGAR3DR) {
- if(pScrn->bitsPerPixel == 8)
- mode->SR66 = (mode->SR66 & 0x33) | 0x00; /* Both RAMLUT on, 6 bits-RAM */
- else
- mode->SR66 = (mode->SR66 & 0x33) | 0x04; /* Both RAMLUT on, Gamma correct ON */
- }
+ if(pSmi->Dualhead){
+ /* set LCD to vclk2 */
+ mode->SR69 = 0x04;
+ }
- /* Disable panel video */
- mode->SRA0 = 0;
+ /* Disable panel video */
+ mode->SRA0 = 0;
- mode->CR33 = 0;
- mode->CR3A = 0;
+ mode->CR33 = 0;
+ mode->CR3A = 0;
+ }
VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17, mode->SR17);
VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20, mode->SR20);
@@ -340,7 +342,30 @@ SMILynx_WriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, SMIRegPtr restore)
ENTER();
- if (pSmi->useBIOS && pSmi->pInt10 != NULL && restore->mode != 0) {
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17, restore->SR17);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18, restore->SR18);
+
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20, restore->SR20);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, restore->SR21);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, restore->SR22);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23, restore->SR23);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24, restore->SR24);
+
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, restore->SR31);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32, restore->SR32);
+
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66, restore->SR66);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68, restore->SR68);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69, restore->SR69);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A, restore->SR6A);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B, restore->SR6B);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C, restore->SR6C);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D, restore->SR6D);
+
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, restore->SR81);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0, restore->SRA0);
+
+ if (pSmi->useBIOS && restore->mode != 0){
pSmi->pInt10->num = 0x10;
pSmi->pInt10->ax = restore->mode | 0x80;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%02X\n",
@@ -356,29 +381,6 @@ SMILynx_WriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, SMIRegPtr restore)
tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21);
VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03);
} else {
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17, restore->SR17);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18, restore->SR18);
-
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20, restore->SR20);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, restore->SR21);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, restore->SR22);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23, restore->SR23);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24, restore->SR24);
-
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, restore->SR31);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32, restore->SR32);
-
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66, restore->SR66);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68, restore->SR68);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69, restore->SR69);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A, restore->SR6A);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B, restore->SR6B);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C, restore->SR6C);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D, restore->SR6D);
-
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, restore->SR81);
- VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0, restore->SRA0);
-
/* Restore the standard VGA registers */
vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL);
if (restore->smiDACMask) {
diff --git a/src/smilynx_output.c b/src/smilynx_output.c
index 4647cdd..4974d2c 100644
--- a/src/smilynx_output.c
+++ b/src/smilynx_output.c
@@ -119,6 +119,36 @@ SMILynx_OutputDPMS_lcd(xf86OutputPtr output, int mode)
}
+static void
+SMILynx_OutputDPMS_bios(xf86OutputPtr output, int mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER();
+
+ pSmi->pInt10->ax = 0x4F10;
+ switch (mode) {
+ case DPMSModeOn:
+ pSmi->pInt10->bx = 0x0001;
+ break;
+ case DPMSModeStandby:
+ pSmi->pInt10->bx = 0x0101;
+ break;
+ case DPMSModeSuspend:
+ pSmi->pInt10->bx = 0x0201;
+ break;
+ case DPMSModeOff:
+ pSmi->pInt10->bx = 0x0401;
+ break;
+ }
+ pSmi->pInt10->cx = 0x0000;
+ pSmi->pInt10->num = 0x10;
+ xf86ExecX86int10(pSmi->pInt10);
+
+ LEAVE();
+}
+
static DisplayModePtr
SMILynx_OutputGetModes_crt(xf86OutputPtr output)
@@ -147,13 +177,6 @@ SMILynx_OutputGetModes_crt(xf86OutputPtr output)
}
}
- /* Try DDC1 */
- pMon=SMILynx_ddc1(pScrn);
- if(pMon){
- xf86OutputSetEDID(output,pMon);
- LEAVE(xf86OutputGetEDIDModes(output));
- }
-
/* Try DDC2 */
if(pSmi->I2C){
pMon=xf86OutputGetEDID(output,pSmi->I2C);
@@ -162,6 +185,13 @@ SMILynx_OutputGetModes_crt(xf86OutputPtr output)
LEAVE(xf86OutputGetEDIDModes(output));
}
}
+
+ /* Try DDC1 */
+ pMon=SMILynx_ddc1(pScrn);
+ if(pMon){
+ xf86OutputSetEDID(output,pMon);
+ LEAVE(xf86OutputGetEDIDModes(output));
+ }
}
LEAVE(NULL);
@@ -255,7 +285,12 @@ SMILynx_OutputPreInit(ScrnInfoPtr pScrn)
}else{
/* CRTC0 is LCD */
SMI_OutputFuncsInit_base(&outputFuncs);
- outputFuncs->dpms = SMILynx_OutputDPMS_lcd;
+
+ if(pSmi->useBIOS)
+ outputFuncs->dpms = SMILynx_OutputDPMS_bios;
+ else
+ outputFuncs->dpms = SMILynx_OutputDPMS_lcd;
+
outputFuncs->get_modes = SMI_OutputGetModes_native;
outputFuncs->detect = SMI_OutputDetect_lcd;