예제 #1
0
static int dpi_display_enable(struct omap_dss_device *dssdev)
{
	int r;

	r = omap_dss_start_device(dssdev);
	if (r) {
		DSSERR("failed to start device\n");
		goto err0;
	}

	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
		DSSERR("display already enabled\n");
		r = -EINVAL;
		goto err1;
	}

	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);

	r = dpi_basic_init(dssdev);
	if (r)
		goto err2;

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	dss_clk_enable(DSS_CLK_FCK2);
	enable_vpll2_power(1);
	r = dsi_pll_init(1, 1);
	if (r)
		goto err3;
#endif
	r = dpi_set_mode(dssdev);
	if (r)
		goto err4;

	mdelay(2);

	dispc_enable_lcd_out(1);

	r = dssdev->driver->enable(dssdev);
	if (r)
		goto err5;

	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

	return 0;

err5:
	dispc_enable_lcd_out(0);
err4:
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	dsi_pll_uninit();
err3:
	dss_clk_disable(DSS_CLK_FCK2);
#endif
err2:
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
err1:
	omap_dss_stop_device(dssdev);
err0:
	return r;
}
예제 #2
0
static int dpi_display_set_update_mode(struct omap_dss_device *dssdev,
		enum omap_dss_update_mode mode)
{
	if (mode == OMAP_DSS_UPDATE_MANUAL)
		return -EINVAL;

	if (mode == OMAP_DSS_UPDATE_DISABLED) {
		if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2)
			dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD2, 0);
		else
			dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 0);

		dpi.update_enabled = 0;
	} else {

		if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2)
			dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD2, 1);
		else
			dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 1);

		dpi.update_enabled = 1;
	}

	return 0;
}
예제 #3
0
static int dpi_display_enable(struct omap_display *display)
{
	struct omap_panel *panel = display->panel;
	int r;

	if (display->state != OMAP_DSS_DISPLAY_DISABLED) {
		DSSERR("display already enabled\n");
		return -EINVAL;
	}

	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);

	r = dpi_basic_init(display);
	if (r)
		goto err0;

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	dss_clk_enable(DSS_CLK_FCK2);
	r = dsi_pll_init(0, 1);
	if (r)
		goto err1;
#endif
	r = dpi_set_mode(display);
	if (r)
		goto err2;

	mdelay(2);

	dispc_enable_lcd_out(1);

	r = panel->enable(display);
	if (r)
		goto err3;

	display->state = OMAP_DSS_DISPLAY_ACTIVE;

	return 0;

err3:
	dispc_enable_lcd_out(0);
err2:
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	dsi_pll_uninit();
err1:
	dss_clk_disable(DSS_CLK_FCK2);
#endif
err0:
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
	return r;
}
예제 #4
0
static int dpi_display_resume(struct omap_dss_device *dssdev)
{
	int r = 0;
	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
		return -EINVAL;

	DSSDBG("dpi_display_resume\n");

	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	dss_clk_enable(DSS_CLK_FCK2);
	enable_vpll2_power(1);

	r = dsi_pll_init(1, 1);
	if (r)
		goto err0;

	r = dpi_set_mode(dssdev);
	if (r)
		goto err0;
#endif

	dispc_enable_lcd_out(1);

	if (dssdev->driver->resume) {
		r = dssdev->driver->resume(dssdev);
		if (r)
			goto err1;
	}

	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

	return 0;

err1:
	dispc_enable_lcd_out(0);

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
err0:
	DSSERR("<%s!!> err0: failed to init DSI_PLL = %d\n", __func__, r);
	dss_select_clk_source(0, 0);
	dsi_pll_uninit();
	dss_clk_disable(DSS_CLK_FCK2);
	enable_vpll2_power(0);
#endif
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
	return r;
}
예제 #5
0
static int sdi_display_resume(struct omap_dss_device *dssdev)
{
	int r;

	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
		return -EINVAL;

	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);

	r = dss_sdi_enable();
	if (r)
		goto err;
	mdelay(2);

	/* TODO: change here if LCD2 support is needed */
	dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 1);

	if (dssdev->driver->resume)
		dssdev->driver->resume(dssdev);

	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

	return 0;
