[Intel-gfx] [PATCH 05/12] drm/i915/bxt: DSI encoder support in CRTC modeset

Jani Nikula jani.nikula at linux.intel.com
Mon May 25 03:25:56 PDT 2015


On Fri, 22 May 2015, Uma Shankar <uma.shankar at intel.com> wrote:
> From: Shashank Sharma <shashank.sharma at intel.com>
>
> SKL and BXT qualifies the HAS_DDI() check, and hence haswell modeset
> functions are re-used for modeset sequence. But DDI interface doesn't
> include support for DSI.
> This patch adds:
> 1. cases for DSI encoder, in those modeset functions and allows a CRTC modeset
> 2. Adds call to pre_pll enabled from CRTC modeset function. Nothing needs to be
>    done as such in CRTC for DSI encoder, as PLL, clock and and transcoder programming
>    will be taken care in encoder's pre_enable and pre_pll_enable function.
>
> Signed-off-by: Shashank Sharma <shashank.sharma at intel.com>
> Signed-off-by: Uma Shankar <uma.shankar at intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h       |    1 +
>  drivers/gpu/drm/i915/intel_ddi.c      |   53 +++++++++++++++++++++++++++++----
>  drivers/gpu/drm/i915/intel_display.c  |    6 +++-
>  drivers/gpu/drm/i915/intel_opregion.c |    1 +
>  4 files changed, 54 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 840f08f..6874121 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2452,6 +2452,7 @@ struct drm_i915_cmd_table {
>  				 INTEL_INFO(dev)->gen >= 9)
>  
>  #define HAS_DDI(dev)		(INTEL_INFO(dev)->has_ddi)
> +#define has_encoder_ddi(type)	((type) == (INTEL_OUTPUT_DSI) ?  0 : 1)
>  #define HAS_FPGA_DBG_UNCLAIMED(dev)	(INTEL_INFO(dev)->has_fpga_dbg)
>  #define HAS_PSR(dev)		(IS_HASWELL(dev) || IS_BROADWELL(dev) || \
>  				 IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev) || \
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index d602db2..2aef8b5 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -395,6 +395,12 @@ void intel_prepare_ddi(struct drm_device *dev)
>  		if (visited[port])
>  			continue;
>  
> +		if (intel_dig_port->base.type ==
> +				INTEL_OUTPUT_DSI) {
> +			visited[intel_dig_port->port] = true;
> +			continue;
> +		}
> +

ddi_get_encoder_port does not support DSI, and DSI does not have
intel_digital_port.

