All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bibby Hsieh <bibby.hsieh@mediatek.com>
To: David Airlie <airlied@linux.ie>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Daniel Vetter <daniel.vetter@ffwll.ch>,
	<dri-devel@lists.freedesktop.org>,
	<linux-mediatek@lists.infradead.org>
Cc: Yingjoe Chen <yingjoe.chen@mediatek.com>,
	Cawa Cheng <cawa.cheng@mediatek.com>,
	Daniel Kurtz <djkurtz@chromium.org>,
	Bibby Hsieh <bibby.hsieh@mediatek.com>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	YT Shen <yt.shen@mediatek.com>,
	Thierry Reding <thierry.reding@gmail.com>,
	CK Hu <ck.hu@mediatek.com>, Mao Huang <littlecvr@chromium.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>,
	Sascha Hauer <kernel@pengutronix.de>
Subject: [PATCH v2 2/2] drm/mediatek: set mt8173 dithering function
Date: Fri, 17 Jun 2016 09:58:14 +0800	[thread overview]
Message-ID: <1466128694-11208-3-git-send-email-bibby.hsieh@mediatek.com> (raw)
In-Reply-To: <1466128694-11208-1-git-send-email-bibby.hsieh@mediatek.com>

Some panels only accept bpc (bit per color) 6-bit.
But, the default bpc in mt8173 display data path is 8-bit.
If we didn't enable dithering function to convert bpc,
display cannot show the smooth grayscale image.

In mt8173, the dithering function in OD (OverDrive) and
GAMMA module, we have to config them with
connector->display_mode.bpc when CRTC initial.

1. Clear the default value at *_DITHER_5 and *_DITHER_7 register.
2. Calculate the LSB_ERR_SHIFT bits and ADD_LSHIFT bits two values.
i.e. Input bpc of OD is 10 bits, we assume the bpc of panel is 6-bit,
so, we need to set 4-bit to LSB_ERR_SHIFT and ADD_LSHIFT bits respectively.
3. Then, set the OD or GAMMA to dithering mode depends on path-1 or path-2.

Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c     |    3 +-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c    |    3 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c     |   18 ++++++--
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   62 +++++++++++++++++++++++++--
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |    6 +--
 5 files changed, 80 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 8f62671f..019b7ca 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -103,7 +103,8 @@ static void mtk_ovl_stop(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w,
-			   unsigned int h, unsigned int vrefresh)
+			   unsigned int h, unsigned int vrefresh,
+			   unsigned int bpc)
 {
 	if (w != 0 && h != 0)
 		writel_relaxed(h << 16 | w, comp->regs + DISP_REG_OVL_ROI_SIZE);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 5fb80cb..0df05f9 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -106,7 +106,8 @@ static void mtk_rdma_stop(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
-			    unsigned int height, unsigned int vrefresh)
+			    unsigned int height, unsigned int vrefresh,
+			    unsigned int bpc)
 {
 	unsigned int threshold;
 	unsigned int reg;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index ee219bb..9f78e6a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -222,7 +222,9 @@ static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc)
 static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 {
 	struct drm_crtc *crtc = &mtk_crtc->base;
-	unsigned int width, height, vrefresh;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	unsigned int width, height, vrefresh, bpc = 0;
 	int ret;
 	int i;
 
@@ -233,6 +235,16 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 	width = crtc->state->adjusted_mode.hdisplay;
 	height = crtc->state->adjusted_mode.vdisplay;
 	vrefresh = crtc->state->adjusted_mode.vrefresh;
+	drm_for_each_encoder(encoder, crtc->dev) {
+		if (encoder->crtc != crtc)
+			continue;
+		drm_for_each_connector(connector, crtc->dev) {
+			if (connector->encoder != encoder)
+				continue;
+			if (bpc == 0 || bpc > connector->display_info.bpc)
+				bpc = connector->display_info.bpc;
+		}
+	}
 
 	ret = pm_runtime_get_sync(crtc->dev->dev);
 	if (ret < 0) {
@@ -266,7 +278,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 		struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i];
 
-		mtk_ddp_comp_config(comp, width, height, vrefresh);
+		mtk_ddp_comp_config(comp, width, height, vrefresh, bpc);
 		mtk_ddp_comp_start(comp);
 	}
 
