1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2019-2022 Bootlin 4 * Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com> 5 */ 6 7 #include <linux/of.h> 8 #include <linux/types.h> 9 10 #include <drm/drm_atomic.h> 11 #include <drm/drm_atomic_helper.h> 12 #include <drm/drm_blend.h> 13 #include <drm/drm_fb_cma_helper.h> 14 #include <drm/drm_fourcc.h> 15 #include <drm/drm_framebuffer.h> 16 #include <drm/drm_plane.h> 17 #include <drm/drm_print.h> 18 19 #include "logicvc_crtc.h" 20 #include "logicvc_drm.h" 21 #include "logicvc_layer.h" 22 #include "logicvc_of.h" 23 #include "logicvc_regs.h" 24 25 #define logicvc_layer(p) \ 26 container_of(p, struct logicvc_layer, drm_plane) 27 28 static uint32_t logicvc_layer_formats_rgb16[] = { 29 DRM_FORMAT_RGB565, 30 DRM_FORMAT_BGR565, 31 DRM_FORMAT_INVALID, 32 }; 33 34 static uint32_t logicvc_layer_formats_rgb24[] = { 35 DRM_FORMAT_XRGB8888, 36 DRM_FORMAT_XBGR8888, 37 DRM_FORMAT_INVALID, 38 }; 39 40 /* 41 * What we call depth in this driver only counts color components, not alpha. 42 * This allows us to stay compatible with the LogiCVC bistream definitions. 43 */ 44 static uint32_t logicvc_layer_formats_rgb24_alpha[] = { 45 DRM_FORMAT_ARGB8888, 46 DRM_FORMAT_ABGR8888, 47 DRM_FORMAT_INVALID, 48 }; 49 50 static struct logicvc_layer_formats logicvc_layer_formats[] = { 51 { 52 .colorspace = LOGICVC_LAYER_COLORSPACE_RGB, 53 .depth = 16, 54 .formats = logicvc_layer_formats_rgb16, 55 }, 56 { 57 .colorspace = LOGICVC_LAYER_COLORSPACE_RGB, 58 .depth = 24, 59 .formats = logicvc_layer_formats_rgb24, 60 }, 61 { 62 .colorspace = LOGICVC_LAYER_COLORSPACE_RGB, 63 .depth = 24, 64 .alpha = true, 65 .formats = logicvc_layer_formats_rgb24_alpha, 66 }, 67 { } 68 }; 69 70 static bool logicvc_layer_format_inverted(uint32_t format) 71 { 72 switch (format) { 73 case DRM_FORMAT_BGR565: 74 case DRM_FORMAT_BGR888: 75 case DRM_FORMAT_XBGR8888: 76 case DRM_FORMAT_ABGR8888: 77 return true; 78 default: 79 return false; 80 } 81 } 82 83 static int logicvc_plane_atomic_check(struct drm_plane *drm_plane, 84 struct drm_atomic_state *state) 85 { 86 struct drm_device *drm_dev = drm_plane->dev; 87 struct logicvc_layer *layer = logicvc_layer(drm_plane); 88 struct logicvc_drm *logicvc = logicvc_drm(drm_dev); 89 struct drm_plane_state *new_state = 90 drm_atomic_get_new_plane_state(state, drm_plane); 91 struct drm_crtc_state *crtc_state; 92 int min_scale, max_scale; 93 bool can_position; 94 int ret; 95 96 if (!new_state->crtc) 97 return 0; 98 99 crtc_state = drm_atomic_get_existing_crtc_state(new_state->state, 100 new_state->crtc); 101 if (WARN_ON(!crtc_state)) 102 return -EINVAL; 103 104 if (new_state->crtc_x < 0 || new_state->crtc_y < 0) { 105 drm_err(drm_dev, 106 "Negative on-CRTC positions are not supported.\n"); 107 return -EINVAL; 108 } 109 110 if (!logicvc->caps->layer_address) { 111 ret = logicvc_layer_buffer_find_setup(logicvc, layer, new_state, 112 NULL); 113 if (ret) { 114 drm_err(drm_dev, "No viable setup for buffer found.\n"); 115 return ret; 116 } 117 } 118 119 min_scale = DRM_PLANE_NO_SCALING; 120 max_scale = DRM_PLANE_NO_SCALING; 121 122 can_position = (drm_plane->type == DRM_PLANE_TYPE_OVERLAY && 123 layer->index != (logicvc->config.layers_count - 1) && 124 logicvc->config.layers_configurable); 125 126 ret = drm_atomic_helper_check_plane_state(new_state, crtc_state, 127 min_scale, max_scale, 128 can_position, true); 129 if (ret) { 130 drm_err(drm_dev, "Invalid plane state\n\n"); 131 return ret; 132 } 133 134 return 0; 135 } 136 137 static void logicvc_plane_atomic_update(struct drm_plane *drm_plane, 138 struct drm_atomic_state *state) 139 { 140 struct logicvc_layer *layer = logicvc_layer(drm_plane); 141 struct logicvc_drm *logicvc = logicvc_drm(drm_plane->dev); 142 struct drm_device *drm_dev = &logicvc->drm_dev; 143 struct drm_plane_state *new_state = 144 drm_atomic_get_new_plane_state(state, drm_plane); 145 struct drm_crtc *drm_crtc = &logicvc->crtc->drm_crtc; 146 struct drm_display_mode *mode = &drm_crtc->state->adjusted_mode; 147 struct drm_framebuffer *fb = new_state->fb; 148 struct logicvc_layer_buffer_setup setup = {}; 149 u32 index = layer->index; 150 u32 reg; 151 152 /* Layer dimensions */ 153 154 regmap_write(logicvc->regmap, LOGICVC_LAYER_WIDTH_REG(index), 155 new_state->crtc_w - 1); 156 regmap_write(logicvc->regmap, LOGICVC_LAYER_HEIGHT_REG(index), 157 new_state->crtc_h - 1); 158 159 if (logicvc->caps->layer_address) { 160 phys_addr_t fb_addr = drm_fb_cma_get_gem_addr(fb, new_state, 0); 161 162 regmap_write(logicvc->regmap, LOGICVC_LAYER_ADDRESS_REG(index), 163 fb_addr); 164 } else { 165 /* Rely on offsets to configure the address. */ 166 167 logicvc_layer_buffer_find_setup(logicvc, layer, new_state, 168 &setup); 169 170 /* Layer memory offsets */ 171 172 regmap_write(logicvc->regmap, LOGICVC_BUFFER_SEL_REG, 173 LOGICVC_BUFFER_SEL_VALUE(index, setup.buffer_sel)); 174 regmap_write(logicvc->regmap, LOGICVC_LAYER_HOFFSET_REG(index), 175 setup.hoffset); 176 regmap_write(logicvc->regmap, LOGICVC_LAYER_VOFFSET_REG(index), 177 setup.voffset); 178 } 179 180 /* Layer position */ 181 182 regmap_write(logicvc->regmap, LOGICVC_LAYER_HPOSITION_REG(index), 183 mode->hdisplay - 1 - new_state->crtc_x); 184 185 /* Vertical position must be set last to sync layer register changes. */ 186 regmap_write(logicvc->regmap, LOGICVC_LAYER_VPOSITION_REG(index), 187 mode->vdisplay - 1 - new_state->crtc_y); 188 189 /* Layer alpha */ 190 191 if (layer->config.alpha_mode == LOGICVC_LAYER_ALPHA_LAYER) { 192 u32 alpha_bits; 193 u32 alpha_max; 194 u32 alpha; 195 196 switch (layer->config.depth) { 197 case 8: 198 alpha_bits = 3; 199 break; 200 case 16: 201 if (layer->config.colorspace == 202 LOGICVC_LAYER_COLORSPACE_YUV) 203 alpha_bits = 8; 204 else 205 alpha_bits = 6; 206 break; 207 default: 208 alpha_bits = 8; 209 break; 210 } 211 212 alpha_max = BIT(alpha_bits) - 1; 213 alpha = new_state->alpha * alpha_max / DRM_BLEND_ALPHA_OPAQUE; 214 215 drm_dbg_kms(drm_dev, "Setting layer %d alpha to %d/%d\n", index, 216 alpha, alpha_max); 217 218 regmap_write(logicvc->regmap, LOGICVC_LAYER_ALPHA_REG(index), 219 alpha); 220 } 221 222 /* Layer control */ 223 224 reg = LOGICVC_LAYER_CTRL_ENABLE; 225 226 if (logicvc_layer_format_inverted(fb->format->format)) 227 reg |= LOGICVC_LAYER_CTRL_PIXEL_FORMAT_INVERT; 228 229 reg |= LOGICVC_LAYER_CTRL_COLOR_KEY_DISABLE; 230 231 regmap_write(logicvc->regmap, LOGICVC_LAYER_CTRL_REG(index), reg); 232 } 233 234 static void logicvc_plane_atomic_disable(struct drm_plane *drm_plane, 235 struct drm_atomic_state *state) 236 { 237 struct logicvc_layer *layer = logicvc_layer(drm_plane); 238 struct logicvc_drm *logicvc = logicvc_drm(drm_plane->dev); 239 u32 index = layer->index; 240 241 regmap_write(logicvc->regmap, LOGICVC_LAYER_CTRL_REG(index), 0); 242 } 243 244 static struct drm_plane_helper_funcs logicvc_plane_helper_funcs = { 245 .atomic_check = logicvc_plane_atomic_check, 246 .atomic_update = logicvc_plane_atomic_update, 247 .atomic_disable = logicvc_plane_atomic_disable, 248 }; 249 250 static const struct drm_plane_funcs logicvc_plane_funcs = { 251 .update_plane = drm_atomic_helper_update_plane, 252 .disable_plane = drm_atomic_helper_disable_plane, 253 .destroy = drm_plane_cleanup, 254 .reset = drm_atomic_helper_plane_reset, 255 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 256 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 257 }; 258 259 int logicvc_layer_buffer_find_setup(struct logicvc_drm *logicvc, 260 struct logicvc_layer *layer, 261 struct drm_plane_state *state, 262 struct logicvc_layer_buffer_setup *setup) 263 { 264 struct drm_device *drm_dev = &logicvc->drm_dev; 265 struct drm_framebuffer *fb = state->fb; 266 /* All the supported formats have a single data plane. */ 267 u32 layer_bytespp = fb->format->cpp[0]; 268 u32 layer_stride = layer_bytespp * logicvc->config.row_stride; 269 u32 base_offset = layer->config.base_offset * layer_stride; 270 u32 buffer_offset = layer->config.buffer_offset * layer_stride; 271 u8 buffer_sel = 0; 272 u16 voffset = 0; 273 u16 hoffset = 0; 274 phys_addr_t fb_addr; 275 u32 fb_offset; 276 u32 gap; 277 278 if (!logicvc->reserved_mem_base) { 279 drm_err(drm_dev, "No reserved memory base was registered!\n"); 280 return -ENOMEM; 281 } 282 283 fb_addr = drm_fb_cma_get_gem_addr(fb, state, 0); 284 if (fb_addr < logicvc->reserved_mem_base) { 285 drm_err(drm_dev, 286 "Framebuffer memory below reserved memory base!\n"); 287 return -EINVAL; 288 } 289 290 fb_offset = (u32) (fb_addr - logicvc->reserved_mem_base); 291 292 if (fb_offset < base_offset) { 293 drm_err(drm_dev, 294 "Framebuffer offset below layer base offset!\n"); 295 return -EINVAL; 296 } 297 298 gap = fb_offset - base_offset; 299 300 /* Use the possible video buffers selection. */ 301 if (gap && buffer_offset) { 302 buffer_sel = gap / buffer_offset; 303 if (buffer_sel > LOGICVC_BUFFER_SEL_MAX) 304 buffer_sel = LOGICVC_BUFFER_SEL_MAX; 305 306 gap -= buffer_sel * buffer_offset; 307 } 308 309 /* Use the vertical offset. */ 310 if (gap && layer_stride && logicvc->config.layers_configurable) { 311 voffset = gap / layer_stride; 312 if (voffset > LOGICVC_LAYER_VOFFSET_MAX) 313 voffset = LOGICVC_LAYER_VOFFSET_MAX; 314 315 gap -= voffset * layer_stride; 316 } 317 318 /* Use the horizontal offset. */ 319 if (gap && layer_bytespp && logicvc->config.layers_configurable) { 320 hoffset = gap / layer_bytespp; 321 if (hoffset > LOGICVC_DIMENSIONS_MAX) 322 hoffset = LOGICVC_DIMENSIONS_MAX; 323 324 gap -= hoffset * layer_bytespp; 325 } 326 327 if (gap) { 328 drm_err(drm_dev, 329 "Unable to find layer %d buffer setup for 0x%x byte gap\n", 330 layer->index, fb_offset - base_offset); 331 return -EINVAL; 332 } 333 334 drm_dbg_kms(drm_dev, "Found layer %d buffer setup for 0x%x byte gap:\n", 335 layer->index, fb_offset - base_offset); 336 337 drm_dbg_kms(drm_dev, "- buffer_sel = 0x%x chunks of 0x%x bytes\n", 338 buffer_sel, buffer_offset); 339 drm_dbg_kms(drm_dev, "- voffset = 0x%x chunks of 0x%x bytes\n", voffset, 340 layer_stride); 341 drm_dbg_kms(drm_dev, "- hoffset = 0x%x chunks of 0x%x bytes\n", hoffset, 342 layer_bytespp); 343 344 if (setup) { 345 setup->buffer_sel = buffer_sel; 346 setup->voffset = voffset; 347 setup->hoffset = hoffset; 348 } 349 350 return 0; 351 } 352 353 static struct logicvc_layer_formats *logicvc_layer_formats_lookup(struct logicvc_layer *layer) 354 { 355 bool alpha; 356 unsigned int i = 0; 357 358 alpha = (layer->config.alpha_mode == LOGICVC_LAYER_ALPHA_PIXEL); 359 360 while (logicvc_layer_formats[i].formats) { 361 if (logicvc_layer_formats[i].colorspace == layer->config.colorspace && 362 logicvc_layer_formats[i].depth == layer->config.depth && 363 logicvc_layer_formats[i].alpha == alpha) 364 return &logicvc_layer_formats[i]; 365 366 i++; 367 } 368 369 return NULL; 370 } 371 372 static unsigned int logicvc_layer_formats_count(struct logicvc_layer_formats *formats) 373 { 374 unsigned int count = 0; 375 376 while (formats->formats[count] != DRM_FORMAT_INVALID) 377 count++; 378 379 return count; 380 } 381 382 static int logicvc_layer_config_parse(struct logicvc_drm *logicvc, 383 struct logicvc_layer *layer) 384 { 385 struct device_node *of_node = layer->of_node; 386 struct logicvc_layer_config *config = &layer->config; 387 int ret; 388 389 logicvc_of_property_parse_bool(of_node, 390 LOGICVC_OF_PROPERTY_LAYER_PRIMARY, 391 &config->primary); 392 393 ret = logicvc_of_property_parse_u32(of_node, 394 LOGICVC_OF_PROPERTY_LAYER_COLORSPACE, 395 &config->colorspace); 396 if (ret) 397 return ret; 398 399 ret = logicvc_of_property_parse_u32(of_node, 400 LOGICVC_OF_PROPERTY_LAYER_DEPTH, 401 &config->depth); 402 if (ret) 403 return ret; 404 405 ret = logicvc_of_property_parse_u32(of_node, 406 LOGICVC_OF_PROPERTY_LAYER_ALPHA_MODE, 407 &config->alpha_mode); 408 if (ret) 409 return ret; 410 411 /* 412 * Memory offset is only relevant without layer address configuration. 413 */ 414 if (logicvc->caps->layer_address) 415 return 0; 416 417 ret = logicvc_of_property_parse_u32(of_node, 418 LOGICVC_OF_PROPERTY_LAYER_BASE_OFFSET, 419 &config->base_offset); 420 if (ret) 421 return ret; 422 423 ret = logicvc_of_property_parse_u32(of_node, 424 LOGICVC_OF_PROPERTY_LAYER_BUFFER_OFFSET, 425 &config->buffer_offset); 426 if (ret) 427 return ret; 428 429 return 0; 430 } 431 432 struct logicvc_layer *logicvc_layer_get_from_index(struct logicvc_drm *logicvc, 433 u32 index) 434 { 435 struct logicvc_layer *layer; 436 437 list_for_each_entry(layer, &logicvc->layers_list, list) 438 if (layer->index == index) 439 return layer; 440 441 return NULL; 442 } 443 444 struct logicvc_layer *logicvc_layer_get_from_type(struct logicvc_drm *logicvc, 445 enum drm_plane_type type) 446 { 447 struct logicvc_layer *layer; 448 449 list_for_each_entry(layer, &logicvc->layers_list, list) 450 if (layer->drm_plane.type == type) 451 return layer; 452 453 return NULL; 454 } 455 456 struct logicvc_layer *logicvc_layer_get_primary(struct logicvc_drm *logicvc) 457 { 458 return logicvc_layer_get_from_type(logicvc, DRM_PLANE_TYPE_PRIMARY); 459 } 460 461 static int logicvc_layer_init(struct logicvc_drm *logicvc, 462 struct device_node *of_node, u32 index) 463 { 464 struct drm_device *drm_dev = &logicvc->drm_dev; 465 struct device *dev = drm_dev->dev; 466 struct logicvc_layer *layer = NULL; 467 struct logicvc_layer_formats *formats; 468 unsigned int formats_count; 469 enum drm_plane_type type; 470 unsigned int zpos; 471 int ret; 472 473 layer = devm_kzalloc(dev, sizeof(*layer), GFP_KERNEL); 474 if (!layer) { 475 ret = -ENOMEM; 476 goto error; 477 } 478 479 layer->of_node = of_node; 480 layer->index = index; 481 482 ret = logicvc_layer_config_parse(logicvc, layer); 483 if (ret) { 484 drm_err(drm_dev, "Failed to parse config for layer #%d\n", 485 index); 486 goto error; 487 } 488 489 formats = logicvc_layer_formats_lookup(layer); 490 if (!formats) { 491 drm_err(drm_dev, "Failed to lookup formats for layer #%d\n", 492 index); 493 ret = -EINVAL; 494 goto error; 495 } 496 497 formats_count = logicvc_layer_formats_count(formats); 498 499 /* The final layer can be configured as a background layer. */ 500 if (logicvc->config.background_layer && 501 index == (logicvc->config.layers_count - 1)) { 502 /* 503 * A zero value for black is only valid for RGB, not for YUV, 504 * so this will need to take the format in account for YUV. 505 */ 506 u32 background = 0; 507 508 drm_dbg_kms(drm_dev, "Using layer #%d as background layer\n", 509 index); 510 511 regmap_write(logicvc->regmap, LOGICVC_BACKGROUND_COLOR_REG, 512 background); 513 514 devm_kfree(dev, layer); 515 516 return 0; 517 } 518 519 if (layer->config.primary) 520 type = DRM_PLANE_TYPE_PRIMARY; 521 else 522 type = DRM_PLANE_TYPE_OVERLAY; 523 524 ret = drm_universal_plane_init(drm_dev, &layer->drm_plane, 0, 525 &logicvc_plane_funcs, formats->formats, 526 formats_count, NULL, type, NULL); 527 if (ret) { 528 drm_err(drm_dev, "Failed to initialize layer plane\n"); 529 return ret; 530 } 531 532 drm_plane_helper_add(&layer->drm_plane, &logicvc_plane_helper_funcs); 533 534 zpos = logicvc->config.layers_count - index - 1; 535 drm_dbg_kms(drm_dev, "Giving layer #%d zpos %d\n", index, zpos); 536 537 if (layer->config.alpha_mode == LOGICVC_LAYER_ALPHA_LAYER) 538 drm_plane_create_alpha_property(&layer->drm_plane); 539 540 drm_plane_create_zpos_immutable_property(&layer->drm_plane, zpos); 541 542 drm_dbg_kms(drm_dev, "Registering layer #%d\n", index); 543 544 layer->formats = formats; 545 546 list_add_tail(&layer->list, &logicvc->layers_list); 547 548 return 0; 549 550 error: 551 if (layer) 552 devm_kfree(dev, layer); 553 554 return ret; 555 } 556 557 static void logicvc_layer_fini(struct logicvc_drm *logicvc, 558 struct logicvc_layer *layer) 559 { 560 struct device *dev = logicvc->drm_dev.dev; 561 562 list_del(&layer->list); 563 devm_kfree(dev, layer); 564 } 565 566 void logicvc_layers_attach_crtc(struct logicvc_drm *logicvc) 567 { 568 uint32_t possible_crtcs = drm_crtc_mask(&logicvc->crtc->drm_crtc); 569 struct logicvc_layer *layer; 570 571 list_for_each_entry(layer, &logicvc->layers_list, list) { 572 if (layer->drm_plane.type != DRM_PLANE_TYPE_OVERLAY) 573 continue; 574 575 layer->drm_plane.possible_crtcs = possible_crtcs; 576 } 577 } 578 579 int logicvc_layers_init(struct logicvc_drm *logicvc) 580 { 581 struct drm_device *drm_dev = &logicvc->drm_dev; 582 struct device *dev = drm_dev->dev; 583 struct device_node *of_node = dev->of_node; 584 struct device_node *layer_node = NULL; 585 struct device_node *layers_node; 586 struct logicvc_layer *layer; 587 struct logicvc_layer *next; 588 int ret = 0; 589 590 layers_node = of_get_child_by_name(of_node, "layers"); 591 if (!layers_node) { 592 drm_err(drm_dev, "No layers node found in the description\n"); 593 ret = -ENODEV; 594 goto error; 595 } 596 597 for_each_child_of_node(layers_node, layer_node) { 598 u32 index = 0; 599 600 if (!logicvc_of_node_is_layer(layer_node)) 601 continue; 602 603 ret = of_property_read_u32(layer_node, "reg", &index); 604 if (ret) 605 continue; 606 607 layer = logicvc_layer_get_from_index(logicvc, index); 608 if (layer) { 609 drm_err(drm_dev, "Duplicated entry for layer #%d\n", 610 index); 611 continue; 612 } 613 614 ret = logicvc_layer_init(logicvc, layer_node, index); 615 if (ret) { 616 of_node_put(layers_node); 617 goto error; 618 } 619 } 620 621 of_node_put(layers_node); 622 623 return 0; 624 625 error: 626 list_for_each_entry_safe(layer, next, &logicvc->layers_list, list) 627 logicvc_layer_fini(logicvc, layer); 628 629 return ret; 630 } 631