Skip to contentSkip to conversation

drm: bridge: Samsung MIPI DSIM bridge

RFC PATCH In review Jagan Teki 12 participants 48 messages Jul 4, 2021 – Dec 15, 2021

Subsystems (8)
lore
Share & tools
lore

Jagan Teki

author maintainer
#0 lore raw

cover drm: bridge: Samsung MIPI DSIM bridge

This series supports common bridge support for Samsung MIPI DSIM which is used in Exynos and i.MX8MM SoC's.

The final bridge supports both the Exynos and i.MX8MM DSI devices.

Right now bridge offers two sets of implementations.

A. With component_ops and exynos specific code exclusively for exynos dsi drivers and it's legacy bindings.

B. Without componenet_ops for newly implemented bridges and its users like i.MX8MM.

The future plan is to fix the implementation A) by dropping component_ops and fixing exynos specific code in order to make the bridge more mature to use and the same is mentioned in drivers TODO.

Patch 0001 - 0006: Bridge conversion
Patch 0007 - 0017: Samsung MIPI DSIM bridge fixes, additions

Tested in Engicam i.Core MX8M Mini SoM.

Anyone interest, please have a look on this repo
https://github.com/openedev/linux/tree/070421-imx8mm-dsim

Would appreciate anyone from the exynos team to test it on the exynos platform?

Any inputs?
Jagan.

Jagan Teki (17):
drm/exynos: dsi: Convert to bridge driver
drm/exynos: dsi: Handle drm_device for bridge
drm/exynos: dsi: Use the drm_panel_bridge API
drm/exynos: dsi: Create bridge connector for encoder drm/exynos: dsi: Get the mode from bridge
drm/exynos: dsi: Handle exynos specifics via driver_data
drm: bridge: Move exynos_drm_dsi into bridges
dt-bindings: display: bridge: Add Samsung MIPI DSIM bridge
drm: bridge: samsung-dsim: Add module init, exit
drm: bridge: samsung-dsim: Update the of_node for port(s)
drm: bridge: samsung-dsim: Find the possible DSI devices
dt-bindings: display: bridge: samsung,mipi-dsim: Add i.MX8MM support
drm: bridge: samsung-dsim: Add i.MX8MM support
drm: bridge: samsung-dsim: Add input_bus_flags
drm: bridge: samsung-dsim: Move DSI init in bridge enable
drm: bridge: samsung-dsim: Fix PLL_P offset
drm: bridge: samsung-dsim: Add bridge mode_fixup

 .../display/bridge/samsung,mipi-dsim.yaml     | 360 +++++++++
 .../bindings/display/exynos/exynos_dsim.txt   |  90 ---
 MAINTAINERS                                   |  12 +
 drivers/gpu/drm/bridge/Kconfig                |  15 +
 drivers/gpu/drm/bridge/Makefile               |   1 +
 .../samsung-dsim.c}                           | 758 ++++++++++--------
 drivers/gpu/drm/exynos/Kconfig                |   9 -
 drivers/gpu/drm/exynos/Makefile               |   1 -
 8 files changed, 795 insertions(+), 451 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
 rename drivers/gpu/drm/{exynos/exynos_drm_dsi.c => bridge/samsung-dsim.c} (69%)
Signature · 1 line
2.25.1
author maintainer
#1 lore raw

RFC PATCH 1/17 drm/exynos: dsi: Convert to bridge driver

DRM bridge drivers have built-in handling of treating all display pipeline components as bridges.

Convert exynos_drm_dsi to a bridge driver with built-in encoder support for compatibility with existing component drivers.

This keeps switching the driver into the bridge in a more feasible manner.

---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 57 +++++++++++++++++--------
 1 file changed, 39 insertions(+), 18 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +39 -18
index 1d777d8c1a83..90d2ce2c3055 100644
@@ -257,6 +257,7 @@ struct exynos_dsi {
 	struct drm_connector connector;
 	struct drm_panel *panel;
 	struct list_head bridge_chain;
+	struct drm_bridge bridge;
 	struct drm_bridge *out_bridge;
 	struct device *dev;
 
@@ -287,9 +288,9 @@ struct exynos_dsi {
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
 #define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
 
-static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e)
+static inline struct exynos_dsi *bridge_to_dsi(struct drm_bridge *b)
 {
-	return container_of(e, struct exynos_dsi, encoder);
+	return container_of(b, struct exynos_dsi, bridge);
 }
 
 enum reg_idx {
@@ -1374,9 +1375,9 @@ static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi)
 	}
 }
 
-static void exynos_dsi_enable(struct drm_encoder *encoder)
+static void exynos_dsi_bridge_enable(struct drm_bridge *bridge)
 {
-	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
+	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
 	struct drm_bridge *iter;
 	int ret;
 
@@ -1429,9 +1430,9 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
 	pm_runtime_put(dsi->dev);
 }
 
-static void exynos_dsi_disable(struct drm_encoder *encoder)
+static void exynos_dsi_bridge_disable(struct drm_bridge *bridge)
 {
-	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
+	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
 	struct drm_bridge *iter;
 
 	if (!(dsi->state & DSIM_STATE_ENABLED))
@@ -1494,9 +1495,9 @@ static const struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs
 	.get_modes = exynos_dsi_get_modes,
 };
 
-static int exynos_dsi_create_connector(struct drm_encoder *encoder)
+static int exynos_dsi_create_connector(struct exynos_dsi *dsi)
 {
-	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
+	struct drm_encoder *encoder = &dsi->encoder;
 	struct drm_connector *connector = &dsi->connector;
 	struct drm_device *drm = encoder->dev;
 	int ret;
@@ -1522,9 +1523,16 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder)
 	return 0;
 }
 
-static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
-	.enable = exynos_dsi_enable,
-	.disable = exynos_dsi_disable,
+static int exynos_dsi_bridge_attach(struct drm_bridge *bridge,
+				    enum drm_bridge_attach_flags flags)
+{
+	return 0;
+}
+
+static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
+	.enable = exynos_dsi_bridge_enable,
+	.disable = exynos_dsi_bridge_disable,
+	.attach = exynos_dsi_bridge_attach,
 };
 
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
@@ -1543,7 +1551,7 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 		dsi->out_bridge = out_bridge;
 		list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
 	} else {
-		int ret = exynos_dsi_create_connector(encoder);
+		int ret = exynos_dsi_create_connector(dsi);
 
 		if (ret) {
 			DRM_DEV_ERROR(dsi->dev,
@@ -1596,7 +1604,7 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
 
 	if (dsi->panel) {
 		mutex_lock(&drm->mode_config.mutex);
-		exynos_dsi_disable(&dsi->encoder);
+		exynos_dsi_bridge_disable(&dsi->bridge);
 		dsi->panel = NULL;
 		dsi->connector.status = connector_status_disconnected;
 		mutex_unlock(&drm->mode_config.mutex);
@@ -1702,12 +1710,16 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 
 	drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
 
-	drm_encoder_helper_add(encoder, &exynos_dsi_encoder_helper_funcs);
-
 	ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_LCD);
 	if (ret < 0)
 		return ret;
 
+	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, 0);
+	if (ret) {
+		drm_encoder_cleanup(&dsi->encoder);
+		return ret;
+	}
+
 	in_bridge_node = of_graph_get_remote_node(dev->of_node, DSI_PORT_IN, 0);
 	if (in_bridge_node) {
 		in_bridge = of_drm_find_bridge(in_bridge_node);
@@ -1723,10 +1735,9 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master,
 				void *data)
 {
 	struct exynos_dsi *dsi = dev_get_drvdata(dev);
-	struct drm_encoder *encoder = &dsi->encoder;
-
-	exynos_dsi_disable(encoder);
 
+	exynos_dsi_bridge_disable(&dsi->bridge);
+	drm_encoder_cleanup(&dsi->encoder);
 	mipi_dsi_host_unregister(&dsi->dsi_host);
 }
 
@@ -1821,6 +1832,12 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 	pm_runtime_enable(dev);
 
+	dsi->bridge.funcs = &exynos_dsi_bridge_funcs;
+	dsi->bridge.of_node = dev->of_node;
+	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
+
+	drm_bridge_add(&dsi->bridge);
+
 	ret = component_add(dev, &exynos_dsi_component_ops);
 	if (ret)
 		goto err_disable_runtime;
@@ -1835,6 +1852,10 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 static int exynos_dsi_remove(struct platform_device *pdev)
 {
+	struct exynos_dsi *dsi = platform_get_drvdata(pdev);
+
+	drm_bridge_remove(&dsi->bridge);
+
 	pm_runtime_disable(&pdev->dev);
 
 	component_del(&pdev->dev, &exynos_dsi_component_ops);
Signature · 1 line
2.25.1
#2 lore raw

Re: [RFC PATCH 01/17] drm/exynos: dsi: Convert to bridge driver

Hi Jagan,

See a few comments below.

Sam

Quoted 83 lines · Jagan Teki

DRM bridge drivers have built-in handling of treating all display pipeline components as bridges.

Convert exynos_drm_dsi to a bridge driver with built-in encoder support for compatibility with existing component drivers.

This keeps switching the driver into the bridge in a more feasible manner.

---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 57 +++++++++++++++++--------
 1 file changed, 39 insertions(+), 18 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +10 -11
index 1d777d8c1a83..90d2ce2c3055 100644
@@ -257,6 +257,7 @@ struct exynos_dsi {
 	struct drm_connector connector;
 	struct drm_panel *panel;
 	struct list_head bridge_chain;
+	struct drm_bridge bridge;
 	struct drm_bridge *out_bridge;
 	struct device *dev;
 
@@ -287,9 +288,9 @@ struct exynos_dsi {
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
 #define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
 
-static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e)
+static inline struct exynos_dsi *bridge_to_dsi(struct drm_bridge *b)
 {
-	return container_of(e, struct exynos_dsi, encoder);
+	return container_of(b, struct exynos_dsi, bridge);
 }
 
 enum reg_idx {
@@ -1374,9 +1375,9 @@ static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi)
 	}
 }
 
-static void exynos_dsi_enable(struct drm_encoder *encoder)
+static void exynos_dsi_bridge_enable(struct drm_bridge *bridge)
 {
-	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
+	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
 	struct drm_bridge *iter;
 	int ret;
 
@@ -1429,9 +1430,9 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
 	pm_runtime_put(dsi->dev);
 }
 
-static void exynos_dsi_disable(struct drm_encoder *encoder)
+static void exynos_dsi_bridge_disable(struct drm_bridge *bridge)
 {
-	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
+	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
 	struct drm_bridge *iter;
 
 	if (!(dsi->state & DSIM_STATE_ENABLED))
@@ -1494,9 +1495,9 @@ static const struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs
 	.get_modes = exynos_dsi_get_modes,
 };
 
-static int exynos_dsi_create_connector(struct drm_encoder *encoder)
+static int exynos_dsi_create_connector(struct exynos_dsi *dsi)
 {
-	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
+	struct drm_encoder *encoder = &dsi->encoder;
 	struct drm_connector *connector = &dsi->connector;
 	struct drm_device *drm = encoder->dev;
 	int ret;
@@ -1522,9 +1523,16 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder)
 	return 0;
 }
 
-static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
-	.enable = exynos_dsi_enable,
-	.disable = exynos_dsi_disable,
+static int exynos_dsi_bridge_attach(struct drm_bridge *bridge,

drivers/gpu/drm/exynos/exynos_drm_dsi.c static int exynos_dsi_create_connector(struct drm_encoder *encoder) · line 1536

Quoted 10 lines
drivers/gpu/drm/exynos/exynos_drm_dsi.c +9 -0
+				    enum drm_bridge_attach_flags flags)
+{
+	return 0;
+}
+
+static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
+	.enable = exynos_dsi_bridge_enable,
+	.disable = exynos_dsi_bridge_disable,
+	.attach = exynos_dsi_bridge_attach,
 };

For new bridge drivers please use atomic_{enable,disable}. The non-atomic variants are deprecated and it is now also documneted. It was not documented when you wrote this patch!

Sam

