18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci *  linux/drivers/video/kyro/STG4000Ramdac.c
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci *  Copyright (C) 2002 STMicroelectronics
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
78c2ecf20Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
88c2ecf20Sopenharmony_ci * for more details.
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/kernel.h>
128c2ecf20Sopenharmony_ci#include <linux/errno.h>
138c2ecf20Sopenharmony_ci#include <linux/types.h>
148c2ecf20Sopenharmony_ci#include <video/kyro.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include "STG4000Reg.h"
178c2ecf20Sopenharmony_ci#include "STG4000Interface.h"
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_cistatic u32 STG_PIXEL_BUS_WIDTH = 128;	/* 128 bit bus width      */
208c2ecf20Sopenharmony_cistatic u32 REF_CLOCK = 14318;
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ciint InitialiseRamdac(volatile STG4000REG __iomem * pSTGReg,
238c2ecf20Sopenharmony_ci		     u32 displayDepth,
248c2ecf20Sopenharmony_ci		     u32 displayWidth,
258c2ecf20Sopenharmony_ci		     u32 displayHeight,
268c2ecf20Sopenharmony_ci		     s32 HSyncPolarity,
278c2ecf20Sopenharmony_ci		     s32 VSyncPolarity, u32 * pixelClock)
288c2ecf20Sopenharmony_ci{
298c2ecf20Sopenharmony_ci	u32 tmp = 0;
308c2ecf20Sopenharmony_ci	u32 F = 0, R = 0, P = 0;
318c2ecf20Sopenharmony_ci	u32 stride = 0;
328c2ecf20Sopenharmony_ci	u32 ulPdiv = 0;
338c2ecf20Sopenharmony_ci	u32 physicalPixelDepth = 0;
348c2ecf20Sopenharmony_ci	/* Make sure DAC is in Reset */
358c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(SoftwareReset);
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	if (tmp & 0x1) {
388c2ecf20Sopenharmony_ci		CLEAR_BIT(1);
398c2ecf20Sopenharmony_ci		STG_WRITE_REG(SoftwareReset, tmp);
408c2ecf20Sopenharmony_ci	}
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	/* Set Pixel Format */
438c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(DACPixelFormat);
448c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 2);
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	/* Set LUT not used from 16bpp to 32 bpp ??? */
478c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(8, 9);
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	switch (displayDepth) {
508c2ecf20Sopenharmony_ci	case 16:
518c2ecf20Sopenharmony_ci		{
528c2ecf20Sopenharmony_ci			physicalPixelDepth = 16;
538c2ecf20Sopenharmony_ci			tmp |= _16BPP;
548c2ecf20Sopenharmony_ci			break;
558c2ecf20Sopenharmony_ci		}
568c2ecf20Sopenharmony_ci	case 32:
578c2ecf20Sopenharmony_ci		{
588c2ecf20Sopenharmony_ci			/* Set for 32 bits per pixel */
598c2ecf20Sopenharmony_ci			physicalPixelDepth = 32;
608c2ecf20Sopenharmony_ci			tmp |= _32BPP;
618c2ecf20Sopenharmony_ci			break;
628c2ecf20Sopenharmony_ci		}
638c2ecf20Sopenharmony_ci	default:
648c2ecf20Sopenharmony_ci		return -EINVAL;
658c2ecf20Sopenharmony_ci	}
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACPixelFormat, tmp);
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	/* Workout Bus transfer bandwidth according to pixel format */
708c2ecf20Sopenharmony_ci	ulPdiv = STG_PIXEL_BUS_WIDTH / physicalPixelDepth;
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	/* Get Screen Stride in pixels */
738c2ecf20Sopenharmony_ci	stride = displayWidth;
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	/* Set Primary size info */
768c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(DACPrimSize);
778c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 10);
788c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(12, 31);
798c2ecf20Sopenharmony_ci	tmp |=
808c2ecf20Sopenharmony_ci	    ((((displayHeight - 1) << 12) | (((displayWidth / ulPdiv) -
818c2ecf20Sopenharmony_ci					      1) << 23))
828c2ecf20Sopenharmony_ci	     | (stride / ulPdiv));
838c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACPrimSize, tmp);
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	/* Set Pixel Clock */
878c2ecf20Sopenharmony_ci	*pixelClock = ProgramClock(REF_CLOCK, *pixelClock, &F, &R, &P);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	/* Set DAC PLL Mode */
908c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(DACPLLMode);
918c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 15);
928c2ecf20Sopenharmony_ci	/* tmp |= ((P-1) | ((F-2) << 2) | ((R-2) << 11)); */
938c2ecf20Sopenharmony_ci	tmp |= ((P) | ((F - 2) << 2) | ((R - 2) << 11));
948c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACPLLMode, tmp);
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	/* Set Prim Address */
978c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(DACPrimAddress);
988c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 20);
998c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(20, 31);
1008c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACPrimAddress, tmp);
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	/* Set Cursor details with HW Cursor disabled */
1038c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(DACCursorCtrl);
1048c2ecf20Sopenharmony_ci	tmp &= ~SET_BIT(31);
1058c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACCursorCtrl, tmp);
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(DACCursorAddr);
1088c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 20);
1098c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACCursorAddr, tmp);
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	/* Set Video Window */
1128c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(DACVidWinStart);
1138c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 10);
1148c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(16, 26);
1158c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACVidWinStart, tmp);
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(DACVidWinEnd);
1188c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 10);
1198c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(16, 26);
1208c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACVidWinEnd, tmp);
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	/* Set DAC Border Color to default */
1238c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(DACBorderColor);
1248c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(0, 23);
1258c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACBorderColor, tmp);
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	/* Set Graphics and Overlay Burst Control */
1288c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACBurstCtrl, 0x0404);
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	/* Set CRC Trigger to default */
1318c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(DACCrcTrigger);
1328c2ecf20Sopenharmony_ci	CLEAR_BIT(0);
1338c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACCrcTrigger, tmp);
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	/* Set Video Port Control to default */
1368c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(DigVidPortCtrl);
1378c2ecf20Sopenharmony_ci	CLEAR_BIT(8);
1388c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(16, 27);
1398c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(1, 3);
1408c2ecf20Sopenharmony_ci	CLEAR_BITS_FRM_TO(10, 11);
1418c2ecf20Sopenharmony_ci	STG_WRITE_REG(DigVidPortCtrl, tmp);
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	return 0;
1448c2ecf20Sopenharmony_ci}
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci/* Ramdac control, turning output to the screen on and off */
1478c2ecf20Sopenharmony_civoid DisableRamdacOutput(volatile STG4000REG __iomem * pSTGReg)
1488c2ecf20Sopenharmony_ci{
1498c2ecf20Sopenharmony_ci	u32 tmp;
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	/* Disable DAC for Graphics Stream Control */
1528c2ecf20Sopenharmony_ci	tmp = (STG_READ_REG(DACStreamCtrl)) & ~SET_BIT(0);
1538c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACStreamCtrl, tmp);
1548c2ecf20Sopenharmony_ci}
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_civoid EnableRamdacOutput(volatile STG4000REG __iomem * pSTGReg)
1578c2ecf20Sopenharmony_ci{
1588c2ecf20Sopenharmony_ci	u32 tmp;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	/* Enable DAC for Graphics Stream Control */
1618c2ecf20Sopenharmony_ci	tmp = (STG_READ_REG(DACStreamCtrl)) | SET_BIT(0);
1628c2ecf20Sopenharmony_ci	STG_WRITE_REG(DACStreamCtrl, tmp);
1638c2ecf20Sopenharmony_ci}
164