1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT) 2 /* 3 * Copyright (c) 2020 Rockchip Electronics Co., Ltd. 4 * Author: Andy Yan <andy.yan@rock-chips.com> 5 */ 6 #include <linux/bitfield.h> 7 #include <linux/clk.h> 8 #include <linux/component.h> 9 #include <linux/delay.h> 10 #include <linux/iopoll.h> 11 #include <linux/kernel.h> 12 #include <linux/media-bus-format.h> 13 #include <linux/mfd/syscon.h> 14 #include <linux/module.h> 15 #include <linux/of.h> 16 #include <linux/of_graph.h> 17 #include <linux/platform_device.h> 18 #include <linux/pm_runtime.h> 19 #include <linux/regmap.h> 20 #include <linux/swab.h> 21 22 #include <drm/drm.h> 23 #include <drm/drm_atomic.h> 24 #include <drm/drm_atomic_uapi.h> 25 #include <drm/drm_blend.h> 26 #include <drm/drm_crtc.h> 27 #include <linux/debugfs.h> 28 #include <drm/drm_debugfs.h> 29 #include <drm/drm_flip_work.h> 30 #include <drm/drm_framebuffer.h> 31 #include <drm/drm_gem_framebuffer_helper.h> 32 #include <drm/drm_print.h> 33 #include <drm/drm_probe_helper.h> 34 #include <drm/drm_vblank.h> 35 36 #include <uapi/linux/videodev2.h> 37 38 #include "rockchip_drm_gem.h" 39 #include "rockchip_drm_vop2.h" 40 #include "rockchip_rgb.h" 41 42 /* 43 * VOP2 architecture 44 * 45 +----------+ +-------------+ +-----------+ 46 | Cluster | | Sel 1 from 6| | 1 from 3 | 47 | window0 | | Layer0 | | RGB | 48 +----------+ +-------------+ +---------------+ +-------------+ +-----------+ 49 +----------+ +-------------+ |N from 6 layers| | | 50 | Cluster | | Sel 1 from 6| | Overlay0 +--->| Video Port0 | +-----------+ 51 | window1 | | Layer1 | | | | | | 1 from 3 | 52 +----------+ +-------------+ +---------------+ +-------------+ | LVDS | 53 +----------+ +-------------+ +-----------+ 54 | Esmart | | Sel 1 from 6| 55 | window0 | | Layer2 | +---------------+ +-------------+ +-----------+ 56 +----------+ +-------------+ |N from 6 Layers| | | +--> | 1 from 3 | 57 +----------+ +-------------+ --------> | Overlay1 +--->| Video Port1 | | MIPI | 58 | Esmart | | Sel 1 from 6| --------> | | | | +-----------+ 59 | Window1 | | Layer3 | +---------------+ +-------------+ 60 +----------+ +-------------+ +-----------+ 61 +----------+ +-------------+ | 1 from 3 | 62 | Smart | | Sel 1 from 6| +---------------+ +-------------+ | HDMI | 63 | Window0 | | Layer4 | |N from 6 Layers| | | +-----------+ 64 +----------+ +-------------+ | Overlay2 +--->| Video Port2 | 65 +----------+ +-------------+ | | | | +-----------+ 66 | Smart | | Sel 1 from 6| +---------------+ +-------------+ | 1 from 3 | 67 | Window1 | | Layer5 | | eDP | 68 +----------+ +-------------+ +-----------+ 69 * 70 */ 71 72 enum vop2_data_format { 73 VOP2_FMT_ARGB8888 = 0, 74 VOP2_FMT_RGB888, 75 VOP2_FMT_RGB565, 76 VOP2_FMT_XRGB101010, 77 VOP2_FMT_YUV420SP, 78 VOP2_FMT_YUV422SP, 79 VOP2_FMT_YUV444SP, 80 VOP2_FMT_YUYV422 = 8, 81 VOP2_FMT_YUYV420, 82 VOP2_FMT_VYUY422, 83 VOP2_FMT_VYUY420, 84 VOP2_FMT_YUV420SP_TILE_8x4 = 0x10, 85 VOP2_FMT_YUV420SP_TILE_16x2, 86 VOP2_FMT_YUV422SP_TILE_8x4, 87 VOP2_FMT_YUV422SP_TILE_16x2, 88 VOP2_FMT_YUV420SP_10, 89 VOP2_FMT_YUV422SP_10, 90 VOP2_FMT_YUV444SP_10, 91 }; 92 93 enum vop2_afbc_format { 94 VOP2_AFBC_FMT_RGB565, 95 VOP2_AFBC_FMT_ARGB2101010 = 2, 96 VOP2_AFBC_FMT_YUV420_10BIT, 97 VOP2_AFBC_FMT_RGB888, 98 VOP2_AFBC_FMT_ARGB8888, 99 VOP2_AFBC_FMT_YUV420 = 9, 100 VOP2_AFBC_FMT_YUV422 = 0xb, 101 VOP2_AFBC_FMT_YUV422_10BIT = 0xe, 102 VOP2_AFBC_FMT_INVALID = -1, 103 }; 104 105 #define VOP2_MAX_DCLK_RATE 600000000UL 106 107 /* 108 * bus-format types. 109 */ 110 struct drm_bus_format_enum_list { 111 int type; 112 const char *name; 113 }; 114 115 static const struct drm_bus_format_enum_list drm_bus_format_enum_list[] = { 116 { DRM_MODE_CONNECTOR_Unknown, "Unknown" }, 117 { MEDIA_BUS_FMT_RGB565_1X16, "RGB565_1X16" }, 118 { MEDIA_BUS_FMT_RGB666_1X18, "RGB666_1X18" }, 119 { MEDIA_BUS_FMT_RGB666_1X24_CPADHI, "RGB666_1X24_CPADHI" }, 120 { MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, "RGB666_1X7X3_SPWG" }, 121 { MEDIA_BUS_FMT_YUV8_1X24, "YUV8_1X24" }, 122 { MEDIA_BUS_FMT_UYYVYY8_0_5X24, "UYYVYY8_0_5X24" }, 123 { MEDIA_BUS_FMT_YUV10_1X30, "YUV10_1X30" }, 124 { MEDIA_BUS_FMT_UYYVYY10_0_5X30, "UYYVYY10_0_5X30" }, 125 { MEDIA_BUS_FMT_RGB888_3X8, "RGB888_3X8" }, 126 { MEDIA_BUS_FMT_RGB888_1X24, "RGB888_1X24" }, 127 { MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, "RGB888_1X7X4_SPWG" }, 128 { MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, "RGB888_1X7X4_JEIDA" }, 129 { MEDIA_BUS_FMT_UYVY8_2X8, "UYVY8_2X8" }, 130 { MEDIA_BUS_FMT_YUYV8_1X16, "YUYV8_1X16" }, 131 { MEDIA_BUS_FMT_UYVY8_1X16, "UYVY8_1X16" }, 132 { MEDIA_BUS_FMT_RGB101010_1X30, "RGB101010_1X30" }, 133 { MEDIA_BUS_FMT_YUYV10_1X20, "YUYV10_1X20" }, 134 }; 135 136 static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list) 137 138 static const struct regmap_config vop2_regmap_config; 139 140 static void vop2_lock(struct vop2 *vop2) 141 { 142 mutex_lock(&vop2->vop2_lock); 143 } 144 145 static void vop2_unlock(struct vop2 *vop2) 146 { 147 mutex_unlock(&vop2->vop2_lock); 148 } 149 150 static void vop2_win_disable(struct vop2_win *win) 151 { 152 vop2_win_write(win, VOP2_WIN_ENABLE, 0); 153 154 if (vop2_cluster_window(win)) 155 vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 0); 156 } 157 158 static u32 vop2_get_bpp(const struct drm_format_info *format) 159 { 160 switch (format->format) { 161 case DRM_FORMAT_YUV420_8BIT: 162 return 12; 163 case DRM_FORMAT_YUV420_10BIT: 164 return 15; 165 case DRM_FORMAT_VUY101010: 166 return 30; 167 default: 168 return drm_format_info_bpp(format, 0); 169 } 170 } 171 172 static enum vop2_data_format vop2_convert_format(u32 format) 173 { 174 switch (format) { 175 case DRM_FORMAT_XRGB2101010: 176 case DRM_FORMAT_ARGB2101010: 177 case DRM_FORMAT_XBGR2101010: 178 case DRM_FORMAT_ABGR2101010: 179 return VOP2_FMT_XRGB101010; 180 case DRM_FORMAT_XRGB8888: 181 case DRM_FORMAT_ARGB8888: 182 case DRM_FORMAT_XBGR8888: 183 case DRM_FORMAT_ABGR8888: 184 return VOP2_FMT_ARGB8888; 185 case DRM_FORMAT_RGB888: 186 case DRM_FORMAT_BGR888: 187 return VOP2_FMT_RGB888; 188 case DRM_FORMAT_RGB565: 189 case DRM_FORMAT_BGR565: 190 return VOP2_FMT_RGB565; 191 case DRM_FORMAT_NV12: 192 case DRM_FORMAT_NV21: 193 case DRM_FORMAT_YUV420_8BIT: 194 return VOP2_FMT_YUV420SP; 195 case DRM_FORMAT_NV15: 196 case DRM_FORMAT_YUV420_10BIT: 197 return VOP2_FMT_YUV420SP_10; 198 case DRM_FORMAT_NV16: 199 case DRM_FORMAT_NV61: 200 return VOP2_FMT_YUV422SP; 201 case DRM_FORMAT_NV20: 202 case DRM_FORMAT_Y210: 203 return VOP2_FMT_YUV422SP_10; 204 case DRM_FORMAT_NV24: 205 case DRM_FORMAT_NV42: 206 return VOP2_FMT_YUV444SP; 207 case DRM_FORMAT_NV30: 208 return VOP2_FMT_YUV444SP_10; 209 case DRM_FORMAT_YUYV: 210 case DRM_FORMAT_YVYU: 211 return VOP2_FMT_VYUY422; 212 case DRM_FORMAT_VYUY: 213 case DRM_FORMAT_UYVY: 214 return VOP2_FMT_YUYV422; 215 default: 216 DRM_ERROR("unsupported format[%08x]\n", format); 217 return -EINVAL; 218 } 219 } 220 221 static enum vop2_afbc_format vop2_convert_afbc_format(u32 format) 222 { 223 switch (format) { 224 case DRM_FORMAT_XRGB2101010: 225 case DRM_FORMAT_ARGB2101010: 226 case DRM_FORMAT_XBGR2101010: 227 case DRM_FORMAT_ABGR2101010: 228 return VOP2_AFBC_FMT_ARGB2101010; 229 case DRM_FORMAT_XRGB8888: 230 case DRM_FORMAT_ARGB8888: 231 case DRM_FORMAT_XBGR8888: 232 case DRM_FORMAT_ABGR8888: 233 return VOP2_AFBC_FMT_ARGB8888; 234 case DRM_FORMAT_RGB888: 235 case DRM_FORMAT_BGR888: 236 return VOP2_AFBC_FMT_RGB888; 237 case DRM_FORMAT_RGB565: 238 case DRM_FORMAT_BGR565: 239 return VOP2_AFBC_FMT_RGB565; 240 case DRM_FORMAT_YUV420_8BIT: 241 return VOP2_AFBC_FMT_YUV420; 242 case DRM_FORMAT_YUV420_10BIT: 243 return VOP2_AFBC_FMT_YUV420_10BIT; 244 case DRM_FORMAT_YVYU: 245 case DRM_FORMAT_YUYV: 246 case DRM_FORMAT_VYUY: 247 case DRM_FORMAT_UYVY: 248 return VOP2_AFBC_FMT_YUV422; 249 case DRM_FORMAT_Y210: 250 return VOP2_AFBC_FMT_YUV422_10BIT; 251 default: 252 return VOP2_AFBC_FMT_INVALID; 253 } 254 255 return VOP2_AFBC_FMT_INVALID; 256 } 257 258 static bool vop2_win_rb_swap(u32 format) 259 { 260 switch (format) { 261 case DRM_FORMAT_XBGR2101010: 262 case DRM_FORMAT_ABGR2101010: 263 case DRM_FORMAT_XBGR8888: 264 case DRM_FORMAT_ABGR8888: 265 case DRM_FORMAT_BGR888: 266 case DRM_FORMAT_BGR565: 267 return true; 268 default: 269 return false; 270 } 271 } 272 273 static bool vop2_afbc_uv_swap(u32 format) 274 { 275 switch (format) { 276 case DRM_FORMAT_YUYV: 277 case DRM_FORMAT_Y210: 278 case DRM_FORMAT_YUV420_8BIT: 279 case DRM_FORMAT_YUV420_10BIT: 280 return true; 281 default: 282 return false; 283 } 284 } 285 286 static bool vop2_win_uv_swap(u32 format) 287 { 288 switch (format) { 289 case DRM_FORMAT_NV12: 290 case DRM_FORMAT_NV16: 291 case DRM_FORMAT_NV24: 292 case DRM_FORMAT_NV15: 293 case DRM_FORMAT_NV20: 294 case DRM_FORMAT_NV30: 295 case DRM_FORMAT_YUYV: 296 case DRM_FORMAT_UYVY: 297 return true; 298 default: 299 return false; 300 } 301 } 302 303 static bool vop2_win_dither_up(u32 format) 304 { 305 switch (format) { 306 case DRM_FORMAT_BGR565: 307 case DRM_FORMAT_RGB565: 308 return true; 309 default: 310 return false; 311 } 312 } 313 314 static bool vop2_output_uv_swap(u32 bus_format, u32 output_mode) 315 { 316 /* 317 * FIXME: 318 * 319 * There is no media type for YUV444 output, 320 * so when out_mode is AAAA or P888, assume output is YUV444 on 321 * yuv format. 322 * 323 * From H/W testing, YUV444 mode need a rb swap. 324 */ 325 if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 || 326 bus_format == MEDIA_BUS_FMT_VYUY8_1X16 || 327 bus_format == MEDIA_BUS_FMT_YVYU8_2X8 || 328 bus_format == MEDIA_BUS_FMT_VYUY8_2X8 || 329 ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 330 bus_format == MEDIA_BUS_FMT_YUV10_1X30) && 331 (output_mode == ROCKCHIP_OUT_MODE_AAAA || 332 output_mode == ROCKCHIP_OUT_MODE_P888))) 333 return true; 334 else 335 return false; 336 } 337 338 static bool vop2_output_rg_swap(struct vop2 *vop2, u32 bus_format) 339 { 340 if (vop2->version == VOP_VERSION_RK3588 || 341 vop2->version == VOP_VERSION_RK3576) { 342 if (bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 343 bus_format == MEDIA_BUS_FMT_YUV10_1X30) 344 return true; 345 } 346 347 return false; 348 } 349 350 static bool is_yuv_output(u32 bus_format) 351 { 352 switch (bus_format) { 353 case MEDIA_BUS_FMT_YUV8_1X24: 354 case MEDIA_BUS_FMT_YUV10_1X30: 355 case MEDIA_BUS_FMT_YUYV10_1X20: 356 case MEDIA_BUS_FMT_UYVY10_1X20: 357 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 358 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 359 case MEDIA_BUS_FMT_YUYV8_2X8: 360 case MEDIA_BUS_FMT_YVYU8_2X8: 361 case MEDIA_BUS_FMT_UYVY8_2X8: 362 case MEDIA_BUS_FMT_VYUY8_2X8: 363 case MEDIA_BUS_FMT_YUYV8_1X16: 364 case MEDIA_BUS_FMT_YVYU8_1X16: 365 case MEDIA_BUS_FMT_UYVY8_1X16: 366 case MEDIA_BUS_FMT_VYUY8_1X16: 367 return true; 368 default: 369 return false; 370 } 371 } 372 373 static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format, 374 u64 modifier) 375 { 376 struct vop2_win *win = to_vop2_win(plane); 377 struct vop2 *vop2 = win->vop2; 378 int i; 379 380 /* No support for implicit modifiers */ 381 if (modifier == DRM_FORMAT_MOD_INVALID) 382 return false; 383 384 /* The cluster window on 3568 is AFBC-only */ 385 if (vop2->version == VOP_VERSION_RK3568 && vop2_cluster_window(win) && 386 !drm_is_afbc(modifier)) { 387 drm_dbg_kms(vop2->drm, 388 "Cluster window only supports format with afbc\n"); 389 return false; 390 } 391 392 /* 10bpc formats on 3588 are AFBC-only */ 393 if (vop2->version == VOP_VERSION_RK3588 && !drm_is_afbc(modifier) && 394 (format == DRM_FORMAT_XRGB2101010 || format == DRM_FORMAT_XBGR2101010)) { 395 drm_dbg_kms(vop2->drm, "Only support 10bpc format with afbc\n"); 396 return false; 397 } 398 399 /* Linear is otherwise supported everywhere */ 400 if (modifier == DRM_FORMAT_MOD_LINEAR) 401 return true; 402 403 /* Not all format+modifier combinations are allowable */ 404 if (vop2_convert_afbc_format(format) == VOP2_AFBC_FMT_INVALID) 405 return false; 406 407 /* Different windows have different format/modifier support */ 408 for (i = 0; i < plane->modifier_count; i++) { 409 if (plane->modifiers[i] == modifier) 410 return true; 411 } 412 413 return false; 414 } 415 416 /* 417 * 0: Full mode, 16 lines for one tail 418 * 1: half block mode, 8 lines one tail 419 */ 420 static bool vop2_half_block_enable(struct drm_plane_state *pstate) 421 { 422 if (pstate->rotation & (DRM_MODE_ROTATE_270 | DRM_MODE_ROTATE_90)) 423 return false; 424 else 425 return true; 426 } 427 428 static u32 vop2_afbc_transform_offset(struct drm_plane_state *pstate, 429 bool afbc_half_block_en) 430 { 431 struct drm_rect *src = &pstate->src; 432 struct drm_framebuffer *fb = pstate->fb; 433 u32 bpp = vop2_get_bpp(fb->format); 434 u32 vir_width = (fb->pitches[0] << 3) / bpp; 435 u32 width = drm_rect_width(src) >> 16; 436 u32 height = drm_rect_height(src) >> 16; 437 u32 act_xoffset = src->x1 >> 16; 438 u32 act_yoffset = src->y1 >> 16; 439 u32 align16_crop = 0; 440 u32 align64_crop = 0; 441 u32 height_tmp; 442 u8 tx, ty; 443 u8 bottom_crop_line_num = 0; 444 445 /* 16 pixel align */ 446 if (height & 0xf) 447 align16_crop = 16 - (height & 0xf); 448 449 height_tmp = height + align16_crop; 450 451 /* 64 pixel align */ 452 if (height_tmp & 0x3f) 453 align64_crop = 64 - (height_tmp & 0x3f); 454 455 bottom_crop_line_num = align16_crop + align64_crop; 456 457 switch (pstate->rotation & 458 (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y | 459 DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270)) { 460 case DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y: 461 tx = 16 - ((act_xoffset + width) & 0xf); 462 ty = bottom_crop_line_num - act_yoffset; 463 break; 464 case DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90: 465 tx = bottom_crop_line_num - act_yoffset; 466 ty = vir_width - width - act_xoffset; 467 break; 468 case DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_270: 469 tx = act_yoffset; 470 ty = act_xoffset; 471 break; 472 case DRM_MODE_REFLECT_X: 473 tx = 16 - ((act_xoffset + width) & 0xf); 474 ty = act_yoffset; 475 break; 476 case DRM_MODE_REFLECT_Y: 477 tx = act_xoffset; 478 ty = bottom_crop_line_num - act_yoffset; 479 break; 480 case DRM_MODE_ROTATE_90: 481 tx = bottom_crop_line_num - act_yoffset; 482 ty = act_xoffset; 483 break; 484 case DRM_MODE_ROTATE_270: 485 tx = act_yoffset; 486 ty = vir_width - width - act_xoffset; 487 break; 488 case 0: 489 tx = act_xoffset; 490 ty = act_yoffset; 491 break; 492 } 493 494 if (afbc_half_block_en) 495 ty &= 0x7f; 496 497 #define TRANSFORM_XOFFSET GENMASK(7, 0) 498 #define TRANSFORM_YOFFSET GENMASK(23, 16) 499 return FIELD_PREP(TRANSFORM_XOFFSET, tx) | 500 FIELD_PREP(TRANSFORM_YOFFSET, ty); 501 } 502 503 /* 504 * A Cluster window has 2048 x 16 line buffer, which can 505 * works at 2048 x 16(Full) or 4096 x 8 (Half) mode. 506 * for Cluster_lb_mode register: 507 * 0: half mode, for plane input width range 2048 ~ 4096 508 * 1: half mode, for cluster work at 2 * 2048 plane mode 509 * 2: half mode, for rotate_90/270 mode 510 * 511 */ 512 static int vop2_get_cluster_lb_mode(struct vop2_win *win, 513 struct drm_plane_state *pstate) 514 { 515 if ((pstate->rotation & DRM_MODE_ROTATE_270) || 516 (pstate->rotation & DRM_MODE_ROTATE_90)) 517 return 2; 518 else 519 return 0; 520 } 521 522 static u16 vop2_scale_factor(u32 src, u32 dst) 523 { 524 u32 fac; 525 int shift; 526 527 if (src == dst) 528 return 0; 529 530 if (dst < 2) 531 return U16_MAX; 532 533 if (src < 2) 534 return 0; 535 536 if (src > dst) 537 shift = 12; 538 else 539 shift = 16; 540 541 src--; 542 dst--; 543 544 fac = DIV_ROUND_UP(src << shift, dst) - 1; 545 546 if (fac > U16_MAX) 547 return U16_MAX; 548 549 return fac; 550 } 551 552 static void vop2_setup_scale(struct vop2 *vop2, const struct vop2_win *win, 553 u32 src_w, u32 src_h, u32 dst_w, 554 u32 dst_h, u32 pixel_format) 555 { 556 const struct drm_format_info *info; 557 u16 hor_scl_mode, ver_scl_mode; 558 u16 hscl_filter_mode, vscl_filter_mode; 559 uint16_t cbcr_src_w = src_w; 560 uint16_t cbcr_src_h = src_h; 561 u8 gt2 = 0; 562 u8 gt4 = 0; 563 u32 val; 564 565 info = drm_format_info(pixel_format); 566 567 if (src_h >= (4 * dst_h)) { 568 gt4 = 1; 569 src_h >>= 2; 570 } else if (src_h >= (2 * dst_h)) { 571 gt2 = 1; 572 src_h >>= 1; 573 } 574 575 hor_scl_mode = scl_get_scl_mode(src_w, dst_w); 576 ver_scl_mode = scl_get_scl_mode(src_h, dst_h); 577 578 if (hor_scl_mode == SCALE_UP) 579 hscl_filter_mode = VOP2_SCALE_UP_BIC; 580 else 581 hscl_filter_mode = VOP2_SCALE_DOWN_BIL; 582 583 if (ver_scl_mode == SCALE_UP) 584 vscl_filter_mode = VOP2_SCALE_UP_BIL; 585 else 586 vscl_filter_mode = VOP2_SCALE_DOWN_BIL; 587 588 /* 589 * RK3568 VOP Esmart/Smart dsp_w should be even pixel 590 * at scale down mode 591 */ 592 if (!(win->data->feature & WIN_FEATURE_AFBDC)) { 593 if ((hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1)) { 594 drm_dbg(vop2->drm, "%s dst_w[%d] should align as 2 pixel\n", 595 win->data->name, dst_w); 596 dst_w++; 597 } 598 } 599 600 val = vop2_scale_factor(src_w, dst_w); 601 vop2_win_write(win, VOP2_WIN_SCALE_YRGB_X, val); 602 val = vop2_scale_factor(src_h, dst_h); 603 vop2_win_write(win, VOP2_WIN_SCALE_YRGB_Y, val); 604 605 vop2_win_write(win, VOP2_WIN_VSD_YRGB_GT4, gt4); 606 vop2_win_write(win, VOP2_WIN_VSD_YRGB_GT2, gt2); 607 608 vop2_win_write(win, VOP2_WIN_YRGB_HOR_SCL_MODE, hor_scl_mode); 609 vop2_win_write(win, VOP2_WIN_YRGB_VER_SCL_MODE, ver_scl_mode); 610 611 if (vop2_cluster_window(win)) 612 return; 613 614 vop2_win_write(win, VOP2_WIN_YRGB_HSCL_FILTER_MODE, hscl_filter_mode); 615 vop2_win_write(win, VOP2_WIN_YRGB_VSCL_FILTER_MODE, vscl_filter_mode); 616 617 if (info->is_yuv) { 618 cbcr_src_w /= info->hsub; 619 cbcr_src_h /= info->vsub; 620 621 gt4 = 0; 622 gt2 = 0; 623 624 if (cbcr_src_h >= (4 * dst_h)) { 625 gt4 = 1; 626 cbcr_src_h >>= 2; 627 } else if (cbcr_src_h >= (2 * dst_h)) { 628 gt2 = 1; 629 cbcr_src_h >>= 1; 630 } 631 632 hor_scl_mode = scl_get_scl_mode(cbcr_src_w, dst_w); 633 ver_scl_mode = scl_get_scl_mode(cbcr_src_h, dst_h); 634 635 val = vop2_scale_factor(cbcr_src_w, dst_w); 636 vop2_win_write(win, VOP2_WIN_SCALE_CBCR_X, val); 637 638 val = vop2_scale_factor(cbcr_src_h, dst_h); 639 vop2_win_write(win, VOP2_WIN_SCALE_CBCR_Y, val); 640 641 vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT4, gt4); 642 vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT2, gt2); 643 vop2_win_write(win, VOP2_WIN_CBCR_HOR_SCL_MODE, hor_scl_mode); 644 vop2_win_write(win, VOP2_WIN_CBCR_VER_SCL_MODE, ver_scl_mode); 645 vop2_win_write(win, VOP2_WIN_CBCR_HSCL_FILTER_MODE, hscl_filter_mode); 646 vop2_win_write(win, VOP2_WIN_CBCR_VSCL_FILTER_MODE, vscl_filter_mode); 647 } 648 } 649 650 static int vop2_convert_csc_mode(int csc_mode) 651 { 652 switch (csc_mode) { 653 case V4L2_COLORSPACE_SMPTE170M: 654 case V4L2_COLORSPACE_470_SYSTEM_M: 655 case V4L2_COLORSPACE_470_SYSTEM_BG: 656 return CSC_BT601L; 657 case V4L2_COLORSPACE_REC709: 658 case V4L2_COLORSPACE_SMPTE240M: 659 case V4L2_COLORSPACE_DEFAULT: 660 return CSC_BT709L; 661 case V4L2_COLORSPACE_JPEG: 662 return CSC_BT601F; 663 case V4L2_COLORSPACE_BT2020: 664 return CSC_BT2020L; 665 default: 666 return CSC_BT709L; 667 } 668 } 669 670 /* 671 * colorspace path: 672 * Input Win csc Output 673 * 1. YUV(2020) --> Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709) 674 * RGB --> R2Y __/ 675 * 676 * 2. YUV(2020) --> bypasss --> YUV_OUTPUT(2020) 677 * RGB --> 709To2020->R2Y __/ 678 * 679 * 3. YUV(2020) --> Y2R->2020To709 --> RGB_OUTPUT(709) 680 * RGB --> R2Y __/ 681 * 682 * 4. YUV(601/709)-> Y2R->709To2020->R2Y --> YUV_OUTPUT(2020) 683 * RGB --> 709To2020->R2Y __/ 684 * 685 * 5. YUV(601/709)-> bypass --> YUV_OUTPUT(709) 686 * RGB --> R2Y __/ 687 * 688 * 6. YUV(601/709)-> bypass --> YUV_OUTPUT(601) 689 * RGB --> R2Y(601) __/ 690 * 691 * 7. YUV --> Y2R(709) --> RGB_OUTPUT(709) 692 * RGB --> bypass __/ 693 * 694 * 8. RGB --> 709To2020->R2Y --> YUV_OUTPUT(2020) 695 * 696 * 9. RGB --> R2Y(709) --> YUV_OUTPUT(709) 697 * 698 * 10. RGB --> R2Y(601) --> YUV_OUTPUT(601) 699 * 700 * 11. RGB --> bypass --> RGB_OUTPUT(709) 701 */ 702 703 static void vop2_setup_csc_mode(struct vop2_video_port *vp, 704 struct vop2_win *win, 705 struct drm_plane_state *pstate) 706 { 707 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); 708 int is_input_yuv = pstate->fb->format->is_yuv; 709 int is_output_yuv = is_yuv_output(vcstate->bus_format); 710 int input_csc = V4L2_COLORSPACE_DEFAULT; 711 int output_csc = vcstate->color_space; 712 bool r2y_en, y2r_en; 713 int csc_mode; 714 715 if (is_input_yuv && !is_output_yuv) { 716 y2r_en = true; 717 r2y_en = false; 718 csc_mode = vop2_convert_csc_mode(input_csc); 719 } else if (!is_input_yuv && is_output_yuv) { 720 y2r_en = false; 721 r2y_en = true; 722 csc_mode = vop2_convert_csc_mode(output_csc); 723 } else { 724 y2r_en = false; 725 r2y_en = false; 726 csc_mode = false; 727 } 728 729 vop2_win_write(win, VOP2_WIN_Y2R_EN, y2r_en); 730 vop2_win_write(win, VOP2_WIN_R2Y_EN, r2y_en); 731 vop2_win_write(win, VOP2_WIN_CSC_MODE, csc_mode); 732 } 733 734 /* 735 * RGB-to-YCbCr conversion based on color_to_ycbcr() and rgb2ycbcr() from 736 * drivers/media/common/v4l2-tpg/v4l2-tpg-core.c. 737 * 738 * Limited-range Y offset & chroma midpoint are expressed in 16-bit space. 739 */ 740 #define RGB2YUV_LIMITED_Y_OFFSET (16 << 8) 741 #define RGB2YUV_CHROMA_OFFSET (128 << 8) 742 #define COEFF(v, r) ((s32)(0.5 + (v) * (r) * 256.0)) 743 744 struct rgb2yuv_matrix { 745 s32 y_r, y_g, y_b; 746 s32 cb_r, cb_g, cb_b; 747 s32 cr_r, cr_g, cr_b; 748 s32 y_offset; 749 }; 750 751 /* BT.601 Limited range */ 752 static const struct rgb2yuv_matrix rgb2yuv_bt601l = { 753 .y_r = COEFF(0.299, 219), .y_g = COEFF(0.587, 219), .y_b = COEFF(0.114, 219), 754 .cb_r = COEFF(-0.1687, 224), .cb_g = COEFF(-0.3313, 224), .cb_b = COEFF(0.5, 224), 755 .cr_r = COEFF(0.5, 224), .cr_g = COEFF(-0.4187, 224), .cr_b = COEFF(-0.0813, 224), 756 .y_offset = RGB2YUV_LIMITED_Y_OFFSET, 757 }; 758 759 /* BT.601 Full range */ 760 static const struct rgb2yuv_matrix rgb2yuv_bt601f = { 761 .y_r = COEFF(0.299, 255), .y_g = COEFF(0.587, 255), .y_b = COEFF(0.114, 255), 762 .cb_r = COEFF(-0.1687, 255), .cb_g = COEFF(-0.3313, 255), .cb_b = COEFF(0.5, 255), 763 .cr_r = COEFF(0.5, 255), .cr_g = COEFF(-0.4187, 255), .cr_b = COEFF(-0.0813, 255), 764 .y_offset = 0, 765 }; 766 767 /* BT.709 Limited range */ 768 static const struct rgb2yuv_matrix rgb2yuv_bt709l = { 769 .y_r = COEFF(0.2126, 219), .y_g = COEFF(0.7152, 219), .y_b = COEFF(0.0722, 219), 770 .cb_r = COEFF(-0.1146, 224), .cb_g = COEFF(-0.3854, 224), .cb_b = COEFF(0.5, 224), 771 .cr_r = COEFF(0.5, 224), .cr_g = COEFF(-0.4542, 224), .cr_b = COEFF(-0.0458, 224), 772 .y_offset = RGB2YUV_LIMITED_Y_OFFSET, 773 }; 774 775 /* BT.2020 Limited range */ 776 static const struct rgb2yuv_matrix rgb2yuv_bt2020l = { 777 .y_r = COEFF(0.2627, 219), .y_g = COEFF(0.6780, 219), .y_b = COEFF(0.0593, 219), 778 .cb_r = COEFF(-0.1396, 224), .cb_g = COEFF(-0.3604, 224), .cb_b = COEFF(0.5, 224), 779 .cr_r = COEFF(0.5, 224), .cr_g = COEFF(-0.4598, 224), .cr_b = COEFF(-0.0402, 224), 780 .y_offset = RGB2YUV_LIMITED_Y_OFFSET, 781 }; 782 783 static const struct rgb2yuv_matrix * 784 vop2_rgb2yuv_get_matrix(enum vop_csc_format csc) 785 { 786 switch (csc) { 787 case CSC_BT601L: 788 return &rgb2yuv_bt601l; 789 case CSC_BT601F: 790 return &rgb2yuv_bt601f; 791 case CSC_BT2020L: 792 return &rgb2yuv_bt2020l; 793 case CSC_BT709L: 794 default: 795 return &rgb2yuv_bt709l; 796 } 797 } 798 799 /* Convert an RGB (16bpc) to YUV444 (16bpc). */ 800 static void vop2_rgb16_to_yuv16(int v4l2_cs, u16 r, u16 g, u16 b, 801 u16 *y, u16 *cb, u16 *cr) 802 { 803 enum vop_csc_format csc = vop2_convert_csc_mode(v4l2_cs); 804 const struct rgb2yuv_matrix *m = vop2_rgb2yuv_get_matrix(csc); 805 s64 rs = r, gs = g, bs = b; 806 s64 ys, cbs, crs; 807 808 ys = m->y_r * rs + m->y_g * gs + m->y_b * bs; 809 cbs = m->cb_r * rs + m->cb_g * gs + m->cb_b * bs; 810 crs = m->cr_r * rs + m->cr_g * gs + m->cr_b * bs; 811 812 *y = (ys >> 16) + m->y_offset; 813 *cb = (cbs >> 16) + RGB2YUV_CHROMA_OFFSET; 814 *cr = (crs >> 16) + RGB2YUV_CHROMA_OFFSET; 815 } 816 817 static void vop2_crtc_enable_irq(struct vop2_video_port *vp, u32 irq) 818 { 819 struct vop2 *vop2 = vp->vop2; 820 821 vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irq << 16 | irq); 822 vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16 | irq); 823 } 824 825 static void vop2_crtc_disable_irq(struct vop2_video_port *vp, u32 irq) 826 { 827 struct vop2 *vop2 = vp->vop2; 828 829 vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16); 830 } 831 832 static int vop2_core_clks_prepare_enable(struct vop2 *vop2) 833 { 834 int ret; 835 836 ret = clk_prepare_enable(vop2->hclk); 837 if (ret < 0) { 838 drm_err(vop2->drm, "failed to enable hclk - %d\n", ret); 839 return ret; 840 } 841 842 ret = clk_prepare_enable(vop2->aclk); 843 if (ret < 0) { 844 drm_err(vop2->drm, "failed to enable aclk - %d\n", ret); 845 goto err; 846 } 847 848 ret = clk_prepare_enable(vop2->pclk); 849 if (ret < 0) { 850 drm_err(vop2->drm, "failed to enable pclk - %d\n", ret); 851 goto err1; 852 } 853 854 return 0; 855 err1: 856 clk_disable_unprepare(vop2->aclk); 857 err: 858 clk_disable_unprepare(vop2->hclk); 859 860 return ret; 861 } 862 863 static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2) 864 { 865 u32 pd; 866 867 pd = vop2_readl(vop2, RK3588_SYS_PD_CTRL); 868 pd &= ~(VOP2_PD_CLUSTER0 | VOP2_PD_CLUSTER1 | VOP2_PD_CLUSTER2 | 869 VOP2_PD_CLUSTER3 | VOP2_PD_ESMART); 870 871 vop2_writel(vop2, RK3588_SYS_PD_CTRL, pd); 872 } 873 874 static void vop2_enable(struct vop2 *vop2) 875 { 876 int ret; 877 u32 version; 878 879 ret = pm_runtime_resume_and_get(vop2->dev); 880 if (ret < 0) { 881 drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret); 882 return; 883 } 884 885 ret = vop2_core_clks_prepare_enable(vop2); 886 if (ret) { 887 pm_runtime_put_sync(vop2->dev); 888 return; 889 } 890 891 ret = rockchip_drm_dma_attach_device(vop2->drm, vop2->dev); 892 if (ret) { 893 drm_err(vop2->drm, "failed to attach dma mapping, %d\n", ret); 894 return; 895 } 896 897 version = vop2_readl(vop2, RK3568_VERSION_INFO); 898 if (version != vop2->version) { 899 drm_err(vop2->drm, "Hardware version(0x%08x) mismatch\n", version); 900 return; 901 } 902 903 /* 904 * rk3566 share the same vop version with rk3568, so 905 * we need to use soc_id for identification here. 906 */ 907 if (vop2->data->soc_id == 3566) 908 vop2_writel(vop2, RK3568_OTP_WIN_EN, 1); 909 910 if (vop2->version == VOP_VERSION_RK3588) 911 rk3588_vop2_power_domain_enable_all(vop2); 912 913 if (vop2->version <= VOP_VERSION_RK3588) { 914 vop2->old_layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL); 915 vop2->old_port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL); 916 } 917 918 vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN); 919 920 /* 921 * Disable auto gating, this is a workaround to 922 * avoid display image shift when a window enabled. 923 */ 924 regmap_clear_bits(vop2->map, RK3568_SYS_AUTO_GATING_CTRL, 925 RK3568_SYS_AUTO_GATING_CTRL__AUTO_GATING_EN); 926 927 vop2_writel(vop2, RK3568_SYS0_INT_CLR, 928 VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR); 929 vop2_writel(vop2, RK3568_SYS0_INT_EN, 930 VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR); 931 vop2_writel(vop2, RK3568_SYS1_INT_CLR, 932 VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR); 933 vop2_writel(vop2, RK3568_SYS1_INT_EN, 934 VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR); 935 } 936 937 static void vop2_disable(struct vop2 *vop2) 938 { 939 rockchip_drm_dma_detach_device(vop2->drm, vop2->dev); 940 941 pm_runtime_put_sync(vop2->dev); 942 943 regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register); 944 945 clk_disable_unprepare(vop2->pclk); 946 clk_disable_unprepare(vop2->aclk); 947 clk_disable_unprepare(vop2->hclk); 948 } 949 950 static bool vop2_vp_dsp_lut_is_enabled(struct vop2_video_port *vp) 951 { 952 u32 dsp_ctrl = vop2_vp_read(vp, RK3568_VP_DSP_CTRL); 953 954 return dsp_ctrl & RK3568_VP_DSP_CTRL__DSP_LUT_EN; 955 } 956 957 static void vop2_vp_dsp_lut_disable(struct vop2_video_port *vp) 958 { 959 u32 dsp_ctrl = vop2_vp_read(vp, RK3568_VP_DSP_CTRL); 960 961 dsp_ctrl &= ~RK3568_VP_DSP_CTRL__DSP_LUT_EN; 962 vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl); 963 } 964 965 static bool vop2_vp_dsp_lut_poll_disabled(struct vop2_video_port *vp) 966 { 967 u32 dsp_ctrl; 968 int ret = readx_poll_timeout(vop2_vp_dsp_lut_is_enabled, vp, dsp_ctrl, 969 !dsp_ctrl, 5, 30 * 1000); 970 if (ret) { 971 drm_err(vp->vop2->drm, "display LUT RAM enable timeout!\n"); 972 return false; 973 } 974 975 return true; 976 } 977 978 static void vop2_vp_dsp_lut_enable(struct vop2_video_port *vp) 979 { 980 u32 dsp_ctrl = vop2_vp_read(vp, RK3568_VP_DSP_CTRL); 981 982 dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_LUT_EN; 983 vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl); 984 } 985 986 static void vop2_vp_dsp_lut_update_enable(struct vop2_video_port *vp) 987 { 988 u32 dsp_ctrl = vop2_vp_read(vp, RK3568_VP_DSP_CTRL); 989 990 dsp_ctrl |= RK3588_VP_DSP_CTRL__GAMMA_UPDATE_EN; 991 vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl); 992 } 993 994 static inline bool vop2_supports_seamless_gamma_lut_update(struct vop2 *vop2) 995 { 996 return vop2->version != VOP_VERSION_RK3568; 997 } 998 999 static bool vop2_gamma_lut_in_use(struct vop2 *vop2, struct vop2_video_port *vp) 1000 { 1001 const int nr_vps = vop2->data->nr_vps; 1002 int gamma_en_vp_id; 1003 1004 for (gamma_en_vp_id = 0; gamma_en_vp_id < nr_vps; gamma_en_vp_id++) 1005 if (vop2_vp_dsp_lut_is_enabled(&vop2->vps[gamma_en_vp_id])) 1006 break; 1007 1008 return gamma_en_vp_id != nr_vps && gamma_en_vp_id != vp->id; 1009 } 1010 1011 static void vop2_crtc_atomic_disable(struct drm_crtc *crtc, 1012 struct drm_atomic_commit *state) 1013 { 1014 struct vop2_video_port *vp = to_vop2_video_port(crtc); 1015 struct vop2 *vop2 = vp->vop2; 1016 struct drm_crtc_state *old_crtc_state; 1017 int ret; 1018 1019 vop2_lock(vop2); 1020 1021 old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); 1022 drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false); 1023 1024 drm_crtc_vblank_off(crtc); 1025 1026 /* 1027 * Vop standby will take effect at end of current frame, 1028 * if dsp hold valid irq happen, it means standby complete. 1029 * 1030 * we must wait standby complete when we want to disable aclk, 1031 * if not, memory bus maybe dead. 1032 */ 1033 reinit_completion(&vp->dsp_hold_completion); 1034 1035 vop2_crtc_enable_irq(vp, VP_INT_DSP_HOLD_VALID); 1036 1037 vop2_vp_write(vp, RK3568_VP_DSP_CTRL, RK3568_VP_DSP_CTRL__STANDBY); 1038 1039 ret = wait_for_completion_timeout(&vp->dsp_hold_completion, 1040 msecs_to_jiffies(50)); 1041 if (!ret) 1042 drm_info(vop2->drm, "wait for vp%d dsp_hold timeout\n", vp->id); 1043 1044 vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID); 1045 1046 if (vp->dclk_src) 1047 clk_set_parent(vp->dclk, vp->dclk_src); 1048 1049 clk_disable_unprepare(vp->dclk); 1050 1051 vop2->enable_count--; 1052 1053 if (!vop2->enable_count) 1054 vop2_disable(vop2); 1055 1056 vop2_unlock(vop2); 1057 1058 if (crtc->state->event && !crtc->state->active) { 1059 spin_lock_irq(&crtc->dev->event_lock); 1060 drm_crtc_send_vblank_event(crtc, crtc->state->event); 1061 spin_unlock_irq(&crtc->dev->event_lock); 1062 1063 crtc->state->event = NULL; 1064 } 1065 } 1066 1067 static int vop2_plane_atomic_check(struct drm_plane *plane, 1068 struct drm_atomic_commit *astate) 1069 { 1070 struct drm_plane_state *pstate = drm_atomic_get_new_plane_state(astate, plane); 1071 struct drm_framebuffer *fb = pstate->fb; 1072 struct drm_crtc *crtc = pstate->crtc; 1073 struct drm_crtc_state *cstate; 1074 struct vop2_video_port *vp; 1075 struct vop2_win *win = to_vop2_win(plane); 1076 struct vop2 *vop2; 1077 const struct vop2_data *vop2_data; 1078 struct drm_rect *dest = &pstate->dst; 1079 struct drm_rect *src = &pstate->src; 1080 int min_scale = FRAC_16_16(1, 8); 1081 int max_scale = FRAC_16_16(8, 1); 1082 int src_x, src_w, src_h; 1083 int dest_w, dest_h; 1084 int format; 1085 int ret; 1086 1087 if (!crtc) 1088 return 0; 1089 1090 vp = to_vop2_video_port(crtc); 1091 vop2 = vp->vop2; 1092 vop2_data = vop2->data; 1093 1094 cstate = drm_atomic_get_new_crtc_state(pstate->state, crtc); 1095 if (WARN_ON(!cstate)) 1096 return -EINVAL; 1097 1098 ret = drm_atomic_helper_check_plane_state(pstate, cstate, 1099 min_scale, max_scale, 1100 true, true); 1101 if (ret) 1102 return ret; 1103 1104 if (!pstate->visible) 1105 return 0; 1106 1107 format = vop2_convert_format(fb->format->format); 1108 /* We shouldn't be able to create a fb for an unsupported format */ 1109 if (WARN_ON(format < 0)) 1110 return format; 1111 1112 /* Co-ordinates have now been clipped */ 1113 src_x = src->x1 >> 16; 1114 src_w = drm_rect_width(src) >> 16; 1115 src_h = drm_rect_height(src) >> 16; 1116 dest_w = drm_rect_width(dest); 1117 dest_h = drm_rect_height(dest); 1118 1119 if (src_w < 4 || src_h < 4 || dest_w < 4 || dest_h < 4) { 1120 drm_dbg_kms(vop2->drm, "Invalid size: %dx%d->%dx%d, min size is 4x4\n", 1121 src_w, src_h, dest_w, dest_h); 1122 return -EINVAL; 1123 } 1124 1125 if (src_w > vop2_data->max_input.width || 1126 src_h > vop2_data->max_input.height) { 1127 drm_dbg_kms(vop2->drm, "Invalid source: %dx%d. max input: %dx%d\n", 1128 src_w, src_h, 1129 vop2_data->max_input.width, 1130 vop2_data->max_input.height); 1131 return -EINVAL; 1132 } 1133 1134 /* 1135 * Src.x1 can be odd when do clip, but yuv plane start point 1136 * need align with 2 pixel. 1137 */ 1138 if (fb->format->is_yuv && src_x % 2) { 1139 drm_dbg_kms(vop2->drm, "Invalid Source: Yuv format not support odd xpos\n"); 1140 return -EINVAL; 1141 } 1142 1143 /* 1144 * This is workaround solution for IC design: 1145 * esmart can't support scale down when src_w % 16 == 1. 1146 */ 1147 if (!vop2_cluster_window(win) && src_w > dest_w && (src_w & 1)) { 1148 drm_dbg_kms(vop2->drm, 1149 "Esmart windows cannot downscale odd-width source regions\n"); 1150 return -EINVAL; 1151 } 1152 1153 if (vop2->version == VOP_VERSION_RK3568 && drm_is_afbc(fb->modifier) && src_w % 4) { 1154 drm_dbg_kms(vop2->drm, 1155 "AFBC source rectangles must be 4-pixel aligned; is %d\n", 1156 src_w); 1157 return -EINVAL; 1158 } 1159 1160 if (drm_is_afbc(fb->modifier) && 1161 pstate->rotation & 1162 (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270) && 1163 (fb->pitches[0] << 3) / vop2_get_bpp(fb->format) % 64) { 1164 drm_dbg_kms(vop2->drm, 1165 "AFBC buffers must be 64-pixel aligned for horizontal rotation or mirroring\n"); 1166 return -EINVAL; 1167 } 1168 1169 if ((cstate->background_color << 16) && 1170 (fb->format->has_alpha || pstate->alpha != 0xffff)) { 1171 drm_dbg_kms(vop2->drm, 1172 "Alpha-blending with background color is unsupported\n"); 1173 return -EINVAL; 1174 } 1175 1176 return 0; 1177 } 1178 1179 static void vop2_plane_atomic_disable(struct drm_plane *plane, 1180 struct drm_atomic_commit *state) 1181 { 1182 struct drm_plane_state *old_pstate = NULL; 1183 struct vop2_win *win = to_vop2_win(plane); 1184 struct vop2 *vop2 = win->vop2; 1185 1186 drm_dbg(vop2->drm, "%s disable\n", win->data->name); 1187 1188 if (state) 1189 old_pstate = drm_atomic_get_old_plane_state(state, plane); 1190 if (old_pstate && !old_pstate->crtc) 1191 return; 1192 1193 vop2_win_disable(win); 1194 vop2_win_write(win, VOP2_WIN_YUV_CLIP, 0); 1195 } 1196 1197 /* 1198 * The color key is 10 bit, so all format should 1199 * convert to 10 bit here. 1200 */ 1201 static void vop2_plane_setup_color_key(struct drm_plane *plane, u32 color_key) 1202 { 1203 struct drm_plane_state *pstate = plane->state; 1204 struct drm_framebuffer *fb = pstate->fb; 1205 struct vop2_win *win = to_vop2_win(plane); 1206 u32 color_key_en = 0; 1207 u32 r = 0; 1208 u32 g = 0; 1209 u32 b = 0; 1210 1211 if (!(color_key & VOP2_COLOR_KEY_MASK) || fb->format->is_yuv) { 1212 vop2_win_write(win, VOP2_WIN_COLOR_KEY_EN, 0); 1213 return; 1214 } 1215 1216 switch (fb->format->format) { 1217 case DRM_FORMAT_RGB565: 1218 case DRM_FORMAT_BGR565: 1219 r = (color_key & 0xf800) >> 11; 1220 g = (color_key & 0x7e0) >> 5; 1221 b = (color_key & 0x1f); 1222 r <<= 5; 1223 g <<= 4; 1224 b <<= 5; 1225 color_key_en = 1; 1226 break; 1227 case DRM_FORMAT_XRGB8888: 1228 case DRM_FORMAT_ARGB8888: 1229 case DRM_FORMAT_XBGR8888: 1230 case DRM_FORMAT_ABGR8888: 1231 case DRM_FORMAT_RGB888: 1232 case DRM_FORMAT_BGR888: 1233 r = (color_key & 0xff0000) >> 16; 1234 g = (color_key & 0xff00) >> 8; 1235 b = (color_key & 0xff); 1236 r <<= 2; 1237 g <<= 2; 1238 b <<= 2; 1239 color_key_en = 1; 1240 break; 1241 } 1242 1243 vop2_win_write(win, VOP2_WIN_COLOR_KEY_EN, color_key_en); 1244 vop2_win_write(win, VOP2_WIN_COLOR_KEY, (r << 20) | (g << 10) | b); 1245 } 1246 1247 static void vop2_plane_atomic_update(struct drm_plane *plane, 1248 struct drm_atomic_commit *state) 1249 { 1250 struct drm_plane_state *pstate = plane->state; 1251 struct drm_crtc *crtc = pstate->crtc; 1252 struct vop2_win *win = to_vop2_win(plane); 1253 struct vop2_video_port *vp = to_vop2_video_port(crtc); 1254 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; 1255 struct vop2 *vop2 = win->vop2; 1256 struct drm_framebuffer *fb = pstate->fb; 1257 u32 bpp = vop2_get_bpp(fb->format); 1258 u32 src_w, src_h, dsp_w, dsp_h; 1259 u32 act_info, dsp_info; 1260 u32 format; 1261 u32 afbc_format; 1262 u32 rb_swap; 1263 u32 uv_swap; 1264 struct drm_rect *src = &pstate->src; 1265 struct drm_rect *dest = &pstate->dst; 1266 u32 afbc_tile_num; 1267 u32 transform_offset; 1268 bool dither_up; 1269 bool xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false; 1270 bool ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false; 1271 bool rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270; 1272 bool rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90; 1273 struct rockchip_gem_object *rk_obj; 1274 unsigned long offset; 1275 bool half_block_en; 1276 bool afbc_en; 1277 dma_addr_t yrgb_mst; 1278 dma_addr_t uv_mst; 1279 1280 /* 1281 * can't update plane when vop2 is disabled. 1282 */ 1283 if (WARN_ON(!crtc)) 1284 return; 1285 1286 if (!pstate->visible) { 1287 vop2_plane_atomic_disable(plane, state); 1288 return; 1289 } 1290 1291 afbc_en = drm_is_afbc(fb->modifier); 1292 1293 offset = (src->x1 >> 16) * fb->format->cpp[0]; 1294 1295 /* 1296 * AFBC HDR_PTR must set to the zero offset of the framebuffer. 1297 */ 1298 if (afbc_en) 1299 offset = 0; 1300 else if (pstate->rotation & DRM_MODE_REFLECT_Y) 1301 offset += ((src->y2 >> 16) - 1) * fb->pitches[0]; 1302 else 1303 offset += (src->y1 >> 16) * fb->pitches[0]; 1304 1305 rk_obj = to_rockchip_obj(fb->obj[0]); 1306 1307 yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0]; 1308 if (fb->format->is_yuv) { 1309 int hsub = fb->format->hsub; 1310 int vsub = fb->format->vsub; 1311 1312 offset = (src->x1 >> 16) * fb->format->cpp[1] / hsub; 1313 offset += (src->y1 >> 16) * fb->pitches[1] / vsub; 1314 1315 if ((pstate->rotation & DRM_MODE_REFLECT_Y) && !afbc_en) 1316 offset += fb->pitches[1] * ((pstate->src_h >> 16) - 2) / vsub; 1317 1318 rk_obj = to_rockchip_obj(fb->obj[0]); 1319 uv_mst = rk_obj->dma_addr + offset + fb->offsets[1]; 1320 } 1321 1322 src_w = drm_rect_width(src) >> 16; 1323 src_h = drm_rect_height(src) >> 16; 1324 dsp_w = drm_rect_width(dest); 1325 dsp_h = drm_rect_height(dest); 1326 1327 /* drm_atomic_helper_check_plane_state calls drm_rect_clip_scaled for 1328 * us, which keeps our planes bounded within the CRTC active area 1329 */ 1330 if (WARN_ON(dest->x1 + dsp_w > adjusted_mode->hdisplay) || 1331 WARN_ON(dest->y1 + dsp_h > adjusted_mode->vdisplay) || 1332 WARN_ON(dsp_w < 4) || WARN_ON(dsp_h < 4) || 1333 WARN_ON(src_w < 4) || WARN_ON(src_h < 4)) 1334 return; 1335 1336 if (vop2->version == VOP_VERSION_RK3568 && drm_is_afbc(fb->modifier)) 1337 if (WARN_ON(src_w % 4)) 1338 return; 1339 1340 act_info = (src_h - 1) << 16 | ((src_w - 1) & 0xffff); 1341 dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff); 1342 1343 format = vop2_convert_format(fb->format->format); 1344 half_block_en = vop2_half_block_enable(pstate); 1345 1346 drm_dbg(vop2->drm, "vp%d update %s[%dx%d->%dx%d@%dx%d] fmt[%p4cc_%s] addr[%pad]\n", 1347 vp->id, win->data->name, src_w, src_h, dsp_w, dsp_h, 1348 dest->x1, dest->y1, 1349 &fb->format->format, 1350 afbc_en ? "AFBC" : "", &yrgb_mst); 1351 1352 if (vop2->version > VOP_VERSION_RK3568) { 1353 vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data->axi_bus_id); 1354 vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data->axi_yrgb_r_id); 1355 vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id); 1356 } 1357 1358 if (vop2->version >= VOP_VERSION_RK3576) 1359 vop2_win_write(win, VOP2_WIN_VP_SEL, vp->id); 1360 1361 if (vop2_cluster_window(win)) 1362 vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en); 1363 1364 if (afbc_en) { 1365 u32 stride, block_w; 1366 1367 /* the afbc superblock is 16 x 16 or 32 x 8 */ 1368 block_w = fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 ? 32 : 16; 1369 1370 afbc_format = vop2_convert_afbc_format(fb->format->format); 1371 1372 /* Enable color transform for YTR */ 1373 if (fb->modifier & AFBC_FORMAT_MOD_YTR) 1374 afbc_format |= (1 << 4); 1375 1376 afbc_tile_num = ALIGN(src_w, block_w) / block_w; 1377 1378 /* 1379 * AFBC pic_vir_width is count by pixel, this is different 1380 * with WIN_VIR_STRIDE. 1381 */ 1382 stride = (fb->pitches[0] << 3) / bpp; 1383 1384 /* It's for head stride, each head size is 16 byte */ 1385 stride = ALIGN(stride, block_w) / block_w * 16; 1386 1387 uv_swap = vop2_afbc_uv_swap(fb->format->format); 1388 /* 1389 * This is a workaround for crazy IC design, Cluster 1390 * and Esmart/Smart use different format configuration map: 1391 * YUV420_10BIT: 0x10 for Cluster, 0x14 for Esmart/Smart. 1392 * 1393 * This is one thing we can make the convert simple: 1394 * AFBCD decode all the YUV data to YUV444. So we just 1395 * set all the yuv 10 bit to YUV444_10. 1396 */ 1397 if (fb->format->is_yuv && bpp == 10) 1398 format = VOP2_CLUSTER_YUV444_10; 1399 1400 if (vop2_cluster_window(win)) 1401 vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1); 1402 vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format); 1403 vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap); 1404 /* 1405 * On rk3566/8, this bit is auto gating enable, 1406 * but this function is not work well so we need 1407 * to disable it for these two platform. 1408 * On rk3588, and the following new soc(rk3528/rk3576), 1409 * this bit is gating disable, we should write 1 to 1410 * disable gating when enable afbc. 1411 */ 1412 if (vop2->version == VOP_VERSION_RK3568) 1413 vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0); 1414 else 1415 vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1); 1416 1417 if (fb->modifier & AFBC_FORMAT_MOD_SPLIT) 1418 vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 1); 1419 else 1420 vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0); 1421 1422 if (vop2->version >= VOP_VERSION_RK3576) { 1423 vop2_win_write(win, VOP2_WIN_AFBC_PLD_OFFSET_EN, 1); 1424 vop2_win_write(win, VOP2_WIN_AFBC_PLD_OFFSET, yrgb_mst); 1425 } 1426 1427 transform_offset = vop2_afbc_transform_offset(pstate, half_block_en); 1428 vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst); 1429 vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info); 1430 vop2_win_write(win, VOP2_WIN_TRANSFORM_OFFSET, transform_offset); 1431 vop2_win_write(win, VOP2_WIN_AFBC_PIC_OFFSET, ((src->x1 >> 16) | src->y1)); 1432 vop2_win_write(win, VOP2_WIN_AFBC_DSP_OFFSET, (dest->x1 | (dest->y1 << 16))); 1433 vop2_win_write(win, VOP2_WIN_AFBC_PIC_VIR_WIDTH, stride); 1434 vop2_win_write(win, VOP2_WIN_AFBC_TILE_NUM, afbc_tile_num); 1435 vop2_win_write(win, VOP2_WIN_XMIRROR, xmirror); 1436 vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_270, rotate_270); 1437 vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_90, rotate_90); 1438 } else { 1439 if (vop2_cluster_window(win)) { 1440 vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 0); 1441 vop2_win_write(win, VOP2_WIN_TRANSFORM_OFFSET, 0); 1442 } 1443 1444 vop2_win_write(win, VOP2_WIN_YRGB_VIR, DIV_ROUND_UP(fb->pitches[0], 4)); 1445 } 1446 1447 vop2_win_write(win, VOP2_WIN_YMIRROR, ymirror); 1448 1449 if (rotate_90 || rotate_270) { 1450 act_info = swahw32(act_info); 1451 src_w = drm_rect_height(src) >> 16; 1452 src_h = drm_rect_width(src) >> 16; 1453 } 1454 1455 vop2_win_write(win, VOP2_WIN_FORMAT, format); 1456 vop2_win_write(win, VOP2_WIN_YRGB_MST, yrgb_mst); 1457 1458 rb_swap = vop2_win_rb_swap(fb->format->format); 1459 vop2_win_write(win, VOP2_WIN_RB_SWAP, rb_swap); 1460 uv_swap = vop2_win_uv_swap(fb->format->format); 1461 vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap); 1462 1463 if (fb->format->is_yuv) { 1464 vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4)); 1465 vop2_win_write(win, VOP2_WIN_UV_MST, uv_mst); 1466 } 1467 1468 vop2_setup_scale(vop2, win, src_w, src_h, dsp_w, dsp_h, fb->format->format); 1469 if (!vop2_cluster_window(win)) 1470 vop2_plane_setup_color_key(plane, 0); 1471 vop2_win_write(win, VOP2_WIN_ACT_INFO, act_info); 1472 vop2_win_write(win, VOP2_WIN_DSP_INFO, dsp_info); 1473 vop2_win_write(win, VOP2_WIN_DSP_ST, dest->y1 << 16 | (dest->x1 & 0xffff)); 1474 1475 vop2_setup_csc_mode(vp, win, pstate); 1476 1477 dither_up = vop2_win_dither_up(fb->format->format); 1478 vop2_win_write(win, VOP2_WIN_DITHER_UP, dither_up); 1479 1480 vop2_win_write(win, VOP2_WIN_ENABLE, 1); 1481 1482 if (vop2_cluster_window(win)) { 1483 int lb_mode = vop2_get_cluster_lb_mode(win, pstate); 1484 1485 vop2_win_write(win, VOP2_WIN_CLUSTER_LB_MODE, lb_mode); 1486 vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 1); 1487 } 1488 } 1489 1490 static const struct drm_plane_helper_funcs vop2_plane_helper_funcs = { 1491 .atomic_check = vop2_plane_atomic_check, 1492 .atomic_update = vop2_plane_atomic_update, 1493 .atomic_disable = vop2_plane_atomic_disable, 1494 }; 1495 1496 static const struct drm_plane_funcs vop2_plane_funcs = { 1497 .update_plane = drm_atomic_helper_update_plane, 1498 .disable_plane = drm_atomic_helper_disable_plane, 1499 .destroy = drm_plane_cleanup, 1500 .reset = drm_atomic_helper_plane_reset, 1501 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 1502 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 1503 .format_mod_supported = rockchip_vop2_mod_supported, 1504 }; 1505 1506 static int vop2_crtc_enable_vblank(struct drm_crtc *crtc) 1507 { 1508 struct vop2_video_port *vp = to_vop2_video_port(crtc); 1509 1510 vop2_crtc_enable_irq(vp, VP_INT_FS_FIELD); 1511 1512 return 0; 1513 } 1514 1515 static void vop2_crtc_disable_vblank(struct drm_crtc *crtc) 1516 { 1517 struct vop2_video_port *vp = to_vop2_video_port(crtc); 1518 1519 vop2_crtc_disable_irq(vp, VP_INT_FS_FIELD); 1520 } 1521 1522 static enum drm_mode_status vop2_crtc_mode_valid(struct drm_crtc *crtc, 1523 const struct drm_display_mode *mode) 1524 { 1525 struct vop2_video_port *vp = to_vop2_video_port(crtc); 1526 1527 if (mode->hdisplay > vp->data->max_output.width) 1528 return MODE_BAD_HVALUE; 1529 1530 return MODE_OK; 1531 } 1532 1533 static bool vop2_crtc_mode_fixup(struct drm_crtc *crtc, 1534 const struct drm_display_mode *mode, 1535 struct drm_display_mode *adj_mode) 1536 { 1537 drm_mode_set_crtcinfo(adj_mode, CRTC_INTERLACE_HALVE_V | 1538 CRTC_STEREO_DOUBLE); 1539 1540 return true; 1541 } 1542 1543 static void vop2_crtc_write_gamma_lut(struct vop2 *vop2, struct drm_crtc *crtc) 1544 { 1545 const struct vop2_video_port *vp = to_vop2_video_port(crtc); 1546 const struct vop2_video_port_data *vp_data = &vop2->data->vp[vp->id]; 1547 struct drm_color_lut *lut = crtc->state->gamma_lut->data; 1548 unsigned int i, bpc = ilog2(vp_data->gamma_lut_len); 1549 u32 word; 1550 1551 for (i = 0; i < crtc->gamma_size; i++) { 1552 word = (drm_color_lut_extract(lut[i].blue, bpc) << (2 * bpc)) | 1553 (drm_color_lut_extract(lut[i].green, bpc) << bpc) | 1554 drm_color_lut_extract(lut[i].red, bpc); 1555 1556 writel(word, vop2->lut_regs + i * 4); 1557 } 1558 } 1559 1560 static void vop2_crtc_atomic_set_gamma_seamless(struct vop2 *vop2, 1561 struct vop2_video_port *vp, 1562 struct drm_crtc *crtc) 1563 { 1564 vop2_writel(vop2, RK3568_LUT_PORT_SEL, 1565 FIELD_PREP(RK3588_LUT_PORT_SEL__GAMMA_AHB_WRITE_SEL, vp->id)); 1566 vop2_vp_dsp_lut_enable(vp); 1567 vop2_crtc_write_gamma_lut(vop2, crtc); 1568 vop2_vp_dsp_lut_update_enable(vp); 1569 } 1570 1571 static void vop2_crtc_atomic_set_gamma_rk356x(struct vop2 *vop2, 1572 struct vop2_video_port *vp, 1573 struct drm_crtc *crtc) 1574 { 1575 vop2_vp_dsp_lut_disable(vp); 1576 vop2_cfg_done(vp); 1577 if (!vop2_vp_dsp_lut_poll_disabled(vp)) 1578 return; 1579 1580 vop2_writel(vop2, RK3568_LUT_PORT_SEL, vp->id); 1581 vop2_crtc_write_gamma_lut(vop2, crtc); 1582 vop2_vp_dsp_lut_enable(vp); 1583 } 1584 1585 static void vop2_crtc_atomic_try_set_gamma(struct vop2 *vop2, 1586 struct vop2_video_port *vp, 1587 struct drm_crtc *crtc, 1588 struct drm_crtc_state *crtc_state) 1589 { 1590 if (!vop2->lut_regs) 1591 return; 1592 1593 if (!crtc_state->gamma_lut) { 1594 vop2_vp_dsp_lut_disable(vp); 1595 return; 1596 } 1597 1598 if (vop2_supports_seamless_gamma_lut_update(vop2)) 1599 vop2_crtc_atomic_set_gamma_seamless(vop2, vp, crtc); 1600 else 1601 vop2_crtc_atomic_set_gamma_rk356x(vop2, vp, crtc); 1602 } 1603 1604 static inline void vop2_crtc_atomic_try_set_gamma_locked(struct vop2 *vop2, 1605 struct vop2_video_port *vp, 1606 struct drm_crtc *crtc, 1607 struct drm_crtc_state *crtc_state) 1608 { 1609 vop2_lock(vop2); 1610 vop2_crtc_atomic_try_set_gamma(vop2, vp, crtc, crtc_state); 1611 vop2_unlock(vop2); 1612 } 1613 1614 static void vop2_dither_setup(struct drm_crtc *crtc, u32 *dsp_ctrl) 1615 { 1616 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); 1617 1618 switch (vcstate->bus_format) { 1619 case MEDIA_BUS_FMT_RGB565_1X16: 1620 *dsp_ctrl |= RK3568_VP_DSP_CTRL__DITHER_DOWN_EN; 1621 break; 1622 case MEDIA_BUS_FMT_RGB666_1X18: 1623 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: 1624 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 1625 *dsp_ctrl |= RK3568_VP_DSP_CTRL__DITHER_DOWN_EN; 1626 *dsp_ctrl |= RGB888_TO_RGB666; 1627 break; 1628 case MEDIA_BUS_FMT_YUV8_1X24: 1629 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 1630 *dsp_ctrl |= RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN; 1631 break; 1632 default: 1633 break; 1634 } 1635 1636 if (vcstate->output_mode != ROCKCHIP_OUT_MODE_AAAA) 1637 *dsp_ctrl |= RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN; 1638 1639 *dsp_ctrl |= FIELD_PREP(RK3568_VP_DSP_CTRL__DITHER_DOWN_SEL, 1640 DITHER_DOWN_ALLEGRO); 1641 } 1642 1643 static void vop2_bgcolor_setup(struct drm_crtc *crtc, bool force, 1644 struct drm_crtc_state *new_crtc_state, 1645 struct drm_crtc_state *old_crtc_state) 1646 { 1647 struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(new_crtc_state); 1648 struct rockchip_crtc_state *old_vcstate = to_rockchip_crtc_state(old_crtc_state); 1649 struct vop2_video_port *vp = to_vop2_video_port(crtc); 1650 u64 bgcolor = new_crtc_state->background_color; 1651 u16 y, cb, cr; 1652 u32 val; 1653 1654 if (!force && old_crtc_state->background_color == bgcolor && 1655 old_vcstate->color_space == new_vcstate->color_space) 1656 return; 1657 1658 /* 1659 * Background color is programmed with 10 bits of precision, using YUV 1660 * format when operating in YUV overlay mode, and RGB otherwise. 1661 */ 1662 if (new_vcstate->yuv_overlay) { 1663 vop2_rgb16_to_yuv16(new_vcstate->color_space, 1664 DRM_ARGB64_GETR(bgcolor), 1665 DRM_ARGB64_GETG(bgcolor), 1666 DRM_ARGB64_GETB(bgcolor), 1667 &y, &cb, &cr); 1668 1669 val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, cr >> 6); 1670 FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_GREEN, &val, y >> 6); 1671 FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_BLUE, &val, cb >> 6); 1672 } else { 1673 /* 1674 * Since performance is more important than accuracy here, make 1675 * use of the DRM_ARGB64_GET*_BPCS() helpers. 1676 */ 1677 val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, 1678 DRM_ARGB64_GETR_BPCS(bgcolor, 10)); 1679 FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_GREEN, &val, 1680 DRM_ARGB64_GETG_BPCS(bgcolor, 10)); 1681 FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_BLUE, &val, 1682 DRM_ARGB64_GETB_BPCS(bgcolor, 10)); 1683 } 1684 1685 vop2_vp_write(vp, RK3568_VP_DSP_BG, val); 1686 } 1687 1688 static void vop2_post_config(struct drm_crtc *crtc, bool force, 1689 struct drm_crtc_state *new_crtc_state, 1690 struct drm_crtc_state *old_crtc_state) 1691 { 1692 struct vop2_video_port *vp = to_vop2_video_port(crtc); 1693 struct vop2 *vop2 = vp->vop2; 1694 struct drm_display_mode *mode = &new_crtc_state->adjusted_mode; 1695 u16 vtotal = mode->crtc_vtotal; 1696 u16 hdisplay = mode->crtc_hdisplay; 1697 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 1698 u16 vdisplay = mode->crtc_vdisplay; 1699 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 1700 u32 left_margin = 100, right_margin = 100; 1701 u32 top_margin = 100, bottom_margin = 100; 1702 u16 hsize = hdisplay * (left_margin + right_margin) / 200; 1703 u16 vsize = vdisplay * (top_margin + bottom_margin) / 200; 1704 u16 hact_end, vact_end; 1705 u32 val; 1706 1707 vop2->ops->setup_bg_dly(vp); 1708 1709 vsize = rounddown(vsize, 2); 1710 hsize = rounddown(hsize, 2); 1711 hact_st += hdisplay * (100 - left_margin) / 200; 1712 hact_end = hact_st + hsize; 1713 val = hact_st << 16; 1714 val |= hact_end; 1715 vop2_vp_write(vp, RK3568_VP_POST_DSP_HACT_INFO, val); 1716 vact_st += vdisplay * (100 - top_margin) / 200; 1717 vact_end = vact_st + vsize; 1718 val = vact_st << 16; 1719 val |= vact_end; 1720 vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO, val); 1721 val = scl_cal_scale2(vdisplay, vsize) << 16; 1722 val |= scl_cal_scale2(hdisplay, hsize); 1723 vop2_vp_write(vp, RK3568_VP_POST_SCL_FACTOR_YRGB, val); 1724 1725 val = 0; 1726 if (hdisplay != hsize) 1727 val |= RK3568_VP_POST_SCL_CTRL__HSCALEDOWN; 1728 if (vdisplay != vsize) 1729 val |= RK3568_VP_POST_SCL_CTRL__VSCALEDOWN; 1730 vop2_vp_write(vp, RK3568_VP_POST_SCL_CTRL, val); 1731 1732 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 1733 u16 vact_st_f1 = vtotal + vact_st + 1; 1734 u16 vact_end_f1 = vact_st_f1 + vsize; 1735 1736 val = vact_st_f1 << 16 | vact_end_f1; 1737 vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO_F1, val); 1738 } 1739 1740 vop2_bgcolor_setup(crtc, force, new_crtc_state, old_crtc_state); 1741 } 1742 1743 static int us_to_vertical_line(struct drm_display_mode *mode, int us) 1744 { 1745 return us * mode->clock / mode->htotal / 1000; 1746 } 1747 1748 static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, 1749 struct drm_atomic_commit *state) 1750 { 1751 struct vop2_video_port *vp = to_vop2_video_port(crtc); 1752 struct vop2 *vop2 = vp->vop2; 1753 const struct vop2_data *vop2_data = vop2->data; 1754 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id]; 1755 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); 1756 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 1757 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc_state); 1758 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 1759 unsigned long clock = mode->crtc_clock * 1000; 1760 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 1761 u16 hdisplay = mode->crtc_hdisplay; 1762 u16 htotal = mode->crtc_htotal; 1763 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 1764 u16 hact_end = hact_st + hdisplay; 1765 u16 vdisplay = mode->crtc_vdisplay; 1766 u16 vtotal = mode->crtc_vtotal; 1767 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; 1768 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 1769 u16 vact_end = vact_st + vdisplay; 1770 u8 out_mode; 1771 u32 dsp_ctrl = 0; 1772 int act_end; 1773 u32 val, polflags; 1774 int ret; 1775 struct drm_encoder *encoder; 1776 1777 drm_dbg(vop2->drm, "Update mode to %dx%d%s%d, type: %d for vp%d\n", 1778 hdisplay, vdisplay, mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p", 1779 drm_mode_vrefresh(mode), vcstate->output_type, vp->id); 1780 1781 vop2_lock(vop2); 1782 1783 ret = clk_prepare_enable(vp->dclk); 1784 if (ret < 0) { 1785 drm_err(vop2->drm, "failed to enable dclk for video port%d - %d\n", 1786 vp->id, ret); 1787 vop2_unlock(vop2); 1788 return; 1789 } 1790 1791 if (!vop2->enable_count) 1792 vop2_enable(vop2); 1793 1794 vop2->enable_count++; 1795 1796 vcstate->yuv_overlay = is_yuv_output(vcstate->bus_format); 1797 1798 vop2_crtc_enable_irq(vp, VP_INT_POST_BUF_EMPTY); 1799 1800 polflags = 0; 1801 if (vcstate->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) 1802 polflags |= POLFLAG_DCLK_INV; 1803 if (mode->flags & DRM_MODE_FLAG_PHSYNC) 1804 polflags |= BIT(HSYNC_POSITIVE); 1805 if (mode->flags & DRM_MODE_FLAG_PVSYNC) 1806 polflags |= BIT(VSYNC_POSITIVE); 1807 1808 drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) { 1809 struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); 1810 1811 /* 1812 * for drive a high resolution(4KP120, 8K), vop on rk3588/rk3576 need 1813 * process multi(1/2/4/8) pixels per cycle, so the dclk feed by the 1814 * system cru may be the 1/2 or 1/4 of mode->clock. 1815 */ 1816 clock = vop2->ops->setup_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags); 1817 } 1818 1819 if (!clock) { 1820 vop2_unlock(vop2); 1821 return; 1822 } 1823 1824 if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA && 1825 !(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT)) 1826 out_mode = ROCKCHIP_OUT_MODE_P888; 1827 else if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV422 && 1828 vop2->version == VOP_VERSION_RK3576) 1829 switch (vcstate->output_type) { 1830 case DRM_MODE_CONNECTOR_DisplayPort: 1831 case DRM_MODE_CONNECTOR_eDP: 1832 out_mode = ROCKCHIP_OUT_MODE_YUV422_RK3576_DP; 1833 break; 1834 case DRM_MODE_CONNECTOR_HDMIA: 1835 out_mode = ROCKCHIP_OUT_MODE_YUV422_RK3576_HDMI; 1836 break; 1837 default: 1838 drm_err(vop2->drm, "Unknown DRM_MODE_CONNECTOR %d\n", 1839 vcstate->output_type); 1840 vop2_unlock(vop2); 1841 return; 1842 } 1843 else 1844 out_mode = vcstate->output_mode; 1845 1846 dsp_ctrl |= FIELD_PREP(RK3568_VP_DSP_CTRL__OUT_MODE, out_mode); 1847 1848 if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode)) 1849 dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RB_SWAP; 1850 if (vop2_output_rg_swap(vop2, vcstate->bus_format)) 1851 dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RG_SWAP; 1852 1853 if (vcstate->yuv_overlay) 1854 dsp_ctrl |= RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y; 1855 1856 vop2_dither_setup(crtc, &dsp_ctrl); 1857 1858 vop2_vp_write(vp, RK3568_VP_DSP_HTOTAL_HS_END, (htotal << 16) | hsync_len); 1859 val = hact_st << 16; 1860 val |= hact_end; 1861 vop2_vp_write(vp, RK3568_VP_DSP_HACT_ST_END, val); 1862 1863 val = vact_st << 16; 1864 val |= vact_end; 1865 vop2_vp_write(vp, RK3568_VP_DSP_VACT_ST_END, val); 1866 1867 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 1868 u16 vact_st_f1 = vtotal + vact_st + 1; 1869 u16 vact_end_f1 = vact_st_f1 + vdisplay; 1870 1871 val = vact_st_f1 << 16 | vact_end_f1; 1872 vop2_vp_write(vp, RK3568_VP_DSP_VACT_ST_END_F1, val); 1873 1874 val = vtotal << 16 | (vtotal + vsync_len); 1875 vop2_vp_write(vp, RK3568_VP_DSP_VS_ST_END_F1, val); 1876 dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_INTERLACE; 1877 dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_FILED_POL; 1878 dsp_ctrl |= RK3568_VP_DSP_CTRL__P2I_EN; 1879 vtotal += vtotal + 1; 1880 act_end = vact_end_f1; 1881 } else { 1882 act_end = vact_end; 1883 } 1884 1885 vop2_writel(vop2, RK3568_VP_LINE_FLAG(vp->id), 1886 (act_end - us_to_vertical_line(mode, 0)) << 16 | act_end); 1887 1888 vop2_vp_write(vp, RK3568_VP_DSP_VTOTAL_VS_END, vtotal << 16 | vsync_len); 1889 1890 if (mode->flags & DRM_MODE_FLAG_DBLCLK) { 1891 dsp_ctrl |= RK3568_VP_DSP_CTRL__CORE_DCLK_DIV; 1892 clock *= 2; 1893 } 1894 1895 vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0); 1896 1897 /* 1898 * Switch to HDMI PHY PLL as DCLK source for display modes up 1899 * to 4K@60Hz, if available, otherwise keep using the system CRU. 1900 */ 1901 if (vop2->pll_hdmiphy0 || vop2->pll_hdmiphy1) { 1902 unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8, 1903 vcstate->output_bpc); 1904 if (clock <= max_dclk) { 1905 drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) { 1906 struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); 1907 1908 if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) { 1909 if (!vop2->pll_hdmiphy0) 1910 break; 1911 1912 if (!vp->dclk_src) 1913 vp->dclk_src = clk_get_parent(vp->dclk); 1914 1915 ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0); 1916 if (ret < 0) 1917 drm_warn(vop2->drm, 1918 "Could not switch to HDMI0 PHY PLL: %d\n", 1919 ret); 1920 break; 1921 } 1922 1923 if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI1) { 1924 if (!vop2->pll_hdmiphy1) 1925 break; 1926 1927 if (!vp->dclk_src) 1928 vp->dclk_src = clk_get_parent(vp->dclk); 1929 1930 ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy1); 1931 if (ret < 0) 1932 drm_warn(vop2->drm, 1933 "Could not switch to HDMI1 PHY PLL: %d\n", 1934 ret); 1935 break; 1936 } 1937 } 1938 } 1939 } 1940 1941 clk_set_rate(vp->dclk, clock); 1942 1943 vop2_post_config(crtc, true, crtc_state, old_crtc_state); 1944 1945 vop2_cfg_done(vp); 1946 1947 vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl); 1948 1949 vop2_crtc_atomic_try_set_gamma(vop2, vp, crtc, crtc_state); 1950 1951 drm_crtc_vblank_on(crtc); 1952 1953 vop2_unlock(vop2); 1954 } 1955 1956 static int vop2_crtc_atomic_check_gamma(struct vop2_video_port *vp, 1957 struct drm_crtc *crtc, 1958 struct drm_atomic_commit *state, 1959 struct drm_crtc_state *crtc_state) 1960 { 1961 struct vop2 *vop2 = vp->vop2; 1962 unsigned int len; 1963 1964 if (!vp->vop2->lut_regs || !crtc_state->color_mgmt_changed || 1965 !crtc_state->gamma_lut) 1966 return 0; 1967 1968 len = drm_color_lut_size(crtc_state->gamma_lut); 1969 if (len != crtc->gamma_size) { 1970 drm_dbg(vop2->drm, "Invalid LUT size; got %d, expected %d\n", 1971 len, crtc->gamma_size); 1972 return -EINVAL; 1973 } 1974 1975 if (!vop2_supports_seamless_gamma_lut_update(vop2) && vop2_gamma_lut_in_use(vop2, vp)) { 1976 drm_info(vop2->drm, "Gamma LUT can be enabled for only one CRTC at a time\n"); 1977 return -EINVAL; 1978 } 1979 1980 return 0; 1981 } 1982 1983 static int vop2_crtc_atomic_check(struct drm_crtc *crtc, 1984 struct drm_atomic_commit *state) 1985 { 1986 struct vop2_video_port *vp = to_vop2_video_port(crtc); 1987 struct drm_plane *plane; 1988 int nplanes = 0; 1989 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 1990 int ret; 1991 1992 ret = vop2_crtc_atomic_check_gamma(vp, crtc, state, crtc_state); 1993 if (ret) 1994 return ret; 1995 1996 drm_atomic_crtc_state_for_each_plane(plane, crtc_state) 1997 nplanes++; 1998 1999 if (nplanes > vp->nlayers) 2000 return -EINVAL; 2001 2002 return 0; 2003 } 2004 2005 static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, 2006 struct drm_atomic_commit *state) 2007 { 2008 struct vop2_video_port *vp = to_vop2_video_port(crtc); 2009 struct vop2 *vop2 = vp->vop2; 2010 2011 vop2->ops->setup_overlay(vp); 2012 } 2013 2014 static void vop2_crtc_atomic_flush(struct drm_crtc *crtc, 2015 struct drm_atomic_commit *state) 2016 { 2017 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 2018 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); 2019 struct vop2_video_port *vp = to_vop2_video_port(crtc); 2020 struct vop2 *vop2 = vp->vop2; 2021 2022 /* In case of modeset, gamma lut update already happened in atomic enable */ 2023 if (!drm_atomic_crtc_needs_modeset(crtc_state) && crtc_state->color_mgmt_changed) 2024 vop2_crtc_atomic_try_set_gamma_locked(vop2, vp, crtc, crtc_state); 2025 2026 vop2_post_config(crtc, false, crtc_state, old_crtc_state); 2027 2028 vop2_cfg_done(vp); 2029 2030 spin_lock_irq(&crtc->dev->event_lock); 2031 2032 if (crtc->state->event) { 2033 WARN_ON(drm_crtc_vblank_get(crtc)); 2034 vp->event = crtc->state->event; 2035 crtc->state->event = NULL; 2036 } 2037 2038 spin_unlock_irq(&crtc->dev->event_lock); 2039 } 2040 2041 static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = { 2042 .mode_fixup = vop2_crtc_mode_fixup, 2043 .mode_valid = vop2_crtc_mode_valid, 2044 .atomic_check = vop2_crtc_atomic_check, 2045 .atomic_begin = vop2_crtc_atomic_begin, 2046 .atomic_flush = vop2_crtc_atomic_flush, 2047 .atomic_enable = vop2_crtc_atomic_enable, 2048 .atomic_disable = vop2_crtc_atomic_disable, 2049 }; 2050 2051 static void vop2_dump_connector_on_crtc(struct drm_crtc *crtc, struct seq_file *s) 2052 { 2053 struct drm_connector_list_iter conn_iter; 2054 struct drm_connector *connector; 2055 2056 drm_connector_list_iter_begin(crtc->dev, &conn_iter); 2057 drm_for_each_connector_iter(connector, &conn_iter) { 2058 if (crtc->state->connector_mask & drm_connector_mask(connector)) 2059 seq_printf(s, " Connector: %s\n", connector->name); 2060 } 2061 drm_connector_list_iter_end(&conn_iter); 2062 } 2063 2064 static int vop2_plane_state_dump(struct seq_file *s, struct drm_plane *plane) 2065 { 2066 struct vop2_win *win = to_vop2_win(plane); 2067 struct drm_plane_state *pstate = plane->state; 2068 struct drm_rect *src, *dst; 2069 struct drm_framebuffer *fb; 2070 struct drm_gem_object *obj; 2071 struct rockchip_gem_object *rk_obj; 2072 bool xmirror; 2073 bool ymirror; 2074 bool rotate_270; 2075 bool rotate_90; 2076 dma_addr_t fb_addr; 2077 int i; 2078 2079 seq_printf(s, " %s: %s\n", win->data->name, !pstate ? 2080 "DISABLED" : pstate->crtc ? "ACTIVE" : "DISABLED"); 2081 2082 if (!pstate || !pstate->fb) 2083 return 0; 2084 2085 fb = pstate->fb; 2086 src = &pstate->src; 2087 dst = &pstate->dst; 2088 xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false; 2089 ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false; 2090 rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270; 2091 rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90; 2092 2093 seq_printf(s, "\twin_id: %d\n", win->win_id); 2094 2095 seq_printf(s, "\tformat: %p4cc%s glb_alpha[0x%x]\n", 2096 &fb->format->format, 2097 drm_is_afbc(fb->modifier) ? "[AFBC]" : "", 2098 pstate->alpha >> 8); 2099 seq_printf(s, "\trotate: xmirror: %d ymirror: %d rotate_90: %d rotate_270: %d\n", 2100 xmirror, ymirror, rotate_90, rotate_270); 2101 seq_printf(s, "\tzpos: %d\n", pstate->normalized_zpos); 2102 seq_printf(s, "\tsrc: pos[%d, %d] rect[%d x %d]\n", src->x1 >> 16, 2103 src->y1 >> 16, drm_rect_width(src) >> 16, 2104 drm_rect_height(src) >> 16); 2105 seq_printf(s, "\tdst: pos[%d, %d] rect[%d x %d]\n", dst->x1, dst->y1, 2106 drm_rect_width(dst), drm_rect_height(dst)); 2107 2108 for (i = 0; i < fb->format->num_planes; i++) { 2109 obj = fb->obj[i]; 2110 rk_obj = to_rockchip_obj(obj); 2111 fb_addr = rk_obj->dma_addr + fb->offsets[i]; 2112 2113 seq_printf(s, "\tbuf[%d]: addr: %pad pitch: %d offset: %d\n", 2114 i, &fb_addr, fb->pitches[i], fb->offsets[i]); 2115 } 2116 2117 return 0; 2118 } 2119 2120 static int vop2_crtc_state_dump(struct drm_crtc *crtc, struct seq_file *s) 2121 { 2122 struct vop2_video_port *vp = to_vop2_video_port(crtc); 2123 struct drm_crtc_state *cstate = crtc->state; 2124 struct rockchip_crtc_state *vcstate; 2125 struct drm_display_mode *mode; 2126 struct drm_plane *plane; 2127 bool interlaced; 2128 2129 seq_printf(s, "Video Port%d: %s\n", vp->id, !cstate ? 2130 "DISABLED" : cstate->active ? "ACTIVE" : "DISABLED"); 2131 2132 if (!cstate || !cstate->active) 2133 return 0; 2134 2135 mode = &crtc->state->adjusted_mode; 2136 vcstate = to_rockchip_crtc_state(cstate); 2137 interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); 2138 2139 vop2_dump_connector_on_crtc(crtc, s); 2140 seq_printf(s, "\tbus_format[%x]: %s\n", vcstate->bus_format, 2141 drm_get_bus_format_name(vcstate->bus_format)); 2142 seq_printf(s, "\toutput_mode[%x]", vcstate->output_mode); 2143 seq_printf(s, " color_space[%d]\n", vcstate->color_space); 2144 seq_printf(s, "\tbackground color (10bpc): r=0x%x g=0x%x b=0x%x\n", 2145 DRM_ARGB64_GETR_BPCS(cstate->background_color, 10), 2146 DRM_ARGB64_GETG_BPCS(cstate->background_color, 10), 2147 DRM_ARGB64_GETB_BPCS(cstate->background_color, 10)); 2148 seq_printf(s, " Display mode: %dx%d%s%d\n", 2149 mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p", 2150 drm_mode_vrefresh(mode)); 2151 seq_printf(s, "\tclk[%d] real_clk[%d] type[%x] flag[%x]\n", 2152 mode->clock, mode->crtc_clock, mode->type, mode->flags); 2153 seq_printf(s, "\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start, 2154 mode->hsync_end, mode->htotal); 2155 seq_printf(s, "\tV: %d %d %d %d\n", mode->vdisplay, mode->vsync_start, 2156 mode->vsync_end, mode->vtotal); 2157 2158 drm_atomic_crtc_for_each_plane(plane, crtc) { 2159 vop2_plane_state_dump(s, plane); 2160 } 2161 2162 return 0; 2163 } 2164 2165 static int vop2_summary_show(struct seq_file *s, void *data) 2166 { 2167 struct drm_info_node *node = s->private; 2168 struct drm_minor *minor = node->minor; 2169 struct drm_device *drm_dev = minor->dev; 2170 struct drm_crtc *crtc; 2171 2172 drm_modeset_lock_all(drm_dev); 2173 drm_for_each_crtc(crtc, drm_dev) { 2174 vop2_crtc_state_dump(crtc, s); 2175 } 2176 drm_modeset_unlock_all(drm_dev); 2177 2178 return 0; 2179 } 2180 2181 static void vop2_regs_print(struct vop2 *vop2, struct seq_file *s, 2182 const struct vop2_regs_dump *dump, bool active_only) 2183 { 2184 resource_size_t start; 2185 u32 val; 2186 int i; 2187 2188 if (dump->en_mask && active_only) { 2189 val = vop2_readl(vop2, dump->base + dump->en_reg); 2190 if ((val & dump->en_mask) != dump->en_val) 2191 return; 2192 } 2193 2194 seq_printf(s, "\n%s:\n", dump->name); 2195 2196 start = vop2->res->start + dump->base; 2197 for (i = 0; i < dump->size >> 2; i += 4) { 2198 seq_printf(s, "%08x: %08x %08x %08x %08x\n", (u32)start + i * 4, 2199 vop2_readl(vop2, dump->base + (4 * i)), 2200 vop2_readl(vop2, dump->base + (4 * (i + 1))), 2201 vop2_readl(vop2, dump->base + (4 * (i + 2))), 2202 vop2_readl(vop2, dump->base + (4 * (i + 3)))); 2203 } 2204 } 2205 2206 static void __vop2_regs_dump(struct seq_file *s, bool active_only) 2207 { 2208 struct drm_info_node *node = s->private; 2209 struct vop2 *vop2 = node->info_ent->data; 2210 struct drm_minor *minor = node->minor; 2211 struct drm_device *drm_dev = minor->dev; 2212 const struct vop2_regs_dump *dump; 2213 unsigned int i; 2214 2215 drm_modeset_lock_all(drm_dev); 2216 2217 regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register); 2218 2219 if (vop2->enable_count) { 2220 for (i = 0; i < vop2->data->regs_dump_size; i++) { 2221 dump = &vop2->data->regs_dump[i]; 2222 vop2_regs_print(vop2, s, dump, active_only); 2223 } 2224 } else { 2225 seq_puts(s, "VOP disabled\n"); 2226 } 2227 drm_modeset_unlock_all(drm_dev); 2228 } 2229 2230 static int vop2_regs_show(struct seq_file *s, void *arg) 2231 { 2232 __vop2_regs_dump(s, false); 2233 2234 return 0; 2235 } 2236 2237 static int vop2_active_regs_show(struct seq_file *s, void *data) 2238 { 2239 __vop2_regs_dump(s, true); 2240 2241 return 0; 2242 } 2243 2244 static struct drm_info_list vop2_debugfs_list[] = { 2245 { "summary", vop2_summary_show, 0, NULL }, 2246 { "active_regs", vop2_active_regs_show, 0, NULL }, 2247 { "regs", vop2_regs_show, 0, NULL }, 2248 }; 2249 2250 static void vop2_debugfs_init(struct vop2 *vop2, struct drm_minor *minor) 2251 { 2252 struct dentry *root; 2253 unsigned int i; 2254 2255 root = debugfs_create_dir("vop2", minor->debugfs_root); 2256 if (!IS_ERR(root)) { 2257 for (i = 0; i < ARRAY_SIZE(vop2_debugfs_list); i++) 2258 vop2_debugfs_list[i].data = vop2; 2259 2260 drm_debugfs_create_files(vop2_debugfs_list, 2261 ARRAY_SIZE(vop2_debugfs_list), 2262 root, minor); 2263 } 2264 } 2265 2266 static int vop2_crtc_late_register(struct drm_crtc *crtc) 2267 { 2268 struct vop2_video_port *vp = to_vop2_video_port(crtc); 2269 struct vop2 *vop2 = vp->vop2; 2270 2271 if (drm_crtc_index(crtc) == 0) 2272 vop2_debugfs_init(vop2, crtc->dev->primary); 2273 2274 return 0; 2275 } 2276 2277 static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc) 2278 { 2279 struct rockchip_crtc_state *vcstate; 2280 2281 if (WARN_ON(!crtc->state)) 2282 return NULL; 2283 2284 vcstate = kmemdup(to_rockchip_crtc_state(crtc->state), 2285 sizeof(*vcstate), GFP_KERNEL); 2286 if (!vcstate) 2287 return NULL; 2288 2289 __drm_atomic_helper_crtc_duplicate_state(crtc, &vcstate->base); 2290 2291 return &vcstate->base; 2292 } 2293 2294 static void vop2_crtc_destroy_state(struct drm_crtc *crtc, 2295 struct drm_crtc_state *state) 2296 { 2297 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(state); 2298 2299 __drm_atomic_helper_crtc_destroy_state(&vcstate->base); 2300 kfree(vcstate); 2301 } 2302 2303 static void vop2_crtc_reset(struct drm_crtc *crtc) 2304 { 2305 struct rockchip_crtc_state *vcstate = kzalloc_obj(*vcstate); 2306 2307 if (crtc->state) 2308 vop2_crtc_destroy_state(crtc, crtc->state); 2309 2310 if (vcstate) 2311 __drm_atomic_helper_crtc_reset(crtc, &vcstate->base); 2312 else 2313 __drm_atomic_helper_crtc_reset(crtc, NULL); 2314 } 2315 2316 static const struct drm_crtc_funcs vop2_crtc_funcs = { 2317 .set_config = drm_atomic_helper_set_config, 2318 .page_flip = drm_atomic_helper_page_flip, 2319 .destroy = drm_crtc_cleanup, 2320 .reset = vop2_crtc_reset, 2321 .atomic_duplicate_state = vop2_crtc_duplicate_state, 2322 .atomic_destroy_state = vop2_crtc_destroy_state, 2323 .enable_vblank = vop2_crtc_enable_vblank, 2324 .disable_vblank = vop2_crtc_disable_vblank, 2325 .late_register = vop2_crtc_late_register, 2326 }; 2327 2328 static irqreturn_t rk3576_vp_isr(int irq, void *data) 2329 { 2330 struct vop2_video_port *vp = data; 2331 struct vop2 *vop2 = vp->vop2; 2332 struct drm_crtc *crtc = &vp->crtc; 2333 uint32_t irqs; 2334 int ret = IRQ_NONE; 2335 2336 if (!pm_runtime_get_if_in_use(vop2->dev)) 2337 return IRQ_NONE; 2338 2339 irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id)); 2340 vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs); 2341 2342 if (irqs & VP_INT_DSP_HOLD_VALID) { 2343 complete(&vp->dsp_hold_completion); 2344 ret = IRQ_HANDLED; 2345 } 2346 2347 if (irqs & VP_INT_FS_FIELD) { 2348 drm_crtc_handle_vblank(crtc); 2349 spin_lock(&crtc->dev->event_lock); 2350 if (vp->event) { 2351 u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE); 2352 2353 if (!(val & BIT(vp->id))) { 2354 drm_crtc_send_vblank_event(crtc, vp->event); 2355 vp->event = NULL; 2356 drm_crtc_vblank_put(crtc); 2357 } 2358 } 2359 spin_unlock(&crtc->dev->event_lock); 2360 2361 ret = IRQ_HANDLED; 2362 } 2363 2364 if (irqs & VP_INT_POST_BUF_EMPTY) { 2365 drm_err_ratelimited(vop2->drm, "POST_BUF_EMPTY irq err at vp%d\n", vp->id); 2366 ret = IRQ_HANDLED; 2367 } 2368 2369 pm_runtime_put(vop2->dev); 2370 2371 return ret; 2372 } 2373 2374 static irqreturn_t vop2_isr(int irq, void *data) 2375 { 2376 struct vop2 *vop2 = data; 2377 const struct vop2_data *vop2_data = vop2->data; 2378 u32 axi_irqs[VOP2_SYS_AXI_BUS_NUM]; 2379 int ret = IRQ_NONE; 2380 int i; 2381 2382 /* 2383 * The irq is shared with the iommu. If the runtime-pm state of the 2384 * vop2-device is disabled the irq has to be targeted at the iommu. 2385 */ 2386 if (!pm_runtime_get_if_in_use(vop2->dev)) 2387 return IRQ_NONE; 2388 2389 if (vop2->version < VOP_VERSION_RK3576) { 2390 for (i = 0; i < vop2_data->nr_vps; i++) { 2391 struct vop2_video_port *vp = &vop2->vps[i]; 2392 struct drm_crtc *crtc = &vp->crtc; 2393 u32 irqs; 2394 2395 irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id)); 2396 vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs); 2397 2398 if (irqs & VP_INT_DSP_HOLD_VALID) { 2399 complete(&vp->dsp_hold_completion); 2400 ret = IRQ_HANDLED; 2401 } 2402 2403 if (irqs & VP_INT_FS_FIELD) { 2404 drm_crtc_handle_vblank(crtc); 2405 spin_lock(&crtc->dev->event_lock); 2406 if (vp->event) { 2407 u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE); 2408 2409 if (!(val & BIT(vp->id))) { 2410 drm_crtc_send_vblank_event(crtc, vp->event); 2411 vp->event = NULL; 2412 drm_crtc_vblank_put(crtc); 2413 } 2414 } 2415 spin_unlock(&crtc->dev->event_lock); 2416 2417 ret = IRQ_HANDLED; 2418 } 2419 2420 if (irqs & VP_INT_POST_BUF_EMPTY) { 2421 drm_err_ratelimited(vop2->drm, 2422 "POST_BUF_EMPTY irq err at vp%d\n", 2423 vp->id); 2424 ret = IRQ_HANDLED; 2425 } 2426 } 2427 } 2428 2429 axi_irqs[0] = vop2_readl(vop2, RK3568_SYS0_INT_STATUS); 2430 vop2_writel(vop2, RK3568_SYS0_INT_CLR, axi_irqs[0] << 16 | axi_irqs[0]); 2431 axi_irqs[1] = vop2_readl(vop2, RK3568_SYS1_INT_STATUS); 2432 vop2_writel(vop2, RK3568_SYS1_INT_CLR, axi_irqs[1] << 16 | axi_irqs[1]); 2433 2434 for (i = 0; i < ARRAY_SIZE(axi_irqs); i++) { 2435 if (axi_irqs[i] & VOP2_INT_BUS_ERRPR) { 2436 drm_err_ratelimited(vop2->drm, "BUS_ERROR irq err\n"); 2437 ret = IRQ_HANDLED; 2438 } 2439 } 2440 2441 pm_runtime_put(vop2->dev); 2442 2443 return ret; 2444 } 2445 2446 static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win, 2447 unsigned long possible_crtcs) 2448 { 2449 const struct vop2_win_data *win_data = win->data; 2450 unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | 2451 BIT(DRM_MODE_BLEND_PREMULTI) | 2452 BIT(DRM_MODE_BLEND_COVERAGE); 2453 int ret; 2454 2455 ret = drm_universal_plane_init(vop2->drm, &win->base, possible_crtcs, 2456 &vop2_plane_funcs, win_data->formats, 2457 win_data->nformats, 2458 win_data->format_modifiers, 2459 win->type, win_data->name); 2460 if (ret) { 2461 drm_err(vop2->drm, "failed to initialize plane %d\n", ret); 2462 return ret; 2463 } 2464 2465 drm_plane_helper_add(&win->base, &vop2_plane_helper_funcs); 2466 2467 if (win->data->supported_rotations) 2468 drm_plane_create_rotation_property(&win->base, DRM_MODE_ROTATE_0, 2469 DRM_MODE_ROTATE_0 | 2470 win->data->supported_rotations); 2471 drm_plane_create_alpha_property(&win->base); 2472 drm_plane_create_blend_mode_property(&win->base, blend_caps); 2473 drm_plane_create_zpos_property(&win->base, win->win_id, 0, 2474 vop2->registered_num_wins - 1); 2475 2476 return 0; 2477 } 2478 2479 /* 2480 * On RK3566 these windows don't have an independent 2481 * framebuffer. They can only share/mirror the framebuffer 2482 * with smart0, esmart0 and cluster0 respectively. 2483 * And RK3566 share the same vop version with Rk3568, so we 2484 * need to use soc_id for identification here. 2485 */ 2486 static bool vop2_is_mirror_win(struct vop2_win *win) 2487 { 2488 struct vop2 *vop2 = win->vop2; 2489 2490 if (vop2->data->soc_id == 3566) { 2491 switch (win->data->phys_id) { 2492 case ROCKCHIP_VOP2_SMART1: 2493 case ROCKCHIP_VOP2_ESMART1: 2494 case ROCKCHIP_VOP2_CLUSTER1: 2495 return true; 2496 default: 2497 return false; 2498 } 2499 } else { 2500 return false; 2501 } 2502 } 2503 2504 static int vop2_create_crtcs(struct vop2 *vop2) 2505 { 2506 const struct vop2_data *vop2_data = vop2->data; 2507 struct drm_device *drm = vop2->drm; 2508 struct device *dev = vop2->dev; 2509 struct drm_plane *plane; 2510 struct device_node *port; 2511 struct vop2_video_port *vp; 2512 struct vop2_win *win; 2513 u32 possible_crtcs; 2514 int i, j, nvp, nvps = 0; 2515 int ret; 2516 2517 for (i = 0; i < vop2_data->nr_vps; i++) { 2518 const struct vop2_video_port_data *vp_data; 2519 struct device_node *np; 2520 char dclk_name[9]; 2521 2522 vp_data = &vop2_data->vp[i]; 2523 vp = &vop2->vps[i]; 2524 vp->vop2 = vop2; 2525 vp->id = vp_data->id; 2526 vp->data = vp_data; 2527 2528 snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id); 2529 vp->dclk = devm_clk_get(vop2->dev, dclk_name); 2530 if (IS_ERR(vp->dclk)) 2531 return dev_err_probe(drm->dev, PTR_ERR(vp->dclk), 2532 "failed to get %s\n", dclk_name); 2533 2534 np = of_graph_get_remote_node(dev->of_node, i, -1); 2535 if (!np) { 2536 drm_dbg(vop2->drm, "%s: No remote for vp%d\n", __func__, i); 2537 continue; 2538 } 2539 of_node_put(np); 2540 2541 port = of_graph_get_port_by_id(dev->of_node, i); 2542 if (!port) 2543 return dev_err_probe(drm->dev, -ENOENT, 2544 "no port node found for video_port%d\n", i); 2545 vp->crtc.port = port; 2546 nvps++; 2547 } 2548 2549 nvp = 0; 2550 /* Register a primary plane for every crtc */ 2551 for (i = 0; i < vop2_data->nr_vps; i++) { 2552 vp = &vop2->vps[i]; 2553 2554 if (!vp->crtc.port) 2555 continue; 2556 2557 for (j = 0; j < vop2->registered_num_wins; j++) { 2558 win = &vop2->win[j]; 2559 2560 /* Aready registered as primary plane */ 2561 if (win->base.type == DRM_PLANE_TYPE_PRIMARY) 2562 continue; 2563 2564 /* If this win can not attached to this VP */ 2565 if (!(win->data->possible_vp_mask & BIT(vp->id))) 2566 continue; 2567 2568 if (vop2_is_mirror_win(win)) 2569 continue; 2570 2571 if (win->type == DRM_PLANE_TYPE_PRIMARY) { 2572 possible_crtcs = BIT(nvp); 2573 vp->primary_plane = win; 2574 ret = vop2_plane_init(vop2, win, possible_crtcs); 2575 if (ret) 2576 return dev_err_probe(drm->dev, ret, 2577 "failed to init primary plane %s\n", 2578 win->data->name); 2579 nvp++; 2580 break; 2581 } 2582 } 2583 2584 if (!vp->primary_plane) 2585 return dev_err_probe(drm->dev, -ENOENT, 2586 "no primary plane for vp %d\n", i); 2587 } 2588 2589 /* Register all unused window as overlay plane */ 2590 for (i = 0; i < vop2->registered_num_wins; i++) { 2591 win = &vop2->win[i]; 2592 2593 /* Aready registered as primary plane */ 2594 if (win->base.type == DRM_PLANE_TYPE_PRIMARY) 2595 continue; 2596 2597 if (vop2_is_mirror_win(win)) 2598 continue; 2599 2600 win->type = DRM_PLANE_TYPE_OVERLAY; 2601 2602 possible_crtcs = 0; 2603 nvp = 0; 2604 for (j = 0; j < vop2_data->nr_vps; j++) { 2605 vp = &vop2->vps[j]; 2606 2607 if (!vp->crtc.port) 2608 continue; 2609 2610 if (win->data->possible_vp_mask & BIT(vp->id)) 2611 possible_crtcs |= BIT(nvp); 2612 nvp++; 2613 } 2614 2615 ret = vop2_plane_init(vop2, win, possible_crtcs); 2616 if (ret) 2617 return dev_err_probe(drm->dev, ret, "failed to init overlay plane %s\n", 2618 win->data->name); 2619 } 2620 2621 for (i = 0; i < vop2_data->nr_vps; i++) { 2622 vp = &vop2->vps[i]; 2623 2624 if (!vp->crtc.port) 2625 continue; 2626 2627 plane = &vp->primary_plane->base; 2628 2629 ret = drm_crtc_init_with_planes(drm, &vp->crtc, plane, NULL, 2630 &vop2_crtc_funcs, 2631 "video_port%d", vp->id); 2632 if (ret) 2633 return dev_err_probe(drm->dev, ret, 2634 "crtc init for video_port%d failed\n", i); 2635 2636 drm_crtc_attach_background_color_property(&vp->crtc); 2637 2638 drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs); 2639 if (vop2->lut_regs) { 2640 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id]; 2641 2642 drm_mode_crtc_set_gamma_size(&vp->crtc, vp_data->gamma_lut_len); 2643 drm_crtc_enable_color_mgmt(&vp->crtc, 0, false, vp_data->gamma_lut_len); 2644 } 2645 init_completion(&vp->dsp_hold_completion); 2646 } 2647 2648 /* 2649 * On the VOP2 it's very hard to change the number of layers on a VP 2650 * during runtime, so we distribute the layers equally over the used 2651 * VPs 2652 */ 2653 for (i = 0; i < vop2->data->nr_vps; i++) { 2654 struct vop2_video_port *vp = &vop2->vps[i]; 2655 2656 if (vp->crtc.port) 2657 vp->nlayers = vop2_data->win_size / nvps; 2658 } 2659 2660 return 0; 2661 } 2662 2663 static void vop2_destroy_crtcs(struct vop2 *vop2) 2664 { 2665 struct drm_device *drm = vop2->drm; 2666 struct list_head *crtc_list = &drm->mode_config.crtc_list; 2667 struct list_head *plane_list = &drm->mode_config.plane_list; 2668 struct drm_crtc *crtc, *tmpc; 2669 struct drm_plane *plane, *tmpp; 2670 2671 list_for_each_entry_safe(plane, tmpp, plane_list, head) 2672 drm_plane_cleanup(plane); 2673 2674 /* 2675 * Destroy CRTC after vop2_plane_destroy() since vop2_disable_plane() 2676 * references the CRTC. 2677 */ 2678 list_for_each_entry_safe(crtc, tmpc, crtc_list, head) { 2679 of_node_put(crtc->port); 2680 drm_crtc_cleanup(crtc); 2681 } 2682 } 2683 2684 static int vop2_find_rgb_encoder(struct vop2 *vop2) 2685 { 2686 struct device_node *node = vop2->dev->of_node; 2687 struct device_node *endpoint; 2688 int i; 2689 2690 for (i = 0; i < vop2->data->nr_vps; i++) { 2691 endpoint = of_graph_get_endpoint_by_regs(node, i, 2692 ROCKCHIP_VOP2_EP_RGB0); 2693 if (!endpoint) 2694 continue; 2695 2696 of_node_put(endpoint); 2697 return i; 2698 } 2699 2700 return -ENOENT; 2701 } 2702 2703 static int vop2_regmap_init(struct vop2_win *win, const struct reg_field *regs, 2704 int nr_regs) 2705 { 2706 struct vop2 *vop2 = win->vop2; 2707 int i; 2708 2709 for (i = 0; i < nr_regs; i++) { 2710 const struct reg_field field = { 2711 .reg = (regs[i].reg != 0xffffffff) ? 2712 regs[i].reg + win->offset : regs[i].reg, 2713 .lsb = regs[i].lsb, 2714 .msb = regs[i].msb 2715 }; 2716 2717 win->reg[i] = devm_regmap_field_alloc(vop2->dev, vop2->map, field); 2718 if (IS_ERR(win->reg[i])) 2719 return PTR_ERR(win->reg[i]); 2720 } 2721 2722 return 0; 2723 }; 2724 2725 static int vop2_win_init(struct vop2 *vop2) 2726 { 2727 const struct vop2_data *vop2_data = vop2->data; 2728 struct vop2_win *win; 2729 int i, ret; 2730 2731 for (i = 0; i < vop2_data->win_size; i++) { 2732 const struct vop2_win_data *win_data = &vop2_data->win[i]; 2733 2734 win = &vop2->win[i]; 2735 win->data = win_data; 2736 win->type = win_data->type; 2737 win->offset = win_data->base; 2738 win->win_id = i; 2739 win->vop2 = vop2; 2740 if (vop2_cluster_window(win)) 2741 ret = vop2_regmap_init(win, vop2->data->cluster_reg, 2742 vop2->data->nr_cluster_regs); 2743 else 2744 ret = vop2_regmap_init(win, vop2->data->smart_reg, 2745 vop2->data->nr_smart_regs); 2746 if (ret) 2747 return ret; 2748 } 2749 2750 vop2->registered_num_wins = vop2_data->win_size; 2751 2752 return 0; 2753 } 2754 2755 /* 2756 * The window and video port registers are only updated when config 2757 * done is written. Until that they read back the old value. As we 2758 * read-modify-write these registers mark them as non-volatile. This 2759 * makes sure we read the new values from the regmap register cache. 2760 */ 2761 static const struct regmap_range vop2_nonvolatile_range[] = { 2762 regmap_reg_range(RK3568_VP0_CTRL_BASE, RK3588_VP3_CTRL_BASE + 255), 2763 regmap_reg_range(0x1000, 0x23ff), 2764 }; 2765 2766 static const struct regmap_access_table vop2_volatile_table = { 2767 .no_ranges = vop2_nonvolatile_range, 2768 .n_no_ranges = ARRAY_SIZE(vop2_nonvolatile_range), 2769 }; 2770 2771 static const struct regmap_config vop2_regmap_config = { 2772 .reg_bits = 32, 2773 .val_bits = 32, 2774 .reg_stride = 4, 2775 .max_register = 0x3000, 2776 .name = "vop2", 2777 .volatile_table = &vop2_volatile_table, 2778 .cache_type = REGCACHE_MAPLE, 2779 }; 2780 2781 static int vop2_bind(struct device *dev, struct device *master, void *data) 2782 { 2783 struct platform_device *pdev = to_platform_device(dev); 2784 const struct vop2_data *vop2_data; 2785 struct drm_device *drm = data; 2786 struct vop2 *vop2; 2787 struct resource *res; 2788 size_t alloc_size; 2789 int ret; 2790 2791 vop2_data = of_device_get_match_data(dev); 2792 if (!vop2_data) 2793 return -ENODEV; 2794 2795 /* Allocate vop2 struct and its vop2_win array */ 2796 alloc_size = struct_size(vop2, win, vop2_data->win_size); 2797 vop2 = devm_kzalloc(dev, alloc_size, GFP_KERNEL); 2798 if (!vop2) 2799 return -ENOMEM; 2800 2801 vop2->dev = dev; 2802 vop2->data = vop2_data; 2803 vop2->ops = vop2_data->ops; 2804 vop2->version = vop2_data->version; 2805 vop2->drm = drm; 2806 2807 dev_set_drvdata(dev, vop2); 2808 2809 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vop"); 2810 if (!res) 2811 return dev_err_probe(drm->dev, -EINVAL, 2812 "failed to get vop2 register byname\n"); 2813 2814 vop2->res = res; 2815 vop2->regs = devm_ioremap_resource(dev, res); 2816 if (IS_ERR(vop2->regs)) 2817 return PTR_ERR(vop2->regs); 2818 vop2->len = resource_size(res); 2819 2820 vop2->map = devm_regmap_init_mmio(dev, vop2->regs, &vop2_regmap_config); 2821 if (IS_ERR(vop2->map)) 2822 return PTR_ERR(vop2->map); 2823 2824 /* Set the bounds for framebuffer creation */ 2825 drm->mode_config.min_width = 4; 2826 drm->mode_config.min_height = 4; 2827 drm->mode_config.max_width = vop2_data->max_input.width; 2828 drm->mode_config.max_height = vop2_data->max_input.height; 2829 2830 ret = vop2_win_init(vop2); 2831 if (ret) 2832 return ret; 2833 2834 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gamma-lut"); 2835 if (res) { 2836 vop2->lut_regs = devm_ioremap_resource(dev, res); 2837 if (IS_ERR(vop2->lut_regs)) 2838 return PTR_ERR(vop2->lut_regs); 2839 } 2840 if (vop2_data->feature & VOP2_FEATURE_HAS_SYS_GRF) { 2841 vop2->sys_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); 2842 if (IS_ERR(vop2->sys_grf)) 2843 return dev_err_probe(drm->dev, PTR_ERR(vop2->sys_grf), 2844 "cannot get sys_grf\n"); 2845 } 2846 2847 if (vop2_data->feature & VOP2_FEATURE_HAS_VOP_GRF) { 2848 vop2->vop_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vop-grf"); 2849 if (IS_ERR(vop2->vop_grf)) 2850 return dev_err_probe(drm->dev, PTR_ERR(vop2->vop_grf), 2851 "cannot get vop_grf\n"); 2852 } 2853 2854 if (vop2_data->feature & VOP2_FEATURE_HAS_VO1_GRF) { 2855 vop2->vo1_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vo1-grf"); 2856 if (IS_ERR(vop2->vo1_grf)) 2857 return dev_err_probe(drm->dev, PTR_ERR(vop2->vo1_grf), 2858 "cannot get vo1_grf\n"); 2859 } 2860 2861 if (vop2_data->feature & VOP2_FEATURE_HAS_SYS_PMU) { 2862 vop2->sys_pmu = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pmu"); 2863 if (IS_ERR(vop2->sys_pmu)) 2864 return dev_err_probe(drm->dev, PTR_ERR(vop2->sys_pmu), 2865 "cannot get sys_pmu\n"); 2866 } 2867 2868 vop2->hclk = devm_clk_get(vop2->dev, "hclk"); 2869 if (IS_ERR(vop2->hclk)) 2870 return dev_err_probe(drm->dev, PTR_ERR(vop2->hclk), 2871 "failed to get hclk source\n"); 2872 2873 vop2->aclk = devm_clk_get(vop2->dev, "aclk"); 2874 if (IS_ERR(vop2->aclk)) 2875 return dev_err_probe(drm->dev, PTR_ERR(vop2->aclk), 2876 "failed to get aclk source\n"); 2877 2878 vop2->pclk = devm_clk_get_optional(vop2->dev, "pclk_vop"); 2879 if (IS_ERR(vop2->pclk)) 2880 return dev_err_probe(drm->dev, PTR_ERR(vop2->pclk), 2881 "failed to get pclk source\n"); 2882 2883 vop2->pll_hdmiphy0 = devm_clk_get_optional(vop2->dev, "pll_hdmiphy0"); 2884 if (IS_ERR(vop2->pll_hdmiphy0)) 2885 return dev_err_probe(drm->dev, PTR_ERR(vop2->pll_hdmiphy0), 2886 "failed to get pll_hdmiphy0\n"); 2887 2888 vop2->pll_hdmiphy1 = devm_clk_get_optional(vop2->dev, "pll_hdmiphy1"); 2889 if (IS_ERR(vop2->pll_hdmiphy1)) 2890 return dev_err_probe(drm->dev, PTR_ERR(vop2->pll_hdmiphy1), 2891 "failed to get pll_hdmiphy1\n"); 2892 2893 vop2->irq = platform_get_irq(pdev, 0); 2894 if (vop2->irq < 0) 2895 return dev_err_probe(drm->dev, vop2->irq, "cannot find irq for vop2\n"); 2896 2897 mutex_init(&vop2->vop2_lock); 2898 mutex_init(&vop2->ovl_lock); 2899 2900 ret = devm_request_irq(dev, vop2->irq, vop2_isr, IRQF_SHARED, dev_name(dev), vop2); 2901 if (ret) 2902 return ret; 2903 2904 ret = vop2_create_crtcs(vop2); 2905 if (ret) 2906 return ret; 2907 2908 if (vop2->version >= VOP_VERSION_RK3576) { 2909 struct drm_crtc *crtc; 2910 2911 drm_for_each_crtc(crtc, drm) { 2912 struct vop2_video_port *vp = to_vop2_video_port(crtc); 2913 int vp_irq; 2914 const char *irq_name = devm_kasprintf(dev, GFP_KERNEL, "vp%d", vp->id); 2915 2916 if (!irq_name) 2917 return -ENOMEM; 2918 2919 vp_irq = platform_get_irq_byname(pdev, irq_name); 2920 if (vp_irq < 0) 2921 return dev_err_probe(drm->dev, vp_irq, 2922 "cannot find irq for vop2 vp%d\n", vp->id); 2923 2924 ret = devm_request_irq(dev, vp_irq, rk3576_vp_isr, IRQF_SHARED, irq_name, 2925 vp); 2926 if (ret) 2927 dev_err_probe(drm->dev, ret, 2928 "request irq for vop2 vp%d failed\n", vp->id); 2929 } 2930 } 2931 2932 ret = vop2_find_rgb_encoder(vop2); 2933 if (ret >= 0) { 2934 vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc, 2935 vop2->drm, ret); 2936 if (IS_ERR(vop2->rgb)) { 2937 if (PTR_ERR(vop2->rgb) == -EPROBE_DEFER) { 2938 ret = PTR_ERR(vop2->rgb); 2939 goto err_crtcs; 2940 } 2941 vop2->rgb = NULL; 2942 } 2943 } 2944 2945 rockchip_drm_dma_init_device(vop2->drm, vop2->dev); 2946 2947 pm_runtime_enable(&pdev->dev); 2948 2949 return 0; 2950 2951 err_crtcs: 2952 vop2_destroy_crtcs(vop2); 2953 2954 return ret; 2955 } 2956 2957 static void vop2_unbind(struct device *dev, struct device *master, void *data) 2958 { 2959 struct vop2 *vop2 = dev_get_drvdata(dev); 2960 2961 pm_runtime_disable(dev); 2962 2963 if (vop2->rgb) 2964 rockchip_rgb_fini(vop2->rgb); 2965 2966 vop2_destroy_crtcs(vop2); 2967 } 2968 2969 const struct component_ops vop2_component_ops = { 2970 .bind = vop2_bind, 2971 .unbind = vop2_unbind, 2972 }; 2973 EXPORT_SYMBOL_GPL(vop2_component_ops); 2974