lkml.org 
[lkml]   [2020]   [Apr]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 72/91] drm/vc4: hdmi: Introduce resource init and variant
    Date
    The HDMI controllers found in the BCM2711 has a pretty different clock and
    registers areas than found in the older BCM283x SoCs.

    Let's create a variant structure to store the various adjustments we'll
    need later on, and a function to get the resources needed for one
    particular version.

    Signed-off-by: Maxime Ripard <maxime@cerno.tech>
    ---
    drivers/gpu/drm/vc4/vc4_hdmi.c | 67 ++++++++++++++++++++++-------------
    drivers/gpu/drm/vc4/vc4_hdmi.h | 10 +++++-
    2 files changed, 54 insertions(+), 23 deletions(-)

    diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
    index eeaea2ad46fa..5f5943370982 100644
    --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
    +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
    @@ -1186,38 +1186,23 @@ static const struct cec_adap_ops vc4_hdmi_cec_adap_ops = {
    };
    #endif

    -static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
    +static int vc4_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
    {
    -#ifdef CONFIG_DRM_VC4_HDMI_CEC
    - struct cec_connector_info conn_info;
    -#endif
    - struct platform_device *pdev = to_platform_device(dev);
    - struct drm_device *drm = dev_get_drvdata(master);
    - struct vc4_hdmi *vc4_hdmi;
    - struct drm_encoder *encoder;
    - struct device_node *ddc_node;
    - u32 value;
    - int ret;
    -
    - vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL);
    - if (!vc4_hdmi)
    - return -ENOMEM;
    -
    - vc4_hdmi->pdev = pdev;
    - encoder = &vc4_hdmi->encoder.base.base;
    - encoder->base.type = VC4_ENCODER_TYPE_HDMI0;
    + struct platform_device *pdev = vc4_hdmi->pdev;
    + struct device *dev = &pdev->dev;

    vc4_hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
    if (IS_ERR(vc4_hdmi->hdmicore_regs))
    return PTR_ERR(vc4_hdmi->hdmicore_regs);

    + vc4_hdmi->hdmi_regset.base = vc4_hdmi->hdmicore_regs;
    + vc4_hdmi->hdmi_regset.regs = hdmi_regs;
    + vc4_hdmi->hdmi_regset.nregs = ARRAY_SIZE(hdmi_regs);
    +
    vc4_hdmi->hd_regs = vc4_ioremap_regs(pdev, 1);
    if (IS_ERR(vc4_hdmi->hd_regs))
    return PTR_ERR(vc4_hdmi->hd_regs);

    - vc4_hdmi->hdmi_regset.base = vc4_hdmi->hdmicore_regs;
    - vc4_hdmi->hdmi_regset.regs = hdmi_regs;
    - vc4_hdmi->hdmi_regset.nregs = ARRAY_SIZE(hdmi_regs);
    vc4_hdmi->hd_regset.base = vc4_hdmi->hd_regs;
    vc4_hdmi->hd_regset.regs = hd_regs;
    vc4_hdmi->hd_regset.nregs = ARRAY_SIZE(hd_regs);
    @@ -1227,12 +1212,44 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
    DRM_ERROR("Failed to get pixel clock\n");
    return PTR_ERR(vc4_hdmi->pixel_clock);
    }
    +
    vc4_hdmi->hsm_clock = devm_clk_get(dev, "hdmi");
    if (IS_ERR(vc4_hdmi->hsm_clock)) {
    DRM_ERROR("Failed to get HDMI state machine clock\n");
    return PTR_ERR(vc4_hdmi->hsm_clock);
    }

    + return 0;
    +}
    +
    +static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
    +{
    +#ifdef CONFIG_DRM_VC4_HDMI_CEC
    + struct cec_connector_info conn_info;
    +#endif
    + struct platform_device *pdev = to_platform_device(dev);
    + struct drm_device *drm = dev_get_drvdata(master);
    + const struct vc4_hdmi_variant *variant;
    + struct vc4_hdmi *vc4_hdmi;
    + struct drm_encoder *encoder;
    + struct device_node *ddc_node;
    + u32 value;
    + int ret;
    +
    + vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL);
    + if (!vc4_hdmi)
    + return -ENOMEM;
    +
    + vc4_hdmi->pdev = pdev;
    + variant = of_device_get_match_data(dev);
    + vc4_hdmi->variant = variant;
    + vc4_hdmi->encoder.base.type = VC4_ENCODER_TYPE_HDMI0;
    + encoder = &vc4_hdmi->encoder.base.base;
    +
    + ret = variant->init_resources(vc4_hdmi);
    + if (ret)
    + return ret;
    +
    ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
    if (!ddc_node) {
    DRM_ERROR("Failed to find ddc node in device tree\n");
    @@ -1393,8 +1410,12 @@ static int vc4_hdmi_dev_remove(struct platform_device *pdev)
    return 0;
    }

    +static const struct vc4_hdmi_variant bcm2835_variant = {
    + .init_resources = vc4_hdmi_init_resources,
    +};
    +
    static const struct of_device_id vc4_hdmi_dt_match[] = {
    - { .compatible = "brcm,bcm2835-hdmi" },
    + { .compatible = "brcm,bcm2835-hdmi", .data = &bcm2835_variant },
    {}
    };

    diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
    index 88794136d2e4..4cd712779ad3 100644
    --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
    +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
    @@ -21,6 +21,15 @@ to_vc4_hdmi_encoder(struct drm_encoder *encoder)
    return container_of(encoder, struct vc4_hdmi_encoder, base.base);
    }

    +struct vc4_hdmi;
    +
    +struct vc4_hdmi_variant {
    + /* Callback to get the resources (memory region, interrupts,
    + * clocks, etc) for that variant.
    + */
    + int (*init_resources)(struct vc4_hdmi *vc4_hdmi);
    +};
    +
    /* HDMI audio information */
    struct vc4_hdmi_audio {
    struct snd_soc_card card;
    @@ -37,6 +46,7 @@ struct vc4_hdmi_audio {
    /* General HDMI hardware state. */
    struct vc4_hdmi {
    struct platform_device *pdev;
    + const struct vc4_hdmi_variant *variant;

    struct vc4_hdmi_encoder encoder;
    struct drm_connector connector;
    --
    git-series 0.9.1
    \
     
     \ /
      Last update: 2020-04-24 17:38    [W:4.071 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site