Skip to contentSkip to conversation

drm/i915/icl: dsi enabling

PATCH Superseded Jani Nikula 5 participants 25 messages Nov 1, 2018 – Nov 2, 2018

Subsystems (2)

v9 of 11 Superseded Latest is v11 →

lore
Share & tools
lore
#0 lore raw

v9 cover drm/i915/icl: dsi enabling

Next version of [1]. Still needs the DSI PLL stuff Vandita covers.

BR,
Jani.

[1] https://patchwork.freedesktop.org/series/51011/

Jani Nikula (5):
drm/i915/icl: Fill DSI ports info
drm/i915/icl: Allocate DSI hosts and imlement host transfer drm/i915/icl: Add DSI encoder remaining functions drm/i915/icl: add dummy DSI GPIO element execution function
HACK: drm/i915/icl: Add changes to program DSI panel GPIOs

Madhav Chauhan (10):
drm/i915/icl: Allocate DSI encoder/connector drm/i915/icl: Add get config functionality for DSI drm/i915/icl: Get HW state for DSI encoder drm/i915/icl: Configure DSI Dual link mode drm/i915/icl: Consider DSI for getting transcoder state drm/i915/icl: Get pipe timings for DSI drm/i915/icl: Define missing bitfield for shortplug reg drm/i915/icl: Define Panel power ctrl register drm/i915/icl: Define display GPIO pins for DSI
HACK: drm/i915/icl: Configure backlight functions for DSI

 drivers/gpu/drm/i915/i915_reg.h      |  12 ++
 drivers/gpu/drm/i915/icl_dsi.c       | 408 ++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_display.c |  34 ++-
 drivers/gpu/drm/i915/intel_dsi_vbt.c |  58 ++++-
 drivers/gpu/drm/i915/intel_panel.c   |   3 +-
 5 files changed, 496 insertions(+), 19 deletions(-)
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#1 lore raw

PATCH v9 1/15 drm/i915/icl: Allocate DSI encoder/connector

From: Madhav Chauhan <[email protected]>

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

v3 by Jani:
- Squash connector and connector helper functions here
- Move intel_dsi_vbt_init call here

---
 drivers/gpu/drm/i915/icl_dsi.c | 117 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 109 insertions(+), 8 deletions(-)
drivers/gpu/drm/i915/icl_dsi.c +109 -8
index 01f422df8c23..a40083a7eb6a 100644
@@ -26,6 +26,7 @@
  */
 
 #include <drm/drm_mipi_dsi.h>
+#include <drm/drm_atomic_helper.h>
 #include "intel_dsi.h"
 
 static inline int header_credits_available(struct drm_i915_private *dev_priv,
@@ -799,10 +800,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 +945,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 +971,112 @@ 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 = {
+	.late_register = intel_connector_register,
+	.early_unregister = intel_connector_unregister,
+	.destroy = intel_connector_destroy,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.atomic_get_property = intel_digital_connector_atomic_get_property,
+	.atomic_set_property = intel_digital_connector_atomic_set_property,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = intel_digital_connector_duplicate_state,
+};
+
+static const struct drm_connector_helper_funcs gen11_dsi_connector_helper_funcs = {
+	.get_modes = intel_dsi_get_modes,
+	.mode_valid = intel_dsi_mode_valid,
+	.atomic_check = intel_digital_connector_atomic_check,
+};
+
 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);
+	drm_connector_helper_add(connector, &gen11_dsi_connector_helper_funcs);
+	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);
+
+	if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID)) {
+		DRM_DEBUG_KMS("no device found\n");
+		goto err;
+	}
+
+	return;
+
+err:
+	drm_encoder_cleanup(&encoder->base);
+	kfree(intel_dsi);
+	kfree(intel_connector);
 }
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#3 lore raw

PATCH v9 2/15 drm/i915/icl: Fill DSI ports info

In reply to Jani Nikula

This patch fills backlight, CABC and general port info for Gen11 DSI.

---
 drivers/gpu/drm/i915/icl_dsi.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/gpu/drm/i915/icl_dsi.c +8 -0
index a40083a7eb6a..fe408ff77924 100644
@@ -1068,6 +1068,14 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 	intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
 	intel_panel_setup_backlight(connector, INVALID_PIPE);
 
+	if (dev_priv->vbt.dsi.config->dual_link)
+		intel_dsi->ports = BIT(PORT_A) | BIT(PORT_B);
+	else
+		intel_dsi->ports = BIT(port);
+
+	intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports;
+	intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports;
+
 	if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID)) {
 		DRM_DEBUG_KMS("no device found\n");
 		goto err;
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#4 lore raw

PATCH v9 3/15 drm/i915/icl: Allocate DSI hosts and imlement host transfer

In reply to Jani Nikula

Allocate DSI host structure for each DSI port available on gen11 and register them with DSI fwk of DRM. Some of the DSI host operations are also registered as part of this.

Retrieves DSI pkt (from DSI msg) to be sent over DSI link using DRM DSI exported functions. A wrapper function is also added as "DSI host transfer" for sending DSI data/cmd. Add DSI packet payload to command payload queue using credit based mechanism for *long* packets.

v2 by Jani:
- indentation
- Use the new credit available helper
- Use int for free_credits
- Add intel_dsi local variable for better code flow
- Use the new credit available helper
- Use int for free_credits, i, and j

v3 by Jani:
- Squash DSI host allocation and transfer patches together

---
 drivers/gpu/drm/i915/icl_dsi.c | 147 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 147 insertions(+)
drivers/gpu/drm/i915/icl_dsi.c +147 -0
index fe408ff77924..806b8c323b53 100644
@@ -108,6 +108,90 @@ static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder)
 	}
 }
 
