[PATCH v2 5/6] drm/vs: Add KMS crtc&plane

Dmitry Baryshkov dmitry.baryshkov at linaro.org
Wed Nov 15 16:00:12 UTC 2023


On Wed, 15 Nov 2023 at 15:30, Keith Zhao <keith.zhao at starfivetech.com> wrote:
>
>
>
> On 2023/11/14 18:59, Dmitry Baryshkov wrote:
> > On Tue, 14 Nov 2023 at 12:42, Keith Zhao <keith.zhao at starfivetech.com> wrote:
> >>
> >>
> >>
> >> On 2023/10/26 3:28, Dmitry Baryshkov wrote:
> >> > On 25/10/2023 13:39, Keith Zhao wrote:
> >> >> add 2 crtcs and 8 planes in vs-drm
> >> >>
> >> >> Signed-off-by: Keith Zhao <keith.zhao at starfivetech.com>
> >> >> ---
> >> >>   drivers/gpu/drm/verisilicon/Makefile   |    8 +-
> >> >>   drivers/gpu/drm/verisilicon/vs_crtc.c  |  257 ++++
> >> >>   drivers/gpu/drm/verisilicon/vs_crtc.h  |   43 +
> >> >>   drivers/gpu/drm/verisilicon/vs_dc.c    | 1002 ++++++++++++
> >> >>   drivers/gpu/drm/verisilicon/vs_dc.h    |   80 +
> >> >>   drivers/gpu/drm/verisilicon/vs_dc_hw.c | 1959 ++++++++++++++++++++++++
> >> >>   drivers/gpu/drm/verisilicon/vs_dc_hw.h |  492 ++++++
> >> >>   drivers/gpu/drm/verisilicon/vs_drv.c   |    2 +
> >> >>   drivers/gpu/drm/verisilicon/vs_plane.c |  526 +++++++
> >> >>   drivers/gpu/drm/verisilicon/vs_plane.h |   58 +
> >> >>   drivers/gpu/drm/verisilicon/vs_type.h  |   69 +
> >> >>   11 files changed, 4494 insertions(+), 2 deletions(-)
> >> >>   create mode 100644 drivers/gpu/drm/verisilicon/vs_crtc.c
> >> >>   create mode 100644 drivers/gpu/drm/verisilicon/vs_crtc.h
> >> >>   create mode 100644 drivers/gpu/drm/verisilicon/vs_dc.c
> >> >>   create mode 100644 drivers/gpu/drm/verisilicon/vs_dc.h
> >> >>   create mode 100644 drivers/gpu/drm/verisilicon/vs_dc_hw.c
> >> >>   create mode 100644 drivers/gpu/drm/verisilicon/vs_dc_hw.h
> >> >>   create mode 100644 drivers/gpu/drm/verisilicon/vs_plane.c
> >> >>   create mode 100644 drivers/gpu/drm/verisilicon/vs_plane.h
> >> >>   create mode 100644 drivers/gpu/drm/verisilicon/vs_type.h
> >> >>
> >> >> diff --git a/drivers/gpu/drm/verisilicon/Makefile b/drivers/gpu/drm/verisilicon/Makefile
> >> >> index 7d3be305b..1d48016ca 100644
> >> >> --- a/drivers/gpu/drm/verisilicon/Makefile
> >> >> +++ b/drivers/gpu/drm/verisilicon/Makefile
> >> >> @@ -1,7 +1,11 @@
> >> >>   # SPDX-License-Identifier: GPL-2.0
> >> >>
> >> >> -vs_drm-objs := vs_drv.o \
> >> >> -            vs_modeset.o
> >> >> +vs_drm-objs := vs_dc_hw.o \
> >> >> +            vs_dc.o \
> >> >> +            vs_crtc.o \
> >> >> +            vs_drv.o \
> >> >> +            vs_modeset.o \
> >> >> +            vs_plane.o
> >> >>
> >> >>   obj-$(CONFIG_DRM_VERISILICON) += vs_drm.o
> >> >>
> >> >> diff --git a/drivers/gpu/drm/verisilicon/vs_crtc.c b/drivers/gpu/drm/verisilicon/vs_crtc.c
> >> >> new file mode 100644
> >> >> index 000000000..8a658ea77
> >> >> --- /dev/null
> >> >> +++ b/drivers/gpu/drm/verisilicon/vs_crtc.c
> >> >> @@ -0,0 +1,257 @@
> >> >> +// SPDX-License-Identifier: GPL-2.0
> >> >> +/*
> >> >> + * Copyright (C) 2023 VeriSilicon Holdings Co., Ltd.
> >> >> + *
> >> >> + */
> >> >> +
> >> >> +#include <linux/clk.h>
> >> >> +#include <linux/debugfs.h>
> >> >> +#include <linux/media-bus-format.h>
> >> >> +
> >> >> +#include <drm/drm_atomic_helper.h>
> >> >> +#include <drm/drm_atomic.h>
> >> >> +#include <drm/drm_crtc.h>
> >> >> +#include <drm/drm_gem_atomic_helper.h>
> >> >> +#include <drm/drm_vblank.h>
> >> >> +#include <drm/vs_drm.h>
> >> >> +
> >> >> +#include "vs_crtc.h"
> >> >> +#include "vs_dc.h"
> >> >> +#include "vs_drv.h"
> >> >> +
> >> >> +static void vs_crtc_reset(struct drm_crtc *crtc)
> >> >> +{
> >> >> +    struct vs_crtc_state *state;
> >> >> +
> >> >> +    if (crtc->state) {
> >> >> +            __drm_atomic_helper_crtc_destroy_state(crtc->state);
> >> >> +
> >> >> +            state = to_vs_crtc_state(crtc->state);
> >> >> +            kfree(state);
> >> >> +            crtc->state = NULL;
> >> >> +    }
> >> >
> >> > You can call your crtc_destroy_state function directly here.
> >> >
> >> >> +
> >> >> +    state = kzalloc(sizeof(*state), GFP_KERNEL);
> >> >> +    if (!state)
> >> >> +            return;
> >> >> +
> >> >> +    __drm_atomic_helper_crtc_reset(crtc, &state->base);
> >> >> +}
> >> >> +
> >> >> +static struct drm_crtc_state *
> >> >> +vs_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
> >> >> +{
> >> >> +    struct vs_crtc_state *ori_state;
> >> >
> >> > It might be a matter of taste, but it is usually old_state.
> >> >
> >> >> +    struct vs_crtc_state *state;
> >> >> +
> >> >> +    if (!crtc->state)
> >> >> +            return NULL;
> >> >> +
> >> >> +    ori_state = to_vs_crtc_state(crtc->state);
> >> >> +    state = kzalloc(sizeof(*state), GFP_KERNEL);
> >> >> +    if (!state)
> >> >> +            return NULL;
> >> >> +
> >> >> +    __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
> >> >> +
> >> >> +    state->output_fmt = ori_state->output_fmt;
> >> >> +    state->encoder_type = ori_state->encoder_type;
> >> >> +    state->bpp = ori_state->bpp;
> >> >> +    state->underflow = ori_state->underflow;
> >> >
> >> > Can you use kmemdup instead?
> >> >
> >> >> +
> >> >> +    return &state->base;
> >> >> +}
> >> >> +
> >> >> +static void vs_crtc_atomic_destroy_state(struct drm_crtc *crtc,
> >> >> +                                     struct drm_crtc_state *state)
> >> >> +{
> >> >> +    __drm_atomic_helper_crtc_destroy_state(state);
> >> >> +    kfree(to_vs_crtc_state(state));
> >> >> +}
> >> >> +
> >> >> +static int vs_crtc_enable_vblank(struct drm_crtc *crtc)
> >> >> +{
> >> >> +    struct vs_crtc *vs_crtc = to_vs_crtc(crtc);
> >> >> +    struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev);
> >> >> +
> >> >> +    vs_dc_enable_vblank(dc, true);
> >> >> +
> >> >> +    return 0;
> >> >> +}
> >> >> +
> >> >> +static void vs_crtc_disable_vblank(struct drm_crtc *crtc)
> >> >> +{
> >> >> +    struct vs_crtc *vs_crtc = to_vs_crtc(crtc);
> >> >> +    struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev);
> >> >> +
> >> >> +    vs_dc_enable_vblank(dc, false);
> >> >> +}
> >> >> +
> >> >> +static const struct drm_crtc_funcs vs_crtc_funcs = {
> >> >> +    .set_config             = drm_atomic_helper_set_config,
> >> >> +    .page_flip              = drm_atomic_helper_page_flip,
> >> >
> >> > destroy is required, see drm_mode_config_cleanup()
> >>
> >> hi Dmitry:
> >> if define destroy in drm_crtc_funcs,
> >> it will make __drmm_crtc_init_with_planes unhappy
> >
> > Ack, I missed that you have been using drmm_crtc_init. BTW, I checked
> > your code, you should be able to switch drm
> > drmm_crtc_alloc_with_planes().
> >
> yes
> I done the replace and it can work well.
>
> >>
> >> see:
> >> __printf(6, 0)
> >> static int __drmm_crtc_init_with_planes(struct drm_device *dev,
> >>                                         struct drm_crtc *crtc,
> >>                                         struct drm_plane *primary,
> >>                                         struct drm_plane *cursor,
> >>                                         const struct drm_crtc_funcs *funcs,
> >>                                         const char *name,
> >>                                         va_list args)
> >> {
> >>         int ret;
> >>
> >>         drm_WARN_ON(dev, funcs && funcs->destroy);
> >>
> >> ........
> >> }
> >>
> >> It should not need to be defined here, I think
> >>
> >> >
> >> >> +    .reset                  = vs_crtc_reset,
> >> >> +    .atomic_duplicate_state = vs_crtc_atomic_duplicate_state,
> >> >> +    .atomic_destroy_state   = vs_crtc_atomic_destroy_state,
> >> >
> >> > please consider adding atomic_print_state to output driver-specific bits.
> >> >
> >> >> +    .enable_vblank          = vs_crtc_enable_vblank,
> >> >> +    .disable_vblank         = vs_crtc_disable_vblank,
> >> >> +};
> >> >> +
> >> >> +static u8 cal_pixel_bits(u32 bus_format)
> >> >
> >> > This looks like a generic helper code, which can go to a common place.
> I don't know if I understand correctly
> Here I remove static
> Add 2 lines in vs_drv.h
>
> /* vs_crtc.c */
> u8 cal_pixel_bits(u32 bus_format);
>
> to make it common

