This source file includes following definitions.
- sm750_get_chip_type
- sm750_set_chip_type
- get_mxclk_freq
- set_chip_clock
- set_memory_clock
- set_master_clock
- ddk750_get_vm_size
- ddk750_init_hw
- sm750_calc_pll_value
- sm750_format_pll_reg
1
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 enum logical_chip_type chip;
12
13 enum logical_chip_type sm750_get_chip_type(void)
14 {
15 return chip;
16 }
17
18 void sm750_set_chip_type(unsigned short dev_id, u8 rev_id)
19 {
20 if (dev_id == 0x718) {
21 chip = SM718;
22 } else if (dev_id == 0x750) {
23 chip = SM750;
24
25 if (rev_id == 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 / BIT(OD) / BIT(POD);
49 }
50
51
52
53
54
55
56 static void set_chip_clock(unsigned int frequency)
57 {
58 struct pll_value pll;
59 unsigned int actual_mx_clk;
60
61
62 if (sm750_get_chip_type() == SM750LE)
63 return;
64
65 if (frequency) {
66
67
68
69 pll.inputFreq = DEFAULT_INPUT_CLOCK;
70 pll.clockType = MXCLK_PLL;
71
72
73
74
75
76
77
78
79 actual_mx_clk = sm750_calc_pll_value(frequency, &pll);
80
81
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
92
93
94 if (sm750_get_chip_type() == SM750LE)
95 return;
96
97 if (frequency) {
98
99
100
101
102 if (frequency > MHz(336))
103 frequency = MHz(336);
104
105
106 divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency);
107
108
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
132
133
134
135
136
137
138 static void set_master_clock(unsigned int frequency)
139 {
140 unsigned int reg, divisor;
141
142
143
144
145
146 if (sm750_get_chip_type() == SM750LE)
147 return;
148
149 if (frequency) {
150
151
152
153
154 if (frequency > MHz(190))
155 frequency = MHz(190);
156
157
158 divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency);
159
160
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
188 if (sm750_get_chip_type() == SM750LE)
189 return SZ_64M;
190
191
192 reg = peek32(MODE0_GATE);
193 reg |= MODE0_GATE_GPIO;
194 poke32(MODE0_GATE, reg);
195
196
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;
201 case MISC_CTRL_LOCALMEM_SIZE_16M:
202 data = SZ_16M; break;
203 case MISC_CTRL_LOCALMEM_SIZE_32M:
204 data = SZ_32M; break;
205 case MISC_CTRL_LOCALMEM_SIZE_64M:
206 data = SZ_64M; break;
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
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
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
235 outb_p(0x88, 0x3d4);
236 outb_p(0x06, 0x3d5);
237 #endif
238 }
239
240
241 set_chip_clock(MHz((unsigned int)pInitParam->chipClock));
242
243
244 set_memory_clock(MHz(pInitParam->memClock));
245
246
247 set_master_clock(MHz(pInitParam->masterClock));
248
249
250
251
252
253
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
268 reg = peek32(VIDEO_DISPLAY_CTRL);
269 reg &= ~DISPLAY_CTRL_PLANE;
270 poke32(VIDEO_DISPLAY_CTRL, reg);
271
272
273 reg = peek32(VIDEO_ALPHA_DISPLAY_CTRL);
274 reg &= ~DISPLAY_CTRL_PLANE;
275 poke32(VIDEO_ALPHA_DISPLAY_CTRL, reg);
276
277
278 reg = peek32(ALPHA_DISPLAY_CTRL);
279 reg &= ~DISPLAY_CTRL_PLANE;
280 poke32(ALPHA_DISPLAY_CTRL, reg);
281
282
283 reg = peek32(DMA_ABORT_INTERRUPT);
284 reg |= DMA_ABORT_INTERRUPT_ABORT_1;
285 poke32(DMA_ABORT_INTERRUPT, reg);
286
287
288 sm750_enable_dma(0);
289 }
290
291
292
293 return 0;
294 }
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313 unsigned int sm750_calc_pll_value(unsigned int request_orig,
314 struct pll_value *pll)
315 {
316
317
318
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 tmp_clock, ret;
325 const int max_OD = 3;
326 int max_d = 6;
327
328 if (sm750_get_chip_type() == SM750LE) {
329
330
331
332
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
344
345
346 if (pll->clockType == MXCLK_PLL)
347 max_d = 3;
348
349 for (N = 15; N > 1; N--) {
350
351
352
353
354 RN = N * request;
355 quo = RN / input;
356 rem = RN % input;
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
364 M += (fl_quo * X % 10000) > 5000 ? 1 : 0;
365 if (M < 256 && M > 0) {
366 unsigned int diff;
367
368 tmp_clock = pll->inputFreq * M / N / X;
369 diff = abs(tmp_clock - 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 = tmp_clock;
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
395
396
397
398
399
400
401 return 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 }