diff options
Diffstat (limited to 'drivers/gpu/drm/bridge/imx')
-rw-r--r-- | drivers/gpu/drm/bridge/imx/Kconfig | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/imx/Makefile | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/imx/imx-ldb-helper.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/imx/imx-ldb-helper.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c | 89 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c | 207 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c | 158 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/imx/imx8qm-ldb.c | 53 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c | 54 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c | 2 |
13 files changed, 572 insertions, 105 deletions
diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig index 5a4f3d58501e..9a480c6abb85 100644 --- a/drivers/gpu/drm/bridge/imx/Kconfig +++ b/drivers/gpu/drm/bridge/imx/Kconfig @@ -3,6 +3,34 @@ if ARCH_MXC || COMPILE_TEST config DRM_IMX_LDB_HELPER tristate +config DRM_IMX_LEGACY_BRIDGE + tristate + depends on DRM_IMX + help + This is a DRM bridge implementation for the DRM i.MX IPUv3 driver, + that uses of_get_drm_display_mode to acquire display mode. + + Newer designs should not use this bridge and should use proper panel + driver instead. + +config DRM_IMX8MP_DW_HDMI_BRIDGE + tristate "Freescale i.MX8MP HDMI-TX bridge support" + depends on OF + depends on COMMON_CLK + select DRM_DW_HDMI + imply DRM_IMX8MP_HDMI_PVI + imply PHY_FSL_SAMSUNG_HDMI_PHY + help + Choose this to enable support for the internal HDMI encoder found + on the i.MX8MP SoC. + +config DRM_IMX8MP_HDMI_PVI + tristate "Freescale i.MX8MP HDMI PVI bridge support" + depends on OF + help + Choose this to enable support for the internal HDMI TX Parallel + Video Interface found on the Freescale i.MX8MP SoC. + config DRM_IMX8QM_LDB tristate "Freescale i.MX8QM LVDS display bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile index 2b0c2e44aa1b..dd5d48584806 100644 --- a/drivers/gpu/drm/bridge/imx/Makefile +++ b/drivers/gpu/drm/bridge/imx/Makefile @@ -1,4 +1,7 @@ obj-$(CONFIG_DRM_IMX_LDB_HELPER) += imx-ldb-helper.o +obj-$(CONFIG_DRM_IMX_LEGACY_BRIDGE) += imx-legacy-bridge.o +obj-$(CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE) += imx8mp-hdmi-tx.o +obj-$(CONFIG_DRM_IMX8MP_HDMI_PVI) += imx8mp-hdmi-pvi.o obj-$(CONFIG_DRM_IMX8QM_LDB) += imx8qm-ldb.o obj-$(CONFIG_DRM_IMX8QXP_LDB) += imx8qxp-ldb.o obj-$(CONFIG_DRM_IMX8QXP_PIXEL_COMBINER) += imx8qxp-pixel-combiner.o diff --git a/drivers/gpu/drm/bridge/imx/imx-ldb-helper.c b/drivers/gpu/drm/bridge/imx/imx-ldb-helper.c index 6967325cd8ee..6149ba141a38 100644 --- a/drivers/gpu/drm/bridge/imx/imx-ldb-helper.c +++ b/drivers/gpu/drm/bridge/imx/imx-ldb-helper.c @@ -104,7 +104,7 @@ void ldb_bridge_disable_helper(struct drm_bridge *bridge) } EXPORT_SYMBOL_GPL(ldb_bridge_disable_helper); -int ldb_bridge_attach_helper(struct drm_bridge *bridge, +int ldb_bridge_attach_helper(struct drm_bridge *bridge, struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) { struct ldb_channel *ldb_ch = bridge->driver_private; @@ -116,14 +116,8 @@ int ldb_bridge_attach_helper(struct drm_bridge *bridge, return -EINVAL; } - if (!bridge->encoder) { - DRM_DEV_ERROR(ldb->dev, "missing encoder\n"); - return -ENODEV; - } - - return drm_bridge_attach(bridge->encoder, - ldb_ch->next_bridge, bridge, - DRM_BRIDGE_ATTACH_NO_CONNECTOR); + return drm_bridge_attach(encoder, ldb_ch->next_bridge, bridge, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); } EXPORT_SYMBOL_GPL(ldb_bridge_attach_helper); @@ -196,8 +190,7 @@ int ldb_find_next_bridge_helper(struct ldb *ldb) } EXPORT_SYMBOL_GPL(ldb_find_next_bridge_helper); -void ldb_add_bridge_helper(struct ldb *ldb, - const struct drm_bridge_funcs *bridge_funcs) +void ldb_add_bridge_helper(struct ldb *ldb) { struct ldb_channel *ldb_ch; int i; @@ -209,7 +202,6 @@ void ldb_add_bridge_helper(struct ldb *ldb, continue; ldb_ch->bridge.driver_private = ldb_ch; - ldb_ch->bridge.funcs = bridge_funcs; ldb_ch->bridge.of_node = ldb_ch->np; drm_bridge_add(&ldb_ch->bridge); diff --git a/drivers/gpu/drm/bridge/imx/imx-ldb-helper.h b/drivers/gpu/drm/bridge/imx/imx-ldb-helper.h index a0a5cde27fbc..de187e326999 100644 --- a/drivers/gpu/drm/bridge/imx/imx-ldb-helper.h +++ b/drivers/gpu/drm/bridge/imx/imx-ldb-helper.h @@ -81,15 +81,14 @@ void ldb_bridge_enable_helper(struct drm_bridge *bridge); void ldb_bridge_disable_helper(struct drm_bridge *bridge); -int ldb_bridge_attach_helper(struct drm_bridge *bridge, +int ldb_bridge_attach_helper(struct drm_bridge *bridge, struct drm_encoder *encoder, enum drm_bridge_attach_flags flags); int ldb_init_helper(struct ldb *ldb); int ldb_find_next_bridge_helper(struct ldb *ldb); -void ldb_add_bridge_helper(struct ldb *ldb, - const struct drm_bridge_funcs *bridge_funcs); +void ldb_add_bridge_helper(struct ldb *ldb); void ldb_remove_bridge_helper(struct ldb *ldb); diff --git a/drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c b/drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c new file mode 100644 index 000000000000..f072c6ed39ef --- /dev/null +++ b/drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Freescale i.MX drm driver + * + * bridge driver for legacy DT bindings, utilizing display-timings node + */ + +#include <drm/drm_bridge.h> +#include <drm/drm_modes.h> +#include <drm/drm_probe_helper.h> +#include <drm/bridge/imx.h> + +#include <video/of_display_timing.h> +#include <video/of_videomode.h> + +struct imx_legacy_bridge { + struct drm_bridge base; + + struct drm_display_mode mode; + u32 bus_flags; +}; + +#define to_imx_legacy_bridge(bridge) container_of(bridge, struct imx_legacy_bridge, base) + +static int imx_legacy_bridge_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, + enum drm_bridge_attach_flags flags) +{ + if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) + return -EINVAL; + + return 0; +} + +static int imx_legacy_bridge_get_modes(struct drm_bridge *bridge, + struct drm_connector *connector) +{ + struct imx_legacy_bridge *imx_bridge = to_imx_legacy_bridge(bridge); + int ret; + + ret = drm_connector_helper_get_modes_fixed(connector, &imx_bridge->mode); + if (ret) + return ret; + + connector->display_info.bus_flags = imx_bridge->bus_flags; + + return 0; +} + +struct drm_bridge_funcs imx_legacy_bridge_funcs = { + .attach = imx_legacy_bridge_attach, + .get_modes = imx_legacy_bridge_get_modes, +}; + +struct drm_bridge *devm_imx_drm_legacy_bridge(struct device *dev, + struct device_node *np, + int type) +{ + struct imx_legacy_bridge *imx_bridge; + int ret; + + imx_bridge = devm_kzalloc(dev, sizeof(*imx_bridge), GFP_KERNEL); + if (!imx_bridge) + return ERR_PTR(-ENOMEM); + + ret = of_get_drm_display_mode(np, + &imx_bridge->mode, + &imx_bridge->bus_flags, + OF_USE_NATIVE_MODE); + if (ret) + return ERR_PTR(ret); + + imx_bridge->mode.type |= DRM_MODE_TYPE_DRIVER; + + imx_bridge->base.funcs = &imx_legacy_bridge_funcs; + imx_bridge->base.of_node = np; + imx_bridge->base.ops = DRM_BRIDGE_OP_MODES; + imx_bridge->base.type = type; + + ret = devm_drm_bridge_add(dev, &imx_bridge->base); + if (ret) + return ERR_PTR(ret); + + return &imx_bridge->base; +} +EXPORT_SYMBOL_GPL(devm_imx_drm_legacy_bridge); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Freescale i.MX DRM bridge driver for legacy DT bindings"); diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c new file mode 100644 index 000000000000..8a4fd7d77a8d --- /dev/null +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright (C) 2022 Pengutronix, Lucas Stach <kernel@pengutronix.de> + */ + +#include <drm/drm_atomic_helper.h> +#include <drm/drm_bridge.h> +#include <drm/drm_crtc.h> +#include <linux/bitfield.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_graph.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> + +#define HTX_PVI_CTRL 0x0 +#define PVI_CTRL_OP_VSYNC_POL BIT(18) +#define PVI_CTRL_OP_HSYNC_POL BIT(17) +#define PVI_CTRL_OP_DE_POL BIT(16) +#define PVI_CTRL_INP_VSYNC_POL BIT(14) +#define PVI_CTRL_INP_HSYNC_POL BIT(13) +#define PVI_CTRL_INP_DE_POL BIT(12) +#define PVI_CTRL_MODE_MASK GENMASK(2, 1) +#define PVI_CTRL_MODE_LCDIF 2 +#define PVI_CTRL_EN BIT(0) + +struct imx8mp_hdmi_pvi { + struct drm_bridge bridge; + struct device *dev; + struct drm_bridge *next_bridge; + void __iomem *regs; +}; + +static inline struct imx8mp_hdmi_pvi * +to_imx8mp_hdmi_pvi(struct drm_bridge *bridge) +{ + return container_of(bridge, struct imx8mp_hdmi_pvi, bridge); +} + +static int imx8mp_hdmi_pvi_bridge_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, + enum drm_bridge_attach_flags flags) +{ + struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge); + + return drm_bridge_attach(encoder, pvi->next_bridge, + bridge, flags); +} + +static void imx8mp_hdmi_pvi_bridge_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state) +{ + struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge); + struct drm_connector_state *conn_state; + struct drm_bridge_state *bridge_state; + const struct drm_display_mode *mode; + struct drm_crtc_state *crtc_state; + struct drm_connector *connector; + u32 bus_flags = 0, val; + + bridge_state = drm_atomic_get_new_bridge_state(state, bridge); + connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); + conn_state = drm_atomic_get_new_connector_state(state, connector); + crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); + + if (WARN_ON(pm_runtime_resume_and_get(pvi->dev))) + return; + + mode = &crtc_state->adjusted_mode; + + val = FIELD_PREP(PVI_CTRL_MODE_MASK, PVI_CTRL_MODE_LCDIF) | PVI_CTRL_EN; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + val |= PVI_CTRL_OP_VSYNC_POL | PVI_CTRL_INP_VSYNC_POL; + + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + val |= PVI_CTRL_OP_HSYNC_POL | PVI_CTRL_INP_HSYNC_POL; + + if (pvi->next_bridge->timings) + bus_flags = pvi->next_bridge->timings->input_bus_flags; + else if (bridge_state) + bus_flags = bridge_state->input_bus_cfg.flags; + + if (bus_flags & DRM_BUS_FLAG_DE_HIGH) + val |= PVI_CTRL_OP_DE_POL | PVI_CTRL_INP_DE_POL; + + writel(val, pvi->regs + HTX_PVI_CTRL); +} + +static void imx8mp_hdmi_pvi_bridge_disable(struct drm_bridge *bridge, + struct drm_atomic_state *state) +{ + struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge); + + writel(0x0, pvi->regs + HTX_PVI_CTRL); + + pm_runtime_put(pvi->dev); +} + +static u32 * +imx8mp_hdmi_pvi_bridge_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 imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge); + struct drm_bridge *next_bridge = pvi->next_bridge; + struct drm_bridge_state *next_state; + + if (!next_bridge->funcs->atomic_get_input_bus_fmts) + return NULL; + + next_state = drm_atomic_get_new_bridge_state(crtc_state->state, + next_bridge); + + return next_bridge->funcs->atomic_get_input_bus_fmts(next_bridge, + next_state, + crtc_state, + conn_state, + output_fmt, + num_input_fmts); +} + +static const struct drm_bridge_funcs imx_hdmi_pvi_bridge_funcs = { + .attach = imx8mp_hdmi_pvi_bridge_attach, + .atomic_enable = imx8mp_hdmi_pvi_bridge_enable, + .atomic_disable = imx8mp_hdmi_pvi_bridge_disable, + .atomic_get_input_bus_fmts = imx8mp_hdmi_pvi_bridge_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 int imx8mp_hdmi_pvi_probe(struct platform_device *pdev) +{ + struct device_node *remote; + struct imx8mp_hdmi_pvi *pvi; + + pvi = devm_kzalloc(&pdev->dev, sizeof(*pvi), GFP_KERNEL); + if (!pvi) + return -ENOMEM; + + platform_set_drvdata(pdev, pvi); + pvi->dev = &pdev->dev; + + pvi->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(pvi->regs)) + return PTR_ERR(pvi->regs); + + /* Get the next bridge in the pipeline. */ + remote = of_graph_get_remote_node(pdev->dev.of_node, 1, -1); + if (!remote) + return -EINVAL; + + pvi->next_bridge = of_drm_find_bridge(remote); + of_node_put(remote); + + if (!pvi->next_bridge) + return dev_err_probe(&pdev->dev, -EPROBE_DEFER, + "could not find next bridge\n"); + + pm_runtime_enable(&pdev->dev); + + /* Register the bridge. */ + pvi->bridge.funcs = &imx_hdmi_pvi_bridge_funcs; + pvi->bridge.of_node = pdev->dev.of_node; + pvi->bridge.timings = pvi->next_bridge->timings; + + drm_bridge_add(&pvi->bridge); + + return 0; +} + +static void imx8mp_hdmi_pvi_remove(struct platform_device *pdev) +{ + struct imx8mp_hdmi_pvi *pvi = platform_get_drvdata(pdev); + + drm_bridge_remove(&pvi->bridge); + + pm_runtime_disable(&pdev->dev); +} + +static const struct of_device_id imx8mp_hdmi_pvi_match[] = { + { + .compatible = "fsl,imx8mp-hdmi-pvi", + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, imx8mp_hdmi_pvi_match); + +static struct platform_driver imx8mp_hdmi_pvi_driver = { + .probe = imx8mp_hdmi_pvi_probe, + .remove = imx8mp_hdmi_pvi_remove, + .driver = { + .name = "imx-hdmi-pvi", + .of_match_table = imx8mp_hdmi_pvi_match, + }, +}; +module_platform_driver(imx8mp_hdmi_pvi_driver); + +MODULE_DESCRIPTION("i.MX8MP HDMI TX Parallel Video Interface bridge driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c new file mode 100644 index 000000000000..1e7a789ec289 --- /dev/null +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright (C) 2022 Pengutronix, Lucas Stach <kernel@pengutronix.de> + */ + +#include <linux/clk.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <drm/bridge/dw_hdmi.h> +#include <drm/drm_modes.h> + +struct imx8mp_hdmi { + struct dw_hdmi_plat_data plat_data; + struct dw_hdmi *dw_hdmi; + struct clk *pixclk; +}; + +static enum drm_mode_status +imx8mp_hdmi_mode_valid(struct dw_hdmi *dw_hdmi, void *data, + const struct drm_display_info *info, + const struct drm_display_mode *mode) +{ + struct imx8mp_hdmi *hdmi = (struct imx8mp_hdmi *)data; + long round_rate; + + if (mode->clock < 13500) + return MODE_CLOCK_LOW; + + if (mode->clock > 297000) + return MODE_CLOCK_HIGH; + + round_rate = clk_round_rate(hdmi->pixclk, mode->clock * 1000); + /* imx8mp's pixel clock generator (fsl-samsung-hdmi) cannot generate + * all possible frequencies, so allow some tolerance to support more + * modes. + * Allow 0.5% difference allowed in various standards (VESA, CEA861) + * 0.5% = 5/1000 tolerance (mode->clock is 1/1000) + */ + if (abs(round_rate - mode->clock * 1000) > mode->clock * 5) + return MODE_CLOCK_RANGE; + + /* We don't support double-clocked and Interlaced modes */ + if ((mode->flags & DRM_MODE_FLAG_DBLCLK) || + (mode->flags & DRM_MODE_FLAG_INTERLACE)) + return MODE_BAD; + + return MODE_OK; +} + +static int imx8mp_hdmi_phy_init(struct dw_hdmi *dw_hdmi, void *data, + const struct drm_display_info *display, + const struct drm_display_mode *mode) +{ + return 0; +} + +static void imx8mp_hdmi_phy_disable(struct dw_hdmi *dw_hdmi, void *data) +{ +} + +static void im8mp_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data) +{ + /* + * Just release PHY core from reset, all other power management is done + * by the PHY driver. + */ + dw_hdmi_phy_gen1_reset(hdmi); + + dw_hdmi_phy_setup_hpd(hdmi, data); +} + +static const struct dw_hdmi_phy_ops imx8mp_hdmi_phy_ops = { + .init = imx8mp_hdmi_phy_init, + .disable = imx8mp_hdmi_phy_disable, + .setup_hpd = im8mp_hdmi_phy_setup_hpd, + .read_hpd = dw_hdmi_phy_read_hpd, + .update_hpd = dw_hdmi_phy_update_hpd, +}; + +static int imx8mp_dw_hdmi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct dw_hdmi_plat_data *plat_data; + struct imx8mp_hdmi *hdmi; + + hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); + if (!hdmi) + return -ENOMEM; + + plat_data = &hdmi->plat_data; + + hdmi->pixclk = devm_clk_get(dev, "pix"); + if (IS_ERR(hdmi->pixclk)) + return dev_err_probe(dev, PTR_ERR(hdmi->pixclk), + "Unable to get pixel clock\n"); + + plat_data->mode_valid = imx8mp_hdmi_mode_valid; + plat_data->phy_ops = &imx8mp_hdmi_phy_ops; + plat_data->phy_name = "SAMSUNG HDMI TX PHY"; + plat_data->priv_data = hdmi; + plat_data->phy_force_vendor = true; + + hdmi->dw_hdmi = dw_hdmi_probe(pdev, plat_data); + if (IS_ERR(hdmi->dw_hdmi)) + return PTR_ERR(hdmi->dw_hdmi); + + platform_set_drvdata(pdev, hdmi); + + return 0; +} + +static void imx8mp_dw_hdmi_remove(struct platform_device *pdev) +{ + struct imx8mp_hdmi *hdmi = platform_get_drvdata(pdev); + + dw_hdmi_remove(hdmi->dw_hdmi); +} + +static int imx8mp_dw_hdmi_pm_suspend(struct device *dev) +{ + return 0; +} + +static int imx8mp_dw_hdmi_pm_resume(struct device *dev) +{ + struct imx8mp_hdmi *hdmi = dev_get_drvdata(dev); + + dw_hdmi_resume(hdmi->dw_hdmi); + + return 0; +} + +static const struct dev_pm_ops imx8mp_dw_hdmi_pm_ops = { + SYSTEM_SLEEP_PM_OPS(imx8mp_dw_hdmi_pm_suspend, imx8mp_dw_hdmi_pm_resume) +}; + +static const struct of_device_id imx8mp_dw_hdmi_of_table[] = { + { .compatible = "fsl,imx8mp-hdmi-tx" }, + { /* Sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx8mp_dw_hdmi_of_table); + +static struct platform_driver imx8mp_dw_hdmi_platform_driver = { + .probe = imx8mp_dw_hdmi_probe, + .remove = imx8mp_dw_hdmi_remove, + .driver = { + .name = "imx8mp-dw-hdmi-tx", + .of_match_table = imx8mp_dw_hdmi_of_table, + .pm = pm_ptr(&imx8mp_dw_hdmi_pm_ops), + }, +}; + +module_platform_driver(imx8mp_dw_hdmi_platform_driver); + +MODULE_DESCRIPTION("i.MX8MP HDMI encoder driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c index 21471a9a28b2..47aa65938e6a 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c +++ b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c @@ -47,7 +47,7 @@ struct imx8qm_ldb_channel { struct imx8qm_ldb { struct ldb base; struct device *dev; - struct imx8qm_ldb_channel channel[MAX_LDB_CHAN_NUM]; + struct imx8qm_ldb_channel *channel[MAX_LDB_CHAN_NUM]; struct clk *clk_pixel; struct clk *clk_bypass; int active_chno; @@ -107,7 +107,7 @@ static int imx8qm_ldb_bridge_atomic_check(struct drm_bridge *bridge, if (is_split) { imx8qm_ldb_ch = - &imx8qm_ldb->channel[imx8qm_ldb->active_chno ^ 1]; + imx8qm_ldb->channel[imx8qm_ldb->active_chno ^ 1]; imx8qm_ldb_set_phy_cfg(imx8qm_ldb, di_clk, is_split, true, phy_cfg); ret = phy_validate(imx8qm_ldb_ch->phy, PHY_MODE_LVDS, 0, &opts); @@ -158,7 +158,7 @@ imx8qm_ldb_bridge_mode_set(struct drm_bridge *bridge, if (is_split) { imx8qm_ldb_ch = - &imx8qm_ldb->channel[imx8qm_ldb->active_chno ^ 1]; + imx8qm_ldb->channel[imx8qm_ldb->active_chno ^ 1]; imx8qm_ldb_set_phy_cfg(imx8qm_ldb, di_clk, is_split, true, phy_cfg); ret = phy_configure(imx8qm_ldb_ch->phy, &opts); @@ -200,9 +200,8 @@ imx8qm_ldb_bridge_mode_set(struct drm_bridge *bridge, CH_HSYNC_M(chno), CH_PHSYNC(chno)); } -static void -imx8qm_ldb_bridge_atomic_enable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) +static void imx8qm_ldb_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { struct ldb_channel *ldb_ch = bridge->driver_private; struct ldb *ldb = ldb_ch->ldb; @@ -227,13 +226,13 @@ imx8qm_ldb_bridge_atomic_enable(struct drm_bridge *bridge, } if (is_split) { - ret = phy_power_on(imx8qm_ldb->channel[0].phy); + ret = phy_power_on(imx8qm_ldb->channel[0]->phy); if (ret) DRM_DEV_ERROR(dev, "failed to power on channel0 PHY: %d\n", ret); - ret = phy_power_on(imx8qm_ldb->channel[1].phy); + ret = phy_power_on(imx8qm_ldb->channel[1]->phy); if (ret) DRM_DEV_ERROR(dev, "failed to power on channel1 PHY: %d\n", @@ -247,9 +246,8 @@ imx8qm_ldb_bridge_atomic_enable(struct drm_bridge *bridge, ldb_bridge_enable_helper(bridge); } -static void -imx8qm_ldb_bridge_atomic_disable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) +static void imx8qm_ldb_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { struct ldb_channel *ldb_ch = bridge->driver_private; struct ldb *ldb = ldb_ch->ldb; @@ -263,12 +261,12 @@ imx8qm_ldb_bridge_atomic_disable(struct drm_bridge *bridge, ldb_bridge_disable_helper(bridge); if (is_split) { - ret = phy_power_off(imx8qm_ldb->channel[0].phy); + ret = phy_power_off(imx8qm_ldb->channel[0]->phy); if (ret) DRM_DEV_ERROR(dev, "failed to power off channel0 PHY: %d\n", ret); - ret = phy_power_off(imx8qm_ldb->channel[1].phy); + ret = phy_power_off(imx8qm_ldb->channel[1]->phy); if (ret) DRM_DEV_ERROR(dev, "failed to power off channel1 PHY: %d\n", @@ -414,7 +412,7 @@ static int imx8qm_ldb_get_phy(struct imx8qm_ldb *imx8qm_ldb) int i, ret; for (i = 0; i < MAX_LDB_CHAN_NUM; i++) { - imx8qm_ldb_ch = &imx8qm_ldb->channel[i]; + imx8qm_ldb_ch = imx8qm_ldb->channel[i]; ldb_ch = &imx8qm_ldb_ch->base; if (!ldb_ch->is_available) @@ -450,6 +448,14 @@ static int imx8qm_ldb_probe(struct platform_device *pdev) if (!imx8qm_ldb) return -ENOMEM; + for (i = 0; i < MAX_LDB_CHAN_NUM; i++) { + imx8qm_ldb->channel[i] = + devm_drm_bridge_alloc(dev, struct imx8qm_ldb_channel, base.bridge, + &imx8qm_ldb_bridge_funcs); + if (IS_ERR(imx8qm_ldb->channel[i])) + return PTR_ERR(imx8qm_ldb->channel[i]); + } + imx8qm_ldb->clk_pixel = devm_clk_get(dev, "pixel"); if (IS_ERR(imx8qm_ldb->clk_pixel)) { ret = PTR_ERR(imx8qm_ldb->clk_pixel); @@ -475,7 +481,7 @@ static int imx8qm_ldb_probe(struct platform_device *pdev) ldb->ctrl_reg = 0xe0; for (i = 0; i < MAX_LDB_CHAN_NUM; i++) - ldb->channel[i] = &imx8qm_ldb->channel[i].base; + ldb->channel[i] = &imx8qm_ldb->channel[i]->base; ret = ldb_init_helper(ldb); if (ret) @@ -501,12 +507,12 @@ static int imx8qm_ldb_probe(struct platform_device *pdev) } imx8qm_ldb->active_chno = 0; - imx8qm_ldb_ch = &imx8qm_ldb->channel[0]; + imx8qm_ldb_ch = imx8qm_ldb->channel[0]; ldb_ch = &imx8qm_ldb_ch->base; ldb_ch->link_type = pixel_order; } else { for (i = 0; i < MAX_LDB_CHAN_NUM; i++) { - imx8qm_ldb_ch = &imx8qm_ldb->channel[i]; + imx8qm_ldb_ch = imx8qm_ldb->channel[i]; ldb_ch = &imx8qm_ldb_ch->base; if (ldb_ch->is_available) { @@ -527,7 +533,7 @@ static int imx8qm_ldb_probe(struct platform_device *pdev) platform_set_drvdata(pdev, imx8qm_ldb); pm_runtime_enable(dev); - ldb_add_bridge_helper(ldb, &imx8qm_ldb_bridge_funcs); + ldb_add_bridge_helper(ldb); return ret; } @@ -542,12 +548,12 @@ static void imx8qm_ldb_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused imx8qm_ldb_runtime_suspend(struct device *dev) +static int imx8qm_ldb_runtime_suspend(struct device *dev) { return 0; } -static int __maybe_unused imx8qm_ldb_runtime_resume(struct device *dev) +static int imx8qm_ldb_runtime_resume(struct device *dev) { struct imx8qm_ldb *imx8qm_ldb = dev_get_drvdata(dev); struct ldb *ldb = &imx8qm_ldb->base; @@ -559,8 +565,7 @@ static int __maybe_unused imx8qm_ldb_runtime_resume(struct device *dev) } static const struct dev_pm_ops imx8qm_ldb_pm_ops = { - SET_RUNTIME_PM_OPS(imx8qm_ldb_runtime_suspend, - imx8qm_ldb_runtime_resume, NULL) + RUNTIME_PM_OPS(imx8qm_ldb_runtime_suspend, imx8qm_ldb_runtime_resume, NULL) }; static const struct of_device_id imx8qm_ldb_dt_ids[] = { @@ -571,9 +576,9 @@ MODULE_DEVICE_TABLE(of, imx8qm_ldb_dt_ids); static struct platform_driver imx8qm_ldb_driver = { .probe = imx8qm_ldb_probe, - .remove_new = imx8qm_ldb_remove, + .remove = imx8qm_ldb_remove, .driver = { - .pm = &imx8qm_ldb_pm_ops, + .pm = pm_ptr(&imx8qm_ldb_pm_ops), .name = DRIVER_NAME, .of_match_table = imx8qm_ldb_dt_ids, }, diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c index 7984da9c0a35..5d272916e200 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c @@ -44,7 +44,7 @@ struct imx8qxp_ldb_channel { struct imx8qxp_ldb { struct ldb base; struct device *dev; - struct imx8qxp_ldb_channel channel[MAX_LDB_CHAN_NUM]; + struct imx8qxp_ldb_channel *channel[MAX_LDB_CHAN_NUM]; struct clk *clk_pixel; struct clk *clk_bypass; struct drm_bridge *companion; @@ -203,9 +203,8 @@ imx8qxp_ldb_bridge_mode_set(struct drm_bridge *bridge, companion->funcs->mode_set(companion, mode, adjusted_mode); } -static void -imx8qxp_ldb_bridge_atomic_pre_enable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) +static void imx8qxp_ldb_bridge_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { struct ldb_channel *ldb_ch = bridge->driver_private; struct ldb *ldb = ldb_ch->ldb; @@ -217,12 +216,11 @@ imx8qxp_ldb_bridge_atomic_pre_enable(struct drm_bridge *bridge, clk_prepare_enable(imx8qxp_ldb->clk_bypass); if (is_split && companion) - companion->funcs->atomic_pre_enable(companion, old_bridge_state); + companion->funcs->atomic_pre_enable(companion, state); } -static void -imx8qxp_ldb_bridge_atomic_enable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) +static void imx8qxp_ldb_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { struct ldb_channel *ldb_ch = bridge->driver_private; struct ldb *ldb = ldb_ch->ldb; @@ -252,12 +250,11 @@ imx8qxp_ldb_bridge_atomic_enable(struct drm_bridge *bridge, DRM_DEV_ERROR(dev, "failed to power on PHY: %d\n", ret); if (is_split && companion) - companion->funcs->atomic_enable(companion, old_bridge_state); + companion->funcs->atomic_enable(companion, state); } -static void -imx8qxp_ldb_bridge_atomic_disable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) +static void imx8qxp_ldb_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { struct ldb_channel *ldb_ch = bridge->driver_private; struct ldb *ldb = ldb_ch->ldb; @@ -283,7 +280,7 @@ imx8qxp_ldb_bridge_atomic_disable(struct drm_bridge *bridge, clk_disable_unprepare(imx8qxp_ldb->clk_pixel); if (is_split && companion) - companion->funcs->atomic_disable(companion, old_bridge_state); + companion->funcs->atomic_disable(companion, state); ret = pm_runtime_put(dev); if (ret < 0) @@ -413,7 +410,7 @@ static const struct drm_bridge_funcs imx8qxp_ldb_bridge_funcs = { static int imx8qxp_ldb_set_di_id(struct imx8qxp_ldb *imx8qxp_ldb) { struct imx8qxp_ldb_channel *imx8qxp_ldb_ch = - &imx8qxp_ldb->channel[imx8qxp_ldb->active_chno]; + imx8qxp_ldb->channel[imx8qxp_ldb->active_chno]; struct ldb_channel *ldb_ch = &imx8qxp_ldb_ch->base; struct device_node *ep, *remote; struct device *dev = imx8qxp_ldb->dev; @@ -459,7 +456,7 @@ imx8qxp_ldb_check_chno_and_dual_link(struct ldb_channel *ldb_ch, int link) static int imx8qxp_ldb_parse_dt_companion(struct imx8qxp_ldb *imx8qxp_ldb) { struct imx8qxp_ldb_channel *imx8qxp_ldb_ch = - &imx8qxp_ldb->channel[imx8qxp_ldb->active_chno]; + imx8qxp_ldb->channel[imx8qxp_ldb->active_chno]; struct ldb_channel *ldb_ch = &imx8qxp_ldb_ch->base; struct ldb_channel *companion_ldb_ch; struct device_node *companion; @@ -589,6 +586,14 @@ static int imx8qxp_ldb_probe(struct platform_device *pdev) if (!imx8qxp_ldb) return -ENOMEM; + for (i = 0; i < MAX_LDB_CHAN_NUM; i++) { + imx8qxp_ldb->channel[i] = + devm_drm_bridge_alloc(dev, struct imx8qxp_ldb_channel, base.bridge, + &imx8qxp_ldb_bridge_funcs); + if (IS_ERR(imx8qxp_ldb->channel[i])) + return PTR_ERR(imx8qxp_ldb->channel[i]); + } + imx8qxp_ldb->clk_pixel = devm_clk_get(dev, "pixel"); if (IS_ERR(imx8qxp_ldb->clk_pixel)) { ret = PTR_ERR(imx8qxp_ldb->clk_pixel); @@ -614,7 +619,7 @@ static int imx8qxp_ldb_probe(struct platform_device *pdev) ldb->ctrl_reg = 0xe0; for (i = 0; i < MAX_LDB_CHAN_NUM; i++) - ldb->channel[i] = &imx8qxp_ldb->channel[i].base; + ldb->channel[i] = &imx8qxp_ldb->channel[i]->base; ret = ldb_init_helper(ldb); if (ret) @@ -630,7 +635,7 @@ static int imx8qxp_ldb_probe(struct platform_device *pdev) } for (i = 0; i < MAX_LDB_CHAN_NUM; i++) { - imx8qxp_ldb_ch = &imx8qxp_ldb->channel[i]; + imx8qxp_ldb_ch = imx8qxp_ldb->channel[i]; ldb_ch = &imx8qxp_ldb_ch->base; if (ldb_ch->is_available) { @@ -663,9 +668,9 @@ static int imx8qxp_ldb_probe(struct platform_device *pdev) platform_set_drvdata(pdev, imx8qxp_ldb); pm_runtime_enable(dev); - ldb_add_bridge_helper(ldb, &imx8qxp_ldb_bridge_funcs); + ldb_add_bridge_helper(ldb); - return ret; + return 0; } static void imx8qxp_ldb_remove(struct platform_device *pdev) @@ -678,12 +683,12 @@ static void imx8qxp_ldb_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused imx8qxp_ldb_runtime_suspend(struct device *dev) +static int imx8qxp_ldb_runtime_suspend(struct device *dev) { return 0; } -static int __maybe_unused imx8qxp_ldb_runtime_resume(struct device *dev) +static int imx8qxp_ldb_runtime_resume(struct device *dev) { struct imx8qxp_ldb *imx8qxp_ldb = dev_get_drvdata(dev); struct ldb *ldb = &imx8qxp_ldb->base; @@ -695,8 +700,7 @@ static int __maybe_unused imx8qxp_ldb_runtime_resume(struct device *dev) } static const struct dev_pm_ops imx8qxp_ldb_pm_ops = { - SET_RUNTIME_PM_OPS(imx8qxp_ldb_runtime_suspend, - imx8qxp_ldb_runtime_resume, NULL) + RUNTIME_PM_OPS(imx8qxp_ldb_runtime_suspend, imx8qxp_ldb_runtime_resume, NULL) }; static const struct of_device_id imx8qxp_ldb_dt_ids[] = { @@ -707,9 +711,9 @@ MODULE_DEVICE_TABLE(of, imx8qxp_ldb_dt_ids); static struct platform_driver imx8qxp_ldb_driver = { .probe = imx8qxp_ldb_probe, - .remove_new = imx8qxp_ldb_remove, + .remove = imx8qxp_ldb_remove, .driver = { - .pm = &imx8qxp_ldb_pm_ops, + .pm = pm_ptr(&imx8qxp_ldb_pm_ops), .name = DRIVER_NAME, .of_match_table = imx8qxp_ldb_dt_ids, }, diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c index d0868a6ac6c9..1f6fd488e703 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c @@ -108,6 +108,7 @@ imx8qxp_pc_bridge_mode_valid(struct drm_bridge *bridge, } static int imx8qxp_pc_bridge_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) { struct imx8qxp_pc_channel *ch = bridge->driver_private; @@ -119,12 +120,7 @@ static int imx8qxp_pc_bridge_attach(struct drm_bridge *bridge, return -EINVAL; } - if (!bridge->encoder) { - DRM_DEV_ERROR(pc->dev, "missing encoder\n"); - return -ENODEV; - } - - return drm_bridge_attach(bridge->encoder, + return drm_bridge_attach(encoder, ch->next_bridge, bridge, DRM_BRIDGE_ATTACH_NO_CONNECTOR); } @@ -181,9 +177,8 @@ imx8qxp_pc_bridge_mode_set(struct drm_bridge *bridge, clk_disable_unprepare(pc->clk_apb); } -static void -imx8qxp_pc_bridge_atomic_disable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) +static void imx8qxp_pc_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { struct imx8qxp_pc_channel *ch = bridge->driver_private; struct imx8qxp_pc *pc = ch->pc; @@ -376,7 +371,7 @@ static void imx8qxp_pc_bridge_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused imx8qxp_pc_runtime_suspend(struct device *dev) +static int imx8qxp_pc_runtime_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct imx8qxp_pc *pc = platform_get_drvdata(pdev); @@ -398,7 +393,7 @@ static int __maybe_unused imx8qxp_pc_runtime_suspend(struct device *dev) return ret; } -static int __maybe_unused imx8qxp_pc_runtime_resume(struct device *dev) +static int imx8qxp_pc_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct imx8qxp_pc *pc = platform_get_drvdata(pdev); @@ -420,8 +415,7 @@ static int __maybe_unused imx8qxp_pc_runtime_resume(struct device *dev) } static const struct dev_pm_ops imx8qxp_pc_pm_ops = { - SET_RUNTIME_PM_OPS(imx8qxp_pc_runtime_suspend, - imx8qxp_pc_runtime_resume, NULL) + RUNTIME_PM_OPS(imx8qxp_pc_runtime_suspend, imx8qxp_pc_runtime_resume, NULL) }; static const struct of_device_id imx8qxp_pc_dt_ids[] = { @@ -433,9 +427,9 @@ MODULE_DEVICE_TABLE(of, imx8qxp_pc_dt_ids); static struct platform_driver imx8qxp_pc_bridge_driver = { .probe = imx8qxp_pc_bridge_probe, - .remove_new = imx8qxp_pc_bridge_remove, + .remove = imx8qxp_pc_bridge_remove, .driver = { - .pm = &imx8qxp_pc_pm_ops, + .pm = pm_ptr(&imx8qxp_pc_pm_ops), .name = DRIVER_NAME, .of_match_table = imx8qxp_pc_dt_ids, }, diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c index ed8b7a4e0e11..e092c9ea99b0 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c @@ -128,6 +128,7 @@ static void imx8qxp_pixel_link_set_mst_addr(struct imx8qxp_pixel_link *pl) } static int imx8qxp_pixel_link_bridge_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) { struct imx8qxp_pixel_link *pl = bridge->driver_private; @@ -138,12 +139,7 @@ static int imx8qxp_pixel_link_bridge_attach(struct drm_bridge *bridge, return -EINVAL; } - if (!bridge->encoder) { - DRM_DEV_ERROR(pl->dev, "missing encoder\n"); - return -ENODEV; - } - - return drm_bridge_attach(bridge->encoder, + return drm_bridge_attach(encoder, pl->next_bridge, bridge, DRM_BRIDGE_ATTACH_NO_CONNECTOR); } @@ -158,9 +154,8 @@ imx8qxp_pixel_link_bridge_mode_set(struct drm_bridge *bridge, imx8qxp_pixel_link_set_mst_addr(pl); } -static void -imx8qxp_pixel_link_bridge_atomic_enable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) +static void imx8qxp_pixel_link_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { struct imx8qxp_pixel_link *pl = bridge->driver_private; @@ -169,9 +164,8 @@ imx8qxp_pixel_link_bridge_atomic_enable(struct drm_bridge *bridge, imx8qxp_pixel_link_enable_sync(pl); } -static void -imx8qxp_pixel_link_bridge_atomic_disable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) +static void imx8qxp_pixel_link_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { struct imx8qxp_pixel_link *pl = bridge->driver_private; @@ -414,7 +408,7 @@ MODULE_DEVICE_TABLE(of, imx8qxp_pixel_link_dt_ids); static struct platform_driver imx8qxp_pixel_link_bridge_driver = { .probe = imx8qxp_pixel_link_bridge_probe, - .remove_new = imx8qxp_pixel_link_bridge_remove, + .remove = imx8qxp_pixel_link_bridge_remove, .driver = { .of_match_table = imx8qxp_pixel_link_dt_ids, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c index 4a886cb808ca..da138ab51b3b 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c @@ -48,6 +48,7 @@ struct imx8qxp_pxl2dpi { #define bridge_to_p2d(b) container_of(b, struct imx8qxp_pxl2dpi, bridge) static int imx8qxp_pxl2dpi_bridge_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) { struct imx8qxp_pxl2dpi *p2d = bridge->driver_private; @@ -58,12 +59,7 @@ static int imx8qxp_pxl2dpi_bridge_attach(struct drm_bridge *bridge, return -EINVAL; } - if (!bridge->encoder) { - DRM_DEV_ERROR(p2d->dev, "missing encoder\n"); - return -ENODEV; - } - - return drm_bridge_attach(bridge->encoder, + return drm_bridge_attach(encoder, p2d->next_bridge, bridge, DRM_BRIDGE_ATTACH_NO_CONNECTOR); } @@ -127,9 +123,8 @@ imx8qxp_pxl2dpi_bridge_mode_set(struct drm_bridge *bridge, } } -static void -imx8qxp_pxl2dpi_bridge_atomic_disable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) +static void imx8qxp_pxl2dpi_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { struct imx8qxp_pxl2dpi *p2d = bridge->driver_private; int ret; @@ -139,8 +134,7 @@ imx8qxp_pxl2dpi_bridge_atomic_disable(struct drm_bridge *bridge, DRM_DEV_ERROR(p2d->dev, "failed to put runtime PM: %d\n", ret); if (p2d->companion) - p2d->companion->funcs->atomic_disable(p2d->companion, - old_bridge_state); + p2d->companion->funcs->atomic_disable(p2d->companion, state); } static const u32 imx8qxp_pxl2dpi_bus_output_fmts[] = { @@ -472,7 +466,7 @@ MODULE_DEVICE_TABLE(of, imx8qxp_pxl2dpi_dt_ids); static struct platform_driver imx8qxp_pxl2dpi_bridge_driver = { .probe = imx8qxp_pxl2dpi_bridge_probe, - .remove_new = imx8qxp_pxl2dpi_bridge_remove, + .remove = imx8qxp_pxl2dpi_bridge_remove, .driver = { .of_match_table = imx8qxp_pxl2dpi_dt_ids, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c index 2347f8dd632f..bea8346515b8 100644 --- a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c @@ -904,7 +904,7 @@ MODULE_DEVICE_TABLE(of, imx93_dsi_dt_ids); static struct platform_driver imx93_dsi_driver = { .probe = imx93_dsi_probe, - .remove_new = imx93_dsi_remove, + .remove = imx93_dsi_remove, .driver = { .of_match_table = imx93_dsi_dt_ids, .name = "imx93_mipi_dsi", |