From: "Paul-pl Chen (陳柏霖)" <Paul-pl.Chen@mediatek.com>
To: "CK Hu (胡俊光)" <ck.hu@mediatek.com>,
"robh@kernel.org" <robh@kernel.org>,
"krzk+dt@kernel.org" <krzk+dt@kernel.org>,
"conor+dt@kernel.org" <conor+dt@kernel.org>,
"chunkuang.hu@kernel.org" <chunkuang.hu@kernel.org>,
"AngeloGioacchino Del Regno"
<angelogioacchino.delregno@collabora.com>
Cc: "Sunny Shen (沈姍姍)" <Sunny.Shen@mediatek.com>,
"Singo Chang (張興國)" <Singo.Chang@mediatek.com>,
"treapking@chromium.org" <treapking@chromium.org>,
Project_Global_Chrome_Upstream_Group
<Project_Global_Chrome_Upstream_Group@mediatek.com>,
"dri-devel@lists.freedesktop.org"
<dri-devel@lists.freedesktop.org>,
"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
"Jason-JH Lin (林睿祥)" <Jason-JH.Lin@mediatek.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"Nancy Lin (林欣螢)" <Nancy.Lin@mediatek.com>,
"Xiandong Wang (王先冬)" <Xiandong.Wang@mediatek.com>,
"matthias.bgg@gmail.com" <matthias.bgg@gmail.com>,
"linux-mediatek@lists.infradead.org"
<linux-mediatek@lists.infradead.org>,
"p.zabel@pengutronix.de" <p.zabel@pengutronix.de>,
"Sirius Wang (王皓昱)" <Sirius.Wang@mediatek.com>,
"linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH 11/12] drm/mediatek: add ovlsys_adaptor support for MT8196
Date: Fri, 21 Feb 2025 12:34:10 +0000 [thread overview]
Message-ID: <90bd076d82bf2cddeb3ce578be6e7539886cfc2b.camel@mediatek.com> (raw)
In-Reply-To: <59aa3e03300ada8f47c0b5ae3a9c173eab45af7e.camel@mediatek.com>
On Wed, 2025-02-12 at 07:09 +0000, CK Hu (胡俊光) wrote:
> Hi, Paul:
>
> On Fri, 2025-01-10 at 20:34 +0800, paul-pl.chen wrote:
> > From: "Nancy.Lin" <nancy.lin@mediatek.com>
> >
> > Ovlsys_adaptor is an encapsulated module designed to
> > simplify the DRM control flow. This module is composed
> > of 20 EXDMAs, 20 BLENDERs, and 12 OUTPROCs.
> > Two EXDMAs merge into one layer, allowing the module
> > to support 20 layers for 3 display paths.
> > Ovlsys_adaptor driver is integrated within the
> > mtk_ddp_comp framework.
> >
> > Signed-off-by: Nancy.Lin <nancy.lin@mediatek.com>
> > Signed-off-by: Paul-pl.Chen <paul-pl.chen@mediatek.com>
> > ---
> > drivers/gpu/drm/mediatek/Makefile | 1 +
> > drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 25 +
> > drivers/gpu/drm/mediatek/mtk_ddp_comp.h | 1 +
> > drivers/gpu/drm/mediatek/mtk_disp_drv.h | 31 +-
> > .../drm/mediatek/mtk_disp_ovlsys_adaptor.c | 758
> > ++++++++++++++++++
> > drivers/gpu/drm/mediatek/mtk_drm_drv.c | 61 +-
> > drivers/gpu/drm/mediatek/mtk_drm_drv.h | 11 +-
> > 7 files changed, 884 insertions(+), 4 deletions(-)
> > create mode 100644
> > drivers/gpu/drm/mediatek/mtk_disp_ovlsys_adaptor.c
> >
> > diff --git a/drivers/gpu/drm/mediatek/Makefile
> > b/drivers/gpu/drm/mediatek/Makefile
> >
//snip
> > +#include "mtk_disp_blender.h"
> > +#include "mtk_disp_drv.h"
> > +#include "mtk_crtc.h"
>
> Alphabetic order.
>
Ok, I will fix this part.
> > +#include "mtk_ddp_comp.h"
> > +#include "mtk_drm_drv.h"
> > +
> > +enum mtk_ovlsys_adaptor_comp_type {
> > + OVLSYS_ADAPTOR_TYPE_EXDMA = 0,
> > + OVLSYS_ADAPTOR_TYPE_BLENDER,
> > + OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > + OVLSYS_ADAPTOR_TYPE_NUM,
> > +};
> > +
> > +enum mtk_ovlsys_adaptor_comp_id {
> > + OVLSYS_ADAPTOR_EXDMA0,
> > + OVLSYS_ADAPTOR_EXDMA1,
> > + OVLSYS_ADAPTOR_EXDMA2,
> > + OVLSYS_ADAPTOR_EXDMA3,
> > + OVLSYS_ADAPTOR_EXDMA4,
> > + OVLSYS_ADAPTOR_EXDMA5,
> > + OVLSYS_ADAPTOR_EXDMA6,
> > + OVLSYS_ADAPTOR_EXDMA7,
> > + OVLSYS_ADAPTOR_EXDMA8,
> > + OVLSYS_ADAPTOR_EXDMA9,
> > + OVLSYS_ADAPTOR_EXDMA10,
> > + OVLSYS_ADAPTOR_EXDMA11,
> > + OVLSYS_ADAPTOR_EXDMA12,
> > + OVLSYS_ADAPTOR_EXDMA13,
> > + OVLSYS_ADAPTOR_EXDMA14,
> > + OVLSYS_ADAPTOR_EXDMA15,
> > + OVLSYS_ADAPTOR_EXDMA16,
> > + OVLSYS_ADAPTOR_EXDMA17,
> > + OVLSYS_ADAPTOR_EXDMA18,
> > + OVLSYS_ADAPTOR_EXDMA19,
> > + OVLSYS_ADAPTOR_BLENDER0,
> > + OVLSYS_ADAPTOR_BLENDER1,
> > + OVLSYS_ADAPTOR_BLENDER2,
> > + OVLSYS_ADAPTOR_BLENDER3,
> > + OVLSYS_ADAPTOR_BLENDER4,
> > + OVLSYS_ADAPTOR_BLENDER5,
> > + OVLSYS_ADAPTOR_BLENDER6,
> > + OVLSYS_ADAPTOR_BLENDER7,
> > + OVLSYS_ADAPTOR_BLENDER8,
> > + OVLSYS_ADAPTOR_BLENDER9,
> > + OVLSYS_ADAPTOR_BLENDER10,
> > + OVLSYS_ADAPTOR_BLENDER11,
> > + OVLSYS_ADAPTOR_BLENDER12,
> > + OVLSYS_ADAPTOR_BLENDER13,
> > + OVLSYS_ADAPTOR_BLENDER14,
> > + OVLSYS_ADAPTOR_BLENDER15,
> > + OVLSYS_ADAPTOR_BLENDER16,
> > + OVLSYS_ADAPTOR_BLENDER17,
> > + OVLSYS_ADAPTOR_BLENDER18,
> > + OVLSYS_ADAPTOR_BLENDER19,
> > + OVLSYS_ADAPTOR_OUTPROC0,
> > + OVLSYS_ADAPTOR_OUTPROC1,
> > + OVLSYS_ADAPTOR_OUTPROC2,
> > + OVLSYS_ADAPTOR_OUTPROC3,
> > + OVLSYS_ADAPTOR_OUTPROC4,
> > + OVLSYS_ADAPTOR_OUTPROC5,
> > + OVLSYS_ADAPTOR_OUTPROC6,
> > + OVLSYS_ADAPTOR_OUTPROC7,
> > + OVLSYS_ADAPTOR_OUTPROC8,
> > + OVLSYS_ADAPTOR_OUTPROC9,
> > + OVLSYS_ADAPTOR_OUTPROC10,
> > + OVLSYS_ADAPTOR_OUTPROC11,
> > + OVLSYS_ADAPTOR_ID_MAX
> > +};
> > +
> > +struct ovlsys_adaptor_comp_match {
> > + enum mtk_ovlsys_adaptor_comp_type type;
> > + int alias_id;
> > + enum mtk_ddp_comp_id comp_id;
> > +};
> > +
> > +struct mtk_disp_ovlsys_adaptor {
> > + struct device *ovl_adaptor_comp[OVLSYS_ADAPTOR_ID_MAX];
> > + struct device *mmsys_dev;
> > + const unsigned int *path;
> > + unsigned int path_size;
> > + unsigned int layer_nr;
> > + bool children_bound;
> > + unsigned int max_size;
> > +};
> > +
> > +static const char * const
> > private_comp_stem[OVLSYS_ADAPTOR_TYPE_NUM] = {
> > + [OVLSYS_ADAPTOR_TYPE_EXDMA] = "exdma",
> > + [OVLSYS_ADAPTOR_TYPE_BLENDER] = "blender",
> > + [OVLSYS_ADAPTOR_TYPE_OUTPROC] = "outproc",
> > +};
> > +
> > +static const struct ovlsys_adaptor_comp_match
> > comp_matches[OVLSYS_ADAPTOR_ID_MAX] = {
> > + [OVLSYS_ADAPTOR_EXDMA0] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 0, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_EXDMA1] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 1, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_EXDMA2] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 2, DDP_COMPONENT_OVL0_EXDMA2},
> > + [OVLSYS_ADAPTOR_EXDMA3] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 3, DDP_COMPONENT_OVL0_EXDMA3},
> > + [OVLSYS_ADAPTOR_EXDMA4] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 4, DDP_COMPONENT_OVL0_EXDMA4},
> > + [OVLSYS_ADAPTOR_EXDMA5] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 5, DDP_COMPONENT_OVL0_EXDMA5},
> > + [OVLSYS_ADAPTOR_EXDMA6] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 6, DDP_COMPONENT_OVL0_EXDMA6},
> > + [OVLSYS_ADAPTOR_EXDMA7] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 7, DDP_COMPONENT_OVL0_EXDMA7},
> > + [OVLSYS_ADAPTOR_EXDMA8] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 8, DDP_COMPONENT_OVL0_EXDMA8},
> > + [OVLSYS_ADAPTOR_EXDMA9] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 9, DDP_COMPONENT_OVL0_EXDMA9},
> > + [OVLSYS_ADAPTOR_EXDMA10] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 10, DDP_COMPONENT_ID_MAX},
>
> EXDMA10 has no component id, so just drop OVLSYS_ADAPTOR_EXDMA10.
>
OK I will check this part.
> > + [OVLSYS_ADAPTOR_EXDMA11] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 11, DDP_COMPONENT_ID_MAX},
>
> Ditto.
>
OK I will check this part, too.
> > + [OVLSYS_ADAPTOR_EXDMA12] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 12, DDP_COMPONENT_OVL1_EXDMA2},
> > + [OVLSYS_ADAPTOR_EXDMA13] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 13, DDP_COMPONENT_OVL1_EXDMA3},
> > + [OVLSYS_ADAPTOR_EXDMA14] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 14, DDP_COMPONENT_OVL1_EXDMA4},
> > + [OVLSYS_ADAPTOR_EXDMA15] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 15, DDP_COMPONENT_OVL1_EXDMA5},
> > + [OVLSYS_ADAPTOR_EXDMA16] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 16, DDP_COMPONENT_OVL1_EXDMA6},
> > + [OVLSYS_ADAPTOR_EXDMA17] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 17, DDP_COMPONENT_OVL1_EXDMA7},
> > + [OVLSYS_ADAPTOR_EXDMA18] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 18, DDP_COMPONENT_OVL1_EXDMA8},
> > + [OVLSYS_ADAPTOR_EXDMA19] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 19, DDP_COMPONENT_OVL1_EXDMA9},
> > + [OVLSYS_ADAPTOR_BLENDER0] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 0, DDP_COMPONENT_ID_MAX},
>
> Ditto.
>
OK I will check this part, too.
> > + [OVLSYS_ADAPTOR_BLENDER1] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 1, DDP_COMPONENT_OVL0_BLENDER1},
> > + [OVLSYS_ADAPTOR_BLENDER2] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 2, DDP_COMPONENT_OVL0_BLENDER2},
> > + [OVLSYS_ADAPTOR_BLENDER3] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 3, DDP_COMPONENT_OVL0_BLENDER3},
> > + [OVLSYS_ADAPTOR_BLENDER4] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 4, DDP_COMPONENT_OVL0_BLENDER4},
> > + [OVLSYS_ADAPTOR_BLENDER5] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 5, DDP_COMPONENT_OVL0_BLENDER5},
> > + [OVLSYS_ADAPTOR_BLENDER6] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 6, DDP_COMPONENT_OVL0_BLENDER6},
> > + [OVLSYS_ADAPTOR_BLENDER7] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 7, DDP_COMPONENT_OVL0_BLENDER7},
> > + [OVLSYS_ADAPTOR_BLENDER8] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 8, DDP_COMPONENT_OVL0_BLENDER8},
> > + [OVLSYS_ADAPTOR_BLENDER9] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 9, DDP_COMPONENT_OVL0_BLENDER9},
> > + [OVLSYS_ADAPTOR_BLENDER10] = {
> > OVLSYS_ADAPTOR_TYPE_BLENDER, 10, DDP_COMPONENT_ID_MAX},
>
> Ditto.
>
OK I will check this part, too.
> > + [OVLSYS_ADAPTOR_BLENDER11] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 11,
> > DDP_COMPONENT_OVL1_BLENDER1},
> > + [OVLSYS_ADAPTOR_BLENDER12] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 12,
> > DDP_COMPONENT_OVL1_BLENDER2},
> > + [OVLSYS_ADAPTOR_BLENDER13] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 13,
> > DDP_COMPONENT_OVL1_BLENDER3},
> > + [OVLSYS_ADAPTOR_BLENDER14] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 14,
> > DDP_COMPONENT_OVL1_BLENDER4},
> > + [OVLSYS_ADAPTOR_BLENDER15] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 15,
> > DDP_COMPONENT_OVL1_BLENDER5},
> > + [OVLSYS_ADAPTOR_BLENDER16] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 16,
> > DDP_COMPONENT_OVL1_BLENDER6},
> > + [OVLSYS_ADAPTOR_BLENDER17] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 17,
> > DDP_COMPONENT_OVL1_BLENDER7},
> > + [OVLSYS_ADAPTOR_BLENDER18] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 18,
> > DDP_COMPONENT_OVL1_BLENDER8},
> > + [OVLSYS_ADAPTOR_BLENDER19] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 19,
> > DDP_COMPONENT_OVL1_BLENDER9},
> > + [OVLSYS_ADAPTOR_OUTPROC0] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 0, DDP_COMPONENT_OVL0_OUTPROC0},
> > + [OVLSYS_ADAPTOR_OUTPROC1] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 1, DDP_COMPONENT_OVL0_OUTPROC1},
> > + [OVLSYS_ADAPTOR_OUTPROC2] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 2, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC3] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 3, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC4] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 4, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC5] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 5, DDP_COMPONENT_ID_MAX},
>
> Ditto.
>
OK I will check this part, too.
> > + [OVLSYS_ADAPTOR_OUTPROC6] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 6, DDP_COMPONENT_OVL1_OUTPROC0},
> > + [OVLSYS_ADAPTOR_OUTPROC7] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 7, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC8] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 8, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC9] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 9, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC10] = {
> > OVLSYS_ADAPTOR_TYPE_OUTPROC, 10, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC11] = {
> > OVLSYS_ADAPTOR_TYPE_OUTPROC, 11, DDP_COMPONENT_ID_MAX},
>
> Ditto.
>
OK I will check this part, too.
> > +};
> > +
> > +static const unsigned int mt8196_mtk_ovl_main[] = {
> > + OVLSYS_ADAPTOR_EXDMA2,
> > + OVLSYS_ADAPTOR_BLENDER1,
> > + OVLSYS_ADAPTOR_EXDMA3,
> > + OVLSYS_ADAPTOR_BLENDER2,
> > + OVLSYS_ADAPTOR_EXDMA4,
> > + OVLSYS_ADAPTOR_BLENDER3,
> > + OVLSYS_ADAPTOR_EXDMA5,
> > + OVLSYS_ADAPTOR_BLENDER4,
> > + OVLSYS_ADAPTOR_OUTPROC0,
> > +};
> > +
> > +static const unsigned int mt8196_mtk_ovl_ext[] = {
> > + OVLSYS_ADAPTOR_EXDMA6,
> > + OVLSYS_ADAPTOR_BLENDER5,
> > + OVLSYS_ADAPTOR_EXDMA7,
> > + OVLSYS_ADAPTOR_BLENDER6,
> > + OVLSYS_ADAPTOR_EXDMA8,
> > + OVLSYS_ADAPTOR_BLENDER7,
> > + OVLSYS_ADAPTOR_EXDMA9,
> > + OVLSYS_ADAPTOR_BLENDER8,
> > + OVLSYS_ADAPTOR_OUTPROC1,
> > +};
> > +
> > +static const unsigned int mt8196_mtk_ovl_third[] = {
> > + OVLSYS_ADAPTOR_EXDMA12,
> > + OVLSYS_ADAPTOR_BLENDER11,
> > + OVLSYS_ADAPTOR_EXDMA13,
> > + OVLSYS_ADAPTOR_BLENDER12,
> > + OVLSYS_ADAPTOR_EXDMA14,
> > + OVLSYS_ADAPTOR_BLENDER13,
> > + OVLSYS_ADAPTOR_EXDMA15,
> > + OVLSYS_ADAPTOR_BLENDER14,
> > + OVLSYS_ADAPTOR_OUTPROC6,
> > +};
> > +
> > +static enum mtk_ovlsys_adaptor_comp_type get_type(enum
> > mtk_ovlsys_adaptor_comp_id id)
> > +{
> > + return comp_matches[id].type;
> > +}
> > +
> > +static enum mtk_ddp_comp_id get_ddp_comp_id(enum
> > mtk_ovlsys_adaptor_comp_id id)
> > +{
> > + return comp_matches[id].comp_id;
> > +}
> > +
> > +static struct device *get_comp_by_type_idx(struct device *dev,
> > + enum
> > mtk_ovlsys_adaptor_comp_type type,
> > + unsigned int idx)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > + int count = 0;
> > +
> > + for (i = 0; i < priv->path_size; i++) {
> > + if (get_type(priv->path[i]) == type) {
> > + if (count == idx)
> > + return priv-
> > >ovl_adaptor_comp[priv->path[i]];
> > + count++;
> > + }
> > + }
> > + return NULL;
> > +}
> > +
> > +void mtk_ovlsys_adaptor_layer_config(struct device *dev, unsigned
> > int idx,
> > + struct mtk_plane_state
> > *state,
> > + struct cmdq_pkt *cmdq_pkt)
> > +{
> > + struct mtk_plane_pending_state *pending = &state->pending;
> > + struct device *exdma;
> > + struct device *blender;
> > + unsigned int align_width = 0;
> > + const struct drm_format_info *fmt_info =
> > drm_format_info(pending->format);
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + dev_dbg(dev, "%s+ idx:%d, enable:%d, fmt:0x%x\n",
> > __func__, idx,
> > + pending->enable, pending->format);
> > + dev_dbg(dev, "addr 0x%pad, fb w:%d, {%d,%d,%d,%d}\n",
> > + &pending->addr, (pending->pitch / fmt_info-
> > >cpp[0]),
> > + pending->x, pending->y, pending->width, pending-
> > >height);
> > +
> > + exdma = get_comp_by_type_idx(dev,
> > OVLSYS_ADAPTOR_TYPE_EXDMA, idx);
> > + blender = get_comp_by_type_idx(dev,
> > OVLSYS_ADAPTOR_TYPE_BLENDER, idx);
> > +
> > + /* OVLSYS is in 1T2P domain, width needs to be 2 pixels
> > align */
> > + align_width = ALIGN_DOWN(pending->width, 2);
>
> align_width is useless, so drop it.
>
> > +
> > + if (!pending->enable || pending->height == 0 ||
> > align_width == 0 ||
> > + pending->x > priv->max_size || pending->y > priv-
> > >max_size) {
> > + pending->enable = false;
> > + mtk_disp_exdma_stop(exdma, cmdq_pkt);
> > + mtk_disp_blender_layer_config(blender, state,
> > cmdq_pkt);
> > + return;
> > + }
> > +
> > + mtk_disp_exdma_config(exdma, state, cmdq_pkt);
>
> mtk_disp_exdma_config() does something like mtk_ovl_layer_config(),
> so I would like to rename it to mtk_disp_exdma_layer_config().
>
Sure, I will rename the function name.
> > +
> > + mtk_disp_blender_layer_config(blender, state, cmdq_pkt);
> > +
> > + mtk_disp_exdma_start(exdma, cmdq_pkt);
>
> Why call start in layer config?
> start should be called in start.
>
Sure, I will fix the order of setting.
> > + mtk_disp_blender_start(blender, cmdq_pkt);
>
> Ditto.
OK I will check this part, too.
>
> > +}
> > +
> > +void mtk_ovlsys_adaptor_config(struct device *dev, unsigned int w,
> > + unsigned int h, unsigned int
> > vrefresh,
> > + unsigned int bpc, struct cmdq_pkt
> > *cmdq_pkt)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > + int blender_idx = 0;
> > +
> > + for (i = 0; i < priv->path_size; i++) {
> > + enum mtk_disp_blender_layer blender;
> > +
> > + if (get_type(priv->path[i]) ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER) {
> > + blender_idx++;
> > + if (priv->layer_nr == 1)
> > + blender = SINGLE_BLENDER;
> > + else if (blender_idx == 1)
> > + blender = FIRST_BLENDER;
> > + else if (blender_idx == priv->layer_nr)
> > + blender = LAST_BLENDER;
> > + else
> > + blender = OTHERS;
> > +
> > + mtk_disp_blender_config(priv-
> > >ovl_adaptor_comp[priv->path[i]], w, h,
> > + vrefresh, bpc,
> > blender, cmdq_pkt);
>
> mtk_disp_blender_config(priv->ovl_adaptor_comp[priv->path[i]], w, h,
> vrefresh, bpc, blender_idx == 1, blender_idx
> == priv->layer_nr, cmdq_pkt);
>
> > + } else if (get_type(priv->path[i]) ==
> > OVLSYS_ADAPTOR_TYPE_OUTPROC) {
> > + mtk_disp_outproc_config(priv-
> > >ovl_adaptor_comp[priv->path[i]], w, h,
> > + vrefresh, bpc,
> > cmdq_pkt);
> > + }
> > + }
> > +}
> > +
> > +int mtk_ovlsys_adaptor_layer_check(struct device *dev,
> > + unsigned int idx,
> > + struct mtk_plane_state
> > *mtk_state)
> > +{
> > + struct drm_plane_state *state = &mtk_state->base;
> > +
> > + /* Check if any unsupported rotation is set */
> > + if (state->rotation & ~DRM_MODE_ROTATE_0)
> > + return -EINVAL;
> > +
> > + return 0;
> > +}
> > +
> > +void mtk_ovlsys_adaptor_start(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > +
> > + for (i = 0; i < priv->path_size; i++) {
> > + if (get_type(priv->path[i]) ==
> > OVLSYS_ADAPTOR_TYPE_EXDMA)
> > + mtk_disp_exdma_start(priv-
> > >ovl_adaptor_comp[priv->path[i]], NULL);
>
> The start never use cmdq, so remove the cmdq parameter.
Ok, I will fix this part.
>
> > + else if (get_type(priv->path[i]) ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER)
> > + mtk_disp_blender_start(priv-
> > >ovl_adaptor_comp[priv->path[i]], NULL);
>
> Ditto.
>
Ok, I will fix this part.> > + else
> > + mtk_disp_outproc_start(priv-
> > >ovl_adaptor_comp[priv->path[i]]);
> > + }
> > +}
> > +
> > +void mtk_ovlsys_adaptor_stop(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > +
> > + for (i = 0; i < priv->path_size; i++) {
> > + if (get_type(priv->path[i]) ==
> > OVLSYS_ADAPTOR_TYPE_EXDMA)
> > + mtk_disp_exdma_stop(priv-
> > >ovl_adaptor_comp[priv->path[i]], NULL);
>
> Ditto.
Ok, I will fix this part.th.
>
> > + else if (get_type(priv->path[i]) ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER)
> > + mtk_disp_blender_stop(priv-
> > >ovl_adaptor_comp[priv->path[i]], NULL);
>
> Ditto.
Ok, I will fix this part.
>
> > + else
> > + mtk_disp_outproc_stop(priv-
> > >ovl_adaptor_comp[priv->path[i]]);
> > + }
> > +}
> > +
> > +int mtk_ovlsys_adaptor_clk_enable(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + struct device *comp;
> > + int ret;
> > + int i;
> > +
> > + for (i = 0; i < OVLSYS_ADAPTOR_ID_MAX; i++) {
> > + comp = priv->ovl_adaptor_comp[i];
> > +
> > + if (!comp)
> > + continue;
> > +
> > + if (get_type(i) != OVLSYS_ADAPTOR_TYPE_EXDMA)
> > + continue;
> > +
> > + ret = pm_runtime_get_sync(comp);
>
> Refer to mtk_ovl_adaptor_power_on().
> This should be done in power_on() callback function.
Sure, I will align the power sequence with the function
mtk_ovl_adaptor_power_on().
>
> > + if (ret < 0) {
> > + dev_err(dev, "Failed to enable power
> > domain %d, err %d\n", i, ret);
> > + goto pwr_err;
> > + }
> > + }
> > +
> > + for (i = 0; i < OVLSYS_ADAPTOR_ID_MAX; i++) {
> > + comp = priv->ovl_adaptor_comp[i];
> > +
> > + if (!comp)
> > + continue;
> > +
> > + if (get_type(i) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> > + ret = mtk_disp_exdma_clk_enable(comp);
> > + else if (get_type(i) ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER)
> > + ret = mtk_disp_blender_clk_enable(comp);
> > + else
> > + ret = mtk_disp_outproc_clk_enable(comp);
> > +
> > + if (ret) {
> > + dev_err(dev, "Failed to enable clock %d,
> > err %d\n", i, ret);
> > + goto clk_err;
> > + }
> > + }
> > +
> > + return ret;
> > +
> > +clk_err:
> > + while (--i >= 0) {
> > + comp = priv->ovl_adaptor_comp[i];
> > + if (!comp)
> > + continue;
> > + if (get_type(i) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> > + mtk_disp_exdma_clk_disable(comp);
> > + else if (get_type(i) ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER)
> > + mtk_disp_blender_clk_disable(comp);
> > + else
> > + mtk_disp_outproc_clk_disable(comp);
> > + }
> > + i = OVLSYS_ADAPTOR_BLENDER0;
> > +
> > +pwr_err:
> > + while (--i >= 0) {
> > + comp = priv->ovl_adaptor_comp[i];
> > + if (!comp)
> > + continue;
> > + pm_runtime_put(priv->ovl_adaptor_comp[i]);
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +void mtk_ovlsys_adaptor_clk_disable(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + struct device *comp;
> > + int i;
> > +
> > + for (i = 0; i < OVLSYS_ADAPTOR_ID_MAX; i++) {
> > + comp = priv->ovl_adaptor_comp[i];
> > +
> > + if (!comp)
> > + continue;
> > +
> > + if (get_type(i) == OVLSYS_ADAPTOR_TYPE_EXDMA) {
> > + mtk_disp_exdma_clk_disable(comp);
> > + pm_runtime_put(comp);
> > + } else if (get_type(i) ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER) {
> > + mtk_disp_blender_clk_disable(comp);
> > + } else {
> > + mtk_disp_outproc_clk_disable(comp);
> > + }
> > + }
> > +}
> > +
> > +unsigned int mtk_ovlsys_adaptor_layer_nr(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + return priv->layer_nr;
> > +}
> > +
> > +struct device *mtk_ovlsys_adaptor_dma_dev_get(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + return priv->ovl_adaptor_comp[priv->path[0]];
> > +}
> > +
> > +void mtk_ovlsys_adaptor_register_vblank_cb(struct device *dev,
> > void (*vblank_cb)(void *),
> > + void *vblank_cb_data)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + mtk_disp_outproc_register_vblank_cb(priv-
> > >ovl_adaptor_comp[priv->path[priv->path_size - 1]],
> > + vblank_cb,
> > vblank_cb_data);
> > +}
> > +
> > +void mtk_ovlsys_adaptor_unregister_vblank_cb(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + struct device *comp = priv->ovl_adaptor_comp[priv-
> > >path[priv->path_size - 1]];
> > +
> > + if (!priv->children_bound)
>
> In ovl adaptor, it does not check this. So remove this checking.
This is because of the mt8916's new hardwarew design.
ovlsys adaptor have to find the possible path.
>
> > + return;
> > +
> > + mtk_disp_outproc_unregister_vblank_cb(comp);
> > +}
> > +
> > +void mtk_ovlsys_adaptor_enable_vblank(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + mtk_disp_outproc_enable_vblank(priv-
> > >ovl_adaptor_comp[priv->path[priv->path_size - 1]]);
> > +}
> > +
> > +void mtk_ovlsys_adaptor_disable_vblank(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + mtk_disp_outproc_disable_vblank(priv-
> > >ovl_adaptor_comp[priv->path[priv->path_size - 1]]);
> > +}
> > +
> > +const u32 *mtk_ovlsys_adaptor_get_formats(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + return mtk_disp_exdma_get_formats(priv-
> > >ovl_adaptor_comp[priv->path[0]]);
> > +}
> > +
> > +size_t mtk_ovlsys_adaptor_get_num_formats(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + return mtk_disp_exdma_get_num_formats(priv-
> > >ovl_adaptor_comp[priv->path[0]]);
> > +}
> > +
> > +void mtk_ovlsys_adaptor_add_comp(struct device *dev, struct
> > mtk_mutex *mutex)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > +
> > + for (i = 0; i < priv->path_size; i++)
> > + mtk_mutex_add_comp(mutex, get_ddp_comp_id(priv-
> > >path[i]));
> > +}
> > +
> > +void mtk_ovlsys_adaptor_remove_comp(struct device *dev, struct
> > mtk_mutex *mutex)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > +
> > + for (i = 0; i < priv->path_size; i++)
> > + mtk_mutex_remove_comp(mutex, get_ddp_comp_id(priv-
> > >path[i]));
> > +}
> > +
> > +void mtk_ovlsys_adaptor_connect(struct device *dev, struct device
> > *mmsys_dev, unsigned int next)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > +
> > + for (i = 0; i < priv->path_size - 1; i++)
> > + mtk_mmsys_ddp_connect(mmsys_dev,
> > get_ddp_comp_id(priv->path[i]),
> > + get_ddp_comp_id(priv->path[i
> > + 1]));
> > +
> > + mtk_mmsys_ddp_connect(mmsys_dev, get_ddp_comp_id(priv-
> > >path[i]), next);
> > +}
> > +
> > +void mtk_ovlsys_adaptor_disconnect(struct device *dev, struct
> > device *mmsys_dev, unsigned int next)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > +
> > + for (i = 0; i < priv->path_size - 1; i++)
> > + mtk_mmsys_ddp_disconnect(mmsys_dev,
> > get_ddp_comp_id(priv->path[i]),
> > + get_ddp_comp_id(priv-
> > >path[i + 1]));
> > +
> > + mtk_mmsys_ddp_disconnect(mmsys_dev, get_ddp_comp_id(priv-
> > >path[i]), next);
> > +}
> > +
> > +static int ovlsys_adaptor_comp_get_id(struct device *dev, struct
> > device_node *node,
> > + enum
> > mtk_ovlsys_adaptor_comp_type type,
> > + enum mtk_ddp_comp_id
> > *comp_id)
> > +{
> > + int alias_id = of_alias_get_id(node,
> > private_comp_stem[type]);
> > + int i;
> > +
> > + for (i = 0; i < ARRAY_SIZE(comp_matches); i++)
> > + if (comp_matches[i].type == type &&
> > + comp_matches[i].alias_id == alias_id) {
> > + *comp_id = comp_matches[i].comp_id;
> > + return i;
> > + }
> > + dev_warn(dev, "Failed to get id. type: %d, alias: %d\n",
> > type, alias_id);
> > + return -EINVAL;
> > +}
> > +
> > +static const struct of_device_id mtk_ovlsys_adaptor_comp_dt_ids[]
> > = {
> > + {
> > + .compatible = "mediatek,mt8196-exdma",
> > + .data = (void *)OVLSYS_ADAPTOR_TYPE_EXDMA,
> > + }, {
> > + .compatible = "mediatek,mt8196-blender",
> > + .data = (void *)OVLSYS_ADAPTOR_TYPE_BLENDER,
> > + }, {
> > + .compatible = "mediatek,mt8196-outproc",
> > + .data = (void *)OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > + },
> > + {},
> > +};
> > +
> > +static int ovlsys_adaptor_comp_init(struct device *dev, struct
> > component_match **match)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + struct device_node *node, *parent;
> > + struct platform_device *comp_pdev;
> > + int i;
> > +
> > + parent = dev->parent->parent->of_node->parent;
> > +
> > + for_each_child_of_node(parent, node) {
> > + const struct of_device_id *of_id;
> > + enum mtk_ovlsys_adaptor_comp_type type;
> > + enum mtk_ddp_comp_id comp_id;
> > + int id;
> > + bool found = false;
> > +
> > + of_id =
> > of_match_node(mtk_ovlsys_adaptor_comp_dt_ids, node);
> > + if (!of_id)
> > + continue;
> > +
> > + if (!of_device_is_available(node)) {
> > + dev_dbg(dev, "Skipping disabled component
> > %pOF\n",
> > + node);
> > + continue;
> > + }
> > +
> > + type = (enum
> > mtk_ovlsys_adaptor_comp_type)(uintptr_t)of_id->data;
> > + id = ovlsys_adaptor_comp_get_id(dev, node, type,
> > &comp_id);
> > + if (id < 0) {
> > + dev_warn(dev, "Skipping unknown component
> > %pOF\n",
> > + node);
> > + continue;
> > + }
> > +
> > + for (i = 0; i < priv->path_size; i++)
> > + if (priv->path[i] == id)
> > + found = true;
> > +
> > + if (!found)
> > + continue;
>
> ovl adaptor does not check this, why ovlsys need this?
> If this is removed, this function is similar to the one in ovl
> adaptor,
> would you try to rewrite this function to be almost the same with the
> one in ovl adator?
> Not merging it, just implement almost the same.
This is because of the mt8916's new hardwarew design.
ovlsys adaptor have to find the possible path.
>
> > +
> > + comp_pdev = of_find_device_by_node(node);
> > + if (!comp_pdev)
> > + return -EPROBE_DEFER;
> > +
> > + priv->ovl_adaptor_comp[id] = &comp_pdev->dev;
> > +
> > + drm_of_component_match_add(dev, match,
> > component_compare_of, node);
> > + dev_dbg(dev, "Adding component match for %pOF\n",
> > node);
> > + }
> > +
> > + if (!*match) {
> > + dev_err(dev, "No match device for
> > ovlsys_adaptor\n");
> > + return -ENODEV;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int mtk_disp_ovlsys_adaptor_comp_bind(struct device *dev,
> > struct device *master,
> > + void *data)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + if (!priv->children_bound)
> > + return -EPROBE_DEFER;
> > +
> > + return 0;
> > +}
> > +
> > +static void mtk_disp_ovlsys_adaptor_comp_unbind(struct device
> > *dev, struct device *master,
> > + void *data)
> > +{
> > +}
> > +
> > +static const struct component_ops mtk_disp_ovlsys_adaptor_comp_ops
> > = {
> > + .bind = mtk_disp_ovlsys_adaptor_comp_bind,
> > + .unbind = mtk_disp_ovlsys_adaptor_comp_unbind,
> > +};
> > +
> > +static int mtk_disp_ovlsys_adaptor_master_bind(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int ret, i;
> > + unsigned int layer_nr = 0;
> > +
> > + ret = component_bind_all(dev, priv->mmsys_dev);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "component_bind_all
> > failed!\n");
> > +
> > + priv->children_bound = true;
> > +
> > + for (i = 0; i < priv->path_size; i++)
> > + if (comp_matches[priv->path[i]].type ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER)
> > + layer_nr++;
> > + priv->layer_nr = layer_nr;
> > +
> > + return 0;
> > +}
> > +
> > +static void mtk_disp_ovlsys_adaptor_master_unbind(struct device
> > *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + priv->children_bound = false;
> > +}
> > +
> > +static const struct component_master_ops
> > mtk_disp_ovlsys_adaptor_master_ops = {
> > + .bind = mtk_disp_ovlsys_adaptor_master_bind,
> > + .unbind =
> > mtk_disp_ovlsys_adaptor_master_unbind,
> > +};
> > +
> > +static const struct mtk_disp_ovlsys_adaptor
> > mt8196_ovlsys_adaptor_driver_data = {
> > + .max_size = 8191,
>
> This is the first SoC has ovlsys, so it's not necessary to has driver
> data.
> After other SoC ovlsys is added, then consider to add driver data.
> So,
>
> #define OVLSYS_MAX_SIZE 8191
>
> > +};
> > +
> > +static int mtk_disp_ovlsys_adaptor_probe(struct platform_device
> > *pdev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv;
> > + struct device *dev = &pdev->dev;
> > + struct component_match *match = NULL;
> > + struct mtk_drm_ovlsys_private *ovlsys_priv;
> > + int ret;
> > +
> > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > + if (!priv)
> > + return -ENOMEM;
> > +
> > + platform_set_drvdata(pdev, priv);
> > +
> > + ovlsys_priv = pdev->dev.platform_data;
> > + priv->mmsys_dev = ovlsys_priv->mmsys_dev;
> > + priv->max_size =
> > mt8196_ovlsys_adaptor_driver_data.max_size;
> > +
> > + if (ovlsys_priv->use_path == 0) {
> > + priv->path = mt8196_mtk_ovl_main;
> > + priv->path_size = ARRAY_SIZE(mt8196_mtk_ovl_main);
> > + } else if (ovlsys_priv->use_path == 1) {
> > + priv->path = mt8196_mtk_ovl_ext;
> > + priv->path_size = ARRAY_SIZE(mt8196_mtk_ovl_ext);
> > + } else {
> > + priv->path = mt8196_mtk_ovl_third;
> > + priv->path_size =
> > ARRAY_SIZE(mt8196_mtk_ovl_third);
> > + }
> > +
> > + ret = ovlsys_adaptor_comp_init(dev, &match);
> > + if (ret < 0)
> > + return ret;
> > +
> > + component_master_add_with_match(dev,
> > &mtk_disp_ovlsys_adaptor_master_ops, match);
> > +
> > + pm_runtime_enable(dev);
> > +
> > + ret = component_add(dev,
> > &mtk_disp_ovlsys_adaptor_comp_ops);
> > + if (ret != 0) {
> > + pm_runtime_disable(dev);
> > + dev_err(dev, "Failed to add component: %d\n",
> > ret);
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +static void mtk_disp_ovlsys_adaptor_remove(struct platform_device
> > *pdev)
> > +{
> > + component_master_del(&pdev->dev,
> > &mtk_disp_ovlsys_adaptor_master_ops);
> > + pm_runtime_disable(&pdev->dev);
> > +}
> > +
> > +struct platform_driver mtk_disp_ovlsys_adaptor_driver = {
> > + .probe = mtk_disp_ovlsys_adaptor_probe,
> > + .remove = mtk_disp_ovlsys_adaptor_remove,
> > + .driver = {
> > + .name = "mediatek-disp-ovlsys-adaptor",
> > + .owner = THIS_MODULE,
> > + },
> > +};
> > +
> > +MODULE_AUTHOR("Nancy Lin <nancy.lin@mediatek.com>");
> > +MODULE_DESCRIPTION("MediaTek Ovlsys Adaptor Driver");
> > +MODULE_LICENSE("GPL");
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index 27190057bd8e..7526bc38bcc7 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -448,6 +448,28 @@ static bool mtk_drm_find_mmsys_comp(struct
> > mtk_drm_private *private, int comp_id
> > return false;
> > }
> >
> > +static int mtk_drm_mmsys_comp_in_path(struct mtk_drm_private
> > *private, int comp_id)
> > +{
> > + const struct mtk_mmsys_driver_data *drv_data = private-
> > >data;
> > + int i;
> > +
> > + if (drv_data->main_path)
> > + for (i = 0; i < drv_data->main_len; i++)
> > + if (drv_data->main_path[i] == comp_id)
> > + return 0;
> > +
> > + if (drv_data->ext_path)
> > + for (i = 0; i < drv_data->ext_len; i++)
> > + if (drv_data->ext_path[i] == comp_id)
> > + return 1;
> > + if (drv_data->third_path)
> > + for (i = 0; i < drv_data->third_len; i++)
> > + if (drv_data->third_path[i] == comp_id)
> > + return 2;
> > +
> > + return -1;
> > +}
> > +
> > static int mtk_drm_kms_init(struct drm_device *drm)
> > {
> > struct mtk_drm_private *private = drm->dev_private;
> > @@ -463,8 +485,8 @@ static int mtk_drm_kms_init(struct drm_device
> > *drm)
> > if (ret)
> > goto put_mutex_dev;
> >
> > - drm->mode_config.min_width = 64;
> > - drm->mode_config.min_height = 64;
> > + drm->mode_config.min_width = 1;
> > + drm->mode_config.min_height = 1;
>
> You change other SoC setting.
> If 8196 has different setting, query min width/height from ddp
> component and separate this to another patch.
>
Ok, I will separate this to another patch.
> >
> > /*
> > * set max width and height as default value(4096x4096).
> > @@ -1107,6 +1129,40 @@ static int mtk_drm_probe(struct
> > platform_device *pdev)
> > component_match_add(dev, &match, compare_dev,
> > &ovl_adaptor->dev);
> > }
> >
> > + if (mtk_drm_find_mmsys_comp(private,
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0)) {
> > + struct mtk_drm_ovlsys_private ovlsys_priv;
> > +
> > + ovlsys_priv.mmsys_dev = private->mmsys_dev;
> > + ovlsys_priv.use_path =
> > + mtk_drm_mmsys_comp_in_path(private,
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0);
> > + ovl_adaptor =
> > + platform_device_register_data(dev,
> > "mediatek-disp-ovlsys-adaptor",
> > +
> > PLATFORM_DEVID_AUTO,
> > + (void
> > *)&ovlsys_priv,
> > +
> > sizeof(struct mtk_drm_ovlsys_private));
> > + private-
> > >ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0].dev = &ovl_adaptor-
> > >dev;
> > + mtk_ddp_comp_init(NULL, &private-
> > >ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0],
> > +
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0);
> > + component_match_add(dev, &match, compare_dev,
> > &ovl_adaptor->dev);
> > + }
> > +
> > + if (mtk_drm_find_mmsys_comp(private,
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1)) {
> > + struct mtk_drm_ovlsys_private ovlsys_priv;
> > +
> > + ovlsys_priv.mmsys_dev = private->mmsys_dev;
> > + ovlsys_priv.use_path =
> > + mtk_drm_mmsys_comp_in_path(private,
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1);
> > + ovl_adaptor =
> > + platform_device_register_data(dev,
> > "mediatek-disp-ovlsys-adaptor",
> > +
> > PLATFORM_DEVID_AUTO,
> > + (void
> > *)&ovlsys_priv,
> > +
> > sizeof(struct mtk_drm_ovlsys_private));
> > + private-
> > >ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1].dev = &ovl_adaptor-
> > >dev;
> > + mtk_ddp_comp_init(NULL, &private-
> > >ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1],
> > +
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1);
> > + component_match_add(dev, &match, compare_dev,
> > &ovl_adaptor->dev);
> > + }
> > +
> > /* Iterate over sibling DISP function blocks */
> > for_each_child_of_node(phandle->parent, node) {
> > enum mtk_ddp_comp_type comp_type;
> > @@ -1268,6 +1324,7 @@ static struct platform_driver * const
> > mtk_drm_drivers[] = {
> > &mtk_disp_outproc_driver,
> > &mtk_disp_ovl_adaptor_driver,
> > &mtk_disp_ovl_driver,
> > + &mtk_disp_ovlsys_adaptor_driver,
> > &mtk_disp_rdma_driver,
> > &mtk_dpi_driver,
> > &mtk_drm_platform_driver,
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > index c4717c37b0f1..aa17e743a1d0 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > @@ -11,7 +11,9 @@
> >
> > #define MAX_CONNECTOR 2
> > #define DDP_COMPONENT_DRM_OVL_ADAPTOR (DDP_COMPONENT_ID_MAX + 1)
> > -#define DDP_COMPONENT_DRM_ID_MAX (DDP_COMPONENT_DRM_OVL_ADAPTOR +
> > 1)
> > +#define DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0
> > (DDP_COMPONENT_DRM_OVL_ADAPTOR + 1)
> > +#define DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1
> > (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0 + 1)
> > +#define DDP_COMPONENT_DRM_ID_MAX
> > (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 + 1)
> >
> > enum mtk_crtc_path {
> > CRTC_MAIN,
> > @@ -69,6 +71,12 @@ struct mtk_drm_private {
> > struct mtk_drm_private **all_drm_private;
> > };
> >
> > +struct mtk_drm_ovlsys_private {
>
> ovlsys has its own private data structure.
> mtk_ovlsys_platform_data is better.
>
> Regards,
> CK
>
Ok, I will fix this problem.
Best, Paul
>
> > + struct device *mmsys_dev;
> > + struct device *mutex_dev;
> > + unsigned int use_path;
> > +};
> > +
> > extern struct platform_driver mtk_disp_aal_driver;
> > extern struct platform_driver mtk_disp_blender_driver;
> > extern struct platform_driver mtk_disp_ccorr_driver;
> > @@ -79,6 +87,7 @@ extern struct platform_driver
> > mtk_disp_merge_driver;
> > extern struct platform_driver mtk_disp_outproc_driver;
> > extern struct platform_driver mtk_disp_ovl_adaptor_driver;
> > extern struct platform_driver mtk_disp_ovl_driver;
> > +extern struct platform_driver mtk_disp_ovlsys_adaptor_driver;
> > extern struct platform_driver mtk_disp_rdma_driver;
> > extern struct platform_driver mtk_dpi_driver;
> > extern struct platform_driver mtk_dsi_driver;
>
WARNING: multiple messages have this Message-ID (diff)
From: "Paul-pl Chen (陳柏霖)" <Paul-pl.Chen@mediatek.com>
To: "CK Hu (胡俊光)" <ck.hu@mediatek.com>,
"robh@kernel.org" <robh@kernel.org>,
"krzk+dt@kernel.org" <krzk+dt@kernel.org>,
"conor+dt@kernel.org" <conor+dt@kernel.org>,
"chunkuang.hu@kernel.org" <chunkuang.hu@kernel.org>,
"AngeloGioacchino Del Regno"
<angelogioacchino.delregno@collabora.com>
Cc: "Sunny Shen (沈姍姍)" <Sunny.Shen@mediatek.com>,
"Singo Chang (張興國)" <Singo.Chang@mediatek.com>,
"treapking@chromium.org" <treapking@chromium.org>,
Project_Global_Chrome_Upstream_Group
<Project_Global_Chrome_Upstream_Group@mediatek.com>,
"dri-devel@lists.freedesktop.org"
<dri-devel@lists.freedesktop.org>,
"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
"Jason-JH Lin (林睿祥)" <Jason-JH.Lin@mediatek.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"Nancy Lin (林欣螢)" <Nancy.Lin@mediatek.com>,
"Xiandong Wang (王先冬)" <Xiandong.Wang@mediatek.com>,
"matthias.bgg@gmail.com" <matthias.bgg@gmail.com>,
"linux-mediatek@lists.infradead.org"
<linux-mediatek@lists.infradead.org>,
"p.zabel@pengutronix.de" <p.zabel@pengutronix.de>,
"Sirius Wang (王皓昱)" <Sirius.Wang@mediatek.com>,
"linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH 11/12] drm/mediatek: add ovlsys_adaptor support for MT8196
Date: Fri, 21 Feb 2025 12:34:10 +0000 [thread overview]
Message-ID: <90bd076d82bf2cddeb3ce578be6e7539886cfc2b.camel@mediatek.com> (raw)
In-Reply-To: <59aa3e03300ada8f47c0b5ae3a9c173eab45af7e.camel@mediatek.com>
[-- Attachment #1: Type: text/plain, Size: 38181 bytes --]
On Wed, 2025-02-12 at 07:09 +0000, CK Hu (胡俊光) wrote:
> Hi, Paul:
>
> On Fri, 2025-01-10 at 20:34 +0800, paul-pl.chen wrote:
> > From: "Nancy.Lin" <nancy.lin@mediatek.com>
> >
> > Ovlsys_adaptor is an encapsulated module designed to
> > simplify the DRM control flow. This module is composed
> > of 20 EXDMAs, 20 BLENDERs, and 12 OUTPROCs.
> > Two EXDMAs merge into one layer, allowing the module
> > to support 20 layers for 3 display paths.
> > Ovlsys_adaptor driver is integrated within the
> > mtk_ddp_comp framework.
> >
> > Signed-off-by: Nancy.Lin <nancy.lin@mediatek.com>
> > Signed-off-by: Paul-pl.Chen <paul-pl.chen@mediatek.com>
> > ---
> > drivers/gpu/drm/mediatek/Makefile | 1 +
> > drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 25 +
> > drivers/gpu/drm/mediatek/mtk_ddp_comp.h | 1 +
> > drivers/gpu/drm/mediatek/mtk_disp_drv.h | 31 +-
> > .../drm/mediatek/mtk_disp_ovlsys_adaptor.c | 758
> > ++++++++++++++++++
> > drivers/gpu/drm/mediatek/mtk_drm_drv.c | 61 +-
> > drivers/gpu/drm/mediatek/mtk_drm_drv.h | 11 +-
> > 7 files changed, 884 insertions(+), 4 deletions(-)
> > create mode 100644
> > drivers/gpu/drm/mediatek/mtk_disp_ovlsys_adaptor.c
> >
> > diff --git a/drivers/gpu/drm/mediatek/Makefile
> > b/drivers/gpu/drm/mediatek/Makefile
> >
//snip
> > +#include "mtk_disp_blender.h"
> > +#include "mtk_disp_drv.h"
> > +#include "mtk_crtc.h"
>
> Alphabetic order.
>
Ok, I will fix this part.
> > +#include "mtk_ddp_comp.h"
> > +#include "mtk_drm_drv.h"
> > +
> > +enum mtk_ovlsys_adaptor_comp_type {
> > + OVLSYS_ADAPTOR_TYPE_EXDMA = 0,
> > + OVLSYS_ADAPTOR_TYPE_BLENDER,
> > + OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > + OVLSYS_ADAPTOR_TYPE_NUM,
> > +};
> > +
> > +enum mtk_ovlsys_adaptor_comp_id {
> > + OVLSYS_ADAPTOR_EXDMA0,
> > + OVLSYS_ADAPTOR_EXDMA1,
> > + OVLSYS_ADAPTOR_EXDMA2,
> > + OVLSYS_ADAPTOR_EXDMA3,
> > + OVLSYS_ADAPTOR_EXDMA4,
> > + OVLSYS_ADAPTOR_EXDMA5,
> > + OVLSYS_ADAPTOR_EXDMA6,
> > + OVLSYS_ADAPTOR_EXDMA7,
> > + OVLSYS_ADAPTOR_EXDMA8,
> > + OVLSYS_ADAPTOR_EXDMA9,
> > + OVLSYS_ADAPTOR_EXDMA10,
> > + OVLSYS_ADAPTOR_EXDMA11,
> > + OVLSYS_ADAPTOR_EXDMA12,
> > + OVLSYS_ADAPTOR_EXDMA13,
> > + OVLSYS_ADAPTOR_EXDMA14,
> > + OVLSYS_ADAPTOR_EXDMA15,
> > + OVLSYS_ADAPTOR_EXDMA16,
> > + OVLSYS_ADAPTOR_EXDMA17,
> > + OVLSYS_ADAPTOR_EXDMA18,
> > + OVLSYS_ADAPTOR_EXDMA19,
> > + OVLSYS_ADAPTOR_BLENDER0,
> > + OVLSYS_ADAPTOR_BLENDER1,
> > + OVLSYS_ADAPTOR_BLENDER2,
> > + OVLSYS_ADAPTOR_BLENDER3,
> > + OVLSYS_ADAPTOR_BLENDER4,
> > + OVLSYS_ADAPTOR_BLENDER5,
> > + OVLSYS_ADAPTOR_BLENDER6,
> > + OVLSYS_ADAPTOR_BLENDER7,
> > + OVLSYS_ADAPTOR_BLENDER8,
> > + OVLSYS_ADAPTOR_BLENDER9,
> > + OVLSYS_ADAPTOR_BLENDER10,
> > + OVLSYS_ADAPTOR_BLENDER11,
> > + OVLSYS_ADAPTOR_BLENDER12,
> > + OVLSYS_ADAPTOR_BLENDER13,
> > + OVLSYS_ADAPTOR_BLENDER14,
> > + OVLSYS_ADAPTOR_BLENDER15,
> > + OVLSYS_ADAPTOR_BLENDER16,
> > + OVLSYS_ADAPTOR_BLENDER17,
> > + OVLSYS_ADAPTOR_BLENDER18,
> > + OVLSYS_ADAPTOR_BLENDER19,
> > + OVLSYS_ADAPTOR_OUTPROC0,
> > + OVLSYS_ADAPTOR_OUTPROC1,
> > + OVLSYS_ADAPTOR_OUTPROC2,
> > + OVLSYS_ADAPTOR_OUTPROC3,
> > + OVLSYS_ADAPTOR_OUTPROC4,
> > + OVLSYS_ADAPTOR_OUTPROC5,
> > + OVLSYS_ADAPTOR_OUTPROC6,
> > + OVLSYS_ADAPTOR_OUTPROC7,
> > + OVLSYS_ADAPTOR_OUTPROC8,
> > + OVLSYS_ADAPTOR_OUTPROC9,
> > + OVLSYS_ADAPTOR_OUTPROC10,
> > + OVLSYS_ADAPTOR_OUTPROC11,
> > + OVLSYS_ADAPTOR_ID_MAX
> > +};
> > +
> > +struct ovlsys_adaptor_comp_match {
> > + enum mtk_ovlsys_adaptor_comp_type type;
> > + int alias_id;
> > + enum mtk_ddp_comp_id comp_id;
> > +};
> > +
> > +struct mtk_disp_ovlsys_adaptor {
> > + struct device *ovl_adaptor_comp[OVLSYS_ADAPTOR_ID_MAX];
> > + struct device *mmsys_dev;
> > + const unsigned int *path;
> > + unsigned int path_size;
> > + unsigned int layer_nr;
> > + bool children_bound;
> > + unsigned int max_size;
> > +};
> > +
> > +static const char * const
> > private_comp_stem[OVLSYS_ADAPTOR_TYPE_NUM] = {
> > + [OVLSYS_ADAPTOR_TYPE_EXDMA] = "exdma",
> > + [OVLSYS_ADAPTOR_TYPE_BLENDER] = "blender",
> > + [OVLSYS_ADAPTOR_TYPE_OUTPROC] = "outproc",
> > +};
> > +
> > +static const struct ovlsys_adaptor_comp_match
> > comp_matches[OVLSYS_ADAPTOR_ID_MAX] = {
> > + [OVLSYS_ADAPTOR_EXDMA0] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 0, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_EXDMA1] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 1, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_EXDMA2] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 2, DDP_COMPONENT_OVL0_EXDMA2},
> > + [OVLSYS_ADAPTOR_EXDMA3] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 3, DDP_COMPONENT_OVL0_EXDMA3},
> > + [OVLSYS_ADAPTOR_EXDMA4] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 4, DDP_COMPONENT_OVL0_EXDMA4},
> > + [OVLSYS_ADAPTOR_EXDMA5] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 5, DDP_COMPONENT_OVL0_EXDMA5},
> > + [OVLSYS_ADAPTOR_EXDMA6] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 6, DDP_COMPONENT_OVL0_EXDMA6},
> > + [OVLSYS_ADAPTOR_EXDMA7] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 7, DDP_COMPONENT_OVL0_EXDMA7},
> > + [OVLSYS_ADAPTOR_EXDMA8] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 8, DDP_COMPONENT_OVL0_EXDMA8},
> > + [OVLSYS_ADAPTOR_EXDMA9] = {
> > OVLSYS_ADAPTOR_TYPE_EXDMA, 9, DDP_COMPONENT_OVL0_EXDMA9},
> > + [OVLSYS_ADAPTOR_EXDMA10] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 10, DDP_COMPONENT_ID_MAX},
>
> EXDMA10 has no component id, so just drop OVLSYS_ADAPTOR_EXDMA10.
>
OK I will check this part.
> > + [OVLSYS_ADAPTOR_EXDMA11] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 11, DDP_COMPONENT_ID_MAX},
>
> Ditto.
>
OK I will check this part, too.
> > + [OVLSYS_ADAPTOR_EXDMA12] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 12, DDP_COMPONENT_OVL1_EXDMA2},
> > + [OVLSYS_ADAPTOR_EXDMA13] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 13, DDP_COMPONENT_OVL1_EXDMA3},
> > + [OVLSYS_ADAPTOR_EXDMA14] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 14, DDP_COMPONENT_OVL1_EXDMA4},
> > + [OVLSYS_ADAPTOR_EXDMA15] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 15, DDP_COMPONENT_OVL1_EXDMA5},
> > + [OVLSYS_ADAPTOR_EXDMA16] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 16, DDP_COMPONENT_OVL1_EXDMA6},
> > + [OVLSYS_ADAPTOR_EXDMA17] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 17, DDP_COMPONENT_OVL1_EXDMA7},
> > + [OVLSYS_ADAPTOR_EXDMA18] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 18, DDP_COMPONENT_OVL1_EXDMA8},
> > + [OVLSYS_ADAPTOR_EXDMA19] = { OVLSYS_ADAPTOR_TYPE_EXDMA,
> > 19, DDP_COMPONENT_OVL1_EXDMA9},
> > + [OVLSYS_ADAPTOR_BLENDER0] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 0, DDP_COMPONENT_ID_MAX},
>
> Ditto.
>
OK I will check this part, too.
> > + [OVLSYS_ADAPTOR_BLENDER1] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 1, DDP_COMPONENT_OVL0_BLENDER1},
> > + [OVLSYS_ADAPTOR_BLENDER2] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 2, DDP_COMPONENT_OVL0_BLENDER2},
> > + [OVLSYS_ADAPTOR_BLENDER3] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 3, DDP_COMPONENT_OVL0_BLENDER3},
> > + [OVLSYS_ADAPTOR_BLENDER4] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 4, DDP_COMPONENT_OVL0_BLENDER4},
> > + [OVLSYS_ADAPTOR_BLENDER5] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 5, DDP_COMPONENT_OVL0_BLENDER5},
> > + [OVLSYS_ADAPTOR_BLENDER6] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 6, DDP_COMPONENT_OVL0_BLENDER6},
> > + [OVLSYS_ADAPTOR_BLENDER7] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 7, DDP_COMPONENT_OVL0_BLENDER7},
> > + [OVLSYS_ADAPTOR_BLENDER8] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 8, DDP_COMPONENT_OVL0_BLENDER8},
> > + [OVLSYS_ADAPTOR_BLENDER9] = { OVLSYS_ADAPTOR_TYPE_BLENDER,
> > 9, DDP_COMPONENT_OVL0_BLENDER9},
> > + [OVLSYS_ADAPTOR_BLENDER10] = {
> > OVLSYS_ADAPTOR_TYPE_BLENDER, 10, DDP_COMPONENT_ID_MAX},
>
> Ditto.
>
OK I will check this part, too.
> > + [OVLSYS_ADAPTOR_BLENDER11] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 11,
> > DDP_COMPONENT_OVL1_BLENDER1},
> > + [OVLSYS_ADAPTOR_BLENDER12] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 12,
> > DDP_COMPONENT_OVL1_BLENDER2},
> > + [OVLSYS_ADAPTOR_BLENDER13] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 13,
> > DDP_COMPONENT_OVL1_BLENDER3},
> > + [OVLSYS_ADAPTOR_BLENDER14] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 14,
> > DDP_COMPONENT_OVL1_BLENDER4},
> > + [OVLSYS_ADAPTOR_BLENDER15] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 15,
> > DDP_COMPONENT_OVL1_BLENDER5},
> > + [OVLSYS_ADAPTOR_BLENDER16] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 16,
> > DDP_COMPONENT_OVL1_BLENDER6},
> > + [OVLSYS_ADAPTOR_BLENDER17] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 17,
> > DDP_COMPONENT_OVL1_BLENDER7},
> > + [OVLSYS_ADAPTOR_BLENDER18] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 18,
> > DDP_COMPONENT_OVL1_BLENDER8},
> > + [OVLSYS_ADAPTOR_BLENDER19] = {
> > + OVLSYS_ADAPTOR_TYPE_BLENDER, 19,
> > DDP_COMPONENT_OVL1_BLENDER9},
> > + [OVLSYS_ADAPTOR_OUTPROC0] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 0, DDP_COMPONENT_OVL0_OUTPROC0},
> > + [OVLSYS_ADAPTOR_OUTPROC1] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 1, DDP_COMPONENT_OVL0_OUTPROC1},
> > + [OVLSYS_ADAPTOR_OUTPROC2] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 2, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC3] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 3, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC4] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 4, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC5] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 5, DDP_COMPONENT_ID_MAX},
>
> Ditto.
>
OK I will check this part, too.
> > + [OVLSYS_ADAPTOR_OUTPROC6] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 6, DDP_COMPONENT_OVL1_OUTPROC0},
> > + [OVLSYS_ADAPTOR_OUTPROC7] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 7, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC8] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 8, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC9] = { OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > 9, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC10] = {
> > OVLSYS_ADAPTOR_TYPE_OUTPROC, 10, DDP_COMPONENT_ID_MAX},
> > + [OVLSYS_ADAPTOR_OUTPROC11] = {
> > OVLSYS_ADAPTOR_TYPE_OUTPROC, 11, DDP_COMPONENT_ID_MAX},
>
> Ditto.
>
OK I will check this part, too.
> > +};
> > +
> > +static const unsigned int mt8196_mtk_ovl_main[] = {
> > + OVLSYS_ADAPTOR_EXDMA2,
> > + OVLSYS_ADAPTOR_BLENDER1,
> > + OVLSYS_ADAPTOR_EXDMA3,
> > + OVLSYS_ADAPTOR_BLENDER2,
> > + OVLSYS_ADAPTOR_EXDMA4,
> > + OVLSYS_ADAPTOR_BLENDER3,
> > + OVLSYS_ADAPTOR_EXDMA5,
> > + OVLSYS_ADAPTOR_BLENDER4,
> > + OVLSYS_ADAPTOR_OUTPROC0,
> > +};
> > +
> > +static const unsigned int mt8196_mtk_ovl_ext[] = {
> > + OVLSYS_ADAPTOR_EXDMA6,
> > + OVLSYS_ADAPTOR_BLENDER5,
> > + OVLSYS_ADAPTOR_EXDMA7,
> > + OVLSYS_ADAPTOR_BLENDER6,
> > + OVLSYS_ADAPTOR_EXDMA8,
> > + OVLSYS_ADAPTOR_BLENDER7,
> > + OVLSYS_ADAPTOR_EXDMA9,
> > + OVLSYS_ADAPTOR_BLENDER8,
> > + OVLSYS_ADAPTOR_OUTPROC1,
> > +};
> > +
> > +static const unsigned int mt8196_mtk_ovl_third[] = {
> > + OVLSYS_ADAPTOR_EXDMA12,
> > + OVLSYS_ADAPTOR_BLENDER11,
> > + OVLSYS_ADAPTOR_EXDMA13,
> > + OVLSYS_ADAPTOR_BLENDER12,
> > + OVLSYS_ADAPTOR_EXDMA14,
> > + OVLSYS_ADAPTOR_BLENDER13,
> > + OVLSYS_ADAPTOR_EXDMA15,
> > + OVLSYS_ADAPTOR_BLENDER14,
> > + OVLSYS_ADAPTOR_OUTPROC6,
> > +};
> > +
> > +static enum mtk_ovlsys_adaptor_comp_type get_type(enum
> > mtk_ovlsys_adaptor_comp_id id)
> > +{
> > + return comp_matches[id].type;
> > +}
> > +
> > +static enum mtk_ddp_comp_id get_ddp_comp_id(enum
> > mtk_ovlsys_adaptor_comp_id id)
> > +{
> > + return comp_matches[id].comp_id;
> > +}
> > +
> > +static struct device *get_comp_by_type_idx(struct device *dev,
> > + enum
> > mtk_ovlsys_adaptor_comp_type type,
> > + unsigned int idx)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > + int count = 0;
> > +
> > + for (i = 0; i < priv->path_size; i++) {
> > + if (get_type(priv->path[i]) == type) {
> > + if (count == idx)
> > + return priv-
> > >ovl_adaptor_comp[priv->path[i]];
> > + count++;
> > + }
> > + }
> > + return NULL;
> > +}
> > +
> > +void mtk_ovlsys_adaptor_layer_config(struct device *dev, unsigned
> > int idx,
> > + struct mtk_plane_state
> > *state,
> > + struct cmdq_pkt *cmdq_pkt)
> > +{
> > + struct mtk_plane_pending_state *pending = &state->pending;
> > + struct device *exdma;
> > + struct device *blender;
> > + unsigned int align_width = 0;
> > + const struct drm_format_info *fmt_info =
> > drm_format_info(pending->format);
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + dev_dbg(dev, "%s+ idx:%d, enable:%d, fmt:0x%x\n",
> > __func__, idx,
> > + pending->enable, pending->format);
> > + dev_dbg(dev, "addr 0x%pad, fb w:%d, {%d,%d,%d,%d}\n",
> > + &pending->addr, (pending->pitch / fmt_info-
> > >cpp[0]),
> > + pending->x, pending->y, pending->width, pending-
> > >height);
> > +
> > + exdma = get_comp_by_type_idx(dev,
> > OVLSYS_ADAPTOR_TYPE_EXDMA, idx);
> > + blender = get_comp_by_type_idx(dev,
> > OVLSYS_ADAPTOR_TYPE_BLENDER, idx);
> > +
> > + /* OVLSYS is in 1T2P domain, width needs to be 2 pixels
> > align */
> > + align_width = ALIGN_DOWN(pending->width, 2);
>
> align_width is useless, so drop it.
>
> > +
> > + if (!pending->enable || pending->height == 0 ||
> > align_width == 0 ||
> > + pending->x > priv->max_size || pending->y > priv-
> > >max_size) {
> > + pending->enable = false;
> > + mtk_disp_exdma_stop(exdma, cmdq_pkt);
> > + mtk_disp_blender_layer_config(blender, state,
> > cmdq_pkt);
> > + return;
> > + }
> > +
> > + mtk_disp_exdma_config(exdma, state, cmdq_pkt);
>
> mtk_disp_exdma_config() does something like mtk_ovl_layer_config(),
> so I would like to rename it to mtk_disp_exdma_layer_config().
>
Sure, I will rename the function name.
> > +
> > + mtk_disp_blender_layer_config(blender, state, cmdq_pkt);
> > +
> > + mtk_disp_exdma_start(exdma, cmdq_pkt);
>
> Why call start in layer config?
> start should be called in start.
>
Sure, I will fix the order of setting.
> > + mtk_disp_blender_start(blender, cmdq_pkt);
>
> Ditto.
OK I will check this part, too.
>
> > +}
> > +
> > +void mtk_ovlsys_adaptor_config(struct device *dev, unsigned int w,
> > + unsigned int h, unsigned int
> > vrefresh,
> > + unsigned int bpc, struct cmdq_pkt
> > *cmdq_pkt)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > + int blender_idx = 0;
> > +
> > + for (i = 0; i < priv->path_size; i++) {
> > + enum mtk_disp_blender_layer blender;
> > +
> > + if (get_type(priv->path[i]) ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER) {
> > + blender_idx++;
> > + if (priv->layer_nr == 1)
> > + blender = SINGLE_BLENDER;
> > + else if (blender_idx == 1)
> > + blender = FIRST_BLENDER;
> > + else if (blender_idx == priv->layer_nr)
> > + blender = LAST_BLENDER;
> > + else
> > + blender = OTHERS;
> > +
> > + mtk_disp_blender_config(priv-
> > >ovl_adaptor_comp[priv->path[i]], w, h,
> > + vrefresh, bpc,
> > blender, cmdq_pkt);
>
> mtk_disp_blender_config(priv->ovl_adaptor_comp[priv->path[i]], w, h,
> vrefresh, bpc, blender_idx == 1, blender_idx
> == priv->layer_nr, cmdq_pkt);
>
> > + } else if (get_type(priv->path[i]) ==
> > OVLSYS_ADAPTOR_TYPE_OUTPROC) {
> > + mtk_disp_outproc_config(priv-
> > >ovl_adaptor_comp[priv->path[i]], w, h,
> > + vrefresh, bpc,
> > cmdq_pkt);
> > + }
> > + }
> > +}
> > +
> > +int mtk_ovlsys_adaptor_layer_check(struct device *dev,
> > + unsigned int idx,
> > + struct mtk_plane_state
> > *mtk_state)
> > +{
> > + struct drm_plane_state *state = &mtk_state->base;
> > +
> > + /* Check if any unsupported rotation is set */
> > + if (state->rotation & ~DRM_MODE_ROTATE_0)
> > + return -EINVAL;
> > +
> > + return 0;
> > +}
> > +
> > +void mtk_ovlsys_adaptor_start(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > +
> > + for (i = 0; i < priv->path_size; i++) {
> > + if (get_type(priv->path[i]) ==
> > OVLSYS_ADAPTOR_TYPE_EXDMA)
> > + mtk_disp_exdma_start(priv-
> > >ovl_adaptor_comp[priv->path[i]], NULL);
>
> The start never use cmdq, so remove the cmdq parameter.
Ok, I will fix this part.
>
> > + else if (get_type(priv->path[i]) ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER)
> > + mtk_disp_blender_start(priv-
> > >ovl_adaptor_comp[priv->path[i]], NULL);
>
> Ditto.
>
Ok, I will fix this part.> > + else
> > + mtk_disp_outproc_start(priv-
> > >ovl_adaptor_comp[priv->path[i]]);
> > + }
> > +}
> > +
> > +void mtk_ovlsys_adaptor_stop(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > +
> > + for (i = 0; i < priv->path_size; i++) {
> > + if (get_type(priv->path[i]) ==
> > OVLSYS_ADAPTOR_TYPE_EXDMA)
> > + mtk_disp_exdma_stop(priv-
> > >ovl_adaptor_comp[priv->path[i]], NULL);
>
> Ditto.
Ok, I will fix this part.th.
>
> > + else if (get_type(priv->path[i]) ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER)
> > + mtk_disp_blender_stop(priv-
> > >ovl_adaptor_comp[priv->path[i]], NULL);
>
> Ditto.
Ok, I will fix this part.
>
> > + else
> > + mtk_disp_outproc_stop(priv-
> > >ovl_adaptor_comp[priv->path[i]]);
> > + }
> > +}
> > +
> > +int mtk_ovlsys_adaptor_clk_enable(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + struct device *comp;
> > + int ret;
> > + int i;
> > +
> > + for (i = 0; i < OVLSYS_ADAPTOR_ID_MAX; i++) {
> > + comp = priv->ovl_adaptor_comp[i];
> > +
> > + if (!comp)
> > + continue;
> > +
> > + if (get_type(i) != OVLSYS_ADAPTOR_TYPE_EXDMA)
> > + continue;
> > +
> > + ret = pm_runtime_get_sync(comp);
>
> Refer to mtk_ovl_adaptor_power_on().
> This should be done in power_on() callback function.
Sure, I will align the power sequence with the function
mtk_ovl_adaptor_power_on().
>
> > + if (ret < 0) {
> > + dev_err(dev, "Failed to enable power
> > domain %d, err %d\n", i, ret);
> > + goto pwr_err;
> > + }
> > + }
> > +
> > + for (i = 0; i < OVLSYS_ADAPTOR_ID_MAX; i++) {
> > + comp = priv->ovl_adaptor_comp[i];
> > +
> > + if (!comp)
> > + continue;
> > +
> > + if (get_type(i) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> > + ret = mtk_disp_exdma_clk_enable(comp);
> > + else if (get_type(i) ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER)
> > + ret = mtk_disp_blender_clk_enable(comp);
> > + else
> > + ret = mtk_disp_outproc_clk_enable(comp);
> > +
> > + if (ret) {
> > + dev_err(dev, "Failed to enable clock %d,
> > err %d\n", i, ret);
> > + goto clk_err;
> > + }
> > + }
> > +
> > + return ret;
> > +
> > +clk_err:
> > + while (--i >= 0) {
> > + comp = priv->ovl_adaptor_comp[i];
> > + if (!comp)
> > + continue;
> > + if (get_type(i) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> > + mtk_disp_exdma_clk_disable(comp);
> > + else if (get_type(i) ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER)
> > + mtk_disp_blender_clk_disable(comp);
> > + else
> > + mtk_disp_outproc_clk_disable(comp);
> > + }
> > + i = OVLSYS_ADAPTOR_BLENDER0;
> > +
> > +pwr_err:
> > + while (--i >= 0) {
> > + comp = priv->ovl_adaptor_comp[i];
> > + if (!comp)
> > + continue;
> > + pm_runtime_put(priv->ovl_adaptor_comp[i]);
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +void mtk_ovlsys_adaptor_clk_disable(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + struct device *comp;
> > + int i;
> > +
> > + for (i = 0; i < OVLSYS_ADAPTOR_ID_MAX; i++) {
> > + comp = priv->ovl_adaptor_comp[i];
> > +
> > + if (!comp)
> > + continue;
> > +
> > + if (get_type(i) == OVLSYS_ADAPTOR_TYPE_EXDMA) {
> > + mtk_disp_exdma_clk_disable(comp);
> > + pm_runtime_put(comp);
> > + } else if (get_type(i) ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER) {
> > + mtk_disp_blender_clk_disable(comp);
> > + } else {
> > + mtk_disp_outproc_clk_disable(comp);
> > + }
> > + }
> > +}
> > +
> > +unsigned int mtk_ovlsys_adaptor_layer_nr(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + return priv->layer_nr;
> > +}
> > +
> > +struct device *mtk_ovlsys_adaptor_dma_dev_get(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + return priv->ovl_adaptor_comp[priv->path[0]];
> > +}
> > +
> > +void mtk_ovlsys_adaptor_register_vblank_cb(struct device *dev,
> > void (*vblank_cb)(void *),
> > + void *vblank_cb_data)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + mtk_disp_outproc_register_vblank_cb(priv-
> > >ovl_adaptor_comp[priv->path[priv->path_size - 1]],
> > + vblank_cb,
> > vblank_cb_data);
> > +}
> > +
> > +void mtk_ovlsys_adaptor_unregister_vblank_cb(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + struct device *comp = priv->ovl_adaptor_comp[priv-
> > >path[priv->path_size - 1]];
> > +
> > + if (!priv->children_bound)
>
> In ovl adaptor, it does not check this. So remove this checking.
This is because of the mt8916's new hardwarew design.
ovlsys adaptor have to find the possible path.
>
> > + return;
> > +
> > + mtk_disp_outproc_unregister_vblank_cb(comp);
> > +}
> > +
> > +void mtk_ovlsys_adaptor_enable_vblank(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + mtk_disp_outproc_enable_vblank(priv-
> > >ovl_adaptor_comp[priv->path[priv->path_size - 1]]);
> > +}
> > +
> > +void mtk_ovlsys_adaptor_disable_vblank(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + mtk_disp_outproc_disable_vblank(priv-
> > >ovl_adaptor_comp[priv->path[priv->path_size - 1]]);
> > +}
> > +
> > +const u32 *mtk_ovlsys_adaptor_get_formats(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + return mtk_disp_exdma_get_formats(priv-
> > >ovl_adaptor_comp[priv->path[0]]);
> > +}
> > +
> > +size_t mtk_ovlsys_adaptor_get_num_formats(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + return mtk_disp_exdma_get_num_formats(priv-
> > >ovl_adaptor_comp[priv->path[0]]);
> > +}
> > +
> > +void mtk_ovlsys_adaptor_add_comp(struct device *dev, struct
> > mtk_mutex *mutex)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > +
> > + for (i = 0; i < priv->path_size; i++)
> > + mtk_mutex_add_comp(mutex, get_ddp_comp_id(priv-
> > >path[i]));
> > +}
> > +
> > +void mtk_ovlsys_adaptor_remove_comp(struct device *dev, struct
> > mtk_mutex *mutex)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > +
> > + for (i = 0; i < priv->path_size; i++)
> > + mtk_mutex_remove_comp(mutex, get_ddp_comp_id(priv-
> > >path[i]));
> > +}
> > +
> > +void mtk_ovlsys_adaptor_connect(struct device *dev, struct device
> > *mmsys_dev, unsigned int next)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > +
> > + for (i = 0; i < priv->path_size - 1; i++)
> > + mtk_mmsys_ddp_connect(mmsys_dev,
> > get_ddp_comp_id(priv->path[i]),
> > + get_ddp_comp_id(priv->path[i
> > + 1]));
> > +
> > + mtk_mmsys_ddp_connect(mmsys_dev, get_ddp_comp_id(priv-
> > >path[i]), next);
> > +}
> > +
> > +void mtk_ovlsys_adaptor_disconnect(struct device *dev, struct
> > device *mmsys_dev, unsigned int next)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int i;
> > +
> > + for (i = 0; i < priv->path_size - 1; i++)
> > + mtk_mmsys_ddp_disconnect(mmsys_dev,
> > get_ddp_comp_id(priv->path[i]),
> > + get_ddp_comp_id(priv-
> > >path[i + 1]));
> > +
> > + mtk_mmsys_ddp_disconnect(mmsys_dev, get_ddp_comp_id(priv-
> > >path[i]), next);
> > +}
> > +
> > +static int ovlsys_adaptor_comp_get_id(struct device *dev, struct
> > device_node *node,
> > + enum
> > mtk_ovlsys_adaptor_comp_type type,
> > + enum mtk_ddp_comp_id
> > *comp_id)
> > +{
> > + int alias_id = of_alias_get_id(node,
> > private_comp_stem[type]);
> > + int i;
> > +
> > + for (i = 0; i < ARRAY_SIZE(comp_matches); i++)
> > + if (comp_matches[i].type == type &&
> > + comp_matches[i].alias_id == alias_id) {
> > + *comp_id = comp_matches[i].comp_id;
> > + return i;
> > + }
> > + dev_warn(dev, "Failed to get id. type: %d, alias: %d\n",
> > type, alias_id);
> > + return -EINVAL;
> > +}
> > +
> > +static const struct of_device_id mtk_ovlsys_adaptor_comp_dt_ids[]
> > = {
> > + {
> > + .compatible = "mediatek,mt8196-exdma",
> > + .data = (void *)OVLSYS_ADAPTOR_TYPE_EXDMA,
> > + }, {
> > + .compatible = "mediatek,mt8196-blender",
> > + .data = (void *)OVLSYS_ADAPTOR_TYPE_BLENDER,
> > + }, {
> > + .compatible = "mediatek,mt8196-outproc",
> > + .data = (void *)OVLSYS_ADAPTOR_TYPE_OUTPROC,
> > + },
> > + {},
> > +};
> > +
> > +static int ovlsys_adaptor_comp_init(struct device *dev, struct
> > component_match **match)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + struct device_node *node, *parent;
> > + struct platform_device *comp_pdev;
> > + int i;
> > +
> > + parent = dev->parent->parent->of_node->parent;
> > +
> > + for_each_child_of_node(parent, node) {
> > + const struct of_device_id *of_id;
> > + enum mtk_ovlsys_adaptor_comp_type type;
> > + enum mtk_ddp_comp_id comp_id;
> > + int id;
> > + bool found = false;
> > +
> > + of_id =
> > of_match_node(mtk_ovlsys_adaptor_comp_dt_ids, node);
> > + if (!of_id)
> > + continue;
> > +
> > + if (!of_device_is_available(node)) {
> > + dev_dbg(dev, "Skipping disabled component
> > %pOF\n",
> > + node);
> > + continue;
> > + }
> > +
> > + type = (enum
> > mtk_ovlsys_adaptor_comp_type)(uintptr_t)of_id->data;
> > + id = ovlsys_adaptor_comp_get_id(dev, node, type,
> > &comp_id);
> > + if (id < 0) {
> > + dev_warn(dev, "Skipping unknown component
> > %pOF\n",
> > + node);
> > + continue;
> > + }
> > +
> > + for (i = 0; i < priv->path_size; i++)
> > + if (priv->path[i] == id)
> > + found = true;
> > +
> > + if (!found)
> > + continue;
>
> ovl adaptor does not check this, why ovlsys need this?
> If this is removed, this function is similar to the one in ovl
> adaptor,
> would you try to rewrite this function to be almost the same with the
> one in ovl adator?
> Not merging it, just implement almost the same.
This is because of the mt8916's new hardwarew design.
ovlsys adaptor have to find the possible path.
>
> > +
> > + comp_pdev = of_find_device_by_node(node);
> > + if (!comp_pdev)
> > + return -EPROBE_DEFER;
> > +
> > + priv->ovl_adaptor_comp[id] = &comp_pdev->dev;
> > +
> > + drm_of_component_match_add(dev, match,
> > component_compare_of, node);
> > + dev_dbg(dev, "Adding component match for %pOF\n",
> > node);
> > + }
> > +
> > + if (!*match) {
> > + dev_err(dev, "No match device for
> > ovlsys_adaptor\n");
> > + return -ENODEV;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int mtk_disp_ovlsys_adaptor_comp_bind(struct device *dev,
> > struct device *master,
> > + void *data)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + if (!priv->children_bound)
> > + return -EPROBE_DEFER;
> > +
> > + return 0;
> > +}
> > +
> > +static void mtk_disp_ovlsys_adaptor_comp_unbind(struct device
> > *dev, struct device *master,
> > + void *data)
> > +{
> > +}
> > +
> > +static const struct component_ops mtk_disp_ovlsys_adaptor_comp_ops
> > = {
> > + .bind = mtk_disp_ovlsys_adaptor_comp_bind,
> > + .unbind = mtk_disp_ovlsys_adaptor_comp_unbind,
> > +};
> > +
> > +static int mtk_disp_ovlsys_adaptor_master_bind(struct device *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > + int ret, i;
> > + unsigned int layer_nr = 0;
> > +
> > + ret = component_bind_all(dev, priv->mmsys_dev);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "component_bind_all
> > failed!\n");
> > +
> > + priv->children_bound = true;
> > +
> > + for (i = 0; i < priv->path_size; i++)
> > + if (comp_matches[priv->path[i]].type ==
> > OVLSYS_ADAPTOR_TYPE_BLENDER)
> > + layer_nr++;
> > + priv->layer_nr = layer_nr;
> > +
> > + return 0;
> > +}
> > +
> > +static void mtk_disp_ovlsys_adaptor_master_unbind(struct device
> > *dev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv =
> > dev_get_drvdata(dev);
> > +
> > + priv->children_bound = false;
> > +}
> > +
> > +static const struct component_master_ops
> > mtk_disp_ovlsys_adaptor_master_ops = {
> > + .bind = mtk_disp_ovlsys_adaptor_master_bind,
> > + .unbind =
> > mtk_disp_ovlsys_adaptor_master_unbind,
> > +};
> > +
> > +static const struct mtk_disp_ovlsys_adaptor
> > mt8196_ovlsys_adaptor_driver_data = {
> > + .max_size = 8191,
>
> This is the first SoC has ovlsys, so it's not necessary to has driver
> data.
> After other SoC ovlsys is added, then consider to add driver data.
> So,
>
> #define OVLSYS_MAX_SIZE 8191
>
> > +};
> > +
> > +static int mtk_disp_ovlsys_adaptor_probe(struct platform_device
> > *pdev)
> > +{
> > + struct mtk_disp_ovlsys_adaptor *priv;
> > + struct device *dev = &pdev->dev;
> > + struct component_match *match = NULL;
> > + struct mtk_drm_ovlsys_private *ovlsys_priv;
> > + int ret;
> > +
> > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > + if (!priv)
> > + return -ENOMEM;
> > +
> > + platform_set_drvdata(pdev, priv);
> > +
> > + ovlsys_priv = pdev->dev.platform_data;
> > + priv->mmsys_dev = ovlsys_priv->mmsys_dev;
> > + priv->max_size =
> > mt8196_ovlsys_adaptor_driver_data.max_size;
> > +
> > + if (ovlsys_priv->use_path == 0) {
> > + priv->path = mt8196_mtk_ovl_main;
> > + priv->path_size = ARRAY_SIZE(mt8196_mtk_ovl_main);
> > + } else if (ovlsys_priv->use_path == 1) {
> > + priv->path = mt8196_mtk_ovl_ext;
> > + priv->path_size = ARRAY_SIZE(mt8196_mtk_ovl_ext);
> > + } else {
> > + priv->path = mt8196_mtk_ovl_third;
> > + priv->path_size =
> > ARRAY_SIZE(mt8196_mtk_ovl_third);
> > + }
> > +
> > + ret = ovlsys_adaptor_comp_init(dev, &match);
> > + if (ret < 0)
> > + return ret;
> > +
> > + component_master_add_with_match(dev,
> > &mtk_disp_ovlsys_adaptor_master_ops, match);
> > +
> > + pm_runtime_enable(dev);
> > +
> > + ret = component_add(dev,
> > &mtk_disp_ovlsys_adaptor_comp_ops);
> > + if (ret != 0) {
> > + pm_runtime_disable(dev);
> > + dev_err(dev, "Failed to add component: %d\n",
> > ret);
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +static void mtk_disp_ovlsys_adaptor_remove(struct platform_device
> > *pdev)
> > +{
> > + component_master_del(&pdev->dev,
> > &mtk_disp_ovlsys_adaptor_master_ops);
> > + pm_runtime_disable(&pdev->dev);
> > +}
> > +
> > +struct platform_driver mtk_disp_ovlsys_adaptor_driver = {
> > + .probe = mtk_disp_ovlsys_adaptor_probe,
> > + .remove = mtk_disp_ovlsys_adaptor_remove,
> > + .driver = {
> > + .name = "mediatek-disp-ovlsys-adaptor",
> > + .owner = THIS_MODULE,
> > + },
> > +};
> > +
> > +MODULE_AUTHOR("Nancy Lin <nancy.lin@mediatek.com>");
> > +MODULE_DESCRIPTION("MediaTek Ovlsys Adaptor Driver");
> > +MODULE_LICENSE("GPL");
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index 27190057bd8e..7526bc38bcc7 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -448,6 +448,28 @@ static bool mtk_drm_find_mmsys_comp(struct
> > mtk_drm_private *private, int comp_id
> > return false;
> > }
> >
> > +static int mtk_drm_mmsys_comp_in_path(struct mtk_drm_private
> > *private, int comp_id)
> > +{
> > + const struct mtk_mmsys_driver_data *drv_data = private-
> > >data;
> > + int i;
> > +
> > + if (drv_data->main_path)
> > + for (i = 0; i < drv_data->main_len; i++)
> > + if (drv_data->main_path[i] == comp_id)
> > + return 0;
> > +
> > + if (drv_data->ext_path)
> > + for (i = 0; i < drv_data->ext_len; i++)
> > + if (drv_data->ext_path[i] == comp_id)
> > + return 1;
> > + if (drv_data->third_path)
> > + for (i = 0; i < drv_data->third_len; i++)
> > + if (drv_data->third_path[i] == comp_id)
> > + return 2;
> > +
> > + return -1;
> > +}
> > +
> > static int mtk_drm_kms_init(struct drm_device *drm)
> > {
> > struct mtk_drm_private *private = drm->dev_private;
> > @@ -463,8 +485,8 @@ static int mtk_drm_kms_init(struct drm_device
> > *drm)
> > if (ret)
> > goto put_mutex_dev;
> >
> > - drm->mode_config.min_width = 64;
> > - drm->mode_config.min_height = 64;
> > + drm->mode_config.min_width = 1;
> > + drm->mode_config.min_height = 1;
>
> You change other SoC setting.
> If 8196 has different setting, query min width/height from ddp
> component and separate this to another patch.
>
Ok, I will separate this to another patch.
> >
> > /*
> > * set max width and height as default value(4096x4096).
> > @@ -1107,6 +1129,40 @@ static int mtk_drm_probe(struct
> > platform_device *pdev)
> > component_match_add(dev, &match, compare_dev,
> > &ovl_adaptor->dev);
> > }
> >
> > + if (mtk_drm_find_mmsys_comp(private,
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0)) {
> > + struct mtk_drm_ovlsys_private ovlsys_priv;
> > +
> > + ovlsys_priv.mmsys_dev = private->mmsys_dev;
> > + ovlsys_priv.use_path =
> > + mtk_drm_mmsys_comp_in_path(private,
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0);
> > + ovl_adaptor =
> > + platform_device_register_data(dev,
> > "mediatek-disp-ovlsys-adaptor",
> > +
> > PLATFORM_DEVID_AUTO,
> > + (void
> > *)&ovlsys_priv,
> > +
> > sizeof(struct mtk_drm_ovlsys_private));
> > + private-
> > >ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0].dev = &ovl_adaptor-
> > >dev;
> > + mtk_ddp_comp_init(NULL, &private-
> > >ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0],
> > +
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0);
> > + component_match_add(dev, &match, compare_dev,
> > &ovl_adaptor->dev);
> > + }
> > +
> > + if (mtk_drm_find_mmsys_comp(private,
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1)) {
> > + struct mtk_drm_ovlsys_private ovlsys_priv;
> > +
> > + ovlsys_priv.mmsys_dev = private->mmsys_dev;
> > + ovlsys_priv.use_path =
> > + mtk_drm_mmsys_comp_in_path(private,
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1);
> > + ovl_adaptor =
> > + platform_device_register_data(dev,
> > "mediatek-disp-ovlsys-adaptor",
> > +
> > PLATFORM_DEVID_AUTO,
> > + (void
> > *)&ovlsys_priv,
> > +
> > sizeof(struct mtk_drm_ovlsys_private));
> > + private-
> > >ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1].dev = &ovl_adaptor-
> > >dev;
> > + mtk_ddp_comp_init(NULL, &private-
> > >ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1],
> > +
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1);
> > + component_match_add(dev, &match, compare_dev,
> > &ovl_adaptor->dev);
> > + }
> > +
> > /* Iterate over sibling DISP function blocks */
> > for_each_child_of_node(phandle->parent, node) {
> > enum mtk_ddp_comp_type comp_type;
> > @@ -1268,6 +1324,7 @@ static struct platform_driver * const
> > mtk_drm_drivers[] = {
> > &mtk_disp_outproc_driver,
> > &mtk_disp_ovl_adaptor_driver,
> > &mtk_disp_ovl_driver,
> > + &mtk_disp_ovlsys_adaptor_driver,
> > &mtk_disp_rdma_driver,
> > &mtk_dpi_driver,
> > &mtk_drm_platform_driver,
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > index c4717c37b0f1..aa17e743a1d0 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > @@ -11,7 +11,9 @@
> >
> > #define MAX_CONNECTOR 2
> > #define DDP_COMPONENT_DRM_OVL_ADAPTOR (DDP_COMPONENT_ID_MAX + 1)
> > -#define DDP_COMPONENT_DRM_ID_MAX (DDP_COMPONENT_DRM_OVL_ADAPTOR +
> > 1)
> > +#define DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0
> > (DDP_COMPONENT_DRM_OVL_ADAPTOR + 1)
> > +#define DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1
> > (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0 + 1)
> > +#define DDP_COMPONENT_DRM_ID_MAX
> > (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 + 1)
> >
> > enum mtk_crtc_path {
> > CRTC_MAIN,
> > @@ -69,6 +71,12 @@ struct mtk_drm_private {
> > struct mtk_drm_private **all_drm_private;
> > };
> >
> > +struct mtk_drm_ovlsys_private {
>
> ovlsys has its own private data structure.
> mtk_ovlsys_platform_data is better.
>
> Regards,
> CK
>
Ok, I will fix this problem.
Best, Paul
>
> > + struct device *mmsys_dev;
> > + struct device *mutex_dev;
> > + unsigned int use_path;
> > +};
> > +
> > extern struct platform_driver mtk_disp_aal_driver;
> > extern struct platform_driver mtk_disp_blender_driver;
> > extern struct platform_driver mtk_disp_ccorr_driver;
> > @@ -79,6 +87,7 @@ extern struct platform_driver
> > mtk_disp_merge_driver;
> > extern struct platform_driver mtk_disp_outproc_driver;
> > extern struct platform_driver mtk_disp_ovl_adaptor_driver;
> > extern struct platform_driver mtk_disp_ovl_driver;
> > +extern struct platform_driver mtk_disp_ovlsys_adaptor_driver;
> > extern struct platform_driver mtk_disp_rdma_driver;
> > extern struct platform_driver mtk_dpi_driver;
> > extern struct platform_driver mtk_dsi_driver;
>
[-- Attachment #2: Type: text/html, Size: 63341 bytes --]
next prev parent reply other threads:[~2025-02-21 12:36 UTC|newest]
Thread overview: 108+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-10 12:33 [PATCH 00/12] Add Mediatek Soc DRM support for mt8196 paul-pl.chen
2025-01-10 12:33 ` paul-pl.chen
2025-01-10 12:33 ` [PATCH 01/12] dt-bindings: arm: mediatek: mmsys: add compatible for MT8196 paul-pl.chen
2025-01-10 12:33 ` paul-pl.chen
2025-01-10 12:58 ` Krzysztof Kozlowski
2025-01-10 12:58 ` Krzysztof Kozlowski
2025-01-13 11:25 ` Fei Shao
2025-01-13 11:30 ` Krzysztof Kozlowski
2025-01-15 9:18 ` Paul-pl Chen (陳柏霖)
2025-01-15 9:18 ` Paul-pl Chen (陳柏霖)
2025-01-15 9:18 ` Paul-pl Chen (陳柏霖)
2025-01-10 12:33 ` [PATCH 02/12] dt-bindings: soc: mediatek: add mutex yaml " paul-pl.chen
2025-01-10 12:33 ` paul-pl.chen
2025-01-10 12:33 ` [PATCH 03/12] dt-bindings: display: mediatek: add EXDMA " paul-pl.chen
2025-01-10 12:33 ` paul-pl.chen
2025-01-10 13:01 ` Krzysztof Kozlowski
2025-01-10 13:01 ` Krzysztof Kozlowski
2025-01-17 10:36 ` Paul-pl Chen (陳柏霖)
2025-01-17 10:36 ` Paul-pl Chen (陳柏霖)
2025-01-17 10:36 ` Paul-pl Chen (陳柏霖)
2025-01-18 8:37 ` Krzysztof Kozlowski
2025-01-18 8:37 ` Krzysztof Kozlowski
2025-01-21 17:07 ` Paul-pl Chen (陳柏霖)
2025-01-21 17:07 ` Paul-pl Chen (陳柏霖)
2025-01-21 17:07 ` Paul-pl Chen (陳柏霖)
2025-02-11 8:23 ` Paul-pl Chen (陳柏霖)
2025-02-11 8:23 ` Paul-pl Chen (陳柏霖)
2025-02-11 8:23 ` Paul-pl Chen (陳柏霖)
2025-02-12 5:40 ` Krzysztof Kozlowski
2025-02-12 5:40 ` Krzysztof Kozlowski
2025-01-10 12:33 ` paul-pl.chen
2025-01-10 12:33 ` paul-pl.chen
2025-01-10 13:54 ` Rob Herring (Arm)
2025-01-10 13:54 ` Rob Herring (Arm)
2025-01-14 5:49 ` Paul-pl Chen (陳柏霖)
2025-01-14 5:49 ` Paul-pl Chen (陳柏霖)
2025-01-14 5:49 ` Paul-pl Chen (陳柏霖)
2025-01-14 10:34 ` AngeloGioacchino Del Regno
2025-01-14 10:34 ` AngeloGioacchino Del Regno
2025-01-15 12:13 ` Paul-pl Chen (陳柏霖)
2025-01-15 12:13 ` Paul-pl Chen (陳柏霖)
2025-01-15 12:13 ` Paul-pl Chen (陳柏霖)
2025-01-18 9:22 ` Krzysztof Kozlowski
2025-01-18 9:22 ` Krzysztof Kozlowski
2025-01-21 17:14 ` Paul-pl Chen (陳柏霖)
2025-01-21 17:14 ` Paul-pl Chen (陳柏霖)
2025-01-21 17:14 ` Paul-pl Chen (陳柏霖)
2025-01-23 6:11 ` Paul-pl Chen (陳柏霖)
2025-01-23 6:11 ` Paul-pl Chen (陳柏霖)
2025-01-23 6:11 ` Paul-pl Chen (陳柏霖)
2025-01-23 6:25 ` Chen-Yu Tsai
2025-01-23 6:25 ` Chen-Yu Tsai
2025-01-23 16:09 ` Paul-pl Chen (陳柏霖)
2025-01-23 16:09 ` Paul-pl Chen (陳柏霖)
2025-01-23 16:09 ` Paul-pl Chen (陳柏霖)
2025-01-23 7:21 ` Krzysztof Kozlowski
2025-01-23 7:21 ` Krzysztof Kozlowski
2025-01-23 16:14 ` Paul-pl Chen (陳柏霖)
2025-01-23 16:14 ` Paul-pl Chen (陳柏霖)
2025-01-23 16:14 ` Paul-pl Chen (陳柏霖)
2025-01-23 16:20 ` Chen-Yu Tsai
2025-01-23 16:20 ` Chen-Yu Tsai
2025-01-10 12:34 ` [PATCH 04/12] dt-bindings: display: mediatek: add BLENDER " paul-pl.chen
2025-01-10 12:34 ` paul-pl.chen
2025-01-10 13:54 ` Rob Herring (Arm)
2025-01-10 13:54 ` Rob Herring (Arm)
2025-01-10 12:34 ` [PATCH 05/12] dt-bindings: display: mediatek: add OUTPROC " paul-pl.chen
2025-01-10 12:34 ` paul-pl.chen
2025-01-10 13:54 ` Rob Herring (Arm)
2025-01-10 13:54 ` Rob Herring (Arm)
2025-01-10 12:34 ` [PATCH 06/12] soc: mediatek: add mmsys support " paul-pl.chen
2025-01-10 12:34 ` paul-pl.chen
2025-01-10 12:34 ` [PATCH 07/12] soc: mediatek: mutex: add mutex " paul-pl.chen
2025-01-10 12:34 ` paul-pl.chen
2025-01-20 8:04 ` Chen-Yu Tsai
2025-01-10 12:34 ` [PATCH 08/12] drm/mediatek: add EXDMA " paul-pl.chen
2025-01-10 12:34 ` paul-pl.chen
2025-01-16 1:45 ` CK Hu (胡俊光)
2025-01-16 1:45 ` CK Hu (胡俊光)
2025-01-20 9:54 ` Chen-Yu Tsai
2025-01-10 12:34 ` [PATCH 09/12] drm/mediatek: add BLENDER " paul-pl.chen
2025-01-10 12:34 ` paul-pl.chen
2025-02-12 3:45 ` CK Hu (胡俊光)
2025-02-12 3:45 ` CK Hu (胡俊光)
2025-02-20 10:11 ` Paul-pl Chen (陳柏霖)
2025-01-10 12:34 ` [PATCH 10/12] drm/mediatek: add OUTPROC " paul-pl.chen
2025-01-10 12:34 ` paul-pl.chen
2025-02-12 4:08 ` CK Hu (胡俊光)
2025-02-12 4:08 ` CK Hu (胡俊光)
2025-02-21 11:54 ` Paul-pl Chen (陳柏霖)
2025-02-21 11:54 ` Paul-pl Chen (陳柏霖)
2025-01-10 12:34 ` [PATCH 11/12] drm/mediatek: add ovlsys_adaptor " paul-pl.chen
2025-01-10 12:34 ` paul-pl.chen
2025-02-12 7:09 ` CK Hu (胡俊光)
2025-02-12 7:09 ` CK Hu (胡俊光)
2025-02-21 12:34 ` Paul-pl Chen (陳柏霖) [this message]
2025-02-21 12:34 ` Paul-pl Chen (陳柏霖)
2025-01-10 12:34 ` [PATCH 12/12] drm/mediatek: Add support for multiple mmsys in the one mediatek-drm driver paul-pl.chen
2025-01-10 12:34 ` paul-pl.chen
2025-02-12 9:30 ` CK Hu (胡俊光)
2025-02-12 9:30 ` CK Hu (胡俊光)
2025-02-21 12:39 ` Paul-pl Chen (陳柏霖)
2025-02-21 12:39 ` Paul-pl Chen (陳柏霖)
2025-01-13 12:50 ` [PATCH 00/12] Add Mediatek Soc DRM support for mt8196 AngeloGioacchino Del Regno
2025-01-13 12:50 ` AngeloGioacchino Del Regno
2025-01-15 8:05 ` Paul-pl Chen (陳柏霖)
2025-01-15 8:05 ` Paul-pl Chen (陳柏霖)
2025-01-15 8:05 ` Paul-pl Chen (陳柏霖)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=90bd076d82bf2cddeb3ce578be6e7539886cfc2b.camel@mediatek.com \
--to=paul-pl.chen@mediatek.com \
--cc=Jason-JH.Lin@mediatek.com \
--cc=Nancy.Lin@mediatek.com \
--cc=Project_Global_Chrome_Upstream_Group@mediatek.com \
--cc=Singo.Chang@mediatek.com \
--cc=Sirius.Wang@mediatek.com \
--cc=Sunny.Shen@mediatek.com \
--cc=Xiandong.Wang@mediatek.com \
--cc=angelogioacchino.delregno@collabora.com \
--cc=chunkuang.hu@kernel.org \
--cc=ck.hu@mediatek.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=matthias.bgg@gmail.com \
--cc=p.zabel@pengutronix.de \
--cc=robh@kernel.org \
--cc=treapking@chromium.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.