Quoted 21 lines
drivers/gpu/drm/exynos/exynos_drm_dsi.c +2 -2
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
@@ -1543,7 +1551,7 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 		dsi->out_bridge = out_bridge;
 		list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
 	} else {
-		int ret = exynos_dsi_create_connector(encoder);
+		int ret = exynos_dsi_create_connector(dsi);
 
 		if (ret) {
 			DRM_DEV_ERROR(dsi->dev,
@@ -1596,7 +1604,7 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
 
 	if (dsi->panel) {
 		mutex_lock(&drm->mode_config.mutex);
-		exynos_dsi_disable(&dsi->encoder);
+		exynos_dsi_bridge_disable(&dsi->bridge);
 		dsi->panel = NULL;
 		dsi->connector.status = connector_status_disconnected;
 		mutex_unlock(&drm->mode_config.mutex);

drivers/gpu/drm/exynos/exynos_drm_dsi.c static int exynos_dsi_bind(struct device *dev, struct device *master, · line 1717

Quoted 10 lines
drivers/gpu/drm/exynos/exynos_drm_dsi.c +1 -2
@@ -1702,12 +1710,16 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 
 	drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
 
-	drm_encoder_helper_add(encoder, &exynos_dsi_encoder_helper_funcs);
-
 	ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_LCD);
 	if (ret < 0)
 		return ret;
 
+	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, 0);

I assume a later patch will move connector creation to the display driver.

Quoted 47 lines
drivers/gpu/drm/exynos/exynos_drm_dsi.c +17 -3
+	if (ret) {
+		drm_encoder_cleanup(&dsi->encoder);
+		return ret;
+	}
+
 	in_bridge_node = of_graph_get_remote_node(dev->of_node, DSI_PORT_IN, 0);
 	if (in_bridge_node) {
 		in_bridge = of_drm_find_bridge(in_bridge_node);
@@ -1723,10 +1735,9 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master,
 				void *data)
 {
 	struct exynos_dsi *dsi = dev_get_drvdata(dev);
-	struct drm_encoder *encoder = &dsi->encoder;
-
-	exynos_dsi_disable(encoder);
 
+	exynos_dsi_bridge_disable(&dsi->bridge);
+	drm_encoder_cleanup(&dsi->encoder);
 	mipi_dsi_host_unregister(&dsi->dsi_host);
 }
 
@@ -1821,6 +1832,12 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 	pm_runtime_enable(dev);
 
+	dsi->bridge.funcs = &exynos_dsi_bridge_funcs;
+	dsi->bridge.of_node = dev->of_node;
+	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
+
+	drm_bridge_add(&dsi->bridge);
+
 	ret = component_add(dev, &exynos_dsi_component_ops);
 	if (ret)
 		goto err_disable_runtime;
@@ -1835,6 +1852,10 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 static int exynos_dsi_remove(struct platform_device *pdev)
 {
+	struct exynos_dsi *dsi = platform_get_drvdata(pdev);
+
+	drm_bridge_remove(&dsi->bridge);
+
 	pm_runtime_disable(&pdev->dev);
 
 	component_del(&pdev->dev, &exynos_dsi_component_ops);
Signature · 1 line
2.25.1
author maintainer
#3 lore raw

RFC PATCH 2/17 drm/exynos: dsi: Handle drm_device for bridge

In reply to Jagan Teki

Now the exynos dsi driver supports bridge and legacy encoder.

In order to support drm_device in both the implementations it is required to preserve the drm_device in a private structure and use it accordingly.

1. encoder case, the bind will assign the drm_device into encoder->dev, so preserve the drm_device in the bind call.

2. bridge case, the drm_bridge_attach will assign the drm_device into bridge->dev, so preserve the drm_device in the bridge_attach function call.

---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +12 -5
index 90d2ce2c3055..d7d60aee465b 100644
@@ -259,6 +259,7 @@ struct exynos_dsi {
 	struct list_head bridge_chain;
 	struct drm_bridge bridge;
 	struct drm_bridge *out_bridge;
+	struct drm_device *drm;
 	struct device *dev;
 
 	void __iomem *reg_base;
@@ -1495,11 +1496,11 @@ static const struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs
 	.get_modes = exynos_dsi_get_modes,
 };
 
-static int exynos_dsi_create_connector(struct exynos_dsi *dsi)
+static int exynos_dsi_create_connector(struct exynos_dsi *dsi,
+				       struct drm_device *drm)
 {
 	struct drm_encoder *encoder = &dsi->encoder;
 	struct drm_connector *connector = &dsi->connector;
-	struct drm_device *drm = encoder->dev;
 	int ret;
 
 	connector->polled = DRM_CONNECTOR_POLL_HPD;
@@ -1526,6 +1527,10 @@ static int exynos_dsi_create_connector(struct exynos_dsi *dsi)
 static int exynos_dsi_bridge_attach(struct drm_bridge *bridge,
 				    enum drm_bridge_attach_flags flags)
 {
+	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+
+	dsi->drm = bridge->dev;
+
 	return 0;
 }
 
@@ -1542,7 +1547,7 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 {
 	struct exynos_dsi *dsi = host_to_dsi(host);
 	struct drm_encoder *encoder = &dsi->encoder;
-	struct drm_device *drm = encoder->dev;
+	struct drm_device *drm = dsi->drm;
 	struct drm_bridge *out_bridge;
 
 	out_bridge  = of_drm_find_bridge(device->dev.of_node);
@@ -1551,7 +1556,7 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 		dsi->out_bridge = out_bridge;
 		list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
 	} else {
-		int ret = exynos_dsi_create_connector(dsi);
+		int ret = exynos_dsi_create_connector(dsi, drm);
 
 		if (ret) {
 			DRM_DEV_ERROR(dsi->dev,
@@ -1600,7 +1605,7 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
 				  struct mipi_dsi_device *device)
 {
 	struct exynos_dsi *dsi = host_to_dsi(host);
-	struct drm_device *drm = dsi->encoder.dev;
+	struct drm_device *drm = dsi->drm;
 
 	if (dsi->panel) {
 		mutex_lock(&drm->mode_config.mutex);
@@ -1728,6 +1733,8 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 		of_node_put(in_bridge_node);
 	}
 
+	dsi->drm = drm_dev;
+
 	return mipi_dsi_host_register(&dsi->dsi_host);
 }
 
Signature · 1 line
2.25.1
Acked-by on v1 2/17
#4 lore raw

Re: [RFC PATCH 02/17] drm/exynos: dsi: Handle drm_device for bridge

Quoted 7 lines · Jagan Teki

Now the exynos dsi driver supports bridge and legacy encoder.

In order to support drm_device in both the implementations it is required to preserve the drm_device in a private structure and use it accordingly.

Quoted 8 lines

1. encoder case, the bind will assign the drm_device into encoder->dev, so preserve the drm_device in the bind call.

2. bridge case, the drm_bridge_attach will assign the drm_device into bridge->dev, so preserve the drm_device in the bridge_attach function call.

author maintainer
#5 lore raw

RFC PATCH 3/17 drm/exynos: dsi: Use the drm_panel_bridge API

In reply to Jagan Teki

Use drm_panel_bridge to replace manual panel and
bridge_chain handling code.

This makes the driver simpler to allow all components in the display pipeline to be treated as bridges by cleaning the way to generic connector handling.

---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 167 ++++--------------------
 1 file changed, 23 insertions(+), 144 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +23 -144
index d7d60aee465b..24f0b082ac6d 100644
@@ -254,9 +254,6 @@ struct exynos_dsi_driver_data {
 struct exynos_dsi {
 	struct drm_encoder encoder;
 	struct mipi_dsi_host dsi_host;
-	struct drm_connector connector;
-	struct drm_panel *panel;
-	struct list_head bridge_chain;
 	struct drm_bridge bridge;
 	struct drm_bridge *out_bridge;
 	struct drm_device *drm;
@@ -287,7 +284,6 @@ struct exynos_dsi {
 };
 
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
-#define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
 
 static inline struct exynos_dsi *bridge_to_dsi(struct drm_bridge *b)
 {
@@ -1379,7 +1375,6 @@ static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi)
 static void exynos_dsi_bridge_enable(struct drm_bridge *bridge)
 {
 	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
-	struct drm_bridge *iter;
 	int ret;
 
 	if (dsi->state & DSIM_STATE_ENABLED)
@@ -1393,134 +1388,51 @@ static void exynos_dsi_bridge_enable(struct drm_bridge *bridge)
 
 	dsi->state |= DSIM_STATE_ENABLED;
 
-	if (dsi->panel) {
-		ret = drm_panel_prepare(dsi->panel);
-		if (ret < 0)
-			goto err_put_sync;
-	} else {
-		list_for_each_entry_reverse(iter, &dsi->bridge_chain,
-					    chain_node) {
-			if (iter->funcs->pre_enable)
-				iter->funcs->pre_enable(iter);
-		}
-	}
-
 	exynos_dsi_set_display_mode(dsi);
 	exynos_dsi_set_display_enable(dsi, true);
 
-	if (dsi->panel) {
-		ret = drm_panel_enable(dsi->panel);
-		if (ret < 0)
-			goto err_display_disable;
-	} else {
-		list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
-			if (iter->funcs->enable)
-				iter->funcs->enable(iter);
-		}
-	}
-
 	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
 	return;
-
-err_display_disable:
-	exynos_dsi_set_display_enable(dsi, false);
-	drm_panel_unprepare(dsi->panel);
-
-err_put_sync:
-	dsi->state &= ~DSIM_STATE_ENABLED;
-	pm_runtime_put(dsi->dev);
 }
 
 static void exynos_dsi_bridge_disable(struct drm_bridge *bridge)
 {
 	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
-	struct drm_bridge *iter;
 
 	if (!(dsi->state & DSIM_STATE_ENABLED))
 		return;
 
 	dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
 
-	drm_panel_disable(dsi->panel);
-
-	list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
-		if (iter->funcs->disable)
-			iter->funcs->disable(iter);
-	}
-
 	exynos_dsi_set_display_enable(dsi, false);
-	drm_panel_unprepare(dsi->panel);
-
-	list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
-		if (iter->funcs->post_disable)
-			iter->funcs->post_disable(iter);
-	}
 
 	dsi->state &= ~DSIM_STATE_ENABLED;
 	pm_runtime_put_sync(dsi->dev);
 }
 
-static enum drm_connector_status
-exynos_dsi_detect(struct drm_connector *connector, bool force)
-{
-	return connector->status;
-}
-
-static void exynos_dsi_connector_destroy(struct drm_connector *connector)
+static int exynos_dsi_panel_or_bridge(struct exynos_dsi *dsi,
+				      struct device_node *node)
 {
-	drm_connector_unregister(connector);
-	drm_connector_cleanup(connector);
-	connector->dev = NULL;
-}
-
-static const struct drm_connector_funcs exynos_dsi_connector_funcs = {
-	.detect = exynos_dsi_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = exynos_dsi_connector_destroy,
-	.reset = drm_atomic_helper_connector_reset,
-	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int exynos_dsi_get_modes(struct drm_connector *connector)
-{
-	struct exynos_dsi *dsi = connector_to_dsi(connector);
-
-	if (dsi->panel)
-		return drm_panel_get_modes(dsi->panel, connector);
-
-	return 0;
-}
+	struct drm_bridge *panel_bridge;
+	struct drm_panel *panel;
 
-static const struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
-	.get_modes = exynos_dsi_get_modes,
-};
+	panel_bridge = of_drm_find_bridge(node);
+	if (!panel_bridge) {
+		panel = of_drm_find_panel(node);
+		if (!IS_ERR(panel)) {
+			panel_bridge = drm_panel_bridge_add(panel);
+			if (IS_ERR(panel_bridge))
+				return PTR_ERR(panel_bridge);
+		}
+	}
 
-static int exynos_dsi_create_connector(struct exynos_dsi *dsi,
-				       struct drm_device *drm)
-{
-	struct drm_encoder *encoder = &dsi->encoder;
-	struct drm_connector *connector = &dsi->connector;
-	int ret;
+	of_node_put(node);
 
-	connector->polled = DRM_CONNECTOR_POLL_HPD;
+	dsi->out_bridge = panel_bridge;
 
-	ret = drm_connector_init(drm, connector, &exynos_dsi_connector_funcs,
-				 DRM_MODE_CONNECTOR_DSI);
-	if (ret) {
-		DRM_DEV_ERROR(dsi->dev,
-			      "Failed to initialize connector with drm\n");
-		return ret;
-	}
+	if (!dsi->out_bridge)
+		return -EPROBE_DEFER;
 
-	connector->status = connector_status_disconnected;
-	drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs);
-	drm_connector_attach_encoder(connector, encoder);
-	if (!drm->registered)
-		return 0;
-
-	connector->funcs->reset(connector);
-	drm_connector_register(connector);
 	return 0;
 }
 
@@ -1531,7 +1443,8 @@ static int exynos_dsi_bridge_attach(struct drm_bridge *bridge,
 
 	dsi->drm = bridge->dev;
 
-	return 0;
+	return drm_bridge_attach(bridge->encoder, dsi->out_bridge, bridge,
+				 flags);
 }
 
 static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
@@ -1546,32 +1459,12 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 				  struct mipi_dsi_device *device)
 {
 	struct exynos_dsi *dsi = host_to_dsi(host);
-	struct drm_encoder *encoder = &dsi->encoder;
 	struct drm_device *drm = dsi->drm;
-	struct drm_bridge *out_bridge;
-
-	out_bridge  = of_drm_find_bridge(device->dev.of_node);
-	if (out_bridge) {
-		drm_bridge_attach(encoder, out_bridge, NULL, 0);
-		dsi->out_bridge = out_bridge;
-		list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
-	} else {
-		int ret = exynos_dsi_create_connector(dsi, drm);
-
-		if (ret) {
-			DRM_DEV_ERROR(dsi->dev,
-				      "failed to create connector ret = %d\n",
-				      ret);
-			drm_encoder_cleanup(encoder);
-			return ret;
-		}
+	int ret;
 
-		dsi->panel = of_drm_find_panel(device->dev.of_node);
-		if (IS_ERR(dsi->panel))
-			dsi->panel = NULL;
-		else
-			dsi->connector.status = connector_status_connected;
-	}
+	ret = exynos_dsi_panel_or_bridge(dsi, device->dev.of_node);
+	if (ret)
+		return ret;
 
 	/*
 	 * This is a temporary solution and should be made by more generic way.
@@ -1607,19 +1500,6 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
 	struct exynos_dsi *dsi = host_to_dsi(host);
 	struct drm_device *drm = dsi->drm;
 
-	if (dsi->panel) {
-		mutex_lock(&drm->mode_config.mutex);
-		exynos_dsi_bridge_disable(&dsi->bridge);
-		dsi->panel = NULL;
-		dsi->connector.status = connector_status_disconnected;
-		mutex_unlock(&drm->mode_config.mutex);
-	} else {
-		if (dsi->out_bridge->funcs->detach)
-			dsi->out_bridge->funcs->detach(dsi->out_bridge);
-		dsi->out_bridge = NULL;
-		INIT_LIST_HEAD(&dsi->bridge_chain);
-	}
-
 	if (drm->mode_config.poll_enabled)
 		drm_kms_helper_hotplug_event(drm);
 
@@ -1770,7 +1650,6 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	init_completion(&dsi->completed);
 	spin_lock_init(&dsi->transfer_lock);
 	INIT_LIST_HEAD(&dsi->transfer_list);
-	INIT_LIST_HEAD(&dsi->bridge_chain);
 
 	dsi->dsi_host.ops = &exynos_dsi_ops;
 	dsi->dsi_host.dev = dev;
Signature · 1 line
2.25.1
maintainer
#6 lore raw

Re: [RFC PATCH 03/17] drm/exynos: dsi: Use the drm_panel_bridge API

Quoted 8 lines · Jagan Teki

Use drm_panel_bridge to replace manual panel and
bridge_chain handling code.

This makes the driver simpler to allow all components in the display pipeline to be treated as bridges by cleaning the way to generic connector handling.

This breaks Exysos DSI driver operation (Trats board worked fine with only patches 1-2):

[    2.540066] exynos4-fb 11c00000.fimd: Adding to iommu group 0 [    2.554733] OF: graph: no port node found in /soc/fimd@11c00000 [    2.602819] [drm] Exynos DRM: using 11c00000.fimd device for DMA mapping operations
[    2.609649] exynos-drm exynos-drm: bound 11c00000.fimd (ops fimd_component_ops)
[    2.632558] exynos-drm exynos-drm: failed to bind 11c80000.dsi (ops exynos_dsi_component_ops): -22
[    2.642263] exynos-drm exynos-drm: master bind failed: -22 [    2.651017] exynos-drm: probe of exynos-drm failed with error -22

Quoted 254 lines
---
  drivers/gpu/drm/exynos/exynos_drm_dsi.c | 167 ++++--------------------
  1 file changed, 23 insertions(+), 144 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +23 -143
index d7d60aee465b..24f0b082ac6d 100644
@@ -254,9 +254,6 @@ struct exynos_dsi_driver_data {
  struct exynos_dsi {
  	struct drm_encoder encoder;
  	struct mipi_dsi_host dsi_host;
-	struct drm_connector connector;
-	struct drm_panel *panel;
-	struct list_head bridge_chain;
  	struct drm_bridge bridge;
  	struct drm_bridge *out_bridge;
  	struct drm_device *drm;
@@ -287,7 +284,6 @@ struct exynos_dsi {
  };
 
  #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
-#define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
 
  static inline struct exynos_dsi *bridge_to_dsi(struct drm_bridge *b)
  {
@@ -1379,7 +1375,6 @@ static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi)
  static void exynos_dsi_bridge_enable(struct drm_bridge *bridge)
  {
  	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
-	struct drm_bridge *iter;
  	int ret;
 
  	if (dsi->state & DSIM_STATE_ENABLED)
@@ -1393,134 +1388,51 @@ static void exynos_dsi_bridge_enable(struct drm_bridge *bridge)
 
  	dsi->state |= DSIM_STATE_ENABLED;
 
-	if (dsi->panel) {
-		ret = drm_panel_prepare(dsi->panel);
-		if (ret < 0)
-			goto err_put_sync;
-	} else {
-		list_for_each_entry_reverse(iter, &dsi->bridge_chain,
-					    chain_node) {
-			if (iter->funcs->pre_enable)
-				iter->funcs->pre_enable(iter);
-		}
-	}
-
  	exynos_dsi_set_display_mode(dsi);
  	exynos_dsi_set_display_enable(dsi, true);
 
-	if (dsi->panel) {
-		ret = drm_panel_enable(dsi->panel);
-		if (ret < 0)
-			goto err_display_disable;
-	} else {
-		list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
-			if (iter->funcs->enable)
-				iter->funcs->enable(iter);
-		}
-	}
-
  	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
  	return;
-
-err_display_disable:
-	exynos_dsi_set_display_enable(dsi, false);
-	drm_panel_unprepare(dsi->panel);
-
-err_put_sync:
-	dsi->state &= ~DSIM_STATE_ENABLED;
-	pm_runtime_put(dsi->dev);
  }
 
  static void exynos_dsi_bridge_disable(struct drm_bridge *bridge)
  {
  	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
-	struct drm_bridge *iter;
 
  	if (!(dsi->state & DSIM_STATE_ENABLED))
  		return;
 
  	dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
 
-	drm_panel_disable(dsi->panel);
-
-	list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
-		if (iter->funcs->disable)
-			iter->funcs->disable(iter);
-	}
-
  	exynos_dsi_set_display_enable(dsi, false);
-	drm_panel_unprepare(dsi->panel);
-
-	list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
-		if (iter->funcs->post_disable)
-			iter->funcs->post_disable(iter);
-	}
 
  	dsi->state &= ~DSIM_STATE_ENABLED;
  	pm_runtime_put_sync(dsi->dev);
  }
 
-static enum drm_connector_status
-exynos_dsi_detect(struct drm_connector *connector, bool force)
-{
-	return connector->status;
-}
-
-static void exynos_dsi_connector_destroy(struct drm_connector *connector)
+static int exynos_dsi_panel_or_bridge(struct exynos_dsi *dsi,
+				      struct device_node *node)
  {
-	drm_connector_unregister(connector);
-	drm_connector_cleanup(connector);
-	connector->dev = NULL;
-}
-
-static const struct drm_connector_funcs exynos_dsi_connector_funcs = {
-	.detect = exynos_dsi_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = exynos_dsi_connector_destroy,
-	.reset = drm_atomic_helper_connector_reset,
-	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int exynos_dsi_get_modes(struct drm_connector *connector)
-{
-	struct exynos_dsi *dsi = connector_to_dsi(connector);
-
-	if (dsi->panel)
-		return drm_panel_get_modes(dsi->panel, connector);
-
-	return 0;
-}
+	struct drm_bridge *panel_bridge;
+	struct drm_panel *panel;
 
-static const struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
-	.get_modes = exynos_dsi_get_modes,
-};
+	panel_bridge = of_drm_find_bridge(node);
+	if (!panel_bridge) {
+		panel = of_drm_find_panel(node);
+		if (!IS_ERR(panel)) {
+			panel_bridge = drm_panel_bridge_add(panel);
+			if (IS_ERR(panel_bridge))
+				return PTR_ERR(panel_bridge);
+		}
+	}
 
-static int exynos_dsi_create_connector(struct exynos_dsi *dsi,
-				       struct drm_device *drm)
-{
-	struct drm_encoder *encoder = &dsi->encoder;
-	struct drm_connector *connector = &dsi->connector;
-	int ret;
+	of_node_put(node);
 
-	connector->polled = DRM_CONNECTOR_POLL_HPD;
+	dsi->out_bridge = panel_bridge;
 
-	ret = drm_connector_init(drm, connector, &exynos_dsi_connector_funcs,
-				 DRM_MODE_CONNECTOR_DSI);
-	if (ret) {
-		DRM_DEV_ERROR(dsi->dev,
-			      "Failed to initialize connector with drm\n");
-		return ret;
-	}
+	if (!dsi->out_bridge)
+		return -EPROBE_DEFER;
 
-	connector->status = connector_status_disconnected;
-	drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs);
-	drm_connector_attach_encoder(connector, encoder);
-	if (!drm->registered)
-		return 0;
-
-	connector->funcs->reset(connector);
-	drm_connector_register(connector);
  	return 0;
  }
 
@@ -1531,7 +1443,8 @@ static int exynos_dsi_bridge_attach(struct drm_bridge *bridge,
 
  	dsi->drm = bridge->dev;
 
-	return 0;
+	return drm_bridge_attach(bridge->encoder, dsi->out_bridge, bridge,
+				 flags);
  }
 
  static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
@@ -1546,32 +1459,12 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
  				  struct mipi_dsi_device *device)
  {
  	struct exynos_dsi *dsi = host_to_dsi(host);
-	struct drm_encoder *encoder = &dsi->encoder;
  	struct drm_device *drm = dsi->drm;
-	struct drm_bridge *out_bridge;
-
-	out_bridge  = of_drm_find_bridge(device->dev.of_node);
-	if (out_bridge) {
-		drm_bridge_attach(encoder, out_bridge, NULL, 0);
-		dsi->out_bridge = out_bridge;
-		list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
-	} else {
-		int ret = exynos_dsi_create_connector(dsi, drm);
-
-		if (ret) {
-			DRM_DEV_ERROR(dsi->dev,
-				      "failed to create connector ret = %d\n",
-				      ret);
-			drm_encoder_cleanup(encoder);
-			return ret;
-		}
+	int ret;
 
-		dsi->panel = of_drm_find_panel(device->dev.of_node);
-		if (IS_ERR(dsi->panel))
-			dsi->panel = NULL;
-		else
-			dsi->connector.status = connector_status_connected;
-	}
+	ret = exynos_dsi_panel_or_bridge(dsi, device->dev.of_node);
+	if (ret)
+		return ret;
 
  	/*
  	 * This is a temporary solution and should be made by more generic way.
@@ -1607,19 +1500,6 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
  	struct exynos_dsi *dsi = host_to_dsi(host);
  	struct drm_device *drm = dsi->drm;
 
-	if (dsi->panel) {
-		mutex_lock(&drm->mode_config.mutex);
-		exynos_dsi_bridge_disable(&dsi->bridge);
-		dsi->panel = NULL;
-		dsi->connector.status = connector_status_disconnected;
-		mutex_unlock(&drm->mode_config.mutex);
-	} else {
-		if (dsi->out_bridge->funcs->detach)
-			dsi->out_bridge->funcs->detach(dsi->out_bridge);
-		dsi->out_bridge = NULL;
-		INIT_LIST_HEAD(&dsi->bridge_chain);
-	}
-
  	if (drm->mode_config.poll_enabled)
  		drm_kms_helper_hotplug_event(drm);
 

drivers/gpu/drm/exynos/exynos_drm_dsi.c static int exynos_dsi_probe(struct platform_device *pdev) · line 1655

Quoted 7 lines
drivers/gpu/drm/exynos/exynos_drm_dsi.c +0 -1
@@ -1770,7 +1650,6 @@ static int exynos_dsi_probe(struct platform_device *pdev)
  	init_completion(&dsi->completed);
  	spin_lock_init(&dsi->transfer_lock);
  	INIT_LIST_HEAD(&dsi->transfer_list);
-	INIT_LIST_HEAD(&dsi->bridge_chain);
 
  	dsi->dsi_host.ops = &exynos_dsi_ops;
  	dsi->dsi_host.dev = dev;

Best regards

Signature · 2 lines
Marek Szyprowski, PhD
Samsung R&D Institute Poland
author maintainer
#7 lore raw

Re: [RFC PATCH 03/17] drm/exynos: dsi: Use the drm_panel_bridge API

Quoted 14 lines · Marek Szyprowski
Quoted 8 lines · Jagan Teki

Use drm_panel_bridge to replace manual panel and
bridge_chain handling code.

This makes the driver simpler to allow all components in the display pipeline to be treated as bridges by cleaning the way to generic connector handling.

This breaks Exysos DSI driver operation (Trats board worked fine with only patches 1-2):

Quoted 10 lines
[    2.540066] exynos4-fb 11c00000.fimd: Adding to iommu group 0
[    2.554733] OF: graph: no port node found in /soc/fimd@11c00000
[    2.602819] [drm] Exynos DRM: using 11c00000.fimd device for DMA
mapping operations
[    2.609649] exynos-drm exynos-drm: bound 11c00000.fimd (ops
fimd_component_ops)
[    2.632558] exynos-drm exynos-drm: failed to bind 11c80000.dsi (ops
exynos_dsi_component_ops): -22
[    2.642263] exynos-drm exynos-drm: master bind failed: -22
[    2.651017] exynos-drm: probe of exynos-drm failed with error -22

Thanks for testing it.

Can you check Squash of 3,4 or 3,4,5 will work or not?

Thanks,
Jagan.

maintainer
#8 lore raw

Re: [RFC PATCH 03/17] drm/exynos: dsi: Use the drm_panel_bridge API

Quoted 24 lines · Jagan Teki
Quoted 12 lines · Marek Szyprowski
Quoted 8 lines · Jagan Teki

Use drm_panel_bridge to replace manual panel and
bridge_chain handling code.

This makes the driver simpler to allow all components in the display pipeline to be treated as bridges by cleaning the way to generic connector handling.

This breaks Exysos DSI driver operation (Trats board worked fine with only patches 1-2):

Quoted 10 lines
[    2.540066] exynos4-fb 11c00000.fimd: Adding to iommu group 0
[    2.554733] OF: graph: no port node found in /soc/fimd@11c00000
[    2.602819] [drm] Exynos DRM: using 11c00000.fimd device for DMA
mapping operations
[    2.609649] exynos-drm exynos-drm: bound 11c00000.fimd (ops
fimd_component_ops)
[    2.632558] exynos-drm exynos-drm: failed to bind 11c80000.dsi (ops
exynos_dsi_component_ops): -22
[    2.642263] exynos-drm exynos-drm: master bind failed: -22
[    2.651017] exynos-drm: probe of exynos-drm failed with error -22
Quoted 3 lines

Thanks for testing it.

Can you check Squash of 3,4 or 3,4,5 will work or not?

I've check both sets: 1-4 and 1-5 and none of them works. The result is same as above. If I remember correctly, last time when I played with that code, there was a problem with DRM core calling bridge ops in different order than when they are used by the Exynos DSI driver.

Best regards

Signature · 2 lines
Marek Szyprowski, PhD
Samsung R&D Institute Poland
author maintainer
#9 lore raw

Re: [RFC PATCH 03/17] drm/exynos: dsi: Use the drm_panel_bridge API

Quoted 26 lines · Marek Szyprowski
Quoted 24 lines · Jagan Teki
Quoted 22 lines · Marek Szyprowski
Quoted 8 lines · Jagan Teki

Use drm_panel_bridge to replace manual panel and
bridge_chain handling code.

This makes the driver simpler to allow all components in the display pipeline to be treated as bridges by cleaning the way to generic connector handling.

This breaks Exysos DSI driver operation (Trats board worked fine with only patches 1-2):

[    2.540066] exynos4-fb 11c00000.fimd: Adding to iommu group 0
[    2.554733] OF: graph: no port node found in /soc/fimd@11c00000
[    2.602819] [drm] Exynos DRM: using 11c00000.fimd device for DMA
mapping operations
[    2.609649] exynos-drm exynos-drm: bound 11c00000.fimd (ops
fimd_component_ops)
[    2.632558] exynos-drm exynos-drm: failed to bind 11c80000.dsi (ops
exynos_dsi_component_ops): -22
[    2.642263] exynos-drm exynos-drm: master bind failed: -22
[    2.651017] exynos-drm: probe of exynos-drm failed with error -22
Quoted 8 lines
Quoted 3 lines

Thanks for testing it.

Can you check Squash of 3,4 or 3,4,5 will work or not?

I've check both sets: 1-4 and 1-5 and none of them works. The result is same as above. If I remember correctly, last time when I played with that code, there was a problem with DRM core calling bridge ops in different order than when they are used by the Exynos DSI driver.

Okay. Let me check with sun6i-mipi-dsi as it is component_ops based.

Jagan.

author maintainer
#10 lore raw

RFC PATCH 4/17 drm/exynos: dsi: Create bridge connector for encoder

In reply to Jagan Teki

Use drm_bridge_connector_init to create a connector for display pipelines that use drm_bridge for encoder implementation.

This allows splitting connector operations across multiple bridges when necessary, instead of having the last bridge in the chain creating the connector and handling all connector operations internally.

---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +13 -1
index 24f0b082ac6d..d828be07c325 100644
@@ -24,6 +24,7 @@
 #include <video/videomode.h>
 
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge_connector.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_mipi_dsi.h>
@@ -1591,6 +1592,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 	struct drm_device *drm_dev = data;
 	struct device_node *in_bridge_node;
 	struct drm_bridge *in_bridge;
+	struct drm_connector *connector;
 	int ret;
 
 	drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
@@ -1599,12 +1601,22 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 	if (ret < 0)
 		return ret;
 
-	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, 0);
+	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
+				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 	if (ret) {
 		drm_encoder_cleanup(&dsi->encoder);
 		return ret;
 	}
 
+	connector = drm_bridge_connector_init(drm_dev, &dsi->encoder);
+	if (IS_ERR(connector)) {
+		DRM_DEV_ERROR(dsi->dev, "Unable to create bridge connector\n");
+		drm_encoder_cleanup(&dsi->encoder);
+		return PTR_ERR(connector);
+	}
+
+	drm_connector_attach_encoder(connector, &dsi->encoder);
+
 	in_bridge_node = of_graph_get_remote_node(dev->of_node, DSI_PORT_IN, 0);
 	if (in_bridge_node) {
 		in_bridge = of_drm_find_bridge(in_bridge_node);
Signature · 1 line
2.25.1
author maintainer
#11 lore raw

RFC PATCH 5/17 drm/exynos: dsi: Get the mode from bridge

In reply to Jagan Teki

Now the exynos dsi driver is fully aware of bridge handling, so get the display mode from bridge, mode_set API instead of legacy encoder crtc.

This makes bridge usage more efficient instead of relying on encoder stack.

Add mode_set in drm_bridge_funcs.

---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +12 -1
index d828be07c325..99a1b8c22313 100644
@@ -275,6 +275,7 @@ struct exynos_dsi {
 	u32 format;
 
 	int state;
+	struct drm_display_mode mode;
 	struct drm_property *brightness;
 	struct completion completed;
 
@@ -881,7 +882,7 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 
 static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
 {
-	struct drm_display_mode *m = &dsi->encoder.crtc->state->adjusted_mode;
+	struct drm_display_mode *m = &dsi->mode;
 	unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;
 	u32 reg;
 
@@ -1411,6 +1412,15 @@ static void exynos_dsi_bridge_disable(struct drm_bridge *bridge)
 	pm_runtime_put_sync(dsi->dev);
 }
 
+static void exynos_dsi_bridge_mode_set(struct drm_bridge *bridge,
+				       const struct drm_display_mode *mode,
+				       const struct drm_display_mode *adjusted_mode)
+{
+	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+
+	drm_mode_copy(&dsi->mode, adjusted_mode);
+}
+
 static int exynos_dsi_panel_or_bridge(struct exynos_dsi *dsi,
 				      struct device_node *node)
 {
@@ -1451,6 +1461,7 @@ static int exynos_dsi_bridge_attach(struct drm_bridge *bridge,
 static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
 	.enable = exynos_dsi_bridge_enable,
 	.disable = exynos_dsi_bridge_disable,
+	.mode_set = exynos_dsi_bridge_mode_set,
 	.attach = exynos_dsi_bridge_attach,
 };
 
Signature · 1 line
2.25.1
#12 lore raw

Re: [RFC PATCH 05/17] drm/exynos: dsi: Get the mode from bridge

Hi Jagan,

Quoted 8 lines · Jagan Teki

Now the exynos dsi driver is fully aware of bridge handling, so get the display mode from bridge, mode_set API instead of legacy encoder crtc.

This makes bridge usage more efficient instead of relying on encoder stack.

Add mode_set in drm_bridge_funcs.

Based on your description I had expected to find get_modes implmneted and the flag DRM_BRIDGE_OP_MODES set.

Sam

Quoted 53 lines
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +12 -1
index d828be07c325..99a1b8c22313 100644
@@ -275,6 +275,7 @@ struct exynos_dsi {
 	u32 format;
 
 	int state;
+	struct drm_display_mode mode;
 	struct drm_property *brightness;
 	struct completion completed;
 
@@ -881,7 +882,7 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 
 static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
 {
-	struct drm_display_mode *m = &dsi->encoder.crtc->state->adjusted_mode;
+	struct drm_display_mode *m = &dsi->mode;
 	unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;
 	u32 reg;
 
@@ -1411,6 +1412,15 @@ static void exynos_dsi_bridge_disable(struct drm_bridge *bridge)
 	pm_runtime_put_sync(dsi->dev);
 }
 
+static void exynos_dsi_bridge_mode_set(struct drm_bridge *bridge,
+				       const struct drm_display_mode *mode,
+				       const struct drm_display_mode *adjusted_mode)
+{
+	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+
+	drm_mode_copy(&dsi->mode, adjusted_mode);
+}
+
 static int exynos_dsi_panel_or_bridge(struct exynos_dsi *dsi,
 				      struct device_node *node)
 {
@@ -1451,6 +1461,7 @@ static int exynos_dsi_bridge_attach(struct drm_bridge *bridge,
 static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
 	.enable = exynos_dsi_bridge_enable,
 	.disable = exynos_dsi_bridge_disable,
+	.mode_set = exynos_dsi_bridge_mode_set,
 	.attach = exynos_dsi_bridge_attach,
 };
 
Signature · 1 line
2.25.1
#13 lore raw

Re: [RFC PATCH 05/17] drm/exynos: dsi: Get the mode from bridge

In reply to Jagan Teki

Hey Jagan,

Quoted 53 lines · Jagan Teki

Now the exynos dsi driver is fully aware of bridge handling, so get the display mode from bridge, mode_set API instead of legacy encoder crtc.

This makes bridge usage more efficient instead of relying on encoder stack.

Add mode_set in drm_bridge_funcs.

---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +11 -1
index d828be07c325..99a1b8c22313 100644
@@ -275,6 +275,7 @@ struct exynos_dsi {
        u32 format;
 
        int state;
+       struct drm_display_mode mode;
        struct drm_property *brightness;
        struct completion completed;
 
@@ -881,7 +882,7 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 
 static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
 {
-       struct drm_display_mode *m = &dsi->encoder.crtc->state->adjusted_mode;
+       struct drm_display_mode *m = &dsi->mode;
        unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;
        u32 reg;
 
@@ -1411,6 +1412,15 @@ static void exynos_dsi_bridge_disable(struct drm_bridge *bridge)
        pm_runtime_put_sync(dsi->dev);
 }
 
+static void exynos_dsi_bridge_mode_set(struct drm_bridge *bridge,
+                                      const struct drm_display_mode *mode,
+                                      const struct drm_display_mode *adjusted_mode)
+{
+       struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+
+       drm_mode_copy(&dsi->mode, adjusted_mode);
+}
+
 static int exynos_dsi_panel_or_bridge(struct exynos_dsi *dsi,
                                      struct device_node *node)
 {

drivers/gpu/drm/exynos/exynos_drm_dsi.c static int exynos_dsi_bridge_attach(struct drm_bridge *bridge, · line 1464

Quoted 4 lines
drivers/gpu/drm/exynos/exynos_drm_dsi.c +1 -0
@@ -1451,6 +1461,7 @@ static int exynos_dsi_bridge_attach(struct drm_bridge *bridge,
 static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
        .enable = exynos_dsi_bridge_enable,
        .disable = exynos_dsi_bridge_disable,
+       .mode_set = exynos_dsi_bridge_mode_set,

As far as I understand it, .enable(), .disable() &.mode_set() are deprecated[1] and should be replaced by atomic_enable(), atomic_disable() & atomic_enable() respectively.

[1] https://lore.kernel.org/dri-devel/[email protected]/

Quoted 6 lines
drivers/gpu/drm/exynos/exynos_drm_dsi.c +0 -1
        .attach = exynos_dsi_bridge_attach,
 };
 
--

2.25.1

#14 lore raw

Re: [RFC PATCH 05/17] drm/exynos: dsi: Get the mode from bridge

Quoted 65 lines · Robert Foss

Hey Jagan,

Quoted 53 lines · Jagan Teki

Now the exynos dsi driver is fully aware of bridge handling, so get the display mode from bridge, mode_set API instead of legacy encoder crtc.

This makes bridge usage more efficient instead of relying on encoder stack.

Add mode_set in drm_bridge_funcs.

---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +11 -1
index d828be07c325..99a1b8c22313 100644
@@ -275,6 +275,7 @@ struct exynos_dsi {
        u32 format;
 
        int state;
+       struct drm_display_mode mode;
        struct drm_property *brightness;
        struct completion completed;
 
@@ -881,7 +882,7 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 
 static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
 {
-       struct drm_display_mode *m = &dsi->encoder.crtc->state->adjusted_mode;
+       struct drm_display_mode *m = &dsi->mode;
        unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;
        u32 reg;
 
@@ -1411,6 +1412,15 @@ static void exynos_dsi_bridge_disable(struct drm_bridge *bridge)
        pm_runtime_put_sync(dsi->dev);
 }
 
+static void exynos_dsi_bridge_mode_set(struct drm_bridge *bridge,
+                                      const struct drm_display_mode *mode,
+                                      const struct drm_display_mode *adjusted_mode)
+{
+       struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+
+       drm_mode_copy(&dsi->mode, adjusted_mode);
+}
+
 static int exynos_dsi_panel_or_bridge(struct exynos_dsi *dsi,
                                      struct device_node *node)
 {

drivers/gpu/drm/exynos/exynos_drm_dsi.c static int exynos_dsi_bridge_attach(struct drm_bridge *bridge, · line 1464

Quoted 4 lines
drivers/gpu/drm/exynos/exynos_drm_dsi.c +1 -0
@@ -1451,6 +1461,7 @@ static int exynos_dsi_bridge_attach(struct drm_bridge *bridge,
 static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
        .enable = exynos_dsi_bridge_enable,
        .disable = exynos_dsi_bridge_disable,
+       .mode_set = exynos_dsi_bridge_mode_set,

As far as I understand it, .enable(), .disable() &.mode_set() are deprecated[1] and should be replaced by atomic_enable(), atomic_disable() & atomic_enable() respectively.

Quoted 1 line

[1] https://lore.kernel.org/dri-devel/[email protected]/

Correct, we are slowly moving away from the deprecated bridge functions. Need to find time to update my patchset that address some of this.

Sam

author maintainer
#15 lore raw

RFC PATCH 6/17 drm/exynos: dsi: Handle exynos specifics via driver_data

In reply to Jagan Teki

Exynos DSI driver is actually a Samsung MIPI DSIM bridge IP which is also used in i.MX8MM platforms.

Right now the existing driver has some exynos drm specific code bases like te_irq, crtc and component_ops.

In order to switch this driver into a common bridge driver We can see 2 options to handle the exynos specific code.

A. Drop the component_ops, and rework other specifics.
This may lead to more foundation work as it requires more changes in exynos drm drivers stack.

B. Handle the exynos specifics via driver data, and make
the common bridge work in different platforms and plan for option A in future.

So, this patch is trying to add option B) changes to handle exynos specifics via driver_data.

---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 37 +++++++++++++++++++------
 1 file changed, 29 insertions(+), 8 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +29 -8
index 99a1b8c22313..53d878d4d2d7 100644
@@ -250,6 +250,7 @@ struct exynos_dsi_driver_data {
 	unsigned int wait_for_reset;
 	unsigned int num_bits_resol;
 	const unsigned int *reg_values;
+	bool exynos_specific;
 };
 
 struct exynos_dsi {
@@ -459,6 +460,7 @@ static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
@@ -471,6 +473,7 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
@@ -481,6 +484,7 @@ static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
@@ -492,6 +496,7 @@ static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
 	.wait_for_reset = 0,
 	.num_bits_resol = 12,
 	.reg_values = exynos5433_reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
@@ -503,6 +508,7 @@ static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 12,
 	.reg_values = exynos5422_reg_values,
+	.exynos_specific = true,
 };
 
 static const struct of_device_id exynos_dsi_of_match[] = {
@@ -1484,7 +1490,8 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	 * If attached panel device is for command mode one, dsi should register
 	 * TE interrupt handler.
 	 */
-	if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
+	if (dsi->driver_data->exynos_specific &&
+	    !(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
 		int ret = exynos_dsi_register_te_irq(dsi, &device->dev);
 		if (ret)
 			return ret;
@@ -1495,8 +1502,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->lanes = device->lanes;
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
-	exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
-			!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
+	if (dsi->driver_data->exynos_specific)
+		exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
+					    !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
 
 	mutex_unlock(&drm->mode_config.mutex);
 
@@ -1515,7 +1523,8 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
 	if (drm->mode_config.poll_enabled)
 		drm_kms_helper_hotplug_event(drm);
 
-	exynos_dsi_unregister_te_irq(dsi);
+	if (dsi->driver_data->exynos_specific)
+		exynos_dsi_unregister_te_irq(dsi);
 
 	return 0;
 }
@@ -1737,6 +1746,15 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (!dsi->driver_data->exynos_specific) {
+		ret = mipi_dsi_host_register(&dsi->dsi_host);
+		if (ret) {
+			dev_err(dev, "failed to register mipi dsi host: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	platform_set_drvdata(pdev, dsi);
 
 	pm_runtime_enable(dev);
@@ -1747,9 +1765,11 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 	drm_bridge_add(&dsi->bridge);
 
-	ret = component_add(dev, &exynos_dsi_component_ops);
-	if (ret)
-		goto err_disable_runtime;
+	if (dsi->driver_data->exynos_specific) {
+		ret = component_add(dev, &exynos_dsi_component_ops);
+		if (ret)
+			goto err_disable_runtime;
+	}
 
 	return 0;
 
@@ -1767,7 +1787,8 @@ static int exynos_dsi_remove(struct platform_device *pdev)
 
 	pm_runtime_disable(&pdev->dev);
 
-	component_del(&pdev->dev, &exynos_dsi_component_ops);
+	if (dsi->driver_data->exynos_specific)
+		component_del(&pdev->dev, &exynos_dsi_component_ops);
 
 	return 0;
 }
Signature · 1 line
2.25.1
#16 lore raw

Re: [RFC PATCH 06/17] drm/exynos: dsi: Handle exynos specifics via driver_data

Quoted 13 lines · Jagan Teki

Exynos DSI driver is actually a Samsung MIPI DSIM bridge IP which is also used in i.MX8MM platforms.

Right now the existing driver has some exynos drm specific code bases like te_irq, crtc and component_ops.

In order to switch this driver into a common bridge driver We can see 2 options to handle the exynos specific code.

A. Drop the component_ops, and rework other specifics.
This may lead to more foundation work as it requires more changes in exynos drm drivers stack.

Quoted 6 lines

B. Handle the exynos specifics via driver data, and make
the common bridge work in different platforms and plan for option A in future.

So, this patch is trying to add option B) changes to handle exynos specifics via driver_data.

We really should find someone that has the time, energy, knowledge and hardware that can include device_link support once anf for all for bridges.
Then we would avoid hacks like this.

I see no other options at the moment, but look forward for a better solution.

Sam

Quoted 133 lines
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 37 +++++++++++++++++++------
 1 file changed, 29 insertions(+), 8 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +29 -8
index 99a1b8c22313..53d878d4d2d7 100644
@@ -250,6 +250,7 @@ struct exynos_dsi_driver_data {
 	unsigned int wait_for_reset;
 	unsigned int num_bits_resol;
 	const unsigned int *reg_values;
+	bool exynos_specific;
 };
 
 struct exynos_dsi {
@@ -459,6 +460,7 @@ static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
@@ -471,6 +473,7 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
@@ -481,6 +484,7 @@ static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
@@ -492,6 +496,7 @@ static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
 	.wait_for_reset = 0,
 	.num_bits_resol = 12,
 	.reg_values = exynos5433_reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
@@ -503,6 +508,7 @@ static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 12,
 	.reg_values = exynos5422_reg_values,
+	.exynos_specific = true,
 };
 
 static const struct of_device_id exynos_dsi_of_match[] = {
@@ -1484,7 +1490,8 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	 * If attached panel device is for command mode one, dsi should register
 	 * TE interrupt handler.
 	 */
-	if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
+	if (dsi->driver_data->exynos_specific &&
+	    !(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
 		int ret = exynos_dsi_register_te_irq(dsi, &device->dev);
 		if (ret)
 			return ret;
@@ -1495,8 +1502,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->lanes = device->lanes;
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
-	exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
-			!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
+	if (dsi->driver_data->exynos_specific)
+		exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
+					    !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
 
 	mutex_unlock(&drm->mode_config.mutex);
 
@@ -1515,7 +1523,8 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
 	if (drm->mode_config.poll_enabled)
 		drm_kms_helper_hotplug_event(drm);
 
-	exynos_dsi_unregister_te_irq(dsi);
+	if (dsi->driver_data->exynos_specific)
+		exynos_dsi_unregister_te_irq(dsi);
 
 	return 0;
 }
@@ -1737,6 +1746,15 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (!dsi->driver_data->exynos_specific) {
+		ret = mipi_dsi_host_register(&dsi->dsi_host);
+		if (ret) {
+			dev_err(dev, "failed to register mipi dsi host: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	platform_set_drvdata(pdev, dsi);
 
 	pm_runtime_enable(dev);
@@ -1747,9 +1765,11 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 	drm_bridge_add(&dsi->bridge);
 
-	ret = component_add(dev, &exynos_dsi_component_ops);
-	if (ret)
-		goto err_disable_runtime;
+	if (dsi->driver_data->exynos_specific) {
+		ret = component_add(dev, &exynos_dsi_component_ops);
+		if (ret)
+			goto err_disable_runtime;
+	}
 
 	return 0;
 
@@ -1767,7 +1787,8 @@ static int exynos_dsi_remove(struct platform_device *pdev)
 
 	pm_runtime_disable(&pdev->dev);
 
-	component_del(&pdev->dev, &exynos_dsi_component_ops);
+	if (dsi->driver_data->exynos_specific)
+		component_del(&pdev->dev, &exynos_dsi_component_ops);
 
 	return 0;
 }
Signature · 1 line
2.25.1
author maintainer
#17 lore raw

Re: [RFC PATCH 06/17] drm/exynos: dsi: Handle exynos specifics via driver_data

Quoted 22 lines · Sam Ravnborg
Quoted 13 lines · Jagan Teki

Exynos DSI driver is actually a Samsung MIPI DSIM bridge IP which is also used in i.MX8MM platforms.

Right now the existing driver has some exynos drm specific code bases like te_irq, crtc and component_ops.

In order to switch this driver into a common bridge driver We can see 2 options to handle the exynos specific code.

A. Drop the component_ops, and rework other specifics.
This may lead to more foundation work as it requires more changes in exynos drm drivers stack.

Quoted 6 lines

B. Handle the exynos specifics via driver data, and make
the common bridge work in different platforms and plan for option A in future.

So, this patch is trying to add option B) changes to handle exynos specifics via driver_data.

Quoted 7 lines

We really should find someone that has the time, energy, knowledge and hardware that can include device_link support once anf for all for bridges.
Then we would avoid hacks like this.

I see no other options at the moment, but look forward for a better solution.

The real key problem here is hardware, unfortunately I'm unable to find any proper exynos DSI hardware for myself to proceed atleast.

Thanks,
Jagan.

maintainer
#18 lore raw

Re: [RFC PATCH 06/17] drm/exynos: dsi: Handle exynos specifics via driver_data

In reply to Sam Ravnborg

Hi,

21. 7. 26. 오전 2:25에 Sam Ravnborg 이(가) 쓴 글:

Quoted 26 lines · Jagan Teki
Quoted 13 lines

Exynos DSI driver is actually a Samsung MIPI DSIM bridge IP which is also used in i.MX8MM platforms.

Right now the existing driver has some exynos drm specific code bases like te_irq, crtc and component_ops.

In order to switch this driver into a common bridge driver We can see 2 options to handle the exynos specific code.

A. Drop the component_ops, and rework other specifics.
This may lead to more foundation work as it requires more changes in exynos drm drivers stack.

Quoted 6 lines

B. Handle the exynos specifics via driver data, and make
the common bridge work in different platforms and plan for option A in future.

So, this patch is trying to add option B) changes to handle exynos specifics via driver_data.

We really should find someone that has the time, energy, knowledge and hardware that can include device_link support once anf for all for bridges.
Then we would avoid hacks like this.

Quoted 5 lines

I see no other options at the moment, but look forward for a better solution.

Sam

I'm not sure that it's correct to share this mipi dsi driver with I.MX8MM SoC even though it's a same IP because this MIPI DSI device isn't peripheral device but in SoC.
It would mean that Exynos MIPI DSI device depends on SoC architecture, and Exynos and I.MX series are totally different SoC. So if we share the same driver for the MIPI DSI device then many things we didn't predict may happen in the future. I don't want to make Jagan's efforts in vain for the community but clarify whether this is correct way or not. If this is only the way we have to go then we could more focus on actual solution not such hack. Impossible work with Jagan alone I think.

So let's get started with a question,
- Is MIPI-DSI bridge device or Encoder device? I think that MIPI-DSI is a Encoder device managed by atomic KMS. If MIPI-DSI should be handled as bridge device then does now drm bridge framework provide everything to share one driver with one more SoC? I mean something that drm bridge has to consider for such driver support, which is shared with one more SoC.

And Display mode - VIDEO and COMMAND mode - is generic type of MIPI DSI, and also componentised subsystem is a generic solution to resolve probing order issue not Exynos specific feature. These are driver specific ones not Exynos SoC I think. As SoC specific things should be considered, I think MIPI DSI Driver - interrupt handler and probing order things are really specific to device driver - should be separated but we could share the control part of the device.

I was busy with other projects so didn't care of Linux DRM world so there may be my missing something.

Thanks,
Inki Dae

Quoted 135 lines
Quoted 134 lines
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 37 +++++++++++++++++++------
 1 file changed, 29 insertions(+), 8 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +29 -8
index 99a1b8c22313..53d878d4d2d7 100644
@@ -250,6 +250,7 @@ struct exynos_dsi_driver_data {
 	unsigned int wait_for_reset;
 	unsigned int num_bits_resol;
 	const unsigned int *reg_values;
+	bool exynos_specific;
 };
 
 struct exynos_dsi {
@@ -459,6 +460,7 @@ static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
@@ -471,6 +473,7 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
@@ -481,6 +484,7 @@ static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
@@ -492,6 +496,7 @@ static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
 	.wait_for_reset = 0,
 	.num_bits_resol = 12,
 	.reg_values = exynos5433_reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
@@ -503,6 +508,7 @@ static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 12,
 	.reg_values = exynos5422_reg_values,
+	.exynos_specific = true,
 };
 
 static const struct of_device_id exynos_dsi_of_match[] = {
@@ -1484,7 +1490,8 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	 * If attached panel device is for command mode one, dsi should register
 	 * TE interrupt handler.
 	 */
-	if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
+	if (dsi->driver_data->exynos_specific &&
+	    !(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
 		int ret = exynos_dsi_register_te_irq(dsi, &device->dev);
 		if (ret)
 			return ret;
@@ -1495,8 +1502,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->lanes = device->lanes;
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
-	exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
-			!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
+	if (dsi->driver_data->exynos_specific)
+		exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
+					    !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
 
 	mutex_unlock(&drm->mode_config.mutex);
 
@@ -1515,7 +1523,8 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
 	if (drm->mode_config.poll_enabled)
 		drm_kms_helper_hotplug_event(drm);
 
-	exynos_dsi_unregister_te_irq(dsi);
+	if (dsi->driver_data->exynos_specific)
+		exynos_dsi_unregister_te_irq(dsi);
 
 	return 0;
 }
@@ -1737,6 +1746,15 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (!dsi->driver_data->exynos_specific) {
+		ret = mipi_dsi_host_register(&dsi->dsi_host);
+		if (ret) {
+			dev_err(dev, "failed to register mipi dsi host: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	platform_set_drvdata(pdev, dsi);
 
 	pm_runtime_enable(dev);
@@ -1747,9 +1765,11 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 	drm_bridge_add(&dsi->bridge);
 
-	ret = component_add(dev, &exynos_dsi_component_ops);
-	if (ret)
-		goto err_disable_runtime;
+	if (dsi->driver_data->exynos_specific) {
+		ret = component_add(dev, &exynos_dsi_component_ops);
+		if (ret)
+			goto err_disable_runtime;
+	}
 
 	return 0;
 
@@ -1767,7 +1787,8 @@ static int exynos_dsi_remove(struct platform_device *pdev)
 
 	pm_runtime_disable(&pdev->dev);
 
-	component_del(&pdev->dev, &exynos_dsi_component_ops);
+	if (dsi->driver_data->exynos_specific)
+		component_del(&pdev->dev, &exynos_dsi_component_ops);
 
 	return 0;
 }
Signature · 1 line
2.25.1
#19 lore raw

Re: [RFC PATCH 06/17] drm/exynos: dsi: Handle exynos specifics via driver_data

Hi Inki,

Quoted 30 lines · Inki Dae

21. 7. 26. 오전 2:25에 Sam Ravnborg 이(가) 쓴 글:

Quoted 21 lines · Jagan Teki
Quoted 13 lines

Exynos DSI driver is actually a Samsung MIPI DSIM bridge IP which is also used in i.MX8MM platforms.

Right now the existing driver has some exynos drm specific code bases like te_irq, crtc and component_ops.

In order to switch this driver into a common bridge driver We can see 2 options to handle the exynos specific code.

A. Drop the component_ops, and rework other specifics.
This may lead to more foundation work as it requires more changes in exynos drm drivers stack.

Quoted 6 lines

B. Handle the exynos specifics via driver data, and make
the common bridge work in different platforms and plan for option A in future.

So, this patch is trying to add option B) changes to handle exynos specifics via driver_data.

Quoted 7 lines

We really should find someone that has the time, energy, knowledge and hardware that can include device_link support once anf for all for bridges.
Then we would avoid hacks like this.

I see no other options at the moment, but look forward for a better solution.

Quoted 8 lines

I'm not sure that it's correct to share this mipi dsi driver with I.MX8MM SoC even though it's a same IP because this MIPI DSI device isn't peripheral device but in SoC.

It would mean that Exynos MIPI DSI device depends on SoC architecture, and Exynos and I.MX series are totally different SoC. So if we share the same driver for the MIPI DSI device then many things we didn't predict may happen in the future.

Isn't that true for external components true thought ? Any driver shared by multiple systems will face this issue, where it will be developed with some use cases in mind, and regressions may happen when the driver is then extended to support other use cases not required for the original platform.

In general we don't want multiple drivers for the same IP core unless there are valid technical reasons for that. It's the whole point of the device tree, being able to describe how IP cores are integrated, so that code can be reused across platforms. Of course, integration differences between SoCs can sometimes vary wildly and require some amount of glue code.

Quoted 5 lines

I don't want to make Jagan's efforts
in vain for the community but clarify whether this is correct way or not. If this is only the way we have to go then we could more focus on actual solution not such hack. Impossible work with Jagan alone I think.

I do agree that we need more correct solutions and less hacks in general :-) The issues faced on Exynos also exist on other platforms, so it would be much better to solve them well once that duplicating implementations with less test coverage and reviews. There have been efforts in the past to address some of these issues, which have resulted in solutions such as the component framework. However, I'd argued that we've never taken it to the last step, and have always stopped with half solutions. The component framework, for instance, is painful to use, and the handling of .remove() in most drivers is completely broken because of that (not just because of that though, we have issues in the DRM core that make hot-unplug just impossible to handle safetly).

Quoted 7 lines

So let's get started with a question,
- Is MIPI-DSI bridge device or Encoder device? I think that MIPI-DSI is a Encoder device managed by atomic KMS. If MIPI-DSI should be handled as bridge device then does now drm bridge framework provide everything to share one driver with one more SoC? I mean something that drm bridge has to consider for such driver support, which is shared with one more SoC.

The DRM "encoder" concept was a bit of a historical mistake that we are stuck with as drm_encoder is exposed to userspace. It comes from a time where nobody was envisioning chaining multiple encoders. DRM is moving to modelling every component after the CRTC as a bridge. This brings much more flexibility, and in that model, the drm_encoder becomes more or less a stub.

The DRM bridge API has been extended in the past to support more features, and if anything is still missing that makes it difficult to move away from drm_encoder, we can of course address the issues in drm_bridge.

Quoted 141 lines

And Display mode - VIDEO and COMMAND mode - is generic type of MIPI DSI, and also componentised subsystem is a generic solution to resolve probing order issue not Exynos specific feature. These are driver specific ones not Exynos SoC I think. As SoC specific things should be considered, I think MIPI DSI Driver - interrupt handler and probing order things are really specific to device driver - should be separated but we could share the control part of the device.

I was busy with other projects so didn't care of Linux DRM world so there may be my missing something.

Quoted 130 lines
Quoted 130 lines
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 37 +++++++++++++++++++------
 1 file changed, 29 insertions(+), 8 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +29 -8
index 99a1b8c22313..53d878d4d2d7 100644
@@ -250,6 +250,7 @@ struct exynos_dsi_driver_data {
 	unsigned int wait_for_reset;
 	unsigned int num_bits_resol;
 	const unsigned int *reg_values;
+	bool exynos_specific;
 };
 
 struct exynos_dsi {
@@ -459,6 +460,7 @@ static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
@@ -471,6 +473,7 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
@@ -481,6 +484,7 @@ static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
@@ -492,6 +496,7 @@ static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
 	.wait_for_reset = 0,
 	.num_bits_resol = 12,
 	.reg_values = exynos5433_reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
@@ -503,6 +508,7 @@ static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 12,
 	.reg_values = exynos5422_reg_values,
+	.exynos_specific = true,
 };
 
 static const struct of_device_id exynos_dsi_of_match[] = {
@@ -1484,7 +1490,8 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	 * If attached panel device is for command mode one, dsi should register
 	 * TE interrupt handler.
 	 */
-	if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
+	if (dsi->driver_data->exynos_specific &&
+	    !(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
 		int ret = exynos_dsi_register_te_irq(dsi, &device->dev);
 		if (ret)
 			return ret;
@@ -1495,8 +1502,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->lanes = device->lanes;
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
-	exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
-			!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
+	if (dsi->driver_data->exynos_specific)
+		exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
+					    !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
 
 	mutex_unlock(&drm->mode_config.mutex);
 
@@ -1515,7 +1523,8 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
 	if (drm->mode_config.poll_enabled)
 		drm_kms_helper_hotplug_event(drm);
 
-	exynos_dsi_unregister_te_irq(dsi);
+	if (dsi->driver_data->exynos_specific)
+		exynos_dsi_unregister_te_irq(dsi);
 
 	return 0;
 }
@@ -1737,6 +1746,15 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (!dsi->driver_data->exynos_specific) {
+		ret = mipi_dsi_host_register(&dsi->dsi_host);
+		if (ret) {
+			dev_err(dev, "failed to register mipi dsi host: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	platform_set_drvdata(pdev, dsi);
 
 	pm_runtime_enable(dev);
@@ -1747,9 +1765,11 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 	drm_bridge_add(&dsi->bridge);
 
-	ret = component_add(dev, &exynos_dsi_component_ops);
-	if (ret)
-		goto err_disable_runtime;
+	if (dsi->driver_data->exynos_specific) {
+		ret = component_add(dev, &exynos_dsi_component_ops);
+		if (ret)
+			goto err_disable_runtime;
+	}
 
 	return 0;
 
@@ -1767,7 +1787,8 @@ static int exynos_dsi_remove(struct platform_device *pdev)
 
 	pm_runtime_disable(&pdev->dev);
 
-	component_del(&pdev->dev, &exynos_dsi_component_ops);
+	if (dsi->driver_data->exynos_specific)
+		component_del(&pdev->dev, &exynos_dsi_component_ops);
 
 	return 0;
 }
Signature · 3 lines
Regards,

Laurent Pinchart
maintainer
#20 lore raw

Re: [RFC PATCH 06/17] drm/exynos: dsi: Handle exynos specifics via driver_data

Hi Laurent,

21. 8. 13. 오후 9:16에 Laurent Pinchart 이(가) 쓴 글:

Quoted 48 lines

Hi Inki,

Quoted 30 lines · Inki Dae

21. 7. 26. 오전 2:25에 Sam Ravnborg 이(가) 쓴 글:

Quoted 21 lines · Jagan Teki
Quoted 13 lines

Exynos DSI driver is actually a Samsung MIPI DSIM bridge IP which is also used in i.MX8MM platforms.

Right now the existing driver has some exynos drm specific code bases like te_irq, crtc and component_ops.

In order to switch this driver into a common bridge driver We can see 2 options to handle the exynos specific code.

A. Drop the component_ops, and rework other specifics.
This may lead to more foundation work as it requires more changes in exynos drm drivers stack.

Quoted 6 lines

B. Handle the exynos specifics via driver data, and make
the common bridge work in different platforms and plan for option A in future.

So, this patch is trying to add option B) changes to handle exynos specifics via driver_data.

Quoted 7 lines

We really should find someone that has the time, energy, knowledge and hardware that can include device_link support once anf for all for bridges.
Then we would avoid hacks like this.

I see no other options at the moment, but look forward for a better solution.

Quoted 8 lines

I'm not sure that it's correct to share this mipi dsi driver with I.MX8MM SoC even though it's a same IP because this MIPI DSI device isn't peripheral device but in SoC.

It would mean that Exynos MIPI DSI device depends on SoC architecture, and Exynos and I.MX series are totally different SoC. So if we share the same driver for the MIPI DSI device then many things we didn't predict may happen in the future.

Isn't that true for external components true thought ? Any driver shared by multiple systems will face this issue, where it will be developed with some use cases in mind, and regressions may happen when the driver is then extended to support other use cases not required for the original platform.

Quoted 6 lines

In general we don't want multiple drivers for the same IP core unless there are valid technical reasons for that. It's the whole point of the device tree, being able to describe how IP cores are integrated, so that code can be reused across platforms. Of course, integration differences between SoCs can sometimes vary wildly and require some amount of glue code.

Agree with you. It would be a good chance to clarify what we need to share same device driver without any regress in this time.

Quoted 7 lines
Quoted 6 lines

I don't want to make Jagan's efforts
in vain for the community but clarify whether this is correct way or not. If this is only the way we have to go then we could more focus on actual solution not such hack. Impossible work with Jagan alone I think.

Quoted 6 lines

I do agree that we need more correct solutions and less hacks in general :-) The issues faced on Exynos also exist on other platforms, so it would be much better to solve them well once that duplicating implementations with less test coverage and reviews. There have been efforts in the past to address some of these issues, which have resulted in solutions such as the component framework. However, I'd argued that

Yeah, most of ARM systems have various separate devices but DRM subsytem wanted each ARM driver to work like one device driver for all of them. And the component framework has been adopted by several ARM DRM drivers for it including Exynos.

Quoted 5 lines

we've never taken it to the last step, and have always stopped with half solutions. The component framework, for instance, is painful to use, and the handling of .remove() in most drivers is completely broken because of that (not just because of that though, we have issues in the DRM core that make hot-unplug just impossible to handle safetly).

This may be one of what we have to clarify. I think ARM DRM drivers need component framework or similar thing to address probing order issue. So would we need to enhance existing compoent framework to be suitable for DRM subsystem, or introducing an alternative solution?

Otherwise, would there be some way to address the probing order issue without the compoment framework?

Quoted 9 lines
Quoted 8 lines

So let's get started with a question,
- Is MIPI-DSI bridge device or Encoder device? I think that MIPI-DSI is a Encoder device managed by atomic KMS. If MIPI-DSI should be handled as bridge device then does now drm bridge framework provide everything to share one driver with one more SoC? I mean something that drm bridge has to consider for such driver support, which is shared with one more SoC.

Quoted 4 lines

The DRM "encoder" concept was a bit of a historical mistake that we are stuck with as drm_encoder is exposed to userspace. It comes from a time where nobody was envisioning chaining multiple encoders. DRM is moving to modelling every component after the CRTC as a bridge. This brings

Thanks for explanation and seems correct direction. :) However, there would be something we have to address before changing the existing modeling because any regress shouldn't be allowed.

Thanks,
Inki Dae

Quoted 150 lines

much more flexibility, and in that model, the drm_encoder becomes more or less a stub.

The DRM bridge API has been extended in the past to support more features, and if anything is still missing that makes it difficult to move away from drm_encoder, we can of course address the issues in drm_bridge.

Quoted 141 lines

And Display mode - VIDEO and COMMAND mode - is generic type of MIPI DSI, and also componentised subsystem is a generic solution to resolve probing order issue not Exynos specific feature. These are driver specific ones not Exynos SoC I think. As SoC specific things should be considered, I think MIPI DSI Driver - interrupt handler and probing order things are really specific to device driver - should be separated but we could share the control part of the device.

I was busy with other projects so didn't care of Linux DRM world so there may be my missing something.

Quoted 130 lines
Quoted 130 lines
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 37 +++++++++++++++++++------
 1 file changed, 29 insertions(+), 8 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_dsi.c +29 -8
index 99a1b8c22313..53d878d4d2d7 100644
@@ -250,6 +250,7 @@ struct exynos_dsi_driver_data {
 	unsigned int wait_for_reset;
 	unsigned int num_bits_resol;
 	const unsigned int *reg_values;
+	bool exynos_specific;
 };
 
 struct exynos_dsi {
@@ -459,6 +460,7 @@ static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
@@ -471,6 +473,7 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
@@ -481,6 +484,7 @@ static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
 	.reg_values = reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
@@ -492,6 +496,7 @@ static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
 	.wait_for_reset = 0,
 	.num_bits_resol = 12,
 	.reg_values = exynos5433_reg_values,
+	.exynos_specific = true,
 };
 
 static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
@@ -503,6 +508,7 @@ static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
 	.wait_for_reset = 1,
 	.num_bits_resol = 12,
 	.reg_values = exynos5422_reg_values,
+	.exynos_specific = true,
 };
 
 static const struct of_device_id exynos_dsi_of_match[] = {
@@ -1484,7 +1490,8 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	 * If attached panel device is for command mode one, dsi should register
 	 * TE interrupt handler.
 	 */
-	if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
+	if (dsi->driver_data->exynos_specific &&
+	    !(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
 		int ret = exynos_dsi_register_te_irq(dsi, &device->dev);
 		if (ret)
 			return ret;
@@ -1495,8 +1502,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->lanes = device->lanes;
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
-	exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
-			!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
+	if (dsi->driver_data->exynos_specific)
+		exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
+					    !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
 
 	mutex_unlock(&drm->mode_config.mutex);
 
@@ -1515,7 +1523,8 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
 	if (drm->mode_config.poll_enabled)
 		drm_kms_helper_hotplug_event(drm);
 
-	exynos_dsi_unregister_te_irq(dsi);
+	if (dsi->driver_data->exynos_specific)
+		exynos_dsi_unregister_te_irq(dsi);
 
 	return 0;
 }
@@ -1737,6 +1746,15 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (!dsi->driver_data->exynos_specific) {
+		ret = mipi_dsi_host_register(&dsi->dsi_host);
+		if (ret) {
+			dev_err(dev, "failed to register mipi dsi host: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	platform_set_drvdata(pdev, dsi);
 
 	pm_runtime_enable(dev);
@@ -1747,9 +1765,11 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 	drm_bridge_add(&dsi->bridge);
 
-	ret = component_add(dev, &exynos_dsi_component_ops);
-	if (ret)
-		goto err_disable_runtime;
+	if (dsi->driver_data->exynos_specific) {
+		ret = component_add(dev, &exynos_dsi_component_ops);
+		if (ret)
+			goto err_disable_runtime;
+	}
 
 	return 0;
 
@@ -1767,7 +1787,8 @@ static int exynos_dsi_remove(struct platform_device *pdev)
 
 	pm_runtime_disable(&pdev->dev);
 
-	component_del(&pdev->dev, &exynos_dsi_component_ops);
+	if (dsi->driver_data->exynos_specific)
+		component_del(&pdev->dev, &exynos_dsi_component_ops);
 
 	return 0;
 }
author maintainer
#21 lore raw

RFC PATCH 7/17 drm: bridge: Move exynos_drm_dsi into bridges

In reply to Jagan Teki

The MIPI DSI IP used in Exynos and i.MX8MM are based Samsung MIPI DSIM bridge.

In order to access the common bridge between platforms the ideal way to push the driver into the bridge area.
So, this patch will move the exynos_drm_dsi.c driver into samsung-dsim.c and do the necessary function name changes.

This would help to improve the bridge driver in future patches in order to make use of different SoC families and platforms.

The bridge now support two implementations,

A. With component_ops and exynos specific code exclusively
for exynos dsi drivers and it's legacy bindings.

B. Without componenet_ops for newly implemented bridges
and its users like i.MX8MM.

The future plan is to fix the implementation A) by dropping component_ops and fixing exynos specific code in order to make the bridge more mature to use.

Updated MAINTAINERS file for this bridge with exynos drm maintainers along with Andrzej as he is the original author.

Tomasz Figa has been not included in MAINTAINERS as he is not available via samsung.com.

---
 MAINTAINERS                                   |  11 +
 drivers/gpu/drm/bridge/Kconfig                |  15 +
 drivers/gpu/drm/bridge/Makefile               |   1 +
 .../samsung-dsim.c}                           | 433 +++++++++---------
 drivers/gpu/drm/exynos/Kconfig                |   9 -
 drivers/gpu/drm/exynos/Makefile               |   1 -
 6 files changed, 246 insertions(+), 224 deletions(-)
 rename drivers/gpu/drm/{exynos/exynos_drm_dsi.c => bridge/samsung-dsim.c} (77%)
MAINTAINERS +11 -0
index cae0c6148590..733c2ebc0393 100644
@@ -5864,6 +5864,17 @@ T:	git git://anongit.freedesktop.org/drm/drm-misc
 F:	Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml
 F:	drivers/gpu/drm/panel/panel-samsung-db7430.c
 
+DRM DRIVER FOR SAMSUNG MIPI DSIM BRIDGE
+M:	Inki Dae <[email protected]>
+M:	Joonyoung Shim <[email protected]>
+M:	Seung-Woo Kim <[email protected]>
+M:	Kyungmin Park <[email protected]>
+M:	Andrzej Hajda <[email protected]>
+M:	Jagan Teki <[email protected]>
+S:	Maintained
+T:	git git://anongit.freedesktop.org/drm/drm-misc
+F:	drivers/gpu/drm/bridge/samsung-dsim.c
+
 DRM DRIVER FOR SITRONIX ST7703 PANELS
 M:	Guido Günther <[email protected]>
 R:	Purism Kernel Team <[email protected]>
drivers/gpu/drm/bridge/Kconfig +15 -0
index 4de6dbb8821b..c8a3b13f730b 100644
@@ -190,6 +190,21 @@ config DRM_PARADE_PS8640
 	  The PS8640 is a high-performance and low-power
 	  MIPI DSI to eDP converter
 
+config DRM_SAMSUNG_DSIM
+	tristate "Samsung MIPI DSIM bridge driver"
+	depends on DRM
+	depends on COMMON_CLK
+	depends on OF && HAS_IOMEM
+	depends on DRM_EXYNOS_FIMD || DRM_EXYNOS5433_DECON || DRM_EXYNOS7_DECON
+	select DRM_KMS_HELPER
+	select DRM_MIPI_DSI
+	select DRM_PANEL_BRIDGE
+	select REGMAP_MMIO
+	help
+	  This enables the Samsung MIPI DSIM bridge controller driver.
+	  This MIPI DSIM bridge can be found it on Exynos and NXP's
+	  i.MX8M Mini and Nano SoC's.
+
 config DRM_SIL_SII8620
 	tristate "Silicon Image SII8620 HDMI/MHL bridge"
 	depends on OF
drivers/gpu/drm/bridge/Makefile +1 -0
index ec2b9fa2699e..1eb04e4857e5 100644
@@ -12,6 +12,7 @@ obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
 obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
+obj-$(CONFIG_DRM_SAMSUNG_DSIM) += samsung-dsim.o
 obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
 obj-$(CONFIG_DRM_SII902X) += sii902x.o
 obj-$(CONFIG_DRM_SII9234) += sii9234.o
drivers/gpu/drm/bridge/samsung-dsim.c renamed from drivers/gpu/drm/exynos/exynos_drm_dsi.c +219 -214

1,147 lines not on this page · raw message

drivers/gpu/drm/exynos/Kconfig +0 -9
index 6a251e3aa779..6bcd0fe03c70 100644
@@ -53,15 +53,6 @@ config DRM_EXYNOS_DPI
 	help
 	  This enables support for Exynos parallel output.
 
-config DRM_EXYNOS_DSI
-	bool "MIPI-DSI host"
-	depends on DRM_EXYNOS_FIMD || DRM_EXYNOS5433_DECON || DRM_EXYNOS7_DECON
-	select DRM_MIPI_DSI
-	select DRM_PANEL
-	default n
-	help
-	  This enables support for Exynos MIPI-DSI device.
-
 config DRM_EXYNOS_DP
 	bool "Exynos specific extensions for Analogix DP driver"
 	depends on DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON
drivers/gpu/drm/exynos/Makefile +0 -1
index 2fd2f3ee4fcf..04832f92051d 100644
@@ -11,7 +11,6 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)	+= exynos_drm_fimd.o
 exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON)	+= exynos5433_drm_decon.o
 exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON)	+= exynos7_drm_decon.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_DPI)	+= exynos_drm_dpi.o
-exynosdrm-$(CONFIG_DRM_EXYNOS_DSI)	+= exynos_drm_dsi.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_DP)	+= exynos_dp.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_MIXER)	+= exynos_mixer.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)	+= exynos_hdmi.o
Signature · 1 line
2.25.1
#22 lore raw

Re: [RFC PATCH 07/17] drm: bridge: Move exynos_drm_dsi into bridges

[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch]

Hi Jagan,

[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on drm-tip/drm-tip]
[cannot apply to drm-exynos/exynos-drm-next robh/for-next drm-intel/for-linux-next linus/master v5.13 next-20210701] [If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jagan-Teki/drm-bridge-Samsung-MIPI-DSIM-bridge/20210704-170731
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: riscv-allmodconfig (attached as .config)
compiler: riscv64-linux-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/ac6267c83b70acaa0da508f00708329b0ec8abcd
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Jagan-Teki/drm-bridge-Samsung-MIPI-DSIM-bridge/20210704-170731 git checkout ac6267c83b70acaa0da508f00708329b0ec8abcd
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=riscv

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "exynos_drm_crtc_get_by_type" [drivers/gpu/drm/bridge/samsung-dsim.ko] undefined!
>> ERROR: modpost: "exynos_drm_crtc_te_handler" [drivers/gpu/drm/bridge/samsung-dsim.ko] undefined!
>> ERROR: modpost: "exynos_drm_set_possible_crtcs" [drivers/gpu/drm/bridge/samsung-dsim.ko] undefined!

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

author maintainer
#23 lore raw

RFC PATCH 8/17 dt-bindings: display: bridge: Add Samsung MIPI DSIM bridge

In reply to Jagan Teki

Samsing MIPI DSIM bridge can be found on Exynos and NXP's i.MX8M Mini and Nano SoC's.

This dt-bindings replaces legacy exynos_dsim.txt.

Used the example node from latest Exynos SoC instead of the one used in legacy exynos_dsim.txt.

Add dt-bingings for it.

---
 .../display/bridge/samsung,mipi-dsim.yaml     | 278 ++++++++++++++++++
 .../bindings/display/exynos/exynos_dsim.txt   |  90 ------
 MAINTAINERS                                   |   1 +
 3 files changed, 279 insertions(+), 90 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +278 -0
new file mode 100644
index 000000000000..b2970734ffd7
@@ -0,0 +1,278 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/samsung,mipi-dsim.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung MIPI DSIM bridge controller
+
+maintainers:
+  - Inki Dae <[email protected]>
+  - Joonyoung Shim <[email protected]>
+  - Seung-Woo Kim <[email protected]>
+  - Kyungmin Park <[email protected]>
+  - Andrzej Hajda <[email protected]>
+  - Jagan Teki <[email protected]>
+
+description: |
+  Samsung MIPI DSIM bridge controller can be found it on Exynos
+  and i.MX8M Mini and Nano SoC's.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos3250-mipi-dsi
+      - samsung,exynos4210-mipi-dsi
+      - samsung,exynos5410-mipi-dsi
+      - samsung,exynos5422-mipi-dsi
+      - samsung,exynos5433-mipi-dsi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+  clocks:
+    minItems: 2
+    maxItems: 5
+
+  clock-names:
+    minItems: 2
+    maxItems: 5
+
+  phys:
+    maxItems: 1
+    description: phandle to the phy module representing the DPHY
+
+  phy-names:
+    items:
+      - const: dsim
+
+  samsung,phy-type:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: phandle to the samsung phy-type
+
+  power-domains:
+    description: phandle to the associated power domain
+    maxItems: 1
+
+  samsung,power-domain:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: phandle to the associated samsung power domain
+    maxItems: 1
+
+  vddcore-supply:
+    description: MIPI DSIM Core voltage supply (e.g. 1.1V)
+
+  vddio-supply:
+    description: MIPI DSIM I/O and PLL voltage supply (e.g. 1.8V)
+
+  samsung,burst-clock-frequency:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      DSIM high speed burst mode frequency.
+
+  samsung,esc-clock-frequency:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      DSIM escape mode frequency.
+
+  samsung,pll-clock-frequency:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      DSIM oscillator clock frequency.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        description:
+          Input port node to receive pixel data from the
+          display controller. Exactly one endpoint must be
+          specified.
+        properties:
+          endpoint@0:
+            $ref: /schemas/graph.yaml#/properties/endpoint
+            description: sub-node describing the input from MIC
+
+        unevaluatedProperties: false
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          DSI output port node to the panel or the next bridge
+          in the chain
+
+required:
+  - '#address-cells'
+  - '#size-cells'
+  - clock-names
+  - clocks
+  - compatible
+  - interrupts
+  - phy-names
+  - phys
+  - reg
+  - samsung,burst-clock-frequency
+  - samsung,esc-clock-frequency
+  - samsung,pll-clock-frequency
+
+allOf:
+  - $ref: ../dsi-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-mipi-dsi
+
+    then:
+      properties:
+        clocks:
+          minItems: 5
+
+        clock-names:
+          items:
+            - const: bus_clk
+            - const: phyclk_mipidphy0_bitclkdiv8
+            - const: phyclk_mipidphy0_rxclkesc0
+            - const: sclk_rgb_vclk_to_dsim0
+            - const: sclk_mipi
+
+        ports:
+          required:
+            - port@0
+
+      required:
+        - ports
+        - vddcore-supply
+        - vddio-supply
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5410-mipi-dsi
+
+    then:
+      properties:
+        clocks:
+          minItems: 2
+
+        clock-names:
+          items:
+            - const: bus_clk
+            - const: pll_clk
+
+      required:
+        - vddcore-supply
+        - vddio-supply
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos4210-mipi-dsi
+
+    then:
+      properties:
+        clocks:
+          minItems: 2
+
+        clock-names:
+          items:
+            - const: bus_clk
+            - const: sclk_mipi
+
+      required:
+        - vddcore-supply
+        - vddio-supply
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos3250-mipi-dsi
+
+    then:
+      properties:
+        clocks:
+          minItems: 2
+
+        clock-names:
+          items:
+            - const: bus_clk
+            - const: pll_clk
+
+      required:
+        - vddcore-supply
+        - vddio-supply
+        - samsung,phy-type
+
+additionalProperties:
+  type: object
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5433.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    dsi@13900000 {
+       compatible = "samsung,exynos5433-mipi-dsi";
+       reg = <0x13900000 0xC0>;
+       interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+       phys = <&mipi_phy 1>;
+       phy-names = "dsim";
+       clocks = <&cmu_disp CLK_PCLK_DSIM0>,
+                <&cmu_disp CLK_PHYCLK_MIPIDPHY0_BITCLKDIV8>,
+                <&cmu_disp CLK_PHYCLK_MIPIDPHY0_RXCLKESC0>,
+                <&cmu_disp CLK_SCLK_RGB_VCLK_TO_DSIM0>,
+                <&cmu_disp CLK_SCLK_DSIM0>;
+       clock-names = "bus_clk",
+                     "phyclk_mipidphy0_bitclkdiv8",
+                     "phyclk_mipidphy0_rxclkesc0",
+                     "sclk_rgb_vclk_to_dsim0",
+                     "sclk_mipi";
+       power-domains = <&pd_disp>;
+       vddcore-supply = <&ldo6_reg>;
+       vddio-supply = <&ldo7_reg>;
+       samsung,burst-clock-frequency = <512000000>;
+       samsung,esc-clock-frequency = <16000000>;
+       samsung,pll-clock-frequency = <24000000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&te_irq>;
+       status = "disabled";
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       panel@0 {
+          compatible = "samsung,s6e3ha2";
+          reg = <0>;
+          vdd3-supply = <&ldo27_reg>;
+          vci-supply = <&ldo28_reg>;
+          reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
+          enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
+       };
+
+       ports {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+          port@0 {
+             reg = <0>;
+
+             dsi_to_mic: endpoint {
+                remote-endpoint = <&mic_to_dsi>;
+             };
+          };
+       };
+    };
Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt deleted +0 -90

90 lines not on this page · raw message

MAINTAINERS +1 -0
index 733c2ebc0393..e571fc7792aa 100644
@@ -5873,6 +5873,7 @@ M:	Andrzej Hajda <[email protected]>
 M:	Jagan Teki <[email protected]>
 S:	Maintained
 T:	git git://anongit.freedesktop.org/drm/drm-misc
+F:	Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml
 F:	drivers/gpu/drm/bridge/samsung-dsim.c
 
 DRM DRIVER FOR SITRONIX ST7703 PANELS
Signature · 1 line
2.25.1
maintainer
#24 lore raw

Re: [RFC PATCH 08/17] dt-bindings: display: bridge: Add Samsung MIPI DSIM bridge

Quoted 9 lines · Jagan Teki

Samsing MIPI DSIM bridge can be found on Exynos and NXP's i.MX8M Mini and Nano SoC's.

This dt-bindings replaces legacy exynos_dsim.txt.

Used the example node from latest Exynos SoC instead of the one used in legacy exynos_dsim.txt.

Add dt-bingings for it.

typo

Quoted 35 lines
---
 .../display/bridge/samsung,mipi-dsim.yaml     | 278 ++++++++++++++++++
 .../bindings/display/exynos/exynos_dsim.txt   |  90 ------
 MAINTAINERS                                   |   1 +
 3 files changed, 279 insertions(+), 90 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +18 -0
new file mode 100644
index 000000000000..b2970734ffd7
@@ -0,0 +1,278 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/samsung,mipi-dsim.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung MIPI DSIM bridge controller
+
+maintainers:
+  - Inki Dae <[email protected]>
+  - Joonyoung Shim <[email protected]>
+  - Seung-Woo Kim <[email protected]>
+  - Kyungmin Park <[email protected]>
+  - Andrzej Hajda <[email protected]>
+  - Jagan Teki <[email protected]>
+
+description: |
+  Samsung MIPI DSIM bridge controller can be found it on Exynos

Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml line 28

Quoted 10 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +10 -0
+  and i.MX8M Mini and Nano SoC's.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos3250-mipi-dsi
+      - samsung,exynos4210-mipi-dsi
+      - samsung,exynos5410-mipi-dsi
+      - samsung,exynos5422-mipi-dsi
+      - samsung,exynos5433-mipi-dsi

What about i.MX compatibles?

Quoted 14 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +14 -0
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+  clocks:

Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml line 52

Quoted 10 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +10 -0
+    minItems: 2
+    maxItems: 5
+
+  clock-names:
+    minItems: 2
+    maxItems: 5
+
+  phys:
+    maxItems: 1
+    description: phandle to the phy module representing the DPHY

Drop

Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml line 63

Quoted 11 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +11 -0
+
+  phy-names:
+    items:
+      - const: dsim
+
+  samsung,phy-type:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: phandle to the samsung phy-type
+
+  power-domains:
+    description: phandle to the associated power domain

Drop

Quoted 24 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +24 -0
+    maxItems: 1
+
+  samsung,power-domain:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: phandle to the associated samsung power domain
+    maxItems: 1
+
+  vddcore-supply:
+    description: MIPI DSIM Core voltage supply (e.g. 1.1V)
+
+  vddio-supply:
+    description: MIPI DSIM I/O and PLL voltage supply (e.g. 1.8V)
+
+  samsung,burst-clock-frequency:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      DSIM high speed burst mode frequency.
+
+  samsung,esc-clock-frequency:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      DSIM escape mode frequency.
+
+  samsung,pll-clock-frequency:

Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml line 97

Quoted 10 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +10 -0
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      DSIM oscillator clock frequency.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/$defs/port-base

If there are no extra endpoint properties, then use '/schemas/graph.yaml#/properties/port'.

Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml line 105

Quoted 8 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +8 -0
+        description:
+          Input port node to receive pixel data from the
+          display controller. Exactly one endpoint must be
+          specified.
+        properties:
+          endpoint@0:
+            $ref: /schemas/graph.yaml#/properties/endpoint
+            description: sub-node describing the input from MIC

I'd assume i.MX has a different input than MIC?

Quoted 285 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +173 -0
+
+        unevaluatedProperties: false
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          DSI output port node to the panel or the next bridge
+          in the chain
+
+required:
+  - '#address-cells'
+  - '#size-cells'
+  - clock-names
+  - clocks
+  - compatible
+  - interrupts
+  - phy-names
+  - phys
+  - reg
+  - samsung,burst-clock-frequency
+  - samsung,esc-clock-frequency
+  - samsung,pll-clock-frequency
+
+allOf:
+  - $ref: ../dsi-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-mipi-dsi
+
+    then:
+      properties:
+        clocks:
+          minItems: 5
+
+        clock-names:
+          items:
+            - const: bus_clk
+            - const: phyclk_mipidphy0_bitclkdiv8
+            - const: phyclk_mipidphy0_rxclkesc0
+            - const: sclk_rgb_vclk_to_dsim0
+            - const: sclk_mipi
+
+        ports:
+          required:
+            - port@0
+
+      required:
+        - ports
+        - vddcore-supply
+        - vddio-supply
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5410-mipi-dsi
+
+    then:
+      properties:
+        clocks:
+          minItems: 2
+
+        clock-names:
+          items:
+            - const: bus_clk
+            - const: pll_clk
+
+      required:
+        - vddcore-supply
+        - vddio-supply
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos4210-mipi-dsi
+
+    then:
+      properties:
+        clocks:
+          minItems: 2
+
+        clock-names:
+          items:
+            - const: bus_clk
+            - const: sclk_mipi
+
+      required:
+        - vddcore-supply
+        - vddio-supply
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos3250-mipi-dsi
+
+    then:
+      properties:
+        clocks:
+          minItems: 2
+
+        clock-names:
+          items:
+            - const: bus_clk
+            - const: pll_clk
+
+      required:
+        - vddcore-supply
+        - vddio-supply
+        - samsung,phy-type
+
+additionalProperties:
+  type: object
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5433.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    dsi@13900000 {
+       compatible = "samsung,exynos5433-mipi-dsi";
+       reg = <0x13900000 0xC0>;
+       interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+       phys = <&mipi_phy 1>;
+       phy-names = "dsim";
+       clocks = <&cmu_disp CLK_PCLK_DSIM0>,
+                <&cmu_disp CLK_PHYCLK_MIPIDPHY0_BITCLKDIV8>,
+                <&cmu_disp CLK_PHYCLK_MIPIDPHY0_RXCLKESC0>,
+                <&cmu_disp CLK_SCLK_RGB_VCLK_TO_DSIM0>,
+                <&cmu_disp CLK_SCLK_DSIM0>;
+       clock-names = "bus_clk",
+                     "phyclk_mipidphy0_bitclkdiv8",
+                     "phyclk_mipidphy0_rxclkesc0",
+                     "sclk_rgb_vclk_to_dsim0",
+                     "sclk_mipi";
+       power-domains = <&pd_disp>;
+       vddcore-supply = <&ldo6_reg>;
+       vddio-supply = <&ldo7_reg>;
+       samsung,burst-clock-frequency = <512000000>;
+       samsung,esc-clock-frequency = <16000000>;
+       samsung,pll-clock-frequency = <24000000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&te_irq>;
+       status = "disabled";
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       panel@0 {
+          compatible = "samsung,s6e3ha2";
+          reg = <0>;
+          vdd3-supply = <&ldo27_reg>;
+          vci-supply = <&ldo28_reg>;
+          reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
+          enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
+       };
+
+       ports {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+          port@0 {
+             reg = <0>;
+
+             dsi_to_mic: endpoint {
+                remote-endpoint = <&mic_to_dsi>;
+             };
+          };
+       };
+    };
Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt deleted +0 -90
deleted file mode 100644
index be377786e8cd..000000000000
@@ -1,90 +0,0 @@
-Exynos MIPI DSI Master
-
-Required properties:
-  - compatible: value should be one of the following
-		"samsung,exynos3250-mipi-dsi" /* for Exynos3250/3472 SoCs */
-		"samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */
-		"samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */
-		"samsung,exynos5422-mipi-dsi" /* for Exynos5422/5800 SoCs */
-		"samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */
-  - reg: physical base address and length of the registers set for the device
-  - interrupts: should contain DSI interrupt
-  - clocks: list of clock specifiers, must contain an entry for each required
-    entry in clock-names
-  - clock-names: should include "bus_clk"and "sclk_mipi" entries
-		 the use of "pll_clk" is deprecated
-  - phys: list of phy specifiers, must contain an entry for each required
-    entry in phy-names
-  - phy-names: should include "dsim" entry
-  - vddcore-supply: MIPI DSIM Core voltage supply (e.g. 1.1V)
-  - vddio-supply: MIPI DSIM I/O and PLL voltage supply (e.g. 1.8V)
-  - samsung,pll-clock-frequency: specifies frequency of the oscillator clock
-  - #address-cells, #size-cells: should be set respectively to <1> and <0>
-    according to DSI host bindings (see MIPI DSI bindings [1])
-  - samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst
-    mode
-  - samsung,esc-clock-frequency: specifies DSI frequency in escape mode
-
-Optional properties:
-  - power-domains: a phandle to DSIM power domain node
-
-Child nodes:
-  Should contain DSI peripheral nodes (see MIPI DSI bindings [1]).
-
-Video interfaces:
-  Device node can contain following video interface port nodes according to [2]:
-  0: RGB input,
-  1: DSI output
-
-[1]: Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
-[2]: Documentation/devicetree/bindings/media/video-interfaces.txt
-
-Example:
-
-	dsi@11c80000 {
-		compatible = "samsung,exynos4210-mipi-dsi";
-		reg = <0x11C80000 0x10000>;
-		interrupts = <0 79 0>;
-		clocks = <&clock 286>, <&clock 143>;
-		clock-names = "bus_clk", "sclk_mipi";
-		phys = <&mipi_phy 1>;
-		phy-names = "dsim";
-		vddcore-supply = <&vusb_reg>;
-		vddio-supply = <&vmipi_reg>;
-		power-domains = <&pd_lcd0>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		samsung,pll-clock-frequency = <24000000>;
-
-		panel@1 {
-			reg = <0>;
-			...
-			port {
-				panel_ep: endpoint {
-					remote-endpoint = <&dsi_ep>;
-				};
-			};
-		};
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				decon_to_mic: endpoint {
-					remote-endpoint = <&mic_to_decon>;
-				};
-			};
-
-			port@1 {
-				reg = <1>;
-				dsi_ep: endpoint {
-					reg = <0>;
-					samsung,burst-clock-frequency = <500000000>;
-					samsung,esc-clock-frequency = <20000000>;
-					remote-endpoint = <&panel_ep>;
-				};
-			};
-		};
-	};
MAINTAINERS +1 -0
index 733c2ebc0393..e571fc7792aa 100644
@@ -5873,6 +5873,7 @@ M:	Andrzej Hajda <[email protected]>
 M:	Jagan Teki <[email protected]>
 S:	Maintained
 T:	git git://anongit.freedesktop.org/drm/drm-misc
+F:	Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml
 F:	drivers/gpu/drm/bridge/samsung-dsim.c
 
 DRM DRIVER FOR SITRONIX ST7703 PANELS
Signature · 1 line
2.25.1
author maintainer
#25 lore raw

Re: [RFC PATCH 08/17] dt-bindings: display: bridge: Add Samsung MIPI DSIM bridge

Quoted 53 lines · Rob Herring
Quoted 9 lines · Jagan Teki

Samsing MIPI DSIM bridge can be found on Exynos and NXP's i.MX8M Mini and Nano SoC's.

This dt-bindings replaces legacy exynos_dsim.txt.

Used the example node from latest Exynos SoC instead of the one used in legacy exynos_dsim.txt.

Add dt-bingings for it.

typo

Quoted 39 lines
---
 .../display/bridge/samsung,mipi-dsim.yaml     | 278 ++++++++++++++++++
 .../bindings/display/exynos/exynos_dsim.txt   |  90 ------
 MAINTAINERS                                   |   1 +
 3 files changed, 279 insertions(+), 90 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +22 -0
new file mode 100644
index 000000000000..b2970734ffd7
@@ -0,0 +1,278 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/samsung,mipi-dsim.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung MIPI DSIM bridge controller
+
+maintainers:
+  - Inki Dae <[email protected]>
+  - Joonyoung Shim <[email protected]>
+  - Seung-Woo Kim <[email protected]>
+  - Kyungmin Park <[email protected]>
+  - Andrzej Hajda <[email protected]>
+  - Jagan Teki <[email protected]>
+
+description: |
+  Samsung MIPI DSIM bridge controller can be found it on Exynos
+  and i.MX8M Mini and Nano SoC's.
+
+properties:
+  compatible:
Quoted 8 lines

Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml line 28

Quoted 6 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +6 -0
+    enum:
+      - samsung,exynos3250-mipi-dsi
+      - samsung,exynos4210-mipi-dsi
+      - samsung,exynos5410-mipi-dsi
+      - samsung,exynos5422-mipi-dsi
+      - samsung,exynos5433-mipi-dsi

What about i.MX compatibles?

I have added in the next patch since this is yml conversation for existing .txt bindings.

Quoted 71 lines
Quoted 15 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +14 -0
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+  clocks:

Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml line 52

Quoted 10 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +10 -0
+    minItems: 2
+    maxItems: 5
+
+  clock-names:
+    minItems: 2
+    maxItems: 5
+
+  phys:
+    maxItems: 1
+    description: phandle to the phy module representing the DPHY

Drop

Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml line 63

Quoted 11 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +11 -0
+
+  phy-names:
+    items:
+      - const: dsim
+
+  samsung,phy-type:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: phandle to the samsung phy-type
+
+  power-domains:
+    description: phandle to the associated power domain

Drop

Quoted 29 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +29 -0
+    maxItems: 1
+
+  samsung,power-domain:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: phandle to the associated samsung power domain
+    maxItems: 1
+
+  vddcore-supply:
+    description: MIPI DSIM Core voltage supply (e.g. 1.1V)
+
+  vddio-supply:
+    description: MIPI DSIM I/O and PLL voltage supply (e.g. 1.8V)
+
+  samsung,burst-clock-frequency:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      DSIM high speed burst mode frequency.
+
+  samsung,esc-clock-frequency:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      DSIM escape mode frequency.
+
+  samsung,pll-clock-frequency:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      DSIM oscillator clock frequency.
+
+  ports:
Quoted 8 lines

Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml line 97

Quoted 5 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +5 -0
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/$defs/port-base

If there are no extra endpoint properties, then use '/schemas/graph.yaml#/properties/port'.

Okay.

Quoted 11 lines

Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml line 105

Quoted 9 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml new file +8 -0
+        description:
+          Input port node to receive pixel data from the
+          display controller. Exactly one endpoint must be
+          specified.
+        properties:
+          endpoint@0:
+            $ref: /schemas/graph.yaml#/properties/endpoint
+            description: sub-node describing the input from MIC

I'd assume i.MX has a different input than MIC?

Yes, updated in next patch.

Thanks,
Jagan.

author maintainer
#26 lore raw

RFC PATCH 9/17 drm: bridge: samsung-dsim: Add module init, exit

In reply to Jagan Teki

Add module init and exit functions for the bridge to register and unregister dsi_driver.

Exynos drm driver stack will register the platform_driver separately in the common of it's exynos_drm_drv.c including dsi_driver. Register again would return -EBUSY, so return 0 for such cases as dsi_driver is already registered.

---
 drivers/gpu/drm/bridge/samsung-dsim.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
drivers/gpu/drm/bridge/samsung-dsim.c +22 -0
index eed6b3ffdea7..627580abd6df 100644
@@ -1878,6 +1878,28 @@ struct platform_driver dsi_driver = {
 	},
 };
 
+static int __init samsung_mipi_dsim_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&dsi_driver);
+
+	/**
+	 * Exynos drm driver stack will register the platform_driver
+	 * separately in the common of it's exynos_drm_drv.c including
+	 * dsi_driver. Register again would return -EBUSY, so return 0
+	 * for such cases as dsi_driver is already registered.
+	 */
+	return ret == -EBUSY ? 0 : ret;
+}
+module_init(samsung_mipi_dsim_init);
+
+static void __exit samsung_mipi_dsim_exit(void)
+{
+	platform_driver_unregister(&dsi_driver);
+}
+module_exit(samsung_mipi_dsim_exit);
+
 MODULE_AUTHOR("Tomasz Figa <[email protected]>");
 MODULE_AUTHOR("Andrzej Hajda <[email protected]>");
 MODULE_AUTHOR("Jagan Teki <[email protected]>");
Signature · 1 line
2.25.1
author maintainer
#27 lore raw

RFC PATCH 10/17 drm: bridge: samsung-dsim: Update the of_node for port(s)

In reply to Jagan Teki

Existing bridge driver is able to find the panel or bridge if of_node isn't a port(s). This is how the exynos dsi node handling has been done so far.

However in order to make use of this bridge in other or new supported platforms like i.MX8MM it is required to have a port based of_node.

So, this patch will check if node is a port based and then update of_node.

This way we can support the platforms which are using legacy or new DSI bindings.

---
 drivers/gpu/drm/bridge/samsung-dsim.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)
drivers/gpu/drm/bridge/samsung-dsim.c +14 -5
index 627580abd6df..2222c27feffd 100644
@@ -226,6 +226,11 @@ enum samsung_dsim_transfer_type {
 	EXYNOS_DSI_RX,
 };
 
+enum {
+	DSI_PORT_IN,
+	DSI_PORT_OUT
+};
+
 struct samsung_dsim_transfer {
 	struct list_head list;
 	struct completion completed;
@@ -1436,6 +1441,15 @@ static int samsung_dsim_panel_or_bridge(struct samsung_dsim *dsi,
 {
 	struct drm_bridge *panel_bridge;
 	struct drm_panel *panel;
+	struct device_node *remote;
+
+	if (of_graph_is_present(node)) {
+		remote = of_graph_get_remote_node(node, DSI_PORT_OUT, 0);
+		if (!remote)
+			return -ENODEV;
+
+		node = remote;
+	}
 
 	panel_bridge = of_drm_find_bridge(node);
 	if (!panel_bridge) {
@@ -1579,11 +1593,6 @@ static int samsung_dsim_of_read_u32(const struct device_node *np,
 	return ret;
 }
 
-enum {
-	DSI_PORT_IN,
-	DSI_PORT_OUT
-};
-
 static int samsung_dsim_parse_dt(struct samsung_dsim *dsi)
 {
 	struct device *dev = dsi->dev;
Signature · 1 line
2.25.1
author maintainer
#28 lore raw

RFC PATCH 11/17 drm: bridge: samsung-dsim: Find the possible DSI devices

In reply to Jagan Teki

Finding panel_or_bridge might vary based on associated DSI device drivers like DSI panel, bridge, and I2C based DSI bridge.

All of these DSI drivers will invoke the DSI host in order to find the panel_or_bridge from probe to host attach and bridge_attach to host bridge attach.

So, in order to handle all these cases of finding the panel_or_bridge invoke the finding API in host attach and bridge attach with the DSIM_STATE_DEVICE_FOUND flag.

This way we can handle all possible cases of finding the DSI devices.

---
 drivers/gpu/drm/bridge/samsung-dsim.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)
drivers/gpu/drm/bridge/samsung-dsim.c +17 -3
index 2222c27feffd..9a2df1212d0f 100644
@@ -248,6 +248,7 @@ struct samsung_dsim_transfer {
 #define DSIM_STATE_INITIALIZED		BIT(1)
 #define DSIM_STATE_CMD_LPM		BIT(2)
 #define DSIM_STATE_VIDOUT_AVAILABLE	BIT(3)
+#define DSIM_STATE_DEVICE_FOUND		BIT(4)
 
 struct samsung_dsim_driver_data {
 	const unsigned int *reg_ofs;
@@ -1475,6 +1476,15 @@ static int samsung_dsim_bridge_attach(struct drm_bridge *bridge,
 				      enum drm_bridge_attach_flags flags)
 {
 	struct samsung_dsim *dsi = bridge_to_dsi(bridge);
+	int ret;
+
+	if (!(dsi->state & DSIM_STATE_DEVICE_FOUND)) {
+		ret = samsung_dsim_panel_or_bridge(dsi, dsi->dev->of_node);
+		if (ret)
+			return ret;
+
+		dsi->state |= DSIM_STATE_DEVICE_FOUND;
+	}
 
 	dsi->drm = bridge->dev;
 
@@ -1498,9 +1508,13 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
 	struct drm_device *drm = dsi->drm;
 	int ret;
 
-	ret = samsung_dsim_panel_or_bridge(dsi, device->dev.of_node);
-	if (ret)
-		return ret;
+	if (!(dsi->state & DSIM_STATE_DEVICE_FOUND)) {
+		ret = samsung_dsim_panel_or_bridge(dsi, device->dev.of_node);
+		if (ret)
+			return ret;
+
+		dsi->state |= DSIM_STATE_DEVICE_FOUND;
+	}
 
 	/*
 	 * This is a temporary solution and should be made by more generic way.
Signature · 1 line
2.25.1
author maintainer
#29 lore raw

RFC PATCH 12/17 dt-bindings: display: bridge: samsung, mipi-dsim: Add i.MX8MM support

In reply to Jagan Teki

Samsung MIPI DSIM bridge can also be found in i.MX8MM SoC.

Add dt-bingings for it.

---
 .../display/bridge/samsung,mipi-dsim.yaml     | 84 ++++++++++++++++++-
 1 file changed, 83 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml +83 -1
index b2970734ffd7..bd12d5706291 100644
@@ -26,6 +26,7 @@ properties:
       - samsung,exynos5410-mipi-dsi
       - samsung,exynos5422-mipi-dsi
       - samsung,exynos5433-mipi-dsi
+      - fsl,imx8mm-mipi-dsim
 
   reg:
     maxItems: 1
@@ -39,6 +40,10 @@ properties:
   '#size-cells':
     const: 0
 
+  assigned-clock-parents: true
+  assigned-clock-rates: true
+  assigned-clocks: true
+
   clocks:
     minItems: 2
     maxItems: 5
@@ -102,7 +107,7 @@ properties:
         properties:
           endpoint@0:
             $ref: /schemas/graph.yaml#/properties/endpoint
-            description: sub-node describing the input from MIC
+            description: sub-node describing the input from MIC or LCDIF
 
         unevaluatedProperties: false
 
@@ -128,6 +133,30 @@ required:
 
 allOf:
   - $ref: ../dsi-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,imx8mm-mipi-dsim
+
+    then:
+      properties:
+        clocks:
+          minItems: 2
+
+        clock-names:
+          items:
+            - const: bus_clk
+            - const: sclk_mipi
+
+        ports:
+          required:
+            - port@0
+            - port@1
+
+      required:
+        - ports
+
   - if:
       properties:
         compatible:
@@ -221,6 +250,59 @@ additionalProperties:
   type: object
 
 examples:
+  - |
+    #include <dt-bindings/clock/imx8mm-clock.h>
+    #include <dt-bindings/power/imx8mm-power.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    dsi@32e10000 {
+       compatible = "fsl,imx8mm-mipi-dsim";
+       reg = <0x32e10000 0x400>;
+       clocks = <&clk IMX8MM_CLK_DSI_CORE>,
+                <&clk IMX8MM_CLK_DSI_PHY_REF>;
+       clock-names = "bus_clk", "sclk_mipi";
+       assigned-clocks = <&clk IMX8MM_CLK_DSI_CORE>,
+                         <&clk IMX8MM_VIDEO_PLL1_OUT>,
+                         <&clk IMX8MM_CLK_DSI_PHY_REF>;
+       assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_266M>,
+                         <&clk IMX8MM_VIDEO_PLL1_BYPASS>,
+                         <&clk IMX8MM_VIDEO_PLL1_OUT>;
+       assigned-clock-rates = <266000000>, <594000000>, <27000000>;
+       interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+       phys = <&mipi_phy 0>;
+       phy-names = "dsim";
+       power-domains = <&dispmix_blk_ctl IMX8MM_BLK_CTL_PD_DISPMIX_MIPI_DSI>;
+       samsung,burst-clock-frequency = <891000000>;
+       samsung,esc-clock-frequency = <54000000>;
+       samsung,pll-clock-frequency = <27000000>;
+       status = "disabled";
+
+       ports {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+          port@0 {
+             reg = <0>;
+             #address-cells = <1>;
+             #size-cells = <0>;
+
+             dsi_in_lcdif: endpoint@0 {
+                reg = <0>;
+                remote-endpoint = <&lcdif_out_dsi>;
+             };
+          };
+
+          port@1 {
+             reg = <1>;
+
+             dsi_out_panel: endpoint {
+                remote-endpoint = <&panel_in_dsi>;
+             };
+          };
+       };
+    };
+
   - |
     #include <dt-bindings/clock/exynos5433.h>
     #include <dt-bindings/gpio/gpio.h>
Signature · 1 line
2.25.1
maintainer
#30 lore raw

Re: [RFC PATCH 12/17] dt-bindings: display: bridge: samsung,mipi-dsim: Add i.MX8MM support

Quoted 23 lines · Jagan Teki

Samsung MIPI DSIM bridge can also be found in i.MX8MM SoC.

Add dt-bingings for it.

---
 .../display/bridge/samsung,mipi-dsim.yaml     | 84 ++++++++++++++++++-
 1 file changed, 83 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml +1 -0
index b2970734ffd7..bd12d5706291 100644
@@ -26,6 +26,7 @@ properties:
       - samsung,exynos5410-mipi-dsi
       - samsung,exynos5422-mipi-dsi
       - samsung,exynos5433-mipi-dsi
+      - fsl,imx8mm-mipi-dsim
 
   reg:
     maxItems: 1

Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml properties: · line 45

Quoted 6 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml +3 -0
@@ -39,6 +40,10 @@ properties:
   '#size-cells':
     const: 0
 
+  assigned-clock-parents: true
+  assigned-clock-rates: true
+  assigned-clocks: true

You don't need these. They are always allowed if 'clocks' is present.

Quoted 108 lines
Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml +79 -1
+
   clocks:
     minItems: 2
     maxItems: 5
@@ -102,7 +107,7 @@ properties:
         properties:
           endpoint@0:
             $ref: /schemas/graph.yaml#/properties/endpoint
-            description: sub-node describing the input from MIC
+            description: sub-node describing the input from MIC or LCDIF
 
         unevaluatedProperties: false
 
@@ -128,6 +133,30 @@ required:
 
 allOf:
   - $ref: ../dsi-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,imx8mm-mipi-dsim
+
+    then:
+      properties:
+        clocks:
+          minItems: 2
+
+        clock-names:
+          items:
+            - const: bus_clk
+            - const: sclk_mipi
+
+        ports:
+          required:
+            - port@0
+            - port@1
+
+      required:
+        - ports
+
   - if:
       properties:
         compatible:
@@ -221,6 +250,59 @@ additionalProperties:
   type: object
 
 examples:
+  - |
+    #include <dt-bindings/clock/imx8mm-clock.h>
+    #include <dt-bindings/power/imx8mm-power.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    dsi@32e10000 {
+       compatible = "fsl,imx8mm-mipi-dsim";
+       reg = <0x32e10000 0x400>;
+       clocks = <&clk IMX8MM_CLK_DSI_CORE>,
+                <&clk IMX8MM_CLK_DSI_PHY_REF>;
+       clock-names = "bus_clk", "sclk_mipi";
+       assigned-clocks = <&clk IMX8MM_CLK_DSI_CORE>,
+                         <&clk IMX8MM_VIDEO_PLL1_OUT>,
+                         <&clk IMX8MM_CLK_DSI_PHY_REF>;
+       assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_266M>,
+                         <&clk IMX8MM_VIDEO_PLL1_BYPASS>,
+                         <&clk IMX8MM_VIDEO_PLL1_OUT>;
+       assigned-clock-rates = <266000000>, <594000000>, <27000000>;
+       interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+       phys = <&mipi_phy 0>;
+       phy-names = "dsim";
+       power-domains = <&dispmix_blk_ctl IMX8MM_BLK_CTL_PD_DISPMIX_MIPI_DSI>;
+       samsung,burst-clock-frequency = <891000000>;
+       samsung,esc-clock-frequency = <54000000>;
+       samsung,pll-clock-frequency = <27000000>;
+       status = "disabled";
+
+       ports {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+          port@0 {
+             reg = <0>;
+             #address-cells = <1>;
+             #size-cells = <0>;
+
+             dsi_in_lcdif: endpoint@0 {
+                reg = <0>;
+                remote-endpoint = <&lcdif_out_dsi>;
+             };
+          };
+
+          port@1 {
+             reg = <1>;
+
+             dsi_out_panel: endpoint {
+                remote-endpoint = <&panel_in_dsi>;
+             };
+          };
+       };
+    };
+
   - |
     #include <dt-bindings/clock/exynos5433.h>
     #include <dt-bindings/gpio/gpio.h>
Signature · 1 line
2.25.1
author maintainer
#31 lore raw

RFC PATCH 13/17 drm: bridge: samsung-dsim: Add i.MX8MM support

In reply to Jagan Teki

Samsung MIPI DSIM bridge can also be found in i.MX8MM SoC.

Add compatible and associated driver_data it.

---
 drivers/gpu/drm/bridge/samsung-dsim.c | 31 +++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
drivers/gpu/drm/bridge/samsung-dsim.c +31 -0
index 9a2df1212d0f..ea379cb0cc32 100644
@@ -460,6 +460,24 @@ static const unsigned int exynos5433_reg_values[] = {
 	[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c),
 };
 
+static const unsigned int imx8mm_dsim_reg_values[] = {
+	[RESET_TYPE] = DSIM_SWRST,
+	[PLL_TIMER] = 500,
+	[STOP_STATE_CNT] = 0xf,
+	[PHYCTRL_ULPS_EXIT] = 0,
+	[PHYCTRL_VREG_LP] = 0,
+	[PHYCTRL_SLEW_UP] = 0,
+	[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),
+	[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0b),
+	[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x07),
+	[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x26),
+	[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d),
+	[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x08),
+	[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x08),
+	[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0d),
+	[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),
+};
+
 static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = {
 	.reg_ofs = exynos_reg_ofs,
 	.plltmr_reg = 0x50,
@@ -521,6 +539,17 @@ static const struct samsung_dsim_driver_data exynos5422_dsi_driver_data = {
 	.exynos_specific = true,
 };
 
+static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {
+	.reg_ofs = exynos5433_reg_ofs,
+	.plltmr_reg = 0xa0,
+	.has_clklane_stop = 1,
+	.num_clks = 2,
+	.max_freq = 2100,
+	.wait_for_reset = 0,
+	.num_bits_resol = 12,
+	.reg_values = imx8mm_dsim_reg_values,
+};
+
 static const struct of_device_id samsung_dsim_of_match[] = {
 	{ .compatible = "samsung,exynos3250-mipi-dsi",
 	  .data = &exynos3_dsi_driver_data },
@@ -532,6 +561,8 @@ static const struct of_device_id samsung_dsim_of_match[] = {
 	  .data = &exynos5422_dsi_driver_data },
 	{ .compatible = "samsung,exynos5433-mipi-dsi",
 	  .data = &exynos5433_dsi_driver_data },
+	{ .compatible = "fsl,imx8mm-mipi-dsim",
+	  .data = &imx8mm_dsi_driver_data },
 	{ }
 };
 
Signature · 1 line
2.25.1
author maintainer
#32 lore raw

RFC PATCH 14/17 drm: bridge: samsung-dsim: Add input_bus_flags

In reply to Jagan Teki

eLCDIF is expecting to have input_bus_flags as DE_LOW in order to set active low during valid data transfer on each horizontal line.

Add DE_LOW flag via drm bridge timings.

---
 drivers/gpu/drm/bridge/samsung-dsim.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/gpu/drm/bridge/samsung-dsim.c +5 -0
index ea379cb0cc32..bc845ae100d4 100644
@@ -1723,6 +1723,10 @@ static const struct component_ops samsung_dsim_component_ops = {
 	.unbind	= samsung_dsim_unbind,
 };
 
+static const struct drm_bridge_timings samsung_dsim_bridge_timings = {
+	.input_bus_flags = DRM_BUS_FLAG_DE_LOW,
+};
+
 static int samsung_dsim_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1819,6 +1823,7 @@ static int samsung_dsim_probe(struct platform_device *pdev)
 
 	dsi->bridge.funcs = &samsung_dsim_bridge_funcs;
 	dsi->bridge.of_node = dev->of_node;
+	dsi->bridge.timings = &samsung_dsim_bridge_timings;
 	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
 	drm_bridge_add(&dsi->bridge);
Signature · 1 line
2.25.1
author maintainer
#33 lore raw

RFC PATCH 15/17 drm: bridge: samsung-dsim: Move DSI init in bridge enable

In reply to Jagan Teki

Host transfer in DSI master will invoke only when the DSI commands sent from DSI devices like DSI Panel or DSI bridges and this host transfer wouldn't invoke I2C based DSI bridge drivers.

Handling DSI host initialization in transfer calls might miss the controller setup for I2C based DSI bridges.

So, move the DSI initialization from transfer to bridge enable as the bridge enable API as it is common across all classes of DSI device drivers.

---
 drivers/gpu/drm/bridge/samsung-dsim.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/gpu/drm/bridge/samsung-dsim.c +7 -7
index bc845ae100d4..54767cbf231c 100644
@@ -1437,6 +1437,13 @@ static void samsung_dsim_bridge_enable(struct drm_bridge *bridge)
 
 	dsi->state |= DSIM_STATE_ENABLED;
 
+	if (!(dsi->state & DSIM_STATE_INITIALIZED)) {
+		ret = samsung_dsim_init(dsi);
+		if (ret)
+			return;
+		dsi->state |= DSIM_STATE_INITIALIZED;
+	}
+
 	samsung_dsim_set_display_mode(dsi);
 	samsung_dsim_set_display_enable(dsi, true);
 
@@ -1602,13 +1609,6 @@ static ssize_t samsung_dsim_host_transfer(struct mipi_dsi_host *host,
 	if (!(dsi->state & DSIM_STATE_ENABLED))
 		return -EINVAL;
 
-	if (!(dsi->state & DSIM_STATE_INITIALIZED)) {
-		ret = samsung_dsim_init(dsi);
-		if (ret)
-			return ret;
-		dsi->state |= DSIM_STATE_INITIALIZED;
-	}
-
 	ret = mipi_dsi_create_packet(&xfer.packet, msg);
 	if (ret < 0)
 		return ret;
Signature · 1 line
2.25.1
author maintainer
#34 lore raw

RFC PATCH 16/17 drm: bridge: samsung-dsim: Fix PLL_P offset

In reply to Jagan Teki

PMS_P offset value in existing driver is not compatible with i.MX8MM.

However the i.MX8M Mini Application Reference manual shows the PMS_P offset is the same in the driver, but the i.MX8MM downstream driver uses a different one.

So, handle the PMS_P offset via driver_data and use the offset value for i.MX8MM from the downstream driver.

---
 drivers/gpu/drm/bridge/samsung-dsim.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/samsung-dsim.c +10 -2
index 54767cbf231c..0ed218f5eefc 100644
@@ -184,7 +184,7 @@
 /* DSIM_PLLCTRL */
 #define DSIM_FREQ_BAND(x)		((x) << 24)
 #define DSIM_PLL_EN			(1 << 23)
-#define DSIM_PLL_P(x)			((x) << 13)
+#define DSIM_PLL_P(x, offset)		((x) << (offset))
 #define DSIM_PLL_M(x)			((x) << 4)
 #define DSIM_PLL_S(x)			((x) << 1)
 
@@ -259,6 +259,7 @@ struct samsung_dsim_driver_data {
 	unsigned int max_freq;
 	unsigned int wait_for_reset;
 	unsigned int num_bits_resol;
+	unsigned int pll_p_offset;
 	const unsigned int *reg_values;
 	bool exynos_specific;
 };
@@ -487,6 +488,7 @@ static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = {
 	.max_freq = 1000,
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
+	.pll_p_offset = 13,
 	.reg_values = reg_values,
 	.exynos_specific = true,
 };
@@ -500,6 +502,7 @@ static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = {
 	.max_freq = 1000,
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
+	.pll_p_offset = 13,
 	.reg_values = reg_values,
 	.exynos_specific = true,
 };
@@ -511,6 +514,7 @@ static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = {
 	.max_freq = 1000,
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
+	.pll_p_offset = 13,
 	.reg_values = reg_values,
 	.exynos_specific = true,
 };
@@ -523,6 +527,7 @@ static const struct samsung_dsim_driver_data exynos5433_dsi_driver_data = {
 	.max_freq = 1500,
 	.wait_for_reset = 0,
 	.num_bits_resol = 12,
+	.pll_p_offset = 13,
 	.reg_values = exynos5433_reg_values,
 	.exynos_specific = true,
 };
@@ -535,6 +540,7 @@ static const struct samsung_dsim_driver_data exynos5422_dsi_driver_data = {
 	.max_freq = 1500,
 	.wait_for_reset = 1,
 	.num_bits_resol = 12,
+	.pll_p_offset = 13,
 	.reg_values = exynos5422_reg_values,
 	.exynos_specific = true,
 };
@@ -547,6 +553,7 @@ static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {
 	.max_freq = 2100,
 	.wait_for_reset = 0,
 	.num_bits_resol = 12,
+	.pll_p_offset = 14,
 	.reg_values = imx8mm_dsim_reg_values,
 };
 
@@ -662,7 +669,8 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi,
 	writel(driver_data->reg_values[PLL_TIMER],
 			dsi->reg_base + driver_data->plltmr_reg);
 
-	reg = DSIM_PLL_EN | DSIM_PLL_P(p) | DSIM_PLL_M(m) | DSIM_PLL_S(s);
+	reg = DSIM_PLL_EN | DSIM_PLL_P(p, driver_data->pll_p_offset) |
+	      DSIM_PLL_M(m) | DSIM_PLL_S(s);
 
 	if (driver_data->has_freqband) {
 		static const unsigned long freq_bands[] = {
Signature · 1 line
2.25.1
#35 lore raw

Re: [RFC PATCH 16/17] drm: bridge: samsung-dsim: Fix PLL_P offset

Hi Jagan,

Quoted 11 lines · Jagan Teki

PMS_P offset value in existing driver is not compatible with i.MX8MM.

However the i.MX8M Mini Application Reference manual shows the PMS_P offset is the same in the driver, but the i.MX8MM downstream driver uses a different one.

So, handle the PMS_P offset via driver_data and use the offset value for i.MX8MM from the downstream driver.

$subject and code speaks of PLL but the changelog says PMS. I think the changelog needs a small update here.

Sam

Quoted 85 lines
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/samsung-dsim.c +10 -2
index 54767cbf231c..0ed218f5eefc 100644
@@ -184,7 +184,7 @@
 /* DSIM_PLLCTRL */
 #define DSIM_FREQ_BAND(x)		((x) << 24)
 #define DSIM_PLL_EN			(1 << 23)
-#define DSIM_PLL_P(x)			((x) << 13)
+#define DSIM_PLL_P(x, offset)		((x) << (offset))
 #define DSIM_PLL_M(x)			((x) << 4)
 #define DSIM_PLL_S(x)			((x) << 1)
 
@@ -259,6 +259,7 @@ struct samsung_dsim_driver_data {
 	unsigned int max_freq;
 	unsigned int wait_for_reset;
 	unsigned int num_bits_resol;
+	unsigned int pll_p_offset;
 	const unsigned int *reg_values;
 	bool exynos_specific;
 };
@@ -487,6 +488,7 @@ static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = {
 	.max_freq = 1000,
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
+	.pll_p_offset = 13,
 	.reg_values = reg_values,
 	.exynos_specific = true,
 };
@@ -500,6 +502,7 @@ static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = {
 	.max_freq = 1000,
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
+	.pll_p_offset = 13,
 	.reg_values = reg_values,
 	.exynos_specific = true,
 };
@@ -511,6 +514,7 @@ static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = {
 	.max_freq = 1000,
 	.wait_for_reset = 1,
 	.num_bits_resol = 11,
+	.pll_p_offset = 13,
 	.reg_values = reg_values,
 	.exynos_specific = true,
 };
@@ -523,6 +527,7 @@ static const struct samsung_dsim_driver_data exynos5433_dsi_driver_data = {
 	.max_freq = 1500,
 	.wait_for_reset = 0,
 	.num_bits_resol = 12,
+	.pll_p_offset = 13,
 	.reg_values = exynos5433_reg_values,
 	.exynos_specific = true,
 };
@@ -535,6 +540,7 @@ static const struct samsung_dsim_driver_data exynos5422_dsi_driver_data = {
 	.max_freq = 1500,
 	.wait_for_reset = 1,
 	.num_bits_resol = 12,
+	.pll_p_offset = 13,
 	.reg_values = exynos5422_reg_values,
 	.exynos_specific = true,
 };
@@ -547,6 +553,7 @@ static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {
 	.max_freq = 2100,
 	.wait_for_reset = 0,
 	.num_bits_resol = 12,
+	.pll_p_offset = 14,
 	.reg_values = imx8mm_dsim_reg_values,
 };
 
@@ -662,7 +669,8 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi,
 	writel(driver_data->reg_values[PLL_TIMER],
 			dsi->reg_base + driver_data->plltmr_reg);
 
-	reg = DSIM_PLL_EN | DSIM_PLL_P(p) | DSIM_PLL_M(m) | DSIM_PLL_S(s);
+	reg = DSIM_PLL_EN | DSIM_PLL_P(p, driver_data->pll_p_offset) |
+	      DSIM_PLL_M(m) | DSIM_PLL_S(s);
 
 	if (driver_data->has_freqband) {
 		static const unsigned long freq_bands[] = {
Signature · 1 line
2.25.1
author maintainer
#36 lore raw

RFC PATCH 17/17 drm: bridge: samsung-dsim: Add bridge mode_fixup

In reply to Jagan Teki

Fixing up the mode flags are required in order to correlate the correct sync flags in i.MX8MM eLCDIF.

So, handle the mode flags via bridge, mode_fixup.

---
 drivers/gpu/drm/bridge/samsung-dsim.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/gpu/drm/bridge/samsung-dsim.c +11 -0
index 0ed218f5eefc..c2a76ee5ac4e 100644
@@ -1474,6 +1474,16 @@ static void samsung_dsim_bridge_disable(struct drm_bridge *bridge)
 	pm_runtime_put_sync(dsi->dev);
 }
 
+static bool samsung_dsim_bridge_mode_fixup(struct drm_bridge *bridge,
+					   const struct drm_display_mode *mode,
+					   struct drm_display_mode *adjusted_mode)
+{
+	adjusted_mode->flags |= (DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
+	adjusted_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+
+	return true;
+}
+
 static void samsung_dsim_bridge_mode_set(struct drm_bridge *bridge,
 					 const struct drm_display_mode *mode,
 					 const struct drm_display_mode *adjusted_mode)
@@ -1542,6 +1552,7 @@ static const struct drm_bridge_funcs samsung_dsim_bridge_funcs = {
 	.enable = samsung_dsim_bridge_enable,
 	.disable = samsung_dsim_bridge_disable,
 	.mode_set = samsung_dsim_bridge_mode_set,
+	.mode_fixup = samsung_dsim_bridge_mode_fixup,
 	.attach = samsung_dsim_bridge_attach,
 };
 
Signature · 1 line
2.25.1
#37 lore raw

Re: [RFC PATCH 17/17] drm: bridge: samsung-dsim: Add bridge mode_fixup

Hi Jagan,

Quoted 4 lines · Jagan Teki

Fixing up the mode flags are required in order to correlate the correct sync flags in i.MX8MM eLCDIF.

So, handle the mode flags via bridge, mode_fixup.

Please do this in atomic_check.
Check rcar-du for a way to get access to adjusted_mode.

I have a helper in the works, but I may not return to it until a week or more.

Sam

Quoted 37 lines
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/gpu/drm/bridge/samsung-dsim.c +11 -0
index 0ed218f5eefc..c2a76ee5ac4e 100644
@@ -1474,6 +1474,16 @@ static void samsung_dsim_bridge_disable(struct drm_bridge *bridge)
 	pm_runtime_put_sync(dsi->dev);
 }
 
+static bool samsung_dsim_bridge_mode_fixup(struct drm_bridge *bridge,
+					   const struct drm_display_mode *mode,
+					   struct drm_display_mode *adjusted_mode)
+{
+	adjusted_mode->flags |= (DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
+	adjusted_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+
+	return true;
+}
+
 static void samsung_dsim_bridge_mode_set(struct drm_bridge *bridge,
 					 const struct drm_display_mode *mode,
 					 const struct drm_display_mode *adjusted_mode)
@@ -1542,6 +1552,7 @@ static const struct drm_bridge_funcs samsung_dsim_bridge_funcs = {
 	.enable = samsung_dsim_bridge_enable,
 	.disable = samsung_dsim_bridge_disable,
 	.mode_set = samsung_dsim_bridge_mode_set,
+	.mode_fixup = samsung_dsim_bridge_mode_fixup,
 	.attach = samsung_dsim_bridge_attach,
 };
 
Signature · 1 line
2.25.1
#38 lore raw
In reply to Jagan Teki

Hi Jagan,

Quoted 23 lines · Jagan Teki

This series supports common bridge support for Samsung MIPI DSIM which is used in Exynos and i.MX8MM SoC's.

The final bridge supports both the Exynos and i.MX8MM DSI devices.

Right now bridge offers two sets of implementations.

A. With component_ops and exynos specific code exclusively for exynos dsi drivers and it's legacy bindings.

B. Without componenet_ops for newly implemented bridges and its users like i.MX8MM.

The future plan is to fix the implementation A) by dropping component_ops and fixing exynos specific code in order to make the bridge more mature to use and the same is mentioned in drivers TODO.

Patch 0001 - 0006: Bridge conversion
Patch 0007 - 0017: Samsung MIPI DSIM bridge fixes, additions

Tested in Engicam i.Core MX8M Mini SoM.

Quoted 7 lines

Anyone interest, please have a look on this repo
https://github.com/openedev/linux/tree/070421-imx8mm-dsim

Would appreciate anyone from the exynos team to test it on the exynos platform?

Any inputs?

I really like where you are headign with this!
No testing - sorry. But I will try to provide a bit of feedback on the individual patches.

I hope you find a way to move forward with this.

Sam

author maintainer
#39 lore raw

Hi Sam,

Quoted 33 lines · Sam Ravnborg

Hi Jagan,

Quoted 29 lines · Jagan Teki

This series supports common bridge support for Samsung MIPI DSIM which is used in Exynos and i.MX8MM SoC's.

The final bridge supports both the Exynos and i.MX8MM DSI devices.

Right now bridge offers two sets of implementations.

A. With component_ops and exynos specific code exclusively for
exynos dsi drivers and it's legacy bindings.

B. Without componenet_ops for newly implemented bridges and its
users like i.MX8MM.

The future plan is to fix the implementation A) by dropping component_ops and fixing exynos specific code in order to make the bridge more mature to use and the same is mentioned in drivers TODO.

Patch 0001 - 0006: Bridge conversion
Patch 0007 - 0017: Samsung MIPI DSIM bridge fixes, additions

Tested in Engicam i.Core MX8M Mini SoM.

Anyone interest, please have a look on this repo
https://github.com/openedev/linux/tree/070421-imx8mm-dsim

Would appreciate anyone from the exynos team to test it on the exynos platform?

Quoted 7 lines
Quoted 1 line

Any inputs?

I really like where you are headign with this!
No testing - sorry. But I will try to provide a bit of feedback on the individual patches.

I hope you find a way to move forward with this.

Thanks for the response.

We have found some issues with Bridge conversion on existing exynos drivers. The component based DSI drivers(like exynos) are difficult to attach if it involves kms hotplug. kms hotplug would require drm pointer and that pointer would only available after the bind call finishes. But the bridge attach in bind call will defer till it find the attached bridge.

Right now I'm trying to find the proper way to attach the bridges for component based DSI drivers which involves kms hot-plug.

If you have any ideas on this, please let me know.

Thanks,
Jagan.

#40 lore raw
Quoted 54 lines · Jagan Teki

Hi Sam,

Quoted 33 lines · Sam Ravnborg

Hi Jagan,

Quoted 29 lines · Jagan Teki

This series supports common bridge support for Samsung MIPI DSIM which is used in Exynos and i.MX8MM SoC's.

The final bridge supports both the Exynos and i.MX8MM DSI devices.

Right now bridge offers two sets of implementations.

A. With component_ops and exynos specific code exclusively for
exynos dsi drivers and it's legacy bindings.

B. Without componenet_ops for newly implemented bridges and its
users like i.MX8MM.

The future plan is to fix the implementation A) by dropping component_ops and fixing exynos specific code in order to make the bridge more mature to use and the same is mentioned in drivers TODO.

Patch 0001 - 0006: Bridge conversion
Patch 0007 - 0017: Samsung MIPI DSIM bridge fixes, additions

Tested in Engicam i.Core MX8M Mini SoM.

Anyone interest, please have a look on this repo
https://github.com/openedev/linux/tree/070421-imx8mm-dsim

Would appreciate anyone from the exynos team to test it on the exynos platform?

Quoted 7 lines
Quoted 1 line

Any inputs?

I really like where you are headign with this!
No testing - sorry. But I will try to provide a bit of feedback on the individual patches.

I hope you find a way to move forward with this.

Thanks for the response.

We have found some issues with Bridge conversion on existing exynos drivers. The component based DSI drivers(like exynos) are difficult to attach if it involves kms hotplug. kms hotplug would require drm pointer and that pointer would only available after the bind call finishes. But the bridge attach in bind call will defer till it find the attached bridge.

Quoted 5 lines

Right now I'm trying to find the proper way to attach the bridges for component based DSI drivers which involves kms hot-plug.

If you have any ideas on this, please let me know.

Jagan,

How is your progress on this series? Looking at your repo it looks like you've rebased on top of 5.13-rc3 in your 070121-imx8mm-dsim branch but you've got a lot of things there that are likely not related to this series?

Best regards,

Tim

#41 lore raw

Hi Tim

Quoted 62 lines · Tim Harvey
Quoted 54 lines · Jagan Teki

Hi Sam,

Quoted 33 lines · Sam Ravnborg

Hi Jagan,

Quoted 29 lines · Jagan Teki

This series supports common bridge support for Samsung MIPI DSIM which is used in Exynos and i.MX8MM SoC's.

The final bridge supports both the Exynos and i.MX8MM DSI devices.

Right now bridge offers two sets of implementations.

A. With component_ops and exynos specific code exclusively for
exynos dsi drivers and it's legacy bindings.

B. Without componenet_ops for newly implemented bridges and its
users like i.MX8MM.

The future plan is to fix the implementation A) by dropping component_ops and fixing exynos specific code in order to make the bridge more mature to use and the same is mentioned in drivers TODO.

Patch 0001 - 0006: Bridge conversion
Patch 0007 - 0017: Samsung MIPI DSIM bridge fixes, additions

Tested in Engicam i.Core MX8M Mini SoM.

Anyone interest, please have a look on this repo
https://github.com/openedev/linux/tree/070421-imx8mm-dsim

Would appreciate anyone from the exynos team to test it on the exynos platform?

Quoted 7 lines
Quoted 1 line

Any inputs?

I really like where you are headign with this!
No testing - sorry. But I will try to provide a bit of feedback on the individual patches.

I hope you find a way to move forward with this.

Thanks for the response.

We have found some issues with Bridge conversion on existing exynos drivers. The component based DSI drivers(like exynos) are difficult to attach if it involves kms hotplug. kms hotplug would require drm pointer and that pointer would only available after the bind call finishes. But the bridge attach in bind call will defer till it find the attached bridge.

Quoted 5 lines

Right now I'm trying to find the proper way to attach the bridges for component based DSI drivers which involves kms hot-plug.

If you have any ideas on this, please let me know.

Quoted 6 lines

Jagan,

How is your progress on this series? Looking at your repo it looks like you've rebased on top of 5.13-rc3 in your 070121-imx8mm-dsim branch but you've got a lot of things there that are likely not related to this series?

I have a bit of work on those patches and tested on imx8mn. Basically:

- add the dsi timing calculation
- change few difference with samsung bridge
- fix crashes of my dsi panels
- compare with NXP driver the final results

I found that I have one problem that gives me some instability. In the NXP original driver the panel needs to be
enabled in bridge_enable before out the standby. If I understand correctly, our standby should be done after.
I would like to have some feedback and help and testing on other boards/devices and some suggestions on how to handle
some of the differences. Another big problem is etnavi that is not stable

Michael

Quoted 6 lines

Best regards,

Tim

Signature · 11 lines
Michael Nazzareno Trimarchi
Co-Founder & Chief Executive Officer
M. +39 347 913 2170
[email protected]
__________________________________

Amarula Solutions BV
Joop Geesinkweg 125, 1114 AB, Amsterdam, NL
T. +31 (0)85 111 9172
[email protected]
www.amarulasolutions.com
#42 lore raw
Quoted 80 lines · Michael Nazzareno Trimarchi

Hi Tim

Quoted 62 lines · Tim Harvey
Quoted 54 lines · Jagan Teki

Hi Sam,

Quoted 33 lines · Sam Ravnborg

Hi Jagan,

Quoted 29 lines · Jagan Teki

This series supports common bridge support for Samsung MIPI DSIM which is used in Exynos and i.MX8MM SoC's.

The final bridge supports both the Exynos and i.MX8MM DSI devices.

Right now bridge offers two sets of implementations.

A. With component_ops and exynos specific code exclusively for
exynos dsi drivers and it's legacy bindings.

B. Without componenet_ops for newly implemented bridges and its
users like i.MX8MM.

The future plan is to fix the implementation A) by dropping component_ops and fixing exynos specific code in order to make the bridge more mature to use and the same is mentioned in drivers TODO.

Patch 0001 - 0006: Bridge conversion
Patch 0007 - 0017: Samsung MIPI DSIM bridge fixes, additions

Tested in Engicam i.Core MX8M Mini SoM.

Anyone interest, please have a look on this repo
https://github.com/openedev/linux/tree/070421-imx8mm-dsim

Would appreciate anyone from the exynos team to test it on the exynos platform?

Quoted 7 lines
Quoted 1 line

Any inputs?

I really like where you are headign with this!
No testing - sorry. But I will try to provide a bit of feedback on the individual patches.

I hope you find a way to move forward with this.

Thanks for the response.

We have found some issues with Bridge conversion on existing exynos drivers. The component based DSI drivers(like exynos) are difficult to attach if it involves kms hotplug. kms hotplug would require drm pointer and that pointer would only available after the bind call finishes. But the bridge attach in bind call will defer till it find the attached bridge.

Quoted 5 lines

Right now I'm trying to find the proper way to attach the bridges for component based DSI drivers which involves kms hot-plug.

If you have any ideas on this, please let me know.

Quoted 6 lines

Jagan,

How is your progress on this series? Looking at your repo it looks like you've rebased on top of 5.13-rc3 in your 070121-imx8mm-dsim branch but you've got a lot of things there that are likely not related to this series?

I have a bit of work on those patches and tested on imx8mn. Basically:

- add the dsi timing calculation
- change few difference with samsung bridge
- fix crashes of my dsi panels
- compare with NXP driver the final results

Quoted 8 lines

I found that I have one problem that gives me some instability. In the NXP original driver the panel needs to be
enabled in bridge_enable before out the standby. If I understand correctly, our standby should be done after.
I would like to have some feedback and help and testing on other boards/devices and some suggestions on how to handle
some of the differences. Another big problem is etnavi that is not stable

Michael,

Where can I find your patches?

What do you mean by etnaviv not being stable?

I did some limited testing with etnaviv on imx8mm with 5.15 + dsi patches on an Ubuntu focal root filesystem by:
apt update
apt install gnome-session gnome-terminal
^^^ 2D hardware acceleration appears to be working (dragging opaque windows around)
apt install mesa-utils glmark2
glxgears
^^^ ~160fps on IMX8MM
glmark2
^^^ score of 39 on IMX8MM

I haven't seen any updates from Jagan since Nov 24
(https://www.spinics.net/lists/dri-devel/msg324059.html) and am not sure if he's been able to work through drm/exynos issues that have been blocking his progress.

Best regards,

Tim

#43 lore raw

Hi Tim

Quoted 92 lines · Tim Harvey
Quoted 80 lines · Michael Nazzareno Trimarchi

Hi Tim

Quoted 62 lines · Tim Harvey
Quoted 54 lines · Jagan Teki

Hi Sam,

Quoted 33 lines · Sam Ravnborg

Hi Jagan,

Quoted 29 lines · Jagan Teki

This series supports common bridge support for Samsung MIPI DSIM which is used in Exynos and i.MX8MM SoC's.

The final bridge supports both the Exynos and i.MX8MM DSI devices.

Right now bridge offers two sets of implementations.

A. With component_ops and exynos specific code exclusively for
exynos dsi drivers and it's legacy bindings.

B. Without componenet_ops for newly implemented bridges and its
users like i.MX8MM.

The future plan is to fix the implementation A) by dropping component_ops and fixing exynos specific code in order to make the bridge more mature to use and the same is mentioned in drivers TODO.

Patch 0001 - 0006: Bridge conversion
Patch 0007 - 0017: Samsung MIPI DSIM bridge fixes, additions

Tested in Engicam i.Core MX8M Mini SoM.

Anyone interest, please have a look on this repo
https://github.com/openedev/linux/tree/070421-imx8mm-dsim

Would appreciate anyone from the exynos team to test it on the exynos platform?

Quoted 7 lines
Quoted 1 line

Any inputs?

I really like where you are headign with this!
No testing - sorry. But I will try to provide a bit of feedback on the individual patches.

I hope you find a way to move forward with this.

Thanks for the response.

We have found some issues with Bridge conversion on existing exynos drivers. The component based DSI drivers(like exynos) are difficult to attach if it involves kms hotplug. kms hotplug would require drm pointer and that pointer would only available after the bind call finishes. But the bridge attach in bind call will defer till it find the attached bridge.

Quoted 5 lines

Right now I'm trying to find the proper way to attach the bridges for component based DSI drivers which involves kms hot-plug.

If you have any ideas on this, please let me know.

Quoted 6 lines

Jagan,

How is your progress on this series? Looking at your repo it looks like you've rebased on top of 5.13-rc3 in your 070121-imx8mm-dsim branch but you've got a lot of things there that are likely not related to this series?

I have a bit of work on those patches and tested on imx8mn. Basically:

- add the dsi timing calculation
- change few difference with samsung bridge
- fix crashes of my dsi panels
- compare with NXP driver the final results

Quoted 8 lines

I found that I have one problem that gives me some instability. In the NXP original driver the panel needs to be
enabled in bridge_enable before out the standby. If I understand correctly, our standby should be done after.
I would like to have some feedback and help and testing on other boards/devices and some suggestions on how to handle
some of the differences. Another big problem is etnavi that is not stable

Quoted 4 lines

Michael,

Where can I find your patches?

I will push on some tree and share

Quoted 17 lines

What do you mean by etnaviv not being stable?

I did some limited testing with etnaviv on imx8mm with 5.15 + dsi

patches on an Ubuntu focal root filesystem by:
apt update
apt install gnome-session gnome-terminal
^^^ 2D hardware acceleration appears to be working (dragging opaque windows around)
apt install mesa-utils glmark2
glxgears
^^^ ~160fps on IMX8MM
glmark2
^^^ score of 39 on IMX8MM

Quoted 4 lines

I haven't seen any updates from Jagan since Nov 24
(https://www.spinics.net/lists/dri-devel/msg324059.html) and am not sure if he's been able to work through drm/exynos issues that have been blocking his progress.

I plan to push on github

[17:07:42.315] Sending ready to systemd

[  214.052085] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  214.595998] etnaviv-gpu 38000000.gpu: recover hung GPU!

** (maynard:386): WARNING **: 17:07:43.874: failed to setup mixer: Success [17:07:44.175] Added surface 0xaaab02630440, app_id (null) to pending list [17:07:44.176] Added surface 0xaaab026172b0, app_id (null) to pending list ** Message: 17:07:44.289: New advertisement app id maynard
** Message: 17:07:44.290: New advertisement app id maynard [17:07:45.171] (background) position view 0xaaab0261f860, x 0, y 0, on output DSI-1
[17:07:45.171] (panel) geom.width 100, geom.height 480, geom.x 0, geom.y 0 [17:07:45.171] (panel) edge 2 position view 0xaaab02634510, x 0, y 0 [17:07:45.172] panel type 2 inited on output DSI-1 [17:07:45.172] Usable area: 380x480+100,0

[  216.932080] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  217.476015] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  218.020157] etnaviv-gpu 38000000.gpu: recover hung GPU!

This is my problem on imx8mn

Michael

Michael

Quoted 3 lines

Best regards,

Tim

--
Michael Nazzareno Trimarchi
Co-Founder & Chief Executive Officer
M. +39 347 913 2170
[email protected]
__________________________________

Amarula Solutions BV
Joop Geesinkweg 125, 1114 AB, Amsterdam, NL
T. +31 (0)85 111 9172
[email protected]
www.amarulasolutions.com

#44 lore raw
Quoted 142 lines · Michael Nazzareno Trimarchi

Hi Tim

Quoted 92 lines · Tim Harvey
Quoted 80 lines · Michael Nazzareno Trimarchi

Hi Tim

Quoted 62 lines · Tim Harvey
Quoted 54 lines · Jagan Teki

Hi Sam,

Quoted 33 lines · Sam Ravnborg

Hi Jagan,

Quoted 29 lines · Jagan Teki

This series supports common bridge support for Samsung MIPI DSIM which is used in Exynos and i.MX8MM SoC's.

The final bridge supports both the Exynos and i.MX8MM DSI devices.

Right now bridge offers two sets of implementations.

A. With component_ops and exynos specific code exclusively for
exynos dsi drivers and it's legacy bindings.

B. Without componenet_ops for newly implemented bridges and its
users like i.MX8MM.

The future plan is to fix the implementation A) by dropping component_ops and fixing exynos specific code in order to make the bridge more mature to use and the same is mentioned in drivers TODO.

Patch 0001 - 0006: Bridge conversion
Patch 0007 - 0017: Samsung MIPI DSIM bridge fixes, additions

Tested in Engicam i.Core MX8M Mini SoM.

Anyone interest, please have a look on this repo
https://github.com/openedev/linux/tree/070421-imx8mm-dsim

Would appreciate anyone from the exynos team to test it on the exynos platform?

Quoted 7 lines
Quoted 1 line

Any inputs?

I really like where you are headign with this!
No testing - sorry. But I will try to provide a bit of feedback on the individual patches.

I hope you find a way to move forward with this.

Thanks for the response.

We have found some issues with Bridge conversion on existing exynos drivers. The component based DSI drivers(like exynos) are difficult to attach if it involves kms hotplug. kms hotplug would require drm pointer and that pointer would only available after the bind call finishes. But the bridge attach in bind call will defer till it find the attached bridge.

Quoted 5 lines

Right now I'm trying to find the proper way to attach the bridges for component based DSI drivers which involves kms hot-plug.

If you have any ideas on this, please let me know.

Quoted 6 lines

Jagan,

How is your progress on this series? Looking at your repo it looks like you've rebased on top of 5.13-rc3 in your 070121-imx8mm-dsim branch but you've got a lot of things there that are likely not related to this series?

I have a bit of work on those patches and tested on imx8mn. Basically:

- add the dsi timing calculation
- change few difference with samsung bridge
- fix crashes of my dsi panels
- compare with NXP driver the final results

Quoted 8 lines

I found that I have one problem that gives me some instability. In the NXP original driver the panel needs to be
enabled in bridge_enable before out the standby. If I understand correctly, our standby should be done after.
I would like to have some feedback and help and testing on other boards/devices and some suggestions on how to handle
some of the differences. Another big problem is etnavi that is not stable

Quoted 4 lines

Michael,

Where can I find your patches?

I will push on some tree and share

Quoted 17 lines

What do you mean by etnaviv not being stable?

I did some limited testing with etnaviv on imx8mm with 5.15 + dsi

patches on an Ubuntu focal root filesystem by:
apt update
apt install gnome-session gnome-terminal
^^^ 2D hardware acceleration appears to be working (dragging opaque windows around)
apt install mesa-utils glmark2
glxgears
^^^ ~160fps on IMX8MM
glmark2
^^^ score of 39 on IMX8MM

Quoted 4 lines

I haven't seen any updates from Jagan since Nov 24
(https://www.spinics.net/lists/dri-devel/msg324059.html) and am not sure if he's been able to work through drm/exynos issues that have been blocking his progress.

I plan to push on github

[17:07:42.315] Sending ready to systemd

[  214.052085] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  214.595998] etnaviv-gpu 38000000.gpu: recover hung GPU!

** (maynard:386): WARNING **: 17:07:43.874: failed to setup mixer: Success [17:07:44.175] Added surface 0xaaab02630440, app_id (null) to pending list [17:07:44.176] Added surface 0xaaab026172b0, app_id (null) to pending list ** Message: 17:07:44.289: New advertisement app id maynard
** Message: 17:07:44.290: New advertisement app id maynard [17:07:45.171] (background) position view 0xaaab0261f860, x 0, y 0, on output DSI-1
[17:07:45.171] (panel) geom.width 100, geom.height 480, geom.x 0, geom.y 0 [17:07:45.171] (panel) edge 2 position view 0xaaab02634510, x 0, y 0 [17:07:45.172] panel type 2 inited on output DSI-1 [17:07:45.172] Usable area: 380x480+100,0

Quoted 6 lines
[  216.932080] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  217.476015] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  218.020157] etnaviv-gpu 38000000.gpu: recover hung GPU!

This is my problem on imx8mn

Do you have an imx8mm to compare with? Unfortunately I do not have an imx8mn with a MIPI DSI connector and can only test with imx8mm.

What software (other than kernel which you will share) do you have installed above and how is it configured or run to show the issue?

Best regards,

Tim

#45 lore raw
In reply to Michael Nazzareno Trimarchi

Am Donnerstag, dem 09.12.2021 um 18:09 +0100 schrieb Michael Nazzareno Trimarchi:

Quoted 141 lines

Hi Tim

Quoted 92 lines · Tim Harvey
Quoted 80 lines · Michael Nazzareno Trimarchi

Hi Tim

Quoted 62 lines · Tim Harvey
Quoted 54 lines · Jagan Teki

Hi Sam,

Quoted 33 lines · Sam Ravnborg

Hi Jagan,

Quoted 29 lines · Jagan Teki

This series supports common bridge support for Samsung MIPI DSIM which is used in Exynos and i.MX8MM SoC's.

The final bridge supports both the Exynos and i.MX8MM DSI devices.

Right now bridge offers two sets of implementations.

A. With component_ops and exynos specific code exclusively for
exynos dsi drivers and it's legacy bindings.

B. Without componenet_ops for newly implemented bridges and its
users like i.MX8MM.

The future plan is to fix the implementation A) by dropping component_ops and fixing exynos specific code in order to make the bridge more mature to use and the same is mentioned in drivers TODO.

Patch 0001 - 0006: Bridge conversion
Patch 0007 - 0017: Samsung MIPI DSIM bridge fixes, additions

Tested in Engicam i.Core MX8M Mini SoM.

Anyone interest, please have a look on this repo
https://github.com/openedev/linux/tree/070421-imx8mm-dsim

Would appreciate anyone from the exynos team to test it on the exynos platform?

Quoted 7 lines
Quoted 1 line

Any inputs?

I really like where you are headign with this!
No testing - sorry. But I will try to provide a bit of feedback on the individual patches.

I hope you find a way to move forward with this.

Thanks for the response.

We have found some issues with Bridge conversion on existing exynos drivers. The component based DSI drivers(like exynos) are difficult to attach if it involves kms hotplug. kms hotplug would require drm pointer and that pointer would only available after the bind call finishes. But the bridge attach in bind call will defer till it find the attached bridge.

Quoted 5 lines

Right now I'm trying to find the proper way to attach the bridges for component based DSI drivers which involves kms hot-plug.

If you have any ideas on this, please let me know.

Quoted 6 lines

Jagan,

How is your progress on this series? Looking at your repo it looks like you've rebased on top of 5.13-rc3 in your 070121-imx8mm-dsim branch but you've got a lot of things there that are likely not related to this series?

I have a bit of work on those patches and tested on imx8mn. Basically:

- add the dsi timing calculation
- change few difference with samsung bridge
- fix crashes of my dsi panels
- compare with NXP driver the final results

Quoted 8 lines

I found that I have one problem that gives me some instability. In the NXP original driver the panel needs to be
enabled in bridge_enable before out the standby. If I understand correctly, our standby should be done after.
I would like to have some feedback and help and testing on other boards/devices and some suggestions on how to handle
some of the differences. Another big problem is etnavi that is not stable

Quoted 4 lines

Michael,

Where can I find your patches?

I will push on some tree and share

Quoted 17 lines

What do you mean by etnaviv not being stable?

I did some limited testing with etnaviv on imx8mm with 5.15 + dsi

patches on an Ubuntu focal root filesystem by:
apt update
apt install gnome-session gnome-terminal
^^^ 2D hardware acceleration appears to be working (dragging opaque windows around)
apt install mesa-utils glmark2
glxgears
^^^ ~160fps on IMX8MM
glmark2
^^^ score of 39 on IMX8MM

Quoted 4 lines

I haven't seen any updates from Jagan since Nov 24
(https://www.spinics.net/lists/dri-devel/msg324059.html) and am not sure if he's been able to work through drm/exynos issues that have been blocking his progress.

I plan to push on github

[17:07:42.315] Sending ready to systemd

[  214.052085] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  214.595998] etnaviv-gpu 38000000.gpu: recover hung GPU!

** (maynard:386): WARNING **: 17:07:43.874: failed to setup mixer: Success [17:07:44.175] Added surface 0xaaab02630440, app_id (null) to pending list [17:07:44.176] Added surface 0xaaab026172b0, app_id (null) to pending list ** Message: 17:07:44.289: New advertisement app id maynard
** Message: 17:07:44.290: New advertisement app id maynard [17:07:45.171] (background) position view 0xaaab0261f860, x 0, y 0, on output DSI-1
[17:07:45.171] (panel) geom.width 100, geom.height 480, geom.x 0, geom.y 0 [17:07:45.171] (panel) edge 2 position view 0xaaab02634510, x 0, y 0 [17:07:45.172] panel type 2 inited on output DSI-1 [17:07:45.172] Usable area: 380x480+100,0

Quoted 5 lines
[  216.932080] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  217.476015] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  218.020157] etnaviv-gpu 38000000.gpu: recover hung GPU!

