123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- #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);
- while ((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg)) {
- cnt++;
- if (cnt > 1000)
- break;
- POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg);
- }
- } 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;
- }
|