[v8,18/38] drm/i915/icl: Allocate DSI encoder/connector

Submitted by Jani Nikula on Oct. 30, 2018, 11:56 a.m.

Details

Message ID 1bf732ff247c13ce3d532868b51589a5cdaac4da.1540900289.git.jani.nikula@intel.com
State New
Headers show
Series "drm/i915/icl: dsi enabling" ( rev: 3 ) in Intel GFX

Not browsing as part of any series.

Commit Message

Jani Nikula Oct. 30, 2018, 11:56 a.m.
This patch allocates memory for DSI encoder and connector
which will be used for various DSI encoder/connector operations
and attaching the same to DRM subsystem. This patch also extracts
DSI modes info from VBT and save the desired mode info to connector.

v2 by Jani:
 - Drop GEN11 prefix from encoder name
 - Drop extra parenthesis
 - Drop extra local variable
 - Squash encoder power domain here

Signed-off-by: Madhav Chauhan <madhav.chauhan@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/icl_dsi.c | 96 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 88 insertions(+), 8 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c
index 01f422df8c23..a117ecc6c5a3 100644
--- a/drivers/gpu/drm/i915/icl_dsi.c
+++ b/drivers/gpu/drm/i915/icl_dsi.c
@@ -799,10 +799,9 @@  static void gen11_dsi_powerup_panel(struct intel_encoder *encoder)
 	wait_for_cmds_dispatched_to_panel(encoder);
 }
 
-static void __attribute__((unused))
-gen11_dsi_pre_enable(struct intel_encoder *encoder,
-		     const struct intel_crtc_state *pipe_config,
-		     const struct drm_connector_state *conn_state)
+static void gen11_dsi_pre_enable(struct intel_encoder *encoder,
+				 const struct intel_crtc_state *pipe_config,
+				 const struct drm_connector_state *conn_state)
 {
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
 
@@ -945,10 +944,9 @@  static void gen11_dsi_disable_io_power(struct intel_encoder *encoder)
 	}
 }
 
-static void __attribute__((unused)) gen11_dsi_disable(
-			struct intel_encoder *encoder,
-			const struct intel_crtc_state *old_crtc_state,
-			const struct drm_connector_state *old_conn_state)
+static void gen11_dsi_disable(struct intel_encoder *encoder,
+			      const struct intel_crtc_state *old_crtc_state,
+			      const struct drm_connector_state *old_conn_state)
 {
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
 
@@ -972,10 +970,92 @@  static void __attribute__((unused)) gen11_dsi_disable(
 	gen11_dsi_disable_io_power(encoder);
 }
 
+static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder)
+{
+	intel_encoder_destroy(encoder);
+}
+
+static const struct drm_encoder_funcs gen11_dsi_encoder_funcs = {
+	.destroy = gen11_dsi_encoder_destroy,
+};
+
+static const struct drm_connector_funcs gen11_dsi_connector_funcs = {
+};
+
 void icl_dsi_init(struct drm_i915_private *dev_priv)
 {
+	struct drm_device *dev = &dev_priv->drm;
+	struct intel_dsi *intel_dsi;
+	struct intel_encoder *encoder;
+	struct intel_connector *intel_connector;
+	struct drm_connector *connector;
+	struct drm_display_mode *scan, *fixed_mode = NULL;
 	enum port port;
 
 	if (!intel_bios_is_dsi_present(dev_priv, &port))
 		return;
+
+	intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
+	if (!intel_dsi)
+		return;
+
+	intel_connector = intel_connector_alloc();
+	if (!intel_connector) {
+		kfree(intel_dsi);
+		return;
+	}
+
+	encoder = &intel_dsi->base;
+	intel_dsi->attached_connector = intel_connector;
+	connector = &intel_connector->base;
+
+	/* register DSI encoder with DRM subsystem */
+	drm_encoder_init(dev, &encoder->base, &gen11_dsi_encoder_funcs,
+			 DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port));
+
+	encoder->pre_enable = gen11_dsi_pre_enable;
+	encoder->disable = gen11_dsi_disable;
+	encoder->port = port;
+	encoder->type = INTEL_OUTPUT_DSI;
+	encoder->cloneable = 0;
+	encoder->crtc_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C);
+	encoder->power_domain = POWER_DOMAIN_PORT_DSI;
+
+	/* register DSI connector with DRM subsystem */
+	drm_connector_init(dev, connector, &gen11_dsi_connector_funcs,
+			   DRM_MODE_CONNECTOR_DSI);
+	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+	connector->interlace_allowed = false;
+	connector->doublescan_allowed = false;
+
+	/* attach connector to encoder */
+	intel_connector_attach_encoder(intel_connector, encoder);
+
+	/* fill mode info from VBT */
+	mutex_lock(&dev->mode_config.mutex);
+	intel_dsi_vbt_get_modes(intel_dsi);
+	list_for_each_entry(scan, &connector->probed_modes, head) {
+		if (scan->type & DRM_MODE_TYPE_PREFERRED) {
+			fixed_mode = drm_mode_duplicate(dev, scan);
+			break;
+		}
+	}
+	mutex_unlock(&dev->mode_config.mutex);
+
+	if (!fixed_mode) {
+		DRM_ERROR("DSI fixed mode info missing\n");
+		goto err;
+	}
+
+	connector->display_info.width_mm = fixed_mode->width_mm;
+	connector->display_info.height_mm = fixed_mode->height_mm;
+	intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
+	intel_panel_setup_backlight(connector, INVALID_PIPE);
+
+	return;
+
+err:
+	drm_encoder_cleanup(&encoder->base);
+	kfree(intel_dsi);
+	kfree(intel_connector);
 }