I mean, move it to a generic location, like include/media/

>
> >> >
> >> >> +{
> >> >> +    u8 bpp;
> >> >> +
> >> >> +    switch (bus_format) {
> >> >> +    case MEDIA_BUS_FMT_RGB565_1X16:
> >> >> +    case MEDIA_BUS_FMT_UYVY8_1X16:
> >> >> +            bpp = 16;
> >> >> +            break;
> >> >> +    case MEDIA_BUS_FMT_RGB666_1X18:
> >> >> +    case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
> >> >> +            bpp = 18;
> >> >> +            break;
> >> >> +    case MEDIA_BUS_FMT_UYVY10_1X20:
> >> >> +            bpp = 20;
> >> >> +            break;
> >> >> +    case MEDIA_BUS_FMT_BGR888_1X24:
> >> >> +    case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
> >> >> +    case MEDIA_BUS_FMT_YUV8_1X24:
> >> >> +            bpp = 24;
> >> >> +            break;
> >> >> +    case MEDIA_BUS_FMT_RGB101010_1X30:
> >> >> +    case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
> >> >> +    case MEDIA_BUS_FMT_YUV10_1X30:
> >> >> +            bpp = 30;
> >> >> +            break;
> >> >> +    default:
> >> >> +            bpp = 24;
> >> >> +            break;
> >> >> +    }
> >> >> +
> >> >> +    return bpp;
> >> >> +}
> >> >> +

[skipped]

> >> >> +struct vs_crtc *vs_crtc_create(struct drm_device *drm_dev,
> >> >> +                           struct vs_dc_info *info)
> >> >> +{
> >> >> +    struct vs_crtc *crtc;
> >> >> +    int ret;
> >> >> +
> >> >> +    if (!info)
> >> >> +            return NULL;
> >> >> +
> >> >> +    crtc = drmm_kzalloc(drm_dev, sizeof(*crtc), GFP_KERNEL);
> >> >> +    if (!crtc)
> >> >> +            return NULL;
> >> >> +
> >> >> +    ret = drmm_crtc_init_with_planes(drm_dev, &crtc->base,
> >> >> +                                     NULL, NULL, &vs_crtc_funcs,
> >> >> +                                     info->name ? info->name : NULL);
> >> >
> >> > It might be better to add drmm_crtc_init() helper.
>         drmm_crtc_alloc_with_planes used:
>         ...
>         struct vs_crtc *crtc;
>         int ret;
>
>         if (!info)
>                 return NULL;
>
>         crtc = drmm_crtc_alloc_with_planes(drm_dev, struct vs_crtc, base,
>                                                NULL, NULL,
>                                                &vs_crtc_funcs, info->name ? info->name : NULL);
>         ...

Ack.

>
> >> >
> >> >> +    if (ret)
> >> >> +            return NULL;
> >> >> +
> >> >> +    drm_crtc_helper_add(&crtc->base, &vs_crtc_helper_funcs);
> >> >> +
> >> >> +    if (info->gamma_size) {
> >> >> +            ret = drm_mode_crtc_set_gamma_size(&crtc->base,
> >> >> +                                               info->gamma_size);
> >> >> +            if (ret)
> >> >> +                    return NULL;
> >> >> +
> >> >> +            drm_crtc_enable_color_mgmt(&crtc->base, 0, false,
> >> >> +                                       info->gamma_size);
> >> >> +    }
> >> >> +
> >> >> +    crtc->max_bpc = info->max_bpc;
> >> >> +    crtc->color_formats = info->color_formats;
> >> >> +    return crtc;
> >> >> +}

