summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-10-22 19:06:06 -0200
committerPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-10-22 19:06:06 -0200
commit1efe36ed5cf5b0931daa915ca3ce231b78168d87 (patch)
tree29080b36b6d9cb93bdcac1a799bbf44ca71e9067
parentdd083c26de400cee8c67977f46cf90d048b22ff9 (diff)
Make UseFBDev option functional again.
It is mean't to be a fallback option, that as long as kernel boots in framebuffer mode, the X Server should also work. Correct incorrect value being checked when printing state of Dualhead option. The M value when programming PLL3 is actually an 8 bits integer, so correct it and comments about it.
-rw-r--r--src/smi501_crtc.c5
-rw-r--r--src/smi_501.c147
-rw-r--r--src/smi_501.h2
-rw-r--r--src/smi_driver.c7
4 files changed, 84 insertions, 77 deletions
diff --git a/src/smi501_crtc.c b/src/smi501_crtc.c
index f7e1551..07a96ed 100644
--- a/src/smi501_crtc.c
+++ b/src/smi501_crtc.c
@@ -152,11 +152,6 @@ SMI501_CrtcModeSet_lcd(xf86CrtcPtr crtc,
ENTER();
- if (pSmi->UseFBDev) {
- LEAVE();
- return;
- }
-
/* Initialize the display controller */
SMI501_CrtcVideoInit_lcd(crtc);
diff --git a/src/smi_501.c b/src/smi_501.c
index 26c8798..80f3401 100644
--- a/src/smi_501.c
+++ b/src/smi_501.c
@@ -207,7 +207,7 @@ SMI501_HWInit(ScrnInfoPtr pScrn)
}
if (!pSmi->Dualhead) {
- /* By default, crt clones panel */
+ /* crt clones panel */
mode->crt_display_ctl.f.enable = 0;
/* 0: select panel - 1: select crt */
mode->crt_display_ctl.f.select = 0;
@@ -226,26 +226,28 @@ SMI501_WriteMode_common(ScrnInfoPtr pScrn, MSOCRegPtr mode)
MSOCClockRec clock;
SMIPtr pSmi = SMIPTR(pScrn);
- /* Update gate first */
- WRITE_SCR(pSmi, mode->current_gate, mode->gate.value);
+ if (!pSmi->UseFBDev) {
+ /* Update gate first */
+ WRITE_SCR(pSmi, mode->current_gate, mode->gate.value);
- clock.value = READ_SCR(pSmi, mode->current_clock);
+ clock.value = READ_SCR(pSmi, mode->current_clock);
- clock.f.m_select = mode->clock.f.m_select;
- pll = clock.value;
- clock.f.m_divider = mode->clock.f.m_divider;
- clock.f.m_shift = mode->clock.f.m_shift;
- SMI501_SetClock(pSmi, mode->current_clock, pll, clock.value);
+ clock.f.m_select = mode->clock.f.m_select;
+ pll = clock.value;
+ clock.f.m_divider = mode->clock.f.m_divider;
+ clock.f.m_shift = mode->clock.f.m_shift;
+ SMI501_SetClock(pSmi, mode->current_clock, pll, clock.value);
- clock.f.m1_select = mode->clock.f.m1_select;
- pll = clock.value;
- clock.f.m1_divider = mode->clock.f.m1_divider;
- clock.f.m1_shift = mode->clock.f.m1_shift;
- SMI501_SetClock(pSmi, mode->current_clock, pll, clock.value);
+ clock.f.m1_select = mode->clock.f.m1_select;
+ pll = clock.value;
+ clock.f.m1_divider = mode->clock.f.m1_divider;
+ clock.f.m1_shift = mode->clock.f.m1_shift;
+ SMI501_SetClock(pSmi, mode->current_clock, pll, clock.value);
- WRITE_SCR(pSmi, MISC_CTL, mode->misc_ctl.value);
+ WRITE_SCR(pSmi, MISC_CTL, mode->misc_ctl.value);
- WRITE_SCR(pSmi, POWER_CTL, mode->power_ctl.value);
+ WRITE_SCR(pSmi, POWER_CTL, mode->power_ctl.value);
+ }
/* Match configuration */
/* FIXME some other fields should also be set, otherwise, since
@@ -267,34 +269,36 @@ SMI501_WriteMode_lcd(ScrnInfoPtr pScrn, MSOCRegPtr mode)
MSOCClockRec clock;
SMIPtr pSmi = SMIPTR(pScrn);
- 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);
+ if (!pSmi->UseFBDev) {
+ 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);
+ }
}
void
@@ -304,33 +308,42 @@ 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;
- clock.f.v2_shift = mode->clock.f.v2_shift;
- 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);
+ if (!pSmi->UseFBDev) {
+ 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;
+ clock.f.v2_shift = mode->clock.f.v2_shift;
+ 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);
+ }
}
void
SMI501_WriteMode(ScrnInfoPtr pScrn, MSOCRegPtr restore)
{
+ /* FIXME There is a problem here:
+ * The kernel may not have modified some values, like clocks,
+ * but when "restoring" them, it will actually change from a
+ * a valid value, to a random value.
+ */
+#if 0
SMIPtr pSmi = SMIPTR(pScrn);
SMI501_WriteMode_common(pScrn, restore);
SMI501_WriteMode_lcd(pScrn, restore);
if (pSmi->Dualhead)
SMI501_WriteMode_crt(pScrn, restore);
+#endif
}
void
@@ -374,12 +387,6 @@ SMI501_PowerPanel(ScrnInfoPtr pScrn, MSOCRegPtr mode, Bool on)
}
}
-void
-SMI501_PowerCrt(ScrnInfoPtr pScrn, MSOCRegPtr mode, Bool onoff)
-{
- SMI501_DisplayPowerManagementSet(pScrn, onoff ? DPMSModeOn : DPMSModeOff, 0);
-}
-
static char *
format_integer_base2(int32_t word)
{
@@ -454,7 +461,7 @@ SMI501_FindPLLClock(double clock, int32_t *m, int32_t *n, int32_t *xclck)
* displayed correctly due to the big difference on the requested
* pixel clock, with the actual pixel clock that can be achieved by
* those divisions. In this method, N can be any integer between 2
- * and 24, M can be any positive, 7 bits integer, and K is either 1
+ * and 24, M can be any positive, 8 bits integer, and K is either 1
* or 2.
* To calculate the programmable PLL, the following formula is
* used:
@@ -475,7 +482,7 @@ SMI501_FindPLLClock(double clock, int32_t *m, int32_t *n, int32_t *xclck)
*
* where requested_clock is modeline pixel clock,
* input_frequency is 12, K is either 1 or 2 (and sets bit15 accordingly),
- * M is a non zero 7 bits unsigned integer, and N is a value from 2 to 24.
+ * M is a non zero 8 bits unsigned integer, and N is a value from 2 to 24.
*/
best = 0x7fffffff;
@@ -484,8 +491,8 @@ SMI501_FindPLLClock(double clock, int32_t *m, int32_t *n, int32_t *xclck)
for (K = 1; K <= 2; K++) {
M = clock / frequency * K * N;
diff = ((int32_t)(frequency / K * M) / N) - clock;
- /* Ensure M is larger then 0 and fits in 7 bits */
- if (M > 0 && M < 0x80 && fabs(diff) < best) {
+ /* Ensure M is larger then 0 and fits in 8 bits */
+ if (M > 0 && M < 0x100 && fabs(diff) < best) {
*m = M;
*n = N;
*xclck = K == 1;
diff --git a/src/smi_501.h b/src/smi_501.h
index 1050a3c..ca49813 100644
--- a/src/smi_501.h
+++ b/src/smi_501.h
@@ -369,7 +369,7 @@ typedef struct _MSOCRegRec {
* Requested Pixel Clock = Input Frequency * M / N
* Input Frequency is the input crystal frequency value (24 MHz in
* the SMI VGX Demo Board). N must be a value between 2 and 24.
- * M can be any (7 bits) value, and a loop testing all possible N
+ * M can be any (8 bits) value, and a loop testing all possible N
* values should be the best approach to calculate it's value.
*/
union {
diff --git a/src/smi_driver.c b/src/smi_driver.c
index 6b8eab7..9b4d07a 100644
--- a/src/smi_driver.c
+++ b/src/smi_driver.c
@@ -846,6 +846,11 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags)
if (IS_MSOC(pSmi)) {
pSmi->lcd = TRUE;
pSmi->IsSecondary = FALSE;
+ if (pSmi->Dualhead && pSmi->UseFBDev) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Dual head disabled when using fbdev mode\n");
+ pSmi->Dualhead = FALSE;
+ }
}
else if (SMI_LYNXM_SERIES(pSmi->Chipset)) {
/* tweak options for dualhead */
@@ -870,7 +875,7 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags)
"MMIOBase=%p\n", vgaCRIndex, vgaIOBase, hwp->MMIOBase);
}
xf86DrvMsg(pScrn->scrnIndex, from, "Dual head %sabled\n",
- pSmi->PCIBurst ? "en" : "dis");
+ pSmi->Dualhead ? "en" : "dis");
SMI_MapMmio(pScrn);
SMI_DetectMem(pScrn);