+static bool add_payld_to_queue(struct intel_dsi_host *host, const u8 *data,
+			       u32 len)
+{
+	struct intel_dsi *intel_dsi = host->intel_dsi;
+	struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
+	enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
+	int free_credits;
+	int i, j;
+
+	for (i = 0; i < len; i += 4) {
+		u32 tmp = 0;
+
+		free_credits = payload_credits_available(dev_priv, dsi_trans);
+		if (free_credits < 1) {
+			DRM_ERROR("Payload credit not available\n");
+			return false;
+		}
+
+		for (j = 0; j < min_t(u32, len - i, 4); j++)
+			tmp |= *data++ << 8 * j;
+
+		I915_WRITE(DSI_CMD_TXPYLD(dsi_trans), tmp);
+	}
+
+	return true;
+}
+
+static int dsi_send_pkt_hdr(struct intel_dsi_host *host,
+			    struct mipi_dsi_packet pkt, bool enable_lpdt)
+{
+	struct intel_dsi *intel_dsi = host->intel_dsi;
+	struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
+	enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
+	u32 tmp;
+	int free_credits;
+
+	/* check if header credit available */
+	free_credits = header_credits_available(dev_priv, dsi_trans);
+	if (free_credits < 1) {
+		DRM_ERROR("send pkt header failed, not enough hdr credits\n");
+		return -1;
+	}
+
+	tmp = I915_READ(DSI_CMD_TXHDR(dsi_trans));
+
+	if (pkt.payload)
+		tmp |= PAYLOAD_PRESENT;
+	else
+		tmp &= ~PAYLOAD_PRESENT;
+
+	tmp &= ~VBLANK_FENCE;
+
+	if (enable_lpdt)
+		tmp |= LP_DATA_TRANSFER;
+
+	tmp &= ~(PARAM_WC_MASK | VC_MASK | DT_MASK);
+	tmp |= ((pkt.header[0] & VC_MASK) << VC_SHIFT);
+	tmp |= ((pkt.header[0] & DT_MASK) << DT_SHIFT);
+	tmp |= (pkt.header[1] << PARAM_WC_LOWER_SHIFT);
+	tmp |= (pkt.header[2] << PARAM_WC_UPPER_SHIFT);
+	I915_WRITE(DSI_CMD_TXHDR(dsi_trans), tmp);
+
+	return 0;
+}
+
+static int dsi_send_pkt_payld(struct intel_dsi_host *host,
+			      struct mipi_dsi_packet pkt)
+{
+	/* payload queue can accept *256 bytes*, check limit */
+	if (pkt.payload_length > MAX_PLOAD_CREDIT * 4) {
+		DRM_ERROR("payload size exceeds max queue limit\n");
+		return -1;
+	}
+
+	/* load data into command payload queue */
+	if (!add_payld_to_queue(host, pkt.payload,
+				pkt.payload_length)) {
+		DRM_ERROR("adding payload to queue failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
 static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -997,6 +1081,58 @@ static const struct drm_connector_helper_funcs gen11_dsi_connector_helper_funcs
 	.atomic_check = intel_digital_connector_atomic_check,
 };
 
+static int gen11_dsi_host_attach(struct mipi_dsi_host *host,
+				 struct mipi_dsi_device *dsi)
+{
+	return 0;
+}
+
+static int gen11_dsi_host_detach(struct mipi_dsi_host *host,
+				 struct mipi_dsi_device *dsi)
+{
+	return 0;
+}
+
+static ssize_t gen11_dsi_host_transfer(struct mipi_dsi_host *host,
+				       const struct mipi_dsi_msg *msg)
+{
+	struct intel_dsi_host *intel_dsi_host = to_intel_dsi_host(host);
+	struct mipi_dsi_packet dsi_pkt;
+	ssize_t ret;
+	bool enable_lpdt = false;
+
+	ret = mipi_dsi_create_packet(&dsi_pkt, msg);
+	if (ret < 0)
+		return ret;
+
+	if (msg->flags & MIPI_DSI_MSG_USE_LPM)
+		enable_lpdt = true;
+
+	/* send packet header */
+	ret  = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt);
+	if (ret < 0)
+		return ret;
+
+	/* only long packet contains payload */
+	if (mipi_dsi_packet_format_is_long(msg->type)) {
+		ret = dsi_send_pkt_payld(intel_dsi_host, dsi_pkt);
+		if (ret < 0)
+			return ret;
+	}
+
+	//TODO: add payload receive code if needed
+
+	ret = sizeof(dsi_pkt.header) + dsi_pkt.payload_length;
+
+	return ret;
+}
+
+static const struct mipi_dsi_host_ops gen11_dsi_host_ops = {
+	.attach = gen11_dsi_host_attach,
+	.detach = gen11_dsi_host_detach,
+	.transfer = gen11_dsi_host_transfer,
+};
+
 void icl_dsi_init(struct drm_i915_private *dev_priv)
 {
 	struct drm_device *dev = &dev_priv->drm;
@@ -1068,6 +1204,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 	intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
 	intel_panel_setup_backlight(connector, INVALID_PIPE);
 
+
 	if (dev_priv->vbt.dsi.config->dual_link)
 		intel_dsi->ports = BIT(PORT_A) | BIT(PORT_B);
 	else
@@ -1076,6 +1213,16 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 	intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports;
 	intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports;
 
+	for_each_dsi_port(port, intel_dsi->ports) {
+		struct intel_dsi_host *host;
+
+		host = intel_dsi_host_init(intel_dsi, &gen11_dsi_host_ops, port);
+		if (!host)
+			goto err;
+
+		intel_dsi->dsi_hosts[port] = host;
+	}
+
 	if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID)) {
 		DRM_DEBUG_KMS("no device found\n");
 		goto err;
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#6 lore raw

PATCH v9 4/15 drm/i915/icl: Add get config functionality for DSI

In reply to Jani Nikula

From: Madhav Chauhan <[email protected]>

This patch implements the functionality for getting PIPE configuration to which DSI encoder is connected. Used during the atomic modeset.

---
 drivers/gpu/drm/i915/icl_dsi.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
drivers/gpu/drm/i915/icl_dsi.c +14 -0
index 806b8c323b53..b47e837f4493 100644
@@ -1055,6 +1055,19 @@ static void gen11_dsi_disable(struct intel_encoder *encoder,
 	gen11_dsi_disable_io_power(encoder);
 }
 
+static void gen11_dsi_get_config(struct intel_encoder *encoder,
+				 struct intel_crtc_state *pipe_config)
+{
+	struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
+						   base);
+	u32 pixel_clk;
+
+	//FIXME: Calculate pixel clock using PLL functions once implemented.
+	pixel_clk = intel_dsi->pclk;
+	pipe_config->base.adjusted_mode.crtc_clock = pixel_clk;
+	pipe_config->port_clock = pixel_clk;
+}
+
 static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder)
 {
 	intel_encoder_destroy(encoder);
@@ -1167,6 +1180,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 	encoder->pre_enable = gen11_dsi_pre_enable;
 	encoder->disable = gen11_dsi_disable;
 	encoder->port = port;
+	encoder->get_config = gen11_dsi_get_config;
 	encoder->type = INTEL_OUTPUT_DSI;
 	encoder->cloneable = 0;
 	encoder->crtc_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C);
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#9 lore raw

PATCH v9 5/15 drm/i915/icl: Get HW state for DSI encoder

In reply to Jani Nikula

From: Madhav Chauhan <[email protected]>

This patch read out the current hw state for DSI and return true if encoder is active.

v2 by Jani:
- Squash connector get hw state hook here
- Squash encode get hw state fix here

v3 by Jani:
- Add encoder->get_power_domains() (Imre)

---
 drivers/gpu/drm/i915/icl_dsi.c | 49 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)
drivers/gpu/drm/i915/icl_dsi.c +49 -0
index b47e837f4493..a193f5f3c047 100644
@@ -1068,6 +1068,52 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
 	pipe_config->port_clock = pixel_clk;
 }
 
