Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1458952 > unrolled thread
| Started by | Peter Senna Tschudin <peter.senna@collabora.com> |
|---|---|
| First post | 2016-08-09 18:50 +0200 |
| Last post | 2016-08-09 18:50 +0200 |
| Articles | 4 — 1 participant |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH V5 0/4] Add driver for GE B850v3 LVDS/DP++ Bridge Peter Senna Tschudin <peter.senna@collabora.com> - 2016-08-09 18:50 +0200
[PATCH V5 2/4] Documentation/devicetree/bindings: b850v3_lvds_dp Peter Senna Tschudin <peter.senna@collabora.com> - 2016-08-09 18:50 +0200
[PATCH V5 1/4] drm/imx-ldb: Add support to drm-bridge Peter Senna Tschudin <peter.senna@collabora.com> - 2016-08-09 18:50 +0200
[PATCH V5 4/4] dts/imx6q-b850v3: Use GE B850v3 LVDS/DP++ Bridge Peter Senna Tschudin <peter.senna@collabora.com> - 2016-08-09 18:50 +0200
| From | Peter Senna Tschudin <peter.senna@collabora.com> |
|---|---|
| Date | 2016-08-09 18:50 +0200 |
| Subject | [PATCH V5 0/4] Add driver for GE B850v3 LVDS/DP++ Bridge |
| Message-ID | <s4io1-1E1-3@gated-at.bofh.it> |
The series adds a driver that creates a drm_bridge and a drm_connector for the
LVDS to DP++ display bridge of the GE B850v3.
There are two physical bridges on the video signal pipeline: a STDP4028(LVDS to
DP) and a STDP2690(DP to DP++). The hardware and firmware made it complicated
for this binding to comprise two device tree nodes, as the design goal is to
configure both bridges based on the LVDS signal, which leave the driver
powerless to control the video processing pipeline. The two bridges behaves as
a single bridge, and the driver is only needed for telling the host about EDID /
HPD, and for giving the host powers to ack interrupts. The video signal
pipeline is as follows:
Host -> LVDS|--(STDP4028)--|DP -> DP|--(STDP2690)--|DP++ -> Video output
The patches from the series:
[1/4] Change the imx-ldb driver to allow attaching a bridge and not only a LVDS
panel.
[2/4] Devicetree documentation for the GE B850v3 LVDS/DP++ Bridge
[3/4] Add the driver, make changes to MAINTAINERS, Kconfig and Makefile
[4/4] Make the changes to the B850v3 dts file to enable the GE B850v3
LVDS/DP++ Bridge.
Changes from V3:
- Removed the patch that was configuring the mapping between IPUs and external
displays on the dts file
Peter Senna Tschudin (4):
drm/imx-ldb: Add support to drm-bridge
Documentation/devicetree/bindings: b850v3_lvds_dp
drm/bridge: Add driver for GE B850v3 LVDS/DP++ Bridge
dts/imx6q-b850v3: Use GE B850v3 LVDS/DP++ Bridge
.../devicetree/bindings/ge/b850v3-lvds-dp.txt | 37 ++
MAINTAINERS | 8 +
arch/arm/boot/dts/imx6q-b850v3.dts | 30 ++
drivers/gpu/drm/bridge/Kconfig | 11 +
drivers/gpu/drm/bridge/Makefile | 1 +
drivers/gpu/drm/bridge/ge_b850v3_lvds_dp.c | 405 +++++++++++++++++++++
drivers/gpu/drm/imx/imx-ldb.c | 118 ++++--
7 files changed, 570 insertions(+), 40 deletions(-)
create mode 100644 Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt
create mode 100644 drivers/gpu/drm/bridge/ge_b850v3_lvds_dp.c
--
2.5.5
[toc] | [next] | [standalone]
| From | Peter Senna Tschudin <peter.senna@collabora.com> |
|---|---|
| Date | 2016-08-09 18:50 +0200 |
| Subject | [PATCH V5 2/4] Documentation/devicetree/bindings: b850v3_lvds_dp |
| Message-ID | <s4io2-1E1-31@gated-at.bofh.it> |
| In reply to | #1458952 |
Devicetree bindings documentation for the GE B850v3 LVDS/DP++
display bridge.
Cc: Martyn Welch <martyn.welch@collabora.co.uk>
Cc: Martin Donnelly <martin.donnelly@ge.com>
Cc: Javier Martinez Canillas <javier@dowhile0.org>
Cc: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Peter Senna Tschudin <peter.senna@collabora.com>
---
Unchanged from V4
Changes from V3:
- 2/4 instead of 3/5
Unchanged from V2
Changes from V1:
- Replaced '_' by '-' in node names or compatible strings
- Added missing @73 to the example
.../devicetree/bindings/ge/b850v3-lvds-dp.txt | 37 ++++++++++++++++++++++
1 file changed, 37 insertions(+)
create mode 100644 Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt
diff --git a/Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt b/Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt
new file mode 100644
index 0000000..f05c3e9
--- /dev/null
+++ b/Documentation/devicetree/bindings/ge/b850v3-lvds-dp.txt
@@ -0,0 +1,37 @@
+Driver for GE B850v3 LVDS/DP++ display bridge
+
+Required properties:
+ - compatible : should be "ge,b850v3-lvds-dp".
+ - reg : should contain the address used to ack the interrupts.
+ - interrupt-parent : phandle of the interrupt controller that services
+ interrupts to the device
+ - interrupts : one interrupt should be described here, as in
+ <0 IRQ_TYPE_LEVEL_HIGH>.
+ - edid-reg : should contain the address used to read edid information
+ - port : should describe the video signal connection between the host
+ and the bridge.
+
+Example:
+
+&mux2_i2c2 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ b850v3-lvds-dp-bridge@73 {
+ compatible = "ge,b850v3-lvds-dp";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <0x73>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+
+ edid-reg = <0x72>;
+
+ port {
+ b850v3_dp_bridge_in: endpoint {
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+};
--
2.5.5
[toc] | [prev] | [next] | [standalone]
| From | Peter Senna Tschudin <peter.senna@collabora.com> |
|---|---|
| Date | 2016-08-09 18:50 +0200 |
| Subject | [PATCH V5 1/4] drm/imx-ldb: Add support to drm-bridge |
| Message-ID | <s4io3-1E1-37@gated-at.bofh.it> |
| In reply to | #1458952 |
Add support to attach a drm_bridge to imx-ldb in addition to
existing support to attach a LVDS panel.
This patch does a simple code refactoring by moving code
from for_each_child_of_node iterator to a new function named
imx_ldb_panel_ddc(). This was necessary to allow the panel ddc
code to run only when the imx_ldb is not attached to a bridge.
Cc: Martyn Welch <martyn.welch@collabora.co.uk>
Cc: Martin Donnelly <martin.donnelly@ge.com>
Cc: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: David Airlie <airlied@linux.ie>
Cc: Thierry Reding <treding@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Signed-off-by: Peter Senna Tschudin <peter.senna@collabora.com>
---
Unchanged from V4
Changes from V3:
- The connector is created when there is no bridge instead of only when
there is a pannel
- Tested on next-20160804
Changes from V2:
- Updated to be aplied on top of Liu Ying changes that made imx-ldb atomic
- Tested on next-20160729
Changes from V1:
- Reanmed ext_bridge to bridge
- Removed empty entry point imx_ldb_encoder_enable()
- Adapted the code to apply to the latest linux next: next-20160609
drivers/gpu/drm/imx/imx-ldb.c | 118 ++++++++++++++++++++++++++++--------------
1 file changed, 78 insertions(+), 40 deletions(-)
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index b03919e..4a33077 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -57,7 +57,11 @@ struct imx_ldb_channel {
struct imx_ldb *ldb;
struct drm_connector connector;
struct drm_encoder encoder;
+
+ /* Defines what is connected to the ldb, only one at a time */
struct drm_panel *panel;
+ struct drm_bridge *bridge;
+
struct device_node *child;
struct i2c_adapter *ddc;
int chno;
@@ -466,10 +470,30 @@ static int imx_ldb_register(struct drm_device *drm,
drm_encoder_init(drm, encoder, &imx_ldb_encoder_funcs,
DRM_MODE_ENCODER_LVDS, NULL);
- drm_connector_helper_add(&imx_ldb_ch->connector,
- &imx_ldb_connector_helper_funcs);
- drm_connector_init(drm, &imx_ldb_ch->connector,
- &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
+ if (imx_ldb_ch->bridge) {
+ imx_ldb_ch->bridge->encoder = encoder;
+
+ imx_ldb_ch->encoder.bridge = imx_ldb_ch->bridge;
+ ret = drm_bridge_attach(drm, imx_ldb_ch->bridge);
+ if (ret) {
+ DRM_ERROR("Failed to initialize bridge with drm\n");
+ return ret;
+ }
+ } else {
+ /*
+ * We want to add the connector whenever there is no bridge
+ * that brings its own, not only when there is a panel. For
+ * historical reasons, the ldb driver can also work without
+ * a panel.
+ */
+ drm_connector_helper_add(&imx_ldb_ch->connector,
+ &imx_ldb_connector_helper_funcs);
+ drm_connector_init(drm, &imx_ldb_ch->connector,
+ &imx_ldb_connector_funcs,
+ DRM_MODE_CONNECTOR_LVDS);
+ drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
+ encoder);
+ }
if (imx_ldb_ch->panel) {
ret = drm_panel_attach(imx_ldb_ch->panel,
@@ -478,8 +502,6 @@ static int imx_ldb_register(struct drm_device *drm,
return ret;
}
- drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, encoder);
-
return 0;
}
@@ -548,6 +570,45 @@ static const struct of_device_id imx_ldb_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids);
+static int imx_ldb_panel_ddc(struct device *dev,
+ struct imx_ldb_channel *channel, struct device_node *child)
+{
+ struct device_node *ddc_node;
+ const u8 *edidp;
+ int ret;
+
+ ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0);
+ if (ddc_node) {
+ channel->ddc = of_find_i2c_adapter_by_node(ddc_node);
+ of_node_put(ddc_node);
+ if (!channel->ddc) {
+ dev_warn(dev, "failed to get ddc i2c adapter\n");
+ return -EPROBE_DEFER;
+ }
+ }
+
+ if (!channel->ddc) {
+ /* if no DDC available, fallback to hardcoded EDID */
+ dev_dbg(dev, "no ddc available\n");
+
+ edidp = of_get_property(child, "edid",
+ &channel->edid_len);
+ if (edidp) {
+ channel->edid = kmemdup(edidp,
+ channel->edid_len,
+ GFP_KERNEL);
+ } else if (!channel->panel) {
+ /* fallback to display-timings node */
+ ret = of_get_drm_display_mode(child,
+ &channel->mode,
+ OF_USE_NATIVE_MODE);
+ if (!ret)
+ channel->mode_valid = 1;
+ }
+ }
+ return 0;
+}
+
static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
{
struct drm_device *drm = data;
@@ -555,7 +616,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
const struct of_device_id *of_id =
of_match_device(imx_ldb_dt_ids, dev);
struct device_node *child;
- const u8 *edidp;
struct imx_ldb *imx_ldb;
int dual;
int ret;
@@ -605,7 +665,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
for_each_child_of_node(np, child) {
struct imx_ldb_channel *channel;
- struct device_node *ddc_node;
struct device_node *ep;
int bus_format;
@@ -638,46 +697,25 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
remote = of_graph_get_remote_port_parent(ep);
of_node_put(ep);
- if (remote)
+ if (remote) {
channel->panel = of_drm_find_panel(remote);
- else
+ channel->bridge = of_drm_find_bridge(remote);
+ } else
return -EPROBE_DEFER;
of_node_put(remote);
- if (!channel->panel) {
- dev_err(dev, "panel not found: %s\n",
- remote->full_name);
- return -EPROBE_DEFER;
- }
- }
- ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0);
- if (ddc_node) {
- channel->ddc = of_find_i2c_adapter_by_node(ddc_node);
- of_node_put(ddc_node);
- if (!channel->ddc) {
- dev_warn(dev, "failed to get ddc i2c adapter\n");
+ if (!channel->panel && !channel->bridge) {
+ dev_err(dev, "panel/bridge not found: %s\n",
+ remote->full_name);
return -EPROBE_DEFER;
}
}
- if (!channel->ddc) {
- /* if no DDC available, fallback to hardcoded EDID */
- dev_dbg(dev, "no ddc available\n");
-
- edidp = of_get_property(child, "edid",
- &channel->edid_len);
- if (edidp) {
- channel->edid = kmemdup(edidp,
- channel->edid_len,
- GFP_KERNEL);
- } else if (!channel->panel) {
- /* fallback to display-timings node */
- ret = of_get_drm_display_mode(child,
- &channel->mode,
- OF_USE_NATIVE_MODE);
- if (!ret)
- channel->mode_valid = 1;
- }
+ /* panel ddc only if there is no bridge */
+ if (!channel->bridge) {
+ ret = imx_ldb_panel_ddc(dev, channel, child);
+ if (ret)
+ return ret;
}
bus_format = of_get_bus_format(dev, child);
--
2.5.5
[toc] | [prev] | [next] | [standalone]
| From | Peter Senna Tschudin <peter.senna@collabora.com> |
|---|---|
| Date | 2016-08-09 18:50 +0200 |
| Subject | [PATCH V5 4/4] dts/imx6q-b850v3: Use GE B850v3 LVDS/DP++ Bridge |
| Message-ID | <s4io3-1E1-41@gated-at.bofh.it> |
| In reply to | #1458952 |
Configures the GE B850v3 LVDS/DP++ bridge on the dts file.
Cc: Martyn Welch <martyn.welch@collabora.co.uk>
Cc: Martin Donnelly <martin.donnelly@ge.com>
Cc: Javier Martinez Canillas <javier@dowhile0.org>
Cc: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Peter Senna Tschudin <peter.senna@collabora.com>
---
Unchanged from V4
Changes from V3:
- 4/4 instead of 5/5
Unchanged from V2
Changes from V1:
- Replaced '_' by '-' in node names or compatible strings
- Added missing @73 to b850v3-lvds-dp-bridge
arch/arm/boot/dts/imx6q-b850v3.dts | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/arch/arm/boot/dts/imx6q-b850v3.dts b/arch/arm/boot/dts/imx6q-b850v3.dts
index 167f744..8db3bf2 100644
--- a/arch/arm/boot/dts/imx6q-b850v3.dts
+++ b/arch/arm/boot/dts/imx6q-b850v3.dts
@@ -72,6 +72,13 @@
fsl,data-mapping = "spwg";
fsl,data-width = <24>;
status = "okay";
+
+ port@4 {
+ reg = <4>;
+ lvds0_out: endpoint {
+ remote-endpoint = <&b850v3_lvds_dp_bridge_in>;
+ };
+ };
};
};
@@ -142,3 +149,26 @@
reg = <0x4a>;
};
};
+
+&mux2_i2c2 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ b850v3-lvds-dp-bridge@73 {
+ compatible = "ge,b850v3-lvds-dp";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <0x73>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+
+ edid-reg = <0x72>;
+
+ port {
+ b850v3_lvds_dp_bridge_in: endpoint {
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+};
--
2.5.5
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web