Comments

On 10/30/2018 5:26 PM, Jani Nikula wrote:
> This patch allocates memory for DSI encoder and connector
> which will be used for various DSI encoder/connector operations
> and attaching the same to DRM subsystem. This patch also extracts
> DSI modes info from VBT and save the desired mode info to connector.
>
> v2 by Jani:
>   - Drop GEN11 prefix from encoder name
>   - Drop extra parenthesis
>   - Drop extra local variable
>   - Squash encoder power domain here

Looks good to me.

Regards,
Madhav

>
> Signed-off-by: Madhav Chauhan <madhav.chauhan@intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>   drivers/gpu/drm/i915/icl_dsi.c | 96 ++++++++++++++++++++++++++++++++++++++----
>   1 file changed, 88 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c
> index 01f422df8c23..a117ecc6c5a3 100644
> --- a/drivers/gpu/drm/i915/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/icl_dsi.c
> @@ -799,10 +799,9 @@ static void gen11_dsi_powerup_panel(struct intel_encoder *encoder)
>   	wait_for_cmds_dispatched_to_panel(encoder);
>   }
>   
> -static void __attribute__((unused))
> -gen11_dsi_pre_enable(struct intel_encoder *encoder,
> -		     const struct intel_crtc_state *pipe_config,
> -		     const struct drm_connector_state *conn_state)
> +static void gen11_dsi_pre_enable(struct intel_encoder *encoder,
> +				 const struct intel_crtc_state *pipe_config,
> +				 const struct drm_connector_state *conn_state)
>   {
>   	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>   
> @@ -945,10 +944,9 @@ static void gen11_dsi_disable_io_power(struct intel_encoder *encoder)
>   	}
>   }
>   
> -static void __attribute__((unused)) gen11_dsi_disable(
> -			struct intel_encoder *encoder,
> -			const struct intel_crtc_state *old_crtc_state,
> -			const struct drm_connector_state *old_conn_state)
> +static void gen11_dsi_disable(struct intel_encoder *encoder,
> +			      const struct intel_crtc_state *old_crtc_state,
> +			      const struct drm_connector_state *old_conn_state)
>   {
>   	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>   
> @@ -972,10 +970,92 @@ static void __attribute__((unused)) gen11_dsi_disable(
>   	gen11_dsi_disable_io_power(encoder);
>   }
>   
> +static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder)
> +{
> +	intel_encoder_destroy(encoder);
> +}
> +
> +static const struct drm_encoder_funcs gen11_dsi_encoder_funcs = {
> +	.destroy = gen11_dsi_encoder_destroy,
> +};
> +
> +static const struct drm_connector_funcs gen11_dsi_connector_funcs = {
> +};
> +
>   void icl_dsi_init(struct drm_i915_private *dev_priv)
>   {
> +	struct drm_device *dev = &dev_priv->drm;
> +	struct intel_dsi *intel_dsi;
> +	struct intel_encoder *encoder;
> +	struct intel_connector *intel_connector;
> +	struct drm_connector *connector;
> +	struct drm_display_mode *scan, *fixed_mode = NULL;
>   	enum port port;
>   
>   	if (!intel_bios_is_dsi_present(dev_priv, &port))
>   		return;
> +
> +	intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
> +	if (!intel_dsi)
> +		return;
> +
> +	intel_connector = intel_connector_alloc();
> +	if (!intel_connector) {
> +		kfree(intel_dsi);
> +		return;
> +	}
> +
> +	encoder = &intel_dsi->base;
> +	intel_dsi->attached_connector = intel_connector;
> +	connector = &intel_connector->base;
> +
> +	/* register DSI encoder with DRM subsystem */
> +	drm_encoder_init(dev, &encoder->base, &gen11_dsi_encoder_funcs,
> +			 DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port));
> +
> +	encoder->pre_enable = gen11_dsi_pre_enable;
> +	encoder->disable = gen11_dsi_disable;
> +	encoder->port = port;
> +	encoder->type = INTEL_OUTPUT_DSI;
> +	encoder->cloneable = 0;
> +	encoder->crtc_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C);
> +	encoder->power_domain = POWER_DOMAIN_PORT_DSI;
> +
> +	/* register DSI connector with DRM subsystem */
> +	drm_connector_init(dev, connector, &gen11_dsi_connector_funcs,
> +			   DRM_MODE_CONNECTOR_DSI);
> +	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
> +	connector->interlace_allowed = false;
> +	connector->doublescan_allowed = false;
> +
> +	/* attach connector to encoder */
> +	intel_connector_attach_encoder(intel_connector, encoder);
> +
> +	/* fill mode info from VBT */
> +	mutex_lock(&dev->mode_config.mutex);
> +	intel_dsi_vbt_get_modes(intel_dsi);
> +	list_for_each_entry(scan, &connector->probed_modes, head) {
> +		if (scan->type & DRM_MODE_TYPE_PREFERRED) {
> +			fixed_mode = drm_mode_duplicate(dev, scan);
> +			break;
> +		}
> +	}
> +	mutex_unlock(&dev->mode_config.mutex);
> +
> +	if (!fixed_mode) {
> +		DRM_ERROR("DSI fixed mode info missing\n");
> +		goto err;
> +	}
> +
> +	connector->display_info.width_mm = fixed_mode->width_mm;
> +	connector->display_info.height_mm = fixed_mode->height_mm;
> +	intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
> +	intel_panel_setup_backlight(connector, INVALID_PIPE);
> +
> +	return;
> +
> +err:
> +	drm_encoder_cleanup(&encoder->base);
> +	kfree(intel_dsi);
> +	kfree(intel_connector);
>   }