This is my problem on imx8mn

Note that the GPU on the 8MN is from the GC7000 generation, which genreally has bogus feature registers, as VeriSilicon stopped using them in favor of a hardware database. To get the GPu working you need to transcribe the entry for this specific GPU from the downstream GPU driver into the etanviv HWDB format, to make the kernel and userspace driver aware of how to drive this GPU.

Regards,
Lucas

#46 lore raw

Hi

Quoted 148 lines · Lucas Stach

Am Donnerstag, dem 09.12.2021 um 18:09 +0100 schrieb Michael Nazzareno Trimarchi:

Quoted 145 lines

Hi Tim

Quoted 92 lines · Tim Harvey
Quoted 80 lines · Michael Nazzareno Trimarchi

Hi Tim

Quoted 62 lines · Tim Harvey
Quoted 54 lines · Jagan Teki

Hi Sam,

Quoted 33 lines · Sam Ravnborg

Hi Jagan,

Quoted 29 lines · Jagan Teki

This series supports common bridge support for Samsung MIPI DSIM which is used in Exynos and i.MX8MM SoC's.

The final bridge supports both the Exynos and i.MX8MM DSI devices.

Right now bridge offers two sets of implementations.

A. With component_ops and exynos specific code exclusively for
exynos dsi drivers and it's legacy bindings.

