1 #include <linux/kernel.h>
2 #include <linux/sizes.h>
4 #include "ddk750_reg.h"
5 #include "ddk750_chip.h"
6 #include "ddk750_power.h"
8 #define MHz(x) ((x) * 1000000)
10 static logical_chip_type_t chip
;
12 logical_chip_type_t
sm750_get_chip_type(void)
17 void sm750_set_chip_type(unsigned short devId
, u8 revId
)
21 } else if (devId
== 0x750) {
23 /* SM750 and SM750LE are different in their revision ID only. */
24 if (revId
== SM750LE_REVISION_ID
) {
26 pr_info("found sm750le\n");
33 static unsigned int get_mxclk_freq(void)
36 unsigned int M
, N
, OD
, POD
;
38 if (sm750_get_chip_type() == SM750LE
)
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
;
47 return DEFAULT_INPUT_CLOCK
* M
/ N
/ (1 << OD
) / (1 << POD
);
51 * This function set up the main chip clock.
53 * Input: Frequency to be set.
55 static void set_chip_clock(unsigned int frequency
)
58 unsigned int ulActualMxClk
;
60 /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */
61 if (sm750_get_chip_type() == SM750LE
)
66 * Set up PLL structure to hold the value to be set in clocks.
68 pll
.inputFreq
= DEFAULT_INPUT_CLOCK
; /* Defined in CLOCK.H */
69 pll
.clockType
= MXCLK_PLL
;
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
78 ulActualMxClk
= sm750_calc_pll_value(frequency
, &pll
);
80 /* Master Clock Control: MXCLK_PLL */
81 poke32(MXCLK_PLL_CTRL
, sm750_format_pll_reg(&pll
));
85 static void set_memory_clock(unsigned int frequency
)
87 unsigned int reg
, divisor
;
90 * Cheok_0509: For SM750LE, the memory clock is fixed.
93 if (sm750_get_chip_type() == SM750LE
)
98 * Set the frequency to the maximum frequency
99 * that the DDR Memory can take which is 336MHz.
101 if (frequency
> MHz(336))
102 frequency
= MHz(336);
104 /* Calculate the divisor */
105 divisor
= DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency
);
107 /* Set the corresponding divisor in the register. */
108 reg
= peek32(CURRENT_GATE
) & ~CURRENT_GATE_M2XCLK_MASK
;
112 reg
|= CURRENT_GATE_M2XCLK_DIV_1
;
115 reg
|= CURRENT_GATE_M2XCLK_DIV_2
;
118 reg
|= CURRENT_GATE_M2XCLK_DIV_3
;
121 reg
|= CURRENT_GATE_M2XCLK_DIV_4
;
125 sm750_set_current_gate(reg
);
130 * This function set up the master clock (MCLK).
132 * Input: Frequency to be set.
135 * The maximum frequency the engine can run is 168MHz.
137 static void set_master_clock(unsigned int frequency
)
139 unsigned int reg
, divisor
;
142 * Cheok_0509: For SM750LE, the memory clock is fixed.
145 if (sm750_get_chip_type() == SM750LE
)
150 * Set the frequency to the maximum frequency
151 * that the SM750 engine can run, which is about 190 MHz.
153 if (frequency
> MHz(190))
154 frequency
= MHz(190);
156 /* Calculate the divisor */
157 divisor
= DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency
);
159 /* Set the corresponding divisor in the register. */
160 reg
= peek32(CURRENT_GATE
) & ~CURRENT_GATE_MCLK_MASK
;
164 reg
|= CURRENT_GATE_MCLK_DIV_3
;
167 reg
|= CURRENT_GATE_MCLK_DIV_4
;
170 reg
|= CURRENT_GATE_MCLK_DIV_6
;
173 reg
|= CURRENT_GATE_MCLK_DIV_8
;
177 sm750_set_current_gate(reg
);
181 unsigned int ddk750_get_vm_size(void)
186 /* sm750le only use 64 mb memory*/
187 if (sm750_get_chip_type() == SM750LE
)
190 /* for 750,always use power mode0*/
191 reg
= peek32(MODE0_GATE
);
192 reg
|= MODE0_GATE_GPIO
;
193 poke32(MODE0_GATE
, reg
);
195 /* get frame buffer size from GPIO */
196 reg
= peek32(MISC_CTRL
) & MISC_CTRL_LOCALMEM_SIZE_MASK
;
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 */
213 int ddk750_init_hw(struct initchip_param
*pInitParam
)
217 if (pInitParam
->powerMode
!= 0)
218 pInitParam
->powerMode
= 0;
219 sm750_set_power_mode(pInitParam
->powerMode
);
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
);
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
);
232 #if defined(__i386__) || defined(__x86_64__)
233 /* set graphic mode via IO method */
239 /* Set the Main Chip Clock */
240 set_chip_clock(MHz((unsigned int)pInitParam
->chipClock
));
242 /* Set up memory clock. */
243 set_memory_clock(MHz(pInitParam
->memClock
));
245 /* Set up master clock */
246 set_master_clock(MHz(pInitParam
->masterClock
));
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.
254 if (pInitParam
->resetMemory
== 1) {
255 reg
= peek32(MISC_CTRL
);
256 reg
&= ~MISC_CTRL_LOCALMEM_RESET
;
257 poke32(MISC_CTRL
, reg
);
259 reg
|= MISC_CTRL_LOCALMEM_RESET
;
260 poke32(MISC_CTRL
, reg
);
263 if (pInitParam
->setAllEngOff
== 1) {
264 sm750_enable_2d_engine(0);
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
);
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
);
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
);
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
);
286 /* Disable DMA Power, if a former application left it on */
290 /* We can add more initialization as needed. */
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
303 * 750 pll clock formular:
304 * Request Clock = (Input Clock * M )/(N * X)
306 * Input Clock = 14318181 hz
312 unsigned int sm750_calc_pll_value(unsigned int request_orig
,
313 struct pll_value
*pll
)
316 * as sm750 register definition,
317 * N located in 2,15 and M located in 1,255
321 unsigned int RN
, quo
, rem
, fl_quo
;
322 unsigned int input
, request
;
323 unsigned int tmpClock
, ret
;
324 const int max_OD
= 3;
327 if (sm750_get_chip_type() == SM750LE
) {
330 * programmable PLL and M/N values to work on.
331 * Just return the requested clock.
338 request
= request_orig
/ 1000;
339 input
= pll
->inputFreq
/ 1000;
342 * for MXCLK register,
343 * no POD provided, so need be treated differently
345 if (pll
->clockType
== MXCLK_PLL
)
348 for (N
= 15; N
> 1; N
--) {
350 * RN will not exceed maximum long
351 * if @request <= 285 MHZ (for 32bit cpu)
355 rem
= RN
% input
;/* rem always small than 14318181 */
356 fl_quo
= rem
* 10000 / input
;
358 for (d
= max_d
; d
>= 0; d
--) {
361 M
+= fl_quo
* X
/ 10000;
363 M
+= (fl_quo
* X
% 10000) > 5000 ? 1 : 0;
364 if (M
< 256 && M
> 0) {
367 tmpClock
= pll
->inputFreq
* M
/ N
/ X
;
368 diff
= abs(tmpClock
- request_orig
);
369 if (diff
< mini_diff
) {
374 pll
->POD
= d
- max_OD
;
375 pll
->OD
= d
- pll
->POD
;
385 unsigned int sm750_format_pll_reg(struct pll_value
*pPLL
)
387 #ifndef VALIDATION_CHIP
388 unsigned int POD
= pPLL
->POD
;
390 unsigned int OD
= pPLL
->OD
;
391 unsigned int M
= pPLL
->M
;
392 unsigned int N
= pPLL
->N
;
393 unsigned int reg
= 0;
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.
401 reg
= PLL_CTRL_POWER
|
402 #ifndef VALIDATION_CHIP
403 ((POD
<< PLL_CTRL_POD_SHIFT
) & PLL_CTRL_POD_MASK
) |
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
);