summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Riesch <michael.riesch@wolfvision.net>2023-01-24 06:47:05 +0100
committerHeiko Stuebner <heiko@sntech.de>2023-02-05 15:21:39 +0100
commitc66c6d7c47058a72a00b50d7f5c4538e3fa49b1c (patch)
tree1b0e987cc0c6968ed63d22bcaf11a4fb3149667c
parentcddddc066b056e7bb629a8c4d99c9c4a8ca70a6a (diff)
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 <michael.riesch@wolfvision.net> Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://patchwork.freedesktop.org/patch/msgid/20230124054706.3921383-6-michael.riesch@wolfvision.net
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop2.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 2c170cbcedee..0e0012368976 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -38,6 +38,7 @@
#include "rockchip_drm_gem.h"
#include "rockchip_drm_fb.h"
#include "rockchip_drm_vop2.h"
+#include "rockchip_rgb.h"
/*
* VOP2 architecture
@@ -211,6 +212,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[];
};
@@ -2392,6 +2396,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),
@@ -2697,11 +2720,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)
@@ -2710,6 +2751,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);
}