+static u64 gen11_dsi_get_power_domains(struct intel_encoder *encoder,
+				       struct intel_crtc_state *crtc_state)
+{
+	return BIT_ULL(encoder->power_domain);
+}
+
+static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
+				   enum pipe *pipe)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	u32 tmp;
+	enum port port;
+	enum transcoder dsi_trans;
+	bool ret = false;
+
+	if (!intel_display_power_get_if_enabled(dev_priv,
+						encoder->power_domain))
+		return false;
+
+	for_each_dsi_port(port, intel_dsi->ports) {
+		dsi_trans = dsi_port_to_transcoder(port);
+		tmp = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans));
+		switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
+		case TRANS_DDI_EDP_INPUT_A_ON:
+			*pipe = PIPE_A;
+			break;
+		case TRANS_DDI_EDP_INPUT_B_ONOFF:
+			*pipe = PIPE_B;
+			break;
+		case TRANS_DDI_EDP_INPUT_C_ONOFF:
+			*pipe = PIPE_C;
+			break;
+		default:
+			DRM_ERROR("Invalid PIPE input\n");
+			goto out;
+		}
+
+		tmp = I915_READ(PIPECONF(dsi_trans));
+		ret = tmp & PIPECONF_ENABLE;
+	}
+out:
+	intel_display_power_put(dev_priv, encoder->power_domain);
+	return ret;
+}
+
 static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder)
 {
 	intel_encoder_destroy(encoder);
@@ -1181,10 +1227,12 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 	encoder->disable = gen11_dsi_disable;
 	encoder->port = port;
 	encoder->get_config = gen11_dsi_get_config;
+	encoder->get_hw_state = gen11_dsi_get_hw_state;
 	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;
+	encoder->get_power_domains = gen11_dsi_get_power_domains;
 
 	/* register DSI connector with DRM subsystem */
 	drm_connector_init(dev, connector, &gen11_dsi_connector_funcs,
@@ -1193,6 +1241,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 	connector->interlace_allowed = false;
 	connector->doublescan_allowed = false;
+	intel_connector->get_hw_state = intel_connector_get_hw_state;
 
 	/* attach connector to encoder */
 	intel_connector_attach_encoder(intel_connector, encoder);
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#11 lore raw

PATCH v9 6/15 drm/i915/icl: Add DSI encoder remaining functions

In reply to Jani Nikula

This patch implements compute config for Gen11 DSI encoder which is required at the time of modeset.

v2 by Jani:
- drop the enable nop hook
- fixed_mode is always true
- HAS_GMCH_DISPLAY() is always false

---
 drivers/gpu/drm/i915/icl_dsi.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
drivers/gpu/drm/i915/icl_dsi.c +31 -0
index a193f5f3c047..f1dd243df1db 100644
@@ -1068,6 +1068,37 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
 	pipe_config->port_clock = pixel_clk;
 }
 
+static bool gen11_dsi_compute_config(struct intel_encoder *encoder,
+				     struct intel_crtc_state *pipe_config,
+				     struct drm_connector_state *conn_state)
+{
+	struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
+						   base);
+	struct intel_connector *intel_connector = intel_dsi->attached_connector;
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	const struct drm_display_mode *fixed_mode =
+					intel_connector->panel.fixed_mode;
+	struct drm_display_mode *adjusted_mode =
+					&pipe_config->base.adjusted_mode;
+
+	intel_fixed_panel_mode(fixed_mode, adjusted_mode);
+	intel_pch_panel_fitting(crtc, pipe_config, conn_state->scaling_mode);
+
+	adjusted_mode->flags = 0;
+
+	/* Dual link goes to trancoder DSI'0' */
+	if (intel_dsi->ports == BIT(PORT_B))
+		pipe_config->cpu_transcoder = TRANSCODER_DSI_1;
+	else
+		pipe_config->cpu_transcoder = TRANSCODER_DSI_0;
+
+	pipe_config->clock_set = true;
+
+	//TODO: Add check if DSI PLL calculation is done
+
+	return true;
+}
+
 static u64 gen11_dsi_get_power_domains(struct intel_encoder *encoder,
 				       struct intel_crtc_state *crtc_state)
 {
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#12 lore raw

PATCH v9 7/15 drm/i915/icl: Configure DSI Dual link mode

In reply to Jani Nikula

From: Madhav Chauhan <[email protected]>

This patch configures DSI video mode dual link by
programming DSS_CTL registers.

v2: Use new bitfield definitions from Anusha's patch
Correct register to be programmed and use max depth buffer value (James)

v3 by Jani:
- checkpatch fixes

---
 drivers/gpu/drm/i915/icl_dsi.c | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/icl_dsi.c +41 -1
index f1dd243df1db..e65e888934be 100644
@@ -257,6 +257,45 @@ static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
 	}
 }
 
+static void configure_dual_link_mode(struct intel_encoder *encoder,
+				     const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	u32 dss_ctl1;
+
+	dss_ctl1 = I915_READ(DSS_CTL1);
+	dss_ctl1 |= SPLITTER_ENABLE;
+	dss_ctl1 &= ~OVERLAP_PIXELS_MASK;
+	dss_ctl1 |= OVERLAP_PIXELS(intel_dsi->pixel_overlap);
+
+	if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
+		const struct drm_display_mode *adjusted_mode =
+					&pipe_config->base.adjusted_mode;
+		u32 dss_ctl2;
+		u16 hactive = adjusted_mode->crtc_hdisplay;
+		u16 dl_buffer_depth;
+
+		dss_ctl1 &= ~DUAL_LINK_MODE_INTERLEAVE;
+		dl_buffer_depth = hactive / 2 + intel_dsi->pixel_overlap;
+
+		if (dl_buffer_depth > MAX_DL_BUFFER_TARGET_DEPTH)
+			DRM_ERROR("DL buffer depth exceed max value\n");
+
+		dss_ctl1 &= ~LEFT_DL_BUF_TARGET_DEPTH_MASK;
+		dss_ctl1 |= LEFT_DL_BUF_TARGET_DEPTH(dl_buffer_depth);
+		dss_ctl2 = I915_READ(DSS_CTL2);
+		dss_ctl2 &= ~RIGHT_DL_BUF_TARGET_DEPTH_MASK;
+		dss_ctl2 |= RIGHT_DL_BUF_TARGET_DEPTH(dl_buffer_depth);
+		I915_WRITE(DSS_CTL2, dss_ctl2);
+	} else {
+		/* Interleave */
+		dss_ctl1 |= DUAL_LINK_MODE_INTERLEAVE;
+	}
+
+	I915_WRITE(DSS_CTL1, dss_ctl1);
+}
+
 static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -591,7 +630,8 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
 			I915_WRITE(TRANS_DDI_FUNC_CTL2(dsi_trans), tmp);
 		}
 
-		//TODO: configure DSS_CTL1
+		/* configure stream splitting */
+		configure_dual_link_mode(encoder, pipe_config);
 	}
 
 	for_each_dsi_port(port, intel_dsi->ports) {
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#13 lore raw

PATCH v9 8/15 drm/i915/icl: Consider DSI for getting transcoder state

In reply to Jani Nikula

From: Madhav Chauhan <[email protected]>

For Gen11 DSI, we use similar registers like for eDP to find if DSI encoder is connected or not to a pipe. This patch refactors existing hsw_get_transcoder_state() to handle this.

v2 by Jani:
- Add WARN_ON(dsi && edp) (Ville)

---
 drivers/gpu/drm/i915/intel_display.c | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)
drivers/gpu/drm/i915/intel_display.c +24 -7
index 2d5d034baa91..7337d579cbb6 100644
@@ -9366,6 +9366,8 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	enum intel_display_power_domain power_domain;
 	u32 tmp;
+	bool is_dsi = false;
+	bool is_edp = false;
 
 	/*
 	 * The pipe->transcoder mapping is fixed with the exception of the eDP
@@ -9378,26 +9380,41 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
 	 * consistency and less surprising code; it's in always on power).
 	 */
 	tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
-	if (tmp & TRANS_DDI_FUNC_ENABLE) {
-		enum pipe trans_edp_pipe;
+	if (tmp & TRANS_DDI_FUNC_ENABLE)
+		is_edp = true;
+
+	if (IS_ICELAKE(dev_priv)) {
+		tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_DSI_0));
+		if (tmp & TRANS_DDI_FUNC_ENABLE)
+			is_dsi = true;
+	}
+
+	WARN_ON(is_edp && is_dsi);
+
+	if (is_edp || is_dsi) {
+		enum pipe trans_pipe;
 		switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
 		default:
 			WARN(1, "unknown pipe linked to edp transcoder\n");
 			/* fall through */
 		case TRANS_DDI_EDP_INPUT_A_ONOFF:
 		case TRANS_DDI_EDP_INPUT_A_ON:
-			trans_edp_pipe = PIPE_A;
+			trans_pipe = PIPE_A;
 			break;
 		case TRANS_DDI_EDP_INPUT_B_ONOFF:
-			trans_edp_pipe = PIPE_B;
+			trans_pipe = PIPE_B;
 			break;
 		case TRANS_DDI_EDP_INPUT_C_ONOFF:
-			trans_edp_pipe = PIPE_C;
+			trans_pipe = PIPE_C;
 			break;
 		}
 
