imxfb.c 25.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 *  Freescale i.MX Frame Buffer device driver
 *
 *  Copyright (C) 2004 Sascha Hauer, Pengutronix
 *   Based on acornfb.c Copyright (C) Russell King.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive for
 * more details.
 *
 * Please direct your questions and comments on this driver to the following
 * email address:
 *
 *	linux-arm-kernel@lists.arm.linux.org.uk
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
23
#include <linux/mm.h>
24 25 26 27 28
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/cpufreq.h>
S
Sascha Hauer 已提交
29
#include <linux/clk.h>
30
#include <linux/platform_device.h>
31
#include <linux/dma-mapping.h>
32
#include <linux/io.h>
33
#include <linux/lcd.h>
S
Sascha Hauer 已提交
34
#include <linux/math64.h>
M
Markus Pargmann 已提交
35 36 37
#include <linux/of.h>
#include <linux/of_device.h>

38 39
#include <linux/regulator/consumer.h>

M
Markus Pargmann 已提交
40 41 42
#include <video/of_display_timing.h>
#include <video/of_videomode.h>
#include <video/videomode.h>
43

44 45 46 47 48 49 50 51 52 53 54 55
#define PCR_TFT		(1 << 31)
#define PCR_BPIX_8	(3 << 25)
#define PCR_BPIX_12	(4 << 25)
#define PCR_BPIX_16	(5 << 25)
#define PCR_BPIX_18	(6 << 25)

struct imx_fb_videomode {
	struct fb_videomode mode;
	u32 pcr;
	bool aus_mode;
	unsigned char	bpp;
};
56 57 58 59 60 61

/*
 * Complain if VAR is out of range.
 */
#define DEBUG_VAR 1

62 63 64 65 66 67
#define DRIVER_NAME "imx-fb"

#define LCDC_SSA	0x00

#define LCDC_SIZE	0x04
#define SIZE_XMAX(x)	((((x) >> 4) & 0x3f) << 20)
S
Sascha Hauer 已提交
68

69 70
#define YMAX_MASK_IMX1	0x1ff
#define YMAX_MASK_IMX21	0x3ff
71 72 73 74 75 76 77 78 79

#define LCDC_VPW	0x08
#define VPW_VPW(x)	((x) & 0x3ff)

#define LCDC_CPOS	0x0C
#define CPOS_CC1	(1<<31)
#define CPOS_CC0	(1<<30)
#define CPOS_OP		(1<<28)
#define CPOS_CXP(x)	(((x) & 3ff) << 16)
S
Sascha Hauer 已提交
80

81 82 83 84 85 86 87
#define LCDC_LCWHB	0x10
#define LCWHB_BK_EN	(1<<31)
#define LCWHB_CW(w)	(((w) & 0x1f) << 24)
#define LCWHB_CH(h)	(((h) & 0x1f) << 16)
#define LCWHB_BD(x)	((x) & 0xff)

#define LCDC_LCHCC	0x14
S
Sascha Hauer 已提交
88

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
#define LCDC_PCR	0x18

#define LCDC_HCR	0x1C
#define HCR_H_WIDTH(x)	(((x) & 0x3f) << 26)
#define HCR_H_WAIT_1(x)	(((x) & 0xff) << 8)
#define HCR_H_WAIT_2(x)	((x) & 0xff)

#define LCDC_VCR	0x20
#define VCR_V_WIDTH(x)	(((x) & 0x3f) << 26)
#define VCR_V_WAIT_1(x)	(((x) & 0xff) << 8)
#define VCR_V_WAIT_2(x)	((x) & 0xff)

#define LCDC_POS	0x24
#define POS_POS(x)	((x) & 1f)

#define LCDC_LSCR1	0x28
/* bit fields in imxfb.h */

#define LCDC_PWMR	0x2C
/* bit fields in imxfb.h */

#define LCDC_DMACR	0x30
/* bit fields in imxfb.h */

#define LCDC_RMCR	0x34
S
Sascha Hauer 已提交
114

115
#define RMCR_LCDC_EN_MX1	(1<<1)
S
Sascha Hauer 已提交
116

117 118 119 120 121 122 123 124 125 126 127 128
#define RMCR_SELF_REF	(1<<0)

#define LCDC_LCDICR	0x38
#define LCDICR_INT_SYN	(1<<2)
#define LCDICR_INT_CON	(1)

#define LCDC_LCDISR	0x40
#define LCDISR_UDR_ERR	(1<<3)
#define LCDISR_ERR_RES	(1<<2)
#define LCDISR_EOF	(1<<1)
#define LCDISR_BOF	(1<<0)

M
Markus Pargmann 已提交
129 130
#define IMXFB_LSCR1_DEFAULT 0x00120300

131 132 133
#define LCDC_LAUSCR	0x80
#define LAUSCR_AUS_MODE	(1<<31)

134 135 136
/* Used fb-mode. Can be set on kernel command line, therefore file-static. */
static const char *fb_mode;

