Commit e1f9c849 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'mediatek-drm-next-6.6' of...

Merge tag 'mediatek-drm-next-6.6' of https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux into drm-next

Mediatek DRM Next for Linux 6.6

1. Small mtk-dpi cleanups
2. DisplayPort: support eDP and aux-bus
3. Fix uninitialized symbol
4. Do not check for 0 return after calling platform_get_irq()
5. Convert to platform remove callback returning void
6. Fix coverity issues
7. Fix potential memory leak if vmap() fail
8. Fix void-pointer-to-enum-cast warning
9. Rid W=1 warnings from GPU
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230813152726.14802-1-chunkuang.hu@kernel.org
parents 57bca71d fb7e600d
...@@ -26,6 +26,7 @@ config DRM_MEDIATEK_DP ...@@ -26,6 +26,7 @@ config DRM_MEDIATEK_DP
select PHY_MTK_DP select PHY_MTK_DP
select DRM_DISPLAY_HELPER select DRM_DISPLAY_HELPER
select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_DP_HELPER
select DRM_DP_AUX_BUS
help help
DRM/KMS Display Port driver for MediaTek SoCs. DRM/KMS Display Port driver for MediaTek SoCs.
......
...@@ -235,13 +235,12 @@ static int mtk_cec_probe(struct platform_device *pdev) ...@@ -235,13 +235,12 @@ static int mtk_cec_probe(struct platform_device *pdev)
return 0; 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); struct mtk_cec *cec = platform_get_drvdata(pdev);
mtk_cec_htplg_irq_disable(cec); mtk_cec_htplg_irq_disable(cec);
clk_disable_unprepare(cec->clk); clk_disable_unprepare(cec->clk);
return 0;
} }
static const struct of_device_id mtk_cec_of_ids[] = { static const struct of_device_id mtk_cec_of_ids[] = {
...@@ -252,7 +251,7 @@ MODULE_DEVICE_TABLE(of, mtk_cec_of_ids); ...@@ -252,7 +251,7 @@ MODULE_DEVICE_TABLE(of, mtk_cec_of_ids);
struct platform_driver mtk_cec_driver = { struct platform_driver mtk_cec_driver = {
.probe = mtk_cec_probe, .probe = mtk_cec_probe,
.remove = mtk_cec_remove, .remove_new = mtk_cec_remove,
.driver = { .driver = {
.name = "mediatek-cec", .name = "mediatek-cec",
.of_match_table = mtk_cec_of_ids, .of_match_table = mtk_cec_of_ids,
......
...@@ -25,11 +25,6 @@ struct mtk_disp_aal_data { ...@@ -25,11 +25,6 @@ struct mtk_disp_aal_data {
bool has_gamma; 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 mtk_disp_aal {
struct clk *clk; struct clk *clk;
void __iomem *regs; void __iomem *regs;
...@@ -139,11 +134,9 @@ static int mtk_disp_aal_probe(struct platform_device *pdev) ...@@ -139,11 +134,9 @@ static int mtk_disp_aal_probe(struct platform_device *pdev)
return ret; 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); component_del(&pdev->dev, &mtk_disp_aal_component_ops);
return 0;
} }
static const struct mtk_disp_aal_data mt8173_aal_driver_data = { static const struct mtk_disp_aal_data mt8173_aal_driver_data = {
...@@ -160,7 +153,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_aal_driver_dt_match); ...@@ -160,7 +153,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_aal_driver_dt_match);
struct platform_driver mtk_disp_aal_driver = { struct platform_driver mtk_disp_aal_driver = {
.probe = mtk_disp_aal_probe, .probe = mtk_disp_aal_probe,
.remove = mtk_disp_aal_remove, .remove_new = mtk_disp_aal_remove,
.driver = { .driver = {
.name = "mediatek-disp-aal", .name = "mediatek-disp-aal",
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -33,11 +33,6 @@ struct mtk_disp_ccorr_data { ...@@ -33,11 +33,6 @@ struct mtk_disp_ccorr_data {
u32 matrix_bits; 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 mtk_disp_ccorr {
struct clk *clk; struct clk *clk;
void __iomem *regs; void __iomem *regs;
...@@ -194,11 +189,9 @@ static int mtk_disp_ccorr_probe(struct platform_device *pdev) ...@@ -194,11 +189,9 @@ static int mtk_disp_ccorr_probe(struct platform_device *pdev)
return ret; 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); component_del(&pdev->dev, &mtk_disp_ccorr_component_ops);
return 0;
} }
static const struct mtk_disp_ccorr_data mt8183_ccorr_driver_data = { static const struct mtk_disp_ccorr_data mt8183_ccorr_driver_data = {
...@@ -220,7 +213,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_ccorr_driver_dt_match); ...@@ -220,7 +213,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_ccorr_driver_dt_match);
struct platform_driver mtk_disp_ccorr_driver = { struct platform_driver mtk_disp_ccorr_driver = {
.probe = mtk_disp_ccorr_probe, .probe = mtk_disp_ccorr_probe,
.remove = mtk_disp_ccorr_remove, .remove_new = mtk_disp_ccorr_remove,
.driver = { .driver = {
.name = "mediatek-disp-ccorr", .name = "mediatek-disp-ccorr",
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -131,11 +131,9 @@ static int mtk_disp_color_probe(struct platform_device *pdev) ...@@ -131,11 +131,9 @@ static int mtk_disp_color_probe(struct platform_device *pdev)
return ret; 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); component_del(&pdev->dev, &mtk_disp_color_component_ops);
return 0;
} }
static const struct mtk_disp_color_data mt2701_color_driver_data = { static const struct mtk_disp_color_data mt2701_color_driver_data = {
...@@ -163,7 +161,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_color_driver_dt_match); ...@@ -163,7 +161,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_color_driver_dt_match);
struct platform_driver mtk_disp_color_driver = { struct platform_driver mtk_disp_color_driver = {
.probe = mtk_disp_color_probe, .probe = mtk_disp_color_probe,
.remove = mtk_disp_color_remove, .remove_new = mtk_disp_color_remove,
.driver = { .driver = {
.name = "mediatek-disp-color", .name = "mediatek-disp-color",
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -182,11 +182,9 @@ static int mtk_disp_gamma_probe(struct platform_device *pdev) ...@@ -182,11 +182,9 @@ static int mtk_disp_gamma_probe(struct platform_device *pdev)
return ret; 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); component_del(&pdev->dev, &mtk_disp_gamma_component_ops);
return 0;
} }
static const struct mtk_disp_gamma_data mt8173_gamma_driver_data = { static const struct mtk_disp_gamma_data mt8173_gamma_driver_data = {
...@@ -208,7 +206,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_gamma_driver_dt_match); ...@@ -208,7 +206,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_gamma_driver_dt_match);
struct platform_driver mtk_disp_gamma_driver = { struct platform_driver mtk_disp_gamma_driver = {
.probe = mtk_disp_gamma_probe, .probe = mtk_disp_gamma_probe,
.remove = mtk_disp_gamma_remove, .remove_new = mtk_disp_gamma_remove,
.driver = { .driver = {
.name = "mediatek-disp-gamma", .name = "mediatek-disp-gamma",
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -294,11 +294,9 @@ static int mtk_disp_merge_probe(struct platform_device *pdev) ...@@ -294,11 +294,9 @@ static int mtk_disp_merge_probe(struct platform_device *pdev)
return ret; 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); component_del(&pdev->dev, &mtk_disp_merge_component_ops);
return 0;
} }
static const struct of_device_id mtk_disp_merge_driver_dt_match[] = { static const struct of_device_id mtk_disp_merge_driver_dt_match[] = {
...@@ -310,7 +308,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match); ...@@ -310,7 +308,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match);
struct platform_driver mtk_disp_merge_driver = { struct platform_driver mtk_disp_merge_driver = {
.probe = mtk_disp_merge_probe, .probe = mtk_disp_merge_probe,
.remove = mtk_disp_merge_remove, .remove_new = mtk_disp_merge_remove,
.driver = { .driver = {
.name = "mediatek-disp-merge", .name = "mediatek-disp-merge",
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -561,12 +561,10 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev) ...@@ -561,12 +561,10 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
return ret; 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); component_del(&pdev->dev, &mtk_disp_ovl_component_ops);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
return 0;
} }
static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = { static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = {
...@@ -658,7 +656,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match); ...@@ -658,7 +656,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match);
struct platform_driver mtk_disp_ovl_driver = { struct platform_driver mtk_disp_ovl_driver = {
.probe = mtk_disp_ovl_probe, .probe = mtk_disp_ovl_probe,
.remove = mtk_disp_ovl_remove, .remove_new = mtk_disp_ovl_remove,
.driver = { .driver = {
.name = "mediatek-disp-ovl", .name = "mediatek-disp-ovl",
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -427,7 +427,7 @@ static int ovl_adaptor_comp_init(struct device *dev, struct component_match **ma ...@@ -427,7 +427,7 @@ static int ovl_adaptor_comp_init(struct device *dev, struct component_match **ma
continue; 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); id = ovl_adaptor_comp_get_id(dev, node, type);
if (id < 0) { if (id < 0) {
dev_warn(dev, "Skipping unknown component %pOF\n", dev_warn(dev, "Skipping unknown component %pOF\n",
......
...@@ -379,13 +379,11 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev) ...@@ -379,13 +379,11 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
return ret; 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); component_del(&pdev->dev, &mtk_disp_rdma_component_ops);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
return 0;
} }
static const struct mtk_disp_rdma_data mt2701_rdma_driver_data = { static const struct mtk_disp_rdma_data mt2701_rdma_driver_data = {
...@@ -427,7 +425,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match); ...@@ -427,7 +425,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
struct platform_driver mtk_disp_rdma_driver = { struct platform_driver mtk_disp_rdma_driver = {
.probe = mtk_disp_rdma_probe, .probe = mtk_disp_rdma_probe,
.remove = mtk_disp_rdma_remove, .remove_new = mtk_disp_rdma_remove,
.driver = { .driver = {
.name = "mediatek-disp-rdma", .name = "mediatek-disp-rdma",
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* Copyright (c) 2022 BayLibre * Copyright (c) 2022 BayLibre
*/ */
#include <drm/display/drm_dp_aux_bus.h>
#include <drm/display/drm_dp.h> #include <drm/display/drm_dp.h>
#include <drm/display/drm_dp_helper.h> #include <drm/display/drm_dp_helper.h>
#include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_helper.h>
...@@ -100,6 +101,7 @@ struct mtk_dp_efuse_fmt { ...@@ -100,6 +101,7 @@ struct mtk_dp_efuse_fmt {
struct mtk_dp { struct mtk_dp {
bool enabled; bool enabled;
bool need_debounce; bool need_debounce;
int irq;
u8 max_lanes; u8 max_lanes;
u8 max_linkrate; u8 max_linkrate;
u8 rx_cap[DP_RECEIVER_CAP_SIZE]; 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, ...@@ -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) & u32 phy_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3628) &
AUX_RX_PHY_STATE_AUX_TX_P0_MASK; AUX_RX_PHY_STATE_AUX_TX_P0_MASK;
if (phy_status != AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE) { 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"); "AUX Rx Aux hang, need SW reset\n");
return -EIO; return -EIO;
} }
...@@ -1009,6 +1011,11 @@ static void mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp) ...@@ -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_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_37C8,
MTK_ATOP_EN_AUX_TX_P0, MTK_ATOP_EN_AUX_TX_P0,
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) 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) ...@@ -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); 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) static void mtk_dp_power_enable(struct mtk_dp *mtk_dp)
{ {
mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_RESET_AND_PROBE, 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) ...@@ -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) 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.link_rate = DP_LINK_BW_5_4;
mtk_dp->train_info.lane_count = mtk_dp->max_lanes; 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; mtk_dp->info.format = DP_PIXELFORMAT_RGB;
memset(&mtk_dp->info.vm, 0, sizeof(struct videomode)); memset(&mtk_dp->info.vm, 0, sizeof(struct videomode));
...@@ -1588,7 +1620,19 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp) ...@@ -1588,7 +1620,19 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
u8 val; u8 val;
ssize_t ret; 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)) if (drm_dp_tps4_supported(mtk_dp->rx_cap))
mtk_dp->train_info.channel_eq_pattern = DP_TRAINING_PATTERN_4; 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) ...@@ -1615,10 +1659,13 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
return ret == 0 ? -EIO : ret; return ret == 0 ? -EIO : ret;
} }
if (val) if (val) {
drm_dp_dpcd_writeb(&mtk_dp->aux, ret = drm_dp_dpcd_writeb(&mtk_dp->aux,
DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
val); val);
if (ret < 0)
return ret;
}
} }
return 0; return 0;
...@@ -1798,10 +1845,6 @@ static void mtk_dp_init_port(struct mtk_dp *mtk_dp) ...@@ -1798,10 +1845,6 @@ static void mtk_dp_init_port(struct mtk_dp *mtk_dp)
mtk_dp_initialize_settings(mtk_dp); mtk_dp_initialize_settings(mtk_dp);
mtk_dp_initialize_aux_settings(mtk_dp); mtk_dp_initialize_aux_settings(mtk_dp);
mtk_dp_initialize_digital_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_initialize_hpd_detect_settings(mtk_dp);
mtk_dp_digital_sw_reset(mtk_dp); mtk_dp_digital_sw_reset(mtk_dp);
...@@ -1877,6 +1920,31 @@ static irqreturn_t mtk_dp_hpd_event(int hpd, void *dev) ...@@ -1877,6 +1920,31 @@ static irqreturn_t mtk_dp_hpd_event(int hpd, void *dev)
return IRQ_WAKE_THREAD; 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, static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
struct platform_device *pdev) struct platform_device *pdev)
{ {
...@@ -1918,6 +1986,9 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp, ...@@ -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) 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); mutex_lock(&mtk_dp->update_plugged_status_lock);
if (mtk_dp->plugged_cb && mtk_dp->codec_dev) if (mtk_dp->plugged_cb && mtk_dp->codec_dev)
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) ...@@ -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) if (!mtk_dp->train_info.cable_plugged_in)
return ret; return ret;
if (!enabled) { if (!enabled)
/* power on aux */ mtk_dp_aux_panel_poweron(mtk_dp, true);
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);
}
/* /*
* Some dongles still source HPD when they do not connect to any * Some dongles still source HPD when they do not connect to any
* sink device. To avoid this, we need to read the sink count * 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) ...@@ -1957,16 +2021,8 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
if (DP_GET_SINK_COUNT(sink_count)) if (DP_GET_SINK_COUNT(sink_count))
ret = connector_status_connected; ret = connector_status_connected;
if (!enabled) { if (!enabled)
/* power off panel */ mtk_dp_aux_panel_poweron(mtk_dp, false);
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);
}
return ret; return ret;
} }
...@@ -1982,15 +2038,7 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge, ...@@ -1982,15 +2038,7 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
if (!enabled) { if (!enabled) {
drm_atomic_bridge_chain_pre_enable(bridge, connector->state->state); drm_atomic_bridge_chain_pre_enable(bridge, connector->state->state);
mtk_dp_aux_panel_poweron(mtk_dp, true);
/* 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);
} }
new_edid = drm_get_edid(connector, &mtk_dp->aux.ddc); 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, ...@@ -2010,15 +2058,7 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
} }
if (!enabled) { if (!enabled) {
/* power off panel */ mtk_dp_aux_panel_poweron(mtk_dp, false);
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);
drm_atomic_bridge_chain_post_disable(bridge, connector->state->state); 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, ...@@ -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, static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
struct drm_dp_aux_msg *msg) 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; bool is_read;
u8 request; u8 request;
size_t accessed_bytes = 0; size_t accessed_bytes = 0;
int ret; int ret;
mtk_dp = container_of(mtk_aux, struct mtk_dp, aux); if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP &&
!mtk_dp->train_info.cable_plugged_in) {
if (!mtk_dp->train_info.cable_plugged_in) {
ret = -EAGAIN; ret = -EAGAIN;
goto err; goto err;
} }
...@@ -2057,7 +2096,7 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux, ...@@ -2057,7 +2096,7 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
is_read = true; is_read = true;
break; break;
default: default:
drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n", dev_err(mtk_dp->dev, "invalid aux cmd = %d\n",
msg->request); msg->request);
ret = -EINVAL; ret = -EINVAL;
goto err; goto err;
...@@ -2073,7 +2112,7 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux, ...@@ -2073,7 +2112,7 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
to_access, &msg->reply); to_access, &msg->reply);
if (ret) { if (ret) {
drm_info(mtk_dp->drm_dev, dev_info(mtk_dp->dev,
"Failed to do AUX transfer: %d\n", ret); "Failed to do AUX transfer: %d\n", ret);
goto err; goto err;
} }
...@@ -2143,7 +2182,11 @@ static int mtk_dp_bridge_attach(struct drm_bridge *bridge, ...@@ -2143,7 +2182,11 @@ static int mtk_dp_bridge_attach(struct drm_bridge *bridge,
mtk_dp->drm_dev = bridge->dev; 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; return 0;
...@@ -2158,7 +2201,10 @@ static void mtk_dp_bridge_detach(struct drm_bridge *bridge) ...@@ -2158,7 +2201,10 @@ static void mtk_dp_bridge_detach(struct drm_bridge *bridge)
{ {
struct mtk_dp *mtk_dp = mtk_dp_from_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->drm_dev = NULL;
mtk_dp_poweroff(mtk_dp); mtk_dp_poweroff(mtk_dp);
drm_dp_aux_unregister(&mtk_dp->aux); drm_dp_aux_unregister(&mtk_dp->aux);
...@@ -2178,15 +2224,7 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge, ...@@ -2178,15 +2224,7 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
return; return;
} }
/* power on aux */ mtk_dp_aux_panel_poweron(mtk_dp, true);
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);
}
/* Training */ /* Training */
ret = mtk_dp_training(mtk_dp); ret = mtk_dp_training(mtk_dp);
...@@ -2481,11 +2519,62 @@ static int mtk_dp_register_audio_driver(struct device *dev) ...@@ -2481,11 +2519,62 @@ static int mtk_dp_register_audio_driver(struct device *dev)
return PTR_ERR_OR_ZERO(mtk_dp->audio_pdev); 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) static int mtk_dp_probe(struct platform_device *pdev)
{ {
struct mtk_dp *mtk_dp; struct mtk_dp *mtk_dp;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
int ret, irq_num; int ret;
mtk_dp = devm_kzalloc(dev, sizeof(*mtk_dp), GFP_KERNEL); mtk_dp = devm_kzalloc(dev, sizeof(*mtk_dp), GFP_KERNEL);
if (!mtk_dp) if (!mtk_dp)
...@@ -2494,42 +2583,49 @@ static int mtk_dp_probe(struct platform_device *pdev) ...@@ -2494,42 +2583,49 @@ static int mtk_dp_probe(struct platform_device *pdev)
mtk_dp->dev = dev; mtk_dp->dev = dev;
mtk_dp->data = (struct mtk_dp_data *)of_device_get_match_data(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); ret = mtk_dp_dt_parse(mtk_dp, pdev);
if (ret) if (ret)
return dev_err_probe(dev, ret, "Failed to parse dt\n"); 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"; * Request the interrupt and install service routine only if we are
mtk_dp->aux.transfer = mtk_dp_aux_transfer; * on full DisplayPort.
* For eDP, polling the HPD instead is more convenient because we
spin_lock_init(&mtk_dp->irq_thread_lock); * 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->need_debounce = true;
mtk_dp_hpd_event_thread, timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0);
IRQ_TYPE_LEVEL_HIGH, dev_name(dev), }
mtk_dp);
if (ret)
return dev_err_probe(dev, ret,
"failed to request mediatek dptx irq\n");
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); platform_set_drvdata(pdev, mtk_dp);
if (mtk_dp->data->audio_supported) { if (mtk_dp->data->audio_supported) {
mutex_init(&mtk_dp->update_plugged_status_lock);
ret = mtk_dp_register_audio_driver(dev); ret = mtk_dp_register_audio_driver(dev);
if (ret) { if (ret) {
dev_err(dev, "Failed to register audio driver: %d\n", dev_err(dev, "Failed to register audio driver: %d\n",
...@@ -2538,35 +2634,59 @@ static int mtk_dp_probe(struct platform_device *pdev) ...@@ -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", ret = mtk_dp_register_phy(mtk_dp);
PLATFORM_DEVID_AUTO, if (ret)
&mtk_dp->regs, return ret;
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");
}
mtk_dp->bridge.funcs = &mtk_dp_bridge_funcs; mtk_dp->bridge.funcs = &mtk_dp_bridge_funcs;
mtk_dp->bridge.of_node = dev->of_node; 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; 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; /* Disable HW interrupts: we don't need any for eDP */
timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0); 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_enable(dev);
pm_runtime_get_sync(dev); pm_runtime_get_sync(dev);
...@@ -2574,19 +2694,17 @@ static int mtk_dp_probe(struct platform_device *pdev) ...@@ -2574,19 +2694,17 @@ static int mtk_dp_probe(struct platform_device *pdev)
return 0; 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); struct mtk_dp *mtk_dp = platform_get_drvdata(pdev);
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
del_timer_sync(&mtk_dp->debounce_timer); if (mtk_dp->data->bridge_type != DRM_MODE_CONNECTOR_eDP)
drm_bridge_remove(&mtk_dp->bridge); del_timer_sync(&mtk_dp->debounce_timer);
platform_device_unregister(mtk_dp->phy_dev); platform_device_unregister(mtk_dp->phy_dev);
if (mtk_dp->audio_pdev) if (mtk_dp->audio_pdev)
platform_device_unregister(mtk_dp->audio_pdev); platform_device_unregister(mtk_dp->audio_pdev);
return 0;
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
...@@ -2595,7 +2713,8 @@ static int mtk_dp_suspend(struct device *dev) ...@@ -2595,7 +2713,8 @@ static int mtk_dp_suspend(struct device *dev)
struct mtk_dp *mtk_dp = dev_get_drvdata(dev); struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
mtk_dp_power_disable(mtk_dp); 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); pm_runtime_put_sync(dev);
return 0; return 0;
...@@ -2607,7 +2726,8 @@ static int mtk_dp_resume(struct device *dev) ...@@ -2607,7 +2726,8 @@ static int mtk_dp_resume(struct device *dev)
pm_runtime_get_sync(dev); pm_runtime_get_sync(dev);
mtk_dp_init_port(mtk_dp); 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); mtk_dp_power_enable(mtk_dp);
return 0; return 0;
...@@ -2645,7 +2765,7 @@ MODULE_DEVICE_TABLE(of, mtk_dp_of_match); ...@@ -2645,7 +2765,7 @@ MODULE_DEVICE_TABLE(of, mtk_dp_of_match);
static struct platform_driver mtk_dp_driver = { static struct platform_driver mtk_dp_driver = {
.probe = mtk_dp_probe, .probe = mtk_dp_probe,
.remove = mtk_dp_remove, .remove_new = mtk_dp_remove,
.driver = { .driver = {
.name = "mediatek-drm-dp", .name = "mediatek-drm-dp",
.of_match_table = mtk_dp_of_match, .of_match_table = mtk_dp_of_match,
......
...@@ -1006,7 +1006,6 @@ static int mtk_dpi_probe(struct platform_device *pdev) ...@@ -1006,7 +1006,6 @@ static int mtk_dpi_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct mtk_dpi *dpi; struct mtk_dpi *dpi;
struct resource *mem;
int ret; int ret;
dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL); dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL);
...@@ -1037,49 +1036,34 @@ static int mtk_dpi_probe(struct platform_device *pdev) ...@@ -1037,49 +1036,34 @@ static int mtk_dpi_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "Cannot find pinctrl active!\n"); dev_dbg(&pdev->dev, "Cannot find pinctrl active!\n");
} }
} }
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); dpi->regs = devm_platform_ioremap_resource(pdev, 0);
dpi->regs = devm_ioremap_resource(dev, mem); if (IS_ERR(dpi->regs))
if (IS_ERR(dpi->regs)) { return dev_err_probe(dev, PTR_ERR(dpi->regs),
ret = PTR_ERR(dpi->regs); "Failed to ioremap mem resource\n");
dev_err(dev, "Failed to ioremap mem resource: %d\n", ret);
return ret;
}
dpi->engine_clk = devm_clk_get(dev, "engine"); dpi->engine_clk = devm_clk_get(dev, "engine");
if (IS_ERR(dpi->engine_clk)) { if (IS_ERR(dpi->engine_clk))
ret = PTR_ERR(dpi->engine_clk); return dev_err_probe(dev, PTR_ERR(dpi->engine_clk),
if (ret != -EPROBE_DEFER) "Failed to get engine clock\n");
dev_err(dev, "Failed to get engine clock: %d\n", ret);
return ret;
}
dpi->pixel_clk = devm_clk_get(dev, "pixel"); dpi->pixel_clk = devm_clk_get(dev, "pixel");
if (IS_ERR(dpi->pixel_clk)) { if (IS_ERR(dpi->pixel_clk))
ret = PTR_ERR(dpi->pixel_clk); return dev_err_probe(dev, PTR_ERR(dpi->pixel_clk),
if (ret != -EPROBE_DEFER) "Failed to get pixel clock\n");
dev_err(dev, "Failed to get pixel clock: %d\n", ret);
return ret;
}
dpi->tvd_clk = devm_clk_get(dev, "pll"); dpi->tvd_clk = devm_clk_get(dev, "pll");
if (IS_ERR(dpi->tvd_clk)) { if (IS_ERR(dpi->tvd_clk))
ret = PTR_ERR(dpi->tvd_clk); return dev_err_probe(dev, PTR_ERR(dpi->tvd_clk),
if (ret != -EPROBE_DEFER) "Failed to get tvdpll clock\n");
dev_err(dev, "Failed to get tvdpll clock: %d\n", ret);
return ret;
}
dpi->irq = platform_get_irq(pdev, 0); dpi->irq = platform_get_irq(pdev, 0);
if (dpi->irq <= 0) if (dpi->irq < 0)
return -EINVAL; return dpi->irq;
ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, dpi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
NULL, &dpi->next_bridge); if (IS_ERR(dpi->next_bridge))
if (ret) return dev_err_probe(dev, PTR_ERR(dpi->next_bridge),
return ret; "Failed to get bridge\n");
dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node); dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node);
...@@ -1089,57 +1073,37 @@ static int mtk_dpi_probe(struct platform_device *pdev) ...@@ -1089,57 +1073,37 @@ static int mtk_dpi_probe(struct platform_device *pdev)
dpi->bridge.of_node = dev->of_node; dpi->bridge.of_node = dev->of_node;
dpi->bridge.type = DRM_MODE_CONNECTOR_DPI; 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); ret = component_add(dev, &mtk_dpi_component_ops);
if (ret) { if (ret)
drm_bridge_remove(&dpi->bridge); return dev_err_probe(dev, ret, "Failed to add component.\n");
dev_err(dev, "Failed to add component: %d\n", ret);
return ret;
}
return 0; 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); 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[] = { static const struct of_device_id mtk_dpi_of_ids[] = {
{ .compatible = "mediatek,mt2701-dpi", { .compatible = "mediatek,mt2701-dpi", .data = &mt2701_conf },
.data = &mt2701_conf, { .compatible = "mediatek,mt8173-dpi", .data = &mt8173_conf },
}, { .compatible = "mediatek,mt8183-dpi", .data = &mt8183_conf },
{ .compatible = "mediatek,mt8173-dpi", { .compatible = "mediatek,mt8186-dpi", .data = &mt8186_conf },
.data = &mt8173_conf, { .compatible = "mediatek,mt8188-dp-intf", .data = &mt8188_dpintf_conf },
}, { .compatible = "mediatek,mt8192-dpi", .data = &mt8192_conf },
{ .compatible = "mediatek,mt8183-dpi", { .compatible = "mediatek,mt8195-dp-intf", .data = &mt8195_dpintf_conf },
.data = &mt8183_conf, { /* sentinel */ },
},
{ .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,
},
{ },
}; };
MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids); MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
struct platform_driver mtk_dpi_driver = { struct platform_driver mtk_dpi_driver = {
.probe = mtk_dpi_probe, .probe = mtk_dpi_probe,
.remove = mtk_dpi_remove, .remove_new = mtk_dpi_remove,
.driver = { .driver = {
.name = "mediatek-dpi", .name = "mediatek-dpi",
.of_match_table = mtk_dpi_of_ids, .of_match_table = mtk_dpi_of_ids,
......
...@@ -117,10 +117,9 @@ static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt * ...@@ -117,10 +117,9 @@ static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *
dma_addr_t dma_addr; dma_addr_t dma_addr;
pkt->va_base = kzalloc(size, GFP_KERNEL); pkt->va_base = kzalloc(size, GFP_KERNEL);
if (!pkt->va_base) { if (!pkt->va_base)
kfree(pkt);
return -ENOMEM; return -ENOMEM;
}
pkt->buf_size = size; pkt->buf_size = size;
pkt->cl = (void *)client; pkt->cl = (void *)client;
...@@ -130,7 +129,6 @@ static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt * ...@@ -130,7 +129,6 @@ static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *
if (dma_mapping_error(dev, dma_addr)) { if (dma_mapping_error(dev, dma_addr)) {
dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size); dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
kfree(pkt->va_base); kfree(pkt->va_base);
kfree(pkt);
return -ENOMEM; return -ENOMEM;
} }
...@@ -146,7 +144,6 @@ static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt) ...@@ -146,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_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
DMA_TO_DEVICE); DMA_TO_DEVICE);
kfree(pkt->va_base); kfree(pkt->va_base);
kfree(pkt);
} }
#endif #endif
......
...@@ -563,14 +563,15 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, ...@@ -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, /* Not all drm components have a DTS device node, such as ovl_adaptor,
* which is the drm bring up sub driver * which is the drm bring up sub driver
*/ */
if (node) { if (!node)
comp_pdev = of_find_device_by_node(node); return 0;
if (!comp_pdev) {
DRM_INFO("Waiting for device %s\n", node->full_name); comp_pdev = of_find_device_by_node(node);
return -EPROBE_DEFER; if (!comp_pdev) {
} DRM_INFO("Waiting for device %s\n", node->full_name);
comp->dev = &comp_pdev->dev; return -EPROBE_DEFER;
} }
comp->dev = &comp_pdev->dev;
if (type == MTK_DISP_AAL || if (type == MTK_DISP_AAL ||
type == MTK_DISP_BLS || type == MTK_DISP_BLS ||
...@@ -580,7 +581,6 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, ...@@ -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_MERGE ||
type == MTK_DISP_OVL || type == MTK_DISP_OVL ||
type == MTK_DISP_OVL_2L || type == MTK_DISP_OVL_2L ||
type == MTK_DISP_OVL_ADAPTOR ||
type == MTK_DISP_PWM || type == MTK_DISP_PWM ||
type == MTK_DISP_RDMA || type == MTK_DISP_RDMA ||
type == MTK_DPI || type == MTK_DPI ||
......
...@@ -355,7 +355,7 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev) ...@@ -355,7 +355,7 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
const struct of_device_id *of_id; const struct of_device_id *of_id;
struct device_node *node; struct device_node *node;
struct device *drm_dev; struct device *drm_dev;
int cnt = 0; unsigned int cnt = 0;
int i, j; int i, j;
for_each_child_of_node(phandle->parent, node) { for_each_child_of_node(phandle->parent, node) {
...@@ -376,6 +376,9 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev) ...@@ -376,6 +376,9 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
all_drm_priv[cnt] = dev_get_drvdata(drm_dev); all_drm_priv[cnt] = dev_get_drvdata(drm_dev);
if (all_drm_priv[cnt] && all_drm_priv[cnt]->mtk_drm_bound) if (all_drm_priv[cnt] && all_drm_priv[cnt]->mtk_drm_bound)
cnt++; cnt++;
if (cnt == MAX_CRTC)
break;
} }
if (drm_priv->data->mmsys_dev_num == cnt) { if (drm_priv->data->mmsys_dev_num == cnt) {
...@@ -827,7 +830,7 @@ static int mtk_drm_probe(struct platform_device *pdev) ...@@ -827,7 +830,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
continue; 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) { if (comp_type == MTK_DISP_MUTEX) {
int id; int id;
...@@ -907,7 +910,7 @@ static int mtk_drm_probe(struct platform_device *pdev) ...@@ -907,7 +910,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
return ret; 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); struct mtk_drm_private *private = platform_get_drvdata(pdev);
int i; int i;
...@@ -917,8 +920,6 @@ static int mtk_drm_remove(struct platform_device *pdev) ...@@ -917,8 +920,6 @@ static int mtk_drm_remove(struct platform_device *pdev)
of_node_put(private->mutex_node); of_node_put(private->mutex_node);
for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++) for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)
of_node_put(private->comp_node[i]); of_node_put(private->comp_node[i]);
return 0;
} }
static int mtk_drm_sys_prepare(struct device *dev) static int mtk_drm_sys_prepare(struct device *dev)
...@@ -951,7 +952,7 @@ static const struct dev_pm_ops mtk_drm_pm_ops = { ...@@ -951,7 +952,7 @@ static const struct dev_pm_ops mtk_drm_pm_ops = {
static struct platform_driver mtk_drm_platform_driver = { static struct platform_driver mtk_drm_platform_driver = {
.probe = mtk_drm_probe, .probe = mtk_drm_probe,
.remove = mtk_drm_remove, .remove_new = mtk_drm_remove,
.driver = { .driver = {
.name = "mediatek-drm", .name = "mediatek-drm",
.pm = &mtk_drm_pm_ops, .pm = &mtk_drm_pm_ops,
......
...@@ -247,7 +247,11 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) ...@@ -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, mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP,
pgprot_writecombine(PAGE_KERNEL)); pgprot_writecombine(PAGE_KERNEL));
if (!mtk_gem->kvaddr) {
kfree(sgt);
kfree(mtk_gem->pages);
return -ENOMEM;
}
out: out:
kfree(sgt); kfree(sgt);
iosys_map_set_vaddr(map, mtk_gem->kvaddr); iosys_map_set_vaddr(map, mtk_gem->kvaddr);
......
...@@ -122,11 +122,7 @@ static int mtk_plane_atomic_async_check(struct drm_plane *plane, ...@@ -122,11 +122,7 @@ static int mtk_plane_atomic_async_check(struct drm_plane *plane,
if (ret) if (ret)
return ret; return ret;
if (state) crtc_state = drm_atomic_get_existing_crtc_state(state, new_plane_state->crtc);
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;
return drm_atomic_helper_check_plane_state(plane->state, crtc_state, return drm_atomic_helper_check_plane_state(plane->state, crtc_state,
DRM_PLANE_NO_SCALING, DRM_PLANE_NO_SCALING,
......
...@@ -1178,14 +1178,12 @@ static int mtk_dsi_probe(struct platform_device *pdev) ...@@ -1178,14 +1178,12 @@ static int mtk_dsi_probe(struct platform_device *pdev)
return ret; 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); struct mtk_dsi *dsi = platform_get_drvdata(pdev);
mtk_output_dsi_disable(dsi); mtk_output_dsi_disable(dsi);
mipi_dsi_host_unregister(&dsi->host); mipi_dsi_host_unregister(&dsi->host);
return 0;
} }
static const struct mtk_dsi_driver_data mt8173_dsi_driver_data = { static const struct mtk_dsi_driver_data mt8173_dsi_driver_data = {
...@@ -1223,7 +1221,7 @@ MODULE_DEVICE_TABLE(of, mtk_dsi_of_match); ...@@ -1223,7 +1221,7 @@ MODULE_DEVICE_TABLE(of, mtk_dsi_of_match);
struct platform_driver mtk_dsi_driver = { struct platform_driver mtk_dsi_driver = {
.probe = mtk_dsi_probe, .probe = mtk_dsi_probe,
.remove = mtk_dsi_remove, .remove_new = mtk_dsi_remove,
.driver = { .driver = {
.name = "mtk-dsi", .name = "mtk-dsi",
.of_match_table = mtk_dsi_of_match, .of_match_table = mtk_dsi_of_match,
......
...@@ -1746,13 +1746,12 @@ static int mtk_drm_hdmi_probe(struct platform_device *pdev) ...@@ -1746,13 +1746,12 @@ static int mtk_drm_hdmi_probe(struct platform_device *pdev)
return ret; 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); struct mtk_hdmi *hdmi = platform_get_drvdata(pdev);
drm_bridge_remove(&hdmi->bridge); drm_bridge_remove(&hdmi->bridge);
mtk_hdmi_clk_disable_audio(hdmi); mtk_hdmi_clk_disable_audio(hdmi);
return 0;
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
...@@ -1806,7 +1805,7 @@ MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_of_ids); ...@@ -1806,7 +1805,7 @@ MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_of_ids);
static struct platform_driver mtk_hdmi_driver = { static struct platform_driver mtk_hdmi_driver = {
.probe = mtk_drm_hdmi_probe, .probe = mtk_drm_hdmi_probe,
.remove = mtk_drm_hdmi_remove, .remove_new = mtk_drm_hdmi_remove,
.driver = { .driver = {
.name = "mediatek-drm-hdmi", .name = "mediatek-drm-hdmi",
.of_match_table = mtk_drm_hdmi_of_ids, .of_match_table = mtk_drm_hdmi_of_ids,
......
...@@ -324,14 +324,12 @@ static int mtk_hdmi_ddc_probe(struct platform_device *pdev) ...@@ -324,14 +324,12 @@ static int mtk_hdmi_ddc_probe(struct platform_device *pdev)
return ret; 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); struct mtk_hdmi_ddc *ddc = platform_get_drvdata(pdev);
i2c_del_adapter(&ddc->adap); i2c_del_adapter(&ddc->adap);
clk_disable_unprepare(ddc->clk); clk_disable_unprepare(ddc->clk);
return 0;
} }
static const struct of_device_id mtk_hdmi_ddc_match[] = { static const struct of_device_id mtk_hdmi_ddc_match[] = {
...@@ -342,7 +340,7 @@ MODULE_DEVICE_TABLE(of, mtk_hdmi_ddc_match); ...@@ -342,7 +340,7 @@ MODULE_DEVICE_TABLE(of, mtk_hdmi_ddc_match);
struct platform_driver mtk_hdmi_ddc_driver = { struct platform_driver mtk_hdmi_ddc_driver = {
.probe = mtk_hdmi_ddc_probe, .probe = mtk_hdmi_ddc_probe,
.remove = mtk_hdmi_ddc_remove, .remove_new = mtk_hdmi_ddc_remove,
.driver = { .driver = {
.name = "mediatek-hdmi-ddc", .name = "mediatek-hdmi-ddc",
.of_match_table = mtk_hdmi_ddc_match, .of_match_table = mtk_hdmi_ddc_match,
......
...@@ -314,11 +314,10 @@ static int mtk_mdp_rdma_probe(struct platform_device *pdev) ...@@ -314,11 +314,10 @@ static int mtk_mdp_rdma_probe(struct platform_device *pdev)
return ret; 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); component_del(&pdev->dev, &mtk_mdp_rdma_component_ops);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
return 0;
} }
static const struct of_device_id mtk_mdp_rdma_driver_dt_match[] = { static const struct of_device_id mtk_mdp_rdma_driver_dt_match[] = {
...@@ -329,7 +328,7 @@ MODULE_DEVICE_TABLE(of, mtk_mdp_rdma_driver_dt_match); ...@@ -329,7 +328,7 @@ MODULE_DEVICE_TABLE(of, mtk_mdp_rdma_driver_dt_match);
struct platform_driver mtk_mdp_rdma_driver = { struct platform_driver mtk_mdp_rdma_driver = {
.probe = mtk_mdp_rdma_probe, .probe = mtk_mdp_rdma_probe,
.remove = mtk_mdp_rdma_remove, .remove_new = mtk_mdp_rdma_remove,
.driver = { .driver = {
.name = "mediatek-mdp-rdma", .name = "mediatek-mdp-rdma",
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment