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


