예제 #1
0
static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req,
		unsigned long *fck, int *lck_div, int *pck_div)
{
	struct dsi_clock_info dsi_cinfo;
	struct dispc_clock_info dispc_cinfo;
	int r;

	r = dsi_pll_calc_clock_div_pck(is_tft, pck_req, &dsi_cinfo,
			&dispc_cinfo);
	if (r)
		return r;

	r = dsi_pll_set_clock_div(&dsi_cinfo);
	if (r)
		return r;

	dss_select_clk_source(0, 1);

	r = dispc_set_clock_div(&dispc_cinfo);
	if (r)
		return r;

	*fck = dsi_cinfo.dsi1_pll_fclk;
	*lck_div = dispc_cinfo.lck_div;
	*pck_div = dispc_cinfo.pck_div;

	return 0;
}
예제 #2
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);
}
예제 #3
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;
}
예제 #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 dpi_set_dsi_clk(int lcd_channel_ix, bool is_tft,
		unsigned long pck_req,
		unsigned long *fck, int *lck_div, int *pck_div)
{
	struct dsi_clock_info dsi_cinfo;
	struct dispc_clock_info dispc_cinfo;
	int r;
	printk(KERN_INFO "DPI set dsi clk");
	if (!cpu_is_omap44xx()) {
		r = dsi_pll_calc_clock_div_pck(lcd_channel_ix, is_tft,
			pck_req, &dsi_cinfo, &dispc_cinfo);
		if (r)
			return r;
	} else {
		dispc_cinfo.lck_div = 1;
		dispc_cinfo.pck_div = 4;
		dsi_cinfo.regn = 19;
		dsi_cinfo.regm = 150;
		dsi_cinfo.regm3 = 4;
		dsi_cinfo.regm4 = 4;
		dsi_cinfo.use_dss2_fck = true;
		dsi_cinfo.highfreq = 0;
		dsi_calc_clock_rates(&dsi_cinfo);
	}
	r = dsi_pll_set_clock_div(lcd_channel_ix, &dsi_cinfo);
	if (r)
		return r;

	if (cpu_is_omap44xx())
		dss_select_clk_source_dsi(lcd_channel_ix, 1, 1);
	else
		dss_select_clk_source(0, 1);

	r = dispc_set_clock_div(lcd_channel_ix, &dispc_cinfo);
	if (r)
		return r;

	*fck = dsi_cinfo.dsi1_pll_fclk;
	*lck_div = dispc_cinfo.lck_div;
	*pck_div = dispc_cinfo.pck_div;

	return 0;
}
예제 #6
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);
}
예제 #7
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;
}
예제 #8
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;
}
예제 #9
0
static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req,
		unsigned long *fck, int *lck_div, int *pck_div)
{
	struct dsi_clock_info cinfo;
	int r;

	r = dsi_pll_calc_pck(is_tft, pck_req, &cinfo);
	if (r)
		return r;

	r = dsi_pll_program(&cinfo);
	if (r)
		return r;

	dss_select_clk_source(0, 1);

	dispc_set_lcd_divisor(cinfo.lck_div, cinfo.pck_div);

	*fck = cinfo.dsi1_pll_fclk;
	*lck_div = cinfo.lck_div;
	*pck_div = cinfo.pck_div;

	return 0;
}
예제 #10
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;
}