err:
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
	return r;
}
예제 #6
0
static int sdi_display_set_update_mode(struct omap_display *display,
		enum omap_dss_update_mode mode)
{
	if (mode == OMAP_DSS_UPDATE_MANUAL)
		return -EINVAL;

	if (mode == OMAP_DSS_UPDATE_DISABLED) {
		dispc_enable_lcd_out(0);
		sdi.update_enabled = 0;
	} else {
		dispc_enable_lcd_out(1);
		sdi.update_enabled = 1;
	}

	return 0;
}
예제 #7
0
static int dpi_display_suspend(struct omap_dss_device *dssdev)
{
	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
		return -EINVAL;

	DSSDBG("dpi_display_suspend\n");

	if (dssdev->driver->suspend)
		dssdev->driver->suspend(dssdev);

	dispc_enable_lcd_out(0);

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	dss_select_clk_source(0, 0);
	dsi_pll_uninit();
	enable_vpll2_power(0);
	dss_clk_disable(DSS_CLK_FCK2);
#endif

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);

	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;

	return 0;
}
예제 #8
0
static int sdi_display_resume(struct omap_display *display)
{
	int r;

	if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
		return -EINVAL;

	twl4030_enable_regulator(RES_VAUX1);

	sdi_pad_config(display, 1);
	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);

	r = dss_sdi_enable();
	if (r)
		goto err;
	mdelay(2);

	dispc_enable_lcd_out(1);

	if (display->panel->resume)
		display->panel->resume(display);

	display->state = OMAP_DSS_DISPLAY_ACTIVE;

	return 0;

 err:
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
	sdi_pad_config(display, 0);

	twl4030_disable_regulator(RES_VAUX1);

	return r;
}
예제 #9
0
void rfbi_transfer_area(u16 width, u16 height,
			     void (callback)(void *data), void *data)
{
	u32 l;

	/*BUG_ON(callback == 0);*/
	BUG_ON(rfbi.framedone_callback != NULL);

	DSSDBG("rfbi_transfer_area %dx%d\n", width, height);

	dispc_set_lcd_size(width, height);

	dispc_enable_lcd_out(1);

	rfbi.framedone_callback = callback;
	rfbi.framedone_callback_data = data;

	rfbi_enable_clocks(1);

	rfbi_write_reg(RFBI_PIXEL_CNT, width * height);

	l = rfbi_read_reg(RFBI_CONTROL);
	l = FLD_MOD(l, 1, 0, 0); /* enable */
	if (!rfbi.te_enabled)
		l = FLD_MOD(l, 1, 4, 4); /* ITE */

	perf_mark_start();

	rfbi_write_reg(RFBI_CONTROL, l);
}
예제 #10
0
static void dpi_display_disable(struct omap_dss_device *dssdev)
{
	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
		return;

	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
		dpi_display_resume(dssdev);

	dssdev->driver->disable(dssdev);

	dispc_enable_lcd_out(0);

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	dss_select_clk_source(0, 0);
	dsi_pll_uninit();
	enable_vpll2_power(0);
	dss_clk_disable(DSS_CLK_FCK2);
#endif

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);

	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;

	omap_dss_stop_device(dssdev);
}
예제 #11
0
static int sdi_display_set_update_mode(struct omap_dss_device *dssdev,
		enum omap_dss_update_mode mode)
{
	if (mode == OMAP_DSS_UPDATE_MANUAL)
		return -EINVAL;

