Re: [PATCH 6/9] drm/verisilicon: Add drm crtc funcs

From: Sam Ravnborg
Date: Fri Jul 21 2023 - 08:34:11 EST


Hi Keith,
On Fri, Jul 21, 2023 at 07:57:24PM +0800, Keith Zhao wrote:
> >> +
> >> +struct vs_crtc_funcs {
> >> +    void (*enable)(struct device *dev, struct drm_crtc *crtc);
> >> +    void (*disable)(struct device *dev, struct drm_crtc *crtc);
> >> +    bool (*mode_fixup)(struct device *dev,
> >> +               const struct drm_display_mode *mode,
> >> +               struct drm_display_mode *adjusted_mode);
> >> +    void (*set_gamma)(struct device *dev, struct drm_crtc *crtc,
> >> +              struct drm_color_lut *lut, unsigned int size);
> >> +    void (*enable_gamma)(struct device *dev, struct drm_crtc *crtc,
> >> +                 bool enable);
> >> +    void (*enable_vblank)(struct device *dev, bool enable);
> >> +    void (*commit)(struct device *dev);
> >> +};
> >
> > Why is this here? You are reproducing our interface with an internal interface. I know where this leads to: you have multiple chipset revisions and each has its own implemenation of these internal interfaces.
> >
> > That will absolutely come back to haunt you in the long rung: the more chip revisions you support, the more obscure these internal interfaces and implentations become. And you won't be able to change these callbacks, as that affects all revisions. We've seen this with a few drivers. It will become unmaintainable.
> >
> > A better approach is to treat DRM's atomic callback funcs and atomic helper funcs as your interface for each chip revision. So for each model, you implement a separate modesetting pipeline. When you add a new chip revision, you copy the previous chip's code into a new file and adopt it. If you find comon code among individual revisions, you can put it into a shared helper.  With this design, each chip revision stands on its own.
> >
> > I suggest to study the mgag200 driver. It detects the chip revision very early and builds a chip-specific modesetting pipline. Although each chip is handled separately, a lot of shared code is in helpers. So the size of the driver remains small.
> >
> hi Thomas:
> I'm trying to understand what you're thinking

I am not Thomas, but let me try to put a few words on this.

> 1. Different chip ids should have their own independent drm_dev, and should not be supported based on a same drm_dev.
Yes, this part is correct understood.

> 2. diff chip id , for example dc8200 , dc9000,
>
> struct vs_crtc_funcs {
> void (*enable)(struct device *dev, struct drm_crtc *crtc);
> void (*disable)(struct device *dev, struct drm_crtc *crtc);
> bool (*mode_fixup)(struct device *dev,
> const struct drm_display_mode *mode,
> struct drm_display_mode *adjusted_mode);
> void (*set_gamma)(struct device *dev, struct drm_crtc *crtc,
> struct drm_color_lut *lut, unsigned int size);
> void (*enable_gamma)(struct device *dev, struct drm_crtc *crtc,
> bool enable);
> void (*enable_vblank)(struct device *dev, bool enable);
> void (*commit)(struct device *dev);
> };
No - the idea is that you populate crtc_funcs direct.
Drop struct vs_crtc_funcs - just fill out your own crtc_funcs structure.

If it turns out that most of the crtc operations are the same then share
them. Avoid the extra layer of indirection that you have with struct vs_crtc_funcs
as this is not needed when you use the pattern described by Thomas.


> static const struct vs_crtc_funcs vs_dc8200_crtc_funcs = {...}
> static const struct vs_crtc_funcs vs_dc9200_crtc_funcs = {...}
>
> struct vs_drm_private {
> struct drm_device base;
> struct device *dma_dev;
> struct iommu_domain *domain;
> unsigned int pitch_alignment;

This parts looks fine.

>
> const struct vs_crtc_funcs *funcs;
No, here you need a pointer to struct crtc_funcs or a struct that embeds
crtc_funcs.
> };

If you, after reading this, thinks you need struct vs_crtc_funcs, then
try to take an extra look at mgag200. It is not needed.

I hope this helps.

Sam