137 138 139 140 141 142 143 144 145 146 147
/*
 * These are the bitfields for each
 * display depth that we support.
 */
struct imxfb_rgb {
	struct fb_bitfield	red;
	struct fb_bitfield	green;
	struct fb_bitfield	blue;
	struct fb_bitfield	transp;
};

148 149 150 151 152
enum imxfb_type {
	IMX1_FB,
	IMX21_FB,
};

153 154 155
struct imxfb_info {
	struct platform_device  *pdev;
	void __iomem		*regs;
156 157 158
	struct clk		*clk_ipg;
	struct clk		*clk_ahb;
	struct clk		*clk_per;
159
	enum imxfb_type		devtype;
160
	bool			enabled;
161 162 163 164 165 166 167 168 169 170 171 172 173 174

	/*
	 * These are the addresses we mapped
	 * the framebuffer memory region to.
	 */
	dma_addr_t		map_dma;
	u_int			map_size;

	u_int			palette_size;

	dma_addr_t		dbar1;
	dma_addr_t		dbar2;

	u_int			pcr;
175
	u_int			lauscr;
176 177 178
	u_int			pwmr;
	u_int			lscr1;
	u_int			dmacr;
179 180
	bool			cmap_inverse;
	bool			cmap_static;
181

182 183 184
	struct imx_fb_videomode *mode;
	int			num_modes;

185
	struct regulator	*lcd_pwr;
186
	int			lcd_pwr_enabled;
187 188
};