@@ -469,7 +481,7 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl)
 	if (state->pending_config) {
 		mtk_ddp_comp_config(ovl, state->pending_width,
 				    state->pending_height,
-				    state->pending_vrefresh);
+				    state->pending_vrefresh, 0);
 
 		state->pending_config = false;
 	}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 56c5894..50c08b9 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -47,22 +47,45 @@
 #define DISP_GAMMA_SIZE				0x030
 #define DISP_GAMMA_LUT				0x700
 
+#define DISP_DITHER_5				0x0114
+#define DISP_DITHER_7				0x011c
+#define DISP_DITHER_15				0x013c
+#define DISP_DITHER_16				0x0140
+
 #define LUT_10BIT_MASK				0x3ff
 
 #define AAL_EN			BIT(0)
 
 #define GAMMA_EN		BIT(0)
 #define GAMMA_LUT_EN		BIT(1)
+#define GAMMA_DITHERING		BIT(2)
 
 #define	OD_RELAY_MODE		BIT(0)
+#define OD_DITHERING		BIT(2)
 
 #define	UFO_BYPASS		BIT(2)
 
 #define	COLOR_BYPASS_ALL	BIT(7)
 #define	COLOR_SEQ_SEL		BIT(13)
 
+#define DITHERING_ALGORITHM_EN	BIT(0)
+
+#define DITHERING_LSB_ERR_SHIFT_R(bits)		((bits) << 28)
+#define DITHERING_OVFLW_R(bits)			((bits) << 24)
+#define DITHERING_ADD_LSHIFT_R(bits)		((bits) << 20)
+#define DITHERING_INPUT_RSHIFT_R(bits)		((bits) << 16)
+#define DITHERING_LSB_ERR_SHIFT_B(bits)		((bits) << 28)
+#define DITHERING_OVFLW_B(bits)			((bits) << 24)
+#define DITHERING_ADD_LSHIFT_B(bits)		((bits) << 20)
+#define DITHERING_INPUT_RSHIFT_B(bits)		((bits) << 16)
+#define DITHERING_LSB_ERR_SHIFT_G(bits)		((bits) << 12)
+#define DITHERING_OVFLW_G(bits)			((bits) << 8)
+#define DITHERING_ADD_LSHIFT_G(bits)		((bits) << 4)
+#define DITHERING_INPUT_RSHIFT_G(bits)		(bits)
+
 static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
-			     unsigned int h, unsigned int vrefresh)
+			     unsigned int h, unsigned int vrefresh,
+			     unsigned int bpc)
 {
 	writel(w, comp->regs + DISP_COLOR_WIDTH);
 	writel(h, comp->regs + DISP_COLOR_HEIGHT);
@@ -76,9 +99,25 @@ static void mtk_color_start(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_od_config(struct mtk_ddp_comp *comp, unsigned int w,
-			  unsigned int h, unsigned int vrefresh)
+			  unsigned int h, unsigned int vrefresh,
+			  unsigned int bpc)
 {
 	writel(w << 16 | h, comp->regs + DISP_OD_SIZE);
+	if (bpc < 10) {
+		writel(0, comp->regs + DISP_DITHER_5);
+		writel(0, comp->regs + DISP_DITHER_7);
+		writel(DITHERING_LSB_ERR_SHIFT_R(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_R(10 - bpc) |
+		       DITHERING_ALGORITHM_EN, comp->regs + DISP_DITHER_15);
+		writel(DITHERING_LSB_ERR_SHIFT_B(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_B(10 - bpc) |
+		       DITHERING_LSB_ERR_SHIFT_G(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_G(10 - bpc),
+		       comp->regs + DISP_DITHER_16);
+		writel(OD_DITHERING, comp->regs + DISP_OD_CFG);
+	} else {
+		writel(OD_RELAY_MODE, comp->regs + DISP_OD_CFG);
+	}
 }
 
 static void mtk_od_start(struct mtk_ddp_comp *comp)
@@ -93,7 +132,8 @@ static void mtk_ufoe_start(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_aal_config(struct mtk_ddp_comp *comp, unsigned int w,
-			   unsigned int h, unsigned int vrefresh)
+			   unsigned int h, unsigned int vrefresh,
+			   unsigned int bpc)
 {
 	writel(h << 16 | w, comp->regs + DISP_AAL_SIZE);
 }
@@ -109,9 +149,23 @@ static void mtk_aal_stop(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_gamma_config(struct mtk_ddp_comp *comp, unsigned int w,
-			     unsigned int h, unsigned int vrefresh)
+			     unsigned int h, unsigned int vrefresh,
+			     unsigned int bpc)
 {
 	writel(h << 16 | w, comp->regs + DISP_GAMMA_SIZE);
+	if (bpc < 10) {
+		writel(0, comp->regs + DISP_DITHER_5);
+		writel(0, comp->regs + DISP_DITHER_7);
+		writel(DITHERING_LSB_ERR_SHIFT_R(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_R(10 - bpc) |
+		       DITHERING_ALGORITHM_EN, comp->regs + DISP_DITHER_15);
+		writel(DITHERING_LSB_ERR_SHIFT_B(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_B(10 - bpc) |
+		       DITHERING_LSB_ERR_SHIFT_G(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_G(10 - bpc),
+		       comp->regs + DISP_DITHER_16);
+		writel(GAMMA_DITHERING, comp->regs + DISP_GAMMA_CFG);
+	}
 }
 
 static void mtk_gamma_start(struct mtk_ddp_comp *comp)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 07e17fe..c7c2e92 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -65,7 +65,7 @@ struct mtk_ddp_comp;
 
 struct mtk_ddp_comp_funcs {
 	void (*config)(struct mtk_ddp_comp *comp, unsigned int w,
-		       unsigned int h, unsigned int vrefresh);
+		       unsigned int h, unsigned int vrefresh, unsigned int bpc);
 	void (*start)(struct mtk_ddp_comp *comp);
 	void (*stop)(struct mtk_ddp_comp *comp);
 	void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc);
@@ -89,10 +89,10 @@ struct mtk_ddp_comp {
 
 static inline void mtk_ddp_comp_config(struct mtk_ddp_comp *comp,
 				       unsigned int w, unsigned int h,
-				       unsigned int vrefresh)
+				       unsigned int vrefresh, unsigned int bpc)
 {
 	if (comp->funcs && comp->funcs->config)
-		comp->funcs->config(comp, w, h, vrefresh);
+		comp->funcs->config(comp, w, h, vrefresh, bpc);
 }
 
 static inline void mtk_ddp_comp_start(struct mtk_ddp_comp *comp)
-- 
1.7.9.5

WARNING: multiple messages have this Message-ID (diff)
From: Bibby Hsieh <bibby.hsieh@mediatek.com>
To: David Airlie <airlied@linux.ie>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Daniel Vetter <daniel.vetter@ffwll.ch>,
	dri-devel@lists.freedesktop.org,
	linux-mediatek@lists.infradead.org
Cc: linux-kernel@vger.kernel.org,
	Cawa Cheng <cawa.cheng@mediatek.com>,
	Mao Huang <littlecvr@chromium.org>,
	Yingjoe Chen <yingjoe.chen@mediatek.com>,
	Sascha Hauer <kernel@pengutronix.de>,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 2/2] drm/mediatek: set mt8173 dithering function
Date: Fri, 17 Jun 2016 09:58:14 +0800	[thread overview]
Message-ID: <1466128694-11208-3-git-send-email-bibby.hsieh@mediatek.com> (raw)
In-Reply-To: <1466128694-11208-1-git-send-email-bibby.hsieh@mediatek.com>

Some panels only accept bpc (bit per color) 6-bit.
But, the default bpc in mt8173 display data path is 8-bit.
If we didn't enable dithering function to convert bpc,
display cannot show the smooth grayscale image.

In mt8173, the dithering function in OD (OverDrive) and
GAMMA module, we have to config them with
connector->display_mode.bpc when CRTC initial.

1. Clear the default value at *_DITHER_5 and *_DITHER_7 register.
2. Calculate the LSB_ERR_SHIFT bits and ADD_LSHIFT bits two values.
i.e. Input bpc of OD is 10 bits, we assume the bpc of panel is 6-bit,
so, we need to set 4-bit to LSB_ERR_SHIFT and ADD_LSHIFT bits respectively.
3. Then, set the OD or GAMMA to dithering mode depends on path-1 or path-2.

Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c     |    3 +-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c    |    3 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c     |   18 ++++++--
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   62 +++++++++++++++++++++++++--
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |    6 +--
 5 files changed, 80 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 8f62671f..019b7ca 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -103,7 +103,8 @@ static void mtk_ovl_stop(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w,
-			   unsigned int h, unsigned int vrefresh)
+			   unsigned int h, unsigned int vrefresh,
+			   unsigned int bpc)
 {
 	if (w != 0 && h != 0)
 		writel_relaxed(h << 16 | w, comp->regs + DISP_REG_OVL_ROI_SIZE);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 5fb80cb..0df05f9 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -106,7 +106,8 @@ static void mtk_rdma_stop(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
-			    unsigned int height, unsigned int vrefresh)
+			    unsigned int height, unsigned int vrefresh,
+			    unsigned int bpc)
 {
 	unsigned int threshold;
 	unsigned int reg;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index ee219bb..9f78e6a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -222,7 +222,9 @@ static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc)
 static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 {
 	struct drm_crtc *crtc = &mtk_crtc->base;
-	unsigned int width, height, vrefresh;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	unsigned int width, height, vrefresh, bpc = 0;
 	int ret;
 	int i;
 
@@ -233,6 +235,16 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 	width = crtc->state->adjusted_mode.hdisplay;
 	height = crtc->state->adjusted_mode.vdisplay;
 	vrefresh = crtc->state->adjusted_mode.vrefresh;
+	drm_for_each_encoder(encoder, crtc->dev) {
+		if (encoder->crtc != crtc)
+			continue;
+		drm_for_each_connector(connector, crtc->dev) {
+			if (connector->encoder != encoder)
+				continue;
+			if (bpc == 0 || bpc > connector->display_info.bpc)
+				bpc = connector->display_info.bpc;
+		}
+	}
 
 	ret = pm_runtime_get_sync(crtc->dev->dev);
 	if (ret < 0) {
@@ -266,7 +278,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 		struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i];
 
-		mtk_ddp_comp_config(comp, width, height, vrefresh);
+		mtk_ddp_comp_config(comp, width, height, vrefresh, bpc);
 		mtk_ddp_comp_start(comp);
 	}
 
@@ -469,7 +481,7 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl)
 	if (state->pending_config) {
 		mtk_ddp_comp_config(ovl, state->pending_width,
 				    state->pending_height,
-				    state->pending_vrefresh);
+				    state->pending_vrefresh, 0);
 
 		state->pending_config = false;
 	}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 56c5894..50c08b9 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -47,22 +47,45 @@
 #define DISP_GAMMA_SIZE				0x030
 #define DISP_GAMMA_LUT				0x700
 
+#define DISP_DITHER_5				0x0114
+#define DISP_DITHER_7				0x011c
+#define DISP_DITHER_15				0x013c
+#define DISP_DITHER_16				0x0140
+
 #define LUT_10BIT_MASK				0x3ff
 
 #define AAL_EN			BIT(0)
 
 #define GAMMA_EN		BIT(0)
 #define GAMMA_LUT_EN		BIT(1)
+#define GAMMA_DITHERING		BIT(2)
 
 #define	OD_RELAY_MODE		BIT(0)
+#define OD_DITHERING		BIT(2)
 
 #define	UFO_BYPASS		BIT(2)
 
 #define	COLOR_BYPASS_ALL	BIT(7)
 #define	COLOR_SEQ_SEL		BIT(13)
 
+#define DITHERING_ALGORITHM_EN	BIT(0)
+
+#define DITHERING_LSB_ERR_SHIFT_R(bits)		((bits) << 28)
+#define DITHERING_OVFLW_R(bits)			((bits) << 24)
+#define DITHERING_ADD_LSHIFT_R(bits)		((bits) << 20)
+#define DITHERING_INPUT_RSHIFT_R(bits)		((bits) << 16)
+#define DITHERING_LSB_ERR_SHIFT_B(bits)		((bits) << 28)
+#define DITHERING_OVFLW_B(bits)			((bits) << 24)
+#define DITHERING_ADD_LSHIFT_B(bits)		((bits) << 20)
+#define DITHERING_INPUT_RSHIFT_B(bits)		((bits) << 16)
+#define DITHERING_LSB_ERR_SHIFT_G(bits)		((bits) << 12)
+#define DITHERING_OVFLW_G(bits)			((bits) << 8)
+#define DITHERING_ADD_LSHIFT_G(bits)		((bits) << 4)
+#define DITHERING_INPUT_RSHIFT_G(bits)		(bits)
+
 static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
-			     unsigned int h, unsigned int vrefresh)
+			     unsigned int h, unsigned int vrefresh,
+			     unsigned int bpc)
 {
 	writel(w, comp->regs + DISP_COLOR_WIDTH);
 	writel(h, comp->regs + DISP_COLOR_HEIGHT);
@@ -76,9 +99,25 @@ static void mtk_color_start(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_od_config(struct mtk_ddp_comp *comp, unsigned int w,
-			  unsigned int h, unsigned int vrefresh)
+			  unsigned int h, unsigned int vrefresh,
+			  unsigned int bpc)
 {
 	writel(w << 16 | h, comp->regs + DISP_OD_SIZE);
+	if (bpc < 10) {
+		writel(0, comp->regs + DISP_DITHER_5);
+		writel(0, comp->regs + DISP_DITHER_7);
+		writel(DITHERING_LSB_ERR_SHIFT_R(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_R(10 - bpc) |
+		       DITHERING_ALGORITHM_EN, comp->regs + DISP_DITHER_15);
+		writel(DITHERING_LSB_ERR_SHIFT_B(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_B(10 - bpc) |
+		       DITHERING_LSB_ERR_SHIFT_G(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_G(10 - bpc),
+		       comp->regs + DISP_DITHER_16);
+		writel(OD_DITHERING, comp->regs + DISP_OD_CFG);
+	} else {
+		writel(OD_RELAY_MODE, comp->regs + DISP_OD_CFG);
+	}
 }
 
 static void mtk_od_start(struct mtk_ddp_comp *comp)
@@ -93,7 +132,8 @@ static void mtk_ufoe_start(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_aal_config(struct mtk_ddp_comp *comp, unsigned int w,
-			   unsigned int h, unsigned int vrefresh)
+			   unsigned int h, unsigned int vrefresh,
+			   unsigned int bpc)
 {
 	writel(h << 16 | w, comp->regs + DISP_AAL_SIZE);
 }
@@ -109,9 +149,23 @@ static void mtk_aal_stop(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_gamma_config(struct mtk_ddp_comp *comp, unsigned int w,
-			     unsigned int h, unsigned int vrefresh)
+			     unsigned int h, unsigned int vrefresh,
+			     unsigned int bpc)
 {
 	writel(h << 16 | w, comp->regs + DISP_GAMMA_SIZE);
+	if (bpc < 10) {
+		writel(0, comp->regs + DISP_DITHER_5);
+		writel(0, comp->regs + DISP_DITHER_7);
+		writel(DITHERING_LSB_ERR_SHIFT_R(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_R(10 - bpc) |
+		       DITHERING_ALGORITHM_EN, comp->regs + DISP_DITHER_15);
+		writel(DITHERING_LSB_ERR_SHIFT_B(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_B(10 - bpc) |
+		       DITHERING_LSB_ERR_SHIFT_G(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_G(10 - bpc),
+		       comp->regs + DISP_DITHER_16);
+		writel(GAMMA_DITHERING, comp->regs + DISP_GAMMA_CFG);
+	}
 }
 
 static void mtk_gamma_start(struct mtk_ddp_comp *comp)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 07e17fe..c7c2e92 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -65,7 +65,7 @@ struct mtk_ddp_comp;
 
 struct mtk_ddp_comp_funcs {
 	void (*config)(struct mtk_ddp_comp *comp, unsigned int w,
-		       unsigned int h, unsigned int vrefresh);
+		       unsigned int h, unsigned int vrefresh, unsigned int bpc);
 	void (*start)(struct mtk_ddp_comp *comp);
 	void (*stop)(struct mtk_ddp_comp *comp);
 	void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc);
@@ -89,10 +89,10 @@ struct mtk_ddp_comp {
 
 static inline void mtk_ddp_comp_config(struct mtk_ddp_comp *comp,
 				       unsigned int w, unsigned int h,
-				       unsigned int vrefresh)
+				       unsigned int vrefresh, unsigned int bpc)
 {
 	if (comp->funcs && comp->funcs->config)
-		comp->funcs->config(comp, w, h, vrefresh);
+		comp->funcs->config(comp, w, h, vrefresh, bpc);
 }
 
 static inline void mtk_ddp_comp_start(struct mtk_ddp_comp *comp)
-- 
1.7.9.5

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

WARNING: multiple messages have this Message-ID (diff)
From: bibby.hsieh@mediatek.com (Bibby Hsieh)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 2/2] drm/mediatek: set mt8173 dithering function
Date: Fri, 17 Jun 2016 09:58:14 +0800	[thread overview]
Message-ID: <1466128694-11208-3-git-send-email-bibby.hsieh@mediatek.com> (raw)
In-Reply-To: <1466128694-11208-1-git-send-email-bibby.hsieh@mediatek.com>

Some panels only accept bpc (bit per color) 6-bit.
But, the default bpc in mt8173 display data path is 8-bit.
If we didn't enable dithering function to convert bpc,
display cannot show the smooth grayscale image.

In mt8173, the dithering function in OD (OverDrive) and
GAMMA module, we have to config them with
connector->display_mode.bpc when CRTC initial.

1. Clear the default value at *_DITHER_5 and *_DITHER_7 register.
2. Calculate the LSB_ERR_SHIFT bits and ADD_LSHIFT bits two values.
i.e. Input bpc of OD is 10 bits, we assume the bpc of panel is 6-bit,
so, we need to set 4-bit to LSB_ERR_SHIFT and ADD_LSHIFT bits respectively.
3. Then, set the OD or GAMMA to dithering mode depends on path-1 or path-2.

Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c     |    3 +-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c    |    3 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c     |   18 ++++++--
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   62 +++++++++++++++++++++++++--
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |    6 +--
 5 files changed, 80 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 8f62671f..019b7ca 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -103,7 +103,8 @@ static void mtk_ovl_stop(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w,
-			   unsigned int h, unsigned int vrefresh)
+			   unsigned int h, unsigned int vrefresh,
+			   unsigned int bpc)
 {
 	if (w != 0 && h != 0)
 		writel_relaxed(h << 16 | w, comp->regs + DISP_REG_OVL_ROI_SIZE);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 5fb80cb..0df05f9 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -106,7 +106,8 @@ static void mtk_rdma_stop(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
-			    unsigned int height, unsigned int vrefresh)
+			    unsigned int height, unsigned int vrefresh,
+			    unsigned int bpc)
 {
 	unsigned int threshold;
 	unsigned int reg;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index ee219bb..9f78e6a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -222,7 +222,9 @@ static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc)
 static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 {
 	struct drm_crtc *crtc = &mtk_crtc->base;
-	unsigned int width, height, vrefresh;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	unsigned int width, height, vrefresh, bpc = 0;
 	int ret;
 	int i;
 
@@ -233,6 +235,16 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 	width = crtc->state->adjusted_mode.hdisplay;
 	height = crtc->state->adjusted_mode.vdisplay;
 	vrefresh = crtc->state->adjusted_mode.vrefresh;
+	drm_for_each_encoder(encoder, crtc->dev) {
+		if (encoder->crtc != crtc)
+			continue;
+		drm_for_each_connector(connector, crtc->dev) {
+			if (connector->encoder != encoder)
+				continue;
+			if (bpc == 0 || bpc > connector->display_info.bpc)
+				bpc = connector->display_info.bpc;
+		}
+	}
 
 	ret = pm_runtime_get_sync(crtc->dev->dev);
 	if (ret < 0) {
@@ -266,7 +278,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 		struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i];
 
-		mtk_ddp_comp_config(comp, width, height, vrefresh);
+		mtk_ddp_comp_config(comp, width, height, vrefresh, bpc);
 		mtk_ddp_comp_start(comp);
 	}
 
@@ -469,7 +481,7 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl)
 	if (state->pending_config) {
 		mtk_ddp_comp_config(ovl, state->pending_width,
 				    state->pending_height,
-				    state->pending_vrefresh);
+				    state->pending_vrefresh, 0);
 
 		state->pending_config = false;
 	}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 56c5894..50c08b9 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -47,22 +47,45 @@
 #define DISP_GAMMA_SIZE				0x030
 #define DISP_GAMMA_LUT				0x700
 
+#define DISP_DITHER_5				0x0114
+#define DISP_DITHER_7				0x011c
+#define DISP_DITHER_15				0x013c
+#define DISP_DITHER_16				0x0140
+
 #define LUT_10BIT_MASK				0x3ff
 
 #define AAL_EN			BIT(0)
 
 #define GAMMA_EN		BIT(0)
 #define GAMMA_LUT_EN		BIT(1)
+#define GAMMA_DITHERING		BIT(2)
 
 #define	OD_RELAY_MODE		BIT(0)
+#define OD_DITHERING		BIT(2)
 
 #define	UFO_BYPASS		BIT(2)
 
 #define	COLOR_BYPASS_ALL	BIT(7)
 #define	COLOR_SEQ_SEL		BIT(13)
 
+#define DITHERING_ALGORITHM_EN	BIT(0)
+
+#define DITHERING_LSB_ERR_SHIFT_R(bits)		((bits) << 28)
+#define DITHERING_OVFLW_R(bits)			((bits) << 24)
+#define DITHERING_ADD_LSHIFT_R(bits)		((bits) << 20)
+#define DITHERING_INPUT_RSHIFT_R(bits)		((bits) << 16)
+#define DITHERING_LSB_ERR_SHIFT_B(bits)		((bits) << 28)
+#define DITHERING_OVFLW_B(bits)			((bits) << 24)
+#define DITHERING_ADD_LSHIFT_B(bits)		((bits) << 20)
+#define DITHERING_INPUT_RSHIFT_B(bits)		((bits) << 16)
+#define DITHERING_LSB_ERR_SHIFT_G(bits)		((bits) << 12)
+#define DITHERING_OVFLW_G(bits)			((bits) << 8)
+#define DITHERING_ADD_LSHIFT_G(bits)		((bits) << 4)
+#define DITHERING_INPUT_RSHIFT_G(bits)		(bits)
+
 static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
-			     unsigned int h, unsigned int vrefresh)
+			     unsigned int h, unsigned int vrefresh,
+			     unsigned int bpc)
 {
 	writel(w, comp->regs + DISP_COLOR_WIDTH);
 	writel(h, comp->regs + DISP_COLOR_HEIGHT);
@@ -76,9 +99,25 @@ static void mtk_color_start(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_od_config(struct mtk_ddp_comp *comp, unsigned int w,
-			  unsigned int h, unsigned int vrefresh)
+			  unsigned int h, unsigned int vrefresh,
+			  unsigned int bpc)
 {
 	writel(w << 16 | h, comp->regs + DISP_OD_SIZE);
+	if (bpc < 10) {
+		writel(0, comp->regs + DISP_DITHER_5);
+		writel(0, comp->regs + DISP_DITHER_7);
+		writel(DITHERING_LSB_ERR_SHIFT_R(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_R(10 - bpc) |
+		       DITHERING_ALGORITHM_EN, comp->regs + DISP_DITHER_15);
+		writel(DITHERING_LSB_ERR_SHIFT_B(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_B(10 - bpc) |
+		       DITHERING_LSB_ERR_SHIFT_G(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_G(10 - bpc),
+		       comp->regs + DISP_DITHER_16);
+		writel(OD_DITHERING, comp->regs + DISP_OD_CFG);
+	} else {
+		writel(OD_RELAY_MODE, comp->regs + DISP_OD_CFG);
+	}
 }
 
 static void mtk_od_start(struct mtk_ddp_comp *comp)
@@ -93,7 +132,8 @@ static void mtk_ufoe_start(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_aal_config(struct mtk_ddp_comp *comp, unsigned int w,
-			   unsigned int h, unsigned int vrefresh)
+			   unsigned int h, unsigned int vrefresh,
+			   unsigned int bpc)
 {
 	writel(h << 16 | w, comp->regs + DISP_AAL_SIZE);
 }
@@ -109,9 +149,23 @@ static void mtk_aal_stop(struct mtk_ddp_comp *comp)
 }
 
 static void mtk_gamma_config(struct mtk_ddp_comp *comp, unsigned int w,
-			     unsigned int h, unsigned int vrefresh)
+			     unsigned int h, unsigned int vrefresh,
+			     unsigned int bpc)
 {
 	writel(h << 16 | w, comp->regs + DISP_GAMMA_SIZE);
+	if (bpc < 10) {
+		writel(0, comp->regs + DISP_DITHER_5);
+		writel(0, comp->regs + DISP_DITHER_7);
+		writel(DITHERING_LSB_ERR_SHIFT_R(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_R(10 - bpc) |
+		       DITHERING_ALGORITHM_EN, comp->regs + DISP_DITHER_15);
+		writel(DITHERING_LSB_ERR_SHIFT_B(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_B(10 - bpc) |
+		       DITHERING_LSB_ERR_SHIFT_G(10 - bpc) |
+		       DITHERING_ADD_LSHIFT_G(10 - bpc),
+		       comp->regs + DISP_DITHER_16);
+		writel(GAMMA_DITHERING, comp->regs + DISP_GAMMA_CFG);
+	}
 }
 
 static void mtk_gamma_start(struct mtk_ddp_comp *comp)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 07e17fe..c7c2e92 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -65,7 +65,7 @@ struct mtk_ddp_comp;
 
 struct mtk_ddp_comp_funcs {
 	void (*config)(struct mtk_ddp_comp *comp, unsigned int w,
-		       unsigned int h, unsigned int vrefresh);
+		       unsigned int h, unsigned int vrefresh, unsigned int bpc);
 	void (*start)(struct mtk_ddp_comp *comp);
 	void (*stop)(struct mtk_ddp_comp *comp);
 	void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc);
@@ -89,10 +89,10 @@ struct mtk_ddp_comp {
 
 static inline void mtk_ddp_comp_config(struct mtk_ddp_comp *comp,
 				       unsigned int w, unsigned int h,
-				       unsigned int vrefresh)
+				       unsigned int vrefresh, unsigned int bpc)
 {
 	if (comp->funcs && comp->funcs->config)
-		comp->funcs->config(comp, w, h, vrefresh);
+		comp->funcs->config(comp, w, h, vrefresh, bpc);
 }
 
 static inline void mtk_ddp_comp_start(struct mtk_ddp_comp *comp)
-- 
1.7.9.5

  parent reply	other threads:[~2016-06-17  1:58 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-17  1:58 [PATCH v2 0/2] drm/mediatek: MT8173 gamma & dither support Bibby Hsieh
2016-06-17  1:58 ` Bibby Hsieh
2016-06-17  1:58 ` Bibby Hsieh
2016-06-17  1:58 ` [PATCH v2 1/2] drm/mediatek: Add gamma correction Bibby Hsieh
2016-06-17  1:58   ` Bibby Hsieh
2016-06-17  1:58   ` Bibby Hsieh
2016-06-17  1:58 ` Bibby Hsieh [this message]
2016-06-17  1:58   ` [PATCH v2 2/2] drm/mediatek: set mt8173 dithering function Bibby Hsieh
2016-06-17  1:58   ` Bibby Hsieh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1466128694-11208-3-git-send-email-bibby.hsieh@mediatek.com \
    --to=bibby.hsieh@mediatek.com \
    --cc=airlied@linux.ie \
    --cc=cawa.cheng@mediatek.com \
    --cc=ck.hu@mediatek.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=djkurtz@chromium.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kernel@pengutronix.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=littlecvr@chromium.org \
    --cc=matthias.bgg@gmail.com \
    --cc=p.zabel@pengutronix.de \
    --cc=thierry.reding@gmail.com \
    --cc=yingjoe.chen@mediatek.com \
    --cc=yt.shen@mediatek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.