diff --git a/drivers/gpu/drm/rockchip/dw-dp.c b/drivers/gpu/drm/rockchip/dw-dp.c index c18d54ad04d7..ba1c710efdcb 100644 --- a/drivers/gpu/drm/rockchip/dw-dp.c +++ b/drivers/gpu/drm/rockchip/dw-dp.c @@ -5128,6 +5128,128 @@ static void dw_dp_unregister_audio_driver(void *data) } } +static int dw_dp_single_audio_init(struct dw_dp *dp, struct dw_dp_audio *audio) +{ + int ret; + + audio->extcon = devm_extcon_dev_allocate(dp->dev, dw_dp_cable); + if (IS_ERR(audio->extcon)) + return dev_err_probe(dp->dev, PTR_ERR(audio->extcon), + "failed to allocate extcon device\n"); + + ret = devm_extcon_dev_register(dp->dev, audio->extcon); + if (ret) + return dev_err_probe(dp->dev, ret, "failed to register extcon device\n"); + + ret = dw_dp_register_audio_driver(dp, audio); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dp->dev, dw_dp_unregister_audio_driver, audio); + if (ret) + return ret; + + return 0; +} + +static int dw_dp_audio_init(struct dw_dp *dp) +{ + struct dw_dp_audio *audio; + int i, ret; + + audio = dp->audio; + ret = dw_dp_single_audio_init(dp, audio); + if (ret) + return ret; + + if (!dp->support_mst) + return 0; + + for (i = 1; i < dp->mst_port_num; i++) { + if (!of_device_is_available(dp->mst_enc[i].port_node)) + continue; + + audio = dp->mst_enc[i].audio; + ret = dw_dp_single_audio_init(dp, audio); + if (ret) + return ret; + } + + return 0; +} + +static int dw_dp_get_audio_clk(struct dw_dp *dp) +{ + struct dw_dp_audio *audio; + char clk_name[10]; + int i; + + audio = devm_kzalloc(dp->dev, sizeof(*audio), GFP_KERNEL); + if (!audio) + return -ENOMEM; + + audio->id = 0; + dp->audio = audio; + + audio->i2s_clk = devm_clk_get_optional(dp->dev, "i2s"); + if (IS_ERR(audio->i2s_clk)) + return dev_err_probe(dp->dev, PTR_ERR(audio->i2s_clk), + "failed to get i2s clock\n"); + + audio->spdif_clk = devm_clk_get_optional(dp->dev, "spdif"); + if (IS_ERR(audio->spdif_clk)) + return dev_err_probe(dp->dev, PTR_ERR(audio->spdif_clk), + "failed to get spdif clock\n"); + + if (!dp->support_mst) + return 0; + + dp->mst_enc[0].audio = audio; + + for (i = 1; i < dp->mst_port_num; i++) { + if (!of_device_is_available(dp->mst_enc[i].port_node)) + continue; + + audio = devm_kzalloc(dp->dev, sizeof(*audio), GFP_KERNEL); + if (!audio) + return -ENOMEM; + + audio->id = i; + + snprintf(clk_name, sizeof(clk_name), "i2s%d", i); + audio->i2s_clk = devm_clk_get_optional(dp->dev, clk_name); + if (IS_ERR(audio->i2s_clk)) + return dev_err_probe(dp->dev, PTR_ERR(audio->i2s_clk), + "failed to get i2s clock\n"); + + snprintf(clk_name, sizeof(clk_name), "spdif%d", i); + audio->spdif_clk = devm_clk_get_optional(dp->dev, clk_name); + if (IS_ERR(audio->spdif_clk)) + return dev_err_probe(dp->dev, PTR_ERR(audio->spdif_clk), + "failed to get spdif clock\n"); + dp->mst_enc[i].audio = audio; + } + + return 0; +} + +static int dw_dp_encoder_late_register(struct drm_encoder *encoder) +{ + struct dw_dp *dp = encoder_to_dp(encoder); + int ret; + + ret = dw_dp_audio_init(dp); + if (ret) + dev_warn(dp->dev, "audio init failed\n"); + + return 0; +} + +static const struct drm_encoder_funcs dw_dp_encoder_funcs = { + .destroy = drm_encoder_cleanup, + .late_register = dw_dp_encoder_late_register, +}; + static int dw_dp_bind(struct device *dev, struct device *master, void *data) { struct dw_dp *dp = dev_get_drvdata(dev); @@ -5151,7 +5273,8 @@ static int dw_dp_bind(struct device *dev, struct device *master, void *data) port_node = dp->mst_enc[0].port_node; else port_node = dev->of_node; - drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS); + drm_encoder_init(drm_dev, encoder, &dw_dp_encoder_funcs, + DRM_MODE_ENCODER_TMDS, NULL); drm_encoder_helper_add(encoder, &dw_dp_encoder_helper_funcs); encoder->possible_crtcs = @@ -5325,91 +5448,6 @@ static int dw_dp_get_port_node(struct dw_dp *dp) return 0; } -static int dw_dp_single_audio_init(struct dw_dp *dp, struct dw_dp_audio *audio) -{ - int ret; - - audio->extcon = devm_extcon_dev_allocate(dp->dev, dw_dp_cable); - if (IS_ERR(audio->extcon)) - return dev_err_probe(dp->dev, PTR_ERR(audio->extcon), - "failed to allocate extcon device\n"); - - ret = devm_extcon_dev_register(dp->dev, audio->extcon); - if (ret) - return dev_err_probe(dp->dev, ret, "failed to register extcon device\n"); - - ret = dw_dp_register_audio_driver(dp, audio); - if (ret) - return ret; - - ret = devm_add_action_or_reset(dp->dev, dw_dp_unregister_audio_driver, audio); - if (ret) - return ret; - - return 0; -} - -static int dw_dp_audio_init(struct dw_dp *dp) -{ - struct dw_dp_audio *audio; - char clk_name[10]; - int i, ret; - - audio = devm_kzalloc(dp->dev, sizeof(*audio), GFP_KERNEL); - if (!audio) - return -ENOMEM; - - audio->id = 0; - ret = dw_dp_single_audio_init(dp, audio); - if (ret) - return ret; - dp->audio = audio; - - audio->i2s_clk = devm_clk_get_optional(dp->dev, "i2s"); - if (IS_ERR(audio->i2s_clk)) - return dev_err_probe(dp->dev, PTR_ERR(audio->i2s_clk), - "failed to get i2s clock\n"); - - audio->spdif_clk = devm_clk_get_optional(dp->dev, "spdif"); - if (IS_ERR(audio->spdif_clk)) - return dev_err_probe(dp->dev, PTR_ERR(audio->spdif_clk), - "failed to get spdif clock\n"); - - if (!dp->support_mst) - return 0; - - dp->mst_enc[0].audio = audio; - - for (i = 1; i < dp->mst_port_num; i++) { - if (!of_device_is_available(dp->mst_enc[i].port_node)) - continue; - - audio = devm_kzalloc(dp->dev, sizeof(*audio), GFP_KERNEL); - if (!audio) - return -ENOMEM; - - audio->id = i; - ret = dw_dp_single_audio_init(dp, audio); - if (ret) - return ret; - - snprintf(clk_name, sizeof(clk_name), "i2s%d", i); - audio->i2s_clk = devm_clk_get_optional(dp->dev, clk_name); - if (IS_ERR(audio->i2s_clk)) - return dev_err_probe(dp->dev, PTR_ERR(audio->i2s_clk), - "failed to get i2s clock\n"); - - snprintf(clk_name, sizeof(clk_name), "spdif%d", i); - audio->spdif_clk = devm_clk_get_optional(dp->dev, clk_name); - if (IS_ERR(audio->spdif_clk)) - return dev_err_probe(dp->dev, PTR_ERR(audio->spdif_clk), - "failed to get spdif clock\n"); - dp->mst_enc[i].audio = audio; - } - - return 0; -} - static int dw_dp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -5527,6 +5565,10 @@ static int dw_dp_probe(struct platform_device *pdev) } } + ret = dw_dp_get_audio_clk(dp); + if (ret) + return ret; + dp->irq = platform_get_irq(pdev, 0); if (dp->irq < 0) return dp->irq; @@ -5539,10 +5581,6 @@ static int dw_dp_probe(struct platform_device *pdev) return ret; } - ret = dw_dp_audio_init(dp); - if (ret) - return ret; - dp->bridge.of_node = dp->support_mst ? dp->mst_enc[0].port_node : dev->of_node; dp->bridge.funcs = &dw_dp_bridge_funcs; dp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |