kmb_plane.c (18383B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright © 2018-2020 Intel Corporation 4 */ 5 6#include <drm/drm_atomic.h> 7#include <drm/drm_atomic_helper.h> 8#include <drm/drm_crtc.h> 9#include <drm/drm_crtc_helper.h> 10#include <drm/drm_fb_cma_helper.h> 11#include <drm/drm_fb_helper.h> 12#include <drm/drm_fourcc.h> 13#include <drm/drm_gem_cma_helper.h> 14#include <drm/drm_managed.h> 15#include <drm/drm_plane_helper.h> 16 17#include "kmb_drv.h" 18#include "kmb_plane.h" 19#include "kmb_regs.h" 20 21const u32 layer_irqs[] = { 22 LCD_INT_VL0, 23 LCD_INT_VL1, 24 LCD_INT_GL0, 25 LCD_INT_GL1 26}; 27 28/* Conversion (yuv->rgb) matrix from myriadx */ 29static const u32 csc_coef_lcd[] = { 30 1024, 0, 1436, 31 1024, -352, -731, 32 1024, 1814, 0, 33 -179, 125, -226 34}; 35 36/* Graphics layer (layers 2 & 3) formats, only packed formats are supported */ 37static const u32 kmb_formats_g[] = { 38 DRM_FORMAT_RGB332, 39 DRM_FORMAT_XRGB4444, DRM_FORMAT_XBGR4444, 40 DRM_FORMAT_ARGB4444, DRM_FORMAT_ABGR4444, 41 DRM_FORMAT_XRGB1555, DRM_FORMAT_XBGR1555, 42 DRM_FORMAT_ARGB1555, DRM_FORMAT_ABGR1555, 43 DRM_FORMAT_RGB565, DRM_FORMAT_BGR565, 44 DRM_FORMAT_RGB888, DRM_FORMAT_BGR888, 45 DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888, 46 DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888, 47}; 48 49/* Video layer ( 0 & 1) formats, packed and planar formats are supported */ 50static const u32 kmb_formats_v[] = { 51 /* packed formats */ 52 DRM_FORMAT_RGB332, 53 DRM_FORMAT_XRGB4444, DRM_FORMAT_XBGR4444, 54 DRM_FORMAT_ARGB4444, DRM_FORMAT_ABGR4444, 55 DRM_FORMAT_XRGB1555, DRM_FORMAT_XBGR1555, 56 DRM_FORMAT_ARGB1555, DRM_FORMAT_ABGR1555, 57 DRM_FORMAT_RGB565, DRM_FORMAT_BGR565, 58 DRM_FORMAT_RGB888, DRM_FORMAT_BGR888, 59 DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888, 60 DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888, 61 /*planar formats */ 62 DRM_FORMAT_YUV420, DRM_FORMAT_YVU420, 63 DRM_FORMAT_YUV422, DRM_FORMAT_YVU422, 64 DRM_FORMAT_YUV444, DRM_FORMAT_YVU444, 65 DRM_FORMAT_NV12, DRM_FORMAT_NV21, 66}; 67 68static unsigned int check_pixel_format(struct drm_plane *plane, u32 format) 69{ 70 struct kmb_drm_private *kmb; 71 struct kmb_plane *kmb_plane = to_kmb_plane(plane); 72 int i; 73 int plane_id = kmb_plane->id; 74 struct disp_cfg init_disp_cfg; 75 76 kmb = to_kmb(plane->dev); 77 init_disp_cfg = kmb->init_disp_cfg[plane_id]; 78 /* Due to HW limitations, changing pixel format after initial 79 * plane configuration is not supported. 80 */ 81 if (init_disp_cfg.format && init_disp_cfg.format != format) { 82 drm_dbg(&kmb->drm, "Cannot change format after initial plane configuration"); 83 return -EINVAL; 84 } 85 for (i = 0; i < plane->format_count; i++) { 86 if (plane->format_types[i] == format) 87 return 0; 88 } 89 return -EINVAL; 90} 91 92static int kmb_plane_atomic_check(struct drm_plane *plane, 93 struct drm_atomic_state *state) 94{ 95 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, 96 plane); 97 struct kmb_drm_private *kmb; 98 struct kmb_plane *kmb_plane = to_kmb_plane(plane); 99 int plane_id = kmb_plane->id; 100 struct disp_cfg init_disp_cfg; 101 struct drm_framebuffer *fb; 102 int ret; 103 struct drm_crtc_state *crtc_state; 104 bool can_position; 105 106 kmb = to_kmb(plane->dev); 107 init_disp_cfg = kmb->init_disp_cfg[plane_id]; 108 fb = new_plane_state->fb; 109 if (!fb || !new_plane_state->crtc) 110 return 0; 111 112 ret = check_pixel_format(plane, fb->format->format); 113 if (ret) 114 return ret; 115 116 if (new_plane_state->crtc_w > KMB_FB_MAX_WIDTH || 117 new_plane_state->crtc_h > KMB_FB_MAX_HEIGHT || 118 new_plane_state->crtc_w < KMB_FB_MIN_WIDTH || 119 new_plane_state->crtc_h < KMB_FB_MIN_HEIGHT) 120 return -EINVAL; 121 122 /* Due to HW limitations, changing plane height or width after 123 * initial plane configuration is not supported. 124 */ 125 if ((init_disp_cfg.width && init_disp_cfg.height) && 126 (init_disp_cfg.width != fb->width || 127 init_disp_cfg.height != fb->height)) { 128 drm_dbg(&kmb->drm, "Cannot change plane height or width after initial configuration"); 129 return -EINVAL; 130 } 131 can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY); 132 crtc_state = 133 drm_atomic_get_existing_crtc_state(state, 134 new_plane_state->crtc); 135 return drm_atomic_helper_check_plane_state(new_plane_state, 136 crtc_state, 137 DRM_PLANE_HELPER_NO_SCALING, 138 DRM_PLANE_HELPER_NO_SCALING, 139 can_position, true); 140} 141 142static void kmb_plane_atomic_disable(struct drm_plane *plane, 143 struct drm_atomic_state *state) 144{ 145 struct kmb_plane *kmb_plane = to_kmb_plane(plane); 146 int plane_id = kmb_plane->id; 147 struct kmb_drm_private *kmb; 148 149 kmb = to_kmb(plane->dev); 150 151 if (WARN_ON(plane_id >= KMB_MAX_PLANES)) 152 return; 153 154 switch (plane_id) { 155 case LAYER_0: 156 kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL1_ENABLE; 157 break; 158 case LAYER_1: 159 kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL2_ENABLE; 160 break; 161 } 162 163 kmb->plane_status[plane_id].disable = true; 164} 165 166static unsigned int get_pixel_format(u32 format) 167{ 168 unsigned int val = 0; 169 170 switch (format) { 171 /* planar formats */ 172 case DRM_FORMAT_YUV444: 173 val = LCD_LAYER_FORMAT_YCBCR444PLAN | LCD_LAYER_PLANAR_STORAGE; 174 break; 175 case DRM_FORMAT_YVU444: 176 val = LCD_LAYER_FORMAT_YCBCR444PLAN | LCD_LAYER_PLANAR_STORAGE 177 | LCD_LAYER_CRCB_ORDER; 178 break; 179 case DRM_FORMAT_YUV422: 180 val = LCD_LAYER_FORMAT_YCBCR422PLAN | LCD_LAYER_PLANAR_STORAGE; 181 break; 182 case DRM_FORMAT_YVU422: 183 val = LCD_LAYER_FORMAT_YCBCR422PLAN | LCD_LAYER_PLANAR_STORAGE 184 | LCD_LAYER_CRCB_ORDER; 185 break; 186 case DRM_FORMAT_YUV420: 187 val = LCD_LAYER_FORMAT_YCBCR420PLAN | LCD_LAYER_PLANAR_STORAGE; 188 break; 189 case DRM_FORMAT_YVU420: 190 val = LCD_LAYER_FORMAT_YCBCR420PLAN | LCD_LAYER_PLANAR_STORAGE 191 | LCD_LAYER_CRCB_ORDER; 192 break; 193 case DRM_FORMAT_NV12: 194 val = LCD_LAYER_FORMAT_NV12 | LCD_LAYER_PLANAR_STORAGE; 195 break; 196 case DRM_FORMAT_NV21: 197 val = LCD_LAYER_FORMAT_NV12 | LCD_LAYER_PLANAR_STORAGE 198 | LCD_LAYER_CRCB_ORDER; 199 break; 200 /* packed formats */ 201 /* looks hw requires B & G to be swapped when RGB */ 202 case DRM_FORMAT_RGB332: 203 val = LCD_LAYER_FORMAT_RGB332 | LCD_LAYER_BGR_ORDER; 204 break; 205 case DRM_FORMAT_XBGR4444: 206 val = LCD_LAYER_FORMAT_RGBX4444; 207 break; 208 case DRM_FORMAT_ARGB4444: 209 val = LCD_LAYER_FORMAT_RGBA4444 | LCD_LAYER_BGR_ORDER; 210 break; 211 case DRM_FORMAT_ABGR4444: 212 val = LCD_LAYER_FORMAT_RGBA4444; 213 break; 214 case DRM_FORMAT_XRGB1555: 215 val = LCD_LAYER_FORMAT_XRGB1555 | LCD_LAYER_BGR_ORDER; 216 break; 217 case DRM_FORMAT_XBGR1555: 218 val = LCD_LAYER_FORMAT_XRGB1555; 219 break; 220 case DRM_FORMAT_ARGB1555: 221 val = LCD_LAYER_FORMAT_RGBA1555 | LCD_LAYER_BGR_ORDER; 222 break; 223 case DRM_FORMAT_ABGR1555: 224 val = LCD_LAYER_FORMAT_RGBA1555; 225 break; 226 case DRM_FORMAT_RGB565: 227 val = LCD_LAYER_FORMAT_RGB565 | LCD_LAYER_BGR_ORDER; 228 break; 229 case DRM_FORMAT_BGR565: 230 val = LCD_LAYER_FORMAT_RGB565; 231 break; 232 case DRM_FORMAT_RGB888: 233 val = LCD_LAYER_FORMAT_RGB888 | LCD_LAYER_BGR_ORDER; 234 break; 235 case DRM_FORMAT_BGR888: 236 val = LCD_LAYER_FORMAT_RGB888; 237 break; 238 case DRM_FORMAT_XRGB8888: 239 val = LCD_LAYER_FORMAT_RGBX8888 | LCD_LAYER_BGR_ORDER; 240 break; 241 case DRM_FORMAT_XBGR8888: 242 val = LCD_LAYER_FORMAT_RGBX8888; 243 break; 244 case DRM_FORMAT_ARGB8888: 245 val = LCD_LAYER_FORMAT_RGBA8888 | LCD_LAYER_BGR_ORDER; 246 break; 247 case DRM_FORMAT_ABGR8888: 248 val = LCD_LAYER_FORMAT_RGBA8888; 249 break; 250 } 251 DRM_INFO_ONCE("%s : %d format=0x%x val=0x%x\n", 252 __func__, __LINE__, format, val); 253 return val; 254} 255 256static unsigned int get_bits_per_pixel(const struct drm_format_info *format) 257{ 258 u32 bpp = 0; 259 unsigned int val = 0; 260 261 if (format->num_planes > 1) { 262 val = LCD_LAYER_8BPP; 263 return val; 264 } 265 266 bpp += 8 * format->cpp[0]; 267 268 switch (bpp) { 269 case 8: 270 val = LCD_LAYER_8BPP; 271 break; 272 case 16: 273 val = LCD_LAYER_16BPP; 274 break; 275 case 24: 276 val = LCD_LAYER_24BPP; 277 break; 278 case 32: 279 val = LCD_LAYER_32BPP; 280 break; 281 } 282 283 DRM_DEBUG("bpp=%d val=0x%x\n", bpp, val); 284 return val; 285} 286 287static void config_csc(struct kmb_drm_private *kmb, int plane_id) 288{ 289 /* YUV to RGB conversion using the fixed matrix csc_coef_lcd */ 290 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF11(plane_id), csc_coef_lcd[0]); 291 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF12(plane_id), csc_coef_lcd[1]); 292 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF13(plane_id), csc_coef_lcd[2]); 293 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF21(plane_id), csc_coef_lcd[3]); 294 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF22(plane_id), csc_coef_lcd[4]); 295 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF23(plane_id), csc_coef_lcd[5]); 296 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF31(plane_id), csc_coef_lcd[6]); 297 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF32(plane_id), csc_coef_lcd[7]); 298 kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF33(plane_id), csc_coef_lcd[8]); 299 kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF1(plane_id), csc_coef_lcd[9]); 300 kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF2(plane_id), csc_coef_lcd[10]); 301 kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF3(plane_id), csc_coef_lcd[11]); 302} 303 304static void kmb_plane_set_alpha(struct kmb_drm_private *kmb, 305 const struct drm_plane_state *state, 306 unsigned char plane_id, 307 unsigned int *val) 308{ 309 u16 plane_alpha = state->alpha; 310 u16 pixel_blend_mode = state->pixel_blend_mode; 311 int has_alpha = state->fb->format->has_alpha; 312 313 if (plane_alpha != DRM_BLEND_ALPHA_OPAQUE) 314 *val |= LCD_LAYER_ALPHA_STATIC; 315 316 if (has_alpha) { 317 switch (pixel_blend_mode) { 318 case DRM_MODE_BLEND_PIXEL_NONE: 319 break; 320 case DRM_MODE_BLEND_PREMULTI: 321 *val |= LCD_LAYER_ALPHA_EMBED | LCD_LAYER_ALPHA_PREMULT; 322 break; 323 case DRM_MODE_BLEND_COVERAGE: 324 *val |= LCD_LAYER_ALPHA_EMBED; 325 break; 326 default: 327 DRM_DEBUG("Missing pixel blend mode case (%s == %ld)\n", 328 __stringify(pixel_blend_mode), 329 (long)pixel_blend_mode); 330 break; 331 } 332 } 333 334 if (plane_alpha == DRM_BLEND_ALPHA_OPAQUE && !has_alpha) { 335 *val &= LCD_LAYER_ALPHA_DISABLED; 336 return; 337 } 338 339 kmb_write_lcd(kmb, LCD_LAYERn_ALPHA(plane_id), plane_alpha); 340} 341 342static void kmb_plane_atomic_update(struct drm_plane *plane, 343 struct drm_atomic_state *state) 344{ 345 struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, 346 plane); 347 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, 348 plane); 349 struct drm_framebuffer *fb; 350 struct kmb_drm_private *kmb; 351 unsigned int width; 352 unsigned int height; 353 unsigned int dma_len; 354 struct kmb_plane *kmb_plane; 355 unsigned int dma_cfg; 356 unsigned int ctrl = 0, val = 0, out_format = 0; 357 unsigned int src_w, src_h, crtc_x, crtc_y; 358 unsigned char plane_id; 359 int num_planes; 360 static dma_addr_t addr[MAX_SUB_PLANES]; 361 struct disp_cfg *init_disp_cfg; 362 363 if (!plane || !new_plane_state || !old_plane_state) 364 return; 365 366 fb = new_plane_state->fb; 367 if (!fb) 368 return; 369 370 num_planes = fb->format->num_planes; 371 kmb_plane = to_kmb_plane(plane); 372 373 kmb = to_kmb(plane->dev); 374 plane_id = kmb_plane->id; 375 376 spin_lock_irq(&kmb->irq_lock); 377 if (kmb->kmb_under_flow || kmb->kmb_flush_done) { 378 spin_unlock_irq(&kmb->irq_lock); 379 drm_dbg(&kmb->drm, "plane_update:underflow!!!! returning"); 380 return; 381 } 382 spin_unlock_irq(&kmb->irq_lock); 383 384 init_disp_cfg = &kmb->init_disp_cfg[plane_id]; 385 src_w = new_plane_state->src_w >> 16; 386 src_h = new_plane_state->src_h >> 16; 387 crtc_x = new_plane_state->crtc_x; 388 crtc_y = new_plane_state->crtc_y; 389 390 drm_dbg(&kmb->drm, 391 "src_w=%d src_h=%d, fb->format->format=0x%x fb->flags=0x%x\n", 392 src_w, src_h, fb->format->format, fb->flags); 393 394 width = fb->width; 395 height = fb->height; 396 dma_len = (width * height * fb->format->cpp[0]); 397 drm_dbg(&kmb->drm, "dma_len=%d ", dma_len); 398 kmb_write_lcd(kmb, LCD_LAYERn_DMA_LEN(plane_id), dma_len); 399 kmb_write_lcd(kmb, LCD_LAYERn_DMA_LEN_SHADOW(plane_id), dma_len); 400 kmb_write_lcd(kmb, LCD_LAYERn_DMA_LINE_VSTRIDE(plane_id), 401 fb->pitches[0]); 402 kmb_write_lcd(kmb, LCD_LAYERn_DMA_LINE_WIDTH(plane_id), 403 (width * fb->format->cpp[0])); 404 405 addr[Y_PLANE] = drm_fb_cma_get_gem_addr(fb, new_plane_state, 0); 406 kmb_write_lcd(kmb, LCD_LAYERn_DMA_START_ADDR(plane_id), 407 addr[Y_PLANE] + fb->offsets[0]); 408 val = get_pixel_format(fb->format->format); 409 val |= get_bits_per_pixel(fb->format); 410 /* Program Cb/Cr for planar formats */ 411 if (num_planes > 1) { 412 kmb_write_lcd(kmb, LCD_LAYERn_DMA_CB_LINE_VSTRIDE(plane_id), 413 width * fb->format->cpp[0]); 414 kmb_write_lcd(kmb, LCD_LAYERn_DMA_CB_LINE_WIDTH(plane_id), 415 (width * fb->format->cpp[0])); 416 417 addr[U_PLANE] = drm_fb_cma_get_gem_addr(fb, new_plane_state, 418 U_PLANE); 419 /* check if Cb/Cr is swapped*/ 420 if (num_planes == 3 && (val & LCD_LAYER_CRCB_ORDER)) 421 kmb_write_lcd(kmb, 422 LCD_LAYERn_DMA_START_CR_ADR(plane_id), 423 addr[U_PLANE]); 424 else 425 kmb_write_lcd(kmb, 426 LCD_LAYERn_DMA_START_CB_ADR(plane_id), 427 addr[U_PLANE]); 428 429 if (num_planes == 3) { 430 kmb_write_lcd(kmb, 431 LCD_LAYERn_DMA_CR_LINE_VSTRIDE(plane_id), 432 ((width) * fb->format->cpp[0])); 433 434 kmb_write_lcd(kmb, 435 LCD_LAYERn_DMA_CR_LINE_WIDTH(plane_id), 436 ((width) * fb->format->cpp[0])); 437 438 addr[V_PLANE] = drm_fb_cma_get_gem_addr(fb, 439 new_plane_state, 440 V_PLANE); 441 442 /* check if Cb/Cr is swapped*/ 443 if (val & LCD_LAYER_CRCB_ORDER) 444 kmb_write_lcd(kmb, 445 LCD_LAYERn_DMA_START_CB_ADR(plane_id), 446 addr[V_PLANE]); 447 else 448 kmb_write_lcd(kmb, 449 LCD_LAYERn_DMA_START_CR_ADR(plane_id), 450 addr[V_PLANE]); 451 } 452 } 453 454 kmb_write_lcd(kmb, LCD_LAYERn_WIDTH(plane_id), src_w - 1); 455 kmb_write_lcd(kmb, LCD_LAYERn_HEIGHT(plane_id), src_h - 1); 456 kmb_write_lcd(kmb, LCD_LAYERn_COL_START(plane_id), crtc_x); 457 kmb_write_lcd(kmb, LCD_LAYERn_ROW_START(plane_id), crtc_y); 458 459 val |= LCD_LAYER_FIFO_100; 460 461 if (val & LCD_LAYER_PLANAR_STORAGE) { 462 val |= LCD_LAYER_CSC_EN; 463 464 /* Enable CSC if input is planar and output is RGB */ 465 config_csc(kmb, plane_id); 466 } 467 468 kmb_plane_set_alpha(kmb, plane->state, plane_id, &val); 469 470 kmb_write_lcd(kmb, LCD_LAYERn_CFG(plane_id), val); 471 472 /* Configure LCD_CONTROL */ 473 ctrl = kmb_read_lcd(kmb, LCD_CONTROL); 474 475 /* Set layer blending config */ 476 ctrl &= ~LCD_CTRL_ALPHA_ALL; 477 ctrl |= LCD_CTRL_ALPHA_BOTTOM_VL1 | 478 LCD_CTRL_ALPHA_BLEND_VL2; 479 480 ctrl &= ~LCD_CTRL_ALPHA_BLEND_BKGND_DISABLE; 481 482 switch (plane_id) { 483 case LAYER_0: 484 ctrl |= LCD_CTRL_VL1_ENABLE; 485 break; 486 case LAYER_1: 487 ctrl |= LCD_CTRL_VL2_ENABLE; 488 break; 489 case LAYER_2: 490 ctrl |= LCD_CTRL_GL1_ENABLE; 491 break; 492 case LAYER_3: 493 ctrl |= LCD_CTRL_GL2_ENABLE; 494 break; 495 } 496 497 ctrl |= LCD_CTRL_PROGRESSIVE | LCD_CTRL_TIM_GEN_ENABLE 498 | LCD_CTRL_CONTINUOUS | LCD_CTRL_OUTPUT_ENABLED; 499 500 /* LCD is connected to MIPI on kmb 501 * Therefore this bit is required for DSI Tx 502 */ 503 ctrl |= LCD_CTRL_VHSYNC_IDLE_LVL; 504 505 kmb_write_lcd(kmb, LCD_CONTROL, ctrl); 506 507 /* Enable pipeline AXI read transactions for the DMA 508 * after setting graphics layers. This must be done 509 * in a separate write cycle. 510 */ 511 kmb_set_bitmask_lcd(kmb, LCD_CONTROL, LCD_CTRL_PIPELINE_DMA); 512 513 /* FIXME no doc on how to set output format, these values are taken 514 * from the Myriadx tests 515 */ 516 out_format |= LCD_OUTF_FORMAT_RGB888; 517 518 /* Leave RGB order,conversion mode and clip mode to default */ 519 /* do not interleave RGB channels for mipi Tx compatibility */ 520 out_format |= LCD_OUTF_MIPI_RGB_MODE; 521 kmb_write_lcd(kmb, LCD_OUT_FORMAT_CFG, out_format); 522 523 dma_cfg = LCD_DMA_LAYER_ENABLE | LCD_DMA_LAYER_VSTRIDE_EN | 524 LCD_DMA_LAYER_CONT_UPDATE | LCD_DMA_LAYER_AXI_BURST_16; 525 526 /* Enable DMA */ 527 kmb_write_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id), dma_cfg); 528 529 /* Save initial display config */ 530 if (!init_disp_cfg->width || 531 !init_disp_cfg->height || 532 !init_disp_cfg->format) { 533 init_disp_cfg->width = width; 534 init_disp_cfg->height = height; 535 init_disp_cfg->format = fb->format->format; 536 } 537 538 drm_dbg(&kmb->drm, "dma_cfg=0x%x LCD_DMA_CFG=0x%x\n", dma_cfg, 539 kmb_read_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id))); 540 541 kmb_set_bitmask_lcd(kmb, LCD_INT_CLEAR, LCD_INT_EOF | 542 LCD_INT_DMA_ERR); 543 kmb_set_bitmask_lcd(kmb, LCD_INT_ENABLE, LCD_INT_EOF | 544 LCD_INT_DMA_ERR); 545} 546 547static const struct drm_plane_helper_funcs kmb_plane_helper_funcs = { 548 .atomic_check = kmb_plane_atomic_check, 549 .atomic_update = kmb_plane_atomic_update, 550 .atomic_disable = kmb_plane_atomic_disable 551}; 552 553void kmb_plane_destroy(struct drm_plane *plane) 554{ 555 struct kmb_plane *kmb_plane = to_kmb_plane(plane); 556 557 drm_plane_cleanup(plane); 558 kfree(kmb_plane); 559} 560 561static const struct drm_plane_funcs kmb_plane_funcs = { 562 .update_plane = drm_atomic_helper_update_plane, 563 .disable_plane = drm_atomic_helper_disable_plane, 564 .destroy = kmb_plane_destroy, 565 .reset = drm_atomic_helper_plane_reset, 566 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 567 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 568}; 569 570struct kmb_plane *kmb_plane_init(struct drm_device *drm) 571{ 572 struct kmb_drm_private *kmb = to_kmb(drm); 573 struct kmb_plane *plane = NULL; 574 struct kmb_plane *primary = NULL; 575 int i = 0; 576 int ret = 0; 577 enum drm_plane_type plane_type; 578 const u32 *plane_formats; 579 int num_plane_formats; 580 unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | 581 BIT(DRM_MODE_BLEND_PREMULTI) | 582 BIT(DRM_MODE_BLEND_COVERAGE); 583 584 for (i = 0; i < KMB_MAX_PLANES; i++) { 585 plane = drmm_kzalloc(drm, sizeof(*plane), GFP_KERNEL); 586 587 if (!plane) { 588 drm_err(drm, "Failed to allocate plane\n"); 589 return ERR_PTR(-ENOMEM); 590 } 591 592 plane_type = (i == 0) ? DRM_PLANE_TYPE_PRIMARY : 593 DRM_PLANE_TYPE_OVERLAY; 594 if (i < 2) { 595 plane_formats = kmb_formats_v; 596 num_plane_formats = ARRAY_SIZE(kmb_formats_v); 597 } else { 598 plane_formats = kmb_formats_g; 599 num_plane_formats = ARRAY_SIZE(kmb_formats_g); 600 } 601 602 ret = drm_universal_plane_init(drm, &plane->base_plane, 603 POSSIBLE_CRTCS, &kmb_plane_funcs, 604 plane_formats, num_plane_formats, 605 NULL, plane_type, "plane %d", i); 606 if (ret < 0) { 607 drm_err(drm, "drm_universal_plane_init failed (ret=%d)", 608 ret); 609 goto cleanup; 610 } 611 drm_dbg(drm, "%s : %d i=%d type=%d", 612 __func__, __LINE__, 613 i, plane_type); 614 drm_plane_create_alpha_property(&plane->base_plane); 615 616 drm_plane_create_blend_mode_property(&plane->base_plane, 617 blend_caps); 618 619 drm_plane_create_zpos_immutable_property(&plane->base_plane, i); 620 621 drm_plane_helper_add(&plane->base_plane, 622 &kmb_plane_helper_funcs); 623 624 if (plane_type == DRM_PLANE_TYPE_PRIMARY) { 625 primary = plane; 626 kmb->plane = plane; 627 } 628 drm_dbg(drm, "%s : %d primary=%p\n", __func__, __LINE__, 629 &primary->base_plane); 630 plane->id = i; 631 } 632 633 /* Disable pipeline AXI read transactions for the DMA 634 * prior to setting graphics layers 635 */ 636 kmb_clr_bitmask_lcd(kmb, LCD_CONTROL, LCD_CTRL_PIPELINE_DMA); 637 638 return primary; 639cleanup: 640 drmm_kfree(drm, plane); 641 return ERR_PTR(ret); 642}