1 #include <linux/sizes.h>
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*/
11 unsigned char value;/* value of 2 power d (2^d) */
16 logical_chip_type_t getChipType(void)
18 unsigned short physicalID;
20 logical_chip_type_t chip;
22 physicalID = devId750; /* either 0x718 or 0x750 */
23 physicalRev = revId750;
25 if (physicalID == 0x718)
27 else if (physicalID == 0x750) {
29 /* SM750 and SM750LE are different in their revision ID only. */
30 if (physicalRev == SM750LE_REVISION_ID)
38 static inline unsigned int calcPLL(pll_value_t *pPLL)
40 return (pPLL->inputFreq * pPLL->M / pPLL->N / (1 << pPLL->OD) /
44 static unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL)
46 unsigned int ulPllReg = 0;
48 pPLL->inputFreq = DEFAULT_INPUT_CLOCK;
49 pPLL->clockType = clockType;
53 ulPllReg = PEEK32(MXCLK_PLL_CTRL);
56 ulPllReg = PEEK32(PANEL_PLL_CTRL);
59 ulPllReg = PEEK32(CRT_PLL_CTRL);
62 ulPllReg = PEEK32(VGA_PLL0_CTRL);
65 ulPllReg = PEEK32(VGA_PLL1_CTRL);
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);
78 static unsigned int getChipClock(void)
82 if (getChipType() == SM750LE)
86 return getPllValue(MXCLK_PLL, &pll);
91 * This function set up the main chip clock.
93 * Input: Frequency to be set.
95 static void setChipClock(unsigned int frequency)
98 unsigned int ulActualMxClk;
100 /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */
101 if (getChipType() == SM750LE)
107 * Set up PLL, a structure to hold the value to be set in clocks.
109 pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */
110 pll.clockType = MXCLK_PLL;
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.
117 ulActualMxClk = calcPllValue(frequency, &pll);
119 /* Master Clock Control: MXCLK_PLL */
120 POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll));
126 static void setMemoryClock(unsigned int frequency)
128 unsigned int ulReg, divisor;
130 /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */
131 if (getChipType() == SM750LE)
135 /* Set the frequency to the maximum frequency that the DDR Memory can take
137 if (frequency > MHz(336))
138 frequency = MHz(336);
140 /* Calculate the divisor */
141 divisor = (unsigned int) roundedDiv(getChipClock(), frequency);
143 /* Set the corresponding divisor in the register. */
144 ulReg = PEEK32(CURRENT_GATE);
148 ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_1);
151 ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_2);
154 ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_3);
157 ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_4);
161 setCurrentGate(ulReg);
167 * This function set up the master clock (MCLK).
169 * Input: Frequency to be set.
172 * The maximum frequency the engine can run is 168MHz.
174 static void setMasterClock(unsigned int frequency)
176 unsigned int ulReg, divisor;
178 /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */
179 if (getChipType() == SM750LE)
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);
188 /* Calculate the divisor */
189 divisor = (unsigned int) roundedDiv(getChipClock(), frequency);
191 /* Set the corresponding divisor in the register. */
192 ulReg = PEEK32(CURRENT_GATE);
196 ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_3);
199 ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_4);
202 ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_6);
205 ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_8);
209 setCurrentGate(ulReg);
214 unsigned int ddk750_getVMSize(void)
219 /* sm750le only use 64 mb memory*/
220 if (getChipType() == SM750LE)
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);
228 /* get frame buffer size from GPIO */
229 reg = FIELD_GET(PEEK32(MISC_CTRL), MISC_CTRL, LOCALMEM_SIZE);
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 */
247 int ddk750_initHw(initchip_param_t *pInitParam)
252 if (pInitParam->powerMode != 0)
253 pInitParam->powerMode = 0;
254 setPowerMode(pInitParam->powerMode);
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);
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);
269 #if defined(__i386__) || defined(__x86_64__)
270 /* set graphic mode via IO method */
276 /* Set the Main Chip Clock */
277 setChipClock(MHz((unsigned int)pInitParam->chipClock));
279 /* Set up memory clock. */
280 setMemoryClock(MHz(pInitParam->memClock));
282 /* Set up master clock */
283 setMasterClock(MHz(pInitParam->masterClock));
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.
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);
295 ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, NORMAL);
296 POKE32(MISC_CTRL, ulReg);
299 if (pInitParam->setAllEngOff == 1) {
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);
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);
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);
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);
322 /* Disable DMA Power, if a former application left it on */
326 /* We can add more initialization as needed. */
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
338 750 pll clock formular:
339 Request Clock = (Input Clock * M )/(N * X)
341 Input Clock = 14318181 hz
347 unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll)
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},
357 /* 2^6 = 64 */ {6, 3, 3, 64},
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},
368 /* as sm750 register definition, N located in 2,15 and M located in 1,255 */
372 unsigned int RN, quo, rem, fl_quo;
373 unsigned int input, request;
374 unsigned int tmpClock, ret;
378 if (getChipType() == SM750LE) {
379 /* SM750LE don't have prgrammable PLL and M/N values to work on.
380 Just return the requested clock. */
387 request = request_orig / 1000;
388 input = pll->inputFreq / 1000;
390 /* for MXCLK register , no POD provided, so need be treated differently */
392 if (pll->clockType != MXCLK_PLL) {
393 xparm = &xparm_PIXEL[0];
394 xcnt = sizeof(xparm_PIXEL) / sizeof(xparm_PIXEL[0]);
396 xparm = &xparm_MXCLK[0];
397 xcnt = sizeof(xparm_MXCLK) / sizeof(xparm_MXCLK[0]);
401 for (N = 15; N > 1; N--) {
402 /* RN will not exceed maximum long if @request <= 285 MHZ (for 32bit cpu) */
405 rem = RN % input;/* rem always small than 14318181 */
406 fl_quo = (rem * 10000 / input);
408 for (d = xcnt - 1; d >= 0; d--) {
411 M += fl_quo * X / 10000;
413 M += (fl_quo * X % 10000) > 5000 ? 1:0;
414 if (M < 256 && M > 0) {
417 tmpClock = pll->inputFreq * M / N / X;
418 diff = absDiff(tmpClock, request_orig);
419 if (diff < miniDiff) {
422 pll->OD = xparm[d].od;
423 pll->POD = xparm[d].pod;
433 unsigned int formatPllReg(pll_value_t *pPLL)
435 unsigned int ulPllReg = 0;
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.
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)
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);