]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/staging/sm750fb/ddk750_chip.c
staging: sm750fb: change definition of PANEL_PLANE_BR fields
[mirror_ubuntu-artful-kernel.git] / drivers / staging / sm750fb / ddk750_chip.c
CommitLineData
4cf26d85
MR
1#include <linux/sizes.h>
2
81dee67e
SM
3#include "ddk750_help.h"
4#include "ddk750_reg.h"
5#include "ddk750_chip.h"
6#include "ddk750_power.h"
81dee67e 7
6fa7db83 8logical_chip_type_t getChipType(void)
81dee67e
SM
9{
10 unsigned short physicalID;
11 char physicalRev;
12 logical_chip_type_t chip;
13
5ee35ea7 14 physicalID = devId750; /* either 0x718 or 0x750 */
81dee67e
SM
15 physicalRev = revId750;
16
de99befd 17 if (physicalID == 0x718)
de99befd 18 chip = SM718;
9767fc51 19 else if (physicalID == 0x750) {
de99befd 20 chip = SM750;
81dee67e 21 /* SM750 and SM750LE are different in their revision ID only. */
9767fc51 22 if (physicalRev == SM750LE_REVISION_ID)
81dee67e 23 chip = SM750LE;
9767fc51 24 } else
de99befd 25 chip = SM_UNKNOWN;
81dee67e
SM
26
27 return chip;
28}
29
7092d76f 30static unsigned int get_mxclk_freq(void)
81dee67e 31{
7751e0e2
MR
32 unsigned int pll_reg;
33 unsigned int M, N, OD, POD;
34
82736d22 35 if (getChipType() == SM750LE)
81dee67e 36 return MHz(130);
81dee67e 37
7751e0e2 38 pll_reg = PEEK32(MXCLK_PLL_CTRL);
cdd5df64
MR
39 M = (pll_reg & PLL_CTRL_M_MASK) >> PLL_CTRL_M_SHIFT;
40 N = (pll_reg & PLL_CTRL_N_MASK) >> PLL_CTRL_M_SHIFT;
41 OD = (pll_reg & PLL_CTRL_OD_MASK) >> PLL_CTRL_OD_SHIFT;
42 POD = (pll_reg & PLL_CTRL_POD_MASK) >> PLL_CTRL_POD_SHIFT;
7751e0e2
MR
43
44 return DEFAULT_INPUT_CLOCK * M / N / (1 << OD) / (1 << POD);
81dee67e
SM
45}
46
81dee67e
SM
47/*
48 * This function set up the main chip clock.
49 *
50 * Input: Frequency to be set.
51 */
fb6f37a8 52static void setChipClock(unsigned int frequency)
81dee67e 53{
de99befd
RN
54 pll_value_t pll;
55 unsigned int ulActualMxClk;
cfac7d6a 56
de99befd
RN
57 /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */
58 if (getChipType() == SM750LE)
59 return;
81dee67e 60
59f08407 61 if (frequency) {
de99befd
RN
62 /*
63 * Set up PLL, a structure to hold the value to be set in clocks.
64 */
65 pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */
66 pll.clockType = MXCLK_PLL;
67
68 /*
69 * Call calcPllValue() to fill up the other fields for PLL structure.
70 * Sometime, the chip cannot set up the exact clock required by User.
71 * Return value from calcPllValue() gives the actual possible clock.
72 */
73 ulActualMxClk = calcPllValue(frequency, &pll);
74
75 /* Master Clock Control: MXCLK_PLL */
76 POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll));
77 }
81dee67e
SM
78}
79
fb6f37a8 80static void setMemoryClock(unsigned int frequency)
81dee67e 81{
19aa2113 82 unsigned int reg, divisor;
cfac7d6a 83
81dee67e
SM
84 /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */
85 if (getChipType() == SM750LE)
86 return;
cfac7d6a 87
59f08407 88 if (frequency) {
de99befd
RN
89 /* Set the frequency to the maximum frequency that the DDR Memory can take
90 which is 336MHz. */
91 if (frequency > MHz(336))
92 frequency = MHz(336);
93
94 /* Calculate the divisor */
b02f9240 95 divisor = roundedDiv(get_mxclk_freq(), frequency);
de99befd
RN
96
97 /* Set the corresponding divisor in the register. */
6e8aa4a1 98 reg = PEEK32(CURRENT_GATE) & ~CURRENT_GATE_M2XCLK_MASK;
c107243b 99 switch (divisor) {
de99befd
RN
100 default:
101 case 1:
6e8aa4a1 102 reg |= CURRENT_GATE_M2XCLK_DIV_1;
de99befd
RN
103 break;
104 case 2:
6e8aa4a1 105 reg |= CURRENT_GATE_M2XCLK_DIV_2;
de99befd
RN
106 break;
107 case 3:
6e8aa4a1 108 reg |= CURRENT_GATE_M2XCLK_DIV_3;
de99befd
RN
109 break;
110 case 4:
6e8aa4a1 111 reg |= CURRENT_GATE_M2XCLK_DIV_4;
de99befd
RN
112 break;
113 }
114
19aa2113 115 setCurrentGate(reg);
de99befd 116 }
81dee67e
SM
117}
118
81dee67e
SM
119/*
120 * This function set up the master clock (MCLK).
121 *
122 * Input: Frequency to be set.
123 *
124 * NOTE:
125 * The maximum frequency the engine can run is 168MHz.
126 */
fb6f37a8 127static void setMasterClock(unsigned int frequency)
81dee67e 128{
19aa2113 129 unsigned int reg, divisor;
cfac7d6a 130
81dee67e
SM
131 /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */
132 if (getChipType() == SM750LE)
133 return;
cfac7d6a 134
59f08407 135 if (frequency) {
de99befd
RN
136 /* Set the frequency to the maximum frequency that the SM750 engine can
137 run, which is about 190 MHz. */
138 if (frequency > MHz(190))
139 frequency = MHz(190);
140
141 /* Calculate the divisor */
b02f9240 142 divisor = roundedDiv(get_mxclk_freq(), frequency);
de99befd
RN
143
144 /* Set the corresponding divisor in the register. */
6e8aa4a1 145 reg = PEEK32(CURRENT_GATE) & ~CURRENT_GATE_MCLK_MASK;
c107243b 146 switch (divisor) {
de99befd
RN
147 default:
148 case 3:
6e8aa4a1 149 reg |= CURRENT_GATE_MCLK_DIV_3;
de99befd
RN
150 break;
151 case 4:
6e8aa4a1 152 reg |= CURRENT_GATE_MCLK_DIV_4;
de99befd
RN
153 break;
154 case 6:
6e8aa4a1 155 reg |= CURRENT_GATE_MCLK_DIV_6;
de99befd
RN
156 break;
157 case 8:
6e8aa4a1 158 reg |= CURRENT_GATE_MCLK_DIV_8;
de99befd
RN
159 break;
160 }
161
19aa2113 162 setCurrentGate(reg);
de99befd 163 }
81dee67e
SM
164}
165
6fa7db83 166unsigned int ddk750_getVMSize(void)
81dee67e
SM
167{
168 unsigned int reg;
169 unsigned int data;
170
171 /* sm750le only use 64 mb memory*/
82736d22 172 if (getChipType() == SM750LE)
4cf26d85 173 return SZ_64M;
81dee67e
SM
174
175 /* for 750,always use power mode0*/
176 reg = PEEK32(MODE0_GATE);
05e9d9ea 177 reg |= MODE0_GATE_GPIO;
c04051f5 178 POKE32(MODE0_GATE, reg);
81dee67e
SM
179
180 /* get frame buffer size from GPIO */
5538d5c8 181 reg = PEEK32(MISC_CTRL) & MISC_CTRL_LOCALMEM_SIZE_MASK;
c107243b 182 switch (reg) {
ae59c465 183 case MISC_CTRL_LOCALMEM_SIZE_8M:
4cf26d85 184 data = SZ_8M; break; /* 8 Mega byte */
ae59c465 185 case MISC_CTRL_LOCALMEM_SIZE_16M:
4cf26d85 186 data = SZ_16M; break; /* 16 Mega byte */
ae59c465 187 case MISC_CTRL_LOCALMEM_SIZE_32M:
4cf26d85 188 data = SZ_32M; break; /* 32 Mega byte */
ae59c465 189 case MISC_CTRL_LOCALMEM_SIZE_64M:
4cf26d85 190 data = SZ_64M; break; /* 64 Mega byte */
ae59c465 191 default:
e261e69e
AKC
192 data = 0;
193 break;
81dee67e
SM
194 }
195 return data;
81dee67e
SM
196}
197
f8da055a 198int ddk750_initHw(initchip_param_t *pInitParam)
81dee67e 199{
8bc728cf 200 unsigned int reg;
81dee67e 201
8332d94c 202 if (pInitParam->powerMode != 0)
81dee67e
SM
203 pInitParam->powerMode = 0;
204 setPowerMode(pInitParam->powerMode);
205
206 /* Enable display power gate & LOCALMEM power gate*/
8bc728cf 207 reg = PEEK32(CURRENT_GATE);
90946e52 208 reg |= (CURRENT_GATE_DISPLAY | CURRENT_GATE_LOCALMEM);
8bc728cf 209 setCurrentGate(reg);
81dee67e 210
82736d22 211 if (getChipType() != SM750LE) {
81dee67e 212 /* set panel pll and graphic mode via mmio_88 */
8bc728cf 213 reg = PEEK32(VGA_CONFIGURATION);
d9798143 214 reg |= (VGA_CONFIGURATION_PLL | VGA_CONFIGURATION_MODE);
8bc728cf 215 POKE32(VGA_CONFIGURATION, reg);
9767fc51 216 } else {
31296ba5 217#if defined(__i386__) || defined(__x86_64__)
81dee67e 218 /* set graphic mode via IO method */
c04051f5
HF
219 outb_p(0x88, 0x3d4);
220 outb_p(0x06, 0x3d5);
81dee67e
SM
221#endif
222 }
223
224 /* Set the Main Chip Clock */
225 setChipClock(MHz((unsigned int)pInitParam->chipClock));
226
227 /* Set up memory clock. */
228 setMemoryClock(MHz(pInitParam->memClock));
229
230 /* Set up master clock */
231 setMasterClock(MHz(pInitParam->masterClock));
232
233
234 /* Reset the memory controller. If the memory controller is not reset in SM750,
235 the system might hang when sw accesses the memory.
236 The memory should be resetted after changing the MXCLK.
237 */
9767fc51 238 if (pInitParam->resetMemory == 1) {
8bc728cf 239 reg = PEEK32(MISC_CTRL);
5372350b 240 reg &= ~MISC_CTRL_LOCALMEM_RESET;
8bc728cf 241 POKE32(MISC_CTRL, reg);
81dee67e 242
5372350b 243 reg |= MISC_CTRL_LOCALMEM_RESET;
8bc728cf 244 POKE32(MISC_CTRL, reg);
81dee67e
SM
245 }
246
9767fc51 247 if (pInitParam->setAllEngOff == 1) {
81dee67e
SM
248 enable2DEngine(0);
249
250 /* Disable Overlay, if a former application left it on */
8bc728cf 251 reg = PEEK32(VIDEO_DISPLAY_CTRL);
6fba39cf 252 reg &= ~DISPLAY_CTRL_PLANE;
8bc728cf 253 POKE32(VIDEO_DISPLAY_CTRL, reg);
81dee67e
SM
254
255 /* Disable video alpha, if a former application left it on */
8bc728cf 256 reg = PEEK32(VIDEO_ALPHA_DISPLAY_CTRL);
6fba39cf 257 reg &= ~DISPLAY_CTRL_PLANE;
8bc728cf 258 POKE32(VIDEO_ALPHA_DISPLAY_CTRL, reg);
81dee67e
SM
259
260 /* Disable alpha plane, if a former application left it on */
8bc728cf 261 reg = PEEK32(ALPHA_DISPLAY_CTRL);
6fba39cf 262 reg &= ~DISPLAY_CTRL_PLANE;
8bc728cf 263 POKE32(ALPHA_DISPLAY_CTRL, reg);
81dee67e 264
81dee67e 265 /* Disable DMA Channel, if a former application left it on */
8bc728cf
MR
266 reg = PEEK32(DMA_ABORT_INTERRUPT);
267 reg = FIELD_SET(reg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT);
268 POKE32(DMA_ABORT_INTERRUPT, reg);
81dee67e
SM
269
270 /* Disable DMA Power, if a former application left it on */
271 enableDMA(0);
272 }
273
274 /* We can add more initialization as needed. */
275
276 return 0;
277}
278
81dee67e
SM
279/*
280 monk liu @ 4/6/2011:
281 re-write the calculatePLL function of ddk750.
282 the original version function does not use some mathematics tricks and shortcut
283 when it doing the calculation of the best N,M,D combination
284 I think this version gives a little upgrade in speed
285
286 750 pll clock formular:
287 Request Clock = (Input Clock * M )/(N * X)
288
289 Input Clock = 14318181 hz
290 X = 2 power D
291 D ={0,1,2,3,4,5,6}
292 M = {1,...,255}
293 N = {2,...,15}
294*/
c04051f5 295unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll)
81dee67e 296{
de99befd 297 /* as sm750 register definition, N located in 2,15 and M located in 1,255 */
c04051f5 298 int N, M, X, d;
43ce0b53 299 int mini_diff;
c04051f5
HF
300 unsigned int RN, quo, rem, fl_quo;
301 unsigned int input, request;
302 unsigned int tmpClock, ret;
a61dc139
MR
303 const int max_OD = 3;
304 int max_d;
81dee67e 305
9767fc51 306 if (getChipType() == SM750LE) {
de99befd
RN
307 /* SM750LE don't have prgrammable PLL and M/N values to work on.
308 Just return the requested clock. */
309 return request_orig;
310 }
81dee67e
SM
311
312 ret = 0;
43ce0b53 313 mini_diff = ~0;
81dee67e
SM
314 request = request_orig / 1000;
315 input = pll->inputFreq / 1000;
316
317 /* for MXCLK register , no POD provided, so need be treated differently */
a61dc139
MR
318 if (pll->clockType == MXCLK_PLL)
319 max_d = 3;
81dee67e 320
ce02a16a 321 for (N = 15; N > 1; N--) {
81dee67e
SM
322 /* RN will not exceed maximum long if @request <= 285 MHZ (for 32bit cpu) */
323 RN = N * request;
324 quo = RN / input;
325 rem = RN % input;/* rem always small than 14318181 */
6ab5b6d1 326 fl_quo = (rem * 10000 / input);
81dee67e 327
a61dc139
MR
328 for (d = max_d; d >= 0; d--) {
329 X = (1 << d);
f40917ea 330 M = quo * X;
81dee67e
SM
331 M += fl_quo * X / 10000;
332 /* round step */
07387cba 333 M += (fl_quo * X % 10000) > 5000 ? 1 : 0;
82736d22 334 if (M < 256 && M > 0) {
81dee67e 335 unsigned int diff;
40403c1b 336
6ab5b6d1 337 tmpClock = pll->inputFreq * M / N / X;
c04051f5 338 diff = absDiff(tmpClock, request_orig);
43ce0b53 339 if (diff < mini_diff) {
81dee67e
SM
340 pll->M = M;
341 pll->N = N;
a61dc139
MR
342 pll->POD = 0;
343 if (d > max_OD)
344 pll->POD = d - max_OD;
345 pll->OD = d - pll->POD;
43ce0b53 346 mini_diff = diff;
81dee67e
SM
347 ret = tmpClock;
348 }
349 }
350 }
351 }
81dee67e
SM
352 return ret;
353}
354
81dee67e
SM
355unsigned int formatPllReg(pll_value_t *pPLL)
356{
cdd5df64
MR
357#ifndef VALIDATION_CHIP
358 unsigned int POD = pPLL->POD;
359#endif
360 unsigned int OD = pPLL->OD;
361 unsigned int M = pPLL->M;
362 unsigned int N = pPLL->N;
375b4d42 363 unsigned int reg = 0;
81dee67e 364
0c4d85fc
MR
365 /*
366 * Note that all PLL's have the same format. Here, we just use
367 * Panel PLL parameter to work out the bit fields in the
368 * register. On returning a 32 bit number, the value can be
369 * applied to any PLL in the calling function.
370 */
cdd5df64 371 reg = PLL_CTRL_POWER |
81dee67e 372#ifndef VALIDATION_CHIP
cdd5df64 373 ((POD << PLL_CTRL_POD_SHIFT) & PLL_CTRL_POD_MASK) |
81dee67e 374#endif
cdd5df64
MR
375 ((OD << PLL_CTRL_OD_SHIFT) & PLL_CTRL_OD_MASK) |
376 ((N << PLL_CTRL_N_SHIFT) & PLL_CTRL_N_MASK) |
377 ((M << PLL_CTRL_M_SHIFT) & PLL_CTRL_M_MASK);
81dee67e 378
375b4d42 379 return reg;
81dee67e
SM
380}
381
382