B. Without componenet_ops for newly implemented bridges and its
users like i.MX8MM.

The future plan is to fix the implementation A) by dropping component_ops and fixing exynos specific code in order to make the bridge more mature to use and the same is mentioned in drivers TODO.

Patch 0001 - 0006: Bridge conversion
Patch 0007 - 0017: Samsung MIPI DSIM bridge fixes, additions

Tested in Engicam i.Core MX8M Mini SoM.

Anyone interest, please have a look on this repo
https://github.com/openedev/linux/tree/070421-imx8mm-dsim

Would appreciate anyone from the exynos team to test it on the exynos platform?

Quoted 7 lines
Quoted 1 line

Any inputs?

I really like where you are headign with this!
No testing - sorry. But I will try to provide a bit of feedback on the individual patches.

I hope you find a way to move forward with this.

Thanks for the response.

We have found some issues with Bridge conversion on existing exynos drivers. The component based DSI drivers(like exynos) are difficult to attach if it involves kms hotplug. kms hotplug would require drm pointer and that pointer would only available after the bind call finishes. But the bridge attach in bind call will defer till it find the attached bridge.

Quoted 5 lines

Right now I'm trying to find the proper way to attach the bridges for component based DSI drivers which involves kms hot-plug.

If you have any ideas on this, please let me know.