	if (mode == OMAP_DSS_UPDATE_DISABLED) {
		/* TODO: change here if LCD2 support is needed */
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 0);
		sdi.update_enabled = 0;
	} else {
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 1);
		sdi.update_enabled = 1;
	}

	return 0;
}
예제 #12
0
static int dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
{
	int r = 0;

	if (dssdev->channel != OMAP_DSS_CHANNEL_LCD &&
		dssdev->channel != OMAP_DSS_CHANNEL_LCD2)
		return -EINVAL;

	dispc_enable_lcd_out(dssdev->channel, 0);

	r = dispc_set_tft_data_lines(dssdev->channel, data_lines);

	if (!r)
		dssdev->phy.dpi.data_lines = data_lines;

	dispc_enable_lcd_out(dssdev->channel, 1);

	return r;
}
예제 #13
0
static void dpi_display_disable(struct omap_dss_device *dssdev)
{
	int lcd_channel_ix = 0;
	int use_dsi_for_hdmi = 0;

	if (strncmp("hdmi", dssdev->name, 4) == 0)
		use_dsi_for_hdmi = 1;

	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2)
		lcd_channel_ix = 1;

	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
		return;

	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
		dpi_display_resume(dssdev);

	dssdev->driver->disable(dssdev);

	if (use_dsi_for_hdmi) {
		dss_select_clk_source(0, 0);

		dispc_go(OMAP_DSS_CHANNEL_LCD);
		while (dispc_go_busy(OMAP_DSS_CHANNEL_LCD))
			;
		dsi_pll_uninit(lcd_channel_ix);
		enable_vpll2_power(0);
		dss_clk_disable(DSS_CLK_FCK2);
	}

	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2)
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD2, 0);
	else
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 0);

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);

	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;

	omap_dss_stop_device(dssdev);
}
예제 #14
0
static int dpi_display_suspend(struct omap_dss_device *dssdev)
{
	int use_dsi_for_hdmi = 0;

	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
		return -EINVAL;

	DSSDBG("dpi_display_suspend\n");

	if (strncmp("hdmi", dssdev->name, 4) == 0)
		use_dsi_for_hdmi = 1;

	if (dssdev->driver->suspend)
		dssdev->driver->suspend(dssdev);

	if (use_dsi_for_hdmi) {
		dss_select_clk_source(0, 0);

		dispc_go(OMAP_DSS_CHANNEL_LCD);
		while (dispc_go_busy(OMAP_DSS_CHANNEL_LCD))
			;

		dsi_pll_uninit(dsi1);
		enable_vpll2_power(0);
		dss_clk_disable(DSS_CLK_FCK2);
	}

	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2)
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD2, 0);
	else
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 0);

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);

	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;

	return 0;
}
예제 #15
0
static int dpi_display_resume(struct omap_dss_device *dssdev)
{
	int r = 0;

	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
		return -EINVAL;

	DSSDBG("dpi_display_resume\n");

	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	dss_clk_enable(DSS_CLK_FCK2);
	r = dsi_pll_init(dssdev, 1, 1);
	if (r) {
		DSSERR("failed in dsi_pll_init\n");
		goto err1;
	}
	r = dpi_set_mode(dssdev);
	if (r) {
		DSSERR("failed in dpi_set_mode\n");
		goto err2;
	}
	mdelay(2);
#endif

	dispc_enable_lcd_out(1);

	if (dssdev->driver->resume)
		dssdev->driver->resume(dssdev);

	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

	return r;

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
err2:
        dsi_pll_uninit();
	dss_clk_disable(DSS_CLK_FCK2);
err1:
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);

	return r;
