Exemple #1
0
static int init_panel(struct device *dev, dma_addr_t phys, int memsize,
		      struct mxs_platform_fb_entry *pentry)
{
	int ret = 0;
	lcd_clk = clk_get(dev, "dis_lcdif");
	if (IS_ERR(lcd_clk)) {
		ret = PTR_ERR(lcd_clk);
		goto out;
	}
	ret = clk_enable(lcd_clk);
	if (ret) {
		clk_put(lcd_clk);
		goto out;
	}

	ret = clk_set_rate(lcd_clk, 1000000 / pentry->cycle_time_ns);	/* kHz */
	if (ret) {
		clk_disable(lcd_clk);
		clk_put(lcd_clk);
		goto out;
	}

	/*
	 * Make sure we do a high-to-low transition to reset the panel.
	 * First make it low for 100 msec, hi for 10 msec, low for 10 msec,
	 * then hi.
	 */
	__raw_writel(BM_LCDIF_CTRL1_RESET, REGS_LCDIF_BASE + HW_LCDIF_CTRL1_CLR);	/* low */
	mdelay(100);
	__raw_writel(BM_LCDIF_CTRL1_RESET, REGS_LCDIF_BASE + HW_LCDIF_CTRL1_SET);	/* high */
	mdelay(10);
	__raw_writel(BM_LCDIF_CTRL1_RESET, REGS_LCDIF_BASE + HW_LCDIF_CTRL1_CLR);	/* low */

	/* For the Samsung, Reset must be held low at least 30 uSec
	 * Therefore, we'll hold it low for about 10 mSec just to be sure.
	 * Then we'll wait 1 mSec afterwards.
	 */
	mdelay(10);
	__raw_writel(BM_LCDIF_CTRL1_RESET, REGS_LCDIF_BASE + HW_LCDIF_CTRL1_SET);	/* high */
	mdelay(1);

	setup_dotclk_panel(DOTCLK_V_PULSE_WIDTH, DOTCLK_V_PERIOD,
			   DOTCLK_V_WAIT_CNT, DOTCLK_V_ACTIVE,
			   DOTCLK_H_PULSE_WIDTH, DOTCLK_H_PERIOD,
			   DOTCLK_H_WAIT_CNT, DOTCLK_H_ACTIVE, 0);

	ret = mxs_lcdif_dma_init(dev, phys, memsize);
	if (ret)
		goto out;

	mxs_lcd_set_bl_pdata(pentry->bl_data);
	mxs_lcdif_notify_clients(MXS_LCDIF_PANEL_INIT, pentry);
	return 0;

out:
	return ret;
}
static int init_panel(struct device *dev, dma_addr_t phys, int memsize,
		struct stmp3xxx_platform_fb_entry *pentry)
{
	int ret = 0;

	lcd_clk = clk_get(dev, "lcdif");
	if (IS_ERR(lcd_clk)) {
		ret = PTR_ERR(lcd_clk);
		goto out_1;
	}
	ret = clk_enable(lcd_clk);
	if (ret) {
		clk_put(lcd_clk);
		goto out_1;
	}
	ret = clk_set_rate(lcd_clk,
			1000000/pentry->cycle_time_ns); /* kHz */
	if (ret) {
		clk_disable(lcd_clk);
		clk_put(lcd_clk);
		goto out_1;
	}

	ret = init_pinmux();
	if (ret)
		goto out_1;
	ret = init_pinmux_spi();
	if (ret)
		goto out_2;
	init_panel_hw();

	ret = stmp3xxx_lcdif_dma_init(dev, phys, memsize, 0);
	if (ret)
		goto out_3;

	setup_dotclk_panel(DOTCLK_V_PULSE_WIDTH, DOTCLK_V_PERIOD,
			DOTCLK_V_WAIT_CNT, DOTCLK_V_ACTIVE,
			DOTCLK_H_PULSE_WIDTH, DOTCLK_H_PERIOD,
			DOTCLK_V_WAIT_CNT, DOTCLK_H_ACTIVE, 1);

	stmp3xxx_lcd_set_bl_pdata(pentry->bl_data);
	stmp3xxx_lcdif_notify_clients(STMP3XXX_LCDIF_PANEL_INIT, pentry);
	return 0;
out_3:
	uninit_pinmux_spi();
out_2:
	uninit_pinmux();
out_1:
	return ret;
}
Exemple #3
0
/*
 * This routine actually sets the video mode. It's in here where we
 * the hardware state info->par and fix which can be affected by the
 * change in par. For this driver it doesn't do much.
 *
 */
static int mxc_elcdif_fb_set_par(struct fb_info *fbi)
{
	struct mxc_elcdif_fb_data *data = (struct mxc_elcdif_fb_data *)fbi->par;
	struct elcdif_signal_cfg sig_cfg;
	int mem_len;

	dev_dbg(fbi->device, "Reconfiguring framebuffer\n");

	/* If parameter no change, don't reconfigure. */
	if (mxc_elcdif_fb_par_equal(fbi, data))
	    return 0;

	sema_init(&data->flip_sem, 1);

	/* release prev panel */
	if (!g_elcdif_pix_clk_enable) {
		clk_enable(g_elcdif_pix_clk);
		g_elcdif_pix_clk_enable = true;
	}
	mxc_elcdif_blank_panel(FB_BLANK_POWERDOWN);
	mxc_elcdif_stop();
	release_dotclk_panel();
	mxc_elcdif_dma_release();
	mxc_elcdif_fb_set_fix(fbi);
	if (g_elcdif_pix_clk_enable) {
		clk_disable(g_elcdif_pix_clk);
		g_elcdif_pix_clk_enable = false;
	}

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

		if (mxc_elcdif_fb_map_video_memory(fbi) < 0)
			return -ENOMEM;
	}

	if (data->next_blank != FB_BLANK_UNBLANK)
		return 0;

	/* init next panel */
	if (!g_elcdif_pix_clk_enable) {
		clk_enable(g_elcdif_pix_clk);
		g_elcdif_pix_clk_enable = true;
	}
	mxc_init_elcdif();
	mxc_elcdif_init_panel();

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

	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_LAT_FALL)
		sig_cfg.clk_pol = true;
	if (!(fbi->var.sync & FB_SYNC_OE_LOW_ACT))
		sig_cfg.enable_pol = true;

	setup_dotclk_panel((PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
			   fbi->var.vsync_len,
			   fbi->var.upper_margin +
			   fbi->var.yres + fbi->var.lower_margin,
			   fbi->var.upper_margin,
			   fbi->var.yres,
			   fbi->var.hsync_len,
			   fbi->var.left_margin +
			   fbi->var.xres + fbi->var.right_margin,
			   fbi->var.left_margin,
			   fbi->var.xres,
			   bpp_to_pixfmt(fbi),
			   data->output_pix_fmt,
			   sig_cfg,
			   1);
	mxc_elcdif_frame_addr_setup(fbi->fix.smem_start);
	mxc_elcdif_run();
	mxc_elcdif_blank_panel(FB_BLANK_UNBLANK);

	fbi->mode = (struct fb_videomode *)fb_match_mode(&fbi->var,
							 &fbi->modelist);
	data->var = fbi->var;

	return 0;
}