Quoted 6 lines

Jagan,

How is your progress on this series? Looking at your repo it looks like you've rebased on top of 5.13-rc3 in your 070121-imx8mm-dsim branch but you've got a lot of things there that are likely not related to this series?

I have a bit of work on those patches and tested on imx8mn. Basically:

- add the dsi timing calculation
- change few difference with samsung bridge
- fix crashes of my dsi panels
- compare with NXP driver the final results

Quoted 8 lines

I found that I have one problem that gives me some instability. In the NXP original driver the panel needs to be
enabled in bridge_enable before out the standby. If I understand correctly, our standby should be done after.
I would like to have some feedback and help and testing on other boards/devices and some suggestions on how to handle
some of the differences. Another big problem is etnavi that is not stable

Quoted 4 lines

Michael,

Where can I find your patches?

I will push on some tree and share

Quoted 17 lines

What do you mean by etnaviv not being stable?

I did some limited testing with etnaviv on imx8mm with 5.15 + dsi

patches on an Ubuntu focal root filesystem by:
apt update
apt install gnome-session gnome-terminal
^^^ 2D hardware acceleration appears to be working (dragging opaque windows around)
apt install mesa-utils glmark2
glxgears
^^^ ~160fps on IMX8MM
glmark2
^^^ score of 39 on IMX8MM