189
static const struct platform_device_id imxfb_devtype[] = {
190 191 192 193 194 195 196 197 198 199 200 201
	{
		.name = "imx1-fb",
		.driver_data = IMX1_FB,
	}, {
		.name = "imx21-fb",
		.driver_data = IMX21_FB,
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(platform, imxfb_devtype);

202
static const struct of_device_id imxfb_of_dev_id[] = {
M
Markus Pargmann 已提交
203 204 205 206 207 208 209 210 211 212 213 214
	{
		.compatible = "fsl,imx1-fb",
		.data = &imxfb_devtype[IMX1_FB],
	}, {
		.compatible = "fsl,imx21-fb",
		.data = &imxfb_devtype[IMX21_FB],
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(of, imxfb_of_dev_id);

215 216 217 218 219
static inline int is_imx1_fb(struct imxfb_info *fbi)
{
	return fbi->devtype == IMX1_FB;
}

220 221 222 223 224 225 226 227
#define IMX_NAME	"IMX"

/*
 * Minimum X and Y resolutions
 */
#define MIN_XRES	64
#define MIN_YRES	64

S
Sascha Hauer 已提交
228 229 230 231 232 233 234 235 236 237 238
/* Actually this really is 18bit support, the lowest 2 bits of each colour
 * are unused in hardware. We claim to have 24bit support to make software
 * like X work, which does not support 18bit.
 */
static struct imxfb_rgb def_rgb_18 = {
	.red	= {.offset = 16, .length = 8,},
	.green	= {.offset = 8, .length = 8,},
	.blue	= {.offset = 0, .length = 8,},
	.transp = {.offset = 0, .length = 0,},
};

S
Sascha Hauer 已提交
239 240 241 242 243 244 245 246
static struct imxfb_rgb def_rgb_16_tft = {
	.red	= {.offset = 11, .length = 5,},
	.green	= {.offset = 5, .length = 6,},
	.blue	= {.offset = 0, .length = 5,},
	.transp = {.offset = 0, .length = 0,},
};

static struct imxfb_rgb def_rgb_16_stn = {
247 248 249 250
	.red	= {.offset = 8, .length = 4,},
	.green	= {.offset = 4, .length = 4,},
	.blue	= {.offset = 0, .length = 4,},
	.transp = {.offset = 0, .length = 0,},
251 252 253
};

static struct imxfb_rgb def_rgb_8 = {
254 255 256 257
	.red	= {.offset = 0, .length = 8,},
	.green	= {.offset = 0, .length = 8,},
	.blue	= {.offset = 0, .length = 8,},
	.transp = {.offset = 0, .length = 0,},
258 259
};

260 261
static int imxfb_activate_var(struct fb_var_screeninfo *var,
		struct fb_info *info);
262 263 264 265 266 267 268 269

static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
{
	chan &= 0xffff;
	chan >>= 16 - bf->length;
	return chan << bf->offset;
}

270 271
static int imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
		u_int trans, struct fb_info *info)
272 273 274 275 276 277 278 279 280 281
{
	struct imxfb_info *fbi = info->par;
	u_int val, ret = 1;

#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
	if (regno < fbi->palette_size) {
		val = (CNVT_TOHW(red, 4) << 8) |
		      (CNVT_TOHW(green,4) << 4) |
		      CNVT_TOHW(blue,  4);

282
		writel(val, fbi->regs + 0x800 + (regno << 2));
283 284 285 286 287
		ret = 0;
	}
	return ret;
}

288
static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
		   u_int trans, struct fb_info *info)
{
	struct imxfb_info *fbi = info->par;
	unsigned int val;
	int ret = 1;

	/*
	 * If inverse mode was selected, invert all the colours
	 * rather than the register number.  The register number
	 * is what you poke into the framebuffer to produce the
	 * colour you requested.
	 */
	if (fbi->cmap_inverse) {
		red   = 0xffff - red;
		green = 0xffff - green;
		blue  = 0xffff - blue;
	}

	/*
	 * If greyscale is true, then we convert the RGB value
	 * to greyscale no mater what visual we are using.
	 */
	if (info->var.grayscale)
		red = green = blue = (19595 * red + 38470 * green +
					7471 * blue) >> 16;

	switch (info->fix.visual) {
	case FB_VISUAL_TRUECOLOR:
		/*
		 * 12 or 16-bit True Colour.  We encode the RGB value
		 * according to the RGB bitfield information.
		 */
		if (regno < 16) {
			u32 *pal = info->pseudo_palette;

			val  = chan_to_field(red, &info->var.red);
			val |= chan_to_field(green, &info->var.green);
			val |= chan_to_field(blue, &info->var.blue);

			pal[regno] = val;
			ret = 0;
		}
		break;

	case FB_VISUAL_STATIC_PSEUDOCOLOR:
	case FB_VISUAL_PSEUDOCOLOR:
		ret = imxfb_setpalettereg(regno, red, green, blue, trans, info);
		break;
	}

	return ret;
}

342 343 344 345 346
static const struct imx_fb_videomode *imxfb_find_mode(struct imxfb_info *fbi)
{
	struct imx_fb_videomode *m;
	int i;

M
Markus Pargmann 已提交
347 348 349
	if (!fb_mode)
		return &fbi->mode[0];

350 351 352 353 354 355 356
	for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) {
		if (!strcmp(m->mode.name, fb_mode))
			return m;
	}
	return NULL;
}

357 358 359 360 361 362
/*
 *  imxfb_check_var():
 *    Round up in the following order: bits_per_pixel, xres,
 *    yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
 *    bitfields, horizontal timing, vertical timing.
 */
363
static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
364 365
{
	struct imxfb_info *fbi = info->par;
S
Sascha Hauer 已提交
366
	struct imxfb_rgb *rgb;
367 368 369 370
	const struct imx_fb_videomode *imxfb_mode;
	unsigned long lcd_clk;
	unsigned long long tmp;
	u32 pcr = 0;
371 372 373 374 375

	if (var->xres < MIN_XRES)
		var->xres = MIN_XRES;
	if (var->yres < MIN_YRES)
		var->yres = MIN_YRES;
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393

	imxfb_mode = imxfb_find_mode(fbi);
	if (!imxfb_mode)
		return -EINVAL;

	var->xres		= imxfb_mode->mode.xres;
	var->yres		= imxfb_mode->mode.yres;
	var->bits_per_pixel	= imxfb_mode->bpp;
	var->pixclock		= imxfb_mode->mode.pixclock;
	var->hsync_len		= imxfb_mode->mode.hsync_len;
	var->left_margin	= imxfb_mode->mode.left_margin;
	var->right_margin	= imxfb_mode->mode.right_margin;
	var->vsync_len		= imxfb_mode->mode.vsync_len;
	var->upper_margin	= imxfb_mode->mode.upper_margin;
	var->lower_margin	= imxfb_mode->mode.lower_margin;
	var->sync		= imxfb_mode->mode.sync;
	var->xres_virtual	= max(var->xres_virtual, var->xres);
	var->yres_virtual	= max(var->yres_virtual, var->yres);
394 395

	pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
396

397
	lcd_clk = clk_get_rate(fbi->clk_per);
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413

	tmp = var->pixclock * (unsigned long long)lcd_clk;

	do_div(tmp, 1000000);

	if (do_div(tmp, 1000000) > 500000)
		tmp++;

	pcr = (unsigned int)tmp;

	if (--pcr > 0x3F) {
		pcr = 0x3F;
		printk(KERN_WARNING "Must limit pixel clock to %luHz\n",
				lcd_clk / pcr);
	}

414
	switch (var->bits_per_pixel) {
S
Sascha Hauer 已提交
415
	case 32:
416
		pcr |= PCR_BPIX_18;
S
Sascha Hauer 已提交
417 418
		rgb = &def_rgb_18;
		break;
419
	case 16:
S
Sascha Hauer 已提交
420
	default:
421
		if (is_imx1_fb(fbi))
422 423 424 425 426
			pcr |= PCR_BPIX_12;
		else
			pcr |= PCR_BPIX_16;

		if (imxfb_mode->pcr & PCR_TFT)
S
Sascha Hauer 已提交
427 428 429
			rgb = &def_rgb_16_tft;
		else
			rgb = &def_rgb_16_stn;
430 431
		break;
	case 8:
432
		pcr |= PCR_BPIX_8;
S
Sascha Hauer 已提交
433
		rgb = &def_rgb_8;
434 435 436
		break;
	}

437 438 439 440
	/* add sync polarities */
	pcr |= imxfb_mode->pcr & ~(0x3f | (7 << 25));

	fbi->pcr = pcr;
441 442 443 444 445
	/*
	 * The LCDC AUS Mode Control Register does not exist on imx1.
	 */
	if (!is_imx1_fb(fbi) && imxfb_mode->aus_mode)
		fbi->lauscr = LAUSCR_AUS_MODE;
446

447 448 449 450
	/*
	 * Copy the RGB parameters for this display
	 * from the machine specific parameters.
	 */
S
Sascha Hauer 已提交
451 452 453 454
	var->red    = rgb->red;
	var->green  = rgb->green;
	var->blue   = rgb->blue;
	var->transp = rgb->transp;
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475

	pr_debug("RGBT length = %d:%d:%d:%d\n",
		var->red.length, var->green.length, var->blue.length,
		var->transp.length);

	pr_debug("RGBT offset = %d:%d:%d:%d\n",
		var->red.offset, var->green.offset, var->blue.offset,
		var->transp.offset);

	return 0;
}

/*
 * imxfb_set_par():
 *	Set the user defined part of the display for the specified console
 */
static int imxfb_set_par(struct fb_info *info)
{
	struct imxfb_info *fbi = info->par;
	struct fb_var_screeninfo *var = &info->var;

S
Sascha Hauer 已提交
476
	if (var->bits_per_pixel == 16 || var->bits_per_pixel == 32)
477 478 479 480 481 482 483 484 485 486 487 488
		info->fix.visual = FB_VISUAL_TRUECOLOR;
	else if (!fbi->cmap_static)
		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
	else {
		/*
		 * Some people have weird ideas about wanting static
		 * pseudocolor maps.  I suspect their user space
		 * applications are broken.
		 */
		info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
	}

489
	info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
490 491 492 493 494 495 496
	fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;

	imxfb_activate_var(var, info);

	return 0;
}

497
static int imxfb_enable_controller(struct imxfb_info *fbi)
498
{
499
	int ret;
500 501

	if (fbi->enabled)
502
		return 0;
503

504 505
	pr_debug("Enabling LCD controller\n");

506
	writel(fbi->map_dma, fbi->regs + LCDC_SSA);
507

508 509
	/* panning offset 0 (0 pixel offset)        */
	writel(0x00000000, fbi->regs + LCDC_POS);
510 511

	/* disable hardware cursor */
512 513
	writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1),
		fbi->regs + LCDC_CPOS);
514

515 516 517 518 519
	/*
	 * RMCR_LCDC_EN_MX1 is present on i.MX1 only, but doesn't hurt
	 * on other SoCs
	 */
	writel(RMCR_LCDC_EN_MX1, fbi->regs + LCDC_RMCR);
520

521 522 523 524 525 526 527 528 529 530 531 532
	ret = clk_prepare_enable(fbi->clk_ipg);
	if (ret)
		goto err_enable_ipg;

	ret = clk_prepare_enable(fbi->clk_ahb);
	if (ret)
		goto err_enable_ahb;

	ret = clk_prepare_enable(fbi->clk_per);
	if (ret)
		goto err_enable_per;

533
	fbi->enabled = true;
534 535 536 537 538 539 540 541 542 543
	return 0;

err_enable_per:
	clk_disable_unprepare(fbi->clk_ahb);
err_enable_ahb:
	clk_disable_unprepare(fbi->clk_ipg);
err_enable_ipg:
	writel(0, fbi->regs + LCDC_RMCR);

	return ret;
544 545 546 547
}

static void imxfb_disable_controller(struct imxfb_info *fbi)
{
548 549 550
	if (!fbi->enabled)
		return;

551 552
	pr_debug("Disabling LCD controller\n");

553 554
	clk_disable_unprepare(fbi->clk_per);
	clk_disable_unprepare(fbi->clk_ahb);
555
	clk_disable_unprepare(fbi->clk_ipg);
556
	fbi->enabled = false;
S
Sascha Hauer 已提交
557

558
	writel(0, fbi->regs + LCDC_RMCR);
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575
}

static int imxfb_blank(int blank, struct fb_info *info)
{
	struct imxfb_info *fbi = info->par;

	pr_debug("imxfb_blank: blank=%d\n", blank);

	switch (blank) {
	case FB_BLANK_POWERDOWN:
	case FB_BLANK_VSYNC_SUSPEND:
	case FB_BLANK_HSYNC_SUSPEND:
	case FB_BLANK_NORMAL:
		imxfb_disable_controller(fbi);
		break;

	case FB_BLANK_UNBLANK:
576
		return imxfb_enable_controller(fbi);
577 578 579 580
	}
	return 0;
}

