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/platform_data/dma-imx.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 uint32_t enabled; 449 unsigned long flags; 450 451 if (mx3_fbi->txd == NULL) 452 return; 453 454 spin_lock_irqsave(&mx3fb->lock, flags); 455 456 enabled = sdc_fb_uninit(mx3_fbi); 457 458 spin_unlock_irqrestore(&mx3fb->lock, flags); 459 460 dmaengine_terminate_all(mx3_fbi->txd->chan); 461 mx3_fbi->txd = NULL; 462 mx3_fbi->cookie = -EINVAL; 463} 464 465/** 466 * sdc_set_window_pos() - set window position of the respective plane. 467 * @mx3fb: mx3fb context. 468 * @channel: IPU DMAC channel ID. 469 * @x_pos: X coordinate relative to the top left corner to place window at. 470 * @y_pos: Y coordinate relative to the top left corner to place window at. 471 * @return: 0 on success or negative error code on failure. 472 */ 473static int sdc_set_window_pos(struct mx3fb_data *mx3fb, enum ipu_channel channel, 474 int16_t x_pos, int16_t y_pos) 475{ 476 if (channel != IDMAC_SDC_0) 477 return -EINVAL; 478 479 x_pos += mx3fb->h_start_width; 480 y_pos += mx3fb->v_start_width; 481 482 mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS); 483 return 0; 484} 485 486/** 487 * sdc_init_panel() - initialize a synchronous LCD panel. 488 * @mx3fb: mx3fb context. 489 * @panel: panel type. 490 * @pixel_clk: desired pixel clock frequency in Hz. 491 * @width: width of panel in pixels. 492 * @height: height of panel in pixels. 493 * @h_start_width: number of pixel clocks between the HSYNC signal pulse 494 * and the start of valid data. 495 * @h_sync_width: width of the HSYNC signal in units of pixel clocks. 496 * @h_end_width: number of pixel clocks between the end of valid data 497 * and the HSYNC signal for next line. 498 * @v_start_width: number of lines between the VSYNC signal pulse and the 499 * start of valid data. 500 * @v_sync_width: width of the VSYNC signal in units of lines 501 * @v_end_width: number of lines between the end of valid data and the 502 * VSYNC signal for next frame. 503 * @sig: bitfield of signal polarities for LCD interface. 504 * @return: 0 on success or negative error code on failure. 505 */ 506static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel, 507 uint32_t pixel_clk, 508 uint16_t width, uint16_t height, 509 uint16_t h_start_width, uint16_t h_sync_width, 510 uint16_t h_end_width, uint16_t v_start_width, 511 uint16_t v_sync_width, uint16_t v_end_width, 512 const struct ipu_di_signal_cfg *sig) 513{ 514 unsigned long lock_flags; 515 uint32_t reg; 516 uint32_t old_conf; 517 uint32_t div; 518 struct clk *ipu_clk; 519 const struct di_mapping *map; 520 521 dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height); 522 523 if (v_sync_width == 0 || h_sync_width == 0) 524 return -EINVAL; 525 526 /* Init panel size and blanking periods */ 527 reg = ((uint32_t) (h_sync_width - 1) << 26) | 528 ((uint32_t) (width + h_start_width + h_end_width - 1) << 16); 529 mx3fb_write_reg(mx3fb, reg, SDC_HOR_CONF); 530 531#ifdef DEBUG 532 printk(KERN_CONT " hor_conf %x,", reg); 533#endif 534 535 reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L | 536 ((uint32_t) (height + v_start_width + v_end_width - 1) << 16); 537 mx3fb_write_reg(mx3fb, reg, SDC_VER_CONF); 538 539#ifdef DEBUG 540 printk(KERN_CONT " ver_conf %x\n", reg); 541#endif 542 543 mx3fb->h_start_width = h_start_width; 544 mx3fb->v_start_width = v_start_width; 545 546 switch (panel) { 547 case IPU_PANEL_SHARP_TFT: 548 mx3fb_write_reg(mx3fb, 0x00FD0102L, SDC_SHARP_CONF_1); 549 mx3fb_write_reg(mx3fb, 0x00F500F4L, SDC_SHARP_CONF_2); 550 mx3fb_write_reg(mx3fb, SDC_COM_SHARP | SDC_COM_TFT_COLOR, SDC_COM_CONF); 551 break; 552 case IPU_PANEL_TFT: 553 mx3fb_write_reg(mx3fb, SDC_COM_TFT_COLOR, SDC_COM_CONF); 554 break; 555 default: 556 return -EINVAL; 557 } 558 559 /* Init clocking */ 560 561 /* 562 * Calculate divider: fractional part is 4 bits so simply multiple by 563 * 2^4 to get fractional part, as long as we stay under ~250MHz and on 564 * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz 565 */ 566 ipu_clk = clk_get(mx3fb->dev, NULL); 567 if (!IS_ERR(ipu_clk)) { 568 div = clk_get_rate(ipu_clk) * 16 / pixel_clk; 569 clk_put(ipu_clk); 570 } else { 571 div = 0; 572 } 573 574 if (div < 0x40) { /* Divider less than 4 */ 575 dev_dbg(mx3fb->dev, 576 "InitPanel() - Pixel clock divider less than 4\n"); 577 div = 0x40; 578 } 579 580 dev_dbg(mx3fb->dev, "pixel clk = %u, divider %u.%u\n", 581 pixel_clk, div >> 4, (div & 7) * 125); 582 583 spin_lock_irqsave(&mx3fb->lock, lock_flags); 584 585 /* 586 * DISP3_IF_CLK_DOWN_WR is half the divider value and 2 fraction bits 587 * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing 588 * debug. DISP3_IF_CLK_UP_WR is 0 589 */ 590 mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF); 591 592 /* DI settings */ 593 old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF; 594 old_conf |= sig->datamask_en << DI_D3_DATAMSK_SHIFT | 595 sig->clksel_en << DI_D3_CLK_SEL_SHIFT | 596 sig->clkidle_en << DI_D3_CLK_IDLE_SHIFT; 597 mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF); 598 599 old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF; 600 old_conf |= sig->data_pol << DI_D3_DATA_POL_SHIFT | 601 sig->clk_pol << DI_D3_CLK_POL_SHIFT | 602 sig->enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT | 603 sig->Hsync_pol << DI_D3_HSYNC_POL_SHIFT | 604 sig->Vsync_pol << DI_D3_VSYNC_POL_SHIFT; 605 mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL); 606 607 map = &di_mappings[mx3fb->disp_data_fmt]; 608 mx3fb_write_reg(mx3fb, map->b0, DI_DISP3_B0_MAP); 609 mx3fb_write_reg(mx3fb, map->b1, DI_DISP3_B1_MAP); 610 mx3fb_write_reg(mx3fb, map->b2, DI_DISP3_B2_MAP); 611 612 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); 613 614 dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n", 615 mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF)); 616 dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n", 617 mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL)); 618 dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n", 619 mx3fb_read_reg(mx3fb, DI_DISP3_TIME_CONF)); 620 621 return 0; 622} 623 624/** 625 * sdc_set_color_key() - set the transparent color key for SDC graphic plane. 626 * @mx3fb: mx3fb context. 627 * @channel: IPU DMAC channel ID. 628 * @enable: boolean to enable or disable color keyl. 629 * @color_key: 24-bit RGB color to use as transparent color key. 630 * @return: 0 on success or negative error code on failure. 631 */ 632static int sdc_set_color_key(struct mx3fb_data *mx3fb, enum ipu_channel channel, 633 bool enable, uint32_t color_key) 634{ 635 uint32_t reg, sdc_conf; 636 unsigned long lock_flags; 637 638 spin_lock_irqsave(&mx3fb->lock, lock_flags); 639 640 sdc_conf = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 641 if (channel == IDMAC_SDC_0) 642 sdc_conf &= ~SDC_COM_GWSEL; 643 else 644 sdc_conf |= SDC_COM_GWSEL; 645 646 if (enable) { 647 reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0xFF000000L; 648 mx3fb_write_reg(mx3fb, reg | (color_key & 0x00FFFFFFL), 649 SDC_GW_CTRL); 650 651 sdc_conf |= SDC_COM_KEY_COLOR_G; 652 } else { 653 sdc_conf &= ~SDC_COM_KEY_COLOR_G; 654 } 655 mx3fb_write_reg(mx3fb, sdc_conf, SDC_COM_CONF); 656 657 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); 658 659 return 0; 660} 661 662/** 663 * sdc_set_global_alpha() - set global alpha blending modes. 664 * @mx3fb: mx3fb context. 665 * @enable: boolean to enable or disable global alpha blending. If disabled, 666 * per pixel blending is used. 667 * @alpha: global alpha value. 668 * @return: 0 on success or negative error code on failure. 669 */ 670static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t alpha) 671{ 672 uint32_t reg; 673 unsigned long lock_flags; 674 675 spin_lock_irqsave(&mx3fb->lock, lock_flags); 676 677 if (enable) { 678 reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0x00FFFFFFL; 679 mx3fb_write_reg(mx3fb, reg | ((uint32_t) alpha << 24), SDC_GW_CTRL); 680 681 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 682 mx3fb_write_reg(mx3fb, reg | SDC_COM_GLB_A, SDC_COM_CONF); 683 } else { 684 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 685 mx3fb_write_reg(mx3fb, reg & ~SDC_COM_GLB_A, SDC_COM_CONF); 686 } 687 688 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); 689 690 return 0; 691} 692 693static u32 sdc_get_brightness(struct mx3fb_data *mx3fb) 694{ 695 u32 brightness; 696 697 brightness = mx3fb_read_reg(mx3fb, SDC_PWM_CTRL); 698 brightness = (brightness >> 16) & 0xFF; 699 700 return brightness; 701} 702 703static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value) 704{ 705 dev_dbg(mx3fb->dev, "%s: value = %d\n", __func__, value); 706 /* This might be board-specific */ 707 mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL); 708 return; 709} 710 711static uint32_t bpp_to_pixfmt(int bpp) 712{ 713 uint32_t pixfmt = 0; 714 switch (bpp) { 715 case 24: 716 pixfmt = IPU_PIX_FMT_BGR24; 717 break; 718 case 32: 719 pixfmt = IPU_PIX_FMT_BGR32; 720 break; 721 case 16: 722 pixfmt = IPU_PIX_FMT_RGB565; 723 break; 724 } 725 return pixfmt; 726} 727 728static int mx3fb_blank(int blank, struct fb_info *fbi); 729static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len, 730 bool lock); 731static int mx3fb_unmap_video_memory(struct fb_info *fbi); 732 733/** 734 * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings. 735 * @info: framebuffer information pointer 736 * @return: 0 on success or negative error code on failure. 737 */ 738static int mx3fb_set_fix(struct fb_info *fbi) 739{ 740 struct fb_fix_screeninfo *fix = &fbi->fix; 741 struct fb_var_screeninfo *var = &fbi->var; 742 743 strncpy(fix->id, "DISP3 BG", 8); 744 745 fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; 746 747 fix->type = FB_TYPE_PACKED_PIXELS; 748 fix->accel = FB_ACCEL_NONE; 749 fix->visual = FB_VISUAL_TRUECOLOR; 750 fix->xpanstep = 1; 751 fix->ypanstep = 1; 752 753 return 0; 754} 755 756static void mx3fb_dma_done(void *arg) 757{ 758 struct idmac_tx_desc *tx_desc = to_tx_desc(arg); 759 struct dma_chan *chan = tx_desc->txd.chan; 760 struct idmac_channel *ichannel = to_idmac_chan(chan); 761 struct mx3fb_data *mx3fb = ichannel->client; 762 struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; 763 764 dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq); 765 766 /* We only need one interrupt, it will be re-enabled as needed */ 767 disable_irq_nosync(ichannel->eof_irq); 768 769 complete(&mx3_fbi->flip_cmpl); 770} 771 772static bool mx3fb_must_set_par(struct fb_info *fbi) 773{ 774 struct mx3fb_info *mx3_fbi = fbi->par; 775 struct fb_var_screeninfo old_var = mx3_fbi->cur_var; 776 struct fb_var_screeninfo new_var = fbi->var; 777 778 if ((fbi->var.activate & FB_ACTIVATE_FORCE) && 779 (fbi->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) 780 return true; 781 782 /* 783 * Ignore xoffset and yoffset update, 784 * because pan display handles this case. 785 */ 786 old_var.xoffset = new_var.xoffset; 787 old_var.yoffset = new_var.yoffset; 788 789 return !!memcmp(&old_var, &new_var, sizeof(struct fb_var_screeninfo)); 790} 791 792static int __set_par(struct fb_info *fbi, bool lock) 793{ 794 u32 mem_len, cur_xoffset, cur_yoffset; 795 struct ipu_di_signal_cfg sig_cfg; 796 enum ipu_panel mode = IPU_PANEL_TFT; 797 struct mx3fb_info *mx3_fbi = fbi->par; 798 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; 799 struct idmac_channel *ichan = mx3_fbi->idmac_channel; 800 struct idmac_video_param *video = &ichan->params.video; 801 struct scatterlist *sg = mx3_fbi->sg; 802 803 /* Total cleanup */ 804 if (mx3_fbi->txd) 805 sdc_disable_channel(mx3_fbi); 806 807 mx3fb_set_fix(fbi); 808 809 mem_len = fbi->var.yres_virtual * fbi->fix.line_length; 810 if (mem_len > fbi->fix.smem_len) { 811 if (fbi->fix.smem_start) 812 mx3fb_unmap_video_memory(fbi); 813 814 if (mx3fb_map_video_memory(fbi, mem_len, lock) < 0) 815 return -ENOMEM; 816 } 817 818 sg_init_table(&sg[0], 1); 819 sg_init_table(&sg[1], 1); 820 821 sg_dma_address(&sg[0]) = fbi->fix.smem_start; 822 sg_set_page(&sg[0], virt_to_page(fbi->screen_base), 823 fbi->fix.smem_len, 824 offset_in_page(fbi->screen_base)); 825 826 if (mx3_fbi->ipu_ch == IDMAC_SDC_0) { 827 memset(&sig_cfg, 0, sizeof(sig_cfg)); 828 if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT) 829 sig_cfg.Hsync_pol = true; 830 if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) 831 sig_cfg.Vsync_pol = true; 832 if (fbi->var.sync & FB_SYNC_CLK_INVERT) 833 sig_cfg.clk_pol = true; 834 if (fbi->var.sync & FB_SYNC_DATA_INVERT) 835 sig_cfg.data_pol = true; 836 if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH) 837 sig_cfg.enable_pol = true; 838 if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN) 839 sig_cfg.clkidle_en = true; 840 if (fbi->var.sync & FB_SYNC_CLK_SEL_EN) 841 sig_cfg.clksel_en = true; 842 if (fbi->var.sync & FB_SYNC_SHARP_MODE) 843 mode = IPU_PANEL_SHARP_TFT; 844 845 dev_dbg(fbi->device, "pixclock = %u Hz\n", 846 (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL)); 847 848 if (sdc_init_panel(mx3fb, mode, 849 (PICOS2KHZ(fbi->var.pixclock)) * 1000UL, 850 fbi->var.xres, fbi->var.yres, 851 fbi->var.left_margin, 852 fbi->var.hsync_len, 853 fbi->var.right_margin + 854 fbi->var.hsync_len, 855 fbi->var.upper_margin, 856 fbi->var.vsync_len, 857 fbi->var.lower_margin + 858 fbi->var.vsync_len, &sig_cfg) != 0) { 859 dev_err(fbi->device, 860 "mx3fb: Error initializing panel.\n"); 861 return -EINVAL; 862 } 863 } 864 865 sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0); 866 867 mx3_fbi->cur_ipu_buf = 0; 868 869 video->out_pixel_fmt = bpp_to_pixfmt(fbi->var.bits_per_pixel); 870 video->out_width = fbi->var.xres; 871 video->out_height = fbi->var.yres; 872 video->out_stride = fbi->var.xres_virtual; 873 874 if (mx3_fbi->blank == FB_BLANK_UNBLANK) { 875 sdc_enable_channel(mx3_fbi); 876 /* 877 * sg[0] points to fb smem_start address 878 * and is actually active in controller. 879 */ 880 mx3_fbi->cur_var.xoffset = 0; 881 mx3_fbi->cur_var.yoffset = 0; 882 } 883 884 /* 885 * Preserve xoffset and yoffest in case they are 886 * inactive in controller as fb is blanked. 887 */ 888 cur_xoffset = mx3_fbi->cur_var.xoffset; 889 cur_yoffset = mx3_fbi->cur_var.yoffset; 890 mx3_fbi->cur_var = fbi->var; 891 mx3_fbi->cur_var.xoffset = cur_xoffset; 892 mx3_fbi->cur_var.yoffset = cur_yoffset; 893 894 return 0; 895} 896 897/** 898 * mx3fb_set_par() - set framebuffer parameters and change the operating mode. 899 * @fbi: framebuffer information pointer. 900 * @return: 0 on success or negative error code on failure. 901 */ 902static int mx3fb_set_par(struct fb_info *fbi) 903{ 904 struct mx3fb_info *mx3_fbi = fbi->par; 905 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; 906 struct idmac_channel *ichan = mx3_fbi->idmac_channel; 907 int ret; 908 909 dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+'); 910 911 mutex_lock(&mx3_fbi->mutex); 912 913 ret = mx3fb_must_set_par(fbi) ? __set_par(fbi, true) : 0; 914 915 mutex_unlock(&mx3_fbi->mutex); 916 917 return ret; 918} 919 920/** 921 * mx3fb_check_var() - check and adjust framebuffer variable parameters. 922 * @var: framebuffer variable parameters 923 * @fbi: framebuffer information pointer 924 */ 925static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) 926{ 927 struct mx3fb_info *mx3_fbi = fbi->par; 928 u32 vtotal; 929 u32 htotal; 930 931 dev_dbg(fbi->device, "%s\n", __func__); 932 933 if (var->xres_virtual < var->xres) 934 var->xres_virtual = var->xres; 935 if (var->yres_virtual < var->yres) 936 var->yres_virtual = var->yres; 937 938 if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) && 939 (var->bits_per_pixel != 16)) 940 var->bits_per_pixel = default_bpp; 941 942 switch (var->bits_per_pixel) { 943 case 16: 944 var->red.length = 5; 945 var->red.offset = 11; 946 var->red.msb_right = 0; 947 948 var->green.length = 6; 949 var->green.offset = 5; 950 var->green.msb_right = 0; 951 952 var->blue.length = 5; 953 var->blue.offset = 0; 954 var->blue.msb_right = 0; 955 956 var->transp.length = 0; 957 var->transp.offset = 0; 958 var->transp.msb_right = 0; 959 break; 960 case 24: 961 var->red.length = 8; 962 var->red.offset = 16; 963 var->red.msb_right = 0; 964 965 var->green.length = 8; 966 var->green.offset = 8; 967 var->green.msb_right = 0; 968 969 var->blue.length = 8; 970 var->blue.offset = 0; 971 var->blue.msb_right = 0; 972 973 var->transp.length = 0; 974 var->transp.offset = 0; 975 var->transp.msb_right = 0; 976 break; 977 case 32: 978 var->red.length = 8; 979 var->red.offset = 16; 980 var->red.msb_right = 0; 981 982 var->green.length = 8; 983 var->green.offset = 8; 984 var->green.msb_right = 0; 985 986 var->blue.length = 8; 987 var->blue.offset = 0; 988 var->blue.msb_right = 0; 989 990 var->transp.length = 8; 991 var->transp.offset = 24; 992 var->transp.msb_right = 0; 993 break; 994 } 995 996 if (var->pixclock < 1000) { 997 htotal = var->xres + var->right_margin + var->hsync_len + 998 var->left_margin; 999 vtotal = var->yres + var->lower_margin + var->vsync_len + 1000 var->upper_margin; 1001 var->pixclock = (vtotal * htotal * 6UL) / 100UL; 1002 var->pixclock = KHZ2PICOS(var->pixclock); 1003 dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n", 1004 var->pixclock); 1005 } 1006 1007 var->height = -1; 1008 var->width = -1; 1009 var->grayscale = 0; 1010 1011 /* Preserve sync flags */ 1012 var->sync |= mx3_fbi->cur_var.sync; 1013 mx3_fbi->cur_var.sync |= var->sync; 1014 1015 return 0; 1016} 1017 1018static u32 chan_to_field(unsigned int chan, struct fb_bitfield *bf) 1019{ 1020 chan &= 0xffff; 1021 chan >>= 16 - bf->length; 1022 return chan << bf->offset; 1023} 1024 1025static int mx3fb_setcolreg(unsigned int regno, unsigned int red, 1026 unsigned int green, unsigned int blue, 1027 unsigned int trans, struct fb_info *fbi) 1028{ 1029 struct mx3fb_info *mx3_fbi = fbi->par; 1030 u32 val; 1031 int ret = 1; 1032 1033 dev_dbg(fbi->device, "%s, regno = %u\n", __func__, regno); 1034 1035 mutex_lock(&mx3_fbi->mutex); 1036 /* 1037 * If greyscale is true, then we convert the RGB value 1038 * to greyscale no matter what visual we are using. 1039 */ 1040 if (fbi->var.grayscale) 1041 red = green = blue = (19595 * red + 38470 * green + 1042 7471 * blue) >> 16; 1043 switch (fbi->fix.visual) { 1044 case FB_VISUAL_TRUECOLOR: 1045 /* 1046 * 16-bit True Colour. We encode the RGB value 1047 * according to the RGB bitfield information. 1048 */ 1049 if (regno < 16) { 1050 u32 *pal = fbi->pseudo_palette; 1051 1052 val = chan_to_field(red, &fbi->var.red); 1053 val |= chan_to_field(green, &fbi->var.green); 1054 val |= chan_to_field(blue, &fbi->var.blue); 1055 1056 pal[regno] = val; 1057 1058 ret = 0; 1059 } 1060 break; 1061 1062 case FB_VISUAL_STATIC_PSEUDOCOLOR: 1063 case FB_VISUAL_PSEUDOCOLOR: 1064 break; 1065 } 1066 mutex_unlock(&mx3_fbi->mutex); 1067 1068 return ret; 1069} 1070 1071static void __blank(int blank, struct fb_info *fbi) 1072{ 1073 struct mx3fb_info *mx3_fbi = fbi->par; 1074 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; 1075 int was_blank = mx3_fbi->blank; 1076 1077 mx3_fbi->blank = blank; 1078 1079 /* Attention! 1080 * Do not call sdc_disable_channel() for a channel that is disabled 1081 * already! This will result in a kernel NULL pointer dereference 1082 * (mx3_fbi->txd is NULL). Hide the fact, that all blank modes are 1083 * handled equally by this driver. 1084 */ 1085 if (blank > FB_BLANK_UNBLANK && was_blank > FB_BLANK_UNBLANK) 1086 return; 1087 1088 switch (blank) { 1089 case FB_BLANK_POWERDOWN: 1090 case FB_BLANK_VSYNC_SUSPEND: 1091 case FB_BLANK_HSYNC_SUSPEND: 1092 case FB_BLANK_NORMAL: 1093 sdc_set_brightness(mx3fb, 0); 1094 memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); 1095 /* Give LCD time to update - enough for 50 and 60 Hz */ 1096 msleep(25); 1097 sdc_disable_channel(mx3_fbi); 1098 break; 1099 case FB_BLANK_UNBLANK: 1100 sdc_enable_channel(mx3_fbi); 1101 sdc_set_brightness(mx3fb, mx3fb->backlight_level); 1102 break; 1103 } 1104} 1105 1106/** 1107 * mx3fb_blank() - blank the display. 1108 */ 1109static int mx3fb_blank(int blank, struct fb_info *fbi) 1110{ 1111 struct mx3fb_info *mx3_fbi = fbi->par; 1112 1113 dev_dbg(fbi->device, "%s, blank = %d, base %p, len %u\n", __func__, 1114 blank, fbi->screen_base, fbi->fix.smem_len); 1115 1116 if (mx3_fbi->blank == blank) 1117 return 0; 1118 1119 mutex_lock(&mx3_fbi->mutex); 1120 __blank(blank, fbi); 1121 mutex_unlock(&mx3_fbi->mutex); 1122 1123 return 0; 1124} 1125 1126/** 1127 * mx3fb_pan_display() - pan or wrap the display 1128 * @var: variable screen buffer information. 1129 * @info: framebuffer information pointer. 1130 * 1131 * We look only at xoffset, yoffset and the FB_VMODE_YWRAP flag 1132 */ 1133static int mx3fb_pan_display(struct fb_var_screeninfo *var, 1134 struct fb_info *fbi) 1135{ 1136 struct mx3fb_info *mx3_fbi = fbi->par; 1137 u32 y_bottom; 1138 unsigned long base; 1139 off_t offset; 1140 dma_cookie_t cookie; 1141 struct scatterlist *sg = mx3_fbi->sg; 1142 struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan; 1143 struct dma_async_tx_descriptor *txd; 1144 int ret; 1145 1146 dev_dbg(fbi->device, "%s [%c]\n", __func__, 1147 list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+'); 1148 1149 if (var->xoffset > 0) { 1150 dev_dbg(fbi->device, "x panning not supported\n"); 1151 return -EINVAL; 1152 } 1153 1154 if (mx3_fbi->cur_var.xoffset == var->xoffset && 1155 mx3_fbi->cur_var.yoffset == var->yoffset) 1156 return 0; /* No change, do nothing */ 1157 1158 y_bottom = var->yoffset; 1159 1160 if (!(var->vmode & FB_VMODE_YWRAP)) 1161 y_bottom += fbi->var.yres; 1162 1163 if (y_bottom > fbi->var.yres_virtual) 1164 return -EINVAL; 1165 1166 mutex_lock(&mx3_fbi->mutex); 1167 1168 offset = var->yoffset * fbi->fix.line_length 1169 + var->xoffset * (fbi->var.bits_per_pixel / 8); 1170 base = fbi->fix.smem_start + offset; 1171 1172 dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n", 1173 mx3_fbi->cur_ipu_buf, base); 1174 1175 /* 1176 * We enable the End of Frame interrupt, which will free a tx-descriptor, 1177 * which we will need for the next dmaengine_prep_slave_sg(). The 1178 * IRQ-handler will disable the IRQ again. 1179 */ 1180 init_completion(&mx3_fbi->flip_cmpl); 1181 enable_irq(mx3_fbi->idmac_channel->eof_irq); 1182 1183 ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10); 1184 if (ret <= 0) { 1185 mutex_unlock(&mx3_fbi->mutex); 1186 dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ? 1187 "user interrupt" : "timeout"); 1188 disable_irq(mx3_fbi->idmac_channel->eof_irq); 1189 return ret ? : -ETIMEDOUT; 1190 } 1191 1192 mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf; 1193 1194 sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base; 1195 sg_set_page(&sg[mx3_fbi->cur_ipu_buf], 1196 virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len, 1197 offset_in_page(fbi->screen_base + offset)); 1198 1199 if (mx3_fbi->txd) 1200 async_tx_ack(mx3_fbi->txd); 1201 1202 txd = dmaengine_prep_slave_sg(dma_chan, sg + 1203 mx3_fbi->cur_ipu_buf, 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); 1204 if (!txd) { 1205 dev_err(fbi->device, 1206 "Error preparing a DMA transaction descriptor.\n"); 1207 mutex_unlock(&mx3_fbi->mutex); 1208 return -EIO; 1209 } 1210 1211 txd->callback_param = txd; 1212 txd->callback = mx3fb_dma_done; 1213 1214 /* 1215 * Emulate original mx3fb behaviour: each new call to idmac_tx_submit() 1216 * should switch to another buffer 1217 */ 1218 cookie = txd->tx_submit(txd); 1219 dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie); 1220 if (cookie < 0) { 1221 dev_err(fbi->device, 1222 "Error updating SDC buf %d to address=0x%08lX\n", 1223 mx3_fbi->cur_ipu_buf, base); 1224 mutex_unlock(&mx3_fbi->mutex); 1225 return -EIO; 1226 } 1227 1228 mx3_fbi->txd = txd; 1229 1230 fbi->var.xoffset = var->xoffset; 1231 fbi->var.yoffset = var->yoffset; 1232 1233 if (var->vmode & FB_VMODE_YWRAP) 1234 fbi->var.vmode |= FB_VMODE_YWRAP; 1235 else 1236 fbi->var.vmode &= ~FB_VMODE_YWRAP; 1237 1238 mx3_fbi->cur_var = fbi->var; 1239 1240 mutex_unlock(&mx3_fbi->mutex); 1241 1242 dev_dbg(fbi->device, "Update complete\n"); 1243 1244 return 0; 1245} 1246 1247/* 1248 * This structure contains the pointers to the control functions that are 1249 * invoked by the core framebuffer driver to perform operations like 1250 * blitting, rectangle filling, copy regions and cursor definition. 1251 */ 1252static const struct fb_ops mx3fb_ops = { 1253 .owner = THIS_MODULE, 1254 .fb_set_par = mx3fb_set_par, 1255 .fb_check_var = mx3fb_check_var, 1256 .fb_setcolreg = mx3fb_setcolreg, 1257 .fb_pan_display = mx3fb_pan_display, 1258 .fb_fillrect = cfb_fillrect, 1259 .fb_copyarea = cfb_copyarea, 1260 .fb_imageblit = cfb_imageblit, 1261 .fb_blank = mx3fb_blank, 1262}; 1263 1264#ifdef CONFIG_PM 1265/* 1266 * Power management hooks. Note that we won't be called from IRQ context, 1267 * unlike the blank functions above, so we may sleep. 1268 */ 1269 1270/* 1271 * Suspends the framebuffer and blanks the screen. Power management support 1272 */ 1273static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state) 1274{ 1275 struct mx3fb_data *mx3fb = platform_get_drvdata(pdev); 1276 struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; 1277 1278 console_lock(); 1279 fb_set_suspend(mx3fb->fbi, 1); 1280 console_unlock(); 1281 1282 if (mx3_fbi->blank == FB_BLANK_UNBLANK) { 1283 sdc_disable_channel(mx3_fbi); 1284 sdc_set_brightness(mx3fb, 0); 1285 1286 } 1287 return 0; 1288} 1289 1290/* 1291 * Resumes the framebuffer and unblanks the screen. Power management support 1292 */ 1293static int mx3fb_resume(struct platform_device *pdev) 1294{ 1295 struct mx3fb_data *mx3fb = platform_get_drvdata(pdev); 1296 struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; 1297 1298 if (mx3_fbi->blank == FB_BLANK_UNBLANK) { 1299 sdc_enable_channel(mx3_fbi); 1300 sdc_set_brightness(mx3fb, mx3fb->backlight_level); 1301 } 1302 1303 console_lock(); 1304 fb_set_suspend(mx3fb->fbi, 0); 1305 console_unlock(); 1306 1307 return 0; 1308} 1309#else 1310#define mx3fb_suspend NULL 1311#define mx3fb_resume NULL 1312#endif 1313 1314/* 1315 * Main framebuffer functions 1316 */ 1317 1318/** 1319 * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. 1320 * @fbi: framebuffer information pointer 1321 * @mem_len: length of mapped memory 1322 * @lock: do not lock during initialisation 1323 * @return: Error code indicating success or failure 1324 * 1325 * This buffer is remapped into a non-cached, non-buffered, memory region to 1326 * allow palette and pixel writes to occur without flushing the cache. Once this 1327 * area is remapped, all virtual memory access to the video memory should occur 1328 * at the new region. 1329 */ 1330static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len, 1331 bool lock) 1332{ 1333 int retval = 0; 1334 dma_addr_t addr; 1335 1336 fbi->screen_base = dma_alloc_wc(fbi->device, mem_len, &addr, 1337 GFP_DMA | GFP_KERNEL); 1338 1339 if (!fbi->screen_base) { 1340 dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", 1341 mem_len); 1342 retval = -EBUSY; 1343 goto err0; 1344 } 1345 1346 if (lock) 1347 mutex_lock(&fbi->mm_lock); 1348 fbi->fix.smem_start = addr; 1349 fbi->fix.smem_len = mem_len; 1350 if (lock) 1351 mutex_unlock(&fbi->mm_lock); 1352 1353 dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", 1354 (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); 1355 1356 fbi->screen_size = fbi->fix.smem_len; 1357 1358 /* Clear the screen */ 1359 memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); 1360 1361 return 0; 1362 1363err0: 1364 fbi->fix.smem_len = 0; 1365 fbi->fix.smem_start = 0; 1366 fbi->screen_base = NULL; 1367 return retval; 1368} 1369 1370/** 1371 * mx3fb_unmap_video_memory() - de-allocate frame buffer memory. 1372 * @fbi: framebuffer information pointer 1373 * @return: error code indicating success or failure 1374 */ 1375static int mx3fb_unmap_video_memory(struct fb_info *fbi) 1376{ 1377 dma_free_wc(fbi->device, fbi->fix.smem_len, fbi->screen_base, 1378 fbi->fix.smem_start); 1379 1380 fbi->screen_base = NULL; 1381 mutex_lock(&fbi->mm_lock); 1382 fbi->fix.smem_start = 0; 1383 fbi->fix.smem_len = 0; 1384 mutex_unlock(&fbi->mm_lock); 1385 return 0; 1386} 1387 1388/** 1389 * mx3fb_init_fbinfo() - initialize framebuffer information object. 1390 * @return: initialized framebuffer structure. 1391 */ 1392static struct fb_info *mx3fb_init_fbinfo(struct device *dev, 1393 const struct fb_ops *ops) 1394{ 1395 struct fb_info *fbi; 1396 struct mx3fb_info *mx3fbi; 1397 int ret; 1398 1399 /* Allocate sufficient memory for the fb structure */ 1400 fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev); 1401 if (!fbi) 1402 return NULL; 1403 1404 mx3fbi = fbi->par; 1405 mx3fbi->cookie = -EINVAL; 1406 mx3fbi->cur_ipu_buf = 0; 1407 1408 fbi->var.activate = FB_ACTIVATE_NOW; 1409 1410 fbi->fbops = ops; 1411 fbi->flags = FBINFO_FLAG_DEFAULT; 1412 fbi->pseudo_palette = mx3fbi->pseudo_palette; 1413 1414 mutex_init(&mx3fbi->mutex); 1415 1416 /* Allocate colormap */ 1417 ret = fb_alloc_cmap(&fbi->cmap, 16, 0); 1418 if (ret < 0) { 1419 framebuffer_release(fbi); 1420 return NULL; 1421 } 1422 1423 return fbi; 1424} 1425 1426static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan) 1427{ 1428 struct device *dev = mx3fb->dev; 1429 struct mx3fb_platform_data *mx3fb_pdata = dev_get_platdata(dev); 1430 const char *name = mx3fb_pdata->name; 1431 unsigned int irq; 1432 struct fb_info *fbi; 1433 struct mx3fb_info *mx3fbi; 1434 const struct fb_videomode *mode; 1435 int ret, num_modes; 1436 1437 if (mx3fb_pdata->disp_data_fmt >= ARRAY_SIZE(di_mappings)) { 1438 dev_err(dev, "Illegal display data format %d\n", 1439 mx3fb_pdata->disp_data_fmt); 1440 return -EINVAL; 1441 } 1442 1443 ichan->client = mx3fb; 1444 irq = ichan->eof_irq; 1445 1446 if (ichan->dma_chan.chan_id != IDMAC_SDC_0) 1447 return -EINVAL; 1448 1449 fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops); 1450 if (!fbi) 1451 return -ENOMEM; 1452 1453 if (!fb_mode) 1454 fb_mode = name; 1455 1456 if (!fb_mode) { 1457 ret = -EINVAL; 1458 goto emode; 1459 } 1460 1461 if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) { 1462 mode = mx3fb_pdata->mode; 1463 num_modes = mx3fb_pdata->num_modes; 1464 } else { 1465 mode = mx3fb_modedb; 1466 num_modes = ARRAY_SIZE(mx3fb_modedb); 1467 } 1468 1469 if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode, 1470 num_modes, NULL, default_bpp)) { 1471 ret = -EBUSY; 1472 goto emode; 1473 } 1474 1475 fb_videomode_to_modelist(mode, num_modes, &fbi->modelist); 1476 1477 /* Default Y virtual size is 2x panel size */ 1478 fbi->var.yres_virtual = fbi->var.yres * 2; 1479 1480 mx3fb->fbi = fbi; 1481 1482 /* set Display Interface clock period */ 1483 mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER); 1484 /* Might need to trigger HSP clock change - see 44.3.3.8.5 */ 1485 1486 sdc_set_brightness(mx3fb, 255); 1487 sdc_set_global_alpha(mx3fb, true, 0xFF); 1488 sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0); 1489 1490 mx3fbi = fbi->par; 1491 mx3fbi->idmac_channel = ichan; 1492 mx3fbi->ipu_ch = ichan->dma_chan.chan_id; 1493 mx3fbi->mx3fb = mx3fb; 1494 mx3fbi->blank = FB_BLANK_NORMAL; 1495 1496 mx3fb->disp_data_fmt = mx3fb_pdata->disp_data_fmt; 1497 1498 init_completion(&mx3fbi->flip_cmpl); 1499 disable_irq(ichan->eof_irq); 1500 dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); 1501 ret = __set_par(fbi, false); 1502 if (ret < 0) 1503 goto esetpar; 1504 1505 __blank(FB_BLANK_UNBLANK, fbi); 1506 1507 dev_info(dev, "registered, using mode %s\n", fb_mode); 1508 1509 ret = register_framebuffer(fbi); 1510 if (ret < 0) 1511 goto erfb; 1512 1513 return 0; 1514 1515erfb: 1516esetpar: 1517emode: 1518 fb_dealloc_cmap(&fbi->cmap); 1519 framebuffer_release(fbi); 1520 1521 return ret; 1522} 1523 1524static bool chan_filter(struct dma_chan *chan, void *arg) 1525{ 1526 struct dma_chan_request *rq = arg; 1527 struct device *dev; 1528 struct mx3fb_platform_data *mx3fb_pdata; 1529 1530 if (!imx_dma_is_ipu(chan)) 1531 return false; 1532 1533 if (!rq) 1534 return false; 1535 1536 dev = rq->mx3fb->dev; 1537 mx3fb_pdata = dev_get_platdata(dev); 1538 1539 return rq->id == chan->chan_id && 1540 mx3fb_pdata->dma_dev == chan->device->dev; 1541} 1542 1543static void release_fbi(struct fb_info *fbi) 1544{ 1545 mx3fb_unmap_video_memory(fbi); 1546 1547 fb_dealloc_cmap(&fbi->cmap); 1548 1549 unregister_framebuffer(fbi); 1550 framebuffer_release(fbi); 1551} 1552 1553static int mx3fb_probe(struct platform_device *pdev) 1554{ 1555 struct device *dev = &pdev->dev; 1556 int ret; 1557 struct resource *sdc_reg; 1558 struct mx3fb_data *mx3fb; 1559 dma_cap_mask_t mask; 1560 struct dma_chan *chan; 1561 struct dma_chan_request rq; 1562 1563 /* 1564 * Display Interface (DI) and Synchronous Display Controller (SDC) 1565 * registers 1566 */ 1567 sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1568 if (!sdc_reg) 1569 return -EINVAL; 1570 1571 mx3fb = devm_kzalloc(&pdev->dev, sizeof(*mx3fb), GFP_KERNEL); 1572 if (!mx3fb) 1573 return -ENOMEM; 1574 1575 spin_lock_init(&mx3fb->lock); 1576 1577 mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg)); 1578 if (!mx3fb->reg_base) { 1579 ret = -ENOMEM; 1580 goto eremap; 1581 } 1582 1583 pr_debug("Remapped %pR at %p\n", sdc_reg, mx3fb->reg_base); 1584 1585 /* IDMAC interface */ 1586 dmaengine_get(); 1587 1588 mx3fb->dev = dev; 1589 platform_set_drvdata(pdev, mx3fb); 1590 1591 rq.mx3fb = mx3fb; 1592 1593 dma_cap_zero(mask); 1594 dma_cap_set(DMA_SLAVE, mask); 1595 dma_cap_set(DMA_PRIVATE, mask); 1596 rq.id = IDMAC_SDC_0; 1597 chan = dma_request_channel(mask, chan_filter, &rq); 1598 if (!chan) { 1599 ret = -EBUSY; 1600 goto ersdc0; 1601 } 1602 1603 mx3fb->backlight_level = 255; 1604 1605 ret = init_fb_chan(mx3fb, to_idmac_chan(chan)); 1606 if (ret < 0) 1607 goto eisdc0; 1608 1609 mx3fb_init_backlight(mx3fb); 1610 1611 return 0; 1612 1613eisdc0: 1614 dma_release_channel(chan); 1615ersdc0: 1616 dmaengine_put(); 1617 iounmap(mx3fb->reg_base); 1618eremap: 1619 dev_err(dev, "mx3fb: failed to register fb\n"); 1620 return ret; 1621} 1622 1623static int mx3fb_remove(struct platform_device *dev) 1624{ 1625 struct mx3fb_data *mx3fb = platform_get_drvdata(dev); 1626 struct fb_info *fbi = mx3fb->fbi; 1627 struct mx3fb_info *mx3_fbi = fbi->par; 1628 struct dma_chan *chan; 1629 1630 chan = &mx3_fbi->idmac_channel->dma_chan; 1631 release_fbi(fbi); 1632 1633 mx3fb_exit_backlight(mx3fb); 1634 1635 dma_release_channel(chan); 1636 dmaengine_put(); 1637 1638 iounmap(mx3fb->reg_base); 1639 return 0; 1640} 1641 1642static struct platform_driver mx3fb_driver = { 1643 .driver = { 1644 .name = MX3FB_NAME, 1645 }, 1646 .probe = mx3fb_probe, 1647 .remove = mx3fb_remove, 1648 .suspend = mx3fb_suspend, 1649 .resume = mx3fb_resume, 1650}; 1651 1652/* 1653 * Parse user specified options (`video=mx3fb:') 1654 * example: 1655 * video=mx3fb:bpp=16 1656 */ 1657static int __init mx3fb_setup(void) 1658{ 1659#ifndef MODULE 1660 char *opt, *options = NULL; 1661 1662 if (fb_get_options("mx3fb", &options)) 1663 return -ENODEV; 1664 1665 if (!options || !*options) 1666 return 0; 1667 1668 while ((opt = strsep(&options, ",")) != NULL) { 1669 if (!*opt) 1670 continue; 1671 if (!strncmp(opt, "bpp=", 4)) 1672 default_bpp = simple_strtoul(opt + 4, NULL, 0); 1673 else 1674 fb_mode = opt; 1675 } 1676#endif 1677 1678 return 0; 1679} 1680 1681static int __init mx3fb_init(void) 1682{ 1683 int ret = mx3fb_setup(); 1684 1685 if (ret < 0) 1686 return ret; 1687 1688 ret = platform_driver_register(&mx3fb_driver); 1689 return ret; 1690} 1691 1692static void __exit mx3fb_exit(void) 1693{ 1694 platform_driver_unregister(&mx3fb_driver); 1695} 1696 1697module_init(mx3fb_init); 1698module_exit(mx3fb_exit); 1699 1700MODULE_AUTHOR("Freescale Semiconductor, Inc."); 1701MODULE_DESCRIPTION("MX3 framebuffer driver"); 1702MODULE_ALIAS("platform:" MX3FB_NAME); 1703MODULE_LICENSE("GPL v2"); 1704