1d0408543SAndy Yan // SPDX-License-Identifier: GPL-2.0-only 2d0408543SAndy Yan /* 3d0408543SAndy Yan * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd 4d0408543SAndy Yan * 5d0408543SAndy Yan */ 6d0408543SAndy Yan 7d0408543SAndy Yan #include <config.h> 8d0408543SAndy Yan #include <common.h> 9d0408543SAndy Yan #include <errno.h> 10d0408543SAndy Yan #include <malloc.h> 11d0408543SAndy Yan #include <fdtdec.h> 12d0408543SAndy Yan #include <fdt_support.h> 13b890760eSAlgea Cao #include <regmap.h> 14feffd38eSSandy Huang #include <asm/arch/cpu.h> 15d0408543SAndy Yan #include <asm/unaligned.h> 16d0408543SAndy Yan #include <asm/io.h> 17d0408543SAndy Yan #include <linux/list.h> 18ecc31b6eSAndy Yan #include <linux/log2.h> 19d0408543SAndy Yan #include <linux/media-bus-format.h> 20d0408543SAndy Yan #include <clk.h> 21d0408543SAndy Yan #include <asm/arch/clock.h> 22d0408543SAndy Yan #include <linux/err.h> 231147facaSSandy Huang #include <linux/ioport.h> 24d0408543SAndy Yan #include <dm/device.h> 25d0408543SAndy Yan #include <dm/read.h> 265fa6e665SDamon Ding #include <dm/ofnode.h> 27ac500a1fSSandy Huang #include <fixp-arith.h> 28d0408543SAndy Yan #include <syscon.h> 2960e469f5SDamon Ding #include <linux/iopoll.h> 305f1357a2SZhang Yubing #include <dm/uclass-internal.h> 31d0408543SAndy Yan 32d0408543SAndy Yan #include "rockchip_display.h" 33d0408543SAndy Yan #include "rockchip_crtc.h" 34d0408543SAndy Yan #include "rockchip_connector.h" 35d0408543SAndy Yan 36d0408543SAndy Yan /* System registers definition */ 37d0408543SAndy Yan #define RK3568_REG_CFG_DONE 0x000 38d0408543SAndy Yan #define CFG_DONE_EN BIT(15) 39d0408543SAndy Yan 40d0408543SAndy Yan #define RK3568_VERSION_INFO 0x004 41d0408543SAndy Yan #define EN_MASK 1 42d0408543SAndy Yan 4363cb669fSSandy Huang #define RK3568_AUTO_GATING_CTRL 0x008 4463cb669fSSandy Huang 456414e3bcSSandy Huang #define RK3568_SYS_AXI_LUT_CTRL 0x024 466414e3bcSSandy Huang #define LUT_DMA_EN_SHIFT 0 476414e3bcSSandy Huang 48d0408543SAndy Yan #define RK3568_DSP_IF_EN 0x028 49d0408543SAndy Yan #define RGB_EN_SHIFT 0 50ecc31b6eSAndy Yan #define RK3588_DP0_EN_SHIFT 0 51ecc31b6eSAndy Yan #define RK3588_DP1_EN_SHIFT 1 52ecc31b6eSAndy Yan #define RK3588_RGB_EN_SHIFT 8 53d0408543SAndy Yan #define HDMI0_EN_SHIFT 1 54d0408543SAndy Yan #define EDP0_EN_SHIFT 3 55ecc31b6eSAndy Yan #define RK3588_EDP0_EN_SHIFT 2 56ecc31b6eSAndy Yan #define RK3588_HDMI0_EN_SHIFT 3 57d0408543SAndy Yan #define MIPI0_EN_SHIFT 4 58ecc31b6eSAndy Yan #define RK3588_EDP1_EN_SHIFT 4 59ecc31b6eSAndy Yan #define RK3588_HDMI1_EN_SHIFT 5 60ecc31b6eSAndy Yan #define RK3588_MIPI0_EN_SHIFT 6 61d0408543SAndy Yan #define MIPI1_EN_SHIFT 20 62ecc31b6eSAndy Yan #define RK3588_MIPI1_EN_SHIFT 7 63d0408543SAndy Yan #define LVDS0_EN_SHIFT 5 64d0408543SAndy Yan #define LVDS1_EN_SHIFT 24 65d0408543SAndy Yan #define BT1120_EN_SHIFT 6 66d0408543SAndy Yan #define BT656_EN_SHIFT 7 67d0408543SAndy Yan #define IF_MUX_MASK 3 68d0408543SAndy Yan #define RGB_MUX_SHIFT 8 69d0408543SAndy Yan #define HDMI0_MUX_SHIFT 10 70ecc31b6eSAndy Yan #define RK3588_DP0_MUX_SHIFT 12 71ecc31b6eSAndy Yan #define RK3588_DP1_MUX_SHIFT 14 72d0408543SAndy Yan #define EDP0_MUX_SHIFT 14 73ecc31b6eSAndy Yan #define RK3588_HDMI_EDP0_MUX_SHIFT 16 74ecc31b6eSAndy Yan #define RK3588_HDMI_EDP1_MUX_SHIFT 18 75d0408543SAndy Yan #define MIPI0_MUX_SHIFT 16 76ecc31b6eSAndy Yan #define RK3588_MIPI0_MUX_SHIFT 20 77d0408543SAndy Yan #define MIPI1_MUX_SHIFT 21 7811f53190SSandy Huang #define LVDS0_MUX_SHIFT 18 79d0408543SAndy Yan #define LVDS1_MUX_SHIFT 25 80d0408543SAndy Yan 81d0408543SAndy Yan #define RK3568_DSP_IF_CTRL 0x02c 82d0408543SAndy Yan #define LVDS_DUAL_EN_SHIFT 0 83d0408543SAndy Yan #define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT 1 84d0408543SAndy Yan #define LVDS_DUAL_SWAP_EN_SHIFT 2 855fa6e665SDamon Ding #define BT656_UV_SWAP 4 865fa6e665SDamon Ding #define BT656_YC_SWAP 5 875fa6e665SDamon Ding #define BT656_DCLK_POL 6 880a1fb152SZhang Yubing #define RK3588_HDMI_DUAL_EN_SHIFT 8 890a1fb152SZhang Yubing #define RK3588_EDP_DUAL_EN_SHIFT 8 900a1fb152SZhang Yubing #define RK3588_DP_DUAL_EN_SHIFT 9 9141874944SGuochun Huang #define RK3568_MIPI_DUAL_EN_SHIFT 10 9241874944SGuochun Huang #define RK3588_MIPI_DSI0_MODE_SEL_SHIFT 11 9341874944SGuochun Huang #define RK3588_MIPI_DSI1_MODE_SEL_SHIFT 12 9441874944SGuochun Huang 95d0408543SAndy Yan #define RK3568_DSP_IF_POL 0x030 96d0408543SAndy Yan #define IF_CTRL_REG_DONE_IMD_MASK 1 97d0408543SAndy Yan #define IF_CTRL_REG_DONE_IMD_SHIFT 28 98d0408543SAndy Yan #define IF_CRTL_MIPI_DCLK_POL_SHIT 19 99d0408543SAndy Yan #define IF_CRTL_EDP_DCLK_POL_SHIT 15 100d0408543SAndy Yan #define IF_CRTL_HDMI_DCLK_POL_SHIT 7 10110ee9f5bSAlgea Cao #define IF_CRTL_HDMI_PIN_POL_MASK 0x7 10210ee9f5bSAlgea Cao #define IF_CRTL_HDMI_PIN_POL_SHIT 4 103ecc31b6eSAndy Yan 104ecc31b6eSAndy Yan #define RK3588_DP0_PIN_POL_SHIFT 8 105ecc31b6eSAndy Yan #define RK3588_DP1_PIN_POL_SHIFT 12 106ecc31b6eSAndy Yan #define RK3588_IF_PIN_POL_MASK 0x7 107ecc31b6eSAndy Yan 108d0408543SAndy Yan #define IF_CRTL_RGB_LVDS_DCLK_POL_SHIT 3 109ecc31b6eSAndy Yan 110ecc31b6eSAndy Yan #define HDMI_EDP0_DCLK_DIV_SHIFT 16 111ecc31b6eSAndy Yan #define HDMI_EDP0_PIXCLK_DIV_SHIFT 18 112ecc31b6eSAndy Yan #define HDMI_EDP1_DCLK_DIV_SHIFT 20 113ecc31b6eSAndy Yan #define HDMI_EDP1_PIXCLK_DIV_SHIFT 22 114ecc31b6eSAndy Yan #define MIPI0_PIXCLK_DIV_SHIFT 24 115ecc31b6eSAndy Yan #define MIPI1_PIXCLK_DIV_SHIFT 26 116ecc31b6eSAndy Yan 117feffd38eSSandy Huang #define RK3568_SYS_OTP_WIN_EN 0x50 118feffd38eSSandy Huang #define OTP_WIN_EN_SHIFT 0 1191147facaSSandy Huang #define RK3568_SYS_LUT_PORT_SEL 0x58 1201147facaSSandy Huang #define GAMMA_PORT_SEL_MASK 0x3 1211147facaSSandy Huang #define GAMMA_PORT_SEL_SHIFT 0 122db328a0dSDamon Ding #define GAMMA_AHB_WRITE_SEL_MASK 0x3 123db328a0dSDamon Ding #define GAMMA_AHB_WRITE_SEL_SHIFT 12 124ee01dbb2SDamon Ding #define PORT_MERGE_EN_SHIFT 16 1255fa6e665SDamon Ding #define ESMART_LB_MODE_SEL_MASK 0x3 1265fa6e665SDamon Ding #define ESMART_LB_MODE_SEL_SHIFT 26 1271147facaSSandy Huang 128ecc31b6eSAndy Yan #define RK3568_SYS_PD_CTRL 0x034 129d0408543SAndy Yan #define RK3568_VP0_LINE_FLAG 0x70 130d0408543SAndy Yan #define RK3568_VP1_LINE_FLAG 0x74 131d0408543SAndy Yan #define RK3568_VP2_LINE_FLAG 0x78 132d0408543SAndy Yan #define RK3568_SYS0_INT_EN 0x80 133d0408543SAndy Yan #define RK3568_SYS0_INT_CLR 0x84 134d0408543SAndy Yan #define RK3568_SYS0_INT_STATUS 0x88 135d0408543SAndy Yan #define RK3568_SYS1_INT_EN 0x90 136d0408543SAndy Yan #define RK3568_SYS1_INT_CLR 0x94 137d0408543SAndy Yan #define RK3568_SYS1_INT_STATUS 0x98 138d0408543SAndy Yan #define RK3568_VP0_INT_EN 0xA0 139d0408543SAndy Yan #define RK3568_VP0_INT_CLR 0xA4 140d0408543SAndy Yan #define RK3568_VP0_INT_STATUS 0xA8 141d0408543SAndy Yan #define RK3568_VP1_INT_EN 0xB0 142d0408543SAndy Yan #define RK3568_VP1_INT_CLR 0xB4 143d0408543SAndy Yan #define RK3568_VP1_INT_STATUS 0xB8 144d0408543SAndy Yan #define RK3568_VP2_INT_EN 0xC0 145d0408543SAndy Yan #define RK3568_VP2_INT_CLR 0xC4 146d0408543SAndy Yan #define RK3568_VP2_INT_STATUS 0xC8 14760e469f5SDamon Ding #define RK3588_CLUSTER0_PD_EN_SHIFT 0 14860e469f5SDamon Ding #define RK3588_CLUSTER1_PD_EN_SHIFT 1 14960e469f5SDamon Ding #define RK3588_CLUSTER2_PD_EN_SHIFT 2 15060e469f5SDamon Ding #define RK3588_CLUSTER3_PD_EN_SHIFT 3 151b6ba80b4SDamon Ding #define RK3588_DSC_8K_PD_EN_SHIFT 5 152b6ba80b4SDamon Ding #define RK3588_DSC_4K_PD_EN_SHIFT 6 15360e469f5SDamon Ding #define RK3588_ESMART_PD_EN_SHIFT 7 15460e469f5SDamon Ding 15560e469f5SDamon Ding #define RK3568_SYS_STATUS0 0x60 15660e469f5SDamon Ding #define RK3588_CLUSTER0_PD_STATUS_SHIFT 8 15760e469f5SDamon Ding #define RK3588_CLUSTER1_PD_STATUS_SHIFT 9 15860e469f5SDamon Ding #define RK3588_CLUSTER2_PD_STATUS_SHIFT 10 15960e469f5SDamon Ding #define RK3588_CLUSTER3_PD_STATUS_SHIFT 11 160b6ba80b4SDamon Ding #define RK3588_DSC_8K_PD_STATUS_SHIFT 13 161b6ba80b4SDamon Ding #define RK3588_DSC_4K_PD_STATUS_SHIFT 14 16260e469f5SDamon Ding #define RK3588_ESMART_PD_STATUS_SHIFT 15 163d0408543SAndy Yan 16466724b9cSDamon Ding #define RK3568_SYS_CTRL_LINE_FLAG0 0x70 16566724b9cSDamon Ding #define LINE_FLAG_NUM_MASK 0x1fff 16666724b9cSDamon Ding #define RK3568_DSP_LINE_FLAG_NUM0_SHIFT 0 16766724b9cSDamon Ding #define RK3568_DSP_LINE_FLAG_NUM1_SHIFT 16 16866724b9cSDamon Ding 16912ee5af0SDamon Ding /* DSC CTRL registers definition */ 17012ee5af0SDamon Ding #define RK3588_DSC_8K_SYS_CTRL 0x200 17112ee5af0SDamon Ding #define DSC_PORT_SEL_MASK 0x3 17212ee5af0SDamon Ding #define DSC_PORT_SEL_SHIFT 0 17312ee5af0SDamon Ding #define DSC_MAN_MODE_MASK 0x1 17412ee5af0SDamon Ding #define DSC_MAN_MODE_SHIFT 2 17512ee5af0SDamon Ding #define DSC_INTERFACE_MODE_MASK 0x3 17612ee5af0SDamon Ding #define DSC_INTERFACE_MODE_SHIFT 4 17712ee5af0SDamon Ding #define DSC_PIXEL_NUM_MASK 0x3 17812ee5af0SDamon Ding #define DSC_PIXEL_NUM_SHIFT 6 17912ee5af0SDamon Ding #define DSC_PXL_CLK_DIV_MASK 0x1 18012ee5af0SDamon Ding #define DSC_PXL_CLK_DIV_SHIFT 8 18112ee5af0SDamon Ding #define DSC_CDS_CLK_DIV_MASK 0x3 18212ee5af0SDamon Ding #define DSC_CDS_CLK_DIV_SHIFT 12 18312ee5af0SDamon Ding #define DSC_TXP_CLK_DIV_MASK 0x3 18412ee5af0SDamon Ding #define DSC_TXP_CLK_DIV_SHIFT 14 18512ee5af0SDamon Ding #define DSC_INIT_DLY_MODE_MASK 0x1 18612ee5af0SDamon Ding #define DSC_INIT_DLY_MODE_SHIFT 16 18712ee5af0SDamon Ding #define DSC_SCAN_EN_SHIFT 17 18812ee5af0SDamon Ding #define DSC_HALT_EN_SHIFT 18 18912ee5af0SDamon Ding 19012ee5af0SDamon Ding #define RK3588_DSC_8K_RST 0x204 19112ee5af0SDamon Ding #define RST_DEASSERT_MASK 0x1 19212ee5af0SDamon Ding #define RST_DEASSERT_SHIFT 0 19312ee5af0SDamon Ding 19412ee5af0SDamon Ding #define RK3588_DSC_8K_CFG_DONE 0x208 19512ee5af0SDamon Ding #define DSC_CFG_DONE_SHIFT 0 19612ee5af0SDamon Ding 19712ee5af0SDamon Ding #define RK3588_DSC_8K_INIT_DLY 0x20C 19812ee5af0SDamon Ding #define DSC_INIT_DLY_NUM_MASK 0xffff 19912ee5af0SDamon Ding #define DSC_INIT_DLY_NUM_SHIFT 0 20012ee5af0SDamon Ding #define SCAN_TIMING_PARA_IMD_EN_SHIFT 16 20112ee5af0SDamon Ding 20212ee5af0SDamon Ding #define RK3588_DSC_8K_HTOTAL_HS_END 0x210 20312ee5af0SDamon Ding #define DSC_HTOTAL_PW_MASK 0xffffffff 20412ee5af0SDamon Ding #define DSC_HTOTAL_PW_SHIFT 0 20512ee5af0SDamon Ding 20612ee5af0SDamon Ding #define RK3588_DSC_8K_HACT_ST_END 0x214 20712ee5af0SDamon Ding #define DSC_HACT_ST_END_MASK 0xffffffff 20812ee5af0SDamon Ding #define DSC_HACT_ST_END_SHIFT 0 20912ee5af0SDamon Ding 21012ee5af0SDamon Ding #define RK3588_DSC_8K_VTOTAL_VS_END 0x218 21112ee5af0SDamon Ding #define DSC_VTOTAL_PW_MASK 0xffffffff 21212ee5af0SDamon Ding #define DSC_VTOTAL_PW_SHIFT 0 21312ee5af0SDamon Ding 21412ee5af0SDamon Ding #define RK3588_DSC_8K_VACT_ST_END 0x21C 21512ee5af0SDamon Ding #define DSC_VACT_ST_END_MASK 0xffffffff 21612ee5af0SDamon Ding #define DSC_VACT_ST_END_SHIFT 0 21712ee5af0SDamon Ding 21812ee5af0SDamon Ding #define RK3588_DSC_8K_STATUS 0x220 21912ee5af0SDamon Ding 22063cb669fSSandy Huang /* Overlay registers definition */ 2215fa6e665SDamon Ding #define RK3528_OVL_SYS 0x500 2225fa6e665SDamon Ding #define RK3528_OVL_SYS_PORT_SEL_IMD 0x504 2235fa6e665SDamon Ding #define RK3528_OVL_SYS_GATING_EN_IMD 0x508 2245fa6e665SDamon Ding #define RK3528_OVL_SYS_CLUSTER0_CTRL 0x510 2255fa6e665SDamon Ding #define RK3528_OVL_SYS_ESMART0_CTRL 0x520 2265fa6e665SDamon Ding #define RK3528_OVL_SYS_ESMART1_CTRL 0x524 2275fa6e665SDamon Ding #define RK3528_OVL_SYS_ESMART2_CTRL 0x528 2285fa6e665SDamon Ding #define RK3528_OVL_SYS_ESMART3_CTRL 0x52C 2295fa6e665SDamon Ding #define RK3528_CLUSTER0_MIX_SRC_COLOR_CTRL 0x530 2305fa6e665SDamon Ding #define RK3528_CLUSTER0_MIX_DST_COLOR_CTRL 0x534 2315fa6e665SDamon Ding #define RK3528_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x538 2325fa6e665SDamon Ding #define RK3528_CLUSTER0_MIX_DST_ALPHA_CTRL 0x53c 2335fa6e665SDamon Ding 2345fa6e665SDamon Ding #define RK3528_OVL_PORT0_CTRL 0x600 23563cb669fSSandy Huang #define RK3568_OVL_CTRL 0x600 236ee01dbb2SDamon Ding #define OVL_MODE_SEL_MASK 0x1 237ee01dbb2SDamon Ding #define OVL_MODE_SEL_SHIFT 0 23863cb669fSSandy Huang #define OVL_PORT_MUX_REG_DONE_IMD_SHIFT 28 2395fa6e665SDamon Ding #define RK3528_OVL_PORT0_LAYER_SEL 0x604 24063cb669fSSandy Huang #define RK3568_OVL_LAYER_SEL 0x604 24163cb669fSSandy Huang #define LAYER_SEL_MASK 0xf 24263cb669fSSandy Huang 24363cb669fSSandy Huang #define RK3568_OVL_PORT_SEL 0x608 24463cb669fSSandy Huang #define PORT_MUX_MASK 0xf 24563cb669fSSandy Huang #define PORT_MUX_SHIFT 0 24663cb669fSSandy Huang #define LAYER_SEL_PORT_MASK 0x3 24763cb669fSSandy Huang #define LAYER_SEL_PORT_SHIFT 16 24863cb669fSSandy Huang 24963cb669fSSandy Huang #define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL 0x610 25063cb669fSSandy Huang #define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL 0x614 25163cb669fSSandy Huang #define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x618 25263cb669fSSandy Huang #define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL 0x61C 2535fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX0_SRC_COLOR_CTRL 0x620 2545fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX0_DST_COLOR_CTRL 0x624 2555fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX0_SRC_ALPHA_CTRL 0x628 2565fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX0_DST_ALPHA_CTRL 0x62C 2575fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX1_SRC_COLOR_CTRL 0x630 2585fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX1_DST_COLOR_CTRL 0x634 2595fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX1_SRC_ALPHA_CTRL 0x638 2605fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX1_DST_ALPHA_CTRL 0x63C 2615fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX2_SRC_COLOR_CTRL 0x640 2625fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX2_DST_COLOR_CTRL 0x644 2635fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX2_SRC_ALPHA_CTRL 0x648 2645fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX2_DST_ALPHA_CTRL 0x64C 26563cb669fSSandy Huang #define RK3568_MIX0_SRC_COLOR_CTRL 0x650 26663cb669fSSandy Huang #define RK3568_MIX0_DST_COLOR_CTRL 0x654 26763cb669fSSandy Huang #define RK3568_MIX0_SRC_ALPHA_CTRL 0x658 26863cb669fSSandy Huang #define RK3568_MIX0_DST_ALPHA_CTRL 0x65C 2695fa6e665SDamon Ding #define RK3528_HDR_SRC_COLOR_CTRL 0x660 2705fa6e665SDamon Ding #define RK3528_HDR_DST_COLOR_CTRL 0x664 2715fa6e665SDamon Ding #define RK3528_HDR_SRC_ALPHA_CTRL 0x668 2725fa6e665SDamon Ding #define RK3528_HDR_DST_ALPHA_CTRL 0x66C 2735fa6e665SDamon Ding #define RK3528_OVL_PORT0_BG_MIX_CTRL 0x670 27463cb669fSSandy Huang #define RK3568_HDR0_SRC_COLOR_CTRL 0x6C0 27563cb669fSSandy Huang #define RK3568_HDR0_DST_COLOR_CTRL 0x6C4 27663cb669fSSandy Huang #define RK3568_HDR0_SRC_ALPHA_CTRL 0x6C8 27763cb669fSSandy Huang #define RK3568_HDR0_DST_ALPHA_CTRL 0x6CC 27863cb669fSSandy Huang #define RK3568_VP0_BG_MIX_CTRL 0x6E0 27963cb669fSSandy Huang #define BG_MIX_CTRL_MASK 0xff 28063cb669fSSandy Huang #define BG_MIX_CTRL_SHIFT 24 28163cb669fSSandy Huang #define RK3568_VP1_BG_MIX_CTRL 0x6E4 28263cb669fSSandy Huang #define RK3568_VP2_BG_MIX_CTRL 0x6E8 28363cb669fSSandy Huang #define RK3568_CLUSTER_DLY_NUM 0x6F0 28463cb669fSSandy Huang #define RK3568_SMART_DLY_NUM 0x6F8 28563cb669fSSandy Huang 2865fa6e665SDamon Ding #define RK3528_OVL_PORT1_CTRL 0x700 2875fa6e665SDamon Ding #define RK3528_OVL_PORT1_LAYER_SEL 0x704 2885fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX0_SRC_COLOR_CTRL 0x720 2895fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX0_DST_COLOR_CTRL 0x724 2905fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX0_SRC_ALPHA_CTRL 0x728 2915fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX0_DST_ALPHA_CTRL 0x72C 2925fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX1_SRC_COLOR_CTRL 0x730 2935fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX1_DST_COLOR_CTRL 0x734 2945fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX1_SRC_ALPHA_CTRL 0x738 2955fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX1_DST_ALPHA_CTRL 0x73C 2965fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX2_SRC_COLOR_CTRL 0x740 2975fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX2_DST_COLOR_CTRL 0x744 2985fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX2_SRC_ALPHA_CTRL 0x748 2995fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX2_DST_ALPHA_CTRL 0x74C 3005fa6e665SDamon Ding #define RK3528_OVL_PORT1_BG_MIX_CTRL 0x770 3015fa6e665SDamon Ding 302d0408543SAndy Yan /* Video Port registers definition */ 303d0408543SAndy Yan #define RK3568_VP0_DSP_CTRL 0xC00 304d0408543SAndy Yan #define OUT_MODE_MASK 0xf 305d0408543SAndy Yan #define OUT_MODE_SHIFT 0 30610ee9f5bSAlgea Cao #define DATA_SWAP_MASK 0x1f 30710ee9f5bSAlgea Cao #define DATA_SWAP_SHIFT 8 30865747de7SDamon Ding #define DSP_BG_SWAP 0x1 30965747de7SDamon Ding #define DSP_RB_SWAP 0x2 31065747de7SDamon Ding #define DSP_RG_SWAP 0x4 31165747de7SDamon Ding #define DSP_DELTA_SWAP 0x8 31210ee9f5bSAlgea Cao #define CORE_DCLK_DIV_EN_SHIFT 4 313d0408543SAndy Yan #define P2I_EN_SHIFT 5 3147a20be36SSandy Huang #define DSP_FILED_POL 6 315d0408543SAndy Yan #define INTERLACE_EN_SHIFT 7 316c2b1fe35SDamon Ding #define DSP_X_MIR_EN_SHIFT 13 31710ee9f5bSAlgea Cao #define POST_DSP_OUT_R2Y_SHIFT 15 318d0408543SAndy Yan #define PRE_DITHER_DOWN_EN_SHIFT 16 319d0408543SAndy Yan #define DITHER_DOWN_EN_SHIFT 17 320db328a0dSDamon Ding #define GAMMA_UPDATE_EN_SHIFT 22 3211147facaSSandy Huang #define DSP_LUT_EN_SHIFT 28 3221147facaSSandy Huang 323d0408543SAndy Yan #define STANDBY_EN_SHIFT 31 324d0408543SAndy Yan 325d0408543SAndy Yan #define RK3568_VP0_MIPI_CTRL 0xC04 32610ee9f5bSAlgea Cao #define DCLK_DIV2_SHIFT 4 32710ee9f5bSAlgea Cao #define DCLK_DIV2_MASK 0x3 328d0408543SAndy Yan #define MIPI_DUAL_EN_SHIFT 20 329d0408543SAndy Yan #define MIPI_DUAL_SWAP_EN_SHIFT 21 33041874944SGuochun Huang #define EDPI_TE_EN 28 33141874944SGuochun Huang #define EDPI_WMS_HOLD_EN 30 33241874944SGuochun Huang #define EDPI_WMS_FS 31 33341874944SGuochun Huang 334d0408543SAndy Yan 335d0408543SAndy Yan #define RK3568_VP0_COLOR_BAR_CTRL 0xC08 3365fa6e665SDamon Ding 3375fa6e665SDamon Ding #define RK3568_VP0_DCLK_SEL 0xC0C 3385fa6e665SDamon Ding 3396414e3bcSSandy Huang #define RK3568_VP0_3D_LUT_CTRL 0xC10 3406414e3bcSSandy Huang #define VP0_3D_LUT_EN_SHIFT 0 3416414e3bcSSandy Huang #define VP0_3D_LUT_UPDATE_SHIFT 2 3426414e3bcSSandy Huang 343ecc31b6eSAndy Yan #define RK3588_VP0_CLK_CTRL 0xC0C 344ecc31b6eSAndy Yan #define DCLK_CORE_DIV_SHIFT 0 345ecc31b6eSAndy Yan #define DCLK_OUT_DIV_SHIFT 2 346ecc31b6eSAndy Yan 3476414e3bcSSandy Huang #define RK3568_VP0_3D_LUT_MST 0xC20 3486414e3bcSSandy Huang 349d0408543SAndy Yan #define RK3568_VP0_DSP_BG 0xC2C 350d0408543SAndy Yan #define RK3568_VP0_PRE_SCAN_HTIMING 0xC30 351d0408543SAndy Yan #define RK3568_VP0_POST_DSP_HACT_INFO 0xC34 352d0408543SAndy Yan #define RK3568_VP0_POST_DSP_VACT_INFO 0xC38 353d0408543SAndy Yan #define RK3568_VP0_POST_SCL_FACTOR_YRGB 0xC3C 354d0408543SAndy Yan #define RK3568_VP0_POST_SCL_CTRL 0xC40 355d0408543SAndy Yan #define RK3568_VP0_POST_DSP_VACT_INFO_F1 0xC44 356d0408543SAndy Yan #define RK3568_VP0_DSP_HTOTAL_HS_END 0xC48 357d0408543SAndy Yan #define RK3568_VP0_DSP_HACT_ST_END 0xC4C 358d0408543SAndy Yan #define RK3568_VP0_DSP_VTOTAL_VS_END 0xC50 359d0408543SAndy Yan #define RK3568_VP0_DSP_VACT_ST_END 0xC54 360d0408543SAndy Yan #define RK3568_VP0_DSP_VS_ST_END_F1 0xC58 361d0408543SAndy Yan #define RK3568_VP0_DSP_VACT_ST_END_F1 0xC5C 362d0408543SAndy Yan 363ac500a1fSSandy Huang #define RK3568_VP0_BCSH_CTRL 0xC60 364ac500a1fSSandy Huang #define BCSH_CTRL_Y2R_SHIFT 0 365ac500a1fSSandy Huang #define BCSH_CTRL_Y2R_MASK 0x1 366ac500a1fSSandy Huang #define BCSH_CTRL_Y2R_CSC_MODE_SHIFT 2 367ac500a1fSSandy Huang #define BCSH_CTRL_Y2R_CSC_MODE_MASK 0x3 368ac500a1fSSandy Huang #define BCSH_CTRL_R2Y_SHIFT 4 369ac500a1fSSandy Huang #define BCSH_CTRL_R2Y_MASK 0x1 370ac500a1fSSandy Huang #define BCSH_CTRL_R2Y_CSC_MODE_SHIFT 6 371ac500a1fSSandy Huang #define BCSH_CTRL_R2Y_CSC_MODE_MASK 0x3 372ac500a1fSSandy Huang 373ac500a1fSSandy Huang #define RK3568_VP0_BCSH_BCS 0xC64 374ac500a1fSSandy Huang #define BCSH_BRIGHTNESS_SHIFT 0 375ac500a1fSSandy Huang #define BCSH_BRIGHTNESS_MASK 0xFF 376ac500a1fSSandy Huang #define BCSH_CONTRAST_SHIFT 8 377ac500a1fSSandy Huang #define BCSH_CONTRAST_MASK 0x1FF 378ac500a1fSSandy Huang #define BCSH_SATURATION_SHIFT 20 379ac500a1fSSandy Huang #define BCSH_SATURATION_MASK 0x3FF 380ac500a1fSSandy Huang #define BCSH_OUT_MODE_SHIFT 30 381ac500a1fSSandy Huang #define BCSH_OUT_MODE_MASK 0x3 382ac500a1fSSandy Huang 383ac500a1fSSandy Huang #define RK3568_VP0_BCSH_H 0xC68 384ac500a1fSSandy Huang #define BCSH_SIN_HUE_SHIFT 0 385ac500a1fSSandy Huang #define BCSH_SIN_HUE_MASK 0x1FF 386ac500a1fSSandy Huang #define BCSH_COS_HUE_SHIFT 16 387ac500a1fSSandy Huang #define BCSH_COS_HUE_MASK 0x1FF 388ac500a1fSSandy Huang 389ac500a1fSSandy Huang #define RK3568_VP0_BCSH_COLOR 0xC6C 390ac500a1fSSandy Huang #define BCSH_EN_SHIFT 31 391ac500a1fSSandy Huang #define BCSH_EN_MASK 1 392ac500a1fSSandy Huang 393d0408543SAndy Yan #define RK3568_VP1_DSP_CTRL 0xD00 394d0408543SAndy Yan #define RK3568_VP1_MIPI_CTRL 0xD04 395d0408543SAndy Yan #define RK3568_VP1_COLOR_BAR_CTRL 0xD08 396d0408543SAndy Yan #define RK3568_VP1_PRE_SCAN_HTIMING 0xD30 397d0408543SAndy Yan #define RK3568_VP1_POST_DSP_HACT_INFO 0xD34 398d0408543SAndy Yan #define RK3568_VP1_POST_DSP_VACT_INFO 0xD38 399d0408543SAndy Yan #define RK3568_VP1_POST_SCL_FACTOR_YRGB 0xD3C 400d0408543SAndy Yan #define RK3568_VP1_POST_SCL_CTRL 0xD40 401d0408543SAndy Yan #define RK3568_VP1_DSP_HACT_INFO 0xD34 402d0408543SAndy Yan #define RK3568_VP1_DSP_VACT_INFO 0xD38 403d0408543SAndy Yan #define RK3568_VP1_POST_DSP_VACT_INFO_F1 0xD44 404d0408543SAndy Yan #define RK3568_VP1_DSP_HTOTAL_HS_END 0xD48 405d0408543SAndy Yan #define RK3568_VP1_DSP_HACT_ST_END 0xD4C 406d0408543SAndy Yan #define RK3568_VP1_DSP_VTOTAL_VS_END 0xD50 407d0408543SAndy Yan #define RK3568_VP1_DSP_VACT_ST_END 0xD54 408d0408543SAndy Yan #define RK3568_VP1_DSP_VS_ST_END_F1 0xD58 409d0408543SAndy Yan #define RK3568_VP1_DSP_VACT_ST_END_F1 0xD5C 410d0408543SAndy Yan 411d0408543SAndy Yan #define RK3568_VP2_DSP_CTRL 0xE00 412d0408543SAndy Yan #define RK3568_VP2_MIPI_CTRL 0xE04 413d0408543SAndy Yan #define RK3568_VP2_COLOR_BAR_CTRL 0xE08 414d0408543SAndy Yan #define RK3568_VP2_PRE_SCAN_HTIMING 0xE30 415d0408543SAndy Yan #define RK3568_VP2_POST_DSP_HACT_INFO 0xE34 416d0408543SAndy Yan #define RK3568_VP2_POST_DSP_VACT_INFO 0xE38 417d0408543SAndy Yan #define RK3568_VP2_POST_SCL_FACTOR_YRGB 0xE3C 418d0408543SAndy Yan #define RK3568_VP2_POST_SCL_CTRL 0xE40 419d0408543SAndy Yan #define RK3568_VP2_DSP_HACT_INFO 0xE34 420d0408543SAndy Yan #define RK3568_VP2_DSP_VACT_INFO 0xE38 421d0408543SAndy Yan #define RK3568_VP2_POST_DSP_VACT_INFO_F1 0xE44 422d0408543SAndy Yan #define RK3568_VP2_DSP_HTOTAL_HS_END 0xE48 423d0408543SAndy Yan #define RK3568_VP2_DSP_HACT_ST_END 0xE4C 424d0408543SAndy Yan #define RK3568_VP2_DSP_VTOTAL_VS_END 0xE50 425d0408543SAndy Yan #define RK3568_VP2_DSP_VACT_ST_END 0xE54 426d0408543SAndy Yan #define RK3568_VP2_DSP_VS_ST_END_F1 0xE58 427d0408543SAndy Yan #define RK3568_VP2_DSP_VACT_ST_END_F1 0xE5C 428d0408543SAndy Yan 429d0408543SAndy Yan /* Cluster0 register definition */ 430d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_CTRL0 0x1000 431ecc31b6eSAndy Yan #define CLUSTER_YUV2RGB_EN_SHIFT 8 432ecc31b6eSAndy Yan #define CLUSTER_RGB2YUV_EN_SHIFT 9 433ecc31b6eSAndy Yan #define CLUSTER_CSC_MODE_SHIFT 10 434d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_CTRL1 0x1004 4355fa6e665SDamon Ding #define RK3568_CLUSTER_YRGB_XSCL_MODE_SHIFT 12 4365fa6e665SDamon Ding #define RK3568_CLUSTER_YRGB_YSCL_MODE_SHIFT 14 4375fa6e665SDamon Ding #define RK3528_CLUSTER_YRGB_YSCL_MODE_SHIFT 14 4385fa6e665SDamon Ding #define AVG2_MASK 0x1 4395fa6e665SDamon Ding #define CLUSTER_AVG2_SHIFT 18 4405fa6e665SDamon Ding #define AVG4_MASK 0x1 4415fa6e665SDamon Ding #define CLUSTER_AVG4_SHIFT 19 4425fa6e665SDamon Ding #define RK3528_CLUSTER_YRGB_XSCL_MODE_SHIFT 22 4435fa6e665SDamon Ding #define CLUSTER_XGT_EN_SHIFT 24 4445fa6e665SDamon Ding #define XGT_MODE_MASK 0x3 4455fa6e665SDamon Ding #define CLUSTER_XGT_MODE_SHIFT 25 4465fa6e665SDamon Ding #define CLUSTER_XAVG_EN_SHIFT 27 447ecc31b6eSAndy Yan #define CLUSTER_YRGB_GT2_SHIFT 28 448ecc31b6eSAndy Yan #define CLUSTER_YRGB_GT4_SHIFT 29 449a33b790fSDamon Ding #define RK3568_CLUSTER0_WIN0_CTRL2 0x1008 450a33b790fSDamon Ding #define CLUSTER_AXI_YRGB_ID_MASK 0x1f 451a33b790fSDamon Ding #define CLUSTER_AXI_YRGB_ID_SHIFT 0 452a33b790fSDamon Ding #define CLUSTER_AXI_UV_ID_MASK 0x1f 453a33b790fSDamon Ding #define CLUSTER_AXI_UV_ID_SHIFT 5 454a33b790fSDamon Ding 455d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_YRGB_MST 0x1010 456d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_CBR_MST 0x1014 457d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_VIR 0x1018 458d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_ACT_INFO 0x1020 459d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_DSP_INFO 0x1024 460d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_DSP_ST 0x1028 461d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB 0x1030 462d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_ROTATE_MODE 0x1054 463d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_HDR_PTR 0x1058 464d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_VIR_WIDTH 0x105C 465d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_SIZE 0x1060 466d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_OFFSET 0x1064 467d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_DSP_OFFSET 0x1068 468d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_CTRL 0x106C 469d0408543SAndy Yan 470d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_CTRL0 0x1080 471d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_CTRL1 0x1084 472d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_YRGB_MST 0x1090 473d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_CBR_MST 0x1094 474d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_VIR 0x1098 475d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_ACT_INFO 0x10A0 476d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_DSP_INFO 0x10A4 477d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_DSP_ST 0x10A8 478d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_SCL_FACTOR_YRGB 0x10B0 479d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_ROTATE_MODE 0x10D4 480d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_HDR_PTR 0x10D8 481d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_VIR_WIDTH 0x10DC 482d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_SIZE 0x10E0 483d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_OFFSET 0x10E4 484d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_DSP_OFFSET 0x10E8 485d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_CTRL 0x10EC 486d0408543SAndy Yan 487d0408543SAndy Yan #define RK3568_CLUSTER0_CTRL 0x1100 488ecc31b6eSAndy Yan #define CLUSTER_EN_SHIFT 0 489a33b790fSDamon Ding #define CLUSTER_AXI_ID_MASK 0x1 490a33b790fSDamon Ding #define CLUSTER_AXI_ID_SHIFT 13 491d0408543SAndy Yan 492d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_CTRL0 0x1200 493d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_CTRL1 0x1204 494d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_YRGB_MST 0x1210 495d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_CBR_MST 0x1214 496d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_VIR 0x1218 497d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_ACT_INFO 0x1220 498d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_DSP_INFO 0x1224 499d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_DSP_ST 0x1228 500d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_SCL_FACTOR_YRGB 0x1230 501d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_ROTATE_MODE 0x1254 502d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_HDR_PTR 0x1258 503d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_VIR_WIDTH 0x125C 504d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_SIZE 0x1260 505d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_OFFSET 0x1264 506d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_DSP_OFFSET 0x1268 507d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_CTRL 0x126C 508d0408543SAndy Yan 509d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_CTRL0 0x1280 510d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_CTRL1 0x1284 511d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_YRGB_MST 0x1290 512d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_CBR_MST 0x1294 513d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_VIR 0x1298 514d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_ACT_INFO 0x12A0 515d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_DSP_INFO 0x12A4 516d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_DSP_ST 0x12A8 517d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_SCL_FACTOR_YRGB 0x12B0 518d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_ROTATE_MODE 0x12D4 519d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_HDR_PTR 0x12D8 520d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_VIR_WIDTH 0x12DC 521d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_SIZE 0x12E0 522d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_OFFSET 0x12E4 523d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_DSP_OFFSET 0x12E8 524d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_CTRL 0x12EC 525d0408543SAndy Yan 526d0408543SAndy Yan #define RK3568_CLUSTER1_CTRL 0x1300 527d0408543SAndy Yan 528d0408543SAndy Yan /* Esmart register definition */ 529d0408543SAndy Yan #define RK3568_ESMART0_CTRL0 0x1800 53010ee9f5bSAlgea Cao #define RGB2YUV_EN_SHIFT 1 53110ee9f5bSAlgea Cao #define CSC_MODE_SHIFT 2 53210ee9f5bSAlgea Cao #define CSC_MODE_MASK 0x3 5335fa6e665SDamon Ding #define ESMART_LB_SELECT_SHIFT 12 5345fa6e665SDamon Ding #define ESMART_LB_SELECT_MASK 0x3 535d0408543SAndy Yan 536d0408543SAndy Yan #define RK3568_ESMART0_CTRL1 0x1804 537a33b790fSDamon Ding #define ESMART_AXI_YRGB_ID_MASK 0x1f 538a33b790fSDamon Ding #define ESMART_AXI_YRGB_ID_SHIFT 4 539a33b790fSDamon Ding #define ESMART_AXI_UV_ID_MASK 0x1f 540a33b790fSDamon Ding #define ESMART_AXI_UV_ID_SHIFT 12 541d0408543SAndy Yan #define YMIRROR_EN_SHIFT 31 542a33b790fSDamon Ding 543a33b790fSDamon Ding #define RK3568_ESMART0_AXI_CTRL 0x1808 544a33b790fSDamon Ding #define ESMART_AXI_ID_MASK 0x1 545a33b790fSDamon Ding #define ESMART_AXI_ID_SHIFT 1 546a33b790fSDamon Ding 547d0408543SAndy Yan #define RK3568_ESMART0_REGION0_CTRL 0x1810 548d0408543SAndy Yan #define WIN_EN_SHIFT 0 549d0408543SAndy Yan #define WIN_FORMAT_MASK 0x1f 550d0408543SAndy Yan #define WIN_FORMAT_SHIFT 1 5515fa6e665SDamon Ding #define REGION0_RB_SWAP_SHIFT 14 5525fa6e665SDamon Ding #define ESMART_XAVG_EN_SHIFT 20 5535fa6e665SDamon Ding #define ESMART_XGT_EN_SHIFT 21 5545fa6e665SDamon Ding #define ESMART_XGT_MODE_SHIFT 22 555d0408543SAndy Yan 556d0408543SAndy Yan #define RK3568_ESMART0_REGION0_YRGB_MST 0x1814 557d0408543SAndy Yan #define RK3568_ESMART0_REGION0_CBR_MST 0x1818 558d0408543SAndy Yan #define RK3568_ESMART0_REGION0_VIR 0x181C 559d0408543SAndy Yan #define RK3568_ESMART0_REGION0_ACT_INFO 0x1820 560d0408543SAndy Yan #define RK3568_ESMART0_REGION0_DSP_INFO 0x1824 561d0408543SAndy Yan #define RK3568_ESMART0_REGION0_DSP_ST 0x1828 562d0408543SAndy Yan #define RK3568_ESMART0_REGION0_SCL_CTRL 0x1830 5633e39a5a1SSandy Huang #define YRGB_XSCL_MODE_MASK 0x3 5643e39a5a1SSandy Huang #define YRGB_XSCL_MODE_SHIFT 0 5653e39a5a1SSandy Huang #define YRGB_XSCL_FILTER_MODE_MASK 0x3 5663e39a5a1SSandy Huang #define YRGB_XSCL_FILTER_MODE_SHIFT 2 5673e39a5a1SSandy Huang #define YRGB_YSCL_MODE_MASK 0x3 5683e39a5a1SSandy Huang #define YRGB_YSCL_MODE_SHIFT 4 5693e39a5a1SSandy Huang #define YRGB_YSCL_FILTER_MODE_MASK 0x3 5703e39a5a1SSandy Huang #define YRGB_YSCL_FILTER_MODE_SHIFT 6 5713e39a5a1SSandy Huang 572d0408543SAndy Yan #define RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB 0x1834 573d0408543SAndy Yan #define RK3568_ESMART0_REGION0_SCL_FACTOR_CBR 0x1838 574d0408543SAndy Yan #define RK3568_ESMART0_REGION0_SCL_OFFSET 0x183C 575d0408543SAndy Yan #define RK3568_ESMART0_REGION1_CTRL 0x1840 5763e39a5a1SSandy Huang #define YRGB_GT2_MASK 0x1 5773e39a5a1SSandy Huang #define YRGB_GT2_SHIFT 8 5783e39a5a1SSandy Huang #define YRGB_GT4_MASK 0x1 5793e39a5a1SSandy Huang #define YRGB_GT4_SHIFT 9 5803e39a5a1SSandy Huang 581d0408543SAndy Yan #define RK3568_ESMART0_REGION1_YRGB_MST 0x1844 582d0408543SAndy Yan #define RK3568_ESMART0_REGION1_CBR_MST 0x1848 583d0408543SAndy Yan #define RK3568_ESMART0_REGION1_VIR 0x184C 584d0408543SAndy Yan #define RK3568_ESMART0_REGION1_ACT_INFO 0x1850 585d0408543SAndy Yan #define RK3568_ESMART0_REGION1_DSP_INFO 0x1854 586d0408543SAndy Yan #define RK3568_ESMART0_REGION1_DSP_ST 0x1858 587d0408543SAndy Yan #define RK3568_ESMART0_REGION1_SCL_CTRL 0x1860 588d0408543SAndy Yan #define RK3568_ESMART0_REGION1_SCL_FACTOR_YRGB 0x1864 589d0408543SAndy Yan #define RK3568_ESMART0_REGION1_SCL_FACTOR_CBR 0x1868 590d0408543SAndy Yan #define RK3568_ESMART0_REGION1_SCL_OFFSET 0x186C 591d0408543SAndy Yan #define RK3568_ESMART0_REGION2_CTRL 0x1870 592d0408543SAndy Yan #define RK3568_ESMART0_REGION2_YRGB_MST 0x1874 593d0408543SAndy Yan #define RK3568_ESMART0_REGION2_CBR_MST 0x1878 594d0408543SAndy Yan #define RK3568_ESMART0_REGION2_VIR 0x187C 595d0408543SAndy Yan #define RK3568_ESMART0_REGION2_ACT_INFO 0x1880 596d0408543SAndy Yan #define RK3568_ESMART0_REGION2_DSP_INFO 0x1884 597d0408543SAndy Yan #define RK3568_ESMART0_REGION2_DSP_ST 0x1888 598d0408543SAndy Yan #define RK3568_ESMART0_REGION2_SCL_CTRL 0x1890 599d0408543SAndy Yan #define RK3568_ESMART0_REGION2_SCL_FACTOR_YRGB 0x1894 600d0408543SAndy Yan #define RK3568_ESMART0_REGION2_SCL_FACTOR_CBR 0x1898 601d0408543SAndy Yan #define RK3568_ESMART0_REGION2_SCL_OFFSET 0x189C 602d0408543SAndy Yan #define RK3568_ESMART0_REGION3_CTRL 0x18A0 603d0408543SAndy Yan #define RK3568_ESMART0_REGION3_YRGB_MST 0x18A4 604d0408543SAndy Yan #define RK3568_ESMART0_REGION3_CBR_MST 0x18A8 605d0408543SAndy Yan #define RK3568_ESMART0_REGION3_VIR 0x18AC 606d0408543SAndy Yan #define RK3568_ESMART0_REGION3_ACT_INFO 0x18B0 607d0408543SAndy Yan #define RK3568_ESMART0_REGION3_DSP_INFO 0x18B4 608d0408543SAndy Yan #define RK3568_ESMART0_REGION3_DSP_ST 0x18B8 609d0408543SAndy Yan #define RK3568_ESMART0_REGION3_SCL_CTRL 0x18C0 610d0408543SAndy Yan #define RK3568_ESMART0_REGION3_SCL_FACTOR_YRGB 0x18C4 611d0408543SAndy Yan #define RK3568_ESMART0_REGION3_SCL_FACTOR_CBR 0x18C8 612d0408543SAndy Yan #define RK3568_ESMART0_REGION3_SCL_OFFSET 0x18CC 613d0408543SAndy Yan 614d0408543SAndy Yan #define RK3568_ESMART1_CTRL0 0x1A00 615d0408543SAndy Yan #define RK3568_ESMART1_CTRL1 0x1A04 616d0408543SAndy Yan #define RK3568_ESMART1_REGION0_CTRL 0x1A10 617d0408543SAndy Yan #define RK3568_ESMART1_REGION0_YRGB_MST 0x1A14 618d0408543SAndy Yan #define RK3568_ESMART1_REGION0_CBR_MST 0x1A18 619d0408543SAndy Yan #define RK3568_ESMART1_REGION0_VIR 0x1A1C 620d0408543SAndy Yan #define RK3568_ESMART1_REGION0_ACT_INFO 0x1A20 621d0408543SAndy Yan #define RK3568_ESMART1_REGION0_DSP_INFO 0x1A24 622d0408543SAndy Yan #define RK3568_ESMART1_REGION0_DSP_ST 0x1A28 623d0408543SAndy Yan #define RK3568_ESMART1_REGION0_SCL_CTRL 0x1A30 624d0408543SAndy Yan #define RK3568_ESMART1_REGION0_SCL_FACTOR_YRGB 0x1A34 625d0408543SAndy Yan #define RK3568_ESMART1_REGION0_SCL_FACTOR_CBR 0x1A38 626d0408543SAndy Yan #define RK3568_ESMART1_REGION0_SCL_OFFSET 0x1A3C 627d0408543SAndy Yan #define RK3568_ESMART1_REGION1_CTRL 0x1A40 628d0408543SAndy Yan #define RK3568_ESMART1_REGION1_YRGB_MST 0x1A44 629d0408543SAndy Yan #define RK3568_ESMART1_REGION1_CBR_MST 0x1A48 630d0408543SAndy Yan #define RK3568_ESMART1_REGION1_VIR 0x1A4C 631d0408543SAndy Yan #define RK3568_ESMART1_REGION1_ACT_INFO 0x1A50 632d0408543SAndy Yan #define RK3568_ESMART1_REGION1_DSP_INFO 0x1A54 633d0408543SAndy Yan #define RK3568_ESMART1_REGION1_DSP_ST 0x1A58 634d0408543SAndy Yan #define RK3568_ESMART1_REGION1_SCL_CTRL 0x1A60 635d0408543SAndy Yan #define RK3568_ESMART1_REGION1_SCL_FACTOR_YRGB 0x1A64 636d0408543SAndy Yan #define RK3568_ESMART1_REGION1_SCL_FACTOR_CBR 0x1A68 637d0408543SAndy Yan #define RK3568_ESMART1_REGION1_SCL_OFFSET 0x1A6C 638d0408543SAndy Yan #define RK3568_ESMART1_REGION2_CTRL 0x1A70 639d0408543SAndy Yan #define RK3568_ESMART1_REGION2_YRGB_MST 0x1A74 640d0408543SAndy Yan #define RK3568_ESMART1_REGION2_CBR_MST 0x1A78 641d0408543SAndy Yan #define RK3568_ESMART1_REGION2_VIR 0x1A7C 642d0408543SAndy Yan #define RK3568_ESMART1_REGION2_ACT_INFO 0x1A80 643d0408543SAndy Yan #define RK3568_ESMART1_REGION2_DSP_INFO 0x1A84 644d0408543SAndy Yan #define RK3568_ESMART1_REGION2_DSP_ST 0x1A88 645d0408543SAndy Yan #define RK3568_ESMART1_REGION2_SCL_CTRL 0x1A90 646d0408543SAndy Yan #define RK3568_ESMART1_REGION2_SCL_FACTOR_YRGB 0x1A94 647d0408543SAndy Yan #define RK3568_ESMART1_REGION2_SCL_FACTOR_CBR 0x1A98 648d0408543SAndy Yan #define RK3568_ESMART1_REGION2_SCL_OFFSET 0x1A9C 649d0408543SAndy Yan #define RK3568_ESMART1_REGION3_CTRL 0x1AA0 650d0408543SAndy Yan #define RK3568_ESMART1_REGION3_YRGB_MST 0x1AA4 651d0408543SAndy Yan #define RK3568_ESMART1_REGION3_CBR_MST 0x1AA8 652d0408543SAndy Yan #define RK3568_ESMART1_REGION3_VIR 0x1AAC 653d0408543SAndy Yan #define RK3568_ESMART1_REGION3_ACT_INFO 0x1AB0 654d0408543SAndy Yan #define RK3568_ESMART1_REGION3_DSP_INFO 0x1AB4 655d0408543SAndy Yan #define RK3568_ESMART1_REGION3_DSP_ST 0x1AB8 656d0408543SAndy Yan #define RK3568_ESMART1_REGION3_SCL_CTRL 0x1AC0 657d0408543SAndy Yan #define RK3568_ESMART1_REGION3_SCL_FACTOR_YRGB 0x1AC4 658d0408543SAndy Yan #define RK3568_ESMART1_REGION3_SCL_FACTOR_CBR 0x1AC8 659d0408543SAndy Yan #define RK3568_ESMART1_REGION3_SCL_OFFSET 0x1ACC 660d0408543SAndy Yan 661d0408543SAndy Yan #define RK3568_SMART0_CTRL0 0x1C00 662d0408543SAndy Yan #define RK3568_SMART0_CTRL1 0x1C04 663d0408543SAndy Yan #define RK3568_SMART0_REGION0_CTRL 0x1C10 664d0408543SAndy Yan #define RK3568_SMART0_REGION0_YRGB_MST 0x1C14 665d0408543SAndy Yan #define RK3568_SMART0_REGION0_CBR_MST 0x1C18 666d0408543SAndy Yan #define RK3568_SMART0_REGION0_VIR 0x1C1C 667d0408543SAndy Yan #define RK3568_SMART0_REGION0_ACT_INFO 0x1C20 668d0408543SAndy Yan #define RK3568_SMART0_REGION0_DSP_INFO 0x1C24 669d0408543SAndy Yan #define RK3568_SMART0_REGION0_DSP_ST 0x1C28 670d0408543SAndy Yan #define RK3568_SMART0_REGION0_SCL_CTRL 0x1C30 671d0408543SAndy Yan #define RK3568_SMART0_REGION0_SCL_FACTOR_YRGB 0x1C34 672d0408543SAndy Yan #define RK3568_SMART0_REGION0_SCL_FACTOR_CBR 0x1C38 673d0408543SAndy Yan #define RK3568_SMART0_REGION0_SCL_OFFSET 0x1C3C 674d0408543SAndy Yan #define RK3568_SMART0_REGION1_CTRL 0x1C40 675d0408543SAndy Yan #define RK3568_SMART0_REGION1_YRGB_MST 0x1C44 676d0408543SAndy Yan #define RK3568_SMART0_REGION1_CBR_MST 0x1C48 677d0408543SAndy Yan #define RK3568_SMART0_REGION1_VIR 0x1C4C 678d0408543SAndy Yan #define RK3568_SMART0_REGION1_ACT_INFO 0x1C50 679d0408543SAndy Yan #define RK3568_SMART0_REGION1_DSP_INFO 0x1C54 680d0408543SAndy Yan #define RK3568_SMART0_REGION1_DSP_ST 0x1C58 681d0408543SAndy Yan #define RK3568_SMART0_REGION1_SCL_CTRL 0x1C60 682d0408543SAndy Yan #define RK3568_SMART0_REGION1_SCL_FACTOR_YRGB 0x1C64 683d0408543SAndy Yan #define RK3568_SMART0_REGION1_SCL_FACTOR_CBR 0x1C68 684d0408543SAndy Yan #define RK3568_SMART0_REGION1_SCL_OFFSET 0x1C6C 685d0408543SAndy Yan #define RK3568_SMART0_REGION2_CTRL 0x1C70 686d0408543SAndy Yan #define RK3568_SMART0_REGION2_YRGB_MST 0x1C74 687d0408543SAndy Yan #define RK3568_SMART0_REGION2_CBR_MST 0x1C78 688d0408543SAndy Yan #define RK3568_SMART0_REGION2_VIR 0x1C7C 689d0408543SAndy Yan #define RK3568_SMART0_REGION2_ACT_INFO 0x1C80 690d0408543SAndy Yan #define RK3568_SMART0_REGION2_DSP_INFO 0x1C84 691d0408543SAndy Yan #define RK3568_SMART0_REGION2_DSP_ST 0x1C88 692d0408543SAndy Yan #define RK3568_SMART0_REGION2_SCL_CTRL 0x1C90 693d0408543SAndy Yan #define RK3568_SMART0_REGION2_SCL_FACTOR_YRGB 0x1C94 694d0408543SAndy Yan #define RK3568_SMART0_REGION2_SCL_FACTOR_CBR 0x1C98 695d0408543SAndy Yan #define RK3568_SMART0_REGION2_SCL_OFFSET 0x1C9C 696d0408543SAndy Yan #define RK3568_SMART0_REGION3_CTRL 0x1CA0 697d0408543SAndy Yan #define RK3568_SMART0_REGION3_YRGB_MST 0x1CA4 698d0408543SAndy Yan #define RK3568_SMART0_REGION3_CBR_MST 0x1CA8 699d0408543SAndy Yan #define RK3568_SMART0_REGION3_VIR 0x1CAC 700d0408543SAndy Yan #define RK3568_SMART0_REGION3_ACT_INFO 0x1CB0 701d0408543SAndy Yan #define RK3568_SMART0_REGION3_DSP_INFO 0x1CB4 702d0408543SAndy Yan #define RK3568_SMART0_REGION3_DSP_ST 0x1CB8 703d0408543SAndy Yan #define RK3568_SMART0_REGION3_SCL_CTRL 0x1CC0 704d0408543SAndy Yan #define RK3568_SMART0_REGION3_SCL_FACTOR_YRGB 0x1CC4 705d0408543SAndy Yan #define RK3568_SMART0_REGION3_SCL_FACTOR_CBR 0x1CC8 706d0408543SAndy Yan #define RK3568_SMART0_REGION3_SCL_OFFSET 0x1CCC 707d0408543SAndy Yan 708d0408543SAndy Yan #define RK3568_SMART1_CTRL0 0x1E00 709d0408543SAndy Yan #define RK3568_SMART1_CTRL1 0x1E04 710d0408543SAndy Yan #define RK3568_SMART1_REGION0_CTRL 0x1E10 711d0408543SAndy Yan #define RK3568_SMART1_REGION0_YRGB_MST 0x1E14 712d0408543SAndy Yan #define RK3568_SMART1_REGION0_CBR_MST 0x1E18 713d0408543SAndy Yan #define RK3568_SMART1_REGION0_VIR 0x1E1C 714d0408543SAndy Yan #define RK3568_SMART1_REGION0_ACT_INFO 0x1E20 715d0408543SAndy Yan #define RK3568_SMART1_REGION0_DSP_INFO 0x1E24 716d0408543SAndy Yan #define RK3568_SMART1_REGION0_DSP_ST 0x1E28 717d0408543SAndy Yan #define RK3568_SMART1_REGION0_SCL_CTRL 0x1E30 718d0408543SAndy Yan #define RK3568_SMART1_REGION0_SCL_FACTOR_YRGB 0x1E34 719d0408543SAndy Yan #define RK3568_SMART1_REGION0_SCL_FACTOR_CBR 0x1E38 720d0408543SAndy Yan #define RK3568_SMART1_REGION0_SCL_OFFSET 0x1E3C 721d0408543SAndy Yan #define RK3568_SMART1_REGION1_CTRL 0x1E40 722d0408543SAndy Yan #define RK3568_SMART1_REGION1_YRGB_MST 0x1E44 723d0408543SAndy Yan #define RK3568_SMART1_REGION1_CBR_MST 0x1E48 724d0408543SAndy Yan #define RK3568_SMART1_REGION1_VIR 0x1E4C 725d0408543SAndy Yan #define RK3568_SMART1_REGION1_ACT_INFO 0x1E50 726d0408543SAndy Yan #define RK3568_SMART1_REGION1_DSP_INFO 0x1E54 727d0408543SAndy Yan #define RK3568_SMART1_REGION1_DSP_ST 0x1E58 728d0408543SAndy Yan #define RK3568_SMART1_REGION1_SCL_CTRL 0x1E60 729d0408543SAndy Yan #define RK3568_SMART1_REGION1_SCL_FACTOR_YRGB 0x1E64 730d0408543SAndy Yan #define RK3568_SMART1_REGION1_SCL_FACTOR_CBR 0x1E68 731d0408543SAndy Yan #define RK3568_SMART1_REGION1_SCL_OFFSET 0x1E6C 732d0408543SAndy Yan #define RK3568_SMART1_REGION2_CTRL 0x1E70 733d0408543SAndy Yan #define RK3568_SMART1_REGION2_YRGB_MST 0x1E74 734d0408543SAndy Yan #define RK3568_SMART1_REGION2_CBR_MST 0x1E78 735d0408543SAndy Yan #define RK3568_SMART1_REGION2_VIR 0x1E7C 736d0408543SAndy Yan #define RK3568_SMART1_REGION2_ACT_INFO 0x1E80 737d0408543SAndy Yan #define RK3568_SMART1_REGION2_DSP_INFO 0x1E84 738d0408543SAndy Yan #define RK3568_SMART1_REGION2_DSP_ST 0x1E88 739d0408543SAndy Yan #define RK3568_SMART1_REGION2_SCL_CTRL 0x1E90 740d0408543SAndy Yan #define RK3568_SMART1_REGION2_SCL_FACTOR_YRGB 0x1E94 741d0408543SAndy Yan #define RK3568_SMART1_REGION2_SCL_FACTOR_CBR 0x1E98 742d0408543SAndy Yan #define RK3568_SMART1_REGION2_SCL_OFFSET 0x1E9C 743d0408543SAndy Yan #define RK3568_SMART1_REGION3_CTRL 0x1EA0 744d0408543SAndy Yan #define RK3568_SMART1_REGION3_YRGB_MST 0x1EA4 745d0408543SAndy Yan #define RK3568_SMART1_REGION3_CBR_MST 0x1EA8 746d0408543SAndy Yan #define RK3568_SMART1_REGION3_VIR 0x1EAC 747d0408543SAndy Yan #define RK3568_SMART1_REGION3_ACT_INFO 0x1EB0 748d0408543SAndy Yan #define RK3568_SMART1_REGION3_DSP_INFO 0x1EB4 749d0408543SAndy Yan #define RK3568_SMART1_REGION3_DSP_ST 0x1EB8 750d0408543SAndy Yan #define RK3568_SMART1_REGION3_SCL_CTRL 0x1EC0 751d0408543SAndy Yan #define RK3568_SMART1_REGION3_SCL_FACTOR_YRGB 0x1EC4 752d0408543SAndy Yan #define RK3568_SMART1_REGION3_SCL_FACTOR_CBR 0x1EC8 753d0408543SAndy Yan #define RK3568_SMART1_REGION3_SCL_OFFSET 0x1ECC 754d0408543SAndy Yan 75512ee5af0SDamon Ding /* DSC 8K/4K register definition */ 75612ee5af0SDamon Ding #define RK3588_DSC_8K_PPS0_3 0x4000 75712ee5af0SDamon Ding #define RK3588_DSC_8K_CTRL0 0x40A0 75812ee5af0SDamon Ding #define DSC_EN_SHIFT 0 75912ee5af0SDamon Ding #define DSC_RBIT_SHIFT 2 76012ee5af0SDamon Ding #define DSC_RBYT_SHIFT 3 76112ee5af0SDamon Ding #define DSC_FLAL_SHIFT 4 76212ee5af0SDamon Ding #define DSC_MER_SHIFT 5 76312ee5af0SDamon Ding #define DSC_EPB_SHIFT 6 76412ee5af0SDamon Ding #define DSC_EPL_SHIFT 7 76512ee5af0SDamon Ding #define DSC_NSLC_SHIFT 16 76612ee5af0SDamon Ding #define DSC_SBO_SHIFT 28 76712ee5af0SDamon Ding #define DSC_IFEP_SHIFT 29 76812ee5af0SDamon Ding #define DSC_PPS_UPD_SHIFT 31 76912ee5af0SDamon Ding 77012ee5af0SDamon Ding #define RK3588_DSC_8K_CTRL1 0x40A4 77112ee5af0SDamon Ding #define RK3588_DSC_8K_STS0 0x40A8 77212ee5af0SDamon Ding #define RK3588_DSC_8K_ERS 0x40C4 77312ee5af0SDamon Ding 77412ee5af0SDamon Ding #define RK3588_DSC_4K_PPS0_3 0x4100 77512ee5af0SDamon Ding #define RK3588_DSC_4K_CTRL0 0x41A0 77612ee5af0SDamon Ding #define RK3588_DSC_4K_CTRL1 0x41A4 77712ee5af0SDamon Ding #define RK3588_DSC_4K_STS0 0x41A8 77812ee5af0SDamon Ding #define RK3588_DSC_4K_ERS 0x41C4 77912ee5af0SDamon Ding 780d0408543SAndy Yan #define RK3568_MAX_REG 0x1ED0 781d0408543SAndy Yan 78252ee18acSSandy Huang #define RK3568_GRF_VO_CON1 0x0364 78352ee18acSSandy Huang #define GRF_BT656_CLK_INV_SHIFT 1 78452ee18acSSandy Huang #define GRF_BT1120_CLK_INV_SHIFT 2 78552ee18acSSandy Huang #define GRF_RGB_DCLK_INV_SHIFT 3 78652ee18acSSandy Huang 787ecc31b6eSAndy Yan #define RK3588_GRF_VOP_CON2 0x0008 788ecc31b6eSAndy Yan #define RK3588_GRF_EDP0_ENABLE_SHIFT 0 789ecc31b6eSAndy Yan #define RK3588_GRF_HDMITX0_ENABLE_SHIFT 1 790ecc31b6eSAndy Yan #define RK3588_GRF_EDP1_ENABLE_SHIFT 3 791ecc31b6eSAndy Yan #define RK3588_GRF_HDMITX1_ENABLE_SHIFT 4 792ecc31b6eSAndy Yan 793b890760eSAlgea Cao #define RK3588_GRF_VO1_CON0 0x0000 794b890760eSAlgea Cao #define HDMI_SYNC_POL_MASK 0x3 795b890760eSAlgea Cao #define HDMI0_SYNC_POL_SHIFT 5 796b890760eSAlgea Cao #define HDMI1_SYNC_POL_SHIFT 7 797b890760eSAlgea Cao 79860e469f5SDamon Ding #define RK3588_PMU_BISR_CON3 0x20C 79960e469f5SDamon Ding #define RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT 9 80060e469f5SDamon Ding #define RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT 10 80160e469f5SDamon Ding #define RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT 11 80260e469f5SDamon Ding #define RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT 12 803b6ba80b4SDamon Ding #define RK3588_PD_DSC_8K_REPAIR_EN_SHIFT 13 804b6ba80b4SDamon Ding #define RK3588_PD_DSC_4K_REPAIR_EN_SHIFT 14 80560e469f5SDamon Ding #define RK3588_PD_ESMART_REPAIR_EN_SHIFT 15 80660e469f5SDamon Ding 80760e469f5SDamon Ding #define RK3588_PMU_BISR_STATUS5 0x294 80860e469f5SDamon Ding #define RK3588_PD_CLUSTER0_PWR_STAT_SHIFI 9 80960e469f5SDamon Ding #define RK3588_PD_CLUSTER1_PWR_STAT_SHIFI 10 81060e469f5SDamon Ding #define RK3588_PD_CLUSTER2_PWR_STAT_SHIFI 11 81160e469f5SDamon Ding #define RK3588_PD_CLUSTER3_PWR_STAT_SHIFI 12 812b6ba80b4SDamon Ding #define RK3588_PD_DSC_8K_PWR_STAT_SHIFI 13 813b6ba80b4SDamon Ding #define RK3588_PD_DSC_4K_PWR_STAT_SHIFI 14 81460e469f5SDamon Ding #define RK3588_PD_ESMART_PWR_STAT_SHIFI 15 81560e469f5SDamon Ding 816d0408543SAndy Yan #define VOP2_LAYER_MAX 8 81763cb669fSSandy Huang 818ee01dbb2SDamon Ding #define VOP2_MAX_VP_OUTPUT_WIDTH 4096 819ee01dbb2SDamon Ding 82063cb669fSSandy Huang #define VOP_FEATURE_OUTPUT_10BIT BIT(0) 821d0408543SAndy Yan 822631ee99aSZhang Yubing /* KHz */ 823631ee99aSZhang Yubing #define VOP2_MAX_DCLK_RATE 600000 824631ee99aSZhang Yubing 825b6ba80b4SDamon Ding /* 826b6ba80b4SDamon Ding * vop2 dsc id 827b6ba80b4SDamon Ding */ 828b6ba80b4SDamon Ding #define ROCKCHIP_VOP2_DSC_8K 0 829b6ba80b4SDamon Ding #define ROCKCHIP_VOP2_DSC_4K 1 830b6ba80b4SDamon Ding 831b6ba80b4SDamon Ding /* 832b6ba80b4SDamon Ding * vop2 internal power domain id, 833b6ba80b4SDamon Ding * should be all none zero, 0 will be 834b6ba80b4SDamon Ding * treat as invalid; 835b6ba80b4SDamon Ding */ 836b6ba80b4SDamon Ding #define VOP2_PD_CLUSTER0 BIT(0) 837b6ba80b4SDamon Ding #define VOP2_PD_CLUSTER1 BIT(1) 838b6ba80b4SDamon Ding #define VOP2_PD_CLUSTER2 BIT(2) 839b6ba80b4SDamon Ding #define VOP2_PD_CLUSTER3 BIT(3) 840b6ba80b4SDamon Ding #define VOP2_PD_DSC_8K BIT(5) 841b6ba80b4SDamon Ding #define VOP2_PD_DSC_4K BIT(6) 842b6ba80b4SDamon Ding #define VOP2_PD_ESMART BIT(7) 843b6ba80b4SDamon Ding 8444c765862SDamon Ding #define VOP2_PLANE_NO_SCALING BIT(16) 8454c765862SDamon Ding 8465fa6e665SDamon Ding #define VOP_FEATURE_OUTPUT_10BIT BIT(0) 8475fa6e665SDamon Ding #define VOP_FEATURE_AFBDC BIT(1) 8485fa6e665SDamon Ding #define VOP_FEATURE_ALPHA_SCALE BIT(2) 8495fa6e665SDamon Ding #define VOP_FEATURE_HDR10 BIT(3) 8505fa6e665SDamon Ding #define VOP_FEATURE_NEXT_HDR BIT(4) 8515fa6e665SDamon Ding /* a feature to splice two windows and two vps to support resolution > 4096 */ 8525fa6e665SDamon Ding #define VOP_FEATURE_SPLICE BIT(5) 8535fa6e665SDamon Ding #define VOP_FEATURE_OVERSCAN BIT(6) 8545fa6e665SDamon Ding 8555fa6e665SDamon Ding #define WIN_FEATURE_HDR2SDR BIT(0) 8565fa6e665SDamon Ding #define WIN_FEATURE_SDR2HDR BIT(1) 8575fa6e665SDamon Ding #define WIN_FEATURE_PRE_OVERLAY BIT(2) 8585fa6e665SDamon Ding #define WIN_FEATURE_AFBDC BIT(3) 8595fa6e665SDamon Ding #define WIN_FEATURE_CLUSTER_MAIN BIT(4) 8605fa6e665SDamon Ding #define WIN_FEATURE_CLUSTER_SUB BIT(5) 8615fa6e665SDamon Ding /* a mirror win can only get fb address 8625fa6e665SDamon Ding * from source win: 8635fa6e665SDamon Ding * Cluster1---->Cluster0 8645fa6e665SDamon Ding * Esmart1 ---->Esmart0 8655fa6e665SDamon Ding * Smart1 ---->Smart0 8665fa6e665SDamon Ding * This is a feather on rk3566 8675fa6e665SDamon Ding */ 8685fa6e665SDamon Ding #define WIN_FEATURE_MIRROR BIT(6) 8695fa6e665SDamon Ding #define WIN_FEATURE_MULTI_AREA BIT(7) 8705fa6e665SDamon Ding #define WIN_FEATURE_Y2R_13BIT_DEPTH BIT(8) 8715fa6e665SDamon Ding 8725fa6e665SDamon Ding #define V4L2_COLORSPACE_BT709F 0xfe 8735fa6e665SDamon Ding #define V4L2_COLORSPACE_BT2020F 0xff 8745fa6e665SDamon Ding 8755fa6e665SDamon Ding enum vop_csc_format { 87610ee9f5bSAlgea Cao CSC_BT601L, 87710ee9f5bSAlgea Cao CSC_BT709L, 87810ee9f5bSAlgea Cao CSC_BT601F, 87910ee9f5bSAlgea Cao CSC_BT2020, 8805fa6e665SDamon Ding CSC_BT709L_13BIT, 8815fa6e665SDamon Ding CSC_BT709F_13BIT, 8825fa6e665SDamon Ding CSC_BT2020L_13BIT, 8835fa6e665SDamon Ding CSC_BT2020F_13BIT, 8845fa6e665SDamon Ding }; 8855fa6e665SDamon Ding 8865fa6e665SDamon Ding enum vop_csc_bit_depth { 8875fa6e665SDamon Ding CSC_10BIT_DEPTH, 8885fa6e665SDamon Ding CSC_13BIT_DEPTH, 88910ee9f5bSAlgea Cao }; 89010ee9f5bSAlgea Cao 89110ee9f5bSAlgea Cao enum vop2_pol { 89210ee9f5bSAlgea Cao HSYNC_POSITIVE = 0, 89310ee9f5bSAlgea Cao VSYNC_POSITIVE = 1, 89410ee9f5bSAlgea Cao DEN_NEGATIVE = 2, 89510ee9f5bSAlgea Cao DCLK_INVERT = 3 89610ee9f5bSAlgea Cao }; 89710ee9f5bSAlgea Cao 898ac500a1fSSandy Huang enum vop2_bcsh_out_mode { 899ac500a1fSSandy Huang BCSH_OUT_MODE_BLACK, 900ac500a1fSSandy Huang BCSH_OUT_MODE_BLUE, 901ac500a1fSSandy Huang BCSH_OUT_MODE_COLOR_BAR, 902ac500a1fSSandy Huang BCSH_OUT_MODE_NORMAL_VIDEO, 903ac500a1fSSandy Huang }; 904ac500a1fSSandy Huang 905d0408543SAndy Yan #define _VOP_REG(off, _mask, _shift, _write_mask) \ 906d0408543SAndy Yan { \ 907d0408543SAndy Yan .offset = off, \ 908d0408543SAndy Yan .mask = _mask, \ 909d0408543SAndy Yan .shift = _shift, \ 910d0408543SAndy Yan .write_mask = _write_mask, \ 911d0408543SAndy Yan } 912d0408543SAndy Yan 913d0408543SAndy Yan #define VOP_REG(off, _mask, _shift) \ 914d0408543SAndy Yan _VOP_REG(off, _mask, _shift, false) 915d0408543SAndy Yan enum dither_down_mode { 916d0408543SAndy Yan RGB888_TO_RGB565 = 0x0, 917d0408543SAndy Yan RGB888_TO_RGB666 = 0x1 918d0408543SAndy Yan }; 919d0408543SAndy Yan 920d0408543SAndy Yan enum vop2_video_ports_id { 921d0408543SAndy Yan VOP2_VP0, 922d0408543SAndy Yan VOP2_VP1, 923d0408543SAndy Yan VOP2_VP2, 924d0408543SAndy Yan VOP2_VP3, 925d0408543SAndy Yan VOP2_VP_MAX, 926d0408543SAndy Yan }; 927d0408543SAndy Yan 928ee008497SSandy Huang enum vop2_layer_type { 929ee008497SSandy Huang CLUSTER_LAYER = 0, 930ee008497SSandy Huang ESMART_LAYER = 1, 931ee008497SSandy Huang SMART_LAYER = 2, 932ee008497SSandy Huang }; 933ee008497SSandy Huang 934b0989546SSandy Huang /* This define must same with kernel win phy id */ 935b0989546SSandy Huang enum vop2_layer_phy_id { 936b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER0 = 0, 937b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER1, 938b0989546SSandy Huang ROCKCHIP_VOP2_ESMART0, 939b0989546SSandy Huang ROCKCHIP_VOP2_ESMART1, 940b0989546SSandy Huang ROCKCHIP_VOP2_SMART0, 941b0989546SSandy Huang ROCKCHIP_VOP2_SMART1, 942b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER2, 943b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER3, 944b0989546SSandy Huang ROCKCHIP_VOP2_ESMART2, 945b0989546SSandy Huang ROCKCHIP_VOP2_ESMART3, 946ee008497SSandy Huang ROCKCHIP_VOP2_LAYER_MAX, 947d0408543SAndy Yan }; 948d0408543SAndy Yan 9493e39a5a1SSandy Huang enum vop2_scale_up_mode { 9503e39a5a1SSandy Huang VOP2_SCALE_UP_NRST_NBOR, 9513e39a5a1SSandy Huang VOP2_SCALE_UP_BIL, 9523e39a5a1SSandy Huang VOP2_SCALE_UP_BIC, 9533e39a5a1SSandy Huang }; 9543e39a5a1SSandy Huang 9553e39a5a1SSandy Huang enum vop2_scale_down_mode { 9563e39a5a1SSandy Huang VOP2_SCALE_DOWN_NRST_NBOR, 9573e39a5a1SSandy Huang VOP2_SCALE_DOWN_BIL, 9583e39a5a1SSandy Huang VOP2_SCALE_DOWN_AVG, 9593e39a5a1SSandy Huang }; 9603e39a5a1SSandy Huang 9613e39a5a1SSandy Huang enum scale_mode { 9623e39a5a1SSandy Huang SCALE_NONE = 0x0, 9633e39a5a1SSandy Huang SCALE_UP = 0x1, 9643e39a5a1SSandy Huang SCALE_DOWN = 0x2 9653e39a5a1SSandy Huang }; 9663e39a5a1SSandy Huang 96712ee5af0SDamon Ding enum vop_dsc_interface_mode { 96812ee5af0SDamon Ding VOP_DSC_IF_DISABLE = 0, 96912ee5af0SDamon Ding VOP_DSC_IF_HDMI = 1, 97012ee5af0SDamon Ding VOP_DSC_IF_MIPI_DS_MODE = 2, 97112ee5af0SDamon Ding VOP_DSC_IF_MIPI_VIDEO_MODE = 3, 97212ee5af0SDamon Ding }; 97312ee5af0SDamon Ding 9745fa6e665SDamon Ding enum vop3_pre_scale_down_mode { 9755fa6e665SDamon Ding VOP3_PRE_SCALE_UNSPPORT, 9765fa6e665SDamon Ding VOP3_PRE_SCALE_DOWN_GT, 9775fa6e665SDamon Ding VOP3_PRE_SCALE_DOWN_AVG, 9785fa6e665SDamon Ding }; 9795fa6e665SDamon Ding 9805fa6e665SDamon Ding enum vop3_esmart_lb_mode { 9815fa6e665SDamon Ding VOP3_ESMART_8K_MODE, 9825fa6e665SDamon Ding VOP3_ESMART_4K_4K_MODE, 9835fa6e665SDamon Ding VOP3_ESMART_4K_2K_2K_MODE, 9845fa6e665SDamon Ding VOP3_ESMART_2K_2K_2K_2K_MODE, 9855fa6e665SDamon Ding }; 9865fa6e665SDamon Ding 9873e39a5a1SSandy Huang struct vop2_layer { 9883e39a5a1SSandy Huang u8 id; 9893e39a5a1SSandy Huang /** 9903e39a5a1SSandy Huang * @win_phys_id: window id of the layer selected. 9913e39a5a1SSandy Huang * Every layer must make sure to select different 9923e39a5a1SSandy Huang * windows of others. 9933e39a5a1SSandy Huang */ 9943e39a5a1SSandy Huang u8 win_phys_id; 9953e39a5a1SSandy Huang }; 9963e39a5a1SSandy Huang 99760e469f5SDamon Ding struct vop2_power_domain_data { 998b6ba80b4SDamon Ding u8 id; 999b6ba80b4SDamon Ding u8 parent_id; 1000b6ba80b4SDamon Ding /* 1001b6ba80b4SDamon Ding * @module_id_mask: module id of which module this power domain is belongs to. 1002b6ba80b4SDamon Ding * PD_CLUSTER0,1,2,3 only belongs to CLUSTER0/1/2/3, PD_Esmart0 shared by Esmart1/2/3 1003b6ba80b4SDamon Ding */ 1004b6ba80b4SDamon Ding u32 module_id_mask; 100560e469f5SDamon Ding }; 100660e469f5SDamon Ding 1007b0989546SSandy Huang struct vop2_win_data { 1008b0989546SSandy Huang char *name; 100963cb669fSSandy Huang u8 phys_id; 1010ecc31b6eSAndy Yan enum vop2_layer_type type; 1011b0989546SSandy Huang u8 win_sel_port_offset; 10125fa6e665SDamon Ding u8 layer_sel_win_id[VOP2_VP_MAX]; 1013a33b790fSDamon Ding u8 axi_id; 1014a33b790fSDamon Ding u8 axi_uv_id; 1015a33b790fSDamon Ding u8 axi_yrgb_id; 1016ee01dbb2SDamon Ding u8 splice_win_id; 1017b6ba80b4SDamon Ding u8 pd_id; 10185fa6e665SDamon Ding u8 hsu_filter_mode; 10195fa6e665SDamon Ding u8 hsd_filter_mode; 10205fa6e665SDamon Ding u8 vsu_filter_mode; 10215fa6e665SDamon Ding u8 vsd_filter_mode; 10225fa6e665SDamon Ding u8 hsd_pre_filter_mode; 10235fa6e665SDamon Ding u8 vsd_pre_filter_mode; 10245fa6e665SDamon Ding u8 scale_engine_num; 1025b0989546SSandy Huang u32 reg_offset; 10264c765862SDamon Ding u32 max_upscale_factor; 10274c765862SDamon Ding u32 max_downscale_factor; 1028ee01dbb2SDamon Ding bool splice_mode_right; 102963cb669fSSandy Huang }; 103063cb669fSSandy Huang 103163cb669fSSandy Huang struct vop2_vp_data { 103263cb669fSSandy Huang u32 feature; 103363cb669fSSandy Huang u8 pre_scan_max_dly; 1034ee01dbb2SDamon Ding u8 splice_vp_id; 103563cb669fSSandy Huang struct vop_rect max_output; 1036ecc31b6eSAndy Yan u32 max_dclk; 1037d0408543SAndy Yan }; 1038d0408543SAndy Yan 1039ee008497SSandy Huang struct vop2_plane_table { 1040ee008497SSandy Huang enum vop2_layer_phy_id plane_id; 1041ee008497SSandy Huang enum vop2_layer_type plane_type; 1042ee008497SSandy Huang }; 1043ee008497SSandy Huang 1044b0989546SSandy Huang struct vop2_vp_plane_mask { 1045b0989546SSandy Huang u8 primary_plane_id; /* use this win to show logo */ 1046b0989546SSandy Huang u8 attached_layers_nr; /* number layers attach to this vp */ 1047b0989546SSandy Huang u8 attached_layers[VOP2_LAYER_MAX]; /* the layers attached to this vp */ 1048b0989546SSandy Huang u32 plane_mask; 1049ee008497SSandy Huang int cursor_plane_id; 1050b0989546SSandy Huang }; 1051b0989546SSandy Huang 105212ee5af0SDamon Ding struct vop2_dsc_data { 105312ee5af0SDamon Ding u8 id; 105412ee5af0SDamon Ding u8 pd_id; 105512ee5af0SDamon Ding u8 max_slice_num; 105612ee5af0SDamon Ding u8 max_linebuf_depth; /* used to generate the bitstream */ 105712ee5af0SDamon Ding u8 min_bits_per_pixel; /* bit num after encoder compress */ 105812ee5af0SDamon Ding const char *dsc_txp_clk_src_name; 105912ee5af0SDamon Ding const char *dsc_txp_clk_name; 106012ee5af0SDamon Ding const char *dsc_pxl_clk_name; 106112ee5af0SDamon Ding const char *dsc_cds_clk_name; 106212ee5af0SDamon Ding }; 106312ee5af0SDamon Ding 106412ee5af0SDamon Ding struct dsc_error_info { 106512ee5af0SDamon Ding u32 dsc_error_val; 106612ee5af0SDamon Ding char dsc_error_info[50]; 106712ee5af0SDamon Ding }; 106812ee5af0SDamon Ding 1069d0408543SAndy Yan struct vop2_data { 107052ee18acSSandy Huang u32 version; 10715fa6e665SDamon Ding u32 esmart_lb_mode; 107263cb669fSSandy Huang struct vop2_vp_data *vp_data; 1073b0989546SSandy Huang struct vop2_win_data *win_data; 1074b0989546SSandy Huang struct vop2_vp_plane_mask *plane_mask; 1075ee008497SSandy Huang struct vop2_plane_table *plane_table; 1076b6ba80b4SDamon Ding struct vop2_power_domain_data *pd; 107712ee5af0SDamon Ding struct vop2_dsc_data *dsc; 107812ee5af0SDamon Ding struct dsc_error_info *dsc_error_ecw; 107912ee5af0SDamon Ding struct dsc_error_info *dsc_error_buffer_flow; 1080337d1c13SDamon Ding u8 *vp_primary_plane_order; 108163cb669fSSandy Huang u8 nr_vps; 108263cb669fSSandy Huang u8 nr_layers; 108363cb669fSSandy Huang u8 nr_mixers; 10841147facaSSandy Huang u8 nr_gammas; 1085b6ba80b4SDamon Ding u8 nr_pd; 108612ee5af0SDamon Ding u8 nr_dscs; 108712ee5af0SDamon Ding u8 nr_dsc_ecw; 108812ee5af0SDamon Ding u8 nr_dsc_buffer_flow; 1089ecc31b6eSAndy Yan u32 reg_len; 1090d0408543SAndy Yan }; 1091d0408543SAndy Yan 1092d0408543SAndy Yan struct vop2 { 1093d0408543SAndy Yan u32 *regsbak; 1094d0408543SAndy Yan void *regs; 1095d0408543SAndy Yan void *grf; 1096ecc31b6eSAndy Yan void *vop_grf; 1097ecc31b6eSAndy Yan void *vo1_grf; 109860e469f5SDamon Ding void *sys_pmu; 109952ee18acSSandy Huang u32 reg_len; 110052ee18acSSandy Huang u32 version; 11015fa6e665SDamon Ding u32 esmart_lb_mode; 110263cb669fSSandy Huang bool global_init; 1103d0408543SAndy Yan const struct vop2_data *data; 1104b0989546SSandy Huang struct vop2_vp_plane_mask vp_plane_mask[VOP2_VP_MAX]; 1105d0408543SAndy Yan }; 1106d0408543SAndy Yan 1107d0408543SAndy Yan static struct vop2 *rockchip_vop2; 11085fa6e665SDamon Ding 11095fa6e665SDamon Ding static inline bool is_vop3(struct vop2 *vop2) 11105fa6e665SDamon Ding { 11115fa6e665SDamon Ding if (vop2->version == VOP_VERSION_RK3568 || vop2->version == VOP_VERSION_RK3588) 11125fa6e665SDamon Ding return false; 11135fa6e665SDamon Ding else 11145fa6e665SDamon Ding return true; 11155fa6e665SDamon Ding } 11165fa6e665SDamon Ding 11173e39a5a1SSandy Huang /* 11183e39a5a1SSandy Huang * bli_sd_factor = (src - 1) / (dst - 1) << 12; 11193e39a5a1SSandy Huang * avg_sd_factor: 11203e39a5a1SSandy Huang * bli_su_factor: 11213e39a5a1SSandy Huang * bic_su_factor: 11223e39a5a1SSandy Huang * = (src - 1) / (dst - 1) << 16; 11233e39a5a1SSandy Huang * 11245fa6e665SDamon Ding * ygt2 enable: dst get one line from two line of the src 11255fa6e665SDamon Ding * ygt4 enable: dst get one line from four line of the src. 11263e39a5a1SSandy Huang * 11273e39a5a1SSandy Huang */ 11283e39a5a1SSandy Huang #define VOP2_BILI_SCL_DN(src, dst) (((src - 1) << 12) / (dst - 1)) 11293e39a5a1SSandy Huang #define VOP2_COMMON_SCL(src, dst) (((src - 1) << 16) / (dst - 1)) 11303e39a5a1SSandy Huang 11313e39a5a1SSandy Huang #define VOP2_BILI_SCL_FAC_CHECK(src, dst, fac) \ 11323e39a5a1SSandy Huang (fac * (dst - 1) >> 12 < (src - 1)) 11333e39a5a1SSandy Huang #define VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac) \ 11343e39a5a1SSandy Huang (fac * (dst - 1) >> 16 < (src - 1)) 11355fa6e665SDamon Ding #define VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac) \ 11365fa6e665SDamon Ding (fac * (dst - 1) >> 16 < (src - 1)) 11373e39a5a1SSandy Huang 11383e39a5a1SSandy Huang static uint16_t vop2_scale_factor(enum scale_mode mode, 11393e39a5a1SSandy Huang int32_t filter_mode, 11403e39a5a1SSandy Huang uint32_t src, uint32_t dst) 11413e39a5a1SSandy Huang { 11423e39a5a1SSandy Huang uint32_t fac = 0; 11433e39a5a1SSandy Huang int i = 0; 11443e39a5a1SSandy Huang 11453e39a5a1SSandy Huang if (mode == SCALE_NONE) 11463e39a5a1SSandy Huang return 0; 11473e39a5a1SSandy Huang 11483e39a5a1SSandy Huang /* 11493e39a5a1SSandy Huang * A workaround to avoid zero div. 11503e39a5a1SSandy Huang */ 11513e39a5a1SSandy Huang if ((dst == 1) || (src == 1)) { 11523e39a5a1SSandy Huang dst = dst + 1; 11533e39a5a1SSandy Huang src = src + 1; 11543e39a5a1SSandy Huang } 11553e39a5a1SSandy Huang 11563e39a5a1SSandy Huang if ((mode == SCALE_DOWN) && (filter_mode == VOP2_SCALE_DOWN_BIL)) { 11573e39a5a1SSandy Huang fac = VOP2_BILI_SCL_DN(src, dst); 11583e39a5a1SSandy Huang for (i = 0; i < 100; i++) { 11593e39a5a1SSandy Huang if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac)) 11603e39a5a1SSandy Huang break; 11613e39a5a1SSandy Huang fac -= 1; 11623e39a5a1SSandy Huang printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 11633e39a5a1SSandy Huang } 11643e39a5a1SSandy Huang } else { 11653e39a5a1SSandy Huang fac = VOP2_COMMON_SCL(src, dst); 11663e39a5a1SSandy Huang for (i = 0; i < 100; i++) { 11673e39a5a1SSandy Huang if (VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac)) 11683e39a5a1SSandy Huang break; 11693e39a5a1SSandy Huang fac -= 1; 11703e39a5a1SSandy Huang printf("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 11713e39a5a1SSandy Huang } 11723e39a5a1SSandy Huang } 11733e39a5a1SSandy Huang 11743e39a5a1SSandy Huang return fac; 11753e39a5a1SSandy Huang } 11763e39a5a1SSandy Huang 11775fa6e665SDamon Ding static bool vop3_scale_up_fac_check(uint32_t src, uint32_t dst, uint32_t fac, bool is_hor) 11785fa6e665SDamon Ding { 11795fa6e665SDamon Ding if (is_hor) 11805fa6e665SDamon Ding return VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac); 11815fa6e665SDamon Ding return VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac); 11825fa6e665SDamon Ding } 11835fa6e665SDamon Ding 11845fa6e665SDamon Ding static uint16_t vop3_scale_factor(enum scale_mode mode, 11855fa6e665SDamon Ding uint32_t src, uint32_t dst, bool is_hor) 11865fa6e665SDamon Ding { 11875fa6e665SDamon Ding uint32_t fac = 0; 11885fa6e665SDamon Ding int i = 0; 11895fa6e665SDamon Ding 11905fa6e665SDamon Ding if (mode == SCALE_NONE) 11915fa6e665SDamon Ding return 0; 11925fa6e665SDamon Ding 11935fa6e665SDamon Ding /* 11945fa6e665SDamon Ding * A workaround to avoid zero div. 11955fa6e665SDamon Ding */ 11965fa6e665SDamon Ding if ((dst == 1) || (src == 1)) { 11975fa6e665SDamon Ding dst = dst + 1; 11985fa6e665SDamon Ding src = src + 1; 11995fa6e665SDamon Ding } 12005fa6e665SDamon Ding 12015fa6e665SDamon Ding if (mode == SCALE_DOWN) { 12025fa6e665SDamon Ding fac = VOP2_BILI_SCL_DN(src, dst); 12035fa6e665SDamon Ding for (i = 0; i < 100; i++) { 12045fa6e665SDamon Ding if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac)) 12055fa6e665SDamon Ding break; 12065fa6e665SDamon Ding fac -= 1; 12075fa6e665SDamon Ding printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 12085fa6e665SDamon Ding } 12095fa6e665SDamon Ding } else { 12105fa6e665SDamon Ding fac = VOP2_COMMON_SCL(src, dst); 12115fa6e665SDamon Ding for (i = 0; i < 100; i++) { 12125fa6e665SDamon Ding if (vop3_scale_up_fac_check(src, dst, fac, is_hor)) 12135fa6e665SDamon Ding break; 12145fa6e665SDamon Ding fac -= 1; 12155fa6e665SDamon Ding printf("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 12165fa6e665SDamon Ding } 12175fa6e665SDamon Ding } 12185fa6e665SDamon Ding 12195fa6e665SDamon Ding return fac; 12205fa6e665SDamon Ding } 12215fa6e665SDamon Ding 12223e39a5a1SSandy Huang static inline enum scale_mode scl_get_scl_mode(int src, int dst) 12233e39a5a1SSandy Huang { 12243e39a5a1SSandy Huang if (src < dst) 12253e39a5a1SSandy Huang return SCALE_UP; 12263e39a5a1SSandy Huang else if (src > dst) 12273e39a5a1SSandy Huang return SCALE_DOWN; 12283e39a5a1SSandy Huang 12293e39a5a1SSandy Huang return SCALE_NONE; 12303e39a5a1SSandy Huang } 1231d0408543SAndy Yan 1232ac500a1fSSandy Huang static inline int interpolate(int x1, int y1, int x2, int y2, int x) 1233ac500a1fSSandy Huang { 1234ac500a1fSSandy Huang return y1 + (y2 - y1) * (x - x1) / (x2 - x1); 1235ac500a1fSSandy Huang } 1236ac500a1fSSandy Huang 1237b0989546SSandy Huang static int vop2_get_primary_plane(struct vop2 *vop2, u32 plane_mask) 1238b0989546SSandy Huang { 1239b0989546SSandy Huang int i = 0; 1240ecc31b6eSAndy Yan 1241337d1c13SDamon Ding for (i = 0; i < vop2->data->nr_layers; i++) { 1242337d1c13SDamon Ding if (plane_mask & BIT(vop2->data->vp_primary_plane_order[i])) 1243337d1c13SDamon Ding return vop2->data->vp_primary_plane_order[i]; 1244ecc31b6eSAndy Yan } 1245b0989546SSandy Huang 1246337d1c13SDamon Ding return vop2->data->vp_primary_plane_order[0]; 1247b0989546SSandy Huang } 1248b0989546SSandy Huang 124963cb669fSSandy Huang static inline u16 scl_cal_scale(int src, int dst, int shift) 1250d0408543SAndy Yan { 1251d0408543SAndy Yan return ((src * 2 - 3) << (shift - 1)) / (dst - 1); 1252d0408543SAndy Yan } 1253d0408543SAndy Yan 125463cb669fSSandy Huang static inline u16 scl_cal_scale2(int src, int dst) 1255d0408543SAndy Yan { 1256d0408543SAndy Yan return ((src - 1) << 12) / (dst - 1); 1257d0408543SAndy Yan } 1258d0408543SAndy Yan 125952ee18acSSandy Huang static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v) 1260d0408543SAndy Yan { 1261d0408543SAndy Yan writel(v, vop2->regs + offset); 1262d0408543SAndy Yan vop2->regsbak[offset >> 2] = v; 1263d0408543SAndy Yan } 1264d0408543SAndy Yan 126552ee18acSSandy Huang static inline u32 vop2_readl(struct vop2 *vop2, u32 offset) 1266d0408543SAndy Yan { 1267d0408543SAndy Yan return readl(vop2->regs + offset); 1268d0408543SAndy Yan } 1269d0408543SAndy Yan 127052ee18acSSandy Huang static inline void vop2_mask_write(struct vop2 *vop2, u32 offset, 127152ee18acSSandy Huang u32 mask, u32 shift, u32 v, 1272d0408543SAndy Yan bool write_mask) 1273d0408543SAndy Yan { 1274d0408543SAndy Yan if (!mask) 1275d0408543SAndy Yan return; 1276d0408543SAndy Yan 1277d0408543SAndy Yan if (write_mask) { 1278d0408543SAndy Yan v = ((v & mask) << shift) | (mask << (shift + 16)); 1279d0408543SAndy Yan } else { 128052ee18acSSandy Huang u32 cached_val = vop2->regsbak[offset >> 2]; 1281d0408543SAndy Yan 1282d0408543SAndy Yan v = (cached_val & ~(mask << shift)) | ((v & mask) << shift); 1283d0408543SAndy Yan vop2->regsbak[offset >> 2] = v; 1284d0408543SAndy Yan } 1285d0408543SAndy Yan 1286d0408543SAndy Yan writel(v, vop2->regs + offset); 1287d0408543SAndy Yan } 1288d0408543SAndy Yan 1289ecc31b6eSAndy Yan static inline void vop2_grf_writel(struct vop2 *vop, void *grf_base, u32 offset, 129052ee18acSSandy Huang u32 mask, u32 shift, u32 v) 129152ee18acSSandy Huang { 129252ee18acSSandy Huang u32 val = 0; 129352ee18acSSandy Huang 129452ee18acSSandy Huang val = (v << shift) | (mask << (shift + 16)); 1295ecc31b6eSAndy Yan writel(val, grf_base + offset); 129652ee18acSSandy Huang } 129752ee18acSSandy Huang 129860e469f5SDamon Ding static inline u32 vop2_grf_readl(struct vop2 *vop, void *grf_base, u32 offset, 129960e469f5SDamon Ding u32 mask, u32 shift) 130060e469f5SDamon Ding { 130160e469f5SDamon Ding return (readl(grf_base + offset) >> shift) & mask; 130260e469f5SDamon Ding } 130360e469f5SDamon Ding 13048895aec1SSandy Huang static char* get_output_if_name(u32 output_if, char *name) 13058895aec1SSandy Huang { 13068895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_RGB) 13078895aec1SSandy Huang strcat(name, " RGB"); 13088895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_BT1120) 13098895aec1SSandy Huang strcat(name, " BT1120"); 13108895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_BT656) 13118895aec1SSandy Huang strcat(name, " BT656"); 13128895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_LVDS0) 13138895aec1SSandy Huang strcat(name, " LVDS0"); 13148895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_LVDS1) 13158895aec1SSandy Huang strcat(name, " LVDS1"); 13168895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_MIPI0) 13178895aec1SSandy Huang strcat(name, " MIPI0"); 13188895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_MIPI1) 13198895aec1SSandy Huang strcat(name, " MIPI1"); 13208895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_eDP0) 13218895aec1SSandy Huang strcat(name, " eDP0"); 13228895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_eDP1) 13238895aec1SSandy Huang strcat(name, " eDP1"); 13248895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_DP0) 13258895aec1SSandy Huang strcat(name, " DP0"); 13268895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_DP1) 13278895aec1SSandy Huang strcat(name, " DP1"); 13288895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_HDMI0) 13298895aec1SSandy Huang strcat(name, " HDMI0"); 13308895aec1SSandy Huang if (output_if & VOP_OUTPUT_IF_HDMI1) 13318895aec1SSandy Huang strcat(name, " HDMI1"); 13328895aec1SSandy Huang 13338895aec1SSandy Huang return name; 13348895aec1SSandy Huang } 13358895aec1SSandy Huang 13368895aec1SSandy Huang static char *get_plane_name(int plane_id, char *name) 13378895aec1SSandy Huang { 13388895aec1SSandy Huang switch (plane_id) { 13398895aec1SSandy Huang case ROCKCHIP_VOP2_CLUSTER0: 13408895aec1SSandy Huang strcat(name, "Cluster0"); 13418895aec1SSandy Huang break; 13428895aec1SSandy Huang case ROCKCHIP_VOP2_CLUSTER1: 13438895aec1SSandy Huang strcat(name, "Cluster1"); 13448895aec1SSandy Huang break; 13458895aec1SSandy Huang case ROCKCHIP_VOP2_ESMART0: 13468895aec1SSandy Huang strcat(name, "Esmart0"); 13478895aec1SSandy Huang break; 13488895aec1SSandy Huang case ROCKCHIP_VOP2_ESMART1: 13498895aec1SSandy Huang strcat(name, "Esmart1"); 13508895aec1SSandy Huang break; 13518895aec1SSandy Huang case ROCKCHIP_VOP2_SMART0: 13528895aec1SSandy Huang strcat(name, "Smart0"); 13538895aec1SSandy Huang break; 13548895aec1SSandy Huang case ROCKCHIP_VOP2_SMART1: 13558895aec1SSandy Huang strcat(name, "Smart1"); 13568895aec1SSandy Huang break; 13578895aec1SSandy Huang case ROCKCHIP_VOP2_CLUSTER2: 13588895aec1SSandy Huang strcat(name, "Cluster2"); 13598895aec1SSandy Huang break; 13608895aec1SSandy Huang case ROCKCHIP_VOP2_CLUSTER3: 13618895aec1SSandy Huang strcat(name, "Cluster3"); 13628895aec1SSandy Huang break; 13638895aec1SSandy Huang case ROCKCHIP_VOP2_ESMART2: 13648895aec1SSandy Huang strcat(name, "Esmart2"); 13658895aec1SSandy Huang break; 13668895aec1SSandy Huang case ROCKCHIP_VOP2_ESMART3: 13678895aec1SSandy Huang strcat(name, "Esmart3"); 13688895aec1SSandy Huang break; 13698895aec1SSandy Huang } 13708895aec1SSandy Huang 13718895aec1SSandy Huang return name; 13728895aec1SSandy Huang } 13738895aec1SSandy Huang 137452ee18acSSandy Huang static bool is_yuv_output(u32 bus_format) 1375d0408543SAndy Yan { 1376d0408543SAndy Yan switch (bus_format) { 1377d0408543SAndy Yan case MEDIA_BUS_FMT_YUV8_1X24: 1378d0408543SAndy Yan case MEDIA_BUS_FMT_YUV10_1X30: 1379d0408543SAndy Yan case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 1380d0408543SAndy Yan case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 1381a0ea2d92SDamon Ding case MEDIA_BUS_FMT_YUYV8_2X8: 1382a0ea2d92SDamon Ding case MEDIA_BUS_FMT_YVYU8_2X8: 1383a0ea2d92SDamon Ding case MEDIA_BUS_FMT_UYVY8_2X8: 1384a0ea2d92SDamon Ding case MEDIA_BUS_FMT_VYUY8_2X8: 1385a0ea2d92SDamon Ding case MEDIA_BUS_FMT_YUYV8_1X16: 1386a0ea2d92SDamon Ding case MEDIA_BUS_FMT_YVYU8_1X16: 1387a0ea2d92SDamon Ding case MEDIA_BUS_FMT_UYVY8_1X16: 1388a0ea2d92SDamon Ding case MEDIA_BUS_FMT_VYUY8_1X16: 1389d0408543SAndy Yan return true; 1390d0408543SAndy Yan default: 1391d0408543SAndy Yan return false; 1392d0408543SAndy Yan } 1393d0408543SAndy Yan } 1394d0408543SAndy Yan 13955fa6e665SDamon Ding static int vop2_convert_csc_mode(int csc_mode, int bit_depth) 139610ee9f5bSAlgea Cao { 139710ee9f5bSAlgea Cao switch (csc_mode) { 139810ee9f5bSAlgea Cao case V4L2_COLORSPACE_SMPTE170M: 139910ee9f5bSAlgea Cao case V4L2_COLORSPACE_470_SYSTEM_M: 140010ee9f5bSAlgea Cao case V4L2_COLORSPACE_470_SYSTEM_BG: 140110ee9f5bSAlgea Cao return CSC_BT601L; 140210ee9f5bSAlgea Cao case V4L2_COLORSPACE_REC709: 140310ee9f5bSAlgea Cao case V4L2_COLORSPACE_SMPTE240M: 140410ee9f5bSAlgea Cao case V4L2_COLORSPACE_DEFAULT: 14055fa6e665SDamon Ding if (bit_depth == CSC_13BIT_DEPTH) 14065fa6e665SDamon Ding return CSC_BT709L_13BIT; 14075fa6e665SDamon Ding else 140810ee9f5bSAlgea Cao return CSC_BT709L; 140910ee9f5bSAlgea Cao case V4L2_COLORSPACE_JPEG: 141010ee9f5bSAlgea Cao return CSC_BT601F; 141110ee9f5bSAlgea Cao case V4L2_COLORSPACE_BT2020: 14125fa6e665SDamon Ding if (bit_depth == CSC_13BIT_DEPTH) 14135fa6e665SDamon Ding return CSC_BT2020L_13BIT; 14145fa6e665SDamon Ding else 141510ee9f5bSAlgea Cao return CSC_BT2020; 14165fa6e665SDamon Ding case V4L2_COLORSPACE_BT709F: 14175fa6e665SDamon Ding if (bit_depth == CSC_10BIT_DEPTH) { 14185fa6e665SDamon Ding printf("WARN: Unsupported bt709f at 10bit csc depth, use bt601f instead\n"); 14195fa6e665SDamon Ding return CSC_BT601F; 14205fa6e665SDamon Ding } else { 14215fa6e665SDamon Ding return CSC_BT709F_13BIT; 14225fa6e665SDamon Ding } 14235fa6e665SDamon Ding case V4L2_COLORSPACE_BT2020F: 14245fa6e665SDamon Ding if (bit_depth == CSC_10BIT_DEPTH) { 14255fa6e665SDamon Ding printf("WARN: Unsupported bt2020f at 10bit csc depth, use bt601f instead\n"); 14265fa6e665SDamon Ding return CSC_BT601F; 14275fa6e665SDamon Ding } else { 14285fa6e665SDamon Ding return CSC_BT2020F_13BIT; 14295fa6e665SDamon Ding } 143010ee9f5bSAlgea Cao default: 143110ee9f5bSAlgea Cao return CSC_BT709L; 143210ee9f5bSAlgea Cao } 143310ee9f5bSAlgea Cao } 143410ee9f5bSAlgea Cao 1435b0989546SSandy Huang static bool is_uv_swap(u32 bus_format, u32 output_mode) 1436d0408543SAndy Yan { 1437d0408543SAndy Yan /* 1438d0408543SAndy Yan * FIXME: 1439d0408543SAndy Yan * 1440d0408543SAndy Yan * There is no media type for YUV444 output, 1441d0408543SAndy Yan * so when out_mode is AAAA or P888, assume output is YUV444 on 1442d0408543SAndy Yan * yuv format. 1443d0408543SAndy Yan * 1444d0408543SAndy Yan * From H/W testing, YUV444 mode need a rb swap. 1445d0408543SAndy Yan */ 14463e59c137SSandy Huang if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 || 14473e59c137SSandy Huang bus_format == MEDIA_BUS_FMT_VYUY8_1X16 || 14483e59c137SSandy Huang bus_format == MEDIA_BUS_FMT_YVYU8_2X8 || 14493e59c137SSandy Huang bus_format == MEDIA_BUS_FMT_VYUY8_2X8 || 14503e59c137SSandy Huang ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 1451d0408543SAndy Yan bus_format == MEDIA_BUS_FMT_YUV10_1X30) && 1452d0408543SAndy Yan (output_mode == ROCKCHIP_OUT_MODE_AAAA || 14533e59c137SSandy Huang output_mode == ROCKCHIP_OUT_MODE_P888))) 1454d0408543SAndy Yan return true; 1455d0408543SAndy Yan else 1456d0408543SAndy Yan return false; 1457d0408543SAndy Yan } 1458d0408543SAndy Yan 1459b0989546SSandy Huang static inline bool is_hot_plug_devices(int output_type) 146063cb669fSSandy Huang { 1461b0989546SSandy Huang switch (output_type) { 1462b0989546SSandy Huang case DRM_MODE_CONNECTOR_HDMIA: 1463b0989546SSandy Huang case DRM_MODE_CONNECTOR_HDMIB: 1464b0989546SSandy Huang case DRM_MODE_CONNECTOR_TV: 1465b0989546SSandy Huang case DRM_MODE_CONNECTOR_DisplayPort: 1466b0989546SSandy Huang case DRM_MODE_CONNECTOR_VGA: 1467b0989546SSandy Huang case DRM_MODE_CONNECTOR_Unknown: 1468b0989546SSandy Huang return true; 1469b0989546SSandy Huang default: 1470b0989546SSandy Huang return false; 147163cb669fSSandy Huang } 147263cb669fSSandy Huang } 147363cb669fSSandy Huang 1474ecc31b6eSAndy Yan static struct vop2_win_data *vop2_find_win_by_phys_id(struct vop2 *vop2, int phys_id) 1475ecc31b6eSAndy Yan { 1476ecc31b6eSAndy Yan int i = 0; 1477ecc31b6eSAndy Yan 1478ecc31b6eSAndy Yan for (i = 0; i < vop2->data->nr_layers; i++) { 1479ecc31b6eSAndy Yan if (vop2->data->win_data[i].phys_id == phys_id) 1480ecc31b6eSAndy Yan return &vop2->data->win_data[i]; 1481ecc31b6eSAndy Yan } 1482ecc31b6eSAndy Yan 1483ecc31b6eSAndy Yan return NULL; 1484ecc31b6eSAndy Yan } 1485ecc31b6eSAndy Yan 1486b6ba80b4SDamon Ding static struct vop2_power_domain_data *vop2_find_pd_data_by_id(struct vop2 *vop2, int pd_id) 1487b6ba80b4SDamon Ding { 1488b6ba80b4SDamon Ding int i = 0; 1489b6ba80b4SDamon Ding 1490b6ba80b4SDamon Ding for (i = 0; i < vop2->data->nr_pd; i++) { 1491b6ba80b4SDamon Ding if (vop2->data->pd[i].id == pd_id) 1492b6ba80b4SDamon Ding return &vop2->data->pd[i]; 1493b6ba80b4SDamon Ding } 1494b6ba80b4SDamon Ding 1495b6ba80b4SDamon Ding return NULL; 1496b6ba80b4SDamon Ding } 1497b6ba80b4SDamon Ding 1498db328a0dSDamon Ding static void rk3568_vop2_load_lut(struct vop2 *vop2, int crtc_id, 1499db328a0dSDamon Ding u32 *lut_regs, u32 *lut_val, int lut_len) 1500db328a0dSDamon Ding { 1501db328a0dSDamon Ding u32 vp_offset = crtc_id * 0x100; 1502db328a0dSDamon Ding int i; 1503db328a0dSDamon Ding 1504db328a0dSDamon Ding vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, 1505db328a0dSDamon Ding GAMMA_PORT_SEL_MASK, GAMMA_PORT_SEL_SHIFT, 1506db328a0dSDamon Ding crtc_id, false); 1507db328a0dSDamon Ding 1508db328a0dSDamon Ding for (i = 0; i < lut_len; i++) 1509db328a0dSDamon Ding writel(lut_val[i], lut_regs + i); 1510db328a0dSDamon Ding 1511db328a0dSDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1512db328a0dSDamon Ding EN_MASK, DSP_LUT_EN_SHIFT, 1, false); 1513db328a0dSDamon Ding } 1514db328a0dSDamon Ding 1515db328a0dSDamon Ding static void rk3588_vop2_load_lut(struct vop2 *vop2, int crtc_id, 1516db328a0dSDamon Ding u32 *lut_regs, u32 *lut_val, int lut_len) 1517db328a0dSDamon Ding { 1518db328a0dSDamon Ding u32 vp_offset = crtc_id * 0x100; 1519db328a0dSDamon Ding int i; 1520db328a0dSDamon Ding 1521db328a0dSDamon Ding vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, 1522db328a0dSDamon Ding GAMMA_AHB_WRITE_SEL_MASK, GAMMA_AHB_WRITE_SEL_SHIFT, 1523db328a0dSDamon Ding crtc_id, false); 1524db328a0dSDamon Ding 1525db328a0dSDamon Ding for (i = 0; i < lut_len; i++) 1526db328a0dSDamon Ding writel(lut_val[i], lut_regs + i); 1527db328a0dSDamon Ding 1528db328a0dSDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1529db328a0dSDamon Ding EN_MASK, DSP_LUT_EN_SHIFT, 1, false); 1530db328a0dSDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1531db328a0dSDamon Ding EN_MASK, GAMMA_UPDATE_EN_SHIFT, 1, false); 1532db328a0dSDamon Ding } 1533db328a0dSDamon Ding 15341147facaSSandy Huang static int rockchip_vop2_gamma_lut_init(struct vop2 *vop2, 1535d0408543SAndy Yan struct display_state *state) 1536d0408543SAndy Yan { 15371147facaSSandy Huang struct connector_state *conn_state = &state->conn_state; 15381147facaSSandy Huang struct crtc_state *cstate = &state->crtc_state; 15391147facaSSandy Huang struct resource gamma_res; 15401147facaSSandy Huang fdt_size_t lut_size; 15411147facaSSandy Huang int i, lut_len, ret = 0; 15421147facaSSandy Huang u32 *lut_regs; 15431147facaSSandy Huang u32 *lut_val; 15441147facaSSandy Huang u32 r, g, b; 15451147facaSSandy Huang struct base2_disp_info *disp_info = conn_state->disp_info; 15461147facaSSandy Huang static int gamma_lut_en_num = 1; 15471147facaSSandy Huang 15481147facaSSandy Huang if (gamma_lut_en_num > vop2->data->nr_gammas) { 15491147facaSSandy Huang printf("warn: only %d vp support gamma\n", vop2->data->nr_gammas); 15501147facaSSandy Huang return 0; 15511147facaSSandy Huang } 15521147facaSSandy Huang 15531147facaSSandy Huang if (!disp_info) 15541147facaSSandy Huang return 0; 15551147facaSSandy Huang 15561147facaSSandy Huang if (!disp_info->gamma_lut_data.size) 15571147facaSSandy Huang return 0; 15581147facaSSandy Huang 15591147facaSSandy Huang ret = ofnode_read_resource_byname(cstate->node, "gamma_lut", &gamma_res); 15601147facaSSandy Huang if (ret) 15611147facaSSandy Huang printf("failed to get gamma lut res\n"); 15621147facaSSandy Huang lut_regs = (u32 *)gamma_res.start; 15631147facaSSandy Huang lut_size = gamma_res.end - gamma_res.start + 1; 15641147facaSSandy Huang if (lut_regs == (u32 *)FDT_ADDR_T_NONE) { 15651147facaSSandy Huang printf("failed to get gamma lut register\n"); 15661147facaSSandy Huang return 0; 15671147facaSSandy Huang } 15681147facaSSandy Huang lut_len = lut_size / 4; 15691147facaSSandy Huang if (lut_len != 256 && lut_len != 1024) { 15701147facaSSandy Huang printf("Warning: unsupport gamma lut table[%d]\n", lut_len); 15711147facaSSandy Huang return 0; 15721147facaSSandy Huang } 15731147facaSSandy Huang lut_val = (u32 *)calloc(1, lut_size); 15741147facaSSandy Huang for (i = 0; i < lut_len; i++) { 15751147facaSSandy Huang r = disp_info->gamma_lut_data.lred[i] * (lut_len - 1) / 0xffff; 15761147facaSSandy Huang g = disp_info->gamma_lut_data.lgreen[i] * (lut_len - 1) / 0xffff; 15771147facaSSandy Huang b = disp_info->gamma_lut_data.lblue[i] * (lut_len - 1) / 0xffff; 15781147facaSSandy Huang 15791147facaSSandy Huang lut_val[i] = b * lut_len * lut_len + g * lut_len + r; 15801147facaSSandy Huang } 15811147facaSSandy Huang 1582db328a0dSDamon Ding if (vop2->version == VOP_VERSION_RK3568) { 1583db328a0dSDamon Ding rk3568_vop2_load_lut(vop2, cstate->crtc_id, lut_regs, lut_val, lut_len); 15841147facaSSandy Huang gamma_lut_en_num++; 1585db328a0dSDamon Ding } else if (vop2->version == VOP_VERSION_RK3588) { 1586db328a0dSDamon Ding rk3588_vop2_load_lut(vop2, cstate->crtc_id, lut_regs, lut_val, lut_len); 1587db328a0dSDamon Ding if (cstate->splice_mode) { 1588db328a0dSDamon Ding rk3588_vop2_load_lut(vop2, cstate->splice_crtc_id, lut_regs, lut_val, lut_len); 1589db328a0dSDamon Ding gamma_lut_en_num++; 1590db328a0dSDamon Ding } 1591db328a0dSDamon Ding gamma_lut_en_num++; 1592db328a0dSDamon Ding } 15931147facaSSandy Huang 1594d0408543SAndy Yan return 0; 1595d0408543SAndy Yan } 1596d0408543SAndy Yan 15976414e3bcSSandy Huang static int rockchip_vop2_cubic_lut_init(struct vop2 *vop2, 15986414e3bcSSandy Huang struct display_state *state) 15996414e3bcSSandy Huang { 16006414e3bcSSandy Huang struct connector_state *conn_state = &state->conn_state; 16016414e3bcSSandy Huang struct crtc_state *cstate = &state->crtc_state; 16026414e3bcSSandy Huang int i, cubic_lut_len; 16036414e3bcSSandy Huang u32 vp_offset = cstate->crtc_id * 0x100; 16046414e3bcSSandy Huang struct base2_disp_info *disp_info = conn_state->disp_info; 16056414e3bcSSandy Huang struct base2_cubic_lut_data *lut = &conn_state->disp_info->cubic_lut_data; 16066414e3bcSSandy Huang u32 *cubic_lut_addr; 16076414e3bcSSandy Huang 16086414e3bcSSandy Huang if (!disp_info || CONFIG_ROCKCHIP_CUBIC_LUT_SIZE == 0) 16096414e3bcSSandy Huang return 0; 16106414e3bcSSandy Huang 16116414e3bcSSandy Huang if (!disp_info->cubic_lut_data.size) 16126414e3bcSSandy Huang return 0; 16136414e3bcSSandy Huang 16146414e3bcSSandy Huang cubic_lut_addr = (u32 *)get_cubic_lut_buffer(cstate->crtc_id); 16156414e3bcSSandy Huang cubic_lut_len = disp_info->cubic_lut_data.size; 16166414e3bcSSandy Huang 16176414e3bcSSandy Huang for (i = 0; i < cubic_lut_len / 2; i++) { 16186414e3bcSSandy Huang *cubic_lut_addr++ = ((lut->lred[2 * i]) & 0xfff) + 16196414e3bcSSandy Huang ((lut->lgreen[2 * i] & 0xfff) << 12) + 16206414e3bcSSandy Huang ((lut->lblue[2 * i] & 0xff) << 24); 16216414e3bcSSandy Huang *cubic_lut_addr++ = ((lut->lblue[2 * i] & 0xf00) >> 8) + 16226414e3bcSSandy Huang ((lut->lred[2 * i + 1] & 0xfff) << 4) + 16236414e3bcSSandy Huang ((lut->lgreen[2 * i + 1] & 0xfff) << 16) + 16246414e3bcSSandy Huang ((lut->lblue[2 * i + 1] & 0xf) << 28); 16256414e3bcSSandy Huang *cubic_lut_addr++ = (lut->lblue[2 * i + 1] & 0xff0) >> 4; 16266414e3bcSSandy Huang *cubic_lut_addr++ = 0; 16276414e3bcSSandy Huang } 16286414e3bcSSandy Huang 16296414e3bcSSandy Huang if (cubic_lut_len % 2) { 16306414e3bcSSandy Huang *cubic_lut_addr++ = (lut->lred[2 * i] & 0xfff) + 16316414e3bcSSandy Huang ((lut->lgreen[2 * i] & 0xfff) << 12) + 16326414e3bcSSandy Huang ((lut->lblue[2 * i] & 0xff) << 24); 16336414e3bcSSandy Huang *cubic_lut_addr++ = (lut->lblue[2 * i] & 0xf00) >> 8; 16346414e3bcSSandy Huang *cubic_lut_addr++ = 0; 16356414e3bcSSandy Huang *cubic_lut_addr = 0; 16366414e3bcSSandy Huang } 16376414e3bcSSandy Huang 16386414e3bcSSandy Huang vop2_writel(vop2, RK3568_VP0_3D_LUT_MST + vp_offset, 16396414e3bcSSandy Huang get_cubic_lut_buffer(cstate->crtc_id)); 16406414e3bcSSandy Huang vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL, 16416414e3bcSSandy Huang EN_MASK, LUT_DMA_EN_SHIFT, 1, false); 16426414e3bcSSandy Huang vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset, 16436414e3bcSSandy Huang EN_MASK, VP0_3D_LUT_EN_SHIFT, 1, false); 16446414e3bcSSandy Huang vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset, 16456414e3bcSSandy Huang EN_MASK, VP0_3D_LUT_UPDATE_SHIFT, 1, false); 16466414e3bcSSandy Huang 16476414e3bcSSandy Huang return 0; 16486414e3bcSSandy Huang } 16496414e3bcSSandy Huang 1650ee01dbb2SDamon Ding static void vop2_bcsh_reg_update(struct display_state *state, struct vop2 *vop2, 1651ee01dbb2SDamon Ding struct bcsh_state *bcsh_state, int crtc_id) 1652ee01dbb2SDamon Ding { 1653ee01dbb2SDamon Ding struct crtc_state *cstate = &state->crtc_state; 1654ee01dbb2SDamon Ding u32 vp_offset = crtc_id * 0x100; 1655ee01dbb2SDamon Ding 1656ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_MASK, 1657ee01dbb2SDamon Ding BCSH_CTRL_R2Y_SHIFT, cstate->post_r2y_en, false); 1658ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_MASK, 1659ee01dbb2SDamon Ding BCSH_CTRL_Y2R_SHIFT, cstate->post_y2r_en, false); 1660ee01dbb2SDamon Ding 1661ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_CSC_MODE_MASK, 1662ee01dbb2SDamon Ding BCSH_CTRL_R2Y_CSC_MODE_SHIFT, cstate->post_csc_mode, false); 1663ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_CSC_MODE_MASK, 1664ee01dbb2SDamon Ding BCSH_CTRL_Y2R_CSC_MODE_SHIFT, cstate->post_csc_mode, false); 1665ee01dbb2SDamon Ding 1666ee01dbb2SDamon Ding if (!cstate->bcsh_en) { 1667ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset, 1668ee01dbb2SDamon Ding BCSH_EN_MASK, BCSH_EN_SHIFT, 0, false); 1669ee01dbb2SDamon Ding return; 1670ee01dbb2SDamon Ding } 1671ee01dbb2SDamon Ding 1672ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1673ee01dbb2SDamon Ding BCSH_BRIGHTNESS_MASK, BCSH_BRIGHTNESS_SHIFT, 1674ee01dbb2SDamon Ding bcsh_state->brightness, false); 1675ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1676ee01dbb2SDamon Ding BCSH_CONTRAST_MASK, BCSH_CONTRAST_SHIFT, bcsh_state->contrast, false); 1677ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1678ee01dbb2SDamon Ding BCSH_SATURATION_MASK, BCSH_SATURATION_SHIFT, 1679ee01dbb2SDamon Ding bcsh_state->saturation * bcsh_state->contrast / 0x100, false); 1680ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset, 1681ee01dbb2SDamon Ding BCSH_SIN_HUE_MASK, BCSH_SIN_HUE_SHIFT, bcsh_state->sin_hue, false); 1682ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset, 1683ee01dbb2SDamon Ding BCSH_COS_HUE_MASK, BCSH_COS_HUE_SHIFT, bcsh_state->cos_hue, false); 1684ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1685ee01dbb2SDamon Ding BCSH_OUT_MODE_MASK, BCSH_OUT_MODE_SHIFT, 1686ee01dbb2SDamon Ding BCSH_OUT_MODE_NORMAL_VIDEO, false); 1687ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset, 1688ee01dbb2SDamon Ding BCSH_EN_MASK, BCSH_EN_SHIFT, 1, false); 1689ee01dbb2SDamon Ding } 1690ee01dbb2SDamon Ding 1691ac500a1fSSandy Huang static void vop2_tv_config_update(struct display_state *state, struct vop2 *vop2) 1692ac500a1fSSandy Huang { 1693ac500a1fSSandy Huang struct connector_state *conn_state = &state->conn_state; 1694ac500a1fSSandy Huang struct base_bcsh_info *bcsh_info; 1695ac500a1fSSandy Huang struct crtc_state *cstate = &state->crtc_state; 1696ee01dbb2SDamon Ding struct bcsh_state bcsh_state; 1697ac500a1fSSandy Huang int brightness, contrast, saturation, hue, sin_hue, cos_hue; 1698ac500a1fSSandy Huang 1699ac500a1fSSandy Huang if (!conn_state->disp_info) 1700ac500a1fSSandy Huang return; 1701ac500a1fSSandy Huang bcsh_info = &conn_state->disp_info->bcsh_info; 1702ac500a1fSSandy Huang if (!bcsh_info) 1703ac500a1fSSandy Huang return; 1704ac500a1fSSandy Huang 1705ac500a1fSSandy Huang if (bcsh_info->brightness != 50 || 1706ac500a1fSSandy Huang bcsh_info->contrast != 50 || 1707ac500a1fSSandy Huang bcsh_info->saturation != 50 || bcsh_info->hue != 50) 1708ee01dbb2SDamon Ding cstate->bcsh_en = true; 1709ac500a1fSSandy Huang 1710ee01dbb2SDamon Ding if (cstate->bcsh_en) { 1711ac500a1fSSandy Huang if (!cstate->yuv_overlay) 1712ee01dbb2SDamon Ding cstate->post_r2y_en = 1; 1713ac500a1fSSandy Huang if (!is_yuv_output(conn_state->bus_format)) 1714ee01dbb2SDamon Ding cstate->post_y2r_en = 1; 1715ac500a1fSSandy Huang } else { 1716ac500a1fSSandy Huang if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format)) 1717ee01dbb2SDamon Ding cstate->post_r2y_en = 1; 1718ac500a1fSSandy Huang if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format)) 1719ee01dbb2SDamon Ding cstate->post_y2r_en = 1; 1720ac500a1fSSandy Huang } 1721ac500a1fSSandy Huang 17225fa6e665SDamon Ding cstate->post_csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_10BIT_DEPTH); 1723ac500a1fSSandy Huang 1724ac500a1fSSandy Huang if (cstate->feature & VOP_FEATURE_OUTPUT_10BIT) 1725ac500a1fSSandy Huang brightness = interpolate(0, -128, 100, 127, 1726ac500a1fSSandy Huang bcsh_info->brightness); 1727ac500a1fSSandy Huang else 1728ac500a1fSSandy Huang brightness = interpolate(0, -32, 100, 31, 1729ac500a1fSSandy Huang bcsh_info->brightness); 1730ac500a1fSSandy Huang contrast = interpolate(0, 0, 100, 511, bcsh_info->contrast); 1731ac500a1fSSandy Huang saturation = interpolate(0, 0, 100, 511, bcsh_info->saturation); 1732ac500a1fSSandy Huang hue = interpolate(0, -30, 100, 30, bcsh_info->hue); 1733ac500a1fSSandy Huang 1734ac500a1fSSandy Huang 1735ac500a1fSSandy Huang /* 1736ac500a1fSSandy Huang * a:[-30~0): 1737ac500a1fSSandy Huang * sin_hue = 0x100 - sin(a)*256; 1738ac500a1fSSandy Huang * cos_hue = cos(a)*256; 1739ac500a1fSSandy Huang * a:[0~30] 1740ac500a1fSSandy Huang * sin_hue = sin(a)*256; 1741ac500a1fSSandy Huang * cos_hue = cos(a)*256; 1742ac500a1fSSandy Huang */ 1743ac500a1fSSandy Huang sin_hue = fixp_sin32(hue) >> 23; 1744ac500a1fSSandy Huang cos_hue = fixp_cos32(hue) >> 23; 1745ac500a1fSSandy Huang 1746ee01dbb2SDamon Ding bcsh_state.brightness = brightness; 1747ee01dbb2SDamon Ding bcsh_state.contrast = contrast; 1748ee01dbb2SDamon Ding bcsh_state.saturation = saturation; 1749ee01dbb2SDamon Ding bcsh_state.sin_hue = sin_hue; 1750ee01dbb2SDamon Ding bcsh_state.cos_hue = cos_hue; 1751ee01dbb2SDamon Ding 1752ee01dbb2SDamon Ding vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->crtc_id); 1753ee01dbb2SDamon Ding if (cstate->splice_mode) 1754ee01dbb2SDamon Ding vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->splice_crtc_id); 1755ee01dbb2SDamon Ding } 1756ee01dbb2SDamon Ding 1757ee01dbb2SDamon Ding static void vop2_setup_dly_for_vp(struct display_state *state, struct vop2 *vop2, int crtc_id) 1758ee01dbb2SDamon Ding { 1759ee01dbb2SDamon Ding struct connector_state *conn_state = &state->conn_state; 1760ee01dbb2SDamon Ding struct drm_display_mode *mode = &conn_state->mode; 1761ee01dbb2SDamon Ding struct crtc_state *cstate = &state->crtc_state; 1762ee01dbb2SDamon Ding u32 bg_ovl_dly, bg_dly, pre_scan_dly; 1763ee01dbb2SDamon Ding u16 hdisplay = mode->crtc_hdisplay; 1764ee01dbb2SDamon Ding u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 1765ee01dbb2SDamon Ding 1766ee01dbb2SDamon Ding bg_ovl_dly = cstate->crtc->vps[crtc_id].bg_ovl_dly; 1767ee01dbb2SDamon Ding bg_dly = vop2->data->vp_data[crtc_id].pre_scan_max_dly; 1768ee01dbb2SDamon Ding bg_dly -= bg_ovl_dly; 1769ee01dbb2SDamon Ding 1770ee01dbb2SDamon Ding if (cstate->splice_mode) 1771ee01dbb2SDamon Ding pre_scan_dly = bg_dly + (hdisplay >> 2) - 1; 1772ee01dbb2SDamon Ding else 1773ee01dbb2SDamon Ding pre_scan_dly = bg_dly + (hdisplay >> 1) - 1; 1774ee01dbb2SDamon Ding 1775ee01dbb2SDamon Ding if (vop2->version == VOP_VERSION_RK3588 && hsync_len < 8) 1776ee01dbb2SDamon Ding hsync_len = 8; 1777ee01dbb2SDamon Ding pre_scan_dly = (pre_scan_dly << 16) | hsync_len; 1778ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BG_MIX_CTRL + crtc_id * 4, 1779ee01dbb2SDamon Ding BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false); 1780ee01dbb2SDamon Ding vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + (crtc_id * 0x100), pre_scan_dly); 1781ac500a1fSSandy Huang } 1782ac500a1fSSandy Huang 1783d0408543SAndy Yan static void vop2_post_config(struct display_state *state, struct vop2 *vop2) 1784d0408543SAndy Yan { 1785d0408543SAndy Yan struct connector_state *conn_state = &state->conn_state; 1786d0408543SAndy Yan struct drm_display_mode *mode = &conn_state->mode; 178752ee18acSSandy Huang struct crtc_state *cstate = &state->crtc_state; 178852ee18acSSandy Huang u32 vp_offset = (cstate->crtc_id * 0x100); 1789d0408543SAndy Yan u16 vtotal = mode->crtc_vtotal; 1790d0408543SAndy Yan u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 1791d0408543SAndy Yan u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 1792d0408543SAndy Yan u16 hdisplay = mode->crtc_hdisplay; 1793d0408543SAndy Yan u16 vdisplay = mode->crtc_vdisplay; 1794d0408543SAndy Yan u16 hsize = 1795d0408543SAndy Yan hdisplay * (conn_state->overscan.left_margin + 1796d0408543SAndy Yan conn_state->overscan.right_margin) / 200; 1797d0408543SAndy Yan u16 vsize = 1798d0408543SAndy Yan vdisplay * (conn_state->overscan.top_margin + 1799d0408543SAndy Yan conn_state->overscan.bottom_margin) / 200; 1800d0408543SAndy Yan u16 hact_end, vact_end; 1801d0408543SAndy Yan u32 val; 1802d0408543SAndy Yan 180374bd8269SSandy Huang hsize = round_down(hsize, 2); 1804d0408543SAndy Yan vsize = round_down(vsize, 2); 1805d0408543SAndy Yan 1806d0408543SAndy Yan hact_st += hdisplay * (100 - conn_state->overscan.left_margin) / 200; 1807d0408543SAndy Yan hact_end = hact_st + hsize; 1808d0408543SAndy Yan val = hact_st << 16; 1809d0408543SAndy Yan val |= hact_end; 1810d0408543SAndy Yan 181152ee18acSSandy Huang vop2_writel(vop2, RK3568_VP0_POST_DSP_HACT_INFO + vp_offset, val); 1812d0408543SAndy Yan vact_st += vdisplay * (100 - conn_state->overscan.top_margin) / 200; 1813d0408543SAndy Yan vact_end = vact_st + vsize; 1814d0408543SAndy Yan val = vact_st << 16; 1815d0408543SAndy Yan val |= vact_end; 181652ee18acSSandy Huang vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO + vp_offset, val); 1817d0408543SAndy Yan val = scl_cal_scale2(vdisplay, vsize) << 16; 1818d0408543SAndy Yan val |= scl_cal_scale2(hdisplay, hsize); 181952ee18acSSandy Huang vop2_writel(vop2, RK3568_VP0_POST_SCL_FACTOR_YRGB + vp_offset, val); 1820d0408543SAndy Yan #define POST_HORIZONTAL_SCALEDOWN_EN(x) ((x) << 0) 1821d0408543SAndy Yan #define POST_VERTICAL_SCALEDOWN_EN(x) ((x) << 1) 182252ee18acSSandy Huang vop2_writel(vop2, RK3568_VP0_POST_SCL_CTRL + vp_offset, 1823d0408543SAndy Yan POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) | 1824d0408543SAndy Yan POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize)); 1825d0408543SAndy Yan if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 1826d0408543SAndy Yan u16 vact_st_f1 = vtotal + vact_st + 1; 1827d0408543SAndy Yan u16 vact_end_f1 = vact_st_f1 + vsize; 1828d0408543SAndy Yan 1829d0408543SAndy Yan val = vact_st_f1 << 16 | vact_end_f1; 183052ee18acSSandy Huang vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO_F1 + vp_offset, val); 1831d0408543SAndy Yan } 1832d0408543SAndy Yan 1833ee01dbb2SDamon Ding vop2_setup_dly_for_vp(state, vop2, cstate->crtc_id); 1834ee01dbb2SDamon Ding if (cstate->splice_mode) 1835ee01dbb2SDamon Ding vop2_setup_dly_for_vp(state, vop2, cstate->splice_crtc_id); 1836d0408543SAndy Yan } 1837d0408543SAndy Yan 1838d2e91fdcSDamon Ding /* 1839d2e91fdcSDamon Ding * Read VOP internal power domain on/off status. 1840d2e91fdcSDamon Ding * We should query BISR_STS register in PMU for 1841d2e91fdcSDamon Ding * power up/down status when memory repair is enabled. 1842d2e91fdcSDamon Ding * Return value: 1 for power on, 0 for power off; 1843d2e91fdcSDamon Ding */ 184460e469f5SDamon Ding static int vop2_wait_power_domain_on(struct vop2 *vop2, struct vop2_power_domain_data *pd_data) 184560e469f5SDamon Ding { 184660e469f5SDamon Ding int val = 0; 184760e469f5SDamon Ding int shift = 0; 1848b6ba80b4SDamon Ding int shift_factor = 0; 184960e469f5SDamon Ding bool is_bisr_en = false; 185060e469f5SDamon Ding 1851b6ba80b4SDamon Ding /* 1852b6ba80b4SDamon Ding * The order of pd status bits in BISR_STS register 1853b6ba80b4SDamon Ding * is different from that in VOP SYS_STS register. 1854b6ba80b4SDamon Ding */ 1855b6ba80b4SDamon Ding if (pd_data->id == VOP2_PD_DSC_8K || 1856b6ba80b4SDamon Ding pd_data->id == VOP2_PD_DSC_4K || 1857b6ba80b4SDamon Ding pd_data->id == VOP2_PD_ESMART) 1858b6ba80b4SDamon Ding shift_factor = 1; 1859b6ba80b4SDamon Ding 1860b6ba80b4SDamon Ding shift = RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT + generic_ffs(pd_data->id) - 1 - shift_factor; 1861b6ba80b4SDamon Ding is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3588_PMU_BISR_CON3, EN_MASK, shift); 186260e469f5SDamon Ding if (is_bisr_en) { 1863b6ba80b4SDamon Ding shift = RK3588_PD_CLUSTER0_PWR_STAT_SHIFI + generic_ffs(pd_data->id) - 1 - shift_factor; 1864b6ba80b4SDamon Ding 186560e469f5SDamon Ding return readl_poll_timeout(vop2->sys_pmu + RK3588_PMU_BISR_STATUS5, val, 1866d2e91fdcSDamon Ding ((val >> shift) & 0x1), 50 * 1000); 186760e469f5SDamon Ding } else { 1868b6ba80b4SDamon Ding shift = RK3588_CLUSTER0_PD_STATUS_SHIFT + generic_ffs(pd_data->id) - 1; 1869b6ba80b4SDamon Ding 187060e469f5SDamon Ding return readl_poll_timeout(vop2->regs + RK3568_SYS_STATUS0, val, 187160e469f5SDamon Ding !((val >> shift) & 0x1), 50 * 1000); 187260e469f5SDamon Ding } 187360e469f5SDamon Ding } 187460e469f5SDamon Ding 1875b6ba80b4SDamon Ding static int vop2_power_domain_on(struct vop2 *vop2, int pd_id) 187660e469f5SDamon Ding { 187760e469f5SDamon Ding struct vop2_power_domain_data *pd_data; 187860e469f5SDamon Ding int ret = 0; 187960e469f5SDamon Ding 1880b6ba80b4SDamon Ding if (!pd_id) 1881b6ba80b4SDamon Ding return 0; 1882b6ba80b4SDamon Ding 1883b6ba80b4SDamon Ding pd_data = vop2_find_pd_data_by_id(vop2, pd_id); 1884b6ba80b4SDamon Ding if (!pd_data) { 1885b6ba80b4SDamon Ding printf("can't find pd_data by id\n"); 188660e469f5SDamon Ding return -EINVAL; 188760e469f5SDamon Ding } 18882c66af11SDamon Ding 1889b6ba80b4SDamon Ding if (pd_data->parent_id) { 1890b6ba80b4SDamon Ding ret = vop2_power_domain_on(vop2, pd_data->parent_id); 189160e469f5SDamon Ding if (ret) { 189260e469f5SDamon Ding printf("can't open parent power domain\n"); 189360e469f5SDamon Ding return -EINVAL; 189460e469f5SDamon Ding } 189560e469f5SDamon Ding } 189660e469f5SDamon Ding 1897b6ba80b4SDamon Ding vop2_mask_write(vop2, RK3568_SYS_PD_CTRL, EN_MASK, 1898b6ba80b4SDamon Ding RK3588_CLUSTER0_PD_EN_SHIFT + generic_ffs(pd_id) - 1, 0, false); 189960e469f5SDamon Ding ret = vop2_wait_power_domain_on(vop2, pd_data); 190060e469f5SDamon Ding if (ret) { 190160e469f5SDamon Ding printf("wait vop2 power domain timeout\n"); 190260e469f5SDamon Ding return ret; 190360e469f5SDamon Ding } 190460e469f5SDamon Ding 190560e469f5SDamon Ding return 0; 190660e469f5SDamon Ding } 190760e469f5SDamon Ding 1908ecc31b6eSAndy Yan static void rk3588_vop2_regsbak(struct vop2 *vop2) 1909ecc31b6eSAndy Yan { 1910ecc31b6eSAndy Yan u32 *base = vop2->regs; 1911ecc31b6eSAndy Yan int i = 0; 1912ecc31b6eSAndy Yan 1913ecc31b6eSAndy Yan /* 1914ecc31b6eSAndy Yan * No need to backup HDR/DSC/GAMMA_LUT/BPP_LUT/MMU 1915ecc31b6eSAndy Yan */ 1916ecc31b6eSAndy Yan for (i = 0; i < (vop2->reg_len >> 2); i++) 1917ecc31b6eSAndy Yan vop2->regsbak[i] = base[i]; 1918ecc31b6eSAndy Yan } 1919ecc31b6eSAndy Yan 19205fa6e665SDamon Ding static void vop3_overlay_init(struct vop2 *vop2, struct display_state *state) 19215fa6e665SDamon Ding { 19225fa6e665SDamon Ding struct vop2_win_data *win_data; 19235fa6e665SDamon Ding int layer_phy_id = 0; 19245fa6e665SDamon Ding int i, j; 19255fa6e665SDamon Ding u32 ovl_port_offset = 0; 19265fa6e665SDamon Ding u32 layer_nr = 0; 19275fa6e665SDamon Ding u8 shift = 0; 19285fa6e665SDamon Ding 19295fa6e665SDamon Ding /* layer sel win id */ 19305fa6e665SDamon Ding for (i = 0; i < vop2->data->nr_vps; i++) { 19315fa6e665SDamon Ding shift = 0; 19325fa6e665SDamon Ding ovl_port_offset = 0x100 * i; 19335fa6e665SDamon Ding layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 19345fa6e665SDamon Ding for (j = 0; j < layer_nr; j++) { 19355fa6e665SDamon Ding layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 19365fa6e665SDamon Ding win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 19375fa6e665SDamon Ding vop2_mask_write(vop2, RK3528_OVL_PORT0_LAYER_SEL + ovl_port_offset, LAYER_SEL_MASK, 19385fa6e665SDamon Ding shift, win_data->layer_sel_win_id[i], false); 19395fa6e665SDamon Ding shift += 4; 19405fa6e665SDamon Ding } 19415fa6e665SDamon Ding } 19425fa6e665SDamon Ding 19435fa6e665SDamon Ding /* win sel port */ 19445fa6e665SDamon Ding for (i = 0; i < vop2->data->nr_vps; i++) { 19455fa6e665SDamon Ding layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 19465fa6e665SDamon Ding for (j = 0; j < layer_nr; j++) { 19475fa6e665SDamon Ding if (!vop2->vp_plane_mask[i].attached_layers[j]) 19485fa6e665SDamon Ding continue; 19495fa6e665SDamon Ding layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 19505fa6e665SDamon Ding win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 19515fa6e665SDamon Ding shift = win_data->win_sel_port_offset * 2; 19525fa6e665SDamon Ding vop2_mask_write(vop2, RK3528_OVL_SYS_PORT_SEL_IMD, LAYER_SEL_PORT_MASK, 19535fa6e665SDamon Ding shift, i, false); 19545fa6e665SDamon Ding } 19555fa6e665SDamon Ding } 19565fa6e665SDamon Ding } 19575fa6e665SDamon Ding 19585fa6e665SDamon Ding static void vop2_overlay_init(struct vop2 *vop2, struct display_state *state) 19595fa6e665SDamon Ding { 19605fa6e665SDamon Ding struct crtc_state *cstate = &state->crtc_state; 19615fa6e665SDamon Ding struct vop2_win_data *win_data; 19625fa6e665SDamon Ding int layer_phy_id = 0; 19635fa6e665SDamon Ding int total_used_layer = 0; 19645fa6e665SDamon Ding int port_mux = 0; 19655fa6e665SDamon Ding int i, j; 19665fa6e665SDamon Ding u32 layer_nr = 0; 19675fa6e665SDamon Ding u8 shift = 0; 19685fa6e665SDamon Ding 19695fa6e665SDamon Ding /* layer sel win id */ 19705fa6e665SDamon Ding for (i = 0; i < vop2->data->nr_vps; i++) { 19715fa6e665SDamon Ding layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 19725fa6e665SDamon Ding for (j = 0; j < layer_nr; j++) { 19735fa6e665SDamon Ding layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 19745fa6e665SDamon Ding win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 19755fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_MASK, 19765fa6e665SDamon Ding shift, win_data->layer_sel_win_id[i], false); 19775fa6e665SDamon Ding shift += 4; 19785fa6e665SDamon Ding } 19795fa6e665SDamon Ding } 19805fa6e665SDamon Ding 19815fa6e665SDamon Ding /* win sel port */ 19825fa6e665SDamon Ding for (i = 0; i < vop2->data->nr_vps; i++) { 19835fa6e665SDamon Ding layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 19845fa6e665SDamon Ding for (j = 0; j < layer_nr; j++) { 19855fa6e665SDamon Ding if (!vop2->vp_plane_mask[i].attached_layers[j]) 19865fa6e665SDamon Ding continue; 19875fa6e665SDamon Ding layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 19885fa6e665SDamon Ding win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 19895fa6e665SDamon Ding shift = win_data->win_sel_port_offset * 2; 19905fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, LAYER_SEL_PORT_MASK, 19915fa6e665SDamon Ding LAYER_SEL_PORT_SHIFT + shift, i, false); 19925fa6e665SDamon Ding } 19935fa6e665SDamon Ding } 19945fa6e665SDamon Ding 19955fa6e665SDamon Ding /** 19965fa6e665SDamon Ding * port mux config 19975fa6e665SDamon Ding */ 19985fa6e665SDamon Ding for (i = 0; i < vop2->data->nr_vps; i++) { 19995fa6e665SDamon Ding shift = i * 4; 20005fa6e665SDamon Ding if (vop2->vp_plane_mask[i].attached_layers_nr) { 20015fa6e665SDamon Ding total_used_layer += vop2->vp_plane_mask[i].attached_layers_nr; 20025fa6e665SDamon Ding port_mux = total_used_layer - 1; 20035fa6e665SDamon Ding } else { 20045fa6e665SDamon Ding port_mux = 8; 20055fa6e665SDamon Ding } 20065fa6e665SDamon Ding 20075fa6e665SDamon Ding if (i == vop2->data->nr_vps - 1) 20085fa6e665SDamon Ding port_mux = vop2->data->nr_mixers; 20095fa6e665SDamon Ding 20105fa6e665SDamon Ding cstate->crtc->vps[i].bg_ovl_dly = (vop2->data->nr_mixers - port_mux) << 1; 20115fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK, 20125fa6e665SDamon Ding PORT_MUX_SHIFT + shift, port_mux, false); 20135fa6e665SDamon Ding } 20145fa6e665SDamon Ding } 20155fa6e665SDamon Ding 20165fa6e665SDamon Ding static bool vop3_ignore_plane(struct vop2 *vop2, struct vop2_win_data *win) 20175fa6e665SDamon Ding { 20185fa6e665SDamon Ding if (!is_vop3(vop2)) 20195fa6e665SDamon Ding return false; 20205fa6e665SDamon Ding 20215fa6e665SDamon Ding if (vop2->esmart_lb_mode == VOP3_ESMART_8K_MODE && 20225fa6e665SDamon Ding win->phys_id != ROCKCHIP_VOP2_ESMART0) 20235fa6e665SDamon Ding return true; 20245fa6e665SDamon Ding else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_4K_MODE && 20255fa6e665SDamon Ding (win->phys_id == ROCKCHIP_VOP2_ESMART1 || win->phys_id == ROCKCHIP_VOP2_ESMART3)) 20265fa6e665SDamon Ding return true; 20275fa6e665SDamon Ding else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_2K_2K_MODE && 20285fa6e665SDamon Ding win->phys_id == ROCKCHIP_VOP2_ESMART1) 20295fa6e665SDamon Ding return true; 20305fa6e665SDamon Ding else 20315fa6e665SDamon Ding return false; 20325fa6e665SDamon Ding } 20335fa6e665SDamon Ding 20345fa6e665SDamon Ding static void vop3_init_esmart_scale_engine(struct vop2 *vop2) 20355fa6e665SDamon Ding { 20365fa6e665SDamon Ding struct vop2_win_data *win_data; 20375fa6e665SDamon Ding int layer_phy_id = 0; 20385fa6e665SDamon Ding int i, j; 20395fa6e665SDamon Ding u8 scale_engine_num = 0; 20405fa6e665SDamon Ding u32 layer_nr = 0; 20415fa6e665SDamon Ding 20425fa6e665SDamon Ding /* store plane mask for vop2_fixup_dts */ 20435fa6e665SDamon Ding for (i = 0; i < vop2->data->nr_vps; i++) { 20445fa6e665SDamon Ding layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 20455fa6e665SDamon Ding for (j = 0; j < layer_nr; j++) { 20465fa6e665SDamon Ding layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 20475fa6e665SDamon Ding win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 20485fa6e665SDamon Ding if (win_data->type == CLUSTER_LAYER || vop3_ignore_plane(vop2, win_data)) 20495fa6e665SDamon Ding continue; 20505fa6e665SDamon Ding 20515fa6e665SDamon Ding win_data->scale_engine_num = scale_engine_num++; 20525fa6e665SDamon Ding } 20535fa6e665SDamon Ding } 20545fa6e665SDamon Ding } 20555fa6e665SDamon Ding 2056b0989546SSandy Huang static void vop2_global_initial(struct vop2 *vop2, struct display_state *state) 2057d0408543SAndy Yan { 2058b0989546SSandy Huang struct crtc_state *cstate = &state->crtc_state; 2059b0989546SSandy Huang struct vop2_vp_plane_mask *plane_mask; 20605fa6e665SDamon Ding int layer_phy_id = 0; 20615fa6e665SDamon Ding int i, j; 20625fa6e665SDamon Ding u32 layer_nr = 0; 2063d0408543SAndy Yan 206463cb669fSSandy Huang if (vop2->global_init) 2065d0408543SAndy Yan return; 206663cb669fSSandy Huang 2067b0989546SSandy Huang /* OTP must enable at the first time, otherwise mirror layer register is error */ 206863cb669fSSandy Huang if (soc_is_rk3566()) 206963cb669fSSandy Huang vop2_mask_write(vop2, RK3568_SYS_OTP_WIN_EN, EN_MASK, 207063cb669fSSandy Huang OTP_WIN_EN_SHIFT, 1, false); 2071b0989546SSandy Huang 2072b0989546SSandy Huang if (cstate->crtc->assign_plane) {/* dts assign plane */ 2073b0989546SSandy Huang u32 plane_mask; 2074b0989546SSandy Huang int primary_plane_id; 2075b0989546SSandy Huang 2076b0989546SSandy Huang for (i = 0; i < vop2->data->nr_vps; i++) { 2077b0989546SSandy Huang plane_mask = cstate->crtc->vps[i].plane_mask; 2078b0989546SSandy Huang vop2->vp_plane_mask[i].plane_mask = plane_mask; 2079b0989546SSandy Huang layer_nr = hweight32(plane_mask); /* use bitmap to store plane mask */ 2080b0989546SSandy Huang vop2->vp_plane_mask[i].attached_layers_nr = layer_nr; 20815fc2b656SDamon Ding primary_plane_id = cstate->crtc->vps[i].primary_plane_id; 2082337d1c13SDamon Ding if (primary_plane_id >= ROCKCHIP_VOP2_LAYER_MAX) 2083b0989546SSandy Huang primary_plane_id = vop2_get_primary_plane(vop2, plane_mask); 2084b0989546SSandy Huang vop2->vp_plane_mask[i].primary_plane_id = primary_plane_id; 2085b0989546SSandy Huang vop2->vp_plane_mask[i].plane_mask = plane_mask; 2086b0989546SSandy Huang 2087b0989546SSandy Huang /* plane mask[bitmap] convert into layer phy id[enum vop2_layer_phy_id]*/ 2088b0989546SSandy Huang for (j = 0; j < layer_nr; j++) { 2089b0989546SSandy Huang vop2->vp_plane_mask[i].attached_layers[j] = ffs(plane_mask) - 1; 2090b0989546SSandy Huang plane_mask &= ~BIT(vop2->vp_plane_mask[i].attached_layers[j]); 209163cb669fSSandy Huang } 2092b0989546SSandy Huang } 2093b0989546SSandy Huang } else {/* need soft assign plane mask */ 2094b0989546SSandy Huang /* find the first unplug devices and set it as main display */ 2095b0989546SSandy Huang int main_vp_index = -1; 2096b0989546SSandy Huang int active_vp_num = 0; 2097b0989546SSandy Huang 2098b0989546SSandy Huang for (i = 0; i < vop2->data->nr_vps; i++) { 2099b0989546SSandy Huang if (cstate->crtc->vps[i].enable) 2100b0989546SSandy Huang active_vp_num++; 2101b0989546SSandy Huang } 2102b0989546SSandy Huang printf("VOP have %d active VP\n", active_vp_num); 2103b0989546SSandy Huang 2104b0989546SSandy Huang if (soc_is_rk3566() && active_vp_num > 2) 2105b0989546SSandy Huang printf("ERROR: rk3566 only support 2 display output!!\n"); 2106b0989546SSandy Huang plane_mask = vop2->data->plane_mask; 2107b0989546SSandy Huang plane_mask += (active_vp_num - 1) * VOP2_VP_MAX; 21085fa6e665SDamon Ding /* 21095fa6e665SDamon Ding * For rk3528, one display policy for hdmi store in plane_mask[0], and the other 21105fa6e665SDamon Ding * for cvbs store in plane_mask[2]. 21115fa6e665SDamon Ding */ 21125fa6e665SDamon Ding if (vop2->version == VOP_VERSION_RK3528 && active_vp_num == 1 && 21135fa6e665SDamon Ding cstate->crtc->vps[1].output_type == DRM_MODE_CONNECTOR_TV) 21145fa6e665SDamon Ding plane_mask += 2 * VOP2_VP_MAX; 2115b0989546SSandy Huang 21165fa6e665SDamon Ding if (vop2->version == VOP_VERSION_RK3528) { 21175fa6e665SDamon Ding /* 21185fa6e665SDamon Ding * For rk3528, the plane mask of vp is limited, only esmart2 can be selected 21195fa6e665SDamon Ding * by both vp0 and vp1. 21205fa6e665SDamon Ding */ 21215fa6e665SDamon Ding j = 0; 21225fa6e665SDamon Ding } else { 2123b0989546SSandy Huang for (i = 0; i < vop2->data->nr_vps; i++) { 2124b0989546SSandy Huang if (!is_hot_plug_devices(cstate->crtc->vps[i].output_type)) { 2125b0989546SSandy Huang vop2->vp_plane_mask[i] = plane_mask[0]; /* the first store main display plane mask*/ 2126b0989546SSandy Huang main_vp_index = i; 2127e007876dSSandy Huang break; 2128b0989546SSandy Huang } 2129b0989546SSandy Huang } 2130b0989546SSandy Huang 2131b0989546SSandy Huang /* if no find unplug devices, use vp0 as main display */ 2132b0989546SSandy Huang if (main_vp_index < 0) { 2133b0989546SSandy Huang main_vp_index = 0; 2134b0989546SSandy Huang vop2->vp_plane_mask[0] = plane_mask[0]; 2135b0989546SSandy Huang } 2136b0989546SSandy Huang 2137b0989546SSandy Huang j = 1; /* plane_mask[0] store main display, so we from plane_mask[1] */ 21385fa6e665SDamon Ding } 2139b0989546SSandy Huang 2140b0989546SSandy Huang /* init other display except main display */ 2141b0989546SSandy Huang for (i = 0; i < vop2->data->nr_vps; i++) { 2142b0989546SSandy Huang if (i == main_vp_index || !cstate->crtc->vps[i].enable) /* main display or no connect devices */ 2143b0989546SSandy Huang continue; 2144b0989546SSandy Huang vop2->vp_plane_mask[i] = plane_mask[j++]; 2145b0989546SSandy Huang } 2146b0989546SSandy Huang 2147b0989546SSandy Huang /* store plane mask for vop2_fixup_dts */ 2148b0989546SSandy Huang for (i = 0; i < vop2->data->nr_vps; i++) { 2149b0989546SSandy Huang layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 2150b0989546SSandy Huang for (j = 0; j < layer_nr; j++) { 2151b0989546SSandy Huang layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 2152b0989546SSandy Huang vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id); 2153b0989546SSandy Huang } 2154b0989546SSandy Huang } 2155b0989546SSandy Huang } 2156b0989546SSandy Huang 215760e469f5SDamon Ding if (vop2->version == VOP_VERSION_RK3588) 215860e469f5SDamon Ding rk3588_vop2_regsbak(vop2); 215960e469f5SDamon Ding else 216060e469f5SDamon Ding memcpy(vop2->regsbak, vop2->regs, vop2->reg_len); 216160e469f5SDamon Ding 216260e469f5SDamon Ding vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, 216360e469f5SDamon Ding OVL_PORT_MUX_REG_DONE_IMD_SHIFT, 1, false); 216460e469f5SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 216560e469f5SDamon Ding IF_CTRL_REG_DONE_IMD_SHIFT, 1, false); 216660e469f5SDamon Ding 2167b0989546SSandy Huang for (i = 0; i < vop2->data->nr_vps; i++) { 2168b0989546SSandy Huang printf("vp%d have layer nr:%d[", i, vop2->vp_plane_mask[i].attached_layers_nr); 2169b0989546SSandy Huang for (j = 0; j < vop2->vp_plane_mask[i].attached_layers_nr; j++) 2170b0989546SSandy Huang printf("%d ", vop2->vp_plane_mask[i].attached_layers[j]); 2171b0989546SSandy Huang printf("], primary plane: %d\n", vop2->vp_plane_mask[i].primary_plane_id); 2172b0989546SSandy Huang } 2173b0989546SSandy Huang 21745fa6e665SDamon Ding if (is_vop3(vop2)) 21755fa6e665SDamon Ding vop3_overlay_init(vop2, state); 21765fa6e665SDamon Ding else 21775fa6e665SDamon Ding vop2_overlay_init(vop2, state); 2178b0989546SSandy Huang 21795fa6e665SDamon Ding if (is_vop3(vop2)) { 21805fa6e665SDamon Ding /* 21815fa6e665SDamon Ding * you can rewrite at dts vop node: 21825fa6e665SDamon Ding * 21835fa6e665SDamon Ding * VOP3_ESMART_8K_MODE = 0, 21845fa6e665SDamon Ding * VOP3_ESMART_4K_4K_MODE = 1, 21855fa6e665SDamon Ding * VOP3_ESMART_4K_2K_2K_MODE = 2, 21865fa6e665SDamon Ding * VOP3_ESMART_2K_2K_2K_2K_MODE = 3, 21875fa6e665SDamon Ding * 21885fa6e665SDamon Ding * &vop { 21895fa6e665SDamon Ding * esmart_lb_mode = /bits/ 8 <2>; 21905fa6e665SDamon Ding * }; 219163cb669fSSandy Huang */ 21925fa6e665SDamon Ding vop2->esmart_lb_mode = ofnode_read_u32_default(cstate->node, "esmart_lb_mode", -1); 21935fa6e665SDamon Ding if (vop2->esmart_lb_mode < 0) 21945fa6e665SDamon Ding vop2->esmart_lb_mode = vop2->data->esmart_lb_mode; 21955fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, ESMART_LB_MODE_SEL_MASK, 21965fa6e665SDamon Ding ESMART_LB_MODE_SEL_SHIFT, vop2->esmart_lb_mode, false); 2197d0408543SAndy Yan 21985fa6e665SDamon Ding vop3_init_esmart_scale_engine(vop2); 219963cb669fSSandy Huang } 220063cb669fSSandy Huang 2201ecc31b6eSAndy Yan if (vop2->version == VOP_VERSION_RK3568) 220263cb669fSSandy Huang vop2_writel(vop2, RK3568_AUTO_GATING_CTRL, 0); 220363cb669fSSandy Huang 220463cb669fSSandy Huang vop2->global_init = true; 2205d0408543SAndy Yan } 2206d0408543SAndy Yan 2207d0408543SAndy Yan static int vop2_initial(struct vop2 *vop2, struct display_state *state) 2208d0408543SAndy Yan { 2209d0408543SAndy Yan struct crtc_state *cstate = &state->crtc_state; 221063cb669fSSandy Huang int ret; 2211d0408543SAndy Yan 2212d0408543SAndy Yan /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 2213d0408543SAndy Yan ret = clk_set_defaults(cstate->dev); 2214d0408543SAndy Yan if (ret) 2215d0408543SAndy Yan debug("%s clk_set_defaults failed %d\n", __func__, ret); 2216d0408543SAndy Yan 22171147facaSSandy Huang rockchip_vop2_gamma_lut_init(vop2, state); 22186414e3bcSSandy Huang rockchip_vop2_cubic_lut_init(vop2, state); 2219d0408543SAndy Yan 2220d0408543SAndy Yan return 0; 2221d0408543SAndy Yan } 2222d0408543SAndy Yan 2223d0408543SAndy Yan /* 2224d0408543SAndy Yan * VOP2 have multi video ports. 2225d0408543SAndy Yan * video port ------- crtc 2226d0408543SAndy Yan */ 2227d0408543SAndy Yan static int rockchip_vop2_preinit(struct display_state *state) 2228d0408543SAndy Yan { 2229d0408543SAndy Yan struct crtc_state *cstate = &state->crtc_state; 2230d0408543SAndy Yan const struct vop2_data *vop2_data = cstate->crtc->data; 2231d0408543SAndy Yan 2232d0408543SAndy Yan if (!rockchip_vop2) { 22330d2d6a97SSandy Huang rockchip_vop2 = calloc(1, sizeof(struct vop2)); 2234d0408543SAndy Yan if (!rockchip_vop2) 2235d0408543SAndy Yan return -ENOMEM; 2236d0408543SAndy Yan rockchip_vop2->regs = dev_read_addr_ptr(cstate->dev); 2237d0408543SAndy Yan rockchip_vop2->regsbak = malloc(RK3568_MAX_REG); 2238d0408543SAndy Yan rockchip_vop2->reg_len = RK3568_MAX_REG; 223963cb669fSSandy Huang rockchip_vop2->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 2240d0408543SAndy Yan if (rockchip_vop2->grf <= 0) 224163cb669fSSandy Huang printf("%s: Get syscon grf failed (ret=%p)\n", __func__, rockchip_vop2->grf); 2242d0408543SAndy Yan rockchip_vop2->version = vop2_data->version; 2243d0408543SAndy Yan rockchip_vop2->data = vop2_data; 2244ecc31b6eSAndy Yan if (rockchip_vop2->version == VOP_VERSION_RK3588) { 2245b890760eSAlgea Cao struct regmap *map; 2246b890760eSAlgea Cao 2247ecc31b6eSAndy Yan rockchip_vop2->vop_grf = syscon_get_first_range(ROCKCHIP_SYSCON_VOP_GRF); 2248ecc31b6eSAndy Yan if (rockchip_vop2->vop_grf <= 0) 2249ecc31b6eSAndy Yan printf("%s: Get syscon vop_grf failed (ret=%p)\n", __func__, rockchip_vop2->vop_grf); 2250b890760eSAlgea Cao map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,vo1-grf"); 2251b890760eSAlgea Cao rockchip_vop2->vo1_grf = regmap_get_range(map, 0); 2252ecc31b6eSAndy Yan if (rockchip_vop2->vo1_grf <= 0) 2253ecc31b6eSAndy Yan printf("%s: Get syscon vo1_grf failed (ret=%p)\n", __func__, rockchip_vop2->vo1_grf); 225460e469f5SDamon Ding rockchip_vop2->sys_pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU); 2255b890760eSAlgea Cao if (rockchip_vop2->sys_pmu <= 0) 225660e469f5SDamon Ding printf("%s: Get syscon sys_pmu failed (ret=%p)\n", __func__, rockchip_vop2->sys_pmu); 2257ecc31b6eSAndy Yan } 2258d0408543SAndy Yan } 2259d0408543SAndy Yan 2260d0408543SAndy Yan cstate->private = rockchip_vop2; 226163cb669fSSandy Huang cstate->max_output = vop2_data->vp_data[cstate->crtc_id].max_output; 226263cb669fSSandy Huang cstate->feature = vop2_data->vp_data[cstate->crtc_id].feature; 2263d0408543SAndy Yan 226489912f2dSSandy Huang vop2_global_initial(rockchip_vop2, state); 226589912f2dSSandy Huang 2266d0408543SAndy Yan return 0; 2267d0408543SAndy Yan } 2268d0408543SAndy Yan 2269ecc31b6eSAndy Yan /* 2270ecc31b6eSAndy Yan * calc the dclk on rk3588 2271ecc31b6eSAndy Yan * the available div of dclk is 1, 2, 4 2272ecc31b6eSAndy Yan * 2273ecc31b6eSAndy Yan */ 2274ecc31b6eSAndy Yan static unsigned long vop2_calc_dclk(unsigned long child_clk, unsigned long max_dclk) 2275ecc31b6eSAndy Yan { 2276ecc31b6eSAndy Yan if (child_clk * 4 <= max_dclk) 2277ecc31b6eSAndy Yan return child_clk * 4; 2278ecc31b6eSAndy Yan else if (child_clk * 2 <= max_dclk) 2279ecc31b6eSAndy Yan return child_clk * 2; 2280ecc31b6eSAndy Yan else if (child_clk <= max_dclk) 2281ecc31b6eSAndy Yan return child_clk; 2282ecc31b6eSAndy Yan else 2283ecc31b6eSAndy Yan return 0; 2284ecc31b6eSAndy Yan } 2285ecc31b6eSAndy Yan 2286ecc31b6eSAndy Yan /* 2287ecc31b6eSAndy Yan * 4 pixclk/cycle on rk3588 2288ecc31b6eSAndy Yan * RGB/eDP/HDMI: if_pixclk >= dclk_core 2289ecc31b6eSAndy Yan * DP: dp_pixclk = dclk_out <= dclk_core 2290ecc31b6eSAndy Yan * DSI: mipi_pixclk <= dclk_out <= dclk_core 2291ecc31b6eSAndy Yan */ 2292ecc31b6eSAndy Yan static unsigned long vop2_calc_cru_cfg(struct display_state *state, 2293ecc31b6eSAndy Yan int *dclk_core_div, int *dclk_out_div, 2294ecc31b6eSAndy Yan int *if_pixclk_div, int *if_dclk_div) 2295d0408543SAndy Yan { 2296d0408543SAndy Yan struct crtc_state *cstate = &state->crtc_state; 2297d0408543SAndy Yan struct connector_state *conn_state = &state->conn_state; 2298d0408543SAndy Yan struct drm_display_mode *mode = &conn_state->mode; 2299d0408543SAndy Yan struct vop2 *vop2 = cstate->private; 23000a1fb152SZhang Yubing unsigned long v_pixclk = mode->crtc_clock; 2301ecc31b6eSAndy Yan unsigned long dclk_core_rate = v_pixclk >> 2; 2302ecc31b6eSAndy Yan unsigned long dclk_rate = v_pixclk; 2303ecc31b6eSAndy Yan unsigned long dclk_out_rate; 2304ecc31b6eSAndy Yan u64 if_dclk_rate; 2305ecc31b6eSAndy Yan u64 if_pixclk_rate; 2306ecc31b6eSAndy Yan int output_type = conn_state->type; 2307ecc31b6eSAndy Yan int output_mode = conn_state->output_mode; 2308ecc31b6eSAndy Yan int K = 1; 2309ecc31b6eSAndy Yan 23100a1fb152SZhang Yubing if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE && 23110a1fb152SZhang Yubing output_mode == ROCKCHIP_OUT_MODE_YUV420) { 23120a1fb152SZhang Yubing printf("Dual channel and YUV420 can't work together\n"); 23130a1fb152SZhang Yubing return -EINVAL; 23140a1fb152SZhang Yubing } 23150a1fb152SZhang Yubing 23160a1fb152SZhang Yubing if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE || 23170a1fb152SZhang Yubing output_mode == ROCKCHIP_OUT_MODE_YUV420) 23180a1fb152SZhang Yubing K = 2; 23190a1fb152SZhang Yubing 2320ecc31b6eSAndy Yan if (output_type == DRM_MODE_CONNECTOR_HDMIA) { 2321ecc31b6eSAndy Yan /* 2322ecc31b6eSAndy Yan * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate 2323ecc31b6eSAndy Yan * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate 2324ecc31b6eSAndy Yan */ 23250a1fb152SZhang Yubing if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE || 23260a1fb152SZhang Yubing output_mode == ROCKCHIP_OUT_MODE_YUV420) { 2327b890760eSAlgea Cao dclk_rate = dclk_rate >> 1; 2328ecc31b6eSAndy Yan K = 2; 2329b890760eSAlgea Cao } 233012ee5af0SDamon Ding if (cstate->dsc_enable) { 233112ee5af0SDamon Ding if_pixclk_rate = cstate->dsc_cds_clk_rate << 1; 233212ee5af0SDamon Ding if_dclk_rate = cstate->dsc_cds_clk_rate; 2333ecc31b6eSAndy Yan } else { 2334ecc31b6eSAndy Yan if_pixclk_rate = (dclk_core_rate << 1) / K; 2335ecc31b6eSAndy Yan if_dclk_rate = dclk_core_rate / K; 2336ecc31b6eSAndy Yan } 2337ecc31b6eSAndy Yan 2338631ee99aSZhang Yubing if (v_pixclk > VOP2_MAX_DCLK_RATE) 2339631ee99aSZhang Yubing dclk_rate = vop2_calc_dclk(dclk_core_rate, vop2->data->vp_data->max_dclk); 2340631ee99aSZhang Yubing 2341ecc31b6eSAndy Yan if (!dclk_rate) { 2342ecc31b6eSAndy Yan printf("DP if_pixclk_rate out of range(max_dclk: %d KHZ, dclk_core: %lld KHZ)\n", 2343ecc31b6eSAndy Yan vop2->data->vp_data->max_dclk, if_pixclk_rate); 2344ecc31b6eSAndy Yan return -EINVAL; 2345ecc31b6eSAndy Yan } 2346ecc31b6eSAndy Yan *if_pixclk_div = dclk_rate / if_pixclk_rate; 2347ecc31b6eSAndy Yan *if_dclk_div = dclk_rate / if_dclk_rate; 2348b890760eSAlgea Cao *dclk_core_div = dclk_rate / dclk_core_rate; 2349b890760eSAlgea Cao printf("dclk:%lu,if_pixclk_div;%d,if_dclk_div:%d\n", 2350b890760eSAlgea Cao dclk_rate, *if_pixclk_div, *if_dclk_div); 2351ecc31b6eSAndy Yan } else if (output_type == DRM_MODE_CONNECTOR_eDP) { 2352ecc31b6eSAndy Yan /* edp_pixclk = edp_dclk > dclk_core */ 2353ecc31b6eSAndy Yan if_pixclk_rate = v_pixclk / K; 2354ecc31b6eSAndy Yan if_dclk_rate = v_pixclk / K; 2355ecc31b6eSAndy Yan dclk_rate = if_pixclk_rate * K; 2356ecc31b6eSAndy Yan *dclk_core_div = dclk_rate / dclk_core_rate; 2357ecc31b6eSAndy Yan *if_pixclk_div = dclk_rate / if_pixclk_rate; 2358ecc31b6eSAndy Yan *if_dclk_div = *if_pixclk_div; 2359ecc31b6eSAndy Yan } else if (output_type == DRM_MODE_CONNECTOR_DisplayPort) { 2360ecc31b6eSAndy Yan dclk_out_rate = v_pixclk >> 2; 23610a1fb152SZhang Yubing dclk_out_rate = dclk_out_rate / K; 2362ecc31b6eSAndy Yan 23636b2bd269SZhang Yubing dclk_rate = vop2_calc_dclk(dclk_out_rate, vop2->data->vp_data->max_dclk); 2364ecc31b6eSAndy Yan if (!dclk_rate) { 2365ecc31b6eSAndy Yan printf("DP dclk_core out of range(max_dclk: %d KHZ, dclk_core: %ld KHZ)\n", 2366ecc31b6eSAndy Yan vop2->data->vp_data->max_dclk, dclk_core_rate); 2367ecc31b6eSAndy Yan return -EINVAL; 2368ecc31b6eSAndy Yan } 2369ecc31b6eSAndy Yan *dclk_out_div = dclk_rate / dclk_out_rate; 2370ecc31b6eSAndy Yan *dclk_core_div = dclk_rate / dclk_core_rate; 2371ecc31b6eSAndy Yan } else if (output_type == DRM_MODE_CONNECTOR_DSI) { 2372ecc31b6eSAndy Yan if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 2373ecc31b6eSAndy Yan K = 2; 237412ee5af0SDamon Ding if (cstate->dsc_enable) 237512ee5af0SDamon Ding /* dsc output is 96bit, dsi input is 192 bit */ 237612ee5af0SDamon Ding if_pixclk_rate = cstate->dsc_cds_clk_rate >> 1; 2377ecc31b6eSAndy Yan else 2378ecc31b6eSAndy Yan if_pixclk_rate = dclk_core_rate / K; 2379ecc31b6eSAndy Yan /* dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4 */ 238012ee5af0SDamon Ding dclk_out_rate = dclk_core_rate / K; 2381ecc31b6eSAndy Yan /* dclk_rate = N * dclk_core_rate N = (1,2,4 ), we get a little factor here */ 23829f076eccSZhang Yubing dclk_rate = vop2_calc_dclk(dclk_out_rate, vop2->data->vp_data->max_dclk); 23839f076eccSZhang Yubing if (!dclk_rate) { 23849f076eccSZhang Yubing printf("MIPI dclk out of range(max_dclk: %d KHZ, dclk_rate: %ld KHZ)\n", 23859f076eccSZhang Yubing vop2->data->vp_data->max_dclk, dclk_rate); 23869f076eccSZhang Yubing return -EINVAL; 23879f076eccSZhang Yubing } 238812ee5af0SDamon Ding 238912ee5af0SDamon Ding if (cstate->dsc_enable) 239012ee5af0SDamon Ding dclk_rate = dclk_rate >> 1; 239112ee5af0SDamon Ding 2392ecc31b6eSAndy Yan *dclk_out_div = dclk_rate / dclk_out_rate; 2393ecc31b6eSAndy Yan *dclk_core_div = dclk_rate / dclk_core_rate; 2394ecc31b6eSAndy Yan *if_pixclk_div = 1; /*mipi pixclk == dclk_out*/ 239512ee5af0SDamon Ding if (cstate->dsc_enable) 239612ee5af0SDamon Ding *if_pixclk_div = dclk_out_rate / if_pixclk_rate; 2397ecc31b6eSAndy Yan 2398ecc31b6eSAndy Yan } else if (output_type == DRM_MODE_CONNECTOR_DPI) { 2399ecc31b6eSAndy Yan dclk_rate = v_pixclk; 2400ecc31b6eSAndy Yan *dclk_core_div = dclk_rate / dclk_core_rate; 2401ecc31b6eSAndy Yan } 2402ecc31b6eSAndy Yan 2403ecc31b6eSAndy Yan *if_pixclk_div = ilog2(*if_pixclk_div); 2404ecc31b6eSAndy Yan *if_dclk_div = ilog2(*if_dclk_div); 2405ecc31b6eSAndy Yan *dclk_core_div = ilog2(*dclk_core_div); 2406ecc31b6eSAndy Yan *dclk_out_div = ilog2(*dclk_out_div); 2407ecc31b6eSAndy Yan 2408ecc31b6eSAndy Yan return dclk_rate; 2409ecc31b6eSAndy Yan } 2410ecc31b6eSAndy Yan 241112ee5af0SDamon Ding static int vop2_calc_dsc_clk(struct display_state *state) 2412ecc31b6eSAndy Yan { 241312ee5af0SDamon Ding struct connector_state *conn_state = &state->conn_state; 2414ecc31b6eSAndy Yan struct drm_display_mode *mode = &conn_state->mode; 241512ee5af0SDamon Ding struct crtc_state *cstate = &state->crtc_state; 241612ee5af0SDamon Ding u64 v_pixclk = mode->clock; /* video timing pixclk */ 2417ecc31b6eSAndy Yan u8 k = 1; 2418ecc31b6eSAndy Yan 2419ecc31b6eSAndy Yan if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 2420ecc31b6eSAndy Yan k = 2; 2421ecc31b6eSAndy Yan 242212ee5af0SDamon Ding cstate->dsc_txp_clk_rate = v_pixclk; 242312ee5af0SDamon Ding do_div(cstate->dsc_txp_clk_rate, (cstate->dsc_pixel_num * k)); 2424ecc31b6eSAndy Yan 242512ee5af0SDamon Ding cstate->dsc_pxl_clk_rate = v_pixclk; 242612ee5af0SDamon Ding do_div(cstate->dsc_pxl_clk_rate, (cstate->dsc_slice_num * k)); 2427ecc31b6eSAndy Yan 2428ecc31b6eSAndy Yan /* dsc_cds = crtc_clock / (cds_dat_width / bits_per_pixel) 2429ecc31b6eSAndy Yan * cds_dat_width = 96; 2430ecc31b6eSAndy Yan * bits_per_pixel = [8-12]; 2431b61227a3SDamon Ding * As cds clk is div from txp clk and only support 1/2/4 div, 2432b61227a3SDamon Ding * so when txp_clk is equal to v_pixclk, we set dsc_cds = crtc_clock / 4, 2433b61227a3SDamon Ding * otherwise dsc_cds = crtc_clock / 8; 2434ecc31b6eSAndy Yan */ 2435b61227a3SDamon Ding cstate->dsc_cds_clk_rate = v_pixclk / (cstate->dsc_txp_clk_rate == v_pixclk ? 4 : 8); 2436ecc31b6eSAndy Yan 2437ecc31b6eSAndy Yan return 0; 2438ecc31b6eSAndy Yan } 2439ecc31b6eSAndy Yan 2440ecc31b6eSAndy Yan static unsigned long rk3588_vop2_if_cfg(struct display_state *state) 2441ecc31b6eSAndy Yan { 2442ecc31b6eSAndy Yan struct crtc_state *cstate = &state->crtc_state; 2443ecc31b6eSAndy Yan struct connector_state *conn_state = &state->conn_state; 2444ecc31b6eSAndy Yan struct drm_display_mode *mode = &conn_state->mode; 244512ee5af0SDamon Ding struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap; 2446ecc31b6eSAndy Yan struct vop2 *vop2 = cstate->private; 244752ee18acSSandy Huang u32 vp_offset = (cstate->crtc_id * 0x100); 2448ecc31b6eSAndy Yan u16 hdisplay = mode->crtc_hdisplay; 2449ecc31b6eSAndy Yan int output_if = conn_state->output_if; 2450ecc31b6eSAndy Yan int if_pixclk_div = 0; 2451ecc31b6eSAndy Yan int if_dclk_div = 0; 2452ecc31b6eSAndy Yan unsigned long dclk_rate; 2453d0408543SAndy Yan u32 val; 2454ecc31b6eSAndy Yan 2455b890760eSAlgea Cao if (output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) { 2456b890760eSAlgea Cao val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0; 2457b890760eSAlgea Cao val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0; 2458b890760eSAlgea Cao } else { 2459ecc31b6eSAndy Yan val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 2460ecc31b6eSAndy Yan val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 2461b890760eSAlgea Cao } 2462ecc31b6eSAndy Yan 246312ee5af0SDamon Ding if (cstate->dsc_enable) { 246412ee5af0SDamon Ding int k = 1; 246512ee5af0SDamon Ding 2466ecc31b6eSAndy Yan if (!vop2->data->nr_dscs) { 246712ee5af0SDamon Ding printf("Unsupported DSC\n"); 2468ecc31b6eSAndy Yan return 0; 2469ecc31b6eSAndy Yan } 247012ee5af0SDamon Ding 247112ee5af0SDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 247212ee5af0SDamon Ding k = 2; 247312ee5af0SDamon Ding 247412ee5af0SDamon Ding cstate->dsc_id = output_if & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_HDMI0) ? 0 : 1; 247512ee5af0SDamon Ding cstate->dsc_slice_num = hdisplay / dsc_sink_cap->slice_width / k; 247612ee5af0SDamon Ding cstate->dsc_pixel_num = cstate->dsc_slice_num > 4 ? 4 : cstate->dsc_slice_num; 247712ee5af0SDamon Ding 247812ee5af0SDamon Ding vop2_calc_dsc_clk(state); 247912ee5af0SDamon Ding printf("Enable DSC%d slice:%dx%d, slice num:%d\n", 248012ee5af0SDamon Ding cstate->dsc_id, dsc_sink_cap->slice_width, 248112ee5af0SDamon Ding dsc_sink_cap->slice_height, cstate->dsc_slice_num); 2482ecc31b6eSAndy Yan } 2483ecc31b6eSAndy Yan 2484b61227a3SDamon Ding dclk_rate = vop2_calc_cru_cfg(state, &cstate->dclk_core_div, &cstate->dclk_out_div, &if_pixclk_div, &if_dclk_div); 2485ecc31b6eSAndy Yan 2486ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_RGB) { 2487ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 2488ecc31b6eSAndy Yan 4, false); 2489ecc31b6eSAndy Yan } 2490ecc31b6eSAndy Yan 2491ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_BT1120) { 2492ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 2493ecc31b6eSAndy Yan 3, false); 2494ecc31b6eSAndy Yan } 2495ecc31b6eSAndy Yan 2496ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_BT656) { 2497ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 2498ecc31b6eSAndy Yan 2, false); 2499ecc31b6eSAndy Yan } 2500ecc31b6eSAndy Yan 2501ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_MIPI0) { 2502ecc31b6eSAndy Yan if (cstate->crtc_id == 2) 2503ecc31b6eSAndy Yan val = 0; 2504ecc31b6eSAndy Yan else 2505ecc31b6eSAndy Yan val = 1; 250641874944SGuochun Huang 25073df6e59eSDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE) 250841874944SGuochun Huang vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 250941874944SGuochun Huang RK3588_MIPI_DSI0_MODE_SEL_SHIFT, 1, false); 251041874944SGuochun Huang 2511ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI0_EN_SHIFT, 2512ecc31b6eSAndy Yan 1, false); 2513ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, 1, RK3588_MIPI0_MUX_SHIFT, val, false); 2514ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI0_PIXCLK_DIV_SHIFT, 2515ecc31b6eSAndy Yan if_pixclk_div, false); 251641874944SGuochun Huang 251741874944SGuochun Huang if (conn_state->hold_mode) { 251841874944SGuochun Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 251941874944SGuochun Huang EN_MASK, EDPI_TE_EN, 1, false); 252041874944SGuochun Huang 252141874944SGuochun Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 252241874944SGuochun Huang EN_MASK, EDPI_WMS_HOLD_EN, 1, false); 252341874944SGuochun Huang } 2524ecc31b6eSAndy Yan } 2525ecc31b6eSAndy Yan 2526ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_MIPI1) { 2527ecc31b6eSAndy Yan if (cstate->crtc_id == 2) 2528ecc31b6eSAndy Yan val = 0; 2529ecc31b6eSAndy Yan else if (cstate->crtc_id == 3) 2530ecc31b6eSAndy Yan val = 1; 2531ecc31b6eSAndy Yan else 2532ecc31b6eSAndy Yan val = 3; /*VP1*/ 25333df6e59eSDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE) 253441874944SGuochun Huang vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 253541874944SGuochun Huang RK3588_MIPI_DSI1_MODE_SEL_SHIFT, 1, false); 253641874944SGuochun Huang 2537ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI1_EN_SHIFT, 2538ecc31b6eSAndy Yan 1, false); 2539ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, MIPI1_MUX_SHIFT, 2540ecc31b6eSAndy Yan val, false); 2541ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI1_PIXCLK_DIV_SHIFT, 2542ecc31b6eSAndy Yan if_pixclk_div, false); 254341874944SGuochun Huang 254441874944SGuochun Huang if (conn_state->hold_mode) { 254541874944SGuochun Huang /* UNDO: RK3588 VP1->DSC1->DSI1 only can support soft TE mode */ 254641874944SGuochun Huang if (vop2->version == VOP_VERSION_RK3588 && val == 3) 254741874944SGuochun Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 254841874944SGuochun Huang EN_MASK, EDPI_TE_EN, 0, false); 254941874944SGuochun Huang else 255041874944SGuochun Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 255141874944SGuochun Huang EN_MASK, EDPI_TE_EN, 1, false); 255241874944SGuochun Huang 255341874944SGuochun Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 255441874944SGuochun Huang EN_MASK, EDPI_WMS_HOLD_EN, 1, false); 255541874944SGuochun Huang } 2556ecc31b6eSAndy Yan } 2557ecc31b6eSAndy Yan 2558ecc31b6eSAndy Yan if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 25593df6e59eSDamon Ding vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 25603df6e59eSDamon Ding MIPI_DUAL_EN_SHIFT, 1, false); 2561ecc31b6eSAndy Yan if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 2562ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2563ecc31b6eSAndy Yan EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1, 2564ecc31b6eSAndy Yan false); 25650a1fb152SZhang Yubing switch (conn_state->type) { 25660a1fb152SZhang Yubing case DRM_MODE_CONNECTOR_DisplayPort: 25670a1fb152SZhang Yubing vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 25680a1fb152SZhang Yubing RK3588_DP_DUAL_EN_SHIFT, 1, false); 25690a1fb152SZhang Yubing break; 25700a1fb152SZhang Yubing case DRM_MODE_CONNECTOR_eDP: 25710a1fb152SZhang Yubing vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 25720a1fb152SZhang Yubing RK3588_EDP_DUAL_EN_SHIFT, 1, false); 25730a1fb152SZhang Yubing break; 25740a1fb152SZhang Yubing case DRM_MODE_CONNECTOR_HDMIA: 25750a1fb152SZhang Yubing vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 25760a1fb152SZhang Yubing RK3588_HDMI_DUAL_EN_SHIFT, 1, false); 25770a1fb152SZhang Yubing break; 25780a1fb152SZhang Yubing case DRM_MODE_CONNECTOR_DSI: 25790a1fb152SZhang Yubing vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 25800a1fb152SZhang Yubing RK3568_MIPI_DUAL_EN_SHIFT, 1, false); 25810a1fb152SZhang Yubing break; 25820a1fb152SZhang Yubing default: 25830a1fb152SZhang Yubing break; 25840a1fb152SZhang Yubing } 2585ecc31b6eSAndy Yan } 2586ecc31b6eSAndy Yan 2587ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_eDP0) { 2588ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP0_EN_SHIFT, 2589ecc31b6eSAndy Yan 1, false); 2590ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT, 2591ecc31b6eSAndy Yan cstate->crtc_id, false); 2592ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT, 2593ecc31b6eSAndy Yan if_dclk_div, false); 2594ecc31b6eSAndy Yan 2595ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT, 2596ecc31b6eSAndy Yan if_pixclk_div, false); 2597ecc31b6eSAndy Yan 2598ecc31b6eSAndy Yan vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 2599ecc31b6eSAndy Yan RK3588_GRF_EDP0_ENABLE_SHIFT, 1); 2600ecc31b6eSAndy Yan } 2601ecc31b6eSAndy Yan 2602ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_eDP1) { 2603ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP1_EN_SHIFT, 2604ecc31b6eSAndy Yan 1, false); 2605ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT, 2606ecc31b6eSAndy Yan cstate->crtc_id, false); 2607ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT, 2608ecc31b6eSAndy Yan if_dclk_div, false); 2609ecc31b6eSAndy Yan 2610ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT, 2611ecc31b6eSAndy Yan if_pixclk_div, false); 26121848455fSDamon Ding 26131848455fSDamon Ding vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 26141848455fSDamon Ding RK3588_GRF_EDP1_ENABLE_SHIFT, 1); 2615ecc31b6eSAndy Yan } 2616ecc31b6eSAndy Yan 2617ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_HDMI0) { 2618ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI0_EN_SHIFT, 2619ecc31b6eSAndy Yan 1, false); 2620ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT, 2621ecc31b6eSAndy Yan cstate->crtc_id, false); 2622ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT, 2623ecc31b6eSAndy Yan if_dclk_div, false); 2624ecc31b6eSAndy Yan 2625ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT, 2626ecc31b6eSAndy Yan if_pixclk_div, false); 2627b890760eSAlgea Cao 2628b890760eSAlgea Cao vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 2629b890760eSAlgea Cao RK3588_GRF_HDMITX0_ENABLE_SHIFT, 1); 2630b890760eSAlgea Cao vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0, 2631b890760eSAlgea Cao HDMI_SYNC_POL_MASK, 2632b890760eSAlgea Cao HDMI0_SYNC_POL_SHIFT, val); 2633ecc31b6eSAndy Yan } 2634ecc31b6eSAndy Yan 2635ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_HDMI1) { 2636ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI1_EN_SHIFT, 2637ecc31b6eSAndy Yan 1, false); 2638ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT, 2639ecc31b6eSAndy Yan cstate->crtc_id, false); 2640ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT, 2641ecc31b6eSAndy Yan if_dclk_div, false); 2642ecc31b6eSAndy Yan 2643ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT, 2644ecc31b6eSAndy Yan if_pixclk_div, false); 2645b890760eSAlgea Cao 2646b890760eSAlgea Cao vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 2647b890760eSAlgea Cao RK3588_GRF_HDMITX1_ENABLE_SHIFT, 1); 2648b890760eSAlgea Cao vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0, 2649b890760eSAlgea Cao HDMI_SYNC_POL_MASK, 2650b890760eSAlgea Cao HDMI1_SYNC_POL_SHIFT, val); 2651ecc31b6eSAndy Yan } 2652ecc31b6eSAndy Yan 2653ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_DP0) { 2654ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP0_EN_SHIFT, 2655ecc31b6eSAndy Yan 1, false); 2656ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP0_MUX_SHIFT, 2657ecc31b6eSAndy Yan cstate->crtc_id, false); 2658ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK, 2659ecc31b6eSAndy Yan RK3588_DP0_PIN_POL_SHIFT, val, false); 2660ecc31b6eSAndy Yan } 2661ecc31b6eSAndy Yan 2662ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_DP1) { 2663108c5f8bSZhang Yubing vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP1_EN_SHIFT, 2664ecc31b6eSAndy Yan 1, false); 2665ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP1_MUX_SHIFT, 2666ecc31b6eSAndy Yan cstate->crtc_id, false); 2667ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK, 2668ecc31b6eSAndy Yan RK3588_DP1_PIN_POL_SHIFT, val, false); 2669ecc31b6eSAndy Yan } 2670ecc31b6eSAndy Yan 2671ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3, 2672b61227a3SDamon Ding DCLK_CORE_DIV_SHIFT, cstate->dclk_core_div, false); 2673ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3, 2674b61227a3SDamon Ding DCLK_OUT_DIV_SHIFT, cstate->dclk_out_div, false); 2675ecc31b6eSAndy Yan 2676ecc31b6eSAndy Yan return dclk_rate; 2677ecc31b6eSAndy Yan } 2678ecc31b6eSAndy Yan 2679ecc31b6eSAndy Yan static unsigned long rk3568_vop2_if_cfg(struct display_state *state) 2680ecc31b6eSAndy Yan { 2681ecc31b6eSAndy Yan struct crtc_state *cstate = &state->crtc_state; 2682ecc31b6eSAndy Yan struct connector_state *conn_state = &state->conn_state; 2683ecc31b6eSAndy Yan struct drm_display_mode *mode = &conn_state->mode; 2684ecc31b6eSAndy Yan struct vop2 *vop2 = cstate->private; 2685ecc31b6eSAndy Yan u32 vp_offset = (cstate->crtc_id * 0x100); 2686d0408543SAndy Yan bool dclk_inv; 2687ecc31b6eSAndy Yan u32 val; 26888895aec1SSandy Huang 2689d0408543SAndy Yan dclk_inv = (mode->flags & DRM_MODE_FLAG_PPIXDATA) ? 0 : 1; 269010ee9f5bSAlgea Cao val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 269110ee9f5bSAlgea Cao val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 2692d0408543SAndy Yan 2693d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_RGB) { 2694d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 2695d0408543SAndy Yan 1, false); 2696d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2697d0408543SAndy Yan RGB_MUX_SHIFT, cstate->crtc_id, false); 2698ecc31b6eSAndy Yan vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 2699c55d261eSSandy Huang GRF_RGB_DCLK_INV_SHIFT, dclk_inv); 2700d0408543SAndy Yan } 2701d0408543SAndy Yan 2702d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_BT1120) { 270352ee18acSSandy Huang vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 270452ee18acSSandy Huang 1, false); 2705d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, 2706d0408543SAndy Yan BT1120_EN_SHIFT, 1, false); 2707d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2708d0408543SAndy Yan RGB_MUX_SHIFT, cstate->crtc_id, false); 2709ecc31b6eSAndy Yan vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 271052ee18acSSandy Huang GRF_BT1120_CLK_INV_SHIFT, !dclk_inv); 2711d0408543SAndy Yan } 2712d0408543SAndy Yan 2713d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_BT656) { 2714d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT, 2715d0408543SAndy Yan 1, false); 2716d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2717d0408543SAndy Yan RGB_MUX_SHIFT, cstate->crtc_id, false); 2718ecc31b6eSAndy Yan vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 271952ee18acSSandy Huang GRF_BT656_CLK_INV_SHIFT, !dclk_inv); 2720d0408543SAndy Yan } 2721d0408543SAndy Yan 2722d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) { 2723d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT, 2724d0408543SAndy Yan 1, false); 2725d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2726d0408543SAndy Yan LVDS0_MUX_SHIFT, cstate->crtc_id, false); 272711f53190SSandy Huang vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 272811f53190SSandy Huang IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false); 2729d0408543SAndy Yan } 2730d0408543SAndy Yan 2731d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) { 2732d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS1_EN_SHIFT, 2733d0408543SAndy Yan 1, false); 2734d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2735d0408543SAndy Yan LVDS1_MUX_SHIFT, cstate->crtc_id, false); 273611f53190SSandy Huang vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 273711f53190SSandy Huang IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false); 2738d0408543SAndy Yan } 2739d0408543SAndy Yan 2740d0408543SAndy Yan if (conn_state->output_flags & 2741d0408543SAndy Yan (ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE | 2742d0408543SAndy Yan ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)) { 2743d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2744d0408543SAndy Yan LVDS_DUAL_EN_SHIFT, 1, false); 2745d0408543SAndy Yan if (conn_state->output_flags & 2746d0408543SAndy Yan ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 2747d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2748d0408543SAndy Yan LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 1, 2749d0408543SAndy Yan false); 2750d0408543SAndy Yan if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 2751d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2752d0408543SAndy Yan LVDS_DUAL_SWAP_EN_SHIFT, 1, false); 2753d0408543SAndy Yan } 2754d0408543SAndy Yan 2755d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) { 2756d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT, 2757d0408543SAndy Yan 1, false); 2758d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2759d0408543SAndy Yan MIPI0_MUX_SHIFT, cstate->crtc_id, false); 2760d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2761c55d261eSSandy Huang IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false); 2762d0408543SAndy Yan } 2763d0408543SAndy Yan 2764d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_MIPI1) { 2765d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI1_EN_SHIFT, 2766d0408543SAndy Yan 1, false); 2767d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2768d0408543SAndy Yan MIPI1_MUX_SHIFT, cstate->crtc_id, false); 2769d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2770c55d261eSSandy Huang IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false); 2771d0408543SAndy Yan } 2772d0408543SAndy Yan 2773d0408543SAndy Yan if (conn_state->output_flags & 2774d0408543SAndy Yan ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 2775d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 2776d0408543SAndy Yan MIPI_DUAL_EN_SHIFT, 1, false); 2777d0408543SAndy Yan if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 2778d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2779d0408543SAndy Yan EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1, 2780d0408543SAndy Yan false); 2781d0408543SAndy Yan } 2782d0408543SAndy Yan 2783d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_eDP0) { 2784d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, EDP0_EN_SHIFT, 2785d0408543SAndy Yan 1, false); 2786d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2787d0408543SAndy Yan EDP0_MUX_SHIFT, cstate->crtc_id, false); 2788c55d261eSSandy Huang vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2789c55d261eSSandy Huang IF_CRTL_EDP_DCLK_POL_SHIT, dclk_inv, false); 2790d0408543SAndy Yan } 2791d0408543SAndy Yan 2792d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) { 2793d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT, 2794d0408543SAndy Yan 1, false); 2795d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2796d0408543SAndy Yan HDMI0_MUX_SHIFT, cstate->crtc_id, false); 279710ee9f5bSAlgea Cao vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 279810ee9f5bSAlgea Cao IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false); 279910ee9f5bSAlgea Cao vop2_mask_write(vop2, RK3568_DSP_IF_POL, 280010ee9f5bSAlgea Cao IF_CRTL_HDMI_PIN_POL_MASK, 280110ee9f5bSAlgea Cao IF_CRTL_HDMI_PIN_POL_SHIT, val, false); 2802d0408543SAndy Yan } 280310ee9f5bSAlgea Cao 2804ecc31b6eSAndy Yan return mode->clock; 2805ecc31b6eSAndy Yan } 2806ecc31b6eSAndy Yan 28075fa6e665SDamon Ding static unsigned long rk3528_vop2_if_cfg(struct display_state *state) 28085fa6e665SDamon Ding { 28095fa6e665SDamon Ding struct crtc_state *cstate = &state->crtc_state; 28105fa6e665SDamon Ding struct connector_state *conn_state = &state->conn_state; 28115fa6e665SDamon Ding struct drm_display_mode *mode = &conn_state->mode; 28125fa6e665SDamon Ding struct vop2 *vop2 = cstate->private; 28135fa6e665SDamon Ding u32 val; 28145fa6e665SDamon Ding 28155fa6e665SDamon Ding val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 28165fa6e665SDamon Ding val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 28175fa6e665SDamon Ding 28185fa6e665SDamon Ding if (conn_state->output_if & VOP_OUTPUT_IF_BT656) { 28195fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT, 28205fa6e665SDamon Ding 1, false); 28215fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 28225fa6e665SDamon Ding RGB_MUX_SHIFT, cstate->crtc_id, false); 28235fa6e665SDamon Ding } 28245fa6e665SDamon Ding 28255fa6e665SDamon Ding if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) { 28265fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT, 28275fa6e665SDamon Ding 1, false); 28285fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 28295fa6e665SDamon Ding HDMI0_MUX_SHIFT, cstate->crtc_id, false); 28305fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 28315fa6e665SDamon Ding IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false); 28325fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, 28335fa6e665SDamon Ding IF_CRTL_HDMI_PIN_POL_MASK, 28345fa6e665SDamon Ding IF_CRTL_HDMI_PIN_POL_SHIT, val, false); 28355fa6e665SDamon Ding } 28365fa6e665SDamon Ding 28375fa6e665SDamon Ding return mode->crtc_clock; 28385fa6e665SDamon Ding } 28395fa6e665SDamon Ding 284065747de7SDamon Ding static void vop2_post_color_swap(struct display_state *state) 284165747de7SDamon Ding { 284265747de7SDamon Ding struct crtc_state *cstate = &state->crtc_state; 284365747de7SDamon Ding struct connector_state *conn_state = &state->conn_state; 284465747de7SDamon Ding struct vop2 *vop2 = cstate->private; 284565747de7SDamon Ding u32 vp_offset = (cstate->crtc_id * 0x100); 284665747de7SDamon Ding u32 output_type = conn_state->type; 284765747de7SDamon Ding u32 data_swap = 0; 284865747de7SDamon Ding 284965747de7SDamon Ding if (is_uv_swap(conn_state->bus_format, conn_state->output_mode)) 285065747de7SDamon Ding data_swap = DSP_RB_SWAP; 285165747de7SDamon Ding 285265747de7SDamon Ding if (vop2->version == VOP_VERSION_RK3588 && 285365747de7SDamon Ding (output_type == DRM_MODE_CONNECTOR_HDMIA || 285465747de7SDamon Ding output_type == DRM_MODE_CONNECTOR_eDP) && 285565747de7SDamon Ding (conn_state->bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 285665747de7SDamon Ding conn_state->bus_format == MEDIA_BUS_FMT_YUV10_1X30)) 285765747de7SDamon Ding data_swap |= DSP_RG_SWAP; 285865747de7SDamon Ding 285965747de7SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 286065747de7SDamon Ding DATA_SWAP_MASK, DATA_SWAP_SHIFT, data_swap, false); 286165747de7SDamon Ding } 286265747de7SDamon Ding 2863b890760eSAlgea Cao static void vop2_clk_set_parent(struct clk *clk, struct clk *parent) 2864b890760eSAlgea Cao { 2865b890760eSAlgea Cao int ret = 0; 2866b890760eSAlgea Cao 2867b890760eSAlgea Cao if (parent->dev) 2868b890760eSAlgea Cao ret = clk_set_parent(clk, parent); 2869b890760eSAlgea Cao if (ret < 0) 2870b890760eSAlgea Cao debug("failed to set %s as parent for %s\n", 2871b890760eSAlgea Cao parent->dev->name, clk->dev->name); 2872b890760eSAlgea Cao } 2873b890760eSAlgea Cao 2874b890760eSAlgea Cao static ulong vop2_clk_set_rate(struct clk *clk, ulong rate) 2875b890760eSAlgea Cao { 2876b890760eSAlgea Cao int ret = 0; 2877b890760eSAlgea Cao 2878b890760eSAlgea Cao if (clk->dev) 2879b890760eSAlgea Cao ret = clk_set_rate(clk, rate); 2880b890760eSAlgea Cao if (ret < 0) 2881b890760eSAlgea Cao debug("failed to set %s rate %lu \n", clk->dev->name, rate); 2882b890760eSAlgea Cao 2883b890760eSAlgea Cao return ret; 2884b890760eSAlgea Cao } 2885b890760eSAlgea Cao 288612ee5af0SDamon Ding static void vop2_calc_dsc_cru_cfg(struct display_state *state, 288712ee5af0SDamon Ding int *dsc_txp_clk_div, int *dsc_pxl_clk_div, 288812ee5af0SDamon Ding int *dsc_cds_clk_div, u64 dclk_rate) 288912ee5af0SDamon Ding { 289012ee5af0SDamon Ding struct crtc_state *cstate = &state->crtc_state; 289112ee5af0SDamon Ding 289212ee5af0SDamon Ding *dsc_txp_clk_div = dclk_rate / cstate->dsc_txp_clk_rate; 289312ee5af0SDamon Ding *dsc_pxl_clk_div = dclk_rate / cstate->dsc_pxl_clk_rate; 289412ee5af0SDamon Ding *dsc_cds_clk_div = dclk_rate / cstate->dsc_cds_clk_rate; 289512ee5af0SDamon Ding 289612ee5af0SDamon Ding *dsc_txp_clk_div = ilog2(*dsc_txp_clk_div); 289712ee5af0SDamon Ding *dsc_pxl_clk_div = ilog2(*dsc_pxl_clk_div); 289812ee5af0SDamon Ding *dsc_cds_clk_div = ilog2(*dsc_cds_clk_div); 289912ee5af0SDamon Ding } 290012ee5af0SDamon Ding 290112ee5af0SDamon Ding static void vop2_load_pps(struct display_state *state, struct vop2 *vop2, u8 dsc_id) 290212ee5af0SDamon Ding { 290312ee5af0SDamon Ding struct crtc_state *cstate = &state->crtc_state; 290412ee5af0SDamon Ding struct drm_dsc_picture_parameter_set *pps = &cstate->pps; 290512ee5af0SDamon Ding struct drm_dsc_picture_parameter_set config_pps; 290612ee5af0SDamon Ding const struct vop2_data *vop2_data = vop2->data; 290712ee5af0SDamon Ding const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id]; 290812ee5af0SDamon Ding u32 *pps_val = (u32 *)&config_pps; 290912ee5af0SDamon Ding u32 decoder_regs_offset = (dsc_id * 0x100); 291012ee5af0SDamon Ding int i = 0; 291112ee5af0SDamon Ding 291212ee5af0SDamon Ding memcpy(&config_pps, pps, sizeof(config_pps)); 291312ee5af0SDamon Ding 291412ee5af0SDamon Ding if ((config_pps.pps_3 & 0xf) > dsc_data->max_linebuf_depth) { 291512ee5af0SDamon Ding config_pps.pps_3 &= 0xf0; 291612ee5af0SDamon Ding config_pps.pps_3 |= dsc_data->max_linebuf_depth; 291712ee5af0SDamon Ding printf("DSC%d max_linebuf_depth is: %d, current set value is: %d\n", 291812ee5af0SDamon Ding dsc_id, dsc_data->max_linebuf_depth, config_pps.pps_3 & 0xf); 291912ee5af0SDamon Ding } 292012ee5af0SDamon Ding 292112ee5af0SDamon Ding for (i = 0; i < DSC_NUM_BUF_RANGES; i++) { 292212ee5af0SDamon Ding config_pps.rc_range_parameters[i] = 292312ee5af0SDamon Ding (pps->rc_range_parameters[i] >> 3 & 0x1f) | 292412ee5af0SDamon Ding ((pps->rc_range_parameters[i] >> 14 & 0x3) << 5) | 292512ee5af0SDamon Ding ((pps->rc_range_parameters[i] >> 0 & 0x7) << 7) | 292612ee5af0SDamon Ding ((pps->rc_range_parameters[i] >> 8 & 0x3f) << 10); 292712ee5af0SDamon Ding } 292812ee5af0SDamon Ding 292912ee5af0SDamon Ding for (i = 0; i < ROCKCHIP_DSC_PPS_SIZE_BYTE / 4; i++) 293012ee5af0SDamon Ding vop2_writel(vop2, RK3588_DSC_8K_PPS0_3 + decoder_regs_offset + i * 4, *pps_val++); 293112ee5af0SDamon Ding } 293212ee5af0SDamon Ding 293312ee5af0SDamon Ding static void vop2_dsc_enable(struct display_state *state, struct vop2 *vop2, u8 dsc_id, u64 dclk_rate) 293412ee5af0SDamon Ding { 293512ee5af0SDamon Ding struct connector_state *conn_state = &state->conn_state; 293612ee5af0SDamon Ding struct drm_display_mode *mode = &conn_state->mode; 293712ee5af0SDamon Ding struct crtc_state *cstate = &state->crtc_state; 293812ee5af0SDamon Ding struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap; 293912ee5af0SDamon Ding const struct vop2_data *vop2_data = vop2->data; 294012ee5af0SDamon Ding const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id]; 294112ee5af0SDamon Ding bool mipi_ds_mode = false; 294212ee5af0SDamon Ding u8 dsc_interface_mode = 0; 294312ee5af0SDamon Ding u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 294412ee5af0SDamon Ding u16 hdisplay = mode->crtc_hdisplay; 294512ee5af0SDamon Ding u16 htotal = mode->crtc_htotal; 294612ee5af0SDamon Ding u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 294712ee5af0SDamon Ding u16 vdisplay = mode->crtc_vdisplay; 294812ee5af0SDamon Ding u16 vtotal = mode->crtc_vtotal; 294912ee5af0SDamon Ding u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; 295012ee5af0SDamon Ding u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 295112ee5af0SDamon Ding u16 vact_end = vact_st + vdisplay; 295212ee5af0SDamon Ding u32 ctrl_regs_offset = (dsc_id * 0x30); 295312ee5af0SDamon Ding u32 decoder_regs_offset = (dsc_id * 0x100); 295412ee5af0SDamon Ding u32 backup_regs_offset = 0; 295512ee5af0SDamon Ding int dsc_txp_clk_div = 0; 295612ee5af0SDamon Ding int dsc_pxl_clk_div = 0; 295712ee5af0SDamon Ding int dsc_cds_clk_div = 0; 295812ee5af0SDamon Ding 295912ee5af0SDamon Ding if (!vop2->data->nr_dscs) { 296012ee5af0SDamon Ding printf("Unsupported DSC\n"); 296112ee5af0SDamon Ding return; 296212ee5af0SDamon Ding } 296312ee5af0SDamon Ding 296412ee5af0SDamon Ding if (cstate->dsc_slice_num > dsc_data->max_slice_num) 296512ee5af0SDamon Ding printf("DSC%d supported max slice is: %d, current is: %d\n", 296612ee5af0SDamon Ding dsc_data->id, dsc_data->max_slice_num, cstate->dsc_slice_num); 296712ee5af0SDamon Ding 296812ee5af0SDamon Ding if (dsc_data->pd_id) { 296912ee5af0SDamon Ding if (vop2_power_domain_on(vop2, dsc_data->pd_id)) 297012ee5af0SDamon Ding printf("open dsc%d pd fail\n", dsc_id); 297112ee5af0SDamon Ding } 297212ee5af0SDamon Ding 297312ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, EN_MASK, 297412ee5af0SDamon Ding SCAN_TIMING_PARA_IMD_EN_SHIFT, 1, false); 297512ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PORT_SEL_MASK, 297612ee5af0SDamon Ding DSC_PORT_SEL_SHIFT, cstate->crtc_id, false); 297712ee5af0SDamon Ding if (conn_state->output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) { 297812ee5af0SDamon Ding dsc_interface_mode = VOP_DSC_IF_HDMI; 297912ee5af0SDamon Ding } else { 298012ee5af0SDamon Ding mipi_ds_mode = !!(conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE); 298112ee5af0SDamon Ding if (mipi_ds_mode) 298212ee5af0SDamon Ding dsc_interface_mode = VOP_DSC_IF_MIPI_DS_MODE; 298312ee5af0SDamon Ding else 298412ee5af0SDamon Ding dsc_interface_mode = VOP_DSC_IF_MIPI_VIDEO_MODE; 298512ee5af0SDamon Ding } 298612ee5af0SDamon Ding 298712ee5af0SDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 298812ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK, 298912ee5af0SDamon Ding DSC_MAN_MODE_SHIFT, 0, false); 299012ee5af0SDamon Ding else 299112ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK, 299212ee5af0SDamon Ding DSC_MAN_MODE_SHIFT, 1, false); 299312ee5af0SDamon Ding 299412ee5af0SDamon Ding vop2_calc_dsc_cru_cfg(state, &dsc_txp_clk_div, &dsc_pxl_clk_div, &dsc_cds_clk_div, dclk_rate); 299512ee5af0SDamon Ding 299612ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_INTERFACE_MODE_MASK, 299712ee5af0SDamon Ding DSC_INTERFACE_MODE_SHIFT, dsc_interface_mode, false); 299812ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PIXEL_NUM_MASK, 299912ee5af0SDamon Ding DSC_PIXEL_NUM_SHIFT, cstate->dsc_pixel_num >> 1, false); 300012ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_TXP_CLK_DIV_MASK, 300112ee5af0SDamon Ding DSC_TXP_CLK_DIV_SHIFT, dsc_txp_clk_div, false); 300212ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PXL_CLK_DIV_MASK, 300312ee5af0SDamon Ding DSC_PXL_CLK_DIV_SHIFT, dsc_pxl_clk_div, false); 300412ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK, 300512ee5af0SDamon Ding DSC_CDS_CLK_DIV_SHIFT, dsc_cds_clk_div, false); 300612ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, EN_MASK, 300712ee5af0SDamon Ding DSC_SCAN_EN_SHIFT, !mipi_ds_mode, false); 300812ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK, 300912ee5af0SDamon Ding DSC_HALT_EN_SHIFT, mipi_ds_mode, false); 301012ee5af0SDamon Ding 301112ee5af0SDamon Ding if (!mipi_ds_mode) { 301212ee5af0SDamon Ding u16 dsc_hsync, dsc_htotal, dsc_hact_st, dsc_hact_end; 301312ee5af0SDamon Ding u32 target_bpp = dsc_sink_cap->target_bits_per_pixel_x16; 301412ee5af0SDamon Ding u64 dsc_cds_rate = cstate->dsc_cds_clk_rate; 301512ee5af0SDamon Ding u32 v_pixclk_mhz = mode->crtc_clock / 1000; /* video timing pixclk */ 301612ee5af0SDamon Ding u32 dly_num, dsc_cds_rate_mhz, val = 0; 3017b61227a3SDamon Ding int k = 1; 3018b61227a3SDamon Ding 3019b61227a3SDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 3020b61227a3SDamon Ding k = 2; 302112ee5af0SDamon Ding 302212ee5af0SDamon Ding if (target_bpp >> 4 < dsc_data->min_bits_per_pixel) 302312ee5af0SDamon Ding printf("Unsupported bpp less than: %d\n", dsc_data->min_bits_per_pixel); 302412ee5af0SDamon Ding 302512ee5af0SDamon Ding /* 302612ee5af0SDamon Ding * dly_num = delay_line_num * T(one-line) / T (dsc_cds) 302712ee5af0SDamon Ding * T (one-line) = 1/v_pixclk_mhz * htotal = htotal/v_pixclk_mhz 302812ee5af0SDamon Ding * T (dsc_cds) = 1 / dsc_cds_rate_mhz 302912ee5af0SDamon Ding * delay_line_num: according the pps initial_xmit_delay to adjust vop dsc delay 303012ee5af0SDamon Ding * delay_line_num = 4 - BPP / 8 303112ee5af0SDamon Ding * = (64 - target_bpp / 8) / 16 303212ee5af0SDamon Ding * 303312ee5af0SDamon Ding * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16; 303412ee5af0SDamon Ding */ 303512ee5af0SDamon Ding do_div(dsc_cds_rate, 1000000); /* hz to Mhz */ 303612ee5af0SDamon Ding dsc_cds_rate_mhz = dsc_cds_rate; 303712ee5af0SDamon Ding dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16; 303812ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_MODE_MASK, 303912ee5af0SDamon Ding DSC_INIT_DLY_MODE_SHIFT, 0, false); 304012ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_NUM_MASK, 304112ee5af0SDamon Ding DSC_INIT_DLY_NUM_SHIFT, dly_num, false); 304212ee5af0SDamon Ding 304312ee5af0SDamon Ding dsc_hsync = hsync_len / 2; 3044b61227a3SDamon Ding /* 3045b61227a3SDamon Ding * htotal / dclk_core = dsc_htotal /cds_clk 3046b61227a3SDamon Ding * 3047b61227a3SDamon Ding * dclk_core = DCLK / (1 << dclk_core->div_val) 3048b61227a3SDamon Ding * cds_clk = txp_clk / (1 << dsc_cds_clk->div_val) 3049b61227a3SDamon Ding * txp_clk = DCLK / (1 << dsc_txp_clk->div_val) 3050b61227a3SDamon Ding * 3051b61227a3SDamon Ding * dsc_htotal = htotal * (1 << dclk_core->div_val) / 3052b61227a3SDamon Ding * ((1 << dsc_txp_clk->div_val) * (1 << dsc_cds_clk->div_val)) 3053b61227a3SDamon Ding */ 3054b61227a3SDamon Ding dsc_htotal = htotal * (1 << cstate->dclk_core_div) / 3055b61227a3SDamon Ding ((1 << dsc_txp_clk_div) * (1 << dsc_cds_clk_div)); 305612ee5af0SDamon Ding val = dsc_htotal << 16 | dsc_hsync; 305712ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_HTOTAL_HS_END + ctrl_regs_offset, DSC_HTOTAL_PW_MASK, 305812ee5af0SDamon Ding DSC_HTOTAL_PW_SHIFT, val, false); 305912ee5af0SDamon Ding 306012ee5af0SDamon Ding dsc_hact_st = hact_st / 2; 3061b61227a3SDamon Ding dsc_hact_end = (hdisplay / k * target_bpp >> 4) / 24 + dsc_hact_st; 306212ee5af0SDamon Ding val = dsc_hact_end << 16 | dsc_hact_st; 306312ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_HACT_ST_END + ctrl_regs_offset, DSC_HACT_ST_END_MASK, 306412ee5af0SDamon Ding DSC_HACT_ST_END_SHIFT, val, false); 306512ee5af0SDamon Ding 306612ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_VTOTAL_VS_END + ctrl_regs_offset, DSC_VTOTAL_PW_MASK, 306712ee5af0SDamon Ding DSC_VTOTAL_PW_SHIFT, vtotal << 16 | vsync_len, false); 306812ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_VACT_ST_END + ctrl_regs_offset, DSC_VACT_ST_END_MASK, 306912ee5af0SDamon Ding DSC_VACT_ST_END_SHIFT, vact_end << 16 | vact_st, false); 307012ee5af0SDamon Ding } 307112ee5af0SDamon Ding 307212ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_RST + ctrl_regs_offset, RST_DEASSERT_MASK, 307312ee5af0SDamon Ding RST_DEASSERT_SHIFT, 1, false); 307412ee5af0SDamon Ding udelay(10); 307512ee5af0SDamon Ding /* read current dsc core register and backup to regsbak */ 307612ee5af0SDamon Ding backup_regs_offset = RK3588_DSC_8K_CTRL0; 307712ee5af0SDamon Ding vop2->regsbak[backup_regs_offset >> 2] = vop2_readl(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset); 307812ee5af0SDamon Ding 307912ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 308012ee5af0SDamon Ding DSC_EN_SHIFT, 1, false); 308112ee5af0SDamon Ding vop2_load_pps(state, vop2, dsc_id); 308212ee5af0SDamon Ding 308312ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 308412ee5af0SDamon Ding DSC_RBIT_SHIFT, 1, false); 308512ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 308612ee5af0SDamon Ding DSC_RBYT_SHIFT, 0, false); 308712ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 308812ee5af0SDamon Ding DSC_FLAL_SHIFT, 1, false); 308912ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 309012ee5af0SDamon Ding DSC_MER_SHIFT, 1, false); 309112ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 309212ee5af0SDamon Ding DSC_EPB_SHIFT, 0, false); 309312ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 309412ee5af0SDamon Ding DSC_EPL_SHIFT, 1, false); 309512ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 309612ee5af0SDamon Ding DSC_NSLC_SHIFT, ilog2(cstate->dsc_slice_num), false); 309712ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 309812ee5af0SDamon Ding DSC_SBO_SHIFT, 1, false); 309912ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 310012ee5af0SDamon Ding DSC_IFEP_SHIFT, dsc_sink_cap->version_minor == 2 ? 1 : 0, false); 310112ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 310212ee5af0SDamon Ding DSC_PPS_UPD_SHIFT, 1, false); 310312ee5af0SDamon Ding 310412ee5af0SDamon Ding printf("DSC%d: txp:%lld div:%d, pxl:%lld div:%d, dsc:%lld div:%d\n", 310512ee5af0SDamon Ding dsc_id, 310612ee5af0SDamon Ding cstate->dsc_txp_clk_rate, dsc_txp_clk_div, 310712ee5af0SDamon Ding cstate->dsc_pxl_clk_rate, dsc_pxl_clk_div, 310812ee5af0SDamon Ding cstate->dsc_cds_clk_rate, dsc_cds_clk_div); 310912ee5af0SDamon Ding } 311012ee5af0SDamon Ding 31115f1357a2SZhang Yubing static bool is_extend_pll(struct display_state *state, struct udevice **clk_dev) 31125f1357a2SZhang Yubing { 31135f1357a2SZhang Yubing struct crtc_state *cstate = &state->crtc_state; 31145f1357a2SZhang Yubing struct vop2 *vop2 = cstate->private; 31155f1357a2SZhang Yubing struct udevice *vp_dev, *dev; 31165f1357a2SZhang Yubing struct ofnode_phandle_args args; 31175f1357a2SZhang Yubing char vp_name[10]; 31185f1357a2SZhang Yubing int ret; 31195f1357a2SZhang Yubing 31205f1357a2SZhang Yubing if (vop2->version != VOP_VERSION_RK3588) 31215f1357a2SZhang Yubing return false; 31225f1357a2SZhang Yubing 31235f1357a2SZhang Yubing sprintf(vp_name, "port@%d", cstate->crtc_id); 31245f1357a2SZhang Yubing if (uclass_find_device_by_name(UCLASS_VIDEO_CRTC, vp_name, &vp_dev)) { 31255e85f4a7SZhang Yubing debug("warn: can't get vp device\n"); 31265f1357a2SZhang Yubing return false; 31275f1357a2SZhang Yubing } 31285f1357a2SZhang Yubing 31295f1357a2SZhang Yubing ret = dev_read_phandle_with_args(vp_dev, "assigned-clock-parents", "#clock-cells", 0, 31305f1357a2SZhang Yubing 0, &args); 31315f1357a2SZhang Yubing if (ret) { 31325e85f4a7SZhang Yubing debug("assigned-clock-parents's node not define\n"); 31335f1357a2SZhang Yubing return false; 31345f1357a2SZhang Yubing } 31355f1357a2SZhang Yubing 31365f1357a2SZhang Yubing if (uclass_find_device_by_ofnode(UCLASS_CLK, args.node, &dev)) { 31375e85f4a7SZhang Yubing debug("warn: can't get clk device\n"); 31385f1357a2SZhang Yubing return false; 31395f1357a2SZhang Yubing } 31405f1357a2SZhang Yubing 31415f1357a2SZhang Yubing if (!strcmp(dev->name, "hdmiphypll_clk0") || !strcmp(dev->name, "hdmiphypll_clk1")) { 31425f1357a2SZhang Yubing printf("%s: clk dev :%s: vp port:%s\n", __func__, dev->name, vp_dev->name); 31435f1357a2SZhang Yubing if (clk_dev) 31445f1357a2SZhang Yubing *clk_dev = dev; 31455f1357a2SZhang Yubing return true; 31465f1357a2SZhang Yubing } 31475f1357a2SZhang Yubing 31485f1357a2SZhang Yubing return false; 31495f1357a2SZhang Yubing } 31505f1357a2SZhang Yubing 3151ecc31b6eSAndy Yan static int rockchip_vop2_init(struct display_state *state) 3152ecc31b6eSAndy Yan { 3153ecc31b6eSAndy Yan struct crtc_state *cstate = &state->crtc_state; 3154c2b1fe35SDamon Ding struct rockchip_vp *vp = &cstate->crtc->vps[cstate->crtc_id]; 3155ecc31b6eSAndy Yan struct connector_state *conn_state = &state->conn_state; 3156ecc31b6eSAndy Yan struct drm_display_mode *mode = &conn_state->mode; 3157ecc31b6eSAndy Yan struct vop2 *vop2 = cstate->private; 3158ecc31b6eSAndy Yan u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 3159ecc31b6eSAndy Yan u16 hdisplay = mode->crtc_hdisplay; 3160ecc31b6eSAndy Yan u16 htotal = mode->crtc_htotal; 3161ecc31b6eSAndy Yan u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 3162ecc31b6eSAndy Yan u16 hact_end = hact_st + hdisplay; 3163ecc31b6eSAndy Yan u16 vdisplay = mode->crtc_vdisplay; 3164ecc31b6eSAndy Yan u16 vtotal = mode->crtc_vtotal; 3165ecc31b6eSAndy Yan u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; 3166ecc31b6eSAndy Yan u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 3167ecc31b6eSAndy Yan u16 vact_end = vact_st + vdisplay; 3168ecc31b6eSAndy Yan bool yuv_overlay = false; 3169ecc31b6eSAndy Yan u32 vp_offset = (cstate->crtc_id * 0x100); 317066724b9cSDamon Ding u32 line_flag_offset = (cstate->crtc_id * 4); 317166724b9cSDamon Ding u32 val, act_end; 3172ecc31b6eSAndy Yan u8 dither_down_en = 0; 3173ecc31b6eSAndy Yan u8 pre_dither_down_en = 0; 3174edfef528SDamon Ding u8 dclk_div_factor = 0; 3175ecc31b6eSAndy Yan char output_type_name[30] = {0}; 3176ecc31b6eSAndy Yan char dclk_name[9]; 3177ecc31b6eSAndy Yan struct clk dclk; 3178b890760eSAlgea Cao struct clk hdmi0_phy_pll; 3179b890760eSAlgea Cao struct clk hdmi1_phy_pll; 31805f1357a2SZhang Yubing struct clk hdmi_phy_pll; 31813e05a7b8SZhang Yubing struct udevice *disp_dev; 31825fa6e665SDamon Ding unsigned long dclk_rate = 0; 3183ecc31b6eSAndy Yan int ret; 3184ecc31b6eSAndy Yan 3185ecc31b6eSAndy Yan printf("VOP update mode to: %dx%d%s%d, type:%s for VP%d\n", 318671ac76f7SDamon Ding mode->crtc_hdisplay, mode->vdisplay, 3187ecc31b6eSAndy Yan mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p", 31885e85f4a7SZhang Yubing mode->vrefresh, 3189ecc31b6eSAndy Yan get_output_if_name(conn_state->output_if, output_type_name), 3190ecc31b6eSAndy Yan cstate->crtc_id); 3191ecc31b6eSAndy Yan 3192ee01dbb2SDamon Ding if (mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) { 3193ee01dbb2SDamon Ding cstate->splice_mode = true; 3194ee01dbb2SDamon Ding cstate->splice_crtc_id = vop2->data->vp_data[cstate->crtc_id].splice_vp_id; 3195ee01dbb2SDamon Ding if (!cstate->splice_crtc_id) { 3196ee01dbb2SDamon Ding printf("%s: Splice mode is unsupported by vp%d\n", 3197ee01dbb2SDamon Ding __func__, cstate->crtc_id); 3198ee01dbb2SDamon Ding return -EINVAL; 3199ee01dbb2SDamon Ding } 3200b70b2d79SDamon Ding 3201b70b2d79SDamon Ding vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, EN_MASK, 3202b70b2d79SDamon Ding PORT_MERGE_EN_SHIFT, 1, false); 3203ee01dbb2SDamon Ding } 3204ee01dbb2SDamon Ding 3205ecc31b6eSAndy Yan vop2_initial(vop2, state); 3206ecc31b6eSAndy Yan if (vop2->version == VOP_VERSION_RK3588) 3207ecc31b6eSAndy Yan dclk_rate = rk3588_vop2_if_cfg(state); 32085fa6e665SDamon Ding else if (vop2->version == VOP_VERSION_RK3568) 3209ecc31b6eSAndy Yan dclk_rate = rk3568_vop2_if_cfg(state); 32105fa6e665SDamon Ding else if (vop2->version == VOP_VERSION_RK3528) 32115fa6e665SDamon Ding dclk_rate = rk3528_vop2_if_cfg(state); 3212ecc31b6eSAndy Yan 321363cb669fSSandy Huang if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA && 321463cb669fSSandy Huang !(cstate->feature & VOP_FEATURE_OUTPUT_10BIT)) 32157bdd0eb6SSandy Huang conn_state->output_mode = ROCKCHIP_OUT_MODE_P888; 32167bdd0eb6SSandy Huang 321765747de7SDamon Ding vop2_post_color_swap(state); 321810ee9f5bSAlgea Cao 3219d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, OUT_MODE_MASK, 3220d0408543SAndy Yan OUT_MODE_SHIFT, conn_state->output_mode, false); 3221d0408543SAndy Yan 3222d0408543SAndy Yan switch (conn_state->bus_format) { 3223d0408543SAndy Yan case MEDIA_BUS_FMT_RGB565_1X16: 3224d0408543SAndy Yan dither_down_en = 1; 3225d0408543SAndy Yan break; 3226d0408543SAndy Yan case MEDIA_BUS_FMT_RGB666_1X18: 3227d0408543SAndy Yan case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: 3228d0408543SAndy Yan case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 3229d0408543SAndy Yan case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA: 3230d0408543SAndy Yan dither_down_en = 1; 3231d0408543SAndy Yan break; 3232d0408543SAndy Yan case MEDIA_BUS_FMT_YUV8_1X24: 3233d0408543SAndy Yan case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 3234d0408543SAndy Yan dither_down_en = 0; 3235d0408543SAndy Yan pre_dither_down_en = 1; 3236d0408543SAndy Yan break; 3237d0408543SAndy Yan case MEDIA_BUS_FMT_YUV10_1X30: 3238d0408543SAndy Yan case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 3239d0408543SAndy Yan case MEDIA_BUS_FMT_RGB888_1X24: 3240d0408543SAndy Yan case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 3241d0408543SAndy Yan case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 3242d0408543SAndy Yan default: 3243d0408543SAndy Yan dither_down_en = 0; 3244d0408543SAndy Yan pre_dither_down_en = 0; 3245d0408543SAndy Yan break; 3246d0408543SAndy Yan } 3247d0408543SAndy Yan 3248d0408543SAndy Yan if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA) 3249d0408543SAndy Yan pre_dither_down_en = 0; 3250d0408543SAndy Yan else 3251d0408543SAndy Yan pre_dither_down_en = 1; 3252d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3253d0408543SAndy Yan DITHER_DOWN_EN_SHIFT, dither_down_en, false); 3254d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3255d0408543SAndy Yan PRE_DITHER_DOWN_EN_SHIFT, pre_dither_down_en, false); 3256d0408543SAndy Yan 3257d0408543SAndy Yan yuv_overlay = is_yuv_output(conn_state->bus_format) ? 1 : 0; 3258d0408543SAndy Yan vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, cstate->crtc_id, 3259d0408543SAndy Yan yuv_overlay, false); 3260d0408543SAndy Yan 3261d0408543SAndy Yan cstate->yuv_overlay = yuv_overlay; 3262d0408543SAndy Yan 3263d0408543SAndy Yan vop2_writel(vop2, RK3568_VP0_DSP_HTOTAL_HS_END + vp_offset, 3264d0408543SAndy Yan (htotal << 16) | hsync_len); 3265d0408543SAndy Yan val = hact_st << 16; 3266d0408543SAndy Yan val |= hact_end; 3267d0408543SAndy Yan vop2_writel(vop2, RK3568_VP0_DSP_HACT_ST_END + vp_offset, val); 3268d0408543SAndy Yan val = vact_st << 16; 3269d0408543SAndy Yan val |= vact_end; 3270d0408543SAndy Yan vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END + vp_offset, val); 3271d0408543SAndy Yan if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 3272d0408543SAndy Yan u16 vact_st_f1 = vtotal + vact_st + 1; 3273d0408543SAndy Yan u16 vact_end_f1 = vact_st_f1 + vdisplay; 3274d0408543SAndy Yan 3275d0408543SAndy Yan val = vact_st_f1 << 16 | vact_end_f1; 3276d0408543SAndy Yan vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END_F1 + vp_offset, 3277d0408543SAndy Yan val); 3278d0408543SAndy Yan 3279d0408543SAndy Yan val = vtotal << 16 | (vtotal + vsync_len); 3280d0408543SAndy Yan vop2_writel(vop2, RK3568_VP0_DSP_VS_ST_END_F1 + vp_offset, val); 3281d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3282d0408543SAndy Yan INTERLACE_EN_SHIFT, 1, false); 32835fa6e665SDamon Ding if (vop2->version == VOP_VERSION_RK3528) { 32845fa6e665SDamon Ding if (conn_state->output_if & VOP_OUTPUT_IF_BT656 && 32855fa6e665SDamon Ding mode->vdisplay == 480) 32865fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 32875fa6e665SDamon Ding DSP_FILED_POL, 0, false); 32885fa6e665SDamon Ding else 3289d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 32907a20be36SSandy Huang DSP_FILED_POL, 1, false); 32915fa6e665SDamon Ding } else { 32925fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 32935fa6e665SDamon Ding DSP_FILED_POL, 1, false); 32945fa6e665SDamon Ding } 32957a20be36SSandy Huang vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3296d0408543SAndy Yan P2I_EN_SHIFT, 1, false); 3297d0408543SAndy Yan vtotal += vtotal + 1; 329866724b9cSDamon Ding act_end = vact_end_f1; 3299d0408543SAndy Yan } else { 3300d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3301d0408543SAndy Yan INTERLACE_EN_SHIFT, 0, false); 3302d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3303d0408543SAndy Yan P2I_EN_SHIFT, 0, false); 330466724b9cSDamon Ding act_end = vact_end; 3305d0408543SAndy Yan } 3306d0408543SAndy Yan vop2_writel(vop2, RK3568_VP0_DSP_VTOTAL_VS_END + vp_offset, 3307d0408543SAndy Yan (vtotal << 16) | vsync_len); 330867be2ffcSDamon Ding 33095fa6e665SDamon Ding if (vop2->version == VOP_VERSION_RK3568 || vop2->version == VOP_VERSION_RK3528) { 331067be2ffcSDamon Ding if (mode->flags & DRM_MODE_FLAG_DBLCLK || 331167be2ffcSDamon Ding conn_state->output_if & VOP_OUTPUT_IF_BT656) 3312d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 331367be2ffcSDamon Ding CORE_DCLK_DIV_EN_SHIFT, 1, false); 331467be2ffcSDamon Ding else 331567be2ffcSDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 331667be2ffcSDamon Ding CORE_DCLK_DIV_EN_SHIFT, 0, false); 331767be2ffcSDamon Ding } 331810ee9f5bSAlgea Cao 331910ee9f5bSAlgea Cao if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420) 332063cb669fSSandy Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 332163cb669fSSandy Huang DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0x3, false); 332210ee9f5bSAlgea Cao else 332363cb669fSSandy Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 332463cb669fSSandy Huang DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0, false); 332510ee9f5bSAlgea Cao 3326ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK, 3327ee01dbb2SDamon Ding OVL_MODE_SEL_SHIFT + cstate->crtc_id, yuv_overlay, false); 3328ee01dbb2SDamon Ding 332910ee9f5bSAlgea Cao if (yuv_overlay) 333010ee9f5bSAlgea Cao val = 0x20010200; 333110ee9f5bSAlgea Cao else 333210ee9f5bSAlgea Cao val = 0; 333310ee9f5bSAlgea Cao vop2_writel(vop2, RK3568_VP0_DSP_BG + vp_offset, val); 3334b70b2d79SDamon Ding if (cstate->splice_mode) { 3335ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK, 3336ee01dbb2SDamon Ding OVL_MODE_SEL_SHIFT + cstate->splice_crtc_id, 3337ee01dbb2SDamon Ding yuv_overlay, false); 3338ee01dbb2SDamon Ding vop2_writel(vop2, RK3568_VP0_DSP_BG + (cstate->splice_crtc_id * 0x100), val); 3339ee01dbb2SDamon Ding } 334010ee9f5bSAlgea Cao 334110ee9f5bSAlgea Cao vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 334210ee9f5bSAlgea Cao POST_DSP_OUT_R2Y_SHIFT, yuv_overlay, false); 3343d0408543SAndy Yan 3344c2b1fe35SDamon Ding if (vp->xmirror_en) 3345c2b1fe35SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3346c2b1fe35SDamon Ding DSP_X_MIR_EN_SHIFT, 1, false); 3347c2b1fe35SDamon Ding 3348ac500a1fSSandy Huang vop2_tv_config_update(state, vop2); 3349d0408543SAndy Yan vop2_post_config(state, vop2); 3350d0408543SAndy Yan 335112ee5af0SDamon Ding if (cstate->dsc_enable) { 335212ee5af0SDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 335312ee5af0SDamon Ding vop2_dsc_enable(state, vop2, 0, dclk_rate); 335412ee5af0SDamon Ding vop2_dsc_enable(state, vop2, 1, dclk_rate); 335512ee5af0SDamon Ding } else { 335612ee5af0SDamon Ding vop2_dsc_enable(state, vop2, cstate->dsc_id, dclk_rate); 335712ee5af0SDamon Ding } 335812ee5af0SDamon Ding } 335912ee5af0SDamon Ding 3360ecc31b6eSAndy Yan snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id); 3361ecc31b6eSAndy Yan ret = clk_get_by_name(cstate->dev, dclk_name, &dclk); 3362b890760eSAlgea Cao if (ret) { 3363b890760eSAlgea Cao printf("%s: Failed to get dclk ret=%d\n", __func__, ret); 3364b890760eSAlgea Cao return ret; 3365b890760eSAlgea Cao } 3366b890760eSAlgea Cao 33673e05a7b8SZhang Yubing ret = uclass_get_device_by_name(UCLASS_VIDEO, "display-subsystem", &disp_dev); 33683e05a7b8SZhang Yubing if (!ret) { 33693e05a7b8SZhang Yubing ret = clk_get_by_name(disp_dev, "hdmi0_phy_pll", &hdmi0_phy_pll); 33703e05a7b8SZhang Yubing if (ret) 33715e85f4a7SZhang Yubing debug("%s: hdmi0_phy_pll may not define\n", __func__); 33723e05a7b8SZhang Yubing ret = clk_get_by_name(disp_dev, "hdmi1_phy_pll", &hdmi1_phy_pll); 33733e05a7b8SZhang Yubing if (ret) 33745e85f4a7SZhang Yubing debug("%s: hdmi1_phy_pll may not define\n", __func__); 33753e05a7b8SZhang Yubing } else { 3376b890760eSAlgea Cao hdmi0_phy_pll.dev = NULL; 3377545a0218SAlgea Cao hdmi1_phy_pll.dev = NULL; 33785e85f4a7SZhang Yubing debug("%s: Faile to find display-subsystem node\n", __func__); 3379b890760eSAlgea Cao } 3380b890760eSAlgea Cao 33810a1fb152SZhang Yubing if (mode->crtc_clock < VOP2_MAX_DCLK_RATE) { 3382b890760eSAlgea Cao if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) 3383b890760eSAlgea Cao vop2_clk_set_parent(&dclk, &hdmi0_phy_pll); 3384b890760eSAlgea Cao else if (conn_state->output_if & VOP_OUTPUT_IF_HDMI1) 3385b890760eSAlgea Cao vop2_clk_set_parent(&dclk, &hdmi1_phy_pll); 3386b890760eSAlgea Cao 3387b890760eSAlgea Cao /* 3388b890760eSAlgea Cao * uboot clk driver won't set dclk parent's rate when use 3389b890760eSAlgea Cao * hdmi phypll as dclk source. 3390b890760eSAlgea Cao * So set dclk rate is meaningless. Set hdmi phypll rate 3391b890760eSAlgea Cao * directly. 3392b890760eSAlgea Cao */ 33935f1357a2SZhang Yubing if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI0) && hdmi0_phy_pll.dev) { 3394b890760eSAlgea Cao ret = vop2_clk_set_rate(&hdmi0_phy_pll, dclk_rate * 1000); 33955f1357a2SZhang Yubing } else if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI1) && hdmi1_phy_pll.dev) { 3396b890760eSAlgea Cao ret = vop2_clk_set_rate(&hdmi1_phy_pll, dclk_rate * 1000); 33975f1357a2SZhang Yubing } else { 3398*7efea85dSDamon Ding if (is_extend_pll(state, &hdmi_phy_pll.dev)) { 33995f1357a2SZhang Yubing ret = vop2_clk_set_rate(&hdmi_phy_pll, dclk_rate * 1000); 3400*7efea85dSDamon Ding } else { 3401*7efea85dSDamon Ding /* 3402*7efea85dSDamon Ding * For RK3528, the path of CVBS output is like: 3403*7efea85dSDamon Ding * VOP BT656 ENCODER -> CVBS BT656 DECODER -> CVBS ENCODER -> CVBS VDAC 3404*7efea85dSDamon Ding * The vop2 dclk should be four times crtc_clock for CVBS sampling 3405*7efea85dSDamon Ding * clock needs. 3406*7efea85dSDamon Ding */ 3407*7efea85dSDamon Ding if (vop2->version == VOP_VERSION_RK3528 && 3408*7efea85dSDamon Ding conn_state->output_if & VOP_OUTPUT_IF_BT656) 3409*7efea85dSDamon Ding ret = vop2_clk_set_rate(&dclk, 4 * dclk_rate * 1000); 3410b890760eSAlgea Cao else 3411b890760eSAlgea Cao ret = vop2_clk_set_rate(&dclk, dclk_rate * 1000); 34125f1357a2SZhang Yubing } 3413*7efea85dSDamon Ding } 3414631ee99aSZhang Yubing } else { 34155f1357a2SZhang Yubing if (is_extend_pll(state, &hdmi_phy_pll.dev)) 34165f1357a2SZhang Yubing ret = vop2_clk_set_rate(&hdmi_phy_pll, dclk_rate * 1000); 34175f1357a2SZhang Yubing else 3418631ee99aSZhang Yubing ret = vop2_clk_set_rate(&dclk, dclk_rate * 1000); 3419edfef528SDamon Ding } 342063638f32SDamon Ding 342163638f32SDamon Ding if (IS_ERR_VALUE(ret)) { 342263638f32SDamon Ding printf("%s: Failed to set vp%d dclk[%ld KHZ] ret=%d\n", 342363638f32SDamon Ding __func__, cstate->crtc_id, dclk_rate, ret); 342463638f32SDamon Ding return ret; 342563638f32SDamon Ding } else { 3426edfef528SDamon Ding dclk_div_factor = mode->clock / dclk_rate; 34275fa6e665SDamon Ding if (vop2->version == VOP_VERSION_RK3528 && 34285fa6e665SDamon Ding conn_state->output_if & VOP_OUTPUT_IF_BT656) 34295fa6e665SDamon Ding mode->crtc_clock = ret / 4 / 1000; 34305fa6e665SDamon Ding else 3431edfef528SDamon Ding mode->crtc_clock = ret * dclk_div_factor / 1000; 3432edfef528SDamon Ding printf("VP%d set crtc_clock to %dKHz\n", cstate->crtc_id, mode->crtc_clock); 3433631ee99aSZhang Yubing } 3434ecc31b6eSAndy Yan 343566724b9cSDamon Ding vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK, 3436e24e9033SSandy Huang RK3568_DSP_LINE_FLAG_NUM0_SHIFT, act_end, false); 343766724b9cSDamon Ding vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK, 3438e24e9033SSandy Huang RK3568_DSP_LINE_FLAG_NUM1_SHIFT, act_end, false); 343966724b9cSDamon Ding 3440d0408543SAndy Yan return 0; 3441d0408543SAndy Yan } 3442d0408543SAndy Yan 3443ecc31b6eSAndy Yan static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win_data *win, 34443e39a5a1SSandy Huang uint32_t src_w, uint32_t src_h, uint32_t dst_w, 34453e39a5a1SSandy Huang uint32_t dst_h) 34463e39a5a1SSandy Huang { 34473e39a5a1SSandy Huang uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode; 34483e39a5a1SSandy Huang uint16_t hscl_filter_mode, vscl_filter_mode; 34495fa6e665SDamon Ding uint8_t xgt2 = 0, xgt4 = 0; 34505fa6e665SDamon Ding uint8_t ygt2 = 0, ygt4 = 0; 34513e39a5a1SSandy Huang uint32_t xfac = 0, yfac = 0; 3452ecc31b6eSAndy Yan u32 win_offset = win->reg_offset; 34535fa6e665SDamon Ding bool xgt_en = false; 34545fa6e665SDamon Ding bool xavg_en = false; 34553e39a5a1SSandy Huang 34565fa6e665SDamon Ding if (is_vop3(vop2)) { 34575fa6e665SDamon Ding if (src_w >= (4 * dst_w)) { 34585fa6e665SDamon Ding xgt4 = 1; 34595fa6e665SDamon Ding src_w >>= 2; 34605fa6e665SDamon Ding } else if (src_w >= (2 * dst_w)) { 34615fa6e665SDamon Ding xgt2 = 1; 34625fa6e665SDamon Ding src_w >>= 1; 34635fa6e665SDamon Ding } 34645fa6e665SDamon Ding } 34653e39a5a1SSandy Huang 34665fa6e665SDamon Ding if (src_h >= (4 * dst_h)) { 34675fa6e665SDamon Ding ygt4 = 1; 34683e39a5a1SSandy Huang src_h >>= 2; 34695fa6e665SDamon Ding } else if (src_h >= (2 * dst_h)) { 34705fa6e665SDamon Ding ygt2 = 1; 34713e39a5a1SSandy Huang src_h >>= 1; 34725fa6e665SDamon Ding } 34733e39a5a1SSandy Huang 34743e39a5a1SSandy Huang yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w); 34753e39a5a1SSandy Huang yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h); 34763e39a5a1SSandy Huang 34773e39a5a1SSandy Huang if (yrgb_hor_scl_mode == SCALE_UP) 34785fa6e665SDamon Ding hscl_filter_mode = win->hsu_filter_mode; 34793e39a5a1SSandy Huang else 34805fa6e665SDamon Ding hscl_filter_mode = win->hsd_filter_mode; 34813e39a5a1SSandy Huang 34823e39a5a1SSandy Huang if (yrgb_ver_scl_mode == SCALE_UP) 34835fa6e665SDamon Ding vscl_filter_mode = win->vsu_filter_mode; 34843e39a5a1SSandy Huang else 34855fa6e665SDamon Ding vscl_filter_mode = win->vsd_filter_mode; 34863e39a5a1SSandy Huang 34873e39a5a1SSandy Huang /* 34883e39a5a1SSandy Huang * RK3568 VOP Esmart/Smart dsp_w should be even pixel 34893e39a5a1SSandy Huang * at scale down mode 34903e39a5a1SSandy Huang */ 34915fa6e665SDamon Ding if ((yrgb_hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1) && !is_vop3(vop2)) { 34923e39a5a1SSandy Huang printf("win dst_w[%d] should align as 2 pixel\n", dst_w); 34933e39a5a1SSandy Huang dst_w += 1; 34943e39a5a1SSandy Huang } 34953e39a5a1SSandy Huang 34965fa6e665SDamon Ding if (is_vop3(vop2)) { 34975fa6e665SDamon Ding xfac = vop3_scale_factor(yrgb_hor_scl_mode, src_w, dst_w, true); 34985fa6e665SDamon Ding yfac = vop3_scale_factor(yrgb_ver_scl_mode, src_h, dst_h, false); 34995fa6e665SDamon Ding 35005fa6e665SDamon Ding if (win->hsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_AVG) 35015fa6e665SDamon Ding xavg_en = xgt2 || xgt4; 35025fa6e665SDamon Ding else 35035fa6e665SDamon Ding xgt_en = xgt2 || xgt4; 35045fa6e665SDamon Ding } else { 35053e39a5a1SSandy Huang xfac = vop2_scale_factor(yrgb_hor_scl_mode, hscl_filter_mode, src_w, dst_w); 35063e39a5a1SSandy Huang yfac = vop2_scale_factor(yrgb_ver_scl_mode, vscl_filter_mode, src_h, dst_h); 35075fa6e665SDamon Ding } 3508ecc31b6eSAndy Yan 3509ecc31b6eSAndy Yan if (win->type == CLUSTER_LAYER) { 3510ecc31b6eSAndy Yan vop2_writel(vop2, RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB + win_offset, 3511ecc31b6eSAndy Yan yfac << 16 | xfac); 3512ecc31b6eSAndy Yan 35135fa6e665SDamon Ding if (is_vop3(vop2)) { 3514ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35155fa6e665SDamon Ding EN_MASK, CLUSTER_XGT_EN_SHIFT, xgt_en, false); 3516ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35175fa6e665SDamon Ding EN_MASK, CLUSTER_XAVG_EN_SHIFT, xavg_en, false); 35185fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35195fa6e665SDamon Ding XGT_MODE_MASK, CLUSTER_XGT_MODE_SHIFT, xgt2 ? 0 : 1, false); 3520ecc31b6eSAndy Yan 3521ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35225fa6e665SDamon Ding YRGB_XSCL_MODE_MASK, RK3528_CLUSTER_YRGB_XSCL_MODE_SHIFT, 35235fa6e665SDamon Ding yrgb_hor_scl_mode, false); 3524ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35255fa6e665SDamon Ding YRGB_YSCL_MODE_MASK, RK3528_CLUSTER_YRGB_YSCL_MODE_SHIFT, 35265fa6e665SDamon Ding yrgb_ver_scl_mode, false); 35275fa6e665SDamon Ding } else { 35285fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35295fa6e665SDamon Ding YRGB_XSCL_MODE_MASK, RK3568_CLUSTER_YRGB_XSCL_MODE_SHIFT, 35305fa6e665SDamon Ding yrgb_hor_scl_mode, false); 35315fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35325fa6e665SDamon Ding YRGB_YSCL_MODE_MASK, RK3568_CLUSTER_YRGB_YSCL_MODE_SHIFT, 35335fa6e665SDamon Ding yrgb_ver_scl_mode, false); 35345fa6e665SDamon Ding } 3535ecc31b6eSAndy Yan 35365fa6e665SDamon Ding if (!is_vop3(vop2) || win->vsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_GT) { 35375fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35385fa6e665SDamon Ding YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, ygt2, false); 35395fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35405fa6e665SDamon Ding YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, ygt4, false); 35415fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35425fa6e665SDamon Ding AVG2_MASK, CLUSTER_AVG2_SHIFT, 0, false); 35435fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35445fa6e665SDamon Ding AVG4_MASK, CLUSTER_AVG4_SHIFT, 0, false); 35455fa6e665SDamon Ding } else { 35465fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35475fa6e665SDamon Ding YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, 0, false); 35485fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35495fa6e665SDamon Ding YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, 0, false); 35505fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35515fa6e665SDamon Ding AVG2_MASK, CLUSTER_AVG2_SHIFT, ygt2, false); 35525fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 35535fa6e665SDamon Ding AVG4_MASK, CLUSTER_AVG4_SHIFT, ygt4, false); 35545fa6e665SDamon Ding } 3555ecc31b6eSAndy Yan } else { 35563e39a5a1SSandy Huang vop2_writel(vop2, RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB + win_offset, 35573e39a5a1SSandy Huang yfac << 16 | xfac); 35583e39a5a1SSandy Huang 35595fa6e665SDamon Ding if (is_vop3(vop2)) { 356034a72bf2SDing Ling Song vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 35615fa6e665SDamon Ding EN_MASK, ESMART_XGT_EN_SHIFT, xgt_en, false); 356234a72bf2SDing Ling Song vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 35635fa6e665SDamon Ding EN_MASK, ESMART_XAVG_EN_SHIFT, xavg_en, false); 35645fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 35655fa6e665SDamon Ding XGT_MODE_MASK, ESMART_XGT_MODE_SHIFT, xgt2 ? 0 : 1, false); 35665fa6e665SDamon Ding } 35675fa6e665SDamon Ding 35685fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 35695fa6e665SDamon Ding YRGB_GT2_MASK, YRGB_GT2_SHIFT, ygt2, false); 35705fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 35715fa6e665SDamon Ding YRGB_GT4_MASK, YRGB_GT4_SHIFT, ygt4, false); 35723e39a5a1SSandy Huang 35733e39a5a1SSandy Huang vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 35743e39a5a1SSandy Huang YRGB_XSCL_MODE_MASK, YRGB_XSCL_MODE_SHIFT, yrgb_hor_scl_mode, false); 35753e39a5a1SSandy Huang vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 35763e39a5a1SSandy Huang YRGB_YSCL_MODE_MASK, YRGB_YSCL_MODE_SHIFT, yrgb_ver_scl_mode, false); 35773e39a5a1SSandy Huang 35783e39a5a1SSandy Huang vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 35793e39a5a1SSandy Huang YRGB_XSCL_FILTER_MODE_MASK, YRGB_XSCL_FILTER_MODE_SHIFT, 35803e39a5a1SSandy Huang hscl_filter_mode, false); 35813e39a5a1SSandy Huang vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 35823e39a5a1SSandy Huang YRGB_YSCL_FILTER_MODE_MASK, YRGB_YSCL_FILTER_MODE_SHIFT, 35833e39a5a1SSandy Huang vscl_filter_mode, false); 35843e39a5a1SSandy Huang } 3585ecc31b6eSAndy Yan } 35863e39a5a1SSandy Huang 3587a33b790fSDamon Ding static void vop2_axi_config(struct vop2 *vop2, struct vop2_win_data *win) 3588a33b790fSDamon Ding { 3589a33b790fSDamon Ding u32 win_offset = win->reg_offset; 3590a33b790fSDamon Ding 3591a33b790fSDamon Ding if (win->type == CLUSTER_LAYER) { 3592a33b790fSDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, CLUSTER_AXI_ID_MASK, 3593a33b790fSDamon Ding CLUSTER_AXI_ID_SHIFT, win->axi_id, false); 3594a33b790fSDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_YRGB_ID_MASK, 3595a33b790fSDamon Ding CLUSTER_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false); 3596a33b790fSDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_UV_ID_MASK, 3597a33b790fSDamon Ding CLUSTER_AXI_UV_ID_SHIFT, win->axi_uv_id, false); 3598a33b790fSDamon Ding } else { 3599a33b790fSDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_AXI_CTRL + win_offset, ESMART_AXI_ID_MASK, 3600a33b790fSDamon Ding ESMART_AXI_ID_SHIFT, win->axi_id, false); 3601a33b790fSDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_YRGB_ID_MASK, 3602a33b790fSDamon Ding ESMART_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false); 3603a33b790fSDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_UV_ID_MASK, 3604a33b790fSDamon Ding ESMART_AXI_UV_ID_SHIFT, win->axi_uv_id, false); 3605a33b790fSDamon Ding } 3606a33b790fSDamon Ding } 3607a33b790fSDamon Ding 3608ecc31b6eSAndy Yan static void vop2_set_cluster_win(struct display_state *state, struct vop2_win_data *win) 3609d0408543SAndy Yan { 3610d0408543SAndy Yan struct crtc_state *cstate = &state->crtc_state; 3611d0408543SAndy Yan struct connector_state *conn_state = &state->conn_state; 3612d0408543SAndy Yan struct drm_display_mode *mode = &conn_state->mode; 3613d0408543SAndy Yan struct vop2 *vop2 = cstate->private; 3614ee01dbb2SDamon Ding int src_w = cstate->src_rect.w; 3615ee01dbb2SDamon Ding int src_h = cstate->src_rect.h; 3616ee01dbb2SDamon Ding int crtc_x = cstate->crtc_rect.x; 3617ee01dbb2SDamon Ding int crtc_y = cstate->crtc_rect.y; 3618ee01dbb2SDamon Ding int crtc_w = cstate->crtc_rect.w; 3619ee01dbb2SDamon Ding int crtc_h = cstate->crtc_rect.h; 3620d0408543SAndy Yan int xvir = cstate->xvir; 3621d0408543SAndy Yan int y_mirror = 0; 362210ee9f5bSAlgea Cao int csc_mode; 3623ecc31b6eSAndy Yan u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty; 3624ee01dbb2SDamon Ding /* offset of the right window in splice mode */ 3625ee01dbb2SDamon Ding u32 splice_pixel_offset = 0; 3626ee01dbb2SDamon Ding u32 splice_yrgb_offset = 0; 3627ecc31b6eSAndy Yan u32 win_offset = win->reg_offset; 3628ecc31b6eSAndy Yan u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 3629d0408543SAndy Yan 3630ee01dbb2SDamon Ding if (win->splice_mode_right) { 3631ee01dbb2SDamon Ding src_w = cstate->right_src_rect.w; 3632ee01dbb2SDamon Ding src_h = cstate->right_src_rect.h; 3633ee01dbb2SDamon Ding crtc_x = cstate->right_crtc_rect.x; 3634ee01dbb2SDamon Ding crtc_y = cstate->right_crtc_rect.y; 3635ee01dbb2SDamon Ding crtc_w = cstate->right_crtc_rect.w; 3636ee01dbb2SDamon Ding crtc_h = cstate->right_crtc_rect.h; 3637ee01dbb2SDamon Ding splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x; 3638ee01dbb2SDamon Ding splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3); 3639ee01dbb2SDamon Ding cfg_done = CFG_DONE_EN | BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 3640ee01dbb2SDamon Ding } 3641ee01dbb2SDamon Ding 3642ecc31b6eSAndy Yan act_info = (src_h - 1) << 16; 3643ecc31b6eSAndy Yan act_info |= (src_w - 1) & 0xffff; 3644ecc31b6eSAndy Yan 3645ecc31b6eSAndy Yan dsp_info = (crtc_h - 1) << 16; 3646ecc31b6eSAndy Yan dsp_info |= (crtc_w - 1) & 0xffff; 3647ecc31b6eSAndy Yan 3648ecc31b6eSAndy Yan dsp_stx = crtc_x; 3649ecc31b6eSAndy Yan dsp_sty = crtc_y; 3650ecc31b6eSAndy Yan dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); 3651ecc31b6eSAndy Yan 3652ecc31b6eSAndy Yan if (mode->flags & DRM_MODE_FLAG_YMIRROR) 3653ecc31b6eSAndy Yan y_mirror = 1; 3654ecc31b6eSAndy Yan else 3655ecc31b6eSAndy Yan y_mirror = 0; 3656ecc31b6eSAndy Yan 3657ecc31b6eSAndy Yan vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h); 3658ecc31b6eSAndy Yan 36595fa6e665SDamon Ding if (vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3528) 3660a33b790fSDamon Ding vop2_axi_config(vop2, win); 3661a33b790fSDamon Ding 3662ecc31b6eSAndy Yan if (y_mirror) 3663ecc31b6eSAndy Yan printf("WARN: y mirror is unsupported by cluster window\n"); 3664ecc31b6eSAndy Yan 3665ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, 3666ecc31b6eSAndy Yan WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format, 3667ecc31b6eSAndy Yan false); 3668ecc31b6eSAndy Yan vop2_writel(vop2, RK3568_CLUSTER0_WIN0_VIR + win_offset, xvir); 3669ee01dbb2SDamon Ding vop2_writel(vop2, RK3568_CLUSTER0_WIN0_YRGB_MST + win_offset, 3670ee01dbb2SDamon Ding cstate->dma_addr + splice_yrgb_offset); 3671ecc31b6eSAndy Yan 3672ecc31b6eSAndy Yan vop2_writel(vop2, RK3568_CLUSTER0_WIN0_ACT_INFO + win_offset, act_info); 3673ecc31b6eSAndy Yan vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_INFO + win_offset, dsp_info); 3674ecc31b6eSAndy Yan vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_ST + win_offset, dsp_st); 3675ecc31b6eSAndy Yan 3676ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, WIN_EN_SHIFT, 1, false); 3677ecc31b6eSAndy Yan 36785fa6e665SDamon Ding csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_10BIT_DEPTH); 3679ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, 3680ecc31b6eSAndy Yan CLUSTER_RGB2YUV_EN_SHIFT, 3681ecc31b6eSAndy Yan is_yuv_output(conn_state->bus_format), false); 3682ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, CSC_MODE_MASK, 3683ecc31b6eSAndy Yan CLUSTER_CSC_MODE_SHIFT, csc_mode, false); 3684ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, EN_MASK, CLUSTER_EN_SHIFT, 1, false); 3685ecc31b6eSAndy Yan 3686ecc31b6eSAndy Yan vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 3687d0408543SAndy Yan } 3688d0408543SAndy Yan 3689ecc31b6eSAndy Yan static void vop2_set_smart_win(struct display_state *state, struct vop2_win_data *win) 3690ecc31b6eSAndy Yan { 3691ecc31b6eSAndy Yan struct crtc_state *cstate = &state->crtc_state; 3692ecc31b6eSAndy Yan struct connector_state *conn_state = &state->conn_state; 3693ecc31b6eSAndy Yan struct drm_display_mode *mode = &conn_state->mode; 3694ecc31b6eSAndy Yan struct vop2 *vop2 = cstate->private; 3695ee01dbb2SDamon Ding int src_w = cstate->src_rect.w; 3696ee01dbb2SDamon Ding int src_h = cstate->src_rect.h; 3697ee01dbb2SDamon Ding int crtc_x = cstate->crtc_rect.x; 3698ee01dbb2SDamon Ding int crtc_y = cstate->crtc_rect.y; 3699ee01dbb2SDamon Ding int crtc_w = cstate->crtc_rect.w; 3700ee01dbb2SDamon Ding int crtc_h = cstate->crtc_rect.h; 3701ecc31b6eSAndy Yan int xvir = cstate->xvir; 3702ecc31b6eSAndy Yan int y_mirror = 0; 3703ecc31b6eSAndy Yan int csc_mode; 3704ecc31b6eSAndy Yan u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty; 3705ee01dbb2SDamon Ding /* offset of the right window in splice mode */ 3706ee01dbb2SDamon Ding u32 splice_pixel_offset = 0; 3707ee01dbb2SDamon Ding u32 splice_yrgb_offset = 0; 3708ecc31b6eSAndy Yan u32 win_offset = win->reg_offset; 3709ecc31b6eSAndy Yan u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 3710ecc31b6eSAndy Yan 3711ee01dbb2SDamon Ding if (win->splice_mode_right) { 3712ee01dbb2SDamon Ding src_w = cstate->right_src_rect.w; 3713ee01dbb2SDamon Ding src_h = cstate->right_src_rect.h; 3714ee01dbb2SDamon Ding crtc_x = cstate->right_crtc_rect.x; 3715ee01dbb2SDamon Ding crtc_y = cstate->right_crtc_rect.y; 3716ee01dbb2SDamon Ding crtc_w = cstate->right_crtc_rect.w; 3717ee01dbb2SDamon Ding crtc_h = cstate->right_crtc_rect.h; 3718ee01dbb2SDamon Ding splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x; 3719ee01dbb2SDamon Ding splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3); 3720ee01dbb2SDamon Ding cfg_done = CFG_DONE_EN | BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 3721ee01dbb2SDamon Ding } 3722ee01dbb2SDamon Ding 372374bd8269SSandy Huang /* 372474bd8269SSandy Huang * This is workaround solution for IC design: 372574bd8269SSandy Huang * esmart can't support scale down when actual_w % 16 == 1. 372674bd8269SSandy Huang */ 372774bd8269SSandy Huang if (src_w > crtc_w && (src_w & 0xf) == 1) { 372874bd8269SSandy Huang printf("WARN: vp%d unsupported act_w[%d] mode 16 = 1 when scale down\n", cstate->crtc_id, src_w); 372974bd8269SSandy Huang src_w -= 1; 373074bd8269SSandy Huang } 373174bd8269SSandy Huang 3732d0408543SAndy Yan act_info = (src_h - 1) << 16; 3733d0408543SAndy Yan act_info |= (src_w - 1) & 0xffff; 3734d0408543SAndy Yan 3735d0408543SAndy Yan dsp_info = (crtc_h - 1) << 16; 3736d0408543SAndy Yan dsp_info |= (crtc_w - 1) & 0xffff; 3737d0408543SAndy Yan 3738d0408543SAndy Yan dsp_stx = crtc_x; 3739d0408543SAndy Yan dsp_sty = crtc_y; 3740d0408543SAndy Yan dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); 3741d0408543SAndy Yan 3742d0408543SAndy Yan if (mode->flags & DRM_MODE_FLAG_YMIRROR) 3743d0408543SAndy Yan y_mirror = 1; 3744d0408543SAndy Yan else 3745d0408543SAndy Yan y_mirror = 0; 3746d0408543SAndy Yan 37475fa6e665SDamon Ding if (is_vop3(vop2)) 37485fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, ESMART_LB_SELECT_MASK, 37495fa6e665SDamon Ding ESMART_LB_SELECT_SHIFT, win->scale_engine_num, false); 37505fa6e665SDamon Ding 3751ecc31b6eSAndy Yan vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h); 37523e39a5a1SSandy Huang 37535fa6e665SDamon Ding if (vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3528) 3754a33b790fSDamon Ding vop2_axi_config(vop2, win); 3755a33b790fSDamon Ding 3756d0408543SAndy Yan if (y_mirror) 3757d0408543SAndy Yan cstate->dma_addr += (src_h - 1) * xvir * 4; 3758d0408543SAndy Yan vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, EN_MASK, 3759d0408543SAndy Yan YMIRROR_EN_SHIFT, y_mirror, false); 3760d0408543SAndy Yan 3761d0408543SAndy Yan vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 3762d0408543SAndy Yan WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format, 3763d0408543SAndy Yan false); 3764d0408543SAndy Yan vop2_writel(vop2, RK3568_ESMART0_REGION0_VIR + win_offset, xvir); 3765d0408543SAndy Yan vop2_writel(vop2, RK3568_ESMART0_REGION0_YRGB_MST + win_offset, 3766ee01dbb2SDamon Ding cstate->dma_addr + splice_yrgb_offset); 3767d0408543SAndy Yan 3768d0408543SAndy Yan vop2_writel(vop2, RK3568_ESMART0_REGION0_ACT_INFO + win_offset, 3769d0408543SAndy Yan act_info); 3770d0408543SAndy Yan vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_INFO + win_offset, 3771d0408543SAndy Yan dsp_info); 3772d0408543SAndy Yan vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_ST + win_offset, dsp_st); 3773d0408543SAndy Yan 3774d0408543SAndy Yan vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK, 3775d0408543SAndy Yan WIN_EN_SHIFT, 1, false); 3776d0408543SAndy Yan 37775fa6e665SDamon Ding csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_10BIT_DEPTH); 377810ee9f5bSAlgea Cao vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, EN_MASK, 377910ee9f5bSAlgea Cao RGB2YUV_EN_SHIFT, 378010ee9f5bSAlgea Cao is_yuv_output(conn_state->bus_format), false); 378110ee9f5bSAlgea Cao vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, CSC_MODE_MASK, 378210ee9f5bSAlgea Cao CSC_MODE_SHIFT, csc_mode, false); 378310ee9f5bSAlgea Cao 3784d0408543SAndy Yan vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 3785ecc31b6eSAndy Yan } 3786ecc31b6eSAndy Yan 3787ee01dbb2SDamon Ding static void vop2_calc_display_rect_for_splice(struct display_state *state) 3788ee01dbb2SDamon Ding { 3789ee01dbb2SDamon Ding struct crtc_state *cstate = &state->crtc_state; 3790ee01dbb2SDamon Ding struct connector_state *conn_state = &state->conn_state; 3791ee01dbb2SDamon Ding struct drm_display_mode *mode = &conn_state->mode; 3792ee01dbb2SDamon Ding struct display_rect *src_rect = &cstate->src_rect; 3793ee01dbb2SDamon Ding struct display_rect *dst_rect = &cstate->crtc_rect; 3794ee01dbb2SDamon Ding struct display_rect left_src, left_dst, right_src, right_dst; 3795ee01dbb2SDamon Ding u16 half_hdisplay = mode->crtc_hdisplay >> 1; 3796ee01dbb2SDamon Ding int left_src_w, left_dst_w, right_dst_w; 3797ee01dbb2SDamon Ding 3798ee01dbb2SDamon Ding left_dst_w = min_t(u16, half_hdisplay, dst_rect->x + dst_rect->w) - dst_rect->x; 3799ee01dbb2SDamon Ding if (left_dst_w < 0) 3800ee01dbb2SDamon Ding left_dst_w = 0; 3801ee01dbb2SDamon Ding right_dst_w = dst_rect->w - left_dst_w; 3802ee01dbb2SDamon Ding 3803ee01dbb2SDamon Ding if (!right_dst_w) 3804ee01dbb2SDamon Ding left_src_w = src_rect->w; 3805ee01dbb2SDamon Ding else 38060df0fd39SSandy Huang left_src_w = src_rect->x + src_rect->w - src_rect->w / 2; 3807ee01dbb2SDamon Ding 3808ee01dbb2SDamon Ding left_src.x = src_rect->x; 3809ee01dbb2SDamon Ding left_src.w = left_src_w; 3810ee01dbb2SDamon Ding left_dst.x = dst_rect->x; 3811ee01dbb2SDamon Ding left_dst.w = left_dst_w; 3812ee01dbb2SDamon Ding right_src.x = left_src.x + left_src.w; 3813ee01dbb2SDamon Ding right_src.w = src_rect->x + src_rect->w - left_src.x - left_src.w; 3814ee01dbb2SDamon Ding right_dst.x = dst_rect->x + left_dst_w - half_hdisplay; 3815ee01dbb2SDamon Ding right_dst.w = right_dst_w; 3816ee01dbb2SDamon Ding 3817ee01dbb2SDamon Ding left_src.y = src_rect->y; 3818ee01dbb2SDamon Ding left_src.h = src_rect->h; 3819ee01dbb2SDamon Ding left_dst.y = dst_rect->y; 3820ee01dbb2SDamon Ding left_dst.h = dst_rect->h; 3821ee01dbb2SDamon Ding right_src.y = src_rect->y; 3822ee01dbb2SDamon Ding right_src.h = src_rect->h; 3823ee01dbb2SDamon Ding right_dst.y = dst_rect->y; 3824ee01dbb2SDamon Ding right_dst.h = dst_rect->h; 3825ee01dbb2SDamon Ding 3826ee01dbb2SDamon Ding memcpy(&cstate->src_rect, &left_src, sizeof(struct display_rect)); 3827ee01dbb2SDamon Ding memcpy(&cstate->crtc_rect, &left_dst, sizeof(struct display_rect)); 3828ee01dbb2SDamon Ding memcpy(&cstate->right_src_rect, &right_src, sizeof(struct display_rect)); 3829ee01dbb2SDamon Ding memcpy(&cstate->right_crtc_rect, &right_dst, sizeof(struct display_rect)); 3830ee01dbb2SDamon Ding } 3831ee01dbb2SDamon Ding 3832ecc31b6eSAndy Yan static int rockchip_vop2_set_plane(struct display_state *state) 3833ecc31b6eSAndy Yan { 3834ecc31b6eSAndy Yan struct crtc_state *cstate = &state->crtc_state; 3835ecc31b6eSAndy Yan struct vop2 *vop2 = cstate->private; 3836ecc31b6eSAndy Yan struct vop2_win_data *win_data; 3837ee01dbb2SDamon Ding struct vop2_win_data *splice_win_data; 3838ecc31b6eSAndy Yan u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id; 3839ecc31b6eSAndy Yan char plane_name[10] = {0}; 3840ecc31b6eSAndy Yan 3841ee01dbb2SDamon Ding if (cstate->crtc_rect.w > cstate->max_output.width) { 3842ecc31b6eSAndy Yan printf("ERROR: output w[%d] exceeded max width[%d]\n", 3843ee01dbb2SDamon Ding cstate->crtc_rect.w, cstate->max_output.width); 3844ecc31b6eSAndy Yan return -EINVAL; 3845ecc31b6eSAndy Yan } 3846ecc31b6eSAndy Yan 3847ecc31b6eSAndy Yan win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id); 3848ecc31b6eSAndy Yan if (!win_data) { 3849ecc31b6eSAndy Yan printf("invalid win id %d\n", primary_plane_id); 3850ecc31b6eSAndy Yan return -ENODEV; 3851ecc31b6eSAndy Yan } 3852ecc31b6eSAndy Yan 38535fa6e665SDamon Ding /* ignore some plane register according vop3 esmart lb mode */ 38545fa6e665SDamon Ding if (vop3_ignore_plane(vop2, win_data)) 38555fa6e665SDamon Ding return -EACCES; 38565fa6e665SDamon Ding 3857b6ba80b4SDamon Ding if (vop2->version == VOP_VERSION_RK3588) { 3858b6ba80b4SDamon Ding if (vop2_power_domain_on(vop2, win_data->pd_id)) 3859b6ba80b4SDamon Ding printf("open vp%d plane pd fail\n", cstate->crtc_id); 3860b6ba80b4SDamon Ding } 3861b6ba80b4SDamon Ding 3862ee01dbb2SDamon Ding if (cstate->splice_mode) { 3863ee01dbb2SDamon Ding if (win_data->splice_win_id) { 3864ee01dbb2SDamon Ding splice_win_data = vop2_find_win_by_phys_id(vop2, win_data->splice_win_id); 3865ee01dbb2SDamon Ding splice_win_data->splice_mode_right = true; 3866b6ba80b4SDamon Ding 3867b6ba80b4SDamon Ding if (vop2_power_domain_on(vop2, splice_win_data->pd_id)) 3868b6ba80b4SDamon Ding printf("splice mode: open vp%d plane pd fail\n", cstate->splice_crtc_id); 3869b6ba80b4SDamon Ding 3870ee01dbb2SDamon Ding vop2_calc_display_rect_for_splice(state); 3871ee01dbb2SDamon Ding if (win_data->type == CLUSTER_LAYER) 3872ee01dbb2SDamon Ding vop2_set_cluster_win(state, splice_win_data); 3873ee01dbb2SDamon Ding else 3874ee01dbb2SDamon Ding vop2_set_smart_win(state, splice_win_data); 3875ee01dbb2SDamon Ding } else { 3876ee01dbb2SDamon Ding printf("ERROR: splice mode is unsupported by plane %s\n", 3877ee01dbb2SDamon Ding get_plane_name(primary_plane_id, plane_name)); 3878ee01dbb2SDamon Ding return -EINVAL; 3879ee01dbb2SDamon Ding } 3880ee01dbb2SDamon Ding } 3881ee01dbb2SDamon Ding 3882ecc31b6eSAndy Yan if (win_data->type == CLUSTER_LAYER) 3883ecc31b6eSAndy Yan vop2_set_cluster_win(state, win_data); 3884ecc31b6eSAndy Yan else 3885ecc31b6eSAndy Yan vop2_set_smart_win(state, win_data); 38868895aec1SSandy Huang 38878895aec1SSandy Huang printf("VOP VP%d enable %s[%dx%d->%dx%d@%dx%d] fmt[%d] addr[0x%x]\n", 38888895aec1SSandy Huang cstate->crtc_id, get_plane_name(primary_plane_id, plane_name), 3889ee01dbb2SDamon Ding cstate->src_rect.w, cstate->src_rect.h, cstate->crtc_rect.w, cstate->crtc_rect.h, 3890ee01dbb2SDamon Ding cstate->crtc_rect.x, cstate->crtc_rect.y, cstate->format, 38918895aec1SSandy Huang cstate->dma_addr); 38928895aec1SSandy Huang 3893d0408543SAndy Yan return 0; 3894d0408543SAndy Yan } 3895d0408543SAndy Yan 3896d0408543SAndy Yan static int rockchip_vop2_prepare(struct display_state *state) 3897d0408543SAndy Yan { 3898d0408543SAndy Yan return 0; 3899d0408543SAndy Yan } 3900d0408543SAndy Yan 390112ee5af0SDamon Ding static void vop2_dsc_cfg_done(struct display_state *state) 390212ee5af0SDamon Ding { 390312ee5af0SDamon Ding struct connector_state *conn_state = &state->conn_state; 390412ee5af0SDamon Ding struct crtc_state *cstate = &state->crtc_state; 390512ee5af0SDamon Ding struct vop2 *vop2 = cstate->private; 390612ee5af0SDamon Ding u8 dsc_id = cstate->dsc_id; 390712ee5af0SDamon Ding u32 ctrl_regs_offset = (dsc_id * 0x30); 390812ee5af0SDamon Ding 390912ee5af0SDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 391012ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE, EN_MASK, 391112ee5af0SDamon Ding DSC_CFG_DONE_SHIFT, 1, false); 391212ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + 0x30, EN_MASK, 391312ee5af0SDamon Ding DSC_CFG_DONE_SHIFT, 1, false); 391412ee5af0SDamon Ding } else { 391512ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + ctrl_regs_offset, EN_MASK, 391612ee5af0SDamon Ding DSC_CFG_DONE_SHIFT, 1, false); 391712ee5af0SDamon Ding } 391812ee5af0SDamon Ding } 391912ee5af0SDamon Ding 3920d0408543SAndy Yan static int rockchip_vop2_enable(struct display_state *state) 3921d0408543SAndy Yan { 3922d0408543SAndy Yan struct crtc_state *cstate = &state->crtc_state; 3923d0408543SAndy Yan struct vop2 *vop2 = cstate->private; 392452ee18acSSandy Huang u32 vp_offset = (cstate->crtc_id * 0x100); 3925ecc31b6eSAndy Yan u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 3926d0408543SAndy Yan 3927d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3928d0408543SAndy Yan STANDBY_EN_SHIFT, 0, false); 3929ee01dbb2SDamon Ding 3930ee01dbb2SDamon Ding if (cstate->splice_mode) 3931ee01dbb2SDamon Ding cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 3932ee01dbb2SDamon Ding 3933d0408543SAndy Yan vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 3934d0408543SAndy Yan 393512ee5af0SDamon Ding if (cstate->dsc_enable) 393612ee5af0SDamon Ding vop2_dsc_cfg_done(state); 393712ee5af0SDamon Ding 3938d0408543SAndy Yan return 0; 3939d0408543SAndy Yan } 3940d0408543SAndy Yan 3941d0408543SAndy Yan static int rockchip_vop2_disable(struct display_state *state) 3942d0408543SAndy Yan { 3943d0408543SAndy Yan struct crtc_state *cstate = &state->crtc_state; 3944d0408543SAndy Yan struct vop2 *vop2 = cstate->private; 394552ee18acSSandy Huang u32 vp_offset = (cstate->crtc_id * 0x100); 3946ecc31b6eSAndy Yan u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 3947d0408543SAndy Yan 3948d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3949d0408543SAndy Yan STANDBY_EN_SHIFT, 1, false); 3950ee01dbb2SDamon Ding 3951ee01dbb2SDamon Ding if (cstate->splice_mode) 3952ee01dbb2SDamon Ding cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 3953ee01dbb2SDamon Ding 3954d0408543SAndy Yan vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 3955d0408543SAndy Yan 3956d0408543SAndy Yan return 0; 3957d0408543SAndy Yan } 3958d0408543SAndy Yan 3959ee008497SSandy Huang static int rockchip_vop2_get_cursor_plane(struct display_state *state, u32 plane_mask, int cursor_plane) 3960ee008497SSandy Huang { 3961ee008497SSandy Huang struct crtc_state *cstate = &state->crtc_state; 3962ee008497SSandy Huang struct vop2 *vop2 = cstate->private; 3963ee008497SSandy Huang int i = 0; 3964ee008497SSandy Huang int correct_cursor_plane = -1; 3965ee008497SSandy Huang int plane_type = -1; 3966ee008497SSandy Huang 3967ee008497SSandy Huang if (cursor_plane < 0) 3968ee008497SSandy Huang return -1; 3969ee008497SSandy Huang 3970ee008497SSandy Huang if (plane_mask & (1 << cursor_plane)) 3971ee008497SSandy Huang return cursor_plane; 3972ee008497SSandy Huang 3973ee008497SSandy Huang /* Get current cursor plane type */ 3974ee008497SSandy Huang for (i = 0; i < vop2->data->nr_layers; i++) { 3975ee008497SSandy Huang if (vop2->data->plane_table[i].plane_id == cursor_plane) { 3976ee008497SSandy Huang plane_type = vop2->data->plane_table[i].plane_type; 3977ee008497SSandy Huang break; 3978ee008497SSandy Huang } 3979ee008497SSandy Huang } 3980ee008497SSandy Huang 3981ee008497SSandy Huang /* Get the other same plane type plane id */ 3982ee008497SSandy Huang for (i = 0; i < vop2->data->nr_layers; i++) { 3983ee008497SSandy Huang if (vop2->data->plane_table[i].plane_type == plane_type && 3984ee008497SSandy Huang vop2->data->plane_table[i].plane_id != cursor_plane) { 3985ee008497SSandy Huang correct_cursor_plane = vop2->data->plane_table[i].plane_id; 3986ee008497SSandy Huang break; 3987ee008497SSandy Huang } 3988ee008497SSandy Huang } 3989ee008497SSandy Huang 3990ee008497SSandy Huang /* To check whether the new correct_cursor_plane is attach to current vp */ 3991ee008497SSandy Huang if (correct_cursor_plane < 0 || !(plane_mask & (1 << correct_cursor_plane))) { 3992ee008497SSandy Huang printf("error: faild to find correct plane as cursor plane\n"); 3993ee008497SSandy Huang return -1; 3994ee008497SSandy Huang } 3995ee008497SSandy Huang 3996ee008497SSandy Huang printf("vp%d adjust cursor plane from %d to %d\n", 3997ee008497SSandy Huang cstate->crtc_id, cursor_plane, correct_cursor_plane); 3998ee008497SSandy Huang 3999ee008497SSandy Huang return correct_cursor_plane; 4000ee008497SSandy Huang } 4001ee008497SSandy Huang 4002b0989546SSandy Huang static int rockchip_vop2_fixup_dts(struct display_state *state, void *blob) 4003b0989546SSandy Huang { 4004b0989546SSandy Huang struct crtc_state *cstate = &state->crtc_state; 4005b0989546SSandy Huang struct vop2 *vop2 = cstate->private; 4006b0989546SSandy Huang ofnode vp_node; 4007b0989546SSandy Huang struct device_node *port_parent_node = cstate->ports_node; 4008b0989546SSandy Huang static bool vop_fix_dts; 4009b0989546SSandy Huang const char *path; 4010b0989546SSandy Huang u32 plane_mask = 0; 4011b0989546SSandy Huang int vp_id = 0; 4012ee008497SSandy Huang int cursor_plane_id = -1; 4013b0989546SSandy Huang 40145fa6e665SDamon Ding if (vop_fix_dts || vop2->version == VOP_VERSION_RK3528) 4015b0989546SSandy Huang return 0; 4016b0989546SSandy Huang 4017b0989546SSandy Huang ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) { 4018b0989546SSandy Huang path = vp_node.np->full_name; 4019b0989546SSandy Huang plane_mask = vop2->vp_plane_mask[vp_id].plane_mask; 4020b0989546SSandy Huang 40218b1fe597SSandy Huang if (cstate->crtc->assign_plane) 40228b1fe597SSandy Huang continue; 4023ee008497SSandy Huang cursor_plane_id = rockchip_vop2_get_cursor_plane(state, plane_mask, 4024ee008497SSandy Huang cstate->crtc->vps[vp_id].cursor_plane); 4025ee008497SSandy Huang printf("vp%d, plane_mask:0x%x, primary-id:%d, curser-id:%d\n", 4026b0989546SSandy Huang vp_id, plane_mask, 4027ee008497SSandy Huang vop2->vp_plane_mask[vp_id].primary_plane_id, 4028ee008497SSandy Huang cursor_plane_id); 4029b0989546SSandy Huang 4030b0989546SSandy Huang do_fixup_by_path_u32(blob, path, "rockchip,plane-mask", 4031b0989546SSandy Huang plane_mask, 1); 4032b0989546SSandy Huang do_fixup_by_path_u32(blob, path, "rockchip,primary-plane", 4033b0989546SSandy Huang vop2->vp_plane_mask[vp_id].primary_plane_id, 1); 4034ee008497SSandy Huang if (cursor_plane_id >= 0) 4035ee008497SSandy Huang do_fixup_by_path_u32(blob, path, "cursor-win-id", 4036ee008497SSandy Huang cursor_plane_id, 1); 4037b0989546SSandy Huang vp_id++; 4038b0989546SSandy Huang } 4039b0989546SSandy Huang 4040b0989546SSandy Huang vop_fix_dts = true; 4041b0989546SSandy Huang 4042b0989546SSandy Huang return 0; 4043b0989546SSandy Huang } 4044b0989546SSandy Huang 4045820a5c17SDamon Ding static int rockchip_vop2_check(struct display_state *state) 4046820a5c17SDamon Ding { 4047820a5c17SDamon Ding struct crtc_state *cstate = &state->crtc_state; 4048820a5c17SDamon Ding struct rockchip_crtc *crtc = cstate->crtc; 4049820a5c17SDamon Ding 4050820a5c17SDamon Ding if (crtc->splice_mode && cstate->crtc_id == crtc->splice_crtc_id) { 4051820a5c17SDamon Ding printf("WARN: VP%d is busy in splice mode\n", cstate->crtc_id); 4052820a5c17SDamon Ding return -ENOTSUPP; 4053820a5c17SDamon Ding } 4054820a5c17SDamon Ding 4055820a5c17SDamon Ding if (cstate->splice_mode) { 4056820a5c17SDamon Ding crtc->splice_mode = true; 4057820a5c17SDamon Ding crtc->splice_crtc_id = cstate->splice_crtc_id; 4058820a5c17SDamon Ding } 4059820a5c17SDamon Ding 4060820a5c17SDamon Ding return 0; 4061820a5c17SDamon Ding } 4062820a5c17SDamon Ding 406322007755SDamon Ding static int rockchip_vop2_mode_valid(struct display_state *state) 406422007755SDamon Ding { 406522007755SDamon Ding struct connector_state *conn_state = &state->conn_state; 406622007755SDamon Ding struct crtc_state *cstate = &state->crtc_state; 406722007755SDamon Ding struct drm_display_mode *mode = &conn_state->mode; 406822007755SDamon Ding struct videomode vm; 406922007755SDamon Ding 407022007755SDamon Ding drm_display_mode_to_videomode(mode, &vm); 407122007755SDamon Ding 407222007755SDamon Ding if (vm.hactive < 32 || vm.vactive < 32 || 407322007755SDamon Ding (vm.hfront_porch * vm.hsync_len * vm.hback_porch * 407422007755SDamon Ding vm.vfront_porch * vm.vsync_len * vm.vback_porch == 0)) { 407522007755SDamon Ding printf("ERROR: VP%d: unsupported display timing\n", cstate->crtc_id); 407622007755SDamon Ding return -EINVAL; 407722007755SDamon Ding } 407822007755SDamon Ding 407922007755SDamon Ding return 0; 408022007755SDamon Ding } 408122007755SDamon Ding 40824c765862SDamon Ding #define FRAC_16_16(mult, div) (((mult) << 16) / (div)) 40834c765862SDamon Ding 40844c765862SDamon Ding static int rockchip_vop2_plane_check(struct display_state *state) 40854c765862SDamon Ding { 40864c765862SDamon Ding struct crtc_state *cstate = &state->crtc_state; 40874c765862SDamon Ding struct vop2 *vop2 = cstate->private; 40884c765862SDamon Ding struct display_rect *src = &cstate->src_rect; 40894c765862SDamon Ding struct display_rect *dst = &cstate->crtc_rect; 40904c765862SDamon Ding struct vop2_win_data *win_data; 40914c765862SDamon Ding int min_scale, max_scale; 40924c765862SDamon Ding int hscale, vscale; 40934c765862SDamon Ding u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id; 40944c765862SDamon Ding 40954c765862SDamon Ding win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id); 40964c765862SDamon Ding if (!win_data) { 40974c765862SDamon Ding printf("ERROR: invalid win id %d\n", primary_plane_id); 40984c765862SDamon Ding return -ENODEV; 40994c765862SDamon Ding } 41004c765862SDamon Ding 41014c765862SDamon Ding min_scale = FRAC_16_16(1, win_data->max_downscale_factor); 41024c765862SDamon Ding max_scale = FRAC_16_16(win_data->max_upscale_factor, 1); 41034c765862SDamon Ding 41044c765862SDamon Ding hscale = display_rect_calc_hscale(src, dst, min_scale, max_scale); 41054c765862SDamon Ding vscale = display_rect_calc_vscale(src, dst, min_scale, max_scale); 41064c765862SDamon Ding if (hscale < 0 || vscale < 0) { 41074c765862SDamon Ding printf("ERROR: VP%d %s: scale factor is out of range\n", cstate->crtc_id, win_data->name); 41084c765862SDamon Ding return -ERANGE; 41094c765862SDamon Ding } 41104c765862SDamon Ding 41114c765862SDamon Ding return 0; 41124c765862SDamon Ding } 4113337d1c13SDamon Ding 41145fa6e665SDamon Ding static u8 rk3528_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = { 41155fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART0, 41165fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART1, 41175fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART2, 41185fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART3, 41195fa6e665SDamon Ding }; 41205fa6e665SDamon Ding 41215fa6e665SDamon Ding static struct vop2_plane_table rk3528_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 41225fa6e665SDamon Ding {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 41235fa6e665SDamon Ding {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 41245fa6e665SDamon Ding {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 41255fa6e665SDamon Ding {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER}, 41265fa6e665SDamon Ding {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER}, 41275fa6e665SDamon Ding }; 41285fa6e665SDamon Ding 41295fa6e665SDamon Ding static struct vop2_vp_plane_mask rk3528_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 41305fa6e665SDamon Ding { /* one display policy for hdmi */ 41315fa6e665SDamon Ding {/* main display */ 41325fa6e665SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART1, 41335fa6e665SDamon Ding .attached_layers_nr = 4, 41345fa6e665SDamon Ding .attached_layers = { 41355fa6e665SDamon Ding ROCKCHIP_VOP2_CLUSTER0, 41365fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART2 41375fa6e665SDamon Ding }, 41385fa6e665SDamon Ding }, 41395fa6e665SDamon Ding {/* second display */}, 41405fa6e665SDamon Ding {/* third display */}, 41415fa6e665SDamon Ding {/* fourth display */}, 41425fa6e665SDamon Ding }, 41435fa6e665SDamon Ding 41445fa6e665SDamon Ding { /* two display policy */ 41455fa6e665SDamon Ding {/* main display */ 41465fa6e665SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART1, 41475fa6e665SDamon Ding .attached_layers_nr = 3, 41485fa6e665SDamon Ding .attached_layers = { 41495fa6e665SDamon Ding ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1 41505fa6e665SDamon Ding }, 41515fa6e665SDamon Ding }, 41525fa6e665SDamon Ding 41535fa6e665SDamon Ding {/* second display */ 41545fa6e665SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART3, 41555fa6e665SDamon Ding .attached_layers_nr = 2, 41565fa6e665SDamon Ding .attached_layers = { 41575fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 41585fa6e665SDamon Ding }, 41595fa6e665SDamon Ding }, 41605fa6e665SDamon Ding {/* third display */}, 41615fa6e665SDamon Ding {/* fourth display */}, 41625fa6e665SDamon Ding }, 41635fa6e665SDamon Ding 41645fa6e665SDamon Ding { /* one display policy for cvbs */ 41655fa6e665SDamon Ding {/* main display */ 41665fa6e665SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART3, 41675fa6e665SDamon Ding .attached_layers_nr = 2, 41685fa6e665SDamon Ding .attached_layers = { 41695fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 41705fa6e665SDamon Ding }, 41715fa6e665SDamon Ding }, 41725fa6e665SDamon Ding {/* second display */}, 41735fa6e665SDamon Ding {/* third display */}, 41745fa6e665SDamon Ding {/* fourth display */}, 41755fa6e665SDamon Ding }, 41765fa6e665SDamon Ding 41775fa6e665SDamon Ding {/* reserved */}, 41785fa6e665SDamon Ding }; 41795fa6e665SDamon Ding 41805fa6e665SDamon Ding static struct vop2_win_data rk3528_win_data[5] = { 41815fa6e665SDamon Ding { 41825fa6e665SDamon Ding .name = "Esmart0", 41835fa6e665SDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART0, 41845fa6e665SDamon Ding .type = ESMART_LAYER, 41855fa6e665SDamon Ding .win_sel_port_offset = 8, 41865fa6e665SDamon Ding .layer_sel_win_id = { 1, 0xff, 0xff, 0xff }, 41875fa6e665SDamon Ding .reg_offset = 0, 41885fa6e665SDamon Ding .axi_id = 0, 41895fa6e665SDamon Ding .axi_yrgb_id = 0x06, 41905fa6e665SDamon Ding .axi_uv_id = 0x07, 41915fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 41925fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 41935fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 41945fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 41955fa6e665SDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 41965fa6e665SDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */ 41975fa6e665SDamon Ding .max_upscale_factor = 8, 41985fa6e665SDamon Ding .max_downscale_factor = 8, 41995fa6e665SDamon Ding }, 42005fa6e665SDamon Ding 42015fa6e665SDamon Ding { 42025fa6e665SDamon Ding .name = "Esmart1", 42035fa6e665SDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART1, 42045fa6e665SDamon Ding .type = ESMART_LAYER, 42055fa6e665SDamon Ding .win_sel_port_offset = 10, 42065fa6e665SDamon Ding .layer_sel_win_id = { 2, 0xff, 0xff, 0xff }, 42075fa6e665SDamon Ding .reg_offset = 0x200, 42085fa6e665SDamon Ding .axi_id = 0, 42095fa6e665SDamon Ding .axi_yrgb_id = 0x08, 42105fa6e665SDamon Ding .axi_uv_id = 0x09, 42115fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 42125fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 42135fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 42145fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 42155fa6e665SDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 42165fa6e665SDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */ 42175fa6e665SDamon Ding .max_upscale_factor = 8, 42185fa6e665SDamon Ding .max_downscale_factor = 8, 42195fa6e665SDamon Ding }, 42205fa6e665SDamon Ding 42215fa6e665SDamon Ding { 42225fa6e665SDamon Ding .name = "Esmart2", 42235fa6e665SDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART2, 42245fa6e665SDamon Ding .type = ESMART_LAYER, 42255fa6e665SDamon Ding .win_sel_port_offset = 12, 42265fa6e665SDamon Ding .layer_sel_win_id = { 3, 0, 0xff, 0xff }, 42275fa6e665SDamon Ding .reg_offset = 0x400, 42285fa6e665SDamon Ding .axi_id = 0, 42295fa6e665SDamon Ding .axi_yrgb_id = 0x0a, 42305fa6e665SDamon Ding .axi_uv_id = 0x0b, 42315fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 42325fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 42335fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 42345fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 42355fa6e665SDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 42365fa6e665SDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */ 42375fa6e665SDamon Ding .max_upscale_factor = 8, 42385fa6e665SDamon Ding .max_downscale_factor = 8, 42395fa6e665SDamon Ding }, 42405fa6e665SDamon Ding 42415fa6e665SDamon Ding { 42425fa6e665SDamon Ding .name = "Esmart3", 42435fa6e665SDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART3, 42445fa6e665SDamon Ding .type = ESMART_LAYER, 42455fa6e665SDamon Ding .win_sel_port_offset = 14, 42465fa6e665SDamon Ding .layer_sel_win_id = { 0xff, 1, 0xff, 0xff }, 42475fa6e665SDamon Ding .reg_offset = 0x600, 42485fa6e665SDamon Ding .axi_id = 0, 42495fa6e665SDamon Ding .axi_yrgb_id = 0x0c, 42505fa6e665SDamon Ding .axi_uv_id = 0x0d, 42515fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 42525fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 42535fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 42545fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 42555fa6e665SDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 42565fa6e665SDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */ 42575fa6e665SDamon Ding .max_upscale_factor = 8, 42585fa6e665SDamon Ding .max_downscale_factor = 8, 42595fa6e665SDamon Ding }, 42605fa6e665SDamon Ding 42615fa6e665SDamon Ding { 42625fa6e665SDamon Ding .name = "Cluster0", 42635fa6e665SDamon Ding .phys_id = ROCKCHIP_VOP2_CLUSTER0, 42645fa6e665SDamon Ding .type = CLUSTER_LAYER, 42655fa6e665SDamon Ding .win_sel_port_offset = 0, 42665fa6e665SDamon Ding .layer_sel_win_id = { 0, 0xff, 0xff, 0xff }, 42675fa6e665SDamon Ding .reg_offset = 0, 42685fa6e665SDamon Ding .axi_id = 0, 42695fa6e665SDamon Ding .axi_yrgb_id = 0x02, 42705fa6e665SDamon Ding .axi_uv_id = 0x03, 42715fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 42725fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 42735fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 42745fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 42755fa6e665SDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 42765fa6e665SDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 42775fa6e665SDamon Ding .max_upscale_factor = 8, 42785fa6e665SDamon Ding .max_downscale_factor = 8, 42795fa6e665SDamon Ding }, 42805fa6e665SDamon Ding }; 42815fa6e665SDamon Ding 42825fa6e665SDamon Ding static struct vop2_vp_data rk3528_vp_data[2] = { 42835fa6e665SDamon Ding { 42845fa6e665SDamon Ding .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN, 42855fa6e665SDamon Ding .pre_scan_max_dly = 43, 42865fa6e665SDamon Ding .max_output = {4096, 4096}, 42875fa6e665SDamon Ding }, 42885fa6e665SDamon Ding { 42895fa6e665SDamon Ding .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN, 42905fa6e665SDamon Ding .pre_scan_max_dly = 37, 42915fa6e665SDamon Ding .max_output = {1920, 1080}, 42925fa6e665SDamon Ding }, 42935fa6e665SDamon Ding }; 42945fa6e665SDamon Ding 42955fa6e665SDamon Ding const struct vop2_data rk3528_vop = { 42965fa6e665SDamon Ding .version = VOP_VERSION_RK3528, 42975fa6e665SDamon Ding .nr_vps = 2, 42985fa6e665SDamon Ding .vp_data = rk3528_vp_data, 42995fa6e665SDamon Ding .win_data = rk3528_win_data, 43005fa6e665SDamon Ding .plane_mask = rk3528_vp_plane_mask[0], 43015fa6e665SDamon Ding .plane_table = rk3528_plane_table, 43025fa6e665SDamon Ding .vp_primary_plane_order = rk3528_vp_primary_plane_order, 43035fa6e665SDamon Ding .nr_layers = 5, 43045fa6e665SDamon Ding .nr_mixers = 3, 43055fa6e665SDamon Ding .nr_gammas = 2, 43065fa6e665SDamon Ding .esmart_lb_mode = VOP3_ESMART_4K_2K_2K_MODE, 43075fa6e665SDamon Ding }; 43085fa6e665SDamon Ding 4309337d1c13SDamon Ding static u8 rk3568_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = { 4310337d1c13SDamon Ding ROCKCHIP_VOP2_SMART0, 4311337d1c13SDamon Ding ROCKCHIP_VOP2_SMART1, 4312337d1c13SDamon Ding ROCKCHIP_VOP2_ESMART0, 4313337d1c13SDamon Ding ROCKCHIP_VOP2_ESMART1, 4314337d1c13SDamon Ding }; 4315337d1c13SDamon Ding 4316ee008497SSandy Huang static struct vop2_plane_table rk356x_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 4317ee008497SSandy Huang {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 4318ee008497SSandy Huang {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER}, 4319ee008497SSandy Huang {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 4320ee008497SSandy Huang {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 4321ee008497SSandy Huang {ROCKCHIP_VOP2_SMART0, SMART_LAYER}, 4322ee008497SSandy Huang {ROCKCHIP_VOP2_SMART0, SMART_LAYER}, 4323ee008497SSandy Huang }; 4324ee008497SSandy Huang 4325b0989546SSandy Huang static struct vop2_vp_plane_mask rk356x_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 4326b0989546SSandy Huang { /* one display policy */ 4327b0989546SSandy Huang {/* main display */ 4328b0989546SSandy Huang .primary_plane_id = ROCKCHIP_VOP2_SMART0, 4329b0989546SSandy Huang .attached_layers_nr = 6, 4330b0989546SSandy Huang .attached_layers = { 4331b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0, 4332b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1 4333b0989546SSandy Huang }, 4334b0989546SSandy Huang }, 4335b0989546SSandy Huang {/* second display */}, 4336b0989546SSandy Huang {/* third display */}, 4337b0989546SSandy Huang {/* fourth display */}, 4338b0989546SSandy Huang }, 4339b0989546SSandy Huang 4340b0989546SSandy Huang { /* two display policy */ 4341b0989546SSandy Huang {/* main display */ 4342b0989546SSandy Huang .primary_plane_id = ROCKCHIP_VOP2_SMART0, 4343b0989546SSandy Huang .attached_layers_nr = 3, 4344b0989546SSandy Huang .attached_layers = { 4345b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0 4346b0989546SSandy Huang }, 4347b0989546SSandy Huang }, 4348b0989546SSandy Huang 4349b0989546SSandy Huang {/* second display */ 4350b0989546SSandy Huang .primary_plane_id = ROCKCHIP_VOP2_SMART1, 4351b0989546SSandy Huang .attached_layers_nr = 3, 4352b0989546SSandy Huang .attached_layers = { 4353b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1 4354b0989546SSandy Huang }, 4355b0989546SSandy Huang }, 4356b0989546SSandy Huang {/* third display */}, 4357b0989546SSandy Huang {/* fourth display */}, 4358b0989546SSandy Huang }, 4359b0989546SSandy Huang 4360b0989546SSandy Huang { /* three display policy */ 4361b0989546SSandy Huang {/* main display */ 4362b0989546SSandy Huang .primary_plane_id = ROCKCHIP_VOP2_SMART0, 4363b0989546SSandy Huang .attached_layers_nr = 3, 4364b0989546SSandy Huang .attached_layers = { 4365b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0 4366b0989546SSandy Huang }, 4367b0989546SSandy Huang }, 4368b0989546SSandy Huang 4369b0989546SSandy Huang {/* second display */ 4370b0989546SSandy Huang .primary_plane_id = ROCKCHIP_VOP2_SMART1, 4371b0989546SSandy Huang .attached_layers_nr = 2, 4372b0989546SSandy Huang .attached_layers = { 4373b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_SMART1 4374b0989546SSandy Huang }, 4375b0989546SSandy Huang }, 4376b0989546SSandy Huang 4377b0989546SSandy Huang {/* third display */ 4378b0989546SSandy Huang .primary_plane_id = ROCKCHIP_VOP2_ESMART1, 4379b0989546SSandy Huang .attached_layers_nr = 1, 4380b0989546SSandy Huang .attached_layers = { ROCKCHIP_VOP2_ESMART1 }, 4381b0989546SSandy Huang }, 4382b0989546SSandy Huang 4383b0989546SSandy Huang {/* fourth display */}, 4384b0989546SSandy Huang }, 4385b0989546SSandy Huang 4386b0989546SSandy Huang {/* reserved for four display policy */}, 4387b0989546SSandy Huang }; 4388b0989546SSandy Huang 4389b0989546SSandy Huang static struct vop2_win_data rk3568_win_data[6] = { 4390b0989546SSandy Huang { 4391b0989546SSandy Huang .name = "Cluster0", 4392b0989546SSandy Huang .phys_id = ROCKCHIP_VOP2_CLUSTER0, 4393ecc31b6eSAndy Yan .type = CLUSTER_LAYER, 4394b0989546SSandy Huang .win_sel_port_offset = 0, 43955fa6e665SDamon Ding .layer_sel_win_id = { 0, 0, 0, 0xff }, 4396b0989546SSandy Huang .reg_offset = 0, 43975fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 43985fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 43995fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 44005fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 44014c765862SDamon Ding .max_upscale_factor = 4, 44024c765862SDamon Ding .max_downscale_factor = 4, 4403b0989546SSandy Huang }, 4404b0989546SSandy Huang 4405b0989546SSandy Huang { 4406b0989546SSandy Huang .name = "Cluster1", 4407b0989546SSandy Huang .phys_id = ROCKCHIP_VOP2_CLUSTER1, 4408ecc31b6eSAndy Yan .type = CLUSTER_LAYER, 4409b0989546SSandy Huang .win_sel_port_offset = 1, 44105fa6e665SDamon Ding .layer_sel_win_id = { 1, 1, 1, 0xff }, 4411b0989546SSandy Huang .reg_offset = 0x200, 44125fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 44135fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 44145fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 44155fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 44164c765862SDamon Ding .max_upscale_factor = 4, 44174c765862SDamon Ding .max_downscale_factor = 4, 4418b0989546SSandy Huang }, 4419b0989546SSandy Huang 4420b0989546SSandy Huang { 4421b0989546SSandy Huang .name = "Esmart0", 4422b0989546SSandy Huang .phys_id = ROCKCHIP_VOP2_ESMART0, 4423ecc31b6eSAndy Yan .type = ESMART_LAYER, 4424b0989546SSandy Huang .win_sel_port_offset = 4, 44255fa6e665SDamon Ding .layer_sel_win_id = { 2, 2, 2, 0xff }, 4426b0989546SSandy Huang .reg_offset = 0, 44275fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 44285fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 44295fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 44305fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 44314c765862SDamon Ding .max_upscale_factor = 8, 44324c765862SDamon Ding .max_downscale_factor = 8, 4433b0989546SSandy Huang }, 4434b0989546SSandy Huang 4435b0989546SSandy Huang { 4436b0989546SSandy Huang .name = "Esmart1", 4437b0989546SSandy Huang .phys_id = ROCKCHIP_VOP2_ESMART1, 4438ecc31b6eSAndy Yan .type = ESMART_LAYER, 4439b0989546SSandy Huang .win_sel_port_offset = 5, 44405fa6e665SDamon Ding .layer_sel_win_id = { 6, 6, 6, 0xff }, 4441b0989546SSandy Huang .reg_offset = 0x200, 44425fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 44435fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 44445fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 44455fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 44464c765862SDamon Ding .max_upscale_factor = 8, 44474c765862SDamon Ding .max_downscale_factor = 8, 4448b0989546SSandy Huang }, 4449b0989546SSandy Huang 4450b0989546SSandy Huang { 4451b0989546SSandy Huang .name = "Smart0", 4452b0989546SSandy Huang .phys_id = ROCKCHIP_VOP2_SMART0, 4453ecc31b6eSAndy Yan .type = SMART_LAYER, 4454b0989546SSandy Huang .win_sel_port_offset = 6, 44555fa6e665SDamon Ding .layer_sel_win_id = { 3, 3, 3, 0xff }, 4456b0989546SSandy Huang .reg_offset = 0x400, 44575fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 44585fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 44595fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 44605fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 44614c765862SDamon Ding .max_upscale_factor = 8, 44624c765862SDamon Ding .max_downscale_factor = 8, 4463b0989546SSandy Huang }, 4464b0989546SSandy Huang 4465b0989546SSandy Huang { 4466b0989546SSandy Huang .name = "Smart1", 4467b0989546SSandy Huang .phys_id = ROCKCHIP_VOP2_SMART1, 4468ecc31b6eSAndy Yan .type = SMART_LAYER, 4469b0989546SSandy Huang .win_sel_port_offset = 7, 44705fa6e665SDamon Ding .layer_sel_win_id = { 7, 7, 7, 0xff }, 4471b0989546SSandy Huang .reg_offset = 0x600, 44725fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 44735fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 44745fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 44755fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 44764c765862SDamon Ding .max_upscale_factor = 8, 44774c765862SDamon Ding .max_downscale_factor = 8, 4478b0989546SSandy Huang }, 4479b0989546SSandy Huang }; 4480b0989546SSandy Huang 448163cb669fSSandy Huang static struct vop2_vp_data rk3568_vp_data[3] = { 448263cb669fSSandy Huang { 448363cb669fSSandy Huang .feature = VOP_FEATURE_OUTPUT_10BIT, 448463cb669fSSandy Huang .pre_scan_max_dly = 42, 448563cb669fSSandy Huang .max_output = {4096, 2304}, 4486d0408543SAndy Yan }, 448763cb669fSSandy Huang { 448863cb669fSSandy Huang .feature = 0, 448963cb669fSSandy Huang .pre_scan_max_dly = 40, 449063cb669fSSandy Huang .max_output = {2048, 1536}, 449163cb669fSSandy Huang }, 449263cb669fSSandy Huang { 449363cb669fSSandy Huang .feature = 0, 449463cb669fSSandy Huang .pre_scan_max_dly = 40, 449563cb669fSSandy Huang .max_output = {1920, 1080}, 449663cb669fSSandy Huang }, 449763cb669fSSandy Huang }; 4498d0408543SAndy Yan 449963cb669fSSandy Huang const struct vop2_data rk3568_vop = { 4500ecc31b6eSAndy Yan .version = VOP_VERSION_RK3568, 450163cb669fSSandy Huang .nr_vps = 3, 450263cb669fSSandy Huang .vp_data = rk3568_vp_data, 4503b0989546SSandy Huang .win_data = rk3568_win_data, 4504b0989546SSandy Huang .plane_mask = rk356x_vp_plane_mask[0], 4505ee008497SSandy Huang .plane_table = rk356x_plane_table, 4506337d1c13SDamon Ding .vp_primary_plane_order = rk3568_vp_primary_plane_order, 4507d0408543SAndy Yan .nr_layers = 6, 450863cb669fSSandy Huang .nr_mixers = 5, 45091147facaSSandy Huang .nr_gammas = 1, 4510d0408543SAndy Yan }; 4511d0408543SAndy Yan 4512337d1c13SDamon Ding static u8 rk3588_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = { 4513337d1c13SDamon Ding ROCKCHIP_VOP2_ESMART0, 4514337d1c13SDamon Ding ROCKCHIP_VOP2_ESMART1, 4515337d1c13SDamon Ding ROCKCHIP_VOP2_ESMART2, 4516337d1c13SDamon Ding ROCKCHIP_VOP2_ESMART3, 4517337d1c13SDamon Ding ROCKCHIP_VOP2_CLUSTER0, 4518337d1c13SDamon Ding ROCKCHIP_VOP2_CLUSTER1, 4519337d1c13SDamon Ding ROCKCHIP_VOP2_CLUSTER2, 4520337d1c13SDamon Ding ROCKCHIP_VOP2_CLUSTER3, 4521337d1c13SDamon Ding }; 4522337d1c13SDamon Ding 4523ecc31b6eSAndy Yan static struct vop2_plane_table rk3588_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 4524ecc31b6eSAndy Yan {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 4525ecc31b6eSAndy Yan {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER}, 4526ecc31b6eSAndy Yan {ROCKCHIP_VOP2_CLUSTER2, CLUSTER_LAYER}, 4527ecc31b6eSAndy Yan {ROCKCHIP_VOP2_CLUSTER3, CLUSTER_LAYER}, 4528ecc31b6eSAndy Yan {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 4529ecc31b6eSAndy Yan {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 4530ecc31b6eSAndy Yan {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER}, 4531ecc31b6eSAndy Yan {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER}, 4532ecc31b6eSAndy Yan }; 4533ecc31b6eSAndy Yan 4534ecc31b6eSAndy Yan static struct vop2_vp_plane_mask rk3588_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 4535ecc31b6eSAndy Yan { /* one display policy */ 4536ecc31b6eSAndy Yan {/* main display */ 4537ecc31b6eSAndy Yan .primary_plane_id = ROCKCHIP_VOP2_CLUSTER0, 4538ecc31b6eSAndy Yan .attached_layers_nr = 8, 4539ecc31b6eSAndy Yan .attached_layers = { 4540ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART2, 4541ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART3, 4542ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3 4543ecc31b6eSAndy Yan }, 4544ecc31b6eSAndy Yan }, 4545ecc31b6eSAndy Yan {/* second display */}, 4546ecc31b6eSAndy Yan {/* third display */}, 4547ecc31b6eSAndy Yan {/* fourth display */}, 4548ecc31b6eSAndy Yan }, 4549ecc31b6eSAndy Yan 4550ecc31b6eSAndy Yan { /* two display policy */ 4551ecc31b6eSAndy Yan {/* main display */ 4552ecc31b6eSAndy Yan .primary_plane_id = ROCKCHIP_VOP2_CLUSTER0, 4553ecc31b6eSAndy Yan .attached_layers_nr = 4, 4554ecc31b6eSAndy Yan .attached_layers = { 4555ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, 4556ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 4557ecc31b6eSAndy Yan }, 4558ecc31b6eSAndy Yan }, 4559ecc31b6eSAndy Yan 4560ecc31b6eSAndy Yan {/* second display */ 4561ecc31b6eSAndy Yan .primary_plane_id = ROCKCHIP_VOP2_CLUSTER2, 4562ecc31b6eSAndy Yan .attached_layers_nr = 4, 4563ecc31b6eSAndy Yan .attached_layers = { 4564ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2, 4565ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 4566ecc31b6eSAndy Yan }, 4567ecc31b6eSAndy Yan }, 4568ecc31b6eSAndy Yan {/* third display */}, 4569ecc31b6eSAndy Yan {/* fourth display */}, 4570ecc31b6eSAndy Yan }, 4571ecc31b6eSAndy Yan 4572ecc31b6eSAndy Yan { /* three display policy */ 4573ecc31b6eSAndy Yan {/* main display */ 4574ecc31b6eSAndy Yan .primary_plane_id = ROCKCHIP_VOP2_CLUSTER0, 4575ecc31b6eSAndy Yan .attached_layers_nr = 3, 4576ecc31b6eSAndy Yan .attached_layers = { 4577ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART0 4578ecc31b6eSAndy Yan }, 4579ecc31b6eSAndy Yan }, 4580ecc31b6eSAndy Yan 4581ecc31b6eSAndy Yan {/* second display */ 4582ecc31b6eSAndy Yan .primary_plane_id = ROCKCHIP_VOP2_CLUSTER2, 4583ecc31b6eSAndy Yan .attached_layers_nr = 3, 4584ecc31b6eSAndy Yan .attached_layers = { 4585ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART1 4586ecc31b6eSAndy Yan }, 4587ecc31b6eSAndy Yan }, 4588ecc31b6eSAndy Yan 4589ecc31b6eSAndy Yan {/* third display */ 4590ecc31b6eSAndy Yan .primary_plane_id = ROCKCHIP_VOP2_ESMART2, 4591ecc31b6eSAndy Yan .attached_layers_nr = 2, 4592ecc31b6eSAndy Yan .attached_layers = { ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 }, 4593ecc31b6eSAndy Yan }, 4594ecc31b6eSAndy Yan 4595ecc31b6eSAndy Yan {/* fourth display */}, 4596ecc31b6eSAndy Yan }, 4597ecc31b6eSAndy Yan 4598ecc31b6eSAndy Yan { /* four display policy */ 4599ecc31b6eSAndy Yan {/* main display */ 4600ecc31b6eSAndy Yan .primary_plane_id = ROCKCHIP_VOP2_CLUSTER0, 4601ecc31b6eSAndy Yan .attached_layers_nr = 2, 4602ecc31b6eSAndy Yan .attached_layers = { ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0 }, 4603ecc31b6eSAndy Yan }, 4604ecc31b6eSAndy Yan 4605ecc31b6eSAndy Yan {/* second display */ 4606ecc31b6eSAndy Yan .primary_plane_id = ROCKCHIP_VOP2_CLUSTER1, 4607ecc31b6eSAndy Yan .attached_layers_nr = 2, 4608ecc31b6eSAndy Yan .attached_layers = { ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 }, 4609ecc31b6eSAndy Yan }, 4610ecc31b6eSAndy Yan 4611ecc31b6eSAndy Yan {/* third display */ 4612ecc31b6eSAndy Yan .primary_plane_id = ROCKCHIP_VOP2_CLUSTER2, 4613ecc31b6eSAndy Yan .attached_layers_nr = 2, 4614ecc31b6eSAndy Yan .attached_layers = { ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2 }, 4615ecc31b6eSAndy Yan }, 4616ecc31b6eSAndy Yan 4617ecc31b6eSAndy Yan {/* fourth display */ 4618ecc31b6eSAndy Yan .primary_plane_id = ROCKCHIP_VOP2_CLUSTER3, 4619ecc31b6eSAndy Yan .attached_layers_nr = 2, 4620ecc31b6eSAndy Yan .attached_layers = { ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 }, 4621ecc31b6eSAndy Yan }, 4622ecc31b6eSAndy Yan }, 4623ecc31b6eSAndy Yan 4624ecc31b6eSAndy Yan }; 4625ecc31b6eSAndy Yan 4626ecc31b6eSAndy Yan static struct vop2_win_data rk3588_win_data[8] = { 4627ecc31b6eSAndy Yan { 4628ecc31b6eSAndy Yan .name = "Cluster0", 4629ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_CLUSTER0, 4630ee01dbb2SDamon Ding .splice_win_id = ROCKCHIP_VOP2_CLUSTER1, 4631ecc31b6eSAndy Yan .type = CLUSTER_LAYER, 4632ecc31b6eSAndy Yan .win_sel_port_offset = 0, 46335fa6e665SDamon Ding .layer_sel_win_id = { 0, 0, 0, 0 }, 4634ecc31b6eSAndy Yan .reg_offset = 0, 4635a33b790fSDamon Ding .axi_id = 0, 4636a33b790fSDamon Ding .axi_yrgb_id = 2, 4637a33b790fSDamon Ding .axi_uv_id = 3, 4638b6ba80b4SDamon Ding .pd_id = VOP2_PD_CLUSTER0, 46395fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 46405fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 46415fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 46425fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 46434c765862SDamon Ding .max_upscale_factor = 4, 46444c765862SDamon Ding .max_downscale_factor = 4, 4645ecc31b6eSAndy Yan }, 4646ecc31b6eSAndy Yan 4647ecc31b6eSAndy Yan { 4648ecc31b6eSAndy Yan .name = "Cluster1", 4649ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_CLUSTER1, 4650ecc31b6eSAndy Yan .type = CLUSTER_LAYER, 4651ecc31b6eSAndy Yan .win_sel_port_offset = 1, 46525fa6e665SDamon Ding .layer_sel_win_id = { 1, 1, 1, 1 }, 4653ecc31b6eSAndy Yan .reg_offset = 0x200, 4654a33b790fSDamon Ding .axi_id = 0, 4655a33b790fSDamon Ding .axi_yrgb_id = 6, 4656a33b790fSDamon Ding .axi_uv_id = 7, 4657b6ba80b4SDamon Ding .pd_id = VOP2_PD_CLUSTER1, 46585fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 46595fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 46605fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 46615fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 46624c765862SDamon Ding .max_upscale_factor = 4, 46634c765862SDamon Ding .max_downscale_factor = 4, 4664ecc31b6eSAndy Yan }, 4665ecc31b6eSAndy Yan 4666ecc31b6eSAndy Yan { 4667ecc31b6eSAndy Yan .name = "Cluster2", 4668ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_CLUSTER2, 4669ee01dbb2SDamon Ding .splice_win_id = ROCKCHIP_VOP2_CLUSTER3, 4670ecc31b6eSAndy Yan .type = CLUSTER_LAYER, 4671ecc31b6eSAndy Yan .win_sel_port_offset = 2, 46725fa6e665SDamon Ding .layer_sel_win_id = { 4, 4, 4, 4 }, 4673ecc31b6eSAndy Yan .reg_offset = 0x400, 4674a33b790fSDamon Ding .axi_id = 1, 4675a33b790fSDamon Ding .axi_yrgb_id = 2, 4676a33b790fSDamon Ding .axi_uv_id = 3, 4677b6ba80b4SDamon Ding .pd_id = VOP2_PD_CLUSTER2, 46785fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 46795fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 46805fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 46815fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 46824c765862SDamon Ding .max_upscale_factor = 4, 46834c765862SDamon Ding .max_downscale_factor = 4, 4684ecc31b6eSAndy Yan }, 4685ecc31b6eSAndy Yan 4686ecc31b6eSAndy Yan { 4687ecc31b6eSAndy Yan .name = "Cluster3", 4688ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_CLUSTER3, 4689ecc31b6eSAndy Yan .type = CLUSTER_LAYER, 4690ecc31b6eSAndy Yan .win_sel_port_offset = 3, 46915fa6e665SDamon Ding .layer_sel_win_id = { 5, 5, 5, 5 }, 4692ecc31b6eSAndy Yan .reg_offset = 0x600, 4693a33b790fSDamon Ding .axi_id = 1, 4694a33b790fSDamon Ding .axi_yrgb_id = 6, 4695a33b790fSDamon Ding .axi_uv_id = 7, 4696b6ba80b4SDamon Ding .pd_id = VOP2_PD_CLUSTER3, 46975fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 46985fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 46995fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 47005fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 47014c765862SDamon Ding .max_upscale_factor = 4, 47024c765862SDamon Ding .max_downscale_factor = 4, 4703ecc31b6eSAndy Yan }, 4704ecc31b6eSAndy Yan 4705ecc31b6eSAndy Yan { 4706ecc31b6eSAndy Yan .name = "Esmart0", 4707ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_ESMART0, 4708ee01dbb2SDamon Ding .splice_win_id = ROCKCHIP_VOP2_ESMART1, 4709ecc31b6eSAndy Yan .type = ESMART_LAYER, 4710ecc31b6eSAndy Yan .win_sel_port_offset = 4, 47115fa6e665SDamon Ding .layer_sel_win_id = { 2, 2, 2, 2 }, 4712ecc31b6eSAndy Yan .reg_offset = 0, 4713a33b790fSDamon Ding .axi_id = 0, 4714a33b790fSDamon Ding .axi_yrgb_id = 0x0a, 4715a33b790fSDamon Ding .axi_uv_id = 0x0b, 47165fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 47175fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 47185fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 47195fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 47204c765862SDamon Ding .max_upscale_factor = 8, 47214c765862SDamon Ding .max_downscale_factor = 8, 4722ecc31b6eSAndy Yan }, 4723ecc31b6eSAndy Yan 4724ecc31b6eSAndy Yan { 4725ecc31b6eSAndy Yan .name = "Esmart1", 4726ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_ESMART1, 4727ecc31b6eSAndy Yan .type = ESMART_LAYER, 4728ecc31b6eSAndy Yan .win_sel_port_offset = 5, 47295fa6e665SDamon Ding .layer_sel_win_id = { 3, 3, 3, 3 }, 4730ecc31b6eSAndy Yan .reg_offset = 0x200, 4731a33b790fSDamon Ding .axi_id = 0, 4732a33b790fSDamon Ding .axi_yrgb_id = 0x0c, 4733a33b790fSDamon Ding .axi_uv_id = 0x0d, 4734b6ba80b4SDamon Ding .pd_id = VOP2_PD_ESMART, 47355fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 47365fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 47375fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 47385fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 47394c765862SDamon Ding .max_upscale_factor = 8, 47404c765862SDamon Ding .max_downscale_factor = 8, 4741ecc31b6eSAndy Yan }, 4742ecc31b6eSAndy Yan 4743ecc31b6eSAndy Yan { 4744ecc31b6eSAndy Yan .name = "Esmart2", 4745ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_ESMART2, 4746ee01dbb2SDamon Ding .splice_win_id = ROCKCHIP_VOP2_ESMART3, 4747ecc31b6eSAndy Yan .type = ESMART_LAYER, 4748ecc31b6eSAndy Yan .win_sel_port_offset = 6, 47495fa6e665SDamon Ding .layer_sel_win_id = { 6, 6, 6, 6 }, 4750ecc31b6eSAndy Yan .reg_offset = 0x400, 4751a33b790fSDamon Ding .axi_id = 1, 4752a33b790fSDamon Ding .axi_yrgb_id = 0x0a, 4753a33b790fSDamon Ding .axi_uv_id = 0x0b, 4754b6ba80b4SDamon Ding .pd_id = VOP2_PD_ESMART, 47555fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 47565fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 47575fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 47585fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 47594c765862SDamon Ding .max_upscale_factor = 8, 47604c765862SDamon Ding .max_downscale_factor = 8, 4761ecc31b6eSAndy Yan }, 4762ecc31b6eSAndy Yan 4763ecc31b6eSAndy Yan { 4764ecc31b6eSAndy Yan .name = "Esmart3", 4765ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_ESMART3, 4766ecc31b6eSAndy Yan .type = ESMART_LAYER, 4767ecc31b6eSAndy Yan .win_sel_port_offset = 7, 47685fa6e665SDamon Ding .layer_sel_win_id = { 7, 7, 7, 7 }, 4769ecc31b6eSAndy Yan .reg_offset = 0x600, 4770a33b790fSDamon Ding .axi_id = 1, 4771a33b790fSDamon Ding .axi_yrgb_id = 0x0c, 4772a33b790fSDamon Ding .axi_uv_id = 0x0d, 4773b6ba80b4SDamon Ding .pd_id = VOP2_PD_ESMART, 47745fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 47755fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 47765fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 47775fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 47784c765862SDamon Ding .max_upscale_factor = 8, 47794c765862SDamon Ding .max_downscale_factor = 8, 4780ecc31b6eSAndy Yan }, 4781ecc31b6eSAndy Yan }; 4782ecc31b6eSAndy Yan 478312ee5af0SDamon Ding static struct dsc_error_info dsc_ecw[] = { 478412ee5af0SDamon Ding {0x00000000, "no error detected by DSC encoder"}, 478512ee5af0SDamon Ding {0x0030ffff, "bits per component error"}, 478612ee5af0SDamon Ding {0x0040ffff, "multiple mode error"}, 478712ee5af0SDamon Ding {0x0050ffff, "line buffer depth error"}, 478812ee5af0SDamon Ding {0x0060ffff, "minor version error"}, 478912ee5af0SDamon Ding {0x0070ffff, "picture height error"}, 479012ee5af0SDamon Ding {0x0080ffff, "picture width error"}, 479112ee5af0SDamon Ding {0x0090ffff, "number of slices error"}, 479212ee5af0SDamon Ding {0x00c0ffff, "slice height Error "}, 479312ee5af0SDamon Ding {0x00d0ffff, "slice width error"}, 479412ee5af0SDamon Ding {0x00e0ffff, "second line BPG offset error"}, 479512ee5af0SDamon Ding {0x00f0ffff, "non second line BPG offset error"}, 479612ee5af0SDamon Ding {0x0100ffff, "PPS ID error"}, 479712ee5af0SDamon Ding {0x0110ffff, "bits per pixel (BPP) Error"}, 479812ee5af0SDamon Ding {0x0120ffff, "buffer flow error"}, /* dsc_buffer_flow */ 479912ee5af0SDamon Ding 480012ee5af0SDamon Ding {0x01510001, "slice 0 RC buffer model overflow error"}, 480112ee5af0SDamon Ding {0x01510002, "slice 1 RC buffer model overflow error"}, 480212ee5af0SDamon Ding {0x01510004, "slice 2 RC buffer model overflow error"}, 480312ee5af0SDamon Ding {0x01510008, "slice 3 RC buffer model overflow error"}, 480412ee5af0SDamon Ding {0x01510010, "slice 4 RC buffer model overflow error"}, 480512ee5af0SDamon Ding {0x01510020, "slice 5 RC buffer model overflow error"}, 480612ee5af0SDamon Ding {0x01510040, "slice 6 RC buffer model overflow error"}, 480712ee5af0SDamon Ding {0x01510080, "slice 7 RC buffer model overflow error"}, 480812ee5af0SDamon Ding 480912ee5af0SDamon Ding {0x01610001, "slice 0 RC buffer model underflow error"}, 481012ee5af0SDamon Ding {0x01610002, "slice 1 RC buffer model underflow error"}, 481112ee5af0SDamon Ding {0x01610004, "slice 2 RC buffer model underflow error"}, 481212ee5af0SDamon Ding {0x01610008, "slice 3 RC buffer model underflow error"}, 481312ee5af0SDamon Ding {0x01610010, "slice 4 RC buffer model underflow error"}, 481412ee5af0SDamon Ding {0x01610020, "slice 5 RC buffer model underflow error"}, 481512ee5af0SDamon Ding {0x01610040, "slice 6 RC buffer model underflow error"}, 481612ee5af0SDamon Ding {0x01610080, "slice 7 RC buffer model underflow error"}, 481712ee5af0SDamon Ding 481812ee5af0SDamon Ding {0xffffffff, "unsuccessful RESET cycle status"}, 481912ee5af0SDamon Ding {0x00a0ffff, "ICH full error precision settings error"}, 482012ee5af0SDamon Ding {0x0020ffff, "native mode"}, 482112ee5af0SDamon Ding }; 482212ee5af0SDamon Ding 482312ee5af0SDamon Ding static struct dsc_error_info dsc_buffer_flow[] = { 482412ee5af0SDamon Ding {0x00000000, "rate buffer status"}, 482512ee5af0SDamon Ding {0x00000001, "line buffer status"}, 482612ee5af0SDamon Ding {0x00000002, "decoder model status"}, 482712ee5af0SDamon Ding {0x00000003, "pixel buffer status"}, 482812ee5af0SDamon Ding {0x00000004, "balance fifo buffer status"}, 482912ee5af0SDamon Ding {0x00000005, "syntax element fifo status"}, 483012ee5af0SDamon Ding }; 483112ee5af0SDamon Ding 483212ee5af0SDamon Ding static struct vop2_dsc_data rk3588_dsc_data[] = { 483312ee5af0SDamon Ding { 483412ee5af0SDamon Ding .id = ROCKCHIP_VOP2_DSC_8K, 483512ee5af0SDamon Ding .pd_id = VOP2_PD_DSC_8K, 483612ee5af0SDamon Ding .max_slice_num = 8, 483712ee5af0SDamon Ding .max_linebuf_depth = 11, 4838b61227a3SDamon Ding .min_bits_per_pixel = 8, 483912ee5af0SDamon Ding .dsc_txp_clk_src_name = "dsc_8k_txp_clk_src", 484012ee5af0SDamon Ding .dsc_txp_clk_name = "dsc_8k_txp_clk", 484112ee5af0SDamon Ding .dsc_pxl_clk_name = "dsc_8k_pxl_clk", 484212ee5af0SDamon Ding .dsc_cds_clk_name = "dsc_8k_cds_clk", 484312ee5af0SDamon Ding }, 484412ee5af0SDamon Ding 484512ee5af0SDamon Ding { 484612ee5af0SDamon Ding .id = ROCKCHIP_VOP2_DSC_4K, 484712ee5af0SDamon Ding .pd_id = VOP2_PD_DSC_4K, 484812ee5af0SDamon Ding .max_slice_num = 2, 484912ee5af0SDamon Ding .max_linebuf_depth = 11, 4850b61227a3SDamon Ding .min_bits_per_pixel = 8, 485112ee5af0SDamon Ding .dsc_txp_clk_src_name = "dsc_4k_txp_clk_src", 485212ee5af0SDamon Ding .dsc_txp_clk_name = "dsc_4k_txp_clk", 485312ee5af0SDamon Ding .dsc_pxl_clk_name = "dsc_4k_pxl_clk", 485412ee5af0SDamon Ding .dsc_cds_clk_name = "dsc_4k_cds_clk", 485512ee5af0SDamon Ding }, 485612ee5af0SDamon Ding }; 485712ee5af0SDamon Ding 4858ecc31b6eSAndy Yan static struct vop2_vp_data rk3588_vp_data[4] = { 4859ecc31b6eSAndy Yan { 4860ee01dbb2SDamon Ding .splice_vp_id = 1, 4861ecc31b6eSAndy Yan .feature = VOP_FEATURE_OUTPUT_10BIT, 4862b890760eSAlgea Cao .pre_scan_max_dly = 54, 4863ecc31b6eSAndy Yan .max_dclk = 600000, 4864ecc31b6eSAndy Yan .max_output = {7680, 4320}, 4865ecc31b6eSAndy Yan }, 4866ecc31b6eSAndy Yan { 4867ecc31b6eSAndy Yan .feature = VOP_FEATURE_OUTPUT_10BIT, 4868ee01dbb2SDamon Ding .pre_scan_max_dly = 54, 4869ecc31b6eSAndy Yan .max_dclk = 600000, 4870ecc31b6eSAndy Yan .max_output = {4096, 2304}, 4871ecc31b6eSAndy Yan }, 4872ecc31b6eSAndy Yan { 4873ecc31b6eSAndy Yan .feature = VOP_FEATURE_OUTPUT_10BIT, 4874ecc31b6eSAndy Yan .pre_scan_max_dly = 52, 4875ecc31b6eSAndy Yan .max_dclk = 600000, 4876ecc31b6eSAndy Yan .max_output = {4096, 2304}, 4877ecc31b6eSAndy Yan }, 4878ecc31b6eSAndy Yan { 4879ecc31b6eSAndy Yan .feature = 0, 4880ecc31b6eSAndy Yan .pre_scan_max_dly = 52, 4881ecc31b6eSAndy Yan .max_dclk = 200000, 4882ecc31b6eSAndy Yan .max_output = {1920, 1080}, 4883ecc31b6eSAndy Yan }, 4884ecc31b6eSAndy Yan }; 4885ecc31b6eSAndy Yan 4886b6ba80b4SDamon Ding static struct vop2_power_domain_data rk3588_vop_pd_data[] = { 4887b6ba80b4SDamon Ding { 4888b6ba80b4SDamon Ding .id = VOP2_PD_CLUSTER0, 4889b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER0), 4890b6ba80b4SDamon Ding }, 4891b6ba80b4SDamon Ding { 4892b6ba80b4SDamon Ding .id = VOP2_PD_CLUSTER1, 4893b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER1), 4894b6ba80b4SDamon Ding .parent_id = VOP2_PD_CLUSTER0, 4895b6ba80b4SDamon Ding }, 4896b6ba80b4SDamon Ding { 4897b6ba80b4SDamon Ding .id = VOP2_PD_CLUSTER2, 4898b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER2), 4899b6ba80b4SDamon Ding .parent_id = VOP2_PD_CLUSTER0, 4900b6ba80b4SDamon Ding }, 4901b6ba80b4SDamon Ding { 4902b6ba80b4SDamon Ding .id = VOP2_PD_CLUSTER3, 4903b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER3), 4904b6ba80b4SDamon Ding .parent_id = VOP2_PD_CLUSTER0, 4905b6ba80b4SDamon Ding }, 4906b6ba80b4SDamon Ding { 4907b6ba80b4SDamon Ding .id = VOP2_PD_ESMART, 4908b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_ESMART1) | 4909b6ba80b4SDamon Ding BIT(ROCKCHIP_VOP2_ESMART2) | 4910b6ba80b4SDamon Ding BIT(ROCKCHIP_VOP2_ESMART3), 4911b6ba80b4SDamon Ding }, 4912b6ba80b4SDamon Ding { 4913b6ba80b4SDamon Ding .id = VOP2_PD_DSC_8K, 4914b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_8K), 4915b6ba80b4SDamon Ding }, 4916b6ba80b4SDamon Ding { 4917b6ba80b4SDamon Ding .id = VOP2_PD_DSC_4K, 4918b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_4K), 4919b6ba80b4SDamon Ding }, 4920b6ba80b4SDamon Ding }; 4921b6ba80b4SDamon Ding 4922ecc31b6eSAndy Yan const struct vop2_data rk3588_vop = { 4923ecc31b6eSAndy Yan .version = VOP_VERSION_RK3588, 4924ecc31b6eSAndy Yan .nr_vps = 4, 4925ecc31b6eSAndy Yan .vp_data = rk3588_vp_data, 4926ecc31b6eSAndy Yan .win_data = rk3588_win_data, 4927ecc31b6eSAndy Yan .plane_mask = rk3588_vp_plane_mask[0], 4928ecc31b6eSAndy Yan .plane_table = rk3588_plane_table, 4929b6ba80b4SDamon Ding .pd = rk3588_vop_pd_data, 493012ee5af0SDamon Ding .dsc = rk3588_dsc_data, 493112ee5af0SDamon Ding .dsc_error_ecw = dsc_ecw, 493212ee5af0SDamon Ding .dsc_error_buffer_flow = dsc_buffer_flow, 4933337d1c13SDamon Ding .vp_primary_plane_order = rk3588_vp_primary_plane_order, 4934ecc31b6eSAndy Yan .nr_layers = 8, 4935ecc31b6eSAndy Yan .nr_mixers = 7, 4936ecc31b6eSAndy Yan .nr_gammas = 4, 4937b6ba80b4SDamon Ding .nr_pd = ARRAY_SIZE(rk3588_vop_pd_data), 493812ee5af0SDamon Ding .nr_dscs = 2, 493912ee5af0SDamon Ding .nr_dsc_ecw = ARRAY_SIZE(dsc_ecw), 494012ee5af0SDamon Ding .nr_dsc_buffer_flow = ARRAY_SIZE(dsc_buffer_flow), 4941ecc31b6eSAndy Yan }; 4942ecc31b6eSAndy Yan 4943d0408543SAndy Yan const struct rockchip_crtc_funcs rockchip_vop2_funcs = { 4944d0408543SAndy Yan .preinit = rockchip_vop2_preinit, 4945d0408543SAndy Yan .prepare = rockchip_vop2_prepare, 4946d0408543SAndy Yan .init = rockchip_vop2_init, 4947d0408543SAndy Yan .set_plane = rockchip_vop2_set_plane, 4948d0408543SAndy Yan .enable = rockchip_vop2_enable, 4949d0408543SAndy Yan .disable = rockchip_vop2_disable, 4950b0989546SSandy Huang .fixup_dts = rockchip_vop2_fixup_dts, 4951820a5c17SDamon Ding .check = rockchip_vop2_check, 495222007755SDamon Ding .mode_valid = rockchip_vop2_mode_valid, 49534c765862SDamon Ding .plane_check = rockchip_vop2_plane_check, 4954d0408543SAndy Yan }; 4955