Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ecf140df authored by Tomi Valkeinen's avatar Tomi Valkeinen
Browse files

Merge branch '4.8/omapdrm-pll' (omapdrm PLL work)

Merge omapdrm PLL work, which makes it possible to use the DSS PLLs in a
versatile manner, for example, HDMI PLL can be used for LCDs.
parents 449c5e9c 31dca077
Loading
Loading
Loading
Loading
+34 −57
Original line number Diff line number Diff line
@@ -3299,30 +3299,21 @@ static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div,

static unsigned long dispc_fclk_rate(void)
{
	struct dss_pll *pll;
	unsigned long r = 0;
	unsigned long r;
	enum dss_clk_source src;

	switch (dss_get_dispc_clk_source()) {
	case OMAP_DSS_CLK_SRC_FCK:
	src = dss_get_dispc_clk_source();

	if (src == DSS_CLK_SRC_FCK) {
		r = dss_get_dispc_clk_rate();
		break;
	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
		pll = dss_pll_find("dsi0");
		if (!pll)
			pll = dss_pll_find("video0");
	} else {
		struct dss_pll *pll;
		unsigned clkout_idx;

		r = pll->cinfo.clkout[0];
		break;
	case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
		pll = dss_pll_find("dsi1");
		if (!pll)
			pll = dss_pll_find("video1");
		pll = dss_pll_find_by_src(src);
		clkout_idx = dss_pll_get_clkout_idx_for_src(src);

		r = pll->cinfo.clkout[0];
		break;
	default:
		BUG();
		return 0;
		r = pll->cinfo.clkout[clkout_idx];
	}

	return r;
@@ -3330,43 +3321,31 @@ static unsigned long dispc_fclk_rate(void)

static unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
{
	struct dss_pll *pll;
	int lcd;
	unsigned long r;
	u32 l;
	enum dss_clk_source src;

	if (dss_mgr_is_lcd(channel)) {
		l = dispc_read_reg(DISPC_DIVISORo(channel));
	/* for TV, LCLK rate is the FCLK rate */
	if (!dss_mgr_is_lcd(channel))
		return dispc_fclk_rate();

		lcd = FLD_GET(l, 23, 16);
	src = dss_get_lcd_clk_source(channel);

		switch (dss_get_lcd_clk_source(channel)) {
		case OMAP_DSS_CLK_SRC_FCK:
	if (src == DSS_CLK_SRC_FCK) {
		r = dss_get_dispc_clk_rate();
			break;
		case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
			pll = dss_pll_find("dsi0");
			if (!pll)
				pll = dss_pll_find("video0");
	} else {
		struct dss_pll *pll;
		unsigned clkout_idx;

			r = pll->cinfo.clkout[0];
			break;
		case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
			pll = dss_pll_find("dsi1");
			if (!pll)
				pll = dss_pll_find("video1");
		pll = dss_pll_find_by_src(src);
		clkout_idx = dss_pll_get_clkout_idx_for_src(src);

			r = pll->cinfo.clkout[0];
			break;
		default:
			BUG();
			return 0;
		r = pll->cinfo.clkout[clkout_idx];
	}

	lcd = REG_GET(DISPC_DIVISORo(channel), 23, 16);

	return r / lcd;
	} else {
		return dispc_fclk_rate();
	}
}

static unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
@@ -3426,15 +3405,14 @@ static unsigned long dispc_plane_lclk_rate(enum omap_plane plane)
static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
{
	int lcd, pcd;
	enum omap_dss_clk_source lcd_clk_src;
	enum dss_clk_source lcd_clk_src;

	seq_printf(s, "- %s -\n", mgr_desc[channel].name);

	lcd_clk_src = dss_get_lcd_clk_source(channel);

	seq_printf(s, "%s clk source = %s (%s)\n", mgr_desc[channel].name,
		dss_get_generic_clk_source_name(lcd_clk_src),
		dss_feat_get_clk_source_name(lcd_clk_src));
	seq_printf(s, "%s clk source = %s\n", mgr_desc[channel].name,
		dss_get_clk_source_name(lcd_clk_src));

	dispc_mgr_get_lcd_divisor(channel, &lcd, &pcd);

@@ -3448,16 +3426,15 @@ void dispc_dump_clocks(struct seq_file *s)
{
	int lcd;
	u32 l;
	enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
	enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();

	if (dispc_runtime_get())
		return;

	seq_printf(s, "- DISPC -\n");

	seq_printf(s, "dispc fclk source = %s (%s)\n",
			dss_get_generic_clk_source_name(dispc_clk_src),
			dss_feat_get_clk_source_name(dispc_clk_src));
	seq_printf(s, "dispc fclk source = %s\n",
			dss_get_clk_source_name(dispc_clk_src));

	seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());

+65 −68
Original line number Diff line number Diff line
@@ -39,12 +39,11 @@
#include "dss.h"
#include "dss_features.h"

#define HSDIV_DISPC	0

struct dpi_data {
	struct platform_device *pdev;

	struct regulator *vdds_dsi_reg;
	enum dss_clk_source clk_src;
	struct dss_pll *pll;

	struct mutex lock;
@@ -69,7 +68,7 @@ static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
	return dev_get_drvdata(&pdev->dev);
}

static struct dss_pll *dpi_get_pll(enum omap_channel channel)
static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel)
{
	/*
	 * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
@@ -83,64 +82,51 @@ static struct dss_pll *dpi_get_pll(enum omap_channel channel)
	case OMAPDSS_VER_OMAP3630:
	case OMAPDSS_VER_AM35xx:
	case OMAPDSS_VER_AM43xx:
		return NULL;
		return DSS_CLK_SRC_FCK;

	case OMAPDSS_VER_OMAP4430_ES1:
	case OMAPDSS_VER_OMAP4430_ES2:
	case OMAPDSS_VER_OMAP4:
		switch (channel) {
		case OMAP_DSS_CHANNEL_LCD:
			return dss_pll_find("dsi0");
			return DSS_CLK_SRC_PLL1_1;
		case OMAP_DSS_CHANNEL_LCD2:
			return dss_pll_find("dsi1");
			return DSS_CLK_SRC_PLL2_1;
		default:
			return NULL;
			return DSS_CLK_SRC_FCK;
		}

	case OMAPDSS_VER_OMAP5:
		switch (channel) {
		case OMAP_DSS_CHANNEL_LCD:
			return dss_pll_find("dsi0");
			return DSS_CLK_SRC_PLL1_1;
		case OMAP_DSS_CHANNEL_LCD3:
			return dss_pll_find("dsi1");
			return DSS_CLK_SRC_PLL2_1;
		case OMAP_DSS_CHANNEL_LCD2:
		default:
			return NULL;
			return DSS_CLK_SRC_FCK;
		}

	case OMAPDSS_VER_DRA7xx:
		switch (channel) {
		case OMAP_DSS_CHANNEL_LCD:
			return DSS_CLK_SRC_PLL1_1;
		case OMAP_DSS_CHANNEL_LCD2:
			return dss_pll_find("video0");
			return DSS_CLK_SRC_PLL1_3;
		case OMAP_DSS_CHANNEL_LCD3:
			return dss_pll_find("video1");
		default:
			return NULL;
		}

			return DSS_CLK_SRC_PLL2_1;
		default:
		return NULL;
	}
			return DSS_CLK_SRC_FCK;
		}

static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel)
{
	switch (channel) {
	case OMAP_DSS_CHANNEL_LCD:
		return OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC;
	case OMAP_DSS_CHANNEL_LCD2:
		return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
	case OMAP_DSS_CHANNEL_LCD3:
		return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
	default:
		/* this shouldn't happen */
		WARN_ON(1);
		return OMAP_DSS_CLK_SRC_FCK;
		return DSS_CLK_SRC_FCK;
	}
}

struct dpi_clk_calc_ctx {
	struct dss_pll *pll;
	unsigned clkout_idx;

	/* inputs */

@@ -148,7 +134,7 @@ struct dpi_clk_calc_ctx {

	/* outputs */

	struct dss_pll_clock_info dsi_cinfo;
	struct dss_pll_clock_info pll_cinfo;
	unsigned long fck;
	struct dispc_clock_info dispc_cinfo;
};
@@ -193,8 +179,8 @@ static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
	if (m_dispc > 1 && m_dispc % 2 != 0 && ctx->pck_min >= 100000000)
		return false;

	ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc;
	ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc;
	ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc;
	ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc;

	return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max,
			dpi_calc_dispc_cb, ctx);
@@ -207,12 +193,12 @@ static bool dpi_calc_pll_cb(int n, int m, unsigned long fint,
{
	struct dpi_clk_calc_ctx *ctx = data;

	ctx->dsi_cinfo.n = n;
	ctx->dsi_cinfo.m = m;
	ctx->dsi_cinfo.fint = fint;
	ctx->dsi_cinfo.clkdco = clkdco;
	ctx->pll_cinfo.n = n;
	ctx->pll_cinfo.m = m;
	ctx->pll_cinfo.fint = fint;
	ctx->pll_cinfo.clkdco = clkdco;

	return dss_pll_hsdiv_calc(ctx->pll, clkdco,
	return dss_pll_hsdiv_calc_a(ctx->pll, clkdco,
		ctx->pck_min, dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
		dpi_calc_hsdiv_cb, ctx);
}
@@ -227,25 +213,39 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
			dpi_calc_dispc_cb, ctx);
}

static bool dpi_dsi_clk_calc(struct dpi_data *dpi, unsigned long pck,
static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned long pck,
		struct dpi_clk_calc_ctx *ctx)
{
	unsigned long clkin;
	unsigned long pll_min, pll_max;

	memset(ctx, 0, sizeof(*ctx));
	ctx->pll = dpi->pll;
	ctx->clkout_idx = dss_pll_get_clkout_idx_for_src(dpi->clk_src);

	clkin = clk_get_rate(dpi->pll->clkin);

	if (dpi->pll->hw->type == DSS_PLL_TYPE_A) {
		unsigned long pll_min, pll_max;

		ctx->pck_min = pck - 1000;
		ctx->pck_max = pck + 1000;

		pll_min = 0;
		pll_max = 0;

	clkin = clk_get_rate(ctx->pll->clkin);

	return dss_pll_calc(ctx->pll, clkin,
		return dss_pll_calc_a(ctx->pll, clkin,
				pll_min, pll_max,
				dpi_calc_pll_cb, ctx);
	} else { /* DSS_PLL_TYPE_B */
		dss_pll_calc_b(dpi->pll, clkin, pck, &ctx->pll_cinfo);

		ctx->dispc_cinfo.lck_div = 1;
		ctx->dispc_cinfo.pck_div = 1;
		ctx->dispc_cinfo.lck = ctx->pll_cinfo.clkout[0];
		ctx->dispc_cinfo.pck = ctx->dispc_cinfo.lck;

		return true;
	}
}

static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
@@ -279,7 +279,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)



static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel,
static int dpi_set_pll_clk(struct dpi_data *dpi, enum omap_channel channel,
		unsigned long pck_req, unsigned long *fck, int *lck_div,
		int *pck_div)
{
@@ -287,20 +287,19 @@ static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel,
	int r;
	bool ok;

	ok = dpi_dsi_clk_calc(dpi, pck_req, &ctx);
	ok = dpi_pll_clk_calc(dpi, pck_req, &ctx);
	if (!ok)
		return -EINVAL;

	r = dss_pll_set_config(dpi->pll, &ctx.dsi_cinfo);
	r = dss_pll_set_config(dpi->pll, &ctx.pll_cinfo);
	if (r)
		return r;

	dss_select_lcd_clk_source(channel,
			dpi_get_alt_clk_src(channel));
	dss_select_lcd_clk_source(channel, dpi->clk_src);

	dpi->mgr_config.clock_info = ctx.dispc_cinfo;

	*fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC];
	*fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
	*lck_div = ctx.dispc_cinfo.lck_div;
	*pck_div = ctx.dispc_cinfo.pck_div;

@@ -342,7 +341,7 @@ static int dpi_set_mode(struct dpi_data *dpi)
	int r = 0;

	if (dpi->pll)
		r = dpi_set_dsi_clk(dpi, channel, t->pixelclock, &fck,
		r = dpi_set_pll_clk(dpi, channel, t->pixelclock, &fck,
				&lck_div, &pck_div);
	else
		r = dpi_set_dispc_clk(dpi, t->pixelclock, &fck,
@@ -419,7 +418,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
	if (dpi->pll) {
		r = dss_pll_enable(dpi->pll);
		if (r)
			goto err_dsi_pll_init;
			goto err_pll_init;
	}

	r = dpi_set_mode(dpi);
@@ -442,7 +441,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
err_set_mode:
	if (dpi->pll)
		dss_pll_disable(dpi->pll);
err_dsi_pll_init:
err_pll_init:
err_src_sel:
	dispc_runtime_put();
err_get_dispc:
@@ -465,7 +464,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev)
	dss_mgr_disable(channel);

	if (dpi->pll) {
		dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK);
		dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
		dss_pll_disable(dpi->pll);
	}

@@ -524,11 +523,11 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
		return -EINVAL;

	if (dpi->pll) {
		ok = dpi_dsi_clk_calc(dpi, timings->pixelclock, &ctx);
		ok = dpi_pll_clk_calc(dpi, timings->pixelclock, &ctx);
		if (!ok)
			return -EINVAL;

		fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC];
		fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
	} else {
		ok = dpi_dss_clk_calc(timings->pixelclock, &ctx);
		if (!ok)
@@ -558,7 +557,7 @@ static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
	mutex_unlock(&dpi->lock);
}

static int dpi_verify_dsi_pll(struct dss_pll *pll)
static int dpi_verify_pll(struct dss_pll *pll)
{
	int r;

@@ -602,16 +601,14 @@ static void dpi_init_pll(struct dpi_data *dpi)
	if (dpi->pll)
		return;

	pll = dpi_get_pll(dpi->output.dispc_channel);
	dpi->clk_src = dpi_get_clk_src(dpi->output.dispc_channel);

	pll = dss_pll_find_by_src(dpi->clk_src);
	if (!pll)
		return;

	/* On DRA7 we need to set a mux to use the PLL */
	if (omapdss_get_version() == OMAPDSS_VER_DRA7xx)
		dss_ctrl_pll_set_control_mux(pll->id, dpi->output.dispc_channel);

	if (dpi_verify_dsi_pll(pll)) {
		DSSWARN("DSI PLL not operational\n");
	if (dpi_verify_pll(pll)) {
		DSSWARN("PLL not operational\n");
		return;
	}

+30 −25
Original line number Diff line number Diff line
@@ -1262,7 +1262,7 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
	unsigned long r;
	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);

	if (dss_get_dsi_clk_source(dsi->module_id) == OMAP_DSS_CLK_SRC_FCK) {
	if (dss_get_dsi_clk_source(dsi->module_id) == DSS_CLK_SRC_FCK) {
		/* DSI FCLK source is DSS_CLK_FCK */
		r = clk_get_rate(dsi->dss_clk);
	} else {
@@ -1475,7 +1475,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
{
	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
	struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo;
	enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
	enum dss_clk_source dispc_clk_src, dsi_clk_src;
	int dsi_module = dsi->module_id;
	struct dss_pll *pll = &dsi->pll;

@@ -1495,28 +1495,27 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
			cinfo->clkdco, cinfo->m);

	seq_printf(s,	"DSI_PLL_HSDIV_DISPC (%s)\t%-16lum_dispc %u\t(%s)\n",
			dss_feat_get_clk_source_name(dsi_module == 0 ?
				OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
				OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC),
			dss_get_clk_source_name(dsi_module == 0 ?
				DSS_CLK_SRC_PLL1_1 :
				DSS_CLK_SRC_PLL2_1),
			cinfo->clkout[HSDIV_DISPC],
			cinfo->mX[HSDIV_DISPC],
			dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ?
			dispc_clk_src == DSS_CLK_SRC_FCK ?
			"off" : "on");

	seq_printf(s,	"DSI_PLL_HSDIV_DSI (%s)\t%-16lum_dsi %u\t(%s)\n",
			dss_feat_get_clk_source_name(dsi_module == 0 ?
				OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
				OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI),
			dss_get_clk_source_name(dsi_module == 0 ?
				DSS_CLK_SRC_PLL1_2 :
				DSS_CLK_SRC_PLL2_2),
			cinfo->clkout[HSDIV_DSI],
			cinfo->mX[HSDIV_DSI],
			dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ?
			dsi_clk_src == DSS_CLK_SRC_FCK ?
			"off" : "on");

	seq_printf(s,	"- DSI%d -\n", dsi_module + 1);

	seq_printf(s,	"dsi fclk source = %s (%s)\n",
			dss_get_generic_clk_source_name(dsi_clk_src),
			dss_feat_get_clk_source_name(dsi_clk_src));
	seq_printf(s,	"dsi fclk source = %s\n",
			dss_get_clk_source_name(dsi_clk_src));

	seq_printf(s,	"DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev));

@@ -4102,8 +4101,8 @@ static int dsi_display_init_dispc(struct platform_device *dsidev,
	int r;

	dss_select_lcd_clk_source(channel, dsi->module_id == 0 ?
			OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
			OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC);
			DSS_CLK_SRC_PLL1_1 :
			DSS_CLK_SRC_PLL2_1);

	if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
		r = dss_mgr_register_framedone_handler(channel,
@@ -4150,7 +4149,7 @@ static int dsi_display_init_dispc(struct platform_device *dsidev,
		dss_mgr_unregister_framedone_handler(channel,
				dsi_framedone_irq_callback, dsidev);
err:
	dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK);
	dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
	return r;
}

@@ -4163,7 +4162,7 @@ static void dsi_display_uninit_dispc(struct platform_device *dsidev,
		dss_mgr_unregister_framedone_handler(channel,
				dsi_framedone_irq_callback, dsidev);

	dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK);
	dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
}

static int dsi_configure_dsi_clocks(struct platform_device *dsidev)
@@ -4197,8 +4196,8 @@ static int dsi_display_init_dsi(struct platform_device *dsidev)
		goto err1;

	dss_select_dsi_clk_source(dsi->module_id, dsi->module_id == 0 ?
			OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
			OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI);
			DSS_CLK_SRC_PLL1_2 :
			DSS_CLK_SRC_PLL2_2);

	DSSDBG("PLL OK\n");

@@ -4230,7 +4229,7 @@ static int dsi_display_init_dsi(struct platform_device *dsidev)
err3:
	dsi_cio_uninit(dsidev);
err2:
	dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
	dss_select_dsi_clk_source(dsi->module_id, DSS_CLK_SRC_FCK);
err1:
	dss_pll_disable(&dsi->pll);
err0:
@@ -4252,7 +4251,7 @@ static void dsi_display_uninit_dsi(struct platform_device *dsidev,
	dsi_vc_enable(dsidev, 2, 0);
	dsi_vc_enable(dsidev, 3, 0);

	dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
	dss_select_dsi_clk_source(dsi->module_id, DSS_CLK_SRC_FCK);
	dsi_cio_uninit(dsidev);
	dsi_pll_uninit(dsidev, disconnect_lanes);
}
@@ -4453,7 +4452,7 @@ static bool dsi_cm_calc_pll_cb(int n, int m, unsigned long fint,
	ctx->dsi_cinfo.fint = fint;
	ctx->dsi_cinfo.clkdco = clkdco;

	return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min,
	return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
			dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
			dsi_cm_calc_hsdiv_cb, ctx);
}
@@ -4492,7 +4491,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
	pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4);
	pll_max = cfg->hs_clk_max * 4;

	return dss_pll_calc(ctx->pll, clkin,
	return dss_pll_calc_a(ctx->pll, clkin,
			pll_min, pll_max,
			dsi_cm_calc_pll_cb, ctx);
}
@@ -4751,7 +4750,7 @@ static bool dsi_vm_calc_pll_cb(int n, int m, unsigned long fint,
	ctx->dsi_cinfo.fint = fint;
	ctx->dsi_cinfo.clkdco = clkdco;

	return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min,
	return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
			dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
			dsi_vm_calc_hsdiv_cb, ctx);
}
@@ -4793,7 +4792,7 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
		pll_max = byteclk_max * 4 * 4;
	}

	return dss_pll_calc(ctx->pll, clkin,
	return dss_pll_calc_a(ctx->pll, clkin,
			pll_min, pll_max,
			dsi_vm_calc_pll_cb, ctx);
}
@@ -5139,6 +5138,8 @@ static const struct dss_pll_ops dsi_pll_ops = {
};