Quoted 4 lines

I haven't seen any updates from Jagan since Nov 24
(https://www.spinics.net/lists/dri-devel/msg324059.html) and am not sure if he's been able to work through drm/exynos issues that have been blocking his progress.

I plan to push on github

[17:07:42.315] Sending ready to systemd

[  214.052085] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  214.595998] etnaviv-gpu 38000000.gpu: recover hung GPU!

** (maynard:386): WARNING **: 17:07:43.874: failed to setup mixer: Success [17:07:44.175] Added surface 0xaaab02630440, app_id (null) to pending list [17:07:44.176] Added surface 0xaaab026172b0, app_id (null) to pending list ** Message: 17:07:44.289: New advertisement app id maynard
** Message: 17:07:44.290: New advertisement app id maynard [17:07:45.171] (background) position view 0xaaab0261f860, x 0, y 0, on output DSI-1
[17:07:45.171] (panel) geom.width 100, geom.height 480, geom.x 0, geom.y 0 [17:07:45.171] (panel) edge 2 position view 0xaaab02634510, x 0, y 0 [17:07:45.172] panel type 2 inited on output DSI-1 [17:07:45.172] Usable area: 380x480+100,0

[  216.932080] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  217.476015] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  218.020157] etnaviv-gpu 38000000.gpu: recover hung GPU!
Quoted 8 lines
Quoted 1 line

