コード例 #1
0
void enable_HFPLL(struct drm_device *dev)
{
	uint32_t pll_select = 0, ctrl_reg5 = 0;
	struct drm_psb_private *dev_priv =
		(struct drm_psb_private *)dev->dev_private;

	/* Enable HFPLL for command mode panel */
	if (dev_priv->bUseHFPLL) {
			pll_select = intel_mid_msgbus_read32(CCK_PORT,
						DSI_PLL_CTRL_REG);
			ctrl_reg5 = intel_mid_msgbus_read32(CCK_PORT,
						FUSE_OVERRIDE_FREQ_CNTRL_REG5);

			pll_select &= ~(_DSI_MUX_SEL_CCK_DSI1 |
					_DSI_MUX_SEL_CCK_DSI0);

			intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG,
					pll_select | _DSI_CCK_PLL_SELECT);
			ctrl_reg5 |= (1 << 7) | 0xF;

			if (get_panel_type(dev, 0) == SHARP_10x19_CMD)
				ctrl_reg5 = 0x1f87;
			intel_mid_msgbus_write32(CCK_PORT,
					FUSE_OVERRIDE_FREQ_CNTRL_REG5,
					ctrl_reg5);
	}
}
コード例 #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
void mdfld_reset_panel_handler_work(struct work_struct *work)
{
	struct drm_psb_private *dev_priv =
		container_of(work, struct drm_psb_private, reset_panel_work);
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_dbi_output *dbi_output = NULL;
	struct panel_funcs *p_funcs  = NULL;
	struct drm_device *dev;

	dbi_output = dev_priv->dbi_output;
	dsi_config = dev_priv->dsi_configs[0];

	if (!dsi_config || !dbi_output)
		return;
	dev = dsi_config->dev;

	/*disable ESD when HDMI connected*/
	if (hdmi_state)
		return;

	PSB_DEBUG_ENTRY("\n");

	p_funcs = dbi_output->p_funcs;
	if (p_funcs) {
		mutex_lock(&dsi_config->context_lock);

		if (!dsi_config->dsi_hw_context.panel_on) {
			DRM_INFO("don't reset panel when panel is off\n");
			mutex_unlock(&dsi_config->context_lock);
			return;
		}

		DRM_INFO("Starts ESD panel reset\n");
		/*
		 * since panel is in abnormal state,
		 * we do a power off/on first
		 */
		power_island_put(OSPM_DISPLAY_A |
				 OSPM_DISPLAY_C |
				 OSPM_DISPLAY_MIO);
		power_island_get(OSPM_DISPLAY_A |
				 OSPM_DISPLAY_C |
				 OSPM_DISPLAY_MIO);

		if (__dbi_panel_power_off(dsi_config, p_funcs))
			DRM_INFO("failed to power off dbi panel\n");

		if (get_panel_type(dev, 0) == JDI_7x12_CMD)
			if (p_funcs && p_funcs->reset)
				p_funcs->reset(dsi_config);

		if (__dbi_panel_power_on(dsi_config, p_funcs)) {
			DRM_ERROR("failed to power on dbi panel\n");
			mutex_unlock(&dsi_config->context_lock);
			return;
		}

		mutex_unlock(&dsi_config->context_lock);

		/*recover pipestat in case island once been poweroff and pipestat was reset to default*/
		mdfld_recover_te(dev, dsi_config->pipe);

		DRM_INFO("%s: End panel reset\n", __func__);
	} else {
		DRM_INFO("%s invalid panel init\n", __func__);
	}
}
コード例 #4
0
bool enable_DSIPLL(struct drm_device *dev)
{
	DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	u32 guit_val = 0x0;
	u32 retry;

	if (!dev_priv)
		goto err_out;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		goto err_out;
	ctx = &dsi_config->dsi_hw_context;

	if (IS_ANN(dev)) {
		int dspfreq;

		if ((get_panel_type(dev, 0) == JDI_7x12_CMD) ||
			(get_panel_type(dev, 0) == JDI_7x12_VID))
			dspfreq = DISPLAY_FREQ_FOR_200;
		else
			dspfreq = DISPLAY_FREQ_FOR_333;

		intel_mid_msgbus_write32(CCK_PORT,
			FUSE_OVERRIDE_FREQ_CNTRL_REG5,
			CKESC_GATE_EN | CKDP1X_GATE_EN | DISPLAY_FRE_EN
			| dspfreq);
	}

	/* Prepare DSI  PLL register before enabling */
	intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, 0);
	guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
	guit_val &= ~(DPLL_VCO_ENABLE | _DSI_LDO_EN
			|_CLK_EN_MASK | _DSI_MUX_SEL_CCK_DSI0 | _DSI_MUX_SEL_CCK_DSI1);
	intel_mid_msgbus_write32(CCK_PORT,
					DSI_PLL_CTRL_REG, guit_val);
	udelay(1);
	/* Program PLL */

	/*first set up the dpll and fp variables
	 * dpll - will contain the following information
	 *      - the clock source - DSI vs HFH vs LFH PLL
	 * 	- what clocks should be running DSI0, DSI1
	 *      - and the divisor.
	 *
	 */

	intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, ctx->fp);
	guit_val &= ~_P1_POST_DIV_MASK;	/*clear the divisor bit*/
	/* the ctx->dpll contains the divisor that we need to use as well as which clocks
	 * need to start up */
	guit_val |= ctx->dpll;
	guit_val &= ~_DSI_LDO_EN;	/* We want to clear the LDO enable when programming*/
	guit_val |=  DPLL_VCO_ENABLE;	/* Enable the DSI PLL */

	/* For the CD clock (clock used by Display controller), we need to set
	 * the DSI_CCK_PLL_SELECT bit (bit 11). This should already be set. But
	 * setting it just in case
	 */
	if (dev_priv->bUseHFPLL)
		guit_val |= _DSI_CCK_PLL_SELECT;

	intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, guit_val);

	/* Wait for DSI PLL lock */
	retry = 10000;
	guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
	while (((guit_val & _DSI_PLL_LOCK) != _DSI_PLL_LOCK) && (--retry)) {
		udelay(3);
		guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
		if (!retry%1000)
			DRM_ERROR("DSI PLL taking too long to lock"
				"- retry count=%d\n", 10000-retry);
	}
	if (retry == 0) {
		DRM_ERROR("DSI PLL fails to lock\n");
		return false;
	}

	return true;
err_out:
	return false;

}