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"
8 logical_chip_type_t getChipType(void)
10 unsigned short physicalID;
12 logical_chip_type_t chip;
14 physicalID = devId750; /* either 0x718 or 0x750 */
15 physicalRev = revId750;
17 if (physicalID == 0x718)
19 else if (physicalID == 0x750) {
21 /* SM750 and SM750LE are different in their revision ID only. */
22 if (physicalRev == SM750LE_REVISION_ID)
30 static unsigned int get_mxclk_freq(void)
33 unsigned int M, N, OD, POD;
35 if (getChipType() == SM750LE)
38 pll_reg = PEEK32(MXCLK_PLL_CTRL);
39 M = FIELD_GET(pll_reg, PANEL_PLL_CTRL, M);
40 N = FIELD_GET(pll_reg, PANEL_PLL_CTRL, N);
41 OD = FIELD_GET(pll_reg, PANEL_PLL_CTRL, OD);
42 POD = FIELD_GET(pll_reg, PANEL_PLL_CTRL, POD);
44 return DEFAULT_INPUT_CLOCK * M / N / (1 << OD) / (1 << POD);
48 * This function set up the main chip clock.
50 * Input: Frequency to be set.
52 static void setChipClock(unsigned int frequency)
55 unsigned int ulActualMxClk;
57 /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */
58 if (getChipType() == SM750LE)
63 * Set up PLL, a structure to hold the value to be set in clocks.
65 pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */
66 pll.clockType = MXCLK_PLL;
69 * Call calcPllValue() to fill up the other fields for PLL structure.
70 * Sometime, the chip cannot set up the exact clock required by User.
71 * Return value from calcPllValue() gives the actual possible clock.
73 ulActualMxClk = calcPllValue(frequency, &pll);
75 /* Master Clock Control: MXCLK_PLL */
76 POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll));
80 static void setMemoryClock(unsigned int frequency)
82 unsigned int ulReg, divisor;
84 /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */
85 if (getChipType() == SM750LE)
89 /* Set the frequency to the maximum frequency that the DDR Memory can take
91 if (frequency > MHz(336))
94 /* Calculate the divisor */
95 divisor = roundedDiv(get_mxclk_freq(), frequency);
97 /* Set the corresponding divisor in the register. */
98 ulReg = PEEK32(CURRENT_GATE);
102 ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_1);
105 ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_2);
108 ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_3);
111 ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_4);
115 setCurrentGate(ulReg);
120 * This function set up the master clock (MCLK).
122 * Input: Frequency to be set.
125 * The maximum frequency the engine can run is 168MHz.
127 static void setMasterClock(unsigned int frequency)
129 unsigned int ulReg, divisor;
131 /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */
132 if (getChipType() == SM750LE)
136 /* Set the frequency to the maximum frequency that the SM750 engine can
137 run, which is about 190 MHz. */
138 if (frequency > MHz(190))
139 frequency = MHz(190);
141 /* Calculate the divisor */
142 divisor = roundedDiv(get_mxclk_freq(), frequency);
144 /* Set the corresponding divisor in the register. */
145 ulReg = PEEK32(CURRENT_GATE);
149 ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_3);
152 ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_4);
155 ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_6);
158 ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_8);
162 setCurrentGate(ulReg);
166 unsigned int ddk750_getVMSize(void)
171 /* sm750le only use 64 mb memory*/
172 if (getChipType() == SM750LE)
175 /* for 750,always use power mode0*/
176 reg = PEEK32(MODE0_GATE);
177 reg = FIELD_SET(reg, MODE0_GATE, GPIO, ON);
178 POKE32(MODE0_GATE, reg);
180 /* get frame buffer size from GPIO */
181 reg = FIELD_GET(PEEK32(MISC_CTRL), MISC_CTRL, LOCALMEM_SIZE);
183 case MISC_CTRL_LOCALMEM_SIZE_8M:
184 data = SZ_8M; break; /* 8 Mega byte */
185 case MISC_CTRL_LOCALMEM_SIZE_16M:
186 data = SZ_16M; break; /* 16 Mega byte */
187 case MISC_CTRL_LOCALMEM_SIZE_32M:
188 data = SZ_32M; break; /* 32 Mega byte */
189 case MISC_CTRL_LOCALMEM_SIZE_64M:
190 data = SZ_64M; break; /* 64 Mega byte */
198 int ddk750_initHw(initchip_param_t *pInitParam)
202 if (pInitParam->powerMode != 0)
203 pInitParam->powerMode = 0;
204 setPowerMode(pInitParam->powerMode);
206 /* Enable display power gate & LOCALMEM power gate*/
207 ulReg = PEEK32(CURRENT_GATE);
208 ulReg = FIELD_SET(ulReg, CURRENT_GATE, DISPLAY, ON);
209 ulReg = FIELD_SET(ulReg, CURRENT_GATE, LOCALMEM, ON);
210 setCurrentGate(ulReg);
212 if (getChipType() != SM750LE) {
213 /* set panel pll and graphic mode via mmio_88 */
214 ulReg = PEEK32(VGA_CONFIGURATION);
215 ulReg = FIELD_SET(ulReg, VGA_CONFIGURATION, PLL, PANEL);
216 ulReg = FIELD_SET(ulReg, VGA_CONFIGURATION, MODE, GRAPHIC);
217 POKE32(VGA_CONFIGURATION, ulReg);
219 #if defined(__i386__) || defined(__x86_64__)
220 /* set graphic mode via IO method */
226 /* Set the Main Chip Clock */
227 setChipClock(MHz((unsigned int)pInitParam->chipClock));
229 /* Set up memory clock. */
230 setMemoryClock(MHz(pInitParam->memClock));
232 /* Set up master clock */
233 setMasterClock(MHz(pInitParam->masterClock));
236 /* Reset the memory controller. If the memory controller is not reset in SM750,
237 the system might hang when sw accesses the memory.
238 The memory should be resetted after changing the MXCLK.
240 if (pInitParam->resetMemory == 1) {
241 ulReg = PEEK32(MISC_CTRL);
242 ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, RESET);
243 POKE32(MISC_CTRL, ulReg);
245 ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, NORMAL);
246 POKE32(MISC_CTRL, ulReg);
249 if (pInitParam->setAllEngOff == 1) {
252 /* Disable Overlay, if a former application left it on */
253 ulReg = PEEK32(VIDEO_DISPLAY_CTRL);
254 ulReg = FIELD_SET(ulReg, VIDEO_DISPLAY_CTRL, PLANE, DISABLE);
255 POKE32(VIDEO_DISPLAY_CTRL, ulReg);
257 /* Disable video alpha, if a former application left it on */
258 ulReg = PEEK32(VIDEO_ALPHA_DISPLAY_CTRL);
259 ulReg = FIELD_SET(ulReg, VIDEO_ALPHA_DISPLAY_CTRL, PLANE, DISABLE);
260 POKE32(VIDEO_ALPHA_DISPLAY_CTRL, ulReg);
262 /* Disable alpha plane, if a former application left it on */
263 ulReg = PEEK32(ALPHA_DISPLAY_CTRL);
264 ulReg = FIELD_SET(ulReg, ALPHA_DISPLAY_CTRL, PLANE, DISABLE);
265 POKE32(ALPHA_DISPLAY_CTRL, ulReg);
267 /* Disable DMA Channel, if a former application left it on */
268 ulReg = PEEK32(DMA_ABORT_INTERRUPT);
269 ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT);
270 POKE32(DMA_ABORT_INTERRUPT, ulReg);
272 /* Disable DMA Power, if a former application left it on */
276 /* We can add more initialization as needed. */
283 re-write the calculatePLL function of ddk750.
284 the original version function does not use some mathematics tricks and shortcut
285 when it doing the calculation of the best N,M,D combination
286 I think this version gives a little upgrade in speed
288 750 pll clock formular:
289 Request Clock = (Input Clock * M )/(N * X)
291 Input Clock = 14318181 hz
297 unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll)
299 /* as sm750 register definition, N located in 2,15 and M located in 1,255 */
302 unsigned int RN, quo, rem, fl_quo;
303 unsigned int input, request;
304 unsigned int tmpClock, ret;
305 const int max_OD = 3;
308 if (getChipType() == SM750LE) {
309 /* SM750LE don't have prgrammable PLL and M/N values to work on.
310 Just return the requested clock. */
316 request = request_orig / 1000;
317 input = pll->inputFreq / 1000;
319 /* for MXCLK register , no POD provided, so need be treated differently */
320 if (pll->clockType == MXCLK_PLL)
323 for (N = 15; N > 1; N--) {
324 /* RN will not exceed maximum long if @request <= 285 MHZ (for 32bit cpu) */
327 rem = RN % input;/* rem always small than 14318181 */
328 fl_quo = (rem * 10000 / input);
330 for (d = max_d; d >= 0; d--) {
333 M += fl_quo * X / 10000;
335 M += (fl_quo * X % 10000) > 5000 ? 1 : 0;
336 if (M < 256 && M > 0) {
339 tmpClock = pll->inputFreq * M / N / X;
340 diff = absDiff(tmpClock, request_orig);
341 if (diff < mini_diff) {
346 pll->POD = d - max_OD;
347 pll->OD = d - pll->POD;
357 unsigned int formatPllReg(pll_value_t *pPLL)
359 unsigned int ulPllReg = 0;
361 /* Note that all PLL's have the same format. Here, we just use Panel PLL parameter
362 to work out the bit fields in the register.
363 On returning a 32 bit number, the value can be applied to any PLL in the calling function.
366 FIELD_SET(0, PANEL_PLL_CTRL, BYPASS, OFF)
367 | FIELD_SET(0, PANEL_PLL_CTRL, POWER, ON)
368 | FIELD_SET(0, PANEL_PLL_CTRL, INPUT, OSC)
369 #ifndef VALIDATION_CHIP
370 | FIELD_VALUE(0, PANEL_PLL_CTRL, POD, pPLL->POD)
372 | FIELD_VALUE(0, PANEL_PLL_CTRL, OD, pPLL->OD)
373 | FIELD_VALUE(0, PANEL_PLL_CTRL, N, pPLL->N)
374 | FIELD_VALUE(0, PANEL_PLL_CTRL, M, pPLL->M);