581
static const struct fb_ops imxfb_ops = {
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
	.owner		= THIS_MODULE,
	.fb_check_var	= imxfb_check_var,
	.fb_set_par	= imxfb_set_par,
	.fb_setcolreg	= imxfb_setcolreg,
	.fb_fillrect	= cfb_fillrect,
	.fb_copyarea	= cfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
	.fb_blank	= imxfb_blank,
};

/*
 * imxfb_activate_var():
 *	Configures LCD Controller based on entries in var parameter.  Settings are
 *	only written to the controller if changes were made.
 */
static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
	struct imxfb_info *fbi = info->par;
600
	u32 ymax_mask = is_imx1_fb(fbi) ? YMAX_MASK_IMX1 : YMAX_MASK_IMX21;
S
Sascha Hauer 已提交
601

602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
	pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
		var->xres, var->hsync_len,
		var->left_margin, var->right_margin);
	pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n",
		var->yres, var->vsync_len,
		var->upper_margin, var->lower_margin);

#if DEBUG_VAR
	if (var->xres < 16        || var->xres > 1024)
		printk(KERN_ERR "%s: invalid xres %d\n",
			info->fix.id, var->xres);
	if (var->hsync_len < 1    || var->hsync_len > 64)
		printk(KERN_ERR "%s: invalid hsync_len %d\n",
			info->fix.id, var->hsync_len);
	if (var->left_margin > 255)
		printk(KERN_ERR "%s: invalid left_margin %d\n",
			info->fix.id, var->left_margin);
	if (var->right_margin > 255)
		printk(KERN_ERR "%s: invalid right_margin %d\n",
			info->fix.id, var->right_margin);
622
	if (var->yres < 1 || var->yres > ymax_mask)
623 624 625 626 627 628 629 630 631 632 633 634 635
		printk(KERN_ERR "%s: invalid yres %d\n",
			info->fix.id, var->yres);
	if (var->vsync_len > 100)
		printk(KERN_ERR "%s: invalid vsync_len %d\n",
			info->fix.id, var->vsync_len);
	if (var->upper_margin > 63)
		printk(KERN_ERR "%s: invalid upper_margin %d\n",
			info->fix.id, var->upper_margin);
	if (var->lower_margin > 255)
		printk(KERN_ERR "%s: invalid lower_margin %d\n",
			info->fix.id, var->lower_margin);
#endif

636 637 638 639
	/* physical screen start address	    */
	writel(VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4),
		fbi->regs + LCDC_VPW);

S
Sascha Hauer 已提交
640 641 642
	writel(HCR_H_WIDTH(var->hsync_len - 1) |
		HCR_H_WAIT_1(var->right_margin - 1) |
		HCR_H_WAIT_2(var->left_margin - 3),
643
		fbi->regs + LCDC_HCR);
644

645
	writel(VCR_V_WIDTH(var->vsync_len) |
S
Sascha Hauer 已提交
646 647
		VCR_V_WAIT_1(var->lower_margin) |
		VCR_V_WAIT_2(var->upper_margin),
648
		fbi->regs + LCDC_VCR);
649

650
	writel(SIZE_XMAX(var->xres) | (var->yres & ymax_mask),
651
			fbi->regs + LCDC_SIZE);
S
Sascha Hauer 已提交
652

653
	writel(fbi->pcr, fbi->regs + LCDC_PCR);
M
Markus Pargmann 已提交
654 655
	if (fbi->pwmr)
		writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
656
	writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
M
Markus Pargmann 已提交
657 658 659 660

	/* dmacr = 0 is no valid value, as we need DMA control marks. */
	if (fbi->dmacr)
		writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
661

662 663 664
	if (fbi->lauscr)
		writel(fbi->lauscr, fbi->regs + LCDC_LAUSCR);

665 666 667
	return 0;
}

