mbox series

[v4,00/17] Add VOP2 support on rk3588

Message ID 20231207075906.651771-1-andyshrk@163.com
Headers show
Series Add VOP2 support on rk3588 | expand

Message

Andy Yan Dec. 7, 2023, 7:59 a.m. UTC
From: Andy Yan <andy.yan@rock-chips.com>

This patch sets aims at enable the VOP2 support on rk3588.

Main feature of VOP2 on rk3588:
Four video ports:
VP0 Max 4096x2160
VP1 Max 4096x2160
VP2 Max 4096x2160
VP3 Max 2048x1080

4 4K Cluster windows with AFBC/line RGB and AFBC-only YUV support
4 4K Esmart windows with line RGB/YUV support

The current version support all the 8 windows with all the suppported
plane format.

And we don't have a upstreamed encoder/connector(HDMI/DP) for rk3588
yet, Cristian from collabora is working on adding upstream support for
HDMI on rk3588.

My current test(1080P/4KP60) is runing with a HDMI driver pick from
downstream bsp kernel.

A branch based on linux-6.7 rc4 containing all the series and
HDMI driver(not compatible with mainline rk3568 hdmi) picked
from downstream bsp kernel is available [0].

[0]https://github.com/andyshrk/linux/commits/rk3588-vop2-upstream-linux-6.7-rc4-2023-12-07

Changes in v4:
- fix the POST_BUF_EMPTY irq when set mode
- use full stop at all the description's end.
- address Krzysztof's review about dt-binding in v3
- keep all VOP2_FEATURE_HAS_xxx macros increase in order.
- address Sascha's review about debugfs
- Add const for rockchip,rk3588-iommu compatible

Changes in v3:
- split from the vop2 driver patch
- put bool variable yuv_overlay next to other bool variable
- define macro for RK3568_OVL_CTRL__YUV_MODE
- just write RK3568_OVL_CTRL register once in function
  vop2_setup_layer_mixer
- constrain properties in allOf:if:then
- some description updates
- change the subject as Krzysztof suggested, and add his ACK
- add braces for x in macro vop2_output_if_is_yyy(x)
- clear the bits of a mask before setting it in rk3588_set_intf_mux
- add more comments.
- put regs dump info in vop2_data

Changes in v2:
- fix errors when running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
- split form vop driver patch
- add rk3588_ prefix for functions which are rk3588 only
- make some calculation as fixed value and keep calculation formula as
  comment
- check return value for some cru calculation functions.
- check return value for syscon_regmap_lookup_by_phandle
- add NV20/NV30 for esmart plane

Andy Yan (17):
  drm/rockchip: move output interface related definition to
    rockchip_drm_drv.h
  Revert "drm/rockchip: vop2: Use regcache_sync() to fix suspend/resume"
  drm/rockchip: vop2: set half_block_en bit in all mode
  drm/rockchip: vop2: clear afbc en and transform bit for cluster window
    at linear mode
  drm/rockchip: vop2: Add write mask for VP config done
  drm/rockchip: vop2: Set YUV/RGB overlay mode
  drm/rockchip: vop2: set bg dly and prescan dly at vop2_post_config
  drm/rockchip: vop2: rename grf to sys_grf
  dt-bindings: soc: rockchip: add rk3588 vop/vo syscon
  dt-bindings: display: vop2: Add rk3588 support
  dt-bindings: rockchip,vop2: Add more endpoint definition
  drm/rockchip: vop2: Add support for rk3588
  drm/rockchip: vop2: rename VOP_FEATURE_OUTPUT_10BIT to
    VOP2_VP_FEATURE_OUTPUT_10BIT
  drm/rockchip: vop2: Add debugfs support
  dt-bindings: iommu: rockchip: Add Rockchip RK3588
  arm64: dts: rockchip: Add vop on rk3588
  MAINTAINERS: Add myself as a reviewer for rockchip drm

 .../display/rockchip/rockchip-vop2.yaml       | 100 ++-
 .../bindings/iommu/rockchip,iommu.yaml        |  11 +-
 .../devicetree/bindings/soc/rockchip/grf.yaml |   2 +
 MAINTAINERS                                   |   1 +
 arch/arm64/boot/dts/rockchip/rk3588s.dtsi     |  96 +++
 .../gpu/drm/rockchip/analogix_dp-rockchip.c   |   1 -
 drivers/gpu/drm/rockchip/cdn-dp-core.c        |   1 -
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   |   1 -
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c   |   1 -
 drivers/gpu/drm/rockchip/inno_hdmi.c          |   1 -
 drivers/gpu/drm/rockchip/rk3066_hdmi.c        |   1 -
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |  18 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h   |  12 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c  | 761 +++++++++++++++++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h  | 111 ++-
 drivers/gpu/drm/rockchip/rockchip_lvds.c      |   1 -
 drivers/gpu/drm/rockchip/rockchip_rgb.c       |   1 -
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c  | 414 +++++++++-
 include/dt-bindings/soc/rockchip,vop2.h       |   4 +
 19 files changed, 1441 insertions(+), 97 deletions(-)

Comments

Heiko Stübner Dec. 8, 2023, 4:07 p.m. UTC | #1
Hi Andy,