-		if (trans_edp_pipe == crtc->pipe)
-			pipe_config->cpu_transcoder = TRANSCODER_EDP;
+		if (trans_pipe == crtc->pipe) {
+			if (is_edp)
+				pipe_config->cpu_transcoder = TRANSCODER_EDP;
+			else if (is_dsi)
+				pipe_config->cpu_transcoder = TRANSCODER_DSI_0;
+		}
 	}
 
 	power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder);
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#15 lore raw

PATCH v9 9/15 drm/i915/icl: Get pipe timings for DSI

In reply to Jani Nikula

From: Madhav Chauhan <[email protected]>

Transcoder timings for Gen11 DSI encoder
is available at pipe level unlike in older platform where port specific registers need to be accessed.

v2 by Jani:
- get timings for (!dsi || icl) instead of (dsi && icl).

---
 drivers/gpu/drm/i915/intel_display.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/intel_display.c +2 -1
index 7337d579cbb6..9137675283d1 100644
@@ -9549,7 +9549,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 	if (!active)
 		goto out;
 
-	if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
+	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
+	    IS_ICELAKE(dev_priv)) {
 		haswell_get_ddi_port_state(crtc, pipe_config);
 		intel_get_pipe_timings(crtc, pipe_config);
 	}
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#17 lore raw

PATCH v9 10/15 drm/i915/icl: Define missing bitfield for shortplug reg

In reply to Jani Nikula

From: Madhav Chauhan <[email protected]>

This patch define missing bitfield for shortplug ctl ddi register which will be used for ICL DSI GPIO programming.

---
 drivers/gpu/drm/i915/i915_reg.h | 1 +
 1 file changed, 1 insertion(+)
