diff options
6 files changed, 451 insertions, 0 deletions
diff --git a/gnu/packages/patches/linux-libre-mnt-reform-0001-nwl-dsi-fixup-mode-only-for-LCDIF-input-not-DCSS.patch b/gnu/packages/patches/linux-libre-mnt-reform-0001-nwl-dsi-fixup-mode-only-for-LCDIF-input-not-DCSS.patch new file mode 100644 index 0000000000..e0ac8080e5 --- /dev/null +++ b/gnu/packages/patches/linux-libre-mnt-reform-0001-nwl-dsi-fixup-mode-only-for-LCDIF-input-not-DCSS.patch @@ -0,0 +1,37 @@ +From e0ab52e9cfe03580140e18aaae15b5127b4e10b3 Mon Sep 17 00:00:00 2001 +From: "Lukas F. Hartmann" <lukas@mntre.com> +Date: Wed, 7 Sep 2022 06:20:37 +0200 +Subject: [PATCH 1/7] nwl-dsi-fixup-mode-only-for-LCDIF-input-not-DCSS + +--- + drivers/gpu/drm/bridge/nwl-dsi.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c +index 6dc2a4e..13c5ade 100644 +--- a/drivers/gpu/drm/bridge/nwl-dsi.c ++++ b/drivers/gpu/drm/bridge/nwl-dsi.c +@@ -822,10 +822,17 @@ static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_connector_state *conn_state) + { + struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; ++ struct device_node *remote; ++ struct nwl_dsi *dsi = bridge_to_dsi(bridge); + +- /* At least LCDIF + NWL needs active high sync */ +- adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); +- adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC); ++ remote = of_graph_get_remote_node(dsi->dev->of_node, 0, ++ NWL_DSI_ENDPOINT_LCDIF); ++ ++ if (remote) { ++ /* At least LCDIF + NWL needs active high sync */ ++ adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); ++ adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC); ++ } + + /* + * Do a full modeset if crtc_state->active is changed to be true. +-- +2.37.2 + diff --git a/gnu/packages/patches/linux-libre-mnt-reform-0002-pci-imx6-add-support-for-internal-refclk-imx8mq.patch b/gnu/packages/patches/linux-libre-mnt-reform-0002-pci-imx6-add-support-for-internal-refclk-imx8mq.patch new file mode 100644 index 0000000000..b8fe7ef6c6 --- /dev/null +++ b/gnu/packages/patches/linux-libre-mnt-reform-0002-pci-imx6-add-support-for-internal-refclk-imx8mq.patch @@ -0,0 +1,95 @@ +From 3b78052d1470fd1ec8d745430a728033b159b793 Mon Sep 17 00:00:00 2001 +From: "Lukas F. Hartmann" <lukas@mntre.com> +Date: Sat, 22 Oct 2022 17:11:19 +0200 +Subject: [PATCH 2/7] pci-imx6-add-support-for-internal-refclk-imx8mq + +--- + drivers/pci/controller/dwc/pci-imx6.c | 44 +++++++++++++++++++++++++-- + 1 file changed, 42 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c +index 6e5debd..e1014b2 100644 +--- a/drivers/pci/controller/dwc/pci-imx6.c ++++ b/drivers/pci/controller/dwc/pci-imx6.c +@@ -67,6 +67,7 @@ struct imx6_pcie { + struct dw_pcie *pci; + int reset_gpio; + bool gpio_active_high; ++ bool internal_refclk; + bool link_is_up; + struct clk *pcie_bus; + struct clk *pcie_phy; +@@ -154,6 +155,40 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie) + return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14; + } + ++#define IMX8MQ_ANA_PLLOUT_REG 0x74 ++#define IMX8MQ_ANA_PLLOUT_CKE BIT(4) ++#define IMX8MQ_ANA_PLLOUT_SEL_MASK 0xF ++#define IMX8MQ_ANA_PLLOUT_SEL_SYSPLL1 0xB ++#define IMX8MQ_ANA_PLLOUT_DIV_REG 0x7C ++#define IMX8MQ_ANA_PLLOUT_SYSPLL1_DIV 0x7 ++ ++static void imx6_pcie_enable_internal_refclk(void) ++{ ++ uint32_t val; ++ struct device_node* np; ++ void __iomem *base; ++ ++ np = of_find_compatible_node(NULL, NULL, ++ "fsl,imx8mq-anatop"); ++ base = of_iomap(np, 0); ++ WARN_ON(!base); ++ ++ val = readl(base + IMX8MQ_ANA_PLLOUT_REG); ++ val &= ~IMX8MQ_ANA_PLLOUT_SEL_MASK; ++ val |= IMX8MQ_ANA_PLLOUT_SEL_SYSPLL1; ++ writel(val, base + IMX8MQ_ANA_PLLOUT_REG); ++ /* SYS_PLL1 is 800M, PCIE REF CLK is 100M */ ++ val = readl(base + IMX8MQ_ANA_PLLOUT_DIV_REG); ++ val |= IMX8MQ_ANA_PLLOUT_SYSPLL1_DIV; ++ writel(val, base + IMX8MQ_ANA_PLLOUT_DIV_REG); ++ ++ val = readl(base + IMX8MQ_ANA_PLLOUT_REG); ++ val |= IMX8MQ_ANA_PLLOUT_CKE; ++ writel(val, base + IMX8MQ_ANA_PLLOUT_REG); ++ ++ usleep_range(9000,10000); ++} ++ + static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie) + { + unsigned int mask, val; +@@ -299,6 +334,9 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, u16 data) + + static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) + { ++ if (imx6_pcie->internal_refclk) ++ imx6_pcie_enable_internal_refclk(); ++ + switch (imx6_pcie->drvdata->variant) { + case IMX8MM: + /* +@@ -314,7 +352,8 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) + regmap_update_bits(imx6_pcie->iomuxc_gpr, + imx6_pcie_grp_offset(imx6_pcie), + IMX8MQ_GPR_PCIE_REF_USE_PAD, +- IMX8MQ_GPR_PCIE_REF_USE_PAD); ++ (imx6_pcie->internal_refclk ? ++ 0 : IMX8MQ_GPR_PCIE_REF_USE_PAD)); + /* + * Regarding the datasheet, the PCIE_VPH is suggested + * to be 1.8V. If the PCIE_VPH is supplied by 3.3V, the +@@ -1158,7 +1197,8 @@ static int imx6_pcie_probe(struct platform_device *pdev) + imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux"); + if (IS_ERR(imx6_pcie->pcie_aux)) + return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux), +- "pcie_aux clock source missing or invalid\n"); ++ "pcie_aux clock source missing or invalid\n"); ++ imx6_pcie->internal_refclk = of_property_read_bool(node, "internal-refclk"); + fallthrough; + case IMX7D: + if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR) +-- +2.37.2 + diff --git a/gnu/packages/patches/linux-libre-mnt-reform-0003-lcdif-fix-pcie-interference.patch b/gnu/packages/patches/linux-libre-mnt-reform-0003-lcdif-fix-pcie-interference.patch new file mode 100644 index 0000000000..9a3a97e309 --- /dev/null +++ b/gnu/packages/patches/linux-libre-mnt-reform-0003-lcdif-fix-pcie-interference.patch @@ -0,0 +1,70 @@ +From bcc4ac93892276613ab6791659ad1418adf5a887 Mon Sep 17 00:00:00 2001 +From: "Lukas F. Hartmann" <lukas@mntre.com> +Date: Wed, 7 Sep 2022 06:23:35 +0200 +Subject: [PATCH 3/7] lcdif-fix-pcie-interference + +--- + drivers/gpu/drm/mxsfb/mxsfb_kms.c | 34 ++++++++++++++++++++++++++++++- + 1 file changed, 33 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c b/drivers/gpu/drm/mxsfb/mxsfb_kms.c +index e38ce57..25f80a6 100644 +--- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c ++++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c +@@ -304,7 +304,7 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb, + + mxsfb_set_formats(mxsfb, bus_format); + +- clk_set_rate(mxsfb->clk, m->crtc_clock * 1000); ++ clk_set_rate(mxsfb->clk, m->crtc_clock * 660); + + mxsfb_set_mode(mxsfb, bus_flags); + } +@@ -663,12 +663,44 @@ static const uint64_t mxsfb_modifiers[] = { + * Initialization + */ + ++void imx8mq_pcie_qos_for_lcdif(void) ++{ ++ void __iomem *qosc = ioremap(0x307f0000, 0x2100); ++ // clock and unlock QoSC registers ++ writel(0x0, qosc); ++ writel(0x1, qosc); ++ writel(0x0, qosc+0x60); ++ ++ // limit number of outstanding transactions for PCIe1 ++ writel(0x0, qosc+0x1000); ++ writel(0x1, qosc+0x1000); ++ writel(0x01010100, qosc+0x1050); ++ writel(0x01010100, qosc+0x1060); ++ writel(0x01010100, qosc+0x1070); ++ writel(0x1, qosc+0x1000); ++ ++ // limit number of outstanding transactions for PCIe2 ++ writel(0x0, qosc+0x2000); ++ writel(0x1, qosc+0x2000); ++ writel(0x01010100, qosc+0x2050); ++ writel(0x01010100, qosc+0x2060); ++ writel(0x01010100, qosc+0x2070); ++ writel(0x1, qosc+0x2000); ++ ++ iounmap(qosc); ++} ++ + int mxsfb_kms_init(struct mxsfb_drm_private *mxsfb) + { + struct drm_encoder *encoder = &mxsfb->encoder; + struct drm_crtc *crtc = &mxsfb->crtc; + int ret; + ++ /* ++ FIXME Workaround to fix PCIe interfering with LCDIF refresh (MNT Reform) ++ */ ++ imx8mq_pcie_qos_for_lcdif(); ++ + drm_plane_helper_add(&mxsfb->planes.primary, + &mxsfb_plane_primary_helper_funcs); + ret = drm_universal_plane_init(mxsfb->drm, &mxsfb->planes.primary, 1, +-- +2.37.2 + diff --git a/gnu/packages/patches/linux-libre-mnt-reform-0004-mnt4002-imx-gpcv2-wake-smccc.patch.patch b/gnu/packages/patches/linux-libre-mnt-reform-0004-mnt4002-imx-gpcv2-wake-smccc.patch.patch new file mode 100644 index 0000000000..6939d5e92e --- /dev/null +++ b/gnu/packages/patches/linux-libre-mnt-reform-0004-mnt4002-imx-gpcv2-wake-smccc.patch.patch @@ -0,0 +1,94 @@ +From 8bdade8b2e46a32aba6a44ef8814c1f902012fa8 Mon Sep 17 00:00:00 2001 +From: "Lukas F. Hartmann" <lukas@mntre.com> +Date: Wed, 7 Sep 2022 06:24:04 +0200 +Subject: [PATCH 4/7] mnt4002-imx-gpcv2-wake-smccc.patch + +--- + drivers/irqchip/irq-imx-gpcv2.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c +index b9c22f7..4f6d924 100644 +--- a/drivers/irqchip/irq-imx-gpcv2.c ++++ b/drivers/irqchip/irq-imx-gpcv2.c +@@ -3,6 +3,7 @@ + * Copyright (C) 2015 Freescale Semiconductor, Inc. + */ + ++#include <linux/arm-smccc.h> + #include <linux/of_address.h> + #include <linux/of_irq.h> + #include <linux/slab.h> +@@ -17,6 +18,13 @@ + #define GPC_IMR1_CORE2 0x1c0 + #define GPC_IMR1_CORE3 0x1d0 + ++#define FSL_SIP_GPC 0xC2000000 ++#define FSL_SIP_CONFIG_GPC_MASK 0x00 ++#define FSL_SIP_CONFIG_GPC_UNMASK 0x01 ++#define FSL_SIP_CONFIG_GPC_SET_WAKE 0x02 ++#define FSL_SIP_CONFIG_GPC_PM_DOMAIN 0x03 ++#define FSL_SIP_CONFIG_GPC_SET_AFF 0x04 ++#define FSL_SIP_CONFIG_GPC_CORE_WAKE 0x05 + + struct gpcv2_irqchip_data { + struct raw_spinlock rlock; +@@ -76,12 +84,17 @@ static int imx_gpcv2_irq_set_wake(struct irq_data *d, unsigned int on) + unsigned int idx = d->hwirq / 32; + unsigned long flags; + u32 mask, val; ++ struct arm_smccc_res res; + + raw_spin_lock_irqsave(&cd->rlock, flags); + mask = BIT(d->hwirq % 32); + val = cd->wakeup_sources[idx]; + + cd->wakeup_sources[idx] = on ? (val & ~mask) : (val | mask); ++ ++ // save wakeup config in vendor tf-a ++ arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_SET_WAKE, d->hwirq, on, 0, 0, 0, 0, &res); ++ + raw_spin_unlock_irqrestore(&cd->rlock, flags); + + /* +@@ -97,6 +110,7 @@ static void imx_gpcv2_irq_unmask(struct irq_data *d) + struct gpcv2_irqchip_data *cd = d->chip_data; + void __iomem *reg; + u32 val; ++ struct arm_smccc_res res; + + raw_spin_lock(&cd->rlock); + reg = gpcv2_idx_to_reg(cd, d->hwirq / 32); +@@ -105,6 +119,10 @@ static void imx_gpcv2_irq_unmask(struct irq_data *d) + writel_relaxed(val, reg); + raw_spin_unlock(&cd->rlock); + ++ // call into vendor tf-a ++ //arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_UNMASK, ++ // d->hwirq, 0, 0, 0, 0, 0, &res); ++ + irq_chip_unmask_parent(d); + } + +@@ -113,12 +131,18 @@ static void imx_gpcv2_irq_mask(struct irq_data *d) + struct gpcv2_irqchip_data *cd = d->chip_data; + void __iomem *reg; + u32 val; ++ struct arm_smccc_res res; + + raw_spin_lock(&cd->rlock); + reg = gpcv2_idx_to_reg(cd, d->hwirq / 32); + val = readl_relaxed(reg); + val |= BIT(d->hwirq % 32); + writel_relaxed(val, reg); ++ ++ // call into vendor tf-a ++ //arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_MASK, ++ // d->hwirq, 0, 0, 0, 0, 0, &res); ++ + raw_spin_unlock(&cd->rlock); + + irq_chip_mask_parent(d); +-- +2.37.2 + diff --git a/gnu/packages/patches/linux-libre-mnt-reform-0006-drm-bridge-ti-sn65dsi86-fetch-bpc-using-drm_atomic_s.patch b/gnu/packages/patches/linux-libre-mnt-reform-0006-drm-bridge-ti-sn65dsi86-fetch-bpc-using-drm_atomic_s.patch new file mode 100644 index 0000000000..667e67c178 --- /dev/null +++ b/gnu/packages/patches/linux-libre-mnt-reform-0006-drm-bridge-ti-sn65dsi86-fetch-bpc-using-drm_atomic_s.patch @@ -0,0 +1,96 @@ +From 330e2f7b2653315d48729200004f15df5948ec76 Mon Sep 17 00:00:00 2001 +From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> +Date: Mon, 11 Jul 2022 12:21:16 +0300 +Subject: [PATCH 6/7] drm/bridge: ti-sn65dsi86: fetch bpc using + drm_atomic_state + +Rather than reading the pdata->connector directly, fetch the connector +using drm_atomic_state. This allows us to make pdata->connector optional +(and thus supporting DRM_BRIDGE_ATTACH_NO_CONNECTOR). + +Reviewed-by: Sam Ravnborg <sam@ravnborg.org> +Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> +--- + drivers/gpu/drm/bridge/ti-sn65dsi86.c | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +index d6dd4d9..b362a7b 100644 +--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c ++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +@@ -779,9 +779,9 @@ static void ti_sn_bridge_set_dsi_rate(struct ti_sn65dsi86 *pdata) + regmap_write(pdata->regmap, SN_DSIA_CLK_FREQ_REG, val); + } + +-static unsigned int ti_sn_bridge_get_bpp(struct ti_sn65dsi86 *pdata) ++static unsigned int ti_sn_bridge_get_bpp(struct drm_connector *connector) + { +- if (pdata->connector->display_info.bpc <= 6) ++ if (connector->display_info.bpc <= 6) + return 18; + else + return 24; +@@ -796,7 +796,7 @@ static const unsigned int ti_sn_bridge_dp_rate_lut[] = { + 0, 1620, 2160, 2430, 2700, 3240, 4320, 5400 + }; + +-static int ti_sn_bridge_calc_min_dp_rate_idx(struct ti_sn65dsi86 *pdata) ++static int ti_sn_bridge_calc_min_dp_rate_idx(struct ti_sn65dsi86 *pdata, unsigned int bpp) + { + unsigned int bit_rate_khz, dp_rate_mhz; + unsigned int i; +@@ -804,7 +804,7 @@ static int ti_sn_bridge_calc_min_dp_rate_idx(struct ti_sn65dsi86 *pdata) + &pdata->bridge.encoder->crtc->state->adjusted_mode; + + /* Calculate minimum bit rate based on our pixel clock. */ +- bit_rate_khz = mode->clock * ti_sn_bridge_get_bpp(pdata); ++ bit_rate_khz = mode->clock * bpp; + + /* Calculate minimum DP data rate, taking 80% as per DP spec */ + dp_rate_mhz = DIV_ROUND_UP(bit_rate_khz * DP_CLK_FUDGE_NUM, +@@ -1016,12 +1016,21 @@ static void ti_sn_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) + { + struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); ++ struct drm_connector *connector; + const char *last_err_str = "No supported DP rate"; + unsigned int valid_rates; + int dp_rate_idx; + unsigned int val; + int ret = -EINVAL; + int max_dp_lanes; ++ unsigned int bpp; ++ ++ connector = drm_atomic_get_new_connector_for_encoder(old_bridge_state->base.state, ++ bridge->encoder); ++ if (!connector) { ++ dev_err_ratelimited(pdata->dev, "Could not get the connector\n"); ++ return; ++ } + + max_dp_lanes = ti_sn_get_max_lanes(pdata); + pdata->dp_lanes = min(pdata->dp_lanes, max_dp_lanes); +@@ -1047,8 +1056,9 @@ static void ti_sn_bridge_atomic_enable(struct drm_bridge *bridge, + drm_dp_dpcd_writeb(&pdata->aux, DP_EDP_CONFIGURATION_SET, + DP_ALTERNATE_SCRAMBLER_RESET_ENABLE); + ++ bpp = ti_sn_bridge_get_bpp(connector); + /* Set the DP output format (18 bpp or 24 bpp) */ +- val = (ti_sn_bridge_get_bpp(pdata) == 18) ? BPP_18_RGB : 0; ++ val = bpp == 18 ? BPP_18_RGB : 0; + regmap_update_bits(pdata->regmap, SN_DATA_FORMAT_REG, BPP_18_RGB, val); + + /* DP lane config */ +@@ -1059,7 +1069,7 @@ static void ti_sn_bridge_atomic_enable(struct drm_bridge *bridge, + valid_rates = ti_sn_bridge_read_valid_rates(pdata); + + /* Train until we run out of rates */ +- for (dp_rate_idx = ti_sn_bridge_calc_min_dp_rate_idx(pdata); ++ for (dp_rate_idx = ti_sn_bridge_calc_min_dp_rate_idx(pdata, bpp); + dp_rate_idx < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut); + dp_rate_idx++) { + if (!(valid_rates & BIT(dp_rate_idx))) +-- +2.37.2 + diff --git a/gnu/packages/patches/linux-libre-mnt-reform-0007-drm-bridge-ti-sn65dsi86-support-DRM_BRIDGE_ATTACH_NO.patch b/gnu/packages/patches/linux-libre-mnt-reform-0007-drm-bridge-ti-sn65dsi86-support-DRM_BRIDGE_ATTACH_NO.patch new file mode 100644 index 0000000000..60e73e01d3 --- /dev/null +++ b/gnu/packages/patches/linux-libre-mnt-reform-0007-drm-bridge-ti-sn65dsi86-support-DRM_BRIDGE_ATTACH_NO.patch @@ -0,0 +1,59 @@ +From 3b8da4be82c0ce989303d7bc2077a85a7fd5674a Mon Sep 17 00:00:00 2001 +From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> +Date: Mon, 11 Jul 2022 12:21:17 +0300 +Subject: [PATCH 7/7] drm/bridge: ti-sn65dsi86: support + DRM_BRIDGE_ATTACH_NO_CONNECTOR + +Now as the driver does not depend on pdata->connector, add support for +attaching the bridge with DRM_BRIDGE_ATTACH_NO_CONNECTOR. + +Reviewed-by: Sam Ravnborg <sam@ravnborg.org> +Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> +--- + drivers/gpu/drm/bridge/ti-sn65dsi86.c | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +index b362a7b..369bf72 100644 +--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c ++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +@@ -698,11 +698,6 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge, + struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); + int ret; + +- if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { +- DRM_ERROR("Fix bridge driver to make connector optional!"); +- return -EINVAL; +- } +- + pdata->aux.drm_dev = bridge->dev; + ret = drm_dp_aux_register(&pdata->aux); + if (ret < 0) { +@@ -710,15 +705,18 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge, + return ret; + } + +- /* We never want the next bridge to *also* create a connector: */ +- flags |= DRM_BRIDGE_ATTACH_NO_CONNECTOR; +- +- /* Attach the next bridge */ ++ /* ++ * Attach the next bridge. ++ * We never want the next bridge to *also* create a connector. ++ */ + ret = drm_bridge_attach(bridge->encoder, pdata->next_bridge, +- &pdata->bridge, flags); ++ &pdata->bridge, flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret < 0) + goto err_initted_aux; + ++ if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) ++ return 0; ++ + pdata->connector = drm_bridge_connector_init(pdata->bridge.dev, + pdata->bridge.encoder); + if (IS_ERR(pdata->connector)) { +-- +2.37.2 + |