summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/smi_501.c106
-rw-r--r--src/smi_driver.c26
-rw-r--r--src/smi_output.c6
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)) ||