[03/59] drm/kmb: Set correct values in the LAYERn_CFG register
diff mbox series

Message ID 1593552491-23698-4-git-send-email-anitha.chrisanthus@intel.com
State New
Headers show
Series
  • Add support for Keem Bay DRM driver
Related show

Commit Message

Chrisanthus, Anitha June 30, 2020, 9:27 p.m. UTC
During update plane, set the layer format, bpp, fifo level,
RGB order, Cb/Cr order etc. in the LAYER_CFG register.

v2: Return val in set_pixel and set_bpp instead of passing in pointer,

Signed-off-by: Anitha Chrisanthus <anitha.chrisanthus@intel.com>
Reviewed-by: Bob Paauwe <bob.j.paauwe@intel.com>
---
 drivers/gpu/drm/kmb/kmb_plane.c | 145 ++++++++++++++++++++++++++++++----
 drivers/gpu/drm/kmb/kmb_regs.h  | 167 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 298 insertions(+), 14 deletions(-)

Patch
diff mbox series

diff --git a/drivers/gpu/drm/kmb/kmb_plane.c b/drivers/gpu/drm/kmb/kmb_plane.c
index b9d8d38..9f1e44f 100644
--- a/drivers/gpu/drm/kmb/kmb_plane.c
+++ b/drivers/gpu/drm/kmb/kmb_plane.c
@@ -53,6 +53,119 @@  static int kmb_plane_atomic_check(struct drm_plane *plane,
 	return 0;
 }
 
