2 * drivers/mb862xx/mb862xxfb.c
4 * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver
6 * (C) 2008 Anatolij Gustschin <agust@denx.de>
7 * DENX Software Engineering
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
18 #include <linux/delay.h>
19 #include <linux/uaccess.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/interrupt.h>
23 #include <linux/pci.h>
24 #if defined(CONFIG_OF)
25 #include <linux/of_platform.h>
27 #include "mb862xxfb.h"
28 #include "mb862xx_reg.h"
30 #define NR_PALETTE 256
31 #define MB862XX_MEM_SIZE 0x1000000
32 #define CORALP_MEM_SIZE 0x2000000
33 #define CARMINE_MEM_SIZE 0x8000000
34 #define DRV_NAME "mb862xxfb"
36 #if defined(CONFIG_SOCRATES)
37 static struct mb862xx_gc_mode socrates_gc_mode
= {
38 /* Mode for Prime View PM070WL4 TFT LCD Panel */
39 { "800x480", 45, 800, 480, 40000, 86, 42, 33, 10, 128, 2, 0, 0, 0 },
40 /* 16 bits/pixel, 16MB, 133MHz, SDRAM memory mode value */
41 16, 0x1000000, GC_CCF_COT_133
, 0x4157ba63
46 static inline int h_total(struct fb_var_screeninfo
*var
)
48 return var
->xres
+ var
->left_margin
+
49 var
->right_margin
+ var
->hsync_len
;
52 static inline int v_total(struct fb_var_screeninfo
*var
)
54 return var
->yres
+ var
->upper_margin
+
55 var
->lower_margin
+ var
->vsync_len
;
58 static inline int hsp(struct fb_var_screeninfo
*var
)
60 return var
->xres
+ var
->right_margin
- 1;
63 static inline int vsp(struct fb_var_screeninfo
*var
)
65 return var
->yres
+ var
->lower_margin
- 1;
68 static inline int d_pitch(struct fb_var_screeninfo
*var
)
70 return var
->xres
* var
->bits_per_pixel
/ 8;
73 static inline unsigned int chan_to_field(unsigned int chan
,
74 struct fb_bitfield
*bf
)
77 chan
>>= 16 - bf
->length
;
78 return chan
<< bf
->offset
;
81 static int mb862xxfb_setcolreg(unsigned regno
,
82 unsigned red
, unsigned green
, unsigned blue
,
83 unsigned transp
, struct fb_info
*info
)
85 struct mb862xxfb_par
*par
= info
->par
;
88 switch (info
->fix
.visual
) {
89 case FB_VISUAL_TRUECOLOR
:
91 val
= chan_to_field(red
, &info
->var
.red
);
92 val
|= chan_to_field(green
, &info
->var
.green
);
93 val
|= chan_to_field(blue
, &info
->var
.blue
);
94 par
->pseudo_palette
[regno
] = val
;
97 case FB_VISUAL_PSEUDOCOLOR
:
99 val
= (red
>> 8) << 16;
100 val
|= (green
>> 8) << 8;
102 outreg(disp
, GC_L0PAL0
+ (regno
* 4), val
);
106 return 1; /* unsupported type */
111 static int mb862xxfb_check_var(struct fb_var_screeninfo
*var
,
117 dev_dbg(fbi
->dev
, "%s\n", __func__
);
119 /* check if these values fit into the registers */
120 if (var
->hsync_len
> 255 || var
->vsync_len
> 255)
123 if ((var
->xres
+ var
->right_margin
) >= 4096)
126 if ((var
->yres
+ var
->lower_margin
) > 4096)
129 if (h_total(var
) > 4096 || v_total(var
) > 4096)
132 if (var
->xres_virtual
> 4096 || var
->yres_virtual
> 4096)
135 if (var
->bits_per_pixel
<= 8)
136 var
->bits_per_pixel
= 8;
137 else if (var
->bits_per_pixel
<= 16)
138 var
->bits_per_pixel
= 16;
139 else if (var
->bits_per_pixel
<= 32)
140 var
->bits_per_pixel
= 32;
143 * can cope with 8,16 or 24/32bpp if resulting
144 * pitch is divisible by 64 without remainder
146 if (d_pitch(&fbi
->var
) % GC_L0M_L0W_UNIT
) {
149 var
->bits_per_pixel
= 0;
151 var
->bits_per_pixel
+= 8;
152 r
= d_pitch(&fbi
->var
) % GC_L0M_L0W_UNIT
;
153 } while (r
&& var
->bits_per_pixel
<= 32);
155 if (d_pitch(&fbi
->var
) % GC_L0M_L0W_UNIT
)
159 /* line length is going to be 128 bit aligned */
160 tmp
= (var
->xres
* var
->bits_per_pixel
) / 8;
164 /* set r/g/b positions and validate bpp */
165 switch (var
->bits_per_pixel
) {
167 var
->red
.length
= var
->bits_per_pixel
;
168 var
->green
.length
= var
->bits_per_pixel
;
169 var
->blue
.length
= var
->bits_per_pixel
;
171 var
->green
.offset
= 0;
172 var
->blue
.offset
= 0;
173 var
->transp
.length
= 0;
177 var
->green
.length
= 5;
178 var
->blue
.length
= 5;
179 var
->red
.offset
= 10;
180 var
->green
.offset
= 5;
181 var
->blue
.offset
= 0;
182 var
->transp
.length
= 0;
186 var
->transp
.length
= 8;
188 var
->green
.length
= 8;
189 var
->blue
.length
= 8;
190 var
->transp
.offset
= 24;
191 var
->red
.offset
= 16;
192 var
->green
.offset
= 8;
193 var
->blue
.offset
= 0;
202 * set display parameters
204 static int mb862xxfb_set_par(struct fb_info
*fbi
)
206 struct mb862xxfb_par
*par
= fbi
->par
;
207 unsigned long reg
, sc
;
209 dev_dbg(par
->dev
, "%s\n", __func__
);
210 if (par
->type
== BT_CORALP
)
211 mb862xxfb_init_accel(fbi
, fbi
->var
.xres
);
217 reg
= inreg(disp
, GC_DCM1
);
218 reg
&= ~GC_DCM01_DEN
;
219 outreg(disp
, GC_DCM1
, reg
);
221 /* set display reference clock div. */
222 sc
= par
->refclk
/ (1000000 / fbi
->var
.pixclock
) - 1;
223 reg
= inreg(disp
, GC_DCM1
);
224 reg
&= ~(GC_DCM01_CKS
| GC_DCM01_RESV
| GC_DCM01_SC
);
226 outreg(disp
, GC_DCM1
, reg
);
227 dev_dbg(par
->dev
, "SC 0x%lx\n", sc
);
229 /* disp dimension, format */
230 reg
= pack(d_pitch(&fbi
->var
) / GC_L0M_L0W_UNIT
,
231 (fbi
->var
.yres
- 1));
232 if (fbi
->var
.bits_per_pixel
== 16)
233 reg
|= GC_L0M_L0C_16
;
234 outreg(disp
, GC_L0M
, reg
);
236 if (fbi
->var
.bits_per_pixel
== 32) {
237 reg
= inreg(disp
, GC_L0EM
);
238 outreg(disp
, GC_L0EM
, reg
| GC_L0EM_L0EC_24
);
240 outreg(disp
, GC_WY_WX
, 0);
241 reg
= pack(fbi
->var
.yres
- 1, fbi
->var
.xres
);
242 outreg(disp
, GC_WH_WW
, reg
);
243 outreg(disp
, GC_L0OA0
, 0);
244 outreg(disp
, GC_L0DA0
, 0);
245 outreg(disp
, GC_L0DY_L0DX
, 0);
246 outreg(disp
, GC_L0WY_L0WX
, 0);
247 outreg(disp
, GC_L0WH_L0WW
, reg
);
249 /* both HW-cursors off */
250 reg
= inreg(disp
, GC_CPM_CUTC
);
251 reg
&= ~(GC_CPM_CEN0
| GC_CPM_CEN1
);
252 outreg(disp
, GC_CPM_CUTC
, reg
);
255 reg
= pack(fbi
->var
.xres
- 1, fbi
->var
.xres
- 1);
256 outreg(disp
, GC_HDB_HDP
, reg
);
257 reg
= pack((fbi
->var
.yres
- 1), vsp(&fbi
->var
));
258 outreg(disp
, GC_VDP_VSP
, reg
);
259 reg
= ((fbi
->var
.vsync_len
- 1) << 24) |
260 pack((fbi
->var
.hsync_len
- 1), hsp(&fbi
->var
));
261 outreg(disp
, GC_VSW_HSW_HSP
, reg
);
262 outreg(disp
, GC_HTP
, pack(h_total(&fbi
->var
) - 1, 0));
263 outreg(disp
, GC_VTR
, pack(v_total(&fbi
->var
) - 1, 0));
266 reg
= inreg(disp
, GC_DCM1
);
267 reg
|= GC_DCM01_DEN
| GC_DCM01_L0E
;
268 reg
&= ~GC_DCM01_ESY
;
269 outreg(disp
, GC_DCM1
, reg
);
273 static int mb862xxfb_pan(struct fb_var_screeninfo
*var
,
274 struct fb_info
*info
)
276 struct mb862xxfb_par
*par
= info
->par
;
279 reg
= pack(var
->yoffset
, var
->xoffset
);
280 outreg(disp
, GC_L0WY_L0WX
, reg
);
282 reg
= pack(info
->var
.yres_virtual
, info
->var
.xres_virtual
);
283 outreg(disp
, GC_L0WH_L0WW
, reg
);
287 static int mb862xxfb_blank(int mode
, struct fb_info
*fbi
)
289 struct mb862xxfb_par
*par
= fbi
->par
;
292 dev_dbg(fbi
->dev
, "blank mode=%d\n", mode
);
295 case FB_BLANK_POWERDOWN
:
296 reg
= inreg(disp
, GC_DCM1
);
297 reg
&= ~GC_DCM01_DEN
;
298 outreg(disp
, GC_DCM1
, reg
);
300 case FB_BLANK_UNBLANK
:
301 reg
= inreg(disp
, GC_DCM1
);
303 outreg(disp
, GC_DCM1
, reg
);
305 case FB_BLANK_NORMAL
:
306 case FB_BLANK_VSYNC_SUSPEND
:
307 case FB_BLANK_HSYNC_SUSPEND
:
314 static int mb862xxfb_ioctl(struct fb_info
*fbi
, unsigned int cmd
,
317 struct mb862xxfb_par
*par
= fbi
->par
;
318 struct mb862xx_l1_cfg
*l1_cfg
= &par
->l1_cfg
;
319 void __user
*argp
= (void __user
*)arg
;
324 case MB862XX_L1_GET_CFG
:
325 if (copy_to_user(argp
, l1_cfg
, sizeof(*l1_cfg
)))
328 case MB862XX_L1_SET_CFG
:
329 if (copy_from_user(l1_cfg
, argp
, sizeof(*l1_cfg
)))
331 if ((l1_cfg
->sw
>= l1_cfg
->dw
) && (l1_cfg
->sh
>= l1_cfg
->dh
)) {
333 outreg(cap
, GC_CAP_CSC
,
334 pack((l1_cfg
->sh
<< 11) / l1_cfg
->dh
,
335 (l1_cfg
->sw
<< 11) / l1_cfg
->dw
));
336 l1em
= inreg(disp
, GC_L1EM
);
338 } else if ((l1_cfg
->sw
<= l1_cfg
->dw
) &&
339 (l1_cfg
->sh
<= l1_cfg
->dh
)) {
341 outreg(cap
, GC_CAP_CSC
,
342 pack((l1_cfg
->sh
<< 11) / l1_cfg
->dh
,
343 (l1_cfg
->sw
<< 11) / l1_cfg
->dw
));
344 outreg(cap
, GC_CAP_CMSS
,
345 pack(l1_cfg
->sw
>> 1, l1_cfg
->sh
));
346 outreg(cap
, GC_CAP_CMDS
,
347 pack(l1_cfg
->dw
>> 1, l1_cfg
->dh
));
348 l1em
= inreg(disp
, GC_L1EM
);
352 if (l1_cfg
->mirror
) {
353 outreg(cap
, GC_CAP_CBM
,
354 inreg(cap
, GC_CAP_CBM
) | GC_CBM_HRV
);
355 l1em
|= l1_cfg
->dw
* 2 - 8;
357 outreg(cap
, GC_CAP_CBM
,
358 inreg(cap
, GC_CAP_CBM
) & ~GC_CBM_HRV
);
361 outreg(disp
, GC_L1EM
, l1em
);
363 case MB862XX_L1_ENABLE
:
366 outreg(disp
, GC_L1DA
, par
->cap_buf
);
367 outreg(cap
, GC_CAP_IMG_START
,
368 pack(l1_cfg
->sy
>> 1, l1_cfg
->sx
));
369 outreg(cap
, GC_CAP_IMG_END
,
370 pack(l1_cfg
->sh
, l1_cfg
->sw
));
371 outreg(disp
, GC_L1M
, GC_L1M_16
| GC_L1M_YC
| GC_L1M_CS
|
372 (par
->l1_stride
<< 16));
373 outreg(disp
, GC_L1WY_L1WX
,
374 pack(l1_cfg
->dy
, l1_cfg
->dx
));
375 outreg(disp
, GC_L1WH_L1WW
,
376 pack(l1_cfg
->dh
- 1, l1_cfg
->dw
));
377 outreg(disp
, GC_DLS
, 1);
378 outreg(cap
, GC_CAP_VCM
,
379 GC_VCM_VIE
| GC_VCM_CM
| GC_VCM_VS_PAL
);
380 outreg(disp
, GC_DCM1
, inreg(disp
, GC_DCM1
) |
381 GC_DCM1_DEN
| GC_DCM1_L1E
);
383 outreg(cap
, GC_CAP_VCM
,
384 inreg(cap
, GC_CAP_VCM
) & ~GC_VCM_VIE
);
385 outreg(disp
, GC_DCM1
,
386 inreg(disp
, GC_DCM1
) & ~GC_DCM1_L1E
);
389 case MB862XX_L1_CAP_CTL
:
392 outreg(cap
, GC_CAP_VCM
,
393 inreg(cap
, GC_CAP_VCM
) | GC_VCM_VIE
);
395 outreg(cap
, GC_CAP_VCM
,
396 inreg(cap
, GC_CAP_VCM
) & ~GC_VCM_VIE
);
405 /* framebuffer ops */
406 static struct fb_ops mb862xxfb_ops
= {
407 .owner
= THIS_MODULE
,
408 .fb_check_var
= mb862xxfb_check_var
,
409 .fb_set_par
= mb862xxfb_set_par
,
410 .fb_setcolreg
= mb862xxfb_setcolreg
,
411 .fb_blank
= mb862xxfb_blank
,
412 .fb_pan_display
= mb862xxfb_pan
,
413 .fb_fillrect
= cfb_fillrect
,
414 .fb_copyarea
= cfb_copyarea
,
415 .fb_imageblit
= cfb_imageblit
,
416 .fb_ioctl
= mb862xxfb_ioctl
,
419 /* initialize fb_info data */
420 static int mb862xxfb_init_fbinfo(struct fb_info
*fbi
)
422 struct mb862xxfb_par
*par
= fbi
->par
;
423 struct mb862xx_gc_mode
*mode
= par
->gc_mode
;
427 fbi
->fbops
= &mb862xxfb_ops
;
428 fbi
->pseudo_palette
= par
->pseudo_palette
;
429 fbi
->screen_base
= par
->fb_base
;
430 fbi
->screen_size
= par
->mapped_vram
;
432 strcpy(fbi
->fix
.id
, DRV_NAME
);
433 fbi
->fix
.smem_start
= (unsigned long)par
->fb_base_phys
;
434 fbi
->fix
.mmio_start
= (unsigned long)par
->mmio_base_phys
;
435 fbi
->fix
.mmio_len
= par
->mmio_len
;
436 fbi
->fix
.accel
= FB_ACCEL_NONE
;
437 fbi
->fix
.type
= FB_TYPE_PACKED_PIXELS
;
438 fbi
->fix
.type_aux
= 0;
439 fbi
->fix
.xpanstep
= 1;
440 fbi
->fix
.ypanstep
= 1;
441 fbi
->fix
.ywrapstep
= 0;
443 reg
= inreg(disp
, GC_DCM1
);
444 if (reg
& GC_DCM01_DEN
&& reg
& GC_DCM01_L0E
) {
445 /* get the disp mode from active display cfg */
446 unsigned long sc
= ((reg
& GC_DCM01_SC
) >> 8) + 1;
447 unsigned long hsp
, vsp
, ht
, vt
;
449 dev_dbg(par
->dev
, "using bootloader's disp. mode\n");
450 fbi
->var
.pixclock
= (sc
* 1000000) / par
->refclk
;
451 fbi
->var
.xres
= (inreg(disp
, GC_HDB_HDP
) & 0x0fff) + 1;
452 reg
= inreg(disp
, GC_VDP_VSP
);
453 fbi
->var
.yres
= ((reg
>> 16) & 0x0fff) + 1;
454 vsp
= (reg
& 0x0fff) + 1;
455 fbi
->var
.xres_virtual
= fbi
->var
.xres
;
456 fbi
->var
.yres_virtual
= fbi
->var
.yres
;
457 reg
= inreg(disp
, GC_L0EM
);
458 if (reg
& GC_L0EM_L0EC_24
) {
459 fbi
->var
.bits_per_pixel
= 32;
461 reg
= inreg(disp
, GC_L0M
);
462 if (reg
& GC_L0M_L0C_16
)
463 fbi
->var
.bits_per_pixel
= 16;
465 fbi
->var
.bits_per_pixel
= 8;
467 reg
= inreg(disp
, GC_VSW_HSW_HSP
);
468 fbi
->var
.hsync_len
= ((reg
& 0xff0000) >> 16) + 1;
469 fbi
->var
.vsync_len
= ((reg
& 0x3f000000) >> 24) + 1;
470 hsp
= (reg
& 0xffff) + 1;
471 ht
= ((inreg(disp
, GC_HTP
) & 0xfff0000) >> 16) + 1;
472 fbi
->var
.right_margin
= hsp
- fbi
->var
.xres
;
473 fbi
->var
.left_margin
= ht
- hsp
- fbi
->var
.hsync_len
;
474 vt
= ((inreg(disp
, GC_VTR
) & 0xfff0000) >> 16) + 1;
475 fbi
->var
.lower_margin
= vsp
- fbi
->var
.yres
;
476 fbi
->var
.upper_margin
= vt
- vsp
- fbi
->var
.vsync_len
;
478 dev_dbg(par
->dev
, "using supplied mode\n");
479 fb_videomode_to_var(&fbi
->var
, (struct fb_videomode
*)mode
);
480 fbi
->var
.bits_per_pixel
= mode
->def_bpp
? mode
->def_bpp
: 8;
484 ret
= fb_find_mode(&fbi
->var
, fbi
, "640x480-16@60",
486 if (ret
== 0 || ret
== 4) {
488 "failed to get initial mode\n");
493 fbi
->var
.xoffset
= 0;
494 fbi
->var
.yoffset
= 0;
495 fbi
->var
.grayscale
= 0;
497 fbi
->var
.height
= -1;
499 fbi
->var
.accel_flags
= 0;
500 fbi
->var
.vmode
= FB_VMODE_NONINTERLACED
;
501 fbi
->var
.activate
= FB_ACTIVATE_NOW
;
502 fbi
->flags
= FBINFO_DEFAULT
|
504 FBINFO_FOREIGN_ENDIAN
|
506 FBINFO_HWACCEL_XPAN
|
509 /* check and possibly fix bpp */
510 if ((fbi
->fbops
->fb_check_var
)(&fbi
->var
, fbi
))
511 dev_err(par
->dev
, "check_var() failed on initial setup?\n");
513 fbi
->fix
.visual
= fbi
->var
.bits_per_pixel
== 8 ?
514 FB_VISUAL_PSEUDOCOLOR
: FB_VISUAL_TRUECOLOR
;
515 fbi
->fix
.line_length
= (fbi
->var
.xres_virtual
*
516 fbi
->var
.bits_per_pixel
) / 8;
517 fbi
->fix
.smem_len
= fbi
->fix
.line_length
* fbi
->var
.yres_virtual
;
520 * reserve space for capture buffers and two cursors
521 * at the end of vram: 720x576 * 2 * 2.2 + 64x64 * 16.
523 par
->cap_buf
= par
->mapped_vram
- 0x1bd800 - 0x10000;
524 par
->cap_len
= 0x1bd800;
527 par
->l1_cfg
.sw
= 720;
528 par
->l1_cfg
.sh
= 576;
531 par
->l1_cfg
.dw
= 720;
532 par
->l1_cfg
.dh
= 576;
533 stride
= par
->l1_cfg
.sw
* (fbi
->var
.bits_per_pixel
/ 8);
534 par
->l1_stride
= stride
/ 64 + ((stride
% 64) ? 1 : 0);
535 outreg(cap
, GC_CAP_CBM
, GC_CBM_OO
| GC_CBM_CBST
|
536 (par
->l1_stride
<< 16));
537 outreg(cap
, GC_CAP_CBOA
, par
->cap_buf
);
538 outreg(cap
, GC_CAP_CBLA
, par
->cap_buf
+ par
->cap_len
);
543 * show some display controller and cursor registers
545 static ssize_t
mb862xxfb_show_dispregs(struct device
*dev
,
546 struct device_attribute
*attr
, char *buf
)
548 struct fb_info
*fbi
= dev_get_drvdata(dev
);
549 struct mb862xxfb_par
*par
= fbi
->par
;
553 for (reg
= GC_DCM0
; reg
<= GC_L0DY_L0DX
; reg
+= 4)
554 ptr
+= sprintf(ptr
, "%08x = %08x\n",
555 reg
, inreg(disp
, reg
));
557 for (reg
= GC_CPM_CUTC
; reg
<= GC_CUY1_CUX1
; reg
+= 4)
558 ptr
+= sprintf(ptr
, "%08x = %08x\n",
559 reg
, inreg(disp
, reg
));
561 for (reg
= GC_DCM1
; reg
<= GC_L0WH_L0WW
; reg
+= 4)
562 ptr
+= sprintf(ptr
, "%08x = %08x\n",
563 reg
, inreg(disp
, reg
));
565 for (reg
= 0x400; reg
<= 0x410; reg
+= 4)
566 ptr
+= sprintf(ptr
, "geo %08x = %08x\n",
567 reg
, inreg(geo
, reg
));
569 for (reg
= 0x400; reg
<= 0x410; reg
+= 4)
570 ptr
+= sprintf(ptr
, "draw %08x = %08x\n",
571 reg
, inreg(draw
, reg
));
573 for (reg
= 0x440; reg
<= 0x450; reg
+= 4)
574 ptr
+= sprintf(ptr
, "draw %08x = %08x\n",
575 reg
, inreg(draw
, reg
));
580 static DEVICE_ATTR(dispregs
, 0444, mb862xxfb_show_dispregs
, NULL
);
582 irqreturn_t
mb862xx_intr(int irq
, void *dev_id
)
584 struct mb862xxfb_par
*par
= (struct mb862xxfb_par
*) dev_id
;
585 unsigned long reg_ist
, mask
;
590 if (par
->type
== BT_CARMINE
) {
591 /* Get Interrupt Status */
592 reg_ist
= inreg(ctrl
, GC_CTRL_STATUS
);
593 mask
= inreg(ctrl
, GC_CTRL_INT_MASK
);
601 /* Clear interrupt status */
602 outreg(ctrl
, 0x0, reg_ist
);
605 reg_ist
= inreg(host
, GC_IST
);
606 mask
= inreg(host
, GC_IMASK
);
613 outreg(host
, GC_IST
, ~reg_ist
);
618 #if defined(CONFIG_FB_MB862XX_LIME)
620 * GDC (Lime, Coral(B/Q), Mint, ...) on host bus
622 static int mb862xx_gdc_init(struct mb862xxfb_par
*par
)
624 unsigned long ccf
, mmr
;
625 unsigned long ver
, rev
;
630 #if defined(CONFIG_FB_PRE_INIT_FB)
633 par
->host
= par
->mmio_base
;
634 par
->i2c
= par
->mmio_base
+ MB862XX_I2C_BASE
;
635 par
->disp
= par
->mmio_base
+ MB862XX_DISP_BASE
;
636 par
->cap
= par
->mmio_base
+ MB862XX_CAP_BASE
;
637 par
->draw
= par
->mmio_base
+ MB862XX_DRAW_BASE
;
638 par
->geo
= par
->mmio_base
+ MB862XX_GEO_BASE
;
639 par
->pio
= par
->mmio_base
+ MB862XX_PIO_BASE
;
641 par
->refclk
= GC_DISP_REFCLK_400
;
643 ver
= inreg(host
, GC_CID
);
644 rev
= inreg(pio
, GC_REVISION
);
645 if ((ver
== 0x303) && (rev
& 0xffffff00) == 0x20050100) {
646 dev_info(par
->dev
, "Fujitsu Lime v1.%d found\n",
649 ccf
= par
->gc_mode
? par
->gc_mode
->ccf
: GC_CCF_COT_100
;
650 mmr
= par
->gc_mode
? par
->gc_mode
->mmr
: 0x414fb7f2;
652 dev_info(par
->dev
, "? GDC, CID/Rev.: 0x%lx/0x%lx \n", ver
, rev
);
656 if (!par
->pre_init
) {
657 outreg(host
, GC_CCF
, ccf
);
659 outreg(host
, GC_MMR
, mmr
);
663 /* interrupt status */
664 outreg(host
, GC_IST
, 0);
665 outreg(host
, GC_IMASK
, GC_INT_EN
);
669 static int __devinit
of_platform_mb862xx_probe(struct platform_device
*ofdev
)
671 struct device_node
*np
= ofdev
->dev
.of_node
;
672 struct device
*dev
= &ofdev
->dev
;
673 struct mb862xxfb_par
*par
;
674 struct fb_info
*info
;
676 resource_size_t res_size
;
677 unsigned long ret
= -ENODEV
;
679 if (of_address_to_resource(np
, 0, &res
)) {
680 dev_err(dev
, "Invalid address\n");
684 info
= framebuffer_alloc(sizeof(struct mb862xxfb_par
), dev
);
686 dev_err(dev
, "cannot allocate framebuffer\n");
694 par
->irq
= irq_of_parse_and_map(np
, 0);
695 if (par
->irq
== NO_IRQ
) {
696 dev_err(dev
, "failed to map irq\n");
701 res_size
= resource_size(&res
);
702 par
->res
= request_mem_region(res
.start
, res_size
, DRV_NAME
);
703 if (par
->res
== NULL
) {
704 dev_err(dev
, "Cannot claim framebuffer/mmio\n");
709 #if defined(CONFIG_SOCRATES)
710 par
->gc_mode
= &socrates_gc_mode
;
713 par
->fb_base_phys
= res
.start
;
714 par
->mmio_base_phys
= res
.start
+ MB862XX_MMIO_BASE
;
715 par
->mmio_len
= MB862XX_MMIO_SIZE
;
717 par
->mapped_vram
= par
->gc_mode
->max_vram
;
719 par
->mapped_vram
= MB862XX_MEM_SIZE
;
721 par
->fb_base
= ioremap(par
->fb_base_phys
, par
->mapped_vram
);
722 if (par
->fb_base
== NULL
) {
723 dev_err(dev
, "Cannot map framebuffer\n");
727 par
->mmio_base
= ioremap(par
->mmio_base_phys
, par
->mmio_len
);
728 if (par
->mmio_base
== NULL
) {
729 dev_err(dev
, "Cannot map registers\n");
733 dev_dbg(dev
, "fb phys 0x%llx 0x%lx\n",
734 (u64
)par
->fb_base_phys
, (ulong
)par
->mapped_vram
);
735 dev_dbg(dev
, "mmio phys 0x%llx 0x%lx, (irq = %d)\n",
736 (u64
)par
->mmio_base_phys
, (ulong
)par
->mmio_len
, par
->irq
);
738 if (mb862xx_gdc_init(par
))
741 if (request_irq(par
->irq
, mb862xx_intr
, IRQF_DISABLED
,
742 DRV_NAME
, (void *)par
)) {
743 dev_err(dev
, "Cannot request irq\n");
747 mb862xxfb_init_fbinfo(info
);
749 if (fb_alloc_cmap(&info
->cmap
, NR_PALETTE
, 0) < 0) {
750 dev_err(dev
, "Could not allocate cmap for fb_info.\n");
754 if ((info
->fbops
->fb_set_par
)(info
))
755 dev_err(dev
, "set_var() failed on initial setup?\n");
757 if (register_framebuffer(info
)) {
758 dev_err(dev
, "failed to register framebuffer\n");
762 dev_set_drvdata(dev
, info
);
764 if (device_create_file(dev
, &dev_attr_dispregs
))
765 dev_err(dev
, "Can't create sysfs regdump file\n");
769 fb_dealloc_cmap(&info
->cmap
);
771 outreg(host
, GC_IMASK
, 0);
772 free_irq(par
->irq
, (void *)par
);
774 iounmap(par
->mmio_base
);
776 iounmap(par
->fb_base
);
778 release_mem_region(res
.start
, res_size
);
780 irq_dispose_mapping(par
->irq
);
782 dev_set_drvdata(dev
, NULL
);
783 framebuffer_release(info
);
787 static int __devexit
of_platform_mb862xx_remove(struct platform_device
*ofdev
)
789 struct fb_info
*fbi
= dev_get_drvdata(&ofdev
->dev
);
790 struct mb862xxfb_par
*par
= fbi
->par
;
791 resource_size_t res_size
= resource_size(par
->res
);
794 dev_dbg(fbi
->dev
, "%s release\n", fbi
->fix
.id
);
797 reg
= inreg(disp
, GC_DCM1
);
798 reg
&= ~(GC_DCM01_DEN
| GC_DCM01_L0E
);
799 outreg(disp
, GC_DCM1
, reg
);
801 /* disable interrupts */
802 outreg(host
, GC_IMASK
, 0);
804 free_irq(par
->irq
, (void *)par
);
805 irq_dispose_mapping(par
->irq
);
807 device_remove_file(&ofdev
->dev
, &dev_attr_dispregs
);
809 unregister_framebuffer(fbi
);
810 fb_dealloc_cmap(&fbi
->cmap
);
812 iounmap(par
->mmio_base
);
813 iounmap(par
->fb_base
);
815 dev_set_drvdata(&ofdev
->dev
, NULL
);
816 release_mem_region(par
->res
->start
, res_size
);
817 framebuffer_release(fbi
);
824 static struct of_device_id __devinitdata of_platform_mb862xx_tbl
[] = {
825 { .compatible
= "fujitsu,MB86276", },
826 { .compatible
= "fujitsu,lime", },
827 { .compatible
= "fujitsu,MB86277", },
828 { .compatible
= "fujitsu,mint", },
829 { .compatible
= "fujitsu,MB86293", },
830 { .compatible
= "fujitsu,MB86294", },
831 { .compatible
= "fujitsu,coral", },
835 static struct platform_driver of_platform_mb862xxfb_driver
= {
838 .owner
= THIS_MODULE
,
839 .of_match_table
= of_platform_mb862xx_tbl
,
841 .probe
= of_platform_mb862xx_probe
,
842 .remove
= __devexit_p(of_platform_mb862xx_remove
),
846 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
847 static int coralp_init(struct mb862xxfb_par
*par
)
851 par
->host
= par
->mmio_base
;
852 par
->i2c
= par
->mmio_base
+ MB862XX_I2C_BASE
;
853 par
->disp
= par
->mmio_base
+ MB862XX_DISP_BASE
;
854 par
->cap
= par
->mmio_base
+ MB862XX_CAP_BASE
;
855 par
->draw
= par
->mmio_base
+ MB862XX_DRAW_BASE
;
856 par
->geo
= par
->mmio_base
+ MB862XX_GEO_BASE
;
857 par
->pio
= par
->mmio_base
+ MB862XX_PIO_BASE
;
859 par
->refclk
= GC_DISP_REFCLK_400
;
861 if (par
->mapped_vram
>= 0x2000000) {
862 /* relocate gdc registers space */
863 writel(1, par
->fb_base
+ MB862XX_MMIO_BASE
+ GC_RSW
);
864 udelay(1); /* wait at least 20 bus cycles */
867 ver
= inreg(host
, GC_CID
);
868 cn
= (ver
& GC_CID_CNAME_MSK
) >> 8;
869 ver
= ver
& GC_CID_VERSION_MSK
;
873 dev_info(par
->dev
, "Fujitsu Coral-%s GDC Rev.%d found\n",\
874 (ver
== 6) ? "P" : (ver
== 8) ? "PA" : "?",
875 par
->pdev
->revision
);
876 reg
= inreg(disp
, GC_DCM1
);
877 if (reg
& GC_DCM01_DEN
&& reg
& GC_DCM01_L0E
)
880 if (!par
->pre_init
) {
881 outreg(host
, GC_CCF
, GC_CCF_CGE_166
| GC_CCF_COT_133
);
883 outreg(host
, GC_MMR
, GC_MMR_CORALP_EVB_VAL
);
886 /* Clear interrupt status */
887 outreg(host
, GC_IST
, 0);
892 mb862xx_i2c_init(par
);
896 static int init_dram_ctrl(struct mb862xxfb_par
*par
)
901 * Set io mode first! Spec. says IC may be destroyed
902 * if not set to SSTL2/LVCMOS before init.
904 outreg(dram_ctrl
, GC_DCTL_IOCONT1_IOCONT0
, GC_EVB_DCTL_IOCONT1_IOCONT0
);
907 outreg(dram_ctrl
, GC_DCTL_MODE_ADD
, GC_EVB_DCTL_MODE_ADD
);
908 outreg(dram_ctrl
, GC_DCTL_SETTIME1_EMODE
, GC_EVB_DCTL_SETTIME1_EMODE
);
909 outreg(dram_ctrl
, GC_DCTL_REFRESH_SETTIME2
,
910 GC_EVB_DCTL_REFRESH_SETTIME2
);
911 outreg(dram_ctrl
, GC_DCTL_RSV2_RSV1
, GC_EVB_DCTL_RSV2_RSV1
);
912 outreg(dram_ctrl
, GC_DCTL_DDRIF2_DDRIF1
, GC_EVB_DCTL_DDRIF2_DDRIF1
);
913 outreg(dram_ctrl
, GC_DCTL_RSV0_STATES
, GC_EVB_DCTL_RSV0_STATES
);
915 /* DLL reset done? */
916 while ((inreg(dram_ctrl
, GC_DCTL_RSV0_STATES
) & GC_DCTL_STATES_MSK
)) {
917 udelay(GC_DCTL_INIT_WAIT_INTERVAL
);
918 if (i
++ > GC_DCTL_INIT_WAIT_CNT
) {
919 dev_err(par
->dev
, "VRAM init failed.\n");
923 outreg(dram_ctrl
, GC_DCTL_MODE_ADD
, GC_EVB_DCTL_MODE_ADD_AFT_RST
);
924 outreg(dram_ctrl
, GC_DCTL_RSV0_STATES
, GC_EVB_DCTL_RSV0_STATES_AFT_RST
);
928 static int carmine_init(struct mb862xxfb_par
*par
)
932 par
->ctrl
= par
->mmio_base
+ MB86297_CTRL_BASE
;
933 par
->i2c
= par
->mmio_base
+ MB86297_I2C_BASE
;
934 par
->disp
= par
->mmio_base
+ MB86297_DISP0_BASE
;
935 par
->disp1
= par
->mmio_base
+ MB86297_DISP1_BASE
;
936 par
->cap
= par
->mmio_base
+ MB86297_CAP0_BASE
;
937 par
->cap1
= par
->mmio_base
+ MB86297_CAP1_BASE
;
938 par
->draw
= par
->mmio_base
+ MB86297_DRAW_BASE
;
939 par
->dram_ctrl
= par
->mmio_base
+ MB86297_DRAMCTRL_BASE
;
940 par
->wrback
= par
->mmio_base
+ MB86297_WRBACK_BASE
;
942 par
->refclk
= GC_DISP_REFCLK_533
;
945 reg
= GC_CTRL_CLK_EN_DRAM
| GC_CTRL_CLK_EN_2D3D
| GC_CTRL_CLK_EN_DISP0
;
946 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, reg
);
948 /* check for engine module revision */
949 if (inreg(draw
, GC_2D3D_REV
) == GC_RE_REVISION
)
950 dev_info(par
->dev
, "Fujitsu Carmine GDC Rev.%d found\n",
951 par
->pdev
->revision
);
955 reg
&= ~GC_CTRL_CLK_EN_2D3D
;
956 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, reg
);
959 if (init_dram_ctrl(par
) < 0)
962 outreg(ctrl
, GC_CTRL_INT_MASK
, 0);
966 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, 0);
970 static inline int mb862xx_pci_gdc_init(struct mb862xxfb_par
*par
)
974 return coralp_init(par
);
976 return carmine_init(par
);
982 #define CHIP_ID(id) \
983 { PCI_DEVICE(PCI_VENDOR_ID_FUJITSU_LIMITED, id) }
985 static struct pci_device_id mb862xx_pci_tbl
[] __devinitdata
= {
986 /* MB86295/MB86296 */
987 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALP
),
988 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALPA
),
990 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CARMINE
),
994 MODULE_DEVICE_TABLE(pci
, mb862xx_pci_tbl
);
996 static int __devinit
mb862xx_pci_probe(struct pci_dev
*pdev
,
997 const struct pci_device_id
*ent
)
999 struct mb862xxfb_par
*par
;
1000 struct fb_info
*info
;
1001 struct device
*dev
= &pdev
->dev
;
1004 ret
= pci_enable_device(pdev
);
1006 dev_err(dev
, "Cannot enable PCI device\n");
1010 info
= framebuffer_alloc(sizeof(struct mb862xxfb_par
), dev
);
1012 dev_err(dev
, "framebuffer alloc failed\n");
1021 par
->irq
= pdev
->irq
;
1023 ret
= pci_request_regions(pdev
, DRV_NAME
);
1025 dev_err(dev
, "Cannot reserve region(s) for PCI device\n");
1029 switch (pdev
->device
) {
1030 case PCI_DEVICE_ID_FUJITSU_CORALP
:
1031 case PCI_DEVICE_ID_FUJITSU_CORALPA
:
1032 par
->fb_base_phys
= pci_resource_start(par
->pdev
, 0);
1033 par
->mapped_vram
= CORALP_MEM_SIZE
;
1034 if (par
->mapped_vram
>= 0x2000000) {
1035 par
->mmio_base_phys
= par
->fb_base_phys
+
1036 MB862XX_MMIO_HIGH_BASE
;
1038 par
->mmio_base_phys
= par
->fb_base_phys
+
1041 par
->mmio_len
= MB862XX_MMIO_SIZE
;
1042 par
->type
= BT_CORALP
;
1044 case PCI_DEVICE_ID_FUJITSU_CARMINE
:
1045 par
->fb_base_phys
= pci_resource_start(par
->pdev
, 2);
1046 par
->mmio_base_phys
= pci_resource_start(par
->pdev
, 3);
1047 par
->mmio_len
= pci_resource_len(par
->pdev
, 3);
1048 par
->mapped_vram
= CARMINE_MEM_SIZE
;
1049 par
->type
= BT_CARMINE
;
1052 /* should never occur */
1056 par
->fb_base
= ioremap(par
->fb_base_phys
, par
->mapped_vram
);
1057 if (par
->fb_base
== NULL
) {
1058 dev_err(dev
, "Cannot map framebuffer\n");
1062 par
->mmio_base
= ioremap(par
->mmio_base_phys
, par
->mmio_len
);
1063 if (par
->mmio_base
== NULL
) {
1064 dev_err(dev
, "Cannot map registers\n");
1069 dev_dbg(dev
, "fb phys 0x%llx 0x%lx\n",
1070 (unsigned long long)par
->fb_base_phys
, (ulong
)par
->mapped_vram
);
1071 dev_dbg(dev
, "mmio phys 0x%llx 0x%lx\n",
1072 (unsigned long long)par
->mmio_base_phys
, (ulong
)par
->mmio_len
);
1074 if (mb862xx_pci_gdc_init(par
))
1077 if (request_irq(par
->irq
, mb862xx_intr
, IRQF_DISABLED
| IRQF_SHARED
,
1078 DRV_NAME
, (void *)par
)) {
1079 dev_err(dev
, "Cannot request irq\n");
1083 mb862xxfb_init_fbinfo(info
);
1085 if (fb_alloc_cmap(&info
->cmap
, NR_PALETTE
, 0) < 0) {
1086 dev_err(dev
, "Could not allocate cmap for fb_info.\n");
1091 if ((info
->fbops
->fb_set_par
)(info
))
1092 dev_err(dev
, "set_var() failed on initial setup?\n");
1094 ret
= register_framebuffer(info
);
1096 dev_err(dev
, "failed to register framebuffer\n");
1100 pci_set_drvdata(pdev
, info
);
1102 if (device_create_file(dev
, &dev_attr_dispregs
))
1103 dev_err(dev
, "Can't create sysfs regdump file\n");
1105 if (par
->type
== BT_CARMINE
)
1106 outreg(ctrl
, GC_CTRL_INT_MASK
, GC_CARMINE_INT_EN
);
1108 outreg(host
, GC_IMASK
, GC_INT_EN
);
1113 fb_dealloc_cmap(&info
->cmap
);
1115 free_irq(par
->irq
, (void *)par
);
1117 iounmap(par
->mmio_base
);
1119 iounmap(par
->fb_base
);
1121 pci_release_regions(pdev
);
1123 framebuffer_release(info
);
1125 pci_disable_device(pdev
);
1130 static void __devexit
mb862xx_pci_remove(struct pci_dev
*pdev
)
1132 struct fb_info
*fbi
= pci_get_drvdata(pdev
);
1133 struct mb862xxfb_par
*par
= fbi
->par
;
1136 dev_dbg(fbi
->dev
, "%s release\n", fbi
->fix
.id
);
1139 reg
= inreg(disp
, GC_DCM1
);
1140 reg
&= ~(GC_DCM01_DEN
| GC_DCM01_L0E
);
1141 outreg(disp
, GC_DCM1
, reg
);
1143 if (par
->type
== BT_CARMINE
) {
1144 outreg(ctrl
, GC_CTRL_INT_MASK
, 0);
1145 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, 0);
1147 outreg(host
, GC_IMASK
, 0);
1150 mb862xx_i2c_exit(par
);
1152 device_remove_file(&pdev
->dev
, &dev_attr_dispregs
);
1154 pci_set_drvdata(pdev
, NULL
);
1155 unregister_framebuffer(fbi
);
1156 fb_dealloc_cmap(&fbi
->cmap
);
1158 free_irq(par
->irq
, (void *)par
);
1159 iounmap(par
->mmio_base
);
1160 iounmap(par
->fb_base
);
1162 pci_release_regions(pdev
);
1163 framebuffer_release(fbi
);
1164 pci_disable_device(pdev
);
1167 static struct pci_driver mb862xxfb_pci_driver
= {
1169 .id_table
= mb862xx_pci_tbl
,
1170 .probe
= mb862xx_pci_probe
,
1171 .remove
= __devexit_p(mb862xx_pci_remove
),
1175 static int __devinit
mb862xxfb_init(void)
1179 #if defined(CONFIG_FB_MB862XX_LIME)
1180 ret
= platform_driver_register(&of_platform_mb862xxfb_driver
);
1182 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
1183 ret
= pci_register_driver(&mb862xxfb_pci_driver
);
1188 static void __exit
mb862xxfb_exit(void)
1190 #if defined(CONFIG_FB_MB862XX_LIME)
1191 platform_driver_unregister(&of_platform_mb862xxfb_driver
);
1193 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
1194 pci_unregister_driver(&mb862xxfb_pci_driver
);
1198 module_init(mb862xxfb_init
);
1199 module_exit(mb862xxfb_exit
);
1201 MODULE_DESCRIPTION("Fujitsu MB862xx Framebuffer driver");
1202 MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
1203 MODULE_LICENSE("GPL v2");