1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/mb862xx/mb862xxfb.c
5 * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver
7 * (C) 2008 Anatolij Gustschin <agust@denx.de>
8 * DENX Software Engineering
14 #include <linux/delay.h>
15 #include <linux/uaccess.h>
16 #include <linux/module.h>
17 #include <linux/init.h>
18 #include <linux/interrupt.h>
19 #include <linux/pci.h>
20 #if defined(CONFIG_OF)
21 #include <linux/of_platform.h>
23 #include "mb862xxfb.h"
24 #include "mb862xx_reg.h"
26 #define NR_PALETTE 256
27 #define MB862XX_MEM_SIZE 0x1000000
28 #define CORALP_MEM_SIZE 0x2000000
29 #define CARMINE_MEM_SIZE 0x8000000
30 #define DRV_NAME "mb862xxfb"
32 #if defined(CONFIG_SOCRATES)
33 static struct mb862xx_gc_mode socrates_gc_mode
= {
34 /* Mode for Prime View PM070WL4 TFT LCD Panel */
35 { "800x480", 45, 800, 480, 40000, 86, 42, 33, 10, 128, 2, 0, 0, 0 },
36 /* 16 bits/pixel, 16MB, 133MHz, SDRAM memory mode value */
37 16, 0x1000000, GC_CCF_COT_133
, 0x4157ba63
42 static inline int h_total(struct fb_var_screeninfo
*var
)
44 return var
->xres
+ var
->left_margin
+
45 var
->right_margin
+ var
->hsync_len
;
48 static inline int v_total(struct fb_var_screeninfo
*var
)
50 return var
->yres
+ var
->upper_margin
+
51 var
->lower_margin
+ var
->vsync_len
;
54 static inline int hsp(struct fb_var_screeninfo
*var
)
56 return var
->xres
+ var
->right_margin
- 1;
59 static inline int vsp(struct fb_var_screeninfo
*var
)
61 return var
->yres
+ var
->lower_margin
- 1;
64 static inline int d_pitch(struct fb_var_screeninfo
*var
)
66 return var
->xres
* var
->bits_per_pixel
/ 8;
69 static inline unsigned int chan_to_field(unsigned int chan
,
70 struct fb_bitfield
*bf
)
73 chan
>>= 16 - bf
->length
;
74 return chan
<< bf
->offset
;
77 static int mb862xxfb_setcolreg(unsigned regno
,
78 unsigned red
, unsigned green
, unsigned blue
,
79 unsigned transp
, struct fb_info
*info
)
81 struct mb862xxfb_par
*par
= info
->par
;
84 switch (info
->fix
.visual
) {
85 case FB_VISUAL_TRUECOLOR
:
87 val
= chan_to_field(red
, &info
->var
.red
);
88 val
|= chan_to_field(green
, &info
->var
.green
);
89 val
|= chan_to_field(blue
, &info
->var
.blue
);
90 par
->pseudo_palette
[regno
] = val
;
93 case FB_VISUAL_PSEUDOCOLOR
:
95 val
= (red
>> 8) << 16;
96 val
|= (green
>> 8) << 8;
98 outreg(disp
, GC_L0PAL0
+ (regno
* 4), val
);
102 return 1; /* unsupported type */
107 static int mb862xxfb_check_var(struct fb_var_screeninfo
*var
,
113 dev_dbg(fbi
->dev
, "%s\n", __func__
);
115 /* check if these values fit into the registers */
116 if (var
->hsync_len
> 255 || var
->vsync_len
> 255)
119 if ((var
->xres
+ var
->right_margin
) >= 4096)
122 if ((var
->yres
+ var
->lower_margin
) > 4096)
125 if (h_total(var
) > 4096 || v_total(var
) > 4096)
128 if (var
->xres_virtual
> 4096 || var
->yres_virtual
> 4096)
131 if (var
->bits_per_pixel
<= 8)
132 var
->bits_per_pixel
= 8;
133 else if (var
->bits_per_pixel
<= 16)
134 var
->bits_per_pixel
= 16;
135 else if (var
->bits_per_pixel
<= 32)
136 var
->bits_per_pixel
= 32;
139 * can cope with 8,16 or 24/32bpp if resulting
140 * pitch is divisible by 64 without remainder
142 if (d_pitch(&fbi
->var
) % GC_L0M_L0W_UNIT
) {
145 var
->bits_per_pixel
= 0;
147 var
->bits_per_pixel
+= 8;
148 r
= d_pitch(&fbi
->var
) % GC_L0M_L0W_UNIT
;
149 } while (r
&& var
->bits_per_pixel
<= 32);
151 if (d_pitch(&fbi
->var
) % GC_L0M_L0W_UNIT
)
155 /* line length is going to be 128 bit aligned */
156 tmp
= (var
->xres
* var
->bits_per_pixel
) / 8;
160 /* set r/g/b positions and validate bpp */
161 switch (var
->bits_per_pixel
) {
163 var
->red
.length
= var
->bits_per_pixel
;
164 var
->green
.length
= var
->bits_per_pixel
;
165 var
->blue
.length
= var
->bits_per_pixel
;
167 var
->green
.offset
= 0;
168 var
->blue
.offset
= 0;
169 var
->transp
.length
= 0;
173 var
->green
.length
= 5;
174 var
->blue
.length
= 5;
175 var
->red
.offset
= 10;
176 var
->green
.offset
= 5;
177 var
->blue
.offset
= 0;
178 var
->transp
.length
= 0;
182 var
->transp
.length
= 8;
184 var
->green
.length
= 8;
185 var
->blue
.length
= 8;
186 var
->transp
.offset
= 24;
187 var
->red
.offset
= 16;
188 var
->green
.offset
= 8;
189 var
->blue
.offset
= 0;
197 static struct fb_ops mb862xxfb_ops
;
200 * set display parameters
202 static int mb862xxfb_set_par(struct fb_info
*fbi
)
204 struct mb862xxfb_par
*par
= fbi
->par
;
205 unsigned long reg
, sc
;
207 dev_dbg(par
->dev
, "%s\n", __func__
);
208 if (par
->type
== BT_CORALP
)
209 mb862xxfb_init_accel(fbi
, &mb862xxfb_ops
, fbi
->var
.xres
);
215 reg
= inreg(disp
, GC_DCM1
);
216 reg
&= ~GC_DCM01_DEN
;
217 outreg(disp
, GC_DCM1
, reg
);
219 /* set display reference clock div. */
220 sc
= par
->refclk
/ (1000000 / fbi
->var
.pixclock
) - 1;
221 reg
= inreg(disp
, GC_DCM1
);
222 reg
&= ~(GC_DCM01_CKS
| GC_DCM01_RESV
| GC_DCM01_SC
);
224 outreg(disp
, GC_DCM1
, reg
);
225 dev_dbg(par
->dev
, "SC 0x%lx\n", sc
);
227 /* disp dimension, format */
228 reg
= pack(d_pitch(&fbi
->var
) / GC_L0M_L0W_UNIT
,
229 (fbi
->var
.yres
- 1));
230 if (fbi
->var
.bits_per_pixel
== 16)
231 reg
|= GC_L0M_L0C_16
;
232 outreg(disp
, GC_L0M
, reg
);
234 if (fbi
->var
.bits_per_pixel
== 32) {
235 reg
= inreg(disp
, GC_L0EM
);
236 outreg(disp
, GC_L0EM
, reg
| GC_L0EM_L0EC_24
);
238 outreg(disp
, GC_WY_WX
, 0);
239 reg
= pack(fbi
->var
.yres
- 1, fbi
->var
.xres
);
240 outreg(disp
, GC_WH_WW
, reg
);
241 outreg(disp
, GC_L0OA0
, 0);
242 outreg(disp
, GC_L0DA0
, 0);
243 outreg(disp
, GC_L0DY_L0DX
, 0);
244 outreg(disp
, GC_L0WY_L0WX
, 0);
245 outreg(disp
, GC_L0WH_L0WW
, reg
);
247 /* both HW-cursors off */
248 reg
= inreg(disp
, GC_CPM_CUTC
);
249 reg
&= ~(GC_CPM_CEN0
| GC_CPM_CEN1
);
250 outreg(disp
, GC_CPM_CUTC
, reg
);
253 reg
= pack(fbi
->var
.xres
- 1, fbi
->var
.xres
- 1);
254 outreg(disp
, GC_HDB_HDP
, reg
);
255 reg
= pack((fbi
->var
.yres
- 1), vsp(&fbi
->var
));
256 outreg(disp
, GC_VDP_VSP
, reg
);
257 reg
= ((fbi
->var
.vsync_len
- 1) << 24) |
258 pack((fbi
->var
.hsync_len
- 1), hsp(&fbi
->var
));
259 outreg(disp
, GC_VSW_HSW_HSP
, reg
);
260 outreg(disp
, GC_HTP
, pack(h_total(&fbi
->var
) - 1, 0));
261 outreg(disp
, GC_VTR
, pack(v_total(&fbi
->var
) - 1, 0));
264 reg
= inreg(disp
, GC_DCM1
);
265 reg
|= GC_DCM01_DEN
| GC_DCM01_L0E
;
266 reg
&= ~GC_DCM01_ESY
;
267 outreg(disp
, GC_DCM1
, reg
);
271 static int mb862xxfb_pan(struct fb_var_screeninfo
*var
,
272 struct fb_info
*info
)
274 struct mb862xxfb_par
*par
= info
->par
;
277 reg
= pack(var
->yoffset
, var
->xoffset
);
278 outreg(disp
, GC_L0WY_L0WX
, reg
);
280 reg
= pack(info
->var
.yres_virtual
, info
->var
.xres_virtual
);
281 outreg(disp
, GC_L0WH_L0WW
, reg
);
285 static int mb862xxfb_blank(int mode
, struct fb_info
*fbi
)
287 struct mb862xxfb_par
*par
= fbi
->par
;
290 dev_dbg(fbi
->dev
, "blank mode=%d\n", mode
);
293 case FB_BLANK_POWERDOWN
:
294 reg
= inreg(disp
, GC_DCM1
);
295 reg
&= ~GC_DCM01_DEN
;
296 outreg(disp
, GC_DCM1
, reg
);
298 case FB_BLANK_UNBLANK
:
299 reg
= inreg(disp
, GC_DCM1
);
301 outreg(disp
, GC_DCM1
, reg
);
303 case FB_BLANK_NORMAL
:
304 case FB_BLANK_VSYNC_SUSPEND
:
305 case FB_BLANK_HSYNC_SUSPEND
:
312 static int mb862xxfb_ioctl(struct fb_info
*fbi
, unsigned int cmd
,
315 struct mb862xxfb_par
*par
= fbi
->par
;
316 struct mb862xx_l1_cfg
*l1_cfg
= &par
->l1_cfg
;
317 void __user
*argp
= (void __user
*)arg
;
322 case MB862XX_L1_GET_CFG
:
323 if (copy_to_user(argp
, l1_cfg
, sizeof(*l1_cfg
)))
326 case MB862XX_L1_SET_CFG
:
327 if (copy_from_user(l1_cfg
, argp
, sizeof(*l1_cfg
)))
329 if (l1_cfg
->dh
== 0 || l1_cfg
->dw
== 0)
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 static 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 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
);
692 par
->irq
= irq_of_parse_and_map(np
, 0);
693 if (par
->irq
== NO_IRQ
) {
694 dev_err(dev
, "failed to map irq\n");
699 res_size
= resource_size(&res
);
700 par
->res
= request_mem_region(res
.start
, res_size
, DRV_NAME
);
701 if (par
->res
== NULL
) {
702 dev_err(dev
, "Cannot claim framebuffer/mmio\n");
707 #if defined(CONFIG_SOCRATES)
708 par
->gc_mode
= &socrates_gc_mode
;
711 par
->fb_base_phys
= res
.start
;
712 par
->mmio_base_phys
= res
.start
+ MB862XX_MMIO_BASE
;
713 par
->mmio_len
= MB862XX_MMIO_SIZE
;
715 par
->mapped_vram
= par
->gc_mode
->max_vram
;
717 par
->mapped_vram
= MB862XX_MEM_SIZE
;
719 par
->fb_base
= ioremap(par
->fb_base_phys
, par
->mapped_vram
);
720 if (par
->fb_base
== NULL
) {
721 dev_err(dev
, "Cannot map framebuffer\n");
725 par
->mmio_base
= ioremap(par
->mmio_base_phys
, par
->mmio_len
);
726 if (par
->mmio_base
== NULL
) {
727 dev_err(dev
, "Cannot map registers\n");
731 dev_dbg(dev
, "fb phys 0x%llx 0x%lx\n",
732 (u64
)par
->fb_base_phys
, (ulong
)par
->mapped_vram
);
733 dev_dbg(dev
, "mmio phys 0x%llx 0x%lx, (irq = %d)\n",
734 (u64
)par
->mmio_base_phys
, (ulong
)par
->mmio_len
, par
->irq
);
736 if (mb862xx_gdc_init(par
))
739 if (request_irq(par
->irq
, mb862xx_intr
, 0,
740 DRV_NAME
, (void *)par
)) {
741 dev_err(dev
, "Cannot request irq\n");
745 mb862xxfb_init_fbinfo(info
);
747 if (fb_alloc_cmap(&info
->cmap
, NR_PALETTE
, 0) < 0) {
748 dev_err(dev
, "Could not allocate cmap for fb_info.\n");
752 if ((info
->fbops
->fb_set_par
)(info
))
753 dev_err(dev
, "set_var() failed on initial setup?\n");
755 if (register_framebuffer(info
)) {
756 dev_err(dev
, "failed to register framebuffer\n");
760 dev_set_drvdata(dev
, info
);
762 if (device_create_file(dev
, &dev_attr_dispregs
))
763 dev_err(dev
, "Can't create sysfs regdump file\n");
767 fb_dealloc_cmap(&info
->cmap
);
769 outreg(host
, GC_IMASK
, 0);
770 free_irq(par
->irq
, (void *)par
);
772 iounmap(par
->mmio_base
);
774 iounmap(par
->fb_base
);
776 release_mem_region(res
.start
, res_size
);
778 irq_dispose_mapping(par
->irq
);
780 framebuffer_release(info
);
784 static int of_platform_mb862xx_remove(struct platform_device
*ofdev
)
786 struct fb_info
*fbi
= dev_get_drvdata(&ofdev
->dev
);
787 struct mb862xxfb_par
*par
= fbi
->par
;
788 resource_size_t res_size
= resource_size(par
->res
);
791 dev_dbg(fbi
->dev
, "%s release\n", fbi
->fix
.id
);
794 reg
= inreg(disp
, GC_DCM1
);
795 reg
&= ~(GC_DCM01_DEN
| GC_DCM01_L0E
);
796 outreg(disp
, GC_DCM1
, reg
);
798 /* disable interrupts */
799 outreg(host
, GC_IMASK
, 0);
801 free_irq(par
->irq
, (void *)par
);
802 irq_dispose_mapping(par
->irq
);
804 device_remove_file(&ofdev
->dev
, &dev_attr_dispregs
);
806 unregister_framebuffer(fbi
);
807 fb_dealloc_cmap(&fbi
->cmap
);
809 iounmap(par
->mmio_base
);
810 iounmap(par
->fb_base
);
812 release_mem_region(par
->res
->start
, res_size
);
813 framebuffer_release(fbi
);
820 static struct of_device_id of_platform_mb862xx_tbl
[] = {
821 { .compatible
= "fujitsu,MB86276", },
822 { .compatible
= "fujitsu,lime", },
823 { .compatible
= "fujitsu,MB86277", },
824 { .compatible
= "fujitsu,mint", },
825 { .compatible
= "fujitsu,MB86293", },
826 { .compatible
= "fujitsu,MB86294", },
827 { .compatible
= "fujitsu,coral", },
830 MODULE_DEVICE_TABLE(of
, of_platform_mb862xx_tbl
);
832 static struct platform_driver of_platform_mb862xxfb_driver
= {
835 .of_match_table
= of_platform_mb862xx_tbl
,
837 .probe
= of_platform_mb862xx_probe
,
838 .remove
= of_platform_mb862xx_remove
,
842 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
843 static int coralp_init(struct mb862xxfb_par
*par
)
847 par
->host
= par
->mmio_base
;
848 par
->i2c
= par
->mmio_base
+ MB862XX_I2C_BASE
;
849 par
->disp
= par
->mmio_base
+ MB862XX_DISP_BASE
;
850 par
->cap
= par
->mmio_base
+ MB862XX_CAP_BASE
;
851 par
->draw
= par
->mmio_base
+ MB862XX_DRAW_BASE
;
852 par
->geo
= par
->mmio_base
+ MB862XX_GEO_BASE
;
853 par
->pio
= par
->mmio_base
+ MB862XX_PIO_BASE
;
855 par
->refclk
= GC_DISP_REFCLK_400
;
857 if (par
->mapped_vram
>= 0x2000000) {
858 /* relocate gdc registers space */
859 writel(1, par
->fb_base
+ MB862XX_MMIO_BASE
+ GC_RSW
);
860 udelay(1); /* wait at least 20 bus cycles */
863 ver
= inreg(host
, GC_CID
);
864 cn
= (ver
& GC_CID_CNAME_MSK
) >> 8;
865 ver
= ver
& GC_CID_VERSION_MSK
;
869 dev_info(par
->dev
, "Fujitsu Coral-%s GDC Rev.%d found\n",\
870 (ver
== 6) ? "P" : (ver
== 8) ? "PA" : "?",
871 par
->pdev
->revision
);
872 reg
= inreg(disp
, GC_DCM1
);
873 if (reg
& GC_DCM01_DEN
&& reg
& GC_DCM01_L0E
)
876 if (!par
->pre_init
) {
877 outreg(host
, GC_CCF
, GC_CCF_CGE_166
| GC_CCF_COT_133
);
879 outreg(host
, GC_MMR
, GC_MMR_CORALP_EVB_VAL
);
882 /* Clear interrupt status */
883 outreg(host
, GC_IST
, 0);
888 mb862xx_i2c_init(par
);
892 static int init_dram_ctrl(struct mb862xxfb_par
*par
)
897 * Set io mode first! Spec. says IC may be destroyed
898 * if not set to SSTL2/LVCMOS before init.
900 outreg(dram_ctrl
, GC_DCTL_IOCONT1_IOCONT0
, GC_EVB_DCTL_IOCONT1_IOCONT0
);
903 outreg(dram_ctrl
, GC_DCTL_MODE_ADD
, GC_EVB_DCTL_MODE_ADD
);
904 outreg(dram_ctrl
, GC_DCTL_SETTIME1_EMODE
, GC_EVB_DCTL_SETTIME1_EMODE
);
905 outreg(dram_ctrl
, GC_DCTL_REFRESH_SETTIME2
,
906 GC_EVB_DCTL_REFRESH_SETTIME2
);
907 outreg(dram_ctrl
, GC_DCTL_RSV2_RSV1
, GC_EVB_DCTL_RSV2_RSV1
);
908 outreg(dram_ctrl
, GC_DCTL_DDRIF2_DDRIF1
, GC_EVB_DCTL_DDRIF2_DDRIF1
);
909 outreg(dram_ctrl
, GC_DCTL_RSV0_STATES
, GC_EVB_DCTL_RSV0_STATES
);
911 /* DLL reset done? */
912 while ((inreg(dram_ctrl
, GC_DCTL_RSV0_STATES
) & GC_DCTL_STATES_MSK
)) {
913 udelay(GC_DCTL_INIT_WAIT_INTERVAL
);
914 if (i
++ > GC_DCTL_INIT_WAIT_CNT
) {
915 dev_err(par
->dev
, "VRAM init failed.\n");
919 outreg(dram_ctrl
, GC_DCTL_MODE_ADD
, GC_EVB_DCTL_MODE_ADD_AFT_RST
);
920 outreg(dram_ctrl
, GC_DCTL_RSV0_STATES
, GC_EVB_DCTL_RSV0_STATES_AFT_RST
);
924 static int carmine_init(struct mb862xxfb_par
*par
)
928 par
->ctrl
= par
->mmio_base
+ MB86297_CTRL_BASE
;
929 par
->i2c
= par
->mmio_base
+ MB86297_I2C_BASE
;
930 par
->disp
= par
->mmio_base
+ MB86297_DISP0_BASE
;
931 par
->disp1
= par
->mmio_base
+ MB86297_DISP1_BASE
;
932 par
->cap
= par
->mmio_base
+ MB86297_CAP0_BASE
;
933 par
->cap1
= par
->mmio_base
+ MB86297_CAP1_BASE
;
934 par
->draw
= par
->mmio_base
+ MB86297_DRAW_BASE
;
935 par
->dram_ctrl
= par
->mmio_base
+ MB86297_DRAMCTRL_BASE
;
936 par
->wrback
= par
->mmio_base
+ MB86297_WRBACK_BASE
;
938 par
->refclk
= GC_DISP_REFCLK_533
;
941 reg
= GC_CTRL_CLK_EN_DRAM
| GC_CTRL_CLK_EN_2D3D
| GC_CTRL_CLK_EN_DISP0
;
942 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, reg
);
944 /* check for engine module revision */
945 if (inreg(draw
, GC_2D3D_REV
) == GC_RE_REVISION
)
946 dev_info(par
->dev
, "Fujitsu Carmine GDC Rev.%d found\n",
947 par
->pdev
->revision
);
951 reg
&= ~GC_CTRL_CLK_EN_2D3D
;
952 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, reg
);
955 if (init_dram_ctrl(par
) < 0)
958 outreg(ctrl
, GC_CTRL_INT_MASK
, 0);
962 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, 0);
966 static inline int mb862xx_pci_gdc_init(struct mb862xxfb_par
*par
)
970 return coralp_init(par
);
972 return carmine_init(par
);
978 #define CHIP_ID(id) \
979 { PCI_DEVICE(PCI_VENDOR_ID_FUJITSU_LIMITED, id) }
981 static const struct pci_device_id mb862xx_pci_tbl
[] = {
982 /* MB86295/MB86296 */
983 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALP
),
984 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALPA
),
986 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CARMINE
),
990 MODULE_DEVICE_TABLE(pci
, mb862xx_pci_tbl
);
992 static int mb862xx_pci_probe(struct pci_dev
*pdev
,
993 const struct pci_device_id
*ent
)
995 struct mb862xxfb_par
*par
;
996 struct fb_info
*info
;
997 struct device
*dev
= &pdev
->dev
;
1000 ret
= pci_enable_device(pdev
);
1002 dev_err(dev
, "Cannot enable PCI device\n");
1006 info
= framebuffer_alloc(sizeof(struct mb862xxfb_par
), dev
);
1016 par
->irq
= pdev
->irq
;
1018 ret
= pci_request_regions(pdev
, DRV_NAME
);
1020 dev_err(dev
, "Cannot reserve region(s) for PCI device\n");
1024 switch (pdev
->device
) {
1025 case PCI_DEVICE_ID_FUJITSU_CORALP
:
1026 case PCI_DEVICE_ID_FUJITSU_CORALPA
:
1027 par
->fb_base_phys
= pci_resource_start(par
->pdev
, 0);
1028 par
->mapped_vram
= CORALP_MEM_SIZE
;
1029 if (par
->mapped_vram
>= 0x2000000) {
1030 par
->mmio_base_phys
= par
->fb_base_phys
+
1031 MB862XX_MMIO_HIGH_BASE
;
1033 par
->mmio_base_phys
= par
->fb_base_phys
+
1036 par
->mmio_len
= MB862XX_MMIO_SIZE
;
1037 par
->type
= BT_CORALP
;
1039 case PCI_DEVICE_ID_FUJITSU_CARMINE
:
1040 par
->fb_base_phys
= pci_resource_start(par
->pdev
, 2);
1041 par
->mmio_base_phys
= pci_resource_start(par
->pdev
, 3);
1042 par
->mmio_len
= pci_resource_len(par
->pdev
, 3);
1043 par
->mapped_vram
= CARMINE_MEM_SIZE
;
1044 par
->type
= BT_CARMINE
;
1047 /* should never occur */
1052 par
->fb_base
= ioremap(par
->fb_base_phys
, par
->mapped_vram
);
1053 if (par
->fb_base
== NULL
) {
1054 dev_err(dev
, "Cannot map framebuffer\n");
1059 par
->mmio_base
= ioremap(par
->mmio_base_phys
, par
->mmio_len
);
1060 if (par
->mmio_base
== NULL
) {
1061 dev_err(dev
, "Cannot map registers\n");
1066 dev_dbg(dev
, "fb phys 0x%llx 0x%lx\n",
1067 (unsigned long long)par
->fb_base_phys
, (ulong
)par
->mapped_vram
);
1068 dev_dbg(dev
, "mmio phys 0x%llx 0x%lx\n",
1069 (unsigned long long)par
->mmio_base_phys
, (ulong
)par
->mmio_len
);
1071 ret
= mb862xx_pci_gdc_init(par
);
1075 ret
= request_irq(par
->irq
, mb862xx_intr
, IRQF_SHARED
,
1076 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 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 unregister_framebuffer(fbi
);
1154 fb_dealloc_cmap(&fbi
->cmap
);
1156 free_irq(par
->irq
, (void *)par
);
1157 iounmap(par
->mmio_base
);
1158 iounmap(par
->fb_base
);
1160 pci_release_regions(pdev
);
1161 framebuffer_release(fbi
);
1162 pci_disable_device(pdev
);
1165 static struct pci_driver mb862xxfb_pci_driver
= {
1167 .id_table
= mb862xx_pci_tbl
,
1168 .probe
= mb862xx_pci_probe
,
1169 .remove
= mb862xx_pci_remove
,
1173 static int mb862xxfb_init(void)
1177 #if defined(CONFIG_FB_MB862XX_LIME)
1178 ret
= platform_driver_register(&of_platform_mb862xxfb_driver
);
1180 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
1181 ret
= pci_register_driver(&mb862xxfb_pci_driver
);
1186 static void __exit
mb862xxfb_exit(void)
1188 #if defined(CONFIG_FB_MB862XX_LIME)
1189 platform_driver_unregister(&of_platform_mb862xxfb_driver
);
1191 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
1192 pci_unregister_driver(&mb862xxfb_pci_driver
);
1196 module_init(mb862xxfb_init
);
1197 module_exit(mb862xxfb_exit
);
1199 MODULE_DESCRIPTION("Fujitsu MB862xx Framebuffer driver");
1200 MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
1201 MODULE_LICENSE("GPL v2");