[PATCH 2/6] drm/bridge: synopsys: Add DW DPTX Controller support library
FUKAUMI Naoki
naoki at radxa.com
Sun Mar 9 06:51:24 UTC 2025
Hi Andy,
On 2/23/25 20:30, Andy Yan wrote:
(snip)
> +struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
> + const struct dw_dp_plat_data *plat_data)
> +{
> + struct platform_device *pdev = to_platform_device(dev);
> + struct dw_dp *dp;
> + struct drm_bridge *bridge;
> + void __iomem *res;
> + int ret;
> +
> + dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
> + if (!dp)
> + return ERR_PTR(-ENOMEM);
> +
> + dp->dev = dev;
> + dp->video.pixel_mode = DW_DP_MP_QUAD_PIXEL;
> +
> + dp->plat_data = plat_data;
> + bridge = &dp->bridge;
> + mutex_init(&dp->irq_lock);
> + INIT_WORK(&dp->hpd_work, dw_dp_hpd_work);
> + init_completion(&dp->complete);
> +
> + res = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(res))
> + return ERR_CAST(res);
> +
> + dp->regmap = devm_regmap_init_mmio(dev, res, &dw_dp_regmap_config);
> + if (IS_ERR(dp->regmap)) {
> + dev_err_probe(dev, PTR_ERR(dp->regmap), "failed to create regmap\n");
> + return ERR_CAST(dp->regmap);
> + }
> +
> + dp->phy = devm_of_phy_get(dev, dev->of_node, NULL);
> + if (IS_ERR(dp->phy)) {
> + dev_err_probe(dev, PTR_ERR(dp->phy), "failed to get phy\n");
> + return ERR_CAST(dp->phy);
> + }
> +
> + dp->apb_clk = devm_clk_get_enabled(dev, "apb");
> + if (IS_ERR(dp->apb_clk)) {
> + dev_err_probe(dev, PTR_ERR(dp->apb_clk), "failed to get apb clock\n");
> + return ERR_CAST(dp->apb_clk);
> + }
> +
> + dp->aux_clk = devm_clk_get_enabled(dev, "aux");
> + if (IS_ERR(dp->aux_clk)) {
> + dev_err_probe(dev, PTR_ERR(dp->aux_clk), "failed to get aux clock\n");
> + return ERR_CAST(dp->aux_clk);
> + }
> +
> + dp->i2s_clk = devm_clk_get(dev, "i2s");
> + if (IS_ERR(dp->i2s_clk)) {
> + dev_err_probe(dev, PTR_ERR(dp->i2s_clk), "failed to get i2s clock\n");
> + return ERR_CAST(dp->i2s_clk);
> + }
> +
> + dp->spdif_clk = devm_clk_get(dev, "spdif");
> + if (IS_ERR(dp->spdif_clk)) {
> + dev_err_probe(dev, PTR_ERR(dp->spdif_clk), "failed to get spdif clock\n");
> + return ERR_CAST(dp->spdif_clk);
> + }
> +
> + dp->hdcp_clk = devm_clk_get(dev, "hdcp");
> + if (IS_ERR(dp->hdcp_clk)) {
> + dev_err_probe(dev, PTR_ERR(dp->hdcp_clk), "failed to get hdcp clock\n");
> + return ERR_CAST(dp->hdcp_clk);
> + }
> +
> + dp->rstc = devm_reset_control_get(dev, NULL);
> + if (IS_ERR(dp->rstc)) {
> + dev_err_probe(dev, PTR_ERR(dp->rstc), "failed to get reset control\n");
> + return ERR_CAST(dp->rstc);
> + }
> +
> + dp->irq = platform_get_irq(pdev, 0);
> + if (dp->irq < 0)
> + return ERR_PTR(ret);
> +
> + ret = devm_request_threaded_irq(dev, dp->irq, NULL, dw_dp_irq,
> + IRQF_ONESHOT, dev_name(dev), dp);
> + if (ret) {
> + dev_err_probe(dev, ret, "failed to request irq\n");
> + return ERR_PTR(ret);
> + }
> +
> + bridge->of_node = dev->of_node;
> + bridge->funcs = &dw_dp_bridge_funcs;
> + bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
> + bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
> + bridge->ycbcr_420_allowed = true;
> + bridge->vendor = "Synopsys";
> + bridge->product = "DW DP TX";
> +
> + platform_set_drvdata(pdev, dp);
> +
> + dp->aux.dev = dev;
> + dp->aux.drm_dev = encoder->dev;
> + dp->aux.name = dev_name(dev);
> + dp->aux.transfer = dw_dp_aux_transfer;
> + ret = drm_dp_aux_register(&dp->aux);
> + if (ret) {
> + dev_err_probe(dev, ret, "Aux register failed\n");
> + return ERR_PTR(ret);
> + }
> +
> + ret = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> + if (ret)
> + dev_err_probe(dev, ret, "Failed to attach bridge\n");
> +
> + dw_dp_init_hw(dp);
> +
> + return dp;
> +}
EXPORT_SYMBOL_GPL(dw_dp_bind);
is required to build it as a module.
Best regards,
--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.
More information about the dri-devel
mailing list