2023-01-24 05:49:24

by Michael Riesch

[permalink] [raw]
Subject: [PATCH v3 5/6] drm/rockchip: vop2: add support for the rgb output block

The Rockchip VOP2 features an internal RGB output block, which can be
attached any video port of the VOP2. Add support for this output block.

Signed-off-by: Michael Riesch <[email protected]>
---
v3:
- fix commit messages (still assumed video port 2)
- fix condition to make 0 a valid video port
v2:
- move away from wrong assumption that the RGB block is always
connected to video port 2 -> check devicetree to find RGB block

drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 44 ++++++++++++++++++++
1 file changed, 44 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 06fcdfa7b885..f38ffd0ccd9f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -39,6 +39,7 @@
#include "rockchip_drm_gem.h"
#include "rockchip_drm_fb.h"
#include "rockchip_drm_vop2.h"
+#include "rockchip_rgb.h"

/*
* VOP2 architecture
@@ -212,6 +213,9 @@ struct vop2 {
struct clk *hclk;
struct clk *aclk;

+ /* optional internal rgb encoder */
+ struct rockchip_rgb *rgb;
+
/* must be put at the end of the struct */
struct vop2_win win[];
};
@@ -2393,6 +2397,25 @@ static void vop2_destroy_crtcs(struct vop2 *vop2)
}
}

+static int vop2_find_rgb_encoder(struct vop2 *vop2)
+{
+ struct device_node *node = vop2->dev->of_node;
+ struct device_node *endpoint;
+ int i;
+
+ for (i = 0; i < vop2->data->nr_vps; i++) {
+ endpoint = of_graph_get_endpoint_by_regs(node, i,
+ ROCKCHIP_VOP2_EP_RGB0);
+ if (!endpoint)
+ continue;
+
+ of_node_put(endpoint);
+ return i;
+ }
+
+ return -ENOENT;
+}
+
static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
@@ -2698,11 +2721,29 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
if (ret)
return ret;

+ ret = vop2_find_rgb_encoder(vop2);
+ if (ret >= 0) {
+ vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc,
+ vop2->drm, ret);
+ if (IS_ERR(vop2->rgb)) {
+ if (PTR_ERR(vop2->rgb) == -EPROBE_DEFER) {
+ ret = PTR_ERR(vop2->rgb);
+ goto err_crtcs;
+ }
+ vop2->rgb = NULL;
+ }
+ }
+
rockchip_drm_dma_init_device(vop2->drm, vop2->dev);

pm_runtime_enable(&pdev->dev);

return 0;
+
+err_crtcs:
+ vop2_destroy_crtcs(vop2);
+
+ return ret;
}

static void vop2_unbind(struct device *dev, struct device *master, void *data)
@@ -2711,6 +2752,9 @@ static void vop2_unbind(struct device *dev, struct device *master, void *data)

pm_runtime_disable(dev);

+ if (vop2->rgb)
+ rockchip_rgb_fini(vop2->rgb);
+
vop2_destroy_crtcs(vop2);
}

--
2.30.2



2023-01-27 09:53:37

by Michael Riesch

[permalink] [raw]
Subject: Re: [PATCH v3 5/6] drm/rockchip: vop2: add support for the rgb output block

On 1/24/23 06:47, Michael Riesch wrote:
> The Rockchip VOP2 features an internal RGB output block, which can be
> attached any video port of the VOP2. Add support for this output block.

s/attached any/attached to any/ of course. Can this be fixed when the
patch is applied?

Michael

> Signed-off-by: Michael Riesch <[email protected]>
> ---
> v3:
> - fix commit messages (still assumed video port 2)
> - fix condition to make 0 a valid video port
> v2:
> - move away from wrong assumption that the RGB block is always
> connected to video port 2 -> check devicetree to find RGB block
>
> drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 44 ++++++++++++++++++++
> 1 file changed, 44 insertions(+)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> index 06fcdfa7b885..f38ffd0ccd9f 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> @@ -39,6 +39,7 @@
> #include "rockchip_drm_gem.h"
> #include "rockchip_drm_fb.h"
> #include "rockchip_drm_vop2.h"
> +#include "rockchip_rgb.h"
>
> /*
> * VOP2 architecture
> @@ -212,6 +213,9 @@ struct vop2 {
> struct clk *hclk;
> struct clk *aclk;
>
> + /* optional internal rgb encoder */
> + struct rockchip_rgb *rgb;
> +
> /* must be put at the end of the struct */
> struct vop2_win win[];
> };
> @@ -2393,6 +2397,25 @@ static void vop2_destroy_crtcs(struct vop2 *vop2)
> }
> }
>
> +static int vop2_find_rgb_encoder(struct vop2 *vop2)
> +{
> + struct device_node *node = vop2->dev->of_node;
> + struct device_node *endpoint;
> + int i;
> +
> + for (i = 0; i < vop2->data->nr_vps; i++) {
> + endpoint = of_graph_get_endpoint_by_regs(node, i,
> + ROCKCHIP_VOP2_EP_RGB0);
> + if (!endpoint)
> + continue;
> +
> + of_node_put(endpoint);
> + return i;
> + }
> +
> + return -ENOENT;
> +}
> +
> static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
> [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
> [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
> @@ -2698,11 +2721,29 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
> if (ret)
> return ret;
>
> + ret = vop2_find_rgb_encoder(vop2);
> + if (ret >= 0) {
> + vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc,
> + vop2->drm, ret);
> + if (IS_ERR(vop2->rgb)) {
> + if (PTR_ERR(vop2->rgb) == -EPROBE_DEFER) {
> + ret = PTR_ERR(vop2->rgb);
> + goto err_crtcs;
> + }
> + vop2->rgb = NULL;
> + }
> + }
> +
> rockchip_drm_dma_init_device(vop2->drm, vop2->dev);
>
> pm_runtime_enable(&pdev->dev);
>
> return 0;
> +
> +err_crtcs:
> + vop2_destroy_crtcs(vop2);
> +
> + return ret;
> }
>
> static void vop2_unbind(struct device *dev, struct device *master, void *data)
> @@ -2711,6 +2752,9 @@ static void vop2_unbind(struct device *dev, struct device *master, void *data)
>
> pm_runtime_disable(dev);
>
> + if (vop2->rgb)
> + rockchip_rgb_fini(vop2->rgb);
> +
> vop2_destroy_crtcs(vop2);
> }
>