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/init.h>
21 #include <linux/interrupt.h>
22 #include <linux/pci.h>
23 #if defined(CONFIG_OF)
24 #include <linux/of_platform.h>
26 #include "mb862xxfb.h"
27 #include "mb862xx_reg.h"
29 #define NR_PALETTE 256
30 #define MB862XX_MEM_SIZE 0x1000000
31 #define CORALP_MEM_SIZE 0x2000000
32 #define CARMINE_MEM_SIZE 0x8000000
33 #define DRV_NAME "mb862xxfb"
35 #if defined(CONFIG_SOCRATES)
36 static struct mb862xx_gc_mode socrates_gc_mode
= {
37 /* Mode for Prime View PM070WL4 TFT LCD Panel */
38 { "800x480", 45, 800, 480, 40000, 86, 42, 33, 10, 128, 2, 0, 0, 0 },
39 /* 16 bits/pixel, 16MB, 133MHz, SDRAM memory mode value */
40 16, 0x1000000, GC_CCF_COT_133
, 0x4157ba63
45 static inline int h_total(struct fb_var_screeninfo
*var
)
47 return var
->xres
+ var
->left_margin
+
48 var
->right_margin
+ var
->hsync_len
;
51 static inline int v_total(struct fb_var_screeninfo
*var
)
53 return var
->yres
+ var
->upper_margin
+
54 var
->lower_margin
+ var
->vsync_len
;
57 static inline int hsp(struct fb_var_screeninfo
*var
)
59 return var
->xres
+ var
->right_margin
- 1;
62 static inline int vsp(struct fb_var_screeninfo
*var
)
64 return var
->yres
+ var
->lower_margin
- 1;
67 static inline int d_pitch(struct fb_var_screeninfo
*var
)
69 return var
->xres
* var
->bits_per_pixel
/ 8;
72 static inline unsigned int chan_to_field(unsigned int chan
,
73 struct fb_bitfield
*bf
)
76 chan
>>= 16 - bf
->length
;
77 return chan
<< bf
->offset
;
80 static int mb862xxfb_setcolreg(unsigned regno
,
81 unsigned red
, unsigned green
, unsigned blue
,
82 unsigned transp
, struct fb_info
*info
)
84 struct mb862xxfb_par
*par
= info
->par
;
87 switch (info
->fix
.visual
) {
88 case FB_VISUAL_TRUECOLOR
:
90 val
= chan_to_field(red
, &info
->var
.red
);
91 val
|= chan_to_field(green
, &info
->var
.green
);
92 val
|= chan_to_field(blue
, &info
->var
.blue
);
93 par
->pseudo_palette
[regno
] = val
;
96 case FB_VISUAL_PSEUDOCOLOR
:
98 val
= (red
>> 8) << 16;
99 val
|= (green
>> 8) << 8;
101 outreg(disp
, GC_L0PAL0
+ (regno
* 4), val
);
105 return 1; /* unsupported type */
110 static int mb862xxfb_check_var(struct fb_var_screeninfo
*var
,
116 dev_dbg(fbi
->dev
, "%s\n", __func__
);
118 /* check if these values fit into the registers */
119 if (var
->hsync_len
> 255 || var
->vsync_len
> 255)
122 if ((var
->xres
+ var
->right_margin
) >= 4096)
125 if ((var
->yres
+ var
->lower_margin
) > 4096)
128 if (h_total(var
) > 4096 || v_total(var
) > 4096)
131 if (var
->xres_virtual
> 4096 || var
->yres_virtual
> 4096)
134 if (var
->bits_per_pixel
<= 8)
135 var
->bits_per_pixel
= 8;
136 else if (var
->bits_per_pixel
<= 16)
137 var
->bits_per_pixel
= 16;
138 else if (var
->bits_per_pixel
<= 32)
139 var
->bits_per_pixel
= 32;
142 * can cope with 8,16 or 24/32bpp if resulting
143 * pitch is divisible by 64 without remainder
145 if (d_pitch(&fbi
->var
) % GC_L0M_L0W_UNIT
) {
148 var
->bits_per_pixel
= 0;
150 var
->bits_per_pixel
+= 8;
151 r
= d_pitch(&fbi
->var
) % GC_L0M_L0W_UNIT
;
152 } while (r
&& var
->bits_per_pixel
<= 32);
154 if (d_pitch(&fbi
->var
) % GC_L0M_L0W_UNIT
)
158 /* line length is going to be 128 bit aligned */
159 tmp
= (var
->xres
* var
->bits_per_pixel
) / 8;
163 /* set r/g/b positions and validate bpp */
164 switch (var
->bits_per_pixel
) {
166 var
->red
.length
= var
->bits_per_pixel
;
167 var
->green
.length
= var
->bits_per_pixel
;
168 var
->blue
.length
= var
->bits_per_pixel
;
170 var
->green
.offset
= 0;
171 var
->blue
.offset
= 0;
172 var
->transp
.length
= 0;
176 var
->green
.length
= 5;
177 var
->blue
.length
= 5;
178 var
->red
.offset
= 10;
179 var
->green
.offset
= 5;
180 var
->blue
.offset
= 0;
181 var
->transp
.length
= 0;
185 var
->transp
.length
= 8;
187 var
->green
.length
= 8;
188 var
->blue
.length
= 8;
189 var
->transp
.offset
= 24;
190 var
->red
.offset
= 16;
191 var
->green
.offset
= 8;
192 var
->blue
.offset
= 0;
201 * set display parameters
203 static int mb862xxfb_set_par(struct fb_info
*fbi
)
205 struct mb862xxfb_par
*par
= fbi
->par
;
206 unsigned long reg
, sc
;
208 dev_dbg(par
->dev
, "%s\n", __func__
);
209 if (par
->type
== BT_CORALP
)
210 mb862xxfb_init_accel(fbi
, fbi
->var
.xres
);
216 reg
= inreg(disp
, GC_DCM1
);
217 reg
&= ~GC_DCM01_DEN
;
218 outreg(disp
, GC_DCM1
, reg
);
220 /* set display reference clock div. */
221 sc
= par
->refclk
/ (1000000 / fbi
->var
.pixclock
) - 1;
222 reg
= inreg(disp
, GC_DCM1
);
223 reg
&= ~(GC_DCM01_CKS
| GC_DCM01_RESV
| GC_DCM01_SC
);
225 outreg(disp
, GC_DCM1
, reg
);
226 dev_dbg(par
->dev
, "SC 0x%lx\n", sc
);
228 /* disp dimension, format */
229 reg
= pack(d_pitch(&fbi
->var
) / GC_L0M_L0W_UNIT
,
230 (fbi
->var
.yres
- 1));
231 if (fbi
->var
.bits_per_pixel
== 16)
232 reg
|= GC_L0M_L0C_16
;
233 outreg(disp
, GC_L0M
, reg
);
235 if (fbi
->var
.bits_per_pixel
== 32) {
236 reg
= inreg(disp
, GC_L0EM
);
237 outreg(disp
, GC_L0EM
, reg
| GC_L0EM_L0EC_24
);
239 outreg(disp
, GC_WY_WX
, 0);
240 reg
= pack(fbi
->var
.yres
- 1, fbi
->var
.xres
);
241 outreg(disp
, GC_WH_WW
, reg
);
242 outreg(disp
, GC_L0OA0
, 0);
243 outreg(disp
, GC_L0DA0
, 0);
244 outreg(disp
, GC_L0DY_L0DX
, 0);
245 outreg(disp
, GC_L0WY_L0WX
, 0);
246 outreg(disp
, GC_L0WH_L0WW
, reg
);
248 /* both HW-cursors off */
249 reg
= inreg(disp
, GC_CPM_CUTC
);
250 reg
&= ~(GC_CPM_CEN0
| GC_CPM_CEN1
);
251 outreg(disp
, GC_CPM_CUTC
, reg
);
254 reg
= pack(fbi
->var
.xres
- 1, fbi
->var
.xres
- 1);
255 outreg(disp
, GC_HDB_HDP
, reg
);
256 reg
= pack((fbi
->var
.yres
- 1), vsp(&fbi
->var
));
257 outreg(disp
, GC_VDP_VSP
, reg
);
258 reg
= ((fbi
->var
.vsync_len
- 1) << 24) |
259 pack((fbi
->var
.hsync_len
- 1), hsp(&fbi
->var
));
260 outreg(disp
, GC_VSW_HSW_HSP
, reg
);
261 outreg(disp
, GC_HTP
, pack(h_total(&fbi
->var
) - 1, 0));
262 outreg(disp
, GC_VTR
, pack(v_total(&fbi
->var
) - 1, 0));
265 reg
= inreg(disp
, GC_DCM1
);
266 reg
|= GC_DCM01_DEN
| GC_DCM01_L0E
;
267 reg
&= ~GC_DCM01_ESY
;
268 outreg(disp
, GC_DCM1
, reg
);
272 static int mb862xxfb_pan(struct fb_var_screeninfo
*var
,
273 struct fb_info
*info
)
275 struct mb862xxfb_par
*par
= info
->par
;
278 reg
= pack(var
->yoffset
, var
->xoffset
);
279 outreg(disp
, GC_L0WY_L0WX
, reg
);
281 reg
= pack(var
->yres_virtual
, var
->xres_virtual
);
282 outreg(disp
, GC_L0WH_L0WW
, reg
);
286 static int mb862xxfb_blank(int mode
, struct fb_info
*fbi
)
288 struct mb862xxfb_par
*par
= fbi
->par
;
291 dev_dbg(fbi
->dev
, "blank mode=%d\n", mode
);
294 case FB_BLANK_POWERDOWN
:
295 reg
= inreg(disp
, GC_DCM1
);
296 reg
&= ~GC_DCM01_DEN
;
297 outreg(disp
, GC_DCM1
, reg
);
299 case FB_BLANK_UNBLANK
:
300 reg
= inreg(disp
, GC_DCM1
);
302 outreg(disp
, GC_DCM1
, reg
);
304 case FB_BLANK_NORMAL
:
305 case FB_BLANK_VSYNC_SUSPEND
:
306 case FB_BLANK_HSYNC_SUSPEND
:
313 static int mb862xxfb_ioctl(struct fb_info
*fbi
, unsigned int cmd
,
316 struct mb862xxfb_par
*par
= fbi
->par
;
317 struct mb862xx_l1_cfg
*l1_cfg
= &par
->l1_cfg
;
318 void __user
*argp
= (void __user
*)arg
;
323 case MB862XX_L1_GET_CFG
:
324 if (copy_to_user(argp
, l1_cfg
, sizeof(*l1_cfg
)))
327 case MB862XX_L1_SET_CFG
:
328 if (copy_from_user(l1_cfg
, argp
, sizeof(*l1_cfg
)))
330 if ((l1_cfg
->sw
>= l1_cfg
->dw
) && (l1_cfg
->sh
>= l1_cfg
->dh
)) {
332 outreg(cap
, GC_CAP_CSC
,
333 pack((l1_cfg
->sh
<< 11) / l1_cfg
->dh
,
334 (l1_cfg
->sw
<< 11) / l1_cfg
->dw
));
335 l1em
= inreg(disp
, GC_L1EM
);
337 } else if ((l1_cfg
->sw
<= l1_cfg
->dw
) &&
338 (l1_cfg
->sh
<= l1_cfg
->dh
)) {
340 outreg(cap
, GC_CAP_CSC
,
341 pack((l1_cfg
->sh
<< 11) / l1_cfg
->dh
,
342 (l1_cfg
->sw
<< 11) / l1_cfg
->dw
));
343 outreg(cap
, GC_CAP_CMSS
,
344 pack(l1_cfg
->sw
>> 1, l1_cfg
->sh
));
345 outreg(cap
, GC_CAP_CMDS
,
346 pack(l1_cfg
->dw
>> 1, l1_cfg
->dh
));
347 l1em
= inreg(disp
, GC_L1EM
);
351 if (l1_cfg
->mirror
) {
352 outreg(cap
, GC_CAP_CBM
,
353 inreg(cap
, GC_CAP_CBM
) | GC_CBM_HRV
);
354 l1em
|= l1_cfg
->dw
* 2 - 8;
356 outreg(cap
, GC_CAP_CBM
,
357 inreg(cap
, GC_CAP_CBM
) & ~GC_CBM_HRV
);
360 outreg(disp
, GC_L1EM
, l1em
);
362 case MB862XX_L1_ENABLE
:
365 outreg(disp
, GC_L1DA
, par
->cap_buf
);
366 outreg(cap
, GC_CAP_IMG_START
,
367 pack(l1_cfg
->sy
>> 1, l1_cfg
->sx
));
368 outreg(cap
, GC_CAP_IMG_END
,
369 pack(l1_cfg
->sh
, l1_cfg
->sw
));
370 outreg(disp
, GC_L1M
, GC_L1M_16
| GC_L1M_YC
| GC_L1M_CS
|
371 (par
->l1_stride
<< 16));
372 outreg(disp
, GC_L1WY_L1WX
,
373 pack(l1_cfg
->dy
, l1_cfg
->dx
));
374 outreg(disp
, GC_L1WH_L1WW
,
375 pack(l1_cfg
->dh
- 1, l1_cfg
->dw
));
376 outreg(disp
, GC_DLS
, 1);
377 outreg(cap
, GC_CAP_VCM
,
378 GC_VCM_VIE
| GC_VCM_CM
| GC_VCM_VS_PAL
);
379 outreg(disp
, GC_DCM1
, inreg(disp
, GC_DCM1
) |
380 GC_DCM1_DEN
| GC_DCM1_L1E
);
382 outreg(cap
, GC_CAP_VCM
,
383 inreg(cap
, GC_CAP_VCM
) & ~GC_VCM_VIE
);
384 outreg(disp
, GC_DCM1
,
385 inreg(disp
, GC_DCM1
) & ~GC_DCM1_L1E
);
388 case MB862XX_L1_CAP_CTL
:
391 outreg(cap
, GC_CAP_VCM
,
392 inreg(cap
, GC_CAP_VCM
) | GC_VCM_VIE
);
394 outreg(cap
, GC_CAP_VCM
,
395 inreg(cap
, GC_CAP_VCM
) & ~GC_VCM_VIE
);
404 /* framebuffer ops */
405 static struct fb_ops mb862xxfb_ops
= {
406 .owner
= THIS_MODULE
,
407 .fb_check_var
= mb862xxfb_check_var
,
408 .fb_set_par
= mb862xxfb_set_par
,
409 .fb_setcolreg
= mb862xxfb_setcolreg
,
410 .fb_blank
= mb862xxfb_blank
,
411 .fb_pan_display
= mb862xxfb_pan
,
412 .fb_fillrect
= cfb_fillrect
,
413 .fb_copyarea
= cfb_copyarea
,
414 .fb_imageblit
= cfb_imageblit
,
415 .fb_ioctl
= mb862xxfb_ioctl
,
418 /* initialize fb_info data */
419 static int mb862xxfb_init_fbinfo(struct fb_info
*fbi
)
421 struct mb862xxfb_par
*par
= fbi
->par
;
422 struct mb862xx_gc_mode
*mode
= par
->gc_mode
;
426 fbi
->fbops
= &mb862xxfb_ops
;
427 fbi
->pseudo_palette
= par
->pseudo_palette
;
428 fbi
->screen_base
= par
->fb_base
;
429 fbi
->screen_size
= par
->mapped_vram
;
431 strcpy(fbi
->fix
.id
, DRV_NAME
);
432 fbi
->fix
.smem_start
= (unsigned long)par
->fb_base_phys
;
433 fbi
->fix
.mmio_start
= (unsigned long)par
->mmio_base_phys
;
434 fbi
->fix
.mmio_len
= par
->mmio_len
;
435 fbi
->fix
.accel
= FB_ACCEL_NONE
;
436 fbi
->fix
.type
= FB_TYPE_PACKED_PIXELS
;
437 fbi
->fix
.type_aux
= 0;
438 fbi
->fix
.xpanstep
= 1;
439 fbi
->fix
.ypanstep
= 1;
440 fbi
->fix
.ywrapstep
= 0;
442 reg
= inreg(disp
, GC_DCM1
);
443 if (reg
& GC_DCM01_DEN
&& reg
& GC_DCM01_L0E
) {
444 /* get the disp mode from active display cfg */
445 unsigned long sc
= ((reg
& GC_DCM01_SC
) >> 8) + 1;
446 unsigned long hsp
, vsp
, ht
, vt
;
448 dev_dbg(par
->dev
, "using bootloader's disp. mode\n");
449 fbi
->var
.pixclock
= (sc
* 1000000) / par
->refclk
;
450 fbi
->var
.xres
= (inreg(disp
, GC_HDB_HDP
) & 0x0fff) + 1;
451 reg
= inreg(disp
, GC_VDP_VSP
);
452 fbi
->var
.yres
= ((reg
>> 16) & 0x0fff) + 1;
453 vsp
= (reg
& 0x0fff) + 1;
454 fbi
->var
.xres_virtual
= fbi
->var
.xres
;
455 fbi
->var
.yres_virtual
= fbi
->var
.yres
;
456 reg
= inreg(disp
, GC_L0EM
);
457 if (reg
& GC_L0EM_L0EC_24
) {
458 fbi
->var
.bits_per_pixel
= 32;
460 reg
= inreg(disp
, GC_L0M
);
461 if (reg
& GC_L0M_L0C_16
)
462 fbi
->var
.bits_per_pixel
= 16;
464 fbi
->var
.bits_per_pixel
= 8;
466 reg
= inreg(disp
, GC_VSW_HSW_HSP
);
467 fbi
->var
.hsync_len
= ((reg
& 0xff0000) >> 16) + 1;
468 fbi
->var
.vsync_len
= ((reg
& 0x3f000000) >> 24) + 1;
469 hsp
= (reg
& 0xffff) + 1;
470 ht
= ((inreg(disp
, GC_HTP
) & 0xfff0000) >> 16) + 1;
471 fbi
->var
.right_margin
= hsp
- fbi
->var
.xres
;
472 fbi
->var
.left_margin
= ht
- hsp
- fbi
->var
.hsync_len
;
473 vt
= ((inreg(disp
, GC_VTR
) & 0xfff0000) >> 16) + 1;
474 fbi
->var
.lower_margin
= vsp
- fbi
->var
.yres
;
475 fbi
->var
.upper_margin
= vt
- vsp
- fbi
->var
.vsync_len
;
477 dev_dbg(par
->dev
, "using supplied mode\n");
478 fb_videomode_to_var(&fbi
->var
, (struct fb_videomode
*)mode
);
479 fbi
->var
.bits_per_pixel
= mode
->def_bpp
? mode
->def_bpp
: 8;
483 ret
= fb_find_mode(&fbi
->var
, fbi
, "640x480-16@60",
485 if (ret
== 0 || ret
== 4) {
487 "failed to get initial mode\n");
492 fbi
->var
.xoffset
= 0;
493 fbi
->var
.yoffset
= 0;
494 fbi
->var
.grayscale
= 0;
496 fbi
->var
.height
= -1;
498 fbi
->var
.accel_flags
= 0;
499 fbi
->var
.vmode
= FB_VMODE_NONINTERLACED
;
500 fbi
->var
.activate
= FB_ACTIVATE_NOW
;
501 fbi
->flags
= FBINFO_DEFAULT
|
503 FBINFO_FOREIGN_ENDIAN
|
505 FBINFO_HWACCEL_XPAN
|
508 /* check and possibly fix bpp */
509 if ((fbi
->fbops
->fb_check_var
)(&fbi
->var
, fbi
))
510 dev_err(par
->dev
, "check_var() failed on initial setup?\n");
512 fbi
->fix
.visual
= fbi
->var
.bits_per_pixel
== 8 ?
513 FB_VISUAL_PSEUDOCOLOR
: FB_VISUAL_TRUECOLOR
;
514 fbi
->fix
.line_length
= (fbi
->var
.xres_virtual
*
515 fbi
->var
.bits_per_pixel
) / 8;
516 fbi
->fix
.smem_len
= fbi
->fix
.line_length
* fbi
->var
.yres_virtual
;
519 * reserve space for capture buffers and two cursors
520 * at the end of vram: 720x576 * 2 * 2.2 + 64x64 * 16.
522 par
->cap_buf
= par
->mapped_vram
- 0x1bd800 - 0x10000;
523 par
->cap_len
= 0x1bd800;
526 par
->l1_cfg
.sw
= 720;
527 par
->l1_cfg
.sh
= 576;
530 par
->l1_cfg
.dw
= 720;
531 par
->l1_cfg
.dh
= 576;
532 stride
= par
->l1_cfg
.sw
* (fbi
->var
.bits_per_pixel
/ 8);
533 par
->l1_stride
= stride
/ 64 + ((stride
% 64) ? 1 : 0);
534 outreg(cap
, GC_CAP_CBM
, GC_CBM_OO
| GC_CBM_CBST
|
535 (par
->l1_stride
<< 16));
536 outreg(cap
, GC_CAP_CBOA
, par
->cap_buf
);
537 outreg(cap
, GC_CAP_CBLA
, par
->cap_buf
+ par
->cap_len
);
542 * show some display controller and cursor registers
544 static ssize_t
mb862xxfb_show_dispregs(struct device
*dev
,
545 struct device_attribute
*attr
, char *buf
)
547 struct fb_info
*fbi
= dev_get_drvdata(dev
);
548 struct mb862xxfb_par
*par
= fbi
->par
;
552 for (reg
= GC_DCM0
; reg
<= GC_L0DY_L0DX
; reg
+= 4)
553 ptr
+= sprintf(ptr
, "%08x = %08x\n",
554 reg
, inreg(disp
, reg
));
556 for (reg
= GC_CPM_CUTC
; reg
<= GC_CUY1_CUX1
; reg
+= 4)
557 ptr
+= sprintf(ptr
, "%08x = %08x\n",
558 reg
, inreg(disp
, reg
));
560 for (reg
= GC_DCM1
; reg
<= GC_L0WH_L0WW
; reg
+= 4)
561 ptr
+= sprintf(ptr
, "%08x = %08x\n",
562 reg
, inreg(disp
, reg
));
564 for (reg
= 0x400; reg
<= 0x410; reg
+= 4)
565 ptr
+= sprintf(ptr
, "geo %08x = %08x\n",
566 reg
, inreg(geo
, reg
));
568 for (reg
= 0x400; reg
<= 0x410; reg
+= 4)
569 ptr
+= sprintf(ptr
, "draw %08x = %08x\n",
570 reg
, inreg(draw
, reg
));
572 for (reg
= 0x440; reg
<= 0x450; reg
+= 4)
573 ptr
+= sprintf(ptr
, "draw %08x = %08x\n",
574 reg
, inreg(draw
, reg
));
579 static DEVICE_ATTR(dispregs
, 0444, mb862xxfb_show_dispregs
, NULL
);
581 irqreturn_t
mb862xx_intr(int irq
, void *dev_id
)
583 struct mb862xxfb_par
*par
= (struct mb862xxfb_par
*) dev_id
;
584 unsigned long reg_ist
, mask
;
589 if (par
->type
== BT_CARMINE
) {
590 /* Get Interrupt Status */
591 reg_ist
= inreg(ctrl
, GC_CTRL_STATUS
);
592 mask
= inreg(ctrl
, GC_CTRL_INT_MASK
);
600 /* Clear interrupt status */
601 outreg(ctrl
, 0x0, reg_ist
);
604 reg_ist
= inreg(host
, GC_IST
);
605 mask
= inreg(host
, GC_IMASK
);
612 outreg(host
, GC_IST
, ~reg_ist
);
617 #if defined(CONFIG_FB_MB862XX_LIME)
619 * GDC (Lime, Coral(B/Q), Mint, ...) on host bus
621 static int mb862xx_gdc_init(struct mb862xxfb_par
*par
)
623 unsigned long ccf
, mmr
;
624 unsigned long ver
, rev
;
629 #if defined(CONFIG_FB_PRE_INIT_FB)
632 par
->host
= par
->mmio_base
;
633 par
->i2c
= par
->mmio_base
+ MB862XX_I2C_BASE
;
634 par
->disp
= par
->mmio_base
+ MB862XX_DISP_BASE
;
635 par
->cap
= par
->mmio_base
+ MB862XX_CAP_BASE
;
636 par
->draw
= par
->mmio_base
+ MB862XX_DRAW_BASE
;
637 par
->geo
= par
->mmio_base
+ MB862XX_GEO_BASE
;
638 par
->pio
= par
->mmio_base
+ MB862XX_PIO_BASE
;
640 par
->refclk
= GC_DISP_REFCLK_400
;
642 ver
= inreg(host
, GC_CID
);
643 rev
= inreg(pio
, GC_REVISION
);
644 if ((ver
== 0x303) && (rev
& 0xffffff00) == 0x20050100) {
645 dev_info(par
->dev
, "Fujitsu Lime v1.%d found\n",
648 ccf
= par
->gc_mode
? par
->gc_mode
->ccf
: GC_CCF_COT_100
;
649 mmr
= par
->gc_mode
? par
->gc_mode
->mmr
: 0x414fb7f2;
651 dev_info(par
->dev
, "? GDC, CID/Rev.: 0x%lx/0x%lx \n", ver
, rev
);
655 if (!par
->pre_init
) {
656 outreg(host
, GC_CCF
, ccf
);
658 outreg(host
, GC_MMR
, mmr
);
662 /* interrupt status */
663 outreg(host
, GC_IST
, 0);
664 outreg(host
, GC_IMASK
, GC_INT_EN
);
668 static int __devinit
of_platform_mb862xx_probe(struct platform_device
*ofdev
)
670 struct device_node
*np
= ofdev
->dev
.of_node
;
671 struct device
*dev
= &ofdev
->dev
;
672 struct mb862xxfb_par
*par
;
673 struct fb_info
*info
;
675 resource_size_t res_size
;
676 unsigned long ret
= -ENODEV
;
678 if (of_address_to_resource(np
, 0, &res
)) {
679 dev_err(dev
, "Invalid address\n");
683 info
= framebuffer_alloc(sizeof(struct mb862xxfb_par
), dev
);
685 dev_err(dev
, "cannot allocate framebuffer\n");
693 par
->irq
= irq_of_parse_and_map(np
, 0);
694 if (par
->irq
== NO_IRQ
) {
695 dev_err(dev
, "failed to map irq\n");
700 res_size
= 1 + res
.end
- res
.start
;
701 par
->res
= request_mem_region(res
.start
, res_size
, DRV_NAME
);
702 if (par
->res
== NULL
) {
703 dev_err(dev
, "Cannot claim framebuffer/mmio\n");
708 #if defined(CONFIG_SOCRATES)
709 par
->gc_mode
= &socrates_gc_mode
;
712 par
->fb_base_phys
= res
.start
;
713 par
->mmio_base_phys
= res
.start
+ MB862XX_MMIO_BASE
;
714 par
->mmio_len
= MB862XX_MMIO_SIZE
;
716 par
->mapped_vram
= par
->gc_mode
->max_vram
;
718 par
->mapped_vram
= MB862XX_MEM_SIZE
;
720 par
->fb_base
= ioremap(par
->fb_base_phys
, par
->mapped_vram
);
721 if (par
->fb_base
== NULL
) {
722 dev_err(dev
, "Cannot map framebuffer\n");
726 par
->mmio_base
= ioremap(par
->mmio_base_phys
, par
->mmio_len
);
727 if (par
->mmio_base
== NULL
) {
728 dev_err(dev
, "Cannot map registers\n");
732 dev_dbg(dev
, "fb phys 0x%llx 0x%lx\n",
733 (u64
)par
->fb_base_phys
, (ulong
)par
->mapped_vram
);
734 dev_dbg(dev
, "mmio phys 0x%llx 0x%lx, (irq = %d)\n",
735 (u64
)par
->mmio_base_phys
, (ulong
)par
->mmio_len
, par
->irq
);
737 if (mb862xx_gdc_init(par
))
740 if (request_irq(par
->irq
, mb862xx_intr
, IRQF_DISABLED
,
741 DRV_NAME
, (void *)par
)) {
742 dev_err(dev
, "Cannot request irq\n");
746 mb862xxfb_init_fbinfo(info
);
748 if (fb_alloc_cmap(&info
->cmap
, NR_PALETTE
, 0) < 0) {
749 dev_err(dev
, "Could not allocate cmap for fb_info.\n");
753 if ((info
->fbops
->fb_set_par
)(info
))
754 dev_err(dev
, "set_var() failed on initial setup?\n");
756 if (register_framebuffer(info
)) {
757 dev_err(dev
, "failed to register framebuffer\n");
761 dev_set_drvdata(dev
, info
);
763 if (device_create_file(dev
, &dev_attr_dispregs
))
764 dev_err(dev
, "Can't create sysfs regdump file\n");
768 fb_dealloc_cmap(&info
->cmap
);
770 outreg(host
, GC_IMASK
, 0);
771 free_irq(par
->irq
, (void *)par
);
773 iounmap(par
->mmio_base
);
775 iounmap(par
->fb_base
);
777 release_mem_region(res
.start
, res_size
);
779 irq_dispose_mapping(par
->irq
);
781 dev_set_drvdata(dev
, NULL
);
782 framebuffer_release(info
);
786 static int __devexit
of_platform_mb862xx_remove(struct platform_device
*ofdev
)
788 struct fb_info
*fbi
= dev_get_drvdata(&ofdev
->dev
);
789 struct mb862xxfb_par
*par
= fbi
->par
;
790 resource_size_t res_size
= 1 + par
->res
->end
- par
->res
->start
;
793 dev_dbg(fbi
->dev
, "%s release\n", fbi
->fix
.id
);
796 reg
= inreg(disp
, GC_DCM1
);
797 reg
&= ~(GC_DCM01_DEN
| GC_DCM01_L0E
);
798 outreg(disp
, GC_DCM1
, reg
);
800 /* disable interrupts */
801 outreg(host
, GC_IMASK
, 0);
803 free_irq(par
->irq
, (void *)par
);
804 irq_dispose_mapping(par
->irq
);
806 device_remove_file(&ofdev
->dev
, &dev_attr_dispregs
);
808 unregister_framebuffer(fbi
);
809 fb_dealloc_cmap(&fbi
->cmap
);
811 iounmap(par
->mmio_base
);
812 iounmap(par
->fb_base
);
814 dev_set_drvdata(&ofdev
->dev
, NULL
);
815 release_mem_region(par
->res
->start
, res_size
);
816 framebuffer_release(fbi
);
823 static struct of_device_id __devinitdata of_platform_mb862xx_tbl
[] = {
824 { .compatible
= "fujitsu,MB86276", },
825 { .compatible
= "fujitsu,lime", },
826 { .compatible
= "fujitsu,MB86277", },
827 { .compatible
= "fujitsu,mint", },
828 { .compatible
= "fujitsu,MB86293", },
829 { .compatible
= "fujitsu,MB86294", },
830 { .compatible
= "fujitsu,coral", },
834 static struct platform_driver of_platform_mb862xxfb_driver
= {
837 .owner
= THIS_MODULE
,
838 .of_match_table
= of_platform_mb862xx_tbl
,
840 .probe
= of_platform_mb862xx_probe
,
841 .remove
= __devexit_p(of_platform_mb862xx_remove
),
845 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
846 static int coralp_init(struct mb862xxfb_par
*par
)
850 par
->host
= par
->mmio_base
;
851 par
->i2c
= par
->mmio_base
+ MB862XX_I2C_BASE
;
852 par
->disp
= par
->mmio_base
+ MB862XX_DISP_BASE
;
853 par
->cap
= par
->mmio_base
+ MB862XX_CAP_BASE
;
854 par
->draw
= par
->mmio_base
+ MB862XX_DRAW_BASE
;
855 par
->geo
= par
->mmio_base
+ MB862XX_GEO_BASE
;
856 par
->pio
= par
->mmio_base
+ MB862XX_PIO_BASE
;
858 par
->refclk
= GC_DISP_REFCLK_400
;
860 if (par
->mapped_vram
>= 0x2000000) {
861 /* relocate gdc registers space */
862 writel(1, par
->fb_base
+ MB862XX_MMIO_BASE
+ GC_RSW
);
863 udelay(1); /* wait at least 20 bus cycles */
866 ver
= inreg(host
, GC_CID
);
867 cn
= (ver
& GC_CID_CNAME_MSK
) >> 8;
868 ver
= ver
& GC_CID_VERSION_MSK
;
872 dev_info(par
->dev
, "Fujitsu Coral-%s GDC Rev.%d found\n",\
873 (ver
== 6) ? "P" : (ver
== 8) ? "PA" : "?",
874 par
->pdev
->revision
);
875 reg
= inreg(disp
, GC_DCM1
);
876 if (reg
& GC_DCM01_DEN
&& reg
& GC_DCM01_L0E
)
879 if (!par
->pre_init
) {
880 outreg(host
, GC_CCF
, GC_CCF_CGE_166
| GC_CCF_COT_133
);
882 outreg(host
, GC_MMR
, GC_MMR_CORALP_EVB_VAL
);
885 /* Clear interrupt status */
886 outreg(host
, GC_IST
, 0);
891 mb862xx_i2c_init(par
);
895 static int init_dram_ctrl(struct mb862xxfb_par
*par
)
900 * Set io mode first! Spec. says IC may be destroyed
901 * if not set to SSTL2/LVCMOS before init.
903 outreg(dram_ctrl
, GC_DCTL_IOCONT1_IOCONT0
, GC_EVB_DCTL_IOCONT1_IOCONT0
);
906 outreg(dram_ctrl
, GC_DCTL_MODE_ADD
, GC_EVB_DCTL_MODE_ADD
);
907 outreg(dram_ctrl
, GC_DCTL_SETTIME1_EMODE
, GC_EVB_DCTL_SETTIME1_EMODE
);
908 outreg(dram_ctrl
, GC_DCTL_REFRESH_SETTIME2
,
909 GC_EVB_DCTL_REFRESH_SETTIME2
);
910 outreg(dram_ctrl
, GC_DCTL_RSV2_RSV1
, GC_EVB_DCTL_RSV2_RSV1
);
911 outreg(dram_ctrl
, GC_DCTL_DDRIF2_DDRIF1
, GC_EVB_DCTL_DDRIF2_DDRIF1
);
912 outreg(dram_ctrl
, GC_DCTL_RSV0_STATES
, GC_EVB_DCTL_RSV0_STATES
);
914 /* DLL reset done? */
915 while ((inreg(dram_ctrl
, GC_DCTL_RSV0_STATES
) & GC_DCTL_STATES_MSK
)) {
916 udelay(GC_DCTL_INIT_WAIT_INTERVAL
);
917 if (i
++ > GC_DCTL_INIT_WAIT_CNT
) {
918 dev_err(par
->dev
, "VRAM init failed.\n");
922 outreg(dram_ctrl
, GC_DCTL_MODE_ADD
, GC_EVB_DCTL_MODE_ADD_AFT_RST
);
923 outreg(dram_ctrl
, GC_DCTL_RSV0_STATES
, GC_EVB_DCTL_RSV0_STATES_AFT_RST
);
927 static int carmine_init(struct mb862xxfb_par
*par
)
931 par
->ctrl
= par
->mmio_base
+ MB86297_CTRL_BASE
;
932 par
->i2c
= par
->mmio_base
+ MB86297_I2C_BASE
;
933 par
->disp
= par
->mmio_base
+ MB86297_DISP0_BASE
;
934 par
->disp1
= par
->mmio_base
+ MB86297_DISP1_BASE
;
935 par
->cap
= par
->mmio_base
+ MB86297_CAP0_BASE
;
936 par
->cap1
= par
->mmio_base
+ MB86297_CAP1_BASE
;
937 par
->draw
= par
->mmio_base
+ MB86297_DRAW_BASE
;
938 par
->dram_ctrl
= par
->mmio_base
+ MB86297_DRAMCTRL_BASE
;
939 par
->wrback
= par
->mmio_base
+ MB86297_WRBACK_BASE
;
941 par
->refclk
= GC_DISP_REFCLK_533
;
944 reg
= GC_CTRL_CLK_EN_DRAM
| GC_CTRL_CLK_EN_2D3D
| GC_CTRL_CLK_EN_DISP0
;
945 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, reg
);
947 /* check for engine module revision */
948 if (inreg(draw
, GC_2D3D_REV
) == GC_RE_REVISION
)
949 dev_info(par
->dev
, "Fujitsu Carmine GDC Rev.%d found\n",
950 par
->pdev
->revision
);
954 reg
&= ~GC_CTRL_CLK_EN_2D3D
;
955 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, reg
);
958 if (init_dram_ctrl(par
) < 0)
961 outreg(ctrl
, GC_CTRL_INT_MASK
, 0);
965 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, 0);
969 static inline int mb862xx_pci_gdc_init(struct mb862xxfb_par
*par
)
973 return coralp_init(par
);
975 return carmine_init(par
);
981 #define CHIP_ID(id) \
982 { PCI_DEVICE(PCI_VENDOR_ID_FUJITSU_LIMITED, id) }
984 static struct pci_device_id mb862xx_pci_tbl
[] __devinitdata
= {
985 /* MB86295/MB86296 */
986 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALP
),
987 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALPA
),
989 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CARMINE
),
993 MODULE_DEVICE_TABLE(pci
, mb862xx_pci_tbl
);
995 static int __devinit
mb862xx_pci_probe(struct pci_dev
*pdev
,
996 const struct pci_device_id
*ent
)
998 struct mb862xxfb_par
*par
;
999 struct fb_info
*info
;
1000 struct device
*dev
= &pdev
->dev
;
1003 ret
= pci_enable_device(pdev
);
1005 dev_err(dev
, "Cannot enable PCI device\n");
1009 info
= framebuffer_alloc(sizeof(struct mb862xxfb_par
), dev
);
1011 dev_err(dev
, "framebuffer alloc failed\n");
1020 par
->irq
= pdev
->irq
;
1022 ret
= pci_request_regions(pdev
, DRV_NAME
);
1024 dev_err(dev
, "Cannot reserve region(s) for PCI device\n");
1028 switch (pdev
->device
) {
1029 case PCI_DEVICE_ID_FUJITSU_CORALP
:
1030 case PCI_DEVICE_ID_FUJITSU_CORALPA
:
1031 par
->fb_base_phys
= pci_resource_start(par
->pdev
, 0);
1032 par
->mapped_vram
= CORALP_MEM_SIZE
;
1033 if (par
->mapped_vram
>= 0x2000000) {
1034 par
->mmio_base_phys
= par
->fb_base_phys
+
1035 MB862XX_MMIO_HIGH_BASE
;
1037 par
->mmio_base_phys
= par
->fb_base_phys
+
1040 par
->mmio_len
= MB862XX_MMIO_SIZE
;
1041 par
->type
= BT_CORALP
;
1043 case PCI_DEVICE_ID_FUJITSU_CARMINE
:
1044 par
->fb_base_phys
= pci_resource_start(par
->pdev
, 2);
1045 par
->mmio_base_phys
= pci_resource_start(par
->pdev
, 3);
1046 par
->mmio_len
= pci_resource_len(par
->pdev
, 3);
1047 par
->mapped_vram
= CARMINE_MEM_SIZE
;
1048 par
->type
= BT_CARMINE
;
1051 /* should never occur */
1055 par
->fb_base
= ioremap(par
->fb_base_phys
, par
->mapped_vram
);
1056 if (par
->fb_base
== NULL
) {
1057 dev_err(dev
, "Cannot map framebuffer\n");
1061 par
->mmio_base
= ioremap(par
->mmio_base_phys
, par
->mmio_len
);
1062 if (par
->mmio_base
== NULL
) {
1063 dev_err(dev
, "Cannot map registers\n");
1068 dev_dbg(dev
, "fb phys 0x%llx 0x%lx\n",
1069 (unsigned long long)par
->fb_base_phys
, (ulong
)par
->mapped_vram
);
1070 dev_dbg(dev
, "mmio phys 0x%llx 0x%lx\n",
1071 (unsigned long long)par
->mmio_base_phys
, (ulong
)par
->mmio_len
);
1073 if (mb862xx_pci_gdc_init(par
))
1076 if (request_irq(par
->irq
, mb862xx_intr
, IRQF_DISABLED
| IRQF_SHARED
,
1077 DRV_NAME
, (void *)par
)) {
1078 dev_err(dev
, "Cannot request irq\n");
1082 mb862xxfb_init_fbinfo(info
);
1084 if (fb_alloc_cmap(&info
->cmap
, NR_PALETTE
, 0) < 0) {
1085 dev_err(dev
, "Could not allocate cmap for fb_info.\n");
1090 if ((info
->fbops
->fb_set_par
)(info
))
1091 dev_err(dev
, "set_var() failed on initial setup?\n");
1093 ret
= register_framebuffer(info
);
1095 dev_err(dev
, "failed to register framebuffer\n");
1099 pci_set_drvdata(pdev
, info
);
1101 if (device_create_file(dev
, &dev_attr_dispregs
))
1102 dev_err(dev
, "Can't create sysfs regdump file\n");
1104 if (par
->type
== BT_CARMINE
)
1105 outreg(ctrl
, GC_CTRL_INT_MASK
, GC_CARMINE_INT_EN
);
1107 outreg(host
, GC_IMASK
, GC_INT_EN
);
1112 fb_dealloc_cmap(&info
->cmap
);
1114 free_irq(par
->irq
, (void *)par
);
1116 iounmap(par
->mmio_base
);
1118 iounmap(par
->fb_base
);
1120 pci_release_regions(pdev
);
1122 framebuffer_release(info
);
1124 pci_disable_device(pdev
);
1129 static void __devexit
mb862xx_pci_remove(struct pci_dev
*pdev
)
1131 struct fb_info
*fbi
= pci_get_drvdata(pdev
);
1132 struct mb862xxfb_par
*par
= fbi
->par
;
1135 dev_dbg(fbi
->dev
, "%s release\n", fbi
->fix
.id
);
1138 reg
= inreg(disp
, GC_DCM1
);
1139 reg
&= ~(GC_DCM01_DEN
| GC_DCM01_L0E
);
1140 outreg(disp
, GC_DCM1
, reg
);
1142 if (par
->type
== BT_CARMINE
) {
1143 outreg(ctrl
, GC_CTRL_INT_MASK
, 0);
1144 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, 0);
1146 outreg(host
, GC_IMASK
, 0);
1149 mb862xx_i2c_exit(par
);
1151 device_remove_file(&pdev
->dev
, &dev_attr_dispregs
);
1153 pci_set_drvdata(pdev
, NULL
);
1154 unregister_framebuffer(fbi
);
1155 fb_dealloc_cmap(&fbi
->cmap
);
1157 free_irq(par
->irq
, (void *)par
);
1158 iounmap(par
->mmio_base
);
1159 iounmap(par
->fb_base
);
1161 pci_release_regions(pdev
);
1162 framebuffer_release(fbi
);
1163 pci_disable_device(pdev
);
1166 static struct pci_driver mb862xxfb_pci_driver
= {
1168 .id_table
= mb862xx_pci_tbl
,
1169 .probe
= mb862xx_pci_probe
,
1170 .remove
= __devexit_p(mb862xx_pci_remove
),
1174 static int __devinit
mb862xxfb_init(void)
1178 #if defined(CONFIG_FB_MB862XX_LIME)
1179 ret
= platform_driver_register(&of_platform_mb862xxfb_driver
);
1181 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
1182 ret
= pci_register_driver(&mb862xxfb_pci_driver
);
1187 static void __exit
mb862xxfb_exit(void)
1189 #if defined(CONFIG_FB_MB862XX_LIME)
1190 platform_driver_unregister(&of_platform_mb862xxfb_driver
);
1192 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
1193 pci_unregister_driver(&mb862xxfb_pci_driver
);
1197 module_init(mb862xxfb_init
);
1198 module_exit(mb862xxfb_exit
);
1200 MODULE_DESCRIPTION("Fujitsu MB862xx Framebuffer driver");
1201 MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
1202 MODULE_LICENSE("GPL v2");