Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
STG4000VTG.c
Go to the documentation of this file.
1 /*
2  * linux/drivers/video/kyro/STG4000VTG.c
3  *
4  * Copyright (C) 2002 STMicroelectronics
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License. See the file COPYING in the main directory of this archive
8  * for more details.
9  */
10 
11 #include <linux/types.h>
12 #include <video/kyro.h>
13 
14 #include "STG4000Reg.h"
15 #include "STG4000Interface.h"
16 
17 void DisableVGA(volatile STG4000REG __iomem *pSTGReg)
18 {
19  u32 tmp;
20  volatile u32 count = 0, i;
21 
22  /* Reset the VGA registers */
23  tmp = STG_READ_REG(SoftwareReset);
24  CLEAR_BIT(8);
25  STG_WRITE_REG(SoftwareReset, tmp);
26 
27  /* Just for Delay */
28  for (i = 0; i < 1000; i++) {
29  count++;
30  }
31 
32  /* Pull-out the VGA registers from reset */
33  tmp = STG_READ_REG(SoftwareReset);
34  tmp |= SET_BIT(8);
35  STG_WRITE_REG(SoftwareReset, tmp);
36 }
37 
38 void StopVTG(volatile STG4000REG __iomem *pSTGReg)
39 {
40  u32 tmp = 0;
41 
42  /* Stop Ver and Hor Sync Generator */
43  tmp = (STG_READ_REG(DACSyncCtrl)) | SET_BIT(0) | SET_BIT(2);
44  CLEAR_BIT(31);
45  STG_WRITE_REG(DACSyncCtrl, tmp);
46 }
47 
48 void StartVTG(volatile STG4000REG __iomem *pSTGReg)
49 {
50  u32 tmp = 0;
51 
52  /* Start Ver and Hor Sync Generator */
53  tmp = ((STG_READ_REG(DACSyncCtrl)) | SET_BIT(31));
54  CLEAR_BIT(0);
55  CLEAR_BIT(2);
56  STG_WRITE_REG(DACSyncCtrl, tmp);
57 }
58 
59 void SetupVTG(volatile STG4000REG __iomem *pSTGReg,
60  const struct kyrofb_info * pTiming)
61 {
62  u32 tmp = 0;
63  u32 margins = 0;
64  u32 ulBorder;
65  u32 xRes = pTiming->XRES;
66  u32 yRes = pTiming->YRES;
67 
68  /* Horizontal */
69  u32 HAddrTime, HRightBorder, HLeftBorder;
70  u32 HBackPorcStrt, HFrontPorchStrt, HTotal,
71  HLeftBorderStrt, HRightBorderStrt, HDisplayStrt;
72 
73  /* Vertical */
74  u32 VDisplayStrt, VBottomBorder, VTopBorder;
75  u32 VBackPorchStrt, VTotal, VTopBorderStrt,
76  VFrontPorchStrt, VBottomBorderStrt, VAddrTime;
77 
78  /* Need to calculate the right border */
79  if ((xRes == 640) && (yRes == 480)) {
80  if ((pTiming->VFREQ == 60) || (pTiming->VFREQ == 72)) {
81  margins = 8;
82  }
83  }
84 
85  /* Work out the Border */
86  ulBorder =
87  (pTiming->HTot -
88  (pTiming->HST + (pTiming->HBP - margins) + xRes +
89  (pTiming->HFP - margins))) >> 1;
90 
91  /* Border the same for Vertical and Horizontal */
92  VBottomBorder = HLeftBorder = VTopBorder = HRightBorder = ulBorder;
93 
94  /************ Get Timing values for Horizontal ******************/
95  HAddrTime = xRes;
96  HBackPorcStrt = pTiming->HST;
97  HTotal = pTiming->HTot;
98  HDisplayStrt =
99  pTiming->HST + (pTiming->HBP - margins) + HLeftBorder;
100  HLeftBorderStrt = HDisplayStrt - HLeftBorder;
101  HFrontPorchStrt =
102  pTiming->HST + (pTiming->HBP - margins) + HLeftBorder +
103  HAddrTime + HRightBorder;
104  HRightBorderStrt = HFrontPorchStrt - HRightBorder;
105 
106  /************ Get Timing values for Vertical ******************/
107  VAddrTime = yRes;
108  VBackPorchStrt = pTiming->VST;
109  VTotal = pTiming->VTot;
110  VDisplayStrt =
111  pTiming->VST + (pTiming->VBP - margins) + VTopBorder;
112  VTopBorderStrt = VDisplayStrt - VTopBorder;
113  VFrontPorchStrt =
114  pTiming->VST + (pTiming->VBP - margins) + VTopBorder +
115  VAddrTime + VBottomBorder;
116  VBottomBorderStrt = VFrontPorchStrt - VBottomBorder;
117 
118  /* Set Hor Timing 1, 2, 3 */
119  tmp = STG_READ_REG(DACHorTim1);
120  CLEAR_BITS_FRM_TO(0, 11);
121  CLEAR_BITS_FRM_TO(16, 27);
122  tmp |= (HTotal) | (HBackPorcStrt << 16);
123  STG_WRITE_REG(DACHorTim1, tmp);
124 
125  tmp = STG_READ_REG(DACHorTim2);
126  CLEAR_BITS_FRM_TO(0, 11);
127  CLEAR_BITS_FRM_TO(16, 27);
128  tmp |= (HDisplayStrt << 16) | HLeftBorderStrt;
129  STG_WRITE_REG(DACHorTim2, tmp);
130 
131  tmp = STG_READ_REG(DACHorTim3);
132  CLEAR_BITS_FRM_TO(0, 11);
133  CLEAR_BITS_FRM_TO(16, 27);
134  tmp |= (HFrontPorchStrt << 16) | HRightBorderStrt;
135  STG_WRITE_REG(DACHorTim3, tmp);
136 
137  /* Set Ver Timing 1, 2, 3 */
138  tmp = STG_READ_REG(DACVerTim1);
139  CLEAR_BITS_FRM_TO(0, 11);
140  CLEAR_BITS_FRM_TO(16, 27);
141  tmp |= (VBackPorchStrt << 16) | (VTotal);
142  STG_WRITE_REG(DACVerTim1, tmp);
143 
144  tmp = STG_READ_REG(DACVerTim2);
145  CLEAR_BITS_FRM_TO(0, 11);
146  CLEAR_BITS_FRM_TO(16, 27);
147  tmp |= (VDisplayStrt << 16) | VTopBorderStrt;
148  STG_WRITE_REG(DACVerTim2, tmp);
149 
150  tmp = STG_READ_REG(DACVerTim3);
151  CLEAR_BITS_FRM_TO(0, 11);
152  CLEAR_BITS_FRM_TO(16, 27);
153  tmp |= (VFrontPorchStrt << 16) | VBottomBorderStrt;
154  STG_WRITE_REG(DACVerTim3, tmp);
155 
156  /* Set Verical and Horizontal Polarity */
157  tmp = STG_READ_REG(DACSyncCtrl) | SET_BIT(3) | SET_BIT(1);
158 
159  if ((pTiming->HSP > 0) && (pTiming->VSP < 0)) { /* +hsync -vsync */
160  tmp &= ~0x8;
161  } else if ((pTiming->HSP < 0) && (pTiming->VSP > 0)) { /* -hsync +vsync */
162  tmp &= ~0x2;
163  } else if ((pTiming->HSP < 0) && (pTiming->VSP < 0)) { /* -hsync -vsync */
164  tmp &= ~0xA;
165  } else if ((pTiming->HSP > 0) && (pTiming->VSP > 0)) { /* +hsync -vsync */
166  tmp &= ~0x0;
167  }
168 
169  STG_WRITE_REG(DACSyncCtrl, tmp);
170 }