From 1efe36ed5cf5b0931daa915ca3ce231b78168d87 Mon Sep 17 00:00:00 2001 From: Paulo Cesar Pereira de Andrade Date: Wed, 22 Oct 2008 19:06:06 -0200 Subject: 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. --- src/smi_501.c | 147 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 77 insertions(+), 70 deletions(-) (limited to 'src/smi_501.c') 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; -- cgit v1.2.3