PageRenderTime 132ms CodeModel.GetById 10ms app.highlight 110ms RepoModel.GetById 1ms app.codeStats 1ms

/drivers/video/da8xx-fb.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2
C | 1192 lines | 915 code | 186 blank | 91 comment | 98 complexity | 1fd1bc4b952cd6da2adc324339b54ad0 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
   1/*
   2 * Copyright (C) 2008-2009 MontaVista Software Inc.
   3 * Copyright (C) 2008-2009 Texas Instruments Inc
   4 *
   5 * Based on the LCD driver for TI Avalanche processors written by
   6 * Ajay Singh and Shalom Hai.
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option)any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21 */
  22#include <linux/module.h>
  23#include <linux/kernel.h>
  24#include <linux/fb.h>
  25#include <linux/dma-mapping.h>
  26#include <linux/device.h>
  27#include <linux/platform_device.h>
  28#include <linux/uaccess.h>
  29#include <linux/interrupt.h>
  30#include <linux/clk.h>
  31#include <linux/cpufreq.h>
  32#include <linux/console.h>
  33#include <linux/slab.h>
  34#include <video/da8xx-fb.h>
  35
  36#define DRIVER_NAME "da8xx_lcdc"
  37
  38/* LCD Status Register */
  39#define LCD_END_OF_FRAME1		BIT(9)
  40#define LCD_END_OF_FRAME0		BIT(8)
  41#define LCD_PL_LOAD_DONE		BIT(6)
  42#define LCD_FIFO_UNDERFLOW		BIT(5)
  43#define LCD_SYNC_LOST			BIT(2)
  44
  45/* LCD DMA Control Register */
  46#define LCD_DMA_BURST_SIZE(x)		((x) << 4)
  47#define LCD_DMA_BURST_1			0x0
  48#define LCD_DMA_BURST_2			0x1
  49#define LCD_DMA_BURST_4			0x2
  50#define LCD_DMA_BURST_8			0x3
  51#define LCD_DMA_BURST_16		0x4
  52#define LCD_END_OF_FRAME_INT_ENA	BIT(2)
  53#define LCD_DUAL_FRAME_BUFFER_ENABLE	BIT(0)
  54
  55/* LCD Control Register */
  56#define LCD_CLK_DIVISOR(x)		((x) << 8)
  57#define LCD_RASTER_MODE			0x01
  58
  59/* LCD Raster Control Register */
  60#define LCD_PALETTE_LOAD_MODE(x)	((x) << 20)
  61#define PALETTE_AND_DATA		0x00
  62#define PALETTE_ONLY			0x01
  63#define DATA_ONLY			0x02
  64
  65#define LCD_MONO_8BIT_MODE		BIT(9)
  66#define LCD_RASTER_ORDER		BIT(8)
  67#define LCD_TFT_MODE			BIT(7)
  68#define LCD_UNDERFLOW_INT_ENA		BIT(6)
  69#define LCD_PL_ENABLE			BIT(4)
  70#define LCD_MONOCHROME_MODE		BIT(1)
  71#define LCD_RASTER_ENABLE		BIT(0)
  72#define LCD_TFT_ALT_ENABLE		BIT(23)
  73#define LCD_STN_565_ENABLE		BIT(24)
  74
  75/* LCD Raster Timing 2 Register */
  76#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)	((x) << 16)
  77#define LCD_AC_BIAS_FREQUENCY(x)		((x) << 8)
  78#define LCD_SYNC_CTRL				BIT(25)
  79#define LCD_SYNC_EDGE				BIT(24)
  80#define LCD_INVERT_PIXEL_CLOCK			BIT(22)
  81#define LCD_INVERT_LINE_CLOCK			BIT(21)
  82#define LCD_INVERT_FRAME_CLOCK			BIT(20)
  83
  84/* LCD Block */
  85#define  LCD_CTRL_REG				0x4
  86#define  LCD_STAT_REG				0x8
  87#define  LCD_RASTER_CTRL_REG			0x28
  88#define  LCD_RASTER_TIMING_0_REG		0x2C
  89#define  LCD_RASTER_TIMING_1_REG		0x30
  90#define  LCD_RASTER_TIMING_2_REG		0x34
  91#define  LCD_DMA_CTRL_REG			0x40
  92#define  LCD_DMA_FRM_BUF_BASE_ADDR_0_REG	0x44
  93#define  LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG	0x48
  94#define  LCD_DMA_FRM_BUF_BASE_ADDR_1_REG	0x4C
  95#define  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG	0x50
  96
  97#define LCD_NUM_BUFFERS	2
  98
  99#define WSI_TIMEOUT	50
 100#define PALETTE_SIZE	256
 101#define LEFT_MARGIN	64
 102#define RIGHT_MARGIN	64
 103#define UPPER_MARGIN	32
 104#define LOWER_MARGIN	32
 105
 106static resource_size_t da8xx_fb_reg_base;
 107static struct resource *lcdc_regs;
 108
 109static inline unsigned int lcdc_read(unsigned int addr)
 110{
 111	return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr));
 112}
 113
 114static inline void lcdc_write(unsigned int val, unsigned int addr)
 115{
 116	__raw_writel(val, da8xx_fb_reg_base + (addr));
 117}
 118
 119struct da8xx_fb_par {
 120	resource_size_t p_palette_base;
 121	unsigned char *v_palette_base;
 122	dma_addr_t		vram_phys;
 123	unsigned long		vram_size;
 124	void			*vram_virt;
 125	unsigned int		dma_start;
 126	unsigned int		dma_end;
 127	struct clk *lcdc_clk;
 128	int irq;
 129	unsigned short pseudo_palette[16];
 130	unsigned int palette_sz;
 131	unsigned int pxl_clk;
 132	int blank;
 133	wait_queue_head_t	vsync_wait;
 134	int			vsync_flag;
 135	int			vsync_timeout;
 136#ifdef CONFIG_CPU_FREQ
 137	struct notifier_block	freq_transition;
 138#endif
 139	void (*panel_power_ctrl)(int);
 140};
 141
 142/* Variable Screen Information */
 143static struct fb_var_screeninfo da8xx_fb_var __devinitdata = {
 144	.xoffset = 0,
 145	.yoffset = 0,
 146	.transp = {0, 0, 0},
 147	.nonstd = 0,
 148	.activate = 0,
 149	.height = -1,
 150	.width = -1,
 151	.pixclock = 46666,	/* 46us - AUO display */
 152	.accel_flags = 0,
 153	.left_margin = LEFT_MARGIN,
 154	.right_margin = RIGHT_MARGIN,
 155	.upper_margin = UPPER_MARGIN,
 156	.lower_margin = LOWER_MARGIN,
 157	.sync = 0,
 158	.vmode = FB_VMODE_NONINTERLACED
 159};
 160
 161static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = {
 162	.id = "DA8xx FB Drv",
 163	.type = FB_TYPE_PACKED_PIXELS,
 164	.type_aux = 0,
 165	.visual = FB_VISUAL_PSEUDOCOLOR,
 166	.xpanstep = 0,
 167	.ypanstep = 1,
 168	.ywrapstep = 0,
 169	.accel = FB_ACCEL_NONE
 170};
 171
 172struct da8xx_panel {
 173	const char	name[25];	/* Full name <vendor>_<model> */
 174	unsigned short	width;
 175	unsigned short	height;
 176	int		hfp;		/* Horizontal front porch */
 177	int		hbp;		/* Horizontal back porch */
 178	int		hsw;		/* Horizontal Sync Pulse Width */
 179	int		vfp;		/* Vertical front porch */
 180	int		vbp;		/* Vertical back porch */
 181	int		vsw;		/* Vertical Sync Pulse Width */
 182	unsigned int	pxl_clk;	/* Pixel clock */
 183	unsigned char	invert_pxl_clk;	/* Invert Pixel clock */
 184};
 185
 186static struct da8xx_panel known_lcd_panels[] = {
 187	/* Sharp LCD035Q3DG01 */
 188	[0] = {
 189		.name = "Sharp_LCD035Q3DG01",
 190		.width = 320,
 191		.height = 240,
 192		.hfp = 8,
 193		.hbp = 6,
 194		.hsw = 0,
 195		.vfp = 2,
 196		.vbp = 2,
 197		.vsw = 0,
 198		.pxl_clk = 4608000,
 199		.invert_pxl_clk = 1,
 200	},
 201	/* Sharp LK043T1DG01 */
 202	[1] = {
 203		.name = "Sharp_LK043T1DG01",
 204		.width = 480,
 205		.height = 272,
 206		.hfp = 2,
 207		.hbp = 2,
 208		.hsw = 41,
 209		.vfp = 2,
 210		.vbp = 2,
 211		.vsw = 10,
 212		.pxl_clk = 7833600,
 213		.invert_pxl_clk = 0,
 214	},
 215};
 216
 217/* Enable the Raster Engine of the LCD Controller */
 218static inline void lcd_enable_raster(void)
 219{
 220	u32 reg;
 221
 222	reg = lcdc_read(LCD_RASTER_CTRL_REG);
 223	if (!(reg & LCD_RASTER_ENABLE))
 224		lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
 225}
 226
 227/* Disable the Raster Engine of the LCD Controller */
 228static inline void lcd_disable_raster(void)
 229{
 230	u32 reg;
 231
 232	reg = lcdc_read(LCD_RASTER_CTRL_REG);
 233	if (reg & LCD_RASTER_ENABLE)
 234		lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
 235}
 236
 237static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
 238{
 239	u32 start;
 240	u32 end;
 241	u32 reg_ras;
 242	u32 reg_dma;
 243
 244	/* init reg to clear PLM (loading mode) fields */
 245	reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
 246	reg_ras &= ~(3 << 20);
 247
 248	reg_dma  = lcdc_read(LCD_DMA_CTRL_REG);
 249
 250	if (load_mode == LOAD_DATA) {
 251		start    = par->dma_start;
 252		end      = par->dma_end;
 253
 254		reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
 255		reg_dma |= LCD_END_OF_FRAME_INT_ENA;
 256		reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
 257
 258		lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
 259		lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
 260		lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
 261		lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
 262	} else if (load_mode == LOAD_PALETTE) {
 263		start    = par->p_palette_base;
 264		end      = start + par->palette_sz - 1;
 265
 266		reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
 267		reg_ras |= LCD_PL_ENABLE;
 268
 269		lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
 270		lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
 271	}
 272
 273	lcdc_write(reg_dma, LCD_DMA_CTRL_REG);
 274	lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
 275
 276	/*
 277	 * The Raster enable bit must be set after all other control fields are
 278	 * set.
 279	 */
 280	lcd_enable_raster();
 281}
 282
 283/* Configure the Burst Size of DMA */
 284static int lcd_cfg_dma(int burst_size)
 285{
 286	u32 reg;
 287
 288	reg = lcdc_read(LCD_DMA_CTRL_REG) & 0x00000001;
 289	switch (burst_size) {
 290	case 1:
 291		reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_1);
 292		break;
 293	case 2:
 294		reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_2);
 295		break;
 296	case 4:
 297		reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_4);
 298		break;
 299	case 8:
 300		reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8);
 301		break;
 302	case 16:
 303		reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
 304		break;
 305	default:
 306		return -EINVAL;
 307	}
 308	lcdc_write(reg, LCD_DMA_CTRL_REG);
 309
 310	return 0;
 311}
 312
 313static void lcd_cfg_ac_bias(int period, int transitions_per_int)
 314{
 315	u32 reg;
 316
 317	/* Set the AC Bias Period and Number of Transisitons per Interrupt */
 318	reg = lcdc_read(LCD_RASTER_TIMING_2_REG) & 0xFFF00000;
 319	reg |= LCD_AC_BIAS_FREQUENCY(period) |
 320		LCD_AC_BIAS_TRANSITIONS_PER_INT(transitions_per_int);
 321	lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
 322}
 323
 324static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width,
 325		int front_porch)
 326{
 327	u32 reg;
 328
 329	reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0xf;
 330	reg |= ((back_porch & 0xff) << 24)
 331	    | ((front_porch & 0xff) << 16)
 332	    | ((pulse_width & 0x3f) << 10);
 333	lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
 334}
 335
 336static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
 337		int front_porch)
 338{
 339	u32 reg;
 340
 341	reg = lcdc_read(LCD_RASTER_TIMING_1_REG) & 0x3ff;
 342	reg |= ((back_porch & 0xff) << 24)
 343	    | ((front_porch & 0xff) << 16)
 344	    | ((pulse_width & 0x3f) << 10);
 345	lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
 346}
 347
 348static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
 349{
 350	u32 reg;
 351
 352	reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
 353						LCD_MONO_8BIT_MODE |
 354						LCD_MONOCHROME_MODE);
 355
 356	switch (cfg->p_disp_panel->panel_shade) {
 357	case MONOCHROME:
 358		reg |= LCD_MONOCHROME_MODE;
 359		if (cfg->mono_8bit_mode)
 360			reg |= LCD_MONO_8BIT_MODE;
 361		break;
 362	case COLOR_ACTIVE:
 363		reg |= LCD_TFT_MODE;
 364		if (cfg->tft_alt_mode)
 365			reg |= LCD_TFT_ALT_ENABLE;
 366		break;
 367
 368	case COLOR_PASSIVE:
 369		if (cfg->stn_565_mode)
 370			reg |= LCD_STN_565_ENABLE;
 371		break;
 372
 373	default:
 374		return -EINVAL;
 375	}
 376
 377	/* enable additional interrupts here */
 378	reg |= LCD_UNDERFLOW_INT_ENA;
 379
 380	lcdc_write(reg, LCD_RASTER_CTRL_REG);
 381
 382	reg = lcdc_read(LCD_RASTER_TIMING_2_REG);
 383
 384	if (cfg->sync_ctrl)
 385		reg |= LCD_SYNC_CTRL;
 386	else
 387		reg &= ~LCD_SYNC_CTRL;
 388
 389	if (cfg->sync_edge)
 390		reg |= LCD_SYNC_EDGE;
 391	else
 392		reg &= ~LCD_SYNC_EDGE;
 393
 394	if (cfg->invert_line_clock)
 395		reg |= LCD_INVERT_LINE_CLOCK;
 396	else
 397		reg &= ~LCD_INVERT_LINE_CLOCK;
 398
 399	if (cfg->invert_frm_clock)
 400		reg |= LCD_INVERT_FRAME_CLOCK;
 401	else
 402		reg &= ~LCD_INVERT_FRAME_CLOCK;
 403
 404	lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
 405
 406	return 0;
 407}
 408
 409static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
 410		u32 bpp, u32 raster_order)
 411{
 412	u32 reg;
 413
 414	/* Set the Panel Width */
 415	/* Pixels per line = (PPL + 1)*16 */
 416	/*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/
 417	width &= 0x3f0;
 418	reg = lcdc_read(LCD_RASTER_TIMING_0_REG);
 419	reg &= 0xfffffc00;
 420	reg |= ((width >> 4) - 1) << 4;
 421	lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
 422
 423	/* Set the Panel Height */
 424	reg = lcdc_read(LCD_RASTER_TIMING_1_REG);
 425	reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00);
 426	lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
 427
 428	/* Set the Raster Order of the Frame Buffer */
 429	reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
 430	if (raster_order)
 431		reg |= LCD_RASTER_ORDER;
 432	lcdc_write(reg, LCD_RASTER_CTRL_REG);
 433
 434	switch (bpp) {
 435	case 1:
 436	case 2:
 437	case 4:
 438	case 16:
 439		par->palette_sz = 16 * 2;
 440		break;
 441
 442	case 8:
 443		par->palette_sz = 256 * 2;
 444		break;
 445
 446	default:
 447		return -EINVAL;
 448	}
 449
 450	return 0;
 451}
 452
 453static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 454			      unsigned blue, unsigned transp,
 455			      struct fb_info *info)
 456{
 457	struct da8xx_fb_par *par = info->par;
 458	unsigned short *palette = (unsigned short *) par->v_palette_base;
 459	u_short pal;
 460	int update_hw = 0;
 461
 462	if (regno > 255)
 463		return 1;
 464
 465	if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
 466		return 1;
 467
 468	if (info->var.bits_per_pixel == 8) {
 469		red >>= 4;
 470		green >>= 8;
 471		blue >>= 12;
 472
 473		pal = (red & 0x0f00);
 474		pal |= (green & 0x00f0);
 475		pal |= (blue & 0x000f);
 476
 477		if (palette[regno] != pal) {
 478			update_hw = 1;
 479			palette[regno] = pal;
 480		}
 481	} else if ((info->var.bits_per_pixel == 16) && regno < 16) {
 482		red >>= (16 - info->var.red.length);
 483		red <<= info->var.red.offset;
 484
 485		green >>= (16 - info->var.green.length);
 486		green <<= info->var.green.offset;
 487
 488		blue >>= (16 - info->var.blue.length);
 489		blue <<= info->var.blue.offset;
 490
 491		par->pseudo_palette[regno] = red | green | blue;
 492
 493		if (palette[0] != 0x4000) {
 494			update_hw = 1;
 495			palette[0] = 0x4000;
 496		}
 497	}
 498
 499	/* Update the palette in the h/w as needed. */
 500	if (update_hw)
 501		lcd_blit(LOAD_PALETTE, par);
 502
 503	return 0;
 504}
 505
 506static void lcd_reset(struct da8xx_fb_par *par)
 507{
 508	/* Disable the Raster if previously Enabled */
 509	lcd_disable_raster();
 510
 511	/* DMA has to be disabled */
 512	lcdc_write(0, LCD_DMA_CTRL_REG);
 513	lcdc_write(0, LCD_RASTER_CTRL_REG);
 514}
 515
 516static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
 517{
 518	unsigned int lcd_clk, div;
 519
 520	lcd_clk = clk_get_rate(par->lcdc_clk);
 521	div = lcd_clk / par->pxl_clk;
 522
 523	/* Configure the LCD clock divisor. */
 524	lcdc_write(LCD_CLK_DIVISOR(div) |
 525			(LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
 526}
 527
 528static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
 529		struct da8xx_panel *panel)
 530{
 531	u32 bpp;
 532	int ret = 0;
 533
 534	lcd_reset(par);
 535
 536	/* Calculate the divider */
 537	lcd_calc_clk_divider(par);
 538
 539	if (panel->invert_pxl_clk)
 540		lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
 541			LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
 542	else
 543		lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) &
 544			~LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
 545
 546	/* Configure the DMA burst size. */
 547	ret = lcd_cfg_dma(cfg->dma_burst_sz);
 548	if (ret < 0)
 549		return ret;
 550
 551	/* Configure the AC bias properties. */
 552	lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
 553
 554	/* Configure the vertical and horizontal sync properties. */
 555	lcd_cfg_vertical_sync(panel->vbp, panel->vsw, panel->vfp);
 556	lcd_cfg_horizontal_sync(panel->hbp, panel->hsw, panel->hfp);
 557
 558	/* Configure for disply */
 559	ret = lcd_cfg_display(cfg);
 560	if (ret < 0)
 561		return ret;
 562
 563	if (QVGA != cfg->p_disp_panel->panel_type)
 564		return -EINVAL;
 565
 566	if (cfg->bpp <= cfg->p_disp_panel->max_bpp &&
 567	    cfg->bpp >= cfg->p_disp_panel->min_bpp)
 568		bpp = cfg->bpp;
 569	else
 570		bpp = cfg->p_disp_panel->max_bpp;
 571	if (bpp == 12)
 572		bpp = 16;
 573	ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->width,
 574				(unsigned int)panel->height, bpp,
 575				cfg->raster_order);
 576	if (ret < 0)
 577		return ret;
 578
 579	/* Configure FDD */
 580	lcdc_write((lcdc_read(LCD_RASTER_CTRL_REG) & 0xfff00fff) |
 581		       (cfg->fdd << 12), LCD_RASTER_CTRL_REG);
 582
 583	return 0;
 584}
 585
 586static irqreturn_t lcdc_irq_handler(int irq, void *arg)
 587{
 588	struct da8xx_fb_par *par = arg;
 589	u32 stat = lcdc_read(LCD_STAT_REG);
 590	u32 reg_ras;
 591
 592	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
 593		lcd_disable_raster();
 594		lcdc_write(stat, LCD_STAT_REG);
 595		lcd_enable_raster();
 596	} else if (stat & LCD_PL_LOAD_DONE) {
 597		/*
 598		 * Must disable raster before changing state of any control bit.
 599		 * And also must be disabled before clearing the PL loading
 600		 * interrupt via the following write to the status register. If
 601		 * this is done after then one gets multiple PL done interrupts.
 602		 */
 603		lcd_disable_raster();
 604
 605		lcdc_write(stat, LCD_STAT_REG);
 606
 607		/* Disable PL completion inerrupt */
 608		reg_ras  = lcdc_read(LCD_RASTER_CTRL_REG);
 609		reg_ras &= ~LCD_PL_ENABLE;
 610		lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
 611
 612		/* Setup and start data loading mode */
 613		lcd_blit(LOAD_DATA, par);
 614	} else {
 615		lcdc_write(stat, LCD_STAT_REG);
 616
 617		if (stat & LCD_END_OF_FRAME0) {
 618			lcdc_write(par->dma_start,
 619				   LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
 620			lcdc_write(par->dma_end,
 621				   LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
 622			par->vsync_flag = 1;
 623			wake_up_interruptible(&par->vsync_wait);
 624		}
 625
 626		if (stat & LCD_END_OF_FRAME1) {
 627			lcdc_write(par->dma_start,
 628				   LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
 629			lcdc_write(par->dma_end,
 630				   LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
 631			par->vsync_flag = 1;
 632			wake_up_interruptible(&par->vsync_wait);
 633		}
 634	}
 635
 636	return IRQ_HANDLED;
 637}
 638
 639static int fb_check_var(struct fb_var_screeninfo *var,
 640			struct fb_info *info)
 641{
 642	int err = 0;
 643
 644	switch (var->bits_per_pixel) {
 645	case 1:
 646	case 8:
 647		var->red.offset = 0;
 648		var->red.length = 8;
 649		var->green.offset = 0;
 650		var->green.length = 8;
 651		var->blue.offset = 0;
 652		var->blue.length = 8;
 653		var->transp.offset = 0;
 654		var->transp.length = 0;
 655		break;
 656	case 4:
 657		var->red.offset = 0;
 658		var->red.length = 4;
 659		var->green.offset = 0;
 660		var->green.length = 4;
 661		var->blue.offset = 0;
 662		var->blue.length = 4;
 663		var->transp.offset = 0;
 664		var->transp.length = 0;
 665		break;
 666	case 16:		/* RGB 565 */
 667		var->red.offset = 11;
 668		var->red.length = 5;
 669		var->green.offset = 5;
 670		var->green.length = 6;
 671		var->blue.offset = 0;
 672		var->blue.length = 5;
 673		var->transp.offset = 0;
 674		var->transp.length = 0;
 675		break;
 676	default:
 677		err = -EINVAL;
 678	}
 679
 680	var->red.msb_right = 0;
 681	var->green.msb_right = 0;
 682	var->blue.msb_right = 0;
 683	var->transp.msb_right = 0;
 684	return err;
 685}
 686
 687#ifdef CONFIG_CPU_FREQ
 688static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
 689				     unsigned long val, void *data)
 690{
 691	struct da8xx_fb_par *par;
 692
 693	par = container_of(nb, struct da8xx_fb_par, freq_transition);
 694	if (val == CPUFREQ_PRECHANGE) {
 695		lcd_disable_raster();
 696	} else if (val == CPUFREQ_POSTCHANGE) {
 697		lcd_calc_clk_divider(par);
 698		lcd_enable_raster();
 699	}
 700
 701	return 0;
 702}
 703
 704static inline int lcd_da8xx_cpufreq_register(struct da8xx_fb_par *par)
 705{
 706	par->freq_transition.notifier_call = lcd_da8xx_cpufreq_transition;
 707
 708	return cpufreq_register_notifier(&par->freq_transition,
 709					 CPUFREQ_TRANSITION_NOTIFIER);
 710}
 711
 712static inline void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par)
 713{
 714	cpufreq_unregister_notifier(&par->freq_transition,
 715				    CPUFREQ_TRANSITION_NOTIFIER);
 716}
 717#endif
 718
 719static int __devexit fb_remove(struct platform_device *dev)
 720{
 721	struct fb_info *info = dev_get_drvdata(&dev->dev);
 722
 723	if (info) {
 724		struct da8xx_fb_par *par = info->par;
 725
 726#ifdef CONFIG_CPU_FREQ
 727		lcd_da8xx_cpufreq_deregister(par);
 728#endif
 729		if (par->panel_power_ctrl)
 730			par->panel_power_ctrl(0);
 731
 732		lcd_disable_raster();
 733		lcdc_write(0, LCD_RASTER_CTRL_REG);
 734
 735		/* disable DMA  */
 736		lcdc_write(0, LCD_DMA_CTRL_REG);
 737
 738		unregister_framebuffer(info);
 739		fb_dealloc_cmap(&info->cmap);
 740		dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base,
 741				  par->p_palette_base);
 742		dma_free_coherent(NULL, par->vram_size, par->vram_virt,
 743				  par->vram_phys);
 744		free_irq(par->irq, par);
 745		clk_disable(par->lcdc_clk);
 746		clk_put(par->lcdc_clk);
 747		framebuffer_release(info);
 748		iounmap((void __iomem *)da8xx_fb_reg_base);
 749		release_mem_region(lcdc_regs->start, resource_size(lcdc_regs));
 750
 751	}
 752	return 0;
 753}
 754
 755/*
 756 * Function to wait for vertical sync which for this LCD peripheral
 757 * translates into waiting for the current raster frame to complete.
 758 */
 759static int fb_wait_for_vsync(struct fb_info *info)
 760{
 761	struct da8xx_fb_par *par = info->par;
 762	int ret;
 763
 764	/*
 765	 * Set flag to 0 and wait for isr to set to 1. It would seem there is a
 766	 * race condition here where the ISR could have occurred just before or
 767	 * just after this set. But since we are just coarsely waiting for
 768	 * a frame to complete then that's OK. i.e. if the frame completed
 769	 * just before this code executed then we have to wait another full
 770	 * frame time but there is no way to avoid such a situation. On the
 771	 * other hand if the frame completed just after then we don't need
 772	 * to wait long at all. Either way we are guaranteed to return to the
 773	 * user immediately after a frame completion which is all that is
 774	 * required.
 775	 */
 776	par->vsync_flag = 0;
 777	ret = wait_event_interruptible_timeout(par->vsync_wait,
 778					       par->vsync_flag != 0,
 779					       par->vsync_timeout);
 780	if (ret < 0)
 781		return ret;
 782	if (ret == 0)
 783		return -ETIMEDOUT;
 784
 785	return 0;
 786}
 787
 788static int fb_ioctl(struct fb_info *info, unsigned int cmd,
 789			  unsigned long arg)
 790{
 791	struct lcd_sync_arg sync_arg;
 792
 793	switch (cmd) {
 794	case FBIOGET_CONTRAST:
 795	case FBIOPUT_CONTRAST:
 796	case FBIGET_BRIGHTNESS:
 797	case FBIPUT_BRIGHTNESS:
 798	case FBIGET_COLOR:
 799	case FBIPUT_COLOR:
 800		return -ENOTTY;
 801	case FBIPUT_HSYNC:
 802		if (copy_from_user(&sync_arg, (char *)arg,
 803				sizeof(struct lcd_sync_arg)))
 804			return -EFAULT;
 805		lcd_cfg_horizontal_sync(sync_arg.back_porch,
 806					sync_arg.pulse_width,
 807					sync_arg.front_porch);
 808		break;
 809	case FBIPUT_VSYNC:
 810		if (copy_from_user(&sync_arg, (char *)arg,
 811				sizeof(struct lcd_sync_arg)))
 812			return -EFAULT;
 813		lcd_cfg_vertical_sync(sync_arg.back_porch,
 814					sync_arg.pulse_width,
 815					sync_arg.front_porch);
 816		break;
 817	case FBIO_WAITFORVSYNC:
 818		return fb_wait_for_vsync(info);
 819	default:
 820		return -EINVAL;
 821	}
 822	return 0;
 823}
 824
 825static int cfb_blank(int blank, struct fb_info *info)
 826{
 827	struct da8xx_fb_par *par = info->par;
 828	int ret = 0;
 829
 830	if (par->blank == blank)
 831		return 0;
 832
 833	par->blank = blank;
 834	switch (blank) {
 835	case FB_BLANK_UNBLANK:
 836		if (par->panel_power_ctrl)
 837			par->panel_power_ctrl(1);
 838
 839		lcd_enable_raster();
 840		break;
 841	case FB_BLANK_POWERDOWN:
 842		if (par->panel_power_ctrl)
 843			par->panel_power_ctrl(0);
 844
 845		lcd_disable_raster();
 846		break;
 847	default:
 848		ret = -EINVAL;
 849	}
 850
 851	return ret;
 852}
 853
 854/*
 855 * Set new x,y offsets in the virtual display for the visible area and switch
 856 * to the new mode.
 857 */
 858static int da8xx_pan_display(struct fb_var_screeninfo *var,
 859			     struct fb_info *fbi)
 860{
 861	int ret = 0;
 862	struct fb_var_screeninfo new_var;
 863	struct da8xx_fb_par         *par = fbi->par;
 864	struct fb_fix_screeninfo    *fix = &fbi->fix;
 865	unsigned int end;
 866	unsigned int start;
 867
 868	if (var->xoffset != fbi->var.xoffset ||
 869			var->yoffset != fbi->var.yoffset) {
 870		memcpy(&new_var, &fbi->var, sizeof(new_var));
 871		new_var.xoffset = var->xoffset;
 872		new_var.yoffset = var->yoffset;
 873		if (fb_check_var(&new_var, fbi))
 874			ret = -EINVAL;
 875		else {
 876			memcpy(&fbi->var, &new_var, sizeof(new_var));
 877
 878			start	= fix->smem_start +
 879				new_var.yoffset * fix->line_length +
 880				new_var.xoffset * var->bits_per_pixel / 8;
 881			end	= start + var->yres * fix->line_length - 1;
 882			par->dma_start	= start;
 883			par->dma_end	= end;
 884		}
 885	}
 886
 887	return ret;
 888}
 889
 890static struct fb_ops da8xx_fb_ops = {
 891	.owner = THIS_MODULE,
 892	.fb_check_var = fb_check_var,
 893	.fb_setcolreg = fb_setcolreg,
 894	.fb_pan_display = da8xx_pan_display,
 895	.fb_ioctl = fb_ioctl,
 896	.fb_fillrect = cfb_fillrect,
 897	.fb_copyarea = cfb_copyarea,
 898	.fb_imageblit = cfb_imageblit,
 899	.fb_blank = cfb_blank,
 900};
 901
 902static int __devinit fb_probe(struct platform_device *device)
 903{
 904	struct da8xx_lcdc_platform_data *fb_pdata =
 905						device->dev.platform_data;
 906	struct lcd_ctrl_config *lcd_cfg;
 907	struct da8xx_panel *lcdc_info;
 908	struct fb_info *da8xx_fb_info;
 909	struct clk *fb_clk = NULL;
 910	struct da8xx_fb_par *par;
 911	resource_size_t len;
 912	int ret, i;
 913
 914	if (fb_pdata == NULL) {
 915		dev_err(&device->dev, "Can not get platform data\n");
 916		return -ENOENT;
 917	}
 918
 919	lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
 920	if (!lcdc_regs) {
 921		dev_err(&device->dev,
 922			"Can not get memory resource for LCD controller\n");
 923		return -ENOENT;
 924	}
 925
 926	len = resource_size(lcdc_regs);
 927
 928	lcdc_regs = request_mem_region(lcdc_regs->start, len, lcdc_regs->name);
 929	if (!lcdc_regs)
 930		return -EBUSY;
 931
 932	da8xx_fb_reg_base = (resource_size_t)ioremap(lcdc_regs->start, len);
 933	if (!da8xx_fb_reg_base) {
 934		ret = -EBUSY;
 935		goto err_request_mem;
 936	}
 937
 938	fb_clk = clk_get(&device->dev, NULL);
 939	if (IS_ERR(fb_clk)) {
 940		dev_err(&device->dev, "Can not get device clock\n");
 941		ret = -ENODEV;
 942		goto err_ioremap;
 943	}
 944	ret = clk_enable(fb_clk);
 945	if (ret)
 946		goto err_clk_put;
 947
 948	for (i = 0, lcdc_info = known_lcd_panels;
 949		i < ARRAY_SIZE(known_lcd_panels);
 950		i++, lcdc_info++) {
 951		if (strcmp(fb_pdata->type, lcdc_info->name) == 0)
 952			break;
 953	}
 954
 955	if (i == ARRAY_SIZE(known_lcd_panels)) {
 956		dev_err(&device->dev, "GLCD: No valid panel found\n");
 957		ret = -ENODEV;
 958		goto err_clk_disable;
 959	} else
 960		dev_info(&device->dev, "GLCD: Found %s panel\n",
 961					fb_pdata->type);
 962
 963	lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
 964
 965	da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par),
 966					&device->dev);
 967	if (!da8xx_fb_info) {
 968		dev_dbg(&device->dev, "Memory allocation failed for fb_info\n");
 969		ret = -ENOMEM;
 970		goto err_clk_disable;
 971	}
 972
 973	par = da8xx_fb_info->par;
 974	par->lcdc_clk = fb_clk;
 975	par->pxl_clk = lcdc_info->pxl_clk;
 976	if (fb_pdata->panel_power_ctrl) {
 977		par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
 978		par->panel_power_ctrl(1);
 979	}
 980
 981	if (lcd_init(par, lcd_cfg, lcdc_info) < 0) {
 982		dev_err(&device->dev, "lcd_init failed\n");
 983		ret = -EFAULT;
 984		goto err_release_fb;
 985	}
 986
 987	/* allocate frame buffer */
 988	par->vram_size = lcdc_info->width * lcdc_info->height * lcd_cfg->bpp;
 989	par->vram_size = PAGE_ALIGN(par->vram_size/8);
 990	par->vram_size = par->vram_size * LCD_NUM_BUFFERS;
 991
 992	par->vram_virt = dma_alloc_coherent(NULL,
 993					    par->vram_size,
 994					    (resource_size_t *) &par->vram_phys,
 995					    GFP_KERNEL | GFP_DMA);
 996	if (!par->vram_virt) {
 997		dev_err(&device->dev,
 998			"GLCD: kmalloc for frame buffer failed\n");
 999		ret = -EINVAL;
1000		goto err_release_fb;
1001	}
1002
1003	da8xx_fb_info->screen_base = (char __iomem *) par->vram_virt;
1004	da8xx_fb_fix.smem_start    = par->vram_phys;
1005	da8xx_fb_fix.smem_len      = par->vram_size;
1006	da8xx_fb_fix.line_length   = (lcdc_info->width * lcd_cfg->bpp) / 8;
1007
1008	par->dma_start = par->vram_phys;
1009	par->dma_end   = par->dma_start + lcdc_info->height *
1010		da8xx_fb_fix.line_length - 1;
1011
1012	/* allocate palette buffer */
1013	par->v_palette_base = dma_alloc_coherent(NULL,
1014					       PALETTE_SIZE,
1015					       (resource_size_t *)
1016					       &par->p_palette_base,
1017					       GFP_KERNEL | GFP_DMA);
1018	if (!par->v_palette_base) {
1019		dev_err(&device->dev,
1020			"GLCD: kmalloc for palette buffer failed\n");
1021		ret = -EINVAL;
1022		goto err_release_fb_mem;
1023	}
1024	memset(par->v_palette_base, 0, PALETTE_SIZE);
1025
1026	par->irq = platform_get_irq(device, 0);
1027	if (par->irq < 0) {
1028		ret = -ENOENT;
1029		goto err_release_pl_mem;
1030	}
1031
1032	/* Initialize par */
1033	da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
1034
1035	da8xx_fb_var.xres = lcdc_info->width;
1036	da8xx_fb_var.xres_virtual = lcdc_info->width;
1037
1038	da8xx_fb_var.yres         = lcdc_info->height;
1039	da8xx_fb_var.yres_virtual = lcdc_info->height * LCD_NUM_BUFFERS;
1040
1041	da8xx_fb_var.grayscale =
1042	    lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0;
1043	da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
1044
1045	da8xx_fb_var.hsync_len = lcdc_info->hsw;
1046	da8xx_fb_var.vsync_len = lcdc_info->vsw;
1047
1048	/* Initialize fbinfo */
1049	da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
1050	da8xx_fb_info->fix = da8xx_fb_fix;
1051	da8xx_fb_info->var = da8xx_fb_var;
1052	da8xx_fb_info->fbops = &da8xx_fb_ops;
1053	da8xx_fb_info->pseudo_palette = par->pseudo_palette;
1054	da8xx_fb_info->fix.visual = (da8xx_fb_info->var.bits_per_pixel <= 8) ?
1055				FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
1056
1057	ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
1058	if (ret)
1059		goto err_release_pl_mem;
1060	da8xx_fb_info->cmap.len = par->palette_sz;
1061
1062	/* initialize var_screeninfo */
1063	da8xx_fb_var.activate = FB_ACTIVATE_FORCE;
1064	fb_set_var(da8xx_fb_info, &da8xx_fb_var);
1065
1066	dev_set_drvdata(&device->dev, da8xx_fb_info);
1067
1068	/* initialize the vsync wait queue */
1069	init_waitqueue_head(&par->vsync_wait);
1070	par->vsync_timeout = HZ / 5;
1071
1072	/* Register the Frame Buffer  */
1073	if (register_framebuffer(da8xx_fb_info) < 0) {
1074		dev_err(&device->dev,
1075			"GLCD: Frame Buffer Registration Failed!\n");
1076		ret = -EINVAL;
1077		goto err_dealloc_cmap;
1078	}
1079
1080#ifdef CONFIG_CPU_FREQ
1081	ret = lcd_da8xx_cpufreq_register(par);
1082	if (ret) {
1083		dev_err(&device->dev, "failed to register cpufreq\n");
1084		goto err_cpu_freq;
1085	}
1086#endif
1087
1088	ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
1089	if (ret)
1090		goto irq_freq;
1091	return 0;
1092
1093irq_freq:
1094#ifdef CONFIG_CPU_FREQ
1095	lcd_da8xx_cpufreq_deregister(par);
1096#endif
1097err_cpu_freq:
1098	unregister_framebuffer(da8xx_fb_info);
1099
1100err_dealloc_cmap:
1101	fb_dealloc_cmap(&da8xx_fb_info->cmap);
1102
1103err_release_pl_mem:
1104	dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base,
1105			  par->p_palette_base);
1106
1107err_release_fb_mem:
1108	dma_free_coherent(NULL, par->vram_size, par->vram_virt, par->vram_phys);
1109
1110err_release_fb:
1111	framebuffer_release(da8xx_fb_info);
1112
1113err_clk_disable:
1114	clk_disable(fb_clk);
1115
1116err_clk_put:
1117	clk_put(fb_clk);
1118
1119err_ioremap:
1120	iounmap((void __iomem *)da8xx_fb_reg_base);
1121
1122err_request_mem:
1123	release_mem_region(lcdc_regs->start, len);
1124
1125	return ret;
1126}
1127
1128#ifdef CONFIG_PM
1129static int fb_suspend(struct platform_device *dev, pm_message_t state)
1130{
1131	struct fb_info *info = platform_get_drvdata(dev);
1132	struct da8xx_fb_par *par = info->par;
1133
1134	console_lock();
1135	if (par->panel_power_ctrl)
1136		par->panel_power_ctrl(0);
1137
1138	fb_set_suspend(info, 1);
1139	lcd_disable_raster();
1140	clk_disable(par->lcdc_clk);
1141	console_unlock();
1142
1143	return 0;
1144}
1145static int fb_resume(struct platform_device *dev)
1146{
1147	struct fb_info *info = platform_get_drvdata(dev);
1148	struct da8xx_fb_par *par = info->par;
1149
1150	console_lock();
1151	if (par->panel_power_ctrl)
1152		par->panel_power_ctrl(1);
1153
1154	clk_enable(par->lcdc_clk);
1155	lcd_enable_raster();
1156	fb_set_suspend(info, 0);
1157	console_unlock();
1158
1159	return 0;
1160}
1161#else
1162#define fb_suspend NULL
1163#define fb_resume NULL
1164#endif
1165
1166static struct platform_driver da8xx_fb_driver = {
1167	.probe = fb_probe,
1168	.remove = __devexit_p(fb_remove),
1169	.suspend = fb_suspend,
1170	.resume = fb_resume,
1171	.driver = {
1172		   .name = DRIVER_NAME,
1173		   .owner = THIS_MODULE,
1174		   },
1175};
1176
1177static int __init da8xx_fb_init(void)
1178{
1179	return platform_driver_register(&da8xx_fb_driver);
1180}
1181
1182static void __exit da8xx_fb_cleanup(void)
1183{
1184	platform_driver_unregister(&da8xx_fb_driver);
1185}
1186
1187module_init(da8xx_fb_init);
1188module_exit(da8xx_fb_cleanup);
1189
1190MODULE_DESCRIPTION("Framebuffer driver for TI da8xx/omap-l1xx");
1191MODULE_AUTHOR("Texas Instruments");
1192MODULE_LICENSE("GPL");