[Intel-gfx] [PATCH v2 59/59] drm/kmb: work around for planar formats
Anitha Chrisanthus
anitha.chrisanthus at intel.com
Tue Jul 14 20:57:45 UTC 2020
Set the DMA Vstride and Line width for U and V planes to the same as the
Y plane and not the actual pitch.
Bit18 of layer config does not have any effect when U and V planes are
swapped, so swap it in the driver.
Signed-off-by: Anitha Chrisanthus <anitha.chrisanthus at intel.com>
Reviewed-by: Edmund Dea <edmund.j.dea at intel.com>
---
drivers/gpu/drm/kmb/kmb_plane.c | 50 ++++++++++++++++++++++++-----------------
1 file changed, 30 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/kmb/kmb_plane.c b/drivers/gpu/drm/kmb/kmb_plane.c
index de225a8..e35d732 100644
--- a/drivers/gpu/drm/kmb/kmb_plane.c
+++ b/drivers/gpu/drm/kmb/kmb_plane.c
@@ -170,6 +170,8 @@ unsigned int set_pixel_format(u32 format)
val = LCD_LAYER_FORMAT_RGBA8888;
break;
}
+ DRM_INFO_ONCE("%s : %d format=0x%x val=0x%x\n",
+ __func__, __LINE__, format, val);
return val;
}
@@ -280,38 +282,48 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
dev_p->fb_addr = addr[Y_PLANE];
kmb_write_lcd(dev_p, LCD_LAYERn_DMA_START_ADDR(plane_id),
addr[Y_PLANE] + fb->offsets[0]);
+ val = set_pixel_format(fb->format->format);
+ val |= set_bits_per_pixel(fb->format);
/* Program Cb/Cr for planar formats */
if (num_planes > 1) {
- if (fb->format->format == DRM_FORMAT_YUV420 ||
- fb->format->format == DRM_FORMAT_YVU420)
- width /= 2;
-
kmb_write_lcd(dev_p, LCD_LAYERn_DMA_CB_LINE_VSTRIDE(plane_id),
- fb->pitches[LAYER_1]);
-
+ width*fb->format->cpp[0]);
kmb_write_lcd(dev_p, LCD_LAYERn_DMA_CB_LINE_WIDTH(plane_id),
(width * fb->format->cpp[0]));
addr[U_PLANE] = drm_fb_cma_get_gem_addr(fb, plane->state,
- U_PLANE);
- kmb_write_lcd(dev_p, LCD_LAYERn_DMA_START_CB_ADR(plane_id),
- addr[U_PLANE]);
+ U_PLANE);
+ /* check if Cb/Cr is swapped*/
+ if ((num_planes == 3) && (val & LCD_LAYER_CRCB_ORDER))
+ kmb_write_lcd(dev_p,
+ LCD_LAYERn_DMA_START_CR_ADR(plane_id),
+ addr[U_PLANE]);
+ else
+ kmb_write_lcd(dev_p,
+ LCD_LAYERn_DMA_START_CB_ADR(plane_id),
+ addr[U_PLANE]);
if (num_planes == 3) {
kmb_write_lcd(dev_p,
- LCD_LAYERn_DMA_CR_LINE_VSTRIDE(plane_id),
- fb->pitches[LAYER_2]);
+ LCD_LAYERn_DMA_CR_LINE_VSTRIDE(plane_id),
+ ((width)*fb->format->cpp[0]));
kmb_write_lcd(dev_p,
- LCD_LAYERn_DMA_CR_LINE_WIDTH(plane_id),
- (width * fb->format->cpp[0]));
+ LCD_LAYERn_DMA_CR_LINE_WIDTH(plane_id),
+ ((width)*fb->format->cpp[0]));
addr[V_PLANE] = drm_fb_cma_get_gem_addr(fb,
- plane->state,
- V_PLANE);
- kmb_write_lcd(dev_p,
- LCD_LAYERn_DMA_START_CR_ADR(plane_id),
- addr[V_PLANE]);
+ plane->state, V_PLANE);
+
+ /* check if Cb/Cr is swapped*/
+ if (val & LCD_LAYER_CRCB_ORDER)
+ kmb_write_lcd(dev_p,
+ LCD_LAYERn_DMA_START_CB_ADR(plane_id),
+ addr[V_PLANE]);
+ else
+ kmb_write_lcd(dev_p,
+ LCD_LAYERn_DMA_START_CR_ADR(plane_id),
+ addr[V_PLANE]);
}
}
@@ -320,8 +332,6 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
kmb_write_lcd(dev_p, LCD_LAYERn_COL_START(plane_id), crtc_x);
kmb_write_lcd(dev_p, LCD_LAYERn_ROW_START(plane_id), crtc_y);
- val = set_pixel_format(fb->format->format);
- val |= set_bits_per_pixel(fb->format);
/*CHECKME Leon drvr sets it to 100 try this for now */
val |= LCD_LAYER_FIFO_100;
--
2.7.4
More information about the Intel-gfx
mailing list