• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * drivers/mb862xx/mb862xxfb.c
3  *
4  * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver
5  *
6  * (C) 2008 Anatolij Gustschin <agust@denx.de>
7  * DENX Software Engineering
8  *
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.
12  *
13  */
14 
15 #undef DEBUG
16 
17 #include <linux/fb.h>
18 #include <linux/delay.h>
19 #include <linux/init.h>
20 #include <linux/interrupt.h>
21 #include <linux/pci.h>
22 #if defined(CONFIG_PPC_OF)
23 #include <linux/of_platform.h>
24 #endif
25 #include "mb862xxfb.h"
26 #include "mb862xx_reg.h"
27 
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"
33 
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
40 };
41 #endif
42 
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
49 };
50 #endif
51 
52 /* Helpers */
h_total(struct fb_var_screeninfo * var)53 static inline int h_total(struct fb_var_screeninfo *var)
54 {
55 	return var->xres + var->left_margin +
56 		var->right_margin + var->hsync_len;
57 }
58 
v_total(struct fb_var_screeninfo * var)59 static inline int v_total(struct fb_var_screeninfo *var)
60 {
61 	return var->yres + var->upper_margin +
62 		var->lower_margin + var->vsync_len;
63 }
64 
hsp(struct fb_var_screeninfo * var)65 static inline int hsp(struct fb_var_screeninfo *var)
66 {
67 	return var->xres + var->right_margin - 1;
68 }
69 
vsp(struct fb_var_screeninfo * var)70 static inline int vsp(struct fb_var_screeninfo *var)
71 {
72 	return var->yres + var->lower_margin - 1;
73 }
74 
d_pitch(struct fb_var_screeninfo * var)75 static inline int d_pitch(struct fb_var_screeninfo *var)
76 {
77 	return var->xres * var->bits_per_pixel / 8;
78 }
79 
chan_to_field(unsigned int chan,struct fb_bitfield * bf)80 static inline unsigned int chan_to_field(unsigned int chan,
81 					 struct fb_bitfield *bf)
82 {
83 	chan &= 0xffff;
84 	chan >>= 16 - bf->length;
85 	return chan << bf->offset;
86 }
87 
mb862xxfb_setcolreg(unsigned regno,unsigned red,unsigned green,unsigned blue,unsigned transp,struct fb_info * info)88 static int mb862xxfb_setcolreg(unsigned regno,
89 			       unsigned red, unsigned green, unsigned blue,
90 			       unsigned transp, struct fb_info *info)
91 {
92 	struct mb862xxfb_par *par = info->par;
93 	unsigned int val;
94 
95 	switch (info->fix.visual) {
96 	case FB_VISUAL_TRUECOLOR:
97 		if (regno < 16) {
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;
102 		}
103 		break;
104 	case FB_VISUAL_PSEUDOCOLOR:
105 		if (regno < 256) {
106 			val = (red >> 8) << 16;
107 			val |= (green >> 8) << 8;
108 			val |= blue >> 8;
109 			outreg(disp, GC_L0PAL0 + (regno * 4), val);
110 		}
111 		break;
112 	default:
113 		return 1;   /* unsupported type */
114 	}
115 	return 0;
116 }
117 
mb862xxfb_check_var(struct fb_var_screeninfo * var,struct fb_info * fbi)118 static int mb862xxfb_check_var(struct fb_var_screeninfo *var,
119 			       struct fb_info *fbi)
120 {
121 	unsigned long tmp;
122 
123 	if (fbi->dev)
124 		dev_dbg(fbi->dev, "%s\n", __func__);
125 
126 	/* check if these values fit into the registers */
127 	if (var->hsync_len > 255 || var->vsync_len > 255)
128 		return -EINVAL;
129 
130 	if ((var->xres + var->right_margin) >= 4096)
131 		return -EINVAL;
132 
133 	if ((var->yres + var->lower_margin) > 4096)
134 		return -EINVAL;
135 
136 	if (h_total(var) > 4096 || v_total(var) > 4096)
137 		return -EINVAL;
138 
139 	if (var->xres_virtual > 4096 || var->yres_virtual > 4096)
140 		return -EINVAL;
141 
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;
148 
149 	/*
150 	 * can cope with 8,16 or 24/32bpp if resulting
151 	 * pitch is divisible by 64 without remainder
152 	 */
153 	if (d_pitch(&fbi->var) % GC_L0M_L0W_UNIT) {
154 		int r;
155 
156 		var->bits_per_pixel = 0;
157 		do {
158 			var->bits_per_pixel += 8;
159 			r = d_pitch(&fbi->var) % GC_L0M_L0W_UNIT;
160 		} while (r && var->bits_per_pixel <= 32);
161 
162 		if (d_pitch(&fbi->var) % GC_L0M_L0W_UNIT)
163 			return -EINVAL;
164 	}
165 
166 	/* line length is going to be 128 bit aligned */
167 	tmp = (var->xres * var->bits_per_pixel) / 8;
168 	if ((tmp & 15) != 0)
169 		return -EINVAL;
170 
171 	/* set r/g/b positions and validate bpp */
172 	switch (var->bits_per_pixel) {
173 	case 8:
174 		var->red.length		= var->bits_per_pixel;
175 		var->green.length	= var->bits_per_pixel;
176 		var->blue.length	= var->bits_per_pixel;
177 		var->red.offset		= 0;
178 		var->green.offset	= 0;
179 		var->blue.offset	= 0;
180 		var->transp.length	= 0;
181 		break;
182 	case 16:
183 		var->red.length		= 5;
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;
190 		break;
191 	case 24:
192 	case 32:
193 		var->transp.length	= 8;
194 		var->red.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;
201 		break;
202 	default:
203 		return -EINVAL;
204 	}
205 	return 0;
206 }
207 
208 /*
209  * set display parameters
210  */
mb862xxfb_set_par(struct fb_info * fbi)211 static int mb862xxfb_set_par(struct fb_info *fbi)
212 {
213 	struct mb862xxfb_par *par = fbi->par;
214 	unsigned long reg, sc;
215 
216 	dev_dbg(par->dev, "%s\n", __func__);
217 
218 	if (par->pre_init)
219 		return 0;
220 
221 	/* disp off */
222 	reg = inreg(disp, GC_DCM1);
223 	reg &= ~GC_DCM01_DEN;
224 	outreg(disp, GC_DCM1, reg);
225 
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);
230 	reg |= sc << 8;
231 	outreg(disp, GC_DCM1, reg);
232 	dev_dbg(par->dev, "SC 0x%lx\n", sc);
233 
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);
240 
241 	if (fbi->var.bits_per_pixel == 32) {
242 		reg = inreg(disp, GC_L0EM);
243 		outreg(disp, GC_L0EM, reg | GC_L0EM_L0EC_24);
244 	}
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);
253 
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);
258 
259 	/* timings */
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));
269 
270 	/* display on */
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);
275 	return 0;
276 }
277 
mb862xxfb_pan(struct fb_var_screeninfo * var,struct fb_info * info)278 static int mb862xxfb_pan(struct fb_var_screeninfo *var,
279 			 struct fb_info *info)
280 {
281 	struct mb862xxfb_par *par = info->par;
282 	unsigned long reg;
283 
284 	reg = pack(var->yoffset, var->xoffset);
285 	outreg(disp, GC_L0WY_L0WX, reg);
286 
287 	reg = pack(var->yres_virtual, var->xres_virtual);
288 	outreg(disp, GC_L0WH_L0WW, reg);
289 	return 0;
290 }
291 
mb862xxfb_blank(int mode,struct fb_info * fbi)292 static int mb862xxfb_blank(int mode, struct fb_info *fbi)
293 {
294 	struct mb862xxfb_par  *par = fbi->par;
295 	unsigned long reg;
296 
297 	dev_dbg(fbi->dev, "blank mode=%d\n", mode);
298 
299 	switch (mode) {
300 	case FB_BLANK_POWERDOWN:
301 		reg = inreg(disp, GC_DCM1);
302 		reg &= ~GC_DCM01_DEN;
303 		outreg(disp, GC_DCM1, reg);
304 		break;
305 	case FB_BLANK_UNBLANK:
306 		reg = inreg(disp, GC_DCM1);
307 		reg |= GC_DCM01_DEN;
308 		outreg(disp, GC_DCM1, reg);
309 		break;
310 	case FB_BLANK_NORMAL:
311 	case FB_BLANK_VSYNC_SUSPEND:
312 	case FB_BLANK_HSYNC_SUSPEND:
313 	default:
314 		return 1;
315 	}
316 	return 0;
317 }
318 
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,
330 };
331 
332 /* initialize fb_info data */
mb862xxfb_init_fbinfo(struct fb_info * fbi)333 static int mb862xxfb_init_fbinfo(struct fb_info *fbi)
334 {
335 	struct mb862xxfb_par *par = fbi->par;
336 	struct mb862xx_gc_mode *mode = par->gc_mode;
337 	unsigned long reg;
338 
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;
343 
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;
355 
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;
361 
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;
373 		} else {
374 			reg = inreg(disp, GC_L0M);
375 			if (reg & GC_L0M_L0C_16)
376 				fbi->var.bits_per_pixel = 16;
377 			else
378 				fbi->var.bits_per_pixel = 8;
379 		}
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;
390 	} else if (mode) {
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;
394 	} else {
395 		int ret;
396 
397 		ret = fb_find_mode(&fbi->var, fbi, "640x480-16@60",
398 				   NULL, 0, NULL, 16);
399 		if (ret == 0 || ret == 4) {
400 			dev_err(par->dev,
401 				"failed to get initial mode\n");
402 			return -EINVAL;
403 		}
404 	}
405 
406 	fbi->var.xoffset = 0;
407 	fbi->var.yoffset = 0;
408 	fbi->var.grayscale = 0;
409 	fbi->var.nonstd = 0;
410 	fbi->var.height = -1;
411 	fbi->var.width = -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 |
416 #ifdef __BIG_ENDIAN
417 		     FBINFO_FOREIGN_ENDIAN |
418 #endif
419 		     FBINFO_HWACCEL_XPAN |
420 		     FBINFO_HWACCEL_YPAN;
421 
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");
425 
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;
430 	return 0;
431 }
432 
433 /*
434  * show some display controller and cursor registers
435  */
mb862xxfb_show_dispregs(struct device * dev,struct device_attribute * attr,char * buf)436 static ssize_t mb862xxfb_show_dispregs(struct device *dev,
437 				       struct device_attribute *attr, char *buf)
438 {
439 	struct fb_info *fbi = dev_get_drvdata(dev);
440 	struct mb862xxfb_par *par = fbi->par;
441 	char *ptr = buf;
442 	unsigned int reg;
443 
444 	for (reg = GC_DCM0; reg <= GC_L0DY_L0DX; reg += 4)
445 		ptr += sprintf(ptr, "%08x = %08x\n",
446 			       reg, inreg(disp, reg));
447 
448 	for (reg = GC_CPM_CUTC; reg <= GC_CUY1_CUX1; reg += 4)
449 		ptr += sprintf(ptr, "%08x = %08x\n",
450 			       reg, inreg(disp, reg));
451 
452 	for (reg = GC_DCM1; reg <= GC_L0WH_L0WW; reg += 4)
453 		ptr += sprintf(ptr, "%08x = %08x\n",
454 			       reg, inreg(disp, reg));
455 
456 	return ptr - buf;
457 }
458 
459 static DEVICE_ATTR(dispregs, 0444, mb862xxfb_show_dispregs, NULL);
460 
mb862xx_intr(int irq,void * dev_id)461 irqreturn_t mb862xx_intr(int irq, void *dev_id)
462 {
463 	struct mb862xxfb_par *par = (struct mb862xxfb_par *) dev_id;
464 	unsigned long reg_ist, mask;
465 
466 	if (!par)
467 		return IRQ_NONE;
468 
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);
473 		if (reg_ist == 0)
474 			return IRQ_HANDLED;
475 
476 		reg_ist &= mask;
477 		if (reg_ist == 0)
478 			return IRQ_HANDLED;
479 
480 		/* Clear interrupt status */
481 		outreg(ctrl, 0x0, reg_ist);
482 	} else {
483 		/* Get status */
484 		reg_ist = inreg(host, GC_IST);
485 		mask = inreg(host, GC_IMASK);
486 
487 		reg_ist &= mask;
488 		if (reg_ist == 0)
489 			return IRQ_HANDLED;
490 
491 		/* Clear status */
492 		outreg(host, GC_IST, ~reg_ist);
493 	}
494 	return IRQ_HANDLED;
495 }
496 
497 #if defined(CONFIG_FB_MB862XX_LIME)
498 /*
499  * GDC (Lime, Coral(B/Q), Mint, ...) on host bus
500  */
mb862xx_gdc_init(struct mb862xxfb_par * par)501 static int mb862xx_gdc_init(struct mb862xxfb_par *par)
502 {
503 	unsigned long ccf, mmr;
504 	unsigned long ver, rev;
505 
506 	if (!par)
507 		return -ENODEV;
508 
509 #if defined(CONFIG_FB_PRE_INIT_FB)
510 	par->pre_init = 1;
511 #endif
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;
519 
520 	par->refclk = GC_DISP_REFCLK_400;
521 
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",
526 			 (int)rev & 0xff);
527 		par->type = BT_LIME;
528 		ccf = par->gc_mode ? par->gc_mode->ccf : GC_CCF_COT_100;
529 		mmr = par->gc_mode ? par->gc_mode->mmr : 0x414fb7f2;
530 	} else {
531 		dev_info(par->dev, "? GDC, CID/Rev.: 0x%lx/0x%lx \n", ver, rev);
532 		return -ENODEV;
533 	}
534 
535 	if (!par->pre_init) {
536 		outreg(host, GC_CCF, ccf);
537 		udelay(200);
538 		outreg(host, GC_MMR, mmr);
539 		udelay(10);
540 	}
541 
542 	/* interrupt status */
543 	outreg(host, GC_IST, 0);
544 	outreg(host, GC_IMASK, GC_INT_EN);
545 	return 0;
546 }
547 
of_platform_mb862xx_probe(struct of_device * ofdev,const struct of_device_id * id)548 static int __devinit of_platform_mb862xx_probe(struct of_device *ofdev,
549 					       const struct of_device_id *id)
550 {
551 	struct device_node *np = ofdev->node;
552 	struct device *dev = &ofdev->dev;
553 	struct mb862xxfb_par *par;
554 	struct fb_info *info;
555 	struct resource res;
556 	resource_size_t res_size;
557 	unsigned long ret = -ENODEV;
558 
559 	if (of_address_to_resource(np, 0, &res)) {
560 		dev_err(dev, "Invalid address\n");
561 		return -ENXIO;
562 	}
563 
564 	info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev);
565 	if (info == NULL) {
566 		dev_err(dev, "cannot allocate framebuffer\n");
567 		return -ENOMEM;
568 	}
569 
570 	par = info->par;
571 	par->info = info;
572 	par->dev = dev;
573 
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");
577 		ret = -ENODEV;
578 		goto fbrel;
579 	}
580 
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");
585 		ret = -ENXIO;
586 		goto irqdisp;
587 	}
588 
589 #if defined(CONFIG_LWMON5)
590 	par->gc_mode = &lwmon5_gc_mode;
591 #endif
592 
593 #if defined(CONFIG_SOCRATES)
594 	par->gc_mode = &socrates_gc_mode;
595 #endif
596 
597 	par->fb_base_phys = res.start;
598 	par->mmio_base_phys = res.start + MB862XX_MMIO_BASE;
599 	par->mmio_len = MB862XX_MMIO_SIZE;
600 	if (par->gc_mode)
601 		par->mapped_vram = par->gc_mode->max_vram;
602 	else
603 		par->mapped_vram = MB862XX_MEM_SIZE;
604 
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");
608 		goto rel_reg;
609 	}
610 
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");
614 		goto fb_unmap;
615 	}
616 
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);
621 
622 	if (mb862xx_gdc_init(par))
623 		goto io_unmap;
624 
625 	if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED,
626 			DRV_NAME, (void *)par)) {
627 		dev_err(dev, "Cannot request irq\n");
628 		goto io_unmap;
629 	}
630 
631 	mb862xxfb_init_fbinfo(info);
632 
633 	if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0) < 0) {
634 		dev_err(dev, "Could not allocate cmap for fb_info.\n");
635 		goto free_irq;
636 	}
637 
638 	if ((info->fbops->fb_set_par)(info))
639 		dev_err(dev, "set_var() failed on initial setup?\n");
640 
641 	if (register_framebuffer(info)) {
642 		dev_err(dev, "failed to register framebuffer\n");
643 		goto rel_cmap;
644 	}
645 
646 	dev_set_drvdata(dev, info);
647 
648 	if (device_create_file(dev, &dev_attr_dispregs))
649 		dev_err(dev, "Can't create sysfs regdump file\n");
650 	return 0;
651 
652 rel_cmap:
653 	fb_dealloc_cmap(&info->cmap);
654 free_irq:
655 	outreg(host, GC_IMASK, 0);
656 	free_irq(par->irq, (void *)par);
657 io_unmap:
658 	iounmap(par->mmio_base);
659 fb_unmap:
660 	iounmap(par->fb_base);
661 rel_reg:
662 	release_mem_region(res.start, res_size);
663 irqdisp:
664 	irq_dispose_mapping(par->irq);
665 fbrel:
666 	dev_set_drvdata(dev, NULL);
667 	framebuffer_release(info);
668 	return ret;
669 }
670 
of_platform_mb862xx_remove(struct of_device * ofdev)671 static int __devexit of_platform_mb862xx_remove(struct of_device *ofdev)
672 {
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;
676 	unsigned long reg;
677 
678 	dev_dbg(fbi->dev, "%s release\n", fbi->fix.id);
679 
680 	/* display off */
681 	reg = inreg(disp, GC_DCM1);
682 	reg &= ~(GC_DCM01_DEN | GC_DCM01_L0E);
683 	outreg(disp, GC_DCM1, reg);
684 
685 	/* disable interrupts */
686 	outreg(host, GC_IMASK, 0);
687 
688 	free_irq(par->irq, (void *)par);
689 	irq_dispose_mapping(par->irq);
690 
691 	device_remove_file(&ofdev->dev, &dev_attr_dispregs);
692 
693 	unregister_framebuffer(fbi);
694 	fb_dealloc_cmap(&fbi->cmap);
695 
696 	iounmap(par->mmio_base);
697 	iounmap(par->fb_base);
698 
699 	dev_set_drvdata(&ofdev->dev, NULL);
700 	release_mem_region(par->res->start, res_size);
701 	framebuffer_release(fbi);
702 	return 0;
703 }
704 
705 /*
706  * common types
707  */
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", },
716 	{ /* end */ }
717 };
718 
719 static struct of_platform_driver of_platform_mb862xxfb_driver = {
720 	.owner		= THIS_MODULE,
721 	.name		= DRV_NAME,
722 	.match_table	= of_platform_mb862xx_tbl,
723 	.probe		= of_platform_mb862xx_probe,
724 	.remove		= __devexit_p(of_platform_mb862xx_remove),
725 };
726 #endif
727 
728 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
coralp_init(struct mb862xxfb_par * par)729 static int coralp_init(struct mb862xxfb_par *par)
730 {
731 	int cn, ver;
732 
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;
740 
741 	par->refclk = GC_DISP_REFCLK_400;
742 
743 	ver = inreg(host, GC_CID);
744 	cn = (ver & GC_CID_CNAME_MSK) >> 8;
745 	ver = ver & GC_CID_VERSION_MSK;
746 	if (cn == 3) {
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);
751 		udelay(200);
752 		outreg(host, GC_MMR, GC_MMR_CORALP_EVB_VAL);
753 		udelay(10);
754 		/* Clear interrupt status */
755 		outreg(host, GC_IST, 0);
756 	} else {
757 		return -ENODEV;
758 	}
759 	return 0;
760 }
761 
init_dram_ctrl(struct mb862xxfb_par * par)762 static int init_dram_ctrl(struct mb862xxfb_par *par)
763 {
764 	unsigned long i = 0;
765 
766 	/*
767 	 * Set io mode first! Spec. says IC may be destroyed
768 	 * if not set to SSTL2/LVCMOS before init.
769 	 */
770 	outreg(dram_ctrl, GC_DCTL_IOCONT1_IOCONT0, GC_EVB_DCTL_IOCONT1_IOCONT0);
771 
772 	/* DRAM init */
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);
780 
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");
786 			return -EINVAL;
787 		}
788 	}
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);
791 	return 0;
792 }
793 
carmine_init(struct mb862xxfb_par * par)794 static int carmine_init(struct mb862xxfb_par *par)
795 {
796 	unsigned long reg;
797 
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;
807 
808 	par->refclk = GC_DISP_REFCLK_533;
809 
810 	/* warm up */
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);
813 
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);
818 	else
819 		goto err_init;
820 
821 	reg &= ~GC_CTRL_CLK_EN_2D3D;
822 	outreg(ctrl, GC_CTRL_CLK_ENABLE, reg);
823 
824 	/* set up vram */
825 	if (init_dram_ctrl(par) < 0)
826 		goto err_init;
827 
828 	outreg(ctrl, GC_CTRL_INT_MASK, 0);
829 	return 0;
830 
831 err_init:
832 	outreg(ctrl, GC_CTRL_CLK_ENABLE, 0);
833 	return -EINVAL;
834 }
835 
mb862xx_pci_gdc_init(struct mb862xxfb_par * par)836 static inline int mb862xx_pci_gdc_init(struct mb862xxfb_par *par)
837 {
838 	switch (par->type) {
839 	case BT_CORALP:
840 		return coralp_init(par);
841 	case BT_CARMINE:
842 		return carmine_init(par);
843 	default:
844 		return -ENODEV;
845 	}
846 }
847 
848 #define CHIP_ID(id)	\
849 	{ PCI_DEVICE(PCI_VENDOR_ID_FUJITSU_LIMITED, id) }
850 
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),
855 	/* MB86297 */
856 	CHIP_ID(PCI_DEVICE_ID_FUJITSU_CARMINE),
857 	{ 0, }
858 };
859 
860 MODULE_DEVICE_TABLE(pci, mb862xx_pci_tbl);
861 
mb862xx_pci_probe(struct pci_dev * pdev,const struct pci_device_id * ent)862 static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,
863 				       const struct pci_device_id *ent)
864 {
865 	struct mb862xxfb_par *par;
866 	struct fb_info *info;
867 	struct device *dev = &pdev->dev;
868 	int ret;
869 
870 	ret = pci_enable_device(pdev);
871 	if (ret < 0) {
872 		dev_err(dev, "Cannot enable PCI device\n");
873 		goto out;
874 	}
875 
876 	info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev);
877 	if (!info) {
878 		dev_err(dev, "framebuffer alloc failed\n");
879 		ret = -ENOMEM;
880 		goto dis_dev;
881 	}
882 
883 	par = info->par;
884 	par->info = info;
885 	par->dev = dev;
886 	par->pdev = pdev;
887 	par->irq = pdev->irq;
888 
889 	ret = pci_request_regions(pdev, DRV_NAME);
890 	if (ret < 0) {
891 		dev_err(dev, "Cannot reserve region(s) for PCI device\n");
892 		goto rel_fb;
893 	}
894 
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;
903 		break;
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;
910 		break;
911 	default:
912 		/* should never occur */
913 		goto rel_reg;
914 	}
915 
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");
919 		goto rel_reg;
920 	}
921 
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");
925 		ret = -EIO;
926 		goto fb_unmap;
927 	}
928 
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);
933 
934 	if (mb862xx_pci_gdc_init(par))
935 		goto io_unmap;
936 
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");
940 		goto io_unmap;
941 	}
942 
943 	mb862xxfb_init_fbinfo(info);
944 
945 	if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0) < 0) {
946 		dev_err(dev, "Could not allocate cmap for fb_info.\n");
947 		ret = -ENOMEM;
948 		goto free_irq;
949 	}
950 
951 	if ((info->fbops->fb_set_par)(info))
952 		dev_err(dev, "set_var() failed on initial setup?\n");
953 
954 	ret = register_framebuffer(info);
955 	if (ret < 0) {
956 		dev_err(dev, "failed to register framebuffer\n");
957 		goto rel_cmap;
958 	}
959 
960 	pci_set_drvdata(pdev, info);
961 
962 	if (device_create_file(dev, &dev_attr_dispregs))
963 		dev_err(dev, "Can't create sysfs regdump file\n");
964 
965 	if (par->type == BT_CARMINE)
966 		outreg(ctrl, GC_CTRL_INT_MASK, GC_CARMINE_INT_EN);
967 	else
968 		outreg(host, GC_IMASK, GC_INT_EN);
969 
970 	return 0;
971 
972 rel_cmap:
973 	fb_dealloc_cmap(&info->cmap);
974 free_irq:
975 	free_irq(par->irq, (void *)par);
976 io_unmap:
977 	iounmap(par->mmio_base);
978 fb_unmap:
979 	iounmap(par->fb_base);
980 rel_reg:
981 	pci_release_regions(pdev);
982 rel_fb:
983 	framebuffer_release(info);
984 dis_dev:
985 	pci_disable_device(pdev);
986 out:
987 	return ret;
988 }
989 
mb862xx_pci_remove(struct pci_dev * pdev)990 static void __devexit mb862xx_pci_remove(struct pci_dev *pdev)
991 {
992 	struct fb_info *fbi = pci_get_drvdata(pdev);
993 	struct mb862xxfb_par *par = fbi->par;
994 	unsigned long reg;
995 
996 	dev_dbg(fbi->dev, "%s release\n", fbi->fix.id);
997 
998 	/* display off */
999 	reg = inreg(disp, GC_DCM1);
1000 	reg &= ~(GC_DCM01_DEN | GC_DCM01_L0E);
1001 	outreg(disp, GC_DCM1, reg);
1002 
1003 	if (par->type == BT_CARMINE) {
1004 		outreg(ctrl, GC_CTRL_INT_MASK, 0);
1005 		outreg(ctrl, GC_CTRL_CLK_ENABLE, 0);
1006 	} else {
1007 		outreg(host, GC_IMASK, 0);
1008 	}
1009 
1010 	device_remove_file(&pdev->dev, &dev_attr_dispregs);
1011 
1012 	pci_set_drvdata(pdev, NULL);
1013 	unregister_framebuffer(fbi);
1014 	fb_dealloc_cmap(&fbi->cmap);
1015 
1016 	free_irq(par->irq, (void *)par);
1017 	iounmap(par->mmio_base);
1018 	iounmap(par->fb_base);
1019 
1020 	pci_release_regions(pdev);
1021 	framebuffer_release(fbi);
1022 	pci_disable_device(pdev);
1023 }
1024 
1025 static struct pci_driver mb862xxfb_pci_driver = {
1026 	.name		= DRV_NAME,
1027 	.id_table	= mb862xx_pci_tbl,
1028 	.probe		= mb862xx_pci_probe,
1029 	.remove		= __devexit_p(mb862xx_pci_remove),
1030 };
1031 #endif
1032 
mb862xxfb_init(void)1033 static int __devinit mb862xxfb_init(void)
1034 {
1035 	int ret = -ENODEV;
1036 
1037 #if defined(CONFIG_FB_MB862XX_LIME)
1038 	ret = of_register_platform_driver(&of_platform_mb862xxfb_driver);
1039 #endif
1040 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
1041 	ret = pci_register_driver(&mb862xxfb_pci_driver);
1042 #endif
1043 	return ret;
1044 }
1045 
mb862xxfb_exit(void)1046 static void __exit mb862xxfb_exit(void)
1047 {
1048 #if defined(CONFIG_FB_MB862XX_LIME)
1049 	of_unregister_platform_driver(&of_platform_mb862xxfb_driver);
1050 #endif
1051 #if defined(CONFIG_FB_MB862XX_PCI_GDC)
1052 	pci_unregister_driver(&mb862xxfb_pci_driver);
1053 #endif
1054 }
1055 
1056 module_init(mb862xxfb_init);
1057 module_exit(mb862xxfb_exit);
1058 
1059 MODULE_DESCRIPTION("Fujitsu MB862xx Framebuffer driver");
1060 MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
1061 MODULE_LICENSE("GPL v2");
1062