Skip to content

Commit 982f8ad

Browse files
ejdea-intelmlankhorst
authored andcommitted
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: 7f7b96a ("drm/kmb: Add support for KeemBay Display") Signed-off-by: Edmund Dea <[email protected]> Signed-off-by: Anitha Chrisanthus <[email protected]> Acked-by: Sam Ravnborg <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Signed-off-by: Maarten Lankhorst <[email protected]>
1 parent 13047a0 commit 982f8ad

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

drivers/gpu/drm/kmb/kmb_drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ struct kmb_drm_private {
5757
spinlock_t irq_lock;
5858
int irq_lcd;
5959
int sys_clk_mhz;
60+
struct disp_cfg init_disp_cfg[KMB_MAX_PLANES];
6061
struct layer_status plane_status[KMB_MAX_PLANES];
6162
int kmb_under_flow;
6263
int kmb_flush_done;

drivers/gpu/drm/kmb/kmb_plane.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,21 @@ static const u32 kmb_formats_v[] = {
6767

6868
static unsigned int check_pixel_format(struct drm_plane *plane, u32 format)
6969
{
70+
struct kmb_drm_private *kmb;
71+
struct kmb_plane *kmb_plane = to_kmb_plane(plane);
7072
int i;
73+
int plane_id = kmb_plane->id;
74+
struct disp_cfg init_disp_cfg;
7175

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+
}
7285
for (i = 0; i < plane->format_count; i++) {
7386
if (plane->format_types[i] == format)
7487
return 0;
@@ -81,11 +94,17 @@ static int kmb_plane_atomic_check(struct drm_plane *plane,
8194
{
8295
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
8396
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;
84101
struct drm_framebuffer *fb;
85102
int ret;
86103
struct drm_crtc_state *crtc_state;
87104
bool can_position;
88105

106+
kmb = to_kmb(plane->dev);
107+
init_disp_cfg = kmb->init_disp_cfg[plane_id];
89108
fb = new_plane_state->fb;
90109
if (!fb || !new_plane_state->crtc)
91110
return 0;
@@ -99,6 +118,16 @@ static int kmb_plane_atomic_check(struct drm_plane *plane,
99118
new_plane_state->crtc_w < KMB_FB_MIN_WIDTH ||
100119
new_plane_state->crtc_h < KMB_FB_MIN_HEIGHT)
101120
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+
}
102131
can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
103132
crtc_state =
104133
drm_atomic_get_existing_crtc_state(state,
@@ -335,6 +364,7 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
335364
unsigned char plane_id;
336365
int num_planes;
337366
static dma_addr_t addr[MAX_SUB_PLANES];
367+
struct disp_cfg *init_disp_cfg;
338368

339369
if (!plane || !new_plane_state || !old_plane_state)
340370
return;
@@ -357,7 +387,8 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
357387
}
358388
spin_unlock_irq(&kmb->irq_lock);
359389

360-
src_w = (new_plane_state->src_w >> 16);
390+
init_disp_cfg = &kmb->init_disp_cfg[plane_id];
391+
src_w = new_plane_state->src_w >> 16;
361392
src_h = new_plane_state->src_h >> 16;
362393
crtc_x = new_plane_state->crtc_x;
363394
crtc_y = new_plane_state->crtc_y;
@@ -500,6 +531,16 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
500531

501532
/* Enable DMA */
502533
kmb_write_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id), dma_cfg);
534+
535+
/* Save initial display config */
536+
if (!init_disp_cfg->width ||
537+
!init_disp_cfg->height ||
538+
!init_disp_cfg->format) {
539+
init_disp_cfg->width = width;
540+
init_disp_cfg->height = height;
541+
init_disp_cfg->format = fb->format->format;
542+
}
543+
503544
drm_dbg(&kmb->drm, "dma_cfg=0x%x LCD_DMA_CFG=0x%x\n", dma_cfg,
504545
kmb_read_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id)));
505546

drivers/gpu/drm/kmb/kmb_plane.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ struct layer_status {
6363
u32 ctrl;
6464
};
6565

66+
struct disp_cfg {
67+
unsigned int width;
68+
unsigned int height;
69+
unsigned int format;
70+
};
71+
6672
struct kmb_plane *kmb_plane_init(struct drm_device *drm);
6773
void kmb_plane_destroy(struct drm_plane *plane);
6874
#endif /* __KMB_PLANE_H__ */

0 commit comments

Comments
 (0)