Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2008
0004  * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
0005  *
0006  * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/kernel.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/sched.h>
0013 #include <linux/errno.h>
0014 #include <linux/string.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/slab.h>
0017 #include <linux/fb.h>
0018 #include <linux/delay.h>
0019 #include <linux/init.h>
0020 #include <linux/ioport.h>
0021 #include <linux/dma-mapping.h>
0022 #include <linux/dmaengine.h>
0023 #include <linux/console.h>
0024 #include <linux/clk.h>
0025 #include <linux/mutex.h>
0026 #include <linux/dma/ipu-dma.h>
0027 #include <linux/backlight.h>
0028 
0029 #include <linux/dma/imx-dma.h>
0030 #include <linux/platform_data/video-mx3fb.h>
0031 
0032 #include <asm/io.h>
0033 #include <linux/uaccess.h>
0034 
0035 #define MX3FB_NAME      "mx3_sdc_fb"
0036 
0037 #define MX3FB_REG_OFFSET    0xB4
0038 
0039 /* SDC Registers */
0040 #define SDC_COM_CONF        (0xB4 - MX3FB_REG_OFFSET)
0041 #define SDC_GW_CTRL     (0xB8 - MX3FB_REG_OFFSET)
0042 #define SDC_FG_POS      (0xBC - MX3FB_REG_OFFSET)
0043 #define SDC_BG_POS      (0xC0 - MX3FB_REG_OFFSET)
0044 #define SDC_CUR_POS     (0xC4 - MX3FB_REG_OFFSET)
0045 #define SDC_PWM_CTRL        (0xC8 - MX3FB_REG_OFFSET)
0046 #define SDC_CUR_MAP     (0xCC - MX3FB_REG_OFFSET)
0047 #define SDC_HOR_CONF        (0xD0 - MX3FB_REG_OFFSET)
0048 #define SDC_VER_CONF        (0xD4 - MX3FB_REG_OFFSET)
0049 #define SDC_SHARP_CONF_1    (0xD8 - MX3FB_REG_OFFSET)
0050 #define SDC_SHARP_CONF_2    (0xDC - MX3FB_REG_OFFSET)
0051 
0052 /* Register bits */
0053 #define SDC_COM_TFT_COLOR   0x00000001UL
0054 #define SDC_COM_FG_EN       0x00000010UL
0055 #define SDC_COM_GWSEL       0x00000020UL
0056 #define SDC_COM_GLB_A       0x00000040UL
0057 #define SDC_COM_KEY_COLOR_G 0x00000080UL
0058 #define SDC_COM_BG_EN       0x00000200UL
0059 #define SDC_COM_SHARP       0x00001000UL
0060 
0061 #define SDC_V_SYNC_WIDTH_L  0x00000001UL
0062 
0063 /* Display Interface registers */
0064 #define DI_DISP_IF_CONF     (0x0124 - MX3FB_REG_OFFSET)
0065 #define DI_DISP_SIG_POL     (0x0128 - MX3FB_REG_OFFSET)
0066 #define DI_SER_DISP1_CONF   (0x012C - MX3FB_REG_OFFSET)
0067 #define DI_SER_DISP2_CONF   (0x0130 - MX3FB_REG_OFFSET)
0068 #define DI_HSP_CLK_PER      (0x0134 - MX3FB_REG_OFFSET)
0069 #define DI_DISP0_TIME_CONF_1    (0x0138 - MX3FB_REG_OFFSET)
0070 #define DI_DISP0_TIME_CONF_2    (0x013C - MX3FB_REG_OFFSET)
0071 #define DI_DISP0_TIME_CONF_3    (0x0140 - MX3FB_REG_OFFSET)
0072 #define DI_DISP1_TIME_CONF_1    (0x0144 - MX3FB_REG_OFFSET)
0073 #define DI_DISP1_TIME_CONF_2    (0x0148 - MX3FB_REG_OFFSET)
0074 #define DI_DISP1_TIME_CONF_3    (0x014C - MX3FB_REG_OFFSET)
0075 #define DI_DISP2_TIME_CONF_1    (0x0150 - MX3FB_REG_OFFSET)
0076 #define DI_DISP2_TIME_CONF_2    (0x0154 - MX3FB_REG_OFFSET)
0077 #define DI_DISP2_TIME_CONF_3    (0x0158 - MX3FB_REG_OFFSET)
0078 #define DI_DISP3_TIME_CONF  (0x015C - MX3FB_REG_OFFSET)
0079 #define DI_DISP0_DB0_MAP    (0x0160 - MX3FB_REG_OFFSET)
0080 #define DI_DISP0_DB1_MAP    (0x0164 - MX3FB_REG_OFFSET)
0081 #define DI_DISP0_DB2_MAP    (0x0168 - MX3FB_REG_OFFSET)
0082 #define DI_DISP0_CB0_MAP    (0x016C - MX3FB_REG_OFFSET)
0083 #define DI_DISP0_CB1_MAP    (0x0170 - MX3FB_REG_OFFSET)
0084 #define DI_DISP0_CB2_MAP    (0x0174 - MX3FB_REG_OFFSET)
0085 #define DI_DISP1_DB0_MAP    (0x0178 - MX3FB_REG_OFFSET)
0086 #define DI_DISP1_DB1_MAP    (0x017C - MX3FB_REG_OFFSET)
0087 #define DI_DISP1_DB2_MAP    (0x0180 - MX3FB_REG_OFFSET)
0088 #define DI_DISP1_CB0_MAP    (0x0184 - MX3FB_REG_OFFSET)
0089 #define DI_DISP1_CB1_MAP    (0x0188 - MX3FB_REG_OFFSET)
0090 #define DI_DISP1_CB2_MAP    (0x018C - MX3FB_REG_OFFSET)
0091 #define DI_DISP2_DB0_MAP    (0x0190 - MX3FB_REG_OFFSET)
0092 #define DI_DISP2_DB1_MAP    (0x0194 - MX3FB_REG_OFFSET)
0093 #define DI_DISP2_DB2_MAP    (0x0198 - MX3FB_REG_OFFSET)
0094 #define DI_DISP2_CB0_MAP    (0x019C - MX3FB_REG_OFFSET)
0095 #define DI_DISP2_CB1_MAP    (0x01A0 - MX3FB_REG_OFFSET)
0096 #define DI_DISP2_CB2_MAP    (0x01A4 - MX3FB_REG_OFFSET)
0097 #define DI_DISP3_B0_MAP     (0x01A8 - MX3FB_REG_OFFSET)
0098 #define DI_DISP3_B1_MAP     (0x01AC - MX3FB_REG_OFFSET)
0099 #define DI_DISP3_B2_MAP     (0x01B0 - MX3FB_REG_OFFSET)
0100 #define DI_DISP_ACC_CC      (0x01B4 - MX3FB_REG_OFFSET)
0101 #define DI_DISP_LLA_CONF    (0x01B8 - MX3FB_REG_OFFSET)
0102 #define DI_DISP_LLA_DATA    (0x01BC - MX3FB_REG_OFFSET)
0103 
0104 /* DI_DISP_SIG_POL bits */
0105 #define DI_D3_VSYNC_POL_SHIFT       28
0106 #define DI_D3_HSYNC_POL_SHIFT       27
0107 #define DI_D3_DRDY_SHARP_POL_SHIFT  26
0108 #define DI_D3_CLK_POL_SHIFT     25
0109 #define DI_D3_DATA_POL_SHIFT        24
0110 
0111 /* DI_DISP_IF_CONF bits */
0112 #define DI_D3_CLK_IDLE_SHIFT        26
0113 #define DI_D3_CLK_SEL_SHIFT     25
0114 #define DI_D3_DATAMSK_SHIFT     24
0115 
0116 enum ipu_panel {
0117     IPU_PANEL_SHARP_TFT,
0118     IPU_PANEL_TFT,
0119 };
0120 
0121 struct ipu_di_signal_cfg {
0122     unsigned datamask_en:1;
0123     unsigned clksel_en:1;
0124     unsigned clkidle_en:1;
0125     unsigned data_pol:1;    /* true = inverted */
0126     unsigned clk_pol:1; /* true = rising edge */
0127     unsigned enable_pol:1;
0128     unsigned Hsync_pol:1;   /* true = active high */
0129     unsigned Vsync_pol:1;
0130 };
0131 
0132 static const struct fb_videomode mx3fb_modedb[] = {
0133     {
0134         /* 240x320 @ 60 Hz */
0135         .name       = "Sharp-QVGA",
0136         .refresh    = 60,
0137         .xres       = 240,
0138         .yres       = 320,
0139         .pixclock   = 185925,
0140         .left_margin    = 9,
0141         .right_margin   = 16,
0142         .upper_margin   = 7,
0143         .lower_margin   = 9,
0144         .hsync_len  = 1,
0145         .vsync_len  = 1,
0146         .sync       = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
0147                   FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT |
0148                   FB_SYNC_CLK_IDLE_EN,
0149         .vmode      = FB_VMODE_NONINTERLACED,
0150         .flag       = 0,
0151     }, {
0152         /* 240x33 @ 60 Hz */
0153         .name       = "Sharp-CLI",
0154         .refresh    = 60,
0155         .xres       = 240,
0156         .yres       = 33,
0157         .pixclock   = 185925,
0158         .left_margin    = 9,
0159         .right_margin   = 16,
0160         .upper_margin   = 7,
0161         .lower_margin   = 9 + 287,
0162         .hsync_len  = 1,
0163         .vsync_len  = 1,
0164         .sync       = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
0165                   FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT |
0166                   FB_SYNC_CLK_IDLE_EN,
0167         .vmode      = FB_VMODE_NONINTERLACED,
0168         .flag       = 0,
0169     }, {
0170         /* 640x480 @ 60 Hz */
0171         .name       = "NEC-VGA",
0172         .refresh    = 60,
0173         .xres       = 640,
0174         .yres       = 480,
0175         .pixclock   = 38255,
0176         .left_margin    = 144,
0177         .right_margin   = 0,
0178         .upper_margin   = 34,
0179         .lower_margin   = 40,
0180         .hsync_len  = 1,
0181         .vsync_len  = 1,
0182         .sync       = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
0183         .vmode      = FB_VMODE_NONINTERLACED,
0184         .flag       = 0,
0185     }, {
0186         /* NTSC TV output */
0187         .name       = "TV-NTSC",
0188         .refresh    = 60,
0189         .xres       = 640,
0190         .yres       = 480,
0191         .pixclock   = 37538,
0192         .left_margin    = 38,
0193         .right_margin   = 858 - 640 - 38 - 3,
0194         .upper_margin   = 36,
0195         .lower_margin   = 518 - 480 - 36 - 1,
0196         .hsync_len  = 3,
0197         .vsync_len  = 1,
0198         .sync       = 0,
0199         .vmode      = FB_VMODE_NONINTERLACED,
0200         .flag       = 0,
0201     }, {
0202         /* PAL TV output */
0203         .name       = "TV-PAL",
0204         .refresh    = 50,
0205         .xres       = 640,
0206         .yres       = 480,
0207         .pixclock   = 37538,
0208         .left_margin    = 38,
0209         .right_margin   = 960 - 640 - 38 - 32,
0210         .upper_margin   = 32,
0211         .lower_margin   = 555 - 480 - 32 - 3,
0212         .hsync_len  = 32,
0213         .vsync_len  = 3,
0214         .sync       = 0,
0215         .vmode      = FB_VMODE_NONINTERLACED,
0216         .flag       = 0,
0217     }, {
0218         /* TV output VGA mode, 640x480 @ 65 Hz */
0219         .name       = "TV-VGA",
0220         .refresh    = 60,
0221         .xres       = 640,
0222         .yres       = 480,
0223         .pixclock   = 40574,
0224         .left_margin    = 35,
0225         .right_margin   = 45,
0226         .upper_margin   = 9,
0227         .lower_margin   = 1,
0228         .hsync_len  = 46,
0229         .vsync_len  = 5,
0230         .sync       = 0,
0231         .vmode      = FB_VMODE_NONINTERLACED,
0232         .flag       = 0,
0233     },
0234 };
0235 
0236 struct mx3fb_data {
0237     struct fb_info      *fbi;
0238     int         backlight_level;
0239     void __iomem        *reg_base;
0240     spinlock_t      lock;
0241     struct device       *dev;
0242     struct backlight_device *bl;
0243 
0244     uint32_t        h_start_width;
0245     uint32_t        v_start_width;
0246     enum disp_data_mapping  disp_data_fmt;
0247 };
0248 
0249 struct dma_chan_request {
0250     struct mx3fb_data   *mx3fb;
0251     enum ipu_channel    id;
0252 };
0253 
0254 /* MX3 specific framebuffer information. */
0255 struct mx3fb_info {
0256     int             blank;
0257     enum ipu_channel        ipu_ch;
0258     uint32_t            cur_ipu_buf;
0259 
0260     u32             pseudo_palette[16];
0261 
0262     struct completion       flip_cmpl;
0263     struct mutex            mutex;  /* Protects fb-ops */
0264     struct mx3fb_data       *mx3fb;
0265     struct idmac_channel        *idmac_channel;
0266     struct dma_async_tx_descriptor  *txd;
0267     dma_cookie_t            cookie;
0268     struct scatterlist      sg[2];
0269 
0270     struct fb_var_screeninfo    cur_var; /* current var info */
0271 };
0272 
0273 static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value);
0274 static u32 sdc_get_brightness(struct mx3fb_data *mx3fb);
0275 
0276 static int mx3fb_bl_get_brightness(struct backlight_device *bl)
0277 {
0278     struct mx3fb_data *fbd = bl_get_data(bl);
0279 
0280     return sdc_get_brightness(fbd);
0281 }
0282 
0283 static int mx3fb_bl_update_status(struct backlight_device *bl)
0284 {
0285     struct mx3fb_data *fbd = bl_get_data(bl);
0286     int brightness = bl->props.brightness;
0287 
0288     if (bl->props.power != FB_BLANK_UNBLANK)
0289         brightness = 0;
0290     if (bl->props.fb_blank != FB_BLANK_UNBLANK)
0291         brightness = 0;
0292 
0293     fbd->backlight_level = (fbd->backlight_level & ~0xFF) | brightness;
0294 
0295     sdc_set_brightness(fbd, fbd->backlight_level);
0296 
0297     return 0;
0298 }
0299 
0300 static const struct backlight_ops mx3fb_lcdc_bl_ops = {
0301     .update_status = mx3fb_bl_update_status,
0302     .get_brightness = mx3fb_bl_get_brightness,
0303 };
0304 
0305 static void mx3fb_init_backlight(struct mx3fb_data *fbd)
0306 {
0307     struct backlight_properties props;
0308     struct backlight_device *bl;
0309 
0310     if (fbd->bl)
0311         return;
0312 
0313     memset(&props, 0, sizeof(struct backlight_properties));
0314     props.max_brightness = 0xff;
0315     props.type = BACKLIGHT_RAW;
0316     sdc_set_brightness(fbd, fbd->backlight_level);
0317 
0318     bl = backlight_device_register("mx3fb-bl", fbd->dev, fbd,
0319                        &mx3fb_lcdc_bl_ops, &props);
0320     if (IS_ERR(bl)) {
0321         dev_err(fbd->dev, "error %ld on backlight register\n",
0322                 PTR_ERR(bl));
0323         return;
0324     }
0325 
0326     fbd->bl = bl;
0327     bl->props.power = FB_BLANK_UNBLANK;
0328     bl->props.fb_blank = FB_BLANK_UNBLANK;
0329     bl->props.brightness = mx3fb_bl_get_brightness(bl);
0330 }
0331 
0332 static void mx3fb_exit_backlight(struct mx3fb_data *fbd)
0333 {
0334     backlight_device_unregister(fbd->bl);
0335 }
0336 
0337 static void mx3fb_dma_done(void *);
0338 
0339 /* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */
0340 static const char *fb_mode;
0341 static unsigned long default_bpp = 16;
0342 
0343 static u32 mx3fb_read_reg(struct mx3fb_data *mx3fb, unsigned long reg)
0344 {
0345     return __raw_readl(mx3fb->reg_base + reg);
0346 }
0347 
0348 static void mx3fb_write_reg(struct mx3fb_data *mx3fb, u32 value, unsigned long reg)
0349 {
0350     __raw_writel(value, mx3fb->reg_base + reg);
0351 }
0352 
0353 struct di_mapping {
0354     uint32_t b0, b1, b2;
0355 };
0356 
0357 static const struct di_mapping di_mappings[] = {
0358     [IPU_DISP_DATA_MAPPING_RGB666] = { 0x0005000f, 0x000b000f, 0x0011000f },
0359     [IPU_DISP_DATA_MAPPING_RGB565] = { 0x0004003f, 0x000a000f, 0x000f003f },
0360     [IPU_DISP_DATA_MAPPING_RGB888] = { 0x00070000, 0x000f0000, 0x00170000 },
0361 };
0362 
0363 static void sdc_fb_init(struct mx3fb_info *fbi)
0364 {
0365     struct mx3fb_data *mx3fb = fbi->mx3fb;
0366     uint32_t reg;
0367 
0368     reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
0369 
0370     mx3fb_write_reg(mx3fb, reg | SDC_COM_BG_EN, SDC_COM_CONF);
0371 }
0372 
0373 /* Returns enabled flag before uninit */
0374 static uint32_t sdc_fb_uninit(struct mx3fb_info *fbi)
0375 {
0376     struct mx3fb_data *mx3fb = fbi->mx3fb;
0377     uint32_t reg;
0378 
0379     reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
0380 
0381     mx3fb_write_reg(mx3fb, reg & ~SDC_COM_BG_EN, SDC_COM_CONF);
0382 
0383     return reg & SDC_COM_BG_EN;
0384 }
0385 
0386 static void sdc_enable_channel(struct mx3fb_info *mx3_fbi)
0387 {
0388     struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
0389     struct idmac_channel *ichan = mx3_fbi->idmac_channel;
0390     struct dma_chan *dma_chan = &ichan->dma_chan;
0391     unsigned long flags;
0392     dma_cookie_t cookie;
0393 
0394     if (mx3_fbi->txd)
0395         dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi,
0396             to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg);
0397     else
0398         dev_dbg(mx3fb->dev, "mx3fbi %p, txd = NULL\n", mx3_fbi);
0399 
0400     /* This enables the channel */
0401     if (mx3_fbi->cookie < 0) {
0402         mx3_fbi->txd = dmaengine_prep_slave_sg(dma_chan,
0403               &mx3_fbi->sg[0], 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
0404         if (!mx3_fbi->txd) {
0405             dev_err(mx3fb->dev, "Cannot allocate descriptor on %d\n",
0406                 dma_chan->chan_id);
0407             return;
0408         }
0409 
0410         mx3_fbi->txd->callback_param    = mx3_fbi->txd;
0411         mx3_fbi->txd->callback      = mx3fb_dma_done;
0412 
0413         cookie = mx3_fbi->txd->tx_submit(mx3_fbi->txd);
0414         dev_dbg(mx3fb->dev, "%d: Submit %p #%d [%c]\n", __LINE__,
0415                mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+');
0416     } else {
0417         if (!mx3_fbi->txd || !mx3_fbi->txd->tx_submit) {
0418             dev_err(mx3fb->dev, "Cannot enable channel %d\n",
0419                 dma_chan->chan_id);
0420             return;
0421         }
0422 
0423         /* Just re-activate the same buffer */
0424         dma_async_issue_pending(dma_chan);
0425         cookie = mx3_fbi->cookie;
0426         dev_dbg(mx3fb->dev, "%d: Re-submit %p #%d [%c]\n", __LINE__,
0427                mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+');
0428     }
0429 
0430     if (cookie >= 0) {
0431         spin_lock_irqsave(&mx3fb->lock, flags);
0432         sdc_fb_init(mx3_fbi);
0433         mx3_fbi->cookie = cookie;
0434         spin_unlock_irqrestore(&mx3fb->lock, flags);
0435     }
0436 
0437     /*
0438      * Attention! Without this msleep the channel keeps generating
0439      * interrupts. Next sdc_set_brightness() is going to be called
0440      * from mx3fb_blank().
0441      */
0442     msleep(2);
0443 }
0444 
0445 static void sdc_disable_channel(struct mx3fb_info *mx3_fbi)
0446 {
0447     struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
0448     unsigned long flags;
0449 
0450     if (mx3_fbi->txd == NULL)
0451         return;
0452 
0453     spin_lock_irqsave(&mx3fb->lock, flags);
0454 
0455     sdc_fb_uninit(mx3_fbi);
0456 
0457     spin_unlock_irqrestore(&mx3fb->lock, flags);
0458 
0459     dmaengine_terminate_all(mx3_fbi->txd->chan);
0460     mx3_fbi->txd = NULL;
0461     mx3_fbi->cookie = -EINVAL;
0462 }
0463 
0464 /**
0465  * sdc_set_window_pos() - set window position of the respective plane.
0466  * @mx3fb:  mx3fb context.
0467  * @channel:    IPU DMAC channel ID.
0468  * @x_pos:  X coordinate relative to the top left corner to place window at.
0469  * @y_pos:  Y coordinate relative to the top left corner to place window at.
0470  * @return: 0 on success or negative error code on failure.
0471  */
0472 static int sdc_set_window_pos(struct mx3fb_data *mx3fb, enum ipu_channel channel,
0473                   int16_t x_pos, int16_t y_pos)
0474 {
0475     if (channel != IDMAC_SDC_0)
0476         return -EINVAL;
0477 
0478     x_pos += mx3fb->h_start_width;
0479     y_pos += mx3fb->v_start_width;
0480 
0481     mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS);
0482     return 0;
0483 }
0484 
0485 /**
0486  * sdc_init_panel() - initialize a synchronous LCD panel.
0487  * @mx3fb:      mx3fb context.
0488  * @panel:      panel type.
0489  * @pixel_clk:      desired pixel clock frequency in Hz.
0490  * @width:      width of panel in pixels.
0491  * @height:     height of panel in pixels.
0492  * @h_start_width:  number of pixel clocks between the HSYNC signal pulse
0493  *          and the start of valid data.
0494  * @h_sync_width:   width of the HSYNC signal in units of pixel clocks.
0495  * @h_end_width:    number of pixel clocks between the end of valid data
0496  *          and the HSYNC signal for next line.
0497  * @v_start_width:  number of lines between the VSYNC signal pulse and the
0498  *          start of valid data.
0499  * @v_sync_width:   width of the VSYNC signal in units of lines
0500  * @v_end_width:    number of lines between the end of valid data and the
0501  *          VSYNC signal for next frame.
0502  * @sig:        bitfield of signal polarities for LCD interface.
0503  * @return:     0 on success or negative error code on failure.
0504  */
0505 static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel,
0506               uint32_t pixel_clk,
0507               uint16_t width, uint16_t height,
0508               uint16_t h_start_width, uint16_t h_sync_width,
0509               uint16_t h_end_width, uint16_t v_start_width,
0510               uint16_t v_sync_width, uint16_t v_end_width,
0511               const struct ipu_di_signal_cfg *sig)
0512 {
0513     unsigned long lock_flags;
0514     uint32_t reg;
0515     uint32_t old_conf;
0516     uint32_t div;
0517     struct clk *ipu_clk;
0518     const struct di_mapping *map;
0519 
0520     dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height);
0521 
0522     if (v_sync_width == 0 || h_sync_width == 0)
0523         return -EINVAL;
0524 
0525     /* Init panel size and blanking periods */
0526     reg = ((uint32_t) (h_sync_width - 1) << 26) |
0527         ((uint32_t) (width + h_start_width + h_end_width - 1) << 16);
0528     mx3fb_write_reg(mx3fb, reg, SDC_HOR_CONF);
0529 
0530 #ifdef DEBUG
0531     printk(KERN_CONT " hor_conf %x,", reg);
0532 #endif
0533 
0534     reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L |
0535         ((uint32_t) (height + v_start_width + v_end_width - 1) << 16);
0536     mx3fb_write_reg(mx3fb, reg, SDC_VER_CONF);
0537 
0538 #ifdef DEBUG
0539     printk(KERN_CONT " ver_conf %x\n", reg);
0540 #endif
0541 
0542     mx3fb->h_start_width = h_start_width;
0543     mx3fb->v_start_width = v_start_width;
0544 
0545     switch (panel) {
0546     case IPU_PANEL_SHARP_TFT:
0547         mx3fb_write_reg(mx3fb, 0x00FD0102L, SDC_SHARP_CONF_1);
0548         mx3fb_write_reg(mx3fb, 0x00F500F4L, SDC_SHARP_CONF_2);
0549         mx3fb_write_reg(mx3fb, SDC_COM_SHARP | SDC_COM_TFT_COLOR, SDC_COM_CONF);
0550         break;
0551     case IPU_PANEL_TFT:
0552         mx3fb_write_reg(mx3fb, SDC_COM_TFT_COLOR, SDC_COM_CONF);
0553         break;
0554     default:
0555         return -EINVAL;
0556     }
0557 
0558     /* Init clocking */
0559 
0560     /*
0561      * Calculate divider: fractional part is 4 bits so simply multiple by
0562      * 2^4 to get fractional part, as long as we stay under ~250MHz and on
0563      * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz
0564      */
0565     ipu_clk = clk_get(mx3fb->dev, NULL);
0566     if (!IS_ERR(ipu_clk)) {
0567         div = clk_get_rate(ipu_clk) * 16 / pixel_clk;
0568         clk_put(ipu_clk);
0569     } else {
0570         div = 0;
0571     }
0572 
0573     if (div < 0x40) {   /* Divider less than 4 */
0574         dev_dbg(mx3fb->dev,
0575             "InitPanel() - Pixel clock divider less than 4\n");
0576         div = 0x40;
0577     }
0578 
0579     dev_dbg(mx3fb->dev, "pixel clk = %u, divider %u.%u\n",
0580         pixel_clk, div >> 4, (div & 7) * 125);
0581 
0582     spin_lock_irqsave(&mx3fb->lock, lock_flags);
0583 
0584     /*
0585      * DISP3_IF_CLK_DOWN_WR is half the divider value and 2 fraction bits
0586      * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing
0587      * debug. DISP3_IF_CLK_UP_WR is 0
0588      */
0589     mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF);
0590 
0591     /* DI settings */
0592     old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF;
0593     old_conf |= sig->datamask_en << DI_D3_DATAMSK_SHIFT |
0594         sig->clksel_en << DI_D3_CLK_SEL_SHIFT |
0595         sig->clkidle_en << DI_D3_CLK_IDLE_SHIFT;
0596     mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF);
0597 
0598     old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF;
0599     old_conf |= sig->data_pol << DI_D3_DATA_POL_SHIFT |
0600         sig->clk_pol << DI_D3_CLK_POL_SHIFT |
0601         sig->enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT |
0602         sig->Hsync_pol << DI_D3_HSYNC_POL_SHIFT |
0603         sig->Vsync_pol << DI_D3_VSYNC_POL_SHIFT;
0604     mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL);
0605 
0606     map = &di_mappings[mx3fb->disp_data_fmt];
0607     mx3fb_write_reg(mx3fb, map->b0, DI_DISP3_B0_MAP);
0608     mx3fb_write_reg(mx3fb, map->b1, DI_DISP3_B1_MAP);
0609     mx3fb_write_reg(mx3fb, map->b2, DI_DISP3_B2_MAP);
0610 
0611     spin_unlock_irqrestore(&mx3fb->lock, lock_flags);
0612 
0613     dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n",
0614         mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF));
0615     dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n",
0616         mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL));
0617     dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n",
0618         mx3fb_read_reg(mx3fb, DI_DISP3_TIME_CONF));
0619 
0620     return 0;
0621 }
0622 
0623 /**
0624  * sdc_set_color_key() - set the transparent color key for SDC graphic plane.
0625  * @mx3fb:  mx3fb context.
0626  * @channel:    IPU DMAC channel ID.
0627  * @enable: boolean to enable or disable color keyl.
0628  * @color_key:  24-bit RGB color to use as transparent color key.
0629  * @return: 0 on success or negative error code on failure.
0630  */
0631 static int sdc_set_color_key(struct mx3fb_data *mx3fb, enum ipu_channel channel,
0632                  bool enable, uint32_t color_key)
0633 {
0634     uint32_t reg, sdc_conf;
0635     unsigned long lock_flags;
0636 
0637     spin_lock_irqsave(&mx3fb->lock, lock_flags);
0638 
0639     sdc_conf = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
0640     if (channel == IDMAC_SDC_0)
0641         sdc_conf &= ~SDC_COM_GWSEL;
0642     else
0643         sdc_conf |= SDC_COM_GWSEL;
0644 
0645     if (enable) {
0646         reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0xFF000000L;
0647         mx3fb_write_reg(mx3fb, reg | (color_key & 0x00FFFFFFL),
0648                  SDC_GW_CTRL);
0649 
0650         sdc_conf |= SDC_COM_KEY_COLOR_G;
0651     } else {
0652         sdc_conf &= ~SDC_COM_KEY_COLOR_G;
0653     }
0654     mx3fb_write_reg(mx3fb, sdc_conf, SDC_COM_CONF);
0655 
0656     spin_unlock_irqrestore(&mx3fb->lock, lock_flags);
0657 
0658     return 0;
0659 }
0660 
0661 /**
0662  * sdc_set_global_alpha() - set global alpha blending modes.
0663  * @mx3fb:  mx3fb context.
0664  * @enable: boolean to enable or disable global alpha blending. If disabled,
0665  *      per pixel blending is used.
0666  * @alpha:  global alpha value.
0667  * @return: 0 on success or negative error code on failure.
0668  */
0669 static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t alpha)
0670 {
0671     uint32_t reg;
0672     unsigned long lock_flags;
0673 
0674     spin_lock_irqsave(&mx3fb->lock, lock_flags);
0675 
0676     if (enable) {
0677         reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0x00FFFFFFL;
0678         mx3fb_write_reg(mx3fb, reg | ((uint32_t) alpha << 24), SDC_GW_CTRL);
0679 
0680         reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
0681         mx3fb_write_reg(mx3fb, reg | SDC_COM_GLB_A, SDC_COM_CONF);
0682     } else {
0683         reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
0684         mx3fb_write_reg(mx3fb, reg & ~SDC_COM_GLB_A, SDC_COM_CONF);
0685     }
0686 
0687     spin_unlock_irqrestore(&mx3fb->lock, lock_flags);
0688 
0689     return 0;
0690 }
0691 
0692 static u32 sdc_get_brightness(struct mx3fb_data *mx3fb)
0693 {
0694     u32 brightness;
0695 
0696     brightness = mx3fb_read_reg(mx3fb, SDC_PWM_CTRL);
0697     brightness = (brightness >> 16) & 0xFF;
0698 
0699     return brightness;
0700 }
0701 
0702 static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value)
0703 {
0704     dev_dbg(mx3fb->dev, "%s: value = %d\n", __func__, value);
0705     /* This might be board-specific */
0706     mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL);
0707     return;
0708 }
0709 
0710 static uint32_t bpp_to_pixfmt(int bpp)
0711 {
0712     uint32_t pixfmt = 0;
0713     switch (bpp) {
0714     case 24:
0715         pixfmt = IPU_PIX_FMT_BGR24;
0716         break;
0717     case 32:
0718         pixfmt = IPU_PIX_FMT_BGR32;
0719         break;
0720     case 16:
0721         pixfmt = IPU_PIX_FMT_RGB565;
0722         break;
0723     }
0724     return pixfmt;
0725 }
0726 
0727 static int mx3fb_blank(int blank, struct fb_info *fbi);
0728 static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len,
0729                   bool lock);
0730 static int mx3fb_unmap_video_memory(struct fb_info *fbi);
0731 
0732 /**
0733  * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings.
0734  * @fbi:    framebuffer information pointer
0735  * @return: 0 on success or negative error code on failure.
0736  */
0737 static int mx3fb_set_fix(struct fb_info *fbi)
0738 {
0739     struct fb_fix_screeninfo *fix = &fbi->fix;
0740     struct fb_var_screeninfo *var = &fbi->var;
0741 
0742     memcpy(fix->id, "DISP3 BG", 8);
0743 
0744     fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
0745 
0746     fix->type = FB_TYPE_PACKED_PIXELS;
0747     fix->accel = FB_ACCEL_NONE;
0748     fix->visual = FB_VISUAL_TRUECOLOR;
0749     fix->xpanstep = 1;
0750     fix->ypanstep = 1;
0751 
0752     return 0;
0753 }
0754 
0755 static void mx3fb_dma_done(void *arg)
0756 {
0757     struct idmac_tx_desc *tx_desc = to_tx_desc(arg);
0758     struct dma_chan *chan = tx_desc->txd.chan;
0759     struct idmac_channel *ichannel = to_idmac_chan(chan);
0760     struct mx3fb_data *mx3fb = ichannel->client;
0761     struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
0762 
0763     dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq);
0764 
0765     /* We only need one interrupt, it will be re-enabled as needed */
0766     disable_irq_nosync(ichannel->eof_irq);
0767 
0768     complete(&mx3_fbi->flip_cmpl);
0769 }
0770 
0771 static bool mx3fb_must_set_par(struct fb_info *fbi)
0772 {
0773     struct mx3fb_info *mx3_fbi = fbi->par;
0774     struct fb_var_screeninfo old_var = mx3_fbi->cur_var;
0775     struct fb_var_screeninfo new_var = fbi->var;
0776 
0777     if ((fbi->var.activate & FB_ACTIVATE_FORCE) &&
0778         (fbi->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
0779         return true;
0780 
0781     /*
0782      * Ignore xoffset and yoffset update,
0783      * because pan display handles this case.
0784      */
0785     old_var.xoffset = new_var.xoffset;
0786     old_var.yoffset = new_var.yoffset;
0787 
0788     return !!memcmp(&old_var, &new_var, sizeof(struct fb_var_screeninfo));
0789 }
0790 
0791 static int __set_par(struct fb_info *fbi, bool lock)
0792 {
0793     u32 mem_len, cur_xoffset, cur_yoffset;
0794     struct ipu_di_signal_cfg sig_cfg;
0795     enum ipu_panel mode = IPU_PANEL_TFT;
0796     struct mx3fb_info *mx3_fbi = fbi->par;
0797     struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
0798     struct idmac_channel *ichan = mx3_fbi->idmac_channel;
0799     struct idmac_video_param *video = &ichan->params.video;
0800     struct scatterlist *sg = mx3_fbi->sg;
0801 
0802     /* Total cleanup */
0803     if (mx3_fbi->txd)
0804         sdc_disable_channel(mx3_fbi);
0805 
0806     mx3fb_set_fix(fbi);
0807 
0808     mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
0809     if (mem_len > fbi->fix.smem_len) {
0810         if (fbi->fix.smem_start)
0811             mx3fb_unmap_video_memory(fbi);
0812 
0813         if (mx3fb_map_video_memory(fbi, mem_len, lock) < 0)
0814             return -ENOMEM;
0815     }
0816 
0817     sg_init_table(&sg[0], 1);
0818     sg_init_table(&sg[1], 1);
0819 
0820     sg_dma_address(&sg[0]) = fbi->fix.smem_start;
0821     sg_set_page(&sg[0], virt_to_page(fbi->screen_base),
0822             fbi->fix.smem_len,
0823             offset_in_page(fbi->screen_base));
0824 
0825     if (mx3_fbi->ipu_ch == IDMAC_SDC_0) {
0826         memset(&sig_cfg, 0, sizeof(sig_cfg));
0827         if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
0828             sig_cfg.Hsync_pol = true;
0829         if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
0830             sig_cfg.Vsync_pol = true;
0831         if (fbi->var.sync & FB_SYNC_CLK_INVERT)
0832             sig_cfg.clk_pol = true;
0833         if (fbi->var.sync & FB_SYNC_DATA_INVERT)
0834             sig_cfg.data_pol = true;
0835         if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH)
0836             sig_cfg.enable_pol = true;
0837         if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
0838             sig_cfg.clkidle_en = true;
0839         if (fbi->var.sync & FB_SYNC_CLK_SEL_EN)
0840             sig_cfg.clksel_en = true;
0841         if (fbi->var.sync & FB_SYNC_SHARP_MODE)
0842             mode = IPU_PANEL_SHARP_TFT;
0843 
0844         dev_dbg(fbi->device, "pixclock = %u Hz\n",
0845             (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));
0846 
0847         if (sdc_init_panel(mx3fb, mode,
0848                    (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
0849                    fbi->var.xres, fbi->var.yres,
0850                    fbi->var.left_margin,
0851                    fbi->var.hsync_len,
0852                    fbi->var.right_margin +
0853                    fbi->var.hsync_len,
0854                    fbi->var.upper_margin,
0855                    fbi->var.vsync_len,
0856                    fbi->var.lower_margin +
0857                    fbi->var.vsync_len, &sig_cfg) != 0) {
0858             dev_err(fbi->device,
0859                 "mx3fb: Error initializing panel.\n");
0860             return -EINVAL;
0861         }
0862     }
0863 
0864     sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0);
0865 
0866     mx3_fbi->cur_ipu_buf    = 0;
0867 
0868     video->out_pixel_fmt    = bpp_to_pixfmt(fbi->var.bits_per_pixel);
0869     video->out_width    = fbi->var.xres;
0870     video->out_height   = fbi->var.yres;
0871     video->out_stride   = fbi->var.xres_virtual;
0872 
0873     if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
0874         sdc_enable_channel(mx3_fbi);
0875         /*
0876          * sg[0] points to fb smem_start address
0877          * and is actually active in controller.
0878          */
0879         mx3_fbi->cur_var.xoffset = 0;
0880         mx3_fbi->cur_var.yoffset = 0;
0881     }
0882 
0883     /*
0884      * Preserve xoffset and yoffest in case they are
0885      * inactive in controller as fb is blanked.
0886      */
0887     cur_xoffset = mx3_fbi->cur_var.xoffset;
0888     cur_yoffset = mx3_fbi->cur_var.yoffset;
0889     mx3_fbi->cur_var = fbi->var;
0890     mx3_fbi->cur_var.xoffset = cur_xoffset;
0891     mx3_fbi->cur_var.yoffset = cur_yoffset;
0892 
0893     return 0;
0894 }
0895 
0896 /**
0897  * mx3fb_set_par() - set framebuffer parameters and change the operating mode.
0898  * @fbi:    framebuffer information pointer.
0899  * @return: 0 on success or negative error code on failure.
0900  */
0901 static int mx3fb_set_par(struct fb_info *fbi)
0902 {
0903     struct mx3fb_info *mx3_fbi = fbi->par;
0904     struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
0905     struct idmac_channel *ichan = mx3_fbi->idmac_channel;
0906     int ret;
0907 
0908     dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+');
0909 
0910     mutex_lock(&mx3_fbi->mutex);
0911 
0912     ret = mx3fb_must_set_par(fbi) ? __set_par(fbi, true) : 0;
0913 
0914     mutex_unlock(&mx3_fbi->mutex);
0915 
0916     return ret;
0917 }
0918 
0919 /**
0920  * mx3fb_check_var() - check and adjust framebuffer variable parameters.
0921  * @var:    framebuffer variable parameters
0922  * @fbi:    framebuffer information pointer
0923  */
0924 static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
0925 {
0926     struct mx3fb_info *mx3_fbi = fbi->par;
0927     u32 vtotal;
0928     u32 htotal;
0929 
0930     dev_dbg(fbi->device, "%s\n", __func__);
0931 
0932     if (var->xres_virtual < var->xres)
0933         var->xres_virtual = var->xres;
0934     if (var->yres_virtual < var->yres)
0935         var->yres_virtual = var->yres;
0936 
0937     if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) &&
0938         (var->bits_per_pixel != 16))
0939         var->bits_per_pixel = default_bpp;
0940 
0941     switch (var->bits_per_pixel) {
0942     case 16:
0943         var->red.length = 5;
0944         var->red.offset = 11;
0945         var->red.msb_right = 0;
0946 
0947         var->green.length = 6;
0948         var->green.offset = 5;
0949         var->green.msb_right = 0;
0950 
0951         var->blue.length = 5;
0952         var->blue.offset = 0;
0953         var->blue.msb_right = 0;
0954 
0955         var->transp.length = 0;
0956         var->transp.offset = 0;
0957         var->transp.msb_right = 0;
0958         break;
0959     case 24:
0960         var->red.length = 8;
0961         var->red.offset = 16;
0962         var->red.msb_right = 0;
0963 
0964         var->green.length = 8;
0965         var->green.offset = 8;
0966         var->green.msb_right = 0;
0967 
0968         var->blue.length = 8;
0969         var->blue.offset = 0;
0970         var->blue.msb_right = 0;
0971 
0972         var->transp.length = 0;
0973         var->transp.offset = 0;
0974         var->transp.msb_right = 0;
0975         break;
0976     case 32:
0977         var->red.length = 8;
0978         var->red.offset = 16;
0979         var->red.msb_right = 0;
0980 
0981         var->green.length = 8;
0982         var->green.offset = 8;
0983         var->green.msb_right = 0;
0984 
0985         var->blue.length = 8;
0986         var->blue.offset = 0;
0987         var->blue.msb_right = 0;
0988 
0989         var->transp.length = 8;
0990         var->transp.offset = 24;
0991         var->transp.msb_right = 0;
0992         break;
0993     }
0994 
0995     if (var->pixclock < 1000) {
0996         htotal = var->xres + var->right_margin + var->hsync_len +
0997             var->left_margin;
0998         vtotal = var->yres + var->lower_margin + var->vsync_len +
0999             var->upper_margin;
1000         var->pixclock = (vtotal * htotal * 6UL) / 100UL;
1001         var->pixclock = KHZ2PICOS(var->pixclock);
1002         dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n",
1003             var->pixclock);
1004     }
1005 
1006     var->height = -1;
1007     var->width = -1;
1008     var->grayscale = 0;
1009 
1010     /* Preserve sync flags */
1011     var->sync |= mx3_fbi->cur_var.sync;
1012     mx3_fbi->cur_var.sync |= var->sync;
1013 
1014     return 0;
1015 }
1016 
1017 static u32 chan_to_field(unsigned int chan, struct fb_bitfield *bf)
1018 {
1019     chan &= 0xffff;
1020     chan >>= 16 - bf->length;
1021     return chan << bf->offset;
1022 }
1023 
1024 static int mx3fb_setcolreg(unsigned int regno, unsigned int red,
1025                unsigned int green, unsigned int blue,
1026                unsigned int trans, struct fb_info *fbi)
1027 {
1028     struct mx3fb_info *mx3_fbi = fbi->par;
1029     u32 val;
1030     int ret = 1;
1031 
1032     dev_dbg(fbi->device, "%s, regno = %u\n", __func__, regno);
1033 
1034     mutex_lock(&mx3_fbi->mutex);
1035     /*
1036      * If greyscale is true, then we convert the RGB value
1037      * to greyscale no matter what visual we are using.
1038      */
1039     if (fbi->var.grayscale)
1040         red = green = blue = (19595 * red + 38470 * green +
1041                       7471 * blue) >> 16;
1042     switch (fbi->fix.visual) {
1043     case FB_VISUAL_TRUECOLOR:
1044         /*
1045          * 16-bit True Colour.  We encode the RGB value
1046          * according to the RGB bitfield information.
1047          */
1048         if (regno < 16) {
1049             u32 *pal = fbi->pseudo_palette;
1050 
1051             val = chan_to_field(red, &fbi->var.red);
1052             val |= chan_to_field(green, &fbi->var.green);
1053             val |= chan_to_field(blue, &fbi->var.blue);
1054 
1055             pal[regno] = val;
1056 
1057             ret = 0;
1058         }
1059         break;
1060 
1061     case FB_VISUAL_STATIC_PSEUDOCOLOR:
1062     case FB_VISUAL_PSEUDOCOLOR:
1063         break;
1064     }
1065     mutex_unlock(&mx3_fbi->mutex);
1066 
1067     return ret;
1068 }
1069 
1070 static void __blank(int blank, struct fb_info *fbi)
1071 {
1072     struct mx3fb_info *mx3_fbi = fbi->par;
1073     struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
1074     int was_blank = mx3_fbi->blank;
1075 
1076     mx3_fbi->blank = blank;
1077 
1078     /* Attention!
1079      * Do not call sdc_disable_channel() for a channel that is disabled
1080      * already! This will result in a kernel NULL pointer dereference
1081      * (mx3_fbi->txd is NULL). Hide the fact, that all blank modes are
1082      * handled equally by this driver.
1083      */
1084     if (blank > FB_BLANK_UNBLANK && was_blank > FB_BLANK_UNBLANK)
1085         return;
1086 
1087     switch (blank) {
1088     case FB_BLANK_POWERDOWN:
1089     case FB_BLANK_VSYNC_SUSPEND:
1090     case FB_BLANK_HSYNC_SUSPEND:
1091     case FB_BLANK_NORMAL:
1092         sdc_set_brightness(mx3fb, 0);
1093         memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
1094         /* Give LCD time to update - enough for 50 and 60 Hz */
1095         msleep(25);
1096         sdc_disable_channel(mx3_fbi);
1097         break;
1098     case FB_BLANK_UNBLANK:
1099         sdc_enable_channel(mx3_fbi);
1100         sdc_set_brightness(mx3fb, mx3fb->backlight_level);
1101         break;
1102     }
1103 }
1104 
1105 /**
1106  * mx3fb_blank() - blank the display.
1107  * @blank:  blank value for the panel
1108  * @fbi:    framebuffer information pointer
1109  */
1110 static int mx3fb_blank(int blank, struct fb_info *fbi)
1111 {
1112     struct mx3fb_info *mx3_fbi = fbi->par;
1113 
1114     dev_dbg(fbi->device, "%s, blank = %d, base %p, len %u\n", __func__,
1115         blank, fbi->screen_base, fbi->fix.smem_len);
1116 
1117     if (mx3_fbi->blank == blank)
1118         return 0;
1119 
1120     mutex_lock(&mx3_fbi->mutex);
1121     __blank(blank, fbi);
1122     mutex_unlock(&mx3_fbi->mutex);
1123 
1124     return 0;
1125 }
1126 
1127 /**
1128  * mx3fb_pan_display() - pan or wrap the display
1129  * @var:    variable screen buffer information.
1130  * @fbi:    framebuffer information pointer.
1131  *
1132  * We look only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1133  */
1134 static int mx3fb_pan_display(struct fb_var_screeninfo *var,
1135                  struct fb_info *fbi)
1136 {
1137     struct mx3fb_info *mx3_fbi = fbi->par;
1138     u32 y_bottom;
1139     unsigned long base;
1140     off_t offset;
1141     dma_cookie_t cookie;
1142     struct scatterlist *sg = mx3_fbi->sg;
1143     struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan;
1144     struct dma_async_tx_descriptor *txd;
1145     int ret;
1146 
1147     dev_dbg(fbi->device, "%s [%c]\n", __func__,
1148         list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+');
1149 
1150     if (var->xoffset > 0) {
1151         dev_dbg(fbi->device, "x panning not supported\n");
1152         return -EINVAL;
1153     }
1154 
1155     if (mx3_fbi->cur_var.xoffset == var->xoffset &&
1156         mx3_fbi->cur_var.yoffset == var->yoffset)
1157         return 0;   /* No change, do nothing */
1158 
1159     y_bottom = var->yoffset;
1160 
1161     if (!(var->vmode & FB_VMODE_YWRAP))
1162         y_bottom += fbi->var.yres;
1163 
1164     if (y_bottom > fbi->var.yres_virtual)
1165         return -EINVAL;
1166 
1167     mutex_lock(&mx3_fbi->mutex);
1168 
1169     offset = var->yoffset * fbi->fix.line_length
1170            + var->xoffset * (fbi->var.bits_per_pixel / 8);
1171     base = fbi->fix.smem_start + offset;
1172 
1173     dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n",
1174         mx3_fbi->cur_ipu_buf, base);
1175 
1176     /*
1177      * We enable the End of Frame interrupt, which will free a tx-descriptor,
1178      * which we will need for the next dmaengine_prep_slave_sg(). The
1179      * IRQ-handler will disable the IRQ again.
1180      */
1181     init_completion(&mx3_fbi->flip_cmpl);
1182     enable_irq(mx3_fbi->idmac_channel->eof_irq);
1183 
1184     ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10);
1185     if (ret <= 0) {
1186         mutex_unlock(&mx3_fbi->mutex);
1187         dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ?
1188              "user interrupt" : "timeout");
1189         disable_irq(mx3_fbi->idmac_channel->eof_irq);
1190         return ret ? : -ETIMEDOUT;
1191     }
1192 
1193     mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf;
1194 
1195     sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base;
1196     sg_set_page(&sg[mx3_fbi->cur_ipu_buf],
1197             virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len,
1198             offset_in_page(fbi->screen_base + offset));
1199 
1200     if (mx3_fbi->txd)
1201         async_tx_ack(mx3_fbi->txd);
1202 
1203     txd = dmaengine_prep_slave_sg(dma_chan, sg +
1204         mx3_fbi->cur_ipu_buf, 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
1205     if (!txd) {
1206         dev_err(fbi->device,
1207             "Error preparing a DMA transaction descriptor.\n");
1208         mutex_unlock(&mx3_fbi->mutex);
1209         return -EIO;
1210     }
1211 
1212     txd->callback_param = txd;
1213     txd->callback       = mx3fb_dma_done;
1214 
1215     /*
1216      * Emulate original mx3fb behaviour: each new call to idmac_tx_submit()
1217      * should switch to another buffer
1218      */
1219     cookie = txd->tx_submit(txd);
1220     dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie);
1221     if (cookie < 0) {
1222         dev_err(fbi->device,
1223             "Error updating SDC buf %d to address=0x%08lX\n",
1224             mx3_fbi->cur_ipu_buf, base);
1225         mutex_unlock(&mx3_fbi->mutex);
1226         return -EIO;
1227     }
1228 
1229     mx3_fbi->txd = txd;
1230 
1231     fbi->var.xoffset = var->xoffset;
1232     fbi->var.yoffset = var->yoffset;
1233 
1234     if (var->vmode & FB_VMODE_YWRAP)
1235         fbi->var.vmode |= FB_VMODE_YWRAP;
1236     else
1237         fbi->var.vmode &= ~FB_VMODE_YWRAP;
1238 
1239     mx3_fbi->cur_var = fbi->var;
1240 
1241     mutex_unlock(&mx3_fbi->mutex);
1242 
1243     dev_dbg(fbi->device, "Update complete\n");
1244 
1245     return 0;
1246 }
1247 
1248 /*
1249  * This structure contains the pointers to the control functions that are
1250  * invoked by the core framebuffer driver to perform operations like
1251  * blitting, rectangle filling, copy regions and cursor definition.
1252  */
1253 static const struct fb_ops mx3fb_ops = {
1254     .owner = THIS_MODULE,
1255     .fb_set_par = mx3fb_set_par,
1256     .fb_check_var = mx3fb_check_var,
1257     .fb_setcolreg = mx3fb_setcolreg,
1258     .fb_pan_display = mx3fb_pan_display,
1259     .fb_fillrect = cfb_fillrect,
1260     .fb_copyarea = cfb_copyarea,
1261     .fb_imageblit = cfb_imageblit,
1262     .fb_blank = mx3fb_blank,
1263 };
1264 
1265 #ifdef CONFIG_PM
1266 /*
1267  * Power management hooks.      Note that we won't be called from IRQ context,
1268  * unlike the blank functions above, so we may sleep.
1269  */
1270 
1271 /*
1272  * Suspends the framebuffer and blanks the screen. Power management support
1273  */
1274 static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
1275 {
1276     struct mx3fb_data *mx3fb = platform_get_drvdata(pdev);
1277     struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
1278 
1279     console_lock();
1280     fb_set_suspend(mx3fb->fbi, 1);
1281     console_unlock();
1282 
1283     if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
1284         sdc_disable_channel(mx3_fbi);
1285         sdc_set_brightness(mx3fb, 0);
1286 
1287     }
1288     return 0;
1289 }
1290 
1291 /*
1292  * Resumes the framebuffer and unblanks the screen. Power management support
1293  */
1294 static int mx3fb_resume(struct platform_device *pdev)
1295 {
1296     struct mx3fb_data *mx3fb = platform_get_drvdata(pdev);
1297     struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
1298 
1299     if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
1300         sdc_enable_channel(mx3_fbi);
1301         sdc_set_brightness(mx3fb, mx3fb->backlight_level);
1302     }
1303 
1304     console_lock();
1305     fb_set_suspend(mx3fb->fbi, 0);
1306     console_unlock();
1307 
1308     return 0;
1309 }
1310 #else
1311 #define mx3fb_suspend   NULL
1312 #define mx3fb_resume    NULL
1313 #endif
1314 
1315 /*
1316  * Main framebuffer functions
1317  */
1318 
1319 /**
1320  * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer.
1321  * @fbi:    framebuffer information pointer
1322  * @mem_len:    length of mapped memory
1323  * @lock:   do not lock during initialisation
1324  * @return: Error code indicating success or failure
1325  *
1326  * This buffer is remapped into a non-cached, non-buffered, memory region to
1327  * allow palette and pixel writes to occur without flushing the cache. Once this
1328  * area is remapped, all virtual memory access to the video memory should occur
1329  * at the new region.
1330  */
1331 static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len,
1332                   bool lock)
1333 {
1334     int retval = 0;
1335     dma_addr_t addr;
1336 
1337     fbi->screen_base = dma_alloc_wc(fbi->device, mem_len, &addr,
1338                     GFP_DMA | GFP_KERNEL);
1339 
1340     if (!fbi->screen_base) {
1341         dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n",
1342             mem_len);
1343         retval = -EBUSY;
1344         goto err0;
1345     }
1346 
1347     if (lock)
1348         mutex_lock(&fbi->mm_lock);
1349     fbi->fix.smem_start = addr;
1350     fbi->fix.smem_len = mem_len;
1351     if (lock)
1352         mutex_unlock(&fbi->mm_lock);
1353 
1354     dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n",
1355         (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len);
1356 
1357     fbi->screen_size = fbi->fix.smem_len;
1358 
1359     /* Clear the screen */
1360     memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
1361 
1362     return 0;
1363 
1364 err0:
1365     fbi->fix.smem_len = 0;
1366     fbi->fix.smem_start = 0;
1367     fbi->screen_base = NULL;
1368     return retval;
1369 }
1370 
1371 /**
1372  * mx3fb_unmap_video_memory() - de-allocate frame buffer memory.
1373  * @fbi:    framebuffer information pointer
1374  * @return: error code indicating success or failure
1375  */
1376 static int mx3fb_unmap_video_memory(struct fb_info *fbi)
1377 {
1378     dma_free_wc(fbi->device, fbi->fix.smem_len, fbi->screen_base,
1379             fbi->fix.smem_start);
1380 
1381     fbi->screen_base = NULL;
1382     mutex_lock(&fbi->mm_lock);
1383     fbi->fix.smem_start = 0;
1384     fbi->fix.smem_len = 0;
1385     mutex_unlock(&fbi->mm_lock);
1386     return 0;
1387 }
1388 
1389 /**
1390  * mx3fb_init_fbinfo() - initialize framebuffer information object.
1391  * @dev: the device
1392  * @ops:    framebuffer device operations
1393  * @return: initialized framebuffer structure.
1394  */
1395 static struct fb_info *mx3fb_init_fbinfo(struct device *dev,
1396                      const struct fb_ops *ops)
1397 {
1398     struct fb_info *fbi;
1399     struct mx3fb_info *mx3fbi;
1400     int ret;
1401 
1402     /* Allocate sufficient memory for the fb structure */
1403     fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev);
1404     if (!fbi)
1405         return NULL;
1406 
1407     mx3fbi          = fbi->par;
1408     mx3fbi->cookie      = -EINVAL;
1409     mx3fbi->cur_ipu_buf = 0;
1410 
1411     fbi->var.activate   = FB_ACTIVATE_NOW;
1412 
1413     fbi->fbops      = ops;
1414     fbi->flags      = FBINFO_FLAG_DEFAULT;
1415     fbi->pseudo_palette = mx3fbi->pseudo_palette;
1416 
1417     mutex_init(&mx3fbi->mutex);
1418 
1419     /* Allocate colormap */
1420     ret = fb_alloc_cmap(&fbi->cmap, 16, 0);
1421     if (ret < 0) {
1422         framebuffer_release(fbi);
1423         return NULL;
1424     }
1425 
1426     return fbi;
1427 }
1428 
1429 static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
1430 {
1431     struct device *dev = mx3fb->dev;
1432     struct mx3fb_platform_data *mx3fb_pdata = dev_get_platdata(dev);
1433     const char *name = mx3fb_pdata->name;
1434     struct fb_info *fbi;
1435     struct mx3fb_info *mx3fbi;
1436     const struct fb_videomode *mode;
1437     int ret, num_modes;
1438 
1439     if (mx3fb_pdata->disp_data_fmt >= ARRAY_SIZE(di_mappings)) {
1440         dev_err(dev, "Illegal display data format %d\n",
1441                 mx3fb_pdata->disp_data_fmt);
1442         return -EINVAL;
1443     }
1444 
1445     ichan->client = mx3fb;
1446 
1447     if (ichan->dma_chan.chan_id != IDMAC_SDC_0)
1448         return -EINVAL;
1449 
1450     fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops);
1451     if (!fbi)
1452         return -ENOMEM;
1453 
1454     if (!fb_mode)
1455         fb_mode = name;
1456 
1457     if (!fb_mode) {
1458         ret = -EINVAL;
1459         goto emode;
1460     }
1461 
1462     if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) {
1463         mode = mx3fb_pdata->mode;
1464         num_modes = mx3fb_pdata->num_modes;
1465     } else {
1466         mode = mx3fb_modedb;
1467         num_modes = ARRAY_SIZE(mx3fb_modedb);
1468     }
1469 
1470     if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode,
1471               num_modes, NULL, default_bpp)) {
1472         ret = -EBUSY;
1473         goto emode;
1474     }
1475 
1476     fb_videomode_to_modelist(mode, num_modes, &fbi->modelist);
1477 
1478     /* Default Y virtual size is 2x panel size */
1479     fbi->var.yres_virtual = fbi->var.yres * 2;
1480 
1481     mx3fb->fbi = fbi;
1482 
1483     /* set Display Interface clock period */
1484     mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER);
1485     /* Might need to trigger HSP clock change - see 44.3.3.8.5 */
1486 
1487     sdc_set_brightness(mx3fb, 255);
1488     sdc_set_global_alpha(mx3fb, true, 0xFF);
1489     sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0);
1490 
1491     mx3fbi          = fbi->par;
1492     mx3fbi->idmac_channel   = ichan;
1493     mx3fbi->ipu_ch      = ichan->dma_chan.chan_id;
1494     mx3fbi->mx3fb       = mx3fb;
1495     mx3fbi->blank       = FB_BLANK_NORMAL;
1496 
1497     mx3fb->disp_data_fmt    = mx3fb_pdata->disp_data_fmt;
1498 
1499     init_completion(&mx3fbi->flip_cmpl);
1500     disable_irq(ichan->eof_irq);
1501     dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq);
1502     ret = __set_par(fbi, false);
1503     if (ret < 0)
1504         goto esetpar;
1505 
1506     __blank(FB_BLANK_UNBLANK, fbi);
1507 
1508     dev_info(dev, "registered, using mode %s\n", fb_mode);
1509 
1510     ret = register_framebuffer(fbi);
1511     if (ret < 0)
1512         goto erfb;
1513 
1514     return 0;
1515 
1516 erfb:
1517 esetpar:
1518 emode:
1519     fb_dealloc_cmap(&fbi->cmap);
1520     framebuffer_release(fbi);
1521 
1522     return ret;
1523 }
1524 
1525 static bool chan_filter(struct dma_chan *chan, void *arg)
1526 {
1527     struct dma_chan_request *rq = arg;
1528     struct device *dev;
1529     struct mx3fb_platform_data *mx3fb_pdata;
1530 
1531     if (!imx_dma_is_ipu(chan))
1532         return false;
1533 
1534     if (!rq)
1535         return false;
1536 
1537     dev = rq->mx3fb->dev;
1538     mx3fb_pdata = dev_get_platdata(dev);
1539 
1540     return rq->id == chan->chan_id &&
1541         mx3fb_pdata->dma_dev == chan->device->dev;
1542 }
1543 
1544 static void release_fbi(struct fb_info *fbi)
1545 {
1546     mx3fb_unmap_video_memory(fbi);
1547 
1548     fb_dealloc_cmap(&fbi->cmap);
1549 
1550     unregister_framebuffer(fbi);
1551     framebuffer_release(fbi);
1552 }
1553 
1554 static int mx3fb_probe(struct platform_device *pdev)
1555 {
1556     struct device *dev = &pdev->dev;
1557     int ret;
1558     struct resource *sdc_reg;
1559     struct mx3fb_data *mx3fb;
1560     dma_cap_mask_t mask;
1561     struct dma_chan *chan;
1562     struct dma_chan_request rq;
1563 
1564     /*
1565      * Display Interface (DI) and Synchronous Display Controller (SDC)
1566      * registers
1567      */
1568     sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1569     if (!sdc_reg)
1570         return -EINVAL;
1571 
1572     mx3fb = devm_kzalloc(&pdev->dev, sizeof(*mx3fb), GFP_KERNEL);
1573     if (!mx3fb)
1574         return -ENOMEM;
1575 
1576     spin_lock_init(&mx3fb->lock);
1577 
1578     mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg));
1579     if (!mx3fb->reg_base) {
1580         ret = -ENOMEM;
1581         goto eremap;
1582     }
1583 
1584     pr_debug("Remapped %pR at %p\n", sdc_reg, mx3fb->reg_base);
1585 
1586     /* IDMAC interface */
1587     dmaengine_get();
1588 
1589     mx3fb->dev = dev;
1590     platform_set_drvdata(pdev, mx3fb);
1591 
1592     rq.mx3fb = mx3fb;
1593 
1594     dma_cap_zero(mask);
1595     dma_cap_set(DMA_SLAVE, mask);
1596     dma_cap_set(DMA_PRIVATE, mask);
1597     rq.id = IDMAC_SDC_0;
1598     chan = dma_request_channel(mask, chan_filter, &rq);
1599     if (!chan) {
1600         ret = -EBUSY;
1601         goto ersdc0;
1602     }
1603 
1604     mx3fb->backlight_level = 255;
1605 
1606     ret = init_fb_chan(mx3fb, to_idmac_chan(chan));
1607     if (ret < 0)
1608         goto eisdc0;
1609 
1610     mx3fb_init_backlight(mx3fb);
1611 
1612     return 0;
1613 
1614 eisdc0:
1615     dma_release_channel(chan);
1616 ersdc0:
1617     dmaengine_put();
1618     iounmap(mx3fb->reg_base);
1619 eremap:
1620     dev_err(dev, "mx3fb: failed to register fb\n");
1621     return ret;
1622 }
1623 
1624 static int mx3fb_remove(struct platform_device *dev)
1625 {
1626     struct mx3fb_data *mx3fb = platform_get_drvdata(dev);
1627     struct fb_info *fbi = mx3fb->fbi;
1628     struct mx3fb_info *mx3_fbi = fbi->par;
1629     struct dma_chan *chan;
1630 
1631     chan = &mx3_fbi->idmac_channel->dma_chan;
1632     release_fbi(fbi);
1633 
1634     mx3fb_exit_backlight(mx3fb);
1635 
1636     dma_release_channel(chan);
1637     dmaengine_put();
1638 
1639     iounmap(mx3fb->reg_base);
1640     return 0;
1641 }
1642 
1643 static struct platform_driver mx3fb_driver = {
1644     .driver = {
1645         .name = MX3FB_NAME,
1646     },
1647     .probe = mx3fb_probe,
1648     .remove = mx3fb_remove,
1649     .suspend = mx3fb_suspend,
1650     .resume = mx3fb_resume,
1651 };
1652 
1653 /*
1654  * Parse user specified options (`video=mx3fb:')
1655  * example:
1656  *  video=mx3fb:bpp=16
1657  */
1658 static int __init mx3fb_setup(void)
1659 {
1660 #ifndef MODULE
1661     char *opt, *options = NULL;
1662 
1663     if (fb_get_options("mx3fb", &options))
1664         return -ENODEV;
1665 
1666     if (!options || !*options)
1667         return 0;
1668 
1669     while ((opt = strsep(&options, ",")) != NULL) {
1670         if (!*opt)
1671             continue;
1672         if (!strncmp(opt, "bpp=", 4))
1673             default_bpp = simple_strtoul(opt + 4, NULL, 0);
1674         else
1675             fb_mode = opt;
1676     }
1677 #endif
1678 
1679     return 0;
1680 }
1681 
1682 static int __init mx3fb_init(void)
1683 {
1684     int ret = mx3fb_setup();
1685 
1686     if (ret < 0)
1687         return ret;
1688 
1689     ret = platform_driver_register(&mx3fb_driver);
1690     return ret;
1691 }
1692 
1693 static void __exit mx3fb_exit(void)
1694 {
1695     platform_driver_unregister(&mx3fb_driver);
1696 }
1697 
1698 module_init(mx3fb_init);
1699 module_exit(mx3fb_exit);
1700 
1701 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
1702 MODULE_DESCRIPTION("MX3 framebuffer driver");
1703 MODULE_ALIAS("platform:" MX3FB_NAME);
1704 MODULE_LICENSE("GPL v2");