1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * linux/drivers/video/kyro/STG4000Ramdac.c
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) 2002 STMicroelectronics
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * This file is subject to the terms and conditions of the GNU General Public
7*4882a593Smuzhiyun * License. See the file COPYING in the main directory of this archive
8*4882a593Smuzhiyun * for more details.
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/kernel.h>
12*4882a593Smuzhiyun #include <linux/errno.h>
13*4882a593Smuzhiyun #include <linux/types.h>
14*4882a593Smuzhiyun #include <video/kyro.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include "STG4000Reg.h"
17*4882a593Smuzhiyun #include "STG4000Interface.h"
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun static u32 STG_PIXEL_BUS_WIDTH = 128; /* 128 bit bus width */
20*4882a593Smuzhiyun static u32 REF_CLOCK = 14318;
21*4882a593Smuzhiyun
InitialiseRamdac(volatile STG4000REG __iomem * pSTGReg,u32 displayDepth,u32 displayWidth,u32 displayHeight,s32 HSyncPolarity,s32 VSyncPolarity,u32 * pixelClock)22*4882a593Smuzhiyun int InitialiseRamdac(volatile STG4000REG __iomem * pSTGReg,
23*4882a593Smuzhiyun u32 displayDepth,
24*4882a593Smuzhiyun u32 displayWidth,
25*4882a593Smuzhiyun u32 displayHeight,
26*4882a593Smuzhiyun s32 HSyncPolarity,
27*4882a593Smuzhiyun s32 VSyncPolarity, u32 * pixelClock)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun u32 tmp = 0;
30*4882a593Smuzhiyun u32 F = 0, R = 0, P = 0;
31*4882a593Smuzhiyun u32 stride = 0;
32*4882a593Smuzhiyun u32 ulPdiv = 0;
33*4882a593Smuzhiyun u32 physicalPixelDepth = 0;
34*4882a593Smuzhiyun /* Make sure DAC is in Reset */
35*4882a593Smuzhiyun tmp = STG_READ_REG(SoftwareReset);
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun if (tmp & 0x1) {
38*4882a593Smuzhiyun CLEAR_BIT(1);
39*4882a593Smuzhiyun STG_WRITE_REG(SoftwareReset, tmp);
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun /* Set Pixel Format */
43*4882a593Smuzhiyun tmp = STG_READ_REG(DACPixelFormat);
44*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(0, 2);
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun /* Set LUT not used from 16bpp to 32 bpp ??? */
47*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(8, 9);
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun switch (displayDepth) {
50*4882a593Smuzhiyun case 16:
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun physicalPixelDepth = 16;
53*4882a593Smuzhiyun tmp |= _16BPP;
54*4882a593Smuzhiyun break;
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun case 32:
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun /* Set for 32 bits per pixel */
59*4882a593Smuzhiyun physicalPixelDepth = 32;
60*4882a593Smuzhiyun tmp |= _32BPP;
61*4882a593Smuzhiyun break;
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun default:
64*4882a593Smuzhiyun return -EINVAL;
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun STG_WRITE_REG(DACPixelFormat, tmp);
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun /* Workout Bus transfer bandwidth according to pixel format */
70*4882a593Smuzhiyun ulPdiv = STG_PIXEL_BUS_WIDTH / physicalPixelDepth;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /* Get Screen Stride in pixels */
73*4882a593Smuzhiyun stride = displayWidth;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun /* Set Primary size info */
76*4882a593Smuzhiyun tmp = STG_READ_REG(DACPrimSize);
77*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(0, 10);
78*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(12, 31);
79*4882a593Smuzhiyun tmp |=
80*4882a593Smuzhiyun ((((displayHeight - 1) << 12) | (((displayWidth / ulPdiv) -
81*4882a593Smuzhiyun 1) << 23))
82*4882a593Smuzhiyun | (stride / ulPdiv));
83*4882a593Smuzhiyun STG_WRITE_REG(DACPrimSize, tmp);
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun /* Set Pixel Clock */
87*4882a593Smuzhiyun *pixelClock = ProgramClock(REF_CLOCK, *pixelClock, &F, &R, &P);
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /* Set DAC PLL Mode */
90*4882a593Smuzhiyun tmp = STG_READ_REG(DACPLLMode);
91*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(0, 15);
92*4882a593Smuzhiyun /* tmp |= ((P-1) | ((F-2) << 2) | ((R-2) << 11)); */
93*4882a593Smuzhiyun tmp |= ((P) | ((F - 2) << 2) | ((R - 2) << 11));
94*4882a593Smuzhiyun STG_WRITE_REG(DACPLLMode, tmp);
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun /* Set Prim Address */
97*4882a593Smuzhiyun tmp = STG_READ_REG(DACPrimAddress);
98*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(0, 20);
99*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(20, 31);
100*4882a593Smuzhiyun STG_WRITE_REG(DACPrimAddress, tmp);
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun /* Set Cursor details with HW Cursor disabled */
103*4882a593Smuzhiyun tmp = STG_READ_REG(DACCursorCtrl);
104*4882a593Smuzhiyun tmp &= ~SET_BIT(31);
105*4882a593Smuzhiyun STG_WRITE_REG(DACCursorCtrl, tmp);
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun tmp = STG_READ_REG(DACCursorAddr);
108*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(0, 20);
109*4882a593Smuzhiyun STG_WRITE_REG(DACCursorAddr, tmp);
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun /* Set Video Window */
112*4882a593Smuzhiyun tmp = STG_READ_REG(DACVidWinStart);
113*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(0, 10);
114*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(16, 26);
115*4882a593Smuzhiyun STG_WRITE_REG(DACVidWinStart, tmp);
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun tmp = STG_READ_REG(DACVidWinEnd);
118*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(0, 10);
119*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(16, 26);
120*4882a593Smuzhiyun STG_WRITE_REG(DACVidWinEnd, tmp);
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun /* Set DAC Border Color to default */
123*4882a593Smuzhiyun tmp = STG_READ_REG(DACBorderColor);
124*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(0, 23);
125*4882a593Smuzhiyun STG_WRITE_REG(DACBorderColor, tmp);
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun /* Set Graphics and Overlay Burst Control */
128*4882a593Smuzhiyun STG_WRITE_REG(DACBurstCtrl, 0x0404);
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun /* Set CRC Trigger to default */
131*4882a593Smuzhiyun tmp = STG_READ_REG(DACCrcTrigger);
132*4882a593Smuzhiyun CLEAR_BIT(0);
133*4882a593Smuzhiyun STG_WRITE_REG(DACCrcTrigger, tmp);
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun /* Set Video Port Control to default */
136*4882a593Smuzhiyun tmp = STG_READ_REG(DigVidPortCtrl);
137*4882a593Smuzhiyun CLEAR_BIT(8);
138*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(16, 27);
139*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(1, 3);
140*4882a593Smuzhiyun CLEAR_BITS_FRM_TO(10, 11);
141*4882a593Smuzhiyun STG_WRITE_REG(DigVidPortCtrl, tmp);
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun return 0;
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun /* Ramdac control, turning output to the screen on and off */
DisableRamdacOutput(volatile STG4000REG __iomem * pSTGReg)147*4882a593Smuzhiyun void DisableRamdacOutput(volatile STG4000REG __iomem * pSTGReg)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun u32 tmp;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /* Disable DAC for Graphics Stream Control */
152*4882a593Smuzhiyun tmp = (STG_READ_REG(DACStreamCtrl)) & ~SET_BIT(0);
153*4882a593Smuzhiyun STG_WRITE_REG(DACStreamCtrl, tmp);
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
EnableRamdacOutput(volatile STG4000REG __iomem * pSTGReg)156*4882a593Smuzhiyun void EnableRamdacOutput(volatile STG4000REG __iomem * pSTGReg)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun u32 tmp;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun /* Enable DAC for Graphics Stream Control */
161*4882a593Smuzhiyun tmp = (STG_READ_REG(DACStreamCtrl)) | SET_BIT(0);
162*4882a593Smuzhiyun STG_WRITE_REG(DACStreamCtrl, tmp);
163*4882a593Smuzhiyun }
164