예제 #1
0
static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, 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(dpi.dsidev, is_tft, pck_req,
			&dsi_cinfo, &dispc_cinfo);
	if (r)
		return r;

	r = dsi_pll_set_clock_div(dpi.dsidev, &dsi_cinfo);
	if (r)
		return r;

	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);

	r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
	if (r) {
		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
		return r;
	}

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

	return 0;
}
static int dpi_set_dsi_clk(enum omap_channel channel, bool is_tft,
		unsigned long pck_req, unsigned long *pck)
{
	struct dsi_clock_info dsi_cinfo;
	struct dispc_clock_info dispc_cinfo;
	int r;
	enum omap_dsi_index ix;

	DSSDBG("DPI clk source is DSI PLL\n");

	ix = (channel == OMAP_DSS_CHANNEL_LCD) ? DSI1 : DSI2;

	if (!cpu_is_omap44xx()) {
		r = dsi_pll_calc_clock_div_pck(ix, is_tft,
			pck_req, &dsi_cinfo, &dispc_cinfo);
		if (r)
			return r;
	} else {
		dsi_cinfo.regn = 16;
		dsi_cinfo.regm = 115;
		dsi_cinfo.regm_dispc = 3;
		dsi_cinfo.regm_dsi = 3;
		dsi_cinfo.use_dss2_fck = true;
		r = dsi_calc_clock_rates(channel, &dsi_cinfo);

		DSSDBG("dpi_set_dsi_clk: dsi_calc_clock_rates=%d\n", r);

		if (r)
			return r;
		dispc_find_clk_divs(is_tft, pck_req,
			dsi_cinfo.dsi_pll_dispc_fclk, &dispc_cinfo);
	}

	r = dsi_pll_set_clock_div(ix, &dsi_cinfo);

	DSSDBG("dpi_set_dsi_clk: dsi_pll_set_clock_div=%d\n", r);
	if (r)
		return r;

	if (cpu_is_omap44xx()){
		dss_select_dispc_clk_source(ix, (ix == DSI1) ?
			DSS_SRC_PLL1_CLK1 : DSS_SRC_PLL2_CLK1);
		dss_select_lcd_clk_source(ix, (ix == DSI1) ?
			DSS_SRC_PLL1_CLK1 : DSS_SRC_PLL2_CLK1);
	}else{
		dss_select_dispc_clk_source(ix, DSS_SRC_DSI1_PLL_FCLK);
        }

	dispc_set_clock_div(channel, &dispc_cinfo);

	*pck = dispc_cinfo.pck;

	return 0;
}
예제 #3
0
static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, 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_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);

	r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
	if (r)
		return r;

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

	return 0;
}
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
{
	if (dssdev->manager)
		dssdev->manager->disable(dssdev->manager);

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	{
		enum omap_dsi_index ix;

		ix = (dssdev->channel == OMAP_DSS_CHANNEL_LCD) ? DSI1 : DSI2;
		dss_select_dispc_clk_source(ix, DSS_SRC_DSS1_ALWON_FCLK);
		dsi_pll_uninit(ix);
	}
#endif

	/* cut clock(s) */
	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
	if (!cpu_is_omap44xx())
		dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
	dss_mainclk_state_disable(true);

	if (cpu_is_omap34xx() && !cpu_is_omap3630())
		regulator_disable(dpi.vdds_dsi_reg);

	omap_dss_stop_device(dssdev);
}
예제 #5
0
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
{

	dssdev->manager->disable(dssdev->manager);
	if (dpi_use_dsi_pll(dssdev)) {
		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
		dsi_pll_uninit(dpi.dsidev, true);
		dsi_runtime_put(dpi.dsidev);
	}

	dispc_runtime_put();

	dss_runtime_put();
#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
	if (dpi.fb_skip) {
		dssdev->dss_clks_disable();
		dpi.fb_skip = false;
	}
#endif

	if (cpu_is_omap34xx())
		regulator_disable(dpi.vdds_dsi_reg);

	omap_dss_stop_device(dssdev);
}
예제 #6
0
파일: dpi.c 프로젝트: AllenDou/linux
static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
		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(dpi.dsidev, pck_req, &dsi_cinfo,
			&dispc_cinfo);
	if (r)
		return r;

	r = dsi_pll_set_clock_div(dpi.dsidev, &dsi_cinfo);
	if (r)
		return r;

	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);

	dpi.mgr_config.clock_info = dispc_cinfo;

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

	return 0;
}
예제 #7
0
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
{
	dssdev->manager->disable(dssdev->manager);

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
	dsi_pll_uninit();
	dss_clk_disable(DSS_CLK_SYSCK);
#endif

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);

	if (cpu_is_omap34xx())
		regulator_disable(dpi.vdds_dsi_reg);

	omap_dss_stop_device(dssdev);
}
예제 #8
0
파일: dpi.c 프로젝트: 119-org/hi3518-osdrv
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
{
	dssdev->manager->disable(dssdev->manager);

	if (dpi_use_dsi_pll(dssdev)) {
		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
		dsi_pll_uninit(dpi.dsidev, true);
		dss_clk_disable(DSS_CLK_SYSCK);
	}

	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);

	if (cpu_is_omap34xx())
		regulator_disable(dpi.vdds_dsi_reg);

	omap_dss_stop_device(dssdev);
}
예제 #9
0
파일: dpi.c 프로젝트: AllenDou/linux
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
{
	struct omap_overlay_manager *mgr = dssdev->output->manager;

	mutex_lock(&dpi.lock);

	dss_mgr_disable(mgr);

	if (dpi_use_dsi_pll(dssdev)) {
		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
		dsi_pll_uninit(dpi.dsidev, true);
		dsi_runtime_put(dpi.dsidev);
	}

	dispc_runtime_put();

	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
		regulator_disable(dpi.vdds_dsi_reg);

	omap_dss_stop_device(dssdev);

	mutex_unlock(&dpi.lock);
}
/*
 * linux/drivers/video/omap2/dss/dpi.c
 *
 * Copyright (C) 2009 Nokia Corporation
 * Author: Tomi Valkeinen <*****@*****.**>
 *
 * Some code and ideas taken from drivers/video/omap/ driver
 * by Imre Deak.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#define DSS_SUBSYS_NAME "DPI"

#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>

#include <plat/display.h>
#include <plat/cpu.h>
#include <plat/omap-pm.h>

#include "dss.h"

static struct {
	struct regulator *vdds_dsi_reg;
} dpi;

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
static int dpi_set_dsi_clk(enum omap_channel channel, bool is_tft,
		unsigned long pck_req, unsigned long *pck)
{
	struct dsi_clock_info dsi_cinfo;
	struct dispc_clock_info dispc_cinfo;
	int r;
	enum omap_dsi_index ix;

	DSSDBG("DPI clk source is DSI PLL\n");

	ix = (channel == OMAP_DSS_CHANNEL_LCD) ? DSI1 : DSI2;

	if (!cpu_is_omap44xx()) {
		r = dsi_pll_calc_clock_div_pck(ix, is_tft,
			pck_req, &dsi_cinfo, &dispc_cinfo);
		if (r)
			return r;
	} else {
		dsi_cinfo.regn = 16;
		dsi_cinfo.regm = 115;
		dsi_cinfo.regm_dispc = 3;
		dsi_cinfo.regm_dsi = 3;
		dsi_cinfo.use_dss2_fck = true;
		r = dsi_calc_clock_rates(channel, &dsi_cinfo);

		DSSDBG("dpi_set_dsi_clk: dsi_calc_clock_rates=%d\n", r);

		if (r)
			return r;
		dispc_find_clk_divs(is_tft, pck_req,
			dsi_cinfo.dsi_pll_dispc_fclk, &dispc_cinfo);
	}

	r = dsi_pll_set_clock_div(ix, &dsi_cinfo);

	DSSDBG("dpi_set_dsi_clk: dsi_pll_set_clock_div=%d\n", r);
	if (r)
		return r;

	if (cpu_is_omap44xx()){
		dss_select_dispc_clk_source(ix, (ix == DSI1) ?
			DSS_SRC_PLL1_CLK1 : DSS_SRC_PLL2_CLK1);
		dss_select_lcd_clk_source(ix, (ix == DSI1) ?
			DSS_SRC_PLL1_CLK1 : DSS_SRC_PLL2_CLK1);
	}else{
		dss_select_dispc_clk_source(ix, DSS_SRC_DSI1_PLL_FCLK);
        }

	dispc_set_clock_div(channel, &dispc_cinfo);

	*pck = dispc_cinfo.pck;

	return 0;
}
#else /* #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL */
static int dpi_set_dispc_clk(enum omap_channel channel,
		bool is_tft, unsigned long pck_req, unsigned long *pck)
{
	struct dispc_clock_info dispc_cinfo;
	enum omap_dsi_index ix;

	DSSDBG("DPI clk source is DISPC\n");

	ix = (channel == OMAP_DSS_CHANNEL_LCD) ? DSI1 : DSI2;

	if (cpu_is_omap44xx())
		dispc_find_clk_divs(is_tft, pck_req,
			dss_clk_get_rate(DSS_CLK_FCK1), &dispc_cinfo);
	else {
		struct dss_clock_info dss_cinfo;
		int r;

		r = dss_calc_clock_div(is_tft, pck_req,
				&dss_cinfo, &dispc_cinfo);
		if (r)
			return r;

		r = dss_set_clock_div(&dss_cinfo);
		if (r)
			return r;
	}

	dss_select_dispc_clk_source(ix, DSS_SRC_DSS1_ALWON_FCLK);
	if (cpu_is_omap44xx())
		dss_select_lcd_clk_source(ix, DSS_SRC_DSS1_ALWON_FCLK);

	dispc_set_clock_div(channel, &dispc_cinfo);

	*pck = dispc_cinfo.pck;

	return 0;
}
예제 #11
0
static int hdmi_power_on(struct omap_dss_device *dssdev)
{
	int r, code = 0;
	struct omap_video_timings *p;
	unsigned long phy;

	r = hdmi_runtime_get();
	if (r)
		return r;

	dss_mgr_disable(dssdev->manager);

	p = &dssdev->panel.timings;

	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
		dssdev->panel.timings.x_res,
		dssdev->panel.timings.y_res);

	code = get_timings_index();
	update_hdmi_timings(&hdmi.ip_data.cfg, p, code);

	phy = p->pixel_clock;

	hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);

	hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);

	/* config the PLL and PHY hdmi_set_pll_pwrfirst */
	r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
	if (r) {
		DSSDBG("Failed to lock PLL\n");
		goto err;
	}

	r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
	if (r) {
		DSSDBG("Failed to start PHY\n");
		goto err;
	}

	hdmi.ip_data.cfg.cm.mode = hdmi.mode;
	hdmi.ip_data.cfg.cm.code = hdmi.code;
	hdmi.ip_data.ops->video_configure(&hdmi.ip_data);

	/* Make selection of HDMI in DSS */
	dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);

	/* Select the dispc clock source as PRCM clock, to ensure that it is not
	 * DSI PLL source as the clock selected by DSI PLL might not be
	 * sufficient for the resolution selected / that can be changed
	 * dynamically by user. This can be moved to single location , say
	 * Boardfile.
	 */
	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);

	/* bypass TV gamma table */
	dispc_enable_gamma_table(0);

	/* tv size */
	dispc_set_digit_size(dssdev->panel.timings.x_res,
			dssdev->panel.timings.y_res);

	hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);

	r = dss_mgr_enable(dssdev->manager);
	if (r)
		goto err_mgr_enable;

	return 0;