Am Donnerstag, 7. Dezember 2023, 08:59:06 CET schrieb Andy Yan:
> From: Andy Yan <andy.yan@rock-chips.com>
> 
> This patch sets aims at enable the VOP2 support on rk3588.
> 
> Main feature of VOP2 on rk3588:
> Four video ports:
> VP0 Max 4096x2160
> VP1 Max 4096x2160
> VP2 Max 4096x2160
> VP3 Max 2048x1080
> 
> 4 4K Cluster windows with AFBC/line RGB and AFBC-only YUV support
> 4 4K Esmart windows with line RGB/YUV support
> 
> The current version support all the 8 windows with all the suppported
> plane format.
> 
> And we don't have a upstreamed encoder/connector(HDMI/DP) for rk3588
> yet, Cristian from collabora is working on adding upstream support for
> HDMI on rk3588.
> 
> My current test(1080P/4KP60) is runing with a HDMI driver pick from
> downstream bsp kernel.
> 
> A branch based on linux-6.7 rc4 containing all the series and
> HDMI driver(not compatible with mainline rk3568 hdmi) picked
> from downstream bsp kernel is available [0].
> 
> [0]https://github.com/andyshrk/linux/commits/rk3588-vop2-upstream-linux-6.7-rc4-2023-12-07
> 
> Changes in v4:
> - fix the POST_BUF_EMPTY irq when set mode
> - use full stop at all the description's end.
> - address Krzysztof's review about dt-binding in v3
> - keep all VOP2_FEATURE_HAS_xxx macros increase in order.
> - address Sascha's review about debugfs
> - Add const for rockchip,rk3588-iommu compatible

very nice, the error messages on "mode changes" are gone now.
Display and even combination with panthor still work of my rk3588-board

Tested-by: Heiko Stuebner <heiko@sntech.de>
Heiko Stübner Dec. 8, 2023, 4:26 p.m. UTC | #2
Hi Andy,

Am Donnerstag, 7. Dezember 2023, 09:02:47 CET schrieb Andy Yan:
> From: Andy Yan <andy.yan@rock-chips.com>
> 
> Add vop dt node for rk3588.
> 
> Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
> ---
> 
> (no changes since v1)
> 
>  arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 96 +++++++++++++++++++++++
>  1 file changed, 96 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
> index 7064c0e9179f..a9810ca78dc4 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
> @@ -593,6 +608,87 @@ i2c0: i2c@fd880000 {
>  		status = "disabled";
>  	};
>  
> +	vop: vop@fdd90000 {
> +		compatible = "rockchip,rk3588-vop";
> +		reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
> +		reg-names = "vop", "gamma_lut";
> +		interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
> +		clocks = <&cru ACLK_VOP>,
> +			 <&cru HCLK_VOP>,
> +			 <&cru DCLK_VOP0>,
> +			 <&cru DCLK_VOP1>,
> +			 <&cru DCLK_VOP2>,
> +			 <&cru DCLK_VOP3>,
> +			 <&cru PCLK_VOP_ROOT>;
> +		clock-names = "aclk",
> +			      "hclk",
> +			      "dclk_vp0",
> +			      "dclk_vp1",
> +			      "dclk_vp2",
> +			      "dclk_vp3",
> +			      "pclk_vop";
> +		resets = <&cru SRST_A_VOP>,
> +			 <&cru SRST_H_VOP>,
> +			 <&cru SRST_D_VOP0>,
> +			 <&cru SRST_D_VOP1>,
> +			 <&cru SRST_D_VOP2>,
> +			 <&cru SRST_D_VOP3>;
> +		reset-names = "axi",
> +			      "ahb",
> +			      "dclk_vp0",
> +			      "dclk_vp1",
> +			      "dclk_vp2",
> +			      "dclk_vp3";

resets and reset-names do not seem to be part of the binding, so
should probably be added there.


> +		iommus = <&vop_mmu>;
> +		power-domains = <&power RK3588_PD_VOP>;
> +		rockchip,grf = <&sys_grf>;
> +		rockchip,vop-grf = <&vop_grf>;
> +		rockchip,vo1-grf = <&vo1_grf>;
> +		rockchip,pmu = <&pmu>;
> +

move this blank line _below_ the status=disabled please.

> +		status = "disabled";
> +		vop_out: ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			vp0: port@0 {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +				reg = <0>;
> +			};
> +
> +			vp1: port@1 {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +				reg = <1>;
> +			};
> +
> +			vp2: port@2 {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +				reg = <2>;
> +			};
> +
> +			vp3: port@3 {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +				reg = <3>;
> +			};
> +		};
> +	};
> +
> +	vop_mmu: iommu@fdd97e00 {
> +		compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
> +		reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
> +		interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
> +		interrupt-names = "vop_mmu";

interrupt-names is not part of the mainline iommu binding, so should be dropped


Thanks
Heiko
Andy Yan Dec. 9, 2023, 1:21 a.m. UTC | #3
Hi Heiko:

On 12/9/23 00:07, Heiko Stübner wrote:
> Hi Andy,
> 
> Am Donnerstag, 7. Dezember 2023, 08:59:06 CET schrieb Andy Yan:
>> From: Andy Yan <andy.yan@rock-chips.com>
>>
>> This patch sets aims at enable the VOP2 support on rk3588.
>>
>> Main feature of VOP2 on rk3588:
>> Four video ports:
>> VP0 Max 4096x2160
>> VP1 Max 4096x2160
>> VP2 Max 4096x2160
>> VP3 Max 2048x1080
>>
>> 4 4K Cluster windows with AFBC/line RGB and AFBC-only YUV support
>> 4 4K Esmart windows with line RGB/YUV support
>>
>> The current version support all the 8 windows with all the suppported
>> plane format.
>>
>> And we don't have a upstreamed encoder/connector(HDMI/DP) for rk3588
>> yet, Cristian from collabora is working on adding upstream support for
>> HDMI on rk3588.
>>
>> My current test(1080P/4KP60) is runing with a HDMI driver pick from
>> downstream bsp kernel.
>>
>> A branch based on linux-6.7 rc4 containing all the series and
>> HDMI driver(not compatible with mainline rk3568 hdmi) picked
>> from downstream bsp kernel is available [0].
>>
>> [0]https://github.com/andyshrk/linux/commits/rk3588-vop2-upstream-linux-6.7-rc4-2023-12-07
>>
>> Changes in v4:
>> - fix the POST_BUF_EMPTY irq when set mode
>> - use full stop at all the description's end.
>> - address Krzysztof's review about dt-binding in v3
>> - keep all VOP2_FEATURE_HAS_xxx macros increase in order.
>> - address Sascha's review about debugfs
>> - Add const for rockchip,rk3588-iommu compatible
> 
> very nice, the error messages on "mode changes" are gone now.
> Display and even combination with panthor still work of my rk3588-board
> 
> Tested-by: Heiko Stuebner <heiko@sntech.de>

Thanks for your honorable work on this platform, and thanks for you test and review.

So can I add your Tested-by for all this series form PATCH 1~16 in next version?
> 
> 
> 
> 
> 
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
Andy Yan Dec. 9, 2023, 1:28 a.m. UTC | #4
Hi Heiko:

On 12/9/23 00:26, Heiko Stübner wrote:
> Hi Andy,
> 
> Am Donnerstag, 7. Dezember 2023, 09:02:47 CET schrieb Andy Yan:
>> From: Andy Yan <andy.yan@rock-chips.com>
>>
>> Add vop dt node for rk3588.
>>
>> Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
>> ---
>>
>> (no changes since v1)
>>
>>   arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 96 +++++++++++++++++++++++
>>   1 file changed, 96 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
>> index 7064c0e9179f..a9810ca78dc4 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
>> @@ -593,6 +608,87 @@ i2c0: i2c@fd880000 {
>>   		status = "disabled";
>>   	};
>>   
>> +	vop: vop@fdd90000 {
>> +		compatible = "rockchip,rk3588-vop";
>> +		reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
>> +		reg-names = "vop", "gamma_lut";
>> +		interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
>> +		clocks = <&cru ACLK_VOP>,
>> +			 <&cru HCLK_VOP>,
>> +			 <&cru DCLK_VOP0>,
>> +			 <&cru DCLK_VOP1>,
>> +			 <&cru DCLK_VOP2>,
>> +			 <&cru DCLK_VOP3>,
>> +			 <&cru PCLK_VOP_ROOT>;
>> +		clock-names = "aclk",
>> +			      "hclk",
>> +			      "dclk_vp0",
>> +			      "dclk_vp1",
>> +			      "dclk_vp2",
>> +			      "dclk_vp3",
>> +			      "pclk_vop";
>> +		resets = <&cru SRST_A_VOP>,
>> +			 <&cru SRST_H_VOP>,
>> +			 <&cru SRST_D_VOP0>,
>> +			 <&cru SRST_D_VOP1>,
>> +			 <&cru SRST_D_VOP2>,
>> +			 <&cru SRST_D_VOP3>;
>> +		reset-names = "axi",
>> +			      "ahb",
>> +			      "dclk_vp0",
>> +			      "dclk_vp1",
>> +			      "dclk_vp2",
>> +			      "dclk_vp3";
> 
> resets and reset-names do not seem to be part of the binding, so
> should probably be added there.

I will drop resets and reset-names in next version.
> 
> 
>> +		iommus = <&vop_mmu>;
>> +		power-domains = <&power RK3588_PD_VOP>;
>> +		rockchip,grf = <&sys_grf>;
>> +		rockchip,vop-grf = <&vop_grf>;
>> +		rockchip,vo1-grf = <&vo1_grf>;
>> +		rockchip,pmu = <&pmu>;
>> +
> 
> move this blank line _below_ the status=disabled please.

ok, will do.
> 
>> +		status = "disabled";
>> +		vop_out: ports {
>> +			#address-cells = <1>;
>> +			#size-cells = <0>;
>> +
>> +			vp0: port@0 {
>> +				#address-cells = <1>;
>> +				#size-cells = <0>;
>> +				reg = <0>;
>> +			};
>> +
>> +			vp1: port@1 {
>> +				#address-cells = <1>;
>> +				#size-cells = <0>;
>> +				reg = <1>;
>> +			};
>> +
>> +			vp2: port@2 {
>> +				#address-cells = <1>;
>> +				#size-cells = <0>;
>> +				reg = <2>;
>> +			};
>> +
>> +			vp3: port@3 {
>> +				#address-cells = <1>;
>> +				#size-cells = <0>;
>> +				reg = <3>;
>> +			};
>> +		};
>> +	};
>> +
>> +	vop_mmu: iommu@fdd97e00 {
>> +		compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
>> +		reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
>> +		interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
>> +		interrupt-names = "vop_mmu";
> 
> interrupt-names is not part of the mainline iommu binding, so should be dropped

will do.
> 
> 
> Thanks
> Heiko
> 
>
Sascha Hauer Dec. 11, 2023, 6:59 a.m. UTC | #5
On Thu, Dec 07, 2023 at 04:02:22PM +0800, Andy Yan wrote:
> From: Andy Yan <andy.yan@rock-chips.com>
> 
> /sys/kernel/debug/dri/vop2/summary:  dump vop display state
> /sys/kernel/debug/dri/vop2/regs: dump whole vop registers
> /sys/kernel/debug/dri/vop2/active_regs: only dump the registers of
> activated modules
> 
> Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>

Sascha

> 
> ---
> 
> Changes in v4:
> - check NULL pointer at right place
> - fix the index of fb->obj
> - drop explicitly cast of void pointer
> - make the register dump code as a common function.
> 
> Changes in v3:
> - put regs dump info in vop2_data
> 
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 256 +++++++++++++++++++
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  11 +
>  drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 191 ++++++++++++++
>  3 files changed, 458 insertions(+)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> index 2b996f1a25ad..1cd86b3bde7e 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> @@ -27,6 +27,7 @@
>  #include <drm/drm_debugfs.h>
>  #include <drm/drm_flip_work.h>
>  #include <drm/drm_framebuffer.h>
> +#include <drm/drm_gem_framebuffer_helper.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_vblank.h>
>  
> @@ -187,6 +188,7 @@ struct vop2 {
>  	 */
>  	u32 registered_num_wins;
>  
> +	struct resource *res;
>  	void __iomem *regs;
>  	struct regmap *map;
>  
> @@ -238,6 +240,37 @@ struct vop2 {
>  
>  #define vop2_output_if_is_dpi(x)	((x) == ROCKCHIP_VOP2_EP_RGB0)
>  
> +
> +/*
> + * bus-format types.
> + */
> +struct drm_bus_format_enum_list {
> +	int type;
> +	const char *name;
> +};
> +
> +static const struct drm_bus_format_enum_list drm_bus_format_enum_list[] = {
> +	{ DRM_MODE_CONNECTOR_Unknown, "Unknown" },
> +	{ MEDIA_BUS_FMT_RGB565_1X16, "RGB565_1X16" },
> +	{ MEDIA_BUS_FMT_RGB666_1X18, "RGB666_1X18" },
> +	{ MEDIA_BUS_FMT_RGB666_1X24_CPADHI, "RGB666_1X24_CPADHI" },
> +	{ MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, "RGB666_1X7X3_SPWG" },
> +	{ MEDIA_BUS_FMT_YUV8_1X24, "YUV8_1X24" },
> +	{ MEDIA_BUS_FMT_UYYVYY8_0_5X24, "UYYVYY8_0_5X24" },
> +	{ MEDIA_BUS_FMT_YUV10_1X30, "YUV10_1X30" },
> +	{ MEDIA_BUS_FMT_UYYVYY10_0_5X30, "UYYVYY10_0_5X30" },
> +	{ MEDIA_BUS_FMT_RGB888_3X8, "RGB888_3X8" },
> +	{ MEDIA_BUS_FMT_RGB888_1X24, "RGB888_1X24" },
> +	{ MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, "RGB888_1X7X4_SPWG" },
> +	{ MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, "RGB888_1X7X4_JEIDA" },
> +	{ MEDIA_BUS_FMT_UYVY8_2X8, "UYVY8_2X8" },
> +	{ MEDIA_BUS_FMT_YUYV8_1X16, "YUYV8_1X16" },
> +	{ MEDIA_BUS_FMT_UYVY8_1X16, "UYVY8_1X16" },
> +	{ MEDIA_BUS_FMT_RGB101010_1X30, "RGB101010_1X30" },
> +	{ MEDIA_BUS_FMT_YUYV10_1X20, "YUYV10_1X20" },
> +};
> +static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list)
> +
>  static const struct regmap_config vop2_regmap_config;
>  
>  static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
> @@ -2516,6 +2549,227 @@ static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = {
>  	.atomic_disable = vop2_crtc_atomic_disable,
>  };
>  
> +static void vop2_dump_connector_on_crtc(struct drm_crtc *crtc, struct seq_file *s)
> +{
> +	struct drm_connector_list_iter conn_iter;
> +	struct drm_connector *connector;
> +
> +	drm_connector_list_iter_begin(crtc->dev, &conn_iter);
> +	drm_for_each_connector_iter(connector, &conn_iter) {
> +		if (crtc->state->connector_mask & drm_connector_mask(connector))
> +			seq_printf(s, "    Connector: %s\n", connector->name);
> +
> +	}
> +	drm_connector_list_iter_end(&conn_iter);
> +}
> +
> +static int vop2_plane_state_dump(struct seq_file *s, struct drm_plane *plane)
> +{
> +	struct vop2_win *win = to_vop2_win(plane);
> +	struct drm_plane_state *pstate = plane->state;
> +	struct drm_rect *src, *dst;
> +	struct drm_framebuffer *fb;
> +	struct drm_gem_object *obj;
> +	struct rockchip_gem_object *rk_obj;
> +	bool xmirror;
> +	bool ymirror;
> +	bool rotate_270;
> +	bool rotate_90;
> +	dma_addr_t fb_addr;
> +	int i;
> +
> +	seq_printf(s, "    %s: %s\n", win->data->name, !pstate ?
> +		   "DISABLED" : pstate->crtc ? "ACTIVE" : "DISABLED");
> +
> +	if (!pstate || !pstate->fb)
> +		return 0;
> +
> +	fb = pstate->fb;
> +	src = &pstate->src;
> +	dst = &pstate->dst;
> +	xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false;
> +	ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false;
> +	rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270;
> +	rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90;
> +
> +	seq_printf(s, "\twin_id: %d\n", win->win_id);
> +
> +	seq_printf(s, "\tformat: %p4cc%s glb_alpha[0x%x]\n",
> +		   &fb->format->format,
> +		   drm_is_afbc(fb->modifier) ? "[AFBC]" : "",
> +		   pstate->alpha >> 8);
> +	seq_printf(s, "\trotate: xmirror: %d ymirror: %d rotate_90: %d rotate_270: %d\n",
> +		   xmirror, ymirror, rotate_90, rotate_270);
> +	seq_printf(s, "\tzpos: %d\n", pstate->normalized_zpos);
> +	seq_printf(s, "\tsrc: pos[%d, %d] rect[%d x %d]\n", src->x1 >> 16,
> +		   src->y1 >> 16, drm_rect_width(src) >> 16,
> +		   drm_rect_height(src) >> 16);
> +	seq_printf(s, "\tdst: pos[%d, %d] rect[%d x %d]\n", dst->x1, dst->y1,
> +		   drm_rect_width(dst), drm_rect_height(dst));
> +
> +	for (i = 0; i < fb->format->num_planes; i++) {
> +		obj = fb->obj[i];
> +		rk_obj = to_rockchip_obj(obj);
> +		fb_addr = rk_obj->dma_addr + fb->offsets[i];
> +
> +		seq_printf(s, "\tbuf[%d]: addr: %pad pitch: %d offset: %d\n",
> +			   i, &fb_addr, fb->pitches[i], fb->offsets[i]);
> +	}
> +
> +	return 0;
> +}
> +
> +static int vop2_crtc_state_dump(struct drm_crtc *crtc, struct seq_file *s)
> +{
> +	struct vop2_video_port *vp = to_vop2_video_port(crtc);
> +	struct drm_crtc_state *cstate = crtc->state;
> +	struct rockchip_crtc_state *vcstate;
> +	struct drm_display_mode *mode;
> +	struct drm_plane *plane;
> +	bool interlaced;
> +
> +	seq_printf(s, "Video Port%d: %s\n", vp->id, !cstate ?
> +		   "DISABLED" : cstate->active ? "ACTIVE" : "DISABLED");
> +
> +	if (!cstate || !cstate->active)
> +		return 0;
> +
> +	mode = &crtc->state->adjusted_mode;
> +	vcstate = to_rockchip_crtc_state(cstate);
> +	interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
> +
> +	vop2_dump_connector_on_crtc(crtc, s);
> +	seq_printf(s, "\tbus_format[%x]: %s\n", vcstate->bus_format,
> +		    drm_get_bus_format_name(vcstate->bus_format));
> +	seq_printf(s, "\toutput_mode[%x]", vcstate->output_mode);
> +	seq_printf(s, " color_space[%d]\n", vcstate->color_space);
> +	seq_printf(s, "    Display mode: %dx%d%s%d\n",
> +		    mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
> +		    drm_mode_vrefresh(mode));
> +	seq_printf(s, "\tclk[%d] real_clk[%d] type[%x] flag[%x]\n",
> +		    mode->clock, mode->crtc_clock, mode->type, mode->flags);
> +	seq_printf(s, "\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start,
> +		    mode->hsync_end, mode->htotal);
> +	seq_printf(s, "\tV: %d %d %d %d\n", mode->vdisplay, mode->vsync_start,
> +		    mode->vsync_end, mode->vtotal);
> +
> +	drm_atomic_crtc_for_each_plane(plane, crtc) {
> +		vop2_plane_state_dump(s, plane);
> +	}
> +
> +	return 0;
> +}
> +
> +static int vop2_summary_show(struct seq_file *s, void *data)
> +{
> +	struct drm_info_node *node = s->private;
> +	struct drm_minor *minor = node->minor;
> +	struct drm_device *drm_dev = minor->dev;
> +	struct drm_crtc *crtc;
> +
> +	drm_modeset_lock_all(drm_dev);
> +	drm_for_each_crtc(crtc, drm_dev) {
> +		vop2_crtc_state_dump(crtc, s);
> +	}
> +	drm_modeset_unlock_all(drm_dev);
> +
> +	return 0;
> +}
> +
> +static void vop2_regs_print(struct vop2 *vop2, struct seq_file *s,
> +			    const struct vop2_regs_dump *dump, bool active_only)
> +{
> +	resource_size_t start;
> +	u32 val;
> +	int i;
> +
> +	if (dump->en_mask && active_only) {
> +		val = vop2_readl(vop2, dump->base + dump->en_reg);
> +		if ((val & dump->en_mask) != dump->en_val)
> +			return;
> +	}
> +
> +	seq_printf(s, "\n%s:\n", dump->name);
> +
> +	start = vop2->res->start + dump->base;
> +	for (i = 0; i < dump->size >> 2; i += 4) {
> +		seq_printf(s, "%08x:  %08x %08x %08x %08x\n", (u32)start + i * 4,
> +			   vop2_readl(vop2, dump->base + (4 * i)),
> +			   vop2_readl(vop2, dump->base + (4 * (i + 1))),
> +			   vop2_readl(vop2, dump->base + (4 * (i + 2))),
> +			   vop2_readl(vop2, dump->base + (4 * (i + 3))));
> +	}
> +}
> +
> +static void __vop2_regs_dump(struct seq_file *s, bool active_only)
> +{
> +	struct drm_info_node *node = s->private;
> +	struct vop2 *vop2 = node->info_ent->data;
> +	struct drm_minor *minor = node->minor;
> +	struct drm_device *drm_dev = minor->dev;
> +	const struct vop2_regs_dump *dump;
> +	unsigned int i;
> +
> +	drm_modeset_lock_all(drm_dev);
> +	if (vop2->enable_count) {
> +		for (i = 0; i < vop2->data->regs_dump_size; i++) {
> +			dump = &vop2->data->regs_dump[i];
> +			vop2_regs_print(vop2, s, dump, active_only);
> +		}
> +	} else {
> +		seq_printf(s, "VOP disabled\n");
> +	}
> +	drm_modeset_unlock_all(drm_dev);
> +
> +}
> +
> +static int vop2_regs_show(struct seq_file *s, void *arg)
> +{
> +	__vop2_regs_dump(s, false);
> +
> +	return 0;
> +}
> +
> +static int vop2_active_regs_show(struct seq_file *s, void *data)
> +{
> +	__vop2_regs_dump(s, true);
> +
> +	return 0;
> +}
> +
> +static struct drm_info_list vop2_debugfs_list[] = {
> +	{ "summary", vop2_summary_show, 0, NULL },
> +	{ "active_regs", vop2_active_regs_show,   0, NULL },
> +	{ "regs", vop2_regs_show,   0, NULL },
> +};
> +
> +static void vop2_debugfs_init(struct vop2 *vop2, struct drm_minor *minor)
> +{
> +	struct dentry *root;
> +	unsigned int i;
> +
> +	root = debugfs_create_dir("vop2", minor->debugfs_root);
> +	if (!IS_ERR(root)) {
> +		for (i = 0; i < ARRAY_SIZE(vop2_debugfs_list); i++)
> +			vop2_debugfs_list[i].data = vop2;
> +
> +		drm_debugfs_create_files(vop2_debugfs_list,
> +					 ARRAY_SIZE(vop2_debugfs_list),
> +					 root, minor);
> +	}
> +}
> +
> +static int vop2_crtc_late_register(struct drm_crtc *crtc)
> +{
> +	struct vop2_video_port *vp = to_vop2_video_port(crtc);
> +	struct vop2 *vop2 = vp->vop2;
> +
> +	if (drm_crtc_index(crtc) == 0)
> +		vop2_debugfs_init(vop2, crtc->dev->primary);
> +
> +	return 0;
> +}
> +
>  static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc)
>  {
>  	struct rockchip_crtc_state *vcstate;
> @@ -2565,6 +2819,7 @@ static const struct drm_crtc_funcs vop2_crtc_funcs = {
>  	.atomic_destroy_state = vop2_crtc_destroy_state,
>  	.enable_vblank = vop2_crtc_enable_vblank,
>  	.disable_vblank = vop2_crtc_disable_vblank,
> +	.late_register = vop2_crtc_late_register,
>  };
>  
>  static irqreturn_t vop2_isr(int irq, void *data)
> @@ -3109,6 +3364,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
>  		return -EINVAL;
>  	}
>  
> +	vop2->res = res;
>  	vop2->regs = devm_ioremap_resource(dev, res);
>  	if (IS_ERR(vop2->regs))
>  		return PTR_ERR(vop2->regs);
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
> index 615a16196aff..59cd6b933bfb 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
> @@ -122,6 +122,15 @@ enum vop2_win_regs {
>  	VOP2_WIN_MAX_REG,
>  };
>  
> +struct vop2_regs_dump {
> +	const char *name;
> +	u32 base;
> +	u32 size;
> +	u32 en_reg;
> +	u32 en_val;
> +	u32 en_mask;
> +};
> +
>  struct vop2_win_data {
>  	const char *name;
>  	unsigned int phys_id;
> @@ -160,10 +169,12 @@ struct vop2_data {
>  	u64 feature;
>  	const struct vop2_win_data *win;
>  	const struct vop2_video_port_data *vp;
> +	const struct vop2_regs_dump *regs_dump;
>  	struct vop_rect max_input;
>  	struct vop_rect max_output;
>  
>  	unsigned int win_size;
> +	unsigned int regs_dump_size;
>  	unsigned int soc_id;
>  };
>  
> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
> index 48170694ac6b..6fc119034a0e 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
> @@ -260,6 +260,88 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
>  	},
>  };
>  
> +static const struct vop2_regs_dump rk3568_regs_dump[] = {
> +	{
> +		.name = "SYS",
> +		.base = RK3568_REG_CFG_DONE,
> +		.size = 0x100,
> +		.en_reg  = 0,
> +		.en_val = 0,
> +		.en_mask = 0
> +	}, {
> +		.name = "OVL",
> +		.base = RK3568_OVL_CTRL,
> +		.size = 0x100,
> +		.en_reg = 0,
> +		.en_val = 0,
> +		.en_mask = 0,
> +	}, {
> +		.name = "VP0",
> +		.base = RK3568_VP0_CTRL_BASE,
> +		.size = 0x100,
> +		.en_reg = RK3568_VP_DSP_CTRL,
> +		.en_val = 0,
> +		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
> +	}, {
> +		.name = "VP1",
> +		.base = RK3568_VP1_CTRL_BASE,
> +		.size = 0x100,
> +		.en_reg = RK3568_VP_DSP_CTRL,
> +		.en_val = 0,
> +		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
> +	}, {
> +		.name = "VP2",
> +		.base = RK3568_VP2_CTRL_BASE,
> +		.size = 0x100,
> +		.en_reg = RK3568_VP_DSP_CTRL,
> +		.en_val = 0,
> +		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
> +
> +	}, {
> +		.name = "Cluster0",
> +		.base = RK3568_CLUSTER0_CTRL_BASE,
> +		.size = 0x110,
> +		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
> +		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
> +		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
> +	}, {
> +		.name = "Cluster1",
> +		.base = RK3568_CLUSTER1_CTRL_BASE,
> +		.size = 0x110,
> +		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
> +		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
> +		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
> +	}, {
> +		.name = "Esmart0",
> +		.base = RK3568_ESMART0_CTRL_BASE,
> +		.size = 0xf0,
> +		.en_reg = RK3568_SMART_REGION0_CTRL,
> +		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +	}, {
> +		.name = "Esmart1",
> +		.base = RK3568_ESMART1_CTRL_BASE,
> +		.size = 0xf0,
> +		.en_reg = RK3568_SMART_REGION0_CTRL,
> +		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +	}, {
> +		.name = "Smart0",
> +		.base = RK3568_SMART0_CTRL_BASE,
> +		.size = 0xf0,
> +		.en_reg = RK3568_SMART_REGION0_CTRL,
> +		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +	}, {
> +		.name = "Smart1",
> +		.base = RK3568_SMART1_CTRL_BASE,
> +		.size = 0xf0,
> +		.en_reg = RK3568_SMART_REGION0_CTRL,
> +		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +	},
> +};
> +
>  static const struct vop2_video_port_data rk3588_vop_video_ports[] = {
>  	{
>  		.id = 0,
> @@ -440,6 +522,109 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
>  	},
>  };
>  
> +static const struct vop2_regs_dump rk3588_regs_dump[] = {
> +	{
> +		.name = "SYS",
> +		.base = RK3568_REG_CFG_DONE,
> +		.size = 0x100,
> +		.en_reg  = 0,
> +		.en_val = 0,
> +		.en_mask = 0
> +	}, {
> +		.name = "OVL",
> +		.base = RK3568_OVL_CTRL,
> +		.size = 0x100,
> +		.en_reg = 0,
> +		.en_val = 0,
> +		.en_mask = 0,
> +	}, {
> +		.name = "VP0",
> +		.base = RK3568_VP0_CTRL_BASE,
> +		.size = 0x100,
> +		.en_reg = RK3568_VP_DSP_CTRL,
> +		.en_val = 0,
> +		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
> +	}, {
> +		.name = "VP1",
> +		.base = RK3568_VP1_CTRL_BASE,
> +		.size = 0x100,
> +		.en_reg = RK3568_VP_DSP_CTRL,
> +		.en_val = 0,
> +		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
> +	}, {
> +		.name = "VP2",
> +		.base = RK3568_VP2_CTRL_BASE,
> +		.size = 0x100,
> +		.en_reg = RK3568_VP_DSP_CTRL,
> +		.en_val = 0,
> +		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
> +
> +	}, {
> +		.name = "VP3",
> +		.base = RK3588_VP3_CTRL_BASE,
> +		.size = 0x100,
> +		.en_reg = RK3568_VP_DSP_CTRL,
> +		.en_val = 0,
> +		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
> +	}, {
> +		.name = "Cluster0",
> +		.base = RK3568_CLUSTER0_CTRL_BASE,
> +		.size = 0x110,
> +		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
> +		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
> +		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
> +	}, {
> +		.name = "Cluster1",
> +		.base = RK3568_CLUSTER1_CTRL_BASE,
> +		.size = 0x110,
> +		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
> +		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
> +		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
> +	}, {
> +		.name = "Cluster2",
> +		.base = RK3588_CLUSTER2_CTRL_BASE,
> +		.size = 0x110,
> +		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
> +		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
> +		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
> +	}, {
> +		.name = "Cluster3",
> +		.base = RK3588_CLUSTER3_CTRL_BASE,
> +		.size = 0x110,
> +		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
> +		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
> +		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
> +	}, {
> +		.name = "Esmart0",
> +		.base = RK3568_ESMART0_CTRL_BASE,
> +		.size = 0xf0,
> +		.en_reg = RK3568_SMART_REGION0_CTRL,
> +		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +	}, {
> +		.name = "Esmart1",
> +		.base = RK3568_ESMART1_CTRL_BASE,
> +		.size = 0xf0,
> +		.en_reg = RK3568_SMART_REGION0_CTRL,
> +		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +	}, {
> +		.name = "Esmart2",
> +		.base = RK3588_ESMART2_CTRL_BASE,
> +		.size = 0xf0,
> +		.en_reg = RK3568_SMART_REGION0_CTRL,
> +		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +	}, {
> +		.name = "Esmart3",
> +		.base = RK3588_ESMART3_CTRL_BASE,
> +		.size = 0xf0,
> +		.en_reg = RK3568_SMART_REGION0_CTRL,
> +		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
> +	},
> +};
> +
>  static const struct vop2_data rk3566_vop = {
>  	.feature = VOP2_FEATURE_HAS_SYS_GRF,
>  	.nr_vps = 3,
> @@ -448,6 +633,8 @@ static const struct vop2_data rk3566_vop = {
>  	.vp = rk3568_vop_video_ports,
>  	.win = rk3568_vop_win_data,
>  	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
> +	.regs_dump = rk3568_regs_dump,
> +	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
>  	.soc_id = 3566,
>  };
>  
> @@ -459,6 +646,8 @@ static const struct vop2_data rk3568_vop = {
>  	.vp = rk3568_vop_video_ports,
>  	.win = rk3568_vop_win_data,
>  	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
> +	.regs_dump = rk3568_regs_dump,
> +	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
>  	.soc_id = 3568,
>  };
>  
> @@ -471,6 +660,8 @@ static const struct vop2_data rk3588_vop = {
>  	.vp = rk3588_vop_video_ports,
>  	.win = rk3588_vop_win_data,
>  	.win_size = ARRAY_SIZE(rk3588_vop_win_data),
> +	.regs_dump = rk3588_regs_dump,
> +	.regs_dump_size = ARRAY_SIZE(rk3588_regs_dump),
>  	.soc_id = 3588,
>  };
>  
> -- 
> 2.34.1
> 
> 
>
Sascha Hauer Dec. 11, 2023, 7:02 a.m. UTC | #6
On Thu, Dec 07, 2023 at 04:02:10PM +0800, Andy Yan wrote:
> From: Andy Yan <andy.yan@rock-chips.com>
> 
> VOP2 has multiple independent video ports with different
> feature, so rename VOP_FEATURE_OUTPUT_10BIT to
> VOP2_VP_FEATURE_OUTPUT_10BIT for more clearly meaning.
> 
> Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
> ---

Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>

Sascha

> 
> (no changes since v1)
> 
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 +-
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 2 +-
>  drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 8 ++++----
>  3 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> index edca7723335f..2b996f1a25ad 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> @@ -1995,7 +1995,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
>  		return;
>  
>  	if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
> -	    !(vp_data->feature & VOP_FEATURE_OUTPUT_10BIT))
> +	    !(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT))
>  		out_mode = ROCKCHIP_OUT_MODE_P888;
>  	else
>  		out_mode = vcstate->output_mode;
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
> index 2763e54350a9..615a16196aff 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
> @@ -11,7 +11,7 @@
>  #include <drm/drm_modes.h>
>  #include "rockchip_drm_vop.h"
>  
> -#define VOP_FEATURE_OUTPUT_10BIT        BIT(0)
> +#define VOP2_VP_FEATURE_OUTPUT_10BIT        BIT(0)
>  
>  #define VOP2_FEATURE_HAS_SYS_GRF	BIT(0)
>  #define VOP2_FEATURE_HAS_VO0_GRF	BIT(1)
> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
> index 275d265891db..48170694ac6b 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
> @@ -136,7 +136,7 @@ static const uint64_t format_modifiers_afbc[] = {
>  static const struct vop2_video_port_data rk3568_vop_video_ports[] = {
>  	{
>  		.id = 0,
> -		.feature = VOP_FEATURE_OUTPUT_10BIT,
> +		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
>  		.gamma_lut_len = 1024,
>  		.cubic_lut_len = 9 * 9 * 9,
>  		.max_output = { 4096, 2304 },
> @@ -263,7 +263,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
>  static const struct vop2_video_port_data rk3588_vop_video_ports[] = {
>  	{
>  		.id = 0,
> -		.feature = VOP_FEATURE_OUTPUT_10BIT,
> +		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
>  		.gamma_lut_len = 1024,
>  		.cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */
>  		.max_output = { 4096, 2304 },
> @@ -272,7 +272,7 @@ static const struct vop2_video_port_data rk3588_vop_video_ports[] = {
>  		.offset = 0xc00,
>  	}, {
>  		.id = 1,
> -		.feature = VOP_FEATURE_OUTPUT_10BIT,
> +		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
>  		.gamma_lut_len = 1024,
>  		.cubic_lut_len = 729, /* 9x9x9 */
>  		.max_output = { 4096, 2304 },
> @@ -280,7 +280,7 @@ static const struct vop2_video_port_data rk3588_vop_video_ports[] = {
>  		.offset = 0xd00,
>  	}, {
>  		.id = 2,
> -		.feature = VOP_FEATURE_OUTPUT_10BIT,
> +		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
>  		.gamma_lut_len = 1024,
>  		.cubic_lut_len = 17 * 17 * 17, /* 17x17x17 */
>  		.max_output = { 4096, 2304 },
> -- 
> 2.34.1
> 
> 
>