static const struct dss_pll_hw dss_omap3_dsi_pll_hw = {
	.type = DSS_PLL_TYPE_A,

	.n_max = (1 << 7) - 1,
	.m_max = (1 << 11) - 1,
	.mX_max = (1 << 4) - 1,
@@ -5164,6 +5165,8 @@ static const struct dss_pll_hw dss_omap3_dsi_pll_hw = {
};

static const struct dss_pll_hw dss_omap4_dsi_pll_hw = {
	.type = DSS_PLL_TYPE_A,

	.n_max = (1 << 8) - 1,
	.m_max = (1 << 12) - 1,
	.mX_max = (1 << 5) - 1,
@@ -5189,6 +5192,8 @@ static const struct dss_pll_hw dss_omap4_dsi_pll_hw = {
};

static const struct dss_pll_hw dss_omap5_dsi_pll_hw = {
	.type = DSS_PLL_TYPE_A,

	.n_max = (1 << 8) - 1,
	.m_max = (1 << 12) - 1,
	.mX_max = (1 << 5) - 1,
+175 −77

File changed.

Preview size limit exceeded, changes collapsed.

+35 −10
Original line number Diff line number Diff line
@@ -102,6 +102,20 @@ enum dss_writeback_channel {
	DSS_WB_LCD3_MGR =	7,
};

enum dss_clk_source {
	DSS_CLK_SRC_FCK = 0,

	DSS_CLK_SRC_PLL1_1,
	DSS_CLK_SRC_PLL1_2,
	DSS_CLK_SRC_PLL1_3,

	DSS_CLK_SRC_PLL2_1,
	DSS_CLK_SRC_PLL2_2,
	DSS_CLK_SRC_PLL2_3,

	DSS_CLK_SRC_HDMI_PLL,
};

enum dss_pll_id {
	DSS_PLL_DSI1,
	DSS_PLL_DSI2,
@@ -114,6 +128,11 @@ struct dss_pll;

#define DSS_PLL_MAX_HSDIVS 4

enum dss_pll_type {
	DSS_PLL_TYPE_A,
	DSS_PLL_TYPE_B,
};

/*
 * Type-A PLLs: clkout[]/mX[] refer to hsdiv outputs m4, m5, m6, m7.
 * Type-B PLLs: clkout[0] refers to m2.
@@ -140,6 +159,8 @@ struct dss_pll_ops {
};

struct dss_pll_hw {
	enum dss_pll_type type;

	unsigned n_max;
	unsigned m_min;
	unsigned m_max;
@@ -227,7 +248,7 @@ unsigned long dss_get_dispc_clk_rate(void);
int dss_dpi_select_source(int port, enum omap_channel channel);
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
const char *dss_get_clk_source_name(enum dss_clk_source clk_src);
void dss_dump_clocks(struct seq_file *s);

/* DSS VIDEO PLL */
@@ -244,20 +265,18 @@ void dss_debug_dump_clocks(struct seq_file *s);
#endif

void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable);
void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id,
	enum omap_channel channel);

void dss_sdi_init(int datapairs);
int dss_sdi_enable(void);
void dss_sdi_disable(void);

void dss_select_dsi_clk_source(int dsi_module,
		enum omap_dss_clk_source clk_src);
		enum dss_clk_source clk_src);
void dss_select_lcd_clk_source(enum omap_channel channel,
		enum omap_dss_clk_source clk_src);
enum omap_dss_clk_source dss_get_dispc_clk_source(void);
enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module);
enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
		enum dss_clk_source clk_src);
