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/init.h>
20 #include <linux/interrupt.h>
21 #include <linux/pci.h>
22 #if defined(CONFIG_OF)
23 #include <linux/of_platform.h>
25 #include "mb862xxfb.h"
26 #include "mb862xx_reg.h"
28 #define NR_PALETTE 256
29 #define MB862XX_MEM_SIZE 0x1000000
30 #define CORALP_MEM_SIZE 0x4000000
31 #define CARMINE_MEM_SIZE 0x8000000
32 #define DRV_NAME "mb862xxfb"
34 #if defined(CONFIG_LWMON5)
35 static struct mb862xx_gc_mode lwmon5_gc_mode
= {
36 /* Mode for Sharp LQ104V1DG61 TFT LCD Panel */
37 { "640x480", 60, 640, 480, 40000, 48, 16, 32, 11, 96, 2, 0, 0, 0 },
38 /* 16 bits/pixel, 32MB, 100MHz, SDRAM memory mode value */
39 16, 0x2000000, GC_CCF_COT_100
, 0x414fb7f2
43 #if defined(CONFIG_SOCRATES)
44 static struct mb862xx_gc_mode socrates_gc_mode
= {
45 /* Mode for Prime View PM070WL4 TFT LCD Panel */
46 { "800x480", 45, 800, 480, 40000, 86, 42, 33, 10, 128, 2, 0, 0, 0 },
47 /* 16 bits/pixel, 16MB, 133MHz, SDRAM memory mode value */
48 16, 0x1000000, GC_CCF_COT_133
, 0x4157ba63
53 static inline int h_total(struct fb_var_screeninfo
*var
)
55 return var
->xres
+ var
->left_margin
+
56 var
->right_margin
+ var
->hsync_len
;
59 static inline int v_total(struct fb_var_screeninfo
*var
)
61 return var
->yres
+ var
->upper_margin
+
62 var
->lower_margin
+ var
->vsync_len
;
65 static inline int hsp(struct fb_var_screeninfo
*var
)
67 return var
->xres
+ var
->right_margin
- 1;
70 static inline int vsp(struct fb_var_screeninfo
*var
)
72 return var
->yres
+ var
->lower_margin
- 1;
75 static inline int d_pitch(struct fb_var_screeninfo
*var
)
77 return var
->xres
* var
->bits_per_pixel
/ 8;
80 static inline unsigned int chan_to_field(unsigned int chan
,
81 struct fb_bitfield
*bf
)
84 chan
>>= 16 - bf
->length
;
85 return chan
<< bf
->offset
;
88 static int mb862xxfb_setcolreg(unsigned regno
,
89 unsigned red
, unsigned green
, unsigned blue
,
90 unsigned transp
, struct fb_info
*info
)
92 struct mb862xxfb_par
*par
= info
->par
;
95 switch (info
->fix
.visual
) {
96 case FB_VISUAL_TRUECOLOR
:
98 val
= chan_to_field(red
, &info
->var
.red
);
99 val
|= chan_to_field(green
, &info
->var
.green
);
100 val
|= chan_to_field(blue
, &info
->var
.blue
);
101 par
->pseudo_palette
[regno
] = val
;
104 case FB_VISUAL_PSEUDOCOLOR
:
106 val
= (red
>> 8) << 16;
107 val
|= (green
>> 8) << 8;
109 outreg(disp
, GC_L0PAL0
+ (regno
* 4), val
);
113 return 1; /* unsupported type */
118 static int mb862xxfb_check_var(struct fb_var_screeninfo
*var
,
124 dev_dbg(fbi
->dev
, "%s\n", __func__
);
126 /* check if these values fit into the registers */
127 if (var
->hsync_len
> 255 || var
->vsync_len
> 255)
130 if ((var
->xres
+ var
->right_margin
) >= 4096)
133 if ((var
->yres
+ var
->lower_margin
) > 4096)
136 if (h_total(var
) > 4096 || v_total(var
) > 4096)
139 if (var
->xres_virtual
> 4096 || var
->yres_virtual
> 4096)
142 if (var
->bits_per_pixel
<= 8)
143 var
->bits_per_pixel
= 8;
144 else if (var
->bits_per_pixel
<= 16)
145 var
->bits_per_pixel
= 16;
146 else if (var
->bits_per_pixel
<= 32)
147 var
->bits_per_pixel
= 32;
150 * can cope with 8,16 or 24/32bpp if resulting
151 * pitch is divisible by 64 without remainder
153 if (d_pitch(&fbi
->var
) % GC_L0M_L0W_UNIT
) {
156 var
->bits_per_pixel
= 0;
158 var
->bits_per_pixel
+= 8;
159 r
= d_pitch(&fbi
->var
) % GC_L0M_L0W_UNIT
;
160 } while (r
&& var
->bits_per_pixel
<= 32);
162 if (d_pitch(&fbi
->var
) % GC_L0M_L0W_UNIT
)
166 /* line length is going to be 128 bit aligned */
167 tmp
= (var
->xres
* var
->bits_per_pixel
) / 8;
171 /* set r/g/b positions and validate bpp */
172 switch (var
->bits_per_pixel
) {
174 var
->red
.length
= var
->bits_per_pixel
;
175 var
->green
.length
= var
->bits_per_pixel
;
176 var
->blue
.length
= var
->bits_per_pixel
;
178 var
->green
.offset
= 0;
179 var
->blue
.offset
= 0;
180 var
->transp
.length
= 0;
184 var
->green
.length
= 5;
185 var
->blue
.length
= 5;
186 var
->red
.offset
= 10;
187 var
->green
.offset
= 5;
188 var
->blue
.offset
= 0;
189 var
->transp
.length
= 0;
193 var
->transp
.length
= 8;
195 var
->green
.length
= 8;
196 var
->blue
.length
= 8;
197 var
->transp
.offset
= 24;
198 var
->red
.offset
= 16;
199 var
->green
.offset
= 8;
200 var
->blue
.offset
= 0;
209 * set display parameters
211 static int mb862xxfb_set_par(struct fb_info
*fbi
)
213 struct mb862xxfb_par
*par
= fbi
->par
;
214 unsigned long reg
, sc
;
216 dev_dbg(par
->dev
, "%s\n", __func__
);
222 reg
= inreg(disp
, GC_DCM1
);
223 reg
&= ~GC_DCM01_DEN
;
224 outreg(disp
, GC_DCM1
, reg
);
226 /* set display reference clock div. */
227 sc
= par
->refclk
/ (1000000 / fbi
->var
.pixclock
) - 1;
228 reg
= inreg(disp
, GC_DCM1
);
229 reg
&= ~(GC_DCM01_CKS
| GC_DCM01_RESV
| GC_DCM01_SC
);
231 outreg(disp
, GC_DCM1
, reg
);
232 dev_dbg(par
->dev
, "SC 0x%lx\n", sc
);
234 /* disp dimension, format */
235 reg
= pack(d_pitch(&fbi
->var
) / GC_L0M_L0W_UNIT
,
236 (fbi
->var
.yres
- 1));
237 if (fbi
->var
.bits_per_pixel
== 16)
238 reg
|= GC_L0M_L0C_16
;
239 outreg(disp
, GC_L0M
, reg
);
241 if (fbi
->var
.bits_per_pixel
== 32) {
242 reg
= inreg(disp
, GC_L0EM
);
243 outreg(disp
, GC_L0EM
, reg
| GC_L0EM_L0EC_24
);
245 outreg(disp
, GC_WY_WX
, 0);
246 reg
= pack(fbi
->var
.yres
- 1, fbi
->var
.xres
);
247 outreg(disp
, GC_WH_WW
, reg
);
248 outreg(disp
, GC_L0OA0
, 0);
249 outreg(disp
, GC_L0DA0
, 0);
250 outreg(disp
, GC_L0DY_L0DX
, 0);
251 outreg(disp
, GC_L0WY_L0WX
, 0);
252 outreg(disp
, GC_L0WH_L0WW
, reg
);
254 /* both HW-cursors off */
255 reg
= inreg(disp
, GC_CPM_CUTC
);
256 reg
&= ~(GC_CPM_CEN0
| GC_CPM_CEN1
);
257 outreg(disp
, GC_CPM_CUTC
, reg
);
260 reg
= pack(fbi
->var
.xres
- 1, fbi
->var
.xres
- 1);
261 outreg(disp
, GC_HDB_HDP
, reg
);
262 reg
= pack((fbi
->var
.yres
- 1), vsp(&fbi
->var
));
263 outreg(disp
, GC_VDP_VSP
, reg
);
264 reg
= ((fbi
->var
.vsync_len
- 1) << 24) |
265 pack((fbi
->var
.hsync_len
- 1), hsp(&fbi
->var
));
266 outreg(disp
, GC_VSW_HSW_HSP
, reg
);
267 outreg(disp
, GC_HTP
, pack(h_total(&fbi
->var
) - 1, 0));
268 outreg(disp
, GC_VTR
, pack(v_total(&fbi
->var
) - 1, 0));
271 reg
= inreg(disp
, GC_DCM1
);
272 reg
|= GC_DCM01_DEN
| GC_DCM01_L0E
;
273 reg
&= ~GC_DCM01_ESY
;
274 outreg(disp
, GC_DCM1
, reg
);
278 static int mb862xxfb_pan(struct fb_var_screeninfo
*var
,
279 struct fb_info
*info
)
281 struct mb862xxfb_par
*par
= info
->par
;
284 reg
= pack(var
->yoffset
, var
->xoffset
);
285 outreg(disp
, GC_L0WY_L0WX
, reg
);
287 reg
= pack(var
->yres_virtual
, var
->xres_virtual
);
288 outreg(disp
, GC_L0WH_L0WW
, reg
);
292 static int mb862xxfb_blank(int mode
, struct fb_info
*fbi
)
294 struct mb862xxfb_par
*par
= fbi
->par
;
297 dev_dbg(fbi
->dev
, "blank mode=%d\n", mode
);
300 case FB_BLANK_POWERDOWN
:
301 reg
= inreg(disp
, GC_DCM1
);
302 reg
&= ~GC_DCM01_DEN
;
303 outreg(disp
, GC_DCM1
, reg
);
305 case FB_BLANK_UNBLANK
:
306 reg
= inreg(disp
, GC_DCM1
);
308 outreg(disp
, GC_DCM1
, reg
);
310 case FB_BLANK_NORMAL
:
311 case FB_BLANK_VSYNC_SUSPEND
:
312 case FB_BLANK_HSYNC_SUSPEND
:
319 /* framebuffer ops */
320 static struct fb_ops mb862xxfb_ops
= {
321 .owner
= THIS_MODULE
,
322 .fb_check_var
= mb862xxfb_check_var
,
323 .fb_set_par
= mb862xxfb_set_par
,
324 .fb_setcolreg
= mb862xxfb_setcolreg
,
325 .fb_blank
= mb862xxfb_blank
,
326 .fb_pan_display
= mb862xxfb_pan
,
327 .fb_fillrect
= cfb_fillrect
,
328 .fb_copyarea
= cfb_copyarea
,
329 .fb_imageblit
= cfb_imageblit
,
332 /* initialize fb_info data */
333 static int mb862xxfb_init_fbinfo(struct fb_info
*fbi
)
335 struct mb862xxfb_par
*par
= fbi
->par
;
336 struct mb862xx_gc_mode
*mode
= par
->gc_mode
;
339 fbi
->fbops
= &mb862xxfb_ops
;
340 fbi
->pseudo_palette
= par
->pseudo_palette
;
341 fbi
->screen_base
= par
->fb_base
;
342 fbi
->screen_size
= par
->mapped_vram
;
344 strcpy(fbi
->fix
.id
, DRV_NAME
);
345 fbi
->fix
.smem_start
= (unsigned long)par
->fb_base_phys
;
346 fbi
->fix
.smem_len
= par
->mapped_vram
;
347 fbi
->fix
.mmio_start
= (unsigned long)par
->mmio_base_phys
;
348 fbi
->fix
.mmio_len
= par
->mmio_len
;
349 fbi
->fix
.accel
= FB_ACCEL_NONE
;
350 fbi
->fix
.type
= FB_TYPE_PACKED_PIXELS
;
351 fbi
->fix
.type_aux
= 0;
352 fbi
->fix
.xpanstep
= 1;
353 fbi
->fix
.ypanstep
= 1;
354 fbi
->fix
.ywrapstep
= 0;
356 reg
= inreg(disp
, GC_DCM1
);
357 if (reg
& GC_DCM01_DEN
&& reg
& GC_DCM01_L0E
) {
358 /* get the disp mode from active display cfg */
359 unsigned long sc
= ((reg
& GC_DCM01_SC
) >> 8) + 1;
360 unsigned long hsp
, vsp
, ht
, vt
;
362 dev_dbg(par
->dev
, "using bootloader's disp. mode\n");
363 fbi
->var
.pixclock
= (sc
* 1000000) / par
->refclk
;
364 fbi
->var
.xres
= (inreg(disp
, GC_HDB_HDP
) & 0x0fff) + 1;
365 reg
= inreg(disp
, GC_VDP_VSP
);
366 fbi
->var
.yres
= ((reg
>> 16) & 0x0fff) + 1;
367 vsp
= (reg
& 0x0fff) + 1;
368 fbi
->var
.xres_virtual
= fbi
->var
.xres
;
369 fbi
->var
.yres_virtual
= fbi
->var
.yres
;
370 reg
= inreg(disp
, GC_L0EM
);
371 if (reg
& GC_L0EM_L0EC_24
) {
372 fbi
->var
.bits_per_pixel
= 32;
374 reg
= inreg(disp
, GC_L0M
);
375 if (reg
& GC_L0M_L0C_16
)
376 fbi
->var
.bits_per_pixel
= 16;
378 fbi
->var
.bits_per_pixel
= 8;
380 reg
= inreg(disp
, GC_VSW_HSW_HSP
);
381 fbi
->var
.hsync_len
= ((reg
& 0xff0000) >> 16) + 1;
382 fbi
->var
.vsync_len
= ((reg
& 0x3f000000) >> 24) + 1;
383 hsp
= (reg
& 0xffff) + 1;
384 ht
= ((inreg(disp
, GC_HTP
) & 0xfff0000) >> 16) + 1;
385 fbi
->var
.right_margin
= hsp
- fbi
->var
.xres
;
386 fbi
->var
.left_margin
= ht
- hsp
- fbi
->var
.hsync_len
;
387 vt
= ((inreg(disp
, GC_VTR
) & 0xfff0000) >> 16) + 1;
388 fbi
->var
.lower_margin
= vsp
- fbi
->var
.yres
;
389 fbi
->var
.upper_margin
= vt
- vsp
- fbi
->var
.vsync_len
;
391 dev_dbg(par
->dev
, "using supplied mode\n");
392 fb_videomode_to_var(&fbi
->var
, (struct fb_videomode
*)mode
);
393 fbi
->var
.bits_per_pixel
= mode
->def_bpp
? mode
->def_bpp
: 8;
397 ret
= fb_find_mode(&fbi
->var
, fbi
, "640x480-16@60",
399 if (ret
== 0 || ret
== 4) {
401 "failed to get initial mode\n");
406 fbi
->var
.xoffset
= 0;
407 fbi
->var
.yoffset
= 0;
408 fbi
->var
.grayscale
= 0;
410 fbi
->var
.height
= -1;
412 fbi
->var
.accel_flags
= 0;
413 fbi
->var
.vmode
= FB_VMODE_NONINTERLACED
;
414 fbi
->var
.activate
= FB_ACTIVATE_NOW
;
415 fbi
->flags
= FBINFO_DEFAULT
|
417 FBINFO_FOREIGN_ENDIAN
|
419 FBINFO_HWACCEL_XPAN
|
422 /* check and possibly fix bpp */
423 if ((fbi
->fbops
->fb_check_var
)(&fbi
->var
, fbi
))
424 dev_err(par
->dev
, "check_var() failed on initial setup?\n");
426 fbi
->fix
.visual
= fbi
->var
.bits_per_pixel
== 8 ?
427 FB_VISUAL_PSEUDOCOLOR
: FB_VISUAL_TRUECOLOR
;
428 fbi
->fix
.line_length
= (fbi
->var
.xres_virtual
*
429 fbi
->var
.bits_per_pixel
) / 8;
434 * show some display controller and cursor registers
436 static ssize_t
mb862xxfb_show_dispregs(struct device
*dev
,
437 struct device_attribute
*attr
, char *buf
)
439 struct fb_info
*fbi
= dev_get_drvdata(dev
);
440 struct mb862xxfb_par
*par
= fbi
->par
;
444 for (reg
= GC_DCM0
; reg
<= GC_L0DY_L0DX
; reg
+= 4)
445 ptr
+= sprintf(ptr
, "%08x = %08x\n",
446 reg
, inreg(disp
, reg
));
448 for (reg
= GC_CPM_CUTC
; reg
<= GC_CUY1_CUX1
; reg
+= 4)
449 ptr
+= sprintf(ptr
, "%08x = %08x\n",
450 reg
, inreg(disp
, reg
));
452 for (reg
= GC_DCM1
; reg
<= GC_L0WH_L0WW
; reg
+= 4)
453 ptr
+= sprintf(ptr
, "%08x = %08x\n",
454 reg
, inreg(disp
, reg
));
459 static DEVICE_ATTR(dispregs
, 0444, mb862xxfb_show_dispregs
, NULL
);
461 irqreturn_t
mb862xx_intr(int irq
, void *dev_id
)
463 struct mb862xxfb_par
*par
= (struct mb862xxfb_par
*) dev_id
;
464 unsigned long reg_ist
, mask
;
469 if (par
->type
== BT_CARMINE
) {
470 /* Get Interrupt Status */
471 reg_ist
= inreg(ctrl
, GC_CTRL_STATUS
);
472 mask
= inreg(ctrl
, GC_CTRL_INT_MASK
);
480 /* Clear interrupt status */
481 outreg(ctrl
, 0x0, reg_ist
);
484 reg_ist
= inreg(host
, GC_IST
);
485 mask
= inreg(host
, GC_IMASK
);
492 outreg(host
, GC_IST
, ~reg_ist
);
497 #if defined(CONFIG_FB_MB862XX_LIME)
499 * GDC (Lime, Coral(B/Q), Mint, ...) on host bus
501 static int mb862xx_gdc_init(struct mb862xxfb_par
*par
)
503 unsigned long ccf
, mmr
;
504 unsigned long ver
, rev
;
509 #if defined(CONFIG_FB_PRE_INIT_FB)
512 par
->host
= par
->mmio_base
;
513 par
->i2c
= par
->mmio_base
+ MB862XX_I2C_BASE
;
514 par
->disp
= par
->mmio_base
+ MB862XX_DISP_BASE
;
515 par
->cap
= par
->mmio_base
+ MB862XX_CAP_BASE
;
516 par
->draw
= par
->mmio_base
+ MB862XX_DRAW_BASE
;
517 par
->geo
= par
->mmio_base
+ MB862XX_GEO_BASE
;
518 par
->pio
= par
->mmio_base
+ MB862XX_PIO_BASE
;
520 par
->refclk
= GC_DISP_REFCLK_400
;
522 ver
= inreg(host
, GC_CID
);
523 rev
= inreg(pio
, GC_REVISION
);
524 if ((ver
== 0x303) && (rev
& 0xffffff00) == 0x20050100) {
525 dev_info(par
->dev
, "Fujitsu Lime v1.%d found\n",
528 ccf
= par
->gc_mode
? par
->gc_mode
->ccf
: GC_CCF_COT_100
;
529 mmr
= par
->gc_mode
? par
->gc_mode
->mmr
: 0x414fb7f2;
531 dev_info(par
->dev
, "? GDC, CID/Rev.: 0x%lx/0x%lx \n", ver
, rev
);
535 if (!par
->pre_init
) {
536 outreg(host
, GC_CCF
, ccf
);
538 outreg(host
, GC_MMR
, mmr
);
542 /* interrupt status */
543 outreg(host
, GC_IST
, 0);
544 outreg(host
, GC_IMASK
, GC_INT_EN
);
548 static int __devinit
of_platform_mb862xx_probe(struct of_device
*ofdev
,
549 const struct of_device_id
*id
)
551 struct device_node
*np
= ofdev
->node
;
552 struct device
*dev
= &ofdev
->dev
;
553 struct mb862xxfb_par
*par
;
554 struct fb_info
*info
;
556 resource_size_t res_size
;
557 unsigned long ret
= -ENODEV
;
559 if (of_address_to_resource(np
, 0, &res
)) {
560 dev_err(dev
, "Invalid address\n");
564 info
= framebuffer_alloc(sizeof(struct mb862xxfb_par
), dev
);
566 dev_err(dev
, "cannot allocate framebuffer\n");
574 par
->irq
= irq_of_parse_and_map(np
, 0);
575 if (par
->irq
== NO_IRQ
) {
576 dev_err(dev
, "failed to map irq\n");
581 res_size
= 1 + res
.end
- res
.start
;
582 par
->res
= request_mem_region(res
.start
, res_size
, DRV_NAME
);
583 if (par
->res
== NULL
) {
584 dev_err(dev
, "Cannot claim framebuffer/mmio\n");
589 #if defined(CONFIG_LWMON5)
590 par
->gc_mode
= &lwmon5_gc_mode
;
593 #if defined(CONFIG_SOCRATES)
594 par
->gc_mode
= &socrates_gc_mode
;
597 par
->fb_base_phys
= res
.start
;
598 par
->mmio_base_phys
= res
.start
+ MB862XX_MMIO_BASE
;
599 par
->mmio_len
= MB862XX_MMIO_SIZE
;
601 par
->mapped_vram
= par
->gc_mode
->max_vram
;
603 par
->mapped_vram
= MB862XX_MEM_SIZE
;
605 par
->fb_base
= ioremap(par
->fb_base_phys
, par
->mapped_vram
);
606 if (par
->fb_base
== NULL
) {
607 dev_err(dev
, "Cannot map framebuffer\n");
611 par
->mmio_base
= ioremap(par
->mmio_base_phys
, par
->mmio_len
);
612 if (par
->mmio_base
== NULL
) {
613 dev_err(dev
, "Cannot map registers\n");
617 dev_dbg(dev
, "fb phys 0x%llx 0x%lx\n",
618 (u64
)par
->fb_base_phys
, (ulong
)par
->mapped_vram
);
619 dev_dbg(dev
, "mmio phys 0x%llx 0x%lx, (irq = %d)\n",
620 (u64
)par
->mmio_base_phys
, (ulong
)par
->mmio_len
, par
->irq
);
622 if (mb862xx_gdc_init(par
))
625 if (request_irq(par
->irq
, mb862xx_intr
, IRQF_DISABLED
,
626 DRV_NAME
, (void *)par
)) {
627 dev_err(dev
, "Cannot request irq\n");
631 mb862xxfb_init_fbinfo(info
);
633 if (fb_alloc_cmap(&info
->cmap
, NR_PALETTE
, 0) < 0) {
634 dev_err(dev
, "Could not allocate cmap for fb_info.\n");
638 if ((info
->fbops
->fb_set_par
)(info
))
639 dev_err(dev
, "set_var() failed on initial setup?\n");
641 if (register_framebuffer(info
)) {
642 dev_err(dev
, "failed to register framebuffer\n");
646 dev_set_drvdata(dev
, info
);
648 if (device_create_file(dev
, &dev_attr_dispregs
))
649 dev_err(dev
, "Can't create sysfs regdump file\n");
653 fb_dealloc_cmap(&info
->cmap
);
655 outreg(host
, GC_IMASK
, 0);
656 free_irq(par
->irq
, (void *)par
);
658 iounmap(par
->mmio_base
);
660 iounmap(par
->fb_base
);
662 release_mem_region(res
.start
, res_size
);
664 irq_dispose_mapping(par
->irq
);
666 dev_set_drvdata(dev
, NULL
);
667 framebuffer_release(info
);
671 static int __devexit
of_platform_mb862xx_remove(struct of_device
*ofdev
)
673 struct fb_info
*fbi
= dev_get_drvdata(&ofdev
->dev
);
674 struct mb862xxfb_par
*par
= fbi
->par
;
675 resource_size_t res_size
= 1 + par
->res
->end
- par
->res
->start
;
678 dev_dbg(fbi
->dev
, "%s release\n", fbi
->fix
.id
);
681 reg
= inreg(disp
, GC_DCM1
);
682 reg
&= ~(GC_DCM01_DEN
| GC_DCM01_L0E
);
683 outreg(disp
, GC_DCM1
, reg
);
685 /* disable interrupts */
686 outreg(host
, GC_IMASK
, 0);
688 free_irq(par
->irq
, (void *)par
);
689 irq_dispose_mapping(par
->irq
);
691 device_remove_file(&ofdev
->dev
, &dev_attr_dispregs
);
693 unregister_framebuffer(fbi
);
694 fb_dealloc_cmap(&fbi
->cmap
);
696 iounmap(par
->mmio_base
);
697 iounmap(par
->fb_base
);
699 dev_set_drvdata(&ofdev
->dev
, NULL
);
700 release_mem_region(par
->res
->start
, res_size
);
701 framebuffer_release(fbi
);
708 static struct of_device_id __devinitdata of_platform_mb862xx_tbl
[] = {
709 { .compatible
= "fujitsu,MB86276", },
710 { .compatible
= "fujitsu,lime", },
711 { .compatible
= "fujitsu,MB86277", },
712 { .compatible
= "fujitsu,mint", },
713 { .compatible
= "fujitsu,MB86293", },
714 { .compatible
= "fujitsu,MB86294", },
715 { .compatible
= "fujitsu,coral", },
719 static struct of_platform_driver of_platform_mb862xxfb_driver
= {
720 .owner
= THIS_MODULE
,
722 .match_table
= of_platform_mb862xx_tbl
,
723 .probe
= of_platform_mb862xx_probe
,
724 .remove
= __devexit_p(of_platform_mb862xx_remove
),
728 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
729 static int coralp_init(struct mb862xxfb_par
*par
)
733 par
->host
= par
->mmio_base
;
734 par
->i2c
= par
->mmio_base
+ MB862XX_I2C_BASE
;
735 par
->disp
= par
->mmio_base
+ MB862XX_DISP_BASE
;
736 par
->cap
= par
->mmio_base
+ MB862XX_CAP_BASE
;
737 par
->draw
= par
->mmio_base
+ MB862XX_DRAW_BASE
;
738 par
->geo
= par
->mmio_base
+ MB862XX_GEO_BASE
;
739 par
->pio
= par
->mmio_base
+ MB862XX_PIO_BASE
;
741 par
->refclk
= GC_DISP_REFCLK_400
;
743 ver
= inreg(host
, GC_CID
);
744 cn
= (ver
& GC_CID_CNAME_MSK
) >> 8;
745 ver
= ver
& GC_CID_VERSION_MSK
;
747 dev_info(par
->dev
, "Fujitsu Coral-%s GDC Rev.%d found\n",\
748 (ver
== 6) ? "P" : (ver
== 8) ? "PA" : "?",
749 par
->pdev
->revision
);
750 outreg(host
, GC_CCF
, GC_CCF_CGE_166
| GC_CCF_COT_133
);
752 outreg(host
, GC_MMR
, GC_MMR_CORALP_EVB_VAL
);
754 /* Clear interrupt status */
755 outreg(host
, GC_IST
, 0);
762 static int init_dram_ctrl(struct mb862xxfb_par
*par
)
767 * Set io mode first! Spec. says IC may be destroyed
768 * if not set to SSTL2/LVCMOS before init.
770 outreg(dram_ctrl
, GC_DCTL_IOCONT1_IOCONT0
, GC_EVB_DCTL_IOCONT1_IOCONT0
);
773 outreg(dram_ctrl
, GC_DCTL_MODE_ADD
, GC_EVB_DCTL_MODE_ADD
);
774 outreg(dram_ctrl
, GC_DCTL_SETTIME1_EMODE
, GC_EVB_DCTL_SETTIME1_EMODE
);
775 outreg(dram_ctrl
, GC_DCTL_REFRESH_SETTIME2
,
776 GC_EVB_DCTL_REFRESH_SETTIME2
);
777 outreg(dram_ctrl
, GC_DCTL_RSV2_RSV1
, GC_EVB_DCTL_RSV2_RSV1
);
778 outreg(dram_ctrl
, GC_DCTL_DDRIF2_DDRIF1
, GC_EVB_DCTL_DDRIF2_DDRIF1
);
779 outreg(dram_ctrl
, GC_DCTL_RSV0_STATES
, GC_EVB_DCTL_RSV0_STATES
);
781 /* DLL reset done? */
782 while ((inreg(dram_ctrl
, GC_DCTL_RSV0_STATES
) & GC_DCTL_STATES_MSK
)) {
783 udelay(GC_DCTL_INIT_WAIT_INTERVAL
);
784 if (i
++ > GC_DCTL_INIT_WAIT_CNT
) {
785 dev_err(par
->dev
, "VRAM init failed.\n");
789 outreg(dram_ctrl
, GC_DCTL_MODE_ADD
, GC_EVB_DCTL_MODE_ADD_AFT_RST
);
790 outreg(dram_ctrl
, GC_DCTL_RSV0_STATES
, GC_EVB_DCTL_RSV0_STATES_AFT_RST
);
794 static int carmine_init(struct mb862xxfb_par
*par
)
798 par
->ctrl
= par
->mmio_base
+ MB86297_CTRL_BASE
;
799 par
->i2c
= par
->mmio_base
+ MB86297_I2C_BASE
;
800 par
->disp
= par
->mmio_base
+ MB86297_DISP0_BASE
;
801 par
->disp1
= par
->mmio_base
+ MB86297_DISP1_BASE
;
802 par
->cap
= par
->mmio_base
+ MB86297_CAP0_BASE
;
803 par
->cap1
= par
->mmio_base
+ MB86297_CAP1_BASE
;
804 par
->draw
= par
->mmio_base
+ MB86297_DRAW_BASE
;
805 par
->dram_ctrl
= par
->mmio_base
+ MB86297_DRAMCTRL_BASE
;
806 par
->wrback
= par
->mmio_base
+ MB86297_WRBACK_BASE
;
808 par
->refclk
= GC_DISP_REFCLK_533
;
811 reg
= GC_CTRL_CLK_EN_DRAM
| GC_CTRL_CLK_EN_2D3D
| GC_CTRL_CLK_EN_DISP0
;
812 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, reg
);
814 /* check for engine module revision */
815 if (inreg(draw
, GC_2D3D_REV
) == GC_RE_REVISION
)
816 dev_info(par
->dev
, "Fujitsu Carmine GDC Rev.%d found\n",
817 par
->pdev
->revision
);
821 reg
&= ~GC_CTRL_CLK_EN_2D3D
;
822 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, reg
);
825 if (init_dram_ctrl(par
) < 0)
828 outreg(ctrl
, GC_CTRL_INT_MASK
, 0);
832 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, 0);
836 static inline int mb862xx_pci_gdc_init(struct mb862xxfb_par
*par
)
840 return coralp_init(par
);
842 return carmine_init(par
);
848 #define CHIP_ID(id) \
849 { PCI_DEVICE(PCI_VENDOR_ID_FUJITSU_LIMITED, id) }
851 static struct pci_device_id mb862xx_pci_tbl
[] __devinitdata
= {
852 /* MB86295/MB86296 */
853 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALP
),
854 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALPA
),
856 CHIP_ID(PCI_DEVICE_ID_FUJITSU_CARMINE
),
860 MODULE_DEVICE_TABLE(pci
, mb862xx_pci_tbl
);
862 static int __devinit
mb862xx_pci_probe(struct pci_dev
*pdev
,
863 const struct pci_device_id
*ent
)
865 struct mb862xxfb_par
*par
;
866 struct fb_info
*info
;
867 struct device
*dev
= &pdev
->dev
;
870 ret
= pci_enable_device(pdev
);
872 dev_err(dev
, "Cannot enable PCI device\n");
876 info
= framebuffer_alloc(sizeof(struct mb862xxfb_par
), dev
);
878 dev_err(dev
, "framebuffer alloc failed\n");
887 par
->irq
= pdev
->irq
;
889 ret
= pci_request_regions(pdev
, DRV_NAME
);
891 dev_err(dev
, "Cannot reserve region(s) for PCI device\n");
895 switch (pdev
->device
) {
896 case PCI_DEVICE_ID_FUJITSU_CORALP
:
897 case PCI_DEVICE_ID_FUJITSU_CORALPA
:
898 par
->fb_base_phys
= pci_resource_start(par
->pdev
, 0);
899 par
->mapped_vram
= CORALP_MEM_SIZE
;
900 par
->mmio_base_phys
= par
->fb_base_phys
+ MB862XX_MMIO_BASE
;
901 par
->mmio_len
= MB862XX_MMIO_SIZE
;
902 par
->type
= BT_CORALP
;
904 case PCI_DEVICE_ID_FUJITSU_CARMINE
:
905 par
->fb_base_phys
= pci_resource_start(par
->pdev
, 2);
906 par
->mmio_base_phys
= pci_resource_start(par
->pdev
, 3);
907 par
->mmio_len
= pci_resource_len(par
->pdev
, 3);
908 par
->mapped_vram
= CARMINE_MEM_SIZE
;
909 par
->type
= BT_CARMINE
;
912 /* should never occur */
916 par
->fb_base
= ioremap(par
->fb_base_phys
, par
->mapped_vram
);
917 if (par
->fb_base
== NULL
) {
918 dev_err(dev
, "Cannot map framebuffer\n");
922 par
->mmio_base
= ioremap(par
->mmio_base_phys
, par
->mmio_len
);
923 if (par
->mmio_base
== NULL
) {
924 dev_err(dev
, "Cannot map registers\n");
929 dev_dbg(dev
, "fb phys 0x%llx 0x%lx\n",
930 (unsigned long long)par
->fb_base_phys
, (ulong
)par
->mapped_vram
);
931 dev_dbg(dev
, "mmio phys 0x%llx 0x%lx\n",
932 (unsigned long long)par
->mmio_base_phys
, (ulong
)par
->mmio_len
);
934 if (mb862xx_pci_gdc_init(par
))
937 if (request_irq(par
->irq
, mb862xx_intr
, IRQF_DISABLED
| IRQF_SHARED
,
938 DRV_NAME
, (void *)par
)) {
939 dev_err(dev
, "Cannot request irq\n");
943 mb862xxfb_init_fbinfo(info
);
945 if (fb_alloc_cmap(&info
->cmap
, NR_PALETTE
, 0) < 0) {
946 dev_err(dev
, "Could not allocate cmap for fb_info.\n");
951 if ((info
->fbops
->fb_set_par
)(info
))
952 dev_err(dev
, "set_var() failed on initial setup?\n");
954 ret
= register_framebuffer(info
);
956 dev_err(dev
, "failed to register framebuffer\n");
960 pci_set_drvdata(pdev
, info
);
962 if (device_create_file(dev
, &dev_attr_dispregs
))
963 dev_err(dev
, "Can't create sysfs regdump file\n");
965 if (par
->type
== BT_CARMINE
)
966 outreg(ctrl
, GC_CTRL_INT_MASK
, GC_CARMINE_INT_EN
);
968 outreg(host
, GC_IMASK
, GC_INT_EN
);
973 fb_dealloc_cmap(&info
->cmap
);
975 free_irq(par
->irq
, (void *)par
);
977 iounmap(par
->mmio_base
);
979 iounmap(par
->fb_base
);
981 pci_release_regions(pdev
);
983 framebuffer_release(info
);
985 pci_disable_device(pdev
);
990 static void __devexit
mb862xx_pci_remove(struct pci_dev
*pdev
)
992 struct fb_info
*fbi
= pci_get_drvdata(pdev
);
993 struct mb862xxfb_par
*par
= fbi
->par
;
996 dev_dbg(fbi
->dev
, "%s release\n", fbi
->fix
.id
);
999 reg
= inreg(disp
, GC_DCM1
);
1000 reg
&= ~(GC_DCM01_DEN
| GC_DCM01_L0E
);
1001 outreg(disp
, GC_DCM1
, reg
);
1003 if (par
->type
== BT_CARMINE
) {
1004 outreg(ctrl
, GC_CTRL_INT_MASK
, 0);
1005 outreg(ctrl
, GC_CTRL_CLK_ENABLE
, 0);
1007 outreg(host
, GC_IMASK
, 0);
1010 device_remove_file(&pdev
->dev
, &dev_attr_dispregs
);
1012 pci_set_drvdata(pdev
, NULL
);
1013 unregister_framebuffer(fbi
);
1014 fb_dealloc_cmap(&fbi
->cmap
);
1016 free_irq(par
->irq
, (void *)par
);
1017 iounmap(par
->mmio_base
);
1018 iounmap(par
->fb_base
);
1020 pci_release_regions(pdev
);
1021 framebuffer_release(fbi
);
1022 pci_disable_device(pdev
);
1025 static struct pci_driver mb862xxfb_pci_driver
= {
1027 .id_table
= mb862xx_pci_tbl
,
1028 .probe
= mb862xx_pci_probe
,
1029 .remove
= __devexit_p(mb862xx_pci_remove
),
1033 static int __devinit
mb862xxfb_init(void)
1037 #if defined(CONFIG_FB_MB862XX_LIME)
1038 ret
= of_register_platform_driver(&of_platform_mb862xxfb_driver
);
1040 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
1041 ret
= pci_register_driver(&mb862xxfb_pci_driver
);
1046 static void __exit
mb862xxfb_exit(void)
1048 #if defined(CONFIG_FB_MB862XX_LIME)
1049 of_unregister_platform_driver(&of_platform_mb862xxfb_driver
);
1051 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
1052 pci_unregister_driver(&mb862xxfb_pci_driver
);
1056 module_init(mb862xxfb_init
);
1057 module_exit(mb862xxfb_exit
);
1059 MODULE_DESCRIPTION("Fujitsu MB862xx Framebuffer driver");
1060 MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
1061 MODULE_LICENSE("GPL v2");