#endif
}
예제 #16
0
static int dpi_display_resume(struct omap_dss_device *dssdev)
{
	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
		return -EINVAL;

	DSSDBG("dpi_display_resume\n");

	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);

	dispc_enable_lcd_out(1);

	if (dssdev->driver->resume)
		dssdev->driver->resume(dssdev);

	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

	return 0;
}
예제 #17
0
static int dpi_display_resume(struct omap_display *display)
{
	if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
		return -EINVAL;

	DSSDBG("dpi_display_resume\n");

	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);

	dispc_enable_lcd_out(1);

	if (display->panel->resume)
		display->panel->resume(display);

	display->state = OMAP_DSS_DISPLAY_ACTIVE;

	return 0;
}
예제 #18
0
static int dpi_display_suspend(struct omap_display *display)
{
	if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
		return -EINVAL;

	DSSDBG("dpi_display_suspend\n");

	if (display->panel->suspend)
		display->panel->suspend(display);

	dispc_enable_lcd_out(0);

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);

	display->state = OMAP_DSS_DISPLAY_SUSPENDED;

	return 0;
}
예제 #19
0
static int dpi_display_suspend(struct omap_dss_device *dssdev)
{
	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
		return -EINVAL;

	DSSDBG("dpi_display_suspend\n");

	if (dssdev->driver->suspend)
		dssdev->driver->suspend(dssdev);

	dispc_enable_lcd_out(0);

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);

	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;

	return 0;
}
예제 #20
0
static int sdi_display_suspend(struct omap_dss_device *dssdev)
{
	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
		return -EINVAL;

	if (dssdev->driver->suspend)
		dssdev->driver->suspend(dssdev);

	/* TODO: change here if LCD2 support is needed */
	dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 0);

	dss_sdi_disable();

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);

	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;

	return 0;
}
예제 #21
0
static int dpi_display_suspend(struct omap_dss_device *dssdev)
{
	
	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
		return -EINVAL;

	DSSDBG("dpi_display_suspend\n");

	if (dssdev->driver->suspend)
		dssdev->driver->suspend(dssdev);

	/* TODO: change here if LCD2 support is needed */
	dispc_enable_lcd_out(dssdev->channel, 0);
#ifndef CONFIG_ARCH_OMAP4
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
#endif
	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;

	return 0;
}
예제 #22
0
static int sdi_display_suspend(struct omap_display *display)
{
	if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
		return -EINVAL;

	if (display->panel->suspend)
		display->panel->suspend(display);

	dispc_enable_lcd_out(0);

	dss_sdi_disable();

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
	sdi_pad_config(display, 0);

	twl4030_disable_regulator(RES_VAUX1);

	display->state = OMAP_DSS_DISPLAY_SUSPENDED;

	return 0;
}
예제 #23
0
static void dpi_display_disable(struct omap_display *display)
{
	if (display->state == OMAP_DSS_DISPLAY_DISABLED)
		return;

	if (display->state == OMAP_DSS_DISPLAY_SUSPENDED)
		dpi_display_resume(display);

	display->panel->disable(display);

	dispc_enable_lcd_out(0);

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	dss_select_clk_source(0, 0);
	dsi_pll_uninit();
	dss_clk_disable(DSS_CLK_FCK2);
#endif

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);

	display->state = OMAP_DSS_DISPLAY_DISABLED;
}
예제 #24
0
static void sdi_display_disable(struct omap_dss_device *dssdev)
{
	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
		return;

	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
		if (sdi_display_resume(dssdev))
			return;

	if (dssdev->driver->disable)
		dssdev->driver->disable(dssdev);

	/* TODO: change here if LCD2 support is needed */
	dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 0);

	dss_sdi_disable();

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);

	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;

	omap_dss_stop_device(dssdev);
}
예제 #25
0
static void sdi_display_disable(struct omap_display *display)
{
	if (display->state == OMAP_DSS_DISPLAY_DISABLED)
		return;

	if (display->state == OMAP_DSS_DISPLAY_SUSPENDED) {
		if (sdi_display_resume(display))
			return;
	}

	display->panel->disable(display);

	dispc_enable_lcd_out(0);

	dss_sdi_disable();

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
	sdi_pad_config(display, 0);

	twl4030_disable_regulator(RES_VAUX1);

	display->state = OMAP_DSS_DISPLAY_DISABLED;
}
예제 #26
0
static int dpi_display_enable(struct omap_dss_device *dssdev)
{
	int r;
	int lcd_channel_ix = 1;
	int use_dsi_for_hdmi = 0;

	if (strncmp("hdmi", dssdev->name, 4) == 0)
		use_dsi_for_hdmi = 1;

	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
		DSSINFO("Lcd channel index 1");
		dpi2_base = ioremap(DPI2_BASE, 2000);
		lcd_channel_ix = 1;
	} else
		lcd_channel_ix = 0;

	r = omap_dss_start_device(dssdev);
	if (r) {
		DSSERR("failed to start device\n");
		goto err0;
	}

	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
		DSSERR("display already enabled\n");
		r = -EINVAL;
		goto err1;
	}

	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);

	r = dpi_basic_init(dssdev);
	if (r)
		goto err2;
	if (use_dsi_for_hdmi) {
		dss_clk_enable(DSS_CLK_FCK2);
		enable_vpll2_power(1);

		if (cpu_is_omap3630())
			r = dsi_pll_init(lcd_channel_ix, dssdev, 1, 1);
		else
			/*check param 2*/
			r = dsi_pll_init(lcd_channel_ix, dssdev, 0, 1);
		if (r)
			goto err3;
	}
	r = dpi_set_mode(dssdev);
	if (r)
		goto err4;

	mdelay(2);

	if (cpu_is_omap44xx())
		dpi_start_auto_update(dssdev);

	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2)
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD2, 1);
	else
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 1);


	r = dssdev->driver->enable(dssdev);
	if (r)
		goto err5;

	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

	/* This is done specifically for HDMI panel
	 * Default HDMI panel timings may not work for all monitors
	 * Reset HDMI panel timings after enabling HDMI.
	 */
	if (use_dsi_for_hdmi)
		dpi_set_timings(dssdev, &dssdev->panel.timings);

	return 0;