M
Markus Pargmann 已提交
668
static int imxfb_init_fbinfo(struct platform_device *pdev)
669
{
670
	struct fb_info *info = platform_get_drvdata(pdev);
671
	struct imxfb_info *fbi = info->par;
M
Markus Pargmann 已提交
672
	struct device_node *np;
673

674
	pr_debug("%s\n",__func__);
675

676
	info->pseudo_palette = kmalloc_array(16, sizeof(u32), GFP_KERNEL);
677 678 679 680 681
	if (!info->pseudo_palette)
		return -ENOMEM;

	memset(fbi, 0, sizeof(struct imxfb_info));

682 683
	fbi->devtype = pdev->id_entry->driver_data;

684
	strscpy(info->fix.id, IMX_NAME, sizeof(info->fix.id));
685

686
	info->fix.type			= FB_TYPE_PACKED_PIXELS;
687 688 689 690
	info->fix.type_aux		= 0;
	info->fix.xpanstep		= 0;
	info->fix.ypanstep		= 0;
	info->fix.ywrapstep		= 0;
691
	info->fix.accel			= FB_ACCEL_NONE;
692 693 694 695 696 697

	info->var.nonstd		= 0;
	info->var.activate		= FB_ACTIVATE_NOW;
	info->var.height		= -1;
	info->var.width	= -1;
	info->var.accel_flags		= 0;
698
	info->var.vmode			= FB_VMODE_NONINTERLACED;
699 700

	info->fbops			= &imxfb_ops;
701 702
	info->flags			= FBINFO_FLAG_DEFAULT |
					  FBINFO_READS_FAST;
M
Markus Pargmann 已提交
703

704 705 706 707 708
	np = pdev->dev.of_node;
	info->var.grayscale = of_property_read_bool(np,
					"cmap-greyscale");
	fbi->cmap_inverse = of_property_read_bool(np, "cmap-inverse");
	fbi->cmap_static = of_property_read_bool(np, "cmap-static");
709

710
	fbi->lscr1 = IMXFB_LSCR1_DEFAULT;
711

712
	of_property_read_u32(np, "fsl,lpccr", &fbi->pwmr);
M
Markus Pargmann 已提交
713

714 715 716
	of_property_read_u32(np, "fsl,lscr1", &fbi->lscr1);

	of_property_read_u32(np, "fsl,dmacr", &fbi->dmacr);
M
Markus Pargmann 已提交
717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753

	return 0;
}

static int imxfb_of_read_mode(struct device *dev, struct device_node *np,
		struct imx_fb_videomode *imxfb_mode)
{
	int ret;
	struct fb_videomode *of_mode = &imxfb_mode->mode;
	u32 bpp;
	u32 pcr;

	ret = of_property_read_string(np, "model", &of_mode->name);
	if (ret)
		of_mode->name = NULL;

	ret = of_get_fb_videomode(np, of_mode, OF_USE_NATIVE_MODE);
	if (ret) {
		dev_err(dev, "Failed to get videomode from DT\n");
		return ret;
	}

	ret = of_property_read_u32(np, "bits-per-pixel", &bpp);
	ret |= of_property_read_u32(np, "fsl,pcr", &pcr);

	if (ret) {
		dev_err(dev, "Failed to read bpp and pcr from DT\n");
		return -EINVAL;
	}

	if (bpp < 1 || bpp > 255) {
		dev_err(dev, "Bits per pixel have to be between 1 and 255\n");
		return -EINVAL;
	}

	imxfb_mode->bpp = bpp;
	imxfb_mode->pcr = pcr;
754

755 756 757 758 759
	/*
	 * fsl,aus-mode is optional
	 */
	imxfb_mode->aus_mode = of_property_read_bool(np, "fsl,aus-mode");

760 761 762
	return 0;
}

763 764 765 766 767 768 769 770 771 772
static int imxfb_lcd_check_fb(struct lcd_device *lcddev, struct fb_info *fi)
{
	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);

	if (!fi || fi->par == fbi)
		return 1;

	return 0;
}

773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
static int imxfb_lcd_get_contrast(struct lcd_device *lcddev)
{
	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);

	return fbi->pwmr & 0xff;
}

static int imxfb_lcd_set_contrast(struct lcd_device *lcddev, int contrast)
{
	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);

	if (fbi->pwmr && fbi->enabled) {
		if (contrast > 255)
			contrast = 255;
		else if (contrast < 0)
			contrast = 0;

		fbi->pwmr &= ~0xff;
		fbi->pwmr |= contrast;

		writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
	}

	return 0;
}

799 800 801 802
static int imxfb_lcd_get_power(struct lcd_device *lcddev)
{
	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);

803 804 805
	if (!IS_ERR(fbi->lcd_pwr) &&
	    !regulator_is_enabled(fbi->lcd_pwr))
		return FB_BLANK_POWERDOWN;
806

807
	return FB_BLANK_UNBLANK;
808 809
}

810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827
static int imxfb_regulator_set(struct imxfb_info *fbi, int enable)
{
	int ret;

	if (enable == fbi->lcd_pwr_enabled)
		return 0;

	if (enable)
		ret = regulator_enable(fbi->lcd_pwr);
	else
		ret = regulator_disable(fbi->lcd_pwr);

	if (ret == 0)
		fbi->lcd_pwr_enabled = enable;

	return ret;
}

828 829 830 831
static int imxfb_lcd_set_power(struct lcd_device *lcddev, int power)
{
	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);

832 833
	if (!IS_ERR(fbi->lcd_pwr))
		return imxfb_regulator_set(fbi, power == FB_BLANK_UNBLANK);
834 835 836 837 838 839

	return 0;
}

static struct lcd_ops imxfb_lcd_ops = {
	.check_fb	= imxfb_lcd_check_fb,
840 841
	.get_contrast	= imxfb_lcd_get_contrast,
	.set_contrast	= imxfb_lcd_set_contrast,
842 843 844 845
	.get_power	= imxfb_lcd_get_power,
	.set_power	= imxfb_lcd_set_power,
};

846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865
static int imxfb_setup(void)
{
	char *opt, *options = NULL;

	if (fb_get_options("imxfb", &options))
		return -ENODEV;

	if (!options || !*options)
		return 0;

	while ((opt = strsep(&options, ",")) != NULL) {
		if (!*opt)
			continue;
		else
			fb_mode = opt;
	}

	return 0;
}

M
Markus Pargmann 已提交
866
static int imxfb_probe(struct platform_device *pdev)
867 868
{
	struct imxfb_info *fbi;
869
	struct lcd_device *lcd;
870 871
	struct fb_info *info;
	struct resource *res;
M
Markus Pargmann 已提交
872 873
	struct imx_fb_videomode *m;
	const struct of_device_id *of_id;
874
	struct device_node *display_np;
875
	int ret, i;
M
Markus Pargmann 已提交
876
	int bytes_per_pixel;
877

S
Sascha Hauer 已提交
878
	dev_info(&pdev->dev, "i.MX Framebuffer driver\n");
879

880 881 882 883
	ret = imxfb_setup();
	if (ret < 0)
		return ret;

M
Markus Pargmann 已提交
884 885 886 887
	of_id = of_match_device(imxfb_of_dev_id, &pdev->dev);
	if (of_id)
		pdev->id_entry = of_id->data;

888
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
889
	if (!res)
890 891
		return -ENODEV;

892
	info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
893
	if (!info)
894 895 896 897
		return -ENOMEM;

	fbi = info->par;

898
	platform_set_drvdata(pdev, info);
899

900
	ret = imxfb_init_fbinfo(pdev);
901
	if (ret < 0)
902 903
		goto failed_init;

904
	fb_mode = NULL;
M
Markus Pargmann 已提交
905

906 907 908 909 910 911
	display_np = of_parse_phandle(pdev->dev.of_node, "display", 0);
	if (!display_np) {
		dev_err(&pdev->dev, "No display defined in devicetree\n");
		ret = -EINVAL;
		goto failed_of_parse;
	}
M
Markus Pargmann 已提交
912

913 914 915 916 917 918 919 920 921 922
	/*
	 * imxfb does not support more modes, we choose only the native
	 * mode.
	 */
	fbi->num_modes = 1;

	fbi->mode = devm_kzalloc(&pdev->dev,
			sizeof(struct imx_fb_videomode), GFP_KERNEL);
	if (!fbi->mode) {
		ret = -ENOMEM;
923
		of_node_put(display_np);
924
		goto failed_of_parse;
M
Markus Pargmann 已提交
925 926
	}

927 928 929 930 931
	ret = imxfb_of_read_mode(&pdev->dev, display_np, fbi->mode);
	of_node_put(display_np);
	if (ret)
		goto failed_of_parse;

M
Markus Pargmann 已提交
932 933 934 935 936 937 938 939
	/* Calculate maximum bytes used per pixel. In most cases this should
	 * be the same as m->bpp/8 */
	m = &fbi->mode[0];
	bytes_per_pixel = (m->bpp + 7) / 8;
	for (i = 0; i < fbi->num_modes; i++, m++)
		info->fix.smem_len = max_t(size_t, info->fix.smem_len,
				m->mode.xres * m->mode.yres * bytes_per_pixel);

940 941 942 943 944 945
	fbi->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
	if (IS_ERR(fbi->clk_ipg)) {
		ret = PTR_ERR(fbi->clk_ipg);
		goto failed_getclock;
	}

946 947 948 949 950 951 952 953 954 955 956 957 958 959 960
	/*
	 * The LCDC controller does not have an enable bit. The
	 * controller starts directly when the clocks are enabled.
	 * If the clocks are enabled when the controller is not yet
	 * programmed with proper register values (enabled at the
	 * bootloader, for example) then it just goes into some undefined
	 * state.
	 * To avoid this issue, let's enable and disable LCDC IPG clock
	 * so that we force some kind of 'reset' to the LCDC block.
	 */
	ret = clk_prepare_enable(fbi->clk_ipg);
	if (ret)
		goto failed_getclock;
	clk_disable_unprepare(fbi->clk_ipg);

961 962 963 964 965 966 967 968 969
	fbi->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
	if (IS_ERR(fbi->clk_ahb)) {
		ret = PTR_ERR(fbi->clk_ahb);
		goto failed_getclock;
	}

	fbi->clk_per = devm_clk_get(&pdev->dev, "per");
	if (IS_ERR(fbi->clk_per)) {
		ret = PTR_ERR(fbi->clk_per);
S
Sascha Hauer 已提交
970 971 972
		goto failed_getclock;
	}

973
	fbi->regs = devm_ioremap_resource(&pdev->dev, res);
974 975
	if (IS_ERR(fbi->regs)) {
		ret = PTR_ERR(fbi->regs);
976
		goto failed_ioremap;
977 978
	}

979
	fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
980 981
	info->screen_buffer = dma_alloc_wc(&pdev->dev, fbi->map_size,
					   &fbi->map_dma, GFP_KERNEL);
982
	if (!info->screen_buffer) {
983
		dev_err(&pdev->dev, "Failed to allocate video RAM\n");
984 985
		ret = -ENOMEM;
		goto failed_map;
986 987
	}

988 989
	info->fix.smem_start = fbi->map_dma;

990
	INIT_LIST_HEAD(&info->modelist);
M
Markus Pargmann 已提交
991 992
	for (i = 0; i < fbi->num_modes; i++)
		fb_add_videomode(&fbi->mode[i].mode, &info->modelist);
993

994 995 996 997 998 999
	/*
	 * This makes sure that our colour bitfield
	 * descriptors are correctly initialised.
	 */
	imxfb_check_var(&info->var, info);

1000 1001 1002 1003 1004
	/*
	 * For modes > 8bpp, the color map is bypassed.
	 * Therefore, 256 entries are enough.
	 */
	ret = fb_alloc_cmap(&info->cmap, 256, 0);
1005 1006 1007 1008 1009 1010
	if (ret < 0)
		goto failed_cmap;

	imxfb_set_par(info);
	ret = register_framebuffer(info);
	if (ret < 0) {
1011
		dev_err(&pdev->dev, "failed to register framebuffer\n");
1012 1013 1014
		goto failed_register;
	}

1015
	fbi->lcd_pwr = devm_regulator_get(&pdev->dev, "lcd");
1016
	if (PTR_ERR(fbi->lcd_pwr) == -EPROBE_DEFER) {
1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
		ret = -EPROBE_DEFER;
		goto failed_lcd;
	}

	lcd = devm_lcd_device_register(&pdev->dev, "imxfb-lcd", &pdev->dev, fbi,
				       &imxfb_lcd_ops);
	if (IS_ERR(lcd)) {
		ret = PTR_ERR(lcd);
		goto failed_lcd;
	}

1028 1029
	lcd->props.max_contrast = 0xff;

1030
	imxfb_enable_controller(fbi);
1031
	fbi->pdev = pdev;
1032 1033 1034

	return 0;

1035 1036 1037
failed_lcd:
	unregister_framebuffer(info);

1038 1039 1040
failed_register:
	fb_dealloc_cmap(&info->cmap);
failed_cmap:
1041
	dma_free_wc(&pdev->dev, fbi->map_size, info->screen_buffer,
1042
		    fbi->map_dma);
1043
failed_map:
1044
failed_ioremap:
1045
failed_getclock:
S
Sascha Hauer 已提交
1046
	release_mem_region(res->start, resource_size(res));
M
Markus Pargmann 已提交
1047
failed_of_parse:
1048
	kfree(info->pseudo_palette);
1049 1050 1051 1052 1053
failed_init:
	framebuffer_release(info);
	return ret;
}

