162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci *  linux/drivers/video/kyro/STG4000VTG.c
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *  Copyright (C) 2002 STMicroelectronics
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
762306a36Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
862306a36Sopenharmony_ci * for more details.
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/types.h>
1262306a36Sopenharmony_ci#include <video/kyro.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include "STG4000Reg.h"
1562306a36Sopenharmony_ci#include "STG4000Interface.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_civoid DisableVGA(volatile STG4000REG __iomem *pSTGReg)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci	u32 tmp;
2062306a36Sopenharmony_ci	volatile u32 count = 0, i;
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci	/* Reset the VGA registers */
2362306a36Sopenharmony_ci	tmp = STG_READ_REG(SoftwareReset);
2462306a36Sopenharmony_ci	CLEAR_BIT(8);
2562306a36Sopenharmony_ci	STG_WRITE_REG(SoftwareReset, tmp);
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	/* Just for Delay */
2862306a36Sopenharmony_ci	for (i = 0; i < 1000; i++) {
2962306a36Sopenharmony_ci		count++;
3062306a36Sopenharmony_ci	}
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	/* Pull-out the VGA registers from reset */
3362306a36Sopenharmony_ci	tmp = STG_READ_REG(SoftwareReset);
3462306a36Sopenharmony_ci	tmp |= SET_BIT(8);
3562306a36Sopenharmony_ci	STG_WRITE_REG(SoftwareReset, tmp);
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_civoid StopVTG(volatile STG4000REG __iomem *pSTGReg)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	u32 tmp = 0;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	/* Stop Ver and Hor Sync Generator */
4362306a36Sopenharmony_ci	tmp = (STG_READ_REG(DACSyncCtrl)) | SET_BIT(0) | SET_BIT(2);
4462306a36Sopenharmony_ci	CLEAR_BIT(31);
4562306a36Sopenharmony_ci	STG_WRITE_REG(DACSyncCtrl, tmp);
4662306a36Sopenharmony_ci}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_civoid StartVTG(volatile STG4000REG __iomem *pSTGReg)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	u32 tmp = 0;
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	/* Start Ver and Hor Sync Generator */
5362306a36Sopenharmony_ci	tmp = ((STG_READ_REG(DACSyncCtrl)) | SET_BIT(31));
5462306a36Sopenharmony_ci	CLEAR_BIT(0);
5562306a36Sopenharmony_ci	CLEAR_BIT(2);
5662306a36Sopenharmony_ci	STG_WRITE_REG(DACSyncCtrl, tmp);
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_civoid SetupVTG(volatile STG4000REG __iomem *pSTGReg,
6062306a36Sopenharmony_ci	      const struct kyrofb_info * pTiming)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	u32 tmp = 0;
6362306a36Sopenharmony_ci	u32 margins = 0;
6462306a36Sopenharmony_ci	u32 ulBorder;
6562306a36Sopenharmony_ci	u32 xRes = pTiming->XRES;
6662306a36Sopenharmony_ci	u32 yRes = pTiming->YRES;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	/* Horizontal */
6962306a36Sopenharmony_ci	u32 HAddrTime, HRightBorder, HLeftBorder;
7062306a36Sopenharmony_ci	u32 HBackPorcStrt, HFrontPorchStrt, HTotal,
7162306a36Sopenharmony_ci	    HLeftBorderStrt, HRightBorderStrt, HDisplayStrt;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	/* Vertical */
7462306a36Sopenharmony_ci	u32 VDisplayStrt, VBottomBorder, VTopBorder;
7562306a36Sopenharmony_ci	u32 VBackPorchStrt, VTotal, VTopBorderStrt,
7662306a36Sopenharmony_ci	    VFrontPorchStrt, VBottomBorderStrt, VAddrTime;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	/* Need to calculate the right border */
7962306a36Sopenharmony_ci	if ((xRes == 640) && (yRes == 480)) {
8062306a36Sopenharmony_ci		if ((pTiming->VFREQ == 60) || (pTiming->VFREQ == 72)) {
8162306a36Sopenharmony_ci			margins = 8;
8262306a36Sopenharmony_ci		}
8362306a36Sopenharmony_ci	}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	/* Work out the Border */
8662306a36Sopenharmony_ci	ulBorder =
8762306a36Sopenharmony_ci	    (pTiming->HTot -
8862306a36Sopenharmony_ci	     (pTiming->HST + (pTiming->HBP - margins) + xRes +
8962306a36Sopenharmony_ci	      (pTiming->HFP - margins))) >> 1;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	/* Border the same for Vertical and Horizontal */
9262306a36Sopenharmony_ci	VBottomBorder = HLeftBorder = VTopBorder = HRightBorder = ulBorder;
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci    /************ Get Timing values for Horizontal ******************/
9562306a36Sopenharmony_ci	HAddrTime = xRes;
9662306a36Sopenharmony_ci	HBackPorcStrt = pTiming->HST;
9762306a36Sopenharmony_ci	HTotal = pTiming->HTot;
9862306a36Sopenharmony_ci	HDisplayStrt =
9962306a36Sopenharmony_ci	    pTiming->HST + (pTiming->HBP - margins) + HLeftBorder;
10062306a36Sopenharmony_ci	HLeftBorderStrt = HDisplayStrt - HLeftBorder;
10162306a36Sopenharmony_ci	HFrontPorchStrt =
10262306a36Sopenharmony_ci	    pTiming->HST + (pTiming->HBP - margins) + HLeftBorder +
10362306a36Sopenharmony_ci	    HAddrTime + HRightBorder;
10462306a36Sopenharmony_ci	HRightBorderStrt = HFrontPorchStrt - HRightBorder;
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci    /************ Get Timing values for Vertical ******************/
10762306a36Sopenharmony_ci	VAddrTime = yRes;
10862306a36Sopenharmony_ci	VBackPorchStrt = pTiming->VST;
10962306a36Sopenharmony_ci	VTotal = pTiming->VTot;
11062306a36Sopenharmony_ci	VDisplayStrt =
11162306a36Sopenharmony_ci	    pTiming->VST + (pTiming->VBP - margins) + VTopBorder;
11262306a36Sopenharmony_ci	VTopBorderStrt = VDisplayStrt - VTopBorder;
11362306a36Sopenharmony_ci	VFrontPorchStrt =
11462306a36Sopenharmony_ci	    pTiming->VST + (pTiming->VBP - margins) + VTopBorder +
11562306a36Sopenharmony_ci	    VAddrTime + VBottomBorder;
11662306a36Sopenharmony_ci	VBottomBorderStrt = VFrontPorchStrt - VBottomBorder;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	/* Set Hor Timing 1, 2, 3 */
11962306a36Sopenharmony_ci	tmp = STG_READ_REG(DACHorTim1);
12062306a36Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 11);
12162306a36Sopenharmony_ci	CLEAR_BITS_FRM_TO(16, 27);
12262306a36Sopenharmony_ci	tmp |= (HTotal) | (HBackPorcStrt << 16);
12362306a36Sopenharmony_ci	STG_WRITE_REG(DACHorTim1, tmp);
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	tmp = STG_READ_REG(DACHorTim2);
12662306a36Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 11);
12762306a36Sopenharmony_ci	CLEAR_BITS_FRM_TO(16, 27);
12862306a36Sopenharmony_ci	tmp |= (HDisplayStrt << 16) | HLeftBorderStrt;
12962306a36Sopenharmony_ci	STG_WRITE_REG(DACHorTim2, tmp);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	tmp = STG_READ_REG(DACHorTim3);
13262306a36Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 11);
13362306a36Sopenharmony_ci	CLEAR_BITS_FRM_TO(16, 27);
13462306a36Sopenharmony_ci	tmp |= (HFrontPorchStrt << 16) | HRightBorderStrt;
13562306a36Sopenharmony_ci	STG_WRITE_REG(DACHorTim3, tmp);
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	/* Set Ver Timing 1, 2, 3 */
13862306a36Sopenharmony_ci	tmp = STG_READ_REG(DACVerTim1);
13962306a36Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 11);
14062306a36Sopenharmony_ci	CLEAR_BITS_FRM_TO(16, 27);
14162306a36Sopenharmony_ci	tmp |= (VBackPorchStrt << 16) | (VTotal);
14262306a36Sopenharmony_ci	STG_WRITE_REG(DACVerTim1, tmp);
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	tmp = STG_READ_REG(DACVerTim2);
14562306a36Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 11);
14662306a36Sopenharmony_ci	CLEAR_BITS_FRM_TO(16, 27);
14762306a36Sopenharmony_ci	tmp |= (VDisplayStrt << 16) | VTopBorderStrt;
14862306a36Sopenharmony_ci	STG_WRITE_REG(DACVerTim2, tmp);
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	tmp = STG_READ_REG(DACVerTim3);
15162306a36Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 11);
15262306a36Sopenharmony_ci	CLEAR_BITS_FRM_TO(16, 27);
15362306a36Sopenharmony_ci	tmp |= (VFrontPorchStrt << 16) | VBottomBorderStrt;
15462306a36Sopenharmony_ci	STG_WRITE_REG(DACVerTim3, tmp);
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	/* Set Verical and Horizontal Polarity */
15762306a36Sopenharmony_ci	tmp = STG_READ_REG(DACSyncCtrl) | SET_BIT(3) | SET_BIT(1);
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	if ((pTiming->HSP > 0) && (pTiming->VSP < 0)) {	/* +hsync -vsync */
16062306a36Sopenharmony_ci		tmp &= ~0x8;
16162306a36Sopenharmony_ci	} else if ((pTiming->HSP < 0) && (pTiming->VSP > 0)) {	/* -hsync +vsync */
16262306a36Sopenharmony_ci		tmp &= ~0x2;
16362306a36Sopenharmony_ci	} else if ((pTiming->HSP < 0) && (pTiming->VSP < 0)) {	/* -hsync -vsync */
16462306a36Sopenharmony_ci		tmp &= ~0xA;
16562306a36Sopenharmony_ci	} else if ((pTiming->HSP > 0) && (pTiming->VSP > 0)) {	/* +hsync -vsync */
16662306a36Sopenharmony_ci		tmp &= ~0x0;
16762306a36Sopenharmony_ci	}
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	STG_WRITE_REG(DACSyncCtrl, tmp);
17062306a36Sopenharmony_ci}
171