>  		supports_hdmi = intel_dig_port &&
>  				intel_dig_port_supports_hdmi(intel_dig_port);
>  
> @@ -1568,10 +1574,21 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	enum pipe pipe = intel_crtc->pipe;
>  	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> -	enum port port = intel_ddi_get_encoder_port(intel_encoder);
> +	enum port port;
>  	int type = intel_encoder->type;
>  	uint32_t temp;
>  
> +	/*
> +	 * Fixme: BXT has DDI, so tries to follow a DDI modeset function,

It's FIXME, TODO, or XXX, upper case. Grep must find these.

> +	 * but DDI interface doesn't support DSI yet, so don't do anything
> +	 * for DSI encoders
> +	 */
> +	if (!(HAS_DDI(dev) && has_encoder_ddi(type))) {

HAS_DDI() is always true here.

Hmm. Perhaps it would be nicer if we added INVALID_PORT = -1 to enum
port, and had intel_ddi_get_encoder_port() return that for DSI. Then we
could leave most of the functions the same, with just

	if (port == INVALID_PORT)
        	return;

at the beginning.

Daniel, opinions?

> +		DRM_DEBUG_DRIVER("Not setting transcoder for DSI\n");
> +		return;
> +	}
> +
> +	port = intel_ddi_get_encoder_port(intel_encoder);
>  	/* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
>  	temp = TRANS_DDI_FUNC_ENABLE;
>  	temp |= TRANS_DDI_SELECT_PORT(port);
> @@ -1779,11 +1796,17 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
>  void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
>  {
>  	struct drm_crtc *crtc = &intel_crtc->base;
> -	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
> -	enum port port = intel_ddi_get_encoder_port(intel_encoder);
> +	enum port port;
>  	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> +	int type = intel_encoder->type;
>  
> +	if (!(HAS_DDI(dev) && has_encoder_ddi(type)))
> +		return;
> +
> +	port = intel_ddi_get_encoder_port(intel_encoder);
>  	if (cpu_transcoder != TRANSCODER_EDP)
>  		I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
>  			   TRANS_CLK_SEL_PORT(port));
> @@ -1866,10 +1889,16 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
>  	struct drm_device *dev = encoder->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> -	enum port port = intel_ddi_get_encoder_port(intel_encoder);
> +	enum port port;
>  	int type = intel_encoder->type;
>  	int hdmi_level;
>  
> +	if (!(HAS_DDI(dev) && has_encoder_ddi(type))) {
> +		DRM_ERROR("DDI func getting called for MIPI?\n");

I don't think it's worth having these checks for pure DDI encoder
callback funcs. If we started on this path, our codebase would be filled
with this. Only do the DSI check on functions called from outside of
intel_ddi.c.

> +		return;
> +	}
> +
> +	port = intel_ddi_get_encoder_port(intel_encoder);
>  	if (type == INTEL_OUTPUT_EDP) {
>  		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>  		intel_edp_panel_on(intel_dp);
> @@ -1942,11 +1971,17 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
>  	struct drm_encoder *encoder = &intel_encoder->base;
>  	struct drm_device *dev = encoder->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	enum port port = intel_ddi_get_encoder_port(intel_encoder);
> +	enum port port;
>  	int type = intel_encoder->type;
>  	uint32_t val;
>  	bool wait = false;
>  
> +	if (!(HAS_DDI(dev) && has_encoder_ddi(type))) {
> +		DRM_ERROR("DDI func got called for DSI?\n");
> +		return;
> +	}
> +
> +	port = intel_ddi_get_encoder_port(intel_encoder);
>  	val = I915_READ(DDI_BUF_CTL(port));
>  	if (val & DDI_BUF_CTL_ENABLE) {
>  		val &= ~DDI_BUF_CTL_ENABLE;
> @@ -1983,9 +2018,15 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct drm_device *dev = encoder->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	enum port port = intel_ddi_get_encoder_port(intel_encoder);
> +	enum port port;
>  	int type = intel_encoder->type;
>  
> +	if (!(HAS_DDI(dev) && has_encoder_ddi(type))) {
> +		DRM_ERROR("DDI func getting called for DSI?\n");
> +		return;
> +	}
> +
> +	port = intel_ddi_get_encoder_port(intel_encoder);
>  	if (type == INTEL_OUTPUT_HDMI) {
>  		struct intel_digital_port *intel_dig_port =
>  			enc_to_dig_port(encoder);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index c30bfd4..c1fac21 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4987,6 +4987,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_encoder *encoder;
>  	int pipe = intel_crtc->pipe;
> +	bool is_dsi = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI);
>  
>  	WARN_ON(!crtc->state->enable);
>  
> @@ -5052,13 +5053,16 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  	if (intel_crtc->config->has_pch_encoder)
>  		lpt_pch_enable(crtc);
>  
> -	if (intel_crtc->config->dp_encoder_is_mst)
> +	if (intel_crtc->config->dp_encoder_is_mst && !is_dsi)
>  		intel_ddi_set_vc_payload_alloc(crtc, true);
>  
>  	assert_vblank_disabled(crtc);
>  	drm_crtc_vblank_on(crtc);
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder) {
> +		if (encoder->pre_pll_enable)
> +			encoder->pre_pll_enable(encoder);
> +
>  		encoder->enable(encoder);
>  		intel_opregion_notify_encoder(encoder, true);
>  	}
> diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
> index 71e87ab..4b025ee 100644
> --- a/drivers/gpu/drm/i915/intel_opregion.c
> +++ b/drivers/gpu/drm/i915/intel_opregion.c
> @@ -356,6 +356,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
>  		type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL;
>  		break;
>  	case INTEL_OUTPUT_EDP:
> +	case INTEL_OUTPUT_DSI:

You would have oopsed in the intel_ddi_get_encoder_port already before
reaching here...


>  		type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL;
>  		break;
>  	default:
> -- 
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center


More information about the Intel-gfx mailing list