diff options
Diffstat (limited to 'drivers/gpu/drm/mediatek')
22 files changed, 340 insertions, 297 deletions
diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig index b451dee64d34..76cab28e010c 100644 --- a/drivers/gpu/drm/mediatek/Kconfig +++ b/drivers/gpu/drm/mediatek/Kconfig @@ -26,6 +26,7 @@ config DRM_MEDIATEK_DP select PHY_MTK_DP select DRM_DISPLAY_HELPER select DRM_DISPLAY_DP_HELPER + select DRM_DP_AUX_BUS help DRM/KMS Display Port driver for MediaTek SoCs. diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c index b640bc0559e7..f47f417d8ba6 100644 --- a/drivers/gpu/drm/mediatek/mtk_cec.c +++ b/drivers/gpu/drm/mediatek/mtk_cec.c @@ -235,13 +235,12 @@ static int mtk_cec_probe(struct platform_device *pdev) return 0; } -static int mtk_cec_remove(struct platform_device *pdev) +static void mtk_cec_remove(struct platform_device *pdev) { struct mtk_cec *cec = platform_get_drvdata(pdev); mtk_cec_htplg_irq_disable(cec); clk_disable_unprepare(cec->clk); - return 0; } static const struct of_device_id mtk_cec_of_ids[] = { @@ -252,7 +251,7 @@ MODULE_DEVICE_TABLE(of, mtk_cec_of_ids); struct platform_driver mtk_cec_driver = { .probe = mtk_cec_probe, - .remove = mtk_cec_remove, + .remove_new = mtk_cec_remove, .driver = { .name = "mediatek-cec", .of_match_table = mtk_cec_of_ids, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_aal.c b/drivers/gpu/drm/mediatek/mtk_disp_aal.c index 434e8a9ce8ab..4da9ac93b29e 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_aal.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_aal.c @@ -6,8 +6,7 @@ #include <linux/clk.h> #include <linux/component.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_irq.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/soc/mediatek/mtk-cmdq.h> @@ -26,11 +25,6 @@ struct mtk_disp_aal_data { bool has_gamma; }; -/** - * struct mtk_disp_aal - DISP_AAL driver structure - * @ddp_comp - structure containing type enum and hardware resources - * @crtc - associated crtc to report irq events to - */ struct mtk_disp_aal { struct clk *clk; void __iomem *regs; @@ -140,11 +134,9 @@ static int mtk_disp_aal_probe(struct platform_device *pdev) return ret; } -static int mtk_disp_aal_remove(struct platform_device *pdev) +static void mtk_disp_aal_remove(struct platform_device *pdev) { component_del(&pdev->dev, &mtk_disp_aal_component_ops); - - return 0; } static const struct mtk_disp_aal_data mt8173_aal_driver_data = { @@ -161,7 +153,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_aal_driver_dt_match); struct platform_driver mtk_disp_aal_driver = { .probe = mtk_disp_aal_probe, - .remove = mtk_disp_aal_remove, + .remove_new = mtk_disp_aal_remove, .driver = { .name = "mediatek-disp-aal", .owner = THIS_MODULE, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c index 1773379b2439..4234ff7485e8 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c @@ -6,8 +6,7 @@ #include <linux/clk.h> #include <linux/component.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_irq.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/soc/mediatek/mtk-cmdq.h> @@ -34,11 +33,6 @@ struct mtk_disp_ccorr_data { u32 matrix_bits; }; -/** - * struct mtk_disp_ccorr - DISP_CCORR driver structure - * @ddp_comp - structure containing type enum and hardware resources - * @crtc - associated crtc to report irq events to - */ struct mtk_disp_ccorr { struct clk *clk; void __iomem *regs; @@ -195,11 +189,9 @@ static int mtk_disp_ccorr_probe(struct platform_device *pdev) return ret; } -static int mtk_disp_ccorr_remove(struct platform_device *pdev) +static void mtk_disp_ccorr_remove(struct platform_device *pdev) { component_del(&pdev->dev, &mtk_disp_ccorr_component_ops); - - return 0; } static const struct mtk_disp_ccorr_data mt8183_ccorr_driver_data = { @@ -221,7 +213,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_ccorr_driver_dt_match); struct platform_driver mtk_disp_ccorr_driver = { .probe = mtk_disp_ccorr_probe, - .remove = mtk_disp_ccorr_remove, + .remove_new = mtk_disp_ccorr_remove, .driver = { .name = "mediatek-disp-ccorr", .owner = THIS_MODULE, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c index cac9206079e7..78ea99f1444f 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_color.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c @@ -6,8 +6,7 @@ #include <linux/clk.h> #include <linux/component.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_irq.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/soc/mediatek/mtk-cmdq.h> @@ -132,11 +131,9 @@ static int mtk_disp_color_probe(struct platform_device *pdev) return ret; } -static int mtk_disp_color_remove(struct platform_device *pdev) +static void mtk_disp_color_remove(struct platform_device *pdev) { component_del(&pdev->dev, &mtk_disp_color_component_ops); - - return 0; } static const struct mtk_disp_color_data mt2701_color_driver_data = { @@ -164,7 +161,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_color_driver_dt_match); struct platform_driver mtk_disp_color_driver = { .probe = mtk_disp_color_probe, - .remove = mtk_disp_color_remove, + .remove_new = mtk_disp_color_remove, .driver = { .name = "mediatek-disp-color", .owner = THIS_MODULE, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c index c844942603f7..673f9a5738f2 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c @@ -6,8 +6,7 @@ #include <linux/clk.h> #include <linux/component.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_irq.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/soc/mediatek/mtk-cmdq.h> @@ -183,11 +182,9 @@ static int mtk_disp_gamma_probe(struct platform_device *pdev) return ret; } -static int mtk_disp_gamma_remove(struct platform_device *pdev) +static void mtk_disp_gamma_remove(struct platform_device *pdev) { component_del(&pdev->dev, &mtk_disp_gamma_component_ops); - - return 0; } static const struct mtk_disp_gamma_data mt8173_gamma_driver_data = { @@ -209,7 +206,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_gamma_driver_dt_match); struct platform_driver mtk_disp_gamma_driver = { .probe = mtk_disp_gamma_probe, - .remove = mtk_disp_gamma_remove, + .remove_new = mtk_disp_gamma_remove, .driver = { .name = "mediatek-disp-gamma", .owner = THIS_MODULE, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c index 6428b6203ffe..e525a6b9e5b0 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c @@ -5,8 +5,7 @@ #include <linux/clk.h> #include <linux/component.h> -#include <linux/of_device.h> -#include <linux/of_irq.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/reset.h> #include <linux/soc/mediatek/mtk-cmdq.h> @@ -295,11 +294,9 @@ static int mtk_disp_merge_probe(struct platform_device *pdev) return ret; } -static int mtk_disp_merge_remove(struct platform_device *pdev) +static void mtk_disp_merge_remove(struct platform_device *pdev) { component_del(&pdev->dev, &mtk_disp_merge_component_ops); - - return 0; } static const struct of_device_id mtk_disp_merge_driver_dt_match[] = { @@ -311,7 +308,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match); struct platform_driver mtk_disp_merge_driver = { .probe = mtk_disp_merge_probe, - .remove = mtk_disp_merge_remove, + .remove_new = mtk_disp_merge_remove, .driver = { .name = "mediatek-disp-merge", .owner = THIS_MODULE, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 8f52cc1f3fba..2bffe4245466 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -10,8 +10,7 @@ #include <linux/clk.h> #include <linux/component.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_irq.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/soc/mediatek/mtk-cmdq.h> @@ -562,12 +561,10 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev) return ret; } -static int mtk_disp_ovl_remove(struct platform_device *pdev) +static void mtk_disp_ovl_remove(struct platform_device *pdev) { component_del(&pdev->dev, &mtk_disp_ovl_component_ops); pm_runtime_disable(&pdev->dev); - - return 0; } static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = { @@ -659,7 +656,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match); struct platform_driver mtk_disp_ovl_driver = { .probe = mtk_disp_ovl_probe, - .remove = mtk_disp_ovl_remove, + .remove_new = mtk_disp_ovl_remove, .driver = { .name = "mediatek-disp-ovl", .owner = THIS_MODULE, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c index c0a38f5217ee..6bf6367853fb 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c @@ -7,8 +7,9 @@ #include <drm/drm_of.h> #include <linux/clk.h> #include <linux/component.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/of_address.h> +#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> @@ -426,7 +427,7 @@ static int ovl_adaptor_comp_init(struct device *dev, struct component_match **ma continue; } - type = (enum mtk_ovl_adaptor_comp_type)of_id->data; + type = (enum mtk_ovl_adaptor_comp_type)(uintptr_t)of_id->data; id = ovl_adaptor_comp_get_id(dev, node, type); if (id < 0) { dev_warn(dev, "Skipping unknown component %pOF\n", diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index d4df17ad600a..faa907f2f443 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -8,8 +8,7 @@ #include <linux/clk.h> #include <linux/component.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_irq.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/soc/mediatek/mtk-cmdq.h> @@ -380,13 +379,11 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev) return ret; } -static int mtk_disp_rdma_remove(struct platform_device *pdev) +static void mtk_disp_rdma_remove(struct platform_device *pdev) { component_del(&pdev->dev, &mtk_disp_rdma_component_ops); pm_runtime_disable(&pdev->dev); - - return 0; } static const struct mtk_disp_rdma_data mt2701_rdma_driver_data = { @@ -428,7 +425,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match); struct platform_driver mtk_disp_rdma_driver = { .probe = mtk_disp_rdma_probe, - .remove = mtk_disp_rdma_remove, + .remove_new = mtk_disp_rdma_remove, .driver = { .name = "mediatek-disp-rdma", .owner = THIS_MODULE, diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index 64eee77452c0..2cb47f663756 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -4,6 +4,7 @@ * Copyright (c) 2022 BayLibre */ +#include <drm/display/drm_dp_aux_bus.h> #include <drm/display/drm_dp.h> #include <drm/display/drm_dp_helper.h> #include <drm/drm_atomic_helper.h> @@ -100,6 +101,7 @@ struct mtk_dp_efuse_fmt { struct mtk_dp { bool enabled; bool need_debounce; + int irq; u8 max_lanes; u8 max_linkrate; u8 rx_cap[DP_RECEIVER_CAP_SIZE]; @@ -847,7 +849,7 @@ static int mtk_dp_aux_do_transfer(struct mtk_dp *mtk_dp, bool is_read, u8 cmd, u32 phy_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3628) & AUX_RX_PHY_STATE_AUX_TX_P0_MASK; if (phy_status != AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE) { - drm_err(mtk_dp->drm_dev, + dev_err(mtk_dp->dev, "AUX Rx Aux hang, need SW reset\n"); return -EIO; } @@ -1009,6 +1011,11 @@ static void mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp) mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_37C8, MTK_ATOP_EN_AUX_TX_P0, MTK_ATOP_EN_AUX_TX_P0); + + /* Set complete reply mode for AUX */ + mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3690, + RX_REPLY_COMPLETE_MODE_AUX_TX_P0, + RX_REPLY_COMPLETE_MODE_AUX_TX_P0); } static void mtk_dp_initialize_digital_settings(struct mtk_dp *mtk_dp) @@ -1251,6 +1258,29 @@ static void mtk_dp_audio_mute(struct mtk_dp *mtk_dp, bool mute) val[2], AU_TS_CFG_DP_ENC0_P0_MASK); } +static void mtk_dp_aux_panel_poweron(struct mtk_dp *mtk_dp, bool pwron) +{ + if (pwron) { + /* power on aux */ + mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, + DP_PWR_STATE_BANDGAP_TPLL_LANE, + DP_PWR_STATE_MASK); + + /* power on panel */ + drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D0); + usleep_range(2000, 5000); + } else { + /* power off panel */ + drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3); + usleep_range(2000, 3000); + + /* power off aux */ + mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, + DP_PWR_STATE_BANDGAP_TPLL, + DP_PWR_STATE_MASK); + } +} + static void mtk_dp_power_enable(struct mtk_dp *mtk_dp) { mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_RESET_AND_PROBE, @@ -1284,9 +1314,11 @@ static void mtk_dp_power_disable(struct mtk_dp *mtk_dp) static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp) { + bool plugged_in = (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP); + mtk_dp->train_info.link_rate = DP_LINK_BW_5_4; mtk_dp->train_info.lane_count = mtk_dp->max_lanes; - mtk_dp->train_info.cable_plugged_in = false; + mtk_dp->train_info.cable_plugged_in = plugged_in; mtk_dp->info.format = DP_PIXELFORMAT_RGB; memset(&mtk_dp->info.vm, 0, sizeof(struct videomode)); @@ -1588,7 +1620,19 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp) u8 val; ssize_t ret; - drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap); + /* + * If we're eDP and capabilities were already parsed we can skip + * reading again because eDP panels aren't hotpluggable hence the + * caps and training information won't ever change in a boot life + */ + if (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP && + mtk_dp->rx_cap[DP_MAX_LINK_RATE] && + mtk_dp->train_info.sink_ssc) + return 0; + + ret = drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap); + if (ret < 0) + return ret; if (drm_dp_tps4_supported(mtk_dp->rx_cap)) mtk_dp->train_info.channel_eq_pattern = DP_TRAINING_PATTERN_4; @@ -1615,10 +1659,13 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp) return ret == 0 ? -EIO : ret; } - if (val) - drm_dp_dpcd_writeb(&mtk_dp->aux, - DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, - val); + if (val) { + ret = drm_dp_dpcd_writeb(&mtk_dp->aux, + DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, + val); + if (ret < 0) + return ret; + } } return 0; @@ -1798,10 +1845,6 @@ static void mtk_dp_init_port(struct mtk_dp *mtk_dp) mtk_dp_initialize_settings(mtk_dp); mtk_dp_initialize_aux_settings(mtk_dp); mtk_dp_initialize_digital_settings(mtk_dp); - - mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3690, - RX_REPLY_COMPLETE_MODE_AUX_TX_P0, - RX_REPLY_COMPLETE_MODE_AUX_TX_P0); mtk_dp_initialize_hpd_detect_settings(mtk_dp); mtk_dp_digital_sw_reset(mtk_dp); @@ -1877,6 +1920,31 @@ static irqreturn_t mtk_dp_hpd_event(int hpd, void *dev) return IRQ_WAKE_THREAD; } +static int mtk_dp_wait_hpd_asserted(struct drm_dp_aux *mtk_aux, unsigned long wait_us) +{ + struct mtk_dp *mtk_dp = container_of(mtk_aux, struct mtk_dp, aux); + u32 val; + int ret; + + ret = regmap_read_poll_timeout(mtk_dp->regs, MTK_DP_TRANS_P0_3414, + val, !!(val & HPD_DB_DP_TRANS_P0_MASK), + wait_us / 100, wait_us); + if (ret) { + mtk_dp->train_info.cable_plugged_in = false; + return ret; + } + + mtk_dp->train_info.cable_plugged_in = true; + + ret = mtk_dp_parse_capabilities(mtk_dp); + if (ret) { + drm_err(mtk_dp->drm_dev, "Can't parse capabilities\n"); + return ret; + } + + return 0; +} + static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp, struct platform_device *pdev) { @@ -1918,6 +1986,9 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp, static void mtk_dp_update_plugged_status(struct mtk_dp *mtk_dp) { + if (!mtk_dp->data->audio_supported || !mtk_dp->audio_enable) + return; + mutex_lock(&mtk_dp->update_plugged_status_lock); if (mtk_dp->plugged_cb && mtk_dp->codec_dev) mtk_dp->plugged_cb(mtk_dp->codec_dev, @@ -1936,16 +2007,9 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge) if (!mtk_dp->train_info.cable_plugged_in) return ret; - if (!enabled) { - /* power on aux */ - mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, - DP_PWR_STATE_BANDGAP_TPLL_LANE, - DP_PWR_STATE_MASK); + if (!enabled) + mtk_dp_aux_panel_poweron(mtk_dp, true); - /* power on panel */ - drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D0); - usleep_range(2000, 5000); - } /* * Some dongles still source HPD when they do not connect to any * sink device. To avoid this, we need to read the sink count @@ -1957,16 +2021,8 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge) if (DP_GET_SINK_COUNT(sink_count)) ret = connector_status_connected; - if (!enabled) { - /* power off panel */ - drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3); - usleep_range(2000, 3000); - - /* power off aux */ - mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, - DP_PWR_STATE_BANDGAP_TPLL, - DP_PWR_STATE_MASK); - } + if (!enabled) + mtk_dp_aux_panel_poweron(mtk_dp, false); return ret; } @@ -1982,15 +2038,7 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge, if (!enabled) { drm_atomic_bridge_chain_pre_enable(bridge, connector->state->state); - - /* power on aux */ - mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, - DP_PWR_STATE_BANDGAP_TPLL_LANE, - DP_PWR_STATE_MASK); - - /* power on panel */ - drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D0); - usleep_range(2000, 5000); + mtk_dp_aux_panel_poweron(mtk_dp, true); } new_edid = drm_get_edid(connector, &mtk_dp->aux.ddc); @@ -2010,15 +2058,7 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge, } if (!enabled) { - /* power off panel */ - drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3); - usleep_range(2000, 3000); - - /* power off aux */ - mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, - DP_PWR_STATE_BANDGAP_TPLL, - DP_PWR_STATE_MASK); - + mtk_dp_aux_panel_poweron(mtk_dp, false); drm_atomic_bridge_chain_post_disable(bridge, connector->state->state); } @@ -2028,15 +2068,14 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge, static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux, struct drm_dp_aux_msg *msg) { - struct mtk_dp *mtk_dp; + struct mtk_dp *mtk_dp = container_of(mtk_aux, struct mtk_dp, aux); bool is_read; u8 request; size_t accessed_bytes = 0; int ret; - mtk_dp = container_of(mtk_aux, struct mtk_dp, aux); - - if (!mtk_dp->train_info.cable_plugged_in) { + if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP && + !mtk_dp->train_info.cable_plugged_in) { ret = -EAGAIN; goto err; } @@ -2057,7 +2096,7 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux, is_read = true; break; default: - drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n", + dev_err(mtk_dp->dev, "invalid aux cmd = %d\n", msg->request); ret = -EINVAL; goto err; @@ -2073,7 +2112,7 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux, to_access, &msg->reply); if (ret) { - drm_info(mtk_dp->drm_dev, + dev_info(mtk_dp->dev, "Failed to do AUX transfer: %d\n", ret); goto err; } @@ -2143,7 +2182,11 @@ static int mtk_dp_bridge_attach(struct drm_bridge *bridge, mtk_dp->drm_dev = bridge->dev; - mtk_dp_hwirq_enable(mtk_dp, true); + if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP) { + irq_clear_status_flags(mtk_dp->irq, IRQ_NOAUTOEN); + enable_irq(mtk_dp->irq); + mtk_dp_hwirq_enable(mtk_dp, true); + } return 0; @@ -2158,7 +2201,10 @@ static void mtk_dp_bridge_detach(struct drm_bridge *bridge) { struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge); - mtk_dp_hwirq_enable(mtk_dp, false); + if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP) { + mtk_dp_hwirq_enable(mtk_dp, false); + disable_irq(mtk_dp->irq); + } mtk_dp->drm_dev = NULL; mtk_dp_poweroff(mtk_dp); drm_dp_aux_unregister(&mtk_dp->aux); @@ -2178,15 +2224,7 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge, return; } - /* power on aux */ - mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, - DP_PWR_STATE_BANDGAP_TPLL_LANE, - DP_PWR_STATE_MASK); - - if (mtk_dp->train_info.cable_plugged_in) { - drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D0); - usleep_range(2000, 5000); - } + mtk_dp_aux_panel_poweron(mtk_dp, true); /* Training */ ret = mtk_dp_training(mtk_dp); @@ -2481,11 +2519,62 @@ static int mtk_dp_register_audio_driver(struct device *dev) return PTR_ERR_OR_ZERO(mtk_dp->audio_pdev); } +static int mtk_dp_register_phy(struct mtk_dp *mtk_dp) +{ + struct device *dev = mtk_dp->dev; + + mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy", + PLATFORM_DEVID_AUTO, + &mtk_dp->regs, + sizeof(struct regmap *)); + if (IS_ERR(mtk_dp->phy_dev)) + return dev_err_probe(dev, PTR_ERR(mtk_dp->phy_dev), + "Failed to create device mediatek-dp-phy\n"); + + mtk_dp_get_calibration_data(mtk_dp); + + mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp"); + if (IS_ERR(mtk_dp->phy)) { + platform_device_unregister(mtk_dp->phy_dev); + return dev_err_probe(dev, PTR_ERR(mtk_dp->phy), "Failed to get phy\n"); + } + + return 0; +} + +static int mtk_dp_edp_link_panel(struct drm_dp_aux *mtk_aux) +{ + struct mtk_dp *mtk_dp = container_of(mtk_aux, struct mtk_dp, aux); + struct device *dev = mtk_aux->dev; + int ret; + + mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); + + /* Power off the DP and AUX: either detection is done, or no panel present */ + mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, + DP_PWR_STATE_BANDGAP_TPLL, + DP_PWR_STATE_MASK); + mtk_dp_power_disable(mtk_dp); + + if (IS_ERR(mtk_dp->next_bridge)) { + ret = PTR_ERR(mtk_dp->next_bridge); + mtk_dp->next_bridge = NULL; + return ret; + } + + /* For eDP, we add the bridge only if the panel was found */ + ret = devm_drm_bridge_add(dev, &mtk_dp->bridge); + if (ret) + return ret; + + return 0; +} + static int mtk_dp_probe(struct platform_device *pdev) { struct mtk_dp *mtk_dp; struct device *dev = &pdev->dev; - int ret, irq_num; + int ret; mtk_dp = devm_kzalloc(dev, sizeof(*mtk_dp), GFP_KERNEL); if (!mtk_dp) @@ -2494,42 +2583,49 @@ static int mtk_dp_probe(struct platform_device *pdev) mtk_dp->dev = dev; mtk_dp->data = (struct mtk_dp_data *)of_device_get_match_data(dev); - irq_num = platform_get_irq(pdev, 0); - if (irq_num < 0) - return dev_err_probe(dev, irq_num, - "failed to request dp irq resource\n"); - - mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); - if (IS_ERR(mtk_dp->next_bridge) && - PTR_ERR(mtk_dp->next_bridge) == -ENODEV) - mtk_dp->next_bridge = NULL; - else if (IS_ERR(mtk_dp->next_bridge)) - return dev_err_probe(dev, PTR_ERR(mtk_dp->next_bridge), - "Failed to get bridge\n"); - ret = mtk_dp_dt_parse(mtk_dp, pdev); if (ret) return dev_err_probe(dev, ret, "Failed to parse dt\n"); - drm_dp_aux_init(&mtk_dp->aux); - mtk_dp->aux.name = "aux_mtk_dp"; - mtk_dp->aux.transfer = mtk_dp_aux_transfer; - - spin_lock_init(&mtk_dp->irq_thread_lock); + /* + * Request the interrupt and install service routine only if we are + * on full DisplayPort. + * For eDP, polling the HPD instead is more convenient because we + * don't expect any (un)plug events during runtime, hence we can + * avoid some locking. + */ + if (mtk_dp->data->bridge_type != DRM_MODE_CONNECTOR_eDP) { + mtk_dp->irq = platform_get_irq(pdev, 0); + if (mtk_dp->irq < 0) + return dev_err_probe(dev, mtk_dp->irq, + "failed to request dp irq resource\n"); + + spin_lock_init(&mtk_dp->irq_thread_lock); + + irq_set_status_flags(mtk_dp->irq, IRQ_NOAUTOEN); + ret = devm_request_threaded_irq(dev, mtk_dp->irq, mtk_dp_hpd_event, + mtk_dp_hpd_event_thread, + IRQ_TYPE_LEVEL_HIGH, dev_name(dev), + mtk_dp); + if (ret) + return dev_err_probe(dev, ret, + "failed to request mediatek dptx irq\n"); - ret = devm_request_threaded_irq(dev, irq_num, mtk_dp_hpd_event, - mtk_dp_hpd_event_thread, - IRQ_TYPE_LEVEL_HIGH, dev_name(dev), - mtk_dp); - if (ret) - return dev_err_probe(dev, ret, - "failed to request mediatek dptx irq\n"); + mtk_dp->need_debounce = true; + timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0); + } - mutex_init(&mtk_dp->update_plugged_status_lock); + mtk_dp->aux.name = "aux_mtk_dp"; + mtk_dp->aux.dev = dev; + mtk_dp->aux.transfer = mtk_dp_aux_transfer; + mtk_dp->aux.wait_hpd_asserted = mtk_dp_wait_hpd_asserted; + drm_dp_aux_init(&mtk_dp->aux); platform_set_drvdata(pdev, mtk_dp); if (mtk_dp->data->audio_supported) { + mutex_init(&mtk_dp->update_plugged_status_lock); + ret = mtk_dp_register_audio_driver(dev); if (ret) { dev_err(dev, "Failed to register audio driver: %d\n", @@ -2538,35 +2634,59 @@ static int mtk_dp_probe(struct platform_device *pdev) } } - mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy", - PLATFORM_DEVID_AUTO, - &mtk_dp->regs, - sizeof(struct regmap *)); - if (IS_ERR(mtk_dp->phy_dev)) - return dev_err_probe(dev, PTR_ERR(mtk_dp->phy_dev), - "Failed to create device mediatek-dp-phy\n"); - - mtk_dp_get_calibration_data(mtk_dp); - - mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp"); - - if (IS_ERR(mtk_dp->phy)) { - platform_device_unregister(mtk_dp->phy_dev); - return dev_err_probe(dev, PTR_ERR(mtk_dp->phy), - "Failed to get phy\n"); - } + ret = mtk_dp_register_phy(mtk_dp); + if (ret) + return ret; mtk_dp->bridge.funcs = &mtk_dp_bridge_funcs; mtk_dp->bridge.of_node = dev->of_node; - - mtk_dp->bridge.ops = - DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD; mtk_dp->bridge.type = mtk_dp->data->bridge_type; - drm_bridge_add(&mtk_dp->bridge); + if (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP) { + /* + * Set the data lanes to idle in case the bootloader didn't + * properly close the eDP port to avoid stalls and then + * reinitialize, reset and power on the AUX block. + */ + mtk_dp_set_idle_pattern(mtk_dp, true); + mtk_dp_initialize_aux_settings(mtk_dp); + mtk_dp_power_enable(mtk_dp); - mtk_dp->need_debounce = true; - timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0); + /* Disable HW interrupts: we don't need any for eDP */ + mtk_dp_hwirq_enable(mtk_dp, false); + + /* + * Power on the AUX to allow reading the EDID from aux-bus: + * please note that it is necessary to call power off in the + * .done_probing() callback (mtk_dp_edp_link_panel), as only + * there we can safely assume that we finished reading EDID. + */ + mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, + DP_PWR_STATE_BANDGAP_TPLL_LANE, + DP_PWR_STATE_MASK); + + ret = devm_of_dp_aux_populate_bus(&mtk_dp->aux, mtk_dp_edp_link_panel); + if (ret) { + /* -ENODEV this means that the panel is not on the aux-bus */ + if (ret == -ENODEV) { + ret = mtk_dp_edp_link_panel(&mtk_dp->aux); + if (ret) + return ret; + } else { + mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, + DP_PWR_STATE_BANDGAP_TPLL, + DP_PWR_STATE_MASK); + mtk_dp_power_disable(mtk_dp); + return ret; + } + } + } else { + mtk_dp->bridge.ops = DRM_BRIDGE_OP_DETECT | + DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD; + ret = devm_drm_bridge_add(dev, &mtk_dp->bridge); + if (ret) + return dev_err_probe(dev, ret, "Failed to add bridge\n"); + } pm_runtime_enable(dev); pm_runtime_get_sync(dev); @@ -2574,19 +2694,17 @@ static int mtk_dp_probe(struct platform_device *pdev) return 0; } -static int mtk_dp_remove(struct platform_device *pdev) +static void mtk_dp_remove(struct platform_device *pdev) { struct mtk_dp *mtk_dp = platform_get_drvdata(pdev); pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); - del_timer_sync(&mtk_dp->debounce_timer); - drm_bridge_remove(&mtk_dp->bridge); + if (mtk_dp->data->bridge_type != DRM_MODE_CONNECTOR_eDP) + del_timer_sync(&mtk_dp->debounce_timer); platform_device_unregister(mtk_dp->phy_dev); if (mtk_dp->audio_pdev) platform_device_unregister(mtk_dp->audio_pdev); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -2595,7 +2713,8 @@ static int mtk_dp_suspend(struct device *dev) struct mtk_dp *mtk_dp = dev_get_drvdata(dev); mtk_dp_power_disable(mtk_dp); - mtk_dp_hwirq_enable(mtk_dp, false); + if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP) + mtk_dp_hwirq_enable(mtk_dp, false); pm_runtime_put_sync(dev); return 0; @@ -2607,7 +2726,8 @@ static int mtk_dp_resume(struct device *dev) pm_runtime_get_sync(dev); mtk_dp_init_port(mtk_dp); - mtk_dp_hwirq_enable(mtk_dp, true); + if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP) + mtk_dp_hwirq_enable(mtk_dp, true); mtk_dp_power_enable(mtk_dp); return 0; @@ -2645,7 +2765,7 @@ MODULE_DEVICE_TABLE(of, mtk_dp_of_match); static struct platform_driver mtk_dp_driver = { .probe = mtk_dp_probe, - .remove = mtk_dp_remove, + .remove_new = mtk_dp_remove, .driver = { .name = "mediatek-drm-dp", .of_match_table = mtk_dp_of_match, diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 948a53f1f4b3..2f931e4e2b60 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -10,7 +10,6 @@ #include <linux/kernel.h> #include <linux/media-bus-format.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/of_graph.h> #include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> @@ -1007,7 +1006,6 @@ static int mtk_dpi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct mtk_dpi *dpi; - struct resource *mem; int ret; dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL); @@ -1038,49 +1036,34 @@ static int mtk_dpi_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Cannot find pinctrl active!\n"); } } - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dpi->regs = devm_ioremap_resource(dev, mem); - if (IS_ERR(dpi->regs)) { - ret = PTR_ERR(dpi->regs); - dev_err(dev, "Failed to ioremap mem resource: %d\n", ret); - return ret; - } + dpi->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(dpi->regs)) + return dev_err_probe(dev, PTR_ERR(dpi->regs), + "Failed to ioremap mem resource\n"); dpi->engine_clk = devm_clk_get(dev, "engine"); - if (IS_ERR(dpi->engine_clk)) { - ret = PTR_ERR(dpi->engine_clk); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get engine clock: %d\n", ret); - - return ret; - } + if (IS_ERR(dpi->engine_clk)) + return dev_err_probe(dev, PTR_ERR(dpi->engine_clk), + "Failed to get engine clock\n"); dpi->pixel_clk = devm_clk_get(dev, "pixel"); - if (IS_ERR(dpi->pixel_clk)) { - ret = PTR_ERR(dpi->pixel_clk); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get pixel clock: %d\n", ret); - - return ret; - } + if (IS_ERR(dpi->pixel_clk)) + return dev_err_probe(dev, PTR_ERR(dpi->pixel_clk), + "Failed to get pixel clock\n"); dpi->tvd_clk = devm_clk_get(dev, "pll"); - if (IS_ERR(dpi->tvd_clk)) { - ret = PTR_ERR(dpi->tvd_clk); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get tvdpll clock: %d\n", ret); - - return ret; - } + if (IS_ERR(dpi->tvd_clk)) + return dev_err_probe(dev, PTR_ERR(dpi->tvd_clk), + "Failed to get tvdpll clock\n"); dpi->irq = platform_get_irq(pdev, 0); - if (dpi->irq <= 0) - return -EINVAL; + if (dpi->irq < 0) + return dpi->irq; - ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, - NULL, &dpi->next_bridge); - if (ret) - return ret; + dpi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0); + if (IS_ERR(dpi->next_bridge)) + return dev_err_probe(dev, PTR_ERR(dpi->next_bridge), + "Failed to get bridge\n"); dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node); @@ -1090,57 +1073,37 @@ static int mtk_dpi_probe(struct platform_device *pdev) dpi->bridge.of_node = dev->of_node; dpi->bridge.type = DRM_MODE_CONNECTOR_DPI; - drm_bridge_add(&dpi->bridge); + ret = devm_drm_bridge_add(dev, &dpi->bridge); + if (ret) + return ret; ret = component_add(dev, &mtk_dpi_component_ops); - if (ret) { - drm_bridge_remove(&dpi->bridge); - dev_err(dev, "Failed to add component: %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to add component.\n"); return 0; } -static int mtk_dpi_remove(struct platform_device *pdev) +static void mtk_dpi_remove(struct platform_device *pdev) { - struct mtk_dpi *dpi = platform_get_drvdata(pdev); - component_del(&pdev->dev, &mtk_dpi_component_ops); - drm_bridge_remove(&dpi->bridge); - - return 0; } static const struct of_device_id mtk_dpi_of_ids[] = { - { .compatible = "mediatek,mt2701-dpi", - .data = &mt2701_conf, - }, - { .compatible = "mediatek,mt8173-dpi", - .data = &mt8173_conf, - }, - { .compatible = "mediatek,mt8183-dpi", - .data = &mt8183_conf, - }, - { .compatible = "mediatek,mt8186-dpi", - .data = &mt8186_conf, - }, - { .compatible = "mediatek,mt8188-dp-intf", - .data = &mt8188_dpintf_conf, - }, - { .compatible = "mediatek,mt8192-dpi", - .data = &mt8192_conf, - }, - { .compatible = "mediatek,mt8195-dp-intf", - .data = &mt8195_dpintf_conf, - }, - { }, + { .compatible = "mediatek,mt2701-dpi", .data = &mt2701_conf }, + { .compatible = "mediatek,mt8173-dpi", .data = &mt8173_conf }, + { .compatible = "mediatek,mt8183-dpi", .data = &mt8183_conf }, + { .compatible = "mediatek,mt8186-dpi", .data = &mt8186_conf }, + { .compatible = "mediatek,mt8188-dp-intf", .data = &mt8188_dpintf_conf }, + { .compatible = "mediatek,mt8192-dpi", .data = &mt8192_conf }, + { .compatible = "mediatek,mt8195-dp-intf", .data = &mt8195_dpintf_conf }, + { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids); struct platform_driver mtk_dpi_driver = { .probe = mtk_dpi_probe, - .remove = mtk_dpi_remove, + .remove_new = mtk_dpi_remove, .driver = { .name = "mediatek-dpi", .of_match_table = mtk_dpi_of_ids, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index d40142842f85..b6fa4ad2f94d 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -6,6 +6,7 @@ #include <linux/clk.h> #include <linux/dma-mapping.h> #include <linux/mailbox_controller.h> +#include <linux/of.h> #include <linux/pm_runtime.h> #include <linux/soc/mediatek/mtk-cmdq.h> #include <linux/soc/mediatek/mtk-mmsys.h> @@ -116,10 +117,9 @@ static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt * dma_addr_t dma_addr; pkt->va_base = kzalloc(size, GFP_KERNEL); - if (!pkt->va_base) { - kfree(pkt); + if (!pkt->va_base) return -ENOMEM; - } + pkt->buf_size = size; pkt->cl = (void *)client; @@ -129,7 +129,6 @@ static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt * if (dma_mapping_error(dev, dma_addr)) { dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size); kfree(pkt->va_base); - kfree(pkt); return -ENOMEM; } @@ -145,7 +144,6 @@ static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt) dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size, DMA_TO_DEVICE); kfree(pkt->va_base); - kfree(pkt); } #endif diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index f114da4d36a9..771f4e173353 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -563,14 +563,15 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, /* Not all drm components have a DTS device node, such as ovl_adaptor, * which is the drm bring up sub driver */ - if (node) { - comp_pdev = of_find_device_by_node(node); - if (!comp_pdev) { - DRM_INFO("Waiting for device %s\n", node->full_name); - return -EPROBE_DEFER; - } - comp->dev = &comp_pdev->dev; + if (!node) + return 0; + + comp_pdev = of_find_device_by_node(node); + if (!comp_pdev) { + DRM_INFO("Waiting for device %s\n", node->full_name); + return -EPROBE_DEFER; } + comp->dev = &comp_pdev->dev; if (type == MTK_DISP_AAL || type == MTK_DISP_BLS || @@ -580,7 +581,6 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, type == MTK_DISP_MERGE || type == MTK_DISP_OVL || type == MTK_DISP_OVL_2L || - type == MTK_DISP_OVL_ADAPTOR || type == MTK_DISP_PWM || type == MTK_DISP_RDMA || type == MTK_DPI || diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 6dcb4ba2466c..93552d76b6e7 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -7,8 +7,9 @@ #include <linux/component.h> #include <linux/iommu.h> #include <linux/module.h> -#include <linux/of_address.h> +#include <linux/of.h> #include <linux/of_platform.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/dma-mapping.h> @@ -354,7 +355,7 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev) const struct of_device_id *of_id; struct device_node *node; struct device *drm_dev; - int cnt = 0; + unsigned int cnt = 0; int i, j; for_each_child_of_node(phandle->parent, node) { @@ -375,6 +376,9 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev) all_drm_priv[cnt] = dev_get_drvdata(drm_dev); if (all_drm_priv[cnt] && all_drm_priv[cnt]->mtk_drm_bound) cnt++; + + if (cnt == MAX_CRTC) + break; } if (drm_priv->data->mmsys_dev_num == cnt) { @@ -556,11 +560,8 @@ static const struct drm_driver mtk_drm_driver = { .dumb_create = mtk_drm_gem_dumb_create, - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_import = mtk_drm_gem_prime_import, .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table, - .gem_prime_mmap = drm_gem_prime_mmap, .fops = &mtk_drm_fops, .name = DRIVER_NAME, @@ -829,7 +830,7 @@ static int mtk_drm_probe(struct platform_device *pdev) continue; } - comp_type = (enum mtk_ddp_comp_type)of_id->data; + comp_type = (enum mtk_ddp_comp_type)(uintptr_t)of_id->data; if (comp_type == MTK_DISP_MUTEX) { int id; @@ -909,7 +910,7 @@ err_node: return ret; } -static int mtk_drm_remove(struct platform_device *pdev) +static void mtk_drm_remove(struct platform_device *pdev) { struct mtk_drm_private *private = platform_get_drvdata(pdev); int i; @@ -919,8 +920,6 @@ static int mtk_drm_remove(struct platform_device *pdev) of_node_put(private->mutex_node); for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++) of_node_put(private->comp_node[i]); - - return 0; } static int mtk_drm_sys_prepare(struct device *dev) @@ -953,7 +952,7 @@ static const struct dev_pm_ops mtk_drm_pm_ops = { static struct platform_driver mtk_drm_platform_driver = { .probe = mtk_drm_probe, - .remove = mtk_drm_remove, + .remove_new = mtk_drm_remove, .driver = { .name = "mediatek-drm", .pm = &mtk_drm_pm_ops, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index a25b28d3ee90..9f364df52478 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -247,7 +247,11 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); - + if (!mtk_gem->kvaddr) { + kfree(sgt); + kfree(mtk_gem->pages); + return -ENOMEM; + } out: kfree(sgt); iosys_map_set_vaddr(map, mtk_gem->kvaddr); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c index 31f9420aff6f..db2f70ae060d 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c @@ -122,11 +122,7 @@ static int mtk_plane_atomic_async_check(struct drm_plane *plane, if (ret) return ret; - if (state) - crtc_state = drm_atomic_get_existing_crtc_state(state, - new_plane_state->crtc); - else /* Special case for asynchronous cursor updates. */ - crtc_state = new_plane_state->crtc->state; + crtc_state = drm_atomic_get_existing_crtc_state(state, new_plane_state->crtc); return drm_atomic_helper_check_plane_state(plane->state, crtc_state, DRM_PLANE_NO_SCALING, diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 7d5250351193..d8bfc2cce54d 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -1178,14 +1178,12 @@ err_unregister_host: return ret; } -static int mtk_dsi_remove(struct platform_device *pdev) +static void mtk_dsi_remove(struct platform_device *pdev) { struct mtk_dsi *dsi = platform_get_drvdata(pdev); mtk_output_dsi_disable(dsi); mipi_dsi_host_unregister(&dsi->host); - - return 0; } static const struct mtk_dsi_driver_data mt8173_dsi_driver_data = { @@ -1223,7 +1221,7 @@ MODULE_DEVICE_TABLE(of, mtk_dsi_of_match); struct platform_driver mtk_dsi_driver = { .probe = mtk_dsi_probe, - .remove = mtk_dsi_remove, + .remove_new = mtk_dsi_remove, .driver = { .name = "mtk-dsi", .of_match_table = mtk_dsi_of_match, diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c index 73dc4da3ba3b..db7ac666ec5e 100644 --- a/drivers/gpu/drm/mediatek/mtk_ethdr.c +++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c @@ -7,7 +7,7 @@ #include <drm/drm_framebuffer.h> #include <linux/clk.h> #include <linux/component.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/reset.h> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index 0a8e0a13f516..86133bf16326 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1746,13 +1746,12 @@ err_bridge_remove: return ret; } -static int mtk_drm_hdmi_remove(struct platform_device *pdev) +static void mtk_drm_hdmi_remove(struct platform_device *pdev) { struct mtk_hdmi *hdmi = platform_get_drvdata(pdev); drm_bridge_remove(&hdmi->bridge); mtk_hdmi_clk_disable_audio(hdmi); - return 0; } #ifdef CONFIG_PM_SLEEP @@ -1806,7 +1805,7 @@ MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_of_ids); static struct platform_driver mtk_hdmi_driver = { .probe = mtk_drm_hdmi_probe, - .remove = mtk_drm_hdmi_remove, + .remove_new = mtk_drm_hdmi_remove, .driver = { .name = "mediatek-drm-hdmi", .of_match_table = mtk_drm_hdmi_of_ids, diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c index 4d39ea0a05ca..d675c954befe 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c @@ -324,14 +324,12 @@ err_clk_disable: return ret; } -static int mtk_hdmi_ddc_remove(struct platform_device *pdev) +static void mtk_hdmi_ddc_remove(struct platform_device *pdev) { struct mtk_hdmi_ddc *ddc = platform_get_drvdata(pdev); i2c_del_adapter(&ddc->adap); clk_disable_unprepare(ddc->clk); - - return 0; } static const struct of_device_id mtk_hdmi_ddc_match[] = { @@ -342,7 +340,7 @@ MODULE_DEVICE_TABLE(of, mtk_hdmi_ddc_match); struct platform_driver mtk_hdmi_ddc_driver = { .probe = mtk_hdmi_ddc_probe, - .remove = mtk_hdmi_ddc_remove, + .remove_new = mtk_hdmi_ddc_remove, .driver = { .name = "mediatek-hdmi-ddc", .of_match_table = mtk_hdmi_ddc_match, diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c index e06db6e56b5f..c3adaeefd551 100644 --- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c @@ -6,8 +6,7 @@ #include <drm/drm_fourcc.h> #include <linux/clk.h> #include <linux/component.h> -#include <linux/of_address.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/soc/mediatek/mtk-cmdq.h> @@ -315,11 +314,10 @@ static int mtk_mdp_rdma_probe(struct platform_device *pdev) return ret; } -static int mtk_mdp_rdma_remove(struct platform_device *pdev) +static void mtk_mdp_rdma_remove(struct platform_device *pdev) { component_del(&pdev->dev, &mtk_mdp_rdma_component_ops); pm_runtime_disable(&pdev->dev); - return 0; } static const struct of_device_id mtk_mdp_rdma_driver_dt_match[] = { @@ -330,7 +328,7 @@ MODULE_DEVICE_TABLE(of, mtk_mdp_rdma_driver_dt_match); struct platform_driver mtk_mdp_rdma_driver = { .probe = mtk_mdp_rdma_probe, - .remove = mtk_mdp_rdma_remove, + .remove_new = mtk_mdp_rdma_remove, .driver = { .name = "mediatek-mdp-rdma", .owner = THIS_MODULE, |