1054
static int imxfb_remove(struct platform_device *pdev)
1055
{
1056
	struct fb_info *info = platform_get_drvdata(pdev);
1057
	struct imxfb_info *fbi = info->par;
1058

1059
	imxfb_disable_controller(fbi);
1060 1061

	unregister_framebuffer(info);
1062
	fb_dealloc_cmap(&info->cmap);
1063
	dma_free_wc(&pdev->dev, fbi->map_size, info->screen_buffer,
1064
		    fbi->map_dma);
1065 1066
	kfree(info->pseudo_palette);
	framebuffer_release(info);
S
Sascha Hauer 已提交
1067

1068 1069 1070
	return 0;
}

1071
static int __maybe_unused imxfb_suspend(struct device *dev)
1072
{
1073
	struct fb_info *info = dev_get_drvdata(dev);
1074
	struct imxfb_info *fbi = info->par;
1075

1076
	imxfb_disable_controller(fbi);
1077 1078

	return 0;
1079 1080
}

1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
static int __maybe_unused imxfb_resume(struct device *dev)
{
	struct fb_info *info = dev_get_drvdata(dev);
	struct imxfb_info *fbi = info->par;

	imxfb_enable_controller(fbi);

	return 0;
}

static SIMPLE_DEV_PM_OPS(imxfb_pm_ops, imxfb_suspend, imxfb_resume);

1093 1094
static struct platform_driver imxfb_driver = {
	.driver		= {
1095
		.name	= DRIVER_NAME,
M
Markus Pargmann 已提交
1096
		.of_match_table = imxfb_of_dev_id,
1097
		.pm	= &imxfb_pm_ops,
1098
	},
1099 1100
	.probe		= imxfb_probe,
	.remove		= imxfb_remove,
1101
	.id_table	= imxfb_devtype,
1102
};
1103
module_platform_driver(imxfb_driver);
1104

1105
MODULE_DESCRIPTION("Freescale i.MX framebuffer driver");
1106 1107
MODULE_AUTHOR("Sascha Hauer, Pengutronix");
MODULE_LICENSE("GPL");