+unsigned int set_pixel_format(u32 format)
+{
+	unsigned int val = 0;
+
+	switch (format) {
+	/*planar formats */
+	case DRM_FORMAT_YUV444:
+		val = LCD_LAYER_FORMAT_YCBCR444PLAN | LCD_LAYER_PLANAR_STORAGE;
+		break;
+	case DRM_FORMAT_YVU444:
+		val = LCD_LAYER_FORMAT_YCBCR444PLAN | LCD_LAYER_PLANAR_STORAGE
+			| LCD_LAYER_CRCB_ORDER;
+		break;
+	case DRM_FORMAT_YUV422:
+		val = LCD_LAYER_FORMAT_YCBCR422PLAN | LCD_LAYER_PLANAR_STORAGE;
+		break;
+	case DRM_FORMAT_YVU422:
+		val = LCD_LAYER_FORMAT_YCBCR422PLAN | LCD_LAYER_PLANAR_STORAGE
+		       | LCD_LAYER_CRCB_ORDER;
+		break;
+	case DRM_FORMAT_YUV420:
+		val = LCD_LAYER_FORMAT_YCBCR420PLAN | LCD_LAYER_PLANAR_STORAGE;
+		break;
+	case DRM_FORMAT_YVU420:
+		val = LCD_LAYER_FORMAT_YCBCR420PLAN | LCD_LAYER_PLANAR_STORAGE
+		       | LCD_LAYER_CRCB_ORDER;
+		break;
+	case DRM_FORMAT_NV12:
+		val = LCD_LAYER_FORMAT_NV12 | LCD_LAYER_PLANAR_STORAGE;
+		break;
+	case DRM_FORMAT_NV21:
+		val = LCD_LAYER_FORMAT_NV12 | LCD_LAYER_PLANAR_STORAGE
+		       | LCD_LAYER_CRCB_ORDER;
+		break;
+	/* packed formats */
+	case DRM_FORMAT_RGB332:
+		val = LCD_LAYER_FORMAT_RGB332;
+		break;
+	case DRM_FORMAT_XBGR4444:
+		val = LCD_LAYER_FORMAT_RGBX4444 | LCD_LAYER_BGR_ORDER;
+		break;
+	case DRM_FORMAT_ARGB4444:
+		val = LCD_LAYER_FORMAT_RGBA4444;
+		break;
+	case DRM_FORMAT_ABGR4444:
+		val = LCD_LAYER_FORMAT_RGBA4444 | LCD_LAYER_BGR_ORDER;
+		break;
+	case DRM_FORMAT_XRGB1555:
+		val = LCD_LAYER_FORMAT_XRGB1555;
+		break;
+	case DRM_FORMAT_XBGR1555:
+		val = LCD_LAYER_FORMAT_XRGB1555 | LCD_LAYER_BGR_ORDER;
+		break;
+	case DRM_FORMAT_ARGB1555:
+		val = LCD_LAYER_FORMAT_RGBA1555;
+		break;
+	case DRM_FORMAT_ABGR1555:
+		val = LCD_LAYER_FORMAT_RGBA1555 | LCD_LAYER_BGR_ORDER;
+		break;
+	case DRM_FORMAT_RGB565:
+		val = LCD_LAYER_FORMAT_RGB565;
+		break;
+	case DRM_FORMAT_BGR565:
+		val = LCD_LAYER_FORMAT_RGB565 | LCD_LAYER_BGR_ORDER;
+		break;
+	case DRM_FORMAT_RGB888:
+		val = LCD_LAYER_FORMAT_RGB888;
+		break;
+	case DRM_FORMAT_BGR888:
+		val = LCD_LAYER_FORMAT_RGB888 | LCD_LAYER_BGR_ORDER;
+		break;
+	case DRM_FORMAT_XRGB8888:
+		val = LCD_LAYER_FORMAT_RGBX8888;
+		break;
+	case DRM_FORMAT_XBGR8888:
+		val = LCD_LAYER_FORMAT_RGBX8888 | LCD_LAYER_BGR_ORDER;
+		break;
+	case DRM_FORMAT_ARGB8888:
+		val = LCD_LAYER_FORMAT_RGBA8888;
+		break;
+	case DRM_FORMAT_ABGR8888:
+		val = LCD_LAYER_FORMAT_RGBA8888 | LCD_LAYER_BGR_ORDER;
+		break;
+	}
+	return val;
+}
+
+unsigned int set_bits_per_pixel(const struct drm_format_info *format)
+{
+	int i;
+	u32 bpp = 0;
+	unsigned int val = 0;
+
+	for (i = 0; i < format->num_planes; i++)
+		bpp += 8*format->cpp[i];
+
+	switch (bpp) {
+	case 8:
+		val = LCD_LAYER_8BPP;
+		break;
+	case 16:
+		val = LCD_LAYER_16BPP;
+		break;
+	case 24:
+		val = LCD_LAYER_24BPP;
+		break;
+	case 32:
+		val = LCD_LAYER_32BPP;
+		break;
+	}
+	return val;
+}
+
 static void kmb_plane_atomic_update(struct drm_plane *plane,
 				    struct drm_plane_state *state)
 {
@@ -64,7 +177,8 @@  static void kmb_plane_atomic_update(struct drm_plane *plane,
 	unsigned int dma_len;
 	struct kmb_plane *kmb_plane = to_kmb_plane(plane);
 	unsigned int dma_cfg;
-	unsigned int ctrl = 0;
+	unsigned int ctrl = 0, val = 0;
+	unsigned int src_w, src_h, crtc_x, crtc_y;
 	unsigned char plane_id = kmb_plane->id;
 
 	if (!fb)
@@ -72,6 +186,22 @@  static void kmb_plane_atomic_update(struct drm_plane *plane,
 
 	lcd = plane->dev->dev_private;
 
+	src_w = plane->state->src_w >> 16;
+	src_h = plane->state->src_h >> 16;
+	crtc_x = plane->state->crtc_x;
+	crtc_y = plane->state->crtc_y;
+
+	kmb_write(lcd, LCD_LAYERn_WIDTH(plane_id), src_w-1);
+	kmb_write(lcd, LCD_LAYERn_HEIGHT(plane_id), src_h-1);
+	kmb_write(lcd, LCD_LAYERn_COL_START(plane_id), crtc_x);
+	kmb_write(lcd, 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 50 try this for now */
+	val |= LCD_LAYER_FIFO_50;
+	kmb_write(lcd, LCD_LAYERn_CFG(plane_id), val);
+
 	switch (plane_id) {
 	case LAYER_0:
 		ctrl = LCD_CTRL_VL1_ENABLE;
@@ -92,12 +222,6 @@  static void kmb_plane_atomic_update(struct drm_plane *plane,
 	    | LCD_CTRL_OUTPUT_ENABLED;
 	kmb_write(lcd, LCD_CONTROL, ctrl);
 
-	/* TBD */
-	/*set LCD_LAYERn_WIDTH, LCD_LAYERn_HEIGHT, LCD_LAYERn_COL_START,
-	 * LCD_LAYERn_ROW_START, LCD_LAYERn_CFG
-	 * CFG should set the pixel format, FIFO level and BPP
-	 */
-
 	/*TBD check visible? */
 
 	/* we may have to set LCD_DMA_VSTRIDE_ENABLE in the future */
@@ -202,9 +326,6 @@  static const u32 kmb_formats_g[] = {
 	DRM_FORMAT_RGB888, DRM_FORMAT_BGR888,
 	DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888,
 	DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888,
-	DRM_FORMAT_XRGB2101010, DRM_FORMAT_XBGR2101010,
-	DRM_FORMAT_YUYV, DRM_FORMAT_YVYU,
-	DRM_FORMAT_UYVY, DRM_FORMAT_VYUY,
 };
 
 /* video layer (0 & 1) formats, packed and planar formats are supported */
@@ -219,11 +340,7 @@  static const u32 kmb_formats_v[] = {
 	DRM_FORMAT_RGB888, DRM_FORMAT_BGR888,
 	DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888,
 	DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888,
-	DRM_FORMAT_XRGB2101010, DRM_FORMAT_XBGR2101010,
-	DRM_FORMAT_YUYV, DRM_FORMAT_YVYU,
-	DRM_FORMAT_UYVY, DRM_FORMAT_VYUY,
 	/*planar formats */
-	DRM_FORMAT_YUV411, DRM_FORMAT_YVU411,
 	DRM_FORMAT_YUV420, DRM_FORMAT_YVU420,
 	DRM_FORMAT_YUV422, DRM_FORMAT_YVU422,
 	DRM_FORMAT_YUV444, DRM_FORMAT_YVU444,
diff --git a/drivers/gpu/drm/kmb/kmb_regs.h b/drivers/gpu/drm/kmb/kmb_regs.h
index 95cf932..9bf2b9f 100644
--- a/drivers/gpu/drm/kmb/kmb_regs.h
+++ b/drivers/gpu/drm/kmb/kmb_regs.h
@@ -381,6 +381,173 @@ 
 /* bit 10 */
 #define LCD_DMA_LAYER_V_STRIDE_EN		(0x400)
 
+/******************************************************************************
+ *		   LCD controller Layer config register
+ ******************************************************************************/
+/* ---bit 1:2 */
+/* enable horizontal scaling,default is
+ * no scaling
+ */
+#define LCD_LAYER_SCALE_H			(0x0002)
+/* enable vertical scaling*/
+#define LCD_LAYER_SCALE_V			(0x0004)
+/* enable vertical and horizontal
+ * scaling
+ */
+#define LCD_LAYER_SCALE_H_V			(0x0006)
+/* --- bit 3*/
+/* enable CSC, default is bypassed*/
+#define LCD_LAYER_CSC_EN			(0x0008)
+/* --- bit 4:5*/
+/* use static alpha value for layer,
+ * default is disabled
+ */
+#define LCD_LAYER_ALPHA_STATIC			(0x10)
+/* use embedded value for alpha blending*/
+#define LCD_LAYER_ALPHA_EMBED			(0x20)
+/* use static alpha and embedded value,
+ * by multiplication
+ */
+#define LCD_LAYER_ALPHA_COMBI			(0x30)
+/* --- bit 6*/
+/* indicates that the RGB values have
+ * been multiplied with alpha
+ */
+#define LCD_LAYER_ALPHA_PREMULT			(0x40)
+/* --- bit 7*/
+#define LCD_LAYER_INVERT_COL			(0x80)
+/* enable color inversion,
+ * default is not inverted
+ */
+/* --- bit 8*/
+/* enable transparency */
+#define LCD_LAYER_TRANSPARENT_EN		(0x100)
+/* --- bit 9:13*/
+/* default Layer config */
+#define LCD_LAYER_FORMAT_YCBCR444PLAN		(0x0000)
+#define LCD_LAYER_FORMAT_YCBCR422PLAN		(0x0200)
+#define LCD_LAYER_FORMAT_YCBCR420PLAN		(0x0400)
+#define LCD_LAYER_FORMAT_RGB888PLAN		(0x0600)
+#define LCD_LAYER_FORMAT_YCBCR444LIN		(0x0800)
+#define LCD_LAYER_FORMAT_YCBCR422LIN		(0x0A00)
+#define LCD_LAYER_FORMAT_RGB888			(0x0C00)
+#define LCD_LAYER_FORMAT_RGBA8888		(0x0E00)
+#define LCD_LAYER_FORMAT_RGBX8888		(0x1000)
+#define LCD_LAYER_FORMAT_RGB565			(0x1200)
+#define LCD_LAYER_FORMAT_RGBA1555		(0x1400)
+#define LCD_LAYER_FORMAT_XRGB1555		(0x1600)
+#define LCD_LAYER_FORMAT_RGB444			(0x1800)
+#define LCD_LAYER_FORMAT_RGBA4444		(0x1A00)
+#define LCD_LAYER_FORMAT_RGBX4444		(0x1C00)
+#define LCD_LAYER_FORMAT_RGB332			(0x1E00)
+#define LCD_LAYER_FORMAT_RGBA3328		(0x2000)
+#define LCD_LAYER_FORMAT_RGBX3328		(0x2200)
+#define LCD_LAYER_FORMAT_CLUT			(0x2400)
+#define LCD_LAYER_FORMAT_NV12			(0x3800)
+/* --- bit 14*/
+/* planar storege format */
+#define LCD_LAYER_PLANAR_STORAGE		(0x4000)
+/* --- bit 15:16*/
+#define LCD_LAYER_8BPP				(0x00000)
+#define LCD_LAYER_16BPP				(0x08000)
+#define LCD_LAYER_24BPP				(0x10000)
+#define LCD_LAYER_32BPP				(0x18000)
+/* --- bit 17*/
+/* Y after CRCb,
+ * default is Y before crcb
+ */
+#define LCD_LAYER_Y_ORDER			(0x020000)
+/* --- bit 18*/
+/* CR before Cb,
+ * default is CB before Cr
+ */
+#define LCD_LAYER_CRCB_ORDER			(0x040000)
+/*--- but 19*/
+/* BGR order, default is RGB */
+#define LCD_LAYER_BGR_ORDER			(0x080000)
+/* ---bit 20:21*/
+/* 2 entry clut, 1bpp */
+#define LCD_LAYER_LUT_2ENT			(0x000000)
+/* 4 entry clut, 2bpp */
+#define LCD_LAYER_LUT_4ENT			(0x100000)
+/* 18 entry clut, 4bpp */
+#define LCD_LAYER_LUT_16ENT			(0x200000)
+/*--- bit 22:24*/
+/* no flip or rotaton */
+#define LCD_LAYER_NO_FLIP			(0x000000)
+/* flip vertical */
+#define LCD_LAYER_FLIP_V			(0x400000)
+/* flip horizontal */
+#define LCD_LAYER_FLIP_H			(0x800000)
+/* rotate right 90 */
+#define LCD_LAYER_ROT_R90			(0xC00000)
+/* rotate left 90 */
+#define LCD_LAYER_ROT_L90			(0x1000000)
+/* rotate 180 (flip H & V ) */
+#define LCD_LAYER_ROT_180			(0x1400000)
+/* --- bit 25:26*/
+/* fifo empty */
+#define LCD_LAYER_FIFO_00			(0x0000000)
+/* fifo 25% */
+#define LCD_LAYER_FIFO_25			(0x2000000)
+/* fifo 50% */
+#define LCD_LAYER_FIFO_50			(0x4000000)
+/* fifo 100% , full */
+#define LCD_LAYER_FIFO_100			(0x6000000)
+
+/* --- bit 27:29*/
+#define LCD_LAYER_INTERLEAVE_DIS		(0x00000000)
+#define LCD_LAYER_INTERLEAVE_V			(0x08000000)
+#define LCD_LAYER_INTERLEAVE_H			(0x10000000)
+#define LCD_LAYER_INTERLEAVE_CH			(0x18000000)
+#define LCD_LAYER_INTERLEAVE_V_SUB		(0x20000000)
+#define LCD_LAYER_INTERLEAVE_H_SUB		(0x28000000)
+#define LCD_LAYER_INTERLEAVE_CH_SUB		(0x30000000)
+/*bit 30*/
+#define LCD_LAYER_INTER_POS_EVEN		(0x00000000)
+#define LCD_LAYER_INTER_POS_ODD			(0x40000000)
+
+/****************************************************************************
+ *		   LCD controller output format register defines
+ ****************************************************************************/
+/* --- bits 0:4*/
+#define D_LCD_OUTF_FORMAT_RGB121212             (0x00 << 0)
+#define D_LCD_OUTF_FORMAT_RGB101010             (0x01 << 0)
+#define D_LCD_OUTF_FORMAT_RGB888                (0x02 << 0)
+#define D_LCD_OUTF_FORMAT_RGB666                (0x03 << 0)
+#define D_LCD_OUTF_FORMAT_RGB565                (0x04 << 0)
+#define D_LCD_OUTF_FORMAT_RGB444                (0x05 << 0)
+#define D_LCD_OUTF_FORMAT_MRGB121212            (0x10 << 0)
+#define D_LCD_OUTF_FORMAT_MRGB101010            (0x11 << 0)
+#define D_LCD_OUTF_FORMAT_MRGB888               (0x12 << 0)
+#define D_LCD_OUTF_FORMAT_MRGB666               (0x13 << 0)
+#define D_LCD_OUTF_FORMAT_MRGB565               (0x14 << 0)
+#define D_LCD_OUTF_FORMAT_YCBCR420_8B_LEGACY    (0x08 << 0)
+#define D_LCD_OUTF_FORMAT_YCBCR420_8B_DCI       (0x09 << 0)
+#define D_LCD_OUTF_FORMAT_YCBCR420_8B           (0x0A << 0)
+#define D_LCD_OUTF_FORMAT_YCBCR420_10B          (0x0B << 0)
+#define D_LCD_OUTF_FORMAT_YCBCR420_12B          (0x0C << 0)
+#define D_LCD_OUTF_FORMAT_YCBCR422_8B           (0x0D << 0)
+#define D_LCD_OUTF_FORMAT_YCBCR422_10B          (0x0E << 0)
+#define D_LCD_OUTF_FORMAT_YCBCR444              (0x0F << 0)
+#define D_LCD_OUTF_FORMAT_MYCBCR420_8B_LEGACY   (0x18 << 0)
+#define D_LCD_OUTF_FORMAT_MYCBCR420_8B_DCI      (0x19 << 0)
+#define D_LCD_OUTF_FORMAT_MYCBCR420_8B          (0x1A << 0)
+#define D_LCD_OUTF_FORMAT_MYCBCR420_10B         (0x1B << 0)
+#define D_LCD_OUTF_FORMAT_MYCBCR420_12B         (0x1C << 0)
+#define D_LCD_OUTF_FORMAT_MYCBCR422_8B          (0x1D << 0)
+#define D_LCD_OUTF_FORMAT_MYCBCR422_10B         (0x1E << 0)
+#define D_LCD_OUTF_FORMAT_MYCBCR444             (0x1F << 0)
+/* --- bit 5*/
+/* default is 0, RGB order */
+#define D_LCD_OUTF_BGR_ORDER			(1 << 5)
+/* --- bit 6*/
+/* Y after CB/Cr, default is Y before CB/CR */
+#define D_LCD_OUTF_Y_ORDER			(1 << 6)
+/* --- bit 7*/
+/* Cr before  Cb, default is Cb before Cr */
+#define D_LCD_OUTF_CRCB_ORDER			(1 << 7)
+
 /* **************************************************************************
  *			LCD controller control register defines
  ****************************************************************************