]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Sep 2022 11:23:37 +0000 (13:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Sep 2022 11:23:37 +0000 (13:23 +0200)
added patches:
drm-bridge-display-connector-implement-bus-fmts-callbacks.patch

queue-5.15/drm-bridge-display-connector-implement-bus-fmts-callbacks.patch [new file with mode: 0644]
queue-5.15/series

diff --git a/queue-5.15/drm-bridge-display-connector-implement-bus-fmts-callbacks.patch b/queue-5.15/drm-bridge-display-connector-implement-bus-fmts-callbacks.patch
new file mode 100644 (file)
index 0000000..719a34e
--- /dev/null
@@ -0,0 +1,137 @@
+From 7cd70656d1285b79c001f041a017fcfee4292ff9 Mon Sep 17 00:00:00 2001
+From: Neil Armstrong <narmstrong@baylibre.com>
+Date: Wed, 20 Oct 2021 14:39:42 +0200
+Subject: drm/bridge: display-connector: implement bus fmts callbacks
+
+From: Neil Armstrong <narmstrong@baylibre.com>
+
+commit 7cd70656d1285b79c001f041a017fcfee4292ff9 upstream.
+
+Since this bridge is tied to the connector, it acts like a passthrough,
+so concerning the output & input bus formats, either pass the bus formats from the
+previous bridge or return fallback data like done in the bridge function:
+drm_atomic_bridge_chain_select_bus_fmts() & select_bus_fmt_recursive.
+
+This permits avoiding skipping the negociation if the remaining bridge chain has
+all the bits in place.
+
+Without this bus fmt negociation breaks on drm/meson HDMI pipeline when attaching
+dw-hdmi with DRM_BRIDGE_ATTACH_NO_CONNECTOR, because the last bridge of the
+display-connector doesn't implement buf fmt callbacks and MEDIA_BUS_FMT_FIXED
+is used leading to select an unsupported default bus format from dw-hdmi.
+
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211020123947.2585572-2-narmstrong@baylibre.com
+Cc: Stefan Agner <stefan@agner.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/bridge/display-connector.c |   86 +++++++++++++++++++++++++++++
+ 1 file changed, 86 insertions(+)
+
+--- a/drivers/gpu/drm/bridge/display-connector.c
++++ b/drivers/gpu/drm/bridge/display-connector.c
+@@ -13,6 +13,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/regulator/consumer.h>
++#include <drm/drm_atomic_helper.h>
+ #include <drm/drm_bridge.h>
+ #include <drm/drm_edid.h>
+@@ -87,10 +88,95 @@ static struct edid *display_connector_ge
+       return drm_get_edid(connector, conn->bridge.ddc);
+ }
++/*
++ * Since this bridge is tied to the connector, it acts like a passthrough,
++ * so concerning the output bus formats, either pass the bus formats from the
++ * previous bridge or return fallback data like done in the bridge function:
++ * drm_atomic_bridge_chain_select_bus_fmts().
++ * This supports negotiation if the bridge chain has all bits in place.
++ */
++static u32 *display_connector_get_output_bus_fmts(struct drm_bridge *bridge,
++                                      struct drm_bridge_state *bridge_state,
++                                      struct drm_crtc_state *crtc_state,
++                                      struct drm_connector_state *conn_state,
++                                      unsigned int *num_output_fmts)
++{
++      struct drm_bridge *prev_bridge = drm_bridge_get_prev_bridge(bridge);
++      struct drm_bridge_state *prev_bridge_state;
++
++      if (!prev_bridge || !prev_bridge->funcs->atomic_get_output_bus_fmts) {
++              struct drm_connector *conn = conn_state->connector;
++              u32 *out_bus_fmts;
++
++              *num_output_fmts = 1;
++              out_bus_fmts = kmalloc(sizeof(*out_bus_fmts), GFP_KERNEL);
++              if (!out_bus_fmts)
++                      return NULL;
++
++              if (conn->display_info.num_bus_formats &&
++                  conn->display_info.bus_formats)
++                      out_bus_fmts[0] = conn->display_info.bus_formats[0];
++              else
++                      out_bus_fmts[0] = MEDIA_BUS_FMT_FIXED;
++
++              return out_bus_fmts;
++      }
++
++      prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
++                                                          prev_bridge);
++
++      return prev_bridge->funcs->atomic_get_output_bus_fmts(prev_bridge, prev_bridge_state,
++                                                            crtc_state, conn_state,
++                                                            num_output_fmts);
++}
++
++/*
++ * Since this bridge is tied to the connector, it acts like a passthrough,
++ * so concerning the input bus formats, either pass the bus formats from the
++ * previous bridge or MEDIA_BUS_FMT_FIXED (like select_bus_fmt_recursive())
++ * when atomic_get_input_bus_fmts is not supported.
++ * This supports negotiation if the bridge chain has all bits in place.
++ */
++static u32 *display_connector_get_input_bus_fmts(struct drm_bridge *bridge,
++                                      struct drm_bridge_state *bridge_state,
++                                      struct drm_crtc_state *crtc_state,
++                                      struct drm_connector_state *conn_state,
++                                      u32 output_fmt,
++                                      unsigned int *num_input_fmts)
++{
++      struct drm_bridge *prev_bridge = drm_bridge_get_prev_bridge(bridge);
++      struct drm_bridge_state *prev_bridge_state;
++
++      if (!prev_bridge || !prev_bridge->funcs->atomic_get_input_bus_fmts) {
++              u32 *in_bus_fmts;
++
++              *num_input_fmts = 1;
++              in_bus_fmts = kmalloc(sizeof(*in_bus_fmts), GFP_KERNEL);
++              if (!in_bus_fmts)
++                      return NULL;
++
++              in_bus_fmts[0] = MEDIA_BUS_FMT_FIXED;
++
++              return in_bus_fmts;
++      }
++
++      prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
++                                                          prev_bridge);
++
++      return prev_bridge->funcs->atomic_get_input_bus_fmts(prev_bridge, prev_bridge_state,
++                                                           crtc_state, conn_state, output_fmt,
++                                                           num_input_fmts);
++}
++
+ static const struct drm_bridge_funcs display_connector_bridge_funcs = {
+       .attach = display_connector_attach,
+       .detect = display_connector_detect,
+       .get_edid = display_connector_get_edid,
++      .atomic_get_output_bus_fmts = display_connector_get_output_bus_fmts,
++      .atomic_get_input_bus_fmts = display_connector_get_input_bus_fmts,
++      .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
++      .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
++      .atomic_reset = drm_atomic_helper_bridge_reset,
+ };
+ static irqreturn_t display_connector_hpd_irq(int irq, void *arg)
index 4fca2917d8dffa61df24c18952f829251b21c6ae..0e917da1224f5c78923526924563d88d87f01620 100644 (file)
@@ -116,3 +116,4 @@ revert-arm64-kasan-revert-arm64-mte-reset-the-page-t.patch
 arm64-bti-disable-in-kernel-bti-when-cross-section-thunks-are-broken.patch
 iommu-vt-d-correctly-calculate-sagaw-value-of-iommu.patch
 arm64-errata-add-detection-for-amevcntr01-incrementing-incorrectly.patch
+drm-bridge-display-connector-implement-bus-fmts-callbacks.patch