@@ -67,8 +67,21 @@ static const u32 kmb_formats_v[] = {
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 ;
@@ -81,11 +94,17 @@ static int kmb_plane_atomic_check(struct drm_plane *plane,
81
94
{
82
95
struct drm_plane_state * new_plane_state = drm_atomic_get_new_plane_state (state ,
83
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 ;
84
101
struct drm_framebuffer * fb ;
85
102
int ret ;
86
103
struct drm_crtc_state * crtc_state ;
87
104
bool can_position ;
88
105
106
+ kmb = to_kmb (plane -> dev );
107
+ init_disp_cfg = kmb -> init_disp_cfg [plane_id ];
89
108
fb = new_plane_state -> fb ;
90
109
if (!fb || !new_plane_state -> crtc )
91
110
return 0 ;
@@ -99,6 +118,16 @@ static int kmb_plane_atomic_check(struct drm_plane *plane,
99
118
new_plane_state -> crtc_w < KMB_FB_MIN_WIDTH ||
100
119
new_plane_state -> crtc_h < KMB_FB_MIN_HEIGHT )
101
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
+ }
102
131
can_position = (plane -> type == DRM_PLANE_TYPE_OVERLAY );
103
132
crtc_state =
104
133
drm_atomic_get_existing_crtc_state (state ,
@@ -335,6 +364,7 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
335
364
unsigned char plane_id ;
336
365
int num_planes ;
337
366
static dma_addr_t addr [MAX_SUB_PLANES ];
367
+ struct disp_cfg * init_disp_cfg ;
338
368
339
369
if (!plane || !new_plane_state || !old_plane_state )
340
370
return ;
@@ -357,7 +387,8 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
357
387
}
358
388
spin_unlock_irq (& kmb -> irq_lock );
359
389
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 ;
361
392
src_h = new_plane_state -> src_h >> 16 ;
362
393
crtc_x = new_plane_state -> crtc_x ;
363
394
crtc_y = new_plane_state -> crtc_y ;
@@ -500,6 +531,16 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
500
531
501
532
/* Enable DMA */
502
533
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
+
503
544
drm_dbg (& kmb -> drm , "dma_cfg=0x%x LCD_DMA_CFG=0x%x\n" , dma_cfg ,
504
545
kmb_read_lcd (kmb , LCD_LAYERn_DMA_CFG (plane_id )));
505
546
0 commit comments