File Index
Files and directories
Sign in
FILE

imxfb.c

File preview with syntax highlighting.

linux-6.19.14/drivers/video/fbdev/imxfb.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *  Freescale i.MX Frame Buffer device driver
   4 *
   5 *  Copyright (C) 2004 Sascha Hauer, Pengutronix
   6 *   Based on acornfb.c Copyright (C) Russell King.
   7 *
   8 * Please direct your questions and comments on this driver to the following
   9 * email address:
  10 *
  11 *	linux-arm-kernel@lists.arm.linux.org.uk
  12 */
  13
  14#include <linux/module.h>
  15#include <linux/kernel.h>
  16#include <linux/errno.h>
  17#include <linux/string.h>
  18#include <linux/interrupt.h>
  19#include <linux/slab.h>
  20#include <linux/mm.h>
  21#include <linux/fb.h>
  22#include <linux/delay.h>
  23#include <linux/init.h>
  24#include <linux/ioport.h>
  25#include <linux/cpufreq.h>
  26#include <linux/clk.h>
  27#include <linux/platform_device.h>
  28#include <linux/dma-mapping.h>
  29#include <linux/io.h>
  30#include <linux/lcd.h>
  31#include <linux/math64.h>
  32#include <linux/of.h>
  33#include <linux/of_device.h>
  34#include <linux/bitfield.h>
  35
  36#include <linux/regulator/consumer.h>
  37
  38#include <video/of_display_timing.h>
  39#include <video/of_videomode.h>
  40#include <video/videomode.h>
  41
  42struct imx_fb_videomode {
  43	struct fb_videomode mode;
  44	u32 pcr;
  45	bool aus_mode;
  46	unsigned char	bpp;
  47};
  48
  49/*
  50 * Complain if VAR is out of range.
  51 */
  52#define DEBUG_VAR 1
  53
  54#define DRIVER_NAME "imx-fb"
  55
  56#define LCDC_SSA	0x00
  57
  58#define LCDC_SIZE	0x04
  59#define SIZE_XMAX_MASK	GENMASK(25, 20)
  60
  61#define YMAX_MASK_IMX1	GENMASK(8, 0)
  62#define YMAX_MASK_IMX21	GENMASK(9, 0)
  63
  64#define LCDC_VPW	0x08
  65#define VPW_VPW_MASK	GENMASK(9, 0)
  66
  67#define LCDC_CPOS	0x0C
  68#define CPOS_CC1	BIT(31)
  69#define CPOS_CC0	BIT(30)
  70#define CPOS_OP		BIT(28)
  71#define CPOS_CXP_MASK	GENMASK(25, 16)
  72
  73#define LCDC_LCWHB	0x10
  74#define LCWHB_BK_EN	BIT(31)
  75#define LCWHB_CW_MASK	GENMASK(28, 24)
  76#define LCWHB_CH_MASK	GENMASK(20, 16)
  77#define LCWHB_BD_MASK	GENMASK(7, 0)
  78
  79#define LCDC_LCHCC	0x14
  80
  81#define LCDC_PCR	0x18
  82#define PCR_TFT		BIT(31)
  83#define PCR_COLOR	BIT(30)
  84#define PCR_BPIX_MASK	GENMASK(27, 25)
  85#define PCR_BPIX_8	3
  86#define PCR_BPIX_12	4
  87#define PCR_BPIX_16	5
  88#define PCR_BPIX_18	6
  89#define PCR_PCD_MASK	GENMASK(5, 0)
  90
  91#define LCDC_HCR	0x1C
  92#define HCR_H_WIDTH_MASK	GENMASK(31, 26)
  93#define HCR_H_WAIT_1_MASK	GENMASK(15, 8)
  94#define HCR_H_WAIT_2_MASK	GENMASK(7, 0)
  95
  96#define LCDC_VCR	0x20
  97#define VCR_V_WIDTH_MASK	GENMASK(31, 26)
  98#define VCR_V_WAIT_1_MASK	GENMASK(15, 8)
  99#define VCR_V_WAIT_2_MASK	GENMASK(7, 0)
 100
 101#define LCDC_POS	0x24
 102#define POS_POS_MASK	GENMASK(4, 0)
 103
 104#define LCDC_LSCR1	0x28
 105/* bit fields in imxfb.h */
 106
 107#define LCDC_PWMR	0x2C
 108/* bit fields in imxfb.h */
 109
 110#define LCDC_DMACR	0x30
 111/* bit fields in imxfb.h */
 112
 113#define LCDC_RMCR	0x34
 114
 115#define RMCR_LCDC_EN_MX1	BIT(1)
 116
 117#define RMCR_SELF_REF	BIT(0)
 118
 119#define LCDC_LCDICR	0x38
 120#define LCDICR_INT_SYN	BIT(2)
 121#define LCDICR_INT_CON	BIT(0)
 122
 123#define LCDC_LCDISR	0x40
 124#define LCDISR_UDR_ERR	BIT(3)
 125#define LCDISR_ERR_RES	BIT(2)
 126#define LCDISR_EOF	BIT(1)
 127#define LCDISR_BOF	BIT(0)
 128
 129#define IMXFB_LSCR1_DEFAULT 0x00120300
 130
 131#define LCDC_LAUSCR	0x80
 132#define LAUSCR_AUS_MODE	BIT(31)
 133
 134/* Used fb-mode. Can be set on kernel command line, therefore file-static. */
 135static const char *fb_mode;
 136
 137/*
 138 * These are the bitfields for each
 139 * display depth that we support.
 140 */
 141struct imxfb_rgb {
 142	struct fb_bitfield	red;
 143	struct fb_bitfield	green;
 144	struct fb_bitfield	blue;
 145	struct fb_bitfield	transp;
 146};
 147
 148enum imxfb_type {
 149	IMX1_FB,
 150	IMX21_FB,
 151};
 152
 153enum imxfb_panel_type {
 154	PANEL_TYPE_MONOCHROME,
 155	PANEL_TYPE_CSTN,
 156	PANEL_TYPE_TFT,
 157};
 158
 159struct imxfb_info {
 160	struct platform_device  *pdev;
 161	void __iomem		*regs;
 162	struct clk		*clk_ipg;
 163	struct clk		*clk_ahb;
 164	struct clk		*clk_per;
 165	enum imxfb_type		devtype;
 166	enum imxfb_panel_type	panel_type;
 167	bool			enabled;
 168
 169	/*
 170	 * These are the addresses we mapped
 171	 * the framebuffer memory region to.
 172	 */
 173	dma_addr_t		map_dma;
 174	u_int			map_size;
 175
 176	u_int			palette_size;
 177
 178	dma_addr_t		dbar1;
 179	dma_addr_t		dbar2;
 180
 181	u_int			pcr;
 182	u_int			lauscr;
 183	u_int			pwmr;
 184	u_int			lscr1;
 185	u_int			dmacr;
 186	bool			cmap_inverse;
 187	bool			cmap_static;
 188
 189	struct imx_fb_videomode *mode;
 190	int			num_modes;
 191
 192	struct regulator	*lcd_pwr;
 193	int			lcd_pwr_enabled;
 194};
 195
 196static const struct platform_device_id imxfb_devtype[] = {
 197	{
 198		.name = "imx1-fb",
 199		.driver_data = IMX1_FB,
 200	}, {
 201		.name = "imx21-fb",
 202		.driver_data = IMX21_FB,
 203	}, {
 204		/* sentinel */
 205	}
 206};
 207MODULE_DEVICE_TABLE(platform, imxfb_devtype);
 208
 209static const struct of_device_id imxfb_of_dev_id[] = {
 210	{
 211		.compatible = "fsl,imx1-fb",
 212		.data = &imxfb_devtype[IMX1_FB],
 213	}, {
 214		.compatible = "fsl,imx21-fb",
 215		.data = &imxfb_devtype[IMX21_FB],
 216	}, {
 217		/* sentinel */
 218	}
 219};
 220MODULE_DEVICE_TABLE(of, imxfb_of_dev_id);
 221
 222static inline int is_imx1_fb(struct imxfb_info *fbi)
 223{
 224	return fbi->devtype == IMX1_FB;
 225}
 226
 227#define IMX_NAME	"IMX"
 228
 229/*
 230 * Minimum X and Y resolutions
 231 */
 232#define MIN_XRES	64
 233#define MIN_YRES	64
 234
 235/* Actually this really is 18bit support, the lowest 2 bits of each colour
 236 * are unused in hardware. We claim to have 24bit support to make software
 237 * like X work, which does not support 18bit.
 238 */
 239static struct imxfb_rgb def_rgb_18 = {
 240	.red	= {.offset = 16, .length = 8,},
 241	.green	= {.offset = 8, .length = 8,},
 242	.blue	= {.offset = 0, .length = 8,},
 243	.transp = {.offset = 0, .length = 0,},
 244};
 245
 246static struct imxfb_rgb def_rgb_16_tft = {
 247	.red	= {.offset = 11, .length = 5,},
 248	.green	= {.offset = 5, .length = 6,},
 249	.blue	= {.offset = 0, .length = 5,},
 250	.transp = {.offset = 0, .length = 0,},
 251};
 252
 253static struct imxfb_rgb def_rgb_16_stn = {
 254	.red	= {.offset = 8, .length = 4,},
 255	.green	= {.offset = 4, .length = 4,},
 256	.blue	= {.offset = 0, .length = 4,},
 257	.transp = {.offset = 0, .length = 0,},
 258};
 259
 260static struct imxfb_rgb def_rgb_8 = {
 261	.red	= {.offset = 0, .length = 8,},
 262	.green	= {.offset = 0, .length = 8,},
 263	.blue	= {.offset = 0, .length = 8,},
 264	.transp = {.offset = 0, .length = 0,},
 265};
 266
 267static int imxfb_activate_var(struct fb_var_screeninfo *var,
 268		struct fb_info *info);
 269
 270static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
 271{
 272	chan &= 0xffff;
 273	chan >>= 16 - bf->length;
 274	return chan << bf->offset;
 275}
 276
 277static int imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
 278		u_int trans, struct fb_info *info)
 279{
 280	struct imxfb_info *fbi = info->par;
 281	u_int val, ret = 1;
 282
 283#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)
 284	if (regno < fbi->palette_size) {
 285		val = (CNVT_TOHW(red, 4) << 8) |
 286		      (CNVT_TOHW(green, 4) << 4) |
 287		      CNVT_TOHW(blue,  4);
 288
 289		writel(val, fbi->regs + 0x800 + (regno << 2));
 290		ret = 0;
 291	}
 292	return ret;
 293}
 294
 295static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 296		   u_int trans, struct fb_info *info)
 297{
 298	struct imxfb_info *fbi = info->par;
 299	unsigned int val;
 300	int ret = 1;
 301
 302	/*
 303	 * If inverse mode was selected, invert all the colours
 304	 * rather than the register number.  The register number
 305	 * is what you poke into the framebuffer to produce the
 306	 * colour you requested.
 307	 */
 308	if (fbi->cmap_inverse) {
 309		red   = 0xffff - red;
 310		green = 0xffff - green;
 311		blue  = 0xffff - blue;
 312	}
 313
 314	/*
 315	 * If greyscale is true, then we convert the RGB value
 316	 * to greyscale no mater what visual we are using.
 317	 */
 318	if (info->var.grayscale)
 319		red = green = blue = (19595 * red + 38470 * green +
 320					7471 * blue) >> 16;
 321
 322	switch (info->fix.visual) {
 323	case FB_VISUAL_TRUECOLOR:
 324		/*
 325		 * 12 or 16-bit True Colour.  We encode the RGB value
 326		 * according to the RGB bitfield information.
 327		 */
 328		if (regno < 16) {
 329			u32 *pal = info->pseudo_palette;
 330
 331			val  = chan_to_field(red, &info->var.red);
 332			val |= chan_to_field(green, &info->var.green);
 333			val |= chan_to_field(blue, &info->var.blue);
 334
 335			pal[regno] = val;
 336			ret = 0;
 337		}
 338		break;
 339
 340	case FB_VISUAL_STATIC_PSEUDOCOLOR:
 341	case FB_VISUAL_PSEUDOCOLOR:
 342		ret = imxfb_setpalettereg(regno, red, green, blue, trans, info);
 343		break;
 344	}
 345
 346	return ret;
 347}
 348
 349static const struct imx_fb_videomode *imxfb_find_mode(struct imxfb_info *fbi)
 350{
 351	struct imx_fb_videomode *m;
 352	int i;
 353
 354	if (!fb_mode)
 355		return &fbi->mode[0];
 356
 357	for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) {
 358		if (!strcmp(m->mode.name, fb_mode))
 359			return m;
 360	}
 361	return NULL;
 362}
 363
 364/*
 365 *  imxfb_check_var():
 366 *    Round up in the following order: bits_per_pixel, xres,
 367 *    yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
 368 *    bitfields, horizontal timing, vertical timing.
 369 */
 370static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 371{
 372	struct imxfb_info *fbi = info->par;
 373	struct imxfb_rgb *rgb;
 374	const struct imx_fb_videomode *imxfb_mode;
 375	unsigned long lcd_clk;
 376	unsigned long long tmp;
 377	u32 pcr = 0;
 378
 379	if (var->xres < MIN_XRES)
 380		var->xres = MIN_XRES;
 381	if (var->yres < MIN_YRES)
 382		var->yres = MIN_YRES;
 383
 384	imxfb_mode = imxfb_find_mode(fbi);
 385	if (!imxfb_mode)
 386		return -EINVAL;
 387
 388	var->xres		= imxfb_mode->mode.xres;
 389	var->yres		= imxfb_mode->mode.yres;
 390	var->bits_per_pixel	= imxfb_mode->bpp;
 391	var->pixclock		= imxfb_mode->mode.pixclock;
 392	var->hsync_len		= imxfb_mode->mode.hsync_len;
 393	var->left_margin	= imxfb_mode->mode.left_margin;
 394	var->right_margin	= imxfb_mode->mode.right_margin;
 395	var->vsync_len		= imxfb_mode->mode.vsync_len;
 396	var->upper_margin	= imxfb_mode->mode.upper_margin;
 397	var->lower_margin	= imxfb_mode->mode.lower_margin;
 398	var->sync		= imxfb_mode->mode.sync;
 399	var->xres_virtual	= max(var->xres_virtual, var->xres);
 400	var->yres_virtual	= max(var->yres_virtual, var->yres);
 401
 402	pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
 403
 404	lcd_clk = clk_get_rate(fbi->clk_per);
 405
 406	tmp = var->pixclock * (unsigned long long)lcd_clk;
 407
 408	do_div(tmp, 1000000);
 409
 410	if (do_div(tmp, 1000000) > 500000)
 411		tmp++;
 412
 413	pcr = (unsigned int)tmp;
 414
 415	if (--pcr > PCR_PCD_MASK) {
 416		pcr = PCR_PCD_MASK;
 417		dev_warn(&fbi->pdev->dev, "Must limit pixel clock to %luHz\n",
 418			 lcd_clk / pcr);
 419	}
 420
 421	switch (var->bits_per_pixel) {
 422	case 32:
 423		pcr |= FIELD_PREP(PCR_BPIX_MASK, PCR_BPIX_18);
 424		rgb = &def_rgb_18;
 425		break;
 426	case 16:
 427	default:
 428		if (is_imx1_fb(fbi))
 429			pcr |= FIELD_PREP(PCR_BPIX_MASK, PCR_BPIX_12);
 430		else
 431			pcr |= FIELD_PREP(PCR_BPIX_MASK, PCR_BPIX_16);
 432
 433		if (imxfb_mode->pcr & PCR_TFT)
 434			rgb = &def_rgb_16_tft;
 435		else
 436			rgb = &def_rgb_16_stn;
 437		break;
 438	case 8:
 439		pcr |= FIELD_PREP(PCR_BPIX_MASK, PCR_BPIX_8);
 440		rgb = &def_rgb_8;
 441		break;
 442	}
 443
 444	/* add sync polarities */
 445	pcr |= imxfb_mode->pcr & ~(PCR_PCD_MASK | PCR_BPIX_MASK);
 446
 447	fbi->pcr = pcr;
 448	/*
 449	 * The LCDC AUS Mode Control Register does not exist on imx1.
 450	 */
 451	if (!is_imx1_fb(fbi) && imxfb_mode->aus_mode)
 452		fbi->lauscr = LAUSCR_AUS_MODE;
 453
 454	if (imxfb_mode->pcr & PCR_TFT)
 455		fbi->panel_type = PANEL_TYPE_TFT;
 456	else if (imxfb_mode->pcr & PCR_COLOR)
 457		fbi->panel_type = PANEL_TYPE_CSTN;
 458	else
 459		fbi->panel_type = PANEL_TYPE_MONOCHROME;
 460
 461	/*
 462	 * Copy the RGB parameters for this display
 463	 * from the machine specific parameters.
 464	 */
 465	var->red    = rgb->red;
 466	var->green  = rgb->green;
 467	var->blue   = rgb->blue;
 468	var->transp = rgb->transp;
 469
 470	pr_debug("RGBT length = %d:%d:%d:%d\n",
 471		var->red.length, var->green.length, var->blue.length,
 472		var->transp.length);
 473
 474	pr_debug("RGBT offset = %d:%d:%d:%d\n",
 475		var->red.offset, var->green.offset, var->blue.offset,
 476		var->transp.offset);
 477
 478	return 0;
 479}
 480
 481/*
 482 * imxfb_set_par():
 483 *	Set the user defined part of the display for the specified console
 484 */
 485static int imxfb_set_par(struct fb_info *info)
 486{
 487	struct imxfb_info *fbi = info->par;
 488	struct fb_var_screeninfo *var = &info->var;
 489
 490	if (var->bits_per_pixel == 16 || var->bits_per_pixel == 32)
 491		info->fix.visual = FB_VISUAL_TRUECOLOR;
 492	else if (!fbi->cmap_static)
 493		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
 494	else {
 495		/*
 496		 * Some people have weird ideas about wanting static
 497		 * pseudocolor maps.  I suspect their user space
 498		 * applications are broken.
 499		 */
 500		info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
 501	}
 502
 503	info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
 504	fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
 505
 506	imxfb_activate_var(var, info);
 507
 508	return 0;
 509}
 510
 511static int imxfb_enable_controller(struct imxfb_info *fbi)
 512{
 513	int ret;
 514
 515	if (fbi->enabled)
 516		return 0;
 517
 518	pr_debug("Enabling LCD controller\n");
 519
 520	writel(fbi->map_dma, fbi->regs + LCDC_SSA);
 521
 522	/* panning offset 0 (0 pixel offset)        */
 523	writel(FIELD_PREP(POS_POS_MASK, 0), fbi->regs + LCDC_POS);
 524
 525	/* disable hardware cursor */
 526	writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1),
 527		fbi->regs + LCDC_CPOS);
 528
 529	/*
 530	 * RMCR_LCDC_EN_MX1 is present on i.MX1 only, but doesn't hurt
 531	 * on other SoCs
 532	 */
 533	writel(RMCR_LCDC_EN_MX1, fbi->regs + LCDC_RMCR);
 534
 535	ret = clk_prepare_enable(fbi->clk_ipg);
 536	if (ret)
 537		goto err_enable_ipg;
 538
 539	ret = clk_prepare_enable(fbi->clk_ahb);
 540	if (ret)
 541		goto err_enable_ahb;
 542
 543	ret = clk_prepare_enable(fbi->clk_per);
 544	if (ret)
 545		goto err_enable_per;
 546
 547	fbi->enabled = true;
 548	return 0;
 549
 550err_enable_per:
 551	clk_disable_unprepare(fbi->clk_ahb);
 552err_enable_ahb:
 553	clk_disable_unprepare(fbi->clk_ipg);
 554err_enable_ipg:
 555	writel(0, fbi->regs + LCDC_RMCR);
 556
 557	return ret;
 558}
 559
 560static void imxfb_disable_controller(struct imxfb_info *fbi)
 561{
 562	if (!fbi->enabled)
 563		return;
 564
 565	pr_debug("Disabling LCD controller\n");
 566
 567	clk_disable_unprepare(fbi->clk_per);
 568	clk_disable_unprepare(fbi->clk_ahb);
 569	clk_disable_unprepare(fbi->clk_ipg);
 570	fbi->enabled = false;
 571
 572	writel(0, fbi->regs + LCDC_RMCR);
 573}
 574
 575static int imxfb_blank(int blank, struct fb_info *info)
 576{
 577	struct imxfb_info *fbi = info->par;
 578
 579	pr_debug("%s: blank=%d\n", __func__, blank);
 580
 581	switch (blank) {
 582	case FB_BLANK_POWERDOWN:
 583	case FB_BLANK_VSYNC_SUSPEND:
 584	case FB_BLANK_HSYNC_SUSPEND:
 585	case FB_BLANK_NORMAL:
 586		imxfb_disable_controller(fbi);
 587		break;
 588
 589	case FB_BLANK_UNBLANK:
 590		return imxfb_enable_controller(fbi);
 591	}
 592	return 0;
 593}
 594
 595static const struct fb_ops imxfb_ops = {
 596	.owner		= THIS_MODULE,
 597	FB_DEFAULT_IOMEM_OPS,
 598	.fb_check_var	= imxfb_check_var,
 599	.fb_set_par	= imxfb_set_par,
 600	.fb_setcolreg	= imxfb_setcolreg,
 601	.fb_blank	= imxfb_blank,
 602};
 603
 604/*
 605 * imxfb_activate_var():
 606 *	Configures LCD Controller based on entries in var parameter.  Settings are
 607 *	only written to the controller if changes were made.
 608 */
 609static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
 610{
 611	struct imxfb_info *fbi = info->par;
 612	u32 ymax_mask = is_imx1_fb(fbi) ? YMAX_MASK_IMX1 : YMAX_MASK_IMX21;
 613	u8 left_margin_low;
 614
 615	pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
 616		var->xres, var->hsync_len,
 617		var->left_margin, var->right_margin);
 618	pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n",
 619		var->yres, var->vsync_len,
 620		var->upper_margin, var->lower_margin);
 621
 622	if (fbi->panel_type == PANEL_TYPE_TFT)
 623		left_margin_low = 3;
 624	else if (fbi->panel_type == PANEL_TYPE_CSTN)
 625		left_margin_low = 2;
 626	else
 627		left_margin_low = 0;
 628
 629#if DEBUG_VAR
 630	if (var->xres < 16        || var->xres > 1024)
 631		dev_err(&fbi->pdev->dev, "%s: invalid xres %d\n",
 632			info->fix.id, var->xres);
 633	if (var->hsync_len < 1    || var->hsync_len > 64)
 634		dev_err(&fbi->pdev->dev, "%s: invalid hsync_len %d\n",
 635			info->fix.id, var->hsync_len);
 636	if (var->left_margin < left_margin_low  || var->left_margin > 255)
 637		dev_err(&fbi->pdev->dev, "%s: invalid left_margin %d\n",
 638			info->fix.id, var->left_margin);
 639	if (var->right_margin < 1 || var->right_margin > 255)
 640		dev_err(&fbi->pdev->dev, "%s: invalid right_margin %d\n",
 641			info->fix.id, var->right_margin);
 642	if (var->yres < 1 || var->yres > ymax_mask)
 643		dev_err(&fbi->pdev->dev, "%s: invalid yres %d\n",
 644			info->fix.id, var->yres);
 645	if (var->vsync_len > 100)
 646		dev_err(&fbi->pdev->dev, "%s: invalid vsync_len %d\n",
 647			info->fix.id, var->vsync_len);
 648	if (var->upper_margin > 63)
 649		dev_err(&fbi->pdev->dev, "%s: invalid upper_margin %d\n",
 650			info->fix.id, var->upper_margin);
 651	if (var->lower_margin > 255)
 652		dev_err(&fbi->pdev->dev, "%s: invalid lower_margin %d\n",
 653			info->fix.id, var->lower_margin);
 654#endif
 655
 656	/* physical screen start address	    */
 657	writel(FIELD_PREP(VPW_VPW_MASK,
 658			  var->xres * var->bits_per_pixel / 8 / 4),
 659	       fbi->regs + LCDC_VPW);
 660
 661	writel(FIELD_PREP(HCR_H_WIDTH_MASK, var->hsync_len - 1) |
 662	       FIELD_PREP(HCR_H_WAIT_1_MASK, var->right_margin - 1) |
 663	       FIELD_PREP(HCR_H_WAIT_2_MASK,
 664			  var->left_margin - left_margin_low),
 665	       fbi->regs + LCDC_HCR);
 666
 667	writel(FIELD_PREP(VCR_V_WIDTH_MASK, var->vsync_len) |
 668	       FIELD_PREP(VCR_V_WAIT_1_MASK, var->lower_margin) |
 669	       FIELD_PREP(VCR_V_WAIT_2_MASK, var->upper_margin),
 670	       fbi->regs + LCDC_VCR);
 671
 672	writel(FIELD_PREP(SIZE_XMAX_MASK, var->xres >> 4) |
 673	       (var->yres & ymax_mask),
 674	       fbi->regs + LCDC_SIZE);
 675
 676	writel(fbi->pcr, fbi->regs + LCDC_PCR);
 677	if (fbi->pwmr)
 678		writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
 679	writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
 680
 681	/* dmacr = 0 is no valid value, as we need DMA control marks. */
 682	if (fbi->dmacr)
 683		writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
 684
 685	if (fbi->lauscr)
 686		writel(fbi->lauscr, fbi->regs + LCDC_LAUSCR);
 687
 688	return 0;
 689}
 690
 691static int imxfb_init_fbinfo(struct platform_device *pdev)
 692{
 693	struct fb_info *info = platform_get_drvdata(pdev);
 694	struct imxfb_info *fbi = info->par;
 695	struct device_node *np;
 696
 697	info->pseudo_palette = devm_kmalloc_array(&pdev->dev, 16,
 698						  sizeof(u32), GFP_KERNEL);
 699	if (!info->pseudo_palette)
 700		return -ENOMEM;
 701
 702	memset(fbi, 0, sizeof(struct imxfb_info));
 703
 704	fbi->pdev = pdev;
 705	fbi->devtype = pdev->id_entry->driver_data;
 706
 707	strscpy(info->fix.id, IMX_NAME, sizeof(info->fix.id));
 708
 709	info->fix.type			= FB_TYPE_PACKED_PIXELS;
 710	info->fix.type_aux		= 0;
 711	info->fix.xpanstep		= 0;
 712	info->fix.ypanstep		= 0;
 713	info->fix.ywrapstep		= 0;
 714	info->fix.accel			= FB_ACCEL_NONE;
 715
 716	info->var.nonstd		= 0;
 717	info->var.activate		= FB_ACTIVATE_NOW;
 718	info->var.height		= -1;
 719	info->var.width	= -1;
 720	info->var.accel_flags		= 0;
 721	info->var.vmode			= FB_VMODE_NONINTERLACED;
 722
 723	info->fbops			= &imxfb_ops;
 724	info->flags			= FBINFO_READS_FAST;
 725
 726	np = pdev->dev.of_node;
 727	info->var.grayscale = of_property_read_bool(np,
 728					"cmap-greyscale");
 729	fbi->cmap_inverse = of_property_read_bool(np, "cmap-inverse");
 730	fbi->cmap_static = of_property_read_bool(np, "cmap-static");
 731
 732	fbi->lscr1 = IMXFB_LSCR1_DEFAULT;
 733
 734	of_property_read_u32(np, "fsl,lpccr", &fbi->pwmr);
 735
 736	of_property_read_u32(np, "fsl,lscr1", &fbi->lscr1);
 737
 738	of_property_read_u32(np, "fsl,dmacr", &fbi->dmacr);
 739
 740	return 0;
 741}
 742
 743static int imxfb_of_read_mode(struct device *dev, struct device_node *np,
 744		struct imx_fb_videomode *imxfb_mode)
 745{
 746	int ret;
 747	struct fb_videomode *of_mode = &imxfb_mode->mode;
 748	u32 bpp;
 749	u32 pcr;
 750
 751	ret = of_property_read_string(np, "model", &of_mode->name);
 752	if (ret)
 753		of_mode->name = NULL;
 754
 755	ret = of_get_fb_videomode(np, of_mode, OF_USE_NATIVE_MODE);
 756	if (ret) {
 757		dev_err(dev, "Failed to get videomode from DT\n");
 758		return ret;
 759	}
 760
 761	ret = of_property_read_u32(np, "bits-per-pixel", &bpp);
 762	ret |= of_property_read_u32(np, "fsl,pcr", &pcr);
 763
 764	if (ret) {
 765		dev_err(dev, "Failed to read bpp and pcr from DT\n");
 766		return -EINVAL;
 767	}
 768
 769	if (bpp < 1 || bpp > 255) {
 770		dev_err(dev, "Bits per pixel have to be between 1 and 255\n");
 771		return -EINVAL;
 772	}
 773
 774	imxfb_mode->bpp = bpp;
 775	imxfb_mode->pcr = pcr;
 776
 777	/*
 778	 * fsl,aus-mode is optional
 779	 */
 780	imxfb_mode->aus_mode = of_property_read_bool(np, "fsl,aus-mode");
 781
 782	return 0;
 783}
 784
 785static int imxfb_lcd_get_contrast(struct lcd_device *lcddev)
 786{
 787	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
 788
 789	return fbi->pwmr & 0xff;
 790}
 791
 792static int imxfb_lcd_set_contrast(struct lcd_device *lcddev, int contrast)
 793{
 794	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
 795
 796	if (fbi->pwmr && fbi->enabled) {
 797		if (contrast > 255)
 798			contrast = 255;
 799		else if (contrast < 0)
 800			contrast = 0;
 801
 802		fbi->pwmr &= ~0xff;
 803		fbi->pwmr |= contrast;
 804
 805		writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
 806	}
 807
 808	return 0;
 809}
 810
 811static int imxfb_lcd_get_power(struct lcd_device *lcddev)
 812{
 813	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
 814
 815	if (!IS_ERR(fbi->lcd_pwr) &&
 816	    !regulator_is_enabled(fbi->lcd_pwr))
 817		return LCD_POWER_OFF;
 818
 819	return LCD_POWER_ON;
 820}
 821
 822static int imxfb_regulator_set(struct imxfb_info *fbi, int enable)
 823{
 824	int ret;
 825
 826	if (enable == fbi->lcd_pwr_enabled)
 827		return 0;
 828
 829	if (enable)
 830		ret = regulator_enable(fbi->lcd_pwr);
 831	else
 832		ret = regulator_disable(fbi->lcd_pwr);
 833
 834	if (ret == 0)
 835		fbi->lcd_pwr_enabled = enable;
 836
 837	return ret;
 838}
 839
 840static int imxfb_lcd_set_power(struct lcd_device *lcddev, int power)
 841{
 842	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
 843
 844	if (!IS_ERR(fbi->lcd_pwr))
 845		return imxfb_regulator_set(fbi, power == LCD_POWER_ON);
 846
 847	return 0;
 848}
 849
 850static const struct lcd_ops imxfb_lcd_ops = {
 851	.get_contrast	= imxfb_lcd_get_contrast,
 852	.set_contrast	= imxfb_lcd_set_contrast,
 853	.get_power	= imxfb_lcd_get_power,
 854	.set_power	= imxfb_lcd_set_power,
 855};
 856
 857static int imxfb_setup(void)
 858{
 859	char *opt, *options = NULL;
 860
 861	if (fb_get_options("imxfb", &options))
 862		return -ENODEV;
 863
 864	if (!options || !*options)
 865		return 0;
 866
 867	while ((opt = strsep(&options, ",")) != NULL) {
 868		if (!*opt)
 869			continue;
 870		else
 871			fb_mode = opt;
 872	}
 873
 874	return 0;
 875}
 876
 877static int imxfb_probe(struct platform_device *pdev)
 878{
 879	struct imxfb_info *fbi;
 880	struct lcd_device *lcd;
 881	struct fb_info *info;
 882	struct imx_fb_videomode *m;
 883	const struct of_device_id *of_id;
 884	struct device_node *display_np;
 885	int ret, i;
 886	int bytes_per_pixel;
 887
 888	dev_info(&pdev->dev, "i.MX Framebuffer driver\n");
 889
 890	ret = imxfb_setup();
 891	if (ret < 0)
 892		return ret;
 893
 894	of_id = of_match_device(imxfb_of_dev_id, &pdev->dev);
 895	if (of_id)
 896		pdev->id_entry = of_id->data;
 897
 898	info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
 899	if (!info)
 900		return -ENOMEM;
 901
 902	fbi = info->par;
 903
 904	platform_set_drvdata(pdev, info);
 905
 906	ret = imxfb_init_fbinfo(pdev);
 907	if (ret < 0)
 908		goto failed_init;
 909
 910	fb_mode = NULL;
 911
 912	display_np = of_parse_phandle(pdev->dev.of_node, "display", 0);
 913	if (!display_np) {
 914		dev_err(&pdev->dev, "No display defined in devicetree\n");
 915		ret = -EINVAL;
 916		goto failed_init;
 917	}
 918
 919	/*
 920	 * imxfb does not support more modes, we choose only the native
 921	 * mode.
 922	 */
 923	fbi->num_modes = 1;
 924
 925	fbi->mode = devm_kzalloc(&pdev->dev,
 926			sizeof(struct imx_fb_videomode), GFP_KERNEL);
 927	if (!fbi->mode) {
 928		ret = -ENOMEM;
 929		of_node_put(display_np);
 930		goto failed_init;
 931	}
 932
 933	ret = imxfb_of_read_mode(&pdev->dev, display_np, fbi->mode);
 934	of_node_put(display_np);
 935	if (ret)
 936		goto failed_init;
 937
 938	/*
 939	 * Calculate maximum bytes used per pixel. In most cases this should
 940	 * be the same as m->bpp/8
 941	 */
 942	m = &fbi->mode[0];
 943	bytes_per_pixel = (m->bpp + 7) / 8;
 944	for (i = 0; i < fbi->num_modes; i++, m++)
 945		info->fix.smem_len = max_t(size_t, info->fix.smem_len,
 946				m->mode.xres * m->mode.yres * bytes_per_pixel);
 947
 948	fbi->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
 949	if (IS_ERR(fbi->clk_ipg)) {
 950		ret = PTR_ERR(fbi->clk_ipg);
 951		goto failed_init;
 952	}
 953
 954	/*
 955	 * The LCDC controller does not have an enable bit. The
 956	 * controller starts directly when the clocks are enabled.
 957	 * If the clocks are enabled when the controller is not yet
 958	 * programmed with proper register values (enabled at the
 959	 * bootloader, for example) then it just goes into some undefined
 960	 * state.
 961	 * To avoid this issue, let's enable and disable LCDC IPG clock
 962	 * so that we force some kind of 'reset' to the LCDC block.
 963	 */
 964	ret = clk_prepare_enable(fbi->clk_ipg);
 965	if (ret)
 966		goto failed_init;
 967	clk_disable_unprepare(fbi->clk_ipg);
 968
 969	fbi->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
 970	if (IS_ERR(fbi->clk_ahb)) {
 971		ret = PTR_ERR(fbi->clk_ahb);
 972		goto failed_init;
 973	}
 974
 975	fbi->clk_per = devm_clk_get(&pdev->dev, "per");
 976	if (IS_ERR(fbi->clk_per)) {
 977		ret = PTR_ERR(fbi->clk_per);
 978		goto failed_init;
 979	}
 980
 981	fbi->regs = devm_platform_ioremap_resource(pdev, 0);
 982	if (IS_ERR(fbi->regs)) {
 983		ret = PTR_ERR(fbi->regs);
 984		goto failed_init;
 985	}
 986
 987	fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
 988	info->screen_buffer = dma_alloc_wc(&pdev->dev, fbi->map_size,
 989					   &fbi->map_dma, GFP_KERNEL);
 990	if (!info->screen_buffer) {
 991		dev_err(&pdev->dev, "Failed to allocate video RAM\n");
 992		ret = -ENOMEM;
 993		goto failed_init;
 994	}
 995
 996	info->fix.smem_start = fbi->map_dma;
 997
 998	INIT_LIST_HEAD(&info->modelist);
 999	for (i = 0; i < fbi->num_modes; i++) {
1000		ret = fb_add_videomode(&fbi->mode[i].mode, &info->modelist);
1001		if (ret) {
1002			dev_err(&pdev->dev, "Failed to add videomode\n");
1003			goto failed_cmap;
1004		}
1005	}
1006
1007	/*
1008	 * This makes sure that our colour bitfield
1009	 * descriptors are correctly initialised.
1010	 */
1011	imxfb_check_var(&info->var, info);
1012
1013	/*
1014	 * For modes > 8bpp, the color map is bypassed.
1015	 * Therefore, 256 entries are enough.
1016	 */
1017	ret = fb_alloc_cmap(&info->cmap, 256, 0);
1018	if (ret < 0)
1019		goto failed_cmap;
1020
1021	imxfb_set_par(info);
1022
1023	fbi->lcd_pwr = devm_regulator_get(&pdev->dev, "lcd");
1024	if (PTR_ERR(fbi->lcd_pwr) == -EPROBE_DEFER) {
1025		ret = -EPROBE_DEFER;
1026		goto failed_lcd;
1027	}
1028
1029	lcd = devm_lcd_device_register(&pdev->dev, "imxfb-lcd", &pdev->dev, fbi,
1030				       &imxfb_lcd_ops);
1031	if (IS_ERR(lcd)) {
1032		ret = PTR_ERR(lcd);
1033		goto failed_lcd;
1034	}
1035
1036	lcd->props.max_contrast = 0xff;
1037
1038	info->lcd_dev = lcd;
1039
1040	ret = register_framebuffer(info);
1041	if (ret < 0) {
1042		dev_err(&pdev->dev, "failed to register framebuffer\n");
1043		goto failed_lcd;
1044	}
1045
1046	imxfb_enable_controller(fbi);
1047
1048	return 0;
1049
1050failed_lcd:
1051	fb_dealloc_cmap(&info->cmap);
1052failed_cmap:
1053	dma_free_wc(&pdev->dev, fbi->map_size, info->screen_buffer,
1054		    fbi->map_dma);
1055failed_init:
1056	framebuffer_release(info);
1057	return ret;
1058}
1059
1060static void imxfb_remove(struct platform_device *pdev)
1061{
1062	struct fb_info *info = platform_get_drvdata(pdev);
1063	struct imxfb_info *fbi = info->par;
1064
1065	imxfb_disable_controller(fbi);
1066
1067	unregister_framebuffer(info);
1068	fb_dealloc_cmap(&info->cmap);
1069	dma_free_wc(&pdev->dev, fbi->map_size, info->screen_buffer,
1070		    fbi->map_dma);
1071	framebuffer_release(info);
1072}
1073
1074static int imxfb_suspend(struct device *dev)
1075{
1076	struct fb_info *info = dev_get_drvdata(dev);
1077	struct imxfb_info *fbi = info->par;
1078
1079	imxfb_disable_controller(fbi);
1080
1081	return 0;
1082}
1083
1084static int imxfb_resume(struct device *dev)
1085{
1086	struct fb_info *info = dev_get_drvdata(dev);
1087	struct imxfb_info *fbi = info->par;
1088
1089	imxfb_enable_controller(fbi);
1090
1091	return 0;
1092}
1093
1094static DEFINE_SIMPLE_DEV_PM_OPS(imxfb_pm_ops, imxfb_suspend, imxfb_resume);
1095
1096static struct platform_driver imxfb_driver = {
1097	.driver		= {
1098		.name	= DRIVER_NAME,
1099		.of_match_table = imxfb_of_dev_id,
1100		.pm	= pm_sleep_ptr(&imxfb_pm_ops),
1101	},
1102	.probe		= imxfb_probe,
1103	.remove		= imxfb_remove,
1104	.id_table	= imxfb_devtype,
1105};
1106module_platform_driver(imxfb_driver);
1107
1108MODULE_DESCRIPTION("Freescale i.MX framebuffer driver");
1109MODULE_AUTHOR("Sascha Hauer, Pengutronix");
1110MODULE_LICENSE("GPL");
~/ Read-only file preview.