err5:
	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2)
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD2, 0);
	else
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 0);
err4:
	if (use_dsi_for_hdmi) {
		dsi_pll_uninit(lcd_channel_ix);
		enable_vpll2_power(0);
err3:
		dss_clk_disable(DSS_CLK_FCK2);
	}
err2:
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
err1:
	omap_dss_stop_device(dssdev);
err0:
	return r;
}
예제 #27
0
static int sdi_display_enable(struct omap_display *display)
{
	struct dispc_clock_info cinfo;
	u16 lck_div, pck_div;
	unsigned long fck;
	struct omap_panel *panel = display->panel;
	unsigned long pck;
	int r;

	if (display->state != OMAP_DSS_DISPLAY_DISABLED) {
		DSSERR("display already enabled\n");
		return -EINVAL;
	}

	twl4030_enable_regulator(RES_VAUX1);

	sdi_pad_config(display, 1);

	/* In case of skip_init sdi_init has already enabled the clocks */
	if (!sdi.skip_init)
		dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);

	sdi_basic_init();

	/* 15.5.9.1.2 */
	panel->config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF;

	dispc_set_pol_freq(panel);

	if (!sdi.skip_init)
		r = dispc_calc_clock_div(1, panel->timings.pixel_clock * 1000,
				&cinfo);
	else
		r = dispc_get_clock_div(&cinfo);

	if (r)
		goto err0;

	fck = cinfo.fck;
	lck_div = cinfo.lck_div;
	pck_div = cinfo.pck_div;

	pck = fck / lck_div / pck_div / 1000;

	if (pck != panel->timings.pixel_clock) {
		DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
				"got %lu kHz\n",
				panel->timings.pixel_clock, pck);

		panel->timings.pixel_clock = pck;
	}


	dispc_set_lcd_timings(&panel->timings);

	r = dispc_set_clock_div(&cinfo);
	if (r)
		goto err1;

	if (!sdi.skip_init) {
		dss_sdi_init(display->hw_config.u.sdi.datapairs);
		r = dss_sdi_enable();
		if (r)
			goto err1;
		mdelay(2);
	}

	dispc_enable_lcd_out(1);

	r = panel->enable(display);
	if (r)
		goto err2;

	display->state = OMAP_DSS_DISPLAY_ACTIVE;

	sdi.skip_init = 0;

	return 0;
err2:
	dispc_enable_lcd_out(0);
err1:
err0:
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
	twl4030_disable_regulator(RES_VAUX1);

	return r;
}
예제 #28
0
static int dpi_display_resume(struct omap_dss_device *dssdev)
{
	int r = 0;
	int lcd_channel_ix = 1;
	int use_dsi_for_hdmi = 0;

	if (strncmp("hdmi", dssdev->name, 4) == 0)
		use_dsi_for_hdmi = 1;

	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
		DSSINFO("Lcd channel index 1");
		dpi2_base = ioremap(DPI2_BASE, 2000);
		lcd_channel_ix = 1;
	} else
		lcd_channel_ix = 0;

	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
		return -EINVAL;

	DSSDBG("dpi_display_resume\n");

	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);

	if (use_dsi_for_hdmi) {
		dss_clk_enable(DSS_CLK_FCK2);
		enable_vpll2_power(1);

		if (cpu_is_omap3630())
			r = dsi_pll_init(lcd_channel_ix, dssdev, 1, 1);
		else
			r = dsi_pll_init(lcd_channel_ix, dssdev, 0, 1);
		if (r)
			goto err0;

		r = dpi_set_mode(dssdev);
		if (r)
			goto err1;
	}

	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2)
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD2, 1);
	else
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 1);

	if (dssdev->driver->resume) {
		r = dssdev->driver->resume(dssdev);
		if (r)
			goto err2;
	}

	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

	/* This is done specifically for HDMI panel
	 * Default HDMI panel timings may not work for all monitors
	 * Reset HDMI panel timings after enabling HDMI.
	 */
	if (use_dsi_for_hdmi)
		dpi_set_timings(dssdev, &dssdev->panel.timings);

	return 0;
