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