1 #include <linux/version.h>
2 #include<linux/module.h>
3 #include<linux/kernel.h>
4 #include<linux/errno.h>
5 #include<linux/string.h>
6 #include<linux/mm.h>
7 #include<linux/slab.h>
8 #include<linux/delay.h>
9 #include<linux/fb.h>
10 #include<linux/ioport.h>
11 #include<linux/init.h>
12 #include<linux/pci.h>
13 #include<linux/vmalloc.h>
14 #include<linux/pagemap.h>
15 #include <linux/console.h>
16 #ifdef CONFIG_MTRR
17 #include <asm/mtrr.h>
18 #endif
19 #include<linux/platform_device.h>
20 #include<linux/screen_info.h>
21 
22 #include "sm750.h"
23 #include "sm750_hw.h"
24 #include "ddk750.h"
25 #include "sm750_accel.h"
26 
hw_sm750_map(struct lynx_share * share,struct pci_dev * pdev)27 int hw_sm750_map(struct lynx_share* share, struct pci_dev* pdev)
28 {
29 	int ret;
30 	struct sm750_share * spec_share;
31 
32 
33 	spec_share = container_of(share, struct sm750_share,share);
34 	ret = 0;
35 
36 	share->vidreg_start  = pci_resource_start(pdev, 1);
37 	share->vidreg_size = MB(2);
38 
39 	pr_info("mmio phyAddr = %lx\n", share->vidreg_start);
40 
41 	/* reserve the vidreg space of smi adaptor
42 	 * if you do this, u need to add release region code
43 	 * in lynxfb_remove, or memory will not be mapped again
44 	 * successfully
45 	 * */
46 
47 	if((ret = pci_request_region(pdev, 1, "sm750fb")))
48 	{
49 		pr_err("Can not request PCI regions.\n");
50 		goto exit;
51 	}
52 
53 	/* now map mmio and vidmem*/
54 	share->pvReg = ioremap_nocache(share->vidreg_start, share->vidreg_size);
55 	if(!share->pvReg){
56 		pr_err("mmio failed\n");
57 		ret = -EFAULT;
58 		goto exit;
59 	}else{
60 		pr_info("mmio virtual addr = %p\n", share->pvReg);
61 	}
62 
63 
64 	share->accel.dprBase = share->pvReg + DE_BASE_ADDR_TYPE1;
65 	share->accel.dpPortBase = share->pvReg + DE_PORT_ADDR_TYPE1;
66 
67 	ddk750_set_mmio(share->pvReg,share->devid, share->revid);
68 
69 	share->vidmem_start = pci_resource_start(pdev, 0);
70 	/* don't use pdev_resource[x].end - resource[x].start to
71 	 * calculate the resource size,its only the maximum available
72 	 * size but not the actual size,use
73 	 * @hw_sm750_getVMSize function can be safe.
74 	 * */
75 	share->vidmem_size = hw_sm750_getVMSize(share);
76 	pr_info("video memory phyAddr = %lx, size = %u bytes\n",
77 	share->vidmem_start, share->vidmem_size);
78 
79 	/* reserve the vidmem space of smi adaptor */
80 #if 0
81 	if((ret = pci_request_region(pdev,0,_moduleName_)))
82 	{
83 		pr_err("Can not request PCI regions.\n");
84 		goto exit;
85 	}
86 #endif
87 
88 	share->pvMem = ioremap(share->vidmem_start,
89 							share->vidmem_size);
90 
91 	if(!share->pvMem){
92 		pr_err("Map video memory failed\n");
93 		ret = -EFAULT;
94 		goto exit;
95 	}else{
96 		pr_info("video memory vaddr = %p\n", share->pvMem);
97 	}
98 exit:
99 	return ret;
100 }
101 
102 
103 
hw_sm750_inithw(struct lynx_share * share,struct pci_dev * pdev)104 int hw_sm750_inithw(struct lynx_share* share, struct pci_dev * pdev)
105 {
106 	struct sm750_share * spec_share;
107 	struct init_status * parm;
108 
109 	spec_share = container_of(share, struct sm750_share,share);
110 	parm = &spec_share->state.initParm;
111 	if(parm->chip_clk == 0)
112 		parm->chip_clk = (getChipType() == SM750LE)?
113 						DEFAULT_SM750LE_CHIP_CLOCK :
114 						DEFAULT_SM750_CHIP_CLOCK;
115 
116 	if(parm->mem_clk == 0)
117 		parm->mem_clk = parm->chip_clk;
118 	if(parm->master_clk == 0)
119 		parm->master_clk = parm->chip_clk/3;
120 
121 	ddk750_initHw((initchip_param_t *)&spec_share->state.initParm);
122 	/* for sm718,open pci burst */
123 	if(share->devid == 0x718){
124 		POKE32(SYSTEM_CTRL,
125 				FIELD_SET(PEEK32(SYSTEM_CTRL), SYSTEM_CTRL, PCI_BURST, ON));
126 	}
127 
128 	/* sm750 use sii164, it can be setup with default value
129 	 * by on power, so initDVIDisp can be skipped */
130 #if 0
131 	ddk750_initDVIDisp();
132 #endif
133 
134 	if(getChipType() != SM750LE)
135 	{
136 		/* does user need CRT ?*/
137 		if(spec_share->state.nocrt){
138 			POKE32(MISC_CTRL,
139 					FIELD_SET(PEEK32(MISC_CTRL),
140 					MISC_CTRL,
141 					DAC_POWER, OFF));
142 			/* shut off dpms */
143 			POKE32(SYSTEM_CTRL,
144 					FIELD_SET(PEEK32(SYSTEM_CTRL),
145 					SYSTEM_CTRL,
146 					DPMS, VNHN));
147 		}else{
148 			POKE32(MISC_CTRL,
149 					FIELD_SET(PEEK32(MISC_CTRL),
150 					MISC_CTRL,
151 					DAC_POWER, ON));
152 			/* turn on dpms */
153 			POKE32(SYSTEM_CTRL,
154 					FIELD_SET(PEEK32(SYSTEM_CTRL),
155 					SYSTEM_CTRL,
156 					DPMS, VPHP));
157 		}
158 
159 		switch (spec_share->state.pnltype){
160 			case sm750_doubleTFT:
161 			case sm750_24TFT:
162 			case sm750_dualTFT:
163 			POKE32(PANEL_DISPLAY_CTRL,
164 				FIELD_VALUE(PEEK32(PANEL_DISPLAY_CTRL),
165 							PANEL_DISPLAY_CTRL,
166 							TFT_DISP,
167 							spec_share->state.pnltype));
168 			break;
169 		}
170 	}else{
171 		/* for 750LE ,no DVI chip initilization makes Monitor no signal */
172 		/* Set up GPIO for software I2C to program DVI chip in the
173 		   Xilinx SP605 board, in order to have video signal.
174 		 */
175         swI2CInit(0,1);
176 
177 
178         /* Customer may NOT use CH7301 DVI chip, which has to be
179            initialized differently.
180          */
181         if (swI2CReadReg(0xec, 0x4a) == 0x95)
182         {
183             /* The following register values for CH7301 are from
184                Chrontel app note and our experiment.
185              */
186 			pr_info("yes,CH7301 DVI chip found\n");
187             swI2CWriteReg(0xec, 0x1d, 0x16);
188             swI2CWriteReg(0xec, 0x21, 0x9);
189             swI2CWriteReg(0xec, 0x49, 0xC0);
190 			pr_info("okay,CH7301 DVI chip setup done\n");
191         }
192 	}
193 
194 	/* init 2d engine */
195 	if(!share->accel_off){
196 		hw_sm750_initAccel(share);
197 //		share->accel.de_wait = hw_sm750_deWait;
198 	}
199 
200 	return 0;
201 }
202 
203 
hw_sm750_getVMSize(struct lynx_share * share)204 resource_size_t hw_sm750_getVMSize(struct lynx_share * share)
205 {
206 	resource_size_t ret;
207 
208 	ret = ddk750_getVMSize();
209 	return ret;
210 }
211 
212 
213 
hw_sm750_output_checkMode(struct lynxfb_output * output,struct fb_var_screeninfo * var)214 int hw_sm750_output_checkMode(struct lynxfb_output* output, struct fb_var_screeninfo* var)
215 {
216 
217 	return 0;
218 }
219 
220 
hw_sm750_output_setMode(struct lynxfb_output * output,struct fb_var_screeninfo * var,struct fb_fix_screeninfo * fix)221 int hw_sm750_output_setMode(struct lynxfb_output* output,
222 									struct fb_var_screeninfo* var, struct fb_fix_screeninfo* fix)
223 {
224 	int ret;
225 	disp_output_t dispSet;
226 	int channel;
227 
228 	ret = 0;
229 	dispSet = 0;
230 	channel = *output->channel;
231 
232 
233 	if(getChipType() != SM750LE){
234 		if(channel == sm750_primary){
235 			pr_info("primary channel\n");
236 			if(output->paths & sm750_panel)
237 				dispSet |= do_LCD1_PRI;
238 			if(output->paths & sm750_crt)
239 				dispSet |= do_CRT_PRI;
240 
241 		}else{
242 			pr_info("secondary channel\n");
243 			if(output->paths & sm750_panel)
244 				dispSet |= do_LCD1_SEC;
245 			if(output->paths & sm750_crt)
246 				dispSet |= do_CRT_SEC;
247 
248 		}
249 		ddk750_setLogicalDispOut(dispSet);
250 	}else{
251 		/* just open DISPLAY_CONTROL_750LE register bit 3:0*/
252 		u32 reg;
253 		reg = PEEK32(DISPLAY_CONTROL_750LE);
254 		reg |= 0xf;
255 		POKE32(DISPLAY_CONTROL_750LE, reg);
256 	}
257 
258 	pr_info("ddk setlogicdispout done \n");
259 	return ret;
260 }
261 
hw_sm750_output_clear(struct lynxfb_output * output)262 void hw_sm750_output_clear(struct lynxfb_output* output)
263 {
264 
265 	return;
266 }
267 
hw_sm750_crtc_checkMode(struct lynxfb_crtc * crtc,struct fb_var_screeninfo * var)268 int hw_sm750_crtc_checkMode(struct lynxfb_crtc* crtc, struct fb_var_screeninfo* var)
269 {
270 	struct lynx_share * share;
271 
272 
273 	share = container_of(crtc, struct lynxfb_par,crtc)->share;
274 
275 	switch (var->bits_per_pixel){
276 		case 8:
277 		case 16:
278 			break;
279 		case 32:
280 			if (share->revid == SM750LE_REVISION_ID) {
281 				pr_debug("750le do not support 32bpp\n");
282 				return -EINVAL;
283 			}
284 			break;
285 		default:
286 			return -EINVAL;
287 
288 	}
289 
290 	return 0;
291 }
292 
293 
294 /*
295 	set the controller's mode for @crtc charged with @var and @fix parameters
296 */
hw_sm750_crtc_setMode(struct lynxfb_crtc * crtc,struct fb_var_screeninfo * var,struct fb_fix_screeninfo * fix)297 int hw_sm750_crtc_setMode(struct lynxfb_crtc* crtc,
298 								struct fb_var_screeninfo* var,
299 								struct fb_fix_screeninfo* fix)
300 {
301 	int ret,fmt;
302 	u32 reg;
303 	mode_parameter_t modparm;
304 	clock_type_t clock;
305 	struct lynx_share * share;
306 	struct lynxfb_par * par;
307 
308 
309 	ret = 0;
310 	par = container_of(crtc, struct lynxfb_par, crtc);
311 	share = par->share;
312 #if 1
313 	if(!share->accel_off){
314 		/* set 2d engine pixel format according to mode bpp */
315 		switch(var->bits_per_pixel){
316 			case 8:
317 				fmt = 0;
318 				break;
319 			case 16:
320 				fmt = 1;
321 				break;
322 			case 32:
323 			default:
324 				fmt = 2;
325 				break;
326 		}
327 		hw_set2dformat(&share->accel, fmt);
328 	}
329 #endif
330 
331 	/* set timing */
332 //	modparm.pixel_clock = PS_TO_HZ(var->pixclock);
333 	modparm.pixel_clock = ps_to_hz(var->pixclock);
334 	modparm.vertical_sync_polarity = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? POS:NEG;
335 	modparm.horizontal_sync_polarity = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? POS:NEG;
336 	modparm.clock_phase_polarity = (var->sync& FB_SYNC_COMP_HIGH_ACT) ? POS:NEG;
337 	modparm.horizontal_display_end = var->xres;
338 	modparm.horizontal_sync_width = var->hsync_len;
339 	modparm.horizontal_sync_start = var->xres + var->right_margin;
340 	modparm.horizontal_total = var->xres + var->left_margin + var->right_margin + var->hsync_len;
341 	modparm.vertical_display_end = var->yres;
342 	modparm.vertical_sync_height = var->vsync_len;
343 	modparm.vertical_sync_start = var->yres + var->lower_margin;
344 	modparm.vertical_total = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
345 
346 	/* choose pll */
347 	if(crtc->channel != sm750_secondary)
348 		clock = PRIMARY_PLL;
349 	else
350 		clock = SECONDARY_PLL;
351 
352 	pr_debug("Request pixel clock = %lu\n", modparm.pixel_clock);
353 	ret = ddk750_setModeTiming(&modparm, clock);
354 	if(ret){
355 		pr_err("Set mode timing failed\n");
356 		goto exit;
357 	}
358 
359 	if(crtc->channel != sm750_secondary){
360 		/* set pitch, offset ,width,start address ,etc... */
361 		POKE32(PANEL_FB_ADDRESS,
362 			FIELD_SET(0, PANEL_FB_ADDRESS, STATUS, CURRENT)|
363 			FIELD_SET(0, PANEL_FB_ADDRESS, EXT, LOCAL)|
364 			FIELD_VALUE(0, PANEL_FB_ADDRESS, ADDRESS, crtc->oScreen));
365 
366 		reg = var->xres * (var->bits_per_pixel >> 3);
367 		/* crtc->channel is not equal to par->index on numeric,be aware of that */
368 		reg = PADDING(crtc->line_pad,reg);
369 
370 		POKE32(PANEL_FB_WIDTH,
371 			FIELD_VALUE(0, PANEL_FB_WIDTH, WIDTH, reg)|
372 			FIELD_VALUE(0, PANEL_FB_WIDTH, OFFSET, fix->line_length));
373 
374 		POKE32(PANEL_WINDOW_WIDTH,
375 			FIELD_VALUE(0, PANEL_WINDOW_WIDTH, WIDTH, var->xres -1)|
376 			FIELD_VALUE(0, PANEL_WINDOW_WIDTH, X, var->xoffset));
377 
378 		POKE32(PANEL_WINDOW_HEIGHT,
379 			FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, HEIGHT, var->yres_virtual - 1)|
380 			FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, Y, var->yoffset));
381 
382 		POKE32(PANEL_PLANE_TL, 0);
383 
384 		POKE32(PANEL_PLANE_BR,
385 			FIELD_VALUE(0, PANEL_PLANE_BR, BOTTOM, var->yres - 1)|
386 			FIELD_VALUE(0, PANEL_PLANE_BR,RIGHT, var->xres - 1));
387 
388 		/* set pixel format */
389 		reg = PEEK32(PANEL_DISPLAY_CTRL);
390 		POKE32(PANEL_DISPLAY_CTRL,
391 			FIELD_VALUE(reg,
392 			PANEL_DISPLAY_CTRL, FORMAT,
393 			(var->bits_per_pixel >> 4)
394 			));
395 	}else{
396 		/* not implemented now */
397 		POKE32(CRT_FB_ADDRESS, crtc->oScreen);
398 		reg = var->xres * (var->bits_per_pixel >> 3);
399 		/* crtc->channel is not equal to par->index on numeric,be aware of that */
400 		reg = PADDING(crtc->line_pad, reg);
401 
402 		POKE32(CRT_FB_WIDTH,
403 			FIELD_VALUE(0, CRT_FB_WIDTH, WIDTH, reg)|
404 			FIELD_VALUE(0, CRT_FB_WIDTH, OFFSET, fix->line_length));
405 
406 		/* SET PIXEL FORMAT */
407 		reg = PEEK32(CRT_DISPLAY_CTRL);
408 		reg = FIELD_VALUE(reg, CRT_DISPLAY_CTRL, FORMAT, var->bits_per_pixel >> 4);
409 		POKE32(CRT_DISPLAY_CTRL, reg);
410 
411 	}
412 
413 
414 exit:
415 	return ret;
416 }
417 
hw_sm750_crtc_clear(struct lynxfb_crtc * crtc)418 void hw_sm750_crtc_clear(struct lynxfb_crtc* crtc)
419 {
420 
421 	return;
422 }
423 
hw_sm750_setColReg(struct lynxfb_crtc * crtc,ushort index,ushort red,ushort green,ushort blue)424 int hw_sm750_setColReg(struct lynxfb_crtc* crtc, ushort index,
425 								ushort red, ushort green, ushort blue)
426 {
427 	static unsigned int add[]={PANEL_PALETTE_RAM,CRT_PALETTE_RAM};
428 	POKE32(add[crtc->channel] + index*4, (red<<16)|(green<<8)|blue);
429 	return 0;
430 }
431 
hw_sm750le_setBLANK(struct lynxfb_output * output,int blank)432 int hw_sm750le_setBLANK(struct lynxfb_output * output, int blank){
433 	int dpms,crtdb;
434 
435 	switch(blank)
436 	{
437 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
438 		case FB_BLANK_UNBLANK:
439 #else
440 		case VESA_NO_BLANKING:
441 #endif
442 			dpms = CRT_DISPLAY_CTRL_DPMS_0;
443 			crtdb = CRT_DISPLAY_CTRL_BLANK_OFF;
444 			break;
445 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
446 		case FB_BLANK_NORMAL:
447 			dpms = CRT_DISPLAY_CTRL_DPMS_0;
448 			crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
449 			break;
450 #endif
451 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
452 		case FB_BLANK_VSYNC_SUSPEND:
453 #else
454 		case VESA_VSYNC_SUSPEND:
455 #endif
456 			dpms = CRT_DISPLAY_CTRL_DPMS_2;
457 			crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
458 			break;
459 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
460 		case FB_BLANK_HSYNC_SUSPEND:
461 #else
462 		case VESA_HSYNC_SUSPEND:
463 #endif
464 			dpms = CRT_DISPLAY_CTRL_DPMS_1;
465 			crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
466 			break;
467 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
468 		case FB_BLANK_POWERDOWN:
469 #else
470 		case VESA_POWERDOWN:
471 #endif
472 			dpms = CRT_DISPLAY_CTRL_DPMS_3;
473 			crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
474 			break;
475 		default:
476 			return -EINVAL;
477 	}
478 
479 	if(output->paths & sm750_crt){
480 		POKE32(CRT_DISPLAY_CTRL, FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, DPMS, dpms));
481 		POKE32(CRT_DISPLAY_CTRL, FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, BLANK, crtdb));
482 	}
483 	return 0;
484 }
485 
hw_sm750_setBLANK(struct lynxfb_output * output,int blank)486 int hw_sm750_setBLANK(struct lynxfb_output* output,int blank)
487 {
488 	unsigned int dpms, pps, crtdb;
489 
490 	dpms = pps = crtdb = 0;
491 
492 	switch (blank)
493 	{
494 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
495 		case FB_BLANK_UNBLANK:
496 #else
497 		case VESA_NO_BLANKING:
498 #endif
499 			pr_info("flag = FB_BLANK_UNBLANK \n");
500 			dpms = SYSTEM_CTRL_DPMS_VPHP;
501 			pps = PANEL_DISPLAY_CTRL_DATA_ENABLE;
502 			crtdb = CRT_DISPLAY_CTRL_BLANK_OFF;
503 			break;
504 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
505 		case FB_BLANK_NORMAL:
506 			pr_info("flag = FB_BLANK_NORMAL \n");
507 			dpms = SYSTEM_CTRL_DPMS_VPHP;
508 			pps = PANEL_DISPLAY_CTRL_DATA_DISABLE;
509 			crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
510 			break;
511 #endif
512 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
513 		case FB_BLANK_VSYNC_SUSPEND:
514 #else
515 		case VESA_VSYNC_SUSPEND:
516 #endif
517 			dpms = SYSTEM_CTRL_DPMS_VNHP;
518 			pps = PANEL_DISPLAY_CTRL_DATA_DISABLE;
519 			crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
520 			break;
521 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
522 		case FB_BLANK_HSYNC_SUSPEND:
523 #else
524 		case VESA_HSYNC_SUSPEND:
525 #endif
526 			dpms = SYSTEM_CTRL_DPMS_VPHN;
527 			pps = PANEL_DISPLAY_CTRL_DATA_DISABLE;
528 			crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
529 			break;
530 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
531 		case FB_BLANK_POWERDOWN:
532 #else
533 		case VESA_POWERDOWN:
534 #endif
535 			dpms = SYSTEM_CTRL_DPMS_VNHN;
536 			pps = PANEL_DISPLAY_CTRL_DATA_DISABLE;
537 			crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
538 			break;
539 	}
540 
541 	if(output->paths & sm750_crt){
542 
543 		POKE32(SYSTEM_CTRL,FIELD_VALUE(PEEK32(SYSTEM_CTRL), SYSTEM_CTRL, DPMS, dpms));
544 		POKE32(CRT_DISPLAY_CTRL,FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL,BLANK, crtdb));
545 	}
546 
547 	if(output->paths & sm750_panel){
548 		POKE32(PANEL_DISPLAY_CTRL, FIELD_VALUE(PEEK32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, DATA, pps));
549 	}
550 
551 	return 0;
552 }
553 
554 
hw_sm750_initAccel(struct lynx_share * share)555 void hw_sm750_initAccel(struct lynx_share * share)
556 {
557 	u32 reg;
558 	enable2DEngine(1);
559 
560 	if(getChipType() == SM750LE){
561 		reg = PEEK32(DE_STATE1);
562 		reg = FIELD_SET(reg, DE_STATE1, DE_ABORT,ON);
563 		POKE32(DE_STATE1,reg);
564 
565 		reg = PEEK32(DE_STATE1);
566 		reg = FIELD_SET(reg, DE_STATE1, DE_ABORT,OFF);
567 		POKE32(DE_STATE1, reg);
568 
569 	}else{
570 		/* engine reset */
571 		reg = PEEK32(SYSTEM_CTRL);
572 	    reg = FIELD_SET(reg, SYSTEM_CTRL, DE_ABORT,ON);
573 		POKE32(SYSTEM_CTRL, reg);
574 
575 		reg = PEEK32(SYSTEM_CTRL);
576 		reg = FIELD_SET(reg, SYSTEM_CTRL, DE_ABORT,OFF);
577 		POKE32(SYSTEM_CTRL, reg);
578 	}
579 
580 	/* call 2d init */
581 	share->accel.de_init(&share->accel);
582 }
583 
hw_sm750le_deWait(void)584 int hw_sm750le_deWait(void)
585 {
586 	int i=0x10000000;
587 	while(i--){
588 		unsigned int dwVal = PEEK32(DE_STATE2);
589 		if((FIELD_GET(dwVal, DE_STATE2, DE_STATUS) == DE_STATE2_DE_STATUS_IDLE) &&
590 			(FIELD_GET(dwVal, DE_STATE2, DE_FIFO)  == DE_STATE2_DE_FIFO_EMPTY) &&
591 			(FIELD_GET(dwVal, DE_STATE2, DE_MEM_FIFO) == DE_STATE2_DE_MEM_FIFO_EMPTY))
592 		{
593 			return 0;
594 		}
595 	}
596 	/* timeout error */
597 	return -1;
598 }
599 
600 
hw_sm750_deWait(void)601 int hw_sm750_deWait(void)
602 {
603 	int i=0x10000000;
604 	while(i--){
605 		unsigned int dwVal = PEEK32(SYSTEM_CTRL);
606 		if((FIELD_GET(dwVal,SYSTEM_CTRL,DE_STATUS) == SYSTEM_CTRL_DE_STATUS_IDLE) &&
607 			(FIELD_GET(dwVal,SYSTEM_CTRL,DE_FIFO)  == SYSTEM_CTRL_DE_FIFO_EMPTY) &&
608 			(FIELD_GET(dwVal,SYSTEM_CTRL,DE_MEM_FIFO) == SYSTEM_CTRL_DE_MEM_FIFO_EMPTY))
609 		{
610 			return 0;
611 		}
612 	}
613 	/* timeout error */
614 	return -1;
615 }
616 
hw_sm750_pan_display(struct lynxfb_crtc * crtc,const struct fb_var_screeninfo * var,const struct fb_info * info)617 int hw_sm750_pan_display(struct lynxfb_crtc *crtc,
618         const struct fb_var_screeninfo *var,
619         const struct fb_info *info)
620 {
621     uint32_t total;
622     //check params
623     if ((var->xoffset + var->xres > var->xres_virtual) ||
624             (var->yoffset + var->yres > var->yres_virtual)) {
625         return -EINVAL;
626     }
627 
628     total = var->yoffset * info->fix.line_length +
629         ((var->xoffset * var->bits_per_pixel) >> 3);
630     total += crtc->oScreen;
631     if (crtc->channel == sm750_primary) {
632         POKE32(PANEL_FB_ADDRESS,
633                 FIELD_VALUE(PEEK32(PANEL_FB_ADDRESS),
634                     PANEL_FB_ADDRESS, ADDRESS, total));
635     } else {
636         POKE32(CRT_FB_ADDRESS,
637                 FIELD_VALUE(PEEK32(CRT_FB_ADDRESS),
638                     CRT_FB_ADDRESS, ADDRESS, total));
639     }
640     return 0;
641 }
642 
643