Lines Matching +full:sync +full:- +full:on +full:- +full:green
1 // SPDX-License-Identifier: GPL-2.0-only
6 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
21 #include <linux/dma-mapping.h>
26 #include <linux/dma/ipu-dma.h>
29 #include <linux/dma/imx-dma.h>
30 #include <linux/platform_data/video-mx3fb.h>
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)
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)
135 .name = "Sharp-QVGA",
146 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
153 .name = "Sharp-CLI",
164 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
171 .name = "NEC-VGA",
182 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
187 .name = "TV-NTSC",
193 .right_margin = 858 - 640 - 38 - 3,
195 .lower_margin = 518 - 480 - 36 - 1,
198 .sync = 0,
203 .name = "TV-PAL",
209 .right_margin = 960 - 640 - 38 - 32,
211 .lower_margin = 555 - 480 - 32 - 3,
214 .sync = 0,
219 .name = "TV-VGA",
230 .sync = 0,
263 struct mutex mutex; /* Protects fb-ops */
286 int brightness = bl->props.brightness; in mx3fb_bl_update_status()
288 if (bl->props.power != FB_BLANK_UNBLANK) in mx3fb_bl_update_status()
290 if (bl->props.fb_blank != FB_BLANK_UNBLANK) in mx3fb_bl_update_status()
293 fbd->backlight_level = (fbd->backlight_level & ~0xFF) | brightness; in mx3fb_bl_update_status()
295 sdc_set_brightness(fbd, fbd->backlight_level); in mx3fb_bl_update_status()
310 if (fbd->bl) in mx3fb_init_backlight()
316 sdc_set_brightness(fbd, fbd->backlight_level); in mx3fb_init_backlight()
318 bl = backlight_device_register("mx3fb-bl", fbd->dev, fbd, in mx3fb_init_backlight()
321 dev_err(fbd->dev, "error %ld on backlight register\n", in mx3fb_init_backlight()
326 fbd->bl = bl; in mx3fb_init_backlight()
327 bl->props.power = FB_BLANK_UNBLANK; in mx3fb_init_backlight()
328 bl->props.fb_blank = FB_BLANK_UNBLANK; in mx3fb_init_backlight()
329 bl->props.brightness = mx3fb_bl_get_brightness(bl); in mx3fb_init_backlight()
334 backlight_device_unregister(fbd->bl); in mx3fb_exit_backlight()
339 /* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */
345 return __raw_readl(mx3fb->reg_base + reg); in mx3fb_read_reg()
350 __raw_writel(value, mx3fb->reg_base + reg); in mx3fb_write_reg()
365 struct mx3fb_data *mx3fb = fbi->mx3fb; in sdc_fb_init()
376 struct mx3fb_data *mx3fb = fbi->mx3fb; in sdc_fb_uninit()
388 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; in sdc_enable_channel()
389 struct idmac_channel *ichan = mx3_fbi->idmac_channel; in sdc_enable_channel()
390 struct dma_chan *dma_chan = &ichan->dma_chan; in sdc_enable_channel()
394 if (mx3_fbi->txd) in sdc_enable_channel()
395 dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi, in sdc_enable_channel()
396 to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg); in sdc_enable_channel()
398 dev_dbg(mx3fb->dev, "mx3fbi %p, txd = NULL\n", mx3_fbi); in sdc_enable_channel()
401 if (mx3_fbi->cookie < 0) { in sdc_enable_channel()
402 mx3_fbi->txd = dmaengine_prep_slave_sg(dma_chan, in sdc_enable_channel()
403 &mx3_fbi->sg[0], 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); in sdc_enable_channel()
404 if (!mx3_fbi->txd) { in sdc_enable_channel()
405 dev_err(mx3fb->dev, "Cannot allocate descriptor on %d\n", in sdc_enable_channel()
406 dma_chan->chan_id); in sdc_enable_channel()
410 mx3_fbi->txd->callback_param = mx3_fbi->txd; in sdc_enable_channel()
411 mx3_fbi->txd->callback = mx3fb_dma_done; in sdc_enable_channel()
413 cookie = mx3_fbi->txd->tx_submit(mx3_fbi->txd); in sdc_enable_channel()
414 dev_dbg(mx3fb->dev, "%d: Submit %p #%d [%c]\n", __LINE__, in sdc_enable_channel()
415 mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); in sdc_enable_channel()
417 if (!mx3_fbi->txd || !mx3_fbi->txd->tx_submit) { in sdc_enable_channel()
418 dev_err(mx3fb->dev, "Cannot enable channel %d\n", in sdc_enable_channel()
419 dma_chan->chan_id); in sdc_enable_channel()
423 /* Just re-activate the same buffer */ in sdc_enable_channel()
425 cookie = mx3_fbi->cookie; in sdc_enable_channel()
426 dev_dbg(mx3fb->dev, "%d: Re-submit %p #%d [%c]\n", __LINE__, in sdc_enable_channel()
427 mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); in sdc_enable_channel()
431 spin_lock_irqsave(&mx3fb->lock, flags); in sdc_enable_channel()
433 mx3_fbi->cookie = cookie; in sdc_enable_channel()
434 spin_unlock_irqrestore(&mx3fb->lock, flags); in sdc_enable_channel()
447 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; in sdc_disable_channel()
450 if (mx3_fbi->txd == NULL) in sdc_disable_channel()
453 spin_lock_irqsave(&mx3fb->lock, flags); in sdc_disable_channel()
457 spin_unlock_irqrestore(&mx3fb->lock, flags); in sdc_disable_channel()
459 dmaengine_terminate_all(mx3_fbi->txd->chan); in sdc_disable_channel()
460 mx3_fbi->txd = NULL; in sdc_disable_channel()
461 mx3_fbi->cookie = -EINVAL; in sdc_disable_channel()
465 * sdc_set_window_pos() - set window position of the respective plane.
470 * @return: 0 on success or negative error code on failure.
476 return -EINVAL; in sdc_set_window_pos()
478 x_pos += mx3fb->h_start_width; in sdc_set_window_pos()
479 y_pos += mx3fb->v_start_width; in sdc_set_window_pos()
486 * sdc_init_panel() - initialize a synchronous LCD panel.
503 * @return: 0 on success or negative error code on failure.
520 dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height); in sdc_init_panel()
523 return -EINVAL; in sdc_init_panel()
526 reg = ((uint32_t) (h_sync_width - 1) << 26) | in sdc_init_panel()
527 ((uint32_t) (width + h_start_width + h_end_width - 1) << 16); in sdc_init_panel()
534 reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L | in sdc_init_panel()
535 ((uint32_t) (height + v_start_width + v_end_width - 1) << 16); in sdc_init_panel()
542 mx3fb->h_start_width = h_start_width; in sdc_init_panel()
543 mx3fb->v_start_width = v_start_width; in sdc_init_panel()
555 return -EINVAL; in sdc_init_panel()
562 * 2^4 to get fractional part, as long as we stay under ~250MHz and on in sdc_init_panel()
565 ipu_clk = clk_get(mx3fb->dev, NULL); in sdc_init_panel()
574 dev_dbg(mx3fb->dev, in sdc_init_panel()
575 "InitPanel() - Pixel clock divider less than 4\n"); in sdc_init_panel()
579 dev_dbg(mx3fb->dev, "pixel clk = %u, divider %u.%u\n", in sdc_init_panel()
582 spin_lock_irqsave(&mx3fb->lock, lock_flags); in sdc_init_panel()
586 * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing in sdc_init_panel()
589 mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF); in sdc_init_panel()
593 old_conf |= sig->datamask_en << DI_D3_DATAMSK_SHIFT | in sdc_init_panel()
594 sig->clksel_en << DI_D3_CLK_SEL_SHIFT | in sdc_init_panel()
595 sig->clkidle_en << DI_D3_CLK_IDLE_SHIFT; in sdc_init_panel()
599 old_conf |= sig->data_pol << DI_D3_DATA_POL_SHIFT | in sdc_init_panel()
600 sig->clk_pol << DI_D3_CLK_POL_SHIFT | in sdc_init_panel()
601 sig->enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT | in sdc_init_panel()
602 sig->Hsync_pol << DI_D3_HSYNC_POL_SHIFT | in sdc_init_panel()
603 sig->Vsync_pol << DI_D3_VSYNC_POL_SHIFT; in sdc_init_panel()
606 map = &di_mappings[mx3fb->disp_data_fmt]; in sdc_init_panel()
607 mx3fb_write_reg(mx3fb, map->b0, DI_DISP3_B0_MAP); in sdc_init_panel()
608 mx3fb_write_reg(mx3fb, map->b1, DI_DISP3_B1_MAP); in sdc_init_panel()
609 mx3fb_write_reg(mx3fb, map->b2, DI_DISP3_B2_MAP); in sdc_init_panel()
611 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); in sdc_init_panel()
613 dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n", in sdc_init_panel()
615 dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n", in sdc_init_panel()
617 dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n", in sdc_init_panel()
624 * sdc_set_color_key() - set the transparent color key for SDC graphic plane.
628 * @color_key: 24-bit RGB color to use as transparent color key.
629 * @return: 0 on success or negative error code on failure.
637 spin_lock_irqsave(&mx3fb->lock, lock_flags); in sdc_set_color_key()
656 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); in sdc_set_color_key()
662 * sdc_set_global_alpha() - set global alpha blending modes.
667 * @return: 0 on success or negative error code on failure.
674 spin_lock_irqsave(&mx3fb->lock, lock_flags); in sdc_set_global_alpha()
687 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); in sdc_set_global_alpha()
704 dev_dbg(mx3fb->dev, "%s: value = %d\n", __func__, value); in sdc_set_brightness()
705 /* This might be board-specific */ in sdc_set_brightness()
733 * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings.
735 * @return: 0 on success or negative error code on failure.
739 struct fb_fix_screeninfo *fix = &fbi->fix; in mx3fb_set_fix()
740 struct fb_var_screeninfo *var = &fbi->var; in mx3fb_set_fix()
742 memcpy(fix->id, "DISP3 BG", 8); in mx3fb_set_fix()
744 fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; in mx3fb_set_fix()
746 fix->type = FB_TYPE_PACKED_PIXELS; in mx3fb_set_fix()
747 fix->accel = FB_ACCEL_NONE; in mx3fb_set_fix()
748 fix->visual = FB_VISUAL_TRUECOLOR; in mx3fb_set_fix()
749 fix->xpanstep = 1; in mx3fb_set_fix()
750 fix->ypanstep = 1; in mx3fb_set_fix()
758 struct dma_chan *chan = tx_desc->txd.chan; in mx3fb_dma_done()
760 struct mx3fb_data *mx3fb = ichannel->client; in mx3fb_dma_done()
761 struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; in mx3fb_dma_done()
763 dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq); in mx3fb_dma_done()
765 /* We only need one interrupt, it will be re-enabled as needed */ in mx3fb_dma_done()
766 disable_irq_nosync(ichannel->eof_irq); in mx3fb_dma_done()
768 complete(&mx3_fbi->flip_cmpl); in mx3fb_dma_done()
773 struct mx3fb_info *mx3_fbi = fbi->par; in mx3fb_must_set_par()
774 struct fb_var_screeninfo old_var = mx3_fbi->cur_var; in mx3fb_must_set_par()
775 struct fb_var_screeninfo new_var = fbi->var; in mx3fb_must_set_par()
777 if ((fbi->var.activate & FB_ACTIVATE_FORCE) && in mx3fb_must_set_par()
778 (fbi->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) in mx3fb_must_set_par()
796 struct mx3fb_info *mx3_fbi = fbi->par; in __set_par()
797 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; in __set_par()
798 struct idmac_channel *ichan = mx3_fbi->idmac_channel; in __set_par()
799 struct idmac_video_param *video = &ichan->params.video; in __set_par()
800 struct scatterlist *sg = mx3_fbi->sg; in __set_par()
803 if (mx3_fbi->txd) in __set_par()
808 mem_len = fbi->var.yres_virtual * fbi->fix.line_length; in __set_par()
809 if (mem_len > fbi->fix.smem_len) { in __set_par()
810 if (fbi->fix.smem_start) in __set_par()
814 return -ENOMEM; in __set_par()
820 sg_dma_address(&sg[0]) = fbi->fix.smem_start; in __set_par()
821 sg_set_page(&sg[0], virt_to_page(fbi->screen_base), in __set_par()
822 fbi->fix.smem_len, in __set_par()
823 offset_in_page(fbi->screen_base)); in __set_par()
825 if (mx3_fbi->ipu_ch == IDMAC_SDC_0) { in __set_par()
827 if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT) in __set_par()
829 if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) in __set_par()
831 if (fbi->var.sync & FB_SYNC_CLK_INVERT) in __set_par()
833 if (fbi->var.sync & FB_SYNC_DATA_INVERT) in __set_par()
835 if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH) in __set_par()
837 if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN) in __set_par()
839 if (fbi->var.sync & FB_SYNC_CLK_SEL_EN) in __set_par()
841 if (fbi->var.sync & FB_SYNC_SHARP_MODE) in __set_par()
844 dev_dbg(fbi->device, "pixclock = %u Hz\n", in __set_par()
845 (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL)); in __set_par()
848 (PICOS2KHZ(fbi->var.pixclock)) * 1000UL, in __set_par()
849 fbi->var.xres, fbi->var.yres, in __set_par()
850 fbi->var.left_margin, in __set_par()
851 fbi->var.hsync_len, in __set_par()
852 fbi->var.right_margin + in __set_par()
853 fbi->var.hsync_len, in __set_par()
854 fbi->var.upper_margin, in __set_par()
855 fbi->var.vsync_len, in __set_par()
856 fbi->var.lower_margin + in __set_par()
857 fbi->var.vsync_len, &sig_cfg) != 0) { in __set_par()
858 dev_err(fbi->device, in __set_par()
860 return -EINVAL; in __set_par()
864 sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0); in __set_par()
866 mx3_fbi->cur_ipu_buf = 0; in __set_par()
868 video->out_pixel_fmt = bpp_to_pixfmt(fbi->var.bits_per_pixel); in __set_par()
869 video->out_width = fbi->var.xres; in __set_par()
870 video->out_height = fbi->var.yres; in __set_par()
871 video->out_stride = fbi->var.xres_virtual; in __set_par()
873 if (mx3_fbi->blank == FB_BLANK_UNBLANK) { in __set_par()
879 mx3_fbi->cur_var.xoffset = 0; in __set_par()
880 mx3_fbi->cur_var.yoffset = 0; in __set_par()
887 cur_xoffset = mx3_fbi->cur_var.xoffset; in __set_par()
888 cur_yoffset = mx3_fbi->cur_var.yoffset; in __set_par()
889 mx3_fbi->cur_var = fbi->var; in __set_par()
890 mx3_fbi->cur_var.xoffset = cur_xoffset; in __set_par()
891 mx3_fbi->cur_var.yoffset = cur_yoffset; in __set_par()
897 * mx3fb_set_par() - set framebuffer parameters and change the operating mode.
899 * @return: 0 on success or negative error code on failure.
903 struct mx3fb_info *mx3_fbi = fbi->par; in mx3fb_set_par()
904 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; in mx3fb_set_par()
905 struct idmac_channel *ichan = mx3_fbi->idmac_channel; in mx3fb_set_par()
908 dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+'); in mx3fb_set_par()
910 mutex_lock(&mx3_fbi->mutex); in mx3fb_set_par()
914 mutex_unlock(&mx3_fbi->mutex); in mx3fb_set_par()
920 * mx3fb_check_var() - check and adjust framebuffer variable parameters.
926 struct mx3fb_info *mx3_fbi = fbi->par; in mx3fb_check_var()
930 dev_dbg(fbi->device, "%s\n", __func__); in mx3fb_check_var()
932 if (var->xres_virtual < var->xres) in mx3fb_check_var()
933 var->xres_virtual = var->xres; in mx3fb_check_var()
934 if (var->yres_virtual < var->yres) in mx3fb_check_var()
935 var->yres_virtual = var->yres; in mx3fb_check_var()
937 if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) && in mx3fb_check_var()
938 (var->bits_per_pixel != 16)) in mx3fb_check_var()
939 var->bits_per_pixel = default_bpp; in mx3fb_check_var()
941 switch (var->bits_per_pixel) { in mx3fb_check_var()
943 var->red.length = 5; in mx3fb_check_var()
944 var->red.offset = 11; in mx3fb_check_var()
945 var->red.msb_right = 0; in mx3fb_check_var()
947 var->green.length = 6; in mx3fb_check_var()
948 var->green.offset = 5; in mx3fb_check_var()
949 var->green.msb_right = 0; in mx3fb_check_var()
951 var->blue.length = 5; in mx3fb_check_var()
952 var->blue.offset = 0; in mx3fb_check_var()
953 var->blue.msb_right = 0; in mx3fb_check_var()
955 var->transp.length = 0; in mx3fb_check_var()
956 var->transp.offset = 0; in mx3fb_check_var()
957 var->transp.msb_right = 0; in mx3fb_check_var()
960 var->red.length = 8; in mx3fb_check_var()
961 var->red.offset = 16; in mx3fb_check_var()
962 var->red.msb_right = 0; in mx3fb_check_var()
964 var->green.length = 8; in mx3fb_check_var()
965 var->green.offset = 8; in mx3fb_check_var()
966 var->green.msb_right = 0; in mx3fb_check_var()
968 var->blue.length = 8; in mx3fb_check_var()
969 var->blue.offset = 0; in mx3fb_check_var()
970 var->blue.msb_right = 0; in mx3fb_check_var()
972 var->transp.length = 0; in mx3fb_check_var()
973 var->transp.offset = 0; in mx3fb_check_var()
974 var->transp.msb_right = 0; in mx3fb_check_var()
977 var->red.length = 8; in mx3fb_check_var()
978 var->red.offset = 16; in mx3fb_check_var()
979 var->red.msb_right = 0; in mx3fb_check_var()
981 var->green.length = 8; in mx3fb_check_var()
982 var->green.offset = 8; in mx3fb_check_var()
983 var->green.msb_right = 0; in mx3fb_check_var()
985 var->blue.length = 8; in mx3fb_check_var()
986 var->blue.offset = 0; in mx3fb_check_var()
987 var->blue.msb_right = 0; in mx3fb_check_var()
989 var->transp.length = 8; in mx3fb_check_var()
990 var->transp.offset = 24; in mx3fb_check_var()
991 var->transp.msb_right = 0; in mx3fb_check_var()
995 if (var->pixclock < 1000) { in mx3fb_check_var()
996 htotal = var->xres + var->right_margin + var->hsync_len + in mx3fb_check_var()
997 var->left_margin; in mx3fb_check_var()
998 vtotal = var->yres + var->lower_margin + var->vsync_len + in mx3fb_check_var()
999 var->upper_margin; in mx3fb_check_var()
1000 var->pixclock = (vtotal * htotal * 6UL) / 100UL; in mx3fb_check_var()
1001 var->pixclock = KHZ2PICOS(var->pixclock); in mx3fb_check_var()
1002 dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n", in mx3fb_check_var()
1003 var->pixclock); in mx3fb_check_var()
1006 var->height = -1; in mx3fb_check_var()
1007 var->width = -1; in mx3fb_check_var()
1008 var->grayscale = 0; in mx3fb_check_var()
1010 /* Preserve sync flags */ in mx3fb_check_var()
1011 var->sync |= mx3_fbi->cur_var.sync; in mx3fb_check_var()
1012 mx3_fbi->cur_var.sync |= var->sync; in mx3fb_check_var()
1020 chan >>= 16 - bf->length; in chan_to_field()
1021 return chan << bf->offset; in chan_to_field()
1025 unsigned int green, unsigned int blue, in mx3fb_setcolreg() argument
1028 struct mx3fb_info *mx3_fbi = fbi->par; in mx3fb_setcolreg()
1032 dev_dbg(fbi->device, "%s, regno = %u\n", __func__, regno); in mx3fb_setcolreg()
1034 mutex_lock(&mx3_fbi->mutex); in mx3fb_setcolreg()
1039 if (fbi->var.grayscale) in mx3fb_setcolreg()
1040 red = green = blue = (19595 * red + 38470 * green + in mx3fb_setcolreg()
1042 switch (fbi->fix.visual) { in mx3fb_setcolreg()
1045 * 16-bit True Colour. We encode the RGB value in mx3fb_setcolreg()
1049 u32 *pal = fbi->pseudo_palette; in mx3fb_setcolreg()
1051 val = chan_to_field(red, &fbi->var.red); in mx3fb_setcolreg()
1052 val |= chan_to_field(green, &fbi->var.green); in mx3fb_setcolreg()
1053 val |= chan_to_field(blue, &fbi->var.blue); in mx3fb_setcolreg()
1065 mutex_unlock(&mx3_fbi->mutex); in mx3fb_setcolreg()
1072 struct mx3fb_info *mx3_fbi = fbi->par; in __blank()
1073 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; in __blank()
1074 int was_blank = mx3_fbi->blank; in __blank()
1076 mx3_fbi->blank = blank; in __blank()
1081 * (mx3_fbi->txd is NULL). Hide the fact, that all blank modes are in __blank()
1093 memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); in __blank()
1094 /* Give LCD time to update - enough for 50 and 60 Hz */ in __blank()
1100 sdc_set_brightness(mx3fb, mx3fb->backlight_level); in __blank()
1106 * mx3fb_blank() - blank the display.
1112 struct mx3fb_info *mx3_fbi = fbi->par; in mx3fb_blank()
1114 dev_dbg(fbi->device, "%s, blank = %d, base %p, len %u\n", __func__, in mx3fb_blank()
1115 blank, fbi->screen_base, fbi->fix.smem_len); in mx3fb_blank()
1117 if (mx3_fbi->blank == blank) in mx3fb_blank()
1120 mutex_lock(&mx3_fbi->mutex); in mx3fb_blank()
1122 mutex_unlock(&mx3_fbi->mutex); in mx3fb_blank()
1128 * mx3fb_pan_display() - pan or wrap the display
1137 struct mx3fb_info *mx3_fbi = fbi->par; in mx3fb_pan_display()
1142 struct scatterlist *sg = mx3_fbi->sg; in mx3fb_pan_display()
1143 struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan; in mx3fb_pan_display()
1147 dev_dbg(fbi->device, "%s [%c]\n", __func__, in mx3fb_pan_display()
1148 list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+'); in mx3fb_pan_display()
1150 if (var->xoffset > 0) { in mx3fb_pan_display()
1151 dev_dbg(fbi->device, "x panning not supported\n"); in mx3fb_pan_display()
1152 return -EINVAL; in mx3fb_pan_display()
1155 if (mx3_fbi->cur_var.xoffset == var->xoffset && in mx3fb_pan_display()
1156 mx3_fbi->cur_var.yoffset == var->yoffset) in mx3fb_pan_display()
1159 y_bottom = var->yoffset; in mx3fb_pan_display()
1161 if (!(var->vmode & FB_VMODE_YWRAP)) in mx3fb_pan_display()
1162 y_bottom += fbi->var.yres; in mx3fb_pan_display()
1164 if (y_bottom > fbi->var.yres_virtual) in mx3fb_pan_display()
1165 return -EINVAL; in mx3fb_pan_display()
1167 mutex_lock(&mx3_fbi->mutex); in mx3fb_pan_display()
1169 offset = var->yoffset * fbi->fix.line_length in mx3fb_pan_display()
1170 + var->xoffset * (fbi->var.bits_per_pixel / 8); in mx3fb_pan_display()
1171 base = fbi->fix.smem_start + offset; in mx3fb_pan_display()
1173 dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n", in mx3fb_pan_display()
1174 mx3_fbi->cur_ipu_buf, base); in mx3fb_pan_display()
1177 * We enable the End of Frame interrupt, which will free a tx-descriptor, in mx3fb_pan_display()
1179 * IRQ-handler will disable the IRQ again. in mx3fb_pan_display()
1181 init_completion(&mx3_fbi->flip_cmpl); in mx3fb_pan_display()
1182 enable_irq(mx3_fbi->idmac_channel->eof_irq); in mx3fb_pan_display()
1184 ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10); in mx3fb_pan_display()
1186 mutex_unlock(&mx3_fbi->mutex); in mx3fb_pan_display()
1187 dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ? in mx3fb_pan_display()
1189 disable_irq(mx3_fbi->idmac_channel->eof_irq); in mx3fb_pan_display()
1190 return ret ? : -ETIMEDOUT; in mx3fb_pan_display()
1193 mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf; in mx3fb_pan_display()
1195 sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base; in mx3fb_pan_display()
1196 sg_set_page(&sg[mx3_fbi->cur_ipu_buf], in mx3fb_pan_display()
1197 virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len, in mx3fb_pan_display()
1198 offset_in_page(fbi->screen_base + offset)); in mx3fb_pan_display()
1200 if (mx3_fbi->txd) in mx3fb_pan_display()
1201 async_tx_ack(mx3_fbi->txd); in mx3fb_pan_display()
1204 mx3_fbi->cur_ipu_buf, 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); in mx3fb_pan_display()
1206 dev_err(fbi->device, in mx3fb_pan_display()
1208 mutex_unlock(&mx3_fbi->mutex); in mx3fb_pan_display()
1209 return -EIO; in mx3fb_pan_display()
1212 txd->callback_param = txd; in mx3fb_pan_display()
1213 txd->callback = mx3fb_dma_done; in mx3fb_pan_display()
1219 cookie = txd->tx_submit(txd); in mx3fb_pan_display()
1220 dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie); in mx3fb_pan_display()
1222 dev_err(fbi->device, in mx3fb_pan_display()
1224 mx3_fbi->cur_ipu_buf, base); in mx3fb_pan_display()
1225 mutex_unlock(&mx3_fbi->mutex); in mx3fb_pan_display()
1226 return -EIO; in mx3fb_pan_display()
1229 mx3_fbi->txd = txd; in mx3fb_pan_display()
1231 fbi->var.xoffset = var->xoffset; in mx3fb_pan_display()
1232 fbi->var.yoffset = var->yoffset; in mx3fb_pan_display()
1234 if (var->vmode & FB_VMODE_YWRAP) in mx3fb_pan_display()
1235 fbi->var.vmode |= FB_VMODE_YWRAP; in mx3fb_pan_display()
1237 fbi->var.vmode &= ~FB_VMODE_YWRAP; in mx3fb_pan_display()
1239 mx3_fbi->cur_var = fbi->var; in mx3fb_pan_display()
1241 mutex_unlock(&mx3_fbi->mutex); in mx3fb_pan_display()
1243 dev_dbg(fbi->device, "Update complete\n"); in mx3fb_pan_display()
1277 struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; in mx3fb_suspend()
1280 fb_set_suspend(mx3fb->fbi, 1); in mx3fb_suspend()
1283 if (mx3_fbi->blank == FB_BLANK_UNBLANK) { in mx3fb_suspend()
1297 struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; in mx3fb_resume()
1299 if (mx3_fbi->blank == FB_BLANK_UNBLANK) { in mx3fb_resume()
1301 sdc_set_brightness(mx3fb, mx3fb->backlight_level); in mx3fb_resume()
1305 fb_set_suspend(mx3fb->fbi, 0); in mx3fb_resume()
1320 * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer.
1326 * This buffer is remapped into a non-cached, non-buffered, memory region to
1337 fbi->screen_base = dma_alloc_wc(fbi->device, mem_len, &addr, in mx3fb_map_video_memory()
1340 if (!fbi->screen_base) { in mx3fb_map_video_memory()
1341 dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", in mx3fb_map_video_memory()
1343 retval = -EBUSY; in mx3fb_map_video_memory()
1348 mutex_lock(&fbi->mm_lock); in mx3fb_map_video_memory()
1349 fbi->fix.smem_start = addr; in mx3fb_map_video_memory()
1350 fbi->fix.smem_len = mem_len; in mx3fb_map_video_memory()
1352 mutex_unlock(&fbi->mm_lock); in mx3fb_map_video_memory()
1354 dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", in mx3fb_map_video_memory()
1355 (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); in mx3fb_map_video_memory()
1357 fbi->screen_size = fbi->fix.smem_len; in mx3fb_map_video_memory()
1360 memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); in mx3fb_map_video_memory()
1365 fbi->fix.smem_len = 0; in mx3fb_map_video_memory()
1366 fbi->fix.smem_start = 0; in mx3fb_map_video_memory()
1367 fbi->screen_base = NULL; in mx3fb_map_video_memory()
1372 * mx3fb_unmap_video_memory() - de-allocate frame buffer memory.
1378 dma_free_wc(fbi->device, fbi->fix.smem_len, fbi->screen_base, in mx3fb_unmap_video_memory()
1379 fbi->fix.smem_start); in mx3fb_unmap_video_memory()
1381 fbi->screen_base = NULL; in mx3fb_unmap_video_memory()
1382 mutex_lock(&fbi->mm_lock); in mx3fb_unmap_video_memory()
1383 fbi->fix.smem_start = 0; in mx3fb_unmap_video_memory()
1384 fbi->fix.smem_len = 0; in mx3fb_unmap_video_memory()
1385 mutex_unlock(&fbi->mm_lock); in mx3fb_unmap_video_memory()
1390 * mx3fb_init_fbinfo() - initialize framebuffer information object.
1407 mx3fbi = fbi->par; in mx3fb_init_fbinfo()
1408 mx3fbi->cookie = -EINVAL; in mx3fb_init_fbinfo()
1409 mx3fbi->cur_ipu_buf = 0; in mx3fb_init_fbinfo()
1411 fbi->var.activate = FB_ACTIVATE_NOW; in mx3fb_init_fbinfo()
1413 fbi->fbops = ops; in mx3fb_init_fbinfo()
1414 fbi->flags = FBINFO_FLAG_DEFAULT; in mx3fb_init_fbinfo()
1415 fbi->pseudo_palette = mx3fbi->pseudo_palette; in mx3fb_init_fbinfo()
1417 mutex_init(&mx3fbi->mutex); in mx3fb_init_fbinfo()
1420 ret = fb_alloc_cmap(&fbi->cmap, 16, 0); in mx3fb_init_fbinfo()
1431 struct device *dev = mx3fb->dev; in init_fb_chan()
1433 const char *name = mx3fb_pdata->name; in init_fb_chan()
1439 if (mx3fb_pdata->disp_data_fmt >= ARRAY_SIZE(di_mappings)) { in init_fb_chan()
1441 mx3fb_pdata->disp_data_fmt); in init_fb_chan()
1442 return -EINVAL; in init_fb_chan()
1445 ichan->client = mx3fb; in init_fb_chan()
1447 if (ichan->dma_chan.chan_id != IDMAC_SDC_0) in init_fb_chan()
1448 return -EINVAL; in init_fb_chan()
1452 return -ENOMEM; in init_fb_chan()
1458 ret = -EINVAL; in init_fb_chan()
1462 if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) { in init_fb_chan()
1463 mode = mx3fb_pdata->mode; in init_fb_chan()
1464 num_modes = mx3fb_pdata->num_modes; in init_fb_chan()
1470 if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode, in init_fb_chan()
1472 ret = -EBUSY; in init_fb_chan()
1476 fb_videomode_to_modelist(mode, num_modes, &fbi->modelist); in init_fb_chan()
1479 fbi->var.yres_virtual = fbi->var.yres * 2; in init_fb_chan()
1481 mx3fb->fbi = fbi; in init_fb_chan()
1485 /* Might need to trigger HSP clock change - see 44.3.3.8.5 */ in init_fb_chan()
1491 mx3fbi = fbi->par; in init_fb_chan()
1492 mx3fbi->idmac_channel = ichan; in init_fb_chan()
1493 mx3fbi->ipu_ch = ichan->dma_chan.chan_id; in init_fb_chan()
1494 mx3fbi->mx3fb = mx3fb; in init_fb_chan()
1495 mx3fbi->blank = FB_BLANK_NORMAL; in init_fb_chan()
1497 mx3fb->disp_data_fmt = mx3fb_pdata->disp_data_fmt; in init_fb_chan()
1499 init_completion(&mx3fbi->flip_cmpl); in init_fb_chan()
1500 disable_irq(ichan->eof_irq); in init_fb_chan()
1501 dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); in init_fb_chan()
1519 fb_dealloc_cmap(&fbi->cmap); in init_fb_chan()
1537 dev = rq->mx3fb->dev; in chan_filter()
1540 return rq->id == chan->chan_id && in chan_filter()
1541 mx3fb_pdata->dma_dev == chan->device->dev; in chan_filter()
1548 fb_dealloc_cmap(&fbi->cmap); in release_fbi()
1556 struct device *dev = &pdev->dev; in mx3fb_probe()
1570 return -EINVAL; in mx3fb_probe()
1572 mx3fb = devm_kzalloc(&pdev->dev, sizeof(*mx3fb), GFP_KERNEL); in mx3fb_probe()
1574 return -ENOMEM; in mx3fb_probe()
1576 spin_lock_init(&mx3fb->lock); in mx3fb_probe()
1578 mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg)); in mx3fb_probe()
1579 if (!mx3fb->reg_base) { in mx3fb_probe()
1580 ret = -ENOMEM; in mx3fb_probe()
1584 pr_debug("Remapped %pR at %p\n", sdc_reg, mx3fb->reg_base); in mx3fb_probe()
1589 mx3fb->dev = dev; in mx3fb_probe()
1600 ret = -EBUSY; in mx3fb_probe()
1604 mx3fb->backlight_level = 255; in mx3fb_probe()
1618 iounmap(mx3fb->reg_base); in mx3fb_probe()
1627 struct fb_info *fbi = mx3fb->fbi; in mx3fb_remove()
1628 struct mx3fb_info *mx3_fbi = fbi->par; in mx3fb_remove()
1631 chan = &mx3_fbi->idmac_channel->dma_chan; in mx3fb_remove()
1639 iounmap(mx3fb->reg_base); in mx3fb_remove()
1664 return -ENODEV; in mx3fb_setup()