> >> >> +const struct component_ops dc_component_ops = {
> >> >> +    .bind = dc_bind,
> >> >> +    .unbind = dc_unbind,
> >> >> +};
> >> >> +
> >> >> +static const struct of_device_id dc_driver_dt_match[] = {
> >> >> +    { .compatible = "starfive,jh7110-dc8200", },
> >> >> +    {},
> >> >> +};
> >> >> +MODULE_DEVICE_TABLE(of, dc_driver_dt_match);
> >> >> +
> >> >> +static int dc_probe(struct platform_device *pdev)
> >> >> +{
> >> >> +    struct device *dev = &pdev->dev;
> >> >> +    struct vs_dc *dc;
> >> >> +    int irq, ret, i;
> >> >> +
> >> >> +    dc = devm_kzalloc(dev, sizeof(*dc), GFP_KERNEL);
> >> >> +    if (!dc)
> >> >> +            return -ENOMEM;
> >> >> +
> >> >> +    dc->hw.hi_base = devm_platform_ioremap_resource(pdev, 0);
> >> >> +    if (IS_ERR(dc->hw.hi_base))
> >> >> +            return PTR_ERR(dc->hw.hi_base);
> >> >> +
> >> >> +    dc->hw.reg_base = devm_platform_ioremap_resource(pdev, 1);
> >> >> +    if (IS_ERR(dc->hw.reg_base))
> >> >> +            return PTR_ERR(dc->hw.reg_base);
> >> >> +
> >> >> +    dc->nclks = ARRAY_SIZE(dc->clk_vout);
> >> >> +    for (i = 0; i < dc->nclks; ++i)
> >> >> +            dc->clk_vout[i].id = vout_clocks[i];
> >> >> +    ret = devm_clk_bulk_get(dev, dc->nclks, dc->clk_vout);
> >> >> +    if (ret) {
> >> >> +            dev_err(dev, "Failed to get clk controls\n");
> >> >> +            return ret;
> >> >> +    }
> >> >> +
> >> >> +    dc->nrsts = ARRAY_SIZE(dc->rst_vout);
> >> >> +    for (i = 0; i < dc->nrsts; ++i)
> >> >> +            dc->rst_vout[i].id = vout_resets[i];
> >> >> +    ret = devm_reset_control_bulk_get_shared(dev, dc->nrsts,
> >> >> +                                             dc->rst_vout);
> >> >> +    if (ret) {
> >> >> +            dev_err(dev, "Failed to get reset controls\n");
> >> >> +            return ret;
> >> >> +    }
> >> >> +
> >> >> +    irq = platform_get_irq(pdev, 0);
> >> >> +
> >> >> +    ret = devm_request_irq(dev, irq, dc_isr, 0, dev_name(dev), dc);
> >> >
> >> > Are you ready to handle the IRQ at this point?
> Do you have some good suggestions?
> Are there any hidden dangers in doing so?


If your driver is not ready, stray interrupt can crash your driver.
For pm_runtime-enabled devices it is even more important: the
interrupt handled might try accessing device which is powered off.

> Hope to get good opinions

The usual suggestion is: request the interrupt when your data is fully
set up. Or request_irq with IRQF_NO_AUTOEN and then enable_irq() /
disable_irq() as required.

>
> >> >
> >> >> +    if (ret < 0) {
> >> >> +            dev_err(dev, "Failed to install irq:%u.\n", irq);
> >> >> +            return ret;
> >> >> +    }
> >> >> +
> >> >> +    dev_set_drvdata(dev, dc);
> >> >> +
> >> >> +    return component_add(dev, &dc_component_ops);
> >> >> +}
> >> >> +