enum dss_clk_source dss_get_dispc_clk_source(void);
enum dss_clk_source dss_get_dsi_clk_source(int dsi_module);
enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);

void dss_set_venc_output(enum omap_dss_venc_type type);
void dss_set_dac_pwrdn_bgz(bool enable);
@@ -409,17 +428,23 @@ typedef bool (*dss_hsdiv_calc_func)(int m_dispc, unsigned long dispc,
int dss_pll_register(struct dss_pll *pll);
void dss_pll_unregister(struct dss_pll *pll);
struct dss_pll *dss_pll_find(const char *name);
struct dss_pll *dss_pll_find_by_src(enum dss_clk_source src);
unsigned dss_pll_get_clkout_idx_for_src(enum dss_clk_source src);
int dss_pll_enable(struct dss_pll *pll);
void dss_pll_disable(struct dss_pll *pll);
int dss_pll_set_config(struct dss_pll *pll,
		const struct dss_pll_clock_info *cinfo);

bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco,
bool dss_pll_hsdiv_calc_a(const struct dss_pll *pll, unsigned long clkdco,
		unsigned long out_min, unsigned long out_max,
		dss_hsdiv_calc_func func, void *data);
bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin,
bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
		unsigned long pll_min, unsigned long pll_max,
		dss_pll_calc_func func, void *data);

bool dss_pll_calc_b(const struct dss_pll *pll, unsigned long clkin,
	unsigned long target_clkout, struct dss_pll_clock_info *cinfo);

int dss_pll_write_config_type_a(struct dss_pll *pll,
		const struct dss_pll_clock_info *cinfo);
int dss_pll_write_config_type_b(struct dss_pll *pll,
Loading