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 <asm/arch/clock.h> 218e7ef808SDamon Ding #include <asm/gpio.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> 31452afb13SDamon Ding #include <stdlib.h> 32d0408543SAndy Yan 33d0408543SAndy Yan #include "rockchip_display.h" 34d0408543SAndy Yan #include "rockchip_crtc.h" 35d0408543SAndy Yan #include "rockchip_connector.h" 36d8e7f4a5SSandy Huang #include "rockchip_phy.h" 376027c871SZhang Yubing #include "rockchip_post_csc.h" 38d0408543SAndy Yan 39d0408543SAndy Yan /* System registers definition */ 40d0408543SAndy Yan #define RK3568_REG_CFG_DONE 0x000 41d0408543SAndy Yan #define CFG_DONE_EN BIT(15) 42d0408543SAndy Yan 43d0408543SAndy Yan #define RK3568_VERSION_INFO 0x004 44d0408543SAndy Yan #define EN_MASK 1 45d0408543SAndy Yan 4663cb669fSSandy Huang #define RK3568_AUTO_GATING_CTRL 0x008 470675a2a4SDamon Ding #define AUTO_GATING_EN_SHIFT 31 480675a2a4SDamon Ding #define PORT_DCLK_AUTO_GATING_EN_SHIFT 14 4963cb669fSSandy Huang 50a552a69cSDamon Ding #define RK3576_SYS_MMU_CTRL 0x020 51a552a69cSDamon Ding #define RKMMU_V2_EN_SHIFT 0 52a552a69cSDamon Ding #define RKMMU_V2_SEL_AXI_SHIFT 1 53a552a69cSDamon Ding 546414e3bcSSandy Huang #define RK3568_SYS_AXI_LUT_CTRL 0x024 556414e3bcSSandy Huang #define LUT_DMA_EN_SHIFT 0 56aa670293SDamon Ding #define DSP_VS_T_SEL_SHIFT 16 576414e3bcSSandy Huang 58d0408543SAndy Yan #define RK3568_DSP_IF_EN 0x028 59d0408543SAndy Yan #define RGB_EN_SHIFT 0 60ecc31b6eSAndy Yan #define RK3588_DP0_EN_SHIFT 0 61ecc31b6eSAndy Yan #define RK3588_DP1_EN_SHIFT 1 62ecc31b6eSAndy Yan #define RK3588_RGB_EN_SHIFT 8 63d0408543SAndy Yan #define HDMI0_EN_SHIFT 1 64d0408543SAndy Yan #define EDP0_EN_SHIFT 3 65ecc31b6eSAndy Yan #define RK3588_EDP0_EN_SHIFT 2 66ecc31b6eSAndy Yan #define RK3588_HDMI0_EN_SHIFT 3 67d0408543SAndy Yan #define MIPI0_EN_SHIFT 4 68ecc31b6eSAndy Yan #define RK3588_EDP1_EN_SHIFT 4 69ecc31b6eSAndy Yan #define RK3588_HDMI1_EN_SHIFT 5 70ecc31b6eSAndy Yan #define RK3588_MIPI0_EN_SHIFT 6 71d0408543SAndy Yan #define MIPI1_EN_SHIFT 20 72ecc31b6eSAndy Yan #define RK3588_MIPI1_EN_SHIFT 7 73d0408543SAndy Yan #define LVDS0_EN_SHIFT 5 74d0408543SAndy Yan #define LVDS1_EN_SHIFT 24 75d0408543SAndy Yan #define BT1120_EN_SHIFT 6 76d0408543SAndy Yan #define BT656_EN_SHIFT 7 77d0408543SAndy Yan #define IF_MUX_MASK 3 78d0408543SAndy Yan #define RGB_MUX_SHIFT 8 79d0408543SAndy Yan #define HDMI0_MUX_SHIFT 10 80ecc31b6eSAndy Yan #define RK3588_DP0_MUX_SHIFT 12 81ecc31b6eSAndy Yan #define RK3588_DP1_MUX_SHIFT 14 82d0408543SAndy Yan #define EDP0_MUX_SHIFT 14 83ecc31b6eSAndy Yan #define RK3588_HDMI_EDP0_MUX_SHIFT 16 84ecc31b6eSAndy Yan #define RK3588_HDMI_EDP1_MUX_SHIFT 18 85d0408543SAndy Yan #define MIPI0_MUX_SHIFT 16 86ecc31b6eSAndy Yan #define RK3588_MIPI0_MUX_SHIFT 20 87d0408543SAndy Yan #define MIPI1_MUX_SHIFT 21 8811f53190SSandy Huang #define LVDS0_MUX_SHIFT 18 89d0408543SAndy Yan #define LVDS1_MUX_SHIFT 25 90d0408543SAndy Yan 91a552a69cSDamon Ding #define RK3576_SYS_PORT_CTRL 0x028 92a552a69cSDamon Ding #define VP_INTR_MERGE_EN_SHIFT 14 93a552a69cSDamon Ding #define INTERLACE_FRM_REG_DONE_MASK 0x7 94a552a69cSDamon Ding #define INTERLACE_FRM_REG_DONE_SHIFT 0 95a552a69cSDamon Ding 96d0408543SAndy Yan #define RK3568_DSP_IF_CTRL 0x02c 97d0408543SAndy Yan #define LVDS_DUAL_EN_SHIFT 0 985d2768f7SDamon Ding #define RK3588_BT656_UV_SWAP_SHIFT 0 99d0408543SAndy Yan #define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT 1 1005d2768f7SDamon Ding #define RK3588_BT656_YC_SWAP_SHIFT 1 101d0408543SAndy Yan #define LVDS_DUAL_SWAP_EN_SHIFT 2 1025fa6e665SDamon Ding #define BT656_UV_SWAP 4 1035d2768f7SDamon Ding #define RK3588_BT1120_UV_SWAP_SHIFT 4 1045fa6e665SDamon Ding #define BT656_YC_SWAP 5 1055d2768f7SDamon Ding #define RK3588_BT1120_YC_SWAP_SHIFT 5 1065fa6e665SDamon Ding #define BT656_DCLK_POL 6 1070a1fb152SZhang Yubing #define RK3588_HDMI_DUAL_EN_SHIFT 8 1080a1fb152SZhang Yubing #define RK3588_EDP_DUAL_EN_SHIFT 8 1090a1fb152SZhang Yubing #define RK3588_DP_DUAL_EN_SHIFT 9 11041874944SGuochun Huang #define RK3568_MIPI_DUAL_EN_SHIFT 10 11141874944SGuochun Huang #define RK3588_MIPI_DSI0_MODE_SEL_SHIFT 11 11241874944SGuochun Huang #define RK3588_MIPI_DSI1_MODE_SEL_SHIFT 12 11341874944SGuochun Huang 114d0408543SAndy Yan #define RK3568_DSP_IF_POL 0x030 115d0408543SAndy Yan #define IF_CTRL_REG_DONE_IMD_SHIFT 28 116d0408543SAndy Yan #define IF_CRTL_MIPI_DCLK_POL_SHIT 19 117d0408543SAndy Yan #define IF_CRTL_EDP_DCLK_POL_SHIT 15 1187bcdc6eeSDamon Ding #define IF_CTRL_EDP_PIN_POL_MASK 0x7 1197bcdc6eeSDamon Ding #define IF_CTRL_EDP_PIN_POL_SHIFT 12 120d0408543SAndy Yan #define IF_CRTL_HDMI_DCLK_POL_SHIT 7 12110ee9f5bSAlgea Cao #define IF_CRTL_HDMI_PIN_POL_MASK 0x7 12210ee9f5bSAlgea Cao #define IF_CRTL_HDMI_PIN_POL_SHIT 4 12315f69071SDamon Ding #define IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT 3 12415f69071SDamon Ding #define IF_CTRL_RGB_LVDS_PIN_POL_MASK 0x7 12515f69071SDamon Ding #define IF_CTRL_RGB_LVDS_PIN_POL_SHIFT 0 126ecc31b6eSAndy Yan 127452afb13SDamon Ding #define RK3562_MIPI_DCLK_POL_SHIFT 15 128452afb13SDamon Ding #define RK3562_MIPI_PIN_POL_SHIFT 12 129452afb13SDamon Ding #define RK3562_IF_PIN_POL_MASK 0x7 130452afb13SDamon Ding 131ecc31b6eSAndy Yan #define RK3588_DP0_PIN_POL_SHIFT 8 132ecc31b6eSAndy Yan #define RK3588_DP1_PIN_POL_SHIFT 12 133ecc31b6eSAndy Yan #define RK3588_IF_PIN_POL_MASK 0x7 134ecc31b6eSAndy Yan 135ecc31b6eSAndy Yan #define HDMI_EDP0_DCLK_DIV_SHIFT 16 136ecc31b6eSAndy Yan #define HDMI_EDP0_PIXCLK_DIV_SHIFT 18 137ecc31b6eSAndy Yan #define HDMI_EDP1_DCLK_DIV_SHIFT 20 138ecc31b6eSAndy Yan #define HDMI_EDP1_PIXCLK_DIV_SHIFT 22 139ecc31b6eSAndy Yan #define MIPI0_PIXCLK_DIV_SHIFT 24 140ecc31b6eSAndy Yan #define MIPI1_PIXCLK_DIV_SHIFT 26 141ecc31b6eSAndy Yan 142a552a69cSDamon Ding #define RK3576_SYS_CLUSTER_PD_CTRL 0x030 143a552a69cSDamon Ding #define RK3576_CLUSTER_PD_EN_SHIFT 0 144a552a69cSDamon Ding 145a552a69cSDamon Ding #define RK3588_SYS_PD_CTRL 0x034 146a552a69cSDamon Ding #define RK3588_CLUSTER0_PD_EN_SHIFT 0 147a552a69cSDamon Ding #define RK3588_CLUSTER1_PD_EN_SHIFT 1 148a552a69cSDamon Ding #define RK3588_CLUSTER2_PD_EN_SHIFT 2 149a552a69cSDamon Ding #define RK3588_CLUSTER3_PD_EN_SHIFT 3 150a552a69cSDamon Ding #define RK3588_DSC_8K_PD_EN_SHIFT 5 151a552a69cSDamon Ding #define RK3588_DSC_4K_PD_EN_SHIFT 6 152a552a69cSDamon Ding #define RK3588_ESMART_PD_EN_SHIFT 7 153a552a69cSDamon Ding 154a552a69cSDamon Ding #define RK3576_SYS_ESMART_PD_CTRL 0x034 155a552a69cSDamon Ding #define RK3576_ESMART_PD_EN_SHIFT 0 156a552a69cSDamon Ding #define RK3576_ESMART_LB_MODE_SEL_SHIFT 6 157a552a69cSDamon Ding #define RK3576_ESMART_LB_MODE_SEL_MASK 0x3 158a552a69cSDamon Ding 159feffd38eSSandy Huang #define RK3568_SYS_OTP_WIN_EN 0x50 160feffd38eSSandy Huang #define OTP_WIN_EN_SHIFT 0 1611147facaSSandy Huang #define RK3568_SYS_LUT_PORT_SEL 0x58 1621147facaSSandy Huang #define GAMMA_PORT_SEL_MASK 0x3 1631147facaSSandy Huang #define GAMMA_PORT_SEL_SHIFT 0 164db328a0dSDamon Ding #define GAMMA_AHB_WRITE_SEL_MASK 0x3 165db328a0dSDamon Ding #define GAMMA_AHB_WRITE_SEL_SHIFT 12 166ee01dbb2SDamon Ding #define PORT_MERGE_EN_SHIFT 16 1675fa6e665SDamon Ding #define ESMART_LB_MODE_SEL_MASK 0x3 1685fa6e665SDamon Ding #define ESMART_LB_MODE_SEL_SHIFT 26 1691147facaSSandy Huang 170d0408543SAndy Yan #define RK3568_VP0_LINE_FLAG 0x70 171d0408543SAndy Yan #define RK3568_VP1_LINE_FLAG 0x74 172d0408543SAndy Yan #define RK3568_VP2_LINE_FLAG 0x78 173d0408543SAndy Yan #define RK3568_SYS0_INT_EN 0x80 174d0408543SAndy Yan #define RK3568_SYS0_INT_CLR 0x84 175d0408543SAndy Yan #define RK3568_SYS0_INT_STATUS 0x88 176d0408543SAndy Yan #define RK3568_SYS1_INT_EN 0x90 177d0408543SAndy Yan #define RK3568_SYS1_INT_CLR 0x94 178d0408543SAndy Yan #define RK3568_SYS1_INT_STATUS 0x98 179d0408543SAndy Yan #define RK3568_VP0_INT_EN 0xA0 180d0408543SAndy Yan #define RK3568_VP0_INT_CLR 0xA4 181d0408543SAndy Yan #define RK3568_VP0_INT_STATUS 0xA8 182d0408543SAndy Yan #define RK3568_VP1_INT_EN 0xB0 183d0408543SAndy Yan #define RK3568_VP1_INT_CLR 0xB4 184d0408543SAndy Yan #define RK3568_VP1_INT_STATUS 0xB8 185d0408543SAndy Yan #define RK3568_VP2_INT_EN 0xC0 186d0408543SAndy Yan #define RK3568_VP2_INT_CLR 0xC4 187d0408543SAndy Yan #define RK3568_VP2_INT_STATUS 0xC8 188a552a69cSDamon Ding #define RK3568_VP2_INT_RAW_STATUS 0xCC 189a552a69cSDamon Ding #define RK3588_VP3_INT_EN 0xD0 190a552a69cSDamon Ding #define RK3588_VP3_INT_CLR 0xD4 191a552a69cSDamon Ding #define RK3588_VP3_INT_STATUS 0xD8 192a552a69cSDamon Ding #define RK3576_WB_CTRL 0x100 193a552a69cSDamon Ding #define RK3576_WB_XSCAL_FACTOR 0x104 194a552a69cSDamon Ding #define RK3576_WB_YRGB_MST 0x108 195a552a69cSDamon Ding #define RK3576_WB_CBR_MST 0x10C 196a552a69cSDamon Ding #define RK3576_WB_VIR_STRIDE 0x110 197a552a69cSDamon Ding #define RK3576_WB_TIMEOUT_CTRL 0x114 198a552a69cSDamon Ding #define RK3576_MIPI0_IF_CTRL 0x180 199a552a69cSDamon Ding #define RK3576_IF_OUT_EN_SHIFT 0 200a552a69cSDamon Ding #define RK3576_IF_CLK_OUT_EN_SHIFT 1 201a552a69cSDamon Ding #define RK3576_IF_PORT_SEL_SHIFT 2 202a552a69cSDamon Ding #define RK3576_IF_PORT_SEL_MASK 0x3 203a552a69cSDamon Ding #define RK3576_IF_PIN_POL_SHIFT 4 204a552a69cSDamon Ding #define RK3576_IF_PIN_POL_MASK 0x7 205a552a69cSDamon Ding #define RK3576_IF_SPLIT_EN_SHIFT 8 206a552a69cSDamon Ding #define RK3576_IF_DATA1_SEL_SHIFT 9 207a552a69cSDamon Ding #define RK3576_MIPI_CMD_MODE_SHIFT 11 208a552a69cSDamon Ding #define RK3576_IF_DCLK_SEL_SHIFT 21 209a552a69cSDamon Ding #define RK3576_IF_DCLK_SEL_MASK 0x1 210a552a69cSDamon Ding #define RK3576_IF_PIX_CLK_SEL_SHIFT 20 211a552a69cSDamon Ding #define RK3576_IF_PIX_CLK_SEL_MASK 0x1 212a552a69cSDamon Ding #define RK3576_IF_REGDONE_IMD_EN_SHIFT 31 213a552a69cSDamon Ding #define RK3576_HDMI0_IF_CTRL 0x184 214a552a69cSDamon Ding #define RK3576_EDP0_IF_CTRL 0x188 215a552a69cSDamon Ding #define RK3576_DP0_IF_CTRL 0x18C 216a552a69cSDamon Ding #define RK3576_RGB_IF_CTRL 0x194 217a552a69cSDamon Ding #define RK3576_BT656_OUT_EN_SHIFT 12 218a552a69cSDamon Ding #define RK3576_BT656_UV_SWAP_SHIFT 13 219a552a69cSDamon Ding #define RK3576_BT656_YC_SWAP_SHIFT 14 220a552a69cSDamon Ding #define RK3576_BT1120_OUT_EN_SHIFT 16 221a552a69cSDamon Ding #define RK3576_BT1120_UV_SWAP_SHIFT 17 222a552a69cSDamon Ding #define RK3576_BT1120_YC_SWAP_SHIFT 18 223a552a69cSDamon Ding #define RK3576_DP1_IF_CTRL 0x1A4 224a552a69cSDamon Ding #define RK3576_DP2_IF_CTRL 0x1B0 22560e469f5SDamon Ding 226cd6c85a9SDamon Ding #define RK3588_SYS_VAR_FREQ_CTRL 0x038 227cd6c85a9SDamon Ding #define RK3588_VP0_LINE_FLAG_OR_EN_SHIFT 20 228cd6c85a9SDamon Ding #define RK3588_VP0_DSP_HOLD_OR_EN_SHIFT 24 229cd6c85a9SDamon Ding #define RK3588_VP0_ALMOST_FULL_OR_EN_SHIFT 28 230cd6c85a9SDamon Ding 23160e469f5SDamon Ding #define RK3568_SYS_STATUS0 0x60 23260e469f5SDamon Ding #define RK3588_CLUSTER0_PD_STATUS_SHIFT 8 23360e469f5SDamon Ding #define RK3588_CLUSTER1_PD_STATUS_SHIFT 9 23460e469f5SDamon Ding #define RK3588_CLUSTER2_PD_STATUS_SHIFT 10 23560e469f5SDamon Ding #define RK3588_CLUSTER3_PD_STATUS_SHIFT 11 236b6ba80b4SDamon Ding #define RK3588_DSC_8K_PD_STATUS_SHIFT 13 237b6ba80b4SDamon Ding #define RK3588_DSC_4K_PD_STATUS_SHIFT 14 23860e469f5SDamon Ding #define RK3588_ESMART_PD_STATUS_SHIFT 15 239d0408543SAndy Yan 24066724b9cSDamon Ding #define RK3568_SYS_CTRL_LINE_FLAG0 0x70 24166724b9cSDamon Ding #define LINE_FLAG_NUM_MASK 0x1fff 24266724b9cSDamon Ding #define RK3568_DSP_LINE_FLAG_NUM0_SHIFT 0 24366724b9cSDamon Ding #define RK3568_DSP_LINE_FLAG_NUM1_SHIFT 16 24466724b9cSDamon Ding 24512ee5af0SDamon Ding /* DSC CTRL registers definition */ 24612ee5af0SDamon Ding #define RK3588_DSC_8K_SYS_CTRL 0x200 24712ee5af0SDamon Ding #define DSC_PORT_SEL_MASK 0x3 24812ee5af0SDamon Ding #define DSC_PORT_SEL_SHIFT 0 24912ee5af0SDamon Ding #define DSC_MAN_MODE_MASK 0x1 25012ee5af0SDamon Ding #define DSC_MAN_MODE_SHIFT 2 25112ee5af0SDamon Ding #define DSC_INTERFACE_MODE_MASK 0x3 25212ee5af0SDamon Ding #define DSC_INTERFACE_MODE_SHIFT 4 25312ee5af0SDamon Ding #define DSC_PIXEL_NUM_MASK 0x3 25412ee5af0SDamon Ding #define DSC_PIXEL_NUM_SHIFT 6 25512ee5af0SDamon Ding #define DSC_PXL_CLK_DIV_MASK 0x1 25612ee5af0SDamon Ding #define DSC_PXL_CLK_DIV_SHIFT 8 25712ee5af0SDamon Ding #define DSC_CDS_CLK_DIV_MASK 0x3 25812ee5af0SDamon Ding #define DSC_CDS_CLK_DIV_SHIFT 12 25912ee5af0SDamon Ding #define DSC_TXP_CLK_DIV_MASK 0x3 26012ee5af0SDamon Ding #define DSC_TXP_CLK_DIV_SHIFT 14 26112ee5af0SDamon Ding #define DSC_INIT_DLY_MODE_MASK 0x1 26212ee5af0SDamon Ding #define DSC_INIT_DLY_MODE_SHIFT 16 26312ee5af0SDamon Ding #define DSC_SCAN_EN_SHIFT 17 26412ee5af0SDamon Ding #define DSC_HALT_EN_SHIFT 18 26512ee5af0SDamon Ding 26612ee5af0SDamon Ding #define RK3588_DSC_8K_RST 0x204 26712ee5af0SDamon Ding #define RST_DEASSERT_MASK 0x1 26812ee5af0SDamon Ding #define RST_DEASSERT_SHIFT 0 26912ee5af0SDamon Ding 27012ee5af0SDamon Ding #define RK3588_DSC_8K_CFG_DONE 0x208 27112ee5af0SDamon Ding #define DSC_CFG_DONE_SHIFT 0 27212ee5af0SDamon Ding 27312ee5af0SDamon Ding #define RK3588_DSC_8K_INIT_DLY 0x20C 27412ee5af0SDamon Ding #define DSC_INIT_DLY_NUM_MASK 0xffff 27512ee5af0SDamon Ding #define DSC_INIT_DLY_NUM_SHIFT 0 27612ee5af0SDamon Ding #define SCAN_TIMING_PARA_IMD_EN_SHIFT 16 27712ee5af0SDamon Ding 27812ee5af0SDamon Ding #define RK3588_DSC_8K_HTOTAL_HS_END 0x210 27912ee5af0SDamon Ding #define DSC_HTOTAL_PW_MASK 0xffffffff 28012ee5af0SDamon Ding #define DSC_HTOTAL_PW_SHIFT 0 28112ee5af0SDamon Ding 28212ee5af0SDamon Ding #define RK3588_DSC_8K_HACT_ST_END 0x214 28312ee5af0SDamon Ding #define DSC_HACT_ST_END_MASK 0xffffffff 28412ee5af0SDamon Ding #define DSC_HACT_ST_END_SHIFT 0 28512ee5af0SDamon Ding 28612ee5af0SDamon Ding #define RK3588_DSC_8K_VTOTAL_VS_END 0x218 28712ee5af0SDamon Ding #define DSC_VTOTAL_PW_MASK 0xffffffff 28812ee5af0SDamon Ding #define DSC_VTOTAL_PW_SHIFT 0 28912ee5af0SDamon Ding 29012ee5af0SDamon Ding #define RK3588_DSC_8K_VACT_ST_END 0x21C 29112ee5af0SDamon Ding #define DSC_VACT_ST_END_MASK 0xffffffff 29212ee5af0SDamon Ding #define DSC_VACT_ST_END_SHIFT 0 29312ee5af0SDamon Ding 29412ee5af0SDamon Ding #define RK3588_DSC_8K_STATUS 0x220 29512ee5af0SDamon Ding 29663cb669fSSandy Huang /* Overlay registers definition */ 2975fa6e665SDamon Ding #define RK3528_OVL_SYS 0x500 298a552a69cSDamon Ding #define RK3528_OVL_SYS_PORT_SEL 0x504 299a552a69cSDamon Ding #define RK3528_OVL_SYS_GATING_EN 0x508 3005fa6e665SDamon Ding #define RK3528_OVL_SYS_CLUSTER0_CTRL 0x510 3015fa6e665SDamon Ding #define RK3528_OVL_SYS_ESMART0_CTRL 0x520 302452afb13SDamon Ding #define ESMART_DLY_NUM_MASK 0xff 303452afb13SDamon Ding #define ESMART_DLY_NUM_SHIFT 0 3045fa6e665SDamon Ding #define RK3528_OVL_SYS_ESMART1_CTRL 0x524 3055fa6e665SDamon Ding #define RK3528_OVL_SYS_ESMART2_CTRL 0x528 3065fa6e665SDamon Ding #define RK3528_OVL_SYS_ESMART3_CTRL 0x52C 3075fa6e665SDamon Ding #define RK3528_CLUSTER0_MIX_SRC_COLOR_CTRL 0x530 3085fa6e665SDamon Ding #define RK3528_CLUSTER0_MIX_DST_COLOR_CTRL 0x534 3095fa6e665SDamon Ding #define RK3528_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x538 3105fa6e665SDamon Ding #define RK3528_CLUSTER0_MIX_DST_ALPHA_CTRL 0x53c 311a552a69cSDamon Ding #define RK3576_CLUSTER1_MIX_SRC_COLOR_CTRL 0x540 312a552a69cSDamon Ding #define RK3576_CLUSTER1_MIX_DST_COLOR_CTRL 0x544 313a552a69cSDamon Ding #define RK3576_CLUSTER1_MIX_SRC_ALPHA_CTRL 0x548 314a552a69cSDamon Ding #define RK3576_CLUSTER1_MIX_DST_ALPHA_CTRL 0x54c 3155fa6e665SDamon Ding 3165fa6e665SDamon Ding #define RK3528_OVL_PORT0_CTRL 0x600 31763cb669fSSandy Huang #define RK3568_OVL_CTRL 0x600 318ee01dbb2SDamon Ding #define OVL_MODE_SEL_MASK 0x1 319ee01dbb2SDamon Ding #define OVL_MODE_SEL_SHIFT 0 32063cb669fSSandy Huang #define OVL_PORT_MUX_REG_DONE_IMD_SHIFT 28 3215fa6e665SDamon Ding #define RK3528_OVL_PORT0_LAYER_SEL 0x604 32263cb669fSSandy Huang #define RK3568_OVL_LAYER_SEL 0x604 32363cb669fSSandy Huang #define LAYER_SEL_MASK 0xf 32463cb669fSSandy Huang 32563cb669fSSandy Huang #define RK3568_OVL_PORT_SEL 0x608 32663cb669fSSandy Huang #define PORT_MUX_MASK 0xf 32763cb669fSSandy Huang #define PORT_MUX_SHIFT 0 32863cb669fSSandy Huang #define LAYER_SEL_PORT_MASK 0x3 32963cb669fSSandy Huang #define LAYER_SEL_PORT_SHIFT 16 33063cb669fSSandy Huang 33163cb669fSSandy Huang #define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL 0x610 33263cb669fSSandy Huang #define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL 0x614 33363cb669fSSandy Huang #define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x618 33463cb669fSSandy Huang #define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL 0x61C 3355fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX0_SRC_COLOR_CTRL 0x620 3365fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX0_DST_COLOR_CTRL 0x624 3375fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX0_SRC_ALPHA_CTRL 0x628 3385fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX0_DST_ALPHA_CTRL 0x62C 3395fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX1_SRC_COLOR_CTRL 0x630 3405fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX1_DST_COLOR_CTRL 0x634 3415fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX1_SRC_ALPHA_CTRL 0x638 3425fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX1_DST_ALPHA_CTRL 0x63C 3435fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX2_SRC_COLOR_CTRL 0x640 3445fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX2_DST_COLOR_CTRL 0x644 3455fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX2_SRC_ALPHA_CTRL 0x648 3465fa6e665SDamon Ding #define RK3528_OVL_PORT0_MIX2_DST_ALPHA_CTRL 0x64C 34763cb669fSSandy Huang #define RK3568_MIX0_SRC_COLOR_CTRL 0x650 34863cb669fSSandy Huang #define RK3568_MIX0_DST_COLOR_CTRL 0x654 34963cb669fSSandy Huang #define RK3568_MIX0_SRC_ALPHA_CTRL 0x658 35063cb669fSSandy Huang #define RK3568_MIX0_DST_ALPHA_CTRL 0x65C 351a552a69cSDamon Ding #define RK3576_EXTRA_SRC_COLOR_CTRL 0x650 352a552a69cSDamon Ding #define RK3576_EXTRA_DST_COLOR_CTRL 0x654 353a552a69cSDamon Ding #define RK3576_EXTRA_SRC_ALPHA_CTRL 0x658 354a552a69cSDamon Ding #define RK3576_EXTRA_DST_ALPHA_CTRL 0x65C 3555fa6e665SDamon Ding #define RK3528_HDR_SRC_COLOR_CTRL 0x660 3565fa6e665SDamon Ding #define RK3528_HDR_DST_COLOR_CTRL 0x664 3575fa6e665SDamon Ding #define RK3528_HDR_SRC_ALPHA_CTRL 0x668 3585fa6e665SDamon Ding #define RK3528_HDR_DST_ALPHA_CTRL 0x66C 3595fa6e665SDamon Ding #define RK3528_OVL_PORT0_BG_MIX_CTRL 0x670 36063cb669fSSandy Huang #define RK3568_HDR0_SRC_COLOR_CTRL 0x6C0 36163cb669fSSandy Huang #define RK3568_HDR0_DST_COLOR_CTRL 0x6C4 36263cb669fSSandy Huang #define RK3568_HDR0_SRC_ALPHA_CTRL 0x6C8 36363cb669fSSandy Huang #define RK3568_HDR0_DST_ALPHA_CTRL 0x6CC 36463cb669fSSandy Huang #define RK3568_VP0_BG_MIX_CTRL 0x6E0 36563cb669fSSandy Huang #define BG_MIX_CTRL_MASK 0xff 36663cb669fSSandy Huang #define BG_MIX_CTRL_SHIFT 24 36763cb669fSSandy Huang #define RK3568_VP1_BG_MIX_CTRL 0x6E4 36863cb669fSSandy Huang #define RK3568_VP2_BG_MIX_CTRL 0x6E8 36963cb669fSSandy Huang #define RK3568_CLUSTER_DLY_NUM 0x6F0 37063cb669fSSandy Huang #define RK3568_SMART_DLY_NUM 0x6F8 37163cb669fSSandy Huang 3725fa6e665SDamon Ding #define RK3528_OVL_PORT1_CTRL 0x700 3735fa6e665SDamon Ding #define RK3528_OVL_PORT1_LAYER_SEL 0x704 3745fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX0_SRC_COLOR_CTRL 0x720 3755fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX0_DST_COLOR_CTRL 0x724 3765fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX0_SRC_ALPHA_CTRL 0x728 3775fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX0_DST_ALPHA_CTRL 0x72C 3785fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX1_SRC_COLOR_CTRL 0x730 3795fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX1_DST_COLOR_CTRL 0x734 3805fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX1_SRC_ALPHA_CTRL 0x738 3815fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX1_DST_ALPHA_CTRL 0x73C 3825fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX2_SRC_COLOR_CTRL 0x740 3835fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX2_DST_COLOR_CTRL 0x744 3845fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX2_SRC_ALPHA_CTRL 0x748 3855fa6e665SDamon Ding #define RK3528_OVL_PORT1_MIX2_DST_ALPHA_CTRL 0x74C 3865fa6e665SDamon Ding #define RK3528_OVL_PORT1_BG_MIX_CTRL 0x770 387a552a69cSDamon Ding #define RK3576_OVL_PORT2_CTRL 0x800 388a552a69cSDamon Ding #define RK3576_OVL_PORT2_LAYER_SEL 0x804 389a552a69cSDamon Ding #define RK3576_OVL_PORT2_MIX0_SRC_COLOR_CTRL 0x820 390a552a69cSDamon Ding #define RK3576_OVL_PORT2_MIX0_DST_COLOR_CTRL 0x824 391a552a69cSDamon Ding #define RK3576_OVL_PORT2_MIX0_SRC_ALPHA_CTRL 0x828 392a552a69cSDamon Ding #define RK3576_OVL_PORT2_MIX0_DST_ALPHA_CTRL 0x82C 393a552a69cSDamon Ding #define RK3576_OVL_PORT2_BG_MIX_CTRL 0x870 3945fa6e665SDamon Ding 395d0408543SAndy Yan /* Video Port registers definition */ 396d0408543SAndy Yan #define RK3568_VP0_DSP_CTRL 0xC00 397d0408543SAndy Yan #define OUT_MODE_MASK 0xf 398d0408543SAndy Yan #define OUT_MODE_SHIFT 0 39910ee9f5bSAlgea Cao #define DATA_SWAP_MASK 0x1f 40010ee9f5bSAlgea Cao #define DATA_SWAP_SHIFT 8 40165747de7SDamon Ding #define DSP_BG_SWAP 0x1 40265747de7SDamon Ding #define DSP_RB_SWAP 0x2 40365747de7SDamon Ding #define DSP_RG_SWAP 0x4 40465747de7SDamon Ding #define DSP_DELTA_SWAP 0x8 40510ee9f5bSAlgea Cao #define CORE_DCLK_DIV_EN_SHIFT 4 406d0408543SAndy Yan #define P2I_EN_SHIFT 5 4077a20be36SSandy Huang #define DSP_FILED_POL 6 408d0408543SAndy Yan #define INTERLACE_EN_SHIFT 7 409c2b1fe35SDamon Ding #define DSP_X_MIR_EN_SHIFT 13 41010ee9f5bSAlgea Cao #define POST_DSP_OUT_R2Y_SHIFT 15 411d0408543SAndy Yan #define PRE_DITHER_DOWN_EN_SHIFT 16 412d0408543SAndy Yan #define DITHER_DOWN_EN_SHIFT 17 413*e2bdb3b3SDamon Ding #define DITHER_DOWN_SEL_SHIFT 18 414*e2bdb3b3SDamon Ding #define DITHER_DOWN_SEL_MASK 0x3 415452afb13SDamon Ding #define DITHER_DOWN_MODE_SHIFT 20 416db328a0dSDamon Ding #define GAMMA_UPDATE_EN_SHIFT 22 4171147facaSSandy Huang #define DSP_LUT_EN_SHIFT 28 4181147facaSSandy Huang 419d0408543SAndy Yan #define STANDBY_EN_SHIFT 31 420d0408543SAndy Yan 421d0408543SAndy Yan #define RK3568_VP0_MIPI_CTRL 0xC04 42210ee9f5bSAlgea Cao #define DCLK_DIV2_SHIFT 4 42310ee9f5bSAlgea Cao #define DCLK_DIV2_MASK 0x3 424d0408543SAndy Yan #define MIPI_DUAL_EN_SHIFT 20 425d0408543SAndy Yan #define MIPI_DUAL_SWAP_EN_SHIFT 21 42641874944SGuochun Huang #define EDPI_TE_EN 28 42741874944SGuochun Huang #define EDPI_WMS_HOLD_EN 30 42841874944SGuochun Huang #define EDPI_WMS_FS 31 42941874944SGuochun Huang 430d0408543SAndy Yan 431d0408543SAndy Yan #define RK3568_VP0_COLOR_BAR_CTRL 0xC08 4325fa6e665SDamon Ding 4335fa6e665SDamon Ding #define RK3568_VP0_DCLK_SEL 0xC0C 434a552a69cSDamon Ding #define RK3576_DCLK_CORE_SEL_SHIFT 0 435a552a69cSDamon Ding #define RK3576_DCLK_OUT_SEL_SHIFT 2 4365fa6e665SDamon Ding 4376414e3bcSSandy Huang #define RK3568_VP0_3D_LUT_CTRL 0xC10 4386414e3bcSSandy Huang #define VP0_3D_LUT_EN_SHIFT 0 4396414e3bcSSandy Huang #define VP0_3D_LUT_UPDATE_SHIFT 2 4406414e3bcSSandy Huang 441ecc31b6eSAndy Yan #define RK3588_VP0_CLK_CTRL 0xC0C 442ecc31b6eSAndy Yan #define DCLK_CORE_DIV_SHIFT 0 443ecc31b6eSAndy Yan #define DCLK_OUT_DIV_SHIFT 2 444ecc31b6eSAndy Yan 4456414e3bcSSandy Huang #define RK3568_VP0_3D_LUT_MST 0xC20 4466414e3bcSSandy Huang 447d0408543SAndy Yan #define RK3568_VP0_DSP_BG 0xC2C 448d0408543SAndy Yan #define RK3568_VP0_PRE_SCAN_HTIMING 0xC30 449d0408543SAndy Yan #define RK3568_VP0_POST_DSP_HACT_INFO 0xC34 450d0408543SAndy Yan #define RK3568_VP0_POST_DSP_VACT_INFO 0xC38 451d0408543SAndy Yan #define RK3568_VP0_POST_SCL_FACTOR_YRGB 0xC3C 452d0408543SAndy Yan #define RK3568_VP0_POST_SCL_CTRL 0xC40 453d0408543SAndy Yan #define RK3568_VP0_POST_DSP_VACT_INFO_F1 0xC44 454d0408543SAndy Yan #define RK3568_VP0_DSP_HTOTAL_HS_END 0xC48 455d0408543SAndy Yan #define RK3568_VP0_DSP_HACT_ST_END 0xC4C 456d0408543SAndy Yan #define RK3568_VP0_DSP_VTOTAL_VS_END 0xC50 457d0408543SAndy Yan #define RK3568_VP0_DSP_VACT_ST_END 0xC54 458d0408543SAndy Yan #define RK3568_VP0_DSP_VS_ST_END_F1 0xC58 459d0408543SAndy Yan #define RK3568_VP0_DSP_VACT_ST_END_F1 0xC5C 460d0408543SAndy Yan 461ac500a1fSSandy Huang #define RK3568_VP0_BCSH_CTRL 0xC60 462ac500a1fSSandy Huang #define BCSH_CTRL_Y2R_SHIFT 0 463ac500a1fSSandy Huang #define BCSH_CTRL_Y2R_MASK 0x1 464ac500a1fSSandy Huang #define BCSH_CTRL_Y2R_CSC_MODE_SHIFT 2 465ac500a1fSSandy Huang #define BCSH_CTRL_Y2R_CSC_MODE_MASK 0x3 466ac500a1fSSandy Huang #define BCSH_CTRL_R2Y_SHIFT 4 467ac500a1fSSandy Huang #define BCSH_CTRL_R2Y_MASK 0x1 468ac500a1fSSandy Huang #define BCSH_CTRL_R2Y_CSC_MODE_SHIFT 6 469ac500a1fSSandy Huang #define BCSH_CTRL_R2Y_CSC_MODE_MASK 0x3 470ac500a1fSSandy Huang 471ac500a1fSSandy Huang #define RK3568_VP0_BCSH_BCS 0xC64 472ac500a1fSSandy Huang #define BCSH_BRIGHTNESS_SHIFT 0 473ac500a1fSSandy Huang #define BCSH_BRIGHTNESS_MASK 0xFF 474ac500a1fSSandy Huang #define BCSH_CONTRAST_SHIFT 8 475ac500a1fSSandy Huang #define BCSH_CONTRAST_MASK 0x1FF 476ac500a1fSSandy Huang #define BCSH_SATURATION_SHIFT 20 477ac500a1fSSandy Huang #define BCSH_SATURATION_MASK 0x3FF 478ac500a1fSSandy Huang #define BCSH_OUT_MODE_SHIFT 30 479ac500a1fSSandy Huang #define BCSH_OUT_MODE_MASK 0x3 480ac500a1fSSandy Huang 481ac500a1fSSandy Huang #define RK3568_VP0_BCSH_H 0xC68 482ac500a1fSSandy Huang #define BCSH_SIN_HUE_SHIFT 0 483ac500a1fSSandy Huang #define BCSH_SIN_HUE_MASK 0x1FF 484ac500a1fSSandy Huang #define BCSH_COS_HUE_SHIFT 16 485ac500a1fSSandy Huang #define BCSH_COS_HUE_MASK 0x1FF 486ac500a1fSSandy Huang 487ac500a1fSSandy Huang #define RK3568_VP0_BCSH_COLOR 0xC6C 488ac500a1fSSandy Huang #define BCSH_EN_SHIFT 31 489ac500a1fSSandy Huang #define BCSH_EN_MASK 1 490ac500a1fSSandy Huang 491a552a69cSDamon Ding #define RK3576_VP0_POST_DITHER_FRC_0 0xCA0 492a552a69cSDamon Ding #define RK3576_VP0_POST_DITHER_FRC_1 0xCA4 493a552a69cSDamon Ding #define RK3576_VP0_POST_DITHER_FRC_2 0xCA8 494a552a69cSDamon Ding 4956027c871SZhang Yubing #define RK3528_VP0_ACM_CTRL 0xCD0 4966027c871SZhang Yubing #define POST_CSC_COE00_MASK 0xFFFF 4976027c871SZhang Yubing #define POST_CSC_COE00_SHIFT 16 4986027c871SZhang Yubing #define POST_R2Y_MODE_MASK 0x7 4996027c871SZhang Yubing #define POST_R2Y_MODE_SHIFT 8 5006027c871SZhang Yubing #define POST_CSC_MODE_MASK 0x7 5016027c871SZhang Yubing #define POST_CSC_MODE_SHIFT 3 5026027c871SZhang Yubing #define POST_R2Y_EN_MASK 0x1 5036027c871SZhang Yubing #define POST_R2Y_EN_SHIFT 2 5046027c871SZhang Yubing #define POST_CSC_EN_MASK 0x1 5056027c871SZhang Yubing #define POST_CSC_EN_SHIFT 1 5066027c871SZhang Yubing #define POST_ACM_BYPASS_EN_MASK 0x1 5076027c871SZhang Yubing #define POST_ACM_BYPASS_EN_SHIFT 0 5086027c871SZhang Yubing #define RK3528_VP0_CSC_COE01_02 0xCD4 5096027c871SZhang Yubing #define RK3528_VP0_CSC_COE10_11 0xCD8 5106027c871SZhang Yubing #define RK3528_VP0_CSC_COE12_20 0xCDC 5116027c871SZhang Yubing #define RK3528_VP0_CSC_COE21_22 0xCE0 5126027c871SZhang Yubing #define RK3528_VP0_CSC_OFFSET0 0xCE4 5136027c871SZhang Yubing #define RK3528_VP0_CSC_OFFSET1 0xCE8 5146027c871SZhang Yubing #define RK3528_VP0_CSC_OFFSET2 0xCEC 5156027c871SZhang Yubing 5160675a2a4SDamon Ding #define RK3562_VP0_MCU_CTRL 0xCF8 5170675a2a4SDamon Ding #define MCU_TYPE_SHIFT 31 5180675a2a4SDamon Ding #define MCU_BYPASS_SHIFT 30 5190675a2a4SDamon Ding #define MCU_RS_SHIFT 29 5200675a2a4SDamon Ding #define MCU_FRAME_ST_SHIFT 28 5210675a2a4SDamon Ding #define MCU_HOLD_MODE_SHIFT 27 5220675a2a4SDamon Ding #define MCU_CLK_SEL_SHIFT 26 5230675a2a4SDamon Ding #define MCU_CLK_SEL_MASK 0x1 5240675a2a4SDamon Ding #define MCU_RW_PEND_SHIFT 20 5250675a2a4SDamon Ding #define MCU_RW_PEND_MASK 0x3F 5260675a2a4SDamon Ding #define MCU_RW_PST_SHIFT 16 5270675a2a4SDamon Ding #define MCU_RW_PST_MASK 0xF 5280675a2a4SDamon Ding #define MCU_CS_PEND_SHIFT 10 5290675a2a4SDamon Ding #define MCU_CS_PEND_MASK 0x3F 5300675a2a4SDamon Ding #define MCU_CS_PST_SHIFT 6 5310675a2a4SDamon Ding #define MCU_CS_PST_MASK 0xF 5320675a2a4SDamon Ding #define MCU_PIX_TOTAL_SHIFT 0 5330675a2a4SDamon Ding #define MCU_PIX_TOTAL_MASK 0x3F 5340675a2a4SDamon Ding 5350675a2a4SDamon Ding #define RK3562_VP0_MCU_RW_BYPASS_PORT 0xCFC 5360675a2a4SDamon Ding #define MCU_WRITE_DATA_BYPASS_SHIFT 0 5370675a2a4SDamon Ding #define MCU_WRITE_DATA_BYPASS_MASK 0xFFFFFFFF 5380675a2a4SDamon Ding 539d0408543SAndy Yan #define RK3568_VP1_DSP_CTRL 0xD00 540d0408543SAndy Yan #define RK3568_VP1_MIPI_CTRL 0xD04 541d0408543SAndy Yan #define RK3568_VP1_COLOR_BAR_CTRL 0xD08 542d0408543SAndy Yan #define RK3568_VP1_PRE_SCAN_HTIMING 0xD30 543d0408543SAndy Yan #define RK3568_VP1_POST_DSP_HACT_INFO 0xD34 544d0408543SAndy Yan #define RK3568_VP1_POST_DSP_VACT_INFO 0xD38 545d0408543SAndy Yan #define RK3568_VP1_POST_SCL_FACTOR_YRGB 0xD3C 546d0408543SAndy Yan #define RK3568_VP1_POST_SCL_CTRL 0xD40 547d0408543SAndy Yan #define RK3568_VP1_DSP_HACT_INFO 0xD34 548d0408543SAndy Yan #define RK3568_VP1_DSP_VACT_INFO 0xD38 549d0408543SAndy Yan #define RK3568_VP1_POST_DSP_VACT_INFO_F1 0xD44 550d0408543SAndy Yan #define RK3568_VP1_DSP_HTOTAL_HS_END 0xD48 551d0408543SAndy Yan #define RK3568_VP1_DSP_HACT_ST_END 0xD4C 552d0408543SAndy Yan #define RK3568_VP1_DSP_VTOTAL_VS_END 0xD50 553d0408543SAndy Yan #define RK3568_VP1_DSP_VACT_ST_END 0xD54 554d0408543SAndy Yan #define RK3568_VP1_DSP_VS_ST_END_F1 0xD58 555d0408543SAndy Yan #define RK3568_VP1_DSP_VACT_ST_END_F1 0xD5C 556d0408543SAndy Yan 557d0408543SAndy Yan #define RK3568_VP2_DSP_CTRL 0xE00 558d0408543SAndy Yan #define RK3568_VP2_MIPI_CTRL 0xE04 559d0408543SAndy Yan #define RK3568_VP2_COLOR_BAR_CTRL 0xE08 560d0408543SAndy Yan #define RK3568_VP2_PRE_SCAN_HTIMING 0xE30 561d0408543SAndy Yan #define RK3568_VP2_POST_DSP_HACT_INFO 0xE34 562d0408543SAndy Yan #define RK3568_VP2_POST_DSP_VACT_INFO 0xE38 563d0408543SAndy Yan #define RK3568_VP2_POST_SCL_FACTOR_YRGB 0xE3C 564d0408543SAndy Yan #define RK3568_VP2_POST_SCL_CTRL 0xE40 565d0408543SAndy Yan #define RK3568_VP2_DSP_HACT_INFO 0xE34 566d0408543SAndy Yan #define RK3568_VP2_DSP_VACT_INFO 0xE38 567d0408543SAndy Yan #define RK3568_VP2_POST_DSP_VACT_INFO_F1 0xE44 568d0408543SAndy Yan #define RK3568_VP2_DSP_HTOTAL_HS_END 0xE48 569d0408543SAndy Yan #define RK3568_VP2_DSP_HACT_ST_END 0xE4C 570d0408543SAndy Yan #define RK3568_VP2_DSP_VTOTAL_VS_END 0xE50 571d0408543SAndy Yan #define RK3568_VP2_DSP_VACT_ST_END 0xE54 572d0408543SAndy Yan #define RK3568_VP2_DSP_VS_ST_END_F1 0xE58 573d0408543SAndy Yan #define RK3568_VP2_DSP_VACT_ST_END_F1 0xE5C 574a552a69cSDamon Ding #define RK3568_VP2_BCSH_CTRL 0xE60 575a552a69cSDamon Ding #define RK3568_VP2_BCSH_BCS 0xE64 576a552a69cSDamon Ding #define RK3568_VP2_BCSH_H 0xE68 577a552a69cSDamon Ding #define RK3568_VP2_BCSH_COLOR_BAR 0xE6C 578a552a69cSDamon Ding #define RK3576_VP2_MCU_CTRL 0xEF8 579a552a69cSDamon Ding #define RK3576_VP2_MCU_RW_BYPASS_PORT 0xEFC 580d0408543SAndy Yan 581d0408543SAndy Yan /* Cluster0 register definition */ 582d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_CTRL0 0x1000 583ecc31b6eSAndy Yan #define CLUSTER_YUV2RGB_EN_SHIFT 8 584ecc31b6eSAndy Yan #define CLUSTER_RGB2YUV_EN_SHIFT 9 585ecc31b6eSAndy Yan #define CLUSTER_CSC_MODE_SHIFT 10 586840bf541SDamon Ding #define CLUSTER_DITHER_UP_EN_SHIFT 18 587d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_CTRL1 0x1004 5885fa6e665SDamon Ding #define RK3568_CLUSTER_YRGB_XSCL_MODE_SHIFT 12 5895fa6e665SDamon Ding #define RK3568_CLUSTER_YRGB_YSCL_MODE_SHIFT 14 5905fa6e665SDamon Ding #define RK3528_CLUSTER_YRGB_YSCL_MODE_SHIFT 14 5915fa6e665SDamon Ding #define AVG2_MASK 0x1 5925fa6e665SDamon Ding #define CLUSTER_AVG2_SHIFT 18 5935fa6e665SDamon Ding #define AVG4_MASK 0x1 5945fa6e665SDamon Ding #define CLUSTER_AVG4_SHIFT 19 5955fa6e665SDamon Ding #define RK3528_CLUSTER_YRGB_XSCL_MODE_SHIFT 22 5965fa6e665SDamon Ding #define CLUSTER_XGT_EN_SHIFT 24 5975fa6e665SDamon Ding #define XGT_MODE_MASK 0x3 5985fa6e665SDamon Ding #define CLUSTER_XGT_MODE_SHIFT 25 5995fa6e665SDamon Ding #define CLUSTER_XAVG_EN_SHIFT 27 600ecc31b6eSAndy Yan #define CLUSTER_YRGB_GT2_SHIFT 28 601ecc31b6eSAndy Yan #define CLUSTER_YRGB_GT4_SHIFT 29 602a33b790fSDamon Ding #define RK3568_CLUSTER0_WIN0_CTRL2 0x1008 603a33b790fSDamon Ding #define CLUSTER_AXI_YRGB_ID_MASK 0x1f 604a33b790fSDamon Ding #define CLUSTER_AXI_YRGB_ID_SHIFT 0 605a33b790fSDamon Ding #define CLUSTER_AXI_UV_ID_MASK 0x1f 606a33b790fSDamon Ding #define CLUSTER_AXI_UV_ID_SHIFT 5 607a33b790fSDamon Ding 608d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_YRGB_MST 0x1010 609d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_CBR_MST 0x1014 610d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_VIR 0x1018 611d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_ACT_INFO 0x1020 612d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_DSP_INFO 0x1024 613d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_DSP_ST 0x1028 614d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB 0x1030 615a552a69cSDamon Ding #define RK3576_CLUSTER0_WIN0_ZME_CTRL 0x1040 616a552a69cSDamon Ding #define WIN0_ZME_DERING_EN_SHIFT 3 617a552a69cSDamon Ding #define WIN0_ZME_GATING_EN_SHIFT 31 618a552a69cSDamon Ding #define RK3576_CLUSTER0_WIN0_ZME_DERING_PARA 0x1044 619d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_ROTATE_MODE 0x1054 620d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_HDR_PTR 0x1058 621d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_VIR_WIDTH 0x105C 622d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_SIZE 0x1060 623d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_OFFSET 0x1064 624d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_DSP_OFFSET 0x1068 625d0408543SAndy Yan #define RK3568_CLUSTER0_WIN0_AFBCD_CTRL 0x106C 626a59754e1SDamon Ding #define CLUSTER_AFBCD_HALF_BLOCK_SHIFT 7 627a552a69cSDamon Ding #define RK3576_CLUSTER0_WIN0_PLD_PTR_OFFSET 0x1078 628a552a69cSDamon Ding #define RK3576_CLUSTER0_WIN0_PLD_PTR_RANGE 0x107C 629d0408543SAndy Yan 630d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_CTRL0 0x1080 631d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_CTRL1 0x1084 632d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_YRGB_MST 0x1090 633d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_CBR_MST 0x1094 634d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_VIR 0x1098 635d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_ACT_INFO 0x10A0 636d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_DSP_INFO 0x10A4 637d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_DSP_ST 0x10A8 638d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_SCL_FACTOR_YRGB 0x10B0 639d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_ROTATE_MODE 0x10D4 640d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_HDR_PTR 0x10D8 641d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_VIR_WIDTH 0x10DC 642d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_SIZE 0x10E0 643d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_OFFSET 0x10E4 644d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_DSP_OFFSET 0x10E8 645d0408543SAndy Yan #define RK3568_CLUSTER0_WIN1_AFBCD_CTRL 0x10EC 646a552a69cSDamon Ding #define RK3576_CLUSTER0_WIN1_PLD_PTR_OFFSET 0x10F8 647a552a69cSDamon Ding #define RK3576_CLUSTER0_WIN1_PLD_PTR_RANGE 0x10FC 648d0408543SAndy Yan 649d0408543SAndy Yan #define RK3568_CLUSTER0_CTRL 0x1100 650ecc31b6eSAndy Yan #define CLUSTER_EN_SHIFT 0 651a33b790fSDamon Ding #define CLUSTER_AXI_ID_MASK 0x1 652a33b790fSDamon Ding #define CLUSTER_AXI_ID_SHIFT 13 653a552a69cSDamon Ding #define RK3576_CLUSTER0_PORT_SEL 0x11F4 654a552a69cSDamon Ding #define CLUSTER_PORT_SEL_SHIFT 0 655a552a69cSDamon Ding #define CLUSTER_PORT_SEL_MASK 0x3 656a552a69cSDamon Ding #define RK3576_CLUSTER0_DLY_NUM 0x11F8 657a552a69cSDamon Ding #define CLUSTER_WIN0_DLY_NUM_SHIFT 0 658a552a69cSDamon Ding #define CLUSTER_WIN0_DLY_NUM_MASK 0xff 659a552a69cSDamon Ding #define CLUSTER_WIN1_DLY_NUM_SHIFT 0 660a552a69cSDamon Ding #define CLUSTER_WIN1_DLY_NUM_MASK 0xff 661d0408543SAndy Yan 662d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_CTRL0 0x1200 663d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_CTRL1 0x1204 664d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_YRGB_MST 0x1210 665d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_CBR_MST 0x1214 666d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_VIR 0x1218 667d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_ACT_INFO 0x1220 668d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_DSP_INFO 0x1224 669d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_DSP_ST 0x1228 670d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_SCL_FACTOR_YRGB 0x1230 671a552a69cSDamon Ding #define RK3576_CLUSTER1_WIN0_ZME_CTRL 0x1240 672a552a69cSDamon Ding #define RK3576_CLUSTER1_WIN0_ZME_DERING_PARA 0x1244 673d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_ROTATE_MODE 0x1254 674d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_HDR_PTR 0x1258 675d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_VIR_WIDTH 0x125C 676d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_SIZE 0x1260 677d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_OFFSET 0x1264 678d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_DSP_OFFSET 0x1268 679d0408543SAndy Yan #define RK3568_CLUSTER1_WIN0_AFBCD_CTRL 0x126C 680a552a69cSDamon Ding #define RK3576_CLUSTER1_WIN0_PLD_PTR_OFFSET 0x1278 681a552a69cSDamon Ding #define RK3576_CLUSTER1_WIN0_PLD_PTR_RANGE 0x127C 682d0408543SAndy Yan 683d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_CTRL0 0x1280 684d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_CTRL1 0x1284 685d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_YRGB_MST 0x1290 686d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_CBR_MST 0x1294 687d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_VIR 0x1298 688d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_ACT_INFO 0x12A0 689d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_DSP_INFO 0x12A4 690d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_DSP_ST 0x12A8 691d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_SCL_FACTOR_YRGB 0x12B0 692d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_ROTATE_MODE 0x12D4 693d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_HDR_PTR 0x12D8 694d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_VIR_WIDTH 0x12DC 695d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_SIZE 0x12E0 696d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_OFFSET 0x12E4 697d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_DSP_OFFSET 0x12E8 698d0408543SAndy Yan #define RK3568_CLUSTER1_WIN1_AFBCD_CTRL 0x12EC 699a552a69cSDamon Ding #define RK3576_CLUSTER1_WIN1_PLD_PTR_OFFSET 0x12F8 700a552a69cSDamon Ding #define RK3576_CLUSTER1_WIN1_PLD_PTR_RANGE 0x12FC 701d0408543SAndy Yan 702d0408543SAndy Yan #define RK3568_CLUSTER1_CTRL 0x1300 703a552a69cSDamon Ding #define RK3576_CLUSTER1_PORT_SEL 0x13F4 704a552a69cSDamon Ding #define RK3576_CLUSTER1_DLY_NUM 0x13F8 705d0408543SAndy Yan 706d0408543SAndy Yan /* Esmart register definition */ 707d0408543SAndy Yan #define RK3568_ESMART0_CTRL0 0x1800 70810ee9f5bSAlgea Cao #define RGB2YUV_EN_SHIFT 1 70910ee9f5bSAlgea Cao #define CSC_MODE_SHIFT 2 71010ee9f5bSAlgea Cao #define CSC_MODE_MASK 0x3 7115fa6e665SDamon Ding #define ESMART_LB_SELECT_SHIFT 12 7125fa6e665SDamon Ding #define ESMART_LB_SELECT_MASK 0x3 713d0408543SAndy Yan 714d0408543SAndy Yan #define RK3568_ESMART0_CTRL1 0x1804 715a33b790fSDamon Ding #define ESMART_AXI_YRGB_ID_MASK 0x1f 716a33b790fSDamon Ding #define ESMART_AXI_YRGB_ID_SHIFT 4 717a33b790fSDamon Ding #define ESMART_AXI_UV_ID_MASK 0x1f 718a33b790fSDamon Ding #define ESMART_AXI_UV_ID_SHIFT 12 719d0408543SAndy Yan #define YMIRROR_EN_SHIFT 31 720a33b790fSDamon Ding 721a33b790fSDamon Ding #define RK3568_ESMART0_AXI_CTRL 0x1808 722a33b790fSDamon Ding #define ESMART_AXI_ID_MASK 0x1 723a33b790fSDamon Ding #define ESMART_AXI_ID_SHIFT 1 724a33b790fSDamon Ding 725d0408543SAndy Yan #define RK3568_ESMART0_REGION0_CTRL 0x1810 726d0408543SAndy Yan #define WIN_EN_SHIFT 0 727d0408543SAndy Yan #define WIN_FORMAT_MASK 0x1f 728d0408543SAndy Yan #define WIN_FORMAT_SHIFT 1 729840bf541SDamon Ding #define REGION0_DITHER_UP_EN_SHIFT 12 7305fa6e665SDamon Ding #define REGION0_RB_SWAP_SHIFT 14 7315fa6e665SDamon Ding #define ESMART_XAVG_EN_SHIFT 20 7325fa6e665SDamon Ding #define ESMART_XGT_EN_SHIFT 21 7335fa6e665SDamon Ding #define ESMART_XGT_MODE_SHIFT 22 734d0408543SAndy Yan 735d0408543SAndy Yan #define RK3568_ESMART0_REGION0_YRGB_MST 0x1814 736d0408543SAndy Yan #define RK3568_ESMART0_REGION0_CBR_MST 0x1818 737d0408543SAndy Yan #define RK3568_ESMART0_REGION0_VIR 0x181C 738d0408543SAndy Yan #define RK3568_ESMART0_REGION0_ACT_INFO 0x1820 739d0408543SAndy Yan #define RK3568_ESMART0_REGION0_DSP_INFO 0x1824 740d0408543SAndy Yan #define RK3568_ESMART0_REGION0_DSP_ST 0x1828 741d0408543SAndy Yan #define RK3568_ESMART0_REGION0_SCL_CTRL 0x1830 7423e39a5a1SSandy Huang #define YRGB_XSCL_MODE_MASK 0x3 7433e39a5a1SSandy Huang #define YRGB_XSCL_MODE_SHIFT 0 7443e39a5a1SSandy Huang #define YRGB_XSCL_FILTER_MODE_MASK 0x3 7453e39a5a1SSandy Huang #define YRGB_XSCL_FILTER_MODE_SHIFT 2 7463e39a5a1SSandy Huang #define YRGB_YSCL_MODE_MASK 0x3 7473e39a5a1SSandy Huang #define YRGB_YSCL_MODE_SHIFT 4 7483e39a5a1SSandy Huang #define YRGB_YSCL_FILTER_MODE_MASK 0x3 7493e39a5a1SSandy Huang #define YRGB_YSCL_FILTER_MODE_SHIFT 6 7503e39a5a1SSandy Huang 751d0408543SAndy Yan #define RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB 0x1834 752d0408543SAndy Yan #define RK3568_ESMART0_REGION0_SCL_FACTOR_CBR 0x1838 753d0408543SAndy Yan #define RK3568_ESMART0_REGION0_SCL_OFFSET 0x183C 754d0408543SAndy Yan #define RK3568_ESMART0_REGION1_CTRL 0x1840 7553e39a5a1SSandy Huang #define YRGB_GT2_MASK 0x1 7563e39a5a1SSandy Huang #define YRGB_GT2_SHIFT 8 7573e39a5a1SSandy Huang #define YRGB_GT4_MASK 0x1 7583e39a5a1SSandy Huang #define YRGB_GT4_SHIFT 9 7593e39a5a1SSandy Huang 760d0408543SAndy Yan #define RK3568_ESMART0_REGION1_YRGB_MST 0x1844 761d0408543SAndy Yan #define RK3568_ESMART0_REGION1_CBR_MST 0x1848 762d0408543SAndy Yan #define RK3568_ESMART0_REGION1_VIR 0x184C 763d0408543SAndy Yan #define RK3568_ESMART0_REGION1_ACT_INFO 0x1850 764d0408543SAndy Yan #define RK3568_ESMART0_REGION1_DSP_INFO 0x1854 765d0408543SAndy Yan #define RK3568_ESMART0_REGION1_DSP_ST 0x1858 766d0408543SAndy Yan #define RK3568_ESMART0_REGION1_SCL_CTRL 0x1860 767d0408543SAndy Yan #define RK3568_ESMART0_REGION1_SCL_FACTOR_YRGB 0x1864 768d0408543SAndy Yan #define RK3568_ESMART0_REGION1_SCL_FACTOR_CBR 0x1868 769d0408543SAndy Yan #define RK3568_ESMART0_REGION1_SCL_OFFSET 0x186C 770d0408543SAndy Yan #define RK3568_ESMART0_REGION2_CTRL 0x1870 771d0408543SAndy Yan #define RK3568_ESMART0_REGION2_YRGB_MST 0x1874 772d0408543SAndy Yan #define RK3568_ESMART0_REGION2_CBR_MST 0x1878 773d0408543SAndy Yan #define RK3568_ESMART0_REGION2_VIR 0x187C 774d0408543SAndy Yan #define RK3568_ESMART0_REGION2_ACT_INFO 0x1880 775d0408543SAndy Yan #define RK3568_ESMART0_REGION2_DSP_INFO 0x1884 776d0408543SAndy Yan #define RK3568_ESMART0_REGION2_DSP_ST 0x1888 777d0408543SAndy Yan #define RK3568_ESMART0_REGION2_SCL_CTRL 0x1890 778d0408543SAndy Yan #define RK3568_ESMART0_REGION2_SCL_FACTOR_YRGB 0x1894 779d0408543SAndy Yan #define RK3568_ESMART0_REGION2_SCL_FACTOR_CBR 0x1898 780d0408543SAndy Yan #define RK3568_ESMART0_REGION2_SCL_OFFSET 0x189C 781d0408543SAndy Yan #define RK3568_ESMART0_REGION3_CTRL 0x18A0 782d0408543SAndy Yan #define RK3568_ESMART0_REGION3_YRGB_MST 0x18A4 783d0408543SAndy Yan #define RK3568_ESMART0_REGION3_CBR_MST 0x18A8 784d0408543SAndy Yan #define RK3568_ESMART0_REGION3_VIR 0x18AC 785d0408543SAndy Yan #define RK3568_ESMART0_REGION3_ACT_INFO 0x18B0 786d0408543SAndy Yan #define RK3568_ESMART0_REGION3_DSP_INFO 0x18B4 787d0408543SAndy Yan #define RK3568_ESMART0_REGION3_DSP_ST 0x18B8 788d0408543SAndy Yan #define RK3568_ESMART0_REGION3_SCL_CTRL 0x18C0 789d0408543SAndy Yan #define RK3568_ESMART0_REGION3_SCL_FACTOR_YRGB 0x18C4 790d0408543SAndy Yan #define RK3568_ESMART0_REGION3_SCL_FACTOR_CBR 0x18C8 791d0408543SAndy Yan #define RK3568_ESMART0_REGION3_SCL_OFFSET 0x18CC 792a552a69cSDamon Ding #define RK3568_ESMART0_COLOR_KEY_CTRL 0x18D0 793a552a69cSDamon Ding #define RK3576_ESMART0_ALPHA_MAP 0x18D8 794a552a69cSDamon Ding #define RK3576_ESMART0_PORT_SEL 0x18F4 795a552a69cSDamon Ding #define ESMART_PORT_SEL_SHIFT 0 796a552a69cSDamon Ding #define ESMART_PORT_SEL_MASK 0x3 797a552a69cSDamon Ding #define RK3576_ESMART0_DLY_NUM 0x18F8 798d0408543SAndy Yan 799d0408543SAndy Yan #define RK3568_ESMART1_CTRL0 0x1A00 800d0408543SAndy Yan #define RK3568_ESMART1_CTRL1 0x1A04 801d0408543SAndy Yan #define RK3568_ESMART1_REGION0_CTRL 0x1A10 802d0408543SAndy Yan #define RK3568_ESMART1_REGION0_YRGB_MST 0x1A14 803d0408543SAndy Yan #define RK3568_ESMART1_REGION0_CBR_MST 0x1A18 804d0408543SAndy Yan #define RK3568_ESMART1_REGION0_VIR 0x1A1C 805d0408543SAndy Yan #define RK3568_ESMART1_REGION0_ACT_INFO 0x1A20 806d0408543SAndy Yan #define RK3568_ESMART1_REGION0_DSP_INFO 0x1A24 807d0408543SAndy Yan #define RK3568_ESMART1_REGION0_DSP_ST 0x1A28 808d0408543SAndy Yan #define RK3568_ESMART1_REGION0_SCL_CTRL 0x1A30 809d0408543SAndy Yan #define RK3568_ESMART1_REGION0_SCL_FACTOR_YRGB 0x1A34 810d0408543SAndy Yan #define RK3568_ESMART1_REGION0_SCL_FACTOR_CBR 0x1A38 811d0408543SAndy Yan #define RK3568_ESMART1_REGION0_SCL_OFFSET 0x1A3C 812d0408543SAndy Yan #define RK3568_ESMART1_REGION1_CTRL 0x1A40 813d0408543SAndy Yan #define RK3568_ESMART1_REGION1_YRGB_MST 0x1A44 814d0408543SAndy Yan #define RK3568_ESMART1_REGION1_CBR_MST 0x1A48 815d0408543SAndy Yan #define RK3568_ESMART1_REGION1_VIR 0x1A4C 816d0408543SAndy Yan #define RK3568_ESMART1_REGION1_ACT_INFO 0x1A50 817d0408543SAndy Yan #define RK3568_ESMART1_REGION1_DSP_INFO 0x1A54 818d0408543SAndy Yan #define RK3568_ESMART1_REGION1_DSP_ST 0x1A58 819d0408543SAndy Yan #define RK3568_ESMART1_REGION1_SCL_CTRL 0x1A60 820d0408543SAndy Yan #define RK3568_ESMART1_REGION1_SCL_FACTOR_YRGB 0x1A64 821d0408543SAndy Yan #define RK3568_ESMART1_REGION1_SCL_FACTOR_CBR 0x1A68 822d0408543SAndy Yan #define RK3568_ESMART1_REGION1_SCL_OFFSET 0x1A6C 823d0408543SAndy Yan #define RK3568_ESMART1_REGION2_CTRL 0x1A70 824d0408543SAndy Yan #define RK3568_ESMART1_REGION2_YRGB_MST 0x1A74 825d0408543SAndy Yan #define RK3568_ESMART1_REGION2_CBR_MST 0x1A78 826d0408543SAndy Yan #define RK3568_ESMART1_REGION2_VIR 0x1A7C 827d0408543SAndy Yan #define RK3568_ESMART1_REGION2_ACT_INFO 0x1A80 828d0408543SAndy Yan #define RK3568_ESMART1_REGION2_DSP_INFO 0x1A84 829d0408543SAndy Yan #define RK3568_ESMART1_REGION2_DSP_ST 0x1A88 830d0408543SAndy Yan #define RK3568_ESMART1_REGION2_SCL_CTRL 0x1A90 831d0408543SAndy Yan #define RK3568_ESMART1_REGION2_SCL_FACTOR_YRGB 0x1A94 832d0408543SAndy Yan #define RK3568_ESMART1_REGION2_SCL_FACTOR_CBR 0x1A98 833d0408543SAndy Yan #define RK3568_ESMART1_REGION2_SCL_OFFSET 0x1A9C 834d0408543SAndy Yan #define RK3568_ESMART1_REGION3_CTRL 0x1AA0 835d0408543SAndy Yan #define RK3568_ESMART1_REGION3_YRGB_MST 0x1AA4 836d0408543SAndy Yan #define RK3568_ESMART1_REGION3_CBR_MST 0x1AA8 837d0408543SAndy Yan #define RK3568_ESMART1_REGION3_VIR 0x1AAC 838d0408543SAndy Yan #define RK3568_ESMART1_REGION3_ACT_INFO 0x1AB0 839d0408543SAndy Yan #define RK3568_ESMART1_REGION3_DSP_INFO 0x1AB4 840d0408543SAndy Yan #define RK3568_ESMART1_REGION3_DSP_ST 0x1AB8 841d0408543SAndy Yan #define RK3568_ESMART1_REGION3_SCL_CTRL 0x1AC0 842d0408543SAndy Yan #define RK3568_ESMART1_REGION3_SCL_FACTOR_YRGB 0x1AC4 843d0408543SAndy Yan #define RK3568_ESMART1_REGION3_SCL_FACTOR_CBR 0x1AC8 844d0408543SAndy Yan #define RK3568_ESMART1_REGION3_SCL_OFFSET 0x1ACC 845a552a69cSDamon Ding #define RK3576_ESMART1_ALPHA_MAP 0x1AD8 846a552a69cSDamon Ding #define RK3576_ESMART1_PORT_SEL 0x1AF4 847a552a69cSDamon Ding #define RK3576_ESMART1_DLY_NUM 0x1AF8 848d0408543SAndy Yan 849d0408543SAndy Yan #define RK3568_SMART0_CTRL0 0x1C00 850d0408543SAndy Yan #define RK3568_SMART0_CTRL1 0x1C04 851d0408543SAndy Yan #define RK3568_SMART0_REGION0_CTRL 0x1C10 852d0408543SAndy Yan #define RK3568_SMART0_REGION0_YRGB_MST 0x1C14 853d0408543SAndy Yan #define RK3568_SMART0_REGION0_CBR_MST 0x1C18 854d0408543SAndy Yan #define RK3568_SMART0_REGION0_VIR 0x1C1C 855d0408543SAndy Yan #define RK3568_SMART0_REGION0_ACT_INFO 0x1C20 856d0408543SAndy Yan #define RK3568_SMART0_REGION0_DSP_INFO 0x1C24 857d0408543SAndy Yan #define RK3568_SMART0_REGION0_DSP_ST 0x1C28 858d0408543SAndy Yan #define RK3568_SMART0_REGION0_SCL_CTRL 0x1C30 859d0408543SAndy Yan #define RK3568_SMART0_REGION0_SCL_FACTOR_YRGB 0x1C34 860d0408543SAndy Yan #define RK3568_SMART0_REGION0_SCL_FACTOR_CBR 0x1C38 861d0408543SAndy Yan #define RK3568_SMART0_REGION0_SCL_OFFSET 0x1C3C 862d0408543SAndy Yan #define RK3568_SMART0_REGION1_CTRL 0x1C40 863d0408543SAndy Yan #define RK3568_SMART0_REGION1_YRGB_MST 0x1C44 864d0408543SAndy Yan #define RK3568_SMART0_REGION1_CBR_MST 0x1C48 865d0408543SAndy Yan #define RK3568_SMART0_REGION1_VIR 0x1C4C 866d0408543SAndy Yan #define RK3568_SMART0_REGION1_ACT_INFO 0x1C50 867d0408543SAndy Yan #define RK3568_SMART0_REGION1_DSP_INFO 0x1C54 868d0408543SAndy Yan #define RK3568_SMART0_REGION1_DSP_ST 0x1C58 869d0408543SAndy Yan #define RK3568_SMART0_REGION1_SCL_CTRL 0x1C60 870d0408543SAndy Yan #define RK3568_SMART0_REGION1_SCL_FACTOR_YRGB 0x1C64 871d0408543SAndy Yan #define RK3568_SMART0_REGION1_SCL_FACTOR_CBR 0x1C68 872d0408543SAndy Yan #define RK3568_SMART0_REGION1_SCL_OFFSET 0x1C6C 873d0408543SAndy Yan #define RK3568_SMART0_REGION2_CTRL 0x1C70 874d0408543SAndy Yan #define RK3568_SMART0_REGION2_YRGB_MST 0x1C74 875d0408543SAndy Yan #define RK3568_SMART0_REGION2_CBR_MST 0x1C78 876d0408543SAndy Yan #define RK3568_SMART0_REGION2_VIR 0x1C7C 877d0408543SAndy Yan #define RK3568_SMART0_REGION2_ACT_INFO 0x1C80 878d0408543SAndy Yan #define RK3568_SMART0_REGION2_DSP_INFO 0x1C84 879d0408543SAndy Yan #define RK3568_SMART0_REGION2_DSP_ST 0x1C88 880d0408543SAndy Yan #define RK3568_SMART0_REGION2_SCL_CTRL 0x1C90 881d0408543SAndy Yan #define RK3568_SMART0_REGION2_SCL_FACTOR_YRGB 0x1C94 882d0408543SAndy Yan #define RK3568_SMART0_REGION2_SCL_FACTOR_CBR 0x1C98 883d0408543SAndy Yan #define RK3568_SMART0_REGION2_SCL_OFFSET 0x1C9C 884d0408543SAndy Yan #define RK3568_SMART0_REGION3_CTRL 0x1CA0 885d0408543SAndy Yan #define RK3568_SMART0_REGION3_YRGB_MST 0x1CA4 886d0408543SAndy Yan #define RK3568_SMART0_REGION3_CBR_MST 0x1CA8 887d0408543SAndy Yan #define RK3568_SMART0_REGION3_VIR 0x1CAC 888d0408543SAndy Yan #define RK3568_SMART0_REGION3_ACT_INFO 0x1CB0 889d0408543SAndy Yan #define RK3568_SMART0_REGION3_DSP_INFO 0x1CB4 890d0408543SAndy Yan #define RK3568_SMART0_REGION3_DSP_ST 0x1CB8 891d0408543SAndy Yan #define RK3568_SMART0_REGION3_SCL_CTRL 0x1CC0 892d0408543SAndy Yan #define RK3568_SMART0_REGION3_SCL_FACTOR_YRGB 0x1CC4 893d0408543SAndy Yan #define RK3568_SMART0_REGION3_SCL_FACTOR_CBR 0x1CC8 894d0408543SAndy Yan #define RK3568_SMART0_REGION3_SCL_OFFSET 0x1CCC 895a552a69cSDamon Ding #define RK3576_ESMART2_ALPHA_MAP 0x1CD8 896a552a69cSDamon Ding #define RK3576_ESMART2_PORT_SEL 0x1CF4 897a552a69cSDamon Ding #define RK3576_ESMART2_DLY_NUM 0x1CF8 898d0408543SAndy Yan 899d0408543SAndy Yan #define RK3568_SMART1_CTRL0 0x1E00 900d0408543SAndy Yan #define RK3568_SMART1_CTRL1 0x1E04 901d0408543SAndy Yan #define RK3568_SMART1_REGION0_CTRL 0x1E10 902d0408543SAndy Yan #define RK3568_SMART1_REGION0_YRGB_MST 0x1E14 903d0408543SAndy Yan #define RK3568_SMART1_REGION0_CBR_MST 0x1E18 904d0408543SAndy Yan #define RK3568_SMART1_REGION0_VIR 0x1E1C 905d0408543SAndy Yan #define RK3568_SMART1_REGION0_ACT_INFO 0x1E20 906d0408543SAndy Yan #define RK3568_SMART1_REGION0_DSP_INFO 0x1E24 907d0408543SAndy Yan #define RK3568_SMART1_REGION0_DSP_ST 0x1E28 908d0408543SAndy Yan #define RK3568_SMART1_REGION0_SCL_CTRL 0x1E30 909d0408543SAndy Yan #define RK3568_SMART1_REGION0_SCL_FACTOR_YRGB 0x1E34 910d0408543SAndy Yan #define RK3568_SMART1_REGION0_SCL_FACTOR_CBR 0x1E38 911d0408543SAndy Yan #define RK3568_SMART1_REGION0_SCL_OFFSET 0x1E3C 912d0408543SAndy Yan #define RK3568_SMART1_REGION1_CTRL 0x1E40 913d0408543SAndy Yan #define RK3568_SMART1_REGION1_YRGB_MST 0x1E44 914d0408543SAndy Yan #define RK3568_SMART1_REGION1_CBR_MST 0x1E48 915d0408543SAndy Yan #define RK3568_SMART1_REGION1_VIR 0x1E4C 916d0408543SAndy Yan #define RK3568_SMART1_REGION1_ACT_INFO 0x1E50 917d0408543SAndy Yan #define RK3568_SMART1_REGION1_DSP_INFO 0x1E54 918d0408543SAndy Yan #define RK3568_SMART1_REGION1_DSP_ST 0x1E58 919d0408543SAndy Yan #define RK3568_SMART1_REGION1_SCL_CTRL 0x1E60 920d0408543SAndy Yan #define RK3568_SMART1_REGION1_SCL_FACTOR_YRGB 0x1E64 921d0408543SAndy Yan #define RK3568_SMART1_REGION1_SCL_FACTOR_CBR 0x1E68 922d0408543SAndy Yan #define RK3568_SMART1_REGION1_SCL_OFFSET 0x1E6C 923d0408543SAndy Yan #define RK3568_SMART1_REGION2_CTRL 0x1E70 924d0408543SAndy Yan #define RK3568_SMART1_REGION2_YRGB_MST 0x1E74 925d0408543SAndy Yan #define RK3568_SMART1_REGION2_CBR_MST 0x1E78 926d0408543SAndy Yan #define RK3568_SMART1_REGION2_VIR 0x1E7C 927d0408543SAndy Yan #define RK3568_SMART1_REGION2_ACT_INFO 0x1E80 928d0408543SAndy Yan #define RK3568_SMART1_REGION2_DSP_INFO 0x1E84 929d0408543SAndy Yan #define RK3568_SMART1_REGION2_DSP_ST 0x1E88 930d0408543SAndy Yan #define RK3568_SMART1_REGION2_SCL_CTRL 0x1E90 931d0408543SAndy Yan #define RK3568_SMART1_REGION2_SCL_FACTOR_YRGB 0x1E94 932d0408543SAndy Yan #define RK3568_SMART1_REGION2_SCL_FACTOR_CBR 0x1E98 933d0408543SAndy Yan #define RK3568_SMART1_REGION2_SCL_OFFSET 0x1E9C 934d0408543SAndy Yan #define RK3568_SMART1_REGION3_CTRL 0x1EA0 935d0408543SAndy Yan #define RK3568_SMART1_REGION3_YRGB_MST 0x1EA4 936d0408543SAndy Yan #define RK3568_SMART1_REGION3_CBR_MST 0x1EA8 937d0408543SAndy Yan #define RK3568_SMART1_REGION3_VIR 0x1EAC 938d0408543SAndy Yan #define RK3568_SMART1_REGION3_ACT_INFO 0x1EB0 939d0408543SAndy Yan #define RK3568_SMART1_REGION3_DSP_INFO 0x1EB4 940d0408543SAndy Yan #define RK3568_SMART1_REGION3_DSP_ST 0x1EB8 941d0408543SAndy Yan #define RK3568_SMART1_REGION3_SCL_CTRL 0x1EC0 942d0408543SAndy Yan #define RK3568_SMART1_REGION3_SCL_FACTOR_YRGB 0x1EC4 943d0408543SAndy Yan #define RK3568_SMART1_REGION3_SCL_FACTOR_CBR 0x1EC8 944d0408543SAndy Yan #define RK3568_SMART1_REGION3_SCL_OFFSET 0x1ECC 945a552a69cSDamon Ding #define RK3576_ESMART3_ALPHA_MAP 0x1ED8 946a552a69cSDamon Ding #define RK3576_ESMART3_PORT_SEL 0x1EF4 947a552a69cSDamon Ding #define RK3576_ESMART3_DLY_NUM 0x1EF8 948d0408543SAndy Yan 94972388c26SDamon Ding /* HDR register definition */ 95072388c26SDamon Ding #define RK3568_HDR_LUT_CTRL 0x2000 95172388c26SDamon Ding 95272388c26SDamon Ding #define RK3588_VP3_DSP_CTRL 0xF00 95372388c26SDamon Ding #define RK3588_CLUSTER2_WIN0_CTRL0 0x1400 95472388c26SDamon Ding #define RK3588_CLUSTER3_WIN0_CTRL0 0x1600 95572388c26SDamon Ding 95612ee5af0SDamon Ding /* DSC 8K/4K register definition */ 95712ee5af0SDamon Ding #define RK3588_DSC_8K_PPS0_3 0x4000 95812ee5af0SDamon Ding #define RK3588_DSC_8K_CTRL0 0x40A0 95912ee5af0SDamon Ding #define DSC_EN_SHIFT 0 96012ee5af0SDamon Ding #define DSC_RBIT_SHIFT 2 96112ee5af0SDamon Ding #define DSC_RBYT_SHIFT 3 96212ee5af0SDamon Ding #define DSC_FLAL_SHIFT 4 96312ee5af0SDamon Ding #define DSC_MER_SHIFT 5 96412ee5af0SDamon Ding #define DSC_EPB_SHIFT 6 96512ee5af0SDamon Ding #define DSC_EPL_SHIFT 7 9661ace1b6dSDamon Ding #define DSC_NSLC_MASK 0x7 96712ee5af0SDamon Ding #define DSC_NSLC_SHIFT 16 96812ee5af0SDamon Ding #define DSC_SBO_SHIFT 28 96912ee5af0SDamon Ding #define DSC_IFEP_SHIFT 29 97012ee5af0SDamon Ding #define DSC_PPS_UPD_SHIFT 31 971baf2c414SDamon Ding #define DSC_CTRL0_DEF_CON ((1 << DSC_EN_SHIFT) | (1 << DSC_RBIT_SHIFT) | (0 << DSC_RBYT_SHIFT) | \ 972baf2c414SDamon Ding (1 << DSC_FLAL_SHIFT) | (1 << DSC_MER_SHIFT) | (0 << DSC_EPB_SHIFT) | \ 973baf2c414SDamon Ding (1 << DSC_EPL_SHIFT) | (1 << DSC_SBO_SHIFT)) 97412ee5af0SDamon Ding 97512ee5af0SDamon Ding #define RK3588_DSC_8K_CTRL1 0x40A4 97612ee5af0SDamon Ding #define RK3588_DSC_8K_STS0 0x40A8 97712ee5af0SDamon Ding #define RK3588_DSC_8K_ERS 0x40C4 97812ee5af0SDamon Ding 97912ee5af0SDamon Ding #define RK3588_DSC_4K_PPS0_3 0x4100 98012ee5af0SDamon Ding #define RK3588_DSC_4K_CTRL0 0x41A0 98112ee5af0SDamon Ding #define RK3588_DSC_4K_CTRL1 0x41A4 98212ee5af0SDamon Ding #define RK3588_DSC_4K_STS0 0x41A8 98312ee5af0SDamon Ding #define RK3588_DSC_4K_ERS 0x41C4 98412ee5af0SDamon Ding 98572388c26SDamon Ding /* RK3528 HDR register definition */ 98672388c26SDamon Ding #define RK3528_HDR_LUT_CTRL 0x2000 98772388c26SDamon Ding 9886027c871SZhang Yubing /* RK3528 ACM register definition */ 9896027c871SZhang Yubing #define RK3528_ACM_CTRL 0x6400 9906027c871SZhang Yubing #define RK3528_ACM_DELTA_RANGE 0x6404 9916027c871SZhang Yubing #define RK3528_ACM_FETCH_START 0x6408 9926027c871SZhang Yubing #define RK3528_ACM_FETCH_DONE 0x6420 9936027c871SZhang Yubing #define RK3528_ACM_YHS_DEL_HY_SEG0 0x6500 9946027c871SZhang Yubing #define RK3528_ACM_YHS_DEL_HY_SEG152 0x6760 9956027c871SZhang Yubing #define RK3528_ACM_YHS_DEL_HS_SEG0 0x6764 9966027c871SZhang Yubing #define RK3528_ACM_YHS_DEL_HS_SEG220 0x6ad4 9976027c871SZhang Yubing #define RK3528_ACM_YHS_DEL_HGAIN_SEG0 0x6ad8 9986027c871SZhang Yubing #define RK3528_ACM_YHS_DEL_HGAIN_SEG64 0x6bd8 9996027c871SZhang Yubing 1000d0408543SAndy Yan #define RK3568_MAX_REG 0x1ED0 1001d0408543SAndy Yan 1002452afb13SDamon Ding #define RK3562_GRF_IOC_VO_IO_CON 0x10500 100352ee18acSSandy Huang #define RK3568_GRF_VO_CON1 0x0364 100452ee18acSSandy Huang #define GRF_BT656_CLK_INV_SHIFT 1 100552ee18acSSandy Huang #define GRF_BT1120_CLK_INV_SHIFT 2 100652ee18acSSandy Huang #define GRF_RGB_DCLK_INV_SHIFT 3 100752ee18acSSandy Huang 1008a552a69cSDamon Ding /* Base SYS_GRF: 0x2600a000*/ 1009a552a69cSDamon Ding #define RK3576_SYS_GRF_MEMFAULT_STATUS0 0x0148 1010a552a69cSDamon Ding 1011a552a69cSDamon Ding /* Base IOC_GRF: 0x26040000 */ 1012a552a69cSDamon Ding #define RK3576_VCCIO_IOC_MISC_CON8 0x6420 1013a552a69cSDamon Ding #define RK3576_IOC_VOP_DCLK_INV_SEL_SHIFT 9 1014a552a69cSDamon Ding #define RK3576_IOC_VOPLITE_SEL_SHIFT 11 1015a552a69cSDamon Ding 1016a552a69cSDamon Ding /* Base PMU2: 0x27380000 */ 1017a552a69cSDamon Ding #define RK3576_PMU_PWR_GATE_STS 0x0230 1018a552a69cSDamon Ding #define PD_VOP_ESMART_DWN_STAT 12 1019a552a69cSDamon Ding #define PD_VOP_CLUSTER_DWN_STAT 13 1020a552a69cSDamon Ding #define RK3576_PMU_BISR_PDGEN_CON0 0x0510 1021a552a69cSDamon Ding #define PD_VOP_ESMART_REPAIR_ENA_SHIFT 12 1022a552a69cSDamon Ding #define PD_VOP_CLUSTER_REPAIR_ENA_SHIFT 13 1023a552a69cSDamon Ding #define RK3576_PMU_BISR_PWR_REPAIR_STATUS0 0x0570 1024a552a69cSDamon Ding #define PD_VOP_ESMART_PWR_REPAIR_STAT_SHIFT 12 1025a552a69cSDamon Ding #define PD_VOP_CLUSTER_PWR_REPAIR_STAT_SHIFT 13 1026a552a69cSDamon Ding 10275d2768f7SDamon Ding #define RK3588_GRF_SOC_CON1 0x0304 10285d2768f7SDamon Ding #define RK3588_GRF_VOP_DCLK_INV_SEL_SHIFT 14 10295d2768f7SDamon Ding 1030ecc31b6eSAndy Yan #define RK3588_GRF_VOP_CON2 0x0008 1031ecc31b6eSAndy Yan #define RK3588_GRF_EDP0_ENABLE_SHIFT 0 1032ecc31b6eSAndy Yan #define RK3588_GRF_HDMITX0_ENABLE_SHIFT 1 1033ecc31b6eSAndy Yan #define RK3588_GRF_EDP1_ENABLE_SHIFT 3 1034ecc31b6eSAndy Yan #define RK3588_GRF_HDMITX1_ENABLE_SHIFT 4 1035ecc31b6eSAndy Yan 1036b890760eSAlgea Cao #define RK3588_GRF_VO1_CON0 0x0000 1037b890760eSAlgea Cao #define HDMI_SYNC_POL_MASK 0x3 1038b890760eSAlgea Cao #define HDMI0_SYNC_POL_SHIFT 5 1039b890760eSAlgea Cao #define HDMI1_SYNC_POL_SHIFT 7 1040b890760eSAlgea Cao 104160e469f5SDamon Ding #define RK3588_PMU_BISR_CON3 0x20C 104260e469f5SDamon Ding #define RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT 9 104360e469f5SDamon Ding #define RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT 10 104460e469f5SDamon Ding #define RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT 11 104560e469f5SDamon Ding #define RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT 12 1046b6ba80b4SDamon Ding #define RK3588_PD_DSC_8K_REPAIR_EN_SHIFT 13 1047b6ba80b4SDamon Ding #define RK3588_PD_DSC_4K_REPAIR_EN_SHIFT 14 104860e469f5SDamon Ding #define RK3588_PD_ESMART_REPAIR_EN_SHIFT 15 104960e469f5SDamon Ding 105060e469f5SDamon Ding #define RK3588_PMU_BISR_STATUS5 0x294 105160e469f5SDamon Ding #define RK3588_PD_CLUSTER0_PWR_STAT_SHIFI 9 105260e469f5SDamon Ding #define RK3588_PD_CLUSTER1_PWR_STAT_SHIFI 10 105360e469f5SDamon Ding #define RK3588_PD_CLUSTER2_PWR_STAT_SHIFI 11 105460e469f5SDamon Ding #define RK3588_PD_CLUSTER3_PWR_STAT_SHIFI 12 1055b6ba80b4SDamon Ding #define RK3588_PD_DSC_8K_PWR_STAT_SHIFI 13 1056b6ba80b4SDamon Ding #define RK3588_PD_DSC_4K_PWR_STAT_SHIFI 14 105760e469f5SDamon Ding #define RK3588_PD_ESMART_PWR_STAT_SHIFI 15 105860e469f5SDamon Ding 1059d0408543SAndy Yan #define VOP2_LAYER_MAX 8 106063cb669fSSandy Huang 1061ee01dbb2SDamon Ding #define VOP2_MAX_VP_OUTPUT_WIDTH 4096 1062ee01dbb2SDamon Ding 1063631ee99aSZhang Yubing /* KHz */ 1064631ee99aSZhang Yubing #define VOP2_MAX_DCLK_RATE 600000 1065631ee99aSZhang Yubing 1066b6ba80b4SDamon Ding /* 1067b6ba80b4SDamon Ding * vop2 dsc id 1068b6ba80b4SDamon Ding */ 1069b6ba80b4SDamon Ding #define ROCKCHIP_VOP2_DSC_8K 0 1070b6ba80b4SDamon Ding #define ROCKCHIP_VOP2_DSC_4K 1 1071b6ba80b4SDamon Ding 1072b6ba80b4SDamon Ding /* 1073b6ba80b4SDamon Ding * vop2 internal power domain id, 1074b6ba80b4SDamon Ding * should be all none zero, 0 will be 1075b6ba80b4SDamon Ding * treat as invalid; 1076b6ba80b4SDamon Ding */ 1077b6ba80b4SDamon Ding #define VOP2_PD_CLUSTER0 BIT(0) 1078b6ba80b4SDamon Ding #define VOP2_PD_CLUSTER1 BIT(1) 1079b6ba80b4SDamon Ding #define VOP2_PD_CLUSTER2 BIT(2) 1080b6ba80b4SDamon Ding #define VOP2_PD_CLUSTER3 BIT(3) 1081b6ba80b4SDamon Ding #define VOP2_PD_DSC_8K BIT(5) 1082b6ba80b4SDamon Ding #define VOP2_PD_DSC_4K BIT(6) 1083b6ba80b4SDamon Ding #define VOP2_PD_ESMART BIT(7) 1084a552a69cSDamon Ding #define VOP2_PD_CLUSTER BIT(8) 1085b6ba80b4SDamon Ding 10864c765862SDamon Ding #define VOP2_PLANE_NO_SCALING BIT(16) 10874c765862SDamon Ding 10885fa6e665SDamon Ding #define VOP_FEATURE_OUTPUT_10BIT BIT(0) 10895fa6e665SDamon Ding #define VOP_FEATURE_AFBDC BIT(1) 10905fa6e665SDamon Ding #define VOP_FEATURE_ALPHA_SCALE BIT(2) 10915fa6e665SDamon Ding #define VOP_FEATURE_HDR10 BIT(3) 10925fa6e665SDamon Ding #define VOP_FEATURE_NEXT_HDR BIT(4) 10935fa6e665SDamon Ding /* a feature to splice two windows and two vps to support resolution > 4096 */ 10945fa6e665SDamon Ding #define VOP_FEATURE_SPLICE BIT(5) 10955fa6e665SDamon Ding #define VOP_FEATURE_OVERSCAN BIT(6) 10966027c871SZhang Yubing #define VOP_FEATURE_VIVID_HDR BIT(7) 10976027c871SZhang Yubing #define VOP_FEATURE_POST_ACM BIT(8) 10986027c871SZhang Yubing #define VOP_FEATURE_POST_CSC BIT(9) 1099a552a69cSDamon Ding #define VOP_FEATURE_POST_FRC_V2 BIT(10) 1100a552a69cSDamon Ding #define VOP_FEATURE_POST_SHARP BIT(11) 11015fa6e665SDamon Ding 11025fa6e665SDamon Ding #define WIN_FEATURE_HDR2SDR BIT(0) 11035fa6e665SDamon Ding #define WIN_FEATURE_SDR2HDR BIT(1) 11045fa6e665SDamon Ding #define WIN_FEATURE_PRE_OVERLAY BIT(2) 11055fa6e665SDamon Ding #define WIN_FEATURE_AFBDC BIT(3) 11065fa6e665SDamon Ding #define WIN_FEATURE_CLUSTER_MAIN BIT(4) 11075fa6e665SDamon Ding #define WIN_FEATURE_CLUSTER_SUB BIT(5) 11085fa6e665SDamon Ding /* a mirror win can only get fb address 11095fa6e665SDamon Ding * from source win: 11105fa6e665SDamon Ding * Cluster1---->Cluster0 11115fa6e665SDamon Ding * Esmart1 ---->Esmart0 11125fa6e665SDamon Ding * Smart1 ---->Smart0 11135fa6e665SDamon Ding * This is a feather on rk3566 11145fa6e665SDamon Ding */ 11155fa6e665SDamon Ding #define WIN_FEATURE_MIRROR BIT(6) 11165fa6e665SDamon Ding #define WIN_FEATURE_MULTI_AREA BIT(7) 11175fa6e665SDamon Ding #define WIN_FEATURE_Y2R_13BIT_DEPTH BIT(8) 1118a552a69cSDamon Ding #define WIN_FEATURE_DCI BIT(9) 11195fa6e665SDamon Ding 11205fa6e665SDamon Ding #define V4L2_COLORSPACE_BT709F 0xfe 11215fa6e665SDamon Ding #define V4L2_COLORSPACE_BT2020F 0xff 11225fa6e665SDamon Ding 11235fa6e665SDamon Ding enum vop_csc_format { 112410ee9f5bSAlgea Cao CSC_BT601L, 112510ee9f5bSAlgea Cao CSC_BT709L, 112610ee9f5bSAlgea Cao CSC_BT601F, 1127df0a5c43SDamon Ding CSC_BT2020L, 11285fa6e665SDamon Ding CSC_BT709L_13BIT, 11295fa6e665SDamon Ding CSC_BT709F_13BIT, 11305fa6e665SDamon Ding CSC_BT2020L_13BIT, 11315fa6e665SDamon Ding CSC_BT2020F_13BIT, 11325fa6e665SDamon Ding }; 11335fa6e665SDamon Ding 11345fa6e665SDamon Ding enum vop_csc_bit_depth { 11355fa6e665SDamon Ding CSC_10BIT_DEPTH, 11365fa6e665SDamon Ding CSC_13BIT_DEPTH, 113710ee9f5bSAlgea Cao }; 113810ee9f5bSAlgea Cao 113910ee9f5bSAlgea Cao enum vop2_pol { 114010ee9f5bSAlgea Cao HSYNC_POSITIVE = 0, 114110ee9f5bSAlgea Cao VSYNC_POSITIVE = 1, 114210ee9f5bSAlgea Cao DEN_NEGATIVE = 2, 114310ee9f5bSAlgea Cao DCLK_INVERT = 3 114410ee9f5bSAlgea Cao }; 114510ee9f5bSAlgea Cao 1146ac500a1fSSandy Huang enum vop2_bcsh_out_mode { 1147ac500a1fSSandy Huang BCSH_OUT_MODE_BLACK, 1148ac500a1fSSandy Huang BCSH_OUT_MODE_BLUE, 1149ac500a1fSSandy Huang BCSH_OUT_MODE_COLOR_BAR, 1150ac500a1fSSandy Huang BCSH_OUT_MODE_NORMAL_VIDEO, 1151ac500a1fSSandy Huang }; 1152ac500a1fSSandy Huang 1153d0408543SAndy Yan #define _VOP_REG(off, _mask, _shift, _write_mask) \ 1154d0408543SAndy Yan { \ 1155d0408543SAndy Yan .offset = off, \ 1156d0408543SAndy Yan .mask = _mask, \ 1157d0408543SAndy Yan .shift = _shift, \ 1158d0408543SAndy Yan .write_mask = _write_mask, \ 1159d0408543SAndy Yan } 1160d0408543SAndy Yan 1161d0408543SAndy Yan #define VOP_REG(off, _mask, _shift) \ 1162d0408543SAndy Yan _VOP_REG(off, _mask, _shift, false) 1163d0408543SAndy Yan enum dither_down_mode { 1164d0408543SAndy Yan RGB888_TO_RGB565 = 0x0, 1165d0408543SAndy Yan RGB888_TO_RGB666 = 0x1 1166d0408543SAndy Yan }; 1167d0408543SAndy Yan 1168a552a69cSDamon Ding enum dither_down_mode_sel { 1169a552a69cSDamon Ding DITHER_DOWN_ALLEGRO = 0x0, 1170a552a69cSDamon Ding DITHER_DOWN_FRC = 0x1 1171a552a69cSDamon Ding }; 1172a552a69cSDamon Ding 1173d0408543SAndy Yan enum vop2_video_ports_id { 1174d0408543SAndy Yan VOP2_VP0, 1175d0408543SAndy Yan VOP2_VP1, 1176d0408543SAndy Yan VOP2_VP2, 1177d0408543SAndy Yan VOP2_VP3, 1178d0408543SAndy Yan VOP2_VP_MAX, 1179d0408543SAndy Yan }; 1180d0408543SAndy Yan 1181ee008497SSandy Huang enum vop2_layer_type { 1182ee008497SSandy Huang CLUSTER_LAYER = 0, 1183ee008497SSandy Huang ESMART_LAYER = 1, 1184ee008497SSandy Huang SMART_LAYER = 2, 1185ee008497SSandy Huang }; 1186ee008497SSandy Huang 1187b0989546SSandy Huang /* This define must same with kernel win phy id */ 1188b0989546SSandy Huang enum vop2_layer_phy_id { 1189b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER0 = 0, 1190b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER1, 1191b0989546SSandy Huang ROCKCHIP_VOP2_ESMART0, 1192b0989546SSandy Huang ROCKCHIP_VOP2_ESMART1, 1193b0989546SSandy Huang ROCKCHIP_VOP2_SMART0, 1194b0989546SSandy Huang ROCKCHIP_VOP2_SMART1, 1195b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER2, 1196b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER3, 1197b0989546SSandy Huang ROCKCHIP_VOP2_ESMART2, 1198b0989546SSandy Huang ROCKCHIP_VOP2_ESMART3, 1199ee008497SSandy Huang ROCKCHIP_VOP2_LAYER_MAX, 1200d0408543SAndy Yan }; 1201d0408543SAndy Yan 12023e39a5a1SSandy Huang enum vop2_scale_up_mode { 12033e39a5a1SSandy Huang VOP2_SCALE_UP_NRST_NBOR, 12043e39a5a1SSandy Huang VOP2_SCALE_UP_BIL, 12053e39a5a1SSandy Huang VOP2_SCALE_UP_BIC, 1206a552a69cSDamon Ding VOP2_SCALE_UP_ZME, 12073e39a5a1SSandy Huang }; 12083e39a5a1SSandy Huang 12093e39a5a1SSandy Huang enum vop2_scale_down_mode { 12103e39a5a1SSandy Huang VOP2_SCALE_DOWN_NRST_NBOR, 12113e39a5a1SSandy Huang VOP2_SCALE_DOWN_BIL, 12123e39a5a1SSandy Huang VOP2_SCALE_DOWN_AVG, 1213a552a69cSDamon Ding VOP2_SCALE_DOWN_ZME, 12143e39a5a1SSandy Huang }; 12153e39a5a1SSandy Huang 12163e39a5a1SSandy Huang enum scale_mode { 12173e39a5a1SSandy Huang SCALE_NONE = 0x0, 12183e39a5a1SSandy Huang SCALE_UP = 0x1, 12193e39a5a1SSandy Huang SCALE_DOWN = 0x2 12203e39a5a1SSandy Huang }; 12213e39a5a1SSandy Huang 122212ee5af0SDamon Ding enum vop_dsc_interface_mode { 122312ee5af0SDamon Ding VOP_DSC_IF_DISABLE = 0, 122412ee5af0SDamon Ding VOP_DSC_IF_HDMI = 1, 122512ee5af0SDamon Ding VOP_DSC_IF_MIPI_DS_MODE = 2, 122612ee5af0SDamon Ding VOP_DSC_IF_MIPI_VIDEO_MODE = 3, 122712ee5af0SDamon Ding }; 122812ee5af0SDamon Ding 12295fa6e665SDamon Ding enum vop3_pre_scale_down_mode { 12305fa6e665SDamon Ding VOP3_PRE_SCALE_UNSPPORT, 12315fa6e665SDamon Ding VOP3_PRE_SCALE_DOWN_GT, 12325fa6e665SDamon Ding VOP3_PRE_SCALE_DOWN_AVG, 12335fa6e665SDamon Ding }; 12345fa6e665SDamon Ding 12355fa6e665SDamon Ding enum vop3_esmart_lb_mode { 12365fa6e665SDamon Ding VOP3_ESMART_8K_MODE, 12375fa6e665SDamon Ding VOP3_ESMART_4K_4K_MODE, 12385fa6e665SDamon Ding VOP3_ESMART_4K_2K_2K_MODE, 12395fa6e665SDamon Ding VOP3_ESMART_2K_2K_2K_2K_MODE, 1240a552a69cSDamon Ding VOP3_ESMART_4K_4K_4K_MODE, 1241a552a69cSDamon Ding VOP3_ESMART_4K_4K_2K_2K_MODE, 12425fa6e665SDamon Ding }; 12435fa6e665SDamon Ding 12443e39a5a1SSandy Huang struct vop2_layer { 12453e39a5a1SSandy Huang u8 id; 12463e39a5a1SSandy Huang /** 12473e39a5a1SSandy Huang * @win_phys_id: window id of the layer selected. 12483e39a5a1SSandy Huang * Every layer must make sure to select different 12493e39a5a1SSandy Huang * windows of others. 12503e39a5a1SSandy Huang */ 12513e39a5a1SSandy Huang u8 win_phys_id; 12523e39a5a1SSandy Huang }; 12533e39a5a1SSandy Huang 125460e469f5SDamon Ding struct vop2_power_domain_data { 1255a552a69cSDamon Ding u16 id; 1256a552a69cSDamon Ding u16 parent_id; 1257b6ba80b4SDamon Ding /* 1258b6ba80b4SDamon Ding * @module_id_mask: module id of which module this power domain is belongs to. 1259b6ba80b4SDamon Ding * PD_CLUSTER0,1,2,3 only belongs to CLUSTER0/1/2/3, PD_Esmart0 shared by Esmart1/2/3 1260b6ba80b4SDamon Ding */ 1261b6ba80b4SDamon Ding u32 module_id_mask; 126260e469f5SDamon Ding }; 126360e469f5SDamon Ding 1264b0989546SSandy Huang struct vop2_win_data { 1265b0989546SSandy Huang char *name; 126663cb669fSSandy Huang u8 phys_id; 1267ecc31b6eSAndy Yan enum vop2_layer_type type; 1268b0989546SSandy Huang u8 win_sel_port_offset; 12695fa6e665SDamon Ding u8 layer_sel_win_id[VOP2_VP_MAX]; 1270a33b790fSDamon Ding u8 axi_id; 1271a33b790fSDamon Ding u8 axi_uv_id; 1272a33b790fSDamon Ding u8 axi_yrgb_id; 1273ee01dbb2SDamon Ding u8 splice_win_id; 12745fa6e665SDamon Ding u8 hsu_filter_mode; 12755fa6e665SDamon Ding u8 hsd_filter_mode; 12765fa6e665SDamon Ding u8 vsu_filter_mode; 12775fa6e665SDamon Ding u8 vsd_filter_mode; 12785fa6e665SDamon Ding u8 hsd_pre_filter_mode; 12795fa6e665SDamon Ding u8 vsd_pre_filter_mode; 12805fa6e665SDamon Ding u8 scale_engine_num; 12811c9572c7SDamon Ding u8 source_win_id; 1282a552a69cSDamon Ding u8 possible_crtcs; 1283a552a69cSDamon Ding u16 pd_id; 1284b0989546SSandy Huang u32 reg_offset; 12854c765862SDamon Ding u32 max_upscale_factor; 12864c765862SDamon Ding u32 max_downscale_factor; 12871c9572c7SDamon Ding u32 feature; 1288a552a69cSDamon Ding u32 supported_rotations; 1289ee01dbb2SDamon Ding bool splice_mode_right; 129063cb669fSSandy Huang }; 129163cb669fSSandy Huang 129263cb669fSSandy Huang struct vop2_vp_data { 129363cb669fSSandy Huang u32 feature; 129463cb669fSSandy Huang u8 pre_scan_max_dly; 1295452afb13SDamon Ding u8 layer_mix_dly; 1296a552a69cSDamon Ding u8 hdrvivid_dly; 1297a552a69cSDamon Ding u8 sdr2hdr_dly; 1298452afb13SDamon Ding u8 hdr_mix_dly; 1299452afb13SDamon Ding u8 win_dly; 1300ee01dbb2SDamon Ding u8 splice_vp_id; 1301a552a69cSDamon Ding u8 pixel_rate; 130263cb669fSSandy Huang struct vop_rect max_output; 1303ecc31b6eSAndy Yan u32 max_dclk; 1304d0408543SAndy Yan }; 1305d0408543SAndy Yan 1306ee008497SSandy Huang struct vop2_plane_table { 1307ee008497SSandy Huang enum vop2_layer_phy_id plane_id; 1308ee008497SSandy Huang enum vop2_layer_type plane_type; 1309ee008497SSandy Huang }; 1310ee008497SSandy Huang 1311b0989546SSandy Huang struct vop2_vp_plane_mask { 1312b0989546SSandy Huang u8 primary_plane_id; /* use this win to show logo */ 1313b0989546SSandy Huang u8 attached_layers_nr; /* number layers attach to this vp */ 1314b0989546SSandy Huang u8 attached_layers[VOP2_LAYER_MAX]; /* the layers attached to this vp */ 1315b0989546SSandy Huang u32 plane_mask; 1316ee008497SSandy Huang int cursor_plane_id; 1317b0989546SSandy Huang }; 1318b0989546SSandy Huang 131912ee5af0SDamon Ding struct vop2_dsc_data { 132012ee5af0SDamon Ding u8 id; 132112ee5af0SDamon Ding u8 max_slice_num; 132212ee5af0SDamon Ding u8 max_linebuf_depth; /* used to generate the bitstream */ 132312ee5af0SDamon Ding u8 min_bits_per_pixel; /* bit num after encoder compress */ 1324a552a69cSDamon Ding u16 pd_id; 132512ee5af0SDamon Ding const char *dsc_txp_clk_src_name; 132612ee5af0SDamon Ding const char *dsc_txp_clk_name; 132712ee5af0SDamon Ding const char *dsc_pxl_clk_name; 132812ee5af0SDamon Ding const char *dsc_cds_clk_name; 132912ee5af0SDamon Ding }; 133012ee5af0SDamon Ding 133112ee5af0SDamon Ding struct dsc_error_info { 133212ee5af0SDamon Ding u32 dsc_error_val; 133312ee5af0SDamon Ding char dsc_error_info[50]; 133412ee5af0SDamon Ding }; 133512ee5af0SDamon Ding 133672388c26SDamon Ding struct vop2_dump_regs { 133772388c26SDamon Ding u32 offset; 133872388c26SDamon Ding const char *name; 133972388c26SDamon Ding u32 state_base; 134072388c26SDamon Ding u32 state_mask; 134172388c26SDamon Ding u32 state_shift; 134272388c26SDamon Ding bool enable_state; 1343a552a69cSDamon Ding u32 size; 1344a552a69cSDamon Ding }; 1345a552a69cSDamon Ding 1346a552a69cSDamon Ding struct vop2_esmart_lb_map { 1347a552a69cSDamon Ding u8 lb_mode; 1348a552a69cSDamon Ding u8 lb_map_value; 134972388c26SDamon Ding }; 135072388c26SDamon Ding 1351d0408543SAndy Yan struct vop2_data { 135252ee18acSSandy Huang u32 version; 13535fa6e665SDamon Ding u32 esmart_lb_mode; 135463cb669fSSandy Huang struct vop2_vp_data *vp_data; 1355b0989546SSandy Huang struct vop2_win_data *win_data; 1356b0989546SSandy Huang struct vop2_vp_plane_mask *plane_mask; 1357ee008497SSandy Huang struct vop2_plane_table *plane_table; 1358b6ba80b4SDamon Ding struct vop2_power_domain_data *pd; 135912ee5af0SDamon Ding struct vop2_dsc_data *dsc; 136012ee5af0SDamon Ding struct dsc_error_info *dsc_error_ecw; 136112ee5af0SDamon Ding struct dsc_error_info *dsc_error_buffer_flow; 136272388c26SDamon Ding struct vop2_dump_regs *dump_regs; 1363a552a69cSDamon Ding const struct vop2_esmart_lb_map *esmart_lb_mode_map; 1364337d1c13SDamon Ding u8 *vp_primary_plane_order; 1365a552a69cSDamon Ding u8 *vp_default_primary_plane; 136663cb669fSSandy Huang u8 nr_vps; 136763cb669fSSandy Huang u8 nr_layers; 136863cb669fSSandy Huang u8 nr_mixers; 13691147facaSSandy Huang u8 nr_gammas; 1370b6ba80b4SDamon Ding u8 nr_pd; 137112ee5af0SDamon Ding u8 nr_dscs; 137212ee5af0SDamon Ding u8 nr_dsc_ecw; 137312ee5af0SDamon Ding u8 nr_dsc_buffer_flow; 1374a552a69cSDamon Ding u8 esmart_lb_mode_num; 1375ecc31b6eSAndy Yan u32 reg_len; 137672388c26SDamon Ding u32 dump_regs_size; 1377d0408543SAndy Yan }; 1378d0408543SAndy Yan 1379d0408543SAndy Yan struct vop2 { 1380d0408543SAndy Yan u32 *regsbak; 1381d0408543SAndy Yan void *regs; 1382d0408543SAndy Yan void *grf; 1383ecc31b6eSAndy Yan void *vop_grf; 1384ecc31b6eSAndy Yan void *vo1_grf; 138560e469f5SDamon Ding void *sys_pmu; 1386a552a69cSDamon Ding void *ioc_grf; 138752ee18acSSandy Huang u32 reg_len; 138852ee18acSSandy Huang u32 version; 13895fa6e665SDamon Ding u32 esmart_lb_mode; 139063cb669fSSandy Huang bool global_init; 1391a552a69cSDamon Ding bool merge_irq; 1392d0408543SAndy Yan const struct vop2_data *data; 1393b0989546SSandy Huang struct vop2_vp_plane_mask vp_plane_mask[VOP2_VP_MAX]; 1394d0408543SAndy Yan }; 1395d0408543SAndy Yan 1396d0408543SAndy Yan static struct vop2 *rockchip_vop2; 13975fa6e665SDamon Ding 13985fa6e665SDamon Ding static inline bool is_vop3(struct vop2 *vop2) 13995fa6e665SDamon Ding { 14005fa6e665SDamon Ding if (vop2->version == VOP_VERSION_RK3568 || vop2->version == VOP_VERSION_RK3588) 14015fa6e665SDamon Ding return false; 14025fa6e665SDamon Ding else 14035fa6e665SDamon Ding return true; 14045fa6e665SDamon Ding } 14055fa6e665SDamon Ding 14063e39a5a1SSandy Huang /* 14073e39a5a1SSandy Huang * bli_sd_factor = (src - 1) / (dst - 1) << 12; 14083e39a5a1SSandy Huang * avg_sd_factor: 14093e39a5a1SSandy Huang * bli_su_factor: 14103e39a5a1SSandy Huang * bic_su_factor: 14113e39a5a1SSandy Huang * = (src - 1) / (dst - 1) << 16; 14123e39a5a1SSandy Huang * 14135fa6e665SDamon Ding * ygt2 enable: dst get one line from two line of the src 14145fa6e665SDamon Ding * ygt4 enable: dst get one line from four line of the src. 14153e39a5a1SSandy Huang * 14163e39a5a1SSandy Huang */ 14173e39a5a1SSandy Huang #define VOP2_BILI_SCL_DN(src, dst) (((src - 1) << 12) / (dst - 1)) 14183e39a5a1SSandy Huang #define VOP2_COMMON_SCL(src, dst) (((src - 1) << 16) / (dst - 1)) 14193e39a5a1SSandy Huang 14203e39a5a1SSandy Huang #define VOP2_BILI_SCL_FAC_CHECK(src, dst, fac) \ 14213e39a5a1SSandy Huang (fac * (dst - 1) >> 12 < (src - 1)) 14223e39a5a1SSandy Huang #define VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac) \ 14233e39a5a1SSandy Huang (fac * (dst - 1) >> 16 < (src - 1)) 14245fa6e665SDamon Ding #define VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac) \ 14255fa6e665SDamon Ding (fac * (dst - 1) >> 16 < (src - 1)) 14263e39a5a1SSandy Huang 14273e39a5a1SSandy Huang static uint16_t vop2_scale_factor(enum scale_mode mode, 14283e39a5a1SSandy Huang int32_t filter_mode, 14293e39a5a1SSandy Huang uint32_t src, uint32_t dst) 14303e39a5a1SSandy Huang { 14313e39a5a1SSandy Huang uint32_t fac = 0; 14323e39a5a1SSandy Huang int i = 0; 14333e39a5a1SSandy Huang 14343e39a5a1SSandy Huang if (mode == SCALE_NONE) 14353e39a5a1SSandy Huang return 0; 14363e39a5a1SSandy Huang 14373e39a5a1SSandy Huang /* 14383e39a5a1SSandy Huang * A workaround to avoid zero div. 14393e39a5a1SSandy Huang */ 14403e39a5a1SSandy Huang if ((dst == 1) || (src == 1)) { 14413e39a5a1SSandy Huang dst = dst + 1; 14423e39a5a1SSandy Huang src = src + 1; 14433e39a5a1SSandy Huang } 14443e39a5a1SSandy Huang 14453e39a5a1SSandy Huang if ((mode == SCALE_DOWN) && (filter_mode == VOP2_SCALE_DOWN_BIL)) { 14463e39a5a1SSandy Huang fac = VOP2_BILI_SCL_DN(src, dst); 14473e39a5a1SSandy Huang for (i = 0; i < 100; i++) { 14483e39a5a1SSandy Huang if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac)) 14493e39a5a1SSandy Huang break; 14503e39a5a1SSandy Huang fac -= 1; 14513e39a5a1SSandy Huang printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 14523e39a5a1SSandy Huang } 14533e39a5a1SSandy Huang } else { 14543e39a5a1SSandy Huang fac = VOP2_COMMON_SCL(src, dst); 14553e39a5a1SSandy Huang for (i = 0; i < 100; i++) { 14563e39a5a1SSandy Huang if (VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac)) 14573e39a5a1SSandy Huang break; 14583e39a5a1SSandy Huang fac -= 1; 14593e39a5a1SSandy Huang printf("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 14603e39a5a1SSandy Huang } 14613e39a5a1SSandy Huang } 14623e39a5a1SSandy Huang 14633e39a5a1SSandy Huang return fac; 14643e39a5a1SSandy Huang } 14653e39a5a1SSandy Huang 14665fa6e665SDamon Ding static bool vop3_scale_up_fac_check(uint32_t src, uint32_t dst, uint32_t fac, bool is_hor) 14675fa6e665SDamon Ding { 14685fa6e665SDamon Ding if (is_hor) 14695fa6e665SDamon Ding return VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac); 14705fa6e665SDamon Ding return VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac); 14715fa6e665SDamon Ding } 14725fa6e665SDamon Ding 14735fa6e665SDamon Ding static uint16_t vop3_scale_factor(enum scale_mode mode, 14745fa6e665SDamon Ding uint32_t src, uint32_t dst, bool is_hor) 14755fa6e665SDamon Ding { 14765fa6e665SDamon Ding uint32_t fac = 0; 14775fa6e665SDamon Ding int i = 0; 14785fa6e665SDamon Ding 14795fa6e665SDamon Ding if (mode == SCALE_NONE) 14805fa6e665SDamon Ding return 0; 14815fa6e665SDamon Ding 14825fa6e665SDamon Ding /* 14835fa6e665SDamon Ding * A workaround to avoid zero div. 14845fa6e665SDamon Ding */ 14855fa6e665SDamon Ding if ((dst == 1) || (src == 1)) { 14865fa6e665SDamon Ding dst = dst + 1; 14875fa6e665SDamon Ding src = src + 1; 14885fa6e665SDamon Ding } 14895fa6e665SDamon Ding 14905fa6e665SDamon Ding if (mode == SCALE_DOWN) { 14915fa6e665SDamon Ding fac = VOP2_BILI_SCL_DN(src, dst); 14925fa6e665SDamon Ding for (i = 0; i < 100; i++) { 14935fa6e665SDamon Ding if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac)) 14945fa6e665SDamon Ding break; 14955fa6e665SDamon Ding fac -= 1; 14965fa6e665SDamon Ding printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 14975fa6e665SDamon Ding } 14985fa6e665SDamon Ding } else { 14995fa6e665SDamon Ding fac = VOP2_COMMON_SCL(src, dst); 15005fa6e665SDamon Ding for (i = 0; i < 100; i++) { 15015fa6e665SDamon Ding if (vop3_scale_up_fac_check(src, dst, fac, is_hor)) 15025fa6e665SDamon Ding break; 15035fa6e665SDamon Ding fac -= 1; 15045fa6e665SDamon Ding printf("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 15055fa6e665SDamon Ding } 15065fa6e665SDamon Ding } 15075fa6e665SDamon Ding 15085fa6e665SDamon Ding return fac; 15095fa6e665SDamon Ding } 15105fa6e665SDamon Ding 15113e39a5a1SSandy Huang static inline enum scale_mode scl_get_scl_mode(int src, int dst) 15123e39a5a1SSandy Huang { 15133e39a5a1SSandy Huang if (src < dst) 15143e39a5a1SSandy Huang return SCALE_UP; 15153e39a5a1SSandy Huang else if (src > dst) 15163e39a5a1SSandy Huang return SCALE_DOWN; 15173e39a5a1SSandy Huang 15183e39a5a1SSandy Huang return SCALE_NONE; 15193e39a5a1SSandy Huang } 1520d0408543SAndy Yan 1521ac500a1fSSandy Huang static inline int interpolate(int x1, int y1, int x2, int y2, int x) 1522ac500a1fSSandy Huang { 1523ac500a1fSSandy Huang return y1 + (y2 - y1) * (x - x1) / (x2 - x1); 1524ac500a1fSSandy Huang } 1525ac500a1fSSandy Huang 1526b0989546SSandy Huang static int vop2_get_primary_plane(struct vop2 *vop2, u32 plane_mask) 1527b0989546SSandy Huang { 1528b0989546SSandy Huang int i = 0; 1529ecc31b6eSAndy Yan 1530337d1c13SDamon Ding for (i = 0; i < vop2->data->nr_layers; i++) { 1531337d1c13SDamon Ding if (plane_mask & BIT(vop2->data->vp_primary_plane_order[i])) 1532337d1c13SDamon Ding return vop2->data->vp_primary_plane_order[i]; 1533ecc31b6eSAndy Yan } 1534b0989546SSandy Huang 1535337d1c13SDamon Ding return vop2->data->vp_primary_plane_order[0]; 1536b0989546SSandy Huang } 1537b0989546SSandy Huang 153863cb669fSSandy Huang static inline u16 scl_cal_scale(int src, int dst, int shift) 1539d0408543SAndy Yan { 1540d0408543SAndy Yan return ((src * 2 - 3) << (shift - 1)) / (dst - 1); 1541d0408543SAndy Yan } 1542d0408543SAndy Yan 154363cb669fSSandy Huang static inline u16 scl_cal_scale2(int src, int dst) 1544d0408543SAndy Yan { 1545d0408543SAndy Yan return ((src - 1) << 12) / (dst - 1); 1546d0408543SAndy Yan } 1547d0408543SAndy Yan 154852ee18acSSandy Huang static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v) 1549d0408543SAndy Yan { 1550d0408543SAndy Yan writel(v, vop2->regs + offset); 1551d0408543SAndy Yan vop2->regsbak[offset >> 2] = v; 1552d0408543SAndy Yan } 1553d0408543SAndy Yan 155452ee18acSSandy Huang static inline u32 vop2_readl(struct vop2 *vop2, u32 offset) 1555d0408543SAndy Yan { 1556d0408543SAndy Yan return readl(vop2->regs + offset); 1557d0408543SAndy Yan } 1558d0408543SAndy Yan 155952ee18acSSandy Huang static inline void vop2_mask_write(struct vop2 *vop2, u32 offset, 156052ee18acSSandy Huang u32 mask, u32 shift, u32 v, 1561d0408543SAndy Yan bool write_mask) 1562d0408543SAndy Yan { 1563d0408543SAndy Yan if (!mask) 1564d0408543SAndy Yan return; 1565d0408543SAndy Yan 1566d0408543SAndy Yan if (write_mask) { 1567d0408543SAndy Yan v = ((v & mask) << shift) | (mask << (shift + 16)); 1568d0408543SAndy Yan } else { 156952ee18acSSandy Huang u32 cached_val = vop2->regsbak[offset >> 2]; 1570d0408543SAndy Yan 1571d0408543SAndy Yan v = (cached_val & ~(mask << shift)) | ((v & mask) << shift); 1572d0408543SAndy Yan vop2->regsbak[offset >> 2] = v; 1573d0408543SAndy Yan } 1574d0408543SAndy Yan 1575d0408543SAndy Yan writel(v, vop2->regs + offset); 1576d0408543SAndy Yan } 1577d0408543SAndy Yan 1578ecc31b6eSAndy Yan static inline void vop2_grf_writel(struct vop2 *vop, void *grf_base, u32 offset, 157952ee18acSSandy Huang u32 mask, u32 shift, u32 v) 158052ee18acSSandy Huang { 158152ee18acSSandy Huang u32 val = 0; 158252ee18acSSandy Huang 158352ee18acSSandy Huang val = (v << shift) | (mask << (shift + 16)); 1584ecc31b6eSAndy Yan writel(val, grf_base + offset); 158552ee18acSSandy Huang } 158652ee18acSSandy Huang 158760e469f5SDamon Ding static inline u32 vop2_grf_readl(struct vop2 *vop, void *grf_base, u32 offset, 158860e469f5SDamon Ding u32 mask, u32 shift) 158960e469f5SDamon Ding { 159060e469f5SDamon Ding return (readl(grf_base + offset) >> shift) & mask; 159160e469f5SDamon Ding } 159260e469f5SDamon Ding 15938895aec1SSandy Huang static char *get_plane_name(int plane_id, char *name) 15948895aec1SSandy Huang { 15958895aec1SSandy Huang switch (plane_id) { 15968895aec1SSandy Huang case ROCKCHIP_VOP2_CLUSTER0: 15978895aec1SSandy Huang strcat(name, "Cluster0"); 15988895aec1SSandy Huang break; 15998895aec1SSandy Huang case ROCKCHIP_VOP2_CLUSTER1: 16008895aec1SSandy Huang strcat(name, "Cluster1"); 16018895aec1SSandy Huang break; 16028895aec1SSandy Huang case ROCKCHIP_VOP2_ESMART0: 16038895aec1SSandy Huang strcat(name, "Esmart0"); 16048895aec1SSandy Huang break; 16058895aec1SSandy Huang case ROCKCHIP_VOP2_ESMART1: 16068895aec1SSandy Huang strcat(name, "Esmart1"); 16078895aec1SSandy Huang break; 16088895aec1SSandy Huang case ROCKCHIP_VOP2_SMART0: 16098895aec1SSandy Huang strcat(name, "Smart0"); 16108895aec1SSandy Huang break; 16118895aec1SSandy Huang case ROCKCHIP_VOP2_SMART1: 16128895aec1SSandy Huang strcat(name, "Smart1"); 16138895aec1SSandy Huang break; 16148895aec1SSandy Huang case ROCKCHIP_VOP2_CLUSTER2: 16158895aec1SSandy Huang strcat(name, "Cluster2"); 16168895aec1SSandy Huang break; 16178895aec1SSandy Huang case ROCKCHIP_VOP2_CLUSTER3: 16188895aec1SSandy Huang strcat(name, "Cluster3"); 16198895aec1SSandy Huang break; 16208895aec1SSandy Huang case ROCKCHIP_VOP2_ESMART2: 16218895aec1SSandy Huang strcat(name, "Esmart2"); 16228895aec1SSandy Huang break; 16238895aec1SSandy Huang case ROCKCHIP_VOP2_ESMART3: 16248895aec1SSandy Huang strcat(name, "Esmart3"); 16258895aec1SSandy Huang break; 16268895aec1SSandy Huang } 16278895aec1SSandy Huang 16288895aec1SSandy Huang return name; 16298895aec1SSandy Huang } 16308895aec1SSandy Huang 163152ee18acSSandy Huang static bool is_yuv_output(u32 bus_format) 1632d0408543SAndy Yan { 1633d0408543SAndy Yan switch (bus_format) { 1634d0408543SAndy Yan case MEDIA_BUS_FMT_YUV8_1X24: 1635d0408543SAndy Yan case MEDIA_BUS_FMT_YUV10_1X30: 1636034a46b5SAlgea Cao case MEDIA_BUS_FMT_YUYV10_1X20: 1637d0408543SAndy Yan case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 1638d0408543SAndy Yan case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 1639a0ea2d92SDamon Ding case MEDIA_BUS_FMT_YUYV8_2X8: 1640a0ea2d92SDamon Ding case MEDIA_BUS_FMT_YVYU8_2X8: 1641a0ea2d92SDamon Ding case MEDIA_BUS_FMT_UYVY8_2X8: 1642a0ea2d92SDamon Ding case MEDIA_BUS_FMT_VYUY8_2X8: 1643a0ea2d92SDamon Ding case MEDIA_BUS_FMT_YUYV8_1X16: 1644a0ea2d92SDamon Ding case MEDIA_BUS_FMT_YVYU8_1X16: 1645a0ea2d92SDamon Ding case MEDIA_BUS_FMT_UYVY8_1X16: 1646a0ea2d92SDamon Ding case MEDIA_BUS_FMT_VYUY8_1X16: 1647d0408543SAndy Yan return true; 1648d0408543SAndy Yan default: 1649d0408543SAndy Yan return false; 1650d0408543SAndy Yan } 1651d0408543SAndy Yan } 1652d0408543SAndy Yan 1653df0a5c43SDamon Ding static enum vop_csc_format vop2_convert_csc_mode(enum drm_color_encoding color_encoding, 1654df0a5c43SDamon Ding enum drm_color_range color_range, 1655df0a5c43SDamon Ding int bit_depth) 165610ee9f5bSAlgea Cao { 1657df0a5c43SDamon Ding bool full_range = color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0; 1658df0a5c43SDamon Ding enum vop_csc_format csc_mode = CSC_BT709L; 1659df0a5c43SDamon Ding 1660df0a5c43SDamon Ding 1661df0a5c43SDamon Ding switch (color_encoding) { 1662df0a5c43SDamon Ding case DRM_COLOR_YCBCR_BT601: 1663df0a5c43SDamon Ding if (full_range) 1664df0a5c43SDamon Ding csc_mode = CSC_BT601F; 16655fa6e665SDamon Ding else 1666df0a5c43SDamon Ding csc_mode = CSC_BT601L; 1667df0a5c43SDamon Ding break; 1668df0a5c43SDamon Ding 1669df0a5c43SDamon Ding case DRM_COLOR_YCBCR_BT709: 1670df0a5c43SDamon Ding if (full_range) { 1671df0a5c43SDamon Ding csc_mode = bit_depth == CSC_13BIT_DEPTH ? CSC_BT709F_13BIT : CSC_BT601F; 1672df0a5c43SDamon Ding if (bit_depth != CSC_13BIT_DEPTH) 1673df0a5c43SDamon Ding printf("Unsupported bt709f at 10bit csc depth, use bt601f instead\n"); 16745fa6e665SDamon Ding } else { 1675df0a5c43SDamon Ding csc_mode = CSC_BT709L; 16765fa6e665SDamon Ding } 1677df0a5c43SDamon Ding break; 1678df0a5c43SDamon Ding 1679df0a5c43SDamon Ding case DRM_COLOR_YCBCR_BT2020: 1680df0a5c43SDamon Ding if (full_range) { 1681df0a5c43SDamon Ding csc_mode = bit_depth == CSC_13BIT_DEPTH ? CSC_BT2020F_13BIT : CSC_BT601F; 1682df0a5c43SDamon Ding if (bit_depth != CSC_13BIT_DEPTH) 1683df0a5c43SDamon Ding printf("Unsupported bt2020f at 10bit csc depth, use bt601f instead\n"); 16845fa6e665SDamon Ding } else { 1685df0a5c43SDamon Ding csc_mode = bit_depth == CSC_13BIT_DEPTH ? CSC_BT2020L_13BIT : CSC_BT2020L; 16865fa6e665SDamon Ding } 1687df0a5c43SDamon Ding break; 1688df0a5c43SDamon Ding 168910ee9f5bSAlgea Cao default: 1690df0a5c43SDamon Ding printf("Unsuport color_encoding:%d\n", color_encoding); 169110ee9f5bSAlgea Cao } 1692df0a5c43SDamon Ding 1693df0a5c43SDamon Ding return csc_mode; 169410ee9f5bSAlgea Cao } 169510ee9f5bSAlgea Cao 1696b0989546SSandy Huang static bool is_uv_swap(u32 bus_format, u32 output_mode) 1697d0408543SAndy Yan { 1698d0408543SAndy Yan /* 1699d0408543SAndy Yan * FIXME: 1700d0408543SAndy Yan * 1701d0408543SAndy Yan * There is no media type for YUV444 output, 1702d0408543SAndy Yan * so when out_mode is AAAA or P888, assume output is YUV444 on 1703d0408543SAndy Yan * yuv format. 1704d0408543SAndy Yan * 1705d0408543SAndy Yan * From H/W testing, YUV444 mode need a rb swap. 1706d0408543SAndy Yan */ 17073e59c137SSandy Huang if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 || 17083e59c137SSandy Huang bus_format == MEDIA_BUS_FMT_VYUY8_1X16 || 17093e59c137SSandy Huang bus_format == MEDIA_BUS_FMT_YVYU8_2X8 || 17103e59c137SSandy Huang bus_format == MEDIA_BUS_FMT_VYUY8_2X8 || 17113e59c137SSandy Huang ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 1712d0408543SAndy Yan bus_format == MEDIA_BUS_FMT_YUV10_1X30) && 1713d0408543SAndy Yan (output_mode == ROCKCHIP_OUT_MODE_AAAA || 17143e59c137SSandy Huang output_mode == ROCKCHIP_OUT_MODE_P888))) 1715d0408543SAndy Yan return true; 1716d0408543SAndy Yan else 1717d0408543SAndy Yan return false; 1718d0408543SAndy Yan } 1719d0408543SAndy Yan 17200675a2a4SDamon Ding static bool is_rb_swap(u32 bus_format, u32 output_mode) 17210675a2a4SDamon Ding { 17220675a2a4SDamon Ding /* 17230675a2a4SDamon Ding * The default component order of serial rgb3x8 formats 17240675a2a4SDamon Ding * is BGR. So it is needed to enable RB swap. 17250675a2a4SDamon Ding */ 1726b7b383ebSDamon Ding if (bus_format == MEDIA_BUS_FMT_RGB888_3X8 || 1727b7b383ebSDamon Ding bus_format == MEDIA_BUS_FMT_RGB888_DUMMY_4X8) 17280675a2a4SDamon Ding return true; 17290675a2a4SDamon Ding else 17300675a2a4SDamon Ding return false; 17310675a2a4SDamon Ding } 17320675a2a4SDamon Ding 17335d2768f7SDamon Ding static bool is_yc_swap(u32 bus_format) 17345d2768f7SDamon Ding { 17355d2768f7SDamon Ding switch (bus_format) { 17365d2768f7SDamon Ding case MEDIA_BUS_FMT_YUYV8_1X16: 17375d2768f7SDamon Ding case MEDIA_BUS_FMT_YVYU8_1X16: 17385d2768f7SDamon Ding case MEDIA_BUS_FMT_YUYV8_2X8: 17395d2768f7SDamon Ding case MEDIA_BUS_FMT_YVYU8_2X8: 17405d2768f7SDamon Ding return true; 17415d2768f7SDamon Ding default: 17425d2768f7SDamon Ding return false; 17435d2768f7SDamon Ding } 17445d2768f7SDamon Ding } 17455d2768f7SDamon Ding 1746b0989546SSandy Huang static inline bool is_hot_plug_devices(int output_type) 174763cb669fSSandy Huang { 1748b0989546SSandy Huang switch (output_type) { 1749b0989546SSandy Huang case DRM_MODE_CONNECTOR_HDMIA: 1750b0989546SSandy Huang case DRM_MODE_CONNECTOR_HDMIB: 1751b0989546SSandy Huang case DRM_MODE_CONNECTOR_TV: 1752b0989546SSandy Huang case DRM_MODE_CONNECTOR_DisplayPort: 1753b0989546SSandy Huang case DRM_MODE_CONNECTOR_VGA: 1754b0989546SSandy Huang case DRM_MODE_CONNECTOR_Unknown: 1755b0989546SSandy Huang return true; 1756b0989546SSandy Huang default: 1757b0989546SSandy Huang return false; 175863cb669fSSandy Huang } 175963cb669fSSandy Huang } 176063cb669fSSandy Huang 1761ecc31b6eSAndy Yan static struct vop2_win_data *vop2_find_win_by_phys_id(struct vop2 *vop2, int phys_id) 1762ecc31b6eSAndy Yan { 1763ecc31b6eSAndy Yan int i = 0; 1764ecc31b6eSAndy Yan 1765ecc31b6eSAndy Yan for (i = 0; i < vop2->data->nr_layers; i++) { 1766ecc31b6eSAndy Yan if (vop2->data->win_data[i].phys_id == phys_id) 1767ecc31b6eSAndy Yan return &vop2->data->win_data[i]; 1768ecc31b6eSAndy Yan } 1769ecc31b6eSAndy Yan 1770ecc31b6eSAndy Yan return NULL; 1771ecc31b6eSAndy Yan } 1772ecc31b6eSAndy Yan 1773b6ba80b4SDamon Ding static struct vop2_power_domain_data *vop2_find_pd_data_by_id(struct vop2 *vop2, int pd_id) 1774b6ba80b4SDamon Ding { 1775b6ba80b4SDamon Ding int i = 0; 1776b6ba80b4SDamon Ding 1777b6ba80b4SDamon Ding for (i = 0; i < vop2->data->nr_pd; i++) { 1778b6ba80b4SDamon Ding if (vop2->data->pd[i].id == pd_id) 1779b6ba80b4SDamon Ding return &vop2->data->pd[i]; 1780b6ba80b4SDamon Ding } 1781b6ba80b4SDamon Ding 1782b6ba80b4SDamon Ding return NULL; 1783b6ba80b4SDamon Ding } 1784b6ba80b4SDamon Ding 1785db328a0dSDamon Ding static void rk3568_vop2_load_lut(struct vop2 *vop2, int crtc_id, 1786db328a0dSDamon Ding u32 *lut_regs, u32 *lut_val, int lut_len) 1787db328a0dSDamon Ding { 1788db328a0dSDamon Ding u32 vp_offset = crtc_id * 0x100; 1789db328a0dSDamon Ding int i; 1790db328a0dSDamon Ding 1791db328a0dSDamon Ding vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, 1792db328a0dSDamon Ding GAMMA_PORT_SEL_MASK, GAMMA_PORT_SEL_SHIFT, 1793db328a0dSDamon Ding crtc_id, false); 1794db328a0dSDamon Ding 1795db328a0dSDamon Ding for (i = 0; i < lut_len; i++) 1796db328a0dSDamon Ding writel(lut_val[i], lut_regs + i); 1797db328a0dSDamon Ding 1798db328a0dSDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1799db328a0dSDamon Ding EN_MASK, DSP_LUT_EN_SHIFT, 1, false); 1800db328a0dSDamon Ding } 1801db328a0dSDamon Ding 1802db328a0dSDamon Ding static void rk3588_vop2_load_lut(struct vop2 *vop2, int crtc_id, 1803db328a0dSDamon Ding u32 *lut_regs, u32 *lut_val, int lut_len) 1804db328a0dSDamon Ding { 1805db328a0dSDamon Ding u32 vp_offset = crtc_id * 0x100; 1806db328a0dSDamon Ding int i; 1807db328a0dSDamon Ding 1808db328a0dSDamon Ding vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, 1809db328a0dSDamon Ding GAMMA_AHB_WRITE_SEL_MASK, GAMMA_AHB_WRITE_SEL_SHIFT, 1810db328a0dSDamon Ding crtc_id, false); 1811db328a0dSDamon Ding 1812db328a0dSDamon Ding for (i = 0; i < lut_len; i++) 1813db328a0dSDamon Ding writel(lut_val[i], lut_regs + i); 1814db328a0dSDamon Ding 1815db328a0dSDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1816db328a0dSDamon Ding EN_MASK, DSP_LUT_EN_SHIFT, 1, false); 1817db328a0dSDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1818db328a0dSDamon Ding EN_MASK, GAMMA_UPDATE_EN_SHIFT, 1, false); 1819db328a0dSDamon Ding } 1820db328a0dSDamon Ding 18211147facaSSandy Huang static int rockchip_vop2_gamma_lut_init(struct vop2 *vop2, 1822d0408543SAndy Yan struct display_state *state) 1823d0408543SAndy Yan { 18241147facaSSandy Huang struct connector_state *conn_state = &state->conn_state; 18251147facaSSandy Huang struct crtc_state *cstate = &state->crtc_state; 18261147facaSSandy Huang struct resource gamma_res; 18271147facaSSandy Huang fdt_size_t lut_size; 18281147facaSSandy Huang int i, lut_len, ret = 0; 18291147facaSSandy Huang u32 *lut_regs; 18301147facaSSandy Huang u32 *lut_val; 18311147facaSSandy Huang u32 r, g, b; 18321147facaSSandy Huang struct base2_disp_info *disp_info = conn_state->disp_info; 18331147facaSSandy Huang static int gamma_lut_en_num = 1; 18341147facaSSandy Huang 18351147facaSSandy Huang if (gamma_lut_en_num > vop2->data->nr_gammas) { 18361147facaSSandy Huang printf("warn: only %d vp support gamma\n", vop2->data->nr_gammas); 18371147facaSSandy Huang return 0; 18381147facaSSandy Huang } 18391147facaSSandy Huang 18401147facaSSandy Huang if (!disp_info) 18411147facaSSandy Huang return 0; 18421147facaSSandy Huang 18431147facaSSandy Huang if (!disp_info->gamma_lut_data.size) 18441147facaSSandy Huang return 0; 18451147facaSSandy Huang 18461147facaSSandy Huang ret = ofnode_read_resource_byname(cstate->node, "gamma_lut", &gamma_res); 18471147facaSSandy Huang if (ret) 18481147facaSSandy Huang printf("failed to get gamma lut res\n"); 18491147facaSSandy Huang lut_regs = (u32 *)gamma_res.start; 18501147facaSSandy Huang lut_size = gamma_res.end - gamma_res.start + 1; 18511147facaSSandy Huang if (lut_regs == (u32 *)FDT_ADDR_T_NONE) { 18521147facaSSandy Huang printf("failed to get gamma lut register\n"); 18531147facaSSandy Huang return 0; 18541147facaSSandy Huang } 18551147facaSSandy Huang lut_len = lut_size / 4; 18561147facaSSandy Huang if (lut_len != 256 && lut_len != 1024) { 18571147facaSSandy Huang printf("Warning: unsupport gamma lut table[%d]\n", lut_len); 18581147facaSSandy Huang return 0; 18591147facaSSandy Huang } 18601147facaSSandy Huang lut_val = (u32 *)calloc(1, lut_size); 18611147facaSSandy Huang for (i = 0; i < lut_len; i++) { 18621147facaSSandy Huang r = disp_info->gamma_lut_data.lred[i] * (lut_len - 1) / 0xffff; 18631147facaSSandy Huang g = disp_info->gamma_lut_data.lgreen[i] * (lut_len - 1) / 0xffff; 18641147facaSSandy Huang b = disp_info->gamma_lut_data.lblue[i] * (lut_len - 1) / 0xffff; 18651147facaSSandy Huang 18661147facaSSandy Huang lut_val[i] = b * lut_len * lut_len + g * lut_len + r; 18671147facaSSandy Huang } 18681147facaSSandy Huang 1869db328a0dSDamon Ding if (vop2->version == VOP_VERSION_RK3568) { 1870db328a0dSDamon Ding rk3568_vop2_load_lut(vop2, cstate->crtc_id, lut_regs, lut_val, lut_len); 18711147facaSSandy Huang gamma_lut_en_num++; 1872db328a0dSDamon Ding } else if (vop2->version == VOP_VERSION_RK3588) { 1873db328a0dSDamon Ding rk3588_vop2_load_lut(vop2, cstate->crtc_id, lut_regs, lut_val, lut_len); 1874db328a0dSDamon Ding if (cstate->splice_mode) { 1875db328a0dSDamon Ding rk3588_vop2_load_lut(vop2, cstate->splice_crtc_id, lut_regs, lut_val, lut_len); 1876db328a0dSDamon Ding gamma_lut_en_num++; 1877db328a0dSDamon Ding } 1878db328a0dSDamon Ding gamma_lut_en_num++; 1879db328a0dSDamon Ding } 18801147facaSSandy Huang 1881d0408543SAndy Yan return 0; 1882d0408543SAndy Yan } 1883d0408543SAndy Yan 18846414e3bcSSandy Huang static int rockchip_vop2_cubic_lut_init(struct vop2 *vop2, 18856414e3bcSSandy Huang struct display_state *state) 18866414e3bcSSandy Huang { 18876414e3bcSSandy Huang struct connector_state *conn_state = &state->conn_state; 18886414e3bcSSandy Huang struct crtc_state *cstate = &state->crtc_state; 18896414e3bcSSandy Huang int i, cubic_lut_len; 18906414e3bcSSandy Huang u32 vp_offset = cstate->crtc_id * 0x100; 18916414e3bcSSandy Huang struct base2_disp_info *disp_info = conn_state->disp_info; 18926414e3bcSSandy Huang struct base2_cubic_lut_data *lut = &conn_state->disp_info->cubic_lut_data; 18936414e3bcSSandy Huang u32 *cubic_lut_addr; 18946414e3bcSSandy Huang 18956414e3bcSSandy Huang if (!disp_info || CONFIG_ROCKCHIP_CUBIC_LUT_SIZE == 0) 18966414e3bcSSandy Huang return 0; 18976414e3bcSSandy Huang 18986414e3bcSSandy Huang if (!disp_info->cubic_lut_data.size) 18996414e3bcSSandy Huang return 0; 19006414e3bcSSandy Huang 19016414e3bcSSandy Huang cubic_lut_addr = (u32 *)get_cubic_lut_buffer(cstate->crtc_id); 19026414e3bcSSandy Huang cubic_lut_len = disp_info->cubic_lut_data.size; 19036414e3bcSSandy Huang 19046414e3bcSSandy Huang for (i = 0; i < cubic_lut_len / 2; i++) { 19056414e3bcSSandy Huang *cubic_lut_addr++ = ((lut->lred[2 * i]) & 0xfff) + 19066414e3bcSSandy Huang ((lut->lgreen[2 * i] & 0xfff) << 12) + 19076414e3bcSSandy Huang ((lut->lblue[2 * i] & 0xff) << 24); 19086414e3bcSSandy Huang *cubic_lut_addr++ = ((lut->lblue[2 * i] & 0xf00) >> 8) + 19096414e3bcSSandy Huang ((lut->lred[2 * i + 1] & 0xfff) << 4) + 19106414e3bcSSandy Huang ((lut->lgreen[2 * i + 1] & 0xfff) << 16) + 19116414e3bcSSandy Huang ((lut->lblue[2 * i + 1] & 0xf) << 28); 19126414e3bcSSandy Huang *cubic_lut_addr++ = (lut->lblue[2 * i + 1] & 0xff0) >> 4; 19136414e3bcSSandy Huang *cubic_lut_addr++ = 0; 19146414e3bcSSandy Huang } 19156414e3bcSSandy Huang 19166414e3bcSSandy Huang if (cubic_lut_len % 2) { 19176414e3bcSSandy Huang *cubic_lut_addr++ = (lut->lred[2 * i] & 0xfff) + 19186414e3bcSSandy Huang ((lut->lgreen[2 * i] & 0xfff) << 12) + 19196414e3bcSSandy Huang ((lut->lblue[2 * i] & 0xff) << 24); 19206414e3bcSSandy Huang *cubic_lut_addr++ = (lut->lblue[2 * i] & 0xf00) >> 8; 19216414e3bcSSandy Huang *cubic_lut_addr++ = 0; 19226414e3bcSSandy Huang *cubic_lut_addr = 0; 19236414e3bcSSandy Huang } 19246414e3bcSSandy Huang 19256414e3bcSSandy Huang vop2_writel(vop2, RK3568_VP0_3D_LUT_MST + vp_offset, 19266414e3bcSSandy Huang get_cubic_lut_buffer(cstate->crtc_id)); 19276414e3bcSSandy Huang vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL, 19286414e3bcSSandy Huang EN_MASK, LUT_DMA_EN_SHIFT, 1, false); 19296414e3bcSSandy Huang vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset, 19306414e3bcSSandy Huang EN_MASK, VP0_3D_LUT_EN_SHIFT, 1, false); 19316414e3bcSSandy Huang vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset, 19326414e3bcSSandy Huang EN_MASK, VP0_3D_LUT_UPDATE_SHIFT, 1, false); 19336414e3bcSSandy Huang 19346414e3bcSSandy Huang return 0; 19356414e3bcSSandy Huang } 19366414e3bcSSandy Huang 1937ee01dbb2SDamon Ding static void vop2_bcsh_reg_update(struct display_state *state, struct vop2 *vop2, 1938ee01dbb2SDamon Ding struct bcsh_state *bcsh_state, int crtc_id) 1939ee01dbb2SDamon Ding { 1940ee01dbb2SDamon Ding struct crtc_state *cstate = &state->crtc_state; 1941ee01dbb2SDamon Ding u32 vp_offset = crtc_id * 0x100; 1942ee01dbb2SDamon Ding 1943ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_MASK, 1944ee01dbb2SDamon Ding BCSH_CTRL_R2Y_SHIFT, cstate->post_r2y_en, false); 1945ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_MASK, 1946ee01dbb2SDamon Ding BCSH_CTRL_Y2R_SHIFT, cstate->post_y2r_en, false); 1947ee01dbb2SDamon Ding 1948ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_CSC_MODE_MASK, 1949ee01dbb2SDamon Ding BCSH_CTRL_R2Y_CSC_MODE_SHIFT, cstate->post_csc_mode, false); 1950ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_CSC_MODE_MASK, 1951ee01dbb2SDamon Ding BCSH_CTRL_Y2R_CSC_MODE_SHIFT, cstate->post_csc_mode, false); 1952ee01dbb2SDamon Ding 1953ee01dbb2SDamon Ding if (!cstate->bcsh_en) { 1954ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset, 1955ee01dbb2SDamon Ding BCSH_EN_MASK, BCSH_EN_SHIFT, 0, false); 1956ee01dbb2SDamon Ding return; 1957ee01dbb2SDamon Ding } 1958ee01dbb2SDamon Ding 1959ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1960ee01dbb2SDamon Ding BCSH_BRIGHTNESS_MASK, BCSH_BRIGHTNESS_SHIFT, 1961ee01dbb2SDamon Ding bcsh_state->brightness, false); 1962ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1963ee01dbb2SDamon Ding BCSH_CONTRAST_MASK, BCSH_CONTRAST_SHIFT, bcsh_state->contrast, false); 1964ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1965ee01dbb2SDamon Ding BCSH_SATURATION_MASK, BCSH_SATURATION_SHIFT, 1966ee01dbb2SDamon Ding bcsh_state->saturation * bcsh_state->contrast / 0x100, false); 1967ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset, 1968ee01dbb2SDamon Ding BCSH_SIN_HUE_MASK, BCSH_SIN_HUE_SHIFT, bcsh_state->sin_hue, false); 1969ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset, 1970ee01dbb2SDamon Ding BCSH_COS_HUE_MASK, BCSH_COS_HUE_SHIFT, bcsh_state->cos_hue, false); 1971ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1972ee01dbb2SDamon Ding BCSH_OUT_MODE_MASK, BCSH_OUT_MODE_SHIFT, 1973ee01dbb2SDamon Ding BCSH_OUT_MODE_NORMAL_VIDEO, false); 1974ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset, 1975ee01dbb2SDamon Ding BCSH_EN_MASK, BCSH_EN_SHIFT, 1, false); 1976ee01dbb2SDamon Ding } 1977ee01dbb2SDamon Ding 1978ac500a1fSSandy Huang static void vop2_tv_config_update(struct display_state *state, struct vop2 *vop2) 1979ac500a1fSSandy Huang { 1980ac500a1fSSandy Huang struct connector_state *conn_state = &state->conn_state; 1981ac500a1fSSandy Huang struct base_bcsh_info *bcsh_info; 1982ac500a1fSSandy Huang struct crtc_state *cstate = &state->crtc_state; 1983ee01dbb2SDamon Ding struct bcsh_state bcsh_state; 1984ac500a1fSSandy Huang int brightness, contrast, saturation, hue, sin_hue, cos_hue; 1985ac500a1fSSandy Huang 1986ac500a1fSSandy Huang if (!conn_state->disp_info) 1987ac500a1fSSandy Huang return; 1988ac500a1fSSandy Huang bcsh_info = &conn_state->disp_info->bcsh_info; 1989ac500a1fSSandy Huang if (!bcsh_info) 1990ac500a1fSSandy Huang return; 1991ac500a1fSSandy Huang 1992ac500a1fSSandy Huang if (bcsh_info->brightness != 50 || 1993ac500a1fSSandy Huang bcsh_info->contrast != 50 || 1994ac500a1fSSandy Huang bcsh_info->saturation != 50 || bcsh_info->hue != 50) 1995ee01dbb2SDamon Ding cstate->bcsh_en = true; 1996ac500a1fSSandy Huang 1997ee01dbb2SDamon Ding if (cstate->bcsh_en) { 1998ac500a1fSSandy Huang if (!cstate->yuv_overlay) 1999ee01dbb2SDamon Ding cstate->post_r2y_en = 1; 2000ac500a1fSSandy Huang if (!is_yuv_output(conn_state->bus_format)) 2001ee01dbb2SDamon Ding cstate->post_y2r_en = 1; 2002ac500a1fSSandy Huang } else { 2003ac500a1fSSandy Huang if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format)) 2004ee01dbb2SDamon Ding cstate->post_r2y_en = 1; 2005ac500a1fSSandy Huang if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format)) 2006ee01dbb2SDamon Ding cstate->post_y2r_en = 1; 2007ac500a1fSSandy Huang } 2008ac500a1fSSandy Huang 2009df0a5c43SDamon Ding cstate->post_csc_mode = vop2_convert_csc_mode(conn_state->color_encoding, 2010df0a5c43SDamon Ding conn_state->color_range, 2011df0a5c43SDamon Ding CSC_10BIT_DEPTH); 2012ac500a1fSSandy Huang 2013ac500a1fSSandy Huang if (cstate->feature & VOP_FEATURE_OUTPUT_10BIT) 2014ac500a1fSSandy Huang brightness = interpolate(0, -128, 100, 127, 2015ac500a1fSSandy Huang bcsh_info->brightness); 2016ac500a1fSSandy Huang else 2017ac500a1fSSandy Huang brightness = interpolate(0, -32, 100, 31, 2018ac500a1fSSandy Huang bcsh_info->brightness); 2019ac500a1fSSandy Huang contrast = interpolate(0, 0, 100, 511, bcsh_info->contrast); 2020ac500a1fSSandy Huang saturation = interpolate(0, 0, 100, 511, bcsh_info->saturation); 2021ac500a1fSSandy Huang hue = interpolate(0, -30, 100, 30, bcsh_info->hue); 2022ac500a1fSSandy Huang 2023ac500a1fSSandy Huang 2024ac500a1fSSandy Huang /* 2025ac500a1fSSandy Huang * a:[-30~0): 2026ac500a1fSSandy Huang * sin_hue = 0x100 - sin(a)*256; 2027ac500a1fSSandy Huang * cos_hue = cos(a)*256; 2028ac500a1fSSandy Huang * a:[0~30] 2029ac500a1fSSandy Huang * sin_hue = sin(a)*256; 2030ac500a1fSSandy Huang * cos_hue = cos(a)*256; 2031ac500a1fSSandy Huang */ 2032ac500a1fSSandy Huang sin_hue = fixp_sin32(hue) >> 23; 2033ac500a1fSSandy Huang cos_hue = fixp_cos32(hue) >> 23; 2034ac500a1fSSandy Huang 2035ee01dbb2SDamon Ding bcsh_state.brightness = brightness; 2036ee01dbb2SDamon Ding bcsh_state.contrast = contrast; 2037ee01dbb2SDamon Ding bcsh_state.saturation = saturation; 2038ee01dbb2SDamon Ding bcsh_state.sin_hue = sin_hue; 2039ee01dbb2SDamon Ding bcsh_state.cos_hue = cos_hue; 2040ee01dbb2SDamon Ding 2041ee01dbb2SDamon Ding vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->crtc_id); 2042ee01dbb2SDamon Ding if (cstate->splice_mode) 2043ee01dbb2SDamon Ding vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->splice_crtc_id); 2044ee01dbb2SDamon Ding } 2045ee01dbb2SDamon Ding 2046ee01dbb2SDamon Ding static void vop2_setup_dly_for_vp(struct display_state *state, struct vop2 *vop2, int crtc_id) 2047ee01dbb2SDamon Ding { 2048ee01dbb2SDamon Ding struct connector_state *conn_state = &state->conn_state; 2049ee01dbb2SDamon Ding struct drm_display_mode *mode = &conn_state->mode; 2050ee01dbb2SDamon Ding struct crtc_state *cstate = &state->crtc_state; 2051ee01dbb2SDamon Ding u32 bg_ovl_dly, bg_dly, pre_scan_dly; 2052ee01dbb2SDamon Ding u16 hdisplay = mode->crtc_hdisplay; 2053ee01dbb2SDamon Ding u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 2054ee01dbb2SDamon Ding 2055ee01dbb2SDamon Ding bg_ovl_dly = cstate->crtc->vps[crtc_id].bg_ovl_dly; 2056ee01dbb2SDamon Ding bg_dly = vop2->data->vp_data[crtc_id].pre_scan_max_dly; 2057ee01dbb2SDamon Ding bg_dly -= bg_ovl_dly; 2058ee01dbb2SDamon Ding 2059a552a69cSDamon Ding /* 2060a552a69cSDamon Ding * splice mode: hdisplay must roundup as 4 pixel, 2061a552a69cSDamon Ding * no splice mode: hdisplay must roundup as 2 pixel. 2062a552a69cSDamon Ding */ 2063ee01dbb2SDamon Ding if (cstate->splice_mode) 2064a552a69cSDamon Ding pre_scan_dly = bg_dly + (roundup(hdisplay, 4) >> 2) - 1; 2065ee01dbb2SDamon Ding else 2066a552a69cSDamon Ding pre_scan_dly = bg_dly + (roundup(hdisplay, 2) >> 1) - 1; 2067ee01dbb2SDamon Ding 2068ee01dbb2SDamon Ding if (vop2->version == VOP_VERSION_RK3588 && hsync_len < 8) 2069ee01dbb2SDamon Ding hsync_len = 8; 2070ee01dbb2SDamon Ding pre_scan_dly = (pre_scan_dly << 16) | hsync_len; 2071ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_VP0_BG_MIX_CTRL + crtc_id * 4, 2072ee01dbb2SDamon Ding BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false); 2073ee01dbb2SDamon Ding vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + (crtc_id * 0x100), pre_scan_dly); 2074ac500a1fSSandy Huang } 2075ac500a1fSSandy Huang 2076452afb13SDamon Ding static void vop3_setup_pipe_dly(struct display_state *state, struct vop2 *vop2, int crtc_id) 2077452afb13SDamon Ding { 2078452afb13SDamon Ding struct connector_state *conn_state = &state->conn_state; 2079452afb13SDamon Ding struct drm_display_mode *mode = &conn_state->mode; 2080452afb13SDamon Ding struct crtc_state *cstate = &state->crtc_state; 2081452afb13SDamon Ding struct vop2_win_data *win_data; 2082452afb13SDamon Ding u32 bg_dly, pre_scan_dly; 2083452afb13SDamon Ding u16 hdisplay = mode->crtc_hdisplay; 2084452afb13SDamon Ding u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 2085452afb13SDamon Ding u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id; 2086452afb13SDamon Ding u8 win_id; 2087452afb13SDamon Ding 2088452afb13SDamon Ding win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id); 2089452afb13SDamon Ding win_id = atoi(&win_data->name[strlen(win_data->name) - 1]); 2090452afb13SDamon Ding vop2_mask_write(vop2, RK3528_OVL_SYS_ESMART0_CTRL + win_id * 4, 2091452afb13SDamon Ding ESMART_DLY_NUM_MASK, ESMART_DLY_NUM_SHIFT, 0, false); 2092452afb13SDamon Ding 2093452afb13SDamon Ding bg_dly = vop2->data->vp_data[crtc_id].win_dly + 2094452afb13SDamon Ding vop2->data->vp_data[crtc_id].layer_mix_dly + 2095452afb13SDamon Ding vop2->data->vp_data[crtc_id].hdr_mix_dly; 2096a552a69cSDamon Ding /* hdisplay must roundup as 2 pixel */ 2097a552a69cSDamon Ding pre_scan_dly = bg_dly + (roundup(hdisplay, 2) >> 1) - 1; 2098a552a69cSDamon Ding /** 2099a552a69cSDamon Ding * pre_scan_hblank minimum value is 8, otherwise the win reset signal will 2100a552a69cSDamon Ding * lead to first line data be zero. 2101a552a69cSDamon Ding */ 2102a552a69cSDamon Ding pre_scan_dly = (pre_scan_dly << 16) | (hsync_len < 8 ? 8 : hsync_len); 2103452afb13SDamon Ding vop2_mask_write(vop2, RK3528_OVL_PORT0_BG_MIX_CTRL + crtc_id * 0x100, 2104452afb13SDamon Ding BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false); 2105452afb13SDamon Ding vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + (crtc_id * 0x100), pre_scan_dly); 2106452afb13SDamon Ding } 2107452afb13SDamon Ding 2108d0408543SAndy Yan static void vop2_post_config(struct display_state *state, struct vop2 *vop2) 2109d0408543SAndy Yan { 2110d0408543SAndy Yan struct connector_state *conn_state = &state->conn_state; 2111d0408543SAndy Yan struct drm_display_mode *mode = &conn_state->mode; 211252ee18acSSandy Huang struct crtc_state *cstate = &state->crtc_state; 211352ee18acSSandy Huang u32 vp_offset = (cstate->crtc_id * 0x100); 2114d0408543SAndy Yan u16 vtotal = mode->crtc_vtotal; 2115d0408543SAndy Yan u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 2116d0408543SAndy Yan u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 2117d0408543SAndy Yan u16 hdisplay = mode->crtc_hdisplay; 2118d0408543SAndy Yan u16 vdisplay = mode->crtc_vdisplay; 2119d0408543SAndy Yan u16 hsize = 2120d0408543SAndy Yan hdisplay * (conn_state->overscan.left_margin + 2121d0408543SAndy Yan conn_state->overscan.right_margin) / 200; 2122d0408543SAndy Yan u16 vsize = 2123d0408543SAndy Yan vdisplay * (conn_state->overscan.top_margin + 2124d0408543SAndy Yan conn_state->overscan.bottom_margin) / 200; 2125d0408543SAndy Yan u16 hact_end, vact_end; 2126d0408543SAndy Yan u32 val; 2127d0408543SAndy Yan 212874bd8269SSandy Huang hsize = round_down(hsize, 2); 2129d0408543SAndy Yan vsize = round_down(vsize, 2); 2130d0408543SAndy Yan 2131d0408543SAndy Yan hact_st += hdisplay * (100 - conn_state->overscan.left_margin) / 200; 2132d0408543SAndy Yan hact_end = hact_st + hsize; 2133d0408543SAndy Yan val = hact_st << 16; 2134d0408543SAndy Yan val |= hact_end; 2135d0408543SAndy Yan 213652ee18acSSandy Huang vop2_writel(vop2, RK3568_VP0_POST_DSP_HACT_INFO + vp_offset, val); 2137d0408543SAndy Yan vact_st += vdisplay * (100 - conn_state->overscan.top_margin) / 200; 2138d0408543SAndy Yan vact_end = vact_st + vsize; 2139d0408543SAndy Yan val = vact_st << 16; 2140d0408543SAndy Yan val |= vact_end; 214152ee18acSSandy Huang vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO + vp_offset, val); 2142d0408543SAndy Yan val = scl_cal_scale2(vdisplay, vsize) << 16; 2143d0408543SAndy Yan val |= scl_cal_scale2(hdisplay, hsize); 214452ee18acSSandy Huang vop2_writel(vop2, RK3568_VP0_POST_SCL_FACTOR_YRGB + vp_offset, val); 2145d0408543SAndy Yan #define POST_HORIZONTAL_SCALEDOWN_EN(x) ((x) << 0) 2146d0408543SAndy Yan #define POST_VERTICAL_SCALEDOWN_EN(x) ((x) << 1) 214752ee18acSSandy Huang vop2_writel(vop2, RK3568_VP0_POST_SCL_CTRL + vp_offset, 2148d0408543SAndy Yan POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) | 2149d0408543SAndy Yan POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize)); 2150d0408543SAndy Yan if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 2151d0408543SAndy Yan u16 vact_st_f1 = vtotal + vact_st + 1; 2152d0408543SAndy Yan u16 vact_end_f1 = vact_st_f1 + vsize; 2153d0408543SAndy Yan 2154d0408543SAndy Yan val = vact_st_f1 << 16 | vact_end_f1; 215552ee18acSSandy Huang vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO_F1 + vp_offset, val); 2156d0408543SAndy Yan } 2157d0408543SAndy Yan 2158452afb13SDamon Ding if (is_vop3(vop2)) { 2159452afb13SDamon Ding vop3_setup_pipe_dly(state, vop2, cstate->crtc_id); 2160452afb13SDamon Ding } else { 2161ee01dbb2SDamon Ding vop2_setup_dly_for_vp(state, vop2, cstate->crtc_id); 2162ee01dbb2SDamon Ding if (cstate->splice_mode) 2163ee01dbb2SDamon Ding vop2_setup_dly_for_vp(state, vop2, cstate->splice_crtc_id); 2164d0408543SAndy Yan } 2165452afb13SDamon Ding } 2166d0408543SAndy Yan 21676027c871SZhang Yubing static void vop3_post_acm_config(struct display_state *state, struct vop2 *vop2) 21686027c871SZhang Yubing { 21696027c871SZhang Yubing struct connector_state *conn_state = &state->conn_state; 21706027c871SZhang Yubing struct crtc_state *cstate = &state->crtc_state; 21716027c871SZhang Yubing struct acm_data *acm = &conn_state->disp_info->acm_data; 21726027c871SZhang Yubing struct drm_display_mode *mode = &conn_state->mode; 21736027c871SZhang Yubing u32 vp_offset = (cstate->crtc_id * 0x100); 21746027c871SZhang Yubing s16 *lut_y; 21756027c871SZhang Yubing s16 *lut_h; 21766027c871SZhang Yubing s16 *lut_s; 21776027c871SZhang Yubing u32 value; 21786027c871SZhang Yubing int i; 21796027c871SZhang Yubing 21806027c871SZhang Yubing vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset, 2181b8db91d0SZhang Yubing POST_ACM_BYPASS_EN_MASK, POST_ACM_BYPASS_EN_SHIFT, 0, false); 2182b8db91d0SZhang Yubing if (!acm->acm_enable) { 2183b8db91d0SZhang Yubing writel(0, vop2->regs + RK3528_ACM_CTRL); 21846027c871SZhang Yubing return; 21856027c871SZhang Yubing } 21866027c871SZhang Yubing 21876027c871SZhang Yubing printf("post acm enable\n"); 21886027c871SZhang Yubing 21896027c871SZhang Yubing writel(1, vop2->regs + RK3528_ACM_FETCH_START); 21906027c871SZhang Yubing 21916027c871SZhang Yubing value = (acm->acm_enable & 0x1) + ((mode->hdisplay & 0xfff) << 8) + 21926027c871SZhang Yubing ((mode->vdisplay & 0xfff) << 20); 21936027c871SZhang Yubing writel(value, vop2->regs + RK3528_ACM_CTRL); 21946027c871SZhang Yubing 21956027c871SZhang Yubing value = (acm->y_gain & 0x3ff) + ((acm->h_gain << 10) & 0xffc00) + 21966027c871SZhang Yubing ((acm->s_gain << 20) & 0x3ff00000); 21976027c871SZhang Yubing writel(value, vop2->regs + RK3528_ACM_DELTA_RANGE); 21986027c871SZhang Yubing 21996027c871SZhang Yubing lut_y = &acm->gain_lut_hy[0]; 22006027c871SZhang Yubing lut_h = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH]; 22016027c871SZhang Yubing lut_s = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH * 2]; 22026027c871SZhang Yubing for (i = 0; i < ACM_GAIN_LUT_HY_LENGTH; i++) { 22036027c871SZhang Yubing value = (lut_y[i] & 0xff) + ((lut_h[i] << 8) & 0xff00) + 22046027c871SZhang Yubing ((lut_s[i] << 16) & 0xff0000); 22056027c871SZhang Yubing writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HY_SEG0 + (i << 2)); 22066027c871SZhang Yubing } 22076027c871SZhang Yubing 22086027c871SZhang Yubing lut_y = &acm->gain_lut_hs[0]; 22096027c871SZhang Yubing lut_h = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH]; 22106027c871SZhang Yubing lut_s = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH * 2]; 22116027c871SZhang Yubing for (i = 0; i < ACM_GAIN_LUT_HS_LENGTH; i++) { 22126027c871SZhang Yubing value = (lut_y[i] & 0xff) + ((lut_h[i] << 8) & 0xff00) + 22136027c871SZhang Yubing ((lut_s[i] << 16) & 0xff0000); 22146027c871SZhang Yubing writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HS_SEG0 + (i << 2)); 22156027c871SZhang Yubing } 22166027c871SZhang Yubing 22176027c871SZhang Yubing lut_y = &acm->delta_lut_h[0]; 22186027c871SZhang Yubing lut_h = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH]; 22196027c871SZhang Yubing lut_s = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH * 2]; 22206027c871SZhang Yubing for (i = 0; i < ACM_DELTA_LUT_H_LENGTH; i++) { 22216027c871SZhang Yubing value = (lut_y[i] & 0x3ff) + ((lut_h[i] << 12) & 0xff000) + 22226027c871SZhang Yubing ((lut_s[i] << 20) & 0x3ff00000); 22236027c871SZhang Yubing writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HGAIN_SEG0 + (i << 2)); 22246027c871SZhang Yubing } 22256027c871SZhang Yubing 22266027c871SZhang Yubing writel(1, vop2->regs + RK3528_ACM_FETCH_DONE); 22276027c871SZhang Yubing } 22286027c871SZhang Yubing 22296027c871SZhang Yubing static void vop3_post_csc_config(struct display_state *state, struct vop2 *vop2) 22306027c871SZhang Yubing { 22316027c871SZhang Yubing struct connector_state *conn_state = &state->conn_state; 22326027c871SZhang Yubing struct crtc_state *cstate = &state->crtc_state; 22336027c871SZhang Yubing struct acm_data *acm = &conn_state->disp_info->acm_data; 22346027c871SZhang Yubing struct csc_info *csc = &conn_state->disp_info->csc_info; 22356027c871SZhang Yubing struct post_csc_coef csc_coef; 22366027c871SZhang Yubing bool is_input_yuv = false; 22376027c871SZhang Yubing bool is_output_yuv = false; 22386027c871SZhang Yubing bool post_r2y_en = false; 22396027c871SZhang Yubing bool post_csc_en = false; 22406027c871SZhang Yubing u32 vp_offset = (cstate->crtc_id * 0x100); 22416027c871SZhang Yubing u32 value; 22426027c871SZhang Yubing int range_type; 22436027c871SZhang Yubing 22446027c871SZhang Yubing printf("post csc enable\n"); 22456027c871SZhang Yubing 22466027c871SZhang Yubing if (acm->acm_enable) { 22476027c871SZhang Yubing if (!cstate->yuv_overlay) 22486027c871SZhang Yubing post_r2y_en = true; 22496027c871SZhang Yubing 22506027c871SZhang Yubing /* do y2r in csc module */ 22516027c871SZhang Yubing if (!is_yuv_output(conn_state->bus_format)) 22526027c871SZhang Yubing post_csc_en = true; 22536027c871SZhang Yubing } else { 22546027c871SZhang Yubing if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format)) 22556027c871SZhang Yubing post_r2y_en = true; 22566027c871SZhang Yubing 22576027c871SZhang Yubing /* do y2r in csc module */ 22586027c871SZhang Yubing if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format)) 22596027c871SZhang Yubing post_csc_en = true; 22606027c871SZhang Yubing } 22616027c871SZhang Yubing 22626027c871SZhang Yubing if (csc->csc_enable) 22636027c871SZhang Yubing post_csc_en = true; 22646027c871SZhang Yubing 22656027c871SZhang Yubing if (cstate->yuv_overlay || post_r2y_en) 22666027c871SZhang Yubing is_input_yuv = true; 22676027c871SZhang Yubing 22686027c871SZhang Yubing if (is_yuv_output(conn_state->bus_format)) 22696027c871SZhang Yubing is_output_yuv = true; 22706027c871SZhang Yubing 2271df0a5c43SDamon Ding cstate->post_csc_mode = vop2_convert_csc_mode(conn_state->color_encoding, 2272df0a5c43SDamon Ding conn_state->color_range, 2273df0a5c43SDamon Ding CSC_13BIT_DEPTH); 22746027c871SZhang Yubing 22756027c871SZhang Yubing if (post_csc_en) { 22766027c871SZhang Yubing rockchip_calc_post_csc(csc, &csc_coef, cstate->post_csc_mode, is_input_yuv, 22776027c871SZhang Yubing is_output_yuv); 22786027c871SZhang Yubing 22796027c871SZhang Yubing vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset, 22806027c871SZhang Yubing POST_CSC_COE00_MASK, POST_CSC_COE00_SHIFT, 22816027c871SZhang Yubing csc_coef.csc_coef00, false); 22825743c73eSZhang Yubing value = csc_coef.csc_coef01 & 0xffff; 22835743c73eSZhang Yubing value |= (csc_coef.csc_coef02 << 16) & 0xffff0000; 22846027c871SZhang Yubing writel(value, vop2->regs + RK3528_VP0_CSC_COE01_02); 22855743c73eSZhang Yubing value = csc_coef.csc_coef10 & 0xffff; 22865743c73eSZhang Yubing value |= (csc_coef.csc_coef11 << 16) & 0xffff0000; 22876027c871SZhang Yubing writel(value, vop2->regs + RK3528_VP0_CSC_COE10_11); 22885743c73eSZhang Yubing value = csc_coef.csc_coef12 & 0xffff; 22895743c73eSZhang Yubing value |= (csc_coef.csc_coef20 << 16) & 0xffff0000; 22906027c871SZhang Yubing writel(value, vop2->regs + RK3528_VP0_CSC_COE12_20); 22915743c73eSZhang Yubing value = csc_coef.csc_coef21 & 0xffff; 22925743c73eSZhang Yubing value |= (csc_coef.csc_coef22 << 16) & 0xffff0000; 22936027c871SZhang Yubing writel(value, vop2->regs + RK3528_VP0_CSC_COE21_22); 22946027c871SZhang Yubing writel(csc_coef.csc_dc0, vop2->regs + RK3528_VP0_CSC_OFFSET0); 22956027c871SZhang Yubing writel(csc_coef.csc_dc1, vop2->regs + RK3528_VP0_CSC_OFFSET1); 22966027c871SZhang Yubing writel(csc_coef.csc_dc2, vop2->regs + RK3528_VP0_CSC_OFFSET2); 22976027c871SZhang Yubing 22986027c871SZhang Yubing range_type = csc_coef.range_type ? 0 : 1; 22996027c871SZhang Yubing range_type <<= is_input_yuv ? 0 : 1; 23006027c871SZhang Yubing vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset, 23016027c871SZhang Yubing POST_CSC_MODE_MASK, POST_CSC_MODE_SHIFT, range_type, false); 23026027c871SZhang Yubing } 23036027c871SZhang Yubing 23046027c871SZhang Yubing vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset, 23055743c73eSZhang Yubing POST_R2Y_EN_MASK, POST_R2Y_EN_SHIFT, post_r2y_en ? 1 : 0, false); 23066027c871SZhang Yubing vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset, 23076027c871SZhang Yubing POST_CSC_EN_MASK, POST_CSC_EN_SHIFT, post_csc_en ? 1 : 0, false); 23086027c871SZhang Yubing vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset, 23096027c871SZhang Yubing POST_R2Y_MODE_MASK, POST_R2Y_MODE_SHIFT, cstate->post_csc_mode, false); 23106027c871SZhang Yubing } 23116027c871SZhang Yubing 23126027c871SZhang Yubing static void vop3_post_config(struct display_state *state, struct vop2 *vop2) 23136027c871SZhang Yubing { 23146027c871SZhang Yubing struct connector_state *conn_state = &state->conn_state; 23156027c871SZhang Yubing struct base2_disp_info *disp_info = conn_state->disp_info; 23166027c871SZhang Yubing const char *enable_flag; 23176027c871SZhang Yubing if (!disp_info) { 23186027c871SZhang Yubing printf("disp_info is empty\n"); 23196027c871SZhang Yubing return; 23206027c871SZhang Yubing } 23216027c871SZhang Yubing 23226027c871SZhang Yubing enable_flag = (const char *)&disp_info->cacm_header; 23236027c871SZhang Yubing if (strncasecmp(enable_flag, "CACM", 4)) { 23246027c871SZhang Yubing printf("acm and csc is not support\n"); 23256027c871SZhang Yubing return; 23266027c871SZhang Yubing } 23276027c871SZhang Yubing 23286027c871SZhang Yubing vop3_post_acm_config(state, vop2); 23296027c871SZhang Yubing vop3_post_csc_config(state, vop2); 23306027c871SZhang Yubing } 23316027c871SZhang Yubing 2332a552a69cSDamon Ding static int rk3576_vop2_wait_power_domain_on(struct vop2 *vop2, 2333a552a69cSDamon Ding struct vop2_power_domain_data *pd_data) 2334a552a69cSDamon Ding { 2335a552a69cSDamon Ding int val = 0; 2336a552a69cSDamon Ding bool is_bisr_en, is_otp_bisr_en; 2337a552a69cSDamon Ding 2338a552a69cSDamon Ding if (pd_data->id == VOP2_PD_CLUSTER) { 2339a552a69cSDamon Ding is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3576_PMU_BISR_PDGEN_CON0, 2340a552a69cSDamon Ding EN_MASK, PD_VOP_CLUSTER_REPAIR_ENA_SHIFT); 2341a552a69cSDamon Ding is_otp_bisr_en = vop2_grf_readl(vop2, vop2->grf, RK3576_SYS_GRF_MEMFAULT_STATUS0, 2342a552a69cSDamon Ding EN_MASK, PD_VOP_CLUSTER_REPAIR_ENA_SHIFT); 2343a552a69cSDamon Ding if (is_bisr_en && is_otp_bisr_en) 2344a552a69cSDamon Ding return readl_poll_timeout(vop2->sys_pmu + RK3576_PMU_BISR_PWR_REPAIR_STATUS0, 2345a552a69cSDamon Ding val, ((val >> PD_VOP_CLUSTER_PWR_REPAIR_STAT_SHIFT) & 0x1), 2346a552a69cSDamon Ding 50 * 1000); 2347a552a69cSDamon Ding else 2348a552a69cSDamon Ding return readl_poll_timeout(vop2->sys_pmu + RK3576_PMU_PWR_GATE_STS, 2349a552a69cSDamon Ding val, ((val >> PD_VOP_CLUSTER_DWN_STAT) & 0x1), 2350a552a69cSDamon Ding 50 * 1000); 2351a552a69cSDamon Ding } else { 2352a552a69cSDamon Ding is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3576_PMU_BISR_PDGEN_CON0, 2353a552a69cSDamon Ding EN_MASK, PD_VOP_ESMART_REPAIR_ENA_SHIFT); 2354a552a69cSDamon Ding is_otp_bisr_en = vop2_grf_readl(vop2, vop2->grf, RK3576_SYS_GRF_MEMFAULT_STATUS0, 2355a552a69cSDamon Ding EN_MASK, PD_VOP_ESMART_REPAIR_ENA_SHIFT); 2356a552a69cSDamon Ding if (is_bisr_en && is_otp_bisr_en) 2357a552a69cSDamon Ding return readl_poll_timeout(vop2->sys_pmu + RK3576_PMU_BISR_PWR_REPAIR_STATUS0, 2358a552a69cSDamon Ding val, ((val >> PD_VOP_ESMART_PWR_REPAIR_STAT_SHIFT) & 0x1), 2359a552a69cSDamon Ding 50 * 1000); 2360a552a69cSDamon Ding else 2361a552a69cSDamon Ding return readl_poll_timeout(vop2->sys_pmu + RK3576_PMU_PWR_GATE_STS, 2362a552a69cSDamon Ding val, !((val >> PD_VOP_ESMART_DWN_STAT) & 0x1), 2363a552a69cSDamon Ding 50 * 1000); 2364a552a69cSDamon Ding } 2365a552a69cSDamon Ding } 2366a552a69cSDamon Ding 2367a552a69cSDamon Ding static int rk3576_vop2_power_domain_on(struct vop2 *vop2, struct vop2_power_domain_data *pd_data) 2368a552a69cSDamon Ding { 2369a552a69cSDamon Ding int ret = 0; 2370a552a69cSDamon Ding 2371a552a69cSDamon Ding if (pd_data->id == VOP2_PD_CLUSTER) 2372a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_SYS_CLUSTER_PD_CTRL, EN_MASK, 2373a552a69cSDamon Ding RK3576_CLUSTER_PD_EN_SHIFT, 0, true); 2374a552a69cSDamon Ding else 2375a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_SYS_ESMART_PD_CTRL, EN_MASK, 2376a552a69cSDamon Ding RK3576_ESMART_PD_EN_SHIFT, 0, true); 2377a552a69cSDamon Ding ret = rk3576_vop2_wait_power_domain_on(vop2, pd_data); 2378a552a69cSDamon Ding if (ret) { 2379a552a69cSDamon Ding printf("wait vop2 power domain timeout\n"); 2380a552a69cSDamon Ding return ret; 2381a552a69cSDamon Ding } 2382a552a69cSDamon Ding 2383a552a69cSDamon Ding return 0; 2384a552a69cSDamon Ding } 2385a552a69cSDamon Ding 2386a552a69cSDamon Ding static int rk3588_vop2_wait_power_domain_on(struct vop2 *vop2, 2387a552a69cSDamon Ding struct vop2_power_domain_data *pd_data) 238860e469f5SDamon Ding { 238960e469f5SDamon Ding int val = 0; 239060e469f5SDamon Ding int shift = 0; 2391b6ba80b4SDamon Ding int shift_factor = 0; 239260e469f5SDamon Ding bool is_bisr_en = false; 239360e469f5SDamon Ding 2394b6ba80b4SDamon Ding /* 2395b6ba80b4SDamon Ding * The order of pd status bits in BISR_STS register 2396b6ba80b4SDamon Ding * is different from that in VOP SYS_STS register. 2397b6ba80b4SDamon Ding */ 2398b6ba80b4SDamon Ding if (pd_data->id == VOP2_PD_DSC_8K || 2399b6ba80b4SDamon Ding pd_data->id == VOP2_PD_DSC_4K || 2400b6ba80b4SDamon Ding pd_data->id == VOP2_PD_ESMART) 2401b6ba80b4SDamon Ding shift_factor = 1; 2402b6ba80b4SDamon Ding 2403b6ba80b4SDamon Ding shift = RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT + generic_ffs(pd_data->id) - 1 - shift_factor; 2404b6ba80b4SDamon Ding is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3588_PMU_BISR_CON3, EN_MASK, shift); 240560e469f5SDamon Ding if (is_bisr_en) { 2406b6ba80b4SDamon Ding shift = RK3588_PD_CLUSTER0_PWR_STAT_SHIFI + generic_ffs(pd_data->id) - 1 - shift_factor; 2407b6ba80b4SDamon Ding 240860e469f5SDamon Ding return readl_poll_timeout(vop2->sys_pmu + RK3588_PMU_BISR_STATUS5, val, 2409d2e91fdcSDamon Ding ((val >> shift) & 0x1), 50 * 1000); 241060e469f5SDamon Ding } else { 2411b6ba80b4SDamon Ding shift = RK3588_CLUSTER0_PD_STATUS_SHIFT + generic_ffs(pd_data->id) - 1; 2412b6ba80b4SDamon Ding 241360e469f5SDamon Ding return readl_poll_timeout(vop2->regs + RK3568_SYS_STATUS0, val, 241460e469f5SDamon Ding !((val >> shift) & 0x1), 50 * 1000); 241560e469f5SDamon Ding } 241660e469f5SDamon Ding } 241760e469f5SDamon Ding 2418a552a69cSDamon Ding static int rk3588_vop2_power_domain_on(struct vop2 *vop2, struct vop2_power_domain_data *pd_data) 2419a552a69cSDamon Ding { 2420a552a69cSDamon Ding int ret = 0; 2421a552a69cSDamon Ding 2422a552a69cSDamon Ding vop2_mask_write(vop2, RK3588_SYS_PD_CTRL, EN_MASK, 2423a552a69cSDamon Ding RK3588_CLUSTER0_PD_EN_SHIFT + generic_ffs(pd_data->id) - 1, 0, false); 2424a552a69cSDamon Ding ret = rk3588_vop2_wait_power_domain_on(vop2, pd_data); 2425a552a69cSDamon Ding if (ret) { 2426a552a69cSDamon Ding printf("wait vop2 power domain timeout\n"); 2427a552a69cSDamon Ding return ret; 2428a552a69cSDamon Ding } 2429a552a69cSDamon Ding 2430a552a69cSDamon Ding return 0; 2431a552a69cSDamon Ding } 2432a552a69cSDamon Ding 2433b6ba80b4SDamon Ding static int vop2_power_domain_on(struct vop2 *vop2, int pd_id) 243460e469f5SDamon Ding { 243560e469f5SDamon Ding struct vop2_power_domain_data *pd_data; 243660e469f5SDamon Ding int ret = 0; 243760e469f5SDamon Ding 2438b6ba80b4SDamon Ding if (!pd_id) 2439b6ba80b4SDamon Ding return 0; 2440b6ba80b4SDamon Ding 2441b6ba80b4SDamon Ding pd_data = vop2_find_pd_data_by_id(vop2, pd_id); 2442b6ba80b4SDamon Ding if (!pd_data) { 2443b6ba80b4SDamon Ding printf("can't find pd_data by id\n"); 244460e469f5SDamon Ding return -EINVAL; 244560e469f5SDamon Ding } 24462c66af11SDamon Ding 2447b6ba80b4SDamon Ding if (pd_data->parent_id) { 2448b6ba80b4SDamon Ding ret = vop2_power_domain_on(vop2, pd_data->parent_id); 244960e469f5SDamon Ding if (ret) { 245060e469f5SDamon Ding printf("can't open parent power domain\n"); 245160e469f5SDamon Ding return -EINVAL; 245260e469f5SDamon Ding } 245360e469f5SDamon Ding } 245460e469f5SDamon Ding 2455a552a69cSDamon Ding /* 2456a552a69cSDamon Ding * Read VOP internal power domain on/off status. 2457a552a69cSDamon Ding * We should query BISR_STS register in PMU for 2458a552a69cSDamon Ding * power up/down status when memory repair is enabled. 2459a552a69cSDamon Ding * Return value: 1 for power on, 0 for power off; 2460a552a69cSDamon Ding */ 2461a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3576) 2462a552a69cSDamon Ding ret = rk3576_vop2_power_domain_on(vop2, pd_data); 2463a552a69cSDamon Ding else 2464a552a69cSDamon Ding ret = rk3588_vop2_power_domain_on(vop2, pd_data); 246560e469f5SDamon Ding 2466a552a69cSDamon Ding return ret; 246760e469f5SDamon Ding } 246860e469f5SDamon Ding 2469ecc31b6eSAndy Yan static void rk3588_vop2_regsbak(struct vop2 *vop2) 2470ecc31b6eSAndy Yan { 2471ecc31b6eSAndy Yan u32 *base = vop2->regs; 2472ecc31b6eSAndy Yan int i = 0; 2473ecc31b6eSAndy Yan 2474ecc31b6eSAndy Yan /* 2475ecc31b6eSAndy Yan * No need to backup HDR/DSC/GAMMA_LUT/BPP_LUT/MMU 2476ecc31b6eSAndy Yan */ 2477ecc31b6eSAndy Yan for (i = 0; i < (vop2->reg_len >> 2); i++) 2478ecc31b6eSAndy Yan vop2->regsbak[i] = base[i]; 2479ecc31b6eSAndy Yan } 2480ecc31b6eSAndy Yan 24815fa6e665SDamon Ding static void vop3_overlay_init(struct vop2 *vop2, struct display_state *state) 24825fa6e665SDamon Ding { 24835fa6e665SDamon Ding struct vop2_win_data *win_data; 24845fa6e665SDamon Ding int layer_phy_id = 0; 24855fa6e665SDamon Ding int i, j; 24865fa6e665SDamon Ding u32 ovl_port_offset = 0; 24875fa6e665SDamon Ding u32 layer_nr = 0; 24885fa6e665SDamon Ding u8 shift = 0; 24895fa6e665SDamon Ding 24905fa6e665SDamon Ding /* layer sel win id */ 24915fa6e665SDamon Ding for (i = 0; i < vop2->data->nr_vps; i++) { 24925fa6e665SDamon Ding shift = 0; 24935fa6e665SDamon Ding ovl_port_offset = 0x100 * i; 24945fa6e665SDamon Ding layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 24955fa6e665SDamon Ding for (j = 0; j < layer_nr; j++) { 24965fa6e665SDamon Ding layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 24975fa6e665SDamon Ding win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 24985fa6e665SDamon Ding vop2_mask_write(vop2, RK3528_OVL_PORT0_LAYER_SEL + ovl_port_offset, LAYER_SEL_MASK, 24995fa6e665SDamon Ding shift, win_data->layer_sel_win_id[i], false); 25005fa6e665SDamon Ding shift += 4; 25015fa6e665SDamon Ding } 25025fa6e665SDamon Ding } 25035fa6e665SDamon Ding 2504a552a69cSDamon Ding if (vop2->version != VOP_VERSION_RK3576) { 25055fa6e665SDamon Ding /* win sel port */ 25065fa6e665SDamon Ding for (i = 0; i < vop2->data->nr_vps; i++) { 25075fa6e665SDamon Ding layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 25085fa6e665SDamon Ding for (j = 0; j < layer_nr; j++) { 25095fa6e665SDamon Ding if (!vop2->vp_plane_mask[i].attached_layers[j]) 25105fa6e665SDamon Ding continue; 25115fa6e665SDamon Ding layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 25125fa6e665SDamon Ding win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 25135fa6e665SDamon Ding shift = win_data->win_sel_port_offset * 2; 2514a552a69cSDamon Ding vop2_mask_write(vop2, RK3528_OVL_SYS_PORT_SEL, 2515a552a69cSDamon Ding LAYER_SEL_PORT_MASK, shift, i, false); 2516a552a69cSDamon Ding } 25175fa6e665SDamon Ding } 25185fa6e665SDamon Ding } 25195fa6e665SDamon Ding } 25205fa6e665SDamon Ding 25215fa6e665SDamon Ding static void vop2_overlay_init(struct vop2 *vop2, struct display_state *state) 25225fa6e665SDamon Ding { 25235fa6e665SDamon Ding struct crtc_state *cstate = &state->crtc_state; 25245fa6e665SDamon Ding struct vop2_win_data *win_data; 25255fa6e665SDamon Ding int layer_phy_id = 0; 25265fa6e665SDamon Ding int total_used_layer = 0; 25275fa6e665SDamon Ding int port_mux = 0; 25285fa6e665SDamon Ding int i, j; 25295fa6e665SDamon Ding u32 layer_nr = 0; 25305fa6e665SDamon Ding u8 shift = 0; 25315fa6e665SDamon Ding 25325fa6e665SDamon Ding /* layer sel win id */ 25335fa6e665SDamon Ding for (i = 0; i < vop2->data->nr_vps; i++) { 25345fa6e665SDamon Ding layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 25355fa6e665SDamon Ding for (j = 0; j < layer_nr; j++) { 25365fa6e665SDamon Ding layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 25375fa6e665SDamon Ding win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 25385fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_MASK, 25395fa6e665SDamon Ding shift, win_data->layer_sel_win_id[i], false); 25405fa6e665SDamon Ding shift += 4; 25415fa6e665SDamon Ding } 25425fa6e665SDamon Ding } 25435fa6e665SDamon Ding 25445fa6e665SDamon Ding /* win sel port */ 25455fa6e665SDamon Ding for (i = 0; i < vop2->data->nr_vps; i++) { 25465fa6e665SDamon Ding layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 25475fa6e665SDamon Ding for (j = 0; j < layer_nr; j++) { 25485fa6e665SDamon Ding if (!vop2->vp_plane_mask[i].attached_layers[j]) 25495fa6e665SDamon Ding continue; 25505fa6e665SDamon Ding layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 25515fa6e665SDamon Ding win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 25525fa6e665SDamon Ding shift = win_data->win_sel_port_offset * 2; 25535fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, LAYER_SEL_PORT_MASK, 25545fa6e665SDamon Ding LAYER_SEL_PORT_SHIFT + shift, i, false); 25555fa6e665SDamon Ding } 25565fa6e665SDamon Ding } 25575fa6e665SDamon Ding 25585fa6e665SDamon Ding /** 25595fa6e665SDamon Ding * port mux config 25605fa6e665SDamon Ding */ 25615fa6e665SDamon Ding for (i = 0; i < vop2->data->nr_vps; i++) { 25625fa6e665SDamon Ding shift = i * 4; 25635fa6e665SDamon Ding if (vop2->vp_plane_mask[i].attached_layers_nr) { 25645fa6e665SDamon Ding total_used_layer += vop2->vp_plane_mask[i].attached_layers_nr; 25655fa6e665SDamon Ding port_mux = total_used_layer - 1; 25665fa6e665SDamon Ding } else { 25675fa6e665SDamon Ding port_mux = 8; 25685fa6e665SDamon Ding } 25695fa6e665SDamon Ding 25705fa6e665SDamon Ding if (i == vop2->data->nr_vps - 1) 25715fa6e665SDamon Ding port_mux = vop2->data->nr_mixers; 25725fa6e665SDamon Ding 25735fa6e665SDamon Ding cstate->crtc->vps[i].bg_ovl_dly = (vop2->data->nr_mixers - port_mux) << 1; 25745fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK, 25755fa6e665SDamon Ding PORT_MUX_SHIFT + shift, port_mux, false); 25765fa6e665SDamon Ding } 25775fa6e665SDamon Ding } 25785fa6e665SDamon Ding 25795fa6e665SDamon Ding static bool vop3_ignore_plane(struct vop2 *vop2, struct vop2_win_data *win) 25805fa6e665SDamon Ding { 25815fa6e665SDamon Ding if (!is_vop3(vop2)) 25825fa6e665SDamon Ding return false; 25835fa6e665SDamon Ding 25845fa6e665SDamon Ding if (vop2->esmart_lb_mode == VOP3_ESMART_8K_MODE && 25855fa6e665SDamon Ding win->phys_id != ROCKCHIP_VOP2_ESMART0) 25865fa6e665SDamon Ding return true; 25875fa6e665SDamon Ding else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_4K_MODE && 25885fa6e665SDamon Ding (win->phys_id == ROCKCHIP_VOP2_ESMART1 || win->phys_id == ROCKCHIP_VOP2_ESMART3)) 25895fa6e665SDamon Ding return true; 25905fa6e665SDamon Ding else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_2K_2K_MODE && 25915fa6e665SDamon Ding win->phys_id == ROCKCHIP_VOP2_ESMART1) 25925fa6e665SDamon Ding return true; 2593a552a69cSDamon Ding else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_4K_4K_MODE && 2594a552a69cSDamon Ding win->phys_id == ROCKCHIP_VOP2_ESMART3) 2595a552a69cSDamon Ding return true; 25965fa6e665SDamon Ding else 25975fa6e665SDamon Ding return false; 25985fa6e665SDamon Ding } 25995fa6e665SDamon Ding 26005fa6e665SDamon Ding static void vop3_init_esmart_scale_engine(struct vop2 *vop2) 26015fa6e665SDamon Ding { 26025fa6e665SDamon Ding struct vop2_win_data *win_data; 2603fa4ecc32SDamon Ding int i; 26045fa6e665SDamon Ding u8 scale_engine_num = 0; 26055fa6e665SDamon Ding 26065fa6e665SDamon Ding /* store plane mask for vop2_fixup_dts */ 2607fa4ecc32SDamon Ding for (i = 0; i < vop2->data->nr_layers; i++) { 2608fa4ecc32SDamon Ding win_data = &vop2->data->win_data[i]; 26095fa6e665SDamon Ding if (win_data->type == CLUSTER_LAYER || vop3_ignore_plane(vop2, win_data)) 26105fa6e665SDamon Ding continue; 26115fa6e665SDamon Ding 26125fa6e665SDamon Ding win_data->scale_engine_num = scale_engine_num++; 26135fa6e665SDamon Ding } 26145fa6e665SDamon Ding } 26155fa6e665SDamon Ding 2616a552a69cSDamon Ding static int vop3_get_esmart_lb_mode(struct vop2 *vop2) 2617a552a69cSDamon Ding { 2618a552a69cSDamon Ding const struct vop2_esmart_lb_map *esmart_lb_mode_map = vop2->data->esmart_lb_mode_map; 2619a552a69cSDamon Ding int i; 2620a552a69cSDamon Ding 2621a552a69cSDamon Ding if (!esmart_lb_mode_map) 2622a552a69cSDamon Ding return vop2->esmart_lb_mode; 2623a552a69cSDamon Ding 2624a552a69cSDamon Ding for (i = 0; i < vop2->data->esmart_lb_mode_num; i++) { 2625a552a69cSDamon Ding if (vop2->esmart_lb_mode == esmart_lb_mode_map->lb_mode) 2626a552a69cSDamon Ding return esmart_lb_mode_map->lb_map_value; 2627a552a69cSDamon Ding esmart_lb_mode_map++; 2628a552a69cSDamon Ding } 2629a552a69cSDamon Ding 2630a552a69cSDamon Ding if (i == vop2->data->esmart_lb_mode_num) 2631a552a69cSDamon Ding printf("Unsupported esmart_lb_mode:%d\n", vop2->esmart_lb_mode); 2632a552a69cSDamon Ding 2633a552a69cSDamon Ding return vop2->data->esmart_lb_mode_map[0].lb_map_value; 2634a552a69cSDamon Ding } 2635a552a69cSDamon Ding 2636b0989546SSandy Huang static void vop2_global_initial(struct vop2 *vop2, struct display_state *state) 2637d0408543SAndy Yan { 2638b0989546SSandy Huang struct crtc_state *cstate = &state->crtc_state; 2639b0989546SSandy Huang struct vop2_vp_plane_mask *plane_mask; 2640a552a69cSDamon Ding int active_vp_num = 0; 26415fa6e665SDamon Ding int layer_phy_id = 0; 26425fa6e665SDamon Ding int i, j; 2643fa4ecc32SDamon Ding int ret; 26445fa6e665SDamon Ding u32 layer_nr = 0; 2645d0408543SAndy Yan 264663cb669fSSandy Huang if (vop2->global_init) 2647d0408543SAndy Yan return; 264863cb669fSSandy Huang 2649b0989546SSandy Huang /* OTP must enable at the first time, otherwise mirror layer register is error */ 265063cb669fSSandy Huang if (soc_is_rk3566()) 265163cb669fSSandy Huang vop2_mask_write(vop2, RK3568_SYS_OTP_WIN_EN, EN_MASK, 265263cb669fSSandy Huang OTP_WIN_EN_SHIFT, 1, false); 2653b0989546SSandy Huang 2654b0989546SSandy Huang if (cstate->crtc->assign_plane) {/* dts assign plane */ 2655b0989546SSandy Huang u32 plane_mask; 2656b0989546SSandy Huang int primary_plane_id; 2657b0989546SSandy Huang 2658b0989546SSandy Huang for (i = 0; i < vop2->data->nr_vps; i++) { 2659b0989546SSandy Huang plane_mask = cstate->crtc->vps[i].plane_mask; 2660b0989546SSandy Huang vop2->vp_plane_mask[i].plane_mask = plane_mask; 2661b0989546SSandy Huang layer_nr = hweight32(plane_mask); /* use bitmap to store plane mask */ 2662b0989546SSandy Huang vop2->vp_plane_mask[i].attached_layers_nr = layer_nr; 26635fc2b656SDamon Ding primary_plane_id = cstate->crtc->vps[i].primary_plane_id; 2664337d1c13SDamon Ding if (primary_plane_id >= ROCKCHIP_VOP2_LAYER_MAX) 2665b0989546SSandy Huang primary_plane_id = vop2_get_primary_plane(vop2, plane_mask); 2666b0989546SSandy Huang vop2->vp_plane_mask[i].primary_plane_id = primary_plane_id; 2667b0989546SSandy Huang vop2->vp_plane_mask[i].plane_mask = plane_mask; 2668b0989546SSandy Huang 2669b0989546SSandy Huang /* plane mask[bitmap] convert into layer phy id[enum vop2_layer_phy_id]*/ 2670b0989546SSandy Huang for (j = 0; j < layer_nr; j++) { 2671b0989546SSandy Huang vop2->vp_plane_mask[i].attached_layers[j] = ffs(plane_mask) - 1; 2672b0989546SSandy Huang plane_mask &= ~BIT(vop2->vp_plane_mask[i].attached_layers[j]); 267363cb669fSSandy Huang } 2674b0989546SSandy Huang } 2675b0989546SSandy Huang } else {/* need soft assign plane mask */ 2676a552a69cSDamon Ding printf("Assign plane mask automatically\n"); 2677a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3576) { 2678a552a69cSDamon Ding for (i = 0; i < vop2->data->nr_vps; i++) { 2679a552a69cSDamon Ding if (cstate->crtc->vps[i].enable) { 2680a552a69cSDamon Ding vop2->vp_plane_mask[i].attached_layers_nr = 1; 2681a552a69cSDamon Ding vop2->vp_plane_mask[i].primary_plane_id = 2682a552a69cSDamon Ding vop2->data->vp_default_primary_plane[i]; 2683a552a69cSDamon Ding vop2->vp_plane_mask[i].attached_layers[0] = 2684a552a69cSDamon Ding vop2->data->vp_default_primary_plane[i]; 2685a552a69cSDamon Ding vop2->vp_plane_mask[i].plane_mask |= 2686a552a69cSDamon Ding BIT(vop2->data->vp_default_primary_plane[i]); 2687a552a69cSDamon Ding active_vp_num++; 2688a552a69cSDamon Ding } 2689a552a69cSDamon Ding } 2690a552a69cSDamon Ding printf("VOP have %d active VP\n", active_vp_num); 2691a552a69cSDamon Ding } else { 2692b0989546SSandy Huang /* find the first unplug devices and set it as main display */ 2693b0989546SSandy Huang int main_vp_index = -1; 2694b0989546SSandy Huang 2695b0989546SSandy Huang for (i = 0; i < vop2->data->nr_vps; i++) { 2696b0989546SSandy Huang if (cstate->crtc->vps[i].enable) 2697b0989546SSandy Huang active_vp_num++; 2698b0989546SSandy Huang } 2699b0989546SSandy Huang printf("VOP have %d active VP\n", active_vp_num); 2700b0989546SSandy Huang 2701b0989546SSandy Huang if (soc_is_rk3566() && active_vp_num > 2) 2702b0989546SSandy Huang printf("ERROR: rk3566 only support 2 display output!!\n"); 2703b0989546SSandy Huang plane_mask = vop2->data->plane_mask; 2704b0989546SSandy Huang plane_mask += (active_vp_num - 1) * VOP2_VP_MAX; 27055fa6e665SDamon Ding /* 2706a552a69cSDamon Ding * For rk3528, one display policy for hdmi store in plane_mask[0], and 2707a552a69cSDamon Ding * the other for cvbs store in plane_mask[2]. 27085fa6e665SDamon Ding */ 27095fa6e665SDamon Ding if (vop2->version == VOP_VERSION_RK3528 && active_vp_num == 1 && 27105fa6e665SDamon Ding cstate->crtc->vps[1].output_type == DRM_MODE_CONNECTOR_TV) 27115fa6e665SDamon Ding plane_mask += 2 * VOP2_VP_MAX; 2712b0989546SSandy Huang 27135fa6e665SDamon Ding if (vop2->version == VOP_VERSION_RK3528) { 27145fa6e665SDamon Ding /* 2715a552a69cSDamon Ding * For rk3528, the plane mask of vp is limited, only esmart2 can 2716a552a69cSDamon Ding * be selected by both vp0 and vp1. 27175fa6e665SDamon Ding */ 27185fa6e665SDamon Ding j = 0; 27195fa6e665SDamon Ding } else { 2720b0989546SSandy Huang for (i = 0; i < vop2->data->nr_vps; i++) { 2721b0989546SSandy Huang if (!is_hot_plug_devices(cstate->crtc->vps[i].output_type)) { 2722a552a69cSDamon Ding /* the first store main display plane mask */ 2723a552a69cSDamon Ding vop2->vp_plane_mask[i] = plane_mask[0]; 2724b0989546SSandy Huang main_vp_index = i; 2725e007876dSSandy Huang break; 2726b0989546SSandy Huang } 2727b0989546SSandy Huang } 2728b0989546SSandy Huang 2729b0989546SSandy Huang /* if no find unplug devices, use vp0 as main display */ 2730b0989546SSandy Huang if (main_vp_index < 0) { 2731b0989546SSandy Huang main_vp_index = 0; 2732b0989546SSandy Huang vop2->vp_plane_mask[0] = plane_mask[0]; 2733b0989546SSandy Huang } 2734b0989546SSandy Huang 2735a552a69cSDamon Ding /* plane_mask[0] store main display, so we from plane_mask[1] */ 2736a552a69cSDamon Ding j = 1; 27375fa6e665SDamon Ding } 2738b0989546SSandy Huang 2739b0989546SSandy Huang /* init other display except main display */ 2740b0989546SSandy Huang for (i = 0; i < vop2->data->nr_vps; i++) { 2741a552a69cSDamon Ding /* main display or no connect devices */ 2742a552a69cSDamon Ding if (i == main_vp_index || !cstate->crtc->vps[i].enable) 2743b0989546SSandy Huang continue; 2744b0989546SSandy Huang vop2->vp_plane_mask[i] = plane_mask[j++]; 2745b0989546SSandy Huang } 2746a552a69cSDamon Ding } 2747b0989546SSandy Huang /* store plane mask for vop2_fixup_dts */ 2748b0989546SSandy Huang for (i = 0; i < vop2->data->nr_vps; i++) { 2749b0989546SSandy Huang layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 2750b0989546SSandy Huang for (j = 0; j < layer_nr; j++) { 2751b0989546SSandy Huang layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 2752b0989546SSandy Huang vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id); 2753b0989546SSandy Huang } 2754b0989546SSandy Huang } 2755b0989546SSandy Huang } 2756b0989546SSandy Huang 275760e469f5SDamon Ding if (vop2->version == VOP_VERSION_RK3588) 275860e469f5SDamon Ding rk3588_vop2_regsbak(vop2); 275960e469f5SDamon Ding else 276060e469f5SDamon Ding memcpy(vop2->regsbak, vop2->regs, vop2->reg_len); 276160e469f5SDamon Ding 276260e469f5SDamon Ding vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, 276360e469f5SDamon Ding OVL_PORT_MUX_REG_DONE_IMD_SHIFT, 1, false); 276460e469f5SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 276560e469f5SDamon Ding IF_CTRL_REG_DONE_IMD_SHIFT, 1, false); 276660e469f5SDamon Ding 2767b0989546SSandy Huang for (i = 0; i < vop2->data->nr_vps; i++) { 2768b0989546SSandy Huang printf("vp%d have layer nr:%d[", i, vop2->vp_plane_mask[i].attached_layers_nr); 2769b0989546SSandy Huang for (j = 0; j < vop2->vp_plane_mask[i].attached_layers_nr; j++) 2770b0989546SSandy Huang printf("%d ", vop2->vp_plane_mask[i].attached_layers[j]); 2771b0989546SSandy Huang printf("], primary plane: %d\n", vop2->vp_plane_mask[i].primary_plane_id); 2772b0989546SSandy Huang } 2773b0989546SSandy Huang 27745fa6e665SDamon Ding if (is_vop3(vop2)) 27755fa6e665SDamon Ding vop3_overlay_init(vop2, state); 27765fa6e665SDamon Ding else 27775fa6e665SDamon Ding vop2_overlay_init(vop2, state); 2778b0989546SSandy Huang 27795fa6e665SDamon Ding if (is_vop3(vop2)) { 27805fa6e665SDamon Ding /* 27815fa6e665SDamon Ding * you can rewrite at dts vop node: 27825fa6e665SDamon Ding * 27835fa6e665SDamon Ding * VOP3_ESMART_8K_MODE = 0, 27845fa6e665SDamon Ding * VOP3_ESMART_4K_4K_MODE = 1, 27855fa6e665SDamon Ding * VOP3_ESMART_4K_2K_2K_MODE = 2, 27865fa6e665SDamon Ding * VOP3_ESMART_2K_2K_2K_2K_MODE = 3, 27875fa6e665SDamon Ding * 27885fa6e665SDamon Ding * &vop { 27895fa6e665SDamon Ding * esmart_lb_mode = /bits/ 8 <2>; 27905fa6e665SDamon Ding * }; 279163cb669fSSandy Huang */ 2792fa4ecc32SDamon Ding ret = ofnode_read_u32(cstate->node, "esmart_lb_mode", &vop2->esmart_lb_mode); 2793fa4ecc32SDamon Ding if (ret < 0) 27945fa6e665SDamon Ding vop2->esmart_lb_mode = vop2->data->esmart_lb_mode; 2795a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3576) 2796a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_SYS_ESMART_PD_CTRL, 2797a552a69cSDamon Ding RK3576_ESMART_LB_MODE_SEL_MASK, 2798a552a69cSDamon Ding RK3576_ESMART_LB_MODE_SEL_SHIFT, 2799a552a69cSDamon Ding vop3_get_esmart_lb_mode(vop2), true); 2800a552a69cSDamon Ding else 2801a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, 2802a552a69cSDamon Ding ESMART_LB_MODE_SEL_MASK, 2803a552a69cSDamon Ding ESMART_LB_MODE_SEL_SHIFT, 2804a552a69cSDamon Ding vop3_get_esmart_lb_mode(vop2), true); 2805d0408543SAndy Yan 28065fa6e665SDamon Ding vop3_init_esmart_scale_engine(vop2); 2807aa670293SDamon Ding 2808aa670293SDamon Ding vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL, EN_MASK, 2809aa670293SDamon Ding DSP_VS_T_SEL_SHIFT, 0, false); 281063cb669fSSandy Huang } 281163cb669fSSandy Huang 2812ecc31b6eSAndy Yan if (vop2->version == VOP_VERSION_RK3568) 281363cb669fSSandy Huang vop2_writel(vop2, RK3568_AUTO_GATING_CTRL, 0); 281463cb669fSSandy Huang 2815a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3576) { 2816a552a69cSDamon Ding vop2->merge_irq = ofnode_read_bool(cstate->node, "rockchip,vop-merge-irq"); 2817a552a69cSDamon Ding 2818f67105fbSSandy Huang /* Default use rkiommu 1.0 for axi0 */ 2819f67105fbSSandy Huang vop2_mask_write(vop2, RK3576_SYS_MMU_CTRL, EN_MASK, RKMMU_V2_EN_SHIFT, 0, true); 2820a552a69cSDamon Ding 2821a552a69cSDamon Ding /* Init frc2.0 config */ 2822a552a69cSDamon Ding vop2_writel(vop2, 0xca0, 0xc8); 2823a552a69cSDamon Ding vop2_writel(vop2, 0xca4, 0x01000100); 2824a552a69cSDamon Ding vop2_writel(vop2, 0xca8, 0x03ff0100); 2825a552a69cSDamon Ding vop2_writel(vop2, 0xda0, 0xc8); 2826a552a69cSDamon Ding vop2_writel(vop2, 0xda4, 0x01000100); 2827a552a69cSDamon Ding vop2_writel(vop2, 0xda8, 0x03ff0100); 2828a552a69cSDamon Ding 2829a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3576 && vop2->merge_irq == true) 2830a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_SYS_PORT_CTRL, EN_MASK, 2831a552a69cSDamon Ding VP_INTR_MERGE_EN_SHIFT, 1, true); 2832a552a69cSDamon Ding 2833a552a69cSDamon Ding /* Set reg done every field for interlace */ 2834a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_SYS_PORT_CTRL, INTERLACE_FRM_REG_DONE_MASK, 2835a552a69cSDamon Ding INTERLACE_FRM_REG_DONE_SHIFT, 0, false); 2836a552a69cSDamon Ding } 2837a552a69cSDamon Ding 283863cb669fSSandy Huang vop2->global_init = true; 2839d0408543SAndy Yan } 2840d0408543SAndy Yan 2841344e932aSDamon Ding static void rockchip_vop2_sharp_init(struct vop2 *vop2, struct display_state *state) 2842344e932aSDamon Ding { 2843344e932aSDamon Ding struct crtc_state *cstate = &state->crtc_state; 2844344e932aSDamon Ding const struct vop2_data *vop2_data = vop2->data; 2845344e932aSDamon Ding const struct vop2_vp_data *vp_data = &vop2_data->vp_data[cstate->crtc_id]; 2846344e932aSDamon Ding struct resource sharp_regs; 2847344e932aSDamon Ding u32 *sharp_reg_base; 2848344e932aSDamon Ding int ret; 2849344e932aSDamon Ding 2850344e932aSDamon Ding if (!(vp_data->feature & VOP_FEATURE_POST_SHARP)) 2851344e932aSDamon Ding return; 2852344e932aSDamon Ding 2853344e932aSDamon Ding ret = ofnode_read_resource_byname(cstate->node, "sharp_regs", &sharp_regs); 2854344e932aSDamon Ding if (ret) { 2855344e932aSDamon Ding printf("failed to get sharp regs\n"); 2856344e932aSDamon Ding return; 2857344e932aSDamon Ding } 2858344e932aSDamon Ding sharp_reg_base = (u32 *)sharp_regs.start; 2859344e932aSDamon Ding 2860344e932aSDamon Ding /* 2861344e932aSDamon Ding * After vop initialization, keep sw_sharp_enable always on. 2862344e932aSDamon Ding * Only enable/disable sharp submodule to avoid black screen. 2863344e932aSDamon Ding */ 2864344e932aSDamon Ding writel(0x1, sharp_reg_base); 2865344e932aSDamon Ding } 2866344e932aSDamon Ding 2867d0408543SAndy Yan static int vop2_initial(struct vop2 *vop2, struct display_state *state) 2868d0408543SAndy Yan { 28691147facaSSandy Huang rockchip_vop2_gamma_lut_init(vop2, state); 28706414e3bcSSandy Huang rockchip_vop2_cubic_lut_init(vop2, state); 2871344e932aSDamon Ding rockchip_vop2_sharp_init(vop2, state); 2872d0408543SAndy Yan 2873d0408543SAndy Yan return 0; 2874d0408543SAndy Yan } 2875d0408543SAndy Yan 2876d0408543SAndy Yan /* 2877d0408543SAndy Yan * VOP2 have multi video ports. 2878d0408543SAndy Yan * video port ------- crtc 2879d0408543SAndy Yan */ 2880d0408543SAndy Yan static int rockchip_vop2_preinit(struct display_state *state) 2881d0408543SAndy Yan { 2882d0408543SAndy Yan struct crtc_state *cstate = &state->crtc_state; 2883d0408543SAndy Yan const struct vop2_data *vop2_data = cstate->crtc->data; 2884734a0ce6SDamon Ding struct regmap *map; 2885d0408543SAndy Yan 2886d0408543SAndy Yan if (!rockchip_vop2) { 28870d2d6a97SSandy Huang rockchip_vop2 = calloc(1, sizeof(struct vop2)); 2888d0408543SAndy Yan if (!rockchip_vop2) 2889d0408543SAndy Yan return -ENOMEM; 2890d8e7f4a5SSandy Huang memset(rockchip_vop2, 0, sizeof(struct vop2)); 2891d0408543SAndy Yan rockchip_vop2->regsbak = malloc(RK3568_MAX_REG); 2892d0408543SAndy Yan rockchip_vop2->reg_len = RK3568_MAX_REG; 2893d8e7f4a5SSandy Huang #ifdef CONFIG_SPL_BUILD 2894d8e7f4a5SSandy Huang rockchip_vop2->regs = (void *)RK3528_VOP_BASE; 2895d8e7f4a5SSandy Huang #else 2896d8e7f4a5SSandy Huang rockchip_vop2->regs = dev_read_addr_ptr(cstate->dev); 2897734a0ce6SDamon Ding map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,grf"); 2898734a0ce6SDamon Ding rockchip_vop2->grf = regmap_get_range(map, 0); 2899d0408543SAndy Yan if (rockchip_vop2->grf <= 0) 290063cb669fSSandy Huang printf("%s: Get syscon grf failed (ret=%p)\n", __func__, rockchip_vop2->grf); 2901d8e7f4a5SSandy Huang #endif 2902d0408543SAndy Yan rockchip_vop2->version = vop2_data->version; 2903d0408543SAndy Yan rockchip_vop2->data = vop2_data; 2904ecc31b6eSAndy Yan if (rockchip_vop2->version == VOP_VERSION_RK3588) { 2905734a0ce6SDamon Ding map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,vop-grf"); 2906734a0ce6SDamon Ding rockchip_vop2->vop_grf = regmap_get_range(map, 0); 2907ecc31b6eSAndy Yan if (rockchip_vop2->vop_grf <= 0) 2908a552a69cSDamon Ding printf("%s: Get syscon vop_grf failed (ret=%p)\n", 2909a552a69cSDamon Ding __func__, rockchip_vop2->vop_grf); 2910b890760eSAlgea Cao map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,vo1-grf"); 2911b890760eSAlgea Cao rockchip_vop2->vo1_grf = regmap_get_range(map, 0); 2912ecc31b6eSAndy Yan if (rockchip_vop2->vo1_grf <= 0) 2913a552a69cSDamon Ding printf("%s: Get syscon vo1_grf failed (ret=%p)\n", 2914a552a69cSDamon Ding __func__, rockchip_vop2->vo1_grf); 2915734a0ce6SDamon Ding map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,pmu"); 2916734a0ce6SDamon Ding rockchip_vop2->sys_pmu = regmap_get_range(map, 0); 2917b890760eSAlgea Cao if (rockchip_vop2->sys_pmu <= 0) 2918a552a69cSDamon Ding printf("%s: Get syscon sys_pmu failed (ret=%p)\n", 2919a552a69cSDamon Ding __func__, rockchip_vop2->sys_pmu); 2920a552a69cSDamon Ding } else if (rockchip_vop2->version == VOP_VERSION_RK3576) { 2921a552a69cSDamon Ding map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,ioc-grf"); 2922a552a69cSDamon Ding rockchip_vop2->ioc_grf = regmap_get_range(map, 0); 2923a552a69cSDamon Ding if (rockchip_vop2->ioc_grf <= 0) 2924a552a69cSDamon Ding printf("%s: Get syscon ioc_grf failed (ret=%p)\n", 2925a552a69cSDamon Ding __func__, rockchip_vop2->ioc_grf); 2926a552a69cSDamon Ding map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,pmu"); 2927a552a69cSDamon Ding rockchip_vop2->sys_pmu = regmap_get_range(map, 0); 2928a552a69cSDamon Ding if (rockchip_vop2->sys_pmu <= 0) 2929a552a69cSDamon Ding printf("%s: Get syscon sys_pmu failed (ret=%p)\n", 2930a552a69cSDamon Ding __func__, rockchip_vop2->sys_pmu); 2931ecc31b6eSAndy Yan } 2932d0408543SAndy Yan } 2933d0408543SAndy Yan 2934d0408543SAndy Yan cstate->private = rockchip_vop2; 293563cb669fSSandy Huang cstate->max_output = vop2_data->vp_data[cstate->crtc_id].max_output; 293663cb669fSSandy Huang cstate->feature = vop2_data->vp_data[cstate->crtc_id].feature; 2937d0408543SAndy Yan 293889912f2dSSandy Huang vop2_global_initial(rockchip_vop2, state); 293989912f2dSSandy Huang 2940d0408543SAndy Yan return 0; 2941d0408543SAndy Yan } 2942d0408543SAndy Yan 2943ecc31b6eSAndy Yan /* 2944ecc31b6eSAndy Yan * calc the dclk on rk3588 2945ecc31b6eSAndy Yan * the available div of dclk is 1, 2, 4 2946ecc31b6eSAndy Yan * 2947ecc31b6eSAndy Yan */ 2948ecc31b6eSAndy Yan static unsigned long vop2_calc_dclk(unsigned long child_clk, unsigned long max_dclk) 2949ecc31b6eSAndy Yan { 2950ecc31b6eSAndy Yan if (child_clk * 4 <= max_dclk) 2951ecc31b6eSAndy Yan return child_clk * 4; 2952ecc31b6eSAndy Yan else if (child_clk * 2 <= max_dclk) 2953ecc31b6eSAndy Yan return child_clk * 2; 2954ecc31b6eSAndy Yan else if (child_clk <= max_dclk) 2955ecc31b6eSAndy Yan return child_clk; 2956ecc31b6eSAndy Yan else 2957ecc31b6eSAndy Yan return 0; 2958ecc31b6eSAndy Yan } 2959ecc31b6eSAndy Yan 2960ecc31b6eSAndy Yan /* 2961ecc31b6eSAndy Yan * 4 pixclk/cycle on rk3588 2962ecc31b6eSAndy Yan * RGB/eDP/HDMI: if_pixclk >= dclk_core 2963ecc31b6eSAndy Yan * DP: dp_pixclk = dclk_out <= dclk_core 2964ecc31b6eSAndy Yan * DSI: mipi_pixclk <= dclk_out <= dclk_core 2965ecc31b6eSAndy Yan */ 2966ecc31b6eSAndy Yan static unsigned long vop2_calc_cru_cfg(struct display_state *state, 2967ecc31b6eSAndy Yan int *dclk_core_div, int *dclk_out_div, 2968ecc31b6eSAndy Yan int *if_pixclk_div, int *if_dclk_div) 2969d0408543SAndy Yan { 2970d0408543SAndy Yan struct crtc_state *cstate = &state->crtc_state; 2971d0408543SAndy Yan struct connector_state *conn_state = &state->conn_state; 2972d0408543SAndy Yan struct drm_display_mode *mode = &conn_state->mode; 2973d0408543SAndy Yan struct vop2 *vop2 = cstate->private; 29740a1fb152SZhang Yubing unsigned long v_pixclk = mode->crtc_clock; 2975ecc31b6eSAndy Yan unsigned long dclk_core_rate = v_pixclk >> 2; 2976ecc31b6eSAndy Yan unsigned long dclk_rate = v_pixclk; 2977ecc31b6eSAndy Yan unsigned long dclk_out_rate; 2978ecc31b6eSAndy Yan u64 if_dclk_rate; 2979ecc31b6eSAndy Yan u64 if_pixclk_rate; 2980ecc31b6eSAndy Yan int output_type = conn_state->type; 2981ecc31b6eSAndy Yan int output_mode = conn_state->output_mode; 2982ecc31b6eSAndy Yan int K = 1; 2983ecc31b6eSAndy Yan 29840a1fb152SZhang Yubing if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE && 29850a1fb152SZhang Yubing output_mode == ROCKCHIP_OUT_MODE_YUV420) { 29860a1fb152SZhang Yubing printf("Dual channel and YUV420 can't work together\n"); 29870a1fb152SZhang Yubing return -EINVAL; 29880a1fb152SZhang Yubing } 29890a1fb152SZhang Yubing 29900a1fb152SZhang Yubing if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE || 29910a1fb152SZhang Yubing output_mode == ROCKCHIP_OUT_MODE_YUV420) 29920a1fb152SZhang Yubing K = 2; 29930a1fb152SZhang Yubing 2994ecc31b6eSAndy Yan if (output_type == DRM_MODE_CONNECTOR_HDMIA) { 2995ecc31b6eSAndy Yan /* 2996ecc31b6eSAndy Yan * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate 2997ecc31b6eSAndy Yan * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate 2998ecc31b6eSAndy Yan */ 29990a1fb152SZhang Yubing if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE || 30000a1fb152SZhang Yubing output_mode == ROCKCHIP_OUT_MODE_YUV420) { 3001b890760eSAlgea Cao dclk_rate = dclk_rate >> 1; 3002ecc31b6eSAndy Yan K = 2; 3003b890760eSAlgea Cao } 300412ee5af0SDamon Ding if (cstate->dsc_enable) { 300512ee5af0SDamon Ding if_pixclk_rate = cstate->dsc_cds_clk_rate << 1; 300612ee5af0SDamon Ding if_dclk_rate = cstate->dsc_cds_clk_rate; 3007ecc31b6eSAndy Yan } else { 3008ecc31b6eSAndy Yan if_pixclk_rate = (dclk_core_rate << 1) / K; 3009ecc31b6eSAndy Yan if_dclk_rate = dclk_core_rate / K; 3010ecc31b6eSAndy Yan } 3011ecc31b6eSAndy Yan 3012631ee99aSZhang Yubing if (v_pixclk > VOP2_MAX_DCLK_RATE) 30134b726cc6SDamon Ding dclk_rate = vop2_calc_dclk(dclk_core_rate, 30144b726cc6SDamon Ding vop2->data->vp_data[cstate->crtc_id].max_dclk); 3015631ee99aSZhang Yubing 3016ecc31b6eSAndy Yan if (!dclk_rate) { 3017ecc31b6eSAndy Yan printf("DP if_pixclk_rate out of range(max_dclk: %d KHZ, dclk_core: %lld KHZ)\n", 30184b726cc6SDamon Ding vop2->data->vp_data[cstate->crtc_id].max_dclk, if_pixclk_rate); 3019ecc31b6eSAndy Yan return -EINVAL; 3020ecc31b6eSAndy Yan } 3021ecc31b6eSAndy Yan *if_pixclk_div = dclk_rate / if_pixclk_rate; 3022ecc31b6eSAndy Yan *if_dclk_div = dclk_rate / if_dclk_rate; 3023b890760eSAlgea Cao *dclk_core_div = dclk_rate / dclk_core_rate; 3024b890760eSAlgea Cao printf("dclk:%lu,if_pixclk_div;%d,if_dclk_div:%d\n", 3025b890760eSAlgea Cao dclk_rate, *if_pixclk_div, *if_dclk_div); 3026ecc31b6eSAndy Yan } else if (output_type == DRM_MODE_CONNECTOR_eDP) { 3027ecc31b6eSAndy Yan /* edp_pixclk = edp_dclk > dclk_core */ 3028ecc31b6eSAndy Yan if_pixclk_rate = v_pixclk / K; 3029ecc31b6eSAndy Yan if_dclk_rate = v_pixclk / K; 3030ecc31b6eSAndy Yan dclk_rate = if_pixclk_rate * K; 3031ecc31b6eSAndy Yan *dclk_core_div = dclk_rate / dclk_core_rate; 3032ecc31b6eSAndy Yan *if_pixclk_div = dclk_rate / if_pixclk_rate; 3033ecc31b6eSAndy Yan *if_dclk_div = *if_pixclk_div; 3034ecc31b6eSAndy Yan } else if (output_type == DRM_MODE_CONNECTOR_DisplayPort) { 3035ecc31b6eSAndy Yan dclk_out_rate = v_pixclk >> 2; 30360a1fb152SZhang Yubing dclk_out_rate = dclk_out_rate / K; 3037ecc31b6eSAndy Yan 30384b726cc6SDamon Ding dclk_rate = vop2_calc_dclk(dclk_out_rate, 30394b726cc6SDamon Ding vop2->data->vp_data[cstate->crtc_id].max_dclk); 3040ecc31b6eSAndy Yan if (!dclk_rate) { 3041ecc31b6eSAndy Yan printf("DP dclk_core out of range(max_dclk: %d KHZ, dclk_core: %ld KHZ)\n", 30424b726cc6SDamon Ding vop2->data->vp_data[cstate->crtc_id].max_dclk, dclk_core_rate); 3043ecc31b6eSAndy Yan return -EINVAL; 3044ecc31b6eSAndy Yan } 3045ecc31b6eSAndy Yan *dclk_out_div = dclk_rate / dclk_out_rate; 3046ecc31b6eSAndy Yan *dclk_core_div = dclk_rate / dclk_core_rate; 3047ecc31b6eSAndy Yan } else if (output_type == DRM_MODE_CONNECTOR_DSI) { 3048ecc31b6eSAndy Yan if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 3049ecc31b6eSAndy Yan K = 2; 305012ee5af0SDamon Ding if (cstate->dsc_enable) 305112ee5af0SDamon Ding /* dsc output is 96bit, dsi input is 192 bit */ 305212ee5af0SDamon Ding if_pixclk_rate = cstate->dsc_cds_clk_rate >> 1; 3053ecc31b6eSAndy Yan else 3054ecc31b6eSAndy Yan if_pixclk_rate = dclk_core_rate / K; 3055ecc31b6eSAndy Yan /* dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4 */ 305612ee5af0SDamon Ding dclk_out_rate = dclk_core_rate / K; 3057ecc31b6eSAndy Yan /* dclk_rate = N * dclk_core_rate N = (1,2,4 ), we get a little factor here */ 30584b726cc6SDamon Ding dclk_rate = vop2_calc_dclk(dclk_out_rate, 30594b726cc6SDamon Ding vop2->data->vp_data[cstate->crtc_id].max_dclk); 30609f076eccSZhang Yubing if (!dclk_rate) { 30619f076eccSZhang Yubing printf("MIPI dclk out of range(max_dclk: %d KHZ, dclk_rate: %ld KHZ)\n", 30624b726cc6SDamon Ding vop2->data->vp_data[cstate->crtc_id].max_dclk, dclk_rate); 30639f076eccSZhang Yubing return -EINVAL; 30649f076eccSZhang Yubing } 306512ee5af0SDamon Ding 306612ee5af0SDamon Ding if (cstate->dsc_enable) 3067d57af898SDamon Ding dclk_rate /= cstate->dsc_slice_num; 306812ee5af0SDamon Ding 3069ecc31b6eSAndy Yan *dclk_out_div = dclk_rate / dclk_out_rate; 3070ecc31b6eSAndy Yan *dclk_core_div = dclk_rate / dclk_core_rate; 3071ecc31b6eSAndy Yan *if_pixclk_div = 1; /*mipi pixclk == dclk_out*/ 307212ee5af0SDamon Ding if (cstate->dsc_enable) 30731ace1b6dSDamon Ding *if_pixclk_div = dclk_out_rate * 1000LL / if_pixclk_rate; 3074ecc31b6eSAndy Yan 3075ecc31b6eSAndy Yan } else if (output_type == DRM_MODE_CONNECTOR_DPI) { 3076ecc31b6eSAndy Yan dclk_rate = v_pixclk; 3077ecc31b6eSAndy Yan *dclk_core_div = dclk_rate / dclk_core_rate; 3078ecc31b6eSAndy Yan } 3079ecc31b6eSAndy Yan 3080ecc31b6eSAndy Yan *if_pixclk_div = ilog2(*if_pixclk_div); 3081ecc31b6eSAndy Yan *if_dclk_div = ilog2(*if_dclk_div); 3082ecc31b6eSAndy Yan *dclk_core_div = ilog2(*dclk_core_div); 3083ecc31b6eSAndy Yan *dclk_out_div = ilog2(*dclk_out_div); 3084ecc31b6eSAndy Yan 3085ecc31b6eSAndy Yan return dclk_rate; 3086ecc31b6eSAndy Yan } 3087ecc31b6eSAndy Yan 308812ee5af0SDamon Ding static int vop2_calc_dsc_clk(struct display_state *state) 3089ecc31b6eSAndy Yan { 309012ee5af0SDamon Ding struct connector_state *conn_state = &state->conn_state; 3091ecc31b6eSAndy Yan struct drm_display_mode *mode = &conn_state->mode; 309212ee5af0SDamon Ding struct crtc_state *cstate = &state->crtc_state; 30931ace1b6dSDamon Ding u64 v_pixclk = mode->crtc_clock * 1000LL; /* video timing pixclk */ 3094ecc31b6eSAndy Yan u8 k = 1; 3095ecc31b6eSAndy Yan 3096ecc31b6eSAndy Yan if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 3097ecc31b6eSAndy Yan k = 2; 3098ecc31b6eSAndy Yan 309912ee5af0SDamon Ding cstate->dsc_txp_clk_rate = v_pixclk; 310012ee5af0SDamon Ding do_div(cstate->dsc_txp_clk_rate, (cstate->dsc_pixel_num * k)); 3101ecc31b6eSAndy Yan 310212ee5af0SDamon Ding cstate->dsc_pxl_clk_rate = v_pixclk; 310312ee5af0SDamon Ding do_div(cstate->dsc_pxl_clk_rate, (cstate->dsc_slice_num * k)); 3104ecc31b6eSAndy Yan 3105ecc31b6eSAndy Yan /* dsc_cds = crtc_clock / (cds_dat_width / bits_per_pixel) 3106ecc31b6eSAndy Yan * cds_dat_width = 96; 3107ecc31b6eSAndy Yan * bits_per_pixel = [8-12]; 3108b61227a3SDamon Ding * As cds clk is div from txp clk and only support 1/2/4 div, 3109b61227a3SDamon Ding * so when txp_clk is equal to v_pixclk, we set dsc_cds = crtc_clock / 4, 3110b61227a3SDamon Ding * otherwise dsc_cds = crtc_clock / 8; 3111ecc31b6eSAndy Yan */ 3112b61227a3SDamon Ding cstate->dsc_cds_clk_rate = v_pixclk / (cstate->dsc_txp_clk_rate == v_pixclk ? 4 : 8); 3113ecc31b6eSAndy Yan 3114ecc31b6eSAndy Yan return 0; 3115ecc31b6eSAndy Yan } 3116ecc31b6eSAndy Yan 3117ecc31b6eSAndy Yan static unsigned long rk3588_vop2_if_cfg(struct display_state *state) 3118ecc31b6eSAndy Yan { 3119ecc31b6eSAndy Yan struct crtc_state *cstate = &state->crtc_state; 3120ecc31b6eSAndy Yan struct connector_state *conn_state = &state->conn_state; 3121ecc31b6eSAndy Yan struct drm_display_mode *mode = &conn_state->mode; 312212ee5af0SDamon Ding struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap; 3123ecc31b6eSAndy Yan struct vop2 *vop2 = cstate->private; 312452ee18acSSandy Huang u32 vp_offset = (cstate->crtc_id * 0x100); 3125ecc31b6eSAndy Yan u16 hdisplay = mode->crtc_hdisplay; 3126ecc31b6eSAndy Yan int output_if = conn_state->output_if; 3127ecc31b6eSAndy Yan int if_pixclk_div = 0; 3128ecc31b6eSAndy Yan int if_dclk_div = 0; 3129ecc31b6eSAndy Yan unsigned long dclk_rate; 31305d2768f7SDamon Ding bool dclk_inv, yc_swap = false; 3131d0408543SAndy Yan u32 val; 3132ecc31b6eSAndy Yan 31335d2768f7SDamon Ding dclk_inv = (conn_state->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0; 3134b890760eSAlgea Cao if (output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) { 3135b890760eSAlgea Cao val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0; 3136b890760eSAlgea Cao val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0; 3137b890760eSAlgea Cao } else { 3138ecc31b6eSAndy Yan val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 3139ecc31b6eSAndy Yan val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 3140b890760eSAlgea Cao } 3141ecc31b6eSAndy Yan 314212ee5af0SDamon Ding if (cstate->dsc_enable) { 314312ee5af0SDamon Ding int k = 1; 314412ee5af0SDamon Ding 3145ecc31b6eSAndy Yan if (!vop2->data->nr_dscs) { 314612ee5af0SDamon Ding printf("Unsupported DSC\n"); 3147ecc31b6eSAndy Yan return 0; 3148ecc31b6eSAndy Yan } 314912ee5af0SDamon Ding 315012ee5af0SDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 315112ee5af0SDamon Ding k = 2; 315212ee5af0SDamon Ding 315312ee5af0SDamon Ding cstate->dsc_id = output_if & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_HDMI0) ? 0 : 1; 315412ee5af0SDamon Ding cstate->dsc_slice_num = hdisplay / dsc_sink_cap->slice_width / k; 315512ee5af0SDamon Ding cstate->dsc_pixel_num = cstate->dsc_slice_num > 4 ? 4 : cstate->dsc_slice_num; 315612ee5af0SDamon Ding 315712ee5af0SDamon Ding vop2_calc_dsc_clk(state); 315812ee5af0SDamon Ding printf("Enable DSC%d slice:%dx%d, slice num:%d\n", 315912ee5af0SDamon Ding cstate->dsc_id, dsc_sink_cap->slice_width, 316012ee5af0SDamon Ding dsc_sink_cap->slice_height, cstate->dsc_slice_num); 3161ecc31b6eSAndy Yan } 3162ecc31b6eSAndy Yan 3163b61227a3SDamon Ding dclk_rate = vop2_calc_cru_cfg(state, &cstate->dclk_core_div, &cstate->dclk_out_div, &if_pixclk_div, &if_dclk_div); 3164ecc31b6eSAndy Yan 3165ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_RGB) { 3166ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 3167ecc31b6eSAndy Yan 4, false); 31685d2768f7SDamon Ding vop2_grf_writel(vop2, vop2->grf, RK3588_GRF_SOC_CON1, EN_MASK, 31695d2768f7SDamon Ding RK3588_GRF_VOP_DCLK_INV_SEL_SHIFT, !dclk_inv); 3170ecc31b6eSAndy Yan } 3171ecc31b6eSAndy Yan 3172ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_BT1120) { 3173ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 3174ecc31b6eSAndy Yan 3, false); 31755d2768f7SDamon Ding vop2_grf_writel(vop2, vop2->grf, RK3588_GRF_SOC_CON1, EN_MASK, 31765d2768f7SDamon Ding RK3588_GRF_VOP_DCLK_INV_SEL_SHIFT, !dclk_inv); 31775d2768f7SDamon Ding yc_swap = is_yc_swap(conn_state->bus_format); 31785d2768f7SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, RK3588_BT1120_YC_SWAP_SHIFT, 31795d2768f7SDamon Ding yc_swap, false); 3180ecc31b6eSAndy Yan } 3181ecc31b6eSAndy Yan 3182ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_BT656) { 3183ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 3184ecc31b6eSAndy Yan 2, false); 31855d2768f7SDamon Ding vop2_grf_writel(vop2, vop2->grf, RK3588_GRF_SOC_CON1, EN_MASK, 31865d2768f7SDamon Ding RK3588_GRF_VOP_DCLK_INV_SEL_SHIFT, !dclk_inv); 31875d2768f7SDamon Ding yc_swap = is_yc_swap(conn_state->bus_format); 31885d2768f7SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, RK3588_BT656_YC_SWAP_SHIFT, 31895d2768f7SDamon Ding yc_swap, false); 3190ecc31b6eSAndy Yan } 3191ecc31b6eSAndy Yan 3192ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_MIPI0) { 3193ecc31b6eSAndy Yan if (cstate->crtc_id == 2) 3194ecc31b6eSAndy Yan val = 0; 3195ecc31b6eSAndy Yan else 3196ecc31b6eSAndy Yan val = 1; 319741874944SGuochun Huang 31983df6e59eSDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE) 319941874944SGuochun Huang vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 320041874944SGuochun Huang RK3588_MIPI_DSI0_MODE_SEL_SHIFT, 1, false); 320141874944SGuochun Huang 3202ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI0_EN_SHIFT, 3203ecc31b6eSAndy Yan 1, false); 3204ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, 1, RK3588_MIPI0_MUX_SHIFT, val, false); 3205ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI0_PIXCLK_DIV_SHIFT, 3206ecc31b6eSAndy Yan if_pixclk_div, false); 320741874944SGuochun Huang 320841874944SGuochun Huang if (conn_state->hold_mode) { 320941874944SGuochun Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 32108e7ef808SDamon Ding EN_MASK, EDPI_TE_EN, !cstate->soft_te, false); 321141874944SGuochun Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 321241874944SGuochun Huang EN_MASK, EDPI_WMS_HOLD_EN, 1, false); 321341874944SGuochun Huang } 3214ecc31b6eSAndy Yan } 3215ecc31b6eSAndy Yan 3216ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_MIPI1) { 3217ecc31b6eSAndy Yan if (cstate->crtc_id == 2) 3218ecc31b6eSAndy Yan val = 0; 3219ecc31b6eSAndy Yan else if (cstate->crtc_id == 3) 3220ecc31b6eSAndy Yan val = 1; 3221ecc31b6eSAndy Yan else 3222ecc31b6eSAndy Yan val = 3; /*VP1*/ 32233df6e59eSDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE) 322441874944SGuochun Huang vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 322541874944SGuochun Huang RK3588_MIPI_DSI1_MODE_SEL_SHIFT, 1, false); 322641874944SGuochun Huang 3227ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI1_EN_SHIFT, 3228ecc31b6eSAndy Yan 1, false); 3229ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, MIPI1_MUX_SHIFT, 3230ecc31b6eSAndy Yan val, false); 3231ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI1_PIXCLK_DIV_SHIFT, 3232ecc31b6eSAndy Yan if_pixclk_div, false); 323341874944SGuochun Huang 323441874944SGuochun Huang if (conn_state->hold_mode) { 323541874944SGuochun Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 32368e7ef808SDamon Ding EN_MASK, EDPI_TE_EN, !cstate->soft_te, false); 323741874944SGuochun Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 323841874944SGuochun Huang EN_MASK, EDPI_WMS_HOLD_EN, 1, false); 323941874944SGuochun Huang } 3240ecc31b6eSAndy Yan } 3241ecc31b6eSAndy Yan 3242ecc31b6eSAndy Yan if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 32433df6e59eSDamon Ding vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 32443df6e59eSDamon Ding MIPI_DUAL_EN_SHIFT, 1, false); 3245ecc31b6eSAndy Yan if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 3246ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 3247ecc31b6eSAndy Yan EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1, 3248ecc31b6eSAndy Yan false); 32490a1fb152SZhang Yubing switch (conn_state->type) { 32500a1fb152SZhang Yubing case DRM_MODE_CONNECTOR_DisplayPort: 32510a1fb152SZhang Yubing vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 32520a1fb152SZhang Yubing RK3588_DP_DUAL_EN_SHIFT, 1, false); 32530a1fb152SZhang Yubing break; 32540a1fb152SZhang Yubing case DRM_MODE_CONNECTOR_eDP: 32550a1fb152SZhang Yubing vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 32560a1fb152SZhang Yubing RK3588_EDP_DUAL_EN_SHIFT, 1, false); 32570a1fb152SZhang Yubing break; 32580a1fb152SZhang Yubing case DRM_MODE_CONNECTOR_HDMIA: 32590a1fb152SZhang Yubing vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 32600a1fb152SZhang Yubing RK3588_HDMI_DUAL_EN_SHIFT, 1, false); 32610a1fb152SZhang Yubing break; 32620a1fb152SZhang Yubing case DRM_MODE_CONNECTOR_DSI: 32630a1fb152SZhang Yubing vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 32640a1fb152SZhang Yubing RK3568_MIPI_DUAL_EN_SHIFT, 1, false); 32650a1fb152SZhang Yubing break; 32660a1fb152SZhang Yubing default: 32670a1fb152SZhang Yubing break; 32680a1fb152SZhang Yubing } 3269ecc31b6eSAndy Yan } 3270ecc31b6eSAndy Yan 3271ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_eDP0) { 3272ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP0_EN_SHIFT, 3273ecc31b6eSAndy Yan 1, false); 3274ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT, 3275ecc31b6eSAndy Yan cstate->crtc_id, false); 3276ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT, 3277ecc31b6eSAndy Yan if_dclk_div, false); 3278ecc31b6eSAndy Yan 3279ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT, 3280ecc31b6eSAndy Yan if_pixclk_div, false); 3281ecc31b6eSAndy Yan 3282ecc31b6eSAndy Yan vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 3283ecc31b6eSAndy Yan RK3588_GRF_EDP0_ENABLE_SHIFT, 1); 3284ecc31b6eSAndy Yan } 3285ecc31b6eSAndy Yan 3286ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_eDP1) { 3287ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP1_EN_SHIFT, 3288ecc31b6eSAndy Yan 1, false); 3289ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT, 3290ecc31b6eSAndy Yan cstate->crtc_id, false); 3291ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT, 3292ecc31b6eSAndy Yan if_dclk_div, false); 3293ecc31b6eSAndy Yan 3294ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT, 3295ecc31b6eSAndy Yan if_pixclk_div, false); 32961848455fSDamon Ding 32971848455fSDamon Ding vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 32981848455fSDamon Ding RK3588_GRF_EDP1_ENABLE_SHIFT, 1); 3299ecc31b6eSAndy Yan } 3300ecc31b6eSAndy Yan 3301ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_HDMI0) { 3302ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI0_EN_SHIFT, 3303ecc31b6eSAndy Yan 1, false); 3304ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT, 3305ecc31b6eSAndy Yan cstate->crtc_id, false); 3306ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT, 3307ecc31b6eSAndy Yan if_dclk_div, false); 3308ecc31b6eSAndy Yan 3309ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT, 3310ecc31b6eSAndy Yan if_pixclk_div, false); 3311b890760eSAlgea Cao 3312b890760eSAlgea Cao vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 3313b890760eSAlgea Cao RK3588_GRF_HDMITX0_ENABLE_SHIFT, 1); 3314b890760eSAlgea Cao vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0, 3315b890760eSAlgea Cao HDMI_SYNC_POL_MASK, 3316b890760eSAlgea Cao HDMI0_SYNC_POL_SHIFT, val); 3317ecc31b6eSAndy Yan } 3318ecc31b6eSAndy Yan 3319ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_HDMI1) { 3320ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI1_EN_SHIFT, 3321ecc31b6eSAndy Yan 1, false); 3322ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT, 3323ecc31b6eSAndy Yan cstate->crtc_id, false); 3324ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT, 3325ecc31b6eSAndy Yan if_dclk_div, false); 3326ecc31b6eSAndy Yan 3327ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT, 3328ecc31b6eSAndy Yan if_pixclk_div, false); 3329b890760eSAlgea Cao 3330b890760eSAlgea Cao vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 3331b890760eSAlgea Cao RK3588_GRF_HDMITX1_ENABLE_SHIFT, 1); 3332b890760eSAlgea Cao vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0, 3333b890760eSAlgea Cao HDMI_SYNC_POL_MASK, 3334b890760eSAlgea Cao HDMI1_SYNC_POL_SHIFT, val); 3335ecc31b6eSAndy Yan } 3336ecc31b6eSAndy Yan 3337ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_DP0) { 3338ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP0_EN_SHIFT, 3339ecc31b6eSAndy Yan 1, false); 3340ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP0_MUX_SHIFT, 3341ecc31b6eSAndy Yan cstate->crtc_id, false); 3342ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK, 3343ecc31b6eSAndy Yan RK3588_DP0_PIN_POL_SHIFT, val, false); 3344ecc31b6eSAndy Yan } 3345ecc31b6eSAndy Yan 3346ecc31b6eSAndy Yan if (output_if & VOP_OUTPUT_IF_DP1) { 3347108c5f8bSZhang Yubing vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP1_EN_SHIFT, 3348ecc31b6eSAndy Yan 1, false); 3349ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP1_MUX_SHIFT, 3350ecc31b6eSAndy Yan cstate->crtc_id, false); 3351ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK, 3352ecc31b6eSAndy Yan RK3588_DP1_PIN_POL_SHIFT, val, false); 3353ecc31b6eSAndy Yan } 3354ecc31b6eSAndy Yan 3355ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3, 3356b61227a3SDamon Ding DCLK_CORE_DIV_SHIFT, cstate->dclk_core_div, false); 3357ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3, 3358b61227a3SDamon Ding DCLK_OUT_DIV_SHIFT, cstate->dclk_out_div, false); 3359ecc31b6eSAndy Yan 3360ecc31b6eSAndy Yan return dclk_rate; 3361ecc31b6eSAndy Yan } 3362ecc31b6eSAndy Yan 3363a552a69cSDamon Ding static unsigned long rk3576_vop2_if_cfg(struct display_state *state) 3364a552a69cSDamon Ding { 3365a552a69cSDamon Ding struct crtc_state *cstate = &state->crtc_state; 3366a552a69cSDamon Ding struct connector_state *conn_state = &state->conn_state; 3367a552a69cSDamon Ding struct drm_display_mode *mode = &conn_state->mode; 3368a552a69cSDamon Ding struct vop2 *vop2 = cstate->private; 3369a552a69cSDamon Ding u32 vp_offset = (cstate->crtc_id * 0x100); 3370a552a69cSDamon Ding u8 port_pix_rate = vop2->data->vp_data[cstate->crtc_id].pixel_rate; 3371a552a69cSDamon Ding int output_if = conn_state->output_if; 3372a552a69cSDamon Ding bool dclk_inv, yc_swap = false; 3373a552a69cSDamon Ding bool split_mode = !!(conn_state->output_flags & 3374a552a69cSDamon Ding ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE); 3375a552a69cSDamon Ding bool post_dclk_core_sel = false, pix_half_rate = false, post_dclk_out_sel = false; 3376a552a69cSDamon Ding bool interface_dclk_sel, interface_pix_clk_sel = false; 3377a552a69cSDamon Ding bool double_pixel = mode->flags & DRM_MODE_FLAG_DBLCLK || 3378a552a69cSDamon Ding conn_state->output_if & VOP_OUTPUT_IF_BT656; 3379a552a69cSDamon Ding u32 val; 3380a552a69cSDamon Ding 3381a552a69cSDamon Ding dclk_inv = (conn_state->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0; 3382a552a69cSDamon Ding if (output_if & VOP_OUTPUT_IF_MIPI0) { 3383a552a69cSDamon Ding /* 3384a552a69cSDamon Ding * RK3576 DSI CTRL hsync/vsync polarity is positive and can't update, 3385a552a69cSDamon Ding * so set VOP hsync/vsync polarity as positive by default. 3386a552a69cSDamon Ding */ 3387a552a69cSDamon Ding val = BIT(HSYNC_POSITIVE) | BIT(VSYNC_POSITIVE); 3388a552a69cSDamon Ding } else { 3389a552a69cSDamon Ding val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 3390a552a69cSDamon Ding val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 3391a552a69cSDamon Ding } 3392a552a69cSDamon Ding 3393a552a69cSDamon Ding if (cstate->crtc_id == 1 || cstate->crtc_id == 2 || 3394a552a69cSDamon Ding (cstate->crtc_id == 0 && conn_state->output_if & VOP_OUTPUT_IF_eDP0) || 3395a552a69cSDamon Ding (conn_state->output_if & VOP_OUTPUT_IF_HDMI0 && mode->crtc_clock <= VOP2_MAX_DCLK_RATE)) 3396a552a69cSDamon Ding cstate->crtc->vps[cstate->crtc_id].dclk_div = 1; /* no div */ 3397a552a69cSDamon Ding else 3398a552a69cSDamon Ding cstate->crtc->vps[cstate->crtc_id].dclk_div = 2; /* div2 */ 3399a552a69cSDamon Ding 3400a552a69cSDamon Ding if (double_pixel || 3401a552a69cSDamon Ding (cstate->crtc_id == 0 && conn_state->output_if & VOP_OUTPUT_IF_eDP0) || 3402a552a69cSDamon Ding (conn_state->output_if & VOP_OUTPUT_IF_HDMI0 && mode->crtc_clock <= VOP2_MAX_DCLK_RATE)) 3403a552a69cSDamon Ding post_dclk_core_sel = true; /* div2 */ 3404a552a69cSDamon Ding else 3405a552a69cSDamon Ding post_dclk_core_sel = false; /* no div */ 3406a552a69cSDamon Ding 3407a552a69cSDamon Ding if (split_mode || conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420) { 3408a552a69cSDamon Ding pix_half_rate = true; 3409a552a69cSDamon Ding post_dclk_out_sel = true; 3410a552a69cSDamon Ding } 3411a552a69cSDamon Ding 3412a552a69cSDamon Ding if (output_if & VOP_OUTPUT_IF_RGB) { 3413a552a69cSDamon Ding interface_dclk_sel = pix_half_rate == 1 ? 1 : 0; 3414a552a69cSDamon Ding /* 3415a552a69cSDamon Ding * RGB interface_pix_clk_sel will auto config according 3416a552a69cSDamon Ding * to rgb_en/bt1120_en/bt656_en. 3417a552a69cSDamon Ding */ 3418a552a69cSDamon Ding } else if (output_if & VOP_OUTPUT_IF_eDP0) { 3419a552a69cSDamon Ding interface_dclk_sel = pix_half_rate == 1 ? 1 : 0; 3420a552a69cSDamon Ding interface_pix_clk_sel = port_pix_rate == 2 ? 1 : 0; 3421a552a69cSDamon Ding } else { 3422a552a69cSDamon Ding interface_dclk_sel = pix_half_rate == 1 ? 1 : 0; 3423a552a69cSDamon Ding interface_pix_clk_sel = port_pix_rate == 1 ? 1 : 0; 3424a552a69cSDamon Ding } 3425a552a69cSDamon Ding 3426a552a69cSDamon Ding /* dclk_core */ 3427a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_VP0_DCLK_SEL + vp_offset, EN_MASK, 3428a552a69cSDamon Ding RK3576_DCLK_CORE_SEL_SHIFT, post_dclk_core_sel, false); 3429a552a69cSDamon Ding /* dclk_out */ 3430a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_VP0_DCLK_SEL + vp_offset, EN_MASK, 3431a552a69cSDamon Ding RK3576_DCLK_OUT_SEL_SHIFT, post_dclk_out_sel, false); 3432a552a69cSDamon Ding 3433a552a69cSDamon Ding if (output_if & VOP_OUTPUT_IF_RGB) { 3434a552a69cSDamon Ding /* 0: dclk_core, 1: dclk_out */ 3435a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_DCLK_SEL_MASK, 3436a552a69cSDamon Ding RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false); 3437a552a69cSDamon Ding 3438a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3439a552a69cSDamon Ding RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false); 3440a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3441a552a69cSDamon Ding RK3576_IF_CLK_OUT_EN_SHIFT, 1, false); 3442a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3443a552a69cSDamon Ding RK3576_IF_OUT_EN_SHIFT, 1, false); 3444a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_PORT_SEL_MASK, 3445a552a69cSDamon Ding RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false); 3446a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_PIN_POL_MASK, 3447a552a69cSDamon Ding RK3576_IF_PIN_POL_SHIFT, val, false); 3448a552a69cSDamon Ding vop2_grf_writel(vop2, vop2->ioc_grf, RK3576_VCCIO_IOC_MISC_CON8, EN_MASK, 3449a552a69cSDamon Ding RK3576_IOC_VOP_DCLK_INV_SEL_SHIFT, dclk_inv); 3450a552a69cSDamon Ding } 3451a552a69cSDamon Ding 3452a552a69cSDamon Ding if (output_if & VOP_OUTPUT_IF_BT1120) { 3453a552a69cSDamon Ding /* 0: dclk_core, 1: dclk_out */ 3454a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_DCLK_SEL_MASK, 3455a552a69cSDamon Ding RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false); 3456a552a69cSDamon Ding 3457a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3458a552a69cSDamon Ding RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false); 3459a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3460a552a69cSDamon Ding RK3576_IF_CLK_OUT_EN_SHIFT, 1, false); 3461a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3462a552a69cSDamon Ding RK3576_IF_OUT_EN_SHIFT, 1, false); 3463a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3464a552a69cSDamon Ding RK3576_BT1120_OUT_EN_SHIFT, 1, false); 3465a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_PORT_SEL_MASK, 3466a552a69cSDamon Ding RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false); 3467a552a69cSDamon Ding vop2_grf_writel(vop2, vop2->ioc_grf, RK3576_VCCIO_IOC_MISC_CON8, EN_MASK, 3468a552a69cSDamon Ding RK3576_IOC_VOP_DCLK_INV_SEL_SHIFT, !dclk_inv); 3469a552a69cSDamon Ding yc_swap = is_yc_swap(conn_state->bus_format); 3470a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3471a552a69cSDamon Ding RK3576_BT1120_YC_SWAP_SHIFT, yc_swap, false); 3472a552a69cSDamon Ding } 3473a552a69cSDamon Ding 3474a552a69cSDamon Ding if (output_if & VOP_OUTPUT_IF_BT656) { 3475a552a69cSDamon Ding /* 0: dclk_core, 1: dclk_out */ 3476a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_DCLK_SEL_MASK, 3477a552a69cSDamon Ding RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false); 3478a552a69cSDamon Ding 3479a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3480a552a69cSDamon Ding RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false); 3481a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3482a552a69cSDamon Ding RK3576_IF_CLK_OUT_EN_SHIFT, 1, false); 3483a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3484a552a69cSDamon Ding RK3576_IF_OUT_EN_SHIFT, 1, false); 3485a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3486a552a69cSDamon Ding RK3576_BT656_OUT_EN_SHIFT, 1, false); 3487a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, RK3576_IF_PORT_SEL_MASK, 3488a552a69cSDamon Ding RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false); 3489a552a69cSDamon Ding vop2_grf_writel(vop2, vop2->ioc_grf, RK3576_VCCIO_IOC_MISC_CON8, EN_MASK, 3490a552a69cSDamon Ding RK3576_IOC_VOP_DCLK_INV_SEL_SHIFT, !dclk_inv); 3491a552a69cSDamon Ding yc_swap = is_yc_swap(conn_state->bus_format); 3492a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_RGB_IF_CTRL, EN_MASK, 3493a552a69cSDamon Ding RK3576_BT656_YC_SWAP_SHIFT, yc_swap, false); 3494a552a69cSDamon Ding } 3495a552a69cSDamon Ding 3496a552a69cSDamon Ding if (output_if & VOP_OUTPUT_IF_MIPI0) { 3497a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, RK3576_IF_DCLK_SEL_MASK, 3498a552a69cSDamon Ding RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false); 3499a552a69cSDamon Ding /* 0: div2, 1: div4 */ 3500a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, RK3576_IF_PIX_CLK_SEL_MASK, 3501a552a69cSDamon Ding RK3576_IF_PIX_CLK_SEL_SHIFT, interface_pix_clk_sel, false); 3502a552a69cSDamon Ding 3503a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, EN_MASK, 3504a552a69cSDamon Ding RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false); 3505a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, EN_MASK, 3506a552a69cSDamon Ding RK3576_IF_CLK_OUT_EN_SHIFT, 1, false); 3507a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, EN_MASK, 3508a552a69cSDamon Ding RK3576_IF_OUT_EN_SHIFT, 1, false); 3509a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, RK3576_IF_PORT_SEL_MASK, 3510a552a69cSDamon Ding RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false); 3511a552a69cSDamon Ding /* 3512a552a69cSDamon Ding * RK3576 DSI CTRL hsync/vsync polarity is positive and can't update, 3513a552a69cSDamon Ding * so set VOP hsync/vsync polarity as positive by default. 3514a552a69cSDamon Ding */ 3515a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3576) 3516a552a69cSDamon Ding val = BIT(HSYNC_POSITIVE) | BIT(VSYNC_POSITIVE); 3517a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, RK3576_IF_PIN_POL_MASK, 3518a552a69cSDamon Ding RK3576_IF_PIN_POL_SHIFT, val, false); 3519a552a69cSDamon Ding 3520a552a69cSDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE) 3521a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, EN_MASK, 3522a552a69cSDamon Ding RK3576_MIPI_CMD_MODE_SHIFT, 1, false); 3523a552a69cSDamon Ding 3524a552a69cSDamon Ding if (conn_state->hold_mode) { 3525a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 3526a552a69cSDamon Ding EDPI_TE_EN, !cstate->soft_te, false); 3527a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 3528a552a69cSDamon Ding EDPI_WMS_HOLD_EN, 1, false); 3529a552a69cSDamon Ding } 3530a552a69cSDamon Ding } 3531a552a69cSDamon Ding 3532a552a69cSDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 3533a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 3534a552a69cSDamon Ding MIPI_DUAL_EN_SHIFT, 1, false); 3535a552a69cSDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 3536a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 3537a552a69cSDamon Ding MIPI_DUAL_SWAP_EN_SHIFT, 1, false); 3538a552a69cSDamon Ding switch (conn_state->type) { 3539a552a69cSDamon Ding case DRM_MODE_CONNECTOR_DisplayPort: 3540a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, EN_MASK, 3541a552a69cSDamon Ding RK3576_IF_SPLIT_EN_SHIFT, 1, false); 3542a552a69cSDamon Ding break; 3543a552a69cSDamon Ding case DRM_MODE_CONNECTOR_eDP: 3544a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, EN_MASK, 3545a552a69cSDamon Ding RK3576_IF_SPLIT_EN_SHIFT, 1, false); 3546a552a69cSDamon Ding break; 3547a552a69cSDamon Ding case DRM_MODE_CONNECTOR_HDMIA: 3548a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, EN_MASK, 3549a552a69cSDamon Ding RK3576_IF_SPLIT_EN_SHIFT, 1, false); 3550a552a69cSDamon Ding break; 3551a552a69cSDamon Ding case DRM_MODE_CONNECTOR_DSI: 3552a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_MIPI0_IF_CTRL, EN_MASK, 3553a552a69cSDamon Ding RK3576_IF_SPLIT_EN_SHIFT, 1, false); 3554a552a69cSDamon Ding break; 3555a552a69cSDamon Ding default: 3556a552a69cSDamon Ding break; 3557a552a69cSDamon Ding } 3558a552a69cSDamon Ding } 3559a552a69cSDamon Ding 3560a552a69cSDamon Ding if (output_if & VOP_OUTPUT_IF_eDP0) { 3561a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, RK3576_IF_DCLK_SEL_MASK, 3562a552a69cSDamon Ding RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false); 3563a552a69cSDamon Ding /* 0: dclk, 1: port0_dclk */ 3564a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, RK3576_IF_PIX_CLK_SEL_MASK, 3565a552a69cSDamon Ding RK3576_IF_PIX_CLK_SEL_SHIFT, interface_pix_clk_sel, false); 3566a552a69cSDamon Ding 3567a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, EN_MASK, 3568a552a69cSDamon Ding RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false); 3569a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, EN_MASK, 3570a552a69cSDamon Ding RK3576_IF_CLK_OUT_EN_SHIFT, 1, false); 3571a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, EN_MASK, 3572a552a69cSDamon Ding RK3576_IF_OUT_EN_SHIFT, 1, false); 3573a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, RK3576_IF_PORT_SEL_MASK, 3574a552a69cSDamon Ding RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false); 3575a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_EDP0_IF_CTRL, RK3576_IF_PIN_POL_MASK, 3576a552a69cSDamon Ding RK3576_IF_PIN_POL_SHIFT, val, false); 3577a552a69cSDamon Ding } 3578a552a69cSDamon Ding 3579a552a69cSDamon Ding if (output_if & VOP_OUTPUT_IF_HDMI0) { 3580a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, RK3576_IF_DCLK_SEL_MASK, 3581a552a69cSDamon Ding RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false); 3582a552a69cSDamon Ding /* 0: div2, 1: div4 */ 3583a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, RK3576_IF_PIX_CLK_SEL_MASK, 3584a552a69cSDamon Ding RK3576_IF_PIX_CLK_SEL_SHIFT, interface_pix_clk_sel, false); 3585a552a69cSDamon Ding 3586a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, EN_MASK, 3587a552a69cSDamon Ding RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false); 3588a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, EN_MASK, 3589a552a69cSDamon Ding RK3576_IF_CLK_OUT_EN_SHIFT, 1, false); 3590a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, EN_MASK, 3591a552a69cSDamon Ding RK3576_IF_OUT_EN_SHIFT, 1, false); 3592a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, RK3576_IF_PORT_SEL_MASK, 3593a552a69cSDamon Ding RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false); 3594a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_HDMI0_IF_CTRL, RK3576_IF_PIN_POL_MASK, 3595a552a69cSDamon Ding RK3576_IF_PIN_POL_SHIFT, val, false); 3596a552a69cSDamon Ding } 3597a552a69cSDamon Ding 3598a552a69cSDamon Ding if (output_if & VOP_OUTPUT_IF_DP0) { 3599a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, RK3576_IF_DCLK_SEL_MASK, 3600a552a69cSDamon Ding RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false); 3601a552a69cSDamon Ding /* 0: no div, 1: div2 */ 3602a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, RK3576_IF_PIX_CLK_SEL_MASK, 3603a552a69cSDamon Ding RK3576_IF_PIX_CLK_SEL_SHIFT, interface_pix_clk_sel, false); 3604a552a69cSDamon Ding 3605a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, EN_MASK, 3606a552a69cSDamon Ding RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false); 3607a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, EN_MASK, 3608a552a69cSDamon Ding RK3576_IF_CLK_OUT_EN_SHIFT, 1, false); 3609a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, EN_MASK, 3610a552a69cSDamon Ding RK3576_IF_OUT_EN_SHIFT, 1, false); 3611a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, RK3576_IF_PORT_SEL_MASK, 3612a552a69cSDamon Ding RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false); 3613a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP0_IF_CTRL, RK3576_IF_PIN_POL_MASK, 3614a552a69cSDamon Ding RK3576_IF_PIN_POL_SHIFT, val, false); 3615a552a69cSDamon Ding } 3616a552a69cSDamon Ding 3617a552a69cSDamon Ding if (output_if & VOP_OUTPUT_IF_DP1) { 3618a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, RK3576_IF_DCLK_SEL_MASK, 3619a552a69cSDamon Ding RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false); 3620a552a69cSDamon Ding /* 0: no div, 1: div2 */ 3621a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, RK3576_IF_PIX_CLK_SEL_MASK, 3622a552a69cSDamon Ding RK3576_IF_PIX_CLK_SEL_SHIFT, interface_pix_clk_sel, false); 3623a552a69cSDamon Ding 3624a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, EN_MASK, 3625a552a69cSDamon Ding RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false); 3626a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, EN_MASK, 3627a552a69cSDamon Ding RK3576_IF_CLK_OUT_EN_SHIFT, 1, false); 3628a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, EN_MASK, 3629a552a69cSDamon Ding RK3576_IF_OUT_EN_SHIFT, 1, false); 3630a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, RK3576_IF_PORT_SEL_MASK, 3631a552a69cSDamon Ding RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false); 3632a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP1_IF_CTRL, RK3576_IF_PIN_POL_MASK, 3633a552a69cSDamon Ding RK3576_IF_PIN_POL_SHIFT, val, false); 3634a552a69cSDamon Ding } 3635a552a69cSDamon Ding 3636a552a69cSDamon Ding if (output_if & VOP_OUTPUT_IF_DP2) { 3637a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, RK3576_IF_DCLK_SEL_MASK, 3638a552a69cSDamon Ding RK3576_IF_DCLK_SEL_SHIFT, interface_dclk_sel, false); 3639a552a69cSDamon Ding /* 0: no div, 1: div2 */ 3640a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, RK3576_IF_PIX_CLK_SEL_MASK, 3641a552a69cSDamon Ding RK3576_IF_PIX_CLK_SEL_SHIFT, interface_pix_clk_sel, false); 3642a552a69cSDamon Ding 3643a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, EN_MASK, 3644a552a69cSDamon Ding RK3576_IF_REGDONE_IMD_EN_SHIFT, 1, false); 3645a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, EN_MASK, 3646a552a69cSDamon Ding RK3576_IF_CLK_OUT_EN_SHIFT, 1, false); 3647a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, EN_MASK, 3648a552a69cSDamon Ding RK3576_IF_OUT_EN_SHIFT, 1, false); 3649a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, RK3576_IF_PORT_SEL_MASK, 3650a552a69cSDamon Ding RK3576_IF_PORT_SEL_SHIFT, cstate->crtc_id, false); 3651a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_DP2_IF_CTRL, RK3576_IF_PIN_POL_MASK, 3652a552a69cSDamon Ding RK3576_IF_PIN_POL_SHIFT, val, false); 3653a552a69cSDamon Ding } 3654a552a69cSDamon Ding 3655a552a69cSDamon Ding return mode->crtc_clock; 3656a552a69cSDamon Ding } 3657a552a69cSDamon Ding 3658a2a16809SChaoyi Chen static void rk3568_vop2_setup_dual_channel_if(struct display_state *state) 3659a2a16809SChaoyi Chen { 3660a2a16809SChaoyi Chen struct crtc_state *cstate = &state->crtc_state; 3661a2a16809SChaoyi Chen struct connector_state *conn_state = &state->conn_state; 3662a2a16809SChaoyi Chen struct vop2 *vop2 = cstate->private; 3663a2a16809SChaoyi Chen u32 vp_offset = (cstate->crtc_id * 0x100); 3664a2a16809SChaoyi Chen 3665a2a16809SChaoyi Chen if (conn_state->output_flags & 3666a2a16809SChaoyi Chen ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE) { 3667a2a16809SChaoyi Chen vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 3668a2a16809SChaoyi Chen LVDS_DUAL_EN_SHIFT, 1, false); 3669a2a16809SChaoyi Chen vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 3670a2a16809SChaoyi Chen LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 0, false); 3671a2a16809SChaoyi Chen if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 3672a2a16809SChaoyi Chen vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 3673a2a16809SChaoyi Chen LVDS_DUAL_SWAP_EN_SHIFT, 1, false); 3674a2a16809SChaoyi Chen 3675a2a16809SChaoyi Chen return; 3676a2a16809SChaoyi Chen } 3677a2a16809SChaoyi Chen 3678a2a16809SChaoyi Chen vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 3679a2a16809SChaoyi Chen MIPI_DUAL_EN_SHIFT, 1, false); 3680a2a16809SChaoyi Chen if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) { 3681a2a16809SChaoyi Chen vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 3682a2a16809SChaoyi Chen MIPI_DUAL_SWAP_EN_SHIFT, 1, false); 3683a2a16809SChaoyi Chen } 3684a2a16809SChaoyi Chen 3685a2a16809SChaoyi Chen if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) { 3686a2a16809SChaoyi Chen vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 3687a2a16809SChaoyi Chen LVDS_DUAL_EN_SHIFT, 1, false); 3688a2a16809SChaoyi Chen vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 3689a2a16809SChaoyi Chen LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 1, false); 3690a2a16809SChaoyi Chen } 3691a2a16809SChaoyi Chen } 3692a2a16809SChaoyi Chen 3693ecc31b6eSAndy Yan static unsigned long rk3568_vop2_if_cfg(struct display_state *state) 3694ecc31b6eSAndy Yan { 3695ecc31b6eSAndy Yan struct crtc_state *cstate = &state->crtc_state; 3696ecc31b6eSAndy Yan struct connector_state *conn_state = &state->conn_state; 3697ecc31b6eSAndy Yan struct drm_display_mode *mode = &conn_state->mode; 3698ecc31b6eSAndy Yan struct vop2 *vop2 = cstate->private; 3699d0408543SAndy Yan bool dclk_inv; 3700ecc31b6eSAndy Yan u32 val; 37018895aec1SSandy Huang 370213f658dcSDamon Ding dclk_inv = (conn_state->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0; 370310ee9f5bSAlgea Cao val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 370410ee9f5bSAlgea Cao val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 3705d0408543SAndy Yan 3706d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_RGB) { 3707d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 3708d0408543SAndy Yan 1, false); 3709d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3710d0408543SAndy Yan RGB_MUX_SHIFT, cstate->crtc_id, false); 371115f69071SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_RGB_LVDS_PIN_POL_MASK, 371215f69071SDamon Ding IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false); 3713ecc31b6eSAndy Yan vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 3714c55d261eSSandy Huang GRF_RGB_DCLK_INV_SHIFT, dclk_inv); 3715d0408543SAndy Yan } 3716d0408543SAndy Yan 3717d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_BT1120) { 371852ee18acSSandy Huang vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 371952ee18acSSandy Huang 1, false); 3720d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, 3721d0408543SAndy Yan BT1120_EN_SHIFT, 1, false); 3722d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3723d0408543SAndy Yan RGB_MUX_SHIFT, cstate->crtc_id, false); 3724ecc31b6eSAndy Yan vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 372552ee18acSSandy Huang GRF_BT1120_CLK_INV_SHIFT, !dclk_inv); 3726d0408543SAndy Yan } 3727d0408543SAndy Yan 3728d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_BT656) { 3729d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT, 3730d0408543SAndy Yan 1, false); 3731d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3732d0408543SAndy Yan RGB_MUX_SHIFT, cstate->crtc_id, false); 3733ecc31b6eSAndy Yan vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 373452ee18acSSandy Huang GRF_BT656_CLK_INV_SHIFT, !dclk_inv); 3735d0408543SAndy Yan } 3736d0408543SAndy Yan 3737d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) { 3738d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT, 3739d0408543SAndy Yan 1, false); 3740d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3741d0408543SAndy Yan LVDS0_MUX_SHIFT, cstate->crtc_id, false); 374215f69071SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_RGB_LVDS_PIN_POL_MASK, 374315f69071SDamon Ding IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false); 374411f53190SSandy Huang vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 374515f69071SDamon Ding IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT, dclk_inv, false); 3746d0408543SAndy Yan } 3747d0408543SAndy Yan 3748d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) { 3749d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS1_EN_SHIFT, 3750d0408543SAndy Yan 1, false); 3751d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3752d0408543SAndy Yan LVDS1_MUX_SHIFT, cstate->crtc_id, false); 375315f69071SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_RGB_LVDS_PIN_POL_MASK, 375415f69071SDamon Ding IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false); 375511f53190SSandy Huang vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 375615f69071SDamon Ding IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT, dclk_inv, false); 3757d0408543SAndy Yan } 3758d0408543SAndy Yan 3759d0408543SAndy Yan 3760d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) { 3761d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT, 3762d0408543SAndy Yan 1, false); 3763d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3764d0408543SAndy Yan MIPI0_MUX_SHIFT, cstate->crtc_id, false); 3765d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3766c55d261eSSandy Huang IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false); 3767d0408543SAndy Yan } 3768d0408543SAndy Yan 3769d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_MIPI1) { 3770d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI1_EN_SHIFT, 3771d0408543SAndy Yan 1, false); 3772d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3773d0408543SAndy Yan MIPI1_MUX_SHIFT, cstate->crtc_id, false); 3774d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3775c55d261eSSandy Huang IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false); 3776d0408543SAndy Yan } 3777d0408543SAndy Yan 3778d0408543SAndy Yan if (conn_state->output_flags & 3779a2a16809SChaoyi Chen ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE || 3780a2a16809SChaoyi Chen conn_state->output_flags & 3781a2a16809SChaoyi Chen ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE) 3782a2a16809SChaoyi Chen rk3568_vop2_setup_dual_channel_if(state); 3783d0408543SAndy Yan 3784d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_eDP0) { 3785d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, EDP0_EN_SHIFT, 3786d0408543SAndy Yan 1, false); 3787d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3788d0408543SAndy Yan EDP0_MUX_SHIFT, cstate->crtc_id, false); 3789c55d261eSSandy Huang vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3790c55d261eSSandy Huang IF_CRTL_EDP_DCLK_POL_SHIT, dclk_inv, false); 37917bcdc6eeSDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_EDP_PIN_POL_MASK, 37927bcdc6eeSDamon Ding IF_CTRL_EDP_PIN_POL_SHIFT, val, false); 3793d0408543SAndy Yan } 3794d0408543SAndy Yan 3795d0408543SAndy Yan if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) { 3796d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT, 3797d0408543SAndy Yan 1, false); 3798d0408543SAndy Yan vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3799d0408543SAndy Yan HDMI0_MUX_SHIFT, cstate->crtc_id, false); 380010ee9f5bSAlgea Cao vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 380110ee9f5bSAlgea Cao IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false); 380210ee9f5bSAlgea Cao vop2_mask_write(vop2, RK3568_DSP_IF_POL, 380310ee9f5bSAlgea Cao IF_CRTL_HDMI_PIN_POL_MASK, 380410ee9f5bSAlgea Cao IF_CRTL_HDMI_PIN_POL_SHIT, val, false); 3805d0408543SAndy Yan } 380610ee9f5bSAlgea Cao 3807823146b6SDamon Ding return mode->crtc_clock; 3808ecc31b6eSAndy Yan } 3809ecc31b6eSAndy Yan 3810452afb13SDamon Ding static unsigned long rk3562_vop2_if_cfg(struct display_state *state) 3811452afb13SDamon Ding { 3812452afb13SDamon Ding struct crtc_state *cstate = &state->crtc_state; 3813452afb13SDamon Ding struct connector_state *conn_state = &state->conn_state; 3814452afb13SDamon Ding struct drm_display_mode *mode = &conn_state->mode; 3815452afb13SDamon Ding struct vop2 *vop2 = cstate->private; 3816452afb13SDamon Ding bool dclk_inv; 3817452afb13SDamon Ding u32 val; 3818452afb13SDamon Ding 381913f658dcSDamon Ding dclk_inv = (conn_state->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0; 3820452afb13SDamon Ding val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 3821452afb13SDamon Ding val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 3822452afb13SDamon Ding 3823452afb13SDamon Ding if (conn_state->output_if & VOP_OUTPUT_IF_RGB) { 3824452afb13SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 3825452afb13SDamon Ding 1, false); 3826452afb13SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3827452afb13SDamon Ding RGB_MUX_SHIFT, cstate->crtc_id, false); 3828452afb13SDamon Ding vop2_grf_writel(vop2, vop2->grf, RK3562_GRF_IOC_VO_IO_CON, EN_MASK, 3829452afb13SDamon Ding GRF_RGB_DCLK_INV_SHIFT, dclk_inv); 3830452afb13SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3562_IF_PIN_POL_MASK, 383115f69071SDamon Ding IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false); 3832452afb13SDamon Ding } 3833452afb13SDamon Ding 3834452afb13SDamon Ding if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) { 3835452afb13SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT, 3836452afb13SDamon Ding 1, false); 3837452afb13SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3838452afb13SDamon Ding LVDS0_MUX_SHIFT, cstate->crtc_id, false); 3839452afb13SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 384015f69071SDamon Ding IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT, dclk_inv, false); 3841452afb13SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3562_IF_PIN_POL_MASK, 384215f69071SDamon Ding IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false); 3843452afb13SDamon Ding } 3844452afb13SDamon Ding 3845452afb13SDamon Ding if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) { 3846452afb13SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT, 3847452afb13SDamon Ding 1, false); 3848452afb13SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3849452afb13SDamon Ding MIPI0_MUX_SHIFT, cstate->crtc_id, false); 3850452afb13SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3851452afb13SDamon Ding RK3562_MIPI_DCLK_POL_SHIFT, dclk_inv, false); 3852452afb13SDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3562_IF_PIN_POL_MASK, 3853452afb13SDamon Ding RK3562_MIPI_PIN_POL_SHIFT, val, false); 3854452afb13SDamon Ding } 3855452afb13SDamon Ding 3856452afb13SDamon Ding return mode->crtc_clock; 3857452afb13SDamon Ding } 3858452afb13SDamon Ding 3859a552a69cSDamon Ding static unsigned long rk3528_vop2_if_cfg(struct display_state *state) 3860a552a69cSDamon Ding { 3861a552a69cSDamon Ding struct crtc_state *cstate = &state->crtc_state; 3862a552a69cSDamon Ding struct connector_state *conn_state = &state->conn_state; 3863a552a69cSDamon Ding struct drm_display_mode *mode = &conn_state->mode; 3864a552a69cSDamon Ding struct vop2 *vop2 = cstate->private; 3865a552a69cSDamon Ding u32 val; 3866a552a69cSDamon Ding 3867a552a69cSDamon Ding val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 3868a552a69cSDamon Ding val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 3869a552a69cSDamon Ding 3870a552a69cSDamon Ding if (conn_state->output_if & VOP_OUTPUT_IF_BT656) { 3871a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT, 3872a552a69cSDamon Ding 1, false); 3873a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3874a552a69cSDamon Ding RGB_MUX_SHIFT, cstate->crtc_id, false); 3875a552a69cSDamon Ding } 3876a552a69cSDamon Ding 3877a552a69cSDamon Ding if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) { 3878a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT, 3879a552a69cSDamon Ding 1, false); 3880a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3881a552a69cSDamon Ding HDMI0_MUX_SHIFT, cstate->crtc_id, false); 3882a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3883a552a69cSDamon Ding IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false); 3884a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_DSP_IF_POL, 3885a552a69cSDamon Ding IF_CRTL_HDMI_PIN_POL_MASK, 3886a552a69cSDamon Ding IF_CRTL_HDMI_PIN_POL_SHIT, val, false); 3887a552a69cSDamon Ding } 3888a552a69cSDamon Ding 3889a552a69cSDamon Ding return mode->crtc_clock; 3890a552a69cSDamon Ding } 3891a552a69cSDamon Ding 389265747de7SDamon Ding static void vop2_post_color_swap(struct display_state *state) 389365747de7SDamon Ding { 389465747de7SDamon Ding struct crtc_state *cstate = &state->crtc_state; 389565747de7SDamon Ding struct connector_state *conn_state = &state->conn_state; 389665747de7SDamon Ding struct vop2 *vop2 = cstate->private; 389765747de7SDamon Ding u32 vp_offset = (cstate->crtc_id * 0x100); 389865747de7SDamon Ding u32 output_type = conn_state->type; 389965747de7SDamon Ding u32 data_swap = 0; 390065747de7SDamon Ding 39010675a2a4SDamon Ding if (is_uv_swap(conn_state->bus_format, conn_state->output_mode) || 39020675a2a4SDamon Ding is_rb_swap(conn_state->bus_format, conn_state->output_mode)) 390365747de7SDamon Ding data_swap = DSP_RB_SWAP; 390465747de7SDamon Ding 3905a552a69cSDamon Ding if ((vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3576)) { 3906a552a69cSDamon Ding if ((output_type == DRM_MODE_CONNECTOR_HDMIA || 390765747de7SDamon Ding output_type == DRM_MODE_CONNECTOR_eDP) && 390865747de7SDamon Ding (conn_state->bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 390965747de7SDamon Ding conn_state->bus_format == MEDIA_BUS_FMT_YUV10_1X30)) 391065747de7SDamon Ding data_swap |= DSP_RG_SWAP; 3911a552a69cSDamon Ding } 391265747de7SDamon Ding 391365747de7SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 391465747de7SDamon Ding DATA_SWAP_MASK, DATA_SWAP_SHIFT, data_swap, false); 391565747de7SDamon Ding } 391665747de7SDamon Ding 3917b890760eSAlgea Cao static void vop2_clk_set_parent(struct clk *clk, struct clk *parent) 3918b890760eSAlgea Cao { 3919b890760eSAlgea Cao int ret = 0; 3920b890760eSAlgea Cao 3921b890760eSAlgea Cao if (parent->dev) 3922b890760eSAlgea Cao ret = clk_set_parent(clk, parent); 3923b890760eSAlgea Cao if (ret < 0) 3924b890760eSAlgea Cao debug("failed to set %s as parent for %s\n", 3925b890760eSAlgea Cao parent->dev->name, clk->dev->name); 3926b890760eSAlgea Cao } 3927b890760eSAlgea Cao 3928b890760eSAlgea Cao static ulong vop2_clk_set_rate(struct clk *clk, ulong rate) 3929b890760eSAlgea Cao { 3930b890760eSAlgea Cao int ret = 0; 3931b890760eSAlgea Cao 3932b890760eSAlgea Cao if (clk->dev) 3933b890760eSAlgea Cao ret = clk_set_rate(clk, rate); 3934b890760eSAlgea Cao if (ret < 0) 3935b890760eSAlgea Cao debug("failed to set %s rate %lu \n", clk->dev->name, rate); 3936b890760eSAlgea Cao 3937b890760eSAlgea Cao return ret; 3938b890760eSAlgea Cao } 3939b890760eSAlgea Cao 394012ee5af0SDamon Ding static void vop2_calc_dsc_cru_cfg(struct display_state *state, 394112ee5af0SDamon Ding int *dsc_txp_clk_div, int *dsc_pxl_clk_div, 394212ee5af0SDamon Ding int *dsc_cds_clk_div, u64 dclk_rate) 394312ee5af0SDamon Ding { 394412ee5af0SDamon Ding struct crtc_state *cstate = &state->crtc_state; 394512ee5af0SDamon Ding 394612ee5af0SDamon Ding *dsc_txp_clk_div = dclk_rate / cstate->dsc_txp_clk_rate; 394712ee5af0SDamon Ding *dsc_pxl_clk_div = dclk_rate / cstate->dsc_pxl_clk_rate; 394812ee5af0SDamon Ding *dsc_cds_clk_div = dclk_rate / cstate->dsc_cds_clk_rate; 394912ee5af0SDamon Ding 395012ee5af0SDamon Ding *dsc_txp_clk_div = ilog2(*dsc_txp_clk_div); 395112ee5af0SDamon Ding *dsc_pxl_clk_div = ilog2(*dsc_pxl_clk_div); 395212ee5af0SDamon Ding *dsc_cds_clk_div = ilog2(*dsc_cds_clk_div); 395312ee5af0SDamon Ding } 395412ee5af0SDamon Ding 395512ee5af0SDamon Ding static void vop2_load_pps(struct display_state *state, struct vop2 *vop2, u8 dsc_id) 395612ee5af0SDamon Ding { 395712ee5af0SDamon Ding struct crtc_state *cstate = &state->crtc_state; 395812ee5af0SDamon Ding struct drm_dsc_picture_parameter_set *pps = &cstate->pps; 395912ee5af0SDamon Ding struct drm_dsc_picture_parameter_set config_pps; 396012ee5af0SDamon Ding const struct vop2_data *vop2_data = vop2->data; 396112ee5af0SDamon Ding const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id]; 396212ee5af0SDamon Ding u32 *pps_val = (u32 *)&config_pps; 396312ee5af0SDamon Ding u32 decoder_regs_offset = (dsc_id * 0x100); 396412ee5af0SDamon Ding int i = 0; 396512ee5af0SDamon Ding 396612ee5af0SDamon Ding memcpy(&config_pps, pps, sizeof(config_pps)); 396712ee5af0SDamon Ding 396812ee5af0SDamon Ding if ((config_pps.pps_3 & 0xf) > dsc_data->max_linebuf_depth) { 396912ee5af0SDamon Ding config_pps.pps_3 &= 0xf0; 397012ee5af0SDamon Ding config_pps.pps_3 |= dsc_data->max_linebuf_depth; 397112ee5af0SDamon Ding printf("DSC%d max_linebuf_depth is: %d, current set value is: %d\n", 397212ee5af0SDamon Ding dsc_id, dsc_data->max_linebuf_depth, config_pps.pps_3 & 0xf); 397312ee5af0SDamon Ding } 397412ee5af0SDamon Ding 397512ee5af0SDamon Ding for (i = 0; i < DSC_NUM_BUF_RANGES; i++) { 397612ee5af0SDamon Ding config_pps.rc_range_parameters[i] = 397712ee5af0SDamon Ding (pps->rc_range_parameters[i] >> 3 & 0x1f) | 397812ee5af0SDamon Ding ((pps->rc_range_parameters[i] >> 14 & 0x3) << 5) | 397912ee5af0SDamon Ding ((pps->rc_range_parameters[i] >> 0 & 0x7) << 7) | 398012ee5af0SDamon Ding ((pps->rc_range_parameters[i] >> 8 & 0x3f) << 10); 398112ee5af0SDamon Ding } 398212ee5af0SDamon Ding 398312ee5af0SDamon Ding for (i = 0; i < ROCKCHIP_DSC_PPS_SIZE_BYTE / 4; i++) 398412ee5af0SDamon Ding vop2_writel(vop2, RK3588_DSC_8K_PPS0_3 + decoder_regs_offset + i * 4, *pps_val++); 398512ee5af0SDamon Ding } 398612ee5af0SDamon Ding 398712ee5af0SDamon Ding static void vop2_dsc_enable(struct display_state *state, struct vop2 *vop2, u8 dsc_id, u64 dclk_rate) 398812ee5af0SDamon Ding { 398912ee5af0SDamon Ding struct connector_state *conn_state = &state->conn_state; 399012ee5af0SDamon Ding struct drm_display_mode *mode = &conn_state->mode; 399112ee5af0SDamon Ding struct crtc_state *cstate = &state->crtc_state; 399212ee5af0SDamon Ding struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap; 399312ee5af0SDamon Ding const struct vop2_data *vop2_data = vop2->data; 399412ee5af0SDamon Ding const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id]; 399512ee5af0SDamon Ding bool mipi_ds_mode = false; 399612ee5af0SDamon Ding u8 dsc_interface_mode = 0; 399712ee5af0SDamon Ding u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 399812ee5af0SDamon Ding u16 hdisplay = mode->crtc_hdisplay; 399912ee5af0SDamon Ding u16 htotal = mode->crtc_htotal; 400012ee5af0SDamon Ding u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 400112ee5af0SDamon Ding u16 vdisplay = mode->crtc_vdisplay; 400212ee5af0SDamon Ding u16 vtotal = mode->crtc_vtotal; 400312ee5af0SDamon Ding u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; 400412ee5af0SDamon Ding u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 400512ee5af0SDamon Ding u16 vact_end = vact_st + vdisplay; 400612ee5af0SDamon Ding u32 ctrl_regs_offset = (dsc_id * 0x30); 400712ee5af0SDamon Ding u32 decoder_regs_offset = (dsc_id * 0x100); 400812ee5af0SDamon Ding int dsc_txp_clk_div = 0; 400912ee5af0SDamon Ding int dsc_pxl_clk_div = 0; 401012ee5af0SDamon Ding int dsc_cds_clk_div = 0; 4011baf2c414SDamon Ding int val = 0; 401212ee5af0SDamon Ding 401312ee5af0SDamon Ding if (!vop2->data->nr_dscs) { 401412ee5af0SDamon Ding printf("Unsupported DSC\n"); 401512ee5af0SDamon Ding return; 401612ee5af0SDamon Ding } 401712ee5af0SDamon Ding 401812ee5af0SDamon Ding if (cstate->dsc_slice_num > dsc_data->max_slice_num) 401912ee5af0SDamon Ding printf("DSC%d supported max slice is: %d, current is: %d\n", 402012ee5af0SDamon Ding dsc_data->id, dsc_data->max_slice_num, cstate->dsc_slice_num); 402112ee5af0SDamon Ding 402212ee5af0SDamon Ding if (dsc_data->pd_id) { 402312ee5af0SDamon Ding if (vop2_power_domain_on(vop2, dsc_data->pd_id)) 402412ee5af0SDamon Ding printf("open dsc%d pd fail\n", dsc_id); 402512ee5af0SDamon Ding } 402612ee5af0SDamon Ding 402712ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, EN_MASK, 402812ee5af0SDamon Ding SCAN_TIMING_PARA_IMD_EN_SHIFT, 1, false); 402912ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PORT_SEL_MASK, 403012ee5af0SDamon Ding DSC_PORT_SEL_SHIFT, cstate->crtc_id, false); 403112ee5af0SDamon Ding if (conn_state->output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) { 403212ee5af0SDamon Ding dsc_interface_mode = VOP_DSC_IF_HDMI; 403312ee5af0SDamon Ding } else { 403412ee5af0SDamon Ding mipi_ds_mode = !!(conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE); 403512ee5af0SDamon Ding if (mipi_ds_mode) 403612ee5af0SDamon Ding dsc_interface_mode = VOP_DSC_IF_MIPI_DS_MODE; 403712ee5af0SDamon Ding else 403812ee5af0SDamon Ding dsc_interface_mode = VOP_DSC_IF_MIPI_VIDEO_MODE; 403912ee5af0SDamon Ding } 404012ee5af0SDamon Ding 404112ee5af0SDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 404212ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK, 404312ee5af0SDamon Ding DSC_MAN_MODE_SHIFT, 0, false); 404412ee5af0SDamon Ding else 404512ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK, 404612ee5af0SDamon Ding DSC_MAN_MODE_SHIFT, 1, false); 404712ee5af0SDamon Ding 404812ee5af0SDamon Ding vop2_calc_dsc_cru_cfg(state, &dsc_txp_clk_div, &dsc_pxl_clk_div, &dsc_cds_clk_div, dclk_rate); 404912ee5af0SDamon Ding 405012ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_INTERFACE_MODE_MASK, 405112ee5af0SDamon Ding DSC_INTERFACE_MODE_SHIFT, dsc_interface_mode, false); 405212ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PIXEL_NUM_MASK, 405312ee5af0SDamon Ding DSC_PIXEL_NUM_SHIFT, cstate->dsc_pixel_num >> 1, false); 405412ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_TXP_CLK_DIV_MASK, 405512ee5af0SDamon Ding DSC_TXP_CLK_DIV_SHIFT, dsc_txp_clk_div, false); 405612ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PXL_CLK_DIV_MASK, 405712ee5af0SDamon Ding DSC_PXL_CLK_DIV_SHIFT, dsc_pxl_clk_div, false); 405812ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK, 405912ee5af0SDamon Ding DSC_CDS_CLK_DIV_SHIFT, dsc_cds_clk_div, false); 406012ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, EN_MASK, 406112ee5af0SDamon Ding DSC_SCAN_EN_SHIFT, !mipi_ds_mode, false); 406212ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK, 406312ee5af0SDamon Ding DSC_HALT_EN_SHIFT, mipi_ds_mode, false); 406412ee5af0SDamon Ding 406512ee5af0SDamon Ding if (!mipi_ds_mode) { 406612ee5af0SDamon Ding u16 dsc_hsync, dsc_htotal, dsc_hact_st, dsc_hact_end; 406712ee5af0SDamon Ding u32 target_bpp = dsc_sink_cap->target_bits_per_pixel_x16; 406812ee5af0SDamon Ding u64 dsc_cds_rate = cstate->dsc_cds_clk_rate; 406912ee5af0SDamon Ding u32 v_pixclk_mhz = mode->crtc_clock / 1000; /* video timing pixclk */ 407012ee5af0SDamon Ding u32 dly_num, dsc_cds_rate_mhz, val = 0; 4071b61227a3SDamon Ding int k = 1; 4072b61227a3SDamon Ding 4073b61227a3SDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 4074b61227a3SDamon Ding k = 2; 407512ee5af0SDamon Ding 407612ee5af0SDamon Ding if (target_bpp >> 4 < dsc_data->min_bits_per_pixel) 407712ee5af0SDamon Ding printf("Unsupported bpp less than: %d\n", dsc_data->min_bits_per_pixel); 407812ee5af0SDamon Ding 407912ee5af0SDamon Ding /* 408012ee5af0SDamon Ding * dly_num = delay_line_num * T(one-line) / T (dsc_cds) 408112ee5af0SDamon Ding * T (one-line) = 1/v_pixclk_mhz * htotal = htotal/v_pixclk_mhz 408212ee5af0SDamon Ding * T (dsc_cds) = 1 / dsc_cds_rate_mhz 40831ace1b6dSDamon Ding * 40841ace1b6dSDamon Ding * HDMI: 408512ee5af0SDamon Ding * delay_line_num: according the pps initial_xmit_delay to adjust vop dsc delay 408612ee5af0SDamon Ding * delay_line_num = 4 - BPP / 8 408712ee5af0SDamon Ding * = (64 - target_bpp / 8) / 16 408812ee5af0SDamon Ding * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16; 40891ace1b6dSDamon Ding * 40901ace1b6dSDamon Ding * MIPI DSI[4320 and 9216 is buffer size for DSC]: 40911ace1b6dSDamon Ding * DSC0:delay_line_num = 4320 * 8 / slince_num / chunk_size; 40921ace1b6dSDamon Ding * delay_line_num = delay_line_num > 5 ? 5 : delay_line_num; 40931ace1b6dSDamon Ding * DSC1:delay_line_num = 9216 * 2 / slince_num / chunk_size; 40941ace1b6dSDamon Ding * delay_line_num = delay_line_num > 5 ? 5 : delay_line_num; 40951ace1b6dSDamon Ding * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num 409612ee5af0SDamon Ding */ 409712ee5af0SDamon Ding do_div(dsc_cds_rate, 1000000); /* hz to Mhz */ 409812ee5af0SDamon Ding dsc_cds_rate_mhz = dsc_cds_rate; 40991ace1b6dSDamon Ding dsc_hsync = hsync_len / 2; 41001ace1b6dSDamon Ding if (dsc_interface_mode == VOP_DSC_IF_HDMI) { 410112ee5af0SDamon Ding dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16; 41021ace1b6dSDamon Ding } else { 41031ace1b6dSDamon Ding int dsc_buf_size = dsc_id == 0 ? 4320 * 8 : 9216 * 2; 41041ace1b6dSDamon Ding int delay_line_num = dsc_buf_size / cstate->dsc_slice_num / 41051ace1b6dSDamon Ding be16_to_cpu(cstate->pps.chunk_size); 41061ace1b6dSDamon Ding 41071ace1b6dSDamon Ding delay_line_num = delay_line_num > 5 ? 5 : delay_line_num; 41081ace1b6dSDamon Ding dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num; 41091ace1b6dSDamon Ding 41101ace1b6dSDamon Ding /* The dsc mipi video mode dsc_hsync minimum size is 8 pixels */ 41111ace1b6dSDamon Ding if (dsc_hsync < 8) 41121ace1b6dSDamon Ding dsc_hsync = 8; 41131ace1b6dSDamon Ding } 411412ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_MODE_MASK, 411512ee5af0SDamon Ding DSC_INIT_DLY_MODE_SHIFT, 0, false); 411612ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_NUM_MASK, 411712ee5af0SDamon Ding DSC_INIT_DLY_NUM_SHIFT, dly_num, false); 411812ee5af0SDamon Ding 4119b61227a3SDamon Ding /* 4120b61227a3SDamon Ding * htotal / dclk_core = dsc_htotal /cds_clk 4121b61227a3SDamon Ding * 4122b61227a3SDamon Ding * dclk_core = DCLK / (1 << dclk_core->div_val) 4123b61227a3SDamon Ding * cds_clk = txp_clk / (1 << dsc_cds_clk->div_val) 4124b61227a3SDamon Ding * txp_clk = DCLK / (1 << dsc_txp_clk->div_val) 4125b61227a3SDamon Ding * 4126b61227a3SDamon Ding * dsc_htotal = htotal * (1 << dclk_core->div_val) / 4127b61227a3SDamon Ding * ((1 << dsc_txp_clk->div_val) * (1 << dsc_cds_clk->div_val)) 4128b61227a3SDamon Ding */ 4129b61227a3SDamon Ding dsc_htotal = htotal * (1 << cstate->dclk_core_div) / 4130b61227a3SDamon Ding ((1 << dsc_txp_clk_div) * (1 << dsc_cds_clk_div)); 413112ee5af0SDamon Ding val = dsc_htotal << 16 | dsc_hsync; 413212ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_HTOTAL_HS_END + ctrl_regs_offset, DSC_HTOTAL_PW_MASK, 413312ee5af0SDamon Ding DSC_HTOTAL_PW_SHIFT, val, false); 413412ee5af0SDamon Ding 413512ee5af0SDamon Ding dsc_hact_st = hact_st / 2; 4136b61227a3SDamon Ding dsc_hact_end = (hdisplay / k * target_bpp >> 4) / 24 + dsc_hact_st; 413712ee5af0SDamon Ding val = dsc_hact_end << 16 | dsc_hact_st; 413812ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_HACT_ST_END + ctrl_regs_offset, DSC_HACT_ST_END_MASK, 413912ee5af0SDamon Ding DSC_HACT_ST_END_SHIFT, val, false); 414012ee5af0SDamon Ding 414112ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_VTOTAL_VS_END + ctrl_regs_offset, DSC_VTOTAL_PW_MASK, 414212ee5af0SDamon Ding DSC_VTOTAL_PW_SHIFT, vtotal << 16 | vsync_len, false); 414312ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_VACT_ST_END + ctrl_regs_offset, DSC_VACT_ST_END_MASK, 414412ee5af0SDamon Ding DSC_VACT_ST_END_SHIFT, vact_end << 16 | vact_st, false); 414512ee5af0SDamon Ding } 414612ee5af0SDamon Ding 414712ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_RST + ctrl_regs_offset, RST_DEASSERT_MASK, 414812ee5af0SDamon Ding RST_DEASSERT_SHIFT, 1, false); 414912ee5af0SDamon Ding udelay(10); 415012ee5af0SDamon Ding 4151baf2c414SDamon Ding val |= DSC_CTRL0_DEF_CON | (ilog2(cstate->dsc_slice_num) << DSC_NSLC_SHIFT) | 4152baf2c414SDamon Ding ((dsc_sink_cap->version_minor == 2 ? 1 : 0) << DSC_IFEP_SHIFT); 4153baf2c414SDamon Ding vop2_writel(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, val); 4154baf2c414SDamon Ding 415512ee5af0SDamon Ding vop2_load_pps(state, vop2, dsc_id); 415612ee5af0SDamon Ding 4157baf2c414SDamon Ding val |= (1 << DSC_PPS_UPD_SHIFT); 4158baf2c414SDamon Ding vop2_writel(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, val); 415912ee5af0SDamon Ding 416012ee5af0SDamon Ding printf("DSC%d: txp:%lld div:%d, pxl:%lld div:%d, dsc:%lld div:%d\n", 416112ee5af0SDamon Ding dsc_id, 416212ee5af0SDamon Ding cstate->dsc_txp_clk_rate, dsc_txp_clk_div, 416312ee5af0SDamon Ding cstate->dsc_pxl_clk_rate, dsc_pxl_clk_div, 416412ee5af0SDamon Ding cstate->dsc_cds_clk_rate, dsc_cds_clk_div); 416512ee5af0SDamon Ding } 416612ee5af0SDamon Ding 41675f1357a2SZhang Yubing static bool is_extend_pll(struct display_state *state, struct udevice **clk_dev) 41685f1357a2SZhang Yubing { 41695f1357a2SZhang Yubing struct crtc_state *cstate = &state->crtc_state; 41705f1357a2SZhang Yubing struct vop2 *vop2 = cstate->private; 41715f1357a2SZhang Yubing struct udevice *vp_dev, *dev; 41725f1357a2SZhang Yubing struct ofnode_phandle_args args; 41735f1357a2SZhang Yubing char vp_name[10]; 41745f1357a2SZhang Yubing int ret; 41755f1357a2SZhang Yubing 4176a552a69cSDamon Ding if (vop2->version != VOP_VERSION_RK3588 && vop2->version != VOP_VERSION_RK3576) 41775f1357a2SZhang Yubing return false; 41785f1357a2SZhang Yubing 41795f1357a2SZhang Yubing sprintf(vp_name, "port@%d", cstate->crtc_id); 41805f1357a2SZhang Yubing if (uclass_find_device_by_name(UCLASS_VIDEO_CRTC, vp_name, &vp_dev)) { 41815e85f4a7SZhang Yubing debug("warn: can't get vp device\n"); 41825f1357a2SZhang Yubing return false; 41835f1357a2SZhang Yubing } 41845f1357a2SZhang Yubing 41855f1357a2SZhang Yubing ret = dev_read_phandle_with_args(vp_dev, "assigned-clock-parents", "#clock-cells", 0, 41865f1357a2SZhang Yubing 0, &args); 41875f1357a2SZhang Yubing if (ret) { 41885e85f4a7SZhang Yubing debug("assigned-clock-parents's node not define\n"); 41895f1357a2SZhang Yubing return false; 41905f1357a2SZhang Yubing } 41915f1357a2SZhang Yubing 41925f1357a2SZhang Yubing if (uclass_find_device_by_ofnode(UCLASS_CLK, args.node, &dev)) { 41935e85f4a7SZhang Yubing debug("warn: can't get clk device\n"); 41945f1357a2SZhang Yubing return false; 41955f1357a2SZhang Yubing } 41965f1357a2SZhang Yubing 41975f1357a2SZhang Yubing if (!strcmp(dev->name, "hdmiphypll_clk0") || !strcmp(dev->name, "hdmiphypll_clk1")) { 41985f1357a2SZhang Yubing printf("%s: clk dev :%s: vp port:%s\n", __func__, dev->name, vp_dev->name); 41995f1357a2SZhang Yubing if (clk_dev) 42005f1357a2SZhang Yubing *clk_dev = dev; 42015f1357a2SZhang Yubing return true; 42025f1357a2SZhang Yubing } 42035f1357a2SZhang Yubing 42045f1357a2SZhang Yubing return false; 42055f1357a2SZhang Yubing } 42065f1357a2SZhang Yubing 42070675a2a4SDamon Ding static void vop3_mcu_mode_setup(struct display_state *state) 42080675a2a4SDamon Ding { 42090675a2a4SDamon Ding struct crtc_state *cstate = &state->crtc_state; 42100675a2a4SDamon Ding struct vop2 *vop2 = cstate->private; 42110675a2a4SDamon Ding u32 vp_offset = (cstate->crtc_id * 0x100); 42120675a2a4SDamon Ding 42130675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 42140675a2a4SDamon Ding MCU_TYPE_SHIFT, 1, false); 42150675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 42160675a2a4SDamon Ding MCU_HOLD_MODE_SHIFT, 1, false); 42170675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_PIX_TOTAL_MASK, 42180675a2a4SDamon Ding MCU_PIX_TOTAL_SHIFT, cstate->mcu_timing.mcu_pix_total, false); 42190675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PST_MASK, 42200675a2a4SDamon Ding MCU_CS_PST_SHIFT, cstate->mcu_timing.mcu_cs_pst, false); 42210675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PEND_MASK, 42220675a2a4SDamon Ding MCU_CS_PEND_SHIFT, cstate->mcu_timing.mcu_cs_pend, false); 42230675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PST_MASK, 42240675a2a4SDamon Ding MCU_RW_PST_SHIFT, cstate->mcu_timing.mcu_rw_pst, false); 42250675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PEND_MASK, 42260675a2a4SDamon Ding MCU_RW_PEND_SHIFT, cstate->mcu_timing.mcu_rw_pend, false); 42270675a2a4SDamon Ding } 42280675a2a4SDamon Ding 42290675a2a4SDamon Ding static void vop3_mcu_bypass_mode_setup(struct display_state *state) 42300675a2a4SDamon Ding { 42310675a2a4SDamon Ding struct crtc_state *cstate = &state->crtc_state; 42320675a2a4SDamon Ding struct vop2 *vop2 = cstate->private; 42330675a2a4SDamon Ding u32 vp_offset = (cstate->crtc_id * 0x100); 42340675a2a4SDamon Ding 42350675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 42360675a2a4SDamon Ding MCU_TYPE_SHIFT, 1, false); 42370675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 42380675a2a4SDamon Ding MCU_HOLD_MODE_SHIFT, 1, false); 42390675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_PIX_TOTAL_MASK, 42400675a2a4SDamon Ding MCU_PIX_TOTAL_SHIFT, 53, false); 42410675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PST_MASK, 42420675a2a4SDamon Ding MCU_CS_PST_SHIFT, 6, false); 42430675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PEND_MASK, 42440675a2a4SDamon Ding MCU_CS_PEND_SHIFT, 48, false); 42450675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PST_MASK, 42460675a2a4SDamon Ding MCU_RW_PST_SHIFT, 12, false); 42470675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PEND_MASK, 42480675a2a4SDamon Ding MCU_RW_PEND_SHIFT, 30, false); 42490675a2a4SDamon Ding } 42500675a2a4SDamon Ding 42510675a2a4SDamon Ding static int rockchip_vop2_send_mcu_cmd(struct display_state *state, u32 type, u32 value) 42520675a2a4SDamon Ding { 42530675a2a4SDamon Ding struct crtc_state *cstate = &state->crtc_state; 42540675a2a4SDamon Ding struct connector_state *conn_state = &state->conn_state; 42550675a2a4SDamon Ding struct drm_display_mode *mode = &conn_state->mode; 42560675a2a4SDamon Ding struct vop2 *vop2 = cstate->private; 42570675a2a4SDamon Ding u32 vp_offset = (cstate->crtc_id * 0x100); 42580675a2a4SDamon Ding 42590675a2a4SDamon Ding /* 426058cf1fa3SDamon Ding * 1.set mcu bypass mode timing. 426158cf1fa3SDamon Ding * 2.set dclk rate to 150M. 42620675a2a4SDamon Ding */ 42630675a2a4SDamon Ding if (type == MCU_SETBYPASS && value) { 42640675a2a4SDamon Ding vop3_mcu_bypass_mode_setup(state); 42650675a2a4SDamon Ding vop2_clk_set_rate(&cstate->dclk, 150000000); 42660675a2a4SDamon Ding } 42670675a2a4SDamon Ding 42680675a2a4SDamon Ding switch (type) { 42690675a2a4SDamon Ding case MCU_WRCMD: 42700675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 42710675a2a4SDamon Ding MCU_RS_SHIFT, 0, false); 42720675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_RW_BYPASS_PORT + vp_offset, 42730675a2a4SDamon Ding MCU_WRITE_DATA_BYPASS_MASK, MCU_WRITE_DATA_BYPASS_SHIFT, 42740675a2a4SDamon Ding value, false); 42750675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 42760675a2a4SDamon Ding MCU_RS_SHIFT, 1, false); 42770675a2a4SDamon Ding break; 42780675a2a4SDamon Ding case MCU_WRDATA: 42790675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 42800675a2a4SDamon Ding MCU_RS_SHIFT, 1, false); 42810675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_RW_BYPASS_PORT + vp_offset, 42820675a2a4SDamon Ding MCU_WRITE_DATA_BYPASS_MASK, MCU_WRITE_DATA_BYPASS_SHIFT, 42830675a2a4SDamon Ding value, false); 42840675a2a4SDamon Ding break; 42850675a2a4SDamon Ding case MCU_SETBYPASS: 42860675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 42870675a2a4SDamon Ding MCU_BYPASS_SHIFT, value ? 1 : 0, false); 42880675a2a4SDamon Ding break; 42890675a2a4SDamon Ding default: 42900675a2a4SDamon Ding break; 42910675a2a4SDamon Ding } 42920675a2a4SDamon Ding 42930675a2a4SDamon Ding /* 429458cf1fa3SDamon Ding * 1.restore mcu data mode timing. 429558cf1fa3SDamon Ding * 2.restore dclk rate to crtc_clock. 42960675a2a4SDamon Ding */ 42970675a2a4SDamon Ding if (type == MCU_SETBYPASS && !value) { 42980675a2a4SDamon Ding vop3_mcu_mode_setup(state); 42990675a2a4SDamon Ding vop2_clk_set_rate(&cstate->dclk, mode->crtc_clock * 1000); 43000675a2a4SDamon Ding } 43010675a2a4SDamon Ding 43020675a2a4SDamon Ding return 0; 43030675a2a4SDamon Ding } 43040675a2a4SDamon Ding 430534d37ef0SDamon Ding static void vop2_dither_setup(struct vop2 *vop2, int bus_format, int crtc_id) 430634d37ef0SDamon Ding { 4307a552a69cSDamon Ding const struct vop2_data *vop2_data = vop2->data; 4308a552a69cSDamon Ding const struct vop2_vp_data *vp_data = &vop2_data->vp_data[crtc_id]; 430934d37ef0SDamon Ding u32 vp_offset = crtc_id * 0x100; 431034d37ef0SDamon Ding bool pre_dither_down_en = false; 431134d37ef0SDamon Ding 431234d37ef0SDamon Ding switch (bus_format) { 431334d37ef0SDamon Ding case MEDIA_BUS_FMT_RGB565_1X16: 431440608a7cSDamon Ding case MEDIA_BUS_FMT_RGB565_2X8_LE: 4315*e2bdb3b3SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4316*e2bdb3b3SDamon Ding PRE_DITHER_DOWN_EN_SHIFT, true, false); 4317*e2bdb3b3SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4318*e2bdb3b3SDamon Ding DITHER_DOWN_MODE_SHIFT, RGB888_TO_RGB565, false); 431934d37ef0SDamon Ding pre_dither_down_en = true; 432034d37ef0SDamon Ding break; 432134d37ef0SDamon Ding case MEDIA_BUS_FMT_RGB666_1X18: 432234d37ef0SDamon Ding case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: 432334d37ef0SDamon Ding case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 432440608a7cSDamon Ding case MEDIA_BUS_FMT_RGB666_3X6: 4325*e2bdb3b3SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4326*e2bdb3b3SDamon Ding PRE_DITHER_DOWN_EN_SHIFT, true, false); 4327*e2bdb3b3SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4328*e2bdb3b3SDamon Ding DITHER_DOWN_MODE_SHIFT, RGB888_TO_RGB666, false); 432934d37ef0SDamon Ding pre_dither_down_en = true; 433034d37ef0SDamon Ding break; 433134d37ef0SDamon Ding case MEDIA_BUS_FMT_YUYV8_1X16: 433234d37ef0SDamon Ding case MEDIA_BUS_FMT_YUV8_1X24: 433334d37ef0SDamon Ding case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 4334*e2bdb3b3SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4335*e2bdb3b3SDamon Ding PRE_DITHER_DOWN_EN_SHIFT, false, false); 433634d37ef0SDamon Ding pre_dither_down_en = true; 433734d37ef0SDamon Ding break; 433834d37ef0SDamon Ding case MEDIA_BUS_FMT_YUYV10_1X20: 433934d37ef0SDamon Ding case MEDIA_BUS_FMT_YUV10_1X30: 434034d37ef0SDamon Ding case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 434134d37ef0SDamon Ding case MEDIA_BUS_FMT_RGB101010_1X30: 4342*e2bdb3b3SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4343*e2bdb3b3SDamon Ding PRE_DITHER_DOWN_EN_SHIFT, false, false); 434434d37ef0SDamon Ding pre_dither_down_en = false; 434534d37ef0SDamon Ding break; 434634d37ef0SDamon Ding case MEDIA_BUS_FMT_RGB888_3X8: 434734d37ef0SDamon Ding case MEDIA_BUS_FMT_RGB888_DUMMY_4X8: 434834d37ef0SDamon Ding case MEDIA_BUS_FMT_RGB888_1X24: 434934d37ef0SDamon Ding case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 435034d37ef0SDamon Ding case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 435134d37ef0SDamon Ding default: 4352*e2bdb3b3SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4353*e2bdb3b3SDamon Ding PRE_DITHER_DOWN_EN_SHIFT, false, false); 435434d37ef0SDamon Ding pre_dither_down_en = true; 435534d37ef0SDamon Ding break; 435634d37ef0SDamon Ding } 435734d37ef0SDamon Ding 4358*e2bdb3b3SDamon Ding if (is_yuv_output(bus_format) && (vp_data->feature & VOP_FEATURE_POST_FRC_V2) == 0) 435934d37ef0SDamon Ding pre_dither_down_en = false; 436034d37ef0SDamon Ding 4361a552a69cSDamon Ding if ((vp_data->feature & VOP_FEATURE_POST_FRC_V2) && pre_dither_down_en) { 4362481ef52dSDamon Ding if (vop2->version == VOP_VERSION_RK3576) { 4363481ef52dSDamon Ding vop2_writel(vop2, RK3576_VP0_POST_DITHER_FRC_0 + vp_offset, 0x00000000); 4364481ef52dSDamon Ding vop2_writel(vop2, RK3576_VP0_POST_DITHER_FRC_1 + vp_offset, 0x01000100); 4365481ef52dSDamon Ding vop2_writel(vop2, RK3576_VP0_POST_DITHER_FRC_2 + vp_offset, 0x04030100); 4366481ef52dSDamon Ding } 4367481ef52dSDamon Ding 4368a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4369a552a69cSDamon Ding PRE_DITHER_DOWN_EN_SHIFT, 0, false); 4370*e2bdb3b3SDamon Ding /* enable frc2.0 do 10->8 */ 4371a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4372a552a69cSDamon Ding DITHER_DOWN_EN_SHIFT, 1, false); 4373*e2bdb3b3SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, DITHER_DOWN_SEL_MASK, 4374*e2bdb3b3SDamon Ding DITHER_DOWN_SEL_SHIFT, DITHER_DOWN_FRC, false); 4375a552a69cSDamon Ding } else { 437634d37ef0SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 437734d37ef0SDamon Ding PRE_DITHER_DOWN_EN_SHIFT, pre_dither_down_en, false); 4378*e2bdb3b3SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, DITHER_DOWN_SEL_MASK, 4379*e2bdb3b3SDamon Ding DITHER_DOWN_SEL_SHIFT, DITHER_DOWN_ALLEGRO, false); 438034d37ef0SDamon Ding } 4381a552a69cSDamon Ding } 438234d37ef0SDamon Ding 4383ecc31b6eSAndy Yan static int rockchip_vop2_init(struct display_state *state) 4384ecc31b6eSAndy Yan { 4385ecc31b6eSAndy Yan struct crtc_state *cstate = &state->crtc_state; 4386c2b1fe35SDamon Ding struct rockchip_vp *vp = &cstate->crtc->vps[cstate->crtc_id]; 4387ecc31b6eSAndy Yan struct connector_state *conn_state = &state->conn_state; 4388ecc31b6eSAndy Yan struct drm_display_mode *mode = &conn_state->mode; 4389ecc31b6eSAndy Yan struct vop2 *vop2 = cstate->private; 4390ecc31b6eSAndy Yan u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 4391ecc31b6eSAndy Yan u16 hdisplay = mode->crtc_hdisplay; 4392ecc31b6eSAndy Yan u16 htotal = mode->crtc_htotal; 4393ecc31b6eSAndy Yan u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 4394ecc31b6eSAndy Yan u16 hact_end = hact_st + hdisplay; 4395ecc31b6eSAndy Yan u16 vdisplay = mode->crtc_vdisplay; 4396ecc31b6eSAndy Yan u16 vtotal = mode->crtc_vtotal; 4397ecc31b6eSAndy Yan u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; 4398ecc31b6eSAndy Yan u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 4399ecc31b6eSAndy Yan u16 vact_end = vact_st + vdisplay; 4400ecc31b6eSAndy Yan bool yuv_overlay = false; 4401ecc31b6eSAndy Yan u32 vp_offset = (cstate->crtc_id * 0x100); 440266724b9cSDamon Ding u32 line_flag_offset = (cstate->crtc_id * 4); 440366724b9cSDamon Ding u32 val, act_end; 440458cf1fa3SDamon Ding u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 4405edfef528SDamon Ding u8 dclk_div_factor = 0; 4406a552a69cSDamon Ding u8 vp_dclk_div = 1; 4407ecc31b6eSAndy Yan char output_type_name[30] = {0}; 4408d8e7f4a5SSandy Huang #ifndef CONFIG_SPL_BUILD 4409ecc31b6eSAndy Yan char dclk_name[9]; 4410d8e7f4a5SSandy Huang #endif 4411b890760eSAlgea Cao struct clk hdmi0_phy_pll; 4412b890760eSAlgea Cao struct clk hdmi1_phy_pll; 44135f1357a2SZhang Yubing struct clk hdmi_phy_pll; 44143e05a7b8SZhang Yubing struct udevice *disp_dev; 44155fa6e665SDamon Ding unsigned long dclk_rate = 0; 4416ecc31b6eSAndy Yan int ret; 4417ecc31b6eSAndy Yan 4418ecc31b6eSAndy Yan printf("VOP update mode to: %dx%d%s%d, type:%s for VP%d\n", 441971ac76f7SDamon Ding mode->crtc_hdisplay, mode->vdisplay, 4420ecc31b6eSAndy Yan mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p", 44214d64cedbSDamon Ding mode->vrefresh, 44222264c88bSDamon Ding rockchip_get_output_if_name(conn_state->output_if, output_type_name), 4423ecc31b6eSAndy Yan cstate->crtc_id); 4424ecc31b6eSAndy Yan 4425ee01dbb2SDamon Ding if (mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) { 4426ee01dbb2SDamon Ding cstate->splice_mode = true; 4427ee01dbb2SDamon Ding cstate->splice_crtc_id = vop2->data->vp_data[cstate->crtc_id].splice_vp_id; 4428ee01dbb2SDamon Ding if (!cstate->splice_crtc_id) { 4429ee01dbb2SDamon Ding printf("%s: Splice mode is unsupported by vp%d\n", 4430ee01dbb2SDamon Ding __func__, cstate->crtc_id); 4431ee01dbb2SDamon Ding return -EINVAL; 4432ee01dbb2SDamon Ding } 4433b70b2d79SDamon Ding 4434b70b2d79SDamon Ding vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, EN_MASK, 4435b70b2d79SDamon Ding PORT_MERGE_EN_SHIFT, 1, false); 4436ee01dbb2SDamon Ding } 4437ee01dbb2SDamon Ding 4438cd6c85a9SDamon Ding vop2_mask_write(vop2, RK3588_SYS_VAR_FREQ_CTRL, EN_MASK, 4439cd6c85a9SDamon Ding RK3588_VP0_LINE_FLAG_OR_EN_SHIFT + cstate->crtc_id, 1, false); 4440cd6c85a9SDamon Ding vop2_mask_write(vop2, RK3588_SYS_VAR_FREQ_CTRL, EN_MASK, 4441cd6c85a9SDamon Ding RK3588_VP0_ALMOST_FULL_OR_EN_SHIFT + cstate->crtc_id, 1, false); 4442cd6c85a9SDamon Ding 4443ecc31b6eSAndy Yan vop2_initial(vop2, state); 4444ecc31b6eSAndy Yan if (vop2->version == VOP_VERSION_RK3588) 4445ecc31b6eSAndy Yan dclk_rate = rk3588_vop2_if_cfg(state); 4446a552a69cSDamon Ding else if (vop2->version == VOP_VERSION_RK3576) 4447a552a69cSDamon Ding dclk_rate = rk3576_vop2_if_cfg(state); 44485fa6e665SDamon Ding else if (vop2->version == VOP_VERSION_RK3568) 4449ecc31b6eSAndy Yan dclk_rate = rk3568_vop2_if_cfg(state); 4450452afb13SDamon Ding else if (vop2->version == VOP_VERSION_RK3562) 4451452afb13SDamon Ding dclk_rate = rk3562_vop2_if_cfg(state); 4452a552a69cSDamon Ding else if (vop2->version == VOP_VERSION_RK3528) 4453a552a69cSDamon Ding dclk_rate = rk3528_vop2_if_cfg(state); 4454ecc31b6eSAndy Yan 44555d2768f7SDamon Ding if ((conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA && 44565d2768f7SDamon Ding !(cstate->feature & VOP_FEATURE_OUTPUT_10BIT)) || 44575d2768f7SDamon Ding conn_state->output_if & VOP_OUTPUT_IF_BT656) 44587bdd0eb6SSandy Huang conn_state->output_mode = ROCKCHIP_OUT_MODE_P888; 44597bdd0eb6SSandy Huang 446065747de7SDamon Ding vop2_post_color_swap(state); 446110ee9f5bSAlgea Cao 4462d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, OUT_MODE_MASK, 4463d0408543SAndy Yan OUT_MODE_SHIFT, conn_state->output_mode, false); 4464d0408543SAndy Yan 446534d37ef0SDamon Ding vop2_dither_setup(vop2, conn_state->bus_format, cstate->crtc_id); 446634d37ef0SDamon Ding if (cstate->splice_mode) 446734d37ef0SDamon Ding vop2_dither_setup(vop2, conn_state->bus_format, cstate->splice_crtc_id); 4468d0408543SAndy Yan 4469d0408543SAndy Yan yuv_overlay = is_yuv_output(conn_state->bus_format) ? 1 : 0; 4470d0408543SAndy Yan vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, cstate->crtc_id, 4471d0408543SAndy Yan yuv_overlay, false); 4472d0408543SAndy Yan 4473d0408543SAndy Yan cstate->yuv_overlay = yuv_overlay; 4474d0408543SAndy Yan 4475d0408543SAndy Yan vop2_writel(vop2, RK3568_VP0_DSP_HTOTAL_HS_END + vp_offset, 4476d0408543SAndy Yan (htotal << 16) | hsync_len); 4477d0408543SAndy Yan val = hact_st << 16; 4478d0408543SAndy Yan val |= hact_end; 4479d0408543SAndy Yan vop2_writel(vop2, RK3568_VP0_DSP_HACT_ST_END + vp_offset, val); 4480d0408543SAndy Yan val = vact_st << 16; 4481d0408543SAndy Yan val |= vact_end; 4482d0408543SAndy Yan vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END + vp_offset, val); 4483d0408543SAndy Yan if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 4484d0408543SAndy Yan u16 vact_st_f1 = vtotal + vact_st + 1; 4485d0408543SAndy Yan u16 vact_end_f1 = vact_st_f1 + vdisplay; 4486d0408543SAndy Yan 4487d0408543SAndy Yan val = vact_st_f1 << 16 | vact_end_f1; 4488d0408543SAndy Yan vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END_F1 + vp_offset, 4489d0408543SAndy Yan val); 4490d0408543SAndy Yan 4491d0408543SAndy Yan val = vtotal << 16 | (vtotal + vsync_len); 4492d0408543SAndy Yan vop2_writel(vop2, RK3568_VP0_DSP_VS_ST_END_F1 + vp_offset, val); 4493d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4494d0408543SAndy Yan INTERLACE_EN_SHIFT, 1, false); 4495d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 44967a20be36SSandy Huang DSP_FILED_POL, 1, false); 44977a20be36SSandy Huang vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4498d0408543SAndy Yan P2I_EN_SHIFT, 1, false); 4499d0408543SAndy Yan vtotal += vtotal + 1; 450066724b9cSDamon Ding act_end = vact_end_f1; 4501d0408543SAndy Yan } else { 4502d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4503d0408543SAndy Yan INTERLACE_EN_SHIFT, 0, false); 4504d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4505d0408543SAndy Yan P2I_EN_SHIFT, 0, false); 450666724b9cSDamon Ding act_end = vact_end; 4507d0408543SAndy Yan } 4508d0408543SAndy Yan vop2_writel(vop2, RK3568_VP0_DSP_VTOTAL_VS_END + vp_offset, 4509d0408543SAndy Yan (vtotal << 16) | vsync_len); 451067be2ffcSDamon Ding 4511a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3528 || 4512a552a69cSDamon Ding vop2->version == VOP_VERSION_RK3562 || 4513a552a69cSDamon Ding vop2->version == VOP_VERSION_RK3568) { 451467be2ffcSDamon Ding if (mode->flags & DRM_MODE_FLAG_DBLCLK || 451567be2ffcSDamon Ding conn_state->output_if & VOP_OUTPUT_IF_BT656) 4516d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 451767be2ffcSDamon Ding CORE_DCLK_DIV_EN_SHIFT, 1, false); 451867be2ffcSDamon Ding else 451967be2ffcSDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 452067be2ffcSDamon Ding CORE_DCLK_DIV_EN_SHIFT, 0, false); 452110ee9f5bSAlgea Cao 452210ee9f5bSAlgea Cao if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420) 452363cb669fSSandy Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 452463cb669fSSandy Huang DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0x3, false); 452510ee9f5bSAlgea Cao else 452663cb669fSSandy Huang vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 452763cb669fSSandy Huang DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0, false); 4528a552a69cSDamon Ding } 452910ee9f5bSAlgea Cao 4530ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK, 4531ee01dbb2SDamon Ding OVL_MODE_SEL_SHIFT + cstate->crtc_id, yuv_overlay, false); 4532ee01dbb2SDamon Ding 453310ee9f5bSAlgea Cao if (yuv_overlay) 453410ee9f5bSAlgea Cao val = 0x20010200; 453510ee9f5bSAlgea Cao else 453610ee9f5bSAlgea Cao val = 0; 453710ee9f5bSAlgea Cao vop2_writel(vop2, RK3568_VP0_DSP_BG + vp_offset, val); 4538b70b2d79SDamon Ding if (cstate->splice_mode) { 4539ee01dbb2SDamon Ding vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK, 4540ee01dbb2SDamon Ding OVL_MODE_SEL_SHIFT + cstate->splice_crtc_id, 4541ee01dbb2SDamon Ding yuv_overlay, false); 4542ee01dbb2SDamon Ding vop2_writel(vop2, RK3568_VP0_DSP_BG + (cstate->splice_crtc_id * 0x100), val); 4543ee01dbb2SDamon Ding } 454410ee9f5bSAlgea Cao 454510ee9f5bSAlgea Cao vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 454610ee9f5bSAlgea Cao POST_DSP_OUT_R2Y_SHIFT, yuv_overlay, false); 4547d0408543SAndy Yan 4548c2b1fe35SDamon Ding if (vp->xmirror_en) 4549c2b1fe35SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4550c2b1fe35SDamon Ding DSP_X_MIR_EN_SHIFT, 1, false); 4551c2b1fe35SDamon Ding 4552ac500a1fSSandy Huang vop2_tv_config_update(state, vop2); 4553d0408543SAndy Yan vop2_post_config(state, vop2); 45546027c871SZhang Yubing if (cstate->feature & (VOP_FEATURE_POST_ACM | VOP_FEATURE_POST_CSC)) 45556027c871SZhang Yubing vop3_post_config(state, vop2); 4556d0408543SAndy Yan 455712ee5af0SDamon Ding if (cstate->dsc_enable) { 455812ee5af0SDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 45591ace1b6dSDamon Ding vop2_dsc_enable(state, vop2, 0, dclk_rate * 1000LL); 45601ace1b6dSDamon Ding vop2_dsc_enable(state, vop2, 1, dclk_rate * 1000LL); 456112ee5af0SDamon Ding } else { 45621ace1b6dSDamon Ding vop2_dsc_enable(state, vop2, cstate->dsc_id, dclk_rate * 1000LL); 456312ee5af0SDamon Ding } 456412ee5af0SDamon Ding } 456512ee5af0SDamon Ding 4566d8e7f4a5SSandy Huang #ifndef CONFIG_SPL_BUILD 4567ecc31b6eSAndy Yan snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id); 45680675a2a4SDamon Ding ret = clk_get_by_name(cstate->dev, dclk_name, &cstate->dclk); 4569b890760eSAlgea Cao if (ret) { 4570b890760eSAlgea Cao printf("%s: Failed to get dclk ret=%d\n", __func__, ret); 4571b890760eSAlgea Cao return ret; 4572b890760eSAlgea Cao } 4573d8e7f4a5SSandy Huang #endif 4574b890760eSAlgea Cao 45753e05a7b8SZhang Yubing ret = uclass_get_device_by_name(UCLASS_VIDEO, "display-subsystem", &disp_dev); 45763e05a7b8SZhang Yubing if (!ret) { 45773e05a7b8SZhang Yubing ret = clk_get_by_name(disp_dev, "hdmi0_phy_pll", &hdmi0_phy_pll); 45783e05a7b8SZhang Yubing if (ret) 45795e85f4a7SZhang Yubing debug("%s: hdmi0_phy_pll may not define\n", __func__); 45803e05a7b8SZhang Yubing ret = clk_get_by_name(disp_dev, "hdmi1_phy_pll", &hdmi1_phy_pll); 45813e05a7b8SZhang Yubing if (ret) 45825e85f4a7SZhang Yubing debug("%s: hdmi1_phy_pll may not define\n", __func__); 45833e05a7b8SZhang Yubing } else { 4584b890760eSAlgea Cao hdmi0_phy_pll.dev = NULL; 4585545a0218SAlgea Cao hdmi1_phy_pll.dev = NULL; 45865e85f4a7SZhang Yubing debug("%s: Faile to find display-subsystem node\n", __func__); 4587b890760eSAlgea Cao } 4588b890760eSAlgea Cao 4589ebbd144cSAlgea Cao if (vop2->version == VOP_VERSION_RK3528) { 4590ebbd144cSAlgea Cao struct ofnode_phandle_args args; 4591ebbd144cSAlgea Cao 4592ebbd144cSAlgea Cao ret = dev_read_phandle_with_args(cstate->dev, "assigned-clock-parents", 4593ebbd144cSAlgea Cao "#clock-cells", 0, 0, &args); 4594ebbd144cSAlgea Cao if (!ret) { 4595ebbd144cSAlgea Cao ret = uclass_find_device_by_ofnode(UCLASS_CLK, args.node, &hdmi0_phy_pll.dev); 4596ebbd144cSAlgea Cao if (ret) { 4597ebbd144cSAlgea Cao debug("warn: can't get clk device\n"); 4598ebbd144cSAlgea Cao return ret; 4599ebbd144cSAlgea Cao } 4600ebbd144cSAlgea Cao } else { 4601ebbd144cSAlgea Cao debug("assigned-clock-parents's node not define\n"); 4602ebbd144cSAlgea Cao } 4603ebbd144cSAlgea Cao } 4604ebbd144cSAlgea Cao 46050a1fb152SZhang Yubing if (mode->crtc_clock < VOP2_MAX_DCLK_RATE) { 4606b890760eSAlgea Cao if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) 46070675a2a4SDamon Ding vop2_clk_set_parent(&cstate->dclk, &hdmi0_phy_pll); 4608b890760eSAlgea Cao else if (conn_state->output_if & VOP_OUTPUT_IF_HDMI1) 46090675a2a4SDamon Ding vop2_clk_set_parent(&cstate->dclk, &hdmi1_phy_pll); 4610b890760eSAlgea Cao 4611b890760eSAlgea Cao /* 4612b890760eSAlgea Cao * uboot clk driver won't set dclk parent's rate when use 4613b890760eSAlgea Cao * hdmi phypll as dclk source. 4614b890760eSAlgea Cao * So set dclk rate is meaningless. Set hdmi phypll rate 4615b890760eSAlgea Cao * directly. 4616b890760eSAlgea Cao */ 46175f1357a2SZhang Yubing if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI0) && hdmi0_phy_pll.dev) { 4618b890760eSAlgea Cao ret = vop2_clk_set_rate(&hdmi0_phy_pll, dclk_rate * 1000); 46195f1357a2SZhang Yubing } else if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI1) && hdmi1_phy_pll.dev) { 4620b890760eSAlgea Cao ret = vop2_clk_set_rate(&hdmi1_phy_pll, dclk_rate * 1000); 46215f1357a2SZhang Yubing } else { 4622a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3576) 4623a552a69cSDamon Ding vp_dclk_div = cstate->crtc->vps[cstate->crtc_id].dclk_div; 46247efea85dSDamon Ding if (is_extend_pll(state, &hdmi_phy_pll.dev)) { 46255f1357a2SZhang Yubing ret = vop2_clk_set_rate(&hdmi_phy_pll, dclk_rate * 1000); 46267efea85dSDamon Ding } else { 4627d8e7f4a5SSandy Huang #ifndef CONFIG_SPL_BUILD 4628a552a69cSDamon Ding ret = vop2_clk_set_rate(&cstate->dclk, 4629a552a69cSDamon Ding dclk_rate / vp_dclk_div * 1000); 4630d8e7f4a5SSandy Huang #else 4631d8e7f4a5SSandy Huang if (vop2->version == VOP_VERSION_RK3528) { 4632d8e7f4a5SSandy Huang void *cru_base = (void *)RK3528_CRU_BASE; 4633d8e7f4a5SSandy Huang 4634d8e7f4a5SSandy Huang /* dclk src switch to hdmiphy pll */ 4635d8e7f4a5SSandy Huang writel((BIT(0) << 16) | BIT(0), cru_base + 0x450); 4636d8e7f4a5SSandy Huang rockchip_phy_set_pll(conn_state->connector->phy, dclk_rate * 1000); 4637d8e7f4a5SSandy Huang ret = dclk_rate * 1000; 4638d8e7f4a5SSandy Huang } 4639d8e7f4a5SSandy Huang #endif 46405f1357a2SZhang Yubing } 46417efea85dSDamon Ding } 4642631ee99aSZhang Yubing } else { 46435f1357a2SZhang Yubing if (is_extend_pll(state, &hdmi_phy_pll.dev)) 46445f1357a2SZhang Yubing ret = vop2_clk_set_rate(&hdmi_phy_pll, dclk_rate * 1000); 46455f1357a2SZhang Yubing else 46460675a2a4SDamon Ding ret = vop2_clk_set_rate(&cstate->dclk, dclk_rate * 1000); 4647edfef528SDamon Ding } 464863638f32SDamon Ding 464963638f32SDamon Ding if (IS_ERR_VALUE(ret)) { 465063638f32SDamon Ding printf("%s: Failed to set vp%d dclk[%ld KHZ] ret=%d\n", 465163638f32SDamon Ding __func__, cstate->crtc_id, dclk_rate, ret); 465263638f32SDamon Ding return ret; 465363638f32SDamon Ding } else { 46544d64cedbSDamon Ding if (cstate->mcu_timing.mcu_pix_total) { 46554d64cedbSDamon Ding mode->crtc_clock = roundup(ret, 1000) / 1000; 46564d64cedbSDamon Ding } else { 46579655ad2fSDamon Ding dclk_div_factor = mode->crtc_clock / dclk_rate; 46584d64cedbSDamon Ding mode->crtc_clock = roundup(ret, 1000) * dclk_div_factor / 1000; 46594d64cedbSDamon Ding } 4660edfef528SDamon Ding printf("VP%d set crtc_clock to %dKHz\n", cstate->crtc_id, mode->crtc_clock); 4661631ee99aSZhang Yubing } 4662ecc31b6eSAndy Yan 466366724b9cSDamon Ding vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK, 4664e24e9033SSandy Huang RK3568_DSP_LINE_FLAG_NUM0_SHIFT, act_end, false); 466566724b9cSDamon Ding vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK, 4666e24e9033SSandy Huang RK3568_DSP_LINE_FLAG_NUM1_SHIFT, act_end, false); 466766724b9cSDamon Ding 466858cf1fa3SDamon Ding if (cstate->mcu_timing.mcu_pix_total) { 466958cf1fa3SDamon Ding vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 467058cf1fa3SDamon Ding vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 467158cf1fa3SDamon Ding STANDBY_EN_SHIFT, 0, false); 46720675a2a4SDamon Ding vop3_mcu_mode_setup(state); 467358cf1fa3SDamon Ding } 46740675a2a4SDamon Ding 4675d0408543SAndy Yan return 0; 4676d0408543SAndy Yan } 4677d0408543SAndy Yan 4678ecc31b6eSAndy Yan static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win_data *win, 46793e39a5a1SSandy Huang uint32_t src_w, uint32_t src_h, uint32_t dst_w, 46803e39a5a1SSandy Huang uint32_t dst_h) 46813e39a5a1SSandy Huang { 46823e39a5a1SSandy Huang uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode; 46833e39a5a1SSandy Huang uint16_t hscl_filter_mode, vscl_filter_mode; 46845fa6e665SDamon Ding uint8_t xgt2 = 0, xgt4 = 0; 46855fa6e665SDamon Ding uint8_t ygt2 = 0, ygt4 = 0; 46863e39a5a1SSandy Huang uint32_t xfac = 0, yfac = 0; 4687ecc31b6eSAndy Yan u32 win_offset = win->reg_offset; 46885fa6e665SDamon Ding bool xgt_en = false; 46895fa6e665SDamon Ding bool xavg_en = false; 46903e39a5a1SSandy Huang 46915fa6e665SDamon Ding if (is_vop3(vop2)) { 4692a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3576 && win->type == CLUSTER_LAYER) { 4693a552a69cSDamon Ding if (src_w >= (8 * dst_w)) { 4694a552a69cSDamon Ding xgt4 = 1; 4695a552a69cSDamon Ding src_w >>= 2; 4696a552a69cSDamon Ding } else if (src_w >= (4 * dst_w)) { 4697a552a69cSDamon Ding xgt2 = 1; 4698a552a69cSDamon Ding src_w >>= 1; 4699a552a69cSDamon Ding } 4700a552a69cSDamon Ding } else { 47015fa6e665SDamon Ding if (src_w >= (4 * dst_w)) { 47025fa6e665SDamon Ding xgt4 = 1; 47035fa6e665SDamon Ding src_w >>= 2; 47045fa6e665SDamon Ding } else if (src_w >= (2 * dst_w)) { 47055fa6e665SDamon Ding xgt2 = 1; 47065fa6e665SDamon Ding src_w >>= 1; 47075fa6e665SDamon Ding } 47085fa6e665SDamon Ding } 4709a552a69cSDamon Ding } 47103e39a5a1SSandy Huang 4711183eb252SDamon Ding /** 4712183eb252SDamon Ding * The rk3528 is processed as 2 pixel/cycle, 4713183eb252SDamon Ding * so ygt2/ygt4 needs to be triggered in advance to improve performance 4714183eb252SDamon Ding * when src_w is bigger than 1920. 4715183eb252SDamon Ding * dst_h / src_h is at [1, 0.65) ygt2=0; ygt4=0; 4716183eb252SDamon Ding * dst_h / src_h is at [0.65, 0.35) ygt2=1; ygt4=0; 4717183eb252SDamon Ding * dst_h / src_h is at [0.35, 0) ygt2=0; ygt4=1; 4718183eb252SDamon Ding */ 4719183eb252SDamon Ding if (vop2->version == VOP_VERSION_RK3528 && src_w > 1920) { 4720183eb252SDamon Ding if (src_h >= (100 * dst_h / 35)) { 4721183eb252SDamon Ding ygt4 = 1; 4722183eb252SDamon Ding src_h >>= 2; 4723183eb252SDamon Ding } else if ((src_h >= 100 * dst_h / 65) && (src_h < 100 * dst_h / 35)) { 4724183eb252SDamon Ding ygt2 = 1; 4725183eb252SDamon Ding src_h >>= 1; 4726183eb252SDamon Ding } 4727183eb252SDamon Ding } else { 4728a552a69cSDamon Ding if (win->vsd_filter_mode == VOP2_SCALE_DOWN_ZME) { 4729a552a69cSDamon Ding if (src_h >= (8 * dst_h)) { 4730a552a69cSDamon Ding ygt4 = 1; 4731a552a69cSDamon Ding src_h >>= 2; 4732a552a69cSDamon Ding } else if (src_h >= (4 * dst_h)) { 4733a552a69cSDamon Ding ygt2 = 1; 4734a552a69cSDamon Ding src_h >>= 1; 4735a552a69cSDamon Ding } 4736a552a69cSDamon Ding } else { 47375fa6e665SDamon Ding if (src_h >= (4 * dst_h)) { 47385fa6e665SDamon Ding ygt4 = 1; 47393e39a5a1SSandy Huang src_h >>= 2; 47405fa6e665SDamon Ding } else if (src_h >= (2 * dst_h)) { 47415fa6e665SDamon Ding ygt2 = 1; 47423e39a5a1SSandy Huang src_h >>= 1; 47435fa6e665SDamon Ding } 4744183eb252SDamon Ding } 4745a552a69cSDamon Ding } 47463e39a5a1SSandy Huang 47473e39a5a1SSandy Huang yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w); 47483e39a5a1SSandy Huang yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h); 47493e39a5a1SSandy Huang 47503e39a5a1SSandy Huang if (yrgb_hor_scl_mode == SCALE_UP) 47515fa6e665SDamon Ding hscl_filter_mode = win->hsu_filter_mode; 47523e39a5a1SSandy Huang else 47535fa6e665SDamon Ding hscl_filter_mode = win->hsd_filter_mode; 47543e39a5a1SSandy Huang 47553e39a5a1SSandy Huang if (yrgb_ver_scl_mode == SCALE_UP) 47565fa6e665SDamon Ding vscl_filter_mode = win->vsu_filter_mode; 47573e39a5a1SSandy Huang else 47585fa6e665SDamon Ding vscl_filter_mode = win->vsd_filter_mode; 47593e39a5a1SSandy Huang 47603e39a5a1SSandy Huang /* 47613e39a5a1SSandy Huang * RK3568 VOP Esmart/Smart dsp_w should be even pixel 47623e39a5a1SSandy Huang * at scale down mode 47633e39a5a1SSandy Huang */ 47645fa6e665SDamon Ding if ((yrgb_hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1) && !is_vop3(vop2)) { 47653e39a5a1SSandy Huang printf("win dst_w[%d] should align as 2 pixel\n", dst_w); 47663e39a5a1SSandy Huang dst_w += 1; 47673e39a5a1SSandy Huang } 47683e39a5a1SSandy Huang 47695fa6e665SDamon Ding if (is_vop3(vop2)) { 47705fa6e665SDamon Ding xfac = vop3_scale_factor(yrgb_hor_scl_mode, src_w, dst_w, true); 47715fa6e665SDamon Ding yfac = vop3_scale_factor(yrgb_ver_scl_mode, src_h, dst_h, false); 47725fa6e665SDamon Ding 47735fa6e665SDamon Ding if (win->hsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_AVG) 47745fa6e665SDamon Ding xavg_en = xgt2 || xgt4; 47755fa6e665SDamon Ding else 47765fa6e665SDamon Ding xgt_en = xgt2 || xgt4; 4777a552a69cSDamon Ding 4778a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3576) { 4779a552a69cSDamon Ding bool zme_dering_en = false; 4780a552a69cSDamon Ding 4781a552a69cSDamon Ding if ((yrgb_hor_scl_mode == SCALE_UP && 4782a552a69cSDamon Ding hscl_filter_mode == VOP2_SCALE_UP_ZME) || 4783a552a69cSDamon Ding (yrgb_ver_scl_mode == SCALE_UP && 4784a552a69cSDamon Ding vscl_filter_mode == VOP2_SCALE_UP_ZME)) 4785a552a69cSDamon Ding zme_dering_en = true; 4786a552a69cSDamon Ding 4787a552a69cSDamon Ding /* Recommended configuration from the algorithm */ 4788a552a69cSDamon Ding vop2_writel(vop2, RK3576_CLUSTER0_WIN0_ZME_DERING_PARA + win_offset, 4789a552a69cSDamon Ding 0x04100d10); 4790a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_CLUSTER0_WIN0_ZME_CTRL + win_offset, 4791a552a69cSDamon Ding EN_MASK, WIN0_ZME_DERING_EN_SHIFT, zme_dering_en, false); 4792a552a69cSDamon Ding } 47935fa6e665SDamon Ding } else { 47943e39a5a1SSandy Huang xfac = vop2_scale_factor(yrgb_hor_scl_mode, hscl_filter_mode, src_w, dst_w); 47953e39a5a1SSandy Huang yfac = vop2_scale_factor(yrgb_ver_scl_mode, vscl_filter_mode, src_h, dst_h); 47965fa6e665SDamon Ding } 4797ecc31b6eSAndy Yan 4798ecc31b6eSAndy Yan if (win->type == CLUSTER_LAYER) { 4799ecc31b6eSAndy Yan vop2_writel(vop2, RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB + win_offset, 4800ecc31b6eSAndy Yan yfac << 16 | xfac); 4801ecc31b6eSAndy Yan 48025fa6e665SDamon Ding if (is_vop3(vop2)) { 4803ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48045fa6e665SDamon Ding EN_MASK, CLUSTER_XGT_EN_SHIFT, xgt_en, false); 4805ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48065fa6e665SDamon Ding EN_MASK, CLUSTER_XAVG_EN_SHIFT, xavg_en, false); 48075fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48085fa6e665SDamon Ding XGT_MODE_MASK, CLUSTER_XGT_MODE_SHIFT, xgt2 ? 0 : 1, false); 4809ecc31b6eSAndy Yan 4810ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48115fa6e665SDamon Ding YRGB_XSCL_MODE_MASK, RK3528_CLUSTER_YRGB_XSCL_MODE_SHIFT, 48125fa6e665SDamon Ding yrgb_hor_scl_mode, false); 4813ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48145fa6e665SDamon Ding YRGB_YSCL_MODE_MASK, RK3528_CLUSTER_YRGB_YSCL_MODE_SHIFT, 48155fa6e665SDamon Ding yrgb_ver_scl_mode, false); 48165fa6e665SDamon Ding } else { 48175fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48185fa6e665SDamon Ding YRGB_XSCL_MODE_MASK, RK3568_CLUSTER_YRGB_XSCL_MODE_SHIFT, 48195fa6e665SDamon Ding yrgb_hor_scl_mode, false); 48205fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48215fa6e665SDamon Ding YRGB_YSCL_MODE_MASK, RK3568_CLUSTER_YRGB_YSCL_MODE_SHIFT, 48225fa6e665SDamon Ding yrgb_ver_scl_mode, false); 48235fa6e665SDamon Ding } 4824ecc31b6eSAndy Yan 48255fa6e665SDamon Ding if (!is_vop3(vop2) || win->vsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_GT) { 48265fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48275fa6e665SDamon Ding YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, ygt2, false); 48285fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48295fa6e665SDamon Ding YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, ygt4, false); 48305fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48315fa6e665SDamon Ding AVG2_MASK, CLUSTER_AVG2_SHIFT, 0, false); 48325fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48335fa6e665SDamon Ding AVG4_MASK, CLUSTER_AVG4_SHIFT, 0, false); 48345fa6e665SDamon Ding } else { 48355fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48365fa6e665SDamon Ding YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, 0, false); 48375fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48385fa6e665SDamon Ding YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, 0, false); 48395fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48405fa6e665SDamon Ding AVG2_MASK, CLUSTER_AVG2_SHIFT, ygt2, false); 48415fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 48425fa6e665SDamon Ding AVG4_MASK, CLUSTER_AVG4_SHIFT, ygt4, false); 48435fa6e665SDamon Ding } 4844ecc31b6eSAndy Yan } else { 48453e39a5a1SSandy Huang vop2_writel(vop2, RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB + win_offset, 48463e39a5a1SSandy Huang yfac << 16 | xfac); 48473e39a5a1SSandy Huang 48485fa6e665SDamon Ding if (is_vop3(vop2)) { 484934a72bf2SDing Ling Song vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 48505fa6e665SDamon Ding EN_MASK, ESMART_XGT_EN_SHIFT, xgt_en, false); 485134a72bf2SDing Ling Song vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 48525fa6e665SDamon Ding EN_MASK, ESMART_XAVG_EN_SHIFT, xavg_en, false); 48535fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 48545fa6e665SDamon Ding XGT_MODE_MASK, ESMART_XGT_MODE_SHIFT, xgt2 ? 0 : 1, false); 48555fa6e665SDamon Ding } 48565fa6e665SDamon Ding 48575fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 48585fa6e665SDamon Ding YRGB_GT2_MASK, YRGB_GT2_SHIFT, ygt2, false); 48595fa6e665SDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 48605fa6e665SDamon Ding YRGB_GT4_MASK, YRGB_GT4_SHIFT, ygt4, false); 48613e39a5a1SSandy Huang 48623e39a5a1SSandy Huang vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 48633e39a5a1SSandy Huang YRGB_XSCL_MODE_MASK, YRGB_XSCL_MODE_SHIFT, yrgb_hor_scl_mode, false); 48643e39a5a1SSandy Huang vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 48653e39a5a1SSandy Huang YRGB_YSCL_MODE_MASK, YRGB_YSCL_MODE_SHIFT, yrgb_ver_scl_mode, false); 48663e39a5a1SSandy Huang 48673e39a5a1SSandy Huang vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 48683e39a5a1SSandy Huang YRGB_XSCL_FILTER_MODE_MASK, YRGB_XSCL_FILTER_MODE_SHIFT, 48693e39a5a1SSandy Huang hscl_filter_mode, false); 48703e39a5a1SSandy Huang vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 48713e39a5a1SSandy Huang YRGB_YSCL_FILTER_MODE_MASK, YRGB_YSCL_FILTER_MODE_SHIFT, 48723e39a5a1SSandy Huang vscl_filter_mode, false); 48733e39a5a1SSandy Huang } 4874ecc31b6eSAndy Yan } 48753e39a5a1SSandy Huang 4876a33b790fSDamon Ding static void vop2_axi_config(struct vop2 *vop2, struct vop2_win_data *win) 4877a33b790fSDamon Ding { 4878a33b790fSDamon Ding u32 win_offset = win->reg_offset; 4879a33b790fSDamon Ding 4880a33b790fSDamon Ding if (win->type == CLUSTER_LAYER) { 4881a33b790fSDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, CLUSTER_AXI_ID_MASK, 4882a33b790fSDamon Ding CLUSTER_AXI_ID_SHIFT, win->axi_id, false); 4883a33b790fSDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_YRGB_ID_MASK, 4884a33b790fSDamon Ding CLUSTER_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false); 4885a33b790fSDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_UV_ID_MASK, 4886a33b790fSDamon Ding CLUSTER_AXI_UV_ID_SHIFT, win->axi_uv_id, false); 4887a33b790fSDamon Ding } else { 4888a33b790fSDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_AXI_CTRL + win_offset, ESMART_AXI_ID_MASK, 4889a33b790fSDamon Ding ESMART_AXI_ID_SHIFT, win->axi_id, false); 4890a33b790fSDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_YRGB_ID_MASK, 4891a33b790fSDamon Ding ESMART_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false); 4892a33b790fSDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_UV_ID_MASK, 4893a33b790fSDamon Ding ESMART_AXI_UV_ID_SHIFT, win->axi_uv_id, false); 4894a33b790fSDamon Ding } 4895a33b790fSDamon Ding } 4896a33b790fSDamon Ding 4897840bf541SDamon Ding static bool vop2_win_dither_up(uint32_t format) 4898840bf541SDamon Ding { 4899840bf541SDamon Ding switch (format) { 4900840bf541SDamon Ding case ROCKCHIP_FMT_RGB565: 4901840bf541SDamon Ding return true; 4902840bf541SDamon Ding default: 4903840bf541SDamon Ding return false; 4904840bf541SDamon Ding } 4905840bf541SDamon Ding } 4906840bf541SDamon Ding 49071c9572c7SDamon Ding static bool vop2_is_mirror_win(struct vop2_win_data *win) 49081c9572c7SDamon Ding { 49091c9572c7SDamon Ding return soc_is_rk3566() && (win->feature & WIN_FEATURE_MIRROR); 49101c9572c7SDamon Ding } 49111c9572c7SDamon Ding 49121c9572c7SDamon Ding static int vop2_set_cluster_win(struct display_state *state, struct vop2_win_data *win) 4913d0408543SAndy Yan { 4914d0408543SAndy Yan struct crtc_state *cstate = &state->crtc_state; 4915d0408543SAndy Yan struct connector_state *conn_state = &state->conn_state; 4916d0408543SAndy Yan struct drm_display_mode *mode = &conn_state->mode; 4917d0408543SAndy Yan struct vop2 *vop2 = cstate->private; 4918ee01dbb2SDamon Ding int src_w = cstate->src_rect.w; 4919ee01dbb2SDamon Ding int src_h = cstate->src_rect.h; 4920ee01dbb2SDamon Ding int crtc_x = cstate->crtc_rect.x; 4921ee01dbb2SDamon Ding int crtc_y = cstate->crtc_rect.y; 4922ee01dbb2SDamon Ding int crtc_w = cstate->crtc_rect.w; 4923ee01dbb2SDamon Ding int crtc_h = cstate->crtc_rect.h; 4924d0408543SAndy Yan int xvir = cstate->xvir; 4925d0408543SAndy Yan int y_mirror = 0; 492610ee9f5bSAlgea Cao int csc_mode; 4927ecc31b6eSAndy Yan u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty; 4928ee01dbb2SDamon Ding /* offset of the right window in splice mode */ 4929ee01dbb2SDamon Ding u32 splice_pixel_offset = 0; 4930ee01dbb2SDamon Ding u32 splice_yrgb_offset = 0; 4931ecc31b6eSAndy Yan u32 win_offset = win->reg_offset; 4932ecc31b6eSAndy Yan u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 4933840bf541SDamon Ding bool dither_up; 4934d0408543SAndy Yan 4935ee01dbb2SDamon Ding if (win->splice_mode_right) { 4936ee01dbb2SDamon Ding src_w = cstate->right_src_rect.w; 4937ee01dbb2SDamon Ding src_h = cstate->right_src_rect.h; 4938ee01dbb2SDamon Ding crtc_x = cstate->right_crtc_rect.x; 4939ee01dbb2SDamon Ding crtc_y = cstate->right_crtc_rect.y; 4940ee01dbb2SDamon Ding crtc_w = cstate->right_crtc_rect.w; 4941ee01dbb2SDamon Ding crtc_h = cstate->right_crtc_rect.h; 4942ee01dbb2SDamon Ding splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x; 4943ee01dbb2SDamon Ding splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3); 4944ee01dbb2SDamon Ding cfg_done = CFG_DONE_EN | BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 4945ee01dbb2SDamon Ding } 4946ee01dbb2SDamon Ding 4947ecc31b6eSAndy Yan act_info = (src_h - 1) << 16; 4948ecc31b6eSAndy Yan act_info |= (src_w - 1) & 0xffff; 4949ecc31b6eSAndy Yan 4950ecc31b6eSAndy Yan dsp_info = (crtc_h - 1) << 16; 4951ecc31b6eSAndy Yan dsp_info |= (crtc_w - 1) & 0xffff; 4952ecc31b6eSAndy Yan 4953ecc31b6eSAndy Yan dsp_stx = crtc_x; 4954ecc31b6eSAndy Yan dsp_sty = crtc_y; 4955ecc31b6eSAndy Yan dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); 4956ecc31b6eSAndy Yan 4957ecc31b6eSAndy Yan if (mode->flags & DRM_MODE_FLAG_YMIRROR) 4958ecc31b6eSAndy Yan y_mirror = 1; 4959ecc31b6eSAndy Yan else 4960ecc31b6eSAndy Yan y_mirror = 0; 4961ecc31b6eSAndy Yan 4962ecc31b6eSAndy Yan vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h); 4963ecc31b6eSAndy Yan 4964a552a69cSDamon Ding if (vop2->version != VOP_VERSION_RK3568) 4965a33b790fSDamon Ding vop2_axi_config(vop2, win); 4966a33b790fSDamon Ding 4967ecc31b6eSAndy Yan if (y_mirror) 4968ecc31b6eSAndy Yan printf("WARN: y mirror is unsupported by cluster window\n"); 4969ecc31b6eSAndy Yan 4970a552a69cSDamon Ding if (is_vop3(vop2)) 4971a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_CLUSTER0_PORT_SEL + win_offset, 4972a552a69cSDamon Ding CLUSTER_PORT_SEL_SHIFT, CLUSTER_PORT_SEL_SHIFT, 4973a552a69cSDamon Ding cstate->crtc_id, false); 4974a552a69cSDamon Ding 4975a59754e1SDamon Ding /* rk3588 should set half_blocK_en to 1 in line and tile mode */ 4976a59754e1SDamon Ding if (vop2->version == VOP_VERSION_RK3588) 4977a59754e1SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_AFBCD_CTRL + win_offset, 4978a59754e1SDamon Ding EN_MASK, CLUSTER_AFBCD_HALF_BLOCK_SHIFT, 1, false); 4979a59754e1SDamon Ding 4980ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, 4981ecc31b6eSAndy Yan WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format, 4982ecc31b6eSAndy Yan false); 4983ecc31b6eSAndy Yan vop2_writel(vop2, RK3568_CLUSTER0_WIN0_VIR + win_offset, xvir); 4984ee01dbb2SDamon Ding vop2_writel(vop2, RK3568_CLUSTER0_WIN0_YRGB_MST + win_offset, 4985ee01dbb2SDamon Ding cstate->dma_addr + splice_yrgb_offset); 4986ecc31b6eSAndy Yan 4987ecc31b6eSAndy Yan vop2_writel(vop2, RK3568_CLUSTER0_WIN0_ACT_INFO + win_offset, act_info); 4988ecc31b6eSAndy Yan vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_INFO + win_offset, dsp_info); 4989ecc31b6eSAndy Yan vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_ST + win_offset, dsp_st); 4990ecc31b6eSAndy Yan 4991ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, WIN_EN_SHIFT, 1, false); 4992ecc31b6eSAndy Yan 4993df0a5c43SDamon Ding csc_mode = vop2_convert_csc_mode(conn_state->color_encoding, conn_state->color_range, 4994df0a5c43SDamon Ding CSC_10BIT_DEPTH); 4995ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, 4996ecc31b6eSAndy Yan CLUSTER_RGB2YUV_EN_SHIFT, 4997ecc31b6eSAndy Yan is_yuv_output(conn_state->bus_format), false); 4998ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, CSC_MODE_MASK, 4999ecc31b6eSAndy Yan CLUSTER_CSC_MODE_SHIFT, csc_mode, false); 5000840bf541SDamon Ding 5001840bf541SDamon Ding dither_up = vop2_win_dither_up(cstate->format); 5002840bf541SDamon Ding vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, 5003840bf541SDamon Ding CLUSTER_DITHER_UP_EN_SHIFT, dither_up, false); 5004840bf541SDamon Ding 5005ecc31b6eSAndy Yan vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, EN_MASK, CLUSTER_EN_SHIFT, 1, false); 5006ecc31b6eSAndy Yan 5007ecc31b6eSAndy Yan vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 50081c9572c7SDamon Ding 50091c9572c7SDamon Ding return 0; 5010d0408543SAndy Yan } 5011d0408543SAndy Yan 50121c9572c7SDamon Ding static int vop2_set_smart_win(struct display_state *state, struct vop2_win_data *win) 5013ecc31b6eSAndy Yan { 5014ecc31b6eSAndy Yan struct crtc_state *cstate = &state->crtc_state; 5015ecc31b6eSAndy Yan struct connector_state *conn_state = &state->conn_state; 5016ecc31b6eSAndy Yan struct drm_display_mode *mode = &conn_state->mode; 5017ecc31b6eSAndy Yan struct vop2 *vop2 = cstate->private; 5018ee01dbb2SDamon Ding int src_w = cstate->src_rect.w; 5019ee01dbb2SDamon Ding int src_h = cstate->src_rect.h; 5020ee01dbb2SDamon Ding int crtc_x = cstate->crtc_rect.x; 5021ee01dbb2SDamon Ding int crtc_y = cstate->crtc_rect.y; 5022ee01dbb2SDamon Ding int crtc_w = cstate->crtc_rect.w; 5023ee01dbb2SDamon Ding int crtc_h = cstate->crtc_rect.h; 5024ecc31b6eSAndy Yan int xvir = cstate->xvir; 5025ecc31b6eSAndy Yan int y_mirror = 0; 5026ecc31b6eSAndy Yan int csc_mode; 5027ecc31b6eSAndy Yan u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty; 5028ee01dbb2SDamon Ding /* offset of the right window in splice mode */ 5029ee01dbb2SDamon Ding u32 splice_pixel_offset = 0; 5030ee01dbb2SDamon Ding u32 splice_yrgb_offset = 0; 5031ecc31b6eSAndy Yan u32 win_offset = win->reg_offset; 5032ecc31b6eSAndy Yan u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 50331c9572c7SDamon Ding u32 val; 5034840bf541SDamon Ding bool dither_up; 5035ecc31b6eSAndy Yan 50361c9572c7SDamon Ding if (vop2_is_mirror_win(win)) { 50371c9572c7SDamon Ding struct vop2_win_data *source_win = vop2_find_win_by_phys_id(vop2, win->source_win_id); 50381c9572c7SDamon Ding 50391c9572c7SDamon Ding if (!source_win) { 50401c9572c7SDamon Ding printf("invalid source win id %d\n", win->source_win_id); 50411c9572c7SDamon Ding return -ENODEV; 50421c9572c7SDamon Ding } 50431c9572c7SDamon Ding 50441c9572c7SDamon Ding val = vop2_readl(vop2, RK3568_ESMART0_REGION0_CTRL + source_win->reg_offset); 50451c9572c7SDamon Ding if (!(val & BIT(WIN_EN_SHIFT))) { 50461c9572c7SDamon Ding printf("WARN: the source win should be enabled before mirror win\n"); 50471c9572c7SDamon Ding return -EAGAIN; 50481c9572c7SDamon Ding } 50491c9572c7SDamon Ding } 50501c9572c7SDamon Ding 5051ee01dbb2SDamon Ding if (win->splice_mode_right) { 5052ee01dbb2SDamon Ding src_w = cstate->right_src_rect.w; 5053ee01dbb2SDamon Ding src_h = cstate->right_src_rect.h; 5054ee01dbb2SDamon Ding crtc_x = cstate->right_crtc_rect.x; 5055ee01dbb2SDamon Ding crtc_y = cstate->right_crtc_rect.y; 5056ee01dbb2SDamon Ding crtc_w = cstate->right_crtc_rect.w; 5057ee01dbb2SDamon Ding crtc_h = cstate->right_crtc_rect.h; 5058ee01dbb2SDamon Ding splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x; 5059ee01dbb2SDamon Ding splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3); 5060ee01dbb2SDamon Ding cfg_done = CFG_DONE_EN | BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 5061ee01dbb2SDamon Ding } 5062ee01dbb2SDamon Ding 506374bd8269SSandy Huang /* 506474bd8269SSandy Huang * This is workaround solution for IC design: 506574bd8269SSandy Huang * esmart can't support scale down when actual_w % 16 == 1. 506674bd8269SSandy Huang */ 506774bd8269SSandy Huang if (src_w > crtc_w && (src_w & 0xf) == 1) { 506874bd8269SSandy Huang printf("WARN: vp%d unsupported act_w[%d] mode 16 = 1 when scale down\n", cstate->crtc_id, src_w); 506974bd8269SSandy Huang src_w -= 1; 507074bd8269SSandy Huang } 507174bd8269SSandy Huang 5072d0408543SAndy Yan act_info = (src_h - 1) << 16; 5073d0408543SAndy Yan act_info |= (src_w - 1) & 0xffff; 5074d0408543SAndy Yan 5075d0408543SAndy Yan dsp_info = (crtc_h - 1) << 16; 5076d0408543SAndy Yan dsp_info |= (crtc_w - 1) & 0xffff; 5077d0408543SAndy Yan 5078d0408543SAndy Yan dsp_stx = crtc_x; 5079d0408543SAndy Yan dsp_sty = crtc_y; 5080d0408543SAndy Yan dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); 5081d0408543SAndy Yan 5082d0408543SAndy Yan if (mode->flags & DRM_MODE_FLAG_YMIRROR) 5083d0408543SAndy Yan y_mirror = 1; 5084d0408543SAndy Yan else 5085d0408543SAndy Yan y_mirror = 0; 5086d0408543SAndy Yan 5087a552a69cSDamon Ding if (is_vop3(vop2)) { 5088a552a69cSDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, 5089a552a69cSDamon Ding ESMART_LB_SELECT_MASK, ESMART_LB_SELECT_SHIFT, 5090a552a69cSDamon Ding win->scale_engine_num, false); 5091a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_ESMART0_PORT_SEL + win_offset, 5092a552a69cSDamon Ding ESMART_PORT_SEL_MASK, ESMART_PORT_SEL_SHIFT, 5093a552a69cSDamon Ding cstate->crtc_id, false); 5094a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_ESMART0_DLY_NUM + win_offset, 5095a552a69cSDamon Ding ESMART_DLY_NUM_MASK, ESMART_DLY_NUM_SHIFT, 5096a552a69cSDamon Ding 0, false); 5097a552a69cSDamon Ding 5098a552a69cSDamon Ding /* Merge esmart1/3 from vp1 post to vp0 */ 5099a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3576 && cstate->crtc_id == 0 && 5100a552a69cSDamon Ding (win->phys_id == ROCKCHIP_VOP2_ESMART1 || 5101a552a69cSDamon Ding win->phys_id == ROCKCHIP_VOP2_ESMART3)) 5102a552a69cSDamon Ding vop2_mask_write(vop2, RK3576_ESMART0_PORT_SEL + win_offset, 5103a552a69cSDamon Ding ESMART_PORT_SEL_MASK, ESMART_PORT_SEL_SHIFT, 5104a552a69cSDamon Ding 1, false); 5105a552a69cSDamon Ding } 51065fa6e665SDamon Ding 5107ecc31b6eSAndy Yan vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h); 51083e39a5a1SSandy Huang 5109a552a69cSDamon Ding if (vop2->version != VOP_VERSION_RK3568) 5110a33b790fSDamon Ding vop2_axi_config(vop2, win); 5111a33b790fSDamon Ding 5112d0408543SAndy Yan if (y_mirror) 5113d0408543SAndy Yan cstate->dma_addr += (src_h - 1) * xvir * 4; 5114d0408543SAndy Yan vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, EN_MASK, 5115d0408543SAndy Yan YMIRROR_EN_SHIFT, y_mirror, false); 5116d0408543SAndy Yan 5117d0408543SAndy Yan vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 5118d0408543SAndy Yan WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format, 5119d0408543SAndy Yan false); 5120a552a69cSDamon Ding 5121a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3576) 5122a552a69cSDamon Ding vop2_writel(vop2, RK3576_ESMART0_ALPHA_MAP + win_offset, 0x8000ff00); 5123a552a69cSDamon Ding 5124d0408543SAndy Yan vop2_writel(vop2, RK3568_ESMART0_REGION0_VIR + win_offset, xvir); 5125d0408543SAndy Yan vop2_writel(vop2, RK3568_ESMART0_REGION0_YRGB_MST + win_offset, 5126ee01dbb2SDamon Ding cstate->dma_addr + splice_yrgb_offset); 5127d0408543SAndy Yan 5128d0408543SAndy Yan vop2_writel(vop2, RK3568_ESMART0_REGION0_ACT_INFO + win_offset, 5129d0408543SAndy Yan act_info); 5130d0408543SAndy Yan vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_INFO + win_offset, 5131d0408543SAndy Yan dsp_info); 5132d0408543SAndy Yan vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_ST + win_offset, dsp_st); 5133d0408543SAndy Yan 5134d0408543SAndy Yan vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK, 5135d0408543SAndy Yan WIN_EN_SHIFT, 1, false); 5136d0408543SAndy Yan 5137df0a5c43SDamon Ding csc_mode = vop2_convert_csc_mode(conn_state->color_encoding, conn_state->color_range, 5138df0a5c43SDamon Ding CSC_10BIT_DEPTH); 513910ee9f5bSAlgea Cao vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, EN_MASK, 514010ee9f5bSAlgea Cao RGB2YUV_EN_SHIFT, 514110ee9f5bSAlgea Cao is_yuv_output(conn_state->bus_format), false); 514210ee9f5bSAlgea Cao vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, CSC_MODE_MASK, 514310ee9f5bSAlgea Cao CSC_MODE_SHIFT, csc_mode, false); 514410ee9f5bSAlgea Cao 5145840bf541SDamon Ding dither_up = vop2_win_dither_up(cstate->format); 5146840bf541SDamon Ding vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK, 5147840bf541SDamon Ding REGION0_DITHER_UP_EN_SHIFT, dither_up, false); 5148840bf541SDamon Ding 5149d0408543SAndy Yan vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 51501c9572c7SDamon Ding 51511c9572c7SDamon Ding return 0; 5152ecc31b6eSAndy Yan } 5153ecc31b6eSAndy Yan 5154ee01dbb2SDamon Ding static void vop2_calc_display_rect_for_splice(struct display_state *state) 5155ee01dbb2SDamon Ding { 5156ee01dbb2SDamon Ding struct crtc_state *cstate = &state->crtc_state; 5157ee01dbb2SDamon Ding struct connector_state *conn_state = &state->conn_state; 5158ee01dbb2SDamon Ding struct drm_display_mode *mode = &conn_state->mode; 5159ee01dbb2SDamon Ding struct display_rect *src_rect = &cstate->src_rect; 5160ee01dbb2SDamon Ding struct display_rect *dst_rect = &cstate->crtc_rect; 5161ee01dbb2SDamon Ding struct display_rect left_src, left_dst, right_src, right_dst; 5162ee01dbb2SDamon Ding u16 half_hdisplay = mode->crtc_hdisplay >> 1; 5163ee01dbb2SDamon Ding int left_src_w, left_dst_w, right_dst_w; 5164ee01dbb2SDamon Ding 5165ee01dbb2SDamon Ding left_dst_w = min_t(u16, half_hdisplay, dst_rect->x + dst_rect->w) - dst_rect->x; 5166ee01dbb2SDamon Ding if (left_dst_w < 0) 5167ee01dbb2SDamon Ding left_dst_w = 0; 5168ee01dbb2SDamon Ding right_dst_w = dst_rect->w - left_dst_w; 5169ee01dbb2SDamon Ding 5170ee01dbb2SDamon Ding if (!right_dst_w) 5171ee01dbb2SDamon Ding left_src_w = src_rect->w; 5172ee01dbb2SDamon Ding else 51730df0fd39SSandy Huang left_src_w = src_rect->x + src_rect->w - src_rect->w / 2; 5174ee01dbb2SDamon Ding 5175ee01dbb2SDamon Ding left_src.x = src_rect->x; 5176ee01dbb2SDamon Ding left_src.w = left_src_w; 5177ee01dbb2SDamon Ding left_dst.x = dst_rect->x; 5178ee01dbb2SDamon Ding left_dst.w = left_dst_w; 5179ee01dbb2SDamon Ding right_src.x = left_src.x + left_src.w; 5180ee01dbb2SDamon Ding right_src.w = src_rect->x + src_rect->w - left_src.x - left_src.w; 5181ee01dbb2SDamon Ding right_dst.x = dst_rect->x + left_dst_w - half_hdisplay; 5182ee01dbb2SDamon Ding right_dst.w = right_dst_w; 5183ee01dbb2SDamon Ding 5184ee01dbb2SDamon Ding left_src.y = src_rect->y; 5185ee01dbb2SDamon Ding left_src.h = src_rect->h; 5186ee01dbb2SDamon Ding left_dst.y = dst_rect->y; 5187ee01dbb2SDamon Ding left_dst.h = dst_rect->h; 5188ee01dbb2SDamon Ding right_src.y = src_rect->y; 5189ee01dbb2SDamon Ding right_src.h = src_rect->h; 5190ee01dbb2SDamon Ding right_dst.y = dst_rect->y; 5191ee01dbb2SDamon Ding right_dst.h = dst_rect->h; 5192ee01dbb2SDamon Ding 5193ee01dbb2SDamon Ding memcpy(&cstate->src_rect, &left_src, sizeof(struct display_rect)); 5194ee01dbb2SDamon Ding memcpy(&cstate->crtc_rect, &left_dst, sizeof(struct display_rect)); 5195ee01dbb2SDamon Ding memcpy(&cstate->right_src_rect, &right_src, sizeof(struct display_rect)); 5196ee01dbb2SDamon Ding memcpy(&cstate->right_crtc_rect, &right_dst, sizeof(struct display_rect)); 5197ee01dbb2SDamon Ding } 5198ee01dbb2SDamon Ding 5199ecc31b6eSAndy Yan static int rockchip_vop2_set_plane(struct display_state *state) 5200ecc31b6eSAndy Yan { 5201ecc31b6eSAndy Yan struct crtc_state *cstate = &state->crtc_state; 5202ecc31b6eSAndy Yan struct vop2 *vop2 = cstate->private; 5203ecc31b6eSAndy Yan struct vop2_win_data *win_data; 5204ee01dbb2SDamon Ding struct vop2_win_data *splice_win_data; 5205ecc31b6eSAndy Yan u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id; 5206ecc31b6eSAndy Yan char plane_name[10] = {0}; 52071c9572c7SDamon Ding int ret; 5208ecc31b6eSAndy Yan 5209ee01dbb2SDamon Ding if (cstate->crtc_rect.w > cstate->max_output.width) { 5210ecc31b6eSAndy Yan printf("ERROR: output w[%d] exceeded max width[%d]\n", 5211ee01dbb2SDamon Ding cstate->crtc_rect.w, cstate->max_output.width); 5212ecc31b6eSAndy Yan return -EINVAL; 5213ecc31b6eSAndy Yan } 5214ecc31b6eSAndy Yan 5215ecc31b6eSAndy Yan win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id); 5216ecc31b6eSAndy Yan if (!win_data) { 5217ecc31b6eSAndy Yan printf("invalid win id %d\n", primary_plane_id); 5218ecc31b6eSAndy Yan return -ENODEV; 5219ecc31b6eSAndy Yan } 5220ecc31b6eSAndy Yan 52215fa6e665SDamon Ding /* ignore some plane register according vop3 esmart lb mode */ 52225fa6e665SDamon Ding if (vop3_ignore_plane(vop2, win_data)) 52235fa6e665SDamon Ding return -EACCES; 52245fa6e665SDamon Ding 5225a552a69cSDamon Ding if (vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3576) { 5226b6ba80b4SDamon Ding if (vop2_power_domain_on(vop2, win_data->pd_id)) 5227b6ba80b4SDamon Ding printf("open vp%d plane pd fail\n", cstate->crtc_id); 5228b6ba80b4SDamon Ding } 5229b6ba80b4SDamon Ding 5230ee01dbb2SDamon Ding if (cstate->splice_mode) { 5231ee01dbb2SDamon Ding if (win_data->splice_win_id) { 5232ee01dbb2SDamon Ding splice_win_data = vop2_find_win_by_phys_id(vop2, win_data->splice_win_id); 5233ee01dbb2SDamon Ding splice_win_data->splice_mode_right = true; 5234b6ba80b4SDamon Ding 5235b6ba80b4SDamon Ding if (vop2_power_domain_on(vop2, splice_win_data->pd_id)) 5236b6ba80b4SDamon Ding printf("splice mode: open vp%d plane pd fail\n", cstate->splice_crtc_id); 5237b6ba80b4SDamon Ding 5238ee01dbb2SDamon Ding vop2_calc_display_rect_for_splice(state); 5239ee01dbb2SDamon Ding if (win_data->type == CLUSTER_LAYER) 5240ee01dbb2SDamon Ding vop2_set_cluster_win(state, splice_win_data); 5241ee01dbb2SDamon Ding else 5242ee01dbb2SDamon Ding vop2_set_smart_win(state, splice_win_data); 5243ee01dbb2SDamon Ding } else { 5244ee01dbb2SDamon Ding printf("ERROR: splice mode is unsupported by plane %s\n", 5245ee01dbb2SDamon Ding get_plane_name(primary_plane_id, plane_name)); 5246ee01dbb2SDamon Ding return -EINVAL; 5247ee01dbb2SDamon Ding } 5248ee01dbb2SDamon Ding } 5249ee01dbb2SDamon Ding 5250ecc31b6eSAndy Yan if (win_data->type == CLUSTER_LAYER) 52511c9572c7SDamon Ding ret = vop2_set_cluster_win(state, win_data); 5252ecc31b6eSAndy Yan else 52531c9572c7SDamon Ding ret = vop2_set_smart_win(state, win_data); 52541c9572c7SDamon Ding if (ret) 52551c9572c7SDamon Ding return ret; 52568895aec1SSandy Huang 52578895aec1SSandy Huang printf("VOP VP%d enable %s[%dx%d->%dx%d@%dx%d] fmt[%d] addr[0x%x]\n", 52588895aec1SSandy Huang cstate->crtc_id, get_plane_name(primary_plane_id, plane_name), 5259ee01dbb2SDamon Ding cstate->src_rect.w, cstate->src_rect.h, cstate->crtc_rect.w, cstate->crtc_rect.h, 5260ee01dbb2SDamon Ding cstate->crtc_rect.x, cstate->crtc_rect.y, cstate->format, 52618895aec1SSandy Huang cstate->dma_addr); 52628895aec1SSandy Huang 5263d0408543SAndy Yan return 0; 5264d0408543SAndy Yan } 5265d0408543SAndy Yan 5266d0408543SAndy Yan static int rockchip_vop2_prepare(struct display_state *state) 5267d0408543SAndy Yan { 5268d0408543SAndy Yan return 0; 5269d0408543SAndy Yan } 5270d0408543SAndy Yan 527112ee5af0SDamon Ding static void vop2_dsc_cfg_done(struct display_state *state) 527212ee5af0SDamon Ding { 527312ee5af0SDamon Ding struct connector_state *conn_state = &state->conn_state; 527412ee5af0SDamon Ding struct crtc_state *cstate = &state->crtc_state; 527512ee5af0SDamon Ding struct vop2 *vop2 = cstate->private; 527612ee5af0SDamon Ding u8 dsc_id = cstate->dsc_id; 527712ee5af0SDamon Ding u32 ctrl_regs_offset = (dsc_id * 0x30); 527812ee5af0SDamon Ding 527912ee5af0SDamon Ding if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 528012ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE, EN_MASK, 528112ee5af0SDamon Ding DSC_CFG_DONE_SHIFT, 1, false); 528212ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + 0x30, EN_MASK, 528312ee5af0SDamon Ding DSC_CFG_DONE_SHIFT, 1, false); 528412ee5af0SDamon Ding } else { 528512ee5af0SDamon Ding vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + ctrl_regs_offset, EN_MASK, 528612ee5af0SDamon Ding DSC_CFG_DONE_SHIFT, 1, false); 528712ee5af0SDamon Ding } 528812ee5af0SDamon Ding } 528912ee5af0SDamon Ding 5290d0408543SAndy Yan static int rockchip_vop2_enable(struct display_state *state) 5291d0408543SAndy Yan { 5292d0408543SAndy Yan struct crtc_state *cstate = &state->crtc_state; 5293d0408543SAndy Yan struct vop2 *vop2 = cstate->private; 529452ee18acSSandy Huang u32 vp_offset = (cstate->crtc_id * 0x100); 5295ecc31b6eSAndy Yan u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 5296d0408543SAndy Yan 5297d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 5298d0408543SAndy Yan STANDBY_EN_SHIFT, 0, false); 5299ee01dbb2SDamon Ding 5300ee01dbb2SDamon Ding if (cstate->splice_mode) 5301ee01dbb2SDamon Ding cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 5302ee01dbb2SDamon Ding 5303d0408543SAndy Yan vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 5304d0408543SAndy Yan 530512ee5af0SDamon Ding if (cstate->dsc_enable) 530612ee5af0SDamon Ding vop2_dsc_cfg_done(state); 530712ee5af0SDamon Ding 53080675a2a4SDamon Ding if (cstate->mcu_timing.mcu_pix_total) 53090675a2a4SDamon Ding vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 53100675a2a4SDamon Ding MCU_HOLD_MODE_SHIFT, 0, false); 53110675a2a4SDamon Ding 5312d0408543SAndy Yan return 0; 5313d0408543SAndy Yan } 5314d0408543SAndy Yan 5315d0408543SAndy Yan static int rockchip_vop2_disable(struct display_state *state) 5316d0408543SAndy Yan { 5317d0408543SAndy Yan struct crtc_state *cstate = &state->crtc_state; 5318d0408543SAndy Yan struct vop2 *vop2 = cstate->private; 531952ee18acSSandy Huang u32 vp_offset = (cstate->crtc_id * 0x100); 5320ecc31b6eSAndy Yan u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 5321d0408543SAndy Yan 5322d0408543SAndy Yan vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 5323d0408543SAndy Yan STANDBY_EN_SHIFT, 1, false); 5324ee01dbb2SDamon Ding 5325ee01dbb2SDamon Ding if (cstate->splice_mode) 5326ee01dbb2SDamon Ding cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 5327ee01dbb2SDamon Ding 5328d0408543SAndy Yan vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 5329d0408543SAndy Yan 5330d0408543SAndy Yan return 0; 5331d0408543SAndy Yan } 5332d0408543SAndy Yan 5333ee008497SSandy Huang static int rockchip_vop2_get_cursor_plane(struct display_state *state, u32 plane_mask, int cursor_plane) 5334ee008497SSandy Huang { 5335ee008497SSandy Huang struct crtc_state *cstate = &state->crtc_state; 5336ee008497SSandy Huang struct vop2 *vop2 = cstate->private; 5337ee008497SSandy Huang int i = 0; 5338ee008497SSandy Huang int correct_cursor_plane = -1; 5339ee008497SSandy Huang int plane_type = -1; 5340ee008497SSandy Huang 5341ee008497SSandy Huang if (cursor_plane < 0) 5342ee008497SSandy Huang return -1; 5343ee008497SSandy Huang 5344ee008497SSandy Huang if (plane_mask & (1 << cursor_plane)) 5345ee008497SSandy Huang return cursor_plane; 5346ee008497SSandy Huang 5347ee008497SSandy Huang /* Get current cursor plane type */ 5348ee008497SSandy Huang for (i = 0; i < vop2->data->nr_layers; i++) { 5349ee008497SSandy Huang if (vop2->data->plane_table[i].plane_id == cursor_plane) { 5350ee008497SSandy Huang plane_type = vop2->data->plane_table[i].plane_type; 5351ee008497SSandy Huang break; 5352ee008497SSandy Huang } 5353ee008497SSandy Huang } 5354ee008497SSandy Huang 5355ee008497SSandy Huang /* Get the other same plane type plane id */ 5356ee008497SSandy Huang for (i = 0; i < vop2->data->nr_layers; i++) { 5357ee008497SSandy Huang if (vop2->data->plane_table[i].plane_type == plane_type && 5358ee008497SSandy Huang vop2->data->plane_table[i].plane_id != cursor_plane) { 5359ee008497SSandy Huang correct_cursor_plane = vop2->data->plane_table[i].plane_id; 5360ee008497SSandy Huang break; 5361ee008497SSandy Huang } 5362ee008497SSandy Huang } 5363ee008497SSandy Huang 5364ee008497SSandy Huang /* To check whether the new correct_cursor_plane is attach to current vp */ 5365ee008497SSandy Huang if (correct_cursor_plane < 0 || !(plane_mask & (1 << correct_cursor_plane))) { 5366ee008497SSandy Huang printf("error: faild to find correct plane as cursor plane\n"); 5367ee008497SSandy Huang return -1; 5368ee008497SSandy Huang } 5369ee008497SSandy Huang 5370ee008497SSandy Huang printf("vp%d adjust cursor plane from %d to %d\n", 5371ee008497SSandy Huang cstate->crtc_id, cursor_plane, correct_cursor_plane); 5372ee008497SSandy Huang 5373ee008497SSandy Huang return correct_cursor_plane; 5374ee008497SSandy Huang } 5375ee008497SSandy Huang 5376b0989546SSandy Huang static int rockchip_vop2_fixup_dts(struct display_state *state, void *blob) 5377b0989546SSandy Huang { 5378b0989546SSandy Huang struct crtc_state *cstate = &state->crtc_state; 5379b0989546SSandy Huang struct vop2 *vop2 = cstate->private; 5380b0989546SSandy Huang ofnode vp_node; 5381b0989546SSandy Huang struct device_node *port_parent_node = cstate->ports_node; 5382b0989546SSandy Huang static bool vop_fix_dts; 5383b0989546SSandy Huang const char *path; 5384b0989546SSandy Huang u32 plane_mask = 0; 5385b0989546SSandy Huang int vp_id = 0; 5386ee008497SSandy Huang int cursor_plane_id = -1; 5387b0989546SSandy Huang 53885fa6e665SDamon Ding if (vop_fix_dts || vop2->version == VOP_VERSION_RK3528) 5389b0989546SSandy Huang return 0; 5390b0989546SSandy Huang 5391b0989546SSandy Huang ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) { 5392b0989546SSandy Huang path = vp_node.np->full_name; 5393b0989546SSandy Huang plane_mask = vop2->vp_plane_mask[vp_id].plane_mask; 5394b0989546SSandy Huang 53958b1fe597SSandy Huang if (cstate->crtc->assign_plane) 53968b1fe597SSandy Huang continue; 5397ee008497SSandy Huang cursor_plane_id = rockchip_vop2_get_cursor_plane(state, plane_mask, 5398ee008497SSandy Huang cstate->crtc->vps[vp_id].cursor_plane); 5399ee008497SSandy Huang printf("vp%d, plane_mask:0x%x, primary-id:%d, curser-id:%d\n", 5400b0989546SSandy Huang vp_id, plane_mask, 5401ee008497SSandy Huang vop2->vp_plane_mask[vp_id].primary_plane_id, 5402ee008497SSandy Huang cursor_plane_id); 5403b0989546SSandy Huang 5404b0989546SSandy Huang do_fixup_by_path_u32(blob, path, "rockchip,plane-mask", 5405b0989546SSandy Huang plane_mask, 1); 5406b0989546SSandy Huang do_fixup_by_path_u32(blob, path, "rockchip,primary-plane", 5407b0989546SSandy Huang vop2->vp_plane_mask[vp_id].primary_plane_id, 1); 5408ee008497SSandy Huang if (cursor_plane_id >= 0) 5409ee008497SSandy Huang do_fixup_by_path_u32(blob, path, "cursor-win-id", 5410ee008497SSandy Huang cursor_plane_id, 1); 5411b0989546SSandy Huang vp_id++; 5412b0989546SSandy Huang } 5413b0989546SSandy Huang 5414b0989546SSandy Huang vop_fix_dts = true; 5415b0989546SSandy Huang 5416b0989546SSandy Huang return 0; 5417b0989546SSandy Huang } 5418b0989546SSandy Huang 5419820a5c17SDamon Ding static int rockchip_vop2_check(struct display_state *state) 5420820a5c17SDamon Ding { 5421820a5c17SDamon Ding struct crtc_state *cstate = &state->crtc_state; 5422820a5c17SDamon Ding struct rockchip_crtc *crtc = cstate->crtc; 5423820a5c17SDamon Ding 5424820a5c17SDamon Ding if (crtc->splice_mode && cstate->crtc_id == crtc->splice_crtc_id) { 5425820a5c17SDamon Ding printf("WARN: VP%d is busy in splice mode\n", cstate->crtc_id); 5426820a5c17SDamon Ding return -ENOTSUPP; 5427820a5c17SDamon Ding } 5428820a5c17SDamon Ding 5429820a5c17SDamon Ding if (cstate->splice_mode) { 5430820a5c17SDamon Ding crtc->splice_mode = true; 5431820a5c17SDamon Ding crtc->splice_crtc_id = cstate->splice_crtc_id; 5432820a5c17SDamon Ding } 5433820a5c17SDamon Ding 5434820a5c17SDamon Ding return 0; 5435820a5c17SDamon Ding } 5436820a5c17SDamon Ding 543722007755SDamon Ding static int rockchip_vop2_mode_valid(struct display_state *state) 543822007755SDamon Ding { 543922007755SDamon Ding struct connector_state *conn_state = &state->conn_state; 544022007755SDamon Ding struct crtc_state *cstate = &state->crtc_state; 544122007755SDamon Ding struct drm_display_mode *mode = &conn_state->mode; 544222007755SDamon Ding struct videomode vm; 544322007755SDamon Ding 544422007755SDamon Ding drm_display_mode_to_videomode(mode, &vm); 544522007755SDamon Ding 544622007755SDamon Ding if (vm.hactive < 32 || vm.vactive < 32 || 544722007755SDamon Ding (vm.hfront_porch * vm.hsync_len * vm.hback_porch * 544822007755SDamon Ding vm.vfront_porch * vm.vsync_len * vm.vback_porch == 0)) { 544922007755SDamon Ding printf("ERROR: VP%d: unsupported display timing\n", cstate->crtc_id); 545022007755SDamon Ding return -EINVAL; 545122007755SDamon Ding } 545222007755SDamon Ding 545322007755SDamon Ding return 0; 545422007755SDamon Ding } 545522007755SDamon Ding 5456b02eb70bSDamon Ding static int rockchip_vop2_mode_fixup(struct display_state *state) 5457b02eb70bSDamon Ding { 5458b02eb70bSDamon Ding struct connector_state *conn_state = &state->conn_state; 5459b02eb70bSDamon Ding struct drm_display_mode *mode = &conn_state->mode; 5460b02eb70bSDamon Ding struct crtc_state *cstate = &state->crtc_state; 5461b02eb70bSDamon Ding struct vop2 *vop2 = cstate->private; 5462b02eb70bSDamon Ding 54631b5811e7SDamon Ding drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V | CRTC_STEREO_DOUBLE); 5464b02eb70bSDamon Ding 5465b02eb70bSDamon Ding if (mode->flags & DRM_MODE_FLAG_DBLCLK || conn_state->output_if & VOP_OUTPUT_IF_BT656) 5466b02eb70bSDamon Ding mode->crtc_clock *= 2; 5467b02eb70bSDamon Ding 5468b02eb70bSDamon Ding /* 5469b02eb70bSDamon Ding * For RK3528, the path of CVBS output is like: 5470b02eb70bSDamon Ding * VOP BT656 ENCODER -> CVBS BT656 DECODER -> CVBS ENCODER -> CVBS VDAC 5471b02eb70bSDamon Ding * The vop2 dclk should be four times crtc_clock for CVBS sampling 5472b02eb70bSDamon Ding * clock needs. 5473b02eb70bSDamon Ding */ 5474b02eb70bSDamon Ding if (vop2->version == VOP_VERSION_RK3528 && conn_state->output_if & VOP_OUTPUT_IF_BT656) 5475b02eb70bSDamon Ding mode->crtc_clock *= 4; 5476b02eb70bSDamon Ding 54774d64cedbSDamon Ding mode->crtc_clock *= rockchip_drm_get_cycles_per_pixel(conn_state->bus_format); 54784d64cedbSDamon Ding if (cstate->mcu_timing.mcu_pix_total) 54794d64cedbSDamon Ding mode->crtc_clock *= cstate->mcu_timing.mcu_pix_total + 1; 54800675a2a4SDamon Ding 548117e6e1a5SChaoyi Chen if (conn_state->secondary && 548217e6e1a5SChaoyi Chen conn_state->secondary->type != DRM_MODE_CONNECTOR_LVDS) { 5483b02eb70bSDamon Ding mode->crtc_clock *= 2; 5484b02eb70bSDamon Ding mode->crtc_hdisplay *= 2; 5485b02eb70bSDamon Ding mode->crtc_hsync_start *= 2; 5486b02eb70bSDamon Ding mode->crtc_hsync_end *= 2; 5487b02eb70bSDamon Ding mode->crtc_htotal *= 2; 5488b02eb70bSDamon Ding } 5489b02eb70bSDamon Ding 5490b02eb70bSDamon Ding return 0; 5491b02eb70bSDamon Ding } 5492b02eb70bSDamon Ding 54934c765862SDamon Ding #define FRAC_16_16(mult, div) (((mult) << 16) / (div)) 54944c765862SDamon Ding 54954c765862SDamon Ding static int rockchip_vop2_plane_check(struct display_state *state) 54964c765862SDamon Ding { 54974c765862SDamon Ding struct crtc_state *cstate = &state->crtc_state; 54984c765862SDamon Ding struct vop2 *vop2 = cstate->private; 54994c765862SDamon Ding struct display_rect *src = &cstate->src_rect; 55004c765862SDamon Ding struct display_rect *dst = &cstate->crtc_rect; 55014c765862SDamon Ding struct vop2_win_data *win_data; 55024c765862SDamon Ding int min_scale, max_scale; 55034c765862SDamon Ding int hscale, vscale; 55044c765862SDamon Ding u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id; 55054c765862SDamon Ding 55064c765862SDamon Ding win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id); 55074c765862SDamon Ding if (!win_data) { 55084c765862SDamon Ding printf("ERROR: invalid win id %d\n", primary_plane_id); 55094c765862SDamon Ding return -ENODEV; 55104c765862SDamon Ding } 55114c765862SDamon Ding 55124c765862SDamon Ding min_scale = FRAC_16_16(1, win_data->max_downscale_factor); 55134c765862SDamon Ding max_scale = FRAC_16_16(win_data->max_upscale_factor, 1); 55144c765862SDamon Ding 55154c765862SDamon Ding hscale = display_rect_calc_hscale(src, dst, min_scale, max_scale); 55164c765862SDamon Ding vscale = display_rect_calc_vscale(src, dst, min_scale, max_scale); 55174c765862SDamon Ding if (hscale < 0 || vscale < 0) { 55184c765862SDamon Ding printf("ERROR: VP%d %s: scale factor is out of range\n", cstate->crtc_id, win_data->name); 55194c765862SDamon Ding return -ERANGE; 55204c765862SDamon Ding } 55214c765862SDamon Ding 55224c765862SDamon Ding return 0; 55234c765862SDamon Ding } 5524337d1c13SDamon Ding 55258e7ef808SDamon Ding static int rockchip_vop2_apply_soft_te(struct display_state *state) 55268e7ef808SDamon Ding { 5527d8e7f4a5SSandy Huang __maybe_unused struct connector_state *conn_state = &state->conn_state; 55288e7ef808SDamon Ding struct crtc_state *cstate = &state->crtc_state; 55298e7ef808SDamon Ding struct vop2 *vop2 = cstate->private; 55308e7ef808SDamon Ding u32 vp_offset = (cstate->crtc_id * 0x100); 55318e7ef808SDamon Ding int val = 0; 55328e7ef808SDamon Ding int ret = 0; 55338e7ef808SDamon Ding 55348e7ef808SDamon Ding ret = readl_poll_timeout(vop2->regs + RK3568_VP0_MIPI_CTRL + vp_offset, val, 55358e7ef808SDamon Ding (val >> EDPI_WMS_FS) & 0x1, 50 * 1000); 55368e7ef808SDamon Ding if (!ret) { 5537d8e7f4a5SSandy Huang #ifndef CONFIG_SPL_BUILD 55388e7ef808SDamon Ding ret = readx_poll_timeout(dm_gpio_get_value, conn_state->te_gpio, val, 55398e7ef808SDamon Ding !val, 50 * 1000); 55408e7ef808SDamon Ding if (!ret) { 55418e7ef808SDamon Ding ret = readx_poll_timeout(dm_gpio_get_value, conn_state->te_gpio, val, 55428e7ef808SDamon Ding val, 50 * 1000); 55438e7ef808SDamon Ding if (!ret) { 55448e7ef808SDamon Ding vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 55458e7ef808SDamon Ding EN_MASK, EDPI_WMS_FS, 1, false); 55468e7ef808SDamon Ding } else { 55478e7ef808SDamon Ding printf("ERROR: vp%d wait for active TE signal timeout\n", 55488e7ef808SDamon Ding cstate->crtc_id); 55498e7ef808SDamon Ding return ret; 55508e7ef808SDamon Ding } 55518e7ef808SDamon Ding } else { 55528e7ef808SDamon Ding printf("ERROR: vp%d TE signal maybe always high\n", cstate->crtc_id); 55538e7ef808SDamon Ding return ret; 55548e7ef808SDamon Ding } 5555d8e7f4a5SSandy Huang #endif 55568e7ef808SDamon Ding } else { 55578e7ef808SDamon Ding printf("ERROR: vp%d wait vop2 frame start timeout in hold mode\n", cstate->crtc_id); 55588e7ef808SDamon Ding return ret; 55598e7ef808SDamon Ding } 55608e7ef808SDamon Ding 55618e7ef808SDamon Ding return 0; 55628e7ef808SDamon Ding } 55638e7ef808SDamon Ding 556472388c26SDamon Ding static int rockchip_vop2_regs_dump(struct display_state *state) 556572388c26SDamon Ding { 556672388c26SDamon Ding struct crtc_state *cstate = &state->crtc_state; 556772388c26SDamon Ding struct vop2 *vop2 = cstate->private; 556872388c26SDamon Ding const struct vop2_data *vop2_data = vop2->data; 556972388c26SDamon Ding const struct vop2_dump_regs *regs = vop2_data->dump_regs; 5570a552a69cSDamon Ding u32 len = 128; 557172388c26SDamon Ding u32 n, i, j; 557272388c26SDamon Ding u32 base; 557372388c26SDamon Ding 557472388c26SDamon Ding if (!cstate->crtc->active) 557572388c26SDamon Ding return -EINVAL; 557672388c26SDamon Ding 557772388c26SDamon Ding n = vop2_data->dump_regs_size; 557872388c26SDamon Ding for (i = 0; i < n; i++) { 557972388c26SDamon Ding base = regs[i].offset; 5580a552a69cSDamon Ding len = 128; 5581a552a69cSDamon Ding if (regs[i].size) 5582a552a69cSDamon Ding len = min(len, regs[i].size >> 2); 558372388c26SDamon Ding printf("\n%s:\n", regs[i].name); 5584a552a69cSDamon Ding for (j = 0; j < len;) { 558572388c26SDamon Ding printf("%08lx: %08x %08x %08x %08x\n", (uintptr_t)vop2->regs + base + j * 4, 558672388c26SDamon Ding vop2_readl(vop2, base + (4 * j)), 558772388c26SDamon Ding vop2_readl(vop2, base + (4 * (j + 1))), 558872388c26SDamon Ding vop2_readl(vop2, base + (4 * (j + 2))), 558972388c26SDamon Ding vop2_readl(vop2, base + (4 * (j + 3)))); 559072388c26SDamon Ding j += 4; 559172388c26SDamon Ding } 559272388c26SDamon Ding } 559372388c26SDamon Ding 559472388c26SDamon Ding return 0; 559572388c26SDamon Ding } 559672388c26SDamon Ding 559772388c26SDamon Ding static int rockchip_vop2_active_regs_dump(struct display_state *state) 559872388c26SDamon Ding { 559972388c26SDamon Ding struct crtc_state *cstate = &state->crtc_state; 560072388c26SDamon Ding struct vop2 *vop2 = cstate->private; 560172388c26SDamon Ding const struct vop2_data *vop2_data = vop2->data; 560272388c26SDamon Ding const struct vop2_dump_regs *regs = vop2_data->dump_regs; 5603a552a69cSDamon Ding u32 len = 128; 560472388c26SDamon Ding u32 n, i, j; 560572388c26SDamon Ding u32 base; 560672388c26SDamon Ding bool enable_state; 560772388c26SDamon Ding 560872388c26SDamon Ding if (!cstate->crtc->active) 560972388c26SDamon Ding return -EINVAL; 561072388c26SDamon Ding 561172388c26SDamon Ding n = vop2_data->dump_regs_size; 561272388c26SDamon Ding for (i = 0; i < n; i++) { 561372388c26SDamon Ding if (regs[i].state_mask) { 561472388c26SDamon Ding enable_state = (vop2_readl(vop2, regs[i].state_base) >> regs[i].state_shift) & 561572388c26SDamon Ding regs[i].state_mask; 561672388c26SDamon Ding if (enable_state != regs[i].enable_state) 561772388c26SDamon Ding continue; 561872388c26SDamon Ding } 561972388c26SDamon Ding 562072388c26SDamon Ding base = regs[i].offset; 5621a552a69cSDamon Ding len = 128; 5622a552a69cSDamon Ding if (regs[i].size) 5623a552a69cSDamon Ding len = min(len, regs[i].size >> 2); 562472388c26SDamon Ding printf("\n%s:\n", regs[i].name); 5625a552a69cSDamon Ding for (j = 0; j < len;) { 562672388c26SDamon Ding printf("%08lx: %08x %08x %08x %08x\n", (uintptr_t)vop2->regs + base + j * 4, 562772388c26SDamon Ding vop2_readl(vop2, base + (4 * j)), 562872388c26SDamon Ding vop2_readl(vop2, base + (4 * (j + 1))), 562972388c26SDamon Ding vop2_readl(vop2, base + (4 * (j + 2))), 563072388c26SDamon Ding vop2_readl(vop2, base + (4 * (j + 3)))); 563172388c26SDamon Ding j += 4; 563272388c26SDamon Ding } 563372388c26SDamon Ding } 563472388c26SDamon Ding 563572388c26SDamon Ding return 0; 563672388c26SDamon Ding } 563772388c26SDamon Ding 563872388c26SDamon Ding static struct vop2_dump_regs rk3528_dump_regs[] = { 563972388c26SDamon Ding { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 }, 564072388c26SDamon Ding { RK3528_OVL_SYS, "OVL_SYS", 0, 0, 0, 0 }, 564172388c26SDamon Ding { RK3528_OVL_PORT0_CTRL, "OVL_VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 }, 564272388c26SDamon Ding { RK3528_OVL_PORT1_CTRL, "OVL_VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 564372388c26SDamon Ding { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 }, 564472388c26SDamon Ding { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 564572388c26SDamon Ding { RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1 }, 564672388c26SDamon Ding { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 }, 564772388c26SDamon Ding { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 }, 564872388c26SDamon Ding { RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_CTRL0, 0x1, 0, 1 }, 564972388c26SDamon Ding { RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_CTRL0, 0x1, 0, 1 }, 565072388c26SDamon Ding { RK3528_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0 }, 565172388c26SDamon Ding { RK3528_ACM_CTRL, "ACM", RK3528_ACM_CTRL, 0x1, 0, 1}, 565272388c26SDamon Ding }; 565372388c26SDamon Ding 56545fa6e665SDamon Ding static u8 rk3528_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = { 56555fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART0, 56565fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART1, 56575fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART2, 56585fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART3, 56595fa6e665SDamon Ding }; 56605fa6e665SDamon Ding 56615fa6e665SDamon Ding static struct vop2_plane_table rk3528_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 56625fa6e665SDamon Ding {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 56635fa6e665SDamon Ding {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 56645fa6e665SDamon Ding {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 56655fa6e665SDamon Ding {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER}, 56665fa6e665SDamon Ding {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER}, 56675fa6e665SDamon Ding }; 56685fa6e665SDamon Ding 56695fa6e665SDamon Ding static struct vop2_vp_plane_mask rk3528_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 56705fa6e665SDamon Ding { /* one display policy for hdmi */ 56715fa6e665SDamon Ding {/* main display */ 5672ebbd144cSAlgea Cao .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 56735fa6e665SDamon Ding .attached_layers_nr = 4, 56745fa6e665SDamon Ding .attached_layers = { 56755fa6e665SDamon Ding ROCKCHIP_VOP2_CLUSTER0, 56765fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART2 56775fa6e665SDamon Ding }, 56785fa6e665SDamon Ding }, 56795fa6e665SDamon Ding {/* second display */}, 56805fa6e665SDamon Ding {/* third display */}, 56815fa6e665SDamon Ding {/* fourth display */}, 56825fa6e665SDamon Ding }, 56835fa6e665SDamon Ding 56845fa6e665SDamon Ding { /* two display policy */ 56855fa6e665SDamon Ding {/* main display */ 5686ebbd144cSAlgea Cao .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 56875fa6e665SDamon Ding .attached_layers_nr = 3, 56885fa6e665SDamon Ding .attached_layers = { 56895fa6e665SDamon Ding ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1 56905fa6e665SDamon Ding }, 56915fa6e665SDamon Ding }, 56925fa6e665SDamon Ding 56935fa6e665SDamon Ding {/* second display */ 56945fa6e665SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART3, 56955fa6e665SDamon Ding .attached_layers_nr = 2, 56965fa6e665SDamon Ding .attached_layers = { 56975fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 56985fa6e665SDamon Ding }, 56995fa6e665SDamon Ding }, 57005fa6e665SDamon Ding {/* third display */}, 57015fa6e665SDamon Ding {/* fourth display */}, 57025fa6e665SDamon Ding }, 57035fa6e665SDamon Ding 57045fa6e665SDamon Ding { /* one display policy for cvbs */ 57055fa6e665SDamon Ding {/* main display */ 57065fa6e665SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART3, 57075fa6e665SDamon Ding .attached_layers_nr = 2, 57085fa6e665SDamon Ding .attached_layers = { 57095fa6e665SDamon Ding ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 57105fa6e665SDamon Ding }, 57115fa6e665SDamon Ding }, 57125fa6e665SDamon Ding {/* second display */}, 57135fa6e665SDamon Ding {/* third display */}, 57145fa6e665SDamon Ding {/* fourth display */}, 57155fa6e665SDamon Ding }, 57165fa6e665SDamon Ding 57175fa6e665SDamon Ding {/* reserved */}, 57185fa6e665SDamon Ding }; 57195fa6e665SDamon Ding 57205fa6e665SDamon Ding static struct vop2_win_data rk3528_win_data[5] = { 57215fa6e665SDamon Ding { 57225fa6e665SDamon Ding .name = "Esmart0", 57235fa6e665SDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART0, 57245fa6e665SDamon Ding .type = ESMART_LAYER, 57255fa6e665SDamon Ding .win_sel_port_offset = 8, 57265fa6e665SDamon Ding .layer_sel_win_id = { 1, 0xff, 0xff, 0xff }, 57275fa6e665SDamon Ding .reg_offset = 0, 57285fa6e665SDamon Ding .axi_id = 0, 57295fa6e665SDamon Ding .axi_yrgb_id = 0x06, 57305fa6e665SDamon Ding .axi_uv_id = 0x07, 57315fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 57325fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 57335fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 57345fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 57355fa6e665SDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 57365fa6e665SDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */ 57375fa6e665SDamon Ding .max_upscale_factor = 8, 57385fa6e665SDamon Ding .max_downscale_factor = 8, 57395fa6e665SDamon Ding }, 57405fa6e665SDamon Ding 57415fa6e665SDamon Ding { 57425fa6e665SDamon Ding .name = "Esmart1", 57435fa6e665SDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART1, 57445fa6e665SDamon Ding .type = ESMART_LAYER, 57455fa6e665SDamon Ding .win_sel_port_offset = 10, 57465fa6e665SDamon Ding .layer_sel_win_id = { 2, 0xff, 0xff, 0xff }, 57475fa6e665SDamon Ding .reg_offset = 0x200, 57485fa6e665SDamon Ding .axi_id = 0, 57495fa6e665SDamon Ding .axi_yrgb_id = 0x08, 57505fa6e665SDamon Ding .axi_uv_id = 0x09, 57515fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 57525fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 57535fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 57545fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 57555fa6e665SDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 57565fa6e665SDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */ 57575fa6e665SDamon Ding .max_upscale_factor = 8, 57585fa6e665SDamon Ding .max_downscale_factor = 8, 57595fa6e665SDamon Ding }, 57605fa6e665SDamon Ding 57615fa6e665SDamon Ding { 57625fa6e665SDamon Ding .name = "Esmart2", 57635fa6e665SDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART2, 57645fa6e665SDamon Ding .type = ESMART_LAYER, 57655fa6e665SDamon Ding .win_sel_port_offset = 12, 57665fa6e665SDamon Ding .layer_sel_win_id = { 3, 0, 0xff, 0xff }, 57675fa6e665SDamon Ding .reg_offset = 0x400, 57685fa6e665SDamon Ding .axi_id = 0, 57695fa6e665SDamon Ding .axi_yrgb_id = 0x0a, 57705fa6e665SDamon Ding .axi_uv_id = 0x0b, 57715fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 57725fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 57735fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 57745fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 57755fa6e665SDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 57765fa6e665SDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */ 57775fa6e665SDamon Ding .max_upscale_factor = 8, 57785fa6e665SDamon Ding .max_downscale_factor = 8, 57795fa6e665SDamon Ding }, 57805fa6e665SDamon Ding 57815fa6e665SDamon Ding { 57825fa6e665SDamon Ding .name = "Esmart3", 57835fa6e665SDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART3, 57845fa6e665SDamon Ding .type = ESMART_LAYER, 57855fa6e665SDamon Ding .win_sel_port_offset = 14, 57865fa6e665SDamon Ding .layer_sel_win_id = { 0xff, 1, 0xff, 0xff }, 57875fa6e665SDamon Ding .reg_offset = 0x600, 57885fa6e665SDamon Ding .axi_id = 0, 57895fa6e665SDamon Ding .axi_yrgb_id = 0x0c, 57905fa6e665SDamon Ding .axi_uv_id = 0x0d, 57915fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 57925fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 57935fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 57945fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 57955fa6e665SDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 57965fa6e665SDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */ 57975fa6e665SDamon Ding .max_upscale_factor = 8, 57985fa6e665SDamon Ding .max_downscale_factor = 8, 57995fa6e665SDamon Ding }, 58005fa6e665SDamon Ding 58015fa6e665SDamon Ding { 58025fa6e665SDamon Ding .name = "Cluster0", 58035fa6e665SDamon Ding .phys_id = ROCKCHIP_VOP2_CLUSTER0, 58045fa6e665SDamon Ding .type = CLUSTER_LAYER, 58055fa6e665SDamon Ding .win_sel_port_offset = 0, 58065fa6e665SDamon Ding .layer_sel_win_id = { 0, 0xff, 0xff, 0xff }, 58075fa6e665SDamon Ding .reg_offset = 0, 58085fa6e665SDamon Ding .axi_id = 0, 58095fa6e665SDamon Ding .axi_yrgb_id = 0x02, 58105fa6e665SDamon Ding .axi_uv_id = 0x03, 58115fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 58125fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 58135fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 58145fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 58155fa6e665SDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 58165fa6e665SDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 58175fa6e665SDamon Ding .max_upscale_factor = 8, 58185fa6e665SDamon Ding .max_downscale_factor = 8, 58195fa6e665SDamon Ding }, 58205fa6e665SDamon Ding }; 58215fa6e665SDamon Ding 58225fa6e665SDamon Ding static struct vop2_vp_data rk3528_vp_data[2] = { 58235fa6e665SDamon Ding { 58246027c871SZhang Yubing .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN | VOP_FEATURE_POST_ACM | 58256027c871SZhang Yubing VOP_FEATURE_POST_CSC, 58265fa6e665SDamon Ding .max_output = {4096, 4096}, 5827b05105abSDamon Ding .layer_mix_dly = 6, 5828b05105abSDamon Ding .hdr_mix_dly = 2, 5829b05105abSDamon Ding .win_dly = 8, 58305fa6e665SDamon Ding }, 58315fa6e665SDamon Ding { 58325fa6e665SDamon Ding .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN, 58335fa6e665SDamon Ding .max_output = {1920, 1080}, 5834b05105abSDamon Ding .layer_mix_dly = 2, 5835b05105abSDamon Ding .hdr_mix_dly = 0, 5836b05105abSDamon Ding .win_dly = 8, 58375fa6e665SDamon Ding }, 58385fa6e665SDamon Ding }; 58395fa6e665SDamon Ding 58405fa6e665SDamon Ding const struct vop2_data rk3528_vop = { 58415fa6e665SDamon Ding .version = VOP_VERSION_RK3528, 58425fa6e665SDamon Ding .nr_vps = 2, 58435fa6e665SDamon Ding .vp_data = rk3528_vp_data, 58445fa6e665SDamon Ding .win_data = rk3528_win_data, 58455fa6e665SDamon Ding .plane_mask = rk3528_vp_plane_mask[0], 58465fa6e665SDamon Ding .plane_table = rk3528_plane_table, 58475fa6e665SDamon Ding .vp_primary_plane_order = rk3528_vp_primary_plane_order, 58485fa6e665SDamon Ding .nr_layers = 5, 58495fa6e665SDamon Ding .nr_mixers = 3, 58505fa6e665SDamon Ding .nr_gammas = 2, 58515fa6e665SDamon Ding .esmart_lb_mode = VOP3_ESMART_4K_2K_2K_MODE, 585272388c26SDamon Ding .dump_regs = rk3528_dump_regs, 585372388c26SDamon Ding .dump_regs_size = ARRAY_SIZE(rk3528_dump_regs), 585472388c26SDamon Ding }; 585572388c26SDamon Ding 585672388c26SDamon Ding static struct vop2_dump_regs rk3562_dump_regs[] = { 585772388c26SDamon Ding { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 }, 585872388c26SDamon Ding { RK3528_OVL_SYS, "OVL_SYS", 0, 0, 0, 0 }, 585972388c26SDamon Ding { RK3528_OVL_PORT0_CTRL, "OVL_VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 }, 586072388c26SDamon Ding { RK3528_OVL_PORT1_CTRL, "OVL_VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 586172388c26SDamon Ding { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 }, 586272388c26SDamon Ding { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 586372388c26SDamon Ding { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 }, 586472388c26SDamon Ding { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 }, 586572388c26SDamon Ding { RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_CTRL0, 0x1, 0, 1 }, 586672388c26SDamon Ding { RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_CTRL0, 0x1, 0, 1 }, 58675fa6e665SDamon Ding }; 58685fa6e665SDamon Ding 5869452afb13SDamon Ding static u8 rk3562_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = { 5870452afb13SDamon Ding ROCKCHIP_VOP2_ESMART0, 5871452afb13SDamon Ding ROCKCHIP_VOP2_ESMART1, 5872452afb13SDamon Ding ROCKCHIP_VOP2_ESMART2, 5873452afb13SDamon Ding ROCKCHIP_VOP2_ESMART3, 5874452afb13SDamon Ding }; 5875452afb13SDamon Ding 5876452afb13SDamon Ding static struct vop2_plane_table rk3562_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 5877452afb13SDamon Ding {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 5878452afb13SDamon Ding {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 5879452afb13SDamon Ding {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER}, 5880452afb13SDamon Ding {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER}, 5881452afb13SDamon Ding }; 5882452afb13SDamon Ding 5883452afb13SDamon Ding static struct vop2_vp_plane_mask rk3562_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 5884452afb13SDamon Ding { /* one display policy for hdmi */ 5885452afb13SDamon Ding {/* main display */ 5886452afb13SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 5887452afb13SDamon Ding .attached_layers_nr = 4, 5888452afb13SDamon Ding .attached_layers = { 5889452afb13SDamon Ding ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1, 5890452afb13SDamon Ding ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 5891452afb13SDamon Ding }, 5892452afb13SDamon Ding }, 5893452afb13SDamon Ding {/* second display */}, 5894452afb13SDamon Ding {/* third display */}, 5895452afb13SDamon Ding {/* fourth display */}, 5896452afb13SDamon Ding }, 5897452afb13SDamon Ding 5898452afb13SDamon Ding { /* two display policy */ 5899452afb13SDamon Ding {/* main display */ 5900452afb13SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 5901452afb13SDamon Ding .attached_layers_nr = 2, 5902452afb13SDamon Ding .attached_layers = { 5903452afb13SDamon Ding ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1 5904452afb13SDamon Ding }, 5905452afb13SDamon Ding }, 5906452afb13SDamon Ding 5907452afb13SDamon Ding {/* second display */ 5908452afb13SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART2, 5909452afb13SDamon Ding .attached_layers_nr = 2, 5910452afb13SDamon Ding .attached_layers = { 5911452afb13SDamon Ding ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 5912452afb13SDamon Ding }, 5913452afb13SDamon Ding }, 5914452afb13SDamon Ding {/* third display */}, 5915452afb13SDamon Ding {/* fourth display */}, 5916452afb13SDamon Ding }, 5917452afb13SDamon Ding 5918452afb13SDamon Ding {/* reserved */}, 5919452afb13SDamon Ding }; 5920452afb13SDamon Ding 5921452afb13SDamon Ding static struct vop2_win_data rk3562_win_data[4] = { 5922452afb13SDamon Ding { 5923452afb13SDamon Ding .name = "Esmart0", 5924452afb13SDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART0, 5925452afb13SDamon Ding .type = ESMART_LAYER, 5926452afb13SDamon Ding .win_sel_port_offset = 8, 5927452afb13SDamon Ding .layer_sel_win_id = { 0, 0, 0xff, 0xff }, 5928452afb13SDamon Ding .reg_offset = 0, 5929452afb13SDamon Ding .axi_id = 0, 5930452afb13SDamon Ding .axi_yrgb_id = 0x02, 5931452afb13SDamon Ding .axi_uv_id = 0x03, 5932452afb13SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5933452afb13SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5934452afb13SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5935452afb13SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5936452afb13SDamon Ding .max_upscale_factor = 8, 5937452afb13SDamon Ding .max_downscale_factor = 8, 5938452afb13SDamon Ding }, 5939452afb13SDamon Ding 5940452afb13SDamon Ding { 5941452afb13SDamon Ding .name = "Esmart1", 5942452afb13SDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART1, 5943452afb13SDamon Ding .type = ESMART_LAYER, 5944452afb13SDamon Ding .win_sel_port_offset = 10, 5945452afb13SDamon Ding .layer_sel_win_id = { 1, 1, 0xff, 0xff }, 5946452afb13SDamon Ding .reg_offset = 0x200, 5947452afb13SDamon Ding .axi_id = 0, 5948452afb13SDamon Ding .axi_yrgb_id = 0x04, 5949452afb13SDamon Ding .axi_uv_id = 0x05, 5950452afb13SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5951452afb13SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5952452afb13SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5953452afb13SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5954452afb13SDamon Ding .max_upscale_factor = 8, 5955452afb13SDamon Ding .max_downscale_factor = 8, 5956452afb13SDamon Ding }, 5957452afb13SDamon Ding 5958452afb13SDamon Ding { 5959452afb13SDamon Ding .name = "Esmart2", 5960452afb13SDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART2, 5961452afb13SDamon Ding .type = ESMART_LAYER, 5962452afb13SDamon Ding .win_sel_port_offset = 12, 5963452afb13SDamon Ding .layer_sel_win_id = { 2, 2, 0xff, 0xff }, 5964452afb13SDamon Ding .reg_offset = 0x400, 5965452afb13SDamon Ding .axi_id = 0, 5966452afb13SDamon Ding .axi_yrgb_id = 0x06, 5967452afb13SDamon Ding .axi_uv_id = 0x07, 5968452afb13SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5969452afb13SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5970452afb13SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5971452afb13SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5972452afb13SDamon Ding .max_upscale_factor = 8, 5973452afb13SDamon Ding .max_downscale_factor = 8, 5974452afb13SDamon Ding }, 5975452afb13SDamon Ding 5976452afb13SDamon Ding { 5977452afb13SDamon Ding .name = "Esmart3", 5978452afb13SDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART3, 5979452afb13SDamon Ding .type = ESMART_LAYER, 5980452afb13SDamon Ding .win_sel_port_offset = 14, 5981452afb13SDamon Ding .layer_sel_win_id = { 3, 3, 0xff, 0xff }, 5982452afb13SDamon Ding .reg_offset = 0x600, 5983452afb13SDamon Ding .axi_id = 0, 5984452afb13SDamon Ding .axi_yrgb_id = 0x08, 5985452afb13SDamon Ding .axi_uv_id = 0x0d, 5986452afb13SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5987452afb13SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5988452afb13SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5989452afb13SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5990452afb13SDamon Ding .max_upscale_factor = 8, 5991452afb13SDamon Ding .max_downscale_factor = 8, 5992452afb13SDamon Ding }, 5993452afb13SDamon Ding }; 5994452afb13SDamon Ding 5995452afb13SDamon Ding static struct vop2_vp_data rk3562_vp_data[2] = { 5996452afb13SDamon Ding { 5997452afb13SDamon Ding .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN, 5998452afb13SDamon Ding .max_output = {2048, 4096}, 5999452afb13SDamon Ding .win_dly = 8, 6000452afb13SDamon Ding .layer_mix_dly = 8, 6001452afb13SDamon Ding }, 6002452afb13SDamon Ding { 6003452afb13SDamon Ding .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN, 6004452afb13SDamon Ding .max_output = {2048, 1080}, 6005452afb13SDamon Ding .win_dly = 8, 6006452afb13SDamon Ding .layer_mix_dly = 8, 6007452afb13SDamon Ding }, 6008452afb13SDamon Ding }; 6009452afb13SDamon Ding 6010452afb13SDamon Ding const struct vop2_data rk3562_vop = { 6011452afb13SDamon Ding .version = VOP_VERSION_RK3562, 6012452afb13SDamon Ding .nr_vps = 2, 6013452afb13SDamon Ding .vp_data = rk3562_vp_data, 6014452afb13SDamon Ding .win_data = rk3562_win_data, 6015452afb13SDamon Ding .plane_mask = rk3562_vp_plane_mask[0], 6016452afb13SDamon Ding .plane_table = rk3562_plane_table, 6017452afb13SDamon Ding .vp_primary_plane_order = rk3562_vp_primary_plane_order, 6018452afb13SDamon Ding .nr_layers = 4, 6019452afb13SDamon Ding .nr_mixers = 3, 6020452afb13SDamon Ding .nr_gammas = 2, 6021452afb13SDamon Ding .esmart_lb_mode = VOP3_ESMART_2K_2K_2K_2K_MODE, 602272388c26SDamon Ding .dump_regs = rk3562_dump_regs, 602372388c26SDamon Ding .dump_regs_size = ARRAY_SIZE(rk3562_dump_regs), 602472388c26SDamon Ding }; 602572388c26SDamon Ding 602672388c26SDamon Ding static struct vop2_dump_regs rk3568_dump_regs[] = { 602772388c26SDamon Ding { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 }, 602872388c26SDamon Ding { RK3568_OVL_CTRL, "OVL", 0, 0, 0, 0 }, 602972388c26SDamon Ding { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 603072388c26SDamon Ding { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 603172388c26SDamon Ding { RK3568_VP2_DSP_CTRL, "VP2", RK3568_VP2_DSP_CTRL, 0x1, 31, 0 }, 603272388c26SDamon Ding { RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1 }, 603372388c26SDamon Ding { RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1", RK3568_CLUSTER1_WIN0_CTRL0, 0x1, 0, 1 }, 603472388c26SDamon Ding { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 }, 603572388c26SDamon Ding { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 }, 603672388c26SDamon Ding { RK3568_SMART0_CTRL0, "Smart0", RK3568_SMART0_REGION0_CTRL, 0x1, 0, 1 }, 603772388c26SDamon Ding { RK3568_SMART1_CTRL0, "Smart1", RK3568_SMART1_REGION0_CTRL, 0x1, 0, 1 }, 603872388c26SDamon Ding { RK3568_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0 }, 6039452afb13SDamon Ding }; 6040452afb13SDamon Ding 6041337d1c13SDamon Ding static u8 rk3568_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = { 6042337d1c13SDamon Ding ROCKCHIP_VOP2_SMART0, 6043337d1c13SDamon Ding ROCKCHIP_VOP2_SMART1, 6044337d1c13SDamon Ding ROCKCHIP_VOP2_ESMART0, 6045337d1c13SDamon Ding ROCKCHIP_VOP2_ESMART1, 6046337d1c13SDamon Ding }; 6047337d1c13SDamon Ding 6048ee008497SSandy Huang static struct vop2_plane_table rk356x_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 6049ee008497SSandy Huang {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 6050ee008497SSandy Huang {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER}, 6051ee008497SSandy Huang {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 6052ee008497SSandy Huang {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 6053ee008497SSandy Huang {ROCKCHIP_VOP2_SMART0, SMART_LAYER}, 6054ee008497SSandy Huang {ROCKCHIP_VOP2_SMART0, SMART_LAYER}, 6055ee008497SSandy Huang }; 6056ee008497SSandy Huang 6057b0989546SSandy Huang static struct vop2_vp_plane_mask rk356x_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 6058b0989546SSandy Huang { /* one display policy */ 6059b0989546SSandy Huang {/* main display */ 6060b0989546SSandy Huang .primary_plane_id = ROCKCHIP_VOP2_SMART0, 6061b0989546SSandy Huang .attached_layers_nr = 6, 6062b0989546SSandy Huang .attached_layers = { 6063b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0, 6064b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1 6065b0989546SSandy Huang }, 6066b0989546SSandy Huang }, 6067b0989546SSandy Huang {/* second display */}, 6068b0989546SSandy Huang {/* third display */}, 6069b0989546SSandy Huang {/* fourth display */}, 6070b0989546SSandy Huang }, 6071b0989546SSandy Huang 6072b0989546SSandy Huang { /* two display policy */ 6073b0989546SSandy Huang {/* main display */ 6074b0989546SSandy Huang .primary_plane_id = ROCKCHIP_VOP2_SMART0, 6075b0989546SSandy Huang .attached_layers_nr = 3, 6076b0989546SSandy Huang .attached_layers = { 6077b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0 6078b0989546SSandy Huang }, 6079b0989546SSandy Huang }, 6080b0989546SSandy Huang 6081b0989546SSandy Huang {/* second display */ 6082b0989546SSandy Huang .primary_plane_id = ROCKCHIP_VOP2_SMART1, 6083b0989546SSandy Huang .attached_layers_nr = 3, 6084b0989546SSandy Huang .attached_layers = { 6085b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1 6086b0989546SSandy Huang }, 6087b0989546SSandy Huang }, 6088b0989546SSandy Huang {/* third display */}, 6089b0989546SSandy Huang {/* fourth display */}, 6090b0989546SSandy Huang }, 6091b0989546SSandy Huang 6092b0989546SSandy Huang { /* three display policy */ 6093b0989546SSandy Huang {/* main display */ 6094b0989546SSandy Huang .primary_plane_id = ROCKCHIP_VOP2_SMART0, 6095b0989546SSandy Huang .attached_layers_nr = 3, 6096b0989546SSandy Huang .attached_layers = { 6097b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0 6098b0989546SSandy Huang }, 6099b0989546SSandy Huang }, 6100b0989546SSandy Huang 6101b0989546SSandy Huang {/* second display */ 6102b0989546SSandy Huang .primary_plane_id = ROCKCHIP_VOP2_SMART1, 6103b0989546SSandy Huang .attached_layers_nr = 2, 6104b0989546SSandy Huang .attached_layers = { 6105b0989546SSandy Huang ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_SMART1 6106b0989546SSandy Huang }, 6107b0989546SSandy Huang }, 6108b0989546SSandy Huang 6109b0989546SSandy Huang {/* third display */ 6110b0989546SSandy Huang .primary_plane_id = ROCKCHIP_VOP2_ESMART1, 6111b0989546SSandy Huang .attached_layers_nr = 1, 6112b0989546SSandy Huang .attached_layers = { ROCKCHIP_VOP2_ESMART1 }, 6113b0989546SSandy Huang }, 6114b0989546SSandy Huang 6115b0989546SSandy Huang {/* fourth display */}, 6116b0989546SSandy Huang }, 6117b0989546SSandy Huang 6118b0989546SSandy Huang {/* reserved for four display policy */}, 6119b0989546SSandy Huang }; 6120b0989546SSandy Huang 6121b0989546SSandy Huang static struct vop2_win_data rk3568_win_data[6] = { 6122b0989546SSandy Huang { 6123b0989546SSandy Huang .name = "Cluster0", 6124b0989546SSandy Huang .phys_id = ROCKCHIP_VOP2_CLUSTER0, 6125ecc31b6eSAndy Yan .type = CLUSTER_LAYER, 6126b0989546SSandy Huang .win_sel_port_offset = 0, 61275fa6e665SDamon Ding .layer_sel_win_id = { 0, 0, 0, 0xff }, 6128b0989546SSandy Huang .reg_offset = 0, 61295fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 61305fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 61315fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 61325fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 61334c765862SDamon Ding .max_upscale_factor = 4, 61344c765862SDamon Ding .max_downscale_factor = 4, 6135b0989546SSandy Huang }, 6136b0989546SSandy Huang 6137b0989546SSandy Huang { 6138b0989546SSandy Huang .name = "Cluster1", 6139b0989546SSandy Huang .phys_id = ROCKCHIP_VOP2_CLUSTER1, 6140ecc31b6eSAndy Yan .type = CLUSTER_LAYER, 6141b0989546SSandy Huang .win_sel_port_offset = 1, 61425fa6e665SDamon Ding .layer_sel_win_id = { 1, 1, 1, 0xff }, 6143b0989546SSandy Huang .reg_offset = 0x200, 61445fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 61455fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 61465fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 61475fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 61484c765862SDamon Ding .max_upscale_factor = 4, 61494c765862SDamon Ding .max_downscale_factor = 4, 61501c9572c7SDamon Ding .source_win_id = ROCKCHIP_VOP2_CLUSTER0, 61511c9572c7SDamon Ding .feature = WIN_FEATURE_MIRROR, 6152b0989546SSandy Huang }, 6153b0989546SSandy Huang 6154b0989546SSandy Huang { 6155b0989546SSandy Huang .name = "Esmart0", 6156b0989546SSandy Huang .phys_id = ROCKCHIP_VOP2_ESMART0, 6157ecc31b6eSAndy Yan .type = ESMART_LAYER, 6158b0989546SSandy Huang .win_sel_port_offset = 4, 61595fa6e665SDamon Ding .layer_sel_win_id = { 2, 2, 2, 0xff }, 6160b0989546SSandy Huang .reg_offset = 0, 61615fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 61625fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 61635fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 61645fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 61654c765862SDamon Ding .max_upscale_factor = 8, 61664c765862SDamon Ding .max_downscale_factor = 8, 6167b0989546SSandy Huang }, 6168b0989546SSandy Huang 6169b0989546SSandy Huang { 6170b0989546SSandy Huang .name = "Esmart1", 6171b0989546SSandy Huang .phys_id = ROCKCHIP_VOP2_ESMART1, 6172ecc31b6eSAndy Yan .type = ESMART_LAYER, 6173b0989546SSandy Huang .win_sel_port_offset = 5, 61745fa6e665SDamon Ding .layer_sel_win_id = { 6, 6, 6, 0xff }, 6175b0989546SSandy Huang .reg_offset = 0x200, 61765fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 61775fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 61785fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 61795fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 61804c765862SDamon Ding .max_upscale_factor = 8, 61814c765862SDamon Ding .max_downscale_factor = 8, 61821c9572c7SDamon Ding .source_win_id = ROCKCHIP_VOP2_ESMART0, 61831c9572c7SDamon Ding .feature = WIN_FEATURE_MIRROR, 6184b0989546SSandy Huang }, 6185b0989546SSandy Huang 6186b0989546SSandy Huang { 6187b0989546SSandy Huang .name = "Smart0", 6188b0989546SSandy Huang .phys_id = ROCKCHIP_VOP2_SMART0, 6189ecc31b6eSAndy Yan .type = SMART_LAYER, 6190b0989546SSandy Huang .win_sel_port_offset = 6, 61915fa6e665SDamon Ding .layer_sel_win_id = { 3, 3, 3, 0xff }, 6192b0989546SSandy Huang .reg_offset = 0x400, 61935fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 61945fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 61955fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 61965fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 61974c765862SDamon Ding .max_upscale_factor = 8, 61984c765862SDamon Ding .max_downscale_factor = 8, 6199b0989546SSandy Huang }, 6200b0989546SSandy Huang 6201b0989546SSandy Huang { 6202b0989546SSandy Huang .name = "Smart1", 6203b0989546SSandy Huang .phys_id = ROCKCHIP_VOP2_SMART1, 6204ecc31b6eSAndy Yan .type = SMART_LAYER, 6205b0989546SSandy Huang .win_sel_port_offset = 7, 62065fa6e665SDamon Ding .layer_sel_win_id = { 7, 7, 7, 0xff }, 6207b0989546SSandy Huang .reg_offset = 0x600, 62085fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 62095fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 62105fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 62115fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 62124c765862SDamon Ding .max_upscale_factor = 8, 62134c765862SDamon Ding .max_downscale_factor = 8, 62141c9572c7SDamon Ding .source_win_id = ROCKCHIP_VOP2_SMART0, 62151c9572c7SDamon Ding .feature = WIN_FEATURE_MIRROR, 6216b0989546SSandy Huang }, 6217b0989546SSandy Huang }; 6218b0989546SSandy Huang 621963cb669fSSandy Huang static struct vop2_vp_data rk3568_vp_data[3] = { 622063cb669fSSandy Huang { 622163cb669fSSandy Huang .feature = VOP_FEATURE_OUTPUT_10BIT, 622263cb669fSSandy Huang .pre_scan_max_dly = 42, 622363cb669fSSandy Huang .max_output = {4096, 2304}, 6224d0408543SAndy Yan }, 622563cb669fSSandy Huang { 622663cb669fSSandy Huang .feature = 0, 622763cb669fSSandy Huang .pre_scan_max_dly = 40, 622863cb669fSSandy Huang .max_output = {2048, 1536}, 622963cb669fSSandy Huang }, 623063cb669fSSandy Huang { 623163cb669fSSandy Huang .feature = 0, 623263cb669fSSandy Huang .pre_scan_max_dly = 40, 623363cb669fSSandy Huang .max_output = {1920, 1080}, 623463cb669fSSandy Huang }, 623563cb669fSSandy Huang }; 6236d0408543SAndy Yan 623763cb669fSSandy Huang const struct vop2_data rk3568_vop = { 6238ecc31b6eSAndy Yan .version = VOP_VERSION_RK3568, 623963cb669fSSandy Huang .nr_vps = 3, 624063cb669fSSandy Huang .vp_data = rk3568_vp_data, 6241b0989546SSandy Huang .win_data = rk3568_win_data, 6242b0989546SSandy Huang .plane_mask = rk356x_vp_plane_mask[0], 6243ee008497SSandy Huang .plane_table = rk356x_plane_table, 6244337d1c13SDamon Ding .vp_primary_plane_order = rk3568_vp_primary_plane_order, 6245d0408543SAndy Yan .nr_layers = 6, 624663cb669fSSandy Huang .nr_mixers = 5, 62471147facaSSandy Huang .nr_gammas = 1, 624872388c26SDamon Ding .dump_regs = rk3568_dump_regs, 624972388c26SDamon Ding .dump_regs_size = ARRAY_SIZE(rk3568_dump_regs), 6250d0408543SAndy Yan }; 6251d0408543SAndy Yan 6252a552a69cSDamon Ding static u8 rk3576_vp_default_primary_plane[VOP2_VP_MAX] = { 6253a552a69cSDamon Ding ROCKCHIP_VOP2_ESMART0, 6254a552a69cSDamon Ding ROCKCHIP_VOP2_ESMART1, 6255a552a69cSDamon Ding ROCKCHIP_VOP2_ESMART2, 6256a552a69cSDamon Ding }; 6257a552a69cSDamon Ding 6258a552a69cSDamon Ding static struct vop2_plane_table rk3576_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 6259a552a69cSDamon Ding {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 6260a552a69cSDamon Ding {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 6261a552a69cSDamon Ding {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER}, 6262a552a69cSDamon Ding {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER}, 6263a552a69cSDamon Ding {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 6264a552a69cSDamon Ding {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER}, 6265a552a69cSDamon Ding }; 6266a552a69cSDamon Ding 6267a552a69cSDamon Ding static struct vop2_dump_regs rk3576_dump_regs[] = { 6268a552a69cSDamon Ding { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0, 0x200 }, 6269a552a69cSDamon Ding { RK3528_OVL_SYS, "OVL_SYS", 0, 0, 0, 0, 0x50 }, 6270a552a69cSDamon Ding { RK3528_OVL_PORT0_CTRL, "OVL_VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0, 0x80 }, 6271a552a69cSDamon Ding { RK3528_OVL_PORT1_CTRL, "OVL_VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0, 0x80 }, 6272a552a69cSDamon Ding { RK3576_OVL_PORT2_CTRL, "OVL_VP2", RK3568_VP2_DSP_CTRL, 0x1, 31, 0, 0x80 }, 6273a552a69cSDamon Ding { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0, 0x100 }, 6274a552a69cSDamon Ding { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP0_DSP_CTRL, 0x1, 31, 0, 0x100 }, 6275a552a69cSDamon Ding { RK3568_VP2_DSP_CTRL, "VP2", RK3568_VP0_DSP_CTRL, 0x1, 31, 0, 0x100 }, 6276a552a69cSDamon Ding { RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1, 0x200 }, 6277a552a69cSDamon Ding { RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1", RK3568_CLUSTER1_WIN0_CTRL0, 0x1, 0, 1, 0x200 }, 6278a552a69cSDamon Ding { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1, 0x100 }, 6279a552a69cSDamon Ding { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1, 0x100 }, 6280a552a69cSDamon Ding { RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_CTRL0, 0x1, 0, 1, 0x100 }, 6281a552a69cSDamon Ding { RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_CTRL0, 0x1, 0, 1, 0x100 }, 6282a552a69cSDamon Ding { RK3528_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0, 0x100 }, 6283a552a69cSDamon Ding }; 6284a552a69cSDamon Ding 6285a552a69cSDamon Ding /* 6286a552a69cSDamon Ding * RK3576 VOP with 2 Cluster win and 4 Esmart win. 6287a552a69cSDamon Ding * Every Esmart win support 4 multi-region. 6288a552a69cSDamon Ding * VP0 can use Cluster0/1 and Esmart0/2 6289a552a69cSDamon Ding * VP1 can use Cluster0/1 and Esmart1/3 6290a552a69cSDamon Ding * VP2 can use Esmart0/1/2/3 6291a552a69cSDamon Ding * 6292a552a69cSDamon Ding * Scale filter mode: 6293a552a69cSDamon Ding * 6294a552a69cSDamon Ding * * Cluster: 6295a552a69cSDamon Ding * * Support prescale down: 6296a552a69cSDamon Ding * * H/V: gt2/avg2 or gt4/avg4 6297a552a69cSDamon Ding * * After prescale down: 6298a552a69cSDamon Ding * * nearest-neighbor/bilinear/multi-phase filter for scale up 6299a552a69cSDamon Ding * * nearest-neighbor/bilinear/multi-phase filter for scale down 6300a552a69cSDamon Ding * 6301a552a69cSDamon Ding * * Esmart: 6302a552a69cSDamon Ding * * Support prescale down: 6303a552a69cSDamon Ding * * H: gt2/avg2 or gt4/avg4 6304a552a69cSDamon Ding * * V: gt2 or gt4 6305a552a69cSDamon Ding * * After prescale down: 6306a552a69cSDamon Ding * * nearest-neighbor/bilinear/bicubic for scale up 6307a552a69cSDamon Ding * * nearest-neighbor/bilinear for scale down 6308a552a69cSDamon Ding */ 6309a552a69cSDamon Ding static struct vop2_win_data rk3576_win_data[6] = { 6310a552a69cSDamon Ding { 6311a552a69cSDamon Ding .name = "Esmart0", 6312a552a69cSDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART0, 6313a552a69cSDamon Ding .type = ESMART_LAYER, 6314a552a69cSDamon Ding .layer_sel_win_id = { 2, 0xff, 0, 0xff }, 6315a552a69cSDamon Ding .reg_offset = 0x0, 6316a552a69cSDamon Ding .supported_rotations = DRM_MODE_REFLECT_Y, 6317a552a69cSDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 6318a552a69cSDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 6319a552a69cSDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 6320a552a69cSDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 6321a552a69cSDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */ 6322a552a69cSDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,/* gt only */ 6323a552a69cSDamon Ding .pd_id = VOP2_PD_ESMART, 6324a552a69cSDamon Ding .axi_id = 0, 6325a552a69cSDamon Ding .axi_yrgb_id = 0x0a, 6326a552a69cSDamon Ding .axi_uv_id = 0x0b, 6327a552a69cSDamon Ding .possible_crtcs = 0x5,/* vp0 or vp2 */ 6328a552a69cSDamon Ding .max_upscale_factor = 8, 6329a552a69cSDamon Ding .max_downscale_factor = 8, 6330a552a69cSDamon Ding .feature = WIN_FEATURE_MULTI_AREA | WIN_FEATURE_Y2R_13BIT_DEPTH, 6331a552a69cSDamon Ding }, 6332a552a69cSDamon Ding { 6333a552a69cSDamon Ding .name = "Esmart1", 6334a552a69cSDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART1, 6335a552a69cSDamon Ding .type = ESMART_LAYER, 6336a552a69cSDamon Ding .layer_sel_win_id = { 0xff, 2, 1, 0xff }, 6337a552a69cSDamon Ding .reg_offset = 0x200, 6338a552a69cSDamon Ding .supported_rotations = DRM_MODE_REFLECT_Y, 6339a552a69cSDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 6340a552a69cSDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 6341a552a69cSDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 6342a552a69cSDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 6343a552a69cSDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */ 6344a552a69cSDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,/* gt only */ 6345a552a69cSDamon Ding .pd_id = VOP2_PD_ESMART, 6346a552a69cSDamon Ding .axi_id = 0, 6347a552a69cSDamon Ding .axi_yrgb_id = 0x0c, 6348a552a69cSDamon Ding .axi_uv_id = 0x0d, 6349a552a69cSDamon Ding .possible_crtcs = 0x6,/* vp1 or vp2 */ 6350a552a69cSDamon Ding .max_upscale_factor = 8, 6351a552a69cSDamon Ding .max_downscale_factor = 8, 6352a552a69cSDamon Ding .feature = WIN_FEATURE_MULTI_AREA, 6353a552a69cSDamon Ding }, 6354a552a69cSDamon Ding 6355a552a69cSDamon Ding { 6356a552a69cSDamon Ding .name = "Esmart2", 6357a552a69cSDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART2, 6358a552a69cSDamon Ding .type = ESMART_LAYER, 6359a552a69cSDamon Ding .layer_sel_win_id = { 3, 0xff, 2, 0xff }, 6360a552a69cSDamon Ding .reg_offset = 0x400, 6361a552a69cSDamon Ding .supported_rotations = DRM_MODE_REFLECT_Y, 6362a552a69cSDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 6363a552a69cSDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 6364a552a69cSDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 6365a552a69cSDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 6366a552a69cSDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */ 6367a552a69cSDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,/* gt only */ 6368a552a69cSDamon Ding .pd_id = VOP2_PD_ESMART, 6369a552a69cSDamon Ding .axi_id = 1, 6370a552a69cSDamon Ding .axi_yrgb_id = 0x0a, 6371a552a69cSDamon Ding .axi_uv_id = 0x0b, 6372a552a69cSDamon Ding .possible_crtcs = 0x5,/* vp0 or vp2 */ 6373a552a69cSDamon Ding .max_upscale_factor = 8, 6374a552a69cSDamon Ding .max_downscale_factor = 8, 6375a552a69cSDamon Ding .feature = WIN_FEATURE_MULTI_AREA, 6376a552a69cSDamon Ding }, 6377a552a69cSDamon Ding 6378a552a69cSDamon Ding { 6379a552a69cSDamon Ding .name = "Esmart3", 6380a552a69cSDamon Ding .phys_id = ROCKCHIP_VOP2_ESMART3, 6381a552a69cSDamon Ding .type = ESMART_LAYER, 6382a552a69cSDamon Ding .layer_sel_win_id = { 0xff, 3, 3, 0xff }, 6383a552a69cSDamon Ding .reg_offset = 0x600, 6384a552a69cSDamon Ding .supported_rotations = DRM_MODE_REFLECT_Y, 6385a552a69cSDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 6386a552a69cSDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 6387a552a69cSDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 6388a552a69cSDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 6389a552a69cSDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */ 6390a552a69cSDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT,/* gt only */ 6391a552a69cSDamon Ding .pd_id = VOP2_PD_ESMART, 6392a552a69cSDamon Ding .axi_id = 1, 6393a552a69cSDamon Ding .axi_yrgb_id = 0x0c, 6394a552a69cSDamon Ding .axi_uv_id = 0x0d, 6395a552a69cSDamon Ding .possible_crtcs = 0x6,/* vp1 or vp2 */ 6396a552a69cSDamon Ding .max_upscale_factor = 8, 6397a552a69cSDamon Ding .max_downscale_factor = 8, 6398a552a69cSDamon Ding .feature = WIN_FEATURE_MULTI_AREA, 6399a552a69cSDamon Ding }, 6400a552a69cSDamon Ding 6401a552a69cSDamon Ding { 6402a552a69cSDamon Ding .name = "Cluster0", 6403a552a69cSDamon Ding .phys_id = ROCKCHIP_VOP2_CLUSTER0, 6404a552a69cSDamon Ding .type = CLUSTER_LAYER, 6405a552a69cSDamon Ding .layer_sel_win_id = { 0, 0, 0xff, 0xff }, 6406a552a69cSDamon Ding .reg_offset = 0x0, 6407a552a69cSDamon Ding .supported_rotations = DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 6408a552a69cSDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIL, 6409a552a69cSDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 6410a552a69cSDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 6411a552a69cSDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 6412a552a69cSDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */ 6413a552a69cSDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */ 6414a552a69cSDamon Ding .pd_id = VOP2_PD_CLUSTER, 6415a552a69cSDamon Ding .axi_yrgb_id = 0x02, 6416a552a69cSDamon Ding .axi_uv_id = 0x03, 6417a552a69cSDamon Ding .possible_crtcs = 0x3,/* vp0 or vp1 */ 6418a552a69cSDamon Ding .max_upscale_factor = 8, 6419a552a69cSDamon Ding .max_downscale_factor = 8, 6420a552a69cSDamon Ding .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER_MAIN | 6421a552a69cSDamon Ding WIN_FEATURE_Y2R_13BIT_DEPTH | WIN_FEATURE_DCI, 6422a552a69cSDamon Ding }, 6423a552a69cSDamon Ding 6424a552a69cSDamon Ding { 6425a552a69cSDamon Ding .name = "Cluster1", 6426a552a69cSDamon Ding .phys_id = ROCKCHIP_VOP2_CLUSTER1, 6427a552a69cSDamon Ding .type = CLUSTER_LAYER, 6428a552a69cSDamon Ding .layer_sel_win_id = { 1, 1, 0xff, 0xff }, 6429a552a69cSDamon Ding .reg_offset = 0x200, 6430a552a69cSDamon Ding .supported_rotations = DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 6431a552a69cSDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIL, 6432a552a69cSDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 6433a552a69cSDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 6434a552a69cSDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 6435a552a69cSDamon Ding .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */ 6436a552a69cSDamon Ding .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG,/* gt or avg */ 6437a552a69cSDamon Ding .pd_id = VOP2_PD_CLUSTER, 6438a552a69cSDamon Ding .axi_yrgb_id = 0x06, 6439a552a69cSDamon Ding .axi_uv_id = 0x07, 6440a552a69cSDamon Ding .possible_crtcs = 0x3,/* vp0 or vp1 */ 6441a552a69cSDamon Ding .max_upscale_factor = 8, 6442a552a69cSDamon Ding .max_downscale_factor = 8, 6443a552a69cSDamon Ding .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER_MAIN | 6444a552a69cSDamon Ding WIN_FEATURE_Y2R_13BIT_DEPTH, 6445a552a69cSDamon Ding }, 6446a552a69cSDamon Ding }; 6447a552a69cSDamon Ding 6448a552a69cSDamon Ding static struct vop2_vp_data rk3576_vp_data[3] = { 6449a552a69cSDamon Ding { 6450a552a69cSDamon Ding .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN | VOP_FEATURE_VIVID_HDR | 6451a552a69cSDamon Ding VOP_FEATURE_POST_ACM | VOP_FEATURE_POST_CSC | VOP_FEATURE_OUTPUT_10BIT | 6452a552a69cSDamon Ding VOP_FEATURE_POST_FRC_V2 | VOP_FEATURE_POST_SHARP, 6453a552a69cSDamon Ding .max_output = { 4096, 4096 }, 6454a552a69cSDamon Ding .hdrvivid_dly = 21, 6455a552a69cSDamon Ding .sdr2hdr_dly = 21, 6456a552a69cSDamon Ding .layer_mix_dly = 8, 6457a552a69cSDamon Ding .hdr_mix_dly = 2, 6458a552a69cSDamon Ding .win_dly = 10, 6459a552a69cSDamon Ding .pixel_rate = 2, 6460a552a69cSDamon Ding }, 6461a552a69cSDamon Ding { 6462a552a69cSDamon Ding .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN | 6463a552a69cSDamon Ding VOP_FEATURE_OUTPUT_10BIT | VOP_FEATURE_POST_FRC_V2, 6464a552a69cSDamon Ding .max_output = { 2560, 2560 }, 6465a552a69cSDamon Ding .hdrvivid_dly = 0, 6466a552a69cSDamon Ding .sdr2hdr_dly = 0, 6467a552a69cSDamon Ding .layer_mix_dly = 6, 6468a552a69cSDamon Ding .hdr_mix_dly = 0, 6469a552a69cSDamon Ding .win_dly = 10, 6470a552a69cSDamon Ding .pixel_rate = 1, 6471a552a69cSDamon Ding }, 6472a552a69cSDamon Ding { 6473a552a69cSDamon Ding .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN, 6474a552a69cSDamon Ding .max_output = { 1920, 1920 }, 6475a552a69cSDamon Ding .hdrvivid_dly = 0, 6476a552a69cSDamon Ding .sdr2hdr_dly = 0, 6477a552a69cSDamon Ding .layer_mix_dly = 6, 6478a552a69cSDamon Ding .hdr_mix_dly = 0, 6479a552a69cSDamon Ding .win_dly = 10, 6480a552a69cSDamon Ding .pixel_rate = 1, 6481a552a69cSDamon Ding }, 6482a552a69cSDamon Ding }; 6483a552a69cSDamon Ding 6484a552a69cSDamon Ding static struct vop2_power_domain_data rk3576_vop_pd_data[] = { 6485a552a69cSDamon Ding { 6486a552a69cSDamon Ding .id = VOP2_PD_CLUSTER, 6487a552a69cSDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER0) | BIT(ROCKCHIP_VOP2_CLUSTER1), 6488a552a69cSDamon Ding }, 6489a552a69cSDamon Ding { 6490a552a69cSDamon Ding .id = VOP2_PD_ESMART, 6491a552a69cSDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_ESMART0) | BIT(ROCKCHIP_VOP2_ESMART1) | 6492a552a69cSDamon Ding BIT(ROCKCHIP_VOP2_ESMART2) | BIT(ROCKCHIP_VOP2_ESMART3), 6493a552a69cSDamon Ding }, 6494a552a69cSDamon Ding }; 6495a552a69cSDamon Ding 6496a552a69cSDamon Ding static const struct vop2_esmart_lb_map rk3576_esmart_lb_mode_map[] = { 6497a552a69cSDamon Ding {VOP3_ESMART_4K_4K_4K_MODE, 2}, 6498a552a69cSDamon Ding {VOP3_ESMART_4K_4K_2K_2K_MODE, 3} 6499a552a69cSDamon Ding }; 6500a552a69cSDamon Ding 6501a552a69cSDamon Ding const struct vop2_data rk3576_vop = { 6502a552a69cSDamon Ding .version = VOP_VERSION_RK3576, 6503a552a69cSDamon Ding .nr_vps = 3, 6504a552a69cSDamon Ding .nr_mixers = 4, 6505a552a69cSDamon Ding .nr_layers = 6, 6506a552a69cSDamon Ding .nr_gammas = 3, 6507a552a69cSDamon Ding .esmart_lb_mode = VOP3_ESMART_4K_4K_2K_2K_MODE, 6508a552a69cSDamon Ding .esmart_lb_mode_num = ARRAY_SIZE(rk3576_esmart_lb_mode_map), 6509a552a69cSDamon Ding .esmart_lb_mode_map = rk3576_esmart_lb_mode_map, 6510a552a69cSDamon Ding .vp_data = rk3576_vp_data, 6511a552a69cSDamon Ding .win_data = rk3576_win_data, 6512a552a69cSDamon Ding .plane_table = rk3576_plane_table, 6513a552a69cSDamon Ding .pd = rk3576_vop_pd_data, 6514a552a69cSDamon Ding .vp_default_primary_plane = rk3576_vp_default_primary_plane, 6515a552a69cSDamon Ding .nr_pd = ARRAY_SIZE(rk3576_vop_pd_data), 6516a552a69cSDamon Ding .dump_regs = rk3576_dump_regs, 6517a552a69cSDamon Ding .dump_regs_size = ARRAY_SIZE(rk3576_dump_regs), 6518a552a69cSDamon Ding }; 6519a552a69cSDamon Ding 6520337d1c13SDamon Ding static u8 rk3588_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = { 6521337d1c13SDamon Ding ROCKCHIP_VOP2_ESMART0, 6522337d1c13SDamon Ding ROCKCHIP_VOP2_ESMART1, 6523337d1c13SDamon Ding ROCKCHIP_VOP2_ESMART2, 6524337d1c13SDamon Ding ROCKCHIP_VOP2_ESMART3, 6525337d1c13SDamon Ding ROCKCHIP_VOP2_CLUSTER0, 6526337d1c13SDamon Ding ROCKCHIP_VOP2_CLUSTER1, 6527337d1c13SDamon Ding ROCKCHIP_VOP2_CLUSTER2, 6528337d1c13SDamon Ding ROCKCHIP_VOP2_CLUSTER3, 6529337d1c13SDamon Ding }; 6530337d1c13SDamon Ding 6531ecc31b6eSAndy Yan static struct vop2_plane_table rk3588_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 6532ecc31b6eSAndy Yan {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 6533ecc31b6eSAndy Yan {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER}, 6534ecc31b6eSAndy Yan {ROCKCHIP_VOP2_CLUSTER2, CLUSTER_LAYER}, 6535ecc31b6eSAndy Yan {ROCKCHIP_VOP2_CLUSTER3, CLUSTER_LAYER}, 6536ecc31b6eSAndy Yan {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 6537ecc31b6eSAndy Yan {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 6538ecc31b6eSAndy Yan {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER}, 6539ecc31b6eSAndy Yan {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER}, 6540ecc31b6eSAndy Yan }; 6541ecc31b6eSAndy Yan 654272388c26SDamon Ding static struct vop2_dump_regs rk3588_dump_regs[] = { 654372388c26SDamon Ding { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 }, 654472388c26SDamon Ding { RK3568_OVL_CTRL, "OVL", 0, 0, 0, 0 }, 654572388c26SDamon Ding { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 }, 654672388c26SDamon Ding { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 654772388c26SDamon Ding { RK3568_VP2_DSP_CTRL, "VP2", RK3568_VP2_DSP_CTRL, 0x1, 31, 0 }, 654872388c26SDamon Ding { RK3588_VP3_DSP_CTRL, "VP3", RK3588_VP3_DSP_CTRL, 0x1, 31, 0 }, 654972388c26SDamon Ding { RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1 }, 655072388c26SDamon Ding { RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1", RK3568_CLUSTER1_WIN0_CTRL0, 0x1, 0, 1 }, 655172388c26SDamon Ding { RK3588_CLUSTER2_WIN0_CTRL0, "Cluster2", RK3588_CLUSTER2_WIN0_CTRL0, 0x1, 0, 1 }, 655272388c26SDamon Ding { RK3588_CLUSTER3_WIN0_CTRL0, "Cluster3", RK3588_CLUSTER3_WIN0_CTRL0, 0x1, 0, 1 }, 655372388c26SDamon Ding { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 }, 655472388c26SDamon Ding { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 }, 655572388c26SDamon Ding { RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_REGION0_CTRL, 0x1, 0, 1 }, 655672388c26SDamon Ding { RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_REGION0_CTRL, 0x1, 0, 1 }, 655772388c26SDamon Ding { RK3568_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0 }, 655872388c26SDamon Ding }; 655972388c26SDamon Ding 6560ecc31b6eSAndy Yan static struct vop2_vp_plane_mask rk3588_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 6561ecc31b6eSAndy Yan { /* one display policy */ 6562ecc31b6eSAndy Yan {/* main display */ 6563608c9f66SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 6564ecc31b6eSAndy Yan .attached_layers_nr = 8, 6565ecc31b6eSAndy Yan .attached_layers = { 6566ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART2, 6567ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART3, 6568ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3 6569ecc31b6eSAndy Yan }, 6570ecc31b6eSAndy Yan }, 6571ecc31b6eSAndy Yan {/* second display */}, 6572ecc31b6eSAndy Yan {/* third display */}, 6573ecc31b6eSAndy Yan {/* fourth display */}, 6574ecc31b6eSAndy Yan }, 6575ecc31b6eSAndy Yan 6576ecc31b6eSAndy Yan { /* two display policy */ 6577ecc31b6eSAndy Yan {/* main display */ 6578608c9f66SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 6579ecc31b6eSAndy Yan .attached_layers_nr = 4, 6580ecc31b6eSAndy Yan .attached_layers = { 6581ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, 6582ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 6583ecc31b6eSAndy Yan }, 6584ecc31b6eSAndy Yan }, 6585ecc31b6eSAndy Yan 6586ecc31b6eSAndy Yan {/* second display */ 6587608c9f66SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART2, 6588ecc31b6eSAndy Yan .attached_layers_nr = 4, 6589ecc31b6eSAndy Yan .attached_layers = { 6590ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2, 6591ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 6592ecc31b6eSAndy Yan }, 6593ecc31b6eSAndy Yan }, 6594ecc31b6eSAndy Yan {/* third display */}, 6595ecc31b6eSAndy Yan {/* fourth display */}, 6596ecc31b6eSAndy Yan }, 6597ecc31b6eSAndy Yan 6598ecc31b6eSAndy Yan { /* three display policy */ 6599ecc31b6eSAndy Yan {/* main display */ 6600608c9f66SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 6601ecc31b6eSAndy Yan .attached_layers_nr = 3, 6602ecc31b6eSAndy Yan .attached_layers = { 6603ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART0 6604ecc31b6eSAndy Yan }, 6605ecc31b6eSAndy Yan }, 6606ecc31b6eSAndy Yan 6607ecc31b6eSAndy Yan {/* second display */ 6608608c9f66SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART1, 6609ecc31b6eSAndy Yan .attached_layers_nr = 3, 6610ecc31b6eSAndy Yan .attached_layers = { 6611ecc31b6eSAndy Yan ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART1 6612ecc31b6eSAndy Yan }, 6613ecc31b6eSAndy Yan }, 6614ecc31b6eSAndy Yan 6615ecc31b6eSAndy Yan {/* third display */ 6616ecc31b6eSAndy Yan .primary_plane_id = ROCKCHIP_VOP2_ESMART2, 6617ecc31b6eSAndy Yan .attached_layers_nr = 2, 6618ecc31b6eSAndy Yan .attached_layers = { ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 }, 6619ecc31b6eSAndy Yan }, 6620ecc31b6eSAndy Yan 6621ecc31b6eSAndy Yan {/* fourth display */}, 6622ecc31b6eSAndy Yan }, 6623ecc31b6eSAndy Yan 6624ecc31b6eSAndy Yan { /* four display policy */ 6625ecc31b6eSAndy Yan {/* main display */ 6626608c9f66SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 6627ecc31b6eSAndy Yan .attached_layers_nr = 2, 6628ecc31b6eSAndy Yan .attached_layers = { ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0 }, 6629ecc31b6eSAndy Yan }, 6630ecc31b6eSAndy Yan 6631ecc31b6eSAndy Yan {/* second display */ 6632608c9f66SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART1, 6633ecc31b6eSAndy Yan .attached_layers_nr = 2, 6634ecc31b6eSAndy Yan .attached_layers = { ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 }, 6635ecc31b6eSAndy Yan }, 6636ecc31b6eSAndy Yan 6637ecc31b6eSAndy Yan {/* third display */ 6638608c9f66SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART2, 6639ecc31b6eSAndy Yan .attached_layers_nr = 2, 6640ecc31b6eSAndy Yan .attached_layers = { ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2 }, 6641ecc31b6eSAndy Yan }, 6642ecc31b6eSAndy Yan 6643ecc31b6eSAndy Yan {/* fourth display */ 6644608c9f66SDamon Ding .primary_plane_id = ROCKCHIP_VOP2_ESMART3, 6645ecc31b6eSAndy Yan .attached_layers_nr = 2, 6646ecc31b6eSAndy Yan .attached_layers = { ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 }, 6647ecc31b6eSAndy Yan }, 6648ecc31b6eSAndy Yan }, 6649ecc31b6eSAndy Yan 6650ecc31b6eSAndy Yan }; 6651ecc31b6eSAndy Yan 6652ecc31b6eSAndy Yan static struct vop2_win_data rk3588_win_data[8] = { 6653ecc31b6eSAndy Yan { 6654ecc31b6eSAndy Yan .name = "Cluster0", 6655ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_CLUSTER0, 6656ee01dbb2SDamon Ding .splice_win_id = ROCKCHIP_VOP2_CLUSTER1, 6657ecc31b6eSAndy Yan .type = CLUSTER_LAYER, 6658ecc31b6eSAndy Yan .win_sel_port_offset = 0, 66595fa6e665SDamon Ding .layer_sel_win_id = { 0, 0, 0, 0 }, 6660ecc31b6eSAndy Yan .reg_offset = 0, 6661a33b790fSDamon Ding .axi_id = 0, 6662a33b790fSDamon Ding .axi_yrgb_id = 2, 6663a33b790fSDamon Ding .axi_uv_id = 3, 6664b6ba80b4SDamon Ding .pd_id = VOP2_PD_CLUSTER0, 66655fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 66665fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 66675fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 66685fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 66694c765862SDamon Ding .max_upscale_factor = 4, 66704c765862SDamon Ding .max_downscale_factor = 4, 6671ecc31b6eSAndy Yan }, 6672ecc31b6eSAndy Yan 6673ecc31b6eSAndy Yan { 6674ecc31b6eSAndy Yan .name = "Cluster1", 6675ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_CLUSTER1, 6676ecc31b6eSAndy Yan .type = CLUSTER_LAYER, 6677ecc31b6eSAndy Yan .win_sel_port_offset = 1, 66785fa6e665SDamon Ding .layer_sel_win_id = { 1, 1, 1, 1 }, 6679ecc31b6eSAndy Yan .reg_offset = 0x200, 6680a33b790fSDamon Ding .axi_id = 0, 6681a33b790fSDamon Ding .axi_yrgb_id = 6, 6682a33b790fSDamon Ding .axi_uv_id = 7, 6683b6ba80b4SDamon Ding .pd_id = VOP2_PD_CLUSTER1, 66845fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 66855fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 66865fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 66875fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 66884c765862SDamon Ding .max_upscale_factor = 4, 66894c765862SDamon Ding .max_downscale_factor = 4, 6690ecc31b6eSAndy Yan }, 6691ecc31b6eSAndy Yan 6692ecc31b6eSAndy Yan { 6693ecc31b6eSAndy Yan .name = "Cluster2", 6694ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_CLUSTER2, 6695ee01dbb2SDamon Ding .splice_win_id = ROCKCHIP_VOP2_CLUSTER3, 6696ecc31b6eSAndy Yan .type = CLUSTER_LAYER, 6697ecc31b6eSAndy Yan .win_sel_port_offset = 2, 66985fa6e665SDamon Ding .layer_sel_win_id = { 4, 4, 4, 4 }, 6699ecc31b6eSAndy Yan .reg_offset = 0x400, 6700a33b790fSDamon Ding .axi_id = 1, 6701a33b790fSDamon Ding .axi_yrgb_id = 2, 6702a33b790fSDamon Ding .axi_uv_id = 3, 6703b6ba80b4SDamon Ding .pd_id = VOP2_PD_CLUSTER2, 67045fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 67055fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 67065fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 67075fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 67084c765862SDamon Ding .max_upscale_factor = 4, 67094c765862SDamon Ding .max_downscale_factor = 4, 6710ecc31b6eSAndy Yan }, 6711ecc31b6eSAndy Yan 6712ecc31b6eSAndy Yan { 6713ecc31b6eSAndy Yan .name = "Cluster3", 6714ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_CLUSTER3, 6715ecc31b6eSAndy Yan .type = CLUSTER_LAYER, 6716ecc31b6eSAndy Yan .win_sel_port_offset = 3, 67175fa6e665SDamon Ding .layer_sel_win_id = { 5, 5, 5, 5 }, 6718ecc31b6eSAndy Yan .reg_offset = 0x600, 6719a33b790fSDamon Ding .axi_id = 1, 6720a33b790fSDamon Ding .axi_yrgb_id = 6, 6721a33b790fSDamon Ding .axi_uv_id = 7, 6722b6ba80b4SDamon Ding .pd_id = VOP2_PD_CLUSTER3, 67235fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 67245fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 67255fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 67265fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 67274c765862SDamon Ding .max_upscale_factor = 4, 67284c765862SDamon Ding .max_downscale_factor = 4, 6729ecc31b6eSAndy Yan }, 6730ecc31b6eSAndy Yan 6731ecc31b6eSAndy Yan { 6732ecc31b6eSAndy Yan .name = "Esmart0", 6733ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_ESMART0, 6734ee01dbb2SDamon Ding .splice_win_id = ROCKCHIP_VOP2_ESMART1, 6735ecc31b6eSAndy Yan .type = ESMART_LAYER, 6736ecc31b6eSAndy Yan .win_sel_port_offset = 4, 67375fa6e665SDamon Ding .layer_sel_win_id = { 2, 2, 2, 2 }, 6738ecc31b6eSAndy Yan .reg_offset = 0, 6739a33b790fSDamon Ding .axi_id = 0, 6740a33b790fSDamon Ding .axi_yrgb_id = 0x0a, 6741a33b790fSDamon Ding .axi_uv_id = 0x0b, 67425fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 67435fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 67445fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 67455fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 67464c765862SDamon Ding .max_upscale_factor = 8, 67474c765862SDamon Ding .max_downscale_factor = 8, 6748ecc31b6eSAndy Yan }, 6749ecc31b6eSAndy Yan 6750ecc31b6eSAndy Yan { 6751ecc31b6eSAndy Yan .name = "Esmart1", 6752ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_ESMART1, 6753ecc31b6eSAndy Yan .type = ESMART_LAYER, 6754ecc31b6eSAndy Yan .win_sel_port_offset = 5, 67555fa6e665SDamon Ding .layer_sel_win_id = { 3, 3, 3, 3 }, 6756ecc31b6eSAndy Yan .reg_offset = 0x200, 6757a33b790fSDamon Ding .axi_id = 0, 6758a33b790fSDamon Ding .axi_yrgb_id = 0x0c, 6759a33b790fSDamon Ding .axi_uv_id = 0x0d, 6760b6ba80b4SDamon Ding .pd_id = VOP2_PD_ESMART, 67615fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 67625fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 67635fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 67645fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 67654c765862SDamon Ding .max_upscale_factor = 8, 67664c765862SDamon Ding .max_downscale_factor = 8, 6767ecc31b6eSAndy Yan }, 6768ecc31b6eSAndy Yan 6769ecc31b6eSAndy Yan { 6770ecc31b6eSAndy Yan .name = "Esmart2", 6771ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_ESMART2, 6772ee01dbb2SDamon Ding .splice_win_id = ROCKCHIP_VOP2_ESMART3, 6773ecc31b6eSAndy Yan .type = ESMART_LAYER, 6774ecc31b6eSAndy Yan .win_sel_port_offset = 6, 67755fa6e665SDamon Ding .layer_sel_win_id = { 6, 6, 6, 6 }, 6776ecc31b6eSAndy Yan .reg_offset = 0x400, 6777a33b790fSDamon Ding .axi_id = 1, 6778a33b790fSDamon Ding .axi_yrgb_id = 0x0a, 6779a33b790fSDamon Ding .axi_uv_id = 0x0b, 6780b6ba80b4SDamon Ding .pd_id = VOP2_PD_ESMART, 67815fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 67825fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 67835fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 67845fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 67854c765862SDamon Ding .max_upscale_factor = 8, 67864c765862SDamon Ding .max_downscale_factor = 8, 6787ecc31b6eSAndy Yan }, 6788ecc31b6eSAndy Yan 6789ecc31b6eSAndy Yan { 6790ecc31b6eSAndy Yan .name = "Esmart3", 6791ecc31b6eSAndy Yan .phys_id = ROCKCHIP_VOP2_ESMART3, 6792ecc31b6eSAndy Yan .type = ESMART_LAYER, 6793ecc31b6eSAndy Yan .win_sel_port_offset = 7, 67945fa6e665SDamon Ding .layer_sel_win_id = { 7, 7, 7, 7 }, 6795ecc31b6eSAndy Yan .reg_offset = 0x600, 6796a33b790fSDamon Ding .axi_id = 1, 6797a33b790fSDamon Ding .axi_yrgb_id = 0x0c, 6798a33b790fSDamon Ding .axi_uv_id = 0x0d, 6799b6ba80b4SDamon Ding .pd_id = VOP2_PD_ESMART, 68005fa6e665SDamon Ding .hsu_filter_mode = VOP2_SCALE_UP_BIC, 68015fa6e665SDamon Ding .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 68025fa6e665SDamon Ding .vsu_filter_mode = VOP2_SCALE_UP_BIL, 68035fa6e665SDamon Ding .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 68044c765862SDamon Ding .max_upscale_factor = 8, 68054c765862SDamon Ding .max_downscale_factor = 8, 6806ecc31b6eSAndy Yan }, 6807ecc31b6eSAndy Yan }; 6808ecc31b6eSAndy Yan 680912ee5af0SDamon Ding static struct dsc_error_info dsc_ecw[] = { 681012ee5af0SDamon Ding {0x00000000, "no error detected by DSC encoder"}, 681112ee5af0SDamon Ding {0x0030ffff, "bits per component error"}, 681212ee5af0SDamon Ding {0x0040ffff, "multiple mode error"}, 681312ee5af0SDamon Ding {0x0050ffff, "line buffer depth error"}, 681412ee5af0SDamon Ding {0x0060ffff, "minor version error"}, 681512ee5af0SDamon Ding {0x0070ffff, "picture height error"}, 681612ee5af0SDamon Ding {0x0080ffff, "picture width error"}, 681712ee5af0SDamon Ding {0x0090ffff, "number of slices error"}, 681812ee5af0SDamon Ding {0x00c0ffff, "slice height Error "}, 681912ee5af0SDamon Ding {0x00d0ffff, "slice width error"}, 682012ee5af0SDamon Ding {0x00e0ffff, "second line BPG offset error"}, 682112ee5af0SDamon Ding {0x00f0ffff, "non second line BPG offset error"}, 682212ee5af0SDamon Ding {0x0100ffff, "PPS ID error"}, 682312ee5af0SDamon Ding {0x0110ffff, "bits per pixel (BPP) Error"}, 682412ee5af0SDamon Ding {0x0120ffff, "buffer flow error"}, /* dsc_buffer_flow */ 682512ee5af0SDamon Ding 682612ee5af0SDamon Ding {0x01510001, "slice 0 RC buffer model overflow error"}, 682712ee5af0SDamon Ding {0x01510002, "slice 1 RC buffer model overflow error"}, 682812ee5af0SDamon Ding {0x01510004, "slice 2 RC buffer model overflow error"}, 682912ee5af0SDamon Ding {0x01510008, "slice 3 RC buffer model overflow error"}, 683012ee5af0SDamon Ding {0x01510010, "slice 4 RC buffer model overflow error"}, 683112ee5af0SDamon Ding {0x01510020, "slice 5 RC buffer model overflow error"}, 683212ee5af0SDamon Ding {0x01510040, "slice 6 RC buffer model overflow error"}, 683312ee5af0SDamon Ding {0x01510080, "slice 7 RC buffer model overflow error"}, 683412ee5af0SDamon Ding 683512ee5af0SDamon Ding {0x01610001, "slice 0 RC buffer model underflow error"}, 683612ee5af0SDamon Ding {0x01610002, "slice 1 RC buffer model underflow error"}, 683712ee5af0SDamon Ding {0x01610004, "slice 2 RC buffer model underflow error"}, 683812ee5af0SDamon Ding {0x01610008, "slice 3 RC buffer model underflow error"}, 683912ee5af0SDamon Ding {0x01610010, "slice 4 RC buffer model underflow error"}, 684012ee5af0SDamon Ding {0x01610020, "slice 5 RC buffer model underflow error"}, 684112ee5af0SDamon Ding {0x01610040, "slice 6 RC buffer model underflow error"}, 684212ee5af0SDamon Ding {0x01610080, "slice 7 RC buffer model underflow error"}, 684312ee5af0SDamon Ding 684412ee5af0SDamon Ding {0xffffffff, "unsuccessful RESET cycle status"}, 684512ee5af0SDamon Ding {0x00a0ffff, "ICH full error precision settings error"}, 684612ee5af0SDamon Ding {0x0020ffff, "native mode"}, 684712ee5af0SDamon Ding }; 684812ee5af0SDamon Ding 684912ee5af0SDamon Ding static struct dsc_error_info dsc_buffer_flow[] = { 685012ee5af0SDamon Ding {0x00000000, "rate buffer status"}, 685112ee5af0SDamon Ding {0x00000001, "line buffer status"}, 685212ee5af0SDamon Ding {0x00000002, "decoder model status"}, 685312ee5af0SDamon Ding {0x00000003, "pixel buffer status"}, 685412ee5af0SDamon Ding {0x00000004, "balance fifo buffer status"}, 685512ee5af0SDamon Ding {0x00000005, "syntax element fifo status"}, 685612ee5af0SDamon Ding }; 685712ee5af0SDamon Ding 685812ee5af0SDamon Ding static struct vop2_dsc_data rk3588_dsc_data[] = { 685912ee5af0SDamon Ding { 686012ee5af0SDamon Ding .id = ROCKCHIP_VOP2_DSC_8K, 686112ee5af0SDamon Ding .pd_id = VOP2_PD_DSC_8K, 686212ee5af0SDamon Ding .max_slice_num = 8, 686312ee5af0SDamon Ding .max_linebuf_depth = 11, 6864b61227a3SDamon Ding .min_bits_per_pixel = 8, 686512ee5af0SDamon Ding .dsc_txp_clk_src_name = "dsc_8k_txp_clk_src", 686612ee5af0SDamon Ding .dsc_txp_clk_name = "dsc_8k_txp_clk", 686712ee5af0SDamon Ding .dsc_pxl_clk_name = "dsc_8k_pxl_clk", 686812ee5af0SDamon Ding .dsc_cds_clk_name = "dsc_8k_cds_clk", 686912ee5af0SDamon Ding }, 687012ee5af0SDamon Ding 687112ee5af0SDamon Ding { 687212ee5af0SDamon Ding .id = ROCKCHIP_VOP2_DSC_4K, 687312ee5af0SDamon Ding .pd_id = VOP2_PD_DSC_4K, 687412ee5af0SDamon Ding .max_slice_num = 2, 687512ee5af0SDamon Ding .max_linebuf_depth = 11, 6876b61227a3SDamon Ding .min_bits_per_pixel = 8, 687712ee5af0SDamon Ding .dsc_txp_clk_src_name = "dsc_4k_txp_clk_src", 687812ee5af0SDamon Ding .dsc_txp_clk_name = "dsc_4k_txp_clk", 687912ee5af0SDamon Ding .dsc_pxl_clk_name = "dsc_4k_pxl_clk", 688012ee5af0SDamon Ding .dsc_cds_clk_name = "dsc_4k_cds_clk", 688112ee5af0SDamon Ding }, 688212ee5af0SDamon Ding }; 688312ee5af0SDamon Ding 6884ecc31b6eSAndy Yan static struct vop2_vp_data rk3588_vp_data[4] = { 6885ecc31b6eSAndy Yan { 6886ee01dbb2SDamon Ding .splice_vp_id = 1, 6887ecc31b6eSAndy Yan .feature = VOP_FEATURE_OUTPUT_10BIT, 6888b890760eSAlgea Cao .pre_scan_max_dly = 54, 6889ecc31b6eSAndy Yan .max_dclk = 600000, 6890ecc31b6eSAndy Yan .max_output = {7680, 4320}, 6891ecc31b6eSAndy Yan }, 6892ecc31b6eSAndy Yan { 6893ecc31b6eSAndy Yan .feature = VOP_FEATURE_OUTPUT_10BIT, 6894ee01dbb2SDamon Ding .pre_scan_max_dly = 54, 6895ecc31b6eSAndy Yan .max_dclk = 600000, 6896ecc31b6eSAndy Yan .max_output = {4096, 2304}, 6897ecc31b6eSAndy Yan }, 6898ecc31b6eSAndy Yan { 6899ecc31b6eSAndy Yan .feature = VOP_FEATURE_OUTPUT_10BIT, 6900ecc31b6eSAndy Yan .pre_scan_max_dly = 52, 6901ecc31b6eSAndy Yan .max_dclk = 600000, 6902ecc31b6eSAndy Yan .max_output = {4096, 2304}, 6903ecc31b6eSAndy Yan }, 6904ecc31b6eSAndy Yan { 6905ecc31b6eSAndy Yan .feature = 0, 6906ecc31b6eSAndy Yan .pre_scan_max_dly = 52, 6907ecc31b6eSAndy Yan .max_dclk = 200000, 6908ecc31b6eSAndy Yan .max_output = {1920, 1080}, 6909ecc31b6eSAndy Yan }, 6910ecc31b6eSAndy Yan }; 6911ecc31b6eSAndy Yan 6912b6ba80b4SDamon Ding static struct vop2_power_domain_data rk3588_vop_pd_data[] = { 6913b6ba80b4SDamon Ding { 6914b6ba80b4SDamon Ding .id = VOP2_PD_CLUSTER0, 6915b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER0), 6916b6ba80b4SDamon Ding }, 6917b6ba80b4SDamon Ding { 6918b6ba80b4SDamon Ding .id = VOP2_PD_CLUSTER1, 6919b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER1), 6920b6ba80b4SDamon Ding .parent_id = VOP2_PD_CLUSTER0, 6921b6ba80b4SDamon Ding }, 6922b6ba80b4SDamon Ding { 6923b6ba80b4SDamon Ding .id = VOP2_PD_CLUSTER2, 6924b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER2), 6925b6ba80b4SDamon Ding .parent_id = VOP2_PD_CLUSTER0, 6926b6ba80b4SDamon Ding }, 6927b6ba80b4SDamon Ding { 6928b6ba80b4SDamon Ding .id = VOP2_PD_CLUSTER3, 6929b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER3), 6930b6ba80b4SDamon Ding .parent_id = VOP2_PD_CLUSTER0, 6931b6ba80b4SDamon Ding }, 6932b6ba80b4SDamon Ding { 6933b6ba80b4SDamon Ding .id = VOP2_PD_ESMART, 6934b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_ESMART1) | 6935b6ba80b4SDamon Ding BIT(ROCKCHIP_VOP2_ESMART2) | 6936b6ba80b4SDamon Ding BIT(ROCKCHIP_VOP2_ESMART3), 6937b6ba80b4SDamon Ding }, 6938b6ba80b4SDamon Ding { 6939b6ba80b4SDamon Ding .id = VOP2_PD_DSC_8K, 6940b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_8K), 6941b6ba80b4SDamon Ding }, 6942b6ba80b4SDamon Ding { 6943b6ba80b4SDamon Ding .id = VOP2_PD_DSC_4K, 6944b6ba80b4SDamon Ding .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_4K), 6945b6ba80b4SDamon Ding }, 6946b6ba80b4SDamon Ding }; 6947b6ba80b4SDamon Ding 6948ecc31b6eSAndy Yan const struct vop2_data rk3588_vop = { 6949ecc31b6eSAndy Yan .version = VOP_VERSION_RK3588, 6950ecc31b6eSAndy Yan .nr_vps = 4, 6951ecc31b6eSAndy Yan .vp_data = rk3588_vp_data, 6952ecc31b6eSAndy Yan .win_data = rk3588_win_data, 6953ecc31b6eSAndy Yan .plane_mask = rk3588_vp_plane_mask[0], 6954ecc31b6eSAndy Yan .plane_table = rk3588_plane_table, 6955b6ba80b4SDamon Ding .pd = rk3588_vop_pd_data, 695612ee5af0SDamon Ding .dsc = rk3588_dsc_data, 695712ee5af0SDamon Ding .dsc_error_ecw = dsc_ecw, 695812ee5af0SDamon Ding .dsc_error_buffer_flow = dsc_buffer_flow, 6959337d1c13SDamon Ding .vp_primary_plane_order = rk3588_vp_primary_plane_order, 6960ecc31b6eSAndy Yan .nr_layers = 8, 6961ecc31b6eSAndy Yan .nr_mixers = 7, 6962ecc31b6eSAndy Yan .nr_gammas = 4, 6963b6ba80b4SDamon Ding .nr_pd = ARRAY_SIZE(rk3588_vop_pd_data), 696412ee5af0SDamon Ding .nr_dscs = 2, 696512ee5af0SDamon Ding .nr_dsc_ecw = ARRAY_SIZE(dsc_ecw), 696612ee5af0SDamon Ding .nr_dsc_buffer_flow = ARRAY_SIZE(dsc_buffer_flow), 696772388c26SDamon Ding .dump_regs = rk3588_dump_regs, 696872388c26SDamon Ding .dump_regs_size = ARRAY_SIZE(rk3588_dump_regs), 6969ecc31b6eSAndy Yan }; 6970ecc31b6eSAndy Yan 6971d0408543SAndy Yan const struct rockchip_crtc_funcs rockchip_vop2_funcs = { 6972d0408543SAndy Yan .preinit = rockchip_vop2_preinit, 6973d0408543SAndy Yan .prepare = rockchip_vop2_prepare, 6974d0408543SAndy Yan .init = rockchip_vop2_init, 6975d0408543SAndy Yan .set_plane = rockchip_vop2_set_plane, 6976d0408543SAndy Yan .enable = rockchip_vop2_enable, 6977d0408543SAndy Yan .disable = rockchip_vop2_disable, 6978b0989546SSandy Huang .fixup_dts = rockchip_vop2_fixup_dts, 69790675a2a4SDamon Ding .send_mcu_cmd = rockchip_vop2_send_mcu_cmd, 6980820a5c17SDamon Ding .check = rockchip_vop2_check, 698122007755SDamon Ding .mode_valid = rockchip_vop2_mode_valid, 6982b02eb70bSDamon Ding .mode_fixup = rockchip_vop2_mode_fixup, 69834c765862SDamon Ding .plane_check = rockchip_vop2_plane_check, 698472388c26SDamon Ding .regs_dump = rockchip_vop2_regs_dump, 698572388c26SDamon Ding .active_regs_dump = rockchip_vop2_active_regs_dump, 69868e7ef808SDamon Ding .apply_soft_te = rockchip_vop2_apply_soft_te, 6987d0408543SAndy Yan }; 6988