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

drm/kmb: Disable change of plane parameters

Due to HW limitations, KMB cannot change height, width, or
pixel format after initial plane configuration.

v2: removed memset disp_cfg as it is already zero.

Fixes: 7f7b96a8a0a1 ("drm/kmb: Add support for KeemBay Display")
Signed-off-by: Edmund Dea <edmund.j.dea@intel.com>
Signed-off-by: Anitha Chrisanthus <anitha.chrisanthus@intel.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20211013233632.471892-4-anitha.chrisanthus@intel.com
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

authored by

Edmund Dea and committed by
Maarten Lankhorst
982f8ad6 13047a09

+49 -1
+1
drivers/gpu/drm/kmb/kmb_drv.h
··· 57 57 spinlock_t irq_lock; 58 58 int irq_lcd; 59 59 int sys_clk_mhz; 60 + struct disp_cfg init_disp_cfg[KMB_MAX_PLANES]; 60 61 struct layer_status plane_status[KMB_MAX_PLANES]; 61 62 int kmb_under_flow; 62 63 int kmb_flush_done;
+42 -1
drivers/gpu/drm/kmb/kmb_plane.c
··· 67 67 68 68 static unsigned int check_pixel_format(struct drm_plane *plane, u32 format) 69 69 { 70 + struct kmb_drm_private *kmb; 71 + struct kmb_plane *kmb_plane = to_kmb_plane(plane); 70 72 int i; 73 + int plane_id = kmb_plane->id; 74 + struct disp_cfg init_disp_cfg; 71 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 + } 72 85 for (i = 0; i < plane->format_count; i++) { 73 86 if (plane->format_types[i] == format) 74 87 return 0; ··· 94 81 { 95 82 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, 96 83 plane); 84 + struct kmb_drm_private *kmb; 85 + struct kmb_plane *kmb_plane = to_kmb_plane(plane); 86 + int plane_id = kmb_plane->id; 87 + struct disp_cfg init_disp_cfg; 97 88 struct drm_framebuffer *fb; 98 89 int ret; 99 90 struct drm_crtc_state *crtc_state; 100 91 bool can_position; 101 92 93 + kmb = to_kmb(plane->dev); 94 + init_disp_cfg = kmb->init_disp_cfg[plane_id]; 102 95 fb = new_plane_state->fb; 103 96 if (!fb || !new_plane_state->crtc) 104 97 return 0; ··· 118 99 new_plane_state->crtc_w < KMB_FB_MIN_WIDTH || 119 100 new_plane_state->crtc_h < KMB_FB_MIN_HEIGHT) 120 101 return -EINVAL; 102 + 103 + /* Due to HW limitations, changing plane height or width after 104 + * initial plane configuration is not supported. 105 + */ 106 + if ((init_disp_cfg.width && init_disp_cfg.height) && 107 + (init_disp_cfg.width != fb->width || 108 + init_disp_cfg.height != fb->height)) { 109 + drm_dbg(&kmb->drm, "Cannot change plane height or width after initial configuration"); 110 + return -EINVAL; 111 + } 121 112 can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY); 122 113 crtc_state = 123 114 drm_atomic_get_existing_crtc_state(state, ··· 364 335 unsigned char plane_id; 365 336 int num_planes; 366 337 static dma_addr_t addr[MAX_SUB_PLANES]; 338 + struct disp_cfg *init_disp_cfg; 367 339 368 340 if (!plane || !new_plane_state || !old_plane_state) 369 341 return; ··· 387 357 } 388 358 spin_unlock_irq(&kmb->irq_lock); 389 359 390 - src_w = (new_plane_state->src_w >> 16); 360 + init_disp_cfg = &kmb->init_disp_cfg[plane_id]; 361 + src_w = new_plane_state->src_w >> 16; 391 362 src_h = new_plane_state->src_h >> 16; 392 363 crtc_x = new_plane_state->crtc_x; 393 364 crtc_y = new_plane_state->crtc_y; ··· 531 500 532 501 /* Enable DMA */ 533 502 kmb_write_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id), dma_cfg); 503 + 504 + /* Save initial display config */ 505 + if (!init_disp_cfg->width || 506 + !init_disp_cfg->height || 507 + !init_disp_cfg->format) { 508 + init_disp_cfg->width = width; 509 + init_disp_cfg->height = height; 510 + init_disp_cfg->format = fb->format->format; 511 + } 512 + 534 513 drm_dbg(&kmb->drm, "dma_cfg=0x%x LCD_DMA_CFG=0x%x\n", dma_cfg, 535 514 kmb_read_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id))); 536 515
+6
drivers/gpu/drm/kmb/kmb_plane.h
··· 63 63 u32 ctrl; 64 64 }; 65 65 66 + struct disp_cfg { 67 + unsigned int width; 68 + unsigned int height; 69 + unsigned int format; 70 + }; 71 + 66 72 struct kmb_plane *kmb_plane_init(struct drm_device *drm); 67 73 void kmb_plane_destroy(struct drm_plane *plane); 68 74 #endif /* __KMB_PLANE_H__ */