![Juston Li](/assets/img/avatar_default.png)
Fixes checkpatch.pl WARNING: Missing a blank line after declarations Signed-off-by: Juston Li <juston.h.li@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
204 lines
7.2 KiB
C
204 lines
7.2 KiB
C
|
|
#include "ddk750_help.h"
|
|
#include "ddk750_reg.h"
|
|
#include "ddk750_mode.h"
|
|
#include "ddk750_chip.h"
|
|
|
|
/*
|
|
SM750LE only:
|
|
This function takes care extra registers and bit fields required to set
|
|
up a mode in SM750LE
|
|
|
|
Explanation about Display Control register:
|
|
HW only supports 7 predefined pixel clocks, and clock select is
|
|
in bit 29:27 of Display Control register.
|
|
*/
|
|
static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, unsigned long dispControl)
|
|
{
|
|
unsigned long x, y;
|
|
|
|
x = pModeParam->horizontal_display_end;
|
|
y = pModeParam->vertical_display_end;
|
|
|
|
/* SM750LE has to set up the top-left and bottom-right
|
|
registers as well.
|
|
Note that normal SM750/SM718 only use those two register for
|
|
auto-centering mode.
|
|
*/
|
|
POKE32(CRT_AUTO_CENTERING_TL,
|
|
FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, TOP, 0)
|
|
| FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, LEFT, 0));
|
|
|
|
POKE32(CRT_AUTO_CENTERING_BR,
|
|
FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, BOTTOM, y-1)
|
|
| FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, RIGHT, x-1));
|
|
|
|
/* Assume common fields in dispControl have been properly set before
|
|
calling this function.
|
|
This function only sets the extra fields in dispControl.
|
|
*/
|
|
|
|
/* Clear bit 29:27 of display control register */
|
|
dispControl &= FIELD_CLEAR(CRT_DISPLAY_CTRL, CLK);
|
|
|
|
/* Set bit 29:27 of display control register for the right clock */
|
|
/* Note that SM750LE only need to supported 7 resoluitons. */
|
|
if (x == 800 && y == 600)
|
|
dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL41);
|
|
else if (x == 1024 && y == 768)
|
|
dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL65);
|
|
else if (x == 1152 && y == 864)
|
|
dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80);
|
|
else if (x == 1280 && y == 768)
|
|
dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80);
|
|
else if (x == 1280 && y == 720)
|
|
dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL74);
|
|
else if (x == 1280 && y == 960)
|
|
dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108);
|
|
else if (x == 1280 && y == 1024)
|
|
dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108);
|
|
else /* default to VGA clock */
|
|
dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL25);
|
|
|
|
/* Set bit 25:24 of display controller */
|
|
dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CRTSELECT, CRT);
|
|
dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, RGBBIT, 24BIT);
|
|
|
|
/* Set bit 14 of display controller */
|
|
dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLOCK_PHASE, ACTIVE_LOW);
|
|
|
|
POKE32(CRT_DISPLAY_CTRL, dispControl);
|
|
|
|
return dispControl;
|
|
}
|
|
|
|
|
|
|
|
/* only timing related registers will be programed */
|
|
static int programModeRegisters(mode_parameter_t *pModeParam, pll_value_t *pll)
|
|
{
|
|
int ret = 0;
|
|
int cnt = 0;
|
|
unsigned int ulTmpValue, ulReg;
|
|
|
|
if (pll->clockType == SECONDARY_PLL) {
|
|
/* programe secondary pixel clock */
|
|
POKE32(CRT_PLL_CTRL, formatPllReg(pll));
|
|
POKE32(CRT_HORIZONTAL_TOTAL,
|
|
FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1)
|
|
| FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1));
|
|
|
|
POKE32(CRT_HORIZONTAL_SYNC,
|
|
FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width)
|
|
| FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1));
|
|
|
|
POKE32(CRT_VERTICAL_TOTAL,
|
|
FIELD_VALUE(0, CRT_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1)
|
|
| FIELD_VALUE(0, CRT_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1));
|
|
|
|
POKE32(CRT_VERTICAL_SYNC,
|
|
FIELD_VALUE(0, CRT_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height)
|
|
| FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1));
|
|
|
|
|
|
ulTmpValue = FIELD_VALUE(0, CRT_DISPLAY_CTRL, VSYNC_PHASE, pModeParam->vertical_sync_polarity)|
|
|
FIELD_VALUE(0, CRT_DISPLAY_CTRL, HSYNC_PHASE, pModeParam->horizontal_sync_polarity)|
|
|
FIELD_SET(0, CRT_DISPLAY_CTRL, TIMING, ENABLE)|
|
|
FIELD_SET(0, CRT_DISPLAY_CTRL, PLANE, ENABLE);
|
|
|
|
|
|
if (getChipType() == SM750LE) {
|
|
displayControlAdjust_SM750LE(pModeParam, ulTmpValue);
|
|
} else {
|
|
ulReg = PEEK32(CRT_DISPLAY_CTRL)
|
|
& FIELD_CLEAR(CRT_DISPLAY_CTRL, VSYNC_PHASE)
|
|
& FIELD_CLEAR(CRT_DISPLAY_CTRL, HSYNC_PHASE)
|
|
& FIELD_CLEAR(CRT_DISPLAY_CTRL, TIMING)
|
|
& FIELD_CLEAR(CRT_DISPLAY_CTRL, PLANE);
|
|
|
|
POKE32(CRT_DISPLAY_CTRL, ulTmpValue|ulReg);
|
|
}
|
|
|
|
} else if (pll->clockType == PRIMARY_PLL) {
|
|
unsigned int ulReservedBits;
|
|
|
|
POKE32(PANEL_PLL_CTRL, formatPllReg(pll));
|
|
|
|
POKE32(PANEL_HORIZONTAL_TOTAL,
|
|
FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1)
|
|
| FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1));
|
|
|
|
POKE32(PANEL_HORIZONTAL_SYNC,
|
|
FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width)
|
|
| FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1));
|
|
|
|
POKE32(PANEL_VERTICAL_TOTAL,
|
|
FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1)
|
|
| FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1));
|
|
|
|
POKE32(PANEL_VERTICAL_SYNC,
|
|
FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height)
|
|
| FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1));
|
|
|
|
ulTmpValue = FIELD_VALUE(0, PANEL_DISPLAY_CTRL, VSYNC_PHASE, pModeParam->vertical_sync_polarity)|
|
|
FIELD_VALUE(0, PANEL_DISPLAY_CTRL, HSYNC_PHASE, pModeParam->horizontal_sync_polarity)|
|
|
FIELD_VALUE(0, PANEL_DISPLAY_CTRL, CLOCK_PHASE, pModeParam->clock_phase_polarity)|
|
|
FIELD_SET(0, PANEL_DISPLAY_CTRL, TIMING, ENABLE)|
|
|
FIELD_SET(0, PANEL_DISPLAY_CTRL, PLANE, ENABLE);
|
|
|
|
ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) |
|
|
FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) |
|
|
FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE)|
|
|
FIELD_SET(0, PANEL_DISPLAY_CTRL, VSYNC, ACTIVE_LOW);
|
|
|
|
ulReg = (PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits)
|
|
& FIELD_CLEAR(PANEL_DISPLAY_CTRL, CLOCK_PHASE)
|
|
& FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE)
|
|
& FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE)
|
|
& FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING)
|
|
& FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE);
|
|
|
|
|
|
/* May a hardware bug or just my test chip (not confirmed).
|
|
* PANEL_DISPLAY_CTRL register seems requiring few writes
|
|
* before a value can be successfully written in.
|
|
* Added some masks to mask out the reserved bits.
|
|
* Note: This problem happens by design. The hardware will wait for the
|
|
* next vertical sync to turn on/off the plane.
|
|
*/
|
|
|
|
POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg);
|
|
#if 1
|
|
while ((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg)) {
|
|
cnt++;
|
|
if (cnt > 1000)
|
|
break;
|
|
POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg);
|
|
}
|
|
#endif
|
|
} else {
|
|
ret = -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ddk750_setModeTiming(mode_parameter_t *parm, clock_type_t clock)
|
|
{
|
|
pll_value_t pll;
|
|
unsigned int uiActualPixelClk;
|
|
|
|
pll.inputFreq = DEFAULT_INPUT_CLOCK;
|
|
pll.clockType = clock;
|
|
|
|
uiActualPixelClk = calcPllValue(parm->pixel_clock, &pll);
|
|
if (getChipType() == SM750LE) {
|
|
/* set graphic mode via IO method */
|
|
outb_p(0x88, 0x3d4);
|
|
outb_p(0x06, 0x3d5);
|
|
}
|
|
programModeRegisters(parm, &pll);
|
|
return 0;
|
|
}
|
|
|
|
|