]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/staging/sm750fb/sm750_hw.c
Merge tag 'arc-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc
[mirror_ubuntu-artful-kernel.git] / drivers / staging / sm750fb / sm750_hw.c
CommitLineData
81dee67e
SM
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
d2a60377 27int hw_sm750_map(struct lynx_share* share, struct pci_dev* pdev)
81dee67e
SM
28{
29 int ret;
30 struct sm750_share * spec_share;
31
32
d2a60377 33 spec_share = container_of(share, struct sm750_share,share);
81dee67e
SM
34 ret = 0;
35
d2a60377 36 share->vidreg_start = pci_resource_start(pdev, 1);
81dee67e
SM
37 share->vidreg_size = MB(2);
38
e936351a 39 pr_info("mmio phyAddr = %lx\n", share->vidreg_start);
81dee67e
SM
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
d2a60377 47 if((ret = pci_request_region(pdev, 1, "sm750fb")))
81dee67e
SM
48 {
49 pr_err("Can not request PCI regions.\n");
50 goto exit;
51 }
52
53 /* now map mmio and vidmem*/
d2a60377 54 share->pvReg = ioremap_nocache(share->vidreg_start, share->vidreg_size);
81dee67e
SM
55 if(!share->pvReg){
56 pr_err("mmio failed\n");
57 ret = -EFAULT;
58 goto exit;
59 }else{
d2a60377 60 pr_info("mmio virtual addr = %p\n", share->pvReg);
81dee67e
SM
61 }
62
63
64 share->accel.dprBase = share->pvReg + DE_BASE_ADDR_TYPE1;
65 share->accel.dpPortBase = share->pvReg + DE_PORT_ADDR_TYPE1;
66
d2a60377 67 ddk750_set_mmio(share->pvReg,share->devid, share->revid);
81dee67e 68
d2a60377 69 share->vidmem_start = pci_resource_start(pdev, 0);
81dee67e
SM
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);
e936351a 76 pr_info("video memory phyAddr = %lx, size = %u bytes\n",
d2a60377 77 share->vidmem_start, share->vidmem_size);
81dee67e
SM
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{
d2a60377 96 pr_info("video memory vaddr = %p\n", share->pvMem);
81dee67e
SM
97 }
98exit:
99 return ret;
100}
101
102
103
d2a60377 104int hw_sm750_inithw(struct lynx_share* share, struct pci_dev * pdev)
81dee67e
SM
105{
106 struct sm750_share * spec_share;
107 struct init_status * parm;
108
d2a60377 109 spec_share = container_of(share, struct sm750_share,share);
81dee67e
SM
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,
d2a60377 125 FIELD_SET(PEEK32(SYSTEM_CTRL), SYSTEM_CTRL, PCI_BURST, ON));
81dee67e
SM
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,
d2a60377 141 DAC_POWER, OFF));
81dee67e
SM
142 /* shut off dpms */
143 POKE32(SYSTEM_CTRL,
144 FIELD_SET(PEEK32(SYSTEM_CTRL),
145 SYSTEM_CTRL,
d2a60377 146 DPMS, VNHN));
81dee67e
SM
147 }else{
148 POKE32(MISC_CTRL,
149 FIELD_SET(PEEK32(MISC_CTRL),
150 MISC_CTRL,
d2a60377 151 DAC_POWER, ON));
81dee67e
SM
152 /* turn on dpms */
153 POKE32(SYSTEM_CTRL,
154 FIELD_SET(PEEK32(SYSTEM_CTRL),
155 SYSTEM_CTRL,
d2a60377 156 DPMS, VPHP));
81dee67e
SM
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
204resource_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
d2a60377 214int hw_sm750_output_checkMode(struct lynxfb_output* output, struct fb_var_screeninfo* var)
81dee67e
SM
215{
216
217 return 0;
218}
219
220
221int hw_sm750_output_setMode(struct lynxfb_output* output,
d2a60377 222 struct fb_var_screeninfo* var, struct fb_fix_screeninfo* fix)
81dee67e
SM
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;
d2a60377 255 POKE32(DISPLAY_CONTROL_750LE, reg);
81dee67e
SM
256 }
257
258 pr_info("ddk setlogicdispout done \n");
259 return ret;
260}
261
262void hw_sm750_output_clear(struct lynxfb_output* output)
263{
264
265 return;
266}
267
d2a60377 268int hw_sm750_crtc_checkMode(struct lynxfb_crtc* crtc, struct fb_var_screeninfo* var)
81dee67e
SM
269{
270 struct lynx_share * share;
271
272
d2a60377 273 share = container_of(crtc, struct lynxfb_par,crtc)->share;
81dee67e
SM
274
275 switch (var->bits_per_pixel){
276 case 8:
277 case 16:
278 break;
279 case 32:
62fa8e10 280 if (share->revid == SM750LE_REVISION_ID) {
81dee67e
SM
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*/
297int 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;
d2a60377 310 par = container_of(crtc, struct lynxfb_par, crtc);
81dee67e
SM
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 }
d2a60377 327 hw_set2dformat(&share->accel, fmt);
81dee67e
SM
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
d2a60377
SA
352 pr_debug("Request pixel clock = %lu\n", modparm.pixel_clock);
353 ret = ddk750_setModeTiming(&modparm, clock);
81dee67e
SM
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,
d2a60377
SA
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));
81dee67e
SM
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,
d2a60377
SA
371 FIELD_VALUE(0, PANEL_FB_WIDTH, WIDTH, reg)|
372 FIELD_VALUE(0, PANEL_FB_WIDTH, OFFSET, fix->line_length));
81dee67e
SM
373
374 POKE32(PANEL_WINDOW_WIDTH,
d2a60377
SA
375 FIELD_VALUE(0, PANEL_WINDOW_WIDTH, WIDTH, var->xres -1)|
376 FIELD_VALUE(0, PANEL_WINDOW_WIDTH, X, var->xoffset));
81dee67e
SM
377
378 POKE32(PANEL_WINDOW_HEIGHT,
d2a60377
SA
379 FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, HEIGHT, var->yres_virtual - 1)|
380 FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, Y, var->yoffset));
81dee67e 381
d2a60377 382 POKE32(PANEL_PLANE_TL, 0);
81dee67e
SM
383
384 POKE32(PANEL_PLANE_BR,
d2a60377
SA
385 FIELD_VALUE(0, PANEL_PLANE_BR, BOTTOM, var->yres - 1)|
386 FIELD_VALUE(0, PANEL_PLANE_BR,RIGHT, var->xres - 1));
81dee67e
SM
387
388 /* set pixel format */
389 reg = PEEK32(PANEL_DISPLAY_CTRL);
390 POKE32(PANEL_DISPLAY_CTRL,
391 FIELD_VALUE(reg,
d2a60377 392 PANEL_DISPLAY_CTRL, FORMAT,
81dee67e
SM
393 (var->bits_per_pixel >> 4)
394 ));
395 }else{
396 /* not implemented now */
d2a60377 397 POKE32(CRT_FB_ADDRESS, crtc->oScreen);
81dee67e
SM
398 reg = var->xres * (var->bits_per_pixel >> 3);
399 /* crtc->channel is not equal to par->index on numeric,be aware of that */
d2a60377 400 reg = PADDING(crtc->line_pad, reg);
81dee67e
SM
401
402 POKE32(CRT_FB_WIDTH,
d2a60377
SA
403 FIELD_VALUE(0, CRT_FB_WIDTH, WIDTH, reg)|
404 FIELD_VALUE(0, CRT_FB_WIDTH, OFFSET, fix->line_length));
81dee67e
SM
405
406 /* SET PIXEL FORMAT */
407 reg = PEEK32(CRT_DISPLAY_CTRL);
d2a60377
SA
408 reg = FIELD_VALUE(reg, CRT_DISPLAY_CTRL, FORMAT, var->bits_per_pixel >> 4);
409 POKE32(CRT_DISPLAY_CTRL, reg);
81dee67e
SM
410
411 }
412
413
414exit:
415 return ret;
416}
417
418void hw_sm750_crtc_clear(struct lynxfb_crtc* crtc)
419{
420
421 return;
422}
423
d2a60377
SA
424int hw_sm750_setColReg(struct lynxfb_crtc* crtc, ushort index,
425 ushort red, ushort green, ushort blue)
81dee67e
SM
426{
427 static unsigned int add[]={PANEL_PALETTE_RAM,CRT_PALETTE_RAM};
d2a60377 428 POKE32(add[crtc->channel] + index*4, (red<<16)|(green<<8)|blue);
81dee67e
SM
429 return 0;
430}
431
d2a60377 432int hw_sm750le_setBLANK(struct lynxfb_output * output, int blank){
81dee67e
SM
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;
e74ac550
GKH
475 default:
476 return -EINVAL;
81dee67e
SM
477 }
478
479 if(output->paths & sm750_crt){
d2a60377
SA
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));
81dee67e
SM
482 }
483 return 0;
484}
485
486int hw_sm750_setBLANK(struct lynxfb_output* output,int blank)
487{
d2a60377 488 unsigned int dpms, pps, crtdb;
81dee67e
SM
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
d2a60377
SA
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));
81dee67e
SM
545 }
546
547 if(output->paths & sm750_panel){
d2a60377 548 POKE32(PANEL_DISPLAY_CTRL, FIELD_VALUE(PEEK32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, DATA, pps));
81dee67e
SM
549 }
550
551 return 0;
552}
553
554
555void hw_sm750_initAccel(struct lynx_share * share)
556{
557 u32 reg;
558 enable2DEngine(1);
559
560 if(getChipType() == SM750LE){
561 reg = PEEK32(DE_STATE1);
d2a60377 562 reg = FIELD_SET(reg, DE_STATE1, DE_ABORT,ON);
81dee67e
SM
563 POKE32(DE_STATE1,reg);
564
565 reg = PEEK32(DE_STATE1);
d2a60377
SA
566 reg = FIELD_SET(reg, DE_STATE1, DE_ABORT,OFF);
567 POKE32(DE_STATE1, reg);
81dee67e
SM
568
569 }else{
570 /* engine reset */
571 reg = PEEK32(SYSTEM_CTRL);
d2a60377
SA
572 reg = FIELD_SET(reg, SYSTEM_CTRL, DE_ABORT,ON);
573 POKE32(SYSTEM_CTRL, reg);
81dee67e
SM
574
575 reg = PEEK32(SYSTEM_CTRL);
d2a60377
SA
576 reg = FIELD_SET(reg, SYSTEM_CTRL, DE_ABORT,OFF);
577 POKE32(SYSTEM_CTRL, reg);
81dee67e
SM
578 }
579
580 /* call 2d init */
581 share->accel.de_init(&share->accel);
582}
583
6fa7db83 584int hw_sm750le_deWait(void)
81dee67e
SM
585{
586 int i=0x10000000;
587 while(i--){
588 unsigned int dwVal = PEEK32(DE_STATE2);
d2a60377
SA
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))
81dee67e
SM
592 {
593 return 0;
594 }
595 }
596 /* timeout error */
597 return -1;
598}
599
600
6fa7db83 601int hw_sm750_deWait(void)
81dee67e
SM
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
617int 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