
#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;
}