drivers/gpu/drm/i915/i915_reg.h +1 -0
index 6c7df179da28..9d58a9ff4f76 100644
@@ -7686,6 +7686,7 @@ enum {
 #define   ICP_DDIB_HPD_LONG_DETECT		(2 << 4)
 #define   ICP_DDIB_HPD_SHORT_LONG_DETECT	(3 << 4)
 #define   ICP_DDIA_HPD_ENABLE			(1 << 3)
+#define   ICP_DDIA_HPD_OP_DRIVE_1		(1 << 2)
 #define   ICP_DDIA_HPD_STATUS_MASK		(3 << 0)
 #define   ICP_DDIA_HPD_NO_DETECT		(0 << 0)
 #define   ICP_DDIA_HPD_SHORT_DETECT		(1 << 0)
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#18 lore raw

PATCH v9 11/15 drm/i915/icl: Define Panel power ctrl register

In reply to Jani Nikula

From: Madhav Chauhan <[email protected]>

There are two panel power sequencers. Each register has two addressable instances. This patch defines both the instances of Panel power control register

---
 drivers/gpu/drm/i915/i915_reg.h | 11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/gpu/drm/i915/i915_reg.h +11 -0
index 9d58a9ff4f76..dbd8eef8aa8c 100644
@@ -4596,6 +4596,17 @@ enum {
 #define _PP_STATUS			0x61200
 #define PP_STATUS(pps_idx)		_MMIO_PPS(pps_idx, _PP_STATUS)
 #define   PP_ON				(1 << 31)
+
+#define _PP_CONTROL_1			0xc7204
+#define _PP_CONTROL_2			0xc7304
+#define ICP_PP_CONTROL(x)		_MMIO(((x) == 1) ? _PP_CONTROL_1 : \
+					      _PP_CONTROL_2)
+#define  POWER_CYCLE_DELAY_MASK	(0x1f << 4)
+#define  POWER_CYCLE_DELAY_SHIFT	4
+#define  VDD_OVERRIDE_FORCE		(1 << 3)
+#define  BACKLIGHT_ENABLE		(1 << 2)
+#define  PWR_DOWN_ON_RESET		(1 << 1)
+#define  PWR_STATE_TARGET		(1 << 0)
 /*
  * Indicates that all dependencies of the panel are on:
  *
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#19 lore raw

PATCH v9 12/15 drm/i915/icl: Define display GPIO pins for DSI

In reply to Jani Nikula

From: Madhav Chauhan <[email protected]>

Display Pins are the only GPIOs that need to be used by driver for DSI panels. So driver should now have its own implementation to toggle these pins based on GPIO info received from VBT sequences.

---
 drivers/gpu/drm/i915/intel_dsi_vbt.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/gpu/drm/i915/intel_dsi_vbt.c +12 -0
index a72de81f4832..b41ca6436401 100644
@@ -103,6 +103,18 @@ static struct gpio_map vlv_gpio_table[] = {
 #define CHV_GPIO_PAD_CFG1(f, i)		(0x4400 + (f) * 0x400 + (i) * 8 + 4)
 #define  CHV_GPIO_CFGLOCK		(1 << 31)
 
+/* ICL DSI Display GPIO Pins */
+#define  ICL_GPIO_DDSP_HPD_A		0
+#define  ICL_GPIO_L_VDDEN_1		1
+#define  ICL_GPIO_L_BKLTEN_1		2
+#define  ICL_GPIO_DDPA_CTRLCLK_1	3
+#define  ICL_GPIO_DDPA_CTRLDATA_1	4
+#define  ICL_GPIO_DDSP_HPD_B		5
+#define  ICL_GPIO_L_VDDEN_2		6
+#define  ICL_GPIO_L_BKLTEN_2		7
+#define  ICL_GPIO_DDPA_CTRLCLK_2	8
+#define  ICL_GPIO_DDPA_CTRLDATA_2	9
+
 static inline enum port intel_dsi_seq_port_to_port(u8 port)
 {
 	return port ? PORT_C : PORT_A;
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#20 lore raw

PATCH v9 13/15 drm/i915/icl: add dummy DSI GPIO element execution function

In reply to Jani Nikula

Add dummy debug logging GPIO element execution function for ICL.

---
 drivers/gpu/drm/i915/intel_dsi_vbt.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/intel_dsi_vbt.c +9 -1
index b41ca6436401..a1a8b3790e61 100644
@@ -336,6 +336,12 @@ static void bxt_exec_gpio(struct drm_i915_private *dev_priv,
 	gpiod_set_value(gpio_desc, value);
 }
 
+static void icl_exec_gpio(struct drm_i915_private *dev_priv,
+			  u8 gpio_source, u8 gpio_index, bool value)
+{
+	DRM_DEBUG_KMS("Skipping ICL GPIO element execution\n");
+}
+
 static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
 {
 	struct drm_device *dev = intel_dsi->base.base.dev;
@@ -359,7 +365,9 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
 	/* pull up/down */
 	value = *data++ & 1;
 
-	if (IS_VALLEYVIEW(dev_priv))
+	if (IS_ICELAKE(dev_priv))
+		icl_exec_gpio(dev_priv, gpio_source, gpio_index, value);
+	else if (IS_VALLEYVIEW(dev_priv))
 		vlv_exec_gpio(dev_priv, gpio_source, gpio_number, value);
 	else if (IS_CHERRYVIEW(dev_priv))
 		chv_exec_gpio(dev_priv, gpio_source, gpio_number, value);
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#21 lore raw

PATCH v9 14/15 HACK: drm/i915/icl: Add changes to program DSI panel GPIOs

In reply to Jani Nikula

For ICELAKE DSI, Display Pins are the only GPIOs that need to be programmed. So DSI driver should have its own implementation to toggle these pins based on GPIO info coming from VBT sequences instead of using platform specific GPIO driver.

---
 drivers/gpu/drm/i915/intel_dsi_vbt.c | 38 +++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/intel_dsi_vbt.c +37 -1
index a1a8b3790e61..e6686dbdf462 100644
@@ -339,7 +339,43 @@ static void bxt_exec_gpio(struct drm_i915_private *dev_priv,
 static void icl_exec_gpio(struct drm_i915_private *dev_priv,
 			  u8 gpio_source, u8 gpio_index, bool value)
 {
-	DRM_DEBUG_KMS("Skipping ICL GPIO element execution\n");
+	u32 val;
+
+	switch (gpio_index) {
+	case ICL_GPIO_DDSP_HPD_A:
+		val = I915_READ(SHOTPLUG_CTL_DDI);
+		val &= ~ICP_DDIA_HPD_ENABLE;
+		I915_WRITE(SHOTPLUG_CTL_DDI, val);
+		val = I915_READ(SHOTPLUG_CTL_DDI);
+
+		if (value)
+			val |= ICP_DDIA_HPD_OP_DRIVE_1;
+		else
+			val &= ~ICP_DDIA_HPD_OP_DRIVE_1;
+
+		I915_WRITE(SHOTPLUG_CTL_DDI, val);
+		break;
+	case ICL_GPIO_L_VDDEN_1:
+		val = I915_READ(ICP_PP_CONTROL(1));
+		if (value)
+			val |= PWR_STATE_TARGET;
+		else
+			val &= ~PWR_STATE_TARGET;
+		I915_WRITE(ICP_PP_CONTROL(1), val);
+		break;
+	case ICL_GPIO_L_BKLTEN_1:
+		val = I915_READ(ICP_PP_CONTROL(1));
+		if (value)
+			val |= BACKLIGHT_ENABLE;
+		else
+			val &= ~BACKLIGHT_ENABLE;
+		I915_WRITE(ICP_PP_CONTROL(1), val);
+		break;
+	default:
+		/* TODO: Add support for remaining GPIOs */
+		DRM_ERROR("Invalid GPIO no from VBT\n");
+		break;
+	}
 }
 
 static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#22 lore raw

PATCH v9 15/15 HACK: drm/i915/icl: Configure backlight functions for DSI

In reply to Jani Nikula

From: Madhav Chauhan <[email protected]>

Gen11 DSI doesn't use DCS commands based functionality for enabling/disabling backlight but uses PWM based functions similar to eDP.

Note by Jani: This should be decided by VBT, not hard coded. DCS brightness control is still a thing.

---
 drivers/gpu/drm/i915/intel_panel.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/intel_panel.c +2 -1
index e6cd7b55c018..b6df63aa11e3 100644
@@ -1835,7 +1835,8 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
 	    intel_dp_aux_init_backlight_funcs(connector) == 0)
 		return;
 
-	if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI &&
+	if (IS_GEN9_LP(dev_priv) &&
+	    connector->base.connector_type == DRM_MODE_CONNECTOR_DSI &&
 	    intel_dsi_dcs_init_backlight_funcs(connector) == 0)
 		return;
 
Signature · 6 lines
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#23 lore raw
In reply to Jani Nikula
Quoted 6 lines · Jani Nikula

Next version of [1]. Still needs the DSI PLL stuff Vandita covers.

BR,
Jani.

Quoted 8 lines

[1] https://patchwork.freedesktop.org/series/51011/

Jani Nikula (5):
drm/i915/icl: Fill DSI ports info
drm/i915/icl: Allocate DSI hosts and imlement host transfer drm/i915/icl: Add DSI encoder remaining functions drm/i915/icl: add dummy DSI GPIO element execution function
HACK: drm/i915/icl: Add changes to program DSI panel GPIOs

Argh, I did it again. All except the dummy GPIO thing are by Madhav.

Quoted 19 lines

Madhav Chauhan (10):
drm/i915/icl: Allocate DSI encoder/connector drm/i915/icl: Add get config functionality for DSI drm/i915/icl: Get HW state for DSI encoder drm/i915/icl: Configure DSI Dual link mode drm/i915/icl: Consider DSI for getting transcoder state drm/i915/icl: Get pipe timings for DSI drm/i915/icl: Define missing bitfield for shortplug reg drm/i915/icl: Define Panel power ctrl register drm/i915/icl: Define display GPIO pins for DSI
HACK: drm/i915/icl: Configure backlight functions for DSI

 drivers/gpu/drm/i915/i915_reg.h      |  12 ++
 drivers/gpu/drm/i915/icl_dsi.c       | 408 ++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_display.c |  34 ++-
 drivers/gpu/drm/i915/intel_dsi_vbt.c |  58 ++++-
 drivers/gpu/drm/i915/intel_panel.c   |   3 +-
 5 files changed, 496 insertions(+), 19 deletions(-)
Signature · 5 lines
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#24 lore raw

✗ Fi.CI.BAT: failure for drm/i915/icl: dsi enabling (rev4)

In reply to Jani Nikula
== Series Details ==

== Series Details ==

Series: drm/i915/icl: dsi enabling (rev4)
URL : https://patchwork.freedesktop.org/series/51011/
State : failure

== Summary ==

CALL scripts/checksyscalls.sh
DESCEND objtool
CHK include/generated/compile.h
CC [M] drivers/gpu/drm/i915/icl_dsi.o
drivers/gpu/drm/i915/icl_dsi.c:1111:13: error: ‘gen11_dsi_compute_config’ defined but not used [-Werror=unused-function]
static bool gen11_dsi_compute_config(struct intel_encoder *encoder,

             ^~~~~~~~~~~~~~~~~~~~~~~~

cc1: all warnings being treated as errors
scripts/Makefile.build:305: recipe for target 'drivers/gpu/drm/i915/icl_dsi.o' failed make[4]: *** [drivers/gpu/drm/i915/icl_dsi.o] Error 1 scripts/Makefile.build:546: recipe for target 'drivers/gpu/drm/i915' failed make[3]: *** [drivers/gpu/drm/i915] Error 2
scripts/Makefile.build:546: recipe for target 'drivers/gpu/drm' failed make[2]: *** [drivers/gpu/drm] Error 2
scripts/Makefile.build:546: recipe for target 'drivers/gpu' failed make[1]: *** [drivers/gpu] Error 2
Makefile:1052: recipe for target 'drivers' failed
make: *** [drivers] Error 2

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

#10 lore raw

Re: [PATCH v9 05/15] drm/i915/icl: Get HW state for DSI encoder

In reply to Jani Nikula
Quoted 24 lines · Jani Nikula

From: Madhav Chauhan <[email protected]>

This patch read out the current hw state for DSI and return true if encoder is active.

v2 by Jani:
- Squash connector get hw state hook here
- Squash encode get hw state fix here

v3 by Jani:
- Add encoder->get_power_domains() (Imre)

---
 drivers/gpu/drm/i915/icl_dsi.c | 49 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)
drivers/gpu/drm/i915/icl_dsi.c +0 -0
index b47e837f4493..a193f5f3c047 100644

drivers/gpu/drm/i915/icl_dsi.c static void gen11_dsi_get_config(struct intel_encoder *encoder, · line 1074

Quoted 7 lines
drivers/gpu/drm/i915/icl_dsi.c +4 -0
@@ -1068,6 +1068,52 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
 	pipe_config->port_clock = pixel_clk;
 }
 
+static u64 gen11_dsi_get_power_domains(struct intel_encoder *encoder,
+				       struct intel_crtc_state *crtc_state)
+{
+	return BIT_ULL(encoder->power_domain);

We have two set of power wells for encoders:

- One domain that can be enabled before any of the encoder's enable hooks are called, which is set in encoder->power_domain. These are get/put already properly by the readout/modeset code in modeset_get_crtc_power_domains().

- Another set which must be enabled in a specific spot during the encoder enabling. These can't be enabled along with encoder->power_domain, but are get/put individually in the encoder enable/disable hooks. This is the set encoder->get_power_domains() needs to return. AFAICS for DSI these are then

domains = 0;
for_each_dsi_port(port, intel_dsi->ports)

           domains |= port == PORT_A ? POWER_DOMAIN_PORT_DDI_A_IO :
                                       POWER_DOMAIN_PORT_DDI_B_IO;
Quoted 69 lines
drivers/gpu/drm/i915/icl_dsi.c +45 -0
+}
+
+static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
+				   enum pipe *pipe)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	u32 tmp;
+	enum port port;
+	enum transcoder dsi_trans;
+	bool ret = false;
+
+	if (!intel_display_power_get_if_enabled(dev_priv,
+						encoder->power_domain))
+		return false;
+
+	for_each_dsi_port(port, intel_dsi->ports) {
+		dsi_trans = dsi_port_to_transcoder(port);
+		tmp = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans));
+		switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
+		case TRANS_DDI_EDP_INPUT_A_ON:
+			*pipe = PIPE_A;
+			break;
+		case TRANS_DDI_EDP_INPUT_B_ONOFF:
+			*pipe = PIPE_B;
+			break;
+		case TRANS_DDI_EDP_INPUT_C_ONOFF:
+			*pipe = PIPE_C;
+			break;
+		default:
+			DRM_ERROR("Invalid PIPE input\n");
+			goto out;
+		}
+
+		tmp = I915_READ(PIPECONF(dsi_trans));
+		ret = tmp & PIPECONF_ENABLE;
+	}
+out:
+	intel_display_power_put(dev_priv, encoder->power_domain);
+	return ret;
+}
+
 static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder)
 {
 	intel_encoder_destroy(encoder);
@@ -1181,10 +1227,12 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 	encoder->disable = gen11_dsi_disable;
 	encoder->port = port;
 	encoder->get_config = gen11_dsi_get_config;
+	encoder->get_hw_state = gen11_dsi_get_hw_state;
 	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;
+	encoder->get_power_domains = gen11_dsi_get_power_domains;
 
 	/* register DSI connector with DRM subsystem */
 	drm_connector_init(dev, connector, &gen11_dsi_connector_funcs,
@@ -1193,6 +1241,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 	connector->interlace_allowed = false;
 	connector->doublescan_allowed = false;
+	intel_connector->get_hw_state = intel_connector_get_hw_state;
 
 	/* attach connector to encoder */
 	intel_connector_attach_encoder(intel_connector, encoder);
Signature · 1 line
2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

#7 lore raw

Re: [PATCH v9 04/15] drm/i915/icl: Add get config functionality for DSI

In reply to Jani Nikula
Quoted 30 lines

-----Original Message-----
From: Nikula, Jani
Sent: Thursday, November 1, 2018 9:04 PM
To: [email protected]
Cc: Chauhan, Madhav <[email protected]>; [email protected]; Kulkarni, Vandita <[email protected]>; Lisovskiy, Stanislav <[email protected]>; Nikula, Jani <[email protected]>
Subject: [PATCH v9 04/15] drm/i915/icl: Add get config functionality for DSI

From: Madhav Chauhan <[email protected]>

This patch implements the functionality for getting PIPE configuration to which DSI encoder is connected. Used during the atomic modeset.

---
 drivers/gpu/drm/i915/icl_dsi.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
drivers/gpu/drm/i915/icl_dsi.c index renamed from drivers/gpu/drm/i915/icl_dsi.c +0 -0

806b8c323b53..b47e837f4493 100644

drivers/gpu/drm/i915/icl_dsi.c +0 -0
@@ -1055,6 +1055,19 @@ static void gen11_dsi_disable(struct intel_encoder
 *encoder,
 	gen11_dsi_disable_io_power(encoder);
 }
 

drivers/gpu/drm/i915/icl_dsi.c static void gen11_dsi_disable(struct intel_encoder · line 1068

Quoted 10 lines
drivers/gpu/drm/i915/icl_dsi.c +10 -0
+static void gen11_dsi_get_config(struct intel_encoder *encoder,
+				 struct intel_crtc_state *pipe_config) {
+	struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
+						   base);
+	u32 pixel_clk;
+
+	//FIXME: Calculate pixel clock using PLL functions once implemented.
+	pixel_clk = intel_dsi->pclk;
+	pipe_config->base.adjusted_mode.crtc_clock = pixel_clk;
+	pipe_config->port_clock = pixel_clk;

Is this Ok for now, or should I continue on the lines that Ville suggested?

Thanks,
Vandita

Quoted 13 lines
drivers/gpu/drm/i915/icl_dsi.c +3 -1
+}
+
 static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder)  {
 	intel_encoder_destroy(encoder);
@@ -1167,6 +1180,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 	encoder->pre_enable = gen11_dsi_pre_enable;
 	encoder->disable = gen11_dsi_disable;
 	encoder->port = port;
+	encoder->get_config = gen11_dsi_get_config;
 	encoder->type = INTEL_OUTPUT_DSI;
 	encoder->cloneable = 0;
 	encoder->crtc_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C);
--
Quoted 1 line

2.11.0

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

#2 lore raw

Re: [PATCH v9 01/15] drm/i915/icl: Allocate DSI encoder/connector

In reply to Jani Nikula
Quoted 13 lines · Jani Nikula

From: Madhav Chauhan <[email protected]>

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

Quoted 3 lines

v3 by Jani:
- Squash connector and connector helper functions here
- Move intel_dsi_vbt_init call here

Ok.

Regards,
Madhav

Quoted 150 lines
---
  drivers/gpu/drm/i915/icl_dsi.c | 117 ++++++++++++++++++++++++++++++++++++++---
  1 file changed, 109 insertions(+), 8 deletions(-)
drivers/gpu/drm/i915/icl_dsi.c +100 -8
index 01f422df8c23..a40083a7eb6a 100644
@@ -26,6 +26,7 @@
   */
 
  #include <drm/drm_mipi_dsi.h>
+#include <drm/drm_atomic_helper.h>
  #include "intel_dsi.h"
 
  static inline int header_credits_available(struct drm_i915_private *dev_priv,
@@ -799,10 +800,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 +945,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 +971,112 @@ 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 = {
+	.late_register = intel_connector_register,
+	.early_unregister = intel_connector_unregister,
+	.destroy = intel_connector_destroy,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.atomic_get_property = intel_digital_connector_atomic_get_property,
+	.atomic_set_property = intel_digital_connector_atomic_set_property,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = intel_digital_connector_duplicate_state,
+};
+
+static const struct drm_connector_helper_funcs gen11_dsi_connector_helper_funcs = {
+	.get_modes = intel_dsi_get_modes,
+	.mode_valid = intel_dsi_mode_valid,
+	.atomic_check = intel_digital_connector_atomic_check,
+};
+
  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);
+	drm_connector_helper_add(connector, &gen11_dsi_connector_helper_funcs);
+	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);
+
+	if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID)) {
+		DRM_DEBUG_KMS("no device found\n");

drivers/gpu/drm/i915/icl_dsi.c static void __attribute__((unused)) gen11_dsi_disable( · line 1082

Quoted 10 lines
drivers/gpu/drm/i915/icl_dsi.c +9 -0
+		goto err;
+	}
+
+	return;
+
+err:
+	drm_encoder_cleanup(&encoder->base);
+	kfree(intel_dsi);
+	kfree(intel_connector);
  }

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

