Merge remote-tracking branch 'staging/staging-next'
[deliverable/linux.git] / drivers / staging / sm750fb / ddk750_mode.c
CommitLineData
81dee67e
SM
1
2#include "ddk750_help.h"
3#include "ddk750_reg.h"
4#include "ddk750_mode.h"
5#include "ddk750_chip.h"
6
7/*
8 SM750LE only:
9 This function takes care extra registers and bit fields required to set
10 up a mode in SM750LE
11
12 Explanation about Display Control register:
13 HW only supports 7 predefined pixel clocks, and clock select is
14 in bit 29:27 of Display Control register.
15*/
16static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, unsigned long dispControl)
17{
18 unsigned long x, y;
19
20 x = pModeParam->horizontal_display_end;
21 y = pModeParam->vertical_display_end;
22
78376535
JL
23 /* SM750LE has to set up the top-left and bottom-right
24 registers as well.
25 Note that normal SM750/SM718 only use those two register for
26 auto-centering mode.
27 */
85943dae 28 POKE32(CRT_AUTO_CENTERING_TL, 0);
78376535
JL
29
30 POKE32(CRT_AUTO_CENTERING_BR,
aed4b787
MR
31 (((y - 1) << CRT_AUTO_CENTERING_BR_BOTTOM_SHIFT) &
32 CRT_AUTO_CENTERING_BR_BOTTOM_MASK) |
33 ((x - 1) & CRT_AUTO_CENTERING_BR_RIGHT_MASK));
78376535
JL
34
35 /* Assume common fields in dispControl have been properly set before
36 calling this function.
37 This function only sets the extra fields in dispControl.
38 */
81dee67e
SM
39
40 /* Clear bit 29:27 of display control register */
cdce1f18 41 dispControl &= ~CRT_DISPLAY_CTRL_CLK_MASK;
81dee67e
SM
42
43 /* Set bit 29:27 of display control register for the right clock */
fbb8c963 44 /* Note that SM750LE only need to supported 7 resolutions. */
8332d94c 45 if (x == 800 && y == 600)
cdce1f18 46 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL41;
81dee67e 47 else if (x == 1024 && y == 768)
cdce1f18 48 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL65;
81dee67e 49 else if (x == 1152 && y == 864)
cdce1f18 50 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL80;
81dee67e 51 else if (x == 1280 && y == 768)
cdce1f18 52 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL80;
81dee67e 53 else if (x == 1280 && y == 720)
cdce1f18 54 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL74;
81dee67e 55 else if (x == 1280 && y == 960)
cdce1f18 56 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL108;
81dee67e 57 else if (x == 1280 && y == 1024)
cdce1f18 58 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL108;
81dee67e 59 else /* default to VGA clock */
cdce1f18 60 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL25;
81dee67e
SM
61
62 /* Set bit 25:24 of display controller */
d8264edf 63 dispControl |= (CRT_DISPLAY_CTRL_CRTSELECT | CRT_DISPLAY_CTRL_RGBBIT);
81dee67e 64
78376535 65 /* Set bit 14 of display controller */
992f9614 66 dispControl |= DISPLAY_CTRL_CLOCK_PHASE;
81dee67e 67
78376535 68 POKE32(CRT_DISPLAY_CTRL, dispControl);
81dee67e
SM
69
70 return dispControl;
71}
72
73
74
75/* only timing related registers will be programed */
eb0f4271 76static int programModeRegisters(mode_parameter_t *pModeParam, pll_value_t *pll)
81dee67e
SM
77{
78 int ret = 0;
79 int cnt = 0;
c436e6ba 80 unsigned int tmp, reg;
40403c1b 81
259fef35 82 if (pll->clockType == SECONDARY_PLL) {
81dee67e 83 /* programe secondary pixel clock */
195d2b64 84 POKE32(CRT_PLL_CTRL, formatPllReg(pll));
78376535 85 POKE32(CRT_HORIZONTAL_TOTAL,
32849f85
MR
86 (((pModeParam->horizontal_total - 1) <<
87 CRT_HORIZONTAL_TOTAL_TOTAL_SHIFT) &
88 CRT_HORIZONTAL_TOTAL_TOTAL_MASK) |
89 ((pModeParam->horizontal_display_end - 1) &
90 CRT_HORIZONTAL_TOTAL_DISPLAY_END_MASK));
81dee67e 91
78376535 92 POKE32(CRT_HORIZONTAL_SYNC,
1adb3c23
MR
93 ((pModeParam->horizontal_sync_width <<
94 CRT_HORIZONTAL_SYNC_WIDTH_SHIFT) &
95 CRT_HORIZONTAL_SYNC_WIDTH_MASK) |
96 ((pModeParam->horizontal_sync_start - 1) &
97 CRT_HORIZONTAL_SYNC_START_MASK));
81dee67e 98
78376535 99 POKE32(CRT_VERTICAL_TOTAL,
3d5158d3
MR
100 (((pModeParam->vertical_total - 1) <<
101 CRT_VERTICAL_TOTAL_TOTAL_SHIFT) &
102 CRT_VERTICAL_TOTAL_TOTAL_MASK) |
103 ((pModeParam->vertical_display_end - 1) &
104 CRT_VERTICAL_TOTAL_DISPLAY_END_MASK));
81dee67e 105
78376535 106 POKE32(CRT_VERTICAL_SYNC,
620c3912
MR
107 ((pModeParam->vertical_sync_height <<
108 CRT_VERTICAL_SYNC_HEIGHT_SHIFT) &
109 CRT_VERTICAL_SYNC_HEIGHT_MASK) |
110 ((pModeParam->vertical_sync_start - 1) &
111 CRT_VERTICAL_SYNC_START_MASK));
81dee67e
SM
112
113
6fba39cf
MR
114 tmp = DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE;
115 if (pModeParam->vertical_sync_polarity)
116 tmp |= DISPLAY_CTRL_VSYNC_PHASE;
117 if (pModeParam->horizontal_sync_polarity)
118 tmp |= DISPLAY_CTRL_HSYNC_PHASE;
81dee67e 119
8c11f5a2 120 if (getChipType() == SM750LE) {
c436e6ba 121 displayControlAdjust_SM750LE(pModeParam, tmp);
6338a781 122 } else {
6fba39cf
MR
123 reg = PEEK32(CRT_DISPLAY_CTRL) &
124 ~(DISPLAY_CTRL_VSYNC_PHASE |
125 DISPLAY_CTRL_HSYNC_PHASE |
126 DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE);
81dee67e 127
c436e6ba 128 POKE32(CRT_DISPLAY_CTRL, tmp | reg);
81dee67e
SM
129 }
130
259fef35 131 } else if (pll->clockType == PRIMARY_PLL) {
c436e6ba 132 unsigned int reserved;
40403c1b 133
195d2b64 134 POKE32(PANEL_PLL_CTRL, formatPllReg(pll));
81dee67e 135
60112069
MR
136 reg = ((pModeParam->horizontal_total - 1) <<
137 PANEL_HORIZONTAL_TOTAL_TOTAL_SHIFT) &
138 PANEL_HORIZONTAL_TOTAL_TOTAL_MASK;
139 reg |= ((pModeParam->horizontal_display_end - 1) &
140 PANEL_HORIZONTAL_TOTAL_DISPLAY_END_MASK);
141 POKE32(PANEL_HORIZONTAL_TOTAL, reg);
81dee67e 142
78376535 143 POKE32(PANEL_HORIZONTAL_SYNC,
a6f17bc4
MR
144 ((pModeParam->horizontal_sync_width <<
145 PANEL_HORIZONTAL_SYNC_WIDTH_SHIFT) &
146 PANEL_HORIZONTAL_SYNC_WIDTH_MASK) |
147 ((pModeParam->horizontal_sync_start - 1) &
148 PANEL_HORIZONTAL_SYNC_START_MASK));
81dee67e 149
78376535 150 POKE32(PANEL_VERTICAL_TOTAL,
6014a31d
MR
151 (((pModeParam->vertical_total - 1) <<
152 PANEL_VERTICAL_TOTAL_TOTAL_SHIFT) &
153 PANEL_VERTICAL_TOTAL_TOTAL_MASK) |
154 ((pModeParam->vertical_display_end - 1) &
155 PANEL_VERTICAL_TOTAL_DISPLAY_END_MASK));
81dee67e 156
78376535 157 POKE32(PANEL_VERTICAL_SYNC,
8ffe4610
MR
158 ((pModeParam->vertical_sync_height <<
159 PANEL_VERTICAL_SYNC_HEIGHT_SHIFT) &
160 PANEL_VERTICAL_SYNC_HEIGHT_MASK) |
161 ((pModeParam->vertical_sync_start - 1) &
162 PANEL_VERTICAL_SYNC_START_MASK));
81dee67e 163
6fba39cf
MR
164 tmp = DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE;
165 if (pModeParam->vertical_sync_polarity)
166 tmp |= DISPLAY_CTRL_VSYNC_PHASE;
167 if (pModeParam->horizontal_sync_polarity)
168 tmp |= DISPLAY_CTRL_HSYNC_PHASE;
169 if (pModeParam->clock_phase_polarity)
170 tmp |= DISPLAY_CTRL_CLOCK_PHASE;
78376535 171
9bd2c86b 172 reserved = PANEL_DISPLAY_CTRL_RESERVED_MASK |
6fba39cf 173 PANEL_DISPLAY_CTRL_VSYNC;
81dee67e 174
6fba39cf
MR
175 reg = (PEEK32(PANEL_DISPLAY_CTRL) & ~reserved) &
176 ~(DISPLAY_CTRL_CLOCK_PHASE | DISPLAY_CTRL_VSYNC_PHASE |
177 DISPLAY_CTRL_HSYNC_PHASE | DISPLAY_CTRL_TIMING |
178 DISPLAY_CTRL_PLANE);
81dee67e
SM
179
180 /* May a hardware bug or just my test chip (not confirmed).
181 * PANEL_DISPLAY_CTRL register seems requiring few writes
69e98df7 182 * before a value can be successfully written in.
81dee67e
SM
183 * Added some masks to mask out the reserved bits.
184 * Note: This problem happens by design. The hardware will wait for the
185 * next vertical sync to turn on/off the plane.
186 */
187
c436e6ba 188 POKE32(PANEL_DISPLAY_CTRL, tmp | reg);
cfac7d6a 189
c436e6ba
MR
190 while ((PEEK32(PANEL_DISPLAY_CTRL) & ~reserved) !=
191 (tmp | reg)) {
81dee67e 192 cnt++;
9ccc5f44 193 if (cnt > 1000)
81dee67e 194 break;
c436e6ba 195 POKE32(PANEL_DISPLAY_CTRL, tmp | reg);
81dee67e 196 }
259fef35 197 } else {
81dee67e
SM
198 ret = -1;
199 }
200 return ret;
201}
202
eb0f4271 203int ddk750_setModeTiming(mode_parameter_t *parm, clock_type_t clock)
81dee67e
SM
204{
205 pll_value_t pll;
206 unsigned int uiActualPixelClk;
40403c1b 207
81dee67e
SM
208 pll.inputFreq = DEFAULT_INPUT_CLOCK;
209 pll.clockType = clock;
210
195d2b64 211 uiActualPixelClk = calcPllValue(parm->pixel_clock, &pll);
8c11f5a2 212 if (getChipType() == SM750LE) {
81dee67e 213 /* set graphic mode via IO method */
195d2b64
IA
214 outb_p(0x88, 0x3d4);
215 outb_p(0x06, 0x3d5);
81dee67e 216 }
195d2b64 217 programModeRegisters(parm, &pll);
81dee67e
SM
218 return 0;
219}
220
221
This page took 0.233903 seconds and 5 git commands to generate.