예제 #1
0
파일: mx3fb.c 프로젝트: 454053205/linux
static void __blank(int blank, struct fb_info *fbi)
{
	struct mx3fb_info *mx3_fbi = fbi->par;
	struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
	int was_blank = mx3_fbi->blank;

	mx3_fbi->blank = blank;

	/* Attention!
	 * Do not call sdc_disable_channel() for a channel that is disabled
	 * already! This will result in a kernel NULL pointer dereference
	 * (mx3_fbi->txd is NULL). Hide the fact, that all blank modes are
	 * handled equally by this driver.
	 */
	if (blank > FB_BLANK_UNBLANK && was_blank > FB_BLANK_UNBLANK)
		return;

	switch (blank) {
	case FB_BLANK_POWERDOWN:
	case FB_BLANK_VSYNC_SUSPEND:
	case FB_BLANK_HSYNC_SUSPEND:
	case FB_BLANK_NORMAL:
		sdc_set_brightness(mx3fb, 0);
		memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
		/* Give LCD time to update - enough for 50 and 60 Hz */
		msleep(25);
		sdc_disable_channel(mx3_fbi);
		break;
	case FB_BLANK_UNBLANK:
		sdc_enable_channel(mx3_fbi);
		sdc_set_brightness(mx3fb, mx3fb->backlight_level);
		break;
	}
}
예제 #2
0
/**
 * mx3fb_blank() - blank the display.
 */
static int mx3fb_blank(int blank, struct fb_info *fbi)
{
	struct mx3fb_info *mx3_fbi = fbi->par;
	struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;

	dev_dbg(fbi->device, "%s, blank = %d, base %p, len %u\n", __func__,
		blank, fbi->screen_base, fbi->fix.smem_len);

	if (mx3_fbi->blank == blank)
		return 0;

	mutex_lock(&mx3_fbi->mutex);
	mx3_fbi->blank = blank;

	switch (blank) {
	case FB_BLANK_POWERDOWN:
	case FB_BLANK_VSYNC_SUSPEND:
	case FB_BLANK_HSYNC_SUSPEND:
	case FB_BLANK_NORMAL:
		sdc_set_brightness(mx3fb, 0);
		memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
		/* Give LCD time to update - enough for 50 and 60 Hz */
		msleep(25);
		sdc_disable_channel(mx3_fbi);
		break;
	case FB_BLANK_UNBLANK:
		sdc_enable_channel(mx3_fbi);
		sdc_set_brightness(mx3fb, mx3fb->backlight_level);
		break;
	}
	mutex_unlock(&mx3_fbi->mutex);

	return 0;
}
예제 #3
0
static void __blank(int blank, struct fb_info *fbi)
{
	struct mx3fb_info *mx3_fbi = fbi->par;
	struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;

	mx3_fbi->blank = blank;

	switch (blank) {
	case FB_BLANK_POWERDOWN:
	case FB_BLANK_VSYNC_SUSPEND:
	case FB_BLANK_HSYNC_SUSPEND:
	case FB_BLANK_NORMAL:
		sdc_set_brightness(mx3fb, 0);
		memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
		/* Give LCD time to update - enough for 50 and 60 Hz */
		msleep(25);
		sdc_disable_channel(mx3_fbi);
		break;
	case FB_BLANK_UNBLANK:
		sdc_enable_channel(mx3_fbi);
		sdc_set_brightness(mx3fb, mx3fb->backlight_level);
		break;
	}
}
예제 #4
0
파일: mx3fb.c 프로젝트: 454053205/linux
static int __set_par(struct fb_info *fbi, bool lock)
{
	u32 mem_len;
	struct ipu_di_signal_cfg sig_cfg;
	enum ipu_panel mode = IPU_PANEL_TFT;
	struct mx3fb_info *mx3_fbi = fbi->par;
	struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
	struct idmac_channel *ichan = mx3_fbi->idmac_channel;
	struct idmac_video_param *video = &ichan->params.video;
	struct scatterlist *sg = mx3_fbi->sg;

	/* Total cleanup */
	if (mx3_fbi->txd)
		sdc_disable_channel(mx3_fbi);

	mx3fb_set_fix(fbi);

	mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
	if (mem_len > fbi->fix.smem_len) {
		if (fbi->fix.smem_start)
			mx3fb_unmap_video_memory(fbi);

		if (mx3fb_map_video_memory(fbi, mem_len, lock) < 0)
			return -ENOMEM;
	}

	sg_init_table(&sg[0], 1);
	sg_init_table(&sg[1], 1);

	sg_dma_address(&sg[0]) = fbi->fix.smem_start;
	sg_set_page(&sg[0], virt_to_page(fbi->screen_base),
		    fbi->fix.smem_len,
		    offset_in_page(fbi->screen_base));

	if (mx3_fbi->ipu_ch == IDMAC_SDC_0) {
		memset(&sig_cfg, 0, sizeof(sig_cfg));
		if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
			sig_cfg.Hsync_pol = true;
		if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
			sig_cfg.Vsync_pol = true;
		if (fbi->var.sync & FB_SYNC_CLK_INVERT)
			sig_cfg.clk_pol = true;
		if (fbi->var.sync & FB_SYNC_DATA_INVERT)
			sig_cfg.data_pol = true;
		if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH)
			sig_cfg.enable_pol = true;
		if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
			sig_cfg.clkidle_en = true;
		if (fbi->var.sync & FB_SYNC_CLK_SEL_EN)
			sig_cfg.clksel_en = true;
		if (fbi->var.sync & FB_SYNC_SHARP_MODE)
			mode = IPU_PANEL_SHARP_TFT;

		dev_dbg(fbi->device, "pixclock = %ul Hz\n",
			(u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));

		if (sdc_init_panel(mx3fb, mode,
				   (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
				   fbi->var.xres, fbi->var.yres,
				   (fbi->var.sync & FB_SYNC_SWAP_RGB) ?
				   IPU_PIX_FMT_BGR666 : IPU_PIX_FMT_RGB666,
				   fbi->var.left_margin,
				   fbi->var.hsync_len,
				   fbi->var.right_margin +
				   fbi->var.hsync_len,
				   fbi->var.upper_margin,
				   fbi->var.vsync_len,
				   fbi->var.lower_margin +
				   fbi->var.vsync_len, sig_cfg) != 0) {
			dev_err(fbi->device,
				"mx3fb: Error initializing panel.\n");
			return -EINVAL;
		}
	}

	sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0);

	mx3_fbi->cur_ipu_buf	= 0;

	video->out_pixel_fmt	= bpp_to_pixfmt(fbi->var.bits_per_pixel);
	video->out_width	= fbi->var.xres;
	video->out_height	= fbi->var.yres;
	video->out_stride	= fbi->var.xres_virtual;

	if (mx3_fbi->blank == FB_BLANK_UNBLANK)
		sdc_enable_channel(mx3_fbi);

	return 0;
}