err_mgr_enable:
	hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
	hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
	hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
err:
	hdmi_runtime_put();
	return -EIO;
}
예제 #12
0
파일: hdmi.c 프로젝트: FoundYa/linux
static int hdmi_power_on(struct omap_dss_device *dssdev)
{
	int r;
	struct omap_video_timings *p;
	struct omap_overlay_manager *mgr = dssdev->output->manager;
	unsigned long phy;

	gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
	gpio_set_value(hdmi.ls_oe_gpio, 1);

	/* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
	udelay(300);

	r = regulator_enable(hdmi.vdda_hdmi_dac_reg);
	if (r)
		goto err_vdac_enable;

	r = hdmi_runtime_get();
	if (r)
		goto err_runtime_get;

	dss_mgr_disable(mgr);

	p = &hdmi.ip_data.cfg.timings;

	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);

	phy = p->pixel_clock;

	hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);

	hdmi.ip_data.ops->video_disable(&hdmi.ip_data);

	/* config the PLL and PHY hdmi_set_pll_pwrfirst */
	r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
	if (r) {
		DSSDBG("Failed to lock PLL\n");
		goto err_pll_enable;
	}

	r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
	if (r) {
		DSSDBG("Failed to start PHY\n");
		goto err_phy_enable;
	}

	hdmi.ip_data.ops->video_configure(&hdmi.ip_data);

	/* Make selection of HDMI in DSS */
	dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);

	/* Select the dispc clock source as PRCM clock, to ensure that it is not
	 * DSI PLL source as the clock selected by DSI PLL might not be
	 * sufficient for the resolution selected / that can be changed
	 * dynamically by user. This can be moved to single location , say
	 * Boardfile.
	 */
	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);

	/* bypass TV gamma table */
	dispc_enable_gamma_table(0);

	/* tv size */
	dss_mgr_set_timings(mgr, p);

	r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
	if (r)
		goto err_vid_enable;

	r = dss_mgr_enable(mgr);
	if (r)
		goto err_mgr_enable;

	return 0;

err_mgr_enable:
	hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
err_vid_enable:
	hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
err_phy_enable:
	hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
err_pll_enable:
	hdmi_runtime_put();
err_runtime_get:
	regulator_disable(hdmi.vdda_hdmi_dac_reg);
err_vdac_enable:
	gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
	gpio_set_value(hdmi.ls_oe_gpio, 0);
	return -EIO;
}