lkml.org 
[lkml]   [2020]   [Feb]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 63/89] drm/vc4: hdmi: rework connectors and encoders
    Date
    the vc4_hdmi driver has some custom structures to hold the data it needs to
    associate with the drm_encoder and drm_connector structures.

    However, it allocates them separately from the vc4_hdmi structure which
    makes it more complicated than it needs to be.

    Move those structures to be contained by vc4_hdmi and update the code
    accordingly.

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

    diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
    index a31fdf1dc6cf..5db003bb3cf5 100644
    --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
    +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
    @@ -190,20 +190,15 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
    .get_modes = vc4_hdmi_connector_get_modes,
    };

    -static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
    - struct drm_encoder *encoder,
    - struct i2c_adapter *ddc)
    +static int vc4_hdmi_connector_init(struct drm_device *dev,
    + struct vc4_hdmi *vc4_hdmi,
    + struct i2c_adapter *ddc)
    {
    - struct drm_connector *connector;
    - struct vc4_hdmi_connector *hdmi_connector;
    + struct vc4_hdmi_connector *hdmi_connector = &vc4_hdmi->connector;
    + struct drm_connector *connector = &hdmi_connector->base;
    + struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
    int ret;

    - hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector),
    - GFP_KERNEL);
    - if (!hdmi_connector)
    - return ERR_PTR(-ENOMEM);
    - connector = &hdmi_connector->base;
    -
    hdmi_connector->encoder = encoder;

    drm_connector_init_with_ddc(dev, connector,
    @@ -215,7 +210,7 @@ static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
    /* Create and attach TV margin props to this connector. */
    ret = drm_mode_create_tv_margin_properties(dev);
    if (ret)
    - return ERR_PTR(ret);
    + return ret;

    drm_connector_attach_tv_margin_properties(connector);

    @@ -227,7 +222,7 @@ static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,

    drm_connector_attach_encoder(connector, encoder);

    - return connector;
    + return 0;
    }

    static void vc4_hdmi_encoder_destroy(struct drm_encoder *encoder)
    @@ -306,21 +301,22 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
    struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
    struct vc4_dev *vc4 = encoder->dev->dev_private;
    struct vc4_hdmi *hdmi = vc4->hdmi;
    - struct drm_connector_state *cstate = hdmi->connector->state;
    + struct drm_connector *connector = &hdmi->connector.base;
    + struct drm_connector_state *cstate = connector->state;
    struct drm_crtc *crtc = encoder->crtc;
    const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
    union hdmi_infoframe frame;
    int ret;

    ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
    - hdmi->connector, mode);
    + connector, mode);
    if (ret < 0) {
    DRM_ERROR("couldn't fill AVI infoframe\n");
    return;
    }

    drm_hdmi_avi_infoframe_quant_range(&frame.avi,
    - hdmi->connector, mode,
    + connector, mode,
    vc4_encoder->limited_rgb_range ?
    HDMI_QUANTIZATION_RANGE_LIMITED :
    HDMI_QUANTIZATION_RANGE_FULL);
    @@ -624,7 +620,8 @@ static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
    /* HDMI audio codec callbacks */
    static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *hdmi)
    {
    - struct drm_device *drm = hdmi->encoder->dev;
    + struct drm_encoder *encoder = &hdmi->encoder.base.base;
    + struct drm_device *drm = encoder->dev;
    struct vc4_dev *vc4 = to_vc4_dev(drm);
    u32 hsm_clock = clk_get_rate(hdmi->hsm_clock);
    unsigned long n, m;
    @@ -643,7 +640,7 @@ static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *hdmi)

    static void vc4_hdmi_set_n_cts(struct vc4_hdmi *hdmi)
    {
    - struct drm_encoder *encoder = hdmi->encoder;
    + struct drm_encoder *encoder = &hdmi->encoder.base.base;
    struct drm_crtc *crtc = encoder->crtc;
    struct drm_device *drm = encoder->dev;
    struct vc4_dev *vc4 = to_vc4_dev(drm);
    @@ -681,7 +678,8 @@ static int vc4_hdmi_audio_startup(struct snd_pcm_substream *substream,
    struct snd_soc_dai *dai)
    {
    struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
    - struct drm_encoder *encoder = hdmi->encoder;
    + struct drm_encoder *encoder = &hdmi->encoder.base.base;
    + struct drm_connector *connector = &hdmi->connector.base;
    struct vc4_dev *vc4 = to_vc4_dev(encoder->dev);
    int ret;

    @@ -698,8 +696,7 @@ static int vc4_hdmi_audio_startup(struct snd_pcm_substream *substream,
    VC4_HDMI_RAM_PACKET_ENABLE))
    return -ENODEV;

    - ret = snd_pcm_hw_constraint_eld(substream->runtime,
    - hdmi->connector->eld);
    + ret = snd_pcm_hw_constraint_eld(substream->runtime, connector->eld);
    if (ret)
    return ret;

    @@ -713,7 +710,7 @@ static int vc4_hdmi_audio_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)

    static void vc4_hdmi_audio_reset(struct vc4_hdmi *hdmi)
    {
    - struct drm_encoder *encoder = hdmi->encoder;
    + struct drm_encoder *encoder = &hdmi->encoder.base.base;
    struct drm_device *drm = encoder->dev;
    struct device *dev = &hdmi->pdev->dev;
    struct vc4_dev *vc4 = to_vc4_dev(drm);
    @@ -747,7 +744,7 @@ static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
    struct snd_soc_dai *dai)
    {
    struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
    - struct drm_encoder *encoder = hdmi->encoder;
    + struct drm_encoder *encoder = &hdmi->encoder.base.base;
    struct drm_device *drm = encoder->dev;
    struct device *dev = &hdmi->pdev->dev;
    struct vc4_dev *vc4 = to_vc4_dev(drm);
    @@ -820,7 +817,7 @@ static int vc4_hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
    struct snd_soc_dai *dai)
    {
    struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
    - struct drm_encoder *encoder = hdmi->encoder;
    + struct drm_encoder *encoder = &hdmi->encoder.base.base;
    struct drm_device *drm = encoder->dev;
    struct vc4_dev *vc4 = to_vc4_dev(drm);

    @@ -864,9 +861,10 @@ static int vc4_hdmi_audio_eld_ctl_info(struct snd_kcontrol *kcontrol,
    {
    struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
    struct vc4_hdmi *hdmi = snd_component_to_hdmi(component);
    + struct drm_connector *connector = &hdmi->connector.base;

    uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
    - uinfo->count = sizeof(hdmi->connector->eld);
    + uinfo->count = sizeof(connector->eld);

    return 0;
    }
    @@ -876,9 +874,10 @@ static int vc4_hdmi_audio_eld_ctl_get(struct snd_kcontrol *kcontrol,
    {
    struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
    struct vc4_hdmi *hdmi = snd_component_to_hdmi(component);
    + struct drm_connector *connector = &hdmi->connector.base;

    - memcpy(ucontrol->value.bytes.data, hdmi->connector->eld,
    - sizeof(hdmi->connector->eld));
    + memcpy(ucontrol->value.bytes.data, connector->eld,
    + sizeof(connector->eld));

    return 0;
    }
    @@ -1216,7 +1215,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
    struct drm_device *drm = dev_get_drvdata(master);
    struct vc4_dev *vc4 = drm->dev_private;
    struct vc4_hdmi *hdmi;
    - struct vc4_hdmi_encoder *vc4_hdmi_encoder;
    + struct drm_encoder *encoder;
    struct device_node *ddc_node;
    u32 value;
    int ret;
    @@ -1225,14 +1224,10 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
    if (!hdmi)
    return -ENOMEM;

    - vc4_hdmi_encoder = devm_kzalloc(dev, sizeof(*vc4_hdmi_encoder),
    - GFP_KERNEL);
    - if (!vc4_hdmi_encoder)
    - return -ENOMEM;
    - vc4_hdmi_encoder->base.type = VC4_ENCODER_TYPE_HDMI0;
    - hdmi->encoder = &vc4_hdmi_encoder->base.base;
    -
    hdmi->pdev = pdev;
    + encoder = &hdmi->encoder.base.base;
    + encoder->base.type = VC4_ENCODER_TYPE_HDMI0;
    +
    hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
    if (IS_ERR(hdmi->hdmicore_regs))
    return PTR_ERR(hdmi->hdmicore_regs);
    @@ -1318,16 +1313,14 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
    }
    pm_runtime_enable(dev);

    - drm_encoder_init(drm, hdmi->encoder, &vc4_hdmi_encoder_funcs,
    + drm_encoder_init(drm, encoder, &vc4_hdmi_encoder_funcs,
    DRM_MODE_ENCODER_TMDS, NULL);
    - drm_encoder_helper_add(hdmi->encoder, &vc4_hdmi_encoder_helper_funcs);
    + drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);

    - hdmi->connector =
    - vc4_hdmi_connector_init(drm, hdmi->encoder, hdmi->ddc);
    - if (IS_ERR(hdmi->connector)) {
    - ret = PTR_ERR(hdmi->connector);
    + ret = vc4_hdmi_connector_init(drm, vc4_hdmi, vc4_hdmi->ddc);
    + if (ret)
    goto err_destroy_encoder;
    - }
    +
    #ifdef CONFIG_DRM_VC4_HDMI_CEC
    hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
    vc4, "vc4",
    @@ -1374,10 +1367,10 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
    err_delete_cec_adap:
    cec_delete_adapter(hdmi->cec_adap);
    err_destroy_conn:
    - vc4_hdmi_connector_destroy(hdmi->connector);
    + vc4_hdmi_connector_destroy(&hdmi->connector.base);
    #endif
    err_destroy_encoder:
    - vc4_hdmi_encoder_destroy(hdmi->encoder);
    + vc4_hdmi_encoder_destroy(encoder);
    err_unprepare_hsm:
    clk_disable_unprepare(hdmi->hsm_clock);
    pm_runtime_disable(dev);
    @@ -1395,8 +1388,8 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
    struct vc4_hdmi *hdmi = vc4->hdmi;

    cec_unregister_adapter(hdmi->cec_adap);
    - vc4_hdmi_connector_destroy(hdmi->connector);
    - vc4_hdmi_encoder_destroy(hdmi->encoder);
    + vc4_hdmi_connector_destroy(&hdmi->connector.base);
    + vc4_hdmi_encoder_destroy(&hdmi->encoder.base.base);

    clk_disable_unprepare(hdmi->hsm_clock);
    pm_runtime_disable(dev);
    diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
    index 5ec5d1f6b1e6..17079a39f1b1 100644
    --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
    +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
    @@ -8,6 +8,36 @@

    #include "vc4_drv.h"

    +/* VC4 HDMI encoder KMS struct */
    +struct vc4_hdmi_encoder {
    + struct vc4_encoder base;
    + bool hdmi_monitor;
    + bool limited_rgb_range;
    +};
    +
    +static inline struct vc4_hdmi_encoder *
    +to_vc4_hdmi_encoder(struct drm_encoder *encoder)
    +{
    + return container_of(encoder, struct vc4_hdmi_encoder, base.base);
    +}
    +
    +/* VC4 HDMI connector KMS struct */
    +struct vc4_hdmi_connector {
    + struct drm_connector base;
    +
    + /* Since the connector is attached to just the one encoder,
    + * this is the reference to it so we can do the best_encoder()
    + * hook.
    + */
    + struct drm_encoder *encoder;
    +};
    +
    +static inline struct vc4_hdmi_connector *
    +to_vc4_hdmi_connector(struct drm_connector *connector)
    +{
    + return container_of(connector, struct vc4_hdmi_connector, base);
    +}
    +
    /* HDMI audio information */
    struct vc4_hdmi_audio {
    struct snd_soc_card card;
    @@ -25,8 +55,8 @@ struct vc4_hdmi_audio {
    struct vc4_hdmi {
    struct platform_device *pdev;

    - struct drm_encoder *encoder;
    - struct drm_connector *connector;
    + struct vc4_hdmi_encoder encoder;
    + struct vc4_hdmi_connector connector;

    struct vc4_hdmi_audio audio;

    @@ -53,34 +83,4 @@ struct vc4_hdmi {
    #define HD_READ(offset) readl(vc4->hdmi->hd_regs + offset)
    #define HD_WRITE(offset, val) writel(val, vc4->hdmi->hd_regs + offset)

    -/* VC4 HDMI encoder KMS struct */
    -struct vc4_hdmi_encoder {
    - struct vc4_encoder base;
    - bool hdmi_monitor;
    - bool limited_rgb_range;
    -};
    -
    -static inline struct vc4_hdmi_encoder *
    -to_vc4_hdmi_encoder(struct drm_encoder *encoder)
    -{
    - return container_of(encoder, struct vc4_hdmi_encoder, base.base);
    -}
    -
    -/* VC4 HDMI connector KMS struct */
    -struct vc4_hdmi_connector {
    - struct drm_connector base;
    -
    - /* Since the connector is attached to just the one encoder,
    - * this is the reference to it so we can do the best_encoder()
    - * hook.
    - */
    - struct drm_encoder *encoder;
    -};
    -
    -static inline struct vc4_hdmi_connector *
    -to_vc4_hdmi_connector(struct drm_connector *connector)
    -{
    - return container_of(connector, struct vc4_hdmi_connector, base);
    -}
    -
    #endif /* _VC4_HDMI_H_ */
    --
    git-series 0.9.1
    \
     
     \ /
      Last update: 2020-02-24 10:11    [W:2.243 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site