#5 lore raw

Re: [PATCH v9 03/15] drm/i915/icl: Allocate DSI hosts and imlement host transfer

In reply to Jani Nikula
Quoted 17 lines · Jani Nikula

Allocate DSI host structure for each DSI port available on gen11 and register them with DSI fwk of DRM. Some of the DSI host operations are also registered as part of this.

Retrieves DSI pkt (from DSI msg) to be sent over DSI link using DRM DSI exported functions. A wrapper function is also added as "DSI host transfer" for sending DSI data/cmd. Add DSI packet payload to command payload queue using credit based mechanism for *long* packets.

v2 by Jani:
- indentation
- Use the new credit available helper
- Use int for free_credits
- Add intel_dsi local variable for better code flow
- Use the new credit available helper
- Use int for free_credits, i, and j

Quoted 2 lines

v3 by Jani:
- Squash DSI host allocation and transfer patches together

Ok.
Patch becomes very big, created them as separate logical patch to debug any issue if comes in header and payload functionality :).

Regards,
Madhav

Quoted 176 lines
---
  drivers/gpu/drm/i915/icl_dsi.c | 147 +++++++++++++++++++++++++++++++++++++++++
  1 file changed, 147 insertions(+)
drivers/gpu/drm/i915/icl_dsi.c +140 -0
index fe408ff77924..806b8c323b53 100644
@@ -108,6 +108,90 @@ static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder)
  	}
  }
 
+static bool add_payld_to_queue(struct intel_dsi_host *host, const u8 *data,
+			       u32 len)
+{
+	struct intel_dsi *intel_dsi = host->intel_dsi;
+	struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
+	enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
+	int free_credits;
+	int i, j;
+
+	for (i = 0; i < len; i += 4) {
+		u32 tmp = 0;
+
+		free_credits = payload_credits_available(dev_priv, dsi_trans);
+		if (free_credits < 1) {
+			DRM_ERROR("Payload credit not available\n");
+			return false;
+		}
+
+		for (j = 0; j < min_t(u32, len - i, 4); j++)
+			tmp |= *data++ << 8 * j;
+
+		I915_WRITE(DSI_CMD_TXPYLD(dsi_trans), tmp);
+	}
+
+	return true;
+}
+
+static int dsi_send_pkt_hdr(struct intel_dsi_host *host,
+			    struct mipi_dsi_packet pkt, bool enable_lpdt)
+{
+	struct intel_dsi *intel_dsi = host->intel_dsi;
+	struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
+	enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
+	u32 tmp;
+	int free_credits;
+
+	/* check if header credit available */
+	free_credits = header_credits_available(dev_priv, dsi_trans);
+	if (free_credits < 1) {
+		DRM_ERROR("send pkt header failed, not enough hdr credits\n");
+		return -1;
+	}
+
+	tmp = I915_READ(DSI_CMD_TXHDR(dsi_trans));
+
+	if (pkt.payload)
+		tmp |= PAYLOAD_PRESENT;
+	else
+		tmp &= ~PAYLOAD_PRESENT;
+
+	tmp &= ~VBLANK_FENCE;
+
+	if (enable_lpdt)
+		tmp |= LP_DATA_TRANSFER;
+
+	tmp &= ~(PARAM_WC_MASK | VC_MASK | DT_MASK);
+	tmp |= ((pkt.header[0] & VC_MASK) << VC_SHIFT);
+	tmp |= ((pkt.header[0] & DT_MASK) << DT_SHIFT);
+	tmp |= (pkt.header[1] << PARAM_WC_LOWER_SHIFT);
+	tmp |= (pkt.header[2] << PARAM_WC_UPPER_SHIFT);
+	I915_WRITE(DSI_CMD_TXHDR(dsi_trans), tmp);
+
+	return 0;
+}
+
+static int dsi_send_pkt_payld(struct intel_dsi_host *host,
+			      struct mipi_dsi_packet pkt)
+{
+	/* payload queue can accept *256 bytes*, check limit */
+	if (pkt.payload_length > MAX_PLOAD_CREDIT * 4) {
+		DRM_ERROR("payload size exceeds max queue limit\n");
+		return -1;
+	}
+
+	/* load data into command payload queue */
+	if (!add_payld_to_queue(host, pkt.payload,
+				pkt.payload_length)) {
+		DRM_ERROR("adding payload to queue failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
  static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
  {
  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -997,6 +1081,58 @@ static const struct drm_connector_helper_funcs gen11_dsi_connector_helper_funcs
  	.atomic_check = intel_digital_connector_atomic_check,
  };
 
+static int gen11_dsi_host_attach(struct mipi_dsi_host *host,
+				 struct mipi_dsi_device *dsi)
+{
+	return 0;
+}
+
+static int gen11_dsi_host_detach(struct mipi_dsi_host *host,
+				 struct mipi_dsi_device *dsi)
+{
+	return 0;
+}
+
+static ssize_t gen11_dsi_host_transfer(struct mipi_dsi_host *host,
+				       const struct mipi_dsi_msg *msg)
+{
+	struct intel_dsi_host *intel_dsi_host = to_intel_dsi_host(host);
+	struct mipi_dsi_packet dsi_pkt;
+	ssize_t ret;
+	bool enable_lpdt = false;
+
+	ret = mipi_dsi_create_packet(&dsi_pkt, msg);
+	if (ret < 0)
+		return ret;
+
+	if (msg->flags & MIPI_DSI_MSG_USE_LPM)
+		enable_lpdt = true;
+
+	/* send packet header */
+	ret  = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt);
+	if (ret < 0)
+		return ret;
+
+	/* only long packet contains payload */
+	if (mipi_dsi_packet_format_is_long(msg->type)) {
+		ret = dsi_send_pkt_payld(intel_dsi_host, dsi_pkt);
+		if (ret < 0)
+			return ret;
+	}
+
+	//TODO: add payload receive code if needed
+
+	ret = sizeof(dsi_pkt.header) + dsi_pkt.payload_length;
+
+	return ret;
+}
+
+static const struct mipi_dsi_host_ops gen11_dsi_host_ops = {
+	.attach = gen11_dsi_host_attach,
+	.detach = gen11_dsi_host_detach,
+	.transfer = gen11_dsi_host_transfer,
+};
+
  void icl_dsi_init(struct drm_i915_private *dev_priv)
  {
  	struct drm_device *dev = &dev_priv->drm;
@@ -1068,6 +1204,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
  	intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
  	intel_panel_setup_backlight(connector, INVALID_PIPE);
 
+
  	if (dev_priv->vbt.dsi.config->dual_link)
  		intel_dsi->ports = BIT(PORT_A) | BIT(PORT_B);
  	else
@@ -1076,6 +1213,16 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
  	intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports;
  	intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports;
 
+	for_each_dsi_port(port, intel_dsi->ports) {
+		struct intel_dsi_host *host;
+

drivers/gpu/drm/i915/icl_dsi.c void icl_dsi_init(struct drm_i915_private *dev_priv) · line 1228

Quoted 10 lines
drivers/gpu/drm/i915/icl_dsi.c +7 -0
+		host = intel_dsi_host_init(intel_dsi, &gen11_dsi_host_ops, port);
+		if (!host)
+			goto err;
+
+		intel_dsi->dsi_hosts[port] = host;
+	}
+
  	if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID)) {
  		DRM_DEBUG_KMS("no device found\n");
  		goto err;

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

#14 lore raw

Re: [PATCH v9 08/15] drm/i915/icl: Consider DSI for getting transcoder state

In reply to Jani Nikula
Quoted 9 lines · Jani Nikula

From: Madhav Chauhan <[email protected]>

For Gen11 DSI, we use similar registers like for eDP to find if DSI encoder is connected or not to a pipe. This patch refactors existing hsw_get_transcoder_state() to handle this.

v2 by Jani:
- Add WARN_ON(dsi && edp) (Ville)

v2 changes looks fine to me.

Regards,
Madhav

Quoted 59 lines
---
  drivers/gpu/drm/i915/intel_display.c | 31 ++++++++++++++++++++++++-------
  1 file changed, 24 insertions(+), 7 deletions(-)
drivers/gpu/drm/i915/intel_display.c +18 -6
index 2d5d034baa91..7337d579cbb6 100644
@@ -9366,6 +9366,8 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
  	struct drm_i915_private *dev_priv = to_i915(dev);
  	enum intel_display_power_domain power_domain;
  	u32 tmp;
+	bool is_dsi = false;
+	bool is_edp = false;
 
  	/*
  	 * The pipe->transcoder mapping is fixed with the exception of the eDP
@@ -9378,26 +9380,41 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
  	 * consistency and less surprising code; it's in always on power).
  	 */
  	tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
-	if (tmp & TRANS_DDI_FUNC_ENABLE) {
-		enum pipe trans_edp_pipe;
+	if (tmp & TRANS_DDI_FUNC_ENABLE)
+		is_edp = true;
+
+	if (IS_ICELAKE(dev_priv)) {
+		tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_DSI_0));
+		if (tmp & TRANS_DDI_FUNC_ENABLE)
+			is_dsi = true;
+	}
+
+	WARN_ON(is_edp && is_dsi);
+
+	if (is_edp || is_dsi) {
+		enum pipe trans_pipe;
  		switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
  		default:
  			WARN(1, "unknown pipe linked to edp transcoder\n");
  			/* fall through */
  		case TRANS_DDI_EDP_INPUT_A_ONOFF:
  		case TRANS_DDI_EDP_INPUT_A_ON:
-			trans_edp_pipe = PIPE_A;
+			trans_pipe = PIPE_A;
  			break;
  		case TRANS_DDI_EDP_INPUT_B_ONOFF:
-			trans_edp_pipe = PIPE_B;
+			trans_pipe = PIPE_B;
  			break;
  		case TRANS_DDI_EDP_INPUT_C_ONOFF:
-			trans_edp_pipe = PIPE_C;
+			trans_pipe = PIPE_C;
  			break;
  		}
 
-		if (trans_edp_pipe == crtc->pipe)

drivers/gpu/drm/i915/intel_display.c static bool hsw_get_transcoder_state(struct intel_crtc *crtc, · line 9420

Quoted 10 lines
drivers/gpu/drm/i915/intel_display.c +6 -1
-			pipe_config->cpu_transcoder = TRANSCODER_EDP;
+		if (trans_pipe == crtc->pipe) {
+			if (is_edp)
+				pipe_config->cpu_transcoder = TRANSCODER_EDP;
+			else if (is_dsi)
+				pipe_config->cpu_transcoder = TRANSCODER_DSI_0;
+		}
  	}
 
  	power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder);

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

#16 lore raw

Re: [PATCH v9 09/15] drm/i915/icl: Get pipe timings for DSI

In reply to Jani Nikula
Quoted 8 lines · Jani Nikula

From: Madhav Chauhan <[email protected]>

Transcoder timings for Gen11 DSI encoder
is available at pipe level unlike in older platform where port specific registers need to be accessed.

v2 by Jani:
- get timings for (!dsi || icl) instead of (dsi && icl).

Looks ok.

Regards,
Madhav

Quoted 12 lines
---
  drivers/gpu/drm/i915/intel_display.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/intel_display.c +0 -0
index 7337d579cbb6..9137675283d1 100644

drivers/gpu/drm/i915/intel_display.c static bool haswell_get_pipe_config(struct intel_crtc *crtc, · line 9556

Quoted 9 lines
drivers/gpu/drm/i915/intel_display.c +2 -1
@@ -9549,7 +9549,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
  	if (!active)
  		goto out;
 
-	if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
+	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
+	    IS_ICELAKE(dev_priv)) {
  		haswell_get_ddi_port_state(crtc, pipe_config);
  		intel_get_pipe_timings(crtc, pipe_config);
  	}

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

#8 lore raw

Re: [PATCH v9 04/15] drm/i915/icl: Add get config functionality for DSI

In reply to Kulkarni, Vandita
Quoted 30 lines · Vandita
Quoted 30 lines

-----Original Message-----
From: Nikula, Jani
Sent: Thursday, November 1, 2018 9:04 PM
To: [email protected]
Cc: Chauhan, Madhav <[email protected]>; [email protected]; Kulkarni, Vandita <[email protected]>; Lisovskiy, Stanislav <[email protected]>; Nikula, Jani <[email protected]>
Subject: [PATCH v9 04/15] drm/i915/icl: Add get config functionality for DSI

From: Madhav Chauhan <[email protected]>

This patch implements the functionality for getting PIPE configuration to which DSI encoder is connected. Used during the atomic modeset.

---
 drivers/gpu/drm/i915/icl_dsi.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
drivers/gpu/drm/i915/icl_dsi.c index renamed from drivers/gpu/drm/i915/icl_dsi.c +0 -0

806b8c323b53..b47e837f4493 100644

drivers/gpu/drm/i915/icl_dsi.c +0 -0
@@ -1055,6 +1055,19 @@ static void gen11_dsi_disable(struct intel_encoder
 *encoder,
 	gen11_dsi_disable_io_power(encoder);
 }
 
Quoted 11 lines

drivers/gpu/drm/i915/icl_dsi.c static void gen11_dsi_disable(struct intel_encoder *encoder, · line 1068

Quoted 10 lines
drivers/gpu/drm/i915/icl_dsi.c +10 -0
+static void gen11_dsi_get_config(struct intel_encoder *encoder,
+				 struct intel_crtc_state *pipe_config) {
+	struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
+						   base);
+	u32 pixel_clk;
+
+	//FIXME: Calculate pixel clock using PLL functions once implemented.
+	pixel_clk = intel_dsi->pclk;
+	pipe_config->base.adjusted_mode.crtc_clock = pixel_clk;
+	pipe_config->port_clock = pixel_clk;

Is this Ok for now, or should I continue on the lines that Ville suggested?

This is pretty much a hack, we need your changes here.

BR,
Jani.

Quoted 18 lines

Thanks,
Vandita

Quoted 14 lines
drivers/gpu/drm/i915/icl_dsi.c +3 -1
+}
+
 static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder)  {
 	intel_encoder_destroy(encoder);
@@ -1167,6 +1180,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 	encoder->pre_enable = gen11_dsi_pre_enable;
 	encoder->disable = gen11_dsi_disable;
 	encoder->port = port;
+	encoder->get_config = gen11_dsi_get_config;
 	encoder->type = INTEL_OUTPUT_DSI;
 	encoder->cloneable = 0;
 	encoder->crtc_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C);
--

2.11.0

Signature · 5 lines
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx