1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) Rockchip Electronics Co., Ltd. 4 * Author: Andy Yan <andy.yan@rock-chips.com> 5 */ 6 7 #include <linux/kernel.h> 8 #include <linux/component.h> 9 #include <linux/mod_devicetable.h> 10 #include <linux/platform_device.h> 11 #include <linux/of.h> 12 #include <drm/drm_fourcc.h> 13 #include <drm/drm_plane.h> 14 #include <drm/drm_print.h> 15 16 #include "rockchip_drm_vop2.h" 17 18 static const uint32_t formats_cluster[] = { 19 DRM_FORMAT_XRGB2101010, 20 DRM_FORMAT_XBGR2101010, 21 DRM_FORMAT_XRGB8888, 22 DRM_FORMAT_ARGB8888, 23 DRM_FORMAT_XBGR8888, 24 DRM_FORMAT_ABGR8888, 25 DRM_FORMAT_RGB888, 26 DRM_FORMAT_BGR888, 27 DRM_FORMAT_RGB565, 28 DRM_FORMAT_BGR565, 29 DRM_FORMAT_YUV420_8BIT, /* yuv420_8bit non-Linear mode only */ 30 DRM_FORMAT_YUV420_10BIT, /* yuv420_10bit non-Linear mode only */ 31 DRM_FORMAT_YUYV, /* yuv422_8bit non-Linear mode only*/ 32 DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */ 33 }; 34 35 static const uint32_t formats_esmart[] = { 36 DRM_FORMAT_XRGB8888, 37 DRM_FORMAT_ARGB8888, 38 DRM_FORMAT_XBGR8888, 39 DRM_FORMAT_ABGR8888, 40 DRM_FORMAT_RGB888, 41 DRM_FORMAT_BGR888, 42 DRM_FORMAT_RGB565, 43 DRM_FORMAT_BGR565, 44 DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */ 45 DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */ 46 DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */ 47 DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */ 48 DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */ 49 DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */ 50 DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */ 51 DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */ 52 DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ 53 DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */ 54 DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */ 55 DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode */ 56 DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode */ 57 }; 58 59 static const uint32_t formats_rk356x_esmart[] = { 60 DRM_FORMAT_XRGB8888, 61 DRM_FORMAT_ARGB8888, 62 DRM_FORMAT_XBGR8888, 63 DRM_FORMAT_ABGR8888, 64 DRM_FORMAT_RGB888, 65 DRM_FORMAT_BGR888, 66 DRM_FORMAT_RGB565, 67 DRM_FORMAT_BGR565, 68 DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */ 69 DRM_FORMAT_NV21, /* yuv420_8bit linear mode, 2 plane */ 70 DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ 71 DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */ 72 DRM_FORMAT_NV61, /* yuv422_8bit linear mode, 2 plane */ 73 DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */ 74 DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */ 75 DRM_FORMAT_NV42, /* yuv444_8bit linear mode, 2 plane */ 76 DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */ 77 DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */ 78 DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */ 79 }; 80 81 static const uint32_t formats_smart[] = { 82 DRM_FORMAT_XRGB8888, 83 DRM_FORMAT_ARGB8888, 84 DRM_FORMAT_XBGR8888, 85 DRM_FORMAT_ABGR8888, 86 DRM_FORMAT_RGB888, 87 DRM_FORMAT_BGR888, 88 DRM_FORMAT_RGB565, 89 DRM_FORMAT_BGR565, 90 }; 91 92 static const uint64_t format_modifiers[] = { 93 DRM_FORMAT_MOD_LINEAR, 94 DRM_FORMAT_MOD_INVALID, 95 }; 96 97 static const uint64_t format_modifiers_afbc[] = { 98 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16), 99 100 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 101 AFBC_FORMAT_MOD_SPARSE), 102 103 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 104 AFBC_FORMAT_MOD_YTR), 105 106 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 107 AFBC_FORMAT_MOD_CBR), 108 109 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 110 AFBC_FORMAT_MOD_YTR | 111 AFBC_FORMAT_MOD_SPARSE), 112 113 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 114 AFBC_FORMAT_MOD_CBR | 115 AFBC_FORMAT_MOD_SPARSE), 116 117 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 118 AFBC_FORMAT_MOD_YTR | 119 AFBC_FORMAT_MOD_CBR), 120 121 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 122 AFBC_FORMAT_MOD_YTR | 123 AFBC_FORMAT_MOD_CBR | 124 AFBC_FORMAT_MOD_SPARSE), 125 126 /* SPLIT mandates SPARSE, RGB modes mandates YTR */ 127 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 128 AFBC_FORMAT_MOD_YTR | 129 AFBC_FORMAT_MOD_SPARSE | 130 AFBC_FORMAT_MOD_SPLIT), 131 DRM_FORMAT_MOD_INVALID, 132 }; 133 134 static const struct vop2_video_port_data rk3568_vop_video_ports[] = { 135 { 136 .id = 0, 137 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 138 .gamma_lut_len = 1024, 139 .cubic_lut_len = 9 * 9 * 9, 140 .max_output = { 4096, 2304 }, 141 .pre_scan_max_dly = { 69, 53, 53, 42 }, 142 .offset = 0xc00, 143 }, { 144 .id = 1, 145 .gamma_lut_len = 1024, 146 .max_output = { 2048, 1536 }, 147 .pre_scan_max_dly = { 40, 40, 40, 40 }, 148 .offset = 0xd00, 149 }, { 150 .id = 2, 151 .gamma_lut_len = 1024, 152 .max_output = { 1920, 1080 }, 153 .pre_scan_max_dly = { 40, 40, 40, 40 }, 154 .offset = 0xe00, 155 }, 156 }; 157 158 /* 159 * rk3568 vop with 2 cluster, 2 esmart win, 2 smart win. 160 * Every cluster can work as 4K win or split into two win. 161 * All win in cluster support AFBCD. 162 * 163 * Every esmart win and smart win support 4 Multi-region. 164 * 165 * Scale filter mode: 166 * 167 * * Cluster: bicubic for horizontal scale up, others use bilinear 168 * * ESmart: 169 * * nearest-neighbor/bilinear/bicubic for scale up 170 * * nearest-neighbor/bilinear/average for scale down 171 * 172 * 173 * @TODO describe the wind like cpu-map dt nodes; 174 */ 175 static const struct vop2_win_data rk3568_vop_win_data[] = { 176 { 177 .name = "Smart0-win0", 178 .phys_id = ROCKCHIP_VOP2_SMART0, 179 .base = 0x1c00, 180 .formats = formats_smart, 181 .nformats = ARRAY_SIZE(formats_smart), 182 .format_modifiers = format_modifiers, 183 .layer_sel_id = 3, 184 .supported_rotations = DRM_MODE_REFLECT_Y, 185 .type = DRM_PLANE_TYPE_PRIMARY, 186 .max_upscale_factor = 8, 187 .max_downscale_factor = 8, 188 .dly = { 20, 47, 41 }, 189 }, { 190 .name = "Smart1-win0", 191 .phys_id = ROCKCHIP_VOP2_SMART1, 192 .formats = formats_smart, 193 .nformats = ARRAY_SIZE(formats_smart), 194 .format_modifiers = format_modifiers, 195 .base = 0x1e00, 196 .layer_sel_id = 7, 197 .supported_rotations = DRM_MODE_REFLECT_Y, 198 .type = DRM_PLANE_TYPE_PRIMARY, 199 .max_upscale_factor = 8, 200 .max_downscale_factor = 8, 201 .dly = { 20, 47, 41 }, 202 }, { 203 .name = "Esmart1-win0", 204 .phys_id = ROCKCHIP_VOP2_ESMART1, 205 .formats = formats_rk356x_esmart, 206 .nformats = ARRAY_SIZE(formats_rk356x_esmart), 207 .format_modifiers = format_modifiers, 208 .base = 0x1a00, 209 .layer_sel_id = 6, 210 .supported_rotations = DRM_MODE_REFLECT_Y, 211 .type = DRM_PLANE_TYPE_PRIMARY, 212 .max_upscale_factor = 8, 213 .max_downscale_factor = 8, 214 .dly = { 20, 47, 41 }, 215 }, { 216 .name = "Esmart0-win0", 217 .phys_id = ROCKCHIP_VOP2_ESMART0, 218 .formats = formats_rk356x_esmart, 219 .nformats = ARRAY_SIZE(formats_rk356x_esmart), 220 .format_modifiers = format_modifiers, 221 .base = 0x1800, 222 .layer_sel_id = 2, 223 .supported_rotations = DRM_MODE_REFLECT_Y, 224 .type = DRM_PLANE_TYPE_PRIMARY, 225 .max_upscale_factor = 8, 226 .max_downscale_factor = 8, 227 .dly = { 20, 47, 41 }, 228 }, { 229 .name = "Cluster0-win0", 230 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 231 .base = 0x1000, 232 .formats = formats_cluster, 233 .nformats = ARRAY_SIZE(formats_cluster), 234 .format_modifiers = format_modifiers_afbc, 235 .layer_sel_id = 0, 236 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 237 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 238 .max_upscale_factor = 4, 239 .max_downscale_factor = 4, 240 .dly = { 0, 27, 21 }, 241 .type = DRM_PLANE_TYPE_OVERLAY, 242 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 243 }, { 244 .name = "Cluster1-win0", 245 .phys_id = ROCKCHIP_VOP2_CLUSTER1, 246 .base = 0x1200, 247 .formats = formats_cluster, 248 .nformats = ARRAY_SIZE(formats_cluster), 249 .format_modifiers = format_modifiers_afbc, 250 .layer_sel_id = 1, 251 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 252 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 253 .type = DRM_PLANE_TYPE_OVERLAY, 254 .max_upscale_factor = 4, 255 .max_downscale_factor = 4, 256 .dly = { 0, 27, 21 }, 257 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 258 }, 259 }; 260 261 static const struct vop2_regs_dump rk3568_regs_dump[] = { 262 { 263 .name = "SYS", 264 .base = RK3568_REG_CFG_DONE, 265 .size = 0x100, 266 .en_reg = 0, 267 .en_val = 0, 268 .en_mask = 0 269 }, { 270 .name = "OVL", 271 .base = RK3568_OVL_CTRL, 272 .size = 0x100, 273 .en_reg = 0, 274 .en_val = 0, 275 .en_mask = 0, 276 }, { 277 .name = "VP0", 278 .base = RK3568_VP0_CTRL_BASE, 279 .size = 0x100, 280 .en_reg = RK3568_VP_DSP_CTRL, 281 .en_val = 0, 282 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 283 }, { 284 .name = "VP1", 285 .base = RK3568_VP1_CTRL_BASE, 286 .size = 0x100, 287 .en_reg = RK3568_VP_DSP_CTRL, 288 .en_val = 0, 289 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 290 }, { 291 .name = "VP2", 292 .base = RK3568_VP2_CTRL_BASE, 293 .size = 0x100, 294 .en_reg = RK3568_VP_DSP_CTRL, 295 .en_val = 0, 296 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 297 298 }, { 299 .name = "Cluster0", 300 .base = RK3568_CLUSTER0_CTRL_BASE, 301 .size = 0x110, 302 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 303 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 304 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 305 }, { 306 .name = "Cluster1", 307 .base = RK3568_CLUSTER1_CTRL_BASE, 308 .size = 0x110, 309 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 310 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 311 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 312 }, { 313 .name = "Esmart0", 314 .base = RK3568_ESMART0_CTRL_BASE, 315 .size = 0xf0, 316 .en_reg = RK3568_SMART_REGION0_CTRL, 317 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 318 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 319 }, { 320 .name = "Esmart1", 321 .base = RK3568_ESMART1_CTRL_BASE, 322 .size = 0xf0, 323 .en_reg = RK3568_SMART_REGION0_CTRL, 324 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 325 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 326 }, { 327 .name = "Smart0", 328 .base = RK3568_SMART0_CTRL_BASE, 329 .size = 0xf0, 330 .en_reg = RK3568_SMART_REGION0_CTRL, 331 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 332 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 333 }, { 334 .name = "Smart1", 335 .base = RK3568_SMART1_CTRL_BASE, 336 .size = 0xf0, 337 .en_reg = RK3568_SMART_REGION0_CTRL, 338 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 339 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 340 }, 341 }; 342 343 static const struct vop2_video_port_data rk3588_vop_video_ports[] = { 344 { 345 .id = 0, 346 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 347 .gamma_lut_len = 1024, 348 .cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */ 349 .max_output = { 4096, 2304 }, 350 /* hdr2sdr sdr2hdr hdr2hdr sdr2sdr */ 351 .pre_scan_max_dly = { 76, 65, 65, 54 }, 352 .offset = 0xc00, 353 }, { 354 .id = 1, 355 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 356 .gamma_lut_len = 1024, 357 .cubic_lut_len = 729, /* 9x9x9 */ 358 .max_output = { 4096, 2304 }, 359 .pre_scan_max_dly = { 76, 65, 65, 54 }, 360 .offset = 0xd00, 361 }, { 362 .id = 2, 363 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 364 .gamma_lut_len = 1024, 365 .cubic_lut_len = 17 * 17 * 17, /* 17x17x17 */ 366 .max_output = { 4096, 2304 }, 367 .pre_scan_max_dly = { 52, 52, 52, 52 }, 368 .offset = 0xe00, 369 }, { 370 .id = 3, 371 .gamma_lut_len = 1024, 372 .max_output = { 2048, 1536 }, 373 .pre_scan_max_dly = { 52, 52, 52, 52 }, 374 .offset = 0xf00, 375 }, 376 }; 377 378 /* 379 * rk3588 vop with 4 cluster, 4 esmart win. 380 * Every cluster can work as 4K win or split into two win. 381 * All win in cluster support AFBCD. 382 * 383 * Every esmart win and smart win support 4 Multi-region. 384 * 385 * Scale filter mode: 386 * 387 * * Cluster: bicubic for horizontal scale up, others use bilinear 388 * * ESmart: 389 * * nearest-neighbor/bilinear/bicubic for scale up 390 * * nearest-neighbor/bilinear/average for scale down 391 * 392 * AXI Read ID assignment: 393 * Two AXI bus: 394 * AXI0 is a read/write bus with a higher performance. 395 * AXI1 is a read only bus. 396 * 397 * Every window on a AXI bus must assigned two unique 398 * read id(yrgb_r_id/uv_r_id, valid id are 0x1~0xe). 399 * 400 * AXI0: 401 * Cluster0/1, Esmart0/1, WriteBack 402 * 403 * AXI 1: 404 * Cluster2/3, Esmart2/3 405 * 406 */ 407 static const struct vop2_win_data rk3588_vop_win_data[] = { 408 { 409 .name = "Cluster0-win0", 410 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 411 .base = 0x1000, 412 .formats = formats_cluster, 413 .nformats = ARRAY_SIZE(formats_cluster), 414 .format_modifiers = format_modifiers_afbc, 415 .layer_sel_id = 0, 416 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 417 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 418 .axi_bus_id = 0, 419 .axi_yrgb_r_id = 2, 420 .axi_uv_r_id = 3, 421 .max_upscale_factor = 4, 422 .max_downscale_factor = 4, 423 .dly = { 4, 26, 29 }, 424 .type = DRM_PLANE_TYPE_PRIMARY, 425 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 426 }, { 427 .name = "Cluster1-win0", 428 .phys_id = ROCKCHIP_VOP2_CLUSTER1, 429 .base = 0x1200, 430 .formats = formats_cluster, 431 .nformats = ARRAY_SIZE(formats_cluster), 432 .format_modifiers = format_modifiers_afbc, 433 .layer_sel_id = 1, 434 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 435 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 436 .type = DRM_PLANE_TYPE_PRIMARY, 437 .axi_bus_id = 0, 438 .axi_yrgb_r_id = 6, 439 .axi_uv_r_id = 7, 440 .max_upscale_factor = 4, 441 .max_downscale_factor = 4, 442 .dly = { 4, 26, 29 }, 443 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 444 }, { 445 .name = "Cluster2-win0", 446 .phys_id = ROCKCHIP_VOP2_CLUSTER2, 447 .base = 0x1400, 448 .formats = formats_cluster, 449 .nformats = ARRAY_SIZE(formats_cluster), 450 .format_modifiers = format_modifiers_afbc, 451 .layer_sel_id = 4, 452 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 453 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 454 .type = DRM_PLANE_TYPE_PRIMARY, 455 .axi_bus_id = 1, 456 .axi_yrgb_r_id = 2, 457 .axi_uv_r_id = 3, 458 .max_upscale_factor = 4, 459 .max_downscale_factor = 4, 460 .dly = { 4, 26, 29 }, 461 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 462 }, { 463 .name = "Cluster3-win0", 464 .phys_id = ROCKCHIP_VOP2_CLUSTER3, 465 .base = 0x1600, 466 .formats = formats_cluster, 467 .nformats = ARRAY_SIZE(formats_cluster), 468 .format_modifiers = format_modifiers_afbc, 469 .layer_sel_id = 5, 470 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 471 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 472 .type = DRM_PLANE_TYPE_PRIMARY, 473 .axi_bus_id = 1, 474 .axi_yrgb_r_id = 6, 475 .axi_uv_r_id = 7, 476 .max_upscale_factor = 4, 477 .max_downscale_factor = 4, 478 .dly = { 4, 26, 29 }, 479 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 480 }, { 481 .name = "Esmart0-win0", 482 .phys_id = ROCKCHIP_VOP2_ESMART0, 483 .formats = formats_esmart, 484 .nformats = ARRAY_SIZE(formats_esmart), 485 .format_modifiers = format_modifiers, 486 .base = 0x1800, 487 .layer_sel_id = 2, 488 .supported_rotations = DRM_MODE_REFLECT_Y, 489 .type = DRM_PLANE_TYPE_OVERLAY, 490 .axi_bus_id = 0, 491 .axi_yrgb_r_id = 0x0a, 492 .axi_uv_r_id = 0x0b, 493 .max_upscale_factor = 8, 494 .max_downscale_factor = 8, 495 .dly = { 23, 45, 48 }, 496 }, { 497 .name = "Esmart1-win0", 498 .phys_id = ROCKCHIP_VOP2_ESMART1, 499 .formats = formats_esmart, 500 .nformats = ARRAY_SIZE(formats_esmart), 501 .format_modifiers = format_modifiers, 502 .base = 0x1a00, 503 .layer_sel_id = 3, 504 .supported_rotations = DRM_MODE_REFLECT_Y, 505 .type = DRM_PLANE_TYPE_OVERLAY, 506 .axi_bus_id = 0, 507 .axi_yrgb_r_id = 0x0c, 508 .axi_uv_r_id = 0x01, 509 .max_upscale_factor = 8, 510 .max_downscale_factor = 8, 511 .dly = { 23, 45, 48 }, 512 }, { 513 .name = "Esmart2-win0", 514 .phys_id = ROCKCHIP_VOP2_ESMART2, 515 .base = 0x1c00, 516 .formats = formats_esmart, 517 .nformats = ARRAY_SIZE(formats_esmart), 518 .format_modifiers = format_modifiers, 519 .layer_sel_id = 6, 520 .supported_rotations = DRM_MODE_REFLECT_Y, 521 .type = DRM_PLANE_TYPE_OVERLAY, 522 .axi_bus_id = 1, 523 .axi_yrgb_r_id = 0x0a, 524 .axi_uv_r_id = 0x0b, 525 .max_upscale_factor = 8, 526 .max_downscale_factor = 8, 527 .dly = { 23, 45, 48 }, 528 }, { 529 .name = "Esmart3-win0", 530 .phys_id = ROCKCHIP_VOP2_ESMART3, 531 .formats = formats_esmart, 532 .nformats = ARRAY_SIZE(formats_esmart), 533 .format_modifiers = format_modifiers, 534 .base = 0x1e00, 535 .layer_sel_id = 7, 536 .supported_rotations = DRM_MODE_REFLECT_Y, 537 .type = DRM_PLANE_TYPE_OVERLAY, 538 .axi_bus_id = 1, 539 .axi_yrgb_r_id = 0x0c, 540 .axi_uv_r_id = 0x0d, 541 .max_upscale_factor = 8, 542 .max_downscale_factor = 8, 543 .dly = { 23, 45, 48 }, 544 }, 545 }; 546 547 static const struct vop2_regs_dump rk3588_regs_dump[] = { 548 { 549 .name = "SYS", 550 .base = RK3568_REG_CFG_DONE, 551 .size = 0x100, 552 .en_reg = 0, 553 .en_val = 0, 554 .en_mask = 0 555 }, { 556 .name = "OVL", 557 .base = RK3568_OVL_CTRL, 558 .size = 0x100, 559 .en_reg = 0, 560 .en_val = 0, 561 .en_mask = 0, 562 }, { 563 .name = "VP0", 564 .base = RK3568_VP0_CTRL_BASE, 565 .size = 0x100, 566 .en_reg = RK3568_VP_DSP_CTRL, 567 .en_val = 0, 568 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 569 }, { 570 .name = "VP1", 571 .base = RK3568_VP1_CTRL_BASE, 572 .size = 0x100, 573 .en_reg = RK3568_VP_DSP_CTRL, 574 .en_val = 0, 575 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 576 }, { 577 .name = "VP2", 578 .base = RK3568_VP2_CTRL_BASE, 579 .size = 0x100, 580 .en_reg = RK3568_VP_DSP_CTRL, 581 .en_val = 0, 582 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 583 584 }, { 585 .name = "VP3", 586 .base = RK3588_VP3_CTRL_BASE, 587 .size = 0x100, 588 .en_reg = RK3568_VP_DSP_CTRL, 589 .en_val = 0, 590 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 591 }, { 592 .name = "Cluster0", 593 .base = RK3568_CLUSTER0_CTRL_BASE, 594 .size = 0x110, 595 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 596 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 597 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 598 }, { 599 .name = "Cluster1", 600 .base = RK3568_CLUSTER1_CTRL_BASE, 601 .size = 0x110, 602 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 603 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 604 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 605 }, { 606 .name = "Cluster2", 607 .base = RK3588_CLUSTER2_CTRL_BASE, 608 .size = 0x110, 609 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 610 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 611 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 612 }, { 613 .name = "Cluster3", 614 .base = RK3588_CLUSTER3_CTRL_BASE, 615 .size = 0x110, 616 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 617 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 618 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 619 }, { 620 .name = "Esmart0", 621 .base = RK3568_ESMART0_CTRL_BASE, 622 .size = 0xf0, 623 .en_reg = RK3568_SMART_REGION0_CTRL, 624 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 625 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 626 }, { 627 .name = "Esmart1", 628 .base = RK3568_ESMART1_CTRL_BASE, 629 .size = 0xf0, 630 .en_reg = RK3568_SMART_REGION0_CTRL, 631 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 632 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 633 }, { 634 .name = "Esmart2", 635 .base = RK3588_ESMART2_CTRL_BASE, 636 .size = 0xf0, 637 .en_reg = RK3568_SMART_REGION0_CTRL, 638 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 639 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 640 }, { 641 .name = "Esmart3", 642 .base = RK3588_ESMART3_CTRL_BASE, 643 .size = 0xf0, 644 .en_reg = RK3568_SMART_REGION0_CTRL, 645 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 646 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 647 }, 648 }; 649 650 static const struct vop2_data rk3566_vop = { 651 .feature = VOP2_FEATURE_HAS_SYS_GRF, 652 .nr_vps = 3, 653 .max_input = { 4096, 2304 }, 654 .max_output = { 4096, 2304 }, 655 .vp = rk3568_vop_video_ports, 656 .win = rk3568_vop_win_data, 657 .win_size = ARRAY_SIZE(rk3568_vop_win_data), 658 .regs_dump = rk3568_regs_dump, 659 .regs_dump_size = ARRAY_SIZE(rk3568_regs_dump), 660 .soc_id = 3566, 661 }; 662 663 static const struct vop2_data rk3568_vop = { 664 .feature = VOP2_FEATURE_HAS_SYS_GRF, 665 .nr_vps = 3, 666 .max_input = { 4096, 2304 }, 667 .max_output = { 4096, 2304 }, 668 .vp = rk3568_vop_video_ports, 669 .win = rk3568_vop_win_data, 670 .win_size = ARRAY_SIZE(rk3568_vop_win_data), 671 .regs_dump = rk3568_regs_dump, 672 .regs_dump_size = ARRAY_SIZE(rk3568_regs_dump), 673 .soc_id = 3568, 674 }; 675 676 static const struct vop2_data rk3588_vop = { 677 .feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF | 678 VOP2_FEATURE_HAS_VOP_GRF | VOP2_FEATURE_HAS_SYS_PMU, 679 .nr_vps = 4, 680 .max_input = { 4096, 4320 }, 681 .max_output = { 4096, 4320 }, 682 .vp = rk3588_vop_video_ports, 683 .win = rk3588_vop_win_data, 684 .win_size = ARRAY_SIZE(rk3588_vop_win_data), 685 .regs_dump = rk3588_regs_dump, 686 .regs_dump_size = ARRAY_SIZE(rk3588_regs_dump), 687 .soc_id = 3588, 688 }; 689 690 static const struct of_device_id vop2_dt_match[] = { 691 { 692 .compatible = "rockchip,rk3566-vop", 693 .data = &rk3566_vop, 694 }, { 695 .compatible = "rockchip,rk3568-vop", 696 .data = &rk3568_vop, 697 }, { 698 .compatible = "rockchip,rk3588-vop", 699 .data = &rk3588_vop 700 }, { 701 }, 702 }; 703 MODULE_DEVICE_TABLE(of, vop2_dt_match); 704 705 static int vop2_probe(struct platform_device *pdev) 706 { 707 struct device *dev = &pdev->dev; 708 709 return component_add(dev, &vop2_component_ops); 710 } 711 712 static void vop2_remove(struct platform_device *pdev) 713 { 714 component_del(&pdev->dev, &vop2_component_ops); 715 } 716 717 struct platform_driver vop2_platform_driver = { 718 .probe = vop2_probe, 719 .remove = vop2_remove, 720 .driver = { 721 .name = "rockchip-vop2", 722 .of_match_table = vop2_dt_match, 723 }, 724 }; 725