Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.15-rc1 930 lines 22 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * rcar_du_kms.c -- R-Car Display Unit Mode Setting 4 * 5 * Copyright (C) 2013-2015 Renesas Electronics Corporation 6 * 7 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) 8 */ 9 10#include <drm/drm_atomic.h> 11#include <drm/drm_atomic_helper.h> 12#include <drm/drm_crtc.h> 13#include <drm/drm_device.h> 14#include <drm/drm_fb_cma_helper.h> 15#include <drm/drm_gem_cma_helper.h> 16#include <drm/drm_gem_framebuffer_helper.h> 17#include <drm/drm_managed.h> 18#include <drm/drm_probe_helper.h> 19#include <drm/drm_vblank.h> 20 21#include <linux/device.h> 22#include <linux/of_graph.h> 23#include <linux/of_platform.h> 24#include <linux/wait.h> 25 26#include "rcar_du_crtc.h" 27#include "rcar_du_drv.h" 28#include "rcar_du_encoder.h" 29#include "rcar_du_kms.h" 30#include "rcar_du_regs.h" 31#include "rcar_du_vsp.h" 32#include "rcar_du_writeback.h" 33 34/* ----------------------------------------------------------------------------- 35 * Format helpers 36 */ 37 38static const struct rcar_du_format_info rcar_du_format_infos[] = { 39 { 40 .fourcc = DRM_FORMAT_RGB565, 41 .v4l2 = V4L2_PIX_FMT_RGB565, 42 .bpp = 16, 43 .planes = 1, 44 .hsub = 1, 45 .pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP, 46 .edf = PnDDCR4_EDF_NONE, 47 }, { 48 .fourcc = DRM_FORMAT_ARGB1555, 49 .v4l2 = V4L2_PIX_FMT_ARGB555, 50 .bpp = 16, 51 .planes = 1, 52 .hsub = 1, 53 .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB, 54 .edf = PnDDCR4_EDF_NONE, 55 }, { 56 .fourcc = DRM_FORMAT_XRGB1555, 57 .v4l2 = V4L2_PIX_FMT_XRGB555, 58 .bpp = 16, 59 .planes = 1, 60 .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB, 61 .edf = PnDDCR4_EDF_NONE, 62 }, { 63 .fourcc = DRM_FORMAT_XRGB8888, 64 .v4l2 = V4L2_PIX_FMT_XBGR32, 65 .bpp = 32, 66 .planes = 1, 67 .hsub = 1, 68 .pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP, 69 .edf = PnDDCR4_EDF_RGB888, 70 }, { 71 .fourcc = DRM_FORMAT_ARGB8888, 72 .v4l2 = V4L2_PIX_FMT_ABGR32, 73 .bpp = 32, 74 .planes = 1, 75 .hsub = 1, 76 .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_16BPP, 77 .edf = PnDDCR4_EDF_ARGB8888, 78 }, { 79 .fourcc = DRM_FORMAT_UYVY, 80 .v4l2 = V4L2_PIX_FMT_UYVY, 81 .bpp = 16, 82 .planes = 1, 83 .hsub = 2, 84 .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC, 85 .edf = PnDDCR4_EDF_NONE, 86 }, { 87 .fourcc = DRM_FORMAT_YUYV, 88 .v4l2 = V4L2_PIX_FMT_YUYV, 89 .bpp = 16, 90 .planes = 1, 91 .hsub = 2, 92 .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC, 93 .edf = PnDDCR4_EDF_NONE, 94 }, { 95 .fourcc = DRM_FORMAT_NV12, 96 .v4l2 = V4L2_PIX_FMT_NV12M, 97 .bpp = 12, 98 .planes = 2, 99 .hsub = 2, 100 .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC, 101 .edf = PnDDCR4_EDF_NONE, 102 }, { 103 .fourcc = DRM_FORMAT_NV21, 104 .v4l2 = V4L2_PIX_FMT_NV21M, 105 .bpp = 12, 106 .planes = 2, 107 .hsub = 2, 108 .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC, 109 .edf = PnDDCR4_EDF_NONE, 110 }, { 111 .fourcc = DRM_FORMAT_NV16, 112 .v4l2 = V4L2_PIX_FMT_NV16M, 113 .bpp = 16, 114 .planes = 2, 115 .hsub = 2, 116 .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC, 117 .edf = PnDDCR4_EDF_NONE, 118 }, 119 /* 120 * The following formats are not supported on Gen2 and thus have no 121 * associated .pnmr or .edf settings. 122 */ 123 { 124 .fourcc = DRM_FORMAT_RGB332, 125 .v4l2 = V4L2_PIX_FMT_RGB332, 126 .bpp = 8, 127 .planes = 1, 128 .hsub = 1, 129 }, { 130 .fourcc = DRM_FORMAT_ARGB4444, 131 .v4l2 = V4L2_PIX_FMT_ARGB444, 132 .bpp = 16, 133 .planes = 1, 134 .hsub = 1, 135 }, { 136 .fourcc = DRM_FORMAT_XRGB4444, 137 .v4l2 = V4L2_PIX_FMT_XRGB444, 138 .bpp = 16, 139 .planes = 1, 140 .hsub = 1, 141 }, { 142 .fourcc = DRM_FORMAT_RGBA4444, 143 .v4l2 = V4L2_PIX_FMT_RGBA444, 144 .bpp = 16, 145 .planes = 1, 146 .hsub = 1, 147 }, { 148 .fourcc = DRM_FORMAT_RGBX4444, 149 .v4l2 = V4L2_PIX_FMT_RGBX444, 150 .bpp = 16, 151 .planes = 1, 152 .hsub = 1, 153 }, { 154 .fourcc = DRM_FORMAT_ABGR4444, 155 .v4l2 = V4L2_PIX_FMT_ABGR444, 156 .bpp = 16, 157 .planes = 1, 158 .hsub = 1, 159 }, { 160 .fourcc = DRM_FORMAT_XBGR4444, 161 .v4l2 = V4L2_PIX_FMT_XBGR444, 162 .bpp = 16, 163 .planes = 1, 164 .hsub = 1, 165 }, { 166 .fourcc = DRM_FORMAT_BGRA4444, 167 .v4l2 = V4L2_PIX_FMT_BGRA444, 168 .bpp = 16, 169 .planes = 1, 170 .hsub = 1, 171 }, { 172 .fourcc = DRM_FORMAT_BGRX4444, 173 .v4l2 = V4L2_PIX_FMT_BGRX444, 174 .bpp = 16, 175 .planes = 1, 176 .hsub = 1, 177 }, { 178 .fourcc = DRM_FORMAT_RGBA5551, 179 .v4l2 = V4L2_PIX_FMT_RGBA555, 180 .bpp = 16, 181 .planes = 1, 182 .hsub = 1, 183 }, { 184 .fourcc = DRM_FORMAT_RGBX5551, 185 .v4l2 = V4L2_PIX_FMT_RGBX555, 186 .bpp = 16, 187 .planes = 1, 188 .hsub = 1, 189 }, { 190 .fourcc = DRM_FORMAT_ABGR1555, 191 .v4l2 = V4L2_PIX_FMT_ABGR555, 192 .bpp = 16, 193 .planes = 1, 194 .hsub = 1, 195 }, { 196 .fourcc = DRM_FORMAT_XBGR1555, 197 .v4l2 = V4L2_PIX_FMT_XBGR555, 198 .bpp = 16, 199 .planes = 1, 200 .hsub = 1, 201 }, { 202 .fourcc = DRM_FORMAT_BGRA5551, 203 .v4l2 = V4L2_PIX_FMT_BGRA555, 204 .bpp = 16, 205 .planes = 1, 206 .hsub = 1, 207 }, { 208 .fourcc = DRM_FORMAT_BGRX5551, 209 .v4l2 = V4L2_PIX_FMT_BGRX555, 210 .bpp = 16, 211 .planes = 1, 212 .hsub = 1, 213 }, { 214 .fourcc = DRM_FORMAT_BGR888, 215 .v4l2 = V4L2_PIX_FMT_RGB24, 216 .bpp = 24, 217 .planes = 1, 218 .hsub = 1, 219 }, { 220 .fourcc = DRM_FORMAT_RGB888, 221 .v4l2 = V4L2_PIX_FMT_BGR24, 222 .bpp = 24, 223 .planes = 1, 224 .hsub = 1, 225 }, { 226 .fourcc = DRM_FORMAT_RGBA8888, 227 .v4l2 = V4L2_PIX_FMT_BGRA32, 228 .bpp = 32, 229 .planes = 1, 230 .hsub = 1, 231 }, { 232 .fourcc = DRM_FORMAT_RGBX8888, 233 .v4l2 = V4L2_PIX_FMT_BGRX32, 234 .bpp = 32, 235 .planes = 1, 236 .hsub = 1, 237 }, { 238 .fourcc = DRM_FORMAT_ABGR8888, 239 .v4l2 = V4L2_PIX_FMT_RGBA32, 240 .bpp = 32, 241 .planes = 1, 242 .hsub = 1, 243 }, { 244 .fourcc = DRM_FORMAT_XBGR8888, 245 .v4l2 = V4L2_PIX_FMT_RGBX32, 246 .bpp = 32, 247 .planes = 1, 248 .hsub = 1, 249 }, { 250 .fourcc = DRM_FORMAT_BGRA8888, 251 .v4l2 = V4L2_PIX_FMT_ARGB32, 252 .bpp = 32, 253 .planes = 1, 254 .hsub = 1, 255 }, { 256 .fourcc = DRM_FORMAT_BGRX8888, 257 .v4l2 = V4L2_PIX_FMT_XRGB32, 258 .bpp = 32, 259 .planes = 1, 260 .hsub = 1, 261 }, { 262 .fourcc = DRM_FORMAT_YVYU, 263 .v4l2 = V4L2_PIX_FMT_YVYU, 264 .bpp = 16, 265 .planes = 1, 266 .hsub = 2, 267 }, { 268 .fourcc = DRM_FORMAT_NV61, 269 .v4l2 = V4L2_PIX_FMT_NV61M, 270 .bpp = 16, 271 .planes = 2, 272 .hsub = 2, 273 }, { 274 .fourcc = DRM_FORMAT_YUV420, 275 .v4l2 = V4L2_PIX_FMT_YUV420M, 276 .bpp = 12, 277 .planes = 3, 278 .hsub = 2, 279 }, { 280 .fourcc = DRM_FORMAT_YVU420, 281 .v4l2 = V4L2_PIX_FMT_YVU420M, 282 .bpp = 12, 283 .planes = 3, 284 .hsub = 2, 285 }, { 286 .fourcc = DRM_FORMAT_YUV422, 287 .v4l2 = V4L2_PIX_FMT_YUV422M, 288 .bpp = 16, 289 .planes = 3, 290 .hsub = 2, 291 }, { 292 .fourcc = DRM_FORMAT_YVU422, 293 .v4l2 = V4L2_PIX_FMT_YVU422M, 294 .bpp = 16, 295 .planes = 3, 296 .hsub = 2, 297 }, { 298 .fourcc = DRM_FORMAT_YUV444, 299 .v4l2 = V4L2_PIX_FMT_YUV444M, 300 .bpp = 24, 301 .planes = 3, 302 .hsub = 1, 303 }, { 304 .fourcc = DRM_FORMAT_YVU444, 305 .v4l2 = V4L2_PIX_FMT_YVU444M, 306 .bpp = 24, 307 .planes = 3, 308 .hsub = 1, 309 }, 310}; 311 312const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc) 313{ 314 unsigned int i; 315 316 for (i = 0; i < ARRAY_SIZE(rcar_du_format_infos); ++i) { 317 if (rcar_du_format_infos[i].fourcc == fourcc) 318 return &rcar_du_format_infos[i]; 319 } 320 321 return NULL; 322} 323 324/* ----------------------------------------------------------------------------- 325 * Frame buffer 326 */ 327 328int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev, 329 struct drm_mode_create_dumb *args) 330{ 331 struct rcar_du_device *rcdu = to_rcar_du_device(dev); 332 unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); 333 unsigned int align; 334 335 /* 336 * The R8A7779 DU requires a 16 pixels pitch alignment as documented, 337 * but the R8A7790 DU seems to require a 128 bytes pitch alignment. 338 */ 339 if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B)) 340 align = 128; 341 else 342 align = 16 * args->bpp / 8; 343 344 args->pitch = roundup(min_pitch, align); 345 346 return drm_gem_cma_dumb_create_internal(file, dev, args); 347} 348 349static struct drm_framebuffer * 350rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, 351 const struct drm_mode_fb_cmd2 *mode_cmd) 352{ 353 struct rcar_du_device *rcdu = to_rcar_du_device(dev); 354 const struct rcar_du_format_info *format; 355 unsigned int chroma_pitch; 356 unsigned int max_pitch; 357 unsigned int align; 358 unsigned int i; 359 360 format = rcar_du_format_info(mode_cmd->pixel_format); 361 if (format == NULL) { 362 dev_dbg(dev->dev, "unsupported pixel format %08x\n", 363 mode_cmd->pixel_format); 364 return ERR_PTR(-EINVAL); 365 } 366 367 if (rcdu->info->gen < 3) { 368 /* 369 * On Gen2 the DU limits the pitch to 4095 pixels and requires 370 * buffers to be aligned to a 16 pixels boundary (or 128 bytes 371 * on some platforms). 372 */ 373 unsigned int bpp = format->planes == 1 ? format->bpp / 8 : 1; 374 375 max_pitch = 4095 * bpp; 376 377 if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B)) 378 align = 128; 379 else 380 align = 16 * bpp; 381 } else { 382 /* 383 * On Gen3 the memory interface is handled by the VSP that 384 * limits the pitch to 65535 bytes and has no alignment 385 * constraint. 386 */ 387 max_pitch = 65535; 388 align = 1; 389 } 390 391 if (mode_cmd->pitches[0] & (align - 1) || 392 mode_cmd->pitches[0] > max_pitch) { 393 dev_dbg(dev->dev, "invalid pitch value %u\n", 394 mode_cmd->pitches[0]); 395 return ERR_PTR(-EINVAL); 396 } 397 398 /* 399 * Calculate the chroma plane(s) pitch using the horizontal subsampling 400 * factor. For semi-planar formats, the U and V planes are combined, the 401 * pitch must thus be doubled. 402 */ 403 chroma_pitch = mode_cmd->pitches[0] / format->hsub; 404 if (format->planes == 2) 405 chroma_pitch *= 2; 406 407 for (i = 1; i < format->planes; ++i) { 408 if (mode_cmd->pitches[i] != chroma_pitch) { 409 dev_dbg(dev->dev, 410 "luma and chroma pitches are not compatible\n"); 411 return ERR_PTR(-EINVAL); 412 } 413 } 414 415 return drm_gem_fb_create(dev, file_priv, mode_cmd); 416} 417 418/* ----------------------------------------------------------------------------- 419 * Atomic Check and Update 420 */ 421 422static int rcar_du_atomic_check(struct drm_device *dev, 423 struct drm_atomic_state *state) 424{ 425 struct rcar_du_device *rcdu = to_rcar_du_device(dev); 426 int ret; 427 428 ret = drm_atomic_helper_check(dev, state); 429 if (ret) 430 return ret; 431 432 if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) 433 return 0; 434 435 return rcar_du_atomic_check_planes(dev, state); 436} 437 438static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state) 439{ 440 struct drm_device *dev = old_state->dev; 441 struct rcar_du_device *rcdu = to_rcar_du_device(dev); 442 struct drm_crtc_state *crtc_state; 443 struct drm_crtc *crtc; 444 unsigned int i; 445 446 /* 447 * Store RGB routing to DPAD0 and DPAD1, the hardware will be configured 448 * when starting the CRTCs. 449 */ 450 rcdu->dpad1_source = -1; 451 452 for_each_new_crtc_in_state(old_state, crtc, crtc_state, i) { 453 struct rcar_du_crtc_state *rcrtc_state = 454 to_rcar_crtc_state(crtc_state); 455 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); 456 457 if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD0)) 458 rcdu->dpad0_source = rcrtc->index; 459 460 if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD1)) 461 rcdu->dpad1_source = rcrtc->index; 462 } 463 464 /* Apply the atomic update. */ 465 drm_atomic_helper_commit_modeset_disables(dev, old_state); 466 drm_atomic_helper_commit_planes(dev, old_state, 467 DRM_PLANE_COMMIT_ACTIVE_ONLY); 468 drm_atomic_helper_commit_modeset_enables(dev, old_state); 469 470 drm_atomic_helper_commit_hw_done(old_state); 471 drm_atomic_helper_wait_for_flip_done(dev, old_state); 472 473 drm_atomic_helper_cleanup_planes(dev, old_state); 474} 475 476/* ----------------------------------------------------------------------------- 477 * Initialization 478 */ 479 480static const struct drm_mode_config_helper_funcs rcar_du_mode_config_helper = { 481 .atomic_commit_tail = rcar_du_atomic_commit_tail, 482}; 483 484static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = { 485 .fb_create = rcar_du_fb_create, 486 .atomic_check = rcar_du_atomic_check, 487 .atomic_commit = drm_atomic_helper_commit, 488}; 489 490static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu, 491 enum rcar_du_output output, 492 struct of_endpoint *ep) 493{ 494 struct device_node *entity; 495 int ret; 496 497 /* Locate the connected entity and initialize the encoder. */ 498 entity = of_graph_get_remote_port_parent(ep->local_node); 499 if (!entity) { 500 dev_dbg(rcdu->dev, "unconnected endpoint %pOF, skipping\n", 501 ep->local_node); 502 return -ENODEV; 503 } 504 505 if (!of_device_is_available(entity)) { 506 dev_dbg(rcdu->dev, 507 "connected entity %pOF is disabled, skipping\n", 508 entity); 509 of_node_put(entity); 510 return -ENODEV; 511 } 512 513 ret = rcar_du_encoder_init(rcdu, output, entity); 514 if (ret && ret != -EPROBE_DEFER && ret != -ENOLINK) 515 dev_warn(rcdu->dev, 516 "failed to initialize encoder %pOF on output %u (%d), skipping\n", 517 entity, output, ret); 518 519 of_node_put(entity); 520 521 return ret; 522} 523 524static int rcar_du_encoders_init(struct rcar_du_device *rcdu) 525{ 526 struct device_node *np = rcdu->dev->of_node; 527 struct device_node *ep_node; 528 unsigned int num_encoders = 0; 529 530 /* 531 * Iterate over the endpoints and create one encoder for each output 532 * pipeline. 533 */ 534 for_each_endpoint_of_node(np, ep_node) { 535 enum rcar_du_output output; 536 struct of_endpoint ep; 537 unsigned int i; 538 int ret; 539 540 ret = of_graph_parse_endpoint(ep_node, &ep); 541 if (ret < 0) { 542 of_node_put(ep_node); 543 return ret; 544 } 545 546 /* Find the output route corresponding to the port number. */ 547 for (i = 0; i < RCAR_DU_OUTPUT_MAX; ++i) { 548 if (rcdu->info->routes[i].possible_crtcs && 549 rcdu->info->routes[i].port == ep.port) { 550 output = i; 551 break; 552 } 553 } 554 555 if (i == RCAR_DU_OUTPUT_MAX) { 556 dev_warn(rcdu->dev, 557 "port %u references unexisting output, skipping\n", 558 ep.port); 559 continue; 560 } 561 562 /* Process the output pipeline. */ 563 ret = rcar_du_encoders_init_one(rcdu, output, &ep); 564 if (ret < 0) { 565 if (ret == -EPROBE_DEFER) { 566 of_node_put(ep_node); 567 return ret; 568 } 569 570 continue; 571 } 572 573 num_encoders++; 574 } 575 576 return num_encoders; 577} 578 579static int rcar_du_properties_init(struct rcar_du_device *rcdu) 580{ 581 /* 582 * The color key is expressed as an RGB888 triplet stored in a 32-bit 583 * integer in XRGB8888 format. Bit 24 is used as a flag to disable (0) 584 * or enable source color keying (1). 585 */ 586 rcdu->props.colorkey = 587 drm_property_create_range(&rcdu->ddev, 0, "colorkey", 588 0, 0x01ffffff); 589 if (rcdu->props.colorkey == NULL) 590 return -ENOMEM; 591 592 return 0; 593} 594 595static int rcar_du_vsps_init(struct rcar_du_device *rcdu) 596{ 597 const struct device_node *np = rcdu->dev->of_node; 598 const char *vsps_prop_name = "renesas,vsps"; 599 struct of_phandle_args args; 600 struct { 601 struct device_node *np; 602 unsigned int crtcs_mask; 603 } vsps[RCAR_DU_MAX_VSPS] = { { NULL, }, }; 604 unsigned int vsps_count = 0; 605 unsigned int cells; 606 unsigned int i; 607 int ret; 608 609 /* 610 * First parse the DT vsps property to populate the list of VSPs. Each 611 * entry contains a pointer to the VSP DT node and a bitmask of the 612 * connected DU CRTCs. 613 */ 614 ret = of_property_count_u32_elems(np, vsps_prop_name); 615 if (ret < 0) { 616 /* Backward compatibility with old DTBs. */ 617 vsps_prop_name = "vsps"; 618 ret = of_property_count_u32_elems(np, vsps_prop_name); 619 } 620 cells = ret / rcdu->num_crtcs - 1; 621 if (cells > 1) 622 return -EINVAL; 623 624 for (i = 0; i < rcdu->num_crtcs; ++i) { 625 unsigned int j; 626 627 ret = of_parse_phandle_with_fixed_args(np, vsps_prop_name, 628 cells, i, &args); 629 if (ret < 0) 630 goto error; 631 632 /* 633 * Add the VSP to the list or update the corresponding existing 634 * entry if the VSP has already been added. 635 */ 636 for (j = 0; j < vsps_count; ++j) { 637 if (vsps[j].np == args.np) 638 break; 639 } 640 641 if (j < vsps_count) 642 of_node_put(args.np); 643 else 644 vsps[vsps_count++].np = args.np; 645 646 vsps[j].crtcs_mask |= BIT(i); 647 648 /* 649 * Store the VSP pointer and pipe index in the CRTC. If the 650 * second cell of the 'renesas,vsps' specifier isn't present, 651 * default to 0 to remain compatible with older DT bindings. 652 */ 653 rcdu->crtcs[i].vsp = &rcdu->vsps[j]; 654 rcdu->crtcs[i].vsp_pipe = cells >= 1 ? args.args[0] : 0; 655 } 656 657 /* 658 * Then initialize all the VSPs from the node pointers and CRTCs bitmask 659 * computed previously. 660 */ 661 for (i = 0; i < vsps_count; ++i) { 662 struct rcar_du_vsp *vsp = &rcdu->vsps[i]; 663 664 vsp->index = i; 665 vsp->dev = rcdu; 666 667 ret = rcar_du_vsp_init(vsp, vsps[i].np, vsps[i].crtcs_mask); 668 if (ret < 0) 669 goto error; 670 } 671 672 return 0; 673 674error: 675 for (i = 0; i < ARRAY_SIZE(vsps); ++i) 676 of_node_put(vsps[i].np); 677 678 return ret; 679} 680 681static int rcar_du_cmm_init(struct rcar_du_device *rcdu) 682{ 683 const struct device_node *np = rcdu->dev->of_node; 684 unsigned int i; 685 int cells; 686 687 cells = of_property_count_u32_elems(np, "renesas,cmms"); 688 if (cells == -EINVAL) 689 return 0; 690 691 if (cells > rcdu->num_crtcs) { 692 dev_err(rcdu->dev, 693 "Invalid number of entries in 'renesas,cmms'\n"); 694 return -EINVAL; 695 } 696 697 for (i = 0; i < cells; ++i) { 698 struct platform_device *pdev; 699 struct device_link *link; 700 struct device_node *cmm; 701 int ret; 702 703 cmm = of_parse_phandle(np, "renesas,cmms", i); 704 if (!cmm) { 705 dev_err(rcdu->dev, 706 "Failed to parse 'renesas,cmms' property\n"); 707 return -EINVAL; 708 } 709 710 if (!of_device_is_available(cmm)) { 711 /* It's fine to have a phandle to a non-enabled CMM. */ 712 of_node_put(cmm); 713 continue; 714 } 715 716 pdev = of_find_device_by_node(cmm); 717 if (!pdev) { 718 dev_err(rcdu->dev, "No device found for CMM%u\n", i); 719 of_node_put(cmm); 720 return -EINVAL; 721 } 722 723 of_node_put(cmm); 724 725 /* 726 * -ENODEV is used to report that the CMM config option is 727 * disabled: return 0 and let the DU continue probing. 728 */ 729 ret = rcar_cmm_init(pdev); 730 if (ret) { 731 platform_device_put(pdev); 732 return ret == -ENODEV ? 0 : ret; 733 } 734 735 rcdu->cmms[i] = pdev; 736 737 /* 738 * Enforce suspend/resume ordering by making the CMM a provider 739 * of the DU: CMM is suspended after and resumed before the DU. 740 */ 741 link = device_link_add(rcdu->dev, &pdev->dev, DL_FLAG_STATELESS); 742 if (!link) { 743 dev_err(rcdu->dev, 744 "Failed to create device link to CMM%u\n", i); 745 return -EINVAL; 746 } 747 } 748 749 return 0; 750} 751 752static void rcar_du_modeset_cleanup(struct drm_device *dev, void *res) 753{ 754 struct rcar_du_device *rcdu = to_rcar_du_device(dev); 755 unsigned int i; 756 757 for (i = 0; i < ARRAY_SIZE(rcdu->cmms); ++i) 758 platform_device_put(rcdu->cmms[i]); 759} 760 761int rcar_du_modeset_init(struct rcar_du_device *rcdu) 762{ 763 static const unsigned int mmio_offsets[] = { 764 DU0_REG_OFFSET, DU2_REG_OFFSET 765 }; 766 767 struct drm_device *dev = &rcdu->ddev; 768 struct drm_encoder *encoder; 769 unsigned int dpad0_sources; 770 unsigned int num_encoders; 771 unsigned int num_groups; 772 unsigned int swindex; 773 unsigned int hwindex; 774 unsigned int i; 775 int ret; 776 777 ret = drmm_mode_config_init(dev); 778 if (ret) 779 return ret; 780 781 ret = drmm_add_action(&rcdu->ddev, rcar_du_modeset_cleanup, NULL); 782 if (ret) 783 return ret; 784 785 dev->mode_config.min_width = 0; 786 dev->mode_config.min_height = 0; 787 dev->mode_config.normalize_zpos = true; 788 dev->mode_config.funcs = &rcar_du_mode_config_funcs; 789 dev->mode_config.helper_private = &rcar_du_mode_config_helper; 790 791 if (rcdu->info->gen < 3) { 792 dev->mode_config.max_width = 4095; 793 dev->mode_config.max_height = 2047; 794 } else { 795 /* 796 * The Gen3 DU uses the VSP1 for memory access, and is limited 797 * to frame sizes of 8190x8190. 798 */ 799 dev->mode_config.max_width = 8190; 800 dev->mode_config.max_height = 8190; 801 } 802 803 rcdu->num_crtcs = hweight8(rcdu->info->channels_mask); 804 805 ret = rcar_du_properties_init(rcdu); 806 if (ret < 0) 807 return ret; 808 809 /* 810 * Initialize vertical blanking interrupts handling. Start with vblank 811 * disabled for all CRTCs. 812 */ 813 ret = drm_vblank_init(dev, rcdu->num_crtcs); 814 if (ret < 0) 815 return ret; 816 817 /* Initialize the groups. */ 818 num_groups = DIV_ROUND_UP(rcdu->num_crtcs, 2); 819 820 for (i = 0; i < num_groups; ++i) { 821 struct rcar_du_group *rgrp = &rcdu->groups[i]; 822 823 mutex_init(&rgrp->lock); 824 825 rgrp->dev = rcdu; 826 rgrp->mmio_offset = mmio_offsets[i]; 827 rgrp->index = i; 828 /* Extract the channel mask for this group only. */ 829 rgrp->channels_mask = (rcdu->info->channels_mask >> (2 * i)) 830 & GENMASK(1, 0); 831 rgrp->num_crtcs = hweight8(rgrp->channels_mask); 832 833 /* 834 * If we have more than one CRTCs in this group pre-associate 835 * the low-order planes with CRTC 0 and the high-order planes 836 * with CRTC 1 to minimize flicker occurring when the 837 * association is changed. 838 */ 839 rgrp->dptsr_planes = rgrp->num_crtcs > 1 840 ? (rcdu->info->gen >= 3 ? 0x04 : 0xf0) 841 : 0; 842 843 if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) { 844 ret = rcar_du_planes_init(rgrp); 845 if (ret < 0) 846 return ret; 847 } 848 } 849 850 /* Initialize the compositors. */ 851 if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) { 852 ret = rcar_du_vsps_init(rcdu); 853 if (ret < 0) 854 return ret; 855 } 856 857 /* Initialize the Color Management Modules. */ 858 ret = rcar_du_cmm_init(rcdu); 859 if (ret) 860 return ret; 861 862 /* Create the CRTCs. */ 863 for (swindex = 0, hwindex = 0; swindex < rcdu->num_crtcs; ++hwindex) { 864 struct rcar_du_group *rgrp; 865 866 /* Skip unpopulated DU channels. */ 867 if (!(rcdu->info->channels_mask & BIT(hwindex))) 868 continue; 869 870 rgrp = &rcdu->groups[hwindex / 2]; 871 872 ret = rcar_du_crtc_create(rgrp, swindex++, hwindex); 873 if (ret < 0) 874 return ret; 875 } 876 877 /* Initialize the encoders. */ 878 ret = rcar_du_encoders_init(rcdu); 879 if (ret < 0) 880 return ret; 881 882 if (ret == 0) { 883 dev_err(rcdu->dev, "error: no encoder could be initialized\n"); 884 return -EINVAL; 885 } 886 887 num_encoders = ret; 888 889 /* 890 * Set the possible CRTCs and possible clones. There's always at least 891 * one way for all encoders to clone each other, set all bits in the 892 * possible clones field. 893 */ 894 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 895 struct rcar_du_encoder *renc = to_rcar_encoder(encoder); 896 const struct rcar_du_output_routing *route = 897 &rcdu->info->routes[renc->output]; 898 899 encoder->possible_crtcs = route->possible_crtcs; 900 encoder->possible_clones = (1 << num_encoders) - 1; 901 } 902 903 /* Create the writeback connectors. */ 904 if (rcdu->info->gen >= 3) { 905 for (i = 0; i < rcdu->num_crtcs; ++i) { 906 struct rcar_du_crtc *rcrtc = &rcdu->crtcs[i]; 907 908 ret = rcar_du_writeback_init(rcdu, rcrtc); 909 if (ret < 0) 910 return ret; 911 } 912 } 913 914 /* 915 * Initialize the default DPAD0 source to the index of the first DU 916 * channel that can be connected to DPAD0. The exact value doesn't 917 * matter as it should be overwritten by mode setting for the RGB 918 * output, but it is nonetheless required to ensure a valid initial 919 * hardware configuration on Gen3 where DU0 can't always be connected to 920 * DPAD0. 921 */ 922 dpad0_sources = rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs; 923 rcdu->dpad0_source = ffs(dpad0_sources) - 1; 924 925 drm_mode_config_reset(dev); 926 927 drm_kms_helper_poll_init(dev); 928 929 return 0; 930}