diff options
-rw-r--r-- | src/smi_501.c | 106 | ||||
-rw-r--r-- | src/smi_driver.c | 26 | ||||
-rw-r--r-- | src/smi_output.c | 6 |
3 files changed, 83 insertions, 55 deletions
diff --git a/src/smi_501.c b/src/smi_501.c index 63d704f..8ce6383 100644 --- a/src/smi_501.c +++ b/src/smi_501.c @@ -266,50 +266,52 @@ SMI501_WriteMode_lcd(ScrnInfoPtr pScrn, MSOCRegPtr mode) MSOCClockRec clock; SMIPtr pSmi = SMIPTR(pScrn); - /* Alternate pll_select is only available for the SMI 502, - * and the bit should be only set in that case. */ - if (mode->clock.f.pll_select) - WRITE_SCR(pSmi, PLL_CTL, mode->pll_ctl.value); - clock.f.p2_select = mode->clock.f.p2_select; - pll = clock.value; - clock.f.p2_divider = mode->clock.f.p2_divider; - clock.f.p2_shift = mode->clock.f.p2_shift; - clock.f.pll_select = mode->clock.f.pll_select; - clock.f.p2_1xclck = mode->clock.f.p2_1xclck; - SMI501_SetClock(pSmi, mode->current_clock, pll, clock.value); - - WRITE_SCR(pSmi, PANEL_FB_ADDRESS, mode->panel_fb_address.value); - WRITE_SCR(pSmi, PANEL_FB_WIDTH, mode->panel_fb_width.value); - - WRITE_SCR(pSmi, PANEL_WWIDTH, mode->panel_wwidth.value); - WRITE_SCR(pSmi, PANEL_WHEIGHT, mode->panel_wheight.value); - - WRITE_SCR(pSmi, PANEL_PLANE_TL, mode->panel_plane_tl.value); - WRITE_SCR(pSmi, PANEL_PLANE_BR, mode->panel_plane_br.value); - - WRITE_SCR(pSmi, PANEL_HTOTAL, mode->panel_htotal.value); - WRITE_SCR(pSmi, PANEL_HSYNC, mode->panel_hsync.value); - 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); - } + clock.value = READ_SCR(pSmi, mode->current_clock); + + /* Alternate pll_select is only available for the SMI 502, + * and the bit should be only set in that case. */ + if (mode->clock.f.pll_select) + WRITE_SCR(pSmi, PLL_CTL, mode->pll_ctl.value); + clock.f.p2_select = mode->clock.f.p2_select; + pll = clock.value; + clock.f.p2_divider = mode->clock.f.p2_divider; + clock.f.p2_shift = mode->clock.f.p2_shift; + clock.f.pll_select = mode->clock.f.pll_select; + clock.f.p2_1xclck = mode->clock.f.p2_1xclck; + SMI501_SetClock(pSmi, mode->current_clock, pll, clock.value); + + WRITE_SCR(pSmi, PANEL_FB_ADDRESS, mode->panel_fb_address.value); + WRITE_SCR(pSmi, PANEL_FB_WIDTH, mode->panel_fb_width.value); + + WRITE_SCR(pSmi, PANEL_WWIDTH, mode->panel_wwidth.value); + WRITE_SCR(pSmi, PANEL_WHEIGHT, mode->panel_wheight.value); + + WRITE_SCR(pSmi, PANEL_PLANE_TL, mode->panel_plane_tl.value); + WRITE_SCR(pSmi, PANEL_PLANE_BR, mode->panel_plane_br.value); + + WRITE_SCR(pSmi, PANEL_HTOTAL, mode->panel_htotal.value); + WRITE_SCR(pSmi, PANEL_HSYNC, mode->panel_hsync.value); + 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); +} void SMI501_WriteMode_crt(ScrnInfoPtr pScrn, MSOCRegPtr mode) @@ -318,6 +320,8 @@ SMI501_WriteMode_crt(ScrnInfoPtr pScrn, MSOCRegPtr mode) MSOCClockRec clock; SMIPtr pSmi = SMIPTR(pScrn); + clock.value = READ_SCR(pSmi, mode->current_clock); + clock.f.v2_select = mode->clock.f.v2_select; pll = clock.value; clock.f.v2_divider = mode->clock.f.v2_divider; @@ -325,13 +329,13 @@ SMI501_WriteMode_crt(ScrnInfoPtr pScrn, MSOCRegPtr mode) clock.f.v2_1xclck = mode->clock.f.v2_1xclck; SMI501_SetClock(pSmi, mode->current_clock, pll, clock.value); - WRITE_SCR(pSmi, CRT_FB_ADDRESS, mode->crt_fb_address.value); - WRITE_SCR(pSmi, CRT_FB_WIDTH, mode->crt_fb_width.value); - WRITE_SCR(pSmi, CRT_HTOTAL, mode->crt_htotal.value); - WRITE_SCR(pSmi, CRT_HSYNC, mode->crt_hsync.value); - WRITE_SCR(pSmi, CRT_VTOTAL, mode->crt_vtotal.value); - WRITE_SCR(pSmi, CRT_VSYNC, mode->crt_vsync.value); - WRITE_SCR(pSmi, CRT_DISPLAY_CTL, mode->crt_display_ctl.value); + WRITE_SCR(pSmi, CRT_FB_ADDRESS, mode->crt_fb_address.value); + WRITE_SCR(pSmi, CRT_FB_WIDTH, mode->crt_fb_width.value); + WRITE_SCR(pSmi, CRT_HTOTAL, mode->crt_htotal.value); + WRITE_SCR(pSmi, CRT_HSYNC, mode->crt_hsync.value); + WRITE_SCR(pSmi, CRT_VTOTAL, mode->crt_vtotal.value); + WRITE_SCR(pSmi, CRT_VSYNC, mode->crt_vsync.value); + WRITE_SCR(pSmi, CRT_DISPLAY_CTL, mode->crt_display_ctl.value); } static char * diff --git a/src/smi_driver.c b/src/smi_driver.c index 61077c7..321a8ab 100644 --- a/src/smi_driver.c +++ b/src/smi_driver.c @@ -839,7 +839,25 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) pSmi->Dualhead = FALSE; - if (!IS_MSOC(pSmi)){ + if (IS_MSOC(pSmi)) { + pSmi->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); + + /* FIXME this assumes the first head is always lcd and second + * always crt */ + pSmi->IsSecondary = FALSE; + 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); + } + } + else { if (SMI_LYNXM_SERIES(pSmi->Chipset) && xf86ReturnOptValBool(pSmi->Options, OPTION_DUALHEAD, FALSE)) pSmi->Dualhead = TRUE; @@ -1243,9 +1261,9 @@ SMI_DetectMCLK(ScrnInfoPtr pScrn) /* FIXME this should just read smi_501.h's bitfields... */ clock = READ_SCR(pSmi, CURRENT_CLOCK); - shift = (clock >> 8) & ((1 << 3) - 1); - divider = (clock >> 11) & 1 ? 3 : 1; - clock = clock & (1 << 12) ? 336 : 288; + shift = clock & ((1 << 3) - 1); + divider = (clock >> 3) & 1 ? 3 : 1; + clock = clock & (1 << 4) ? 336 : 288; mclk = (clock / (divider << shift)) * 1000; } else { diff --git a/src/smi_output.c b/src/smi_output.c index d0188b7..209e2f9 100644 --- a/src/smi_output.c +++ b/src/smi_output.c @@ -49,6 +49,12 @@ SMI_OutputModeValid(xf86OutputPtr output, DisplayModePtr mode) ScrnInfoPtr pScrn = output->scrn; SMIPtr pSmi = SMIPTR(pScrn); + ENTER(); + + if (pSmi->lcd && + (mode->HDisplay > pSmi->lcdWidth || mode->VDisplay > pSmi->lcdHeight)) + RETURN(MODE_PANEL); + if (!(((mode->HDisplay == 1280) && (mode->VDisplay == 1024)) || ((mode->HDisplay == 1024) && (mode->VDisplay == 768)) || ((mode->HDisplay == 800) && (mode->VDisplay == 600)) || |