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