err2:
	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2)
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD2, 0);
	else
		dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 0);

	if (use_dsi_for_hdmi) {
err1:
		DSSERR("<%s!!> err0: failed to init DSI_PLL = %d\n",
		       __func__, r);
		dss_select_clk_source(0, 0);

		dispc_go(OMAP_DSS_CHANNEL_LCD);
		while (dispc_go_busy(OMAP_DSS_CHANNEL_LCD))
			;

		dsi_pll_uninit(dsi1);
		enable_vpll2_power(0);
err0:
		dss_clk_disable(DSS_CLK_FCK2);
	}

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
	return r;
}
예제 #29
0
static int sdi_display_enable(struct omap_dss_device *dssdev)
{
	struct omap_video_timings *t = &dssdev->panel.timings;
	struct dss_clock_info dss_cinfo;
	struct dispc_clock_info dispc_cinfo;
	u16 lck_div, pck_div;
	unsigned long fck;
	unsigned long pck;
	int r;

	r = omap_dss_start_device(dssdev);
	if (r) {
		DSSERR("failed to start device\n");
		goto err0;
	}

	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
		DSSERR("dssdev already enabled\n");
		r = -EINVAL;
		goto err1;
	}

	/* In case of skip_init sdi_init has already enabled the clocks */
	if (!sdi.skip_init)
		dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);

	sdi_basic_init();

	/* 15.5.9.1.2 */
	dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF;

	/* TODO: update for LCD2 here */
	dispc_set_pol_freq(OMAP_DSS_CHANNEL_LCD, dssdev->panel.config,
			dssdev->panel.acbi, dssdev->panel.acb);

	if (!sdi.skip_init) {
		r = dss_calc_clock_div(1, t->pixel_clock * 1000,
				&dss_cinfo, &dispc_cinfo);
	} else {
		r = dss_get_clock_div(&dss_cinfo);
		r = dispc_get_clock_div(&dispc_cinfo);
	}

	if (r)
		goto err2;

	fck = dss_cinfo.fck;
	lck_div = dispc_cinfo.lck_div;
	pck_div = dispc_cinfo.pck_div;

	pck = fck / lck_div / pck_div / 1000;

	if (pck != t->pixel_clock) {
		DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
				"got %lu kHz\n",
				t->pixel_clock, pck);

		t->pixel_clock = pck;
	}

	/* TODO: if needed, add LCD2 support here*/
	dispc_set_lcd_timings(OMAP_DSS_CHANNEL_LCD, t);

	r = dss_set_clock_div(&dss_cinfo);
	if (r)
		goto err2;

	r = dispc_set_clock_div(&dispc_cinfo);
	if (r)
		goto err2;

	if (!sdi.skip_init) {
		dss_sdi_init(dssdev->phy.sdi.datapairs);
		r = dss_sdi_enable();
		if (r)
			goto err1;
		mdelay(2);
	}

	/* TODO: change here if LCD2 support is needed */
	dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 1);

	if (dssdev->driver->enable) {
		r = dssdev->driver->enable(dssdev);
		if (r)
			goto err3;
	}

	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

	sdi.skip_init = 0;

	return 0;
err3:
	/* TODO: change here if LCD2 support is needed */
	dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 0);
err2:
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
err1:
	omap_dss_stop_device(dssdev);
err0:
	return r;
}