<html><body><p>
<pre>
On Thu, 2025-05-15 at 17: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>
> ---
[snip]
> +
> +int mtk_ovlsys_adaptor_power_on(struct device *dev)
> +{
> +struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +struct device *comp;
> +int ret = 0;
int ret;
> +int i;
> +
> +for (i = 0; i < priv->path_size; i++) {
> +comp = priv->ovl_adaptor_comp[priv->path[i]];
> +if (!comp || get_type(priv->path[i]) != OVLSYS_ADAPTOR_TYPE_EXDMA)
> +continue;
> +
> +ret = pm_runtime_get_sync(comp);
> +if (ret < 0) {
> +dev_err(dev, "Failed to enable power domain %d, err %d\n", i, ret);
> +goto pwr_err;
> +}
> +}
> +
> +return ret;
return 0;
> +
> +pwr_err:
> +while (--i >= 0) {
> +comp = priv->ovl_adaptor_comp[i];
> +if (!comp || get_type(priv->path[i]) != OVLSYS_ADAPTOR_TYPE_EXDMA)
> +continue;
> +
> +pm_runtime_put(priv->ovl_adaptor_comp[i]);
> +}
> +
> +return ret;
> +}
> +
[snip]
> +
> +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 mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +struct device *exdma;
> +struct device *blender;
> +const struct drm_format_info *fmt_info = drm_format_info(pending->format);
> +
> +DRM_DEV_DEBUG_DRIVER(dev, "idx:%d enable:%d fmt:0x%x addr:0x%pad fb_w:%d {%d,%d,%d,%d}\n",
> + idx, pending->enable, pending->format,
> + &pending->addr, (pending->pitch / fmt_info->cpp[0]),
> + pending->x, pending->y, pending->width, pending->height);
> +
> +exdma = priv->ovl_adaptor_comp[priv->path[idx * 2]];
> +if (!exdma) {
> +dev_err(dev, "%s: exdma%d comp not found\n", __func__, idx);
> +return;
> +}
> +
> +blender = priv->ovl_adaptor_comp[priv->path[idx * 2 + 1]];
> +if (!blender) {
> +dev_err(dev, "%s: blender%d comp not found\n", __func__, idx);
> +return;
> +}
> +
> +if (pending->height == 0 || pending->width == 0 ||
> + pending->x > OVLSYS_ADAPTOR_DRIVER_DATA_MAX_SIZE ||
> + pending->y > OVLSYS_ADAPTOR_DRIVER_DATA_MAX_SIZE)
> +pending->enable = false;
In ovl_adaptor, it does not modify this.
And mtk_ethdr_layer_config() would check this again.
So align this behavior.
> +
> +mtk_disp_exdma_layer_config(exdma, state, cmdq_pkt);
> +mtk_disp_blender_layer_config(blender, state, cmdq_pkt);
> +}
> +
> +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++) {
> +if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_BLENDER) {
> +blender_idx++;
> +
> +mtk_disp_blender_config(priv->ovl_adaptor_comp[priv->path[i]], w, h,
> +vrefresh, bpc, blender_idx == priv->layer_nr,
> +blender_idx == 1, 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);
> +}
> +}
for (i = 0; i < priv->layer_nr; i++)
mtk_disp_blender_config(priv->ovl_adaptor_comp[priv->path[i * 2 + 1]], w, h,
vrefresh, bpc, i == (priv->layer_nr - 1),
i == 0, cmdq_pkt);
mtk_disp_outproc_config(priv->ovl_adaptor_comp[priv->path[i * 2]], 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;
> +}
> +
>
[snip]
> +
> +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 - 1); i += 2) {
> +mtk_disp_exdma_start(priv->ovl_adaptor_comp[priv->path[i]], NULL);
mtk_disp_exdma_stop()
> +mtk_disp_blender_start(priv->ovl_adaptor_comp[priv->path[i + 1]], NULL);
mtk_disp_blender_stop()
> +}
> +
> +mtk_disp_outproc_start(priv->ovl_adaptor_comp[priv->path[i]]);
mtk_disp_outproc_stop()
> +}
> +
> +int mtk_ovlsys_adaptor_clk_enable(struct device *dev)
> +{
> +struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +struct device *comp;
> +int ret = 0;
int ret;
> +int i;
> +
> +for (i = 0; i < priv->path_size; i++) {
> +comp = priv->ovl_adaptor_comp[priv->path[i]];
> +if (!comp)
I'm curious about why this happen?
If this would not happen, remove this.
> +continue;
> +
> +if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> +ret = mtk_disp_exdma_clk_enable(comp);
> +else if (get_type(priv->path[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;
return 0;
> +
> +clk_err:
> +while (--i >= 0) {
> +comp = priv->ovl_adaptor_comp[priv->path[i]];
> +if (!comp)
> +continue;
> +
> +if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> +mtk_disp_exdma_clk_disable(comp);
> +else if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_BLENDER)
> +mtk_disp_blender_clk_disable(comp);
> +else
> +mtk_disp_outproc_clk_disable(comp);
> +}
> +
> +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 < priv->path_size; i++) {
> +comp = priv->ovl_adaptor_comp[priv->path[i]];
> +if (!comp)
> +continue;
> +
> +if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> +mtk_disp_exdma_clk_disable(comp);
> +else if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_BLENDER)
> +mtk_disp_blender_clk_disable(comp);
> +else
> +mtk_disp_outproc_clk_disable(comp);
> +}
> +}
> +
[snip]
> +
> +static int mtk_disp_ovlsys_adaptor_master_bind(struct device *dev)
> +{
> +struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +int ret, i;
> +
> +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;
> +priv->layer_nr = 0;
priv->layer_nr = priv->path_size / 2;
Regards,
CK
> +
> +for (i = 0; i < priv->path_size; i++)
> +if (comp_matches[priv->path[i]].type == OVLSYS_ADAPTOR_TYPE_BLENDER)
> +priv->layer_nr++;
> +
> +return 0;
> +}
> +
</pre>
</p></body></html><!--type:text--><!--{--><pre>************* MEDIATEK Confidentiality Notice
********************
The information contained in this e-mail message (including any
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be
conveyed only to the designated recipient(s). Any use, dissemination,
distribution, printing, retaining or copying of this e-mail (including its
attachments) by unintended recipient(s) is strictly prohibited and may
be unlawful. If you are not an intended recipient of this e-mail, or believe
that you have received this e-mail in error, please notify the sender
immediately (by replying to this e-mail), delete any and all copies of
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!
</pre><!--}-->