[skipped]

> >> >> +static int vs_plane_atomic_get_property(struct drm_plane *plane,
> >> >> +                                    const struct drm_plane_state *state,
> >> >> +                                    struct drm_property *property,
> >> >> +                                    uint64_t *val)
> >> >> +{
> >> >> +    struct vs_plane *vs_plane = to_vs_plane(plane);
> >> >> +    const struct vs_plane_state *vs_plane_state =
> >> >> +            container_of(state, const struct vs_plane_state, base);
> >> >> +
> >> >> +    if (property == vs_plane->degamma_mode)
> >> >> +            *val = vs_plane_state->degamma;
> >> >> +    else if (property == vs_plane->watermark_prop)
> >> >> +            *val = (vs_plane_state->watermark) ?
> >> >> +                                    vs_plane_state->watermark->base.id : 0;
> >> >> +    else if (property == vs_plane->color_mgmt_prop)
> >> >> +            *val = (vs_plane_state->color_mgmt) ?
> >> >> +                                    vs_plane_state->color_mgmt->base.id : 0;
> >> >
> >> > degamma and color management should use standard properties.
>
> hello Dmitry:
> There is a question that troubles me
>
> drm_plane include such standard properties.
> {
>         struct drm_property *alpha_property;
>         struct drm_property *zpos_property;
>         struct drm_property *rotation_property;
>         struct drm_property *blend_mode_property;
>         struct drm_property *color_encoding_property;
>         struct drm_property *color_range_property;
>         struct drm_property *scaling_filter_property;
> }
>
> it doesn't include degamma and color management properties

Which is because they are not standardised yet.

>
> >> >
> >> >> +    else if (property == vs_plane->roi_prop)
> >> >> +            *val = (vs_plane_state->roi) ?
> >> >> +                                    vs_plane_state->roi->base.id : 0;
> >> >> +    else
> >> >> +            return -EINVAL;
> >> >> +
> >> >> +    return 0;
> >> >> +}
> >> >> +
> >> >> +static bool vs_format_mod_supported(struct drm_plane *plane,
> >> >> +                                u32 format,
> >> >> +                                u64 modifier)
> >> >> +{
> >> >> +    int i;
> >> >> +
> >> >> +    /* We always have to allow these modifiers:
> >> >> +     * 1. Core DRM checks for LINEAR support if userspace does not provide modifiers.
> >> >> +     * 2. Not passing any modifiers is the same as explicitly passing INVALID.
> >> >> +     */
> >> >> +    if (modifier == DRM_FORMAT_MOD_LINEAR)
> >> >> +            return true;
> >> >> +
> >> >> +    /* Check that the modifier is on the list of the plane's supported modifiers. */
> >> >> +    for (i = 0; i < plane->modifier_count; i++) {
> >> >> +            if (modifier == plane->modifiers[i])
> >> >> +                    break;
> >> >> +    }
> >> >> +
> >> >> +    if (i == plane->modifier_count)
> >> >> +            return false;
> >> >> +
> >> >> +    return true;
> >> >> +}
> >> >> +
> >> >> +const struct drm_plane_funcs vs_plane_funcs = {
> >> >> +    .update_plane           = drm_atomic_helper_update_plane,
> >> >> +    .disable_plane          = drm_atomic_helper_disable_plane,
> >> >> +    .reset                  = vs_plane_reset,
> >> >> +    .atomic_duplicate_state = vs_plane_atomic_duplicate_state,
> >> >> +    .atomic_destroy_state   = vs_plane_atomic_destroy_state,
> >> >> +    .atomic_set_property    = vs_plane_atomic_set_property,
> >> >> +    .atomic_get_property    = vs_plane_atomic_get_property,
> >> >> +    .format_mod_supported   = vs_format_mod_supported,
> >> >> +};
> >> >> +
> >> >> +static unsigned char vs_get_plane_number(struct drm_framebuffer *fb)
> >> >> +{
> >> >> +    const struct drm_format_info *info;
> >> >> +
> >> >> +    if (!fb)
> >> >> +            return 0;
> >> >> +
> >> >> +    info = drm_format_info(fb->format->format);
> >> >> +    if (!info || info->num_planes > DRM_FORMAT_MAX_PLANES)
> >> >> +            return 0;
> >> >> +
> >> >> +    return info->num_planes;
> >> >> +}
> >> >> +
> >> >> +static int vs_plane_atomic_check(struct drm_plane *plane,
> >> >> +                             struct drm_atomic_state *state)
> >> >> +{
> >> >> +    struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
> >> >> +                                                                             plane);
> >> >> +    unsigned char i, num_planes;
> >> >> +    struct drm_framebuffer *fb = new_plane_state->fb;
> >> >> +    struct drm_crtc *crtc = new_plane_state->crtc;
> >> >> +    struct vs_crtc *vs_crtc = to_vs_crtc(crtc);
> >> >> +    struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev);
> >> >> +    struct vs_plane_state *plane_state = to_vs_plane_state(new_plane_state);
> >> >> +
> >> >> +    if (!crtc || !fb)
> >> >> +            return 0;
> >> >> +
> >> >> +    num_planes = vs_get_plane_number(fb);
> >> >> +
> >> >> +    for (i = 0; i < num_planes; i++) {
> >> >> +            dma_addr_t dma_addr;
> >> >> +
> >> >> +            dma_addr = drm_fb_dma_get_gem_addr(fb, new_plane_state, i);
> >> >> +            plane_state->dma_addr[i] = dma_addr;
> >> >> +    }
> >> >> +
> >> >> +    return vs_dc_check_plane(dc, plane, state);
> >> >> +}
> >> >> +
> >> >> +static int vs_cursor_plane_atomic_check(struct drm_plane *plane,
> >> >> +                                    struct drm_atomic_state *state)
> >> >> +{
> >> >> +    struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
> >> >> +                                                                      plane);
> >> >> +    unsigned char i, num_planes;
> >> >> +    struct drm_framebuffer *fb = new_plane_state->fb;
> >> >> +    struct drm_crtc *crtc = new_plane_state->crtc;
> >> >> +    struct vs_crtc *vs_crtc = to_vs_crtc(crtc);
> >> >> +    struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev);
> >> >> +    struct vs_plane_state *plane_state = to_vs_plane_state(new_plane_state);
> >> >> +
> >> >> +    if (!crtc || !fb)
> >> >> +            return 0;
> >> >> +
> >> >> +    num_planes = vs_get_plane_number(fb);
> >> >> +
> >> >> +    for (i = 0; i < num_planes; i++) {
> >> >> +            dma_addr_t dma_addr;
> >> >> +
> >> >> +            dma_addr = drm_fb_dma_get_gem_addr(fb, new_plane_state, i);
> >> >> +            plane_state->dma_addr[i] = dma_addr;
> >> >> +    }
> >> >> +
> >> >> +    return vs_dc_check_cursor_plane(dc, plane, state);
> >> >> +}
> >> >> +
> >> >> +static void vs_plane_atomic_update(struct drm_plane *plane,
> >> >> +                               struct drm_atomic_state *state)
> >> >> +{
> >> >> +    struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
> >> >> +                                                                      plane);
> >> >
> >> > New line after the equal sign will be better.
> >> >
> >> >> +    struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
> >> >> +                                                                      plane);
> >> >> +
> >> >> +    unsigned char i, num_planes;
> >> >> +    struct drm_framebuffer *fb;
> >> >> +    struct vs_plane *vs_plane = to_vs_plane(plane);
> >> >> +    struct vs_crtc *vs_crtc = to_vs_crtc(new_state->crtc);
> >> >> +    struct vs_plane_state *plane_state = to_vs_plane_state(new_state);
> >> >> +    struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev);
> >> >> +
> >> >> +    if (!new_state->fb || !new_state->crtc)
> >> >> +            return;
> >> >
> >> > if (!new_state->visible) ?
>
> no matter what value it is ? the driver will handle it
> in func
>
> static void update_fb(struct vs_plane *plane, u8 display_id,
>                       struct dc_hw_fb *fb, struct drm_plane_state *state)
> {
>         struct vs_plane_state *plane_state = to_vs_plane_state(state);
>         struct drm_framebuffer *drm_fb = state->fb;
>         struct drm_rect *src = &state->src;
>
> .......
>         fb->enable = state->visible;
> .......
> }
>
> so no need add "if (!new_state->visible)" i think

I mean instead of fb&&crtc check. Otherwise you are duplicating checks
in drm_atomic_helper_check_plane_state(). And with the pixel_source
being on their way this condition becomes legacy.

>
> >> >
> >> >> +
> >> >> +    fb = new_state->fb;
> >> >> +
> >> >> +    drm_fb_dma_sync_non_coherent(fb->dev, old_state, new_state);
> >> >> +
> >> >> +    num_planes = vs_get_plane_number(fb);
> >> >> +
> >> >> +    for (i = 0; i < num_planes; i++) {
> >> >> +            dma_addr_t dma_addr;
> >> >> +
> >> >> +            dma_addr = drm_fb_dma_get_gem_addr(fb, new_state, i);
> >> >> +            plane_state->dma_addr[i] = dma_addr;
> >> >> +    }
> >> >> +
> >> >> +    plane_state->status.src = drm_plane_state_src(new_state);
> >> >> +    plane_state->status.dest = drm_plane_state_dest(new_state);
> >> >> +
> >> >> +    vs_dc_update_plane(dc, vs_plane, plane, state);
> >> >> +}
> >> >> +


-- 
With best wishes
Dmitry


More information about the dri-devel mailing list