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