staging: sm750fb: Add space around '?'
[firefly-linux-kernel-4.4.55.git] / drivers / staging / sm750fb / ddk750_chip.c
1 #include <linux/sizes.h>
2
3 #include "ddk750_help.h"
4 #include "ddk750_reg.h"
5 #include "ddk750_chip.h"
6 #include "ddk750_power.h"
7 typedef struct _pllcalparam {
8         unsigned char power;/* d : 0~ 6*/
9         unsigned char pod;
10         unsigned char od;
11         unsigned char value;/* value of  2 power d (2^d) */
12 }
13 pllcalparam;
14
15
16 logical_chip_type_t getChipType(void)
17 {
18         unsigned short physicalID;
19         char physicalRev;
20         logical_chip_type_t chip;
21
22         physicalID = devId750; /* either 0x718 or 0x750 */
23         physicalRev = revId750;
24
25         if (physicalID == 0x718)
26                 chip = SM718;
27         else if (physicalID == 0x750) {
28                 chip = SM750;
29                 /* SM750 and SM750LE are different in their revision ID only. */
30                 if (physicalRev == SM750LE_REVISION_ID)
31                         chip = SM750LE;
32         } else
33                 chip = SM_UNKNOWN;
34
35         return chip;
36 }
37
38 static inline unsigned int calcPLL(pll_value_t *pPLL)
39 {
40         return (pPLL->inputFreq * pPLL->M / pPLL->N / (1 << pPLL->OD) /
41                 (1 << pPLL->POD));
42 }
43
44 static unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL)
45 {
46         unsigned int ulPllReg = 0;
47
48         pPLL->inputFreq = DEFAULT_INPUT_CLOCK;
49         pPLL->clockType = clockType;
50
51         switch (clockType) {
52         case MXCLK_PLL:
53                 ulPllReg = PEEK32(MXCLK_PLL_CTRL);
54                 break;
55         case PRIMARY_PLL:
56                 ulPllReg = PEEK32(PANEL_PLL_CTRL);
57                 break;
58         case SECONDARY_PLL:
59                 ulPllReg = PEEK32(CRT_PLL_CTRL);
60                 break;
61         case VGA0_PLL:
62                 ulPllReg = PEEK32(VGA_PLL0_CTRL);
63                 break;
64         case VGA1_PLL:
65                 ulPllReg = PEEK32(VGA_PLL1_CTRL);
66                 break;
67         }
68
69         pPLL->M = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, M);
70         pPLL->N = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, N);
71         pPLL->OD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, OD);
72         pPLL->POD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, POD);
73
74         return calcPLL(pPLL);
75 }
76
77
78 static unsigned int getChipClock(void)
79 {
80         pll_value_t pll;
81 #if 1
82         if (getChipType() == SM750LE)
83                 return MHz(130);
84 #endif
85
86         return getPllValue(MXCLK_PLL, &pll);
87 }
88
89
90 /*
91  * This function set up the main chip clock.
92  *
93  * Input: Frequency to be set.
94  */
95 static void setChipClock(unsigned int frequency)
96 {
97         pll_value_t pll;
98         unsigned int ulActualMxClk;
99 #if 1
100         /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */
101         if (getChipType() == SM750LE)
102                 return;
103 #endif
104
105         if (frequency) {
106                 /*
107                 * Set up PLL, a structure to hold the value to be set in clocks.
108                 */
109                 pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */
110                 pll.clockType = MXCLK_PLL;
111
112                 /*
113                 * Call calcPllValue() to fill up the other fields for PLL structure.
114                 * Sometime, the chip cannot set up the exact clock required by User.
115                 * Return value from calcPllValue() gives the actual possible clock.
116                 */
117                 ulActualMxClk = calcPllValue(frequency, &pll);
118
119                 /* Master Clock Control: MXCLK_PLL */
120                 POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll));
121         }
122 }
123
124
125
126 static void setMemoryClock(unsigned int frequency)
127 {
128         unsigned int ulReg, divisor;
129  #if 1
130         /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */
131         if (getChipType() == SM750LE)
132                 return;
133 #endif
134         if (frequency) {
135                 /* Set the frequency to the maximum frequency that the DDR Memory can take
136                 which is 336MHz. */
137                 if (frequency > MHz(336))
138                         frequency = MHz(336);
139
140                 /* Calculate the divisor */
141                 divisor = (unsigned int) roundedDiv(getChipClock(), frequency);
142
143                 /* Set the corresponding divisor in the register. */
144                 ulReg = PEEK32(CURRENT_GATE);
145                 switch (divisor) {
146                 default:
147                 case 1:
148                         ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_1);
149                         break;
150                 case 2:
151                         ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_2);
152                         break;
153                 case 3:
154                         ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_3);
155                         break;
156                 case 4:
157                         ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_4);
158                         break;
159                 }
160
161                 setCurrentGate(ulReg);
162         }
163 }
164
165
166 /*
167  * This function set up the master clock (MCLK).
168  *
169  * Input: Frequency to be set.
170  *
171  * NOTE:
172  *      The maximum frequency the engine can run is 168MHz.
173  */
174 static void setMasterClock(unsigned int frequency)
175 {
176         unsigned int ulReg, divisor;
177 #if 1
178         /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */
179         if (getChipType() == SM750LE)
180                 return;
181 #endif
182         if (frequency) {
183                 /* Set the frequency to the maximum frequency that the SM750 engine can
184                 run, which is about 190 MHz. */
185                 if (frequency > MHz(190))
186                         frequency = MHz(190);
187
188                 /* Calculate the divisor */
189                 divisor = (unsigned int) roundedDiv(getChipClock(), frequency);
190
191                 /* Set the corresponding divisor in the register. */
192                 ulReg = PEEK32(CURRENT_GATE);
193                 switch (divisor) {
194                 default:
195                 case 3:
196                         ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_3);
197                         break;
198                 case 4:
199                         ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_4);
200                         break;
201                 case 6:
202                         ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_6);
203                         break;
204                 case 8:
205                         ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_8);
206                         break;
207                 }
208
209                 setCurrentGate(ulReg);
210                 }
211 }
212
213
214 unsigned int ddk750_getVMSize(void)
215 {
216         unsigned int reg;
217         unsigned int data;
218
219         /* sm750le only use 64 mb memory*/
220         if (getChipType() == SM750LE)
221                 return SZ_64M;
222
223         /* for 750,always use power mode0*/
224         reg = PEEK32(MODE0_GATE);
225         reg = FIELD_SET(reg, MODE0_GATE, GPIO, ON);
226         POKE32(MODE0_GATE, reg);
227
228         /* get frame buffer size from GPIO */
229         reg = FIELD_GET(PEEK32(MISC_CTRL), MISC_CTRL, LOCALMEM_SIZE);
230         switch (reg) {
231         case MISC_CTRL_LOCALMEM_SIZE_8M:
232                 data = SZ_8M;  break; /* 8  Mega byte */
233         case MISC_CTRL_LOCALMEM_SIZE_16M:
234                 data = SZ_16M; break; /* 16 Mega byte */
235         case MISC_CTRL_LOCALMEM_SIZE_32M:
236                 data = SZ_32M; break; /* 32 Mega byte */
237         case MISC_CTRL_LOCALMEM_SIZE_64M:
238                 data = SZ_64M; break; /* 64 Mega byte */
239         default:
240                 data = 0;
241                 break;
242         }
243         return data;
244
245 }
246
247 int ddk750_initHw(initchip_param_t *pInitParam)
248 {
249
250         unsigned int ulReg;
251
252         if (pInitParam->powerMode != 0)
253                 pInitParam->powerMode = 0;
254         setPowerMode(pInitParam->powerMode);
255
256         /* Enable display power gate & LOCALMEM power gate*/
257         ulReg = PEEK32(CURRENT_GATE);
258         ulReg = FIELD_SET(ulReg, CURRENT_GATE, DISPLAY, ON);
259         ulReg = FIELD_SET(ulReg, CURRENT_GATE, LOCALMEM, ON);
260         setCurrentGate(ulReg);
261
262         if (getChipType() != SM750LE) {
263                 /*      set panel pll and graphic mode via mmio_88 */
264                 ulReg = PEEK32(VGA_CONFIGURATION);
265                 ulReg = FIELD_SET(ulReg, VGA_CONFIGURATION, PLL, PANEL);
266                 ulReg = FIELD_SET(ulReg, VGA_CONFIGURATION, MODE, GRAPHIC);
267                 POKE32(VGA_CONFIGURATION, ulReg);
268         } else {
269 #if defined(__i386__) || defined(__x86_64__)
270                 /* set graphic mode via IO method */
271                 outb_p(0x88, 0x3d4);
272                 outb_p(0x06, 0x3d5);
273 #endif
274         }
275
276         /* Set the Main Chip Clock */
277         setChipClock(MHz((unsigned int)pInitParam->chipClock));
278
279         /* Set up memory clock. */
280         setMemoryClock(MHz(pInitParam->memClock));
281
282         /* Set up master clock */
283         setMasterClock(MHz(pInitParam->masterClock));
284
285
286         /* Reset the memory controller. If the memory controller is not reset in SM750,
287            the system might hang when sw accesses the memory.
288            The memory should be resetted after changing the MXCLK.
289          */
290         if (pInitParam->resetMemory == 1) {
291                 ulReg = PEEK32(MISC_CTRL);
292                 ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, RESET);
293                 POKE32(MISC_CTRL, ulReg);
294
295                 ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, NORMAL);
296                 POKE32(MISC_CTRL, ulReg);
297         }
298
299         if (pInitParam->setAllEngOff == 1) {
300                 enable2DEngine(0);
301
302                 /* Disable Overlay, if a former application left it on */
303                 ulReg = PEEK32(VIDEO_DISPLAY_CTRL);
304                 ulReg = FIELD_SET(ulReg, VIDEO_DISPLAY_CTRL, PLANE, DISABLE);
305                 POKE32(VIDEO_DISPLAY_CTRL, ulReg);
306
307                 /* Disable video alpha, if a former application left it on */
308                 ulReg = PEEK32(VIDEO_ALPHA_DISPLAY_CTRL);
309                 ulReg = FIELD_SET(ulReg, VIDEO_ALPHA_DISPLAY_CTRL, PLANE, DISABLE);
310                 POKE32(VIDEO_ALPHA_DISPLAY_CTRL, ulReg);
311
312                 /* Disable alpha plane, if a former application left it on */
313                 ulReg = PEEK32(ALPHA_DISPLAY_CTRL);
314                 ulReg = FIELD_SET(ulReg, ALPHA_DISPLAY_CTRL, PLANE, DISABLE);
315                 POKE32(ALPHA_DISPLAY_CTRL, ulReg);
316
317                 /* Disable DMA Channel, if a former application left it on */
318                 ulReg = PEEK32(DMA_ABORT_INTERRUPT);
319                 ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT);
320                 POKE32(DMA_ABORT_INTERRUPT, ulReg);
321
322                 /* Disable DMA Power, if a former application left it on */
323                 enableDMA(0);
324         }
325
326         /* We can add more initialization as needed. */
327
328         return 0;
329 }
330
331 /*
332         monk liu @ 4/6/2011:
333                    re-write the calculatePLL function of ddk750.
334                    the original version function does not use some mathematics tricks and shortcut
335                    when it doing the calculation of the best N,M,D combination
336                    I think this version gives a little upgrade in speed
337
338         750 pll clock formular:
339         Request Clock = (Input Clock * M )/(N * X)
340
341         Input Clock = 14318181 hz
342         X = 2 power D
343         D ={0,1,2,3,4,5,6}
344         M = {1,...,255}
345         N = {2,...,15}
346 */
347 unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll)
348 {
349         /* used for primary and secondary channel pixel clock pll */
350         static pllcalparam xparm_PIXEL[] = {
351                 /* 2^0 = 1*/                    {0, 0, 0, 1},
352                 /* 2^ 1 =2*/                    {1, 0, 1, 2},
353                 /* 2^ 2  = 4*/          {2, 0, 2, 4},
354                                                         {3, 0, 3, 8},
355                                                         {4, 1, 3, 16},
356                                                         {5, 2, 3, 32},
357                 /* 2^6 = 64  */         {6, 3, 3, 64},
358                                                         };
359
360         /* used for MXCLK (chip clock) */
361         static pllcalparam xparm_MXCLK[] = {
362                 /* 2^0 = 1*/                    {0, 0, 0, 1},
363                 /* 2^ 1 =2*/                    {1, 0, 1, 2},
364                 /* 2^ 2  = 4*/          {2, 0, 2, 4},
365                                                         {3, 0, 3, 8},
366                                                         };
367
368         /* as sm750 register definition, N located in 2,15 and M located in 1,255       */
369         int N, M, X, d;
370         int xcnt;
371         int miniDiff;
372         unsigned int RN, quo, rem, fl_quo;
373         unsigned int input, request;
374         unsigned int tmpClock, ret;
375         pllcalparam *xparm;
376
377 #if 1
378         if (getChipType() == SM750LE) {
379                 /* SM750LE don't have prgrammable PLL and M/N values to work on.
380                 Just return the requested clock. */
381                 return request_orig;
382         }
383 #endif
384
385         ret = 0;
386         miniDiff = ~0;
387         request = request_orig / 1000;
388         input = pll->inputFreq / 1000;
389
390         /* for MXCLK register , no POD provided, so need be treated differently */
391
392         if (pll->clockType != MXCLK_PLL) {
393                 xparm = &xparm_PIXEL[0];
394                 xcnt = sizeof(xparm_PIXEL) / sizeof(xparm_PIXEL[0]);
395         } else {
396                 xparm = &xparm_MXCLK[0];
397                 xcnt = sizeof(xparm_MXCLK) / sizeof(xparm_MXCLK[0]);
398         }
399
400
401         for (N = 15; N > 1; N--) {
402                 /* RN will not exceed maximum long if @request <= 285 MHZ (for 32bit cpu) */
403                 RN = N * request;
404                 quo = RN / input;
405                 rem = RN % input;/* rem always small than 14318181 */
406                 fl_quo = (rem * 10000 / input);
407
408                 for (d = xcnt - 1; d >= 0; d--) {
409                         X = xparm[d].value;
410                         M = quo * X;
411                         M += fl_quo * X / 10000;
412                         /* round step */
413                         M += (fl_quo * X % 10000) > 5000 ? 1:0;
414                         if (M < 256 && M > 0) {
415                                 unsigned int diff;
416
417                                 tmpClock = pll->inputFreq * M / N / X;
418                                 diff = absDiff(tmpClock, request_orig);
419                                 if (diff < miniDiff) {
420                                         pll->M = M;
421                                         pll->N = N;
422                                         pll->OD = xparm[d].od;
423                                         pll->POD = xparm[d].pod;
424                                         miniDiff = diff;
425                                         ret = tmpClock;
426                                 }
427                         }
428                 }
429         }
430         return ret;
431 }
432
433 unsigned int formatPllReg(pll_value_t *pPLL)
434 {
435         unsigned int ulPllReg = 0;
436
437     /* Note that all PLL's have the same format. Here, we just use Panel PLL parameter
438        to work out the bit fields in the register.
439        On returning a 32 bit number, the value can be applied to any PLL in the calling function.
440     */
441         ulPllReg =
442         FIELD_SET(0, PANEL_PLL_CTRL, BYPASS, OFF)
443         | FIELD_SET(0, PANEL_PLL_CTRL, POWER,  ON)
444         | FIELD_SET(0, PANEL_PLL_CTRL, INPUT,  OSC)
445 #ifndef VALIDATION_CHIP
446         | FIELD_VALUE(0, PANEL_PLL_CTRL, POD,    pPLL->POD)
447 #endif
448         | FIELD_VALUE(0, PANEL_PLL_CTRL, OD,     pPLL->OD)
449         | FIELD_VALUE(0, PANEL_PLL_CTRL, N,      pPLL->N)
450         | FIELD_VALUE(0, PANEL_PLL_CTRL, M,      pPLL->M);
451
452         return ulPllReg;
453 }
454
455