mx3fb.c (44249B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2008 4 * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de> 5 * 6 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. 7 */ 8 9#include <linux/module.h> 10#include <linux/kernel.h> 11#include <linux/platform_device.h> 12#include <linux/sched.h> 13#include <linux/errno.h> 14#include <linux/string.h> 15#include <linux/interrupt.h> 16#include <linux/slab.h> 17#include <linux/fb.h> 18#include <linux/delay.h> 19#include <linux/init.h> 20#include <linux/ioport.h> 21#include <linux/dma-mapping.h> 22#include <linux/dmaengine.h> 23#include <linux/console.h> 24#include <linux/clk.h> 25#include <linux/mutex.h> 26#include <linux/dma/ipu-dma.h> 27#include <linux/backlight.h> 28 29#include <linux/dma/imx-dma.h> 30#include <linux/platform_data/video-mx3fb.h> 31 32#include <asm/io.h> 33#include <linux/uaccess.h> 34 35#define MX3FB_NAME "mx3_sdc_fb" 36 37#define MX3FB_REG_OFFSET 0xB4 38 39/* SDC Registers */ 40#define SDC_COM_CONF (0xB4 - MX3FB_REG_OFFSET) 41#define SDC_GW_CTRL (0xB8 - MX3FB_REG_OFFSET) 42#define SDC_FG_POS (0xBC - MX3FB_REG_OFFSET) 43#define SDC_BG_POS (0xC0 - MX3FB_REG_OFFSET) 44#define SDC_CUR_POS (0xC4 - MX3FB_REG_OFFSET) 45#define SDC_PWM_CTRL (0xC8 - MX3FB_REG_OFFSET) 46#define SDC_CUR_MAP (0xCC - MX3FB_REG_OFFSET) 47#define SDC_HOR_CONF (0xD0 - MX3FB_REG_OFFSET) 48#define SDC_VER_CONF (0xD4 - MX3FB_REG_OFFSET) 49#define SDC_SHARP_CONF_1 (0xD8 - MX3FB_REG_OFFSET) 50#define SDC_SHARP_CONF_2 (0xDC - MX3FB_REG_OFFSET) 51 52/* Register bits */ 53#define SDC_COM_TFT_COLOR 0x00000001UL 54#define SDC_COM_FG_EN 0x00000010UL 55#define SDC_COM_GWSEL 0x00000020UL 56#define SDC_COM_GLB_A 0x00000040UL 57#define SDC_COM_KEY_COLOR_G 0x00000080UL 58#define SDC_COM_BG_EN 0x00000200UL 59#define SDC_COM_SHARP 0x00001000UL 60 61#define SDC_V_SYNC_WIDTH_L 0x00000001UL 62 63/* Display Interface registers */ 64#define DI_DISP_IF_CONF (0x0124 - MX3FB_REG_OFFSET) 65#define DI_DISP_SIG_POL (0x0128 - MX3FB_REG_OFFSET) 66#define DI_SER_DISP1_CONF (0x012C - MX3FB_REG_OFFSET) 67#define DI_SER_DISP2_CONF (0x0130 - MX3FB_REG_OFFSET) 68#define DI_HSP_CLK_PER (0x0134 - MX3FB_REG_OFFSET) 69#define DI_DISP0_TIME_CONF_1 (0x0138 - MX3FB_REG_OFFSET) 70#define DI_DISP0_TIME_CONF_2 (0x013C - MX3FB_REG_OFFSET) 71#define DI_DISP0_TIME_CONF_3 (0x0140 - MX3FB_REG_OFFSET) 72#define DI_DISP1_TIME_CONF_1 (0x0144 - MX3FB_REG_OFFSET) 73#define DI_DISP1_TIME_CONF_2 (0x0148 - MX3FB_REG_OFFSET) 74#define DI_DISP1_TIME_CONF_3 (0x014C - MX3FB_REG_OFFSET) 75#define DI_DISP2_TIME_CONF_1 (0x0150 - MX3FB_REG_OFFSET) 76#define DI_DISP2_TIME_CONF_2 (0x0154 - MX3FB_REG_OFFSET) 77#define DI_DISP2_TIME_CONF_3 (0x0158 - MX3FB_REG_OFFSET) 78#define DI_DISP3_TIME_CONF (0x015C - MX3FB_REG_OFFSET) 79#define DI_DISP0_DB0_MAP (0x0160 - MX3FB_REG_OFFSET) 80#define DI_DISP0_DB1_MAP (0x0164 - MX3FB_REG_OFFSET) 81#define DI_DISP0_DB2_MAP (0x0168 - MX3FB_REG_OFFSET) 82#define DI_DISP0_CB0_MAP (0x016C - MX3FB_REG_OFFSET) 83#define DI_DISP0_CB1_MAP (0x0170 - MX3FB_REG_OFFSET) 84#define DI_DISP0_CB2_MAP (0x0174 - MX3FB_REG_OFFSET) 85#define DI_DISP1_DB0_MAP (0x0178 - MX3FB_REG_OFFSET) 86#define DI_DISP1_DB1_MAP (0x017C - MX3FB_REG_OFFSET) 87#define DI_DISP1_DB2_MAP (0x0180 - MX3FB_REG_OFFSET) 88#define DI_DISP1_CB0_MAP (0x0184 - MX3FB_REG_OFFSET) 89#define DI_DISP1_CB1_MAP (0x0188 - MX3FB_REG_OFFSET) 90#define DI_DISP1_CB2_MAP (0x018C - MX3FB_REG_OFFSET) 91#define DI_DISP2_DB0_MAP (0x0190 - MX3FB_REG_OFFSET) 92#define DI_DISP2_DB1_MAP (0x0194 - MX3FB_REG_OFFSET) 93#define DI_DISP2_DB2_MAP (0x0198 - MX3FB_REG_OFFSET) 94#define DI_DISP2_CB0_MAP (0x019C - MX3FB_REG_OFFSET) 95#define DI_DISP2_CB1_MAP (0x01A0 - MX3FB_REG_OFFSET) 96#define DI_DISP2_CB2_MAP (0x01A4 - MX3FB_REG_OFFSET) 97#define DI_DISP3_B0_MAP (0x01A8 - MX3FB_REG_OFFSET) 98#define DI_DISP3_B1_MAP (0x01AC - MX3FB_REG_OFFSET) 99#define DI_DISP3_B2_MAP (0x01B0 - MX3FB_REG_OFFSET) 100#define DI_DISP_ACC_CC (0x01B4 - MX3FB_REG_OFFSET) 101#define DI_DISP_LLA_CONF (0x01B8 - MX3FB_REG_OFFSET) 102#define DI_DISP_LLA_DATA (0x01BC - MX3FB_REG_OFFSET) 103 104/* DI_DISP_SIG_POL bits */ 105#define DI_D3_VSYNC_POL_SHIFT 28 106#define DI_D3_HSYNC_POL_SHIFT 27 107#define DI_D3_DRDY_SHARP_POL_SHIFT 26 108#define DI_D3_CLK_POL_SHIFT 25 109#define DI_D3_DATA_POL_SHIFT 24 110 111/* DI_DISP_IF_CONF bits */ 112#define DI_D3_CLK_IDLE_SHIFT 26 113#define DI_D3_CLK_SEL_SHIFT 25 114#define DI_D3_DATAMSK_SHIFT 24 115 116enum ipu_panel { 117 IPU_PANEL_SHARP_TFT, 118 IPU_PANEL_TFT, 119}; 120 121struct ipu_di_signal_cfg { 122 unsigned datamask_en:1; 123 unsigned clksel_en:1; 124 unsigned clkidle_en:1; 125 unsigned data_pol:1; /* true = inverted */ 126 unsigned clk_pol:1; /* true = rising edge */ 127 unsigned enable_pol:1; 128 unsigned Hsync_pol:1; /* true = active high */ 129 unsigned Vsync_pol:1; 130}; 131 132static const struct fb_videomode mx3fb_modedb[] = { 133 { 134 /* 240x320 @ 60 Hz */ 135 .name = "Sharp-QVGA", 136 .refresh = 60, 137 .xres = 240, 138 .yres = 320, 139 .pixclock = 185925, 140 .left_margin = 9, 141 .right_margin = 16, 142 .upper_margin = 7, 143 .lower_margin = 9, 144 .hsync_len = 1, 145 .vsync_len = 1, 146 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | 147 FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT | 148 FB_SYNC_CLK_IDLE_EN, 149 .vmode = FB_VMODE_NONINTERLACED, 150 .flag = 0, 151 }, { 152 /* 240x33 @ 60 Hz */ 153 .name = "Sharp-CLI", 154 .refresh = 60, 155 .xres = 240, 156 .yres = 33, 157 .pixclock = 185925, 158 .left_margin = 9, 159 .right_margin = 16, 160 .upper_margin = 7, 161 .lower_margin = 9 + 287, 162 .hsync_len = 1, 163 .vsync_len = 1, 164 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | 165 FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT | 166 FB_SYNC_CLK_IDLE_EN, 167 .vmode = FB_VMODE_NONINTERLACED, 168 .flag = 0, 169 }, { 170 /* 640x480 @ 60 Hz */ 171 .name = "NEC-VGA", 172 .refresh = 60, 173 .xres = 640, 174 .yres = 480, 175 .pixclock = 38255, 176 .left_margin = 144, 177 .right_margin = 0, 178 .upper_margin = 34, 179 .lower_margin = 40, 180 .hsync_len = 1, 181 .vsync_len = 1, 182 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, 183 .vmode = FB_VMODE_NONINTERLACED, 184 .flag = 0, 185 }, { 186 /* NTSC TV output */ 187 .name = "TV-NTSC", 188 .refresh = 60, 189 .xres = 640, 190 .yres = 480, 191 .pixclock = 37538, 192 .left_margin = 38, 193 .right_margin = 858 - 640 - 38 - 3, 194 .upper_margin = 36, 195 .lower_margin = 518 - 480 - 36 - 1, 196 .hsync_len = 3, 197 .vsync_len = 1, 198 .sync = 0, 199 .vmode = FB_VMODE_NONINTERLACED, 200 .flag = 0, 201 }, { 202 /* PAL TV output */ 203 .name = "TV-PAL", 204 .refresh = 50, 205 .xres = 640, 206 .yres = 480, 207 .pixclock = 37538, 208 .left_margin = 38, 209 .right_margin = 960 - 640 - 38 - 32, 210 .upper_margin = 32, 211 .lower_margin = 555 - 480 - 32 - 3, 212 .hsync_len = 32, 213 .vsync_len = 3, 214 .sync = 0, 215 .vmode = FB_VMODE_NONINTERLACED, 216 .flag = 0, 217 }, { 218 /* TV output VGA mode, 640x480 @ 65 Hz */ 219 .name = "TV-VGA", 220 .refresh = 60, 221 .xres = 640, 222 .yres = 480, 223 .pixclock = 40574, 224 .left_margin = 35, 225 .right_margin = 45, 226 .upper_margin = 9, 227 .lower_margin = 1, 228 .hsync_len = 46, 229 .vsync_len = 5, 230 .sync = 0, 231 .vmode = FB_VMODE_NONINTERLACED, 232 .flag = 0, 233 }, 234}; 235 236struct mx3fb_data { 237 struct fb_info *fbi; 238 int backlight_level; 239 void __iomem *reg_base; 240 spinlock_t lock; 241 struct device *dev; 242 struct backlight_device *bl; 243 244 uint32_t h_start_width; 245 uint32_t v_start_width; 246 enum disp_data_mapping disp_data_fmt; 247}; 248 249struct dma_chan_request { 250 struct mx3fb_data *mx3fb; 251 enum ipu_channel id; 252}; 253 254/* MX3 specific framebuffer information. */ 255struct mx3fb_info { 256 int blank; 257 enum ipu_channel ipu_ch; 258 uint32_t cur_ipu_buf; 259 260 u32 pseudo_palette[16]; 261 262 struct completion flip_cmpl; 263 struct mutex mutex; /* Protects fb-ops */ 264 struct mx3fb_data *mx3fb; 265 struct idmac_channel *idmac_channel; 266 struct dma_async_tx_descriptor *txd; 267 dma_cookie_t cookie; 268 struct scatterlist sg[2]; 269 270 struct fb_var_screeninfo cur_var; /* current var info */ 271}; 272 273static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value); 274static u32 sdc_get_brightness(struct mx3fb_data *mx3fb); 275 276static int mx3fb_bl_get_brightness(struct backlight_device *bl) 277{ 278 struct mx3fb_data *fbd = bl_get_data(bl); 279 280 return sdc_get_brightness(fbd); 281} 282 283static int mx3fb_bl_update_status(struct backlight_device *bl) 284{ 285 struct mx3fb_data *fbd = bl_get_data(bl); 286 int brightness = bl->props.brightness; 287 288 if (bl->props.power != FB_BLANK_UNBLANK) 289 brightness = 0; 290 if (bl->props.fb_blank != FB_BLANK_UNBLANK) 291 brightness = 0; 292 293 fbd->backlight_level = (fbd->backlight_level & ~0xFF) | brightness; 294 295 sdc_set_brightness(fbd, fbd->backlight_level); 296 297 return 0; 298} 299 300static const struct backlight_ops mx3fb_lcdc_bl_ops = { 301 .update_status = mx3fb_bl_update_status, 302 .get_brightness = mx3fb_bl_get_brightness, 303}; 304 305static void mx3fb_init_backlight(struct mx3fb_data *fbd) 306{ 307 struct backlight_properties props; 308 struct backlight_device *bl; 309 310 if (fbd->bl) 311 return; 312 313 memset(&props, 0, sizeof(struct backlight_properties)); 314 props.max_brightness = 0xff; 315 props.type = BACKLIGHT_RAW; 316 sdc_set_brightness(fbd, fbd->backlight_level); 317 318 bl = backlight_device_register("mx3fb-bl", fbd->dev, fbd, 319 &mx3fb_lcdc_bl_ops, &props); 320 if (IS_ERR(bl)) { 321 dev_err(fbd->dev, "error %ld on backlight register\n", 322 PTR_ERR(bl)); 323 return; 324 } 325 326 fbd->bl = bl; 327 bl->props.power = FB_BLANK_UNBLANK; 328 bl->props.fb_blank = FB_BLANK_UNBLANK; 329 bl->props.brightness = mx3fb_bl_get_brightness(bl); 330} 331 332static void mx3fb_exit_backlight(struct mx3fb_data *fbd) 333{ 334 backlight_device_unregister(fbd->bl); 335} 336 337static void mx3fb_dma_done(void *); 338 339/* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */ 340static const char *fb_mode; 341static unsigned long default_bpp = 16; 342 343static u32 mx3fb_read_reg(struct mx3fb_data *mx3fb, unsigned long reg) 344{ 345 return __raw_readl(mx3fb->reg_base + reg); 346} 347 348static void mx3fb_write_reg(struct mx3fb_data *mx3fb, u32 value, unsigned long reg) 349{ 350 __raw_writel(value, mx3fb->reg_base + reg); 351} 352 353struct di_mapping { 354 uint32_t b0, b1, b2; 355}; 356 357static const struct di_mapping di_mappings[] = { 358 [IPU_DISP_DATA_MAPPING_RGB666] = { 0x0005000f, 0x000b000f, 0x0011000f }, 359 [IPU_DISP_DATA_MAPPING_RGB565] = { 0x0004003f, 0x000a000f, 0x000f003f }, 360 [IPU_DISP_DATA_MAPPING_RGB888] = { 0x00070000, 0x000f0000, 0x00170000 }, 361}; 362 363static void sdc_fb_init(struct mx3fb_info *fbi) 364{ 365 struct mx3fb_data *mx3fb = fbi->mx3fb; 366 uint32_t reg; 367 368 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 369 370 mx3fb_write_reg(mx3fb, reg | SDC_COM_BG_EN, SDC_COM_CONF); 371} 372 373/* Returns enabled flag before uninit */ 374static uint32_t sdc_fb_uninit(struct mx3fb_info *fbi) 375{ 376 struct mx3fb_data *mx3fb = fbi->mx3fb; 377 uint32_t reg; 378 379 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 380 381 mx3fb_write_reg(mx3fb, reg & ~SDC_COM_BG_EN, SDC_COM_CONF); 382 383 return reg & SDC_COM_BG_EN; 384} 385 386static void sdc_enable_channel(struct mx3fb_info *mx3_fbi) 387{ 388 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; 389 struct idmac_channel *ichan = mx3_fbi->idmac_channel; 390 struct dma_chan *dma_chan = &ichan->dma_chan; 391 unsigned long flags; 392 dma_cookie_t cookie; 393 394 if (mx3_fbi->txd) 395 dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi, 396 to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg); 397 else 398 dev_dbg(mx3fb->dev, "mx3fbi %p, txd = NULL\n", mx3_fbi); 399 400 /* This enables the channel */ 401 if (mx3_fbi->cookie < 0) { 402 mx3_fbi->txd = dmaengine_prep_slave_sg(dma_chan, 403 &mx3_fbi->sg[0], 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); 404 if (!mx3_fbi->txd) { 405 dev_err(mx3fb->dev, "Cannot allocate descriptor on %d\n", 406 dma_chan->chan_id); 407 return; 408 } 409 410 mx3_fbi->txd->callback_param = mx3_fbi->txd; 411 mx3_fbi->txd->callback = mx3fb_dma_done; 412 413 cookie = mx3_fbi->txd->tx_submit(mx3_fbi->txd); 414 dev_dbg(mx3fb->dev, "%d: Submit %p #%d [%c]\n", __LINE__, 415 mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); 416 } else { 417 if (!mx3_fbi->txd || !mx3_fbi->txd->tx_submit) { 418 dev_err(mx3fb->dev, "Cannot enable channel %d\n", 419 dma_chan->chan_id); 420 return; 421 } 422 423 /* Just re-activate the same buffer */ 424 dma_async_issue_pending(dma_chan); 425 cookie = mx3_fbi->cookie; 426 dev_dbg(mx3fb->dev, "%d: Re-submit %p #%d [%c]\n", __LINE__, 427 mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); 428 } 429 430 if (cookie >= 0) { 431 spin_lock_irqsave(&mx3fb->lock, flags); 432 sdc_fb_init(mx3_fbi); 433 mx3_fbi->cookie = cookie; 434 spin_unlock_irqrestore(&mx3fb->lock, flags); 435 } 436 437 /* 438 * Attention! Without this msleep the channel keeps generating 439 * interrupts. Next sdc_set_brightness() is going to be called 440 * from mx3fb_blank(). 441 */ 442 msleep(2); 443} 444 445static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) 446{ 447 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; 448 unsigned long flags; 449 450 if (mx3_fbi->txd == NULL) 451 return; 452 453 spin_lock_irqsave(&mx3fb->lock, flags); 454 455 sdc_fb_uninit(mx3_fbi); 456 457 spin_unlock_irqrestore(&mx3fb->lock, flags); 458 459 dmaengine_terminate_all(mx3_fbi->txd->chan); 460 mx3_fbi->txd = NULL; 461 mx3_fbi->cookie = -EINVAL; 462} 463 464/** 465 * sdc_set_window_pos() - set window position of the respective plane. 466 * @mx3fb: mx3fb context. 467 * @channel: IPU DMAC channel ID. 468 * @x_pos: X coordinate relative to the top left corner to place window at. 469 * @y_pos: Y coordinate relative to the top left corner to place window at. 470 * @return: 0 on success or negative error code on failure. 471 */ 472static int sdc_set_window_pos(struct mx3fb_data *mx3fb, enum ipu_channel channel, 473 int16_t x_pos, int16_t y_pos) 474{ 475 if (channel != IDMAC_SDC_0) 476 return -EINVAL; 477 478 x_pos += mx3fb->h_start_width; 479 y_pos += mx3fb->v_start_width; 480 481 mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS); 482 return 0; 483} 484 485/** 486 * sdc_init_panel() - initialize a synchronous LCD panel. 487 * @mx3fb: mx3fb context. 488 * @panel: panel type. 489 * @pixel_clk: desired pixel clock frequency in Hz. 490 * @width: width of panel in pixels. 491 * @height: height of panel in pixels. 492 * @h_start_width: number of pixel clocks between the HSYNC signal pulse 493 * and the start of valid data. 494 * @h_sync_width: width of the HSYNC signal in units of pixel clocks. 495 * @h_end_width: number of pixel clocks between the end of valid data 496 * and the HSYNC signal for next line. 497 * @v_start_width: number of lines between the VSYNC signal pulse and the 498 * start of valid data. 499 * @v_sync_width: width of the VSYNC signal in units of lines 500 * @v_end_width: number of lines between the end of valid data and the 501 * VSYNC signal for next frame. 502 * @sig: bitfield of signal polarities for LCD interface. 503 * @return: 0 on success or negative error code on failure. 504 */ 505static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel, 506 uint32_t pixel_clk, 507 uint16_t width, uint16_t height, 508 uint16_t h_start_width, uint16_t h_sync_width, 509 uint16_t h_end_width, uint16_t v_start_width, 510 uint16_t v_sync_width, uint16_t v_end_width, 511 const struct ipu_di_signal_cfg *sig) 512{ 513 unsigned long lock_flags; 514 uint32_t reg; 515 uint32_t old_conf; 516 uint32_t div; 517 struct clk *ipu_clk; 518 const struct di_mapping *map; 519 520 dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height); 521 522 if (v_sync_width == 0 || h_sync_width == 0) 523 return -EINVAL; 524 525 /* Init panel size and blanking periods */ 526 reg = ((uint32_t) (h_sync_width - 1) << 26) | 527 ((uint32_t) (width + h_start_width + h_end_width - 1) << 16); 528 mx3fb_write_reg(mx3fb, reg, SDC_HOR_CONF); 529 530#ifdef DEBUG 531 printk(KERN_CONT " hor_conf %x,", reg); 532#endif 533 534 reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L | 535 ((uint32_t) (height + v_start_width + v_end_width - 1) << 16); 536 mx3fb_write_reg(mx3fb, reg, SDC_VER_CONF); 537 538#ifdef DEBUG 539 printk(KERN_CONT " ver_conf %x\n", reg); 540#endif 541 542 mx3fb->h_start_width = h_start_width; 543 mx3fb->v_start_width = v_start_width; 544 545 switch (panel) { 546 case IPU_PANEL_SHARP_TFT: 547 mx3fb_write_reg(mx3fb, 0x00FD0102L, SDC_SHARP_CONF_1); 548 mx3fb_write_reg(mx3fb, 0x00F500F4L, SDC_SHARP_CONF_2); 549 mx3fb_write_reg(mx3fb, SDC_COM_SHARP | SDC_COM_TFT_COLOR, SDC_COM_CONF); 550 break; 551 case IPU_PANEL_TFT: 552 mx3fb_write_reg(mx3fb, SDC_COM_TFT_COLOR, SDC_COM_CONF); 553 break; 554 default: 555 return -EINVAL; 556 } 557 558 /* Init clocking */ 559 560 /* 561 * Calculate divider: fractional part is 4 bits so simply multiple by 562 * 2^4 to get fractional part, as long as we stay under ~250MHz and on 563 * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz 564 */ 565 ipu_clk = clk_get(mx3fb->dev, NULL); 566 if (!IS_ERR(ipu_clk)) { 567 div = clk_get_rate(ipu_clk) * 16 / pixel_clk; 568 clk_put(ipu_clk); 569 } else { 570 div = 0; 571 } 572 573 if (div < 0x40) { /* Divider less than 4 */ 574 dev_dbg(mx3fb->dev, 575 "InitPanel() - Pixel clock divider less than 4\n"); 576 div = 0x40; 577 } 578 579 dev_dbg(mx3fb->dev, "pixel clk = %u, divider %u.%u\n", 580 pixel_clk, div >> 4, (div & 7) * 125); 581 582 spin_lock_irqsave(&mx3fb->lock, lock_flags); 583 584 /* 585 * DISP3_IF_CLK_DOWN_WR is half the divider value and 2 fraction bits 586 * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing 587 * debug. DISP3_IF_CLK_UP_WR is 0 588 */ 589 mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF); 590 591 /* DI settings */ 592 old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF; 593 old_conf |= sig->datamask_en << DI_D3_DATAMSK_SHIFT | 594 sig->clksel_en << DI_D3_CLK_SEL_SHIFT | 595 sig->clkidle_en << DI_D3_CLK_IDLE_SHIFT; 596 mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF); 597 598 old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF; 599 old_conf |= sig->data_pol << DI_D3_DATA_POL_SHIFT | 600 sig->clk_pol << DI_D3_CLK_POL_SHIFT | 601 sig->enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT | 602 sig->Hsync_pol << DI_D3_HSYNC_POL_SHIFT | 603 sig->Vsync_pol << DI_D3_VSYNC_POL_SHIFT; 604 mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL); 605 606 map = &di_mappings[mx3fb->disp_data_fmt]; 607 mx3fb_write_reg(mx3fb, map->b0, DI_DISP3_B0_MAP); 608 mx3fb_write_reg(mx3fb, map->b1, DI_DISP3_B1_MAP); 609 mx3fb_write_reg(mx3fb, map->b2, DI_DISP3_B2_MAP); 610 611 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); 612 613 dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n", 614 mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF)); 615 dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n", 616 mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL)); 617 dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n", 618 mx3fb_read_reg(mx3fb, DI_DISP3_TIME_CONF)); 619 620 return 0; 621} 622 623/** 624 * sdc_set_color_key() - set the transparent color key for SDC graphic plane. 625 * @mx3fb: mx3fb context. 626 * @channel: IPU DMAC channel ID. 627 * @enable: boolean to enable or disable color keyl. 628 * @color_key: 24-bit RGB color to use as transparent color key. 629 * @return: 0 on success or negative error code on failure. 630 */ 631static int sdc_set_color_key(struct mx3fb_data *mx3fb, enum ipu_channel channel, 632 bool enable, uint32_t color_key) 633{ 634 uint32_t reg, sdc_conf; 635 unsigned long lock_flags; 636 637 spin_lock_irqsave(&mx3fb->lock, lock_flags); 638 639 sdc_conf = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 640 if (channel == IDMAC_SDC_0) 641 sdc_conf &= ~SDC_COM_GWSEL; 642 else 643 sdc_conf |= SDC_COM_GWSEL; 644 645 if (enable) { 646 reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0xFF000000L; 647 mx3fb_write_reg(mx3fb, reg | (color_key & 0x00FFFFFFL), 648 SDC_GW_CTRL); 649 650 sdc_conf |= SDC_COM_KEY_COLOR_G; 651 } else { 652 sdc_conf &= ~SDC_COM_KEY_COLOR_G; 653 } 654 mx3fb_write_reg(mx3fb, sdc_conf, SDC_COM_CONF); 655 656 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); 657 658 return 0; 659} 660 661/** 662 * sdc_set_global_alpha() - set global alpha blending modes. 663 * @mx3fb: mx3fb context. 664 * @enable: boolean to enable or disable global alpha blending. If disabled, 665 * per pixel blending is used. 666 * @alpha: global alpha value. 667 * @return: 0 on success or negative error code on failure. 668 */ 669static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t alpha) 670{ 671 uint32_t reg; 672 unsigned long lock_flags; 673 674 spin_lock_irqsave(&mx3fb->lock, lock_flags); 675 676 if (enable) { 677 reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0x00FFFFFFL; 678 mx3fb_write_reg(mx3fb, reg | ((uint32_t) alpha << 24), SDC_GW_CTRL); 679 680 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 681 mx3fb_write_reg(mx3fb, reg | SDC_COM_GLB_A, SDC_COM_CONF); 682 } else { 683 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 684 mx3fb_write_reg(mx3fb, reg & ~SDC_COM_GLB_A, SDC_COM_CONF); 685 } 686 687 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); 688 689 return 0; 690} 691 692static u32 sdc_get_brightness(struct mx3fb_data *mx3fb) 693{ 694 u32 brightness; 695 696 brightness = mx3fb_read_reg(mx3fb, SDC_PWM_CTRL); 697 brightness = (brightness >> 16) & 0xFF; 698 699 return brightness; 700} 701 702static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value) 703{ 704 dev_dbg(mx3fb->dev, "%s: value = %d\n", __func__, value); 705 /* This might be board-specific */ 706 mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL); 707 return; 708} 709 710static uint32_t bpp_to_pixfmt(int bpp) 711{ 712 uint32_t pixfmt = 0; 713 switch (bpp) { 714 case 24: 715 pixfmt = IPU_PIX_FMT_BGR24; 716 break; 717 case 32: 718 pixfmt = IPU_PIX_FMT_BGR32; 719 break; 720 case 16: 721 pixfmt = IPU_PIX_FMT_RGB565; 722 break; 723 } 724 return pixfmt; 725} 726 727static int mx3fb_blank(int blank, struct fb_info *fbi); 728static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len, 729 bool lock); 730static int mx3fb_unmap_video_memory(struct fb_info *fbi); 731 732/** 733 * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings. 734 * @fbi: framebuffer information pointer 735 * @return: 0 on success or negative error code on failure. 736 */ 737static int mx3fb_set_fix(struct fb_info *fbi) 738{ 739 struct fb_fix_screeninfo *fix = &fbi->fix; 740 struct fb_var_screeninfo *var = &fbi->var; 741 742 memcpy(fix->id, "DISP3 BG", 8); 743 744 fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; 745 746 fix->type = FB_TYPE_PACKED_PIXELS; 747 fix->accel = FB_ACCEL_NONE; 748 fix->visual = FB_VISUAL_TRUECOLOR; 749 fix->xpanstep = 1; 750 fix->ypanstep = 1; 751 752 return 0; 753} 754 755static void mx3fb_dma_done(void *arg) 756{ 757 struct idmac_tx_desc *tx_desc = to_tx_desc(arg); 758 struct dma_chan *chan = tx_desc->txd.chan; 759 struct idmac_channel *ichannel = to_idmac_chan(chan); 760 struct mx3fb_data *mx3fb = ichannel->client; 761 struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; 762 763 dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq); 764 765 /* We only need one interrupt, it will be re-enabled as needed */ 766 disable_irq_nosync(ichannel->eof_irq); 767 768 complete(&mx3_fbi->flip_cmpl); 769} 770 771static bool mx3fb_must_set_par(struct fb_info *fbi) 772{ 773 struct mx3fb_info *mx3_fbi = fbi->par; 774 struct fb_var_screeninfo old_var = mx3_fbi->cur_var; 775 struct fb_var_screeninfo new_var = fbi->var; 776 777 if ((fbi->var.activate & FB_ACTIVATE_FORCE) && 778 (fbi->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) 779 return true; 780 781 /* 782 * Ignore xoffset and yoffset update, 783 * because pan display handles this case. 784 */ 785 old_var.xoffset = new_var.xoffset; 786 old_var.yoffset = new_var.yoffset; 787 788 return !!memcmp(&old_var, &new_var, sizeof(struct fb_var_screeninfo)); 789} 790 791static int __set_par(struct fb_info *fbi, bool lock) 792{ 793 u32 mem_len, cur_xoffset, cur_yoffset; 794 struct ipu_di_signal_cfg sig_cfg; 795 enum ipu_panel mode = IPU_PANEL_TFT; 796 struct mx3fb_info *mx3_fbi = fbi->par; 797 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; 798 struct idmac_channel *ichan = mx3_fbi->idmac_channel; 799 struct idmac_video_param *video = &ichan->params.video; 800 struct scatterlist *sg = mx3_fbi->sg; 801 802 /* Total cleanup */ 803 if (mx3_fbi->txd) 804 sdc_disable_channel(mx3_fbi); 805 806 mx3fb_set_fix(fbi); 807 808 mem_len = fbi->var.yres_virtual * fbi->fix.line_length; 809 if (mem_len > fbi->fix.smem_len) { 810 if (fbi->fix.smem_start) 811 mx3fb_unmap_video_memory(fbi); 812 813 if (mx3fb_map_video_memory(fbi, mem_len, lock) < 0) 814 return -ENOMEM; 815 } 816 817 sg_init_table(&sg[0], 1); 818 sg_init_table(&sg[1], 1); 819 820 sg_dma_address(&sg[0]) = fbi->fix.smem_start; 821 sg_set_page(&sg[0], virt_to_page(fbi->screen_base), 822 fbi->fix.smem_len, 823 offset_in_page(fbi->screen_base)); 824 825 if (mx3_fbi->ipu_ch == IDMAC_SDC_0) { 826 memset(&sig_cfg, 0, sizeof(sig_cfg)); 827 if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT) 828 sig_cfg.Hsync_pol = true; 829 if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) 830 sig_cfg.Vsync_pol = true; 831 if (fbi->var.sync & FB_SYNC_CLK_INVERT) 832 sig_cfg.clk_pol = true; 833 if (fbi->var.sync & FB_SYNC_DATA_INVERT) 834 sig_cfg.data_pol = true; 835 if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH) 836 sig_cfg.enable_pol = true; 837 if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN) 838 sig_cfg.clkidle_en = true; 839 if (fbi->var.sync & FB_SYNC_CLK_SEL_EN) 840 sig_cfg.clksel_en = true; 841 if (fbi->var.sync & FB_SYNC_SHARP_MODE) 842 mode = IPU_PANEL_SHARP_TFT; 843 844 dev_dbg(fbi->device, "pixclock = %u Hz\n", 845 (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL)); 846 847 if (sdc_init_panel(mx3fb, mode, 848 (PICOS2KHZ(fbi->var.pixclock)) * 1000UL, 849 fbi->var.xres, fbi->var.yres, 850 fbi->var.left_margin, 851 fbi->var.hsync_len, 852 fbi->var.right_margin + 853 fbi->var.hsync_len, 854 fbi->var.upper_margin, 855 fbi->var.vsync_len, 856 fbi->var.lower_margin + 857 fbi->var.vsync_len, &sig_cfg) != 0) { 858 dev_err(fbi->device, 859 "mx3fb: Error initializing panel.\n"); 860 return -EINVAL; 861 } 862 } 863 864 sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0); 865 866 mx3_fbi->cur_ipu_buf = 0; 867 868 video->out_pixel_fmt = bpp_to_pixfmt(fbi->var.bits_per_pixel); 869 video->out_width = fbi->var.xres; 870 video->out_height = fbi->var.yres; 871 video->out_stride = fbi->var.xres_virtual; 872 873 if (mx3_fbi->blank == FB_BLANK_UNBLANK) { 874 sdc_enable_channel(mx3_fbi); 875 /* 876 * sg[0] points to fb smem_start address 877 * and is actually active in controller. 878 */ 879 mx3_fbi->cur_var.xoffset = 0; 880 mx3_fbi->cur_var.yoffset = 0; 881 } 882 883 /* 884 * Preserve xoffset and yoffest in case they are 885 * inactive in controller as fb is blanked. 886 */ 887 cur_xoffset = mx3_fbi->cur_var.xoffset; 888 cur_yoffset = mx3_fbi->cur_var.yoffset; 889 mx3_fbi->cur_var = fbi->var; 890 mx3_fbi->cur_var.xoffset = cur_xoffset; 891 mx3_fbi->cur_var.yoffset = cur_yoffset; 892 893 return 0; 894} 895 896/** 897 * mx3fb_set_par() - set framebuffer parameters and change the operating mode. 898 * @fbi: framebuffer information pointer. 899 * @return: 0 on success or negative error code on failure. 900 */ 901static int mx3fb_set_par(struct fb_info *fbi) 902{ 903 struct mx3fb_info *mx3_fbi = fbi->par; 904 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; 905 struct idmac_channel *ichan = mx3_fbi->idmac_channel; 906 int ret; 907 908 dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+'); 909 910 mutex_lock(&mx3_fbi->mutex); 911 912 ret = mx3fb_must_set_par(fbi) ? __set_par(fbi, true) : 0; 913 914 mutex_unlock(&mx3_fbi->mutex); 915 916 return ret; 917} 918 919/** 920 * mx3fb_check_var() - check and adjust framebuffer variable parameters. 921 * @var: framebuffer variable parameters 922 * @fbi: framebuffer information pointer 923 */ 924static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) 925{ 926 struct mx3fb_info *mx3_fbi = fbi->par; 927 u32 vtotal; 928 u32 htotal; 929 930 dev_dbg(fbi->device, "%s\n", __func__); 931 932 if (var->xres_virtual < var->xres) 933 var->xres_virtual = var->xres; 934 if (var->yres_virtual < var->yres) 935 var->yres_virtual = var->yres; 936 937 if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) && 938 (var->bits_per_pixel != 16)) 939 var->bits_per_pixel = default_bpp; 940 941 switch (var->bits_per_pixel) { 942 case 16: 943 var->red.length = 5; 944 var->red.offset = 11; 945 var->red.msb_right = 0; 946 947 var->green.length = 6; 948 var->green.offset = 5; 949 var->green.msb_right = 0; 950 951 var->blue.length = 5; 952 var->blue.offset = 0; 953 var->blue.msb_right = 0; 954 955 var->transp.length = 0; 956 var->transp.offset = 0; 957 var->transp.msb_right = 0; 958 break; 959 case 24: 960 var->red.length = 8; 961 var->red.offset = 16; 962 var->red.msb_right = 0; 963 964 var->green.length = 8; 965 var->green.offset = 8; 966 var->green.msb_right = 0; 967 968 var->blue.length = 8; 969 var->blue.offset = 0; 970 var->blue.msb_right = 0; 971 972 var->transp.length = 0; 973 var->transp.offset = 0; 974 var->transp.msb_right = 0; 975 break; 976 case 32: 977 var->red.length = 8; 978 var->red.offset = 16; 979 var->red.msb_right = 0; 980 981 var->green.length = 8; 982 var->green.offset = 8; 983 var->green.msb_right = 0; 984 985 var->blue.length = 8; 986 var->blue.offset = 0; 987 var->blue.msb_right = 0; 988 989 var->transp.length = 8; 990 var->transp.offset = 24; 991 var->transp.msb_right = 0; 992 break; 993 } 994 995 if (var->pixclock < 1000) { 996 htotal = var->xres + var->right_margin + var->hsync_len + 997 var->left_margin; 998 vtotal = var->yres + var->lower_margin + var->vsync_len + 999 var->upper_margin; 1000 var->pixclock = (vtotal * htotal * 6UL) / 100UL; 1001 var->pixclock = KHZ2PICOS(var->pixclock); 1002 dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n", 1003 var->pixclock); 1004 } 1005 1006 var->height = -1; 1007 var->width = -1; 1008 var->grayscale = 0; 1009 1010 /* Preserve sync flags */ 1011 var->sync |= mx3_fbi->cur_var.sync; 1012 mx3_fbi->cur_var.sync |= var->sync; 1013 1014 return 0; 1015} 1016 1017static u32 chan_to_field(unsigned int chan, struct fb_bitfield *bf) 1018{ 1019 chan &= 0xffff; 1020 chan >>= 16 - bf->length; 1021 return chan << bf->offset; 1022} 1023 1024static int mx3fb_setcolreg(unsigned int regno, unsigned int red, 1025 unsigned int green, unsigned int blue, 1026 unsigned int trans, struct fb_info *fbi) 1027{ 1028 struct mx3fb_info *mx3_fbi = fbi->par; 1029 u32 val; 1030 int ret = 1; 1031 1032 dev_dbg(fbi->device, "%s, regno = %u\n", __func__, regno); 1033 1034 mutex_lock(&mx3_fbi->mutex); 1035 /* 1036 * If greyscale is true, then we convert the RGB value 1037 * to greyscale no matter what visual we are using. 1038 */ 1039 if (fbi->var.grayscale) 1040 red = green = blue = (19595 * red + 38470 * green + 1041 7471 * blue) >> 16; 1042 switch (fbi->fix.visual) { 1043 case FB_VISUAL_TRUECOLOR: 1044 /* 1045 * 16-bit True Colour. We encode the RGB value 1046 * according to the RGB bitfield information. 1047 */ 1048 if (regno < 16) { 1049 u32 *pal = fbi->pseudo_palette; 1050 1051 val = chan_to_field(red, &fbi->var.red); 1052 val |= chan_to_field(green, &fbi->var.green); 1053 val |= chan_to_field(blue, &fbi->var.blue); 1054 1055 pal[regno] = val; 1056 1057 ret = 0; 1058 } 1059 break; 1060 1061 case FB_VISUAL_STATIC_PSEUDOCOLOR: 1062 case FB_VISUAL_PSEUDOCOLOR: 1063 break; 1064 } 1065 mutex_unlock(&mx3_fbi->mutex); 1066 1067 return ret; 1068} 1069 1070static void __blank(int blank, struct fb_info *fbi) 1071{ 1072 struct mx3fb_info *mx3_fbi = fbi->par; 1073 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; 1074 int was_blank = mx3_fbi->blank; 1075 1076 mx3_fbi->blank = blank; 1077 1078 /* Attention! 1079 * Do not call sdc_disable_channel() for a channel that is disabled 1080 * already! This will result in a kernel NULL pointer dereference 1081 * (mx3_fbi->txd is NULL). Hide the fact, that all blank modes are 1082 * handled equally by this driver. 1083 */ 1084 if (blank > FB_BLANK_UNBLANK && was_blank > FB_BLANK_UNBLANK) 1085 return; 1086 1087 switch (blank) { 1088 case FB_BLANK_POWERDOWN: 1089 case FB_BLANK_VSYNC_SUSPEND: 1090 case FB_BLANK_HSYNC_SUSPEND: 1091 case FB_BLANK_NORMAL: 1092 sdc_set_brightness(mx3fb, 0); 1093 memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); 1094 /* Give LCD time to update - enough for 50 and 60 Hz */ 1095 msleep(25); 1096 sdc_disable_channel(mx3_fbi); 1097 break; 1098 case FB_BLANK_UNBLANK: 1099 sdc_enable_channel(mx3_fbi); 1100 sdc_set_brightness(mx3fb, mx3fb->backlight_level); 1101 break; 1102 } 1103} 1104 1105/** 1106 * mx3fb_blank() - blank the display. 1107 * @blank: blank value for the panel 1108 * @fbi: framebuffer information pointer 1109 */ 1110static int mx3fb_blank(int blank, struct fb_info *fbi) 1111{ 1112 struct mx3fb_info *mx3_fbi = fbi->par; 1113 1114 dev_dbg(fbi->device, "%s, blank = %d, base %p, len %u\n", __func__, 1115 blank, fbi->screen_base, fbi->fix.smem_len); 1116 1117 if (mx3_fbi->blank == blank) 1118 return 0; 1119 1120 mutex_lock(&mx3_fbi->mutex); 1121 __blank(blank, fbi); 1122 mutex_unlock(&mx3_fbi->mutex); 1123 1124 return 0; 1125} 1126 1127/** 1128 * mx3fb_pan_display() - pan or wrap the display 1129 * @var: variable screen buffer information. 1130 * @fbi: framebuffer information pointer. 1131 * 1132 * We look only at xoffset, yoffset and the FB_VMODE_YWRAP flag 1133 */ 1134static int mx3fb_pan_display(struct fb_var_screeninfo *var, 1135 struct fb_info *fbi) 1136{ 1137 struct mx3fb_info *mx3_fbi = fbi->par; 1138 u32 y_bottom; 1139 unsigned long base; 1140 off_t offset; 1141 dma_cookie_t cookie; 1142 struct scatterlist *sg = mx3_fbi->sg; 1143 struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan; 1144 struct dma_async_tx_descriptor *txd; 1145 int ret; 1146 1147 dev_dbg(fbi->device, "%s [%c]\n", __func__, 1148 list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+'); 1149 1150 if (var->xoffset > 0) { 1151 dev_dbg(fbi->device, "x panning not supported\n"); 1152 return -EINVAL; 1153 } 1154 1155 if (mx3_fbi->cur_var.xoffset == var->xoffset && 1156 mx3_fbi->cur_var.yoffset == var->yoffset) 1157 return 0; /* No change, do nothing */ 1158 1159 y_bottom = var->yoffset; 1160 1161 if (!(var->vmode & FB_VMODE_YWRAP)) 1162 y_bottom += fbi->var.yres; 1163 1164 if (y_bottom > fbi->var.yres_virtual) 1165 return -EINVAL; 1166 1167 mutex_lock(&mx3_fbi->mutex); 1168 1169 offset = var->yoffset * fbi->fix.line_length 1170 + var->xoffset * (fbi->var.bits_per_pixel / 8); 1171 base = fbi->fix.smem_start + offset; 1172 1173 dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n", 1174 mx3_fbi->cur_ipu_buf, base); 1175 1176 /* 1177 * We enable the End of Frame interrupt, which will free a tx-descriptor, 1178 * which we will need for the next dmaengine_prep_slave_sg(). The 1179 * IRQ-handler will disable the IRQ again. 1180 */ 1181 init_completion(&mx3_fbi->flip_cmpl); 1182 enable_irq(mx3_fbi->idmac_channel->eof_irq); 1183 1184 ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10); 1185 if (ret <= 0) { 1186 mutex_unlock(&mx3_fbi->mutex); 1187 dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ? 1188 "user interrupt" : "timeout"); 1189 disable_irq(mx3_fbi->idmac_channel->eof_irq); 1190 return ret ? : -ETIMEDOUT; 1191 } 1192 1193 mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf; 1194 1195 sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base; 1196 sg_set_page(&sg[mx3_fbi->cur_ipu_buf], 1197 virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len, 1198 offset_in_page(fbi->screen_base + offset)); 1199 1200 if (mx3_fbi->txd) 1201 async_tx_ack(mx3_fbi->txd); 1202 1203 txd = dmaengine_prep_slave_sg(dma_chan, sg + 1204 mx3_fbi->cur_ipu_buf, 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); 1205 if (!txd) { 1206 dev_err(fbi->device, 1207 "Error preparing a DMA transaction descriptor.\n"); 1208 mutex_unlock(&mx3_fbi->mutex); 1209 return -EIO; 1210 } 1211 1212 txd->callback_param = txd; 1213 txd->callback = mx3fb_dma_done; 1214 1215 /* 1216 * Emulate original mx3fb behaviour: each new call to idmac_tx_submit() 1217 * should switch to another buffer 1218 */ 1219 cookie = txd->tx_submit(txd); 1220 dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie); 1221 if (cookie < 0) { 1222 dev_err(fbi->device, 1223 "Error updating SDC buf %d to address=0x%08lX\n", 1224 mx3_fbi->cur_ipu_buf, base); 1225 mutex_unlock(&mx3_fbi->mutex); 1226 return -EIO; 1227 } 1228 1229 mx3_fbi->txd = txd; 1230 1231 fbi->var.xoffset = var->xoffset; 1232 fbi->var.yoffset = var->yoffset; 1233 1234 if (var->vmode & FB_VMODE_YWRAP) 1235 fbi->var.vmode |= FB_VMODE_YWRAP; 1236 else 1237 fbi->var.vmode &= ~FB_VMODE_YWRAP; 1238 1239 mx3_fbi->cur_var = fbi->var; 1240 1241 mutex_unlock(&mx3_fbi->mutex); 1242 1243 dev_dbg(fbi->device, "Update complete\n"); 1244 1245 return 0; 1246} 1247 1248/* 1249 * This structure contains the pointers to the control functions that are 1250 * invoked by the core framebuffer driver to perform operations like 1251 * blitting, rectangle filling, copy regions and cursor definition. 1252 */ 1253static const struct fb_ops mx3fb_ops = { 1254 .owner = THIS_MODULE, 1255 .fb_set_par = mx3fb_set_par, 1256 .fb_check_var = mx3fb_check_var, 1257 .fb_setcolreg = mx3fb_setcolreg, 1258 .fb_pan_display = mx3fb_pan_display, 1259 .fb_fillrect = cfb_fillrect, 1260 .fb_copyarea = cfb_copyarea, 1261 .fb_imageblit = cfb_imageblit, 1262 .fb_blank = mx3fb_blank, 1263}; 1264 1265#ifdef CONFIG_PM 1266/* 1267 * Power management hooks. Note that we won't be called from IRQ context, 1268 * unlike the blank functions above, so we may sleep. 1269 */ 1270 1271/* 1272 * Suspends the framebuffer and blanks the screen. Power management support 1273 */ 1274static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state) 1275{ 1276 struct mx3fb_data *mx3fb = platform_get_drvdata(pdev); 1277 struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; 1278 1279 console_lock(); 1280 fb_set_suspend(mx3fb->fbi, 1); 1281 console_unlock(); 1282 1283 if (mx3_fbi->blank == FB_BLANK_UNBLANK) { 1284 sdc_disable_channel(mx3_fbi); 1285 sdc_set_brightness(mx3fb, 0); 1286 1287 } 1288 return 0; 1289} 1290 1291/* 1292 * Resumes the framebuffer and unblanks the screen. Power management support 1293 */ 1294static int mx3fb_resume(struct platform_device *pdev) 1295{ 1296 struct mx3fb_data *mx3fb = platform_get_drvdata(pdev); 1297 struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; 1298 1299 if (mx3_fbi->blank == FB_BLANK_UNBLANK) { 1300 sdc_enable_channel(mx3_fbi); 1301 sdc_set_brightness(mx3fb, mx3fb->backlight_level); 1302 } 1303 1304 console_lock(); 1305 fb_set_suspend(mx3fb->fbi, 0); 1306 console_unlock(); 1307 1308 return 0; 1309} 1310#else 1311#define mx3fb_suspend NULL 1312#define mx3fb_resume NULL 1313#endif 1314 1315/* 1316 * Main framebuffer functions 1317 */ 1318 1319/** 1320 * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. 1321 * @fbi: framebuffer information pointer 1322 * @mem_len: length of mapped memory 1323 * @lock: do not lock during initialisation 1324 * @return: Error code indicating success or failure 1325 * 1326 * This buffer is remapped into a non-cached, non-buffered, memory region to 1327 * allow palette and pixel writes to occur without flushing the cache. Once this 1328 * area is remapped, all virtual memory access to the video memory should occur 1329 * at the new region. 1330 */ 1331static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len, 1332 bool lock) 1333{ 1334 int retval = 0; 1335 dma_addr_t addr; 1336 1337 fbi->screen_base = dma_alloc_wc(fbi->device, mem_len, &addr, 1338 GFP_DMA | GFP_KERNEL); 1339 1340 if (!fbi->screen_base) { 1341 dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", 1342 mem_len); 1343 retval = -EBUSY; 1344 goto err0; 1345 } 1346 1347 if (lock) 1348 mutex_lock(&fbi->mm_lock); 1349 fbi->fix.smem_start = addr; 1350 fbi->fix.smem_len = mem_len; 1351 if (lock) 1352 mutex_unlock(&fbi->mm_lock); 1353 1354 dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", 1355 (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); 1356 1357 fbi->screen_size = fbi->fix.smem_len; 1358 1359 /* Clear the screen */ 1360 memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); 1361 1362 return 0; 1363 1364err0: 1365 fbi->fix.smem_len = 0; 1366 fbi->fix.smem_start = 0; 1367 fbi->screen_base = NULL; 1368 return retval; 1369} 1370 1371/** 1372 * mx3fb_unmap_video_memory() - de-allocate frame buffer memory. 1373 * @fbi: framebuffer information pointer 1374 * @return: error code indicating success or failure 1375 */ 1376static int mx3fb_unmap_video_memory(struct fb_info *fbi) 1377{ 1378 dma_free_wc(fbi->device, fbi->fix.smem_len, fbi->screen_base, 1379 fbi->fix.smem_start); 1380 1381 fbi->screen_base = NULL; 1382 mutex_lock(&fbi->mm_lock); 1383 fbi->fix.smem_start = 0; 1384 fbi->fix.smem_len = 0; 1385 mutex_unlock(&fbi->mm_lock); 1386 return 0; 1387} 1388 1389/** 1390 * mx3fb_init_fbinfo() - initialize framebuffer information object. 1391 * @dev: the device 1392 * @ops: framebuffer device operations 1393 * @return: initialized framebuffer structure. 1394 */ 1395static struct fb_info *mx3fb_init_fbinfo(struct device *dev, 1396 const struct fb_ops *ops) 1397{ 1398 struct fb_info *fbi; 1399 struct mx3fb_info *mx3fbi; 1400 int ret; 1401 1402 /* Allocate sufficient memory for the fb structure */ 1403 fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev); 1404 if (!fbi) 1405 return NULL; 1406 1407 mx3fbi = fbi->par; 1408 mx3fbi->cookie = -EINVAL; 1409 mx3fbi->cur_ipu_buf = 0; 1410 1411 fbi->var.activate = FB_ACTIVATE_NOW; 1412 1413 fbi->fbops = ops; 1414 fbi->flags = FBINFO_FLAG_DEFAULT; 1415 fbi->pseudo_palette = mx3fbi->pseudo_palette; 1416 1417 mutex_init(&mx3fbi->mutex); 1418 1419 /* Allocate colormap */ 1420 ret = fb_alloc_cmap(&fbi->cmap, 16, 0); 1421 if (ret < 0) { 1422 framebuffer_release(fbi); 1423 return NULL; 1424 } 1425 1426 return fbi; 1427} 1428 1429static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan) 1430{ 1431 struct device *dev = mx3fb->dev; 1432 struct mx3fb_platform_data *mx3fb_pdata = dev_get_platdata(dev); 1433 const char *name = mx3fb_pdata->name; 1434 struct fb_info *fbi; 1435 struct mx3fb_info *mx3fbi; 1436 const struct fb_videomode *mode; 1437 int ret, num_modes; 1438 1439 if (mx3fb_pdata->disp_data_fmt >= ARRAY_SIZE(di_mappings)) { 1440 dev_err(dev, "Illegal display data format %d\n", 1441 mx3fb_pdata->disp_data_fmt); 1442 return -EINVAL; 1443 } 1444 1445 ichan->client = mx3fb; 1446 1447 if (ichan->dma_chan.chan_id != IDMAC_SDC_0) 1448 return -EINVAL; 1449 1450 fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops); 1451 if (!fbi) 1452 return -ENOMEM; 1453 1454 if (!fb_mode) 1455 fb_mode = name; 1456 1457 if (!fb_mode) { 1458 ret = -EINVAL; 1459 goto emode; 1460 } 1461 1462 if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) { 1463 mode = mx3fb_pdata->mode; 1464 num_modes = mx3fb_pdata->num_modes; 1465 } else { 1466 mode = mx3fb_modedb; 1467 num_modes = ARRAY_SIZE(mx3fb_modedb); 1468 } 1469 1470 if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode, 1471 num_modes, NULL, default_bpp)) { 1472 ret = -EBUSY; 1473 goto emode; 1474 } 1475 1476 fb_videomode_to_modelist(mode, num_modes, &fbi->modelist); 1477 1478 /* Default Y virtual size is 2x panel size */ 1479 fbi->var.yres_virtual = fbi->var.yres * 2; 1480 1481 mx3fb->fbi = fbi; 1482 1483 /* set Display Interface clock period */ 1484 mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER); 1485 /* Might need to trigger HSP clock change - see 44.3.3.8.5 */ 1486 1487 sdc_set_brightness(mx3fb, 255); 1488 sdc_set_global_alpha(mx3fb, true, 0xFF); 1489 sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0); 1490 1491 mx3fbi = fbi->par; 1492 mx3fbi->idmac_channel = ichan; 1493 mx3fbi->ipu_ch = ichan->dma_chan.chan_id; 1494 mx3fbi->mx3fb = mx3fb; 1495 mx3fbi->blank = FB_BLANK_NORMAL; 1496 1497 mx3fb->disp_data_fmt = mx3fb_pdata->disp_data_fmt; 1498 1499 init_completion(&mx3fbi->flip_cmpl); 1500 disable_irq(ichan->eof_irq); 1501 dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); 1502 ret = __set_par(fbi, false); 1503 if (ret < 0) 1504 goto esetpar; 1505 1506 __blank(FB_BLANK_UNBLANK, fbi); 1507 1508 dev_info(dev, "registered, using mode %s\n", fb_mode); 1509 1510 ret = register_framebuffer(fbi); 1511 if (ret < 0) 1512 goto erfb; 1513 1514 return 0; 1515 1516erfb: 1517esetpar: 1518emode: 1519 fb_dealloc_cmap(&fbi->cmap); 1520 framebuffer_release(fbi); 1521 1522 return ret; 1523} 1524 1525static bool chan_filter(struct dma_chan *chan, void *arg) 1526{ 1527 struct dma_chan_request *rq = arg; 1528 struct device *dev; 1529 struct mx3fb_platform_data *mx3fb_pdata; 1530 1531 if (!imx_dma_is_ipu(chan)) 1532 return false; 1533 1534 if (!rq) 1535 return false; 1536 1537 dev = rq->mx3fb->dev; 1538 mx3fb_pdata = dev_get_platdata(dev); 1539 1540 return rq->id == chan->chan_id && 1541 mx3fb_pdata->dma_dev == chan->device->dev; 1542} 1543 1544static void release_fbi(struct fb_info *fbi) 1545{ 1546 mx3fb_unmap_video_memory(fbi); 1547 1548 fb_dealloc_cmap(&fbi->cmap); 1549 1550 unregister_framebuffer(fbi); 1551 framebuffer_release(fbi); 1552} 1553 1554static int mx3fb_probe(struct platform_device *pdev) 1555{ 1556 struct device *dev = &pdev->dev; 1557 int ret; 1558 struct resource *sdc_reg; 1559 struct mx3fb_data *mx3fb; 1560 dma_cap_mask_t mask; 1561 struct dma_chan *chan; 1562 struct dma_chan_request rq; 1563 1564 /* 1565 * Display Interface (DI) and Synchronous Display Controller (SDC) 1566 * registers 1567 */ 1568 sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1569 if (!sdc_reg) 1570 return -EINVAL; 1571 1572 mx3fb = devm_kzalloc(&pdev->dev, sizeof(*mx3fb), GFP_KERNEL); 1573 if (!mx3fb) 1574 return -ENOMEM; 1575 1576 spin_lock_init(&mx3fb->lock); 1577 1578 mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg)); 1579 if (!mx3fb->reg_base) { 1580 ret = -ENOMEM; 1581 goto eremap; 1582 } 1583 1584 pr_debug("Remapped %pR at %p\n", sdc_reg, mx3fb->reg_base); 1585 1586 /* IDMAC interface */ 1587 dmaengine_get(); 1588 1589 mx3fb->dev = dev; 1590 platform_set_drvdata(pdev, mx3fb); 1591 1592 rq.mx3fb = mx3fb; 1593 1594 dma_cap_zero(mask); 1595 dma_cap_set(DMA_SLAVE, mask); 1596 dma_cap_set(DMA_PRIVATE, mask); 1597 rq.id = IDMAC_SDC_0; 1598 chan = dma_request_channel(mask, chan_filter, &rq); 1599 if (!chan) { 1600 ret = -EBUSY; 1601 goto ersdc0; 1602 } 1603 1604 mx3fb->backlight_level = 255; 1605 1606 ret = init_fb_chan(mx3fb, to_idmac_chan(chan)); 1607 if (ret < 0) 1608 goto eisdc0; 1609 1610 mx3fb_init_backlight(mx3fb); 1611 1612 return 0; 1613 1614eisdc0: 1615 dma_release_channel(chan); 1616ersdc0: 1617 dmaengine_put(); 1618 iounmap(mx3fb->reg_base); 1619eremap: 1620 dev_err(dev, "mx3fb: failed to register fb\n"); 1621 return ret; 1622} 1623 1624static int mx3fb_remove(struct platform_device *dev) 1625{ 1626 struct mx3fb_data *mx3fb = platform_get_drvdata(dev); 1627 struct fb_info *fbi = mx3fb->fbi; 1628 struct mx3fb_info *mx3_fbi = fbi->par; 1629 struct dma_chan *chan; 1630 1631 chan = &mx3_fbi->idmac_channel->dma_chan; 1632 release_fbi(fbi); 1633 1634 mx3fb_exit_backlight(mx3fb); 1635 1636 dma_release_channel(chan); 1637 dmaengine_put(); 1638 1639 iounmap(mx3fb->reg_base); 1640 return 0; 1641} 1642 1643static struct platform_driver mx3fb_driver = { 1644 .driver = { 1645 .name = MX3FB_NAME, 1646 }, 1647 .probe = mx3fb_probe, 1648 .remove = mx3fb_remove, 1649 .suspend = mx3fb_suspend, 1650 .resume = mx3fb_resume, 1651}; 1652 1653/* 1654 * Parse user specified options (`video=mx3fb:') 1655 * example: 1656 * video=mx3fb:bpp=16 1657 */ 1658static int __init mx3fb_setup(void) 1659{ 1660#ifndef MODULE 1661 char *opt, *options = NULL; 1662 1663 if (fb_get_options("mx3fb", &options)) 1664 return -ENODEV; 1665 1666 if (!options || !*options) 1667 return 0; 1668 1669 while ((opt = strsep(&options, ",")) != NULL) { 1670 if (!*opt) 1671 continue; 1672 if (!strncmp(opt, "bpp=", 4)) 1673 default_bpp = simple_strtoul(opt + 4, NULL, 0); 1674 else 1675 fb_mode = opt; 1676 } 1677#endif 1678 1679 return 0; 1680} 1681 1682static int __init mx3fb_init(void) 1683{ 1684 int ret = mx3fb_setup(); 1685 1686 if (ret < 0) 1687 return ret; 1688 1689 ret = platform_driver_register(&mx3fb_driver); 1690 return ret; 1691} 1692 1693static void __exit mx3fb_exit(void) 1694{ 1695 platform_driver_unregister(&mx3fb_driver); 1696} 1697 1698module_init(mx3fb_init); 1699module_exit(mx3fb_exit); 1700 1701MODULE_AUTHOR("Freescale Semiconductor, Inc."); 1702MODULE_DESCRIPTION("MX3 framebuffer driver"); 1703MODULE_ALIAS("platform:" MX3FB_NAME); 1704MODULE_LICENSE("GPL v2");