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 }
412