This is my problem on imx8mn

Note that the GPU on the 8MN is from the GC7000 generation, which genreally has bogus feature registers, as VeriSilicon stopped using them in favor of a hardware database. To get the GPu working you need to transcribe the entry for this specific GPU from the downstream GPU driver into the etanviv HWDB format, to make the kernel and userspace driver aware of how to drive this GPU.

(quoted diff) +0 -0

b/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c
index f2fc645c7956..724f78fd37e5 100644

drivers/gpu/drm/etnaviv/etnaviv_hwdb.c +0 -0
@@ -68,6 +68,37 @@ static const struct etnaviv_chip_identity
etnaviv_chip_identities[] = {
                .minor_features10 = 0x00004040,
                .minor_features11 = 0x00000024,
        },
+       {
+               .model = 0x7000,
+               .revision = 0x6203,
+               .product_id = ~0U,
+               .customer_id = ~0U,
+               .eco_id = 0,
+               .stream_count = 16,
+               .register_max = 64,
+               .thread_count = 512,
+               .shader_core_count = 2,
+               .vertex_cache_size = 16,
+               .vertex_output_buffer_size = 1024,
+               .pixel_pipes = 1,
+               .instruction_count = 512,
+               .num_constants = 320,
+               .buffer_size = 0,
+               .varyings_count = 16,
+               .features = 0xe0287c8c,
+               .minor_features0 = 0xc1589eff,
+               .minor_features1 = 0xfefbfad9,
+               .minor_features2 = 0xeb9d4fbf,
+               .minor_features3 = 0xedfffced,
+               .minor_features4 = 0xdb0dafc7,
+               .minor_features5 = 0x3b5ac333,
+               .minor_features6 = 0xfcce6000,
+               .minor_features7 = 0xfffbfa6f,
+               .minor_features8 = 0x00e10ef3,
+               .minor_features9 = 0x00c8003c,
+               .minor_features10 = 0x00004040,
+               .minor_features11 = 0x00000024,
+       },
        {
                .model = 0x7000,
                .revision = 0x6204,

Ok, should something like this. Only does not know about this gcFEATURE_BIT_DE_2D_FAST_CLEAR. I put in features but can even a minor. Do you know the right mapping?

Michael

Michael

Quoted 4 lines

Regards,
Lucas

Signature · 11 lines
Michael Nazzareno Trimarchi
Co-Founder & Chief Executive Officer
M. +39 347 913 2170
[email protected]
__________________________________

Amarula Solutions BV
Joop Geesinkweg 125, 1114 AB, Amsterdam, NL
T. +31 (0)85 111 9172
[email protected]
www.amarulasolutions.com
#47 lore raw
Quoted 136 lines · Michael Nazzareno Trimarchi

Hi

Quoted 132 lines · Lucas Stach

Am Donnerstag, dem 09.12.2021 um 18:09 +0100 schrieb Michael Nazzareno Trimarchi:

Quoted 129 lines

Hi Tim

Quoted 92 lines · Tim Harvey
Quoted 80 lines · Michael Nazzareno Trimarchi

Hi Tim

Quoted 62 lines · Tim Harvey
Quoted 54 lines · Jagan Teki

Hi Sam,

Quoted 33 lines · Sam Ravnborg

Hi Jagan,

Quoted 29 lines · Jagan Teki

This series supports common bridge support for Samsung MIPI DSIM which is used in Exynos and i.MX8MM SoC's.

The final bridge supports both the Exynos and i.MX8MM DSI devices.

Right now bridge offers two sets of implementations.

A. With component_ops and exynos specific code exclusively for
exynos dsi drivers and it's legacy bindings.

B. Without componenet_ops for newly implemented bridges and its
users like i.MX8MM.

The future plan is to fix the implementation A) by dropping component_ops and fixing exynos specific code in order to make the bridge more mature to use and the same is mentioned in drivers TODO.

