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