コード例 #1
0
/* Perodically update dbi panel */
void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
	struct mdfld_dsi_dbi_output **dbi_outputs;
	struct mdfld_dsi_dbi_output *dbi_output;
	struct mdfld_dsi_config *dsi_config;
	struct mdfld_dsi_hw_context *ctx;

	if (!dsr_info)
		return;

	dbi_outputs = dsr_info->dbi_outputs;
	dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0];
	dsi_config = pipe ? dev_priv->dsi_configs[1] : dev_priv->dsi_configs[0];

	if (!dbi_output || !dsi_config || (pipe == 1) ||
		(is_panel_vid_or_cmd(dev) != MDFLD_DSI_ENCODER_DBI))
		return;

	ctx = &dsi_config->dsi_hw_context;

	/*lock dsi config*/
	mutex_lock(&dsi_config->context_lock);

	/*if FB is damaged and panel is on update on-panel FB*/
	if (!ctx->panel_on)
		goto update_out;

	intel_dsi_dbi_update_fb(dbi_output);

update_out:
	mutex_unlock(&dsi_config->context_lock);
}
コード例 #2
0
/**
 * Set up the display clock 
 *
 */
void mrfld_setup_pll(struct drm_device *dev, int pipe, int clk)
{
	DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
	int refclk = 0;
	int clk_n = 0, clk_p2 = 0, clk_byte = 1, m_conv = 0, clk_tmp = 0;
	struct mrst_clock_t clock;
	bool ok;
	u32 pll = 0, fp = 0;
	bool is_mipi = false, is_mipi2 = false, is_hdmi = false;
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;

	PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe);

	if (pipe == 0)
		dsi_config = dev_priv->dsi_configs[0];
	else if (pipe == 2)
		dsi_config = dev_priv->dsi_configs[1];

	if ((pipe != 1) && !dsi_config) {
		DRM_ERROR("Invalid DSI config\n");
		return;
	}

	if (pipe != 1) {
		ctx = &dsi_config->dsi_hw_context;

		mutex_lock(&dsi_config->context_lock);
	}

	switch (pipe) {
	case 0:
		is_mipi = true;
		break;
	case 1:
		is_hdmi = true;
		break;
	case 2:
		is_mipi2 = true;
		break;
	}

	if ((dev_priv->ksel == KSEL_CRYSTAL_19)
	    || (dev_priv->ksel == KSEL_BYPASS_19)) {
		refclk = 19200;

		if (is_mipi || is_mipi2) {
			clk_n = 1, clk_p2 = 8;
		} else if (is_hdmi) {
			clk_n = 1, clk_p2 = 10;
		}
	} else if (dev_priv->ksel == KSEL_BYPASS_25) {
		refclk = 25000;

		if (is_mipi || is_mipi2) {
			clk_n = 1, clk_p2 = 8;
		} else if (is_hdmi) {
			clk_n = 1, clk_p2 = 10;
		}
	} else if ((dev_priv->ksel == KSEL_BYPASS_83_100)
		   && (dev_priv->core_freq == 166)) {
		refclk = 83000;

		if (is_mipi || is_mipi2) {
			clk_n = 4, clk_p2 = 8;
		} else if (is_hdmi) {
			clk_n = 4, clk_p2 = 10;
		}
	} else if ((dev_priv->ksel == KSEL_BYPASS_83_100) &&
		   (dev_priv->core_freq == 100 || dev_priv->core_freq == 200)) {
		refclk = 100000;
		if (is_mipi || is_mipi2) {
			clk_n = 4, clk_p2 = 8;
		} else if (is_hdmi) {
			clk_n = 4, clk_p2 = 10;
		}
	}

	if (is_mipi || is_mipi2)
		clk_byte = 3;

	clk_tmp = clk * clk_n * clk_p2 * clk_byte;

	PSB_DEBUG_ENTRY("clk = %d, clk_n = %d, clk_p2 = %d. \n", clk, clk_n,
			clk_p2);
	PSB_DEBUG_ENTRY("clk = %d, clk_tmp = %d, clk_byte = %d. \n", clk,
			clk_tmp, clk_byte);

	ok = mrfld_find_best_PLL(dev, pipe, clk_tmp, refclk, &clock);
	dev_priv->tmds_clock_khz = clock.dot / (clk_n * clk_p2 * clk_byte);

	/*
	 * FIXME: Hard code the divisors' value for JDI panel, and need to
	 * calculate them according to the DSI PLL HAS spec.
	 */
	if (pipe != 1) {
		if (is_panel_vid_or_cmd(dev) == MDFLD_DSI_ENCODER_DBI) {
			if (get_panel_type(dev, pipe) == JDI_CMD) {
				clock.p1 = 4;
				clk_n = 1;
				clock.m = 142;
			} else {
				clock.p1 = 4;
				clk_n = 1;
				clock.m = 120;
			}
		} else {
			clock.p1 = 5;
			clk_n = 1;
			clock.m = 130;
		}
	}

	if (!ok) {
		DRM_ERROR("mdfldFindBestPLL fail in mrfld_crtc_mode_set.\n");
	} else {
		m_conv = mrfld_m_converts[(clock.m - MRFLD_M_MIN)];

		PSB_DEBUG_ENTRY("dot clock = %d,"
				"m = %d, p1 = %d, m_conv = %d. \n", clock.dot,
				clock.m, clock.p1, m_conv);
	}

	/* Write the N1 & M1 parameters into DSI_PLL_DIV_REG */
	fp = (clk_n / 2) << 16;
	fp |= m_conv;

	if (is_mipi) {
		/* Enable DSI PLL clocks for DSI0 rather than CCK. */
		pll |= _CLK_EN_PLL_DSI0;
		pll &= ~_CLK_EN_CCK_DSI0;
		/* Select DSI PLL as the source of the mux input clocks. */
		pll &= ~_DSI_MUX_SEL_CCK_DSI0;
	}

	if (is_mipi2) {
		/* Enable DSI PLL clocks for DSI1 rather than CCK. */
		pll |= _CLK_EN_PLL_DSI1;
		pll &= ~_CLK_EN_CCK_DSI1;
		/* Select DSI PLL as the source of the mux input clocks. */
		pll &= ~_DSI_MUX_SEL_CCK_DSI1;
	}

	if (is_hdmi)
		pll |= MDFLD_VCO_SEL;

	/* compute bitmask from p1 value */
	pll |= (1 << (clock.p1 - 2)) << 17;

	if (pipe != 1) {
		ctx->dpll = pll;
		ctx->fp = fp;

		mutex_unlock(&dsi_config->context_lock);
	}
}
コード例 #3
0
static
void intel_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output)
{
	struct mdfld_dsi_pkg_sender *sender;
	struct drm_device *dev = dbi_output->dev;
	struct drm_crtc *crtc = dbi_output->base.base.crtc;
	struct psb_intel_crtc *psb_crtc =
		(crtc) ? to_psb_intel_crtc(crtc) : NULL;
	int pipe = dbi_output->channel_num ? 2 : 0;
	u32 dpll_reg = MRST_DPLL_A;
	u32 dspcntr_reg = DSPACNTR;
	u32 pipeconf_reg = PIPEACONF;
	u32 dsplinoff_reg = DSPALINOFF;
	u32 dspsurf_reg = DSPASURF;

	sender = mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
	if (!sender) {
		DRM_ERROR("pkg sender is NULL\n");
		return;
	}

	/* if mode setting on-going, back off */

	if (!IS_ANN_A0(dev)) {
		if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
				(psb_crtc && (psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) ||
				!(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
			return;
	}

	if (pipe == 2) {
		dspcntr_reg = DSPCCNTR;
		pipeconf_reg = PIPECCONF;
		dsplinoff_reg = DSPCLINOFF;
		dspsurf_reg = DSPCSURF;
	}

	/* check DBI FIFO status */
	if (is_panel_vid_or_cmd(dev) == MDFLD_DSI_ENCODER_DBI) {
		if (!(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
		   !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE))
			return;
	} else if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
	   !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
	   !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE))
		return;

	if (!IS_ANN_A0(dev)) {
		/* refresh plane changes */

		REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
		REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
		REG_READ(dspsurf_reg);
	}

	mdfld_dsi_send_dcs(sender,
			   write_mem_start,
			   NULL,
			   0,
			   CMD_DATA_SRC_PIPE,
			   MDFLD_DSI_SEND_PACKAGE);
	dbi_output->dsr_fb_update_done = true;
	mdfld_dsi_cmds_kick_out(sender);
}