Patch 0001 - 0006: Bridge conversion
Patch 0007 - 0017: Samsung MIPI DSIM bridge fixes, additions

Tested in Engicam i.Core MX8M Mini SoM.

Anyone interest, please have a look on this repo
https://github.com/openedev/linux/tree/070421-imx8mm-dsim

Would appreciate anyone from the exynos team to test it on the exynos platform?

Quoted 7 lines
Quoted 1 line

Any inputs?

I really like where you are headign with this!
No testing - sorry. But I will try to provide a bit of feedback on the individual patches.

I hope you find a way to move forward with this.

Thanks for the response.

We have found some issues with Bridge conversion on existing exynos drivers. The component based DSI drivers(like exynos) are difficult to attach if it involves kms hotplug. kms hotplug would require drm pointer and that pointer would only available after the bind call finishes. But the bridge attach in bind call will defer till it find the attached bridge.

Quoted 5 lines

Right now I'm trying to find the proper way to attach the bridges for component based DSI drivers which involves kms hot-plug.

If you have any ideas on this, please let me know.

Quoted 6 lines

Jagan,

How is your progress on this series? Looking at your repo it looks like you've rebased on top of 5.13-rc3 in your 070121-imx8mm-dsim branch but you've got a lot of things there that are likely not related to this series?

I have a bit of work on those patches and tested on imx8mn. Basically:

- add the dsi timing calculation
- change few difference with samsung bridge
- fix crashes of my dsi panels
- compare with NXP driver the final results

Quoted 8 lines

I found that I have one problem that gives me some instability. In the NXP original driver the panel needs to be
enabled in bridge_enable before out the standby. If I understand correctly, our standby should be done after.
I would like to have some feedback and help and testing on other boards/devices and some suggestions on how to handle
some of the differences. Another big problem is etnavi that is not stable

Quoted 4 lines

Michael,

Where can I find your patches?

I will push on some tree and share

Quoted 17 lines

What do you mean by etnaviv not being stable?

I did some limited testing with etnaviv on imx8mm with 5.15 + dsi

patches on an Ubuntu focal root filesystem by:
apt update
apt install gnome-session gnome-terminal
^^^ 2D hardware acceleration appears to be working (dragging opaque windows around)
apt install mesa-utils glmark2
glxgears
^^^ ~160fps on IMX8MM
glmark2
^^^ score of 39 on IMX8MM

Quoted 4 lines

I haven't seen any updates from Jagan since Nov 24
(https://www.spinics.net/lists/dri-devel/msg324059.html) and am not sure if he's been able to work through drm/exynos issues that have been blocking his progress.

I plan to push on github

[17:07:42.315] Sending ready to systemd

[  214.052085] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  214.595998] etnaviv-gpu 38000000.gpu: recover hung GPU!

Which Nano variant do you have? Not all Nano's have a GPU. I know Tim Harvey was having a similar issue, but it turns out his variant of the Nano did not include a GPU.

Quoted 96 lines
Quoted 24 lines
Quoted 12 lines

** (maynard:386): WARNING **: 17:07:43.874: failed to setup mixer: Success [17:07:44.175] Added surface 0xaaab02630440, app_id (null) to pending list [17:07:44.176] Added surface 0xaaab026172b0, app_id (null) to pending list ** Message: 17:07:44.289: New advertisement app id maynard
** Message: 17:07:44.290: New advertisement app id maynard [17:07:45.171] (background) position view 0xaaab0261f860, x 0, y 0, on output DSI-1
[17:07:45.171] (panel) geom.width 100, geom.height 480, geom.x 0, geom.y 0 [17:07:45.171] (panel) edge 2 position view 0xaaab02634510, x 0, y 0 [17:07:45.172] panel type 2 inited on output DSI-1 [17:07:45.172] Usable area: 380x480+100,0

Quoted 5 lines
[  216.932080] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  217.476015] etnaviv-gpu 38000000.gpu: recover hung GPU!
[  218.020157] etnaviv-gpu 38000000.gpu: recover hung GPU!

This is my problem on imx8mn

Note that the GPU on the 8MN is from the GC7000 generation, which genreally has bogus feature registers, as VeriSilicon stopped using them in favor of a hardware database. To get the GPu working you need to transcribe the entry for this specific GPU from the downstream GPU driver into the etanviv HWDB format, to make the kernel and userspace driver aware of how to drive this GPU.

drivers/gpu/drm/etnaviv/etnaviv_hwdb.c +31 -0
index f2fc645c7956..724f78fd37e5 100644
@@ -68,6 +68,37 @@ static const struct etnaviv_chip_identity
 etnaviv_chip_identities[] = {
                .minor_features10 = 0x00004040,
                .minor_features11 = 0x00000024,
        },
+       {
+               .model = 0x7000,
+               .revision = 0x6203,
+               .product_id = ~0U,
+               .customer_id = ~0U,
+               .eco_id = 0,
+               .stream_count = 16,
+               .register_max = 64,
+               .thread_count = 512,
+               .shader_core_count = 2,
+               .vertex_cache_size = 16,
+               .vertex_output_buffer_size = 1024,
+               .pixel_pipes = 1,
+               .instruction_count = 512,
+               .num_constants = 320,
+               .buffer_size = 0,
+               .varyings_count = 16,
+               .features = 0xe0287c8c,
+               .minor_features0 = 0xc1589eff,
+               .minor_features1 = 0xfefbfad9,
+               .minor_features2 = 0xeb9d4fbf,
+               .minor_features3 = 0xedfffced,
+               .minor_features4 = 0xdb0dafc7,
+               .minor_features5 = 0x3b5ac333,
+               .minor_features6 = 0xfcce6000,
+               .minor_features7 = 0xfffbfa6f,
+               .minor_features8 = 0x00e10ef3,
+               .minor_features9 = 0x00c8003c,
+               .minor_features10 = 0x00004040,
+               .minor_features11 = 0x00000024,
+       },
        {
                .model = 0x7000,
                .revision = 0x6204,

Ok, should something like this. Only does not know about this gcFEATURE_BIT_DE_2D_FAST_CLEAR. I put in features but can even a minor. Do you know the right mapping?

Michael

Michael

Quoted 4 lines

Regards,
Lucas

--
Michael Nazzareno Trimarchi
Co-Founder & Chief Executive Officer
M. +39 347 913 2170
[email protected]
__________________________________

Amarula Solutions BV
Joop Geesinkweg 125, 1114 AB, Amsterdam, NL
T. +31 (0)85 111 9172
[email protected]
www.amarulasolutions.com