Re: [PATCH v2 2/3] drm/mediatek: Add gamma lut support for mt8195

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Il 30/08/22 08:39, zheng-yan.chen ha scritto:
Since the previous gamma_set_common() function is designed for
9bit-to-10bit conversion, which is not feasible for the
10bit-to-12bit conversion in mt8195.

Update the function to fit the need of mt8195.

Fixes: 7266e90a51a3 ("drm/mediatek: Add mediatek-drm of vdosys0 support for mt8195")
Signed-off-by: zheng-yan.chen <zheng-yan.chen@xxxxxxxxxxxx>
---
  drivers/gpu/drm/mediatek/mtk_disp_aal.c     |   2 +-
  drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   3 +-
  drivers/gpu/drm/mediatek/mtk_disp_gamma.c   | 102 +++++++++++++++-----
  drivers/gpu/drm/mediatek/mtk_drm_crtc.c     |   5 +-
  drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |   1 -
  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   1 +
  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   2 +
  8 files changed, 85 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_aal.c b/drivers/gpu/drm/mediatek/mtk_disp_aal.c
index 0f9d7efb61d7..f563eee3c330 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_aal.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_aal.c
@@ -66,7 +66,7 @@ void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)
  	struct mtk_disp_aal *aal = dev_get_drvdata(dev);
if (aal->data && aal->data->has_gamma)
-		mtk_gamma_set_common(aal->regs, state, false);
+		mtk_gamma_set_common(aal->regs, state, dev);
  }
void mtk_aal_start(struct device *dev)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 33e61a136bbc..c1269fce9a66 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -51,8 +51,9 @@ void mtk_gamma_clk_disable(struct device *dev);
  void mtk_gamma_config(struct device *dev, unsigned int w,
  		      unsigned int h, unsigned int vrefresh,
  		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+unsigned int mtk_gamma_size(struct device *dev);
  void mtk_gamma_set(struct device *dev, struct drm_crtc_state *state);
-void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state, bool lut_diff);
+void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state, struct device *dev);
  void mtk_gamma_start(struct device *dev);
  void mtk_gamma_stop(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
index bbd558a036ec..0409e15fceb3 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
@@ -18,18 +18,22 @@
  #define DISP_GAMMA_EN				0x0000
  #define GAMMA_EN					BIT(0)
  #define DISP_GAMMA_CFG				0x0020
+#define RELAY_MODE					BIT(0)
  #define GAMMA_LUT_EN					BIT(1)
  #define GAMMA_DITHERING					BIT(2)
  #define DISP_GAMMA_SIZE				0x0030
+#define DISP_GAMMA_BANK				0x0100
  #define DISP_GAMMA_LUT				0x0700
-
-#define LUT_10BIT_MASK				0x03ff
-
+#define DISP_GAMMA_LUT1				0x0b00

+#define TABLE_9BIT_SIZE				512
+#define TABLE_10BIT_SIZE			1024

Please remove these two unused definitions.

+#define BANK_SIZE				256
  struct mtk_disp_gamma_data {
  	bool has_dither;
  	bool lut_diff;
+	unsigned int lut_size;
+	unsigned int lut_bits;

We can reduce the size of this structure by using

	u16 lut_size;
	u8 lut_bits;

  };
-
  /*
   * struct mtk_disp_gamma - DISP_GAMMA driver structure
   */
@@ -54,40 +58,75 @@ void mtk_gamma_clk_disable(struct device *dev)
  	clk_disable_unprepare(gamma->clk);
  }
-void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state, bool lut_diff)
+void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state, struct device *dev)
  {
-	unsigned int i, reg;
-	struct drm_color_lut *lut;
+	unsigned int i, reg, idx;
  	void __iomem *lut_base;
-	u32 word;
-	u32 diff[3] = {0};
+	void __iomem *lut1_base;
+	u32 word, word1;
+	struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);

Please reorder these definitions, (columns) longest first, shortest last

if (state->gamma_lut) {
+		u32 table_size;
+		u32 mask;
+		u32 lut_bits;
+		u32 shift_bits;
+		bool lut_diff;
+		struct drm_color_lut color, color_rec;
+		struct drm_color_lut *lut = (struct drm_color_lut *)state->gamma_lut;


struct drm_color_lut *lut = (struct drm_color_lut *)state->gamma_lut;
struct drm_color_lut color, color_rec;
u32 lut_bits, shift_bits;
u32 mask, table_size;
bool lut_diff;

+
+		table_size = gamma->data->lut_size;
+		lut_bits = gamma->data->lut_bits;
+		lut_diff = gamma->data->lut_diff;
+		shift_bits = (lut_bits == 12) ? 4 : 6;
+		mask = GENMASK(lut_bits - 1, 0);
  		reg = readl(regs + DISP_GAMMA_CFG);
+		reg = reg & ~RELAY_MODE;
  		reg = reg | GAMMA_LUT_EN;
  		writel(reg, regs + DISP_GAMMA_CFG);
  		lut_base = regs + DISP_GAMMA_LUT;
-		lut = (struct drm_color_lut *)state->gamma_lut->data;
-		for (i = 0; i < MTK_LUT_SIZE; i++) {
-
-			if (!lut_diff || (i % 2 == 0)) {
-				word = (((lut[i].red >> 6) & LUT_10BIT_MASK) << 20) +
-					(((lut[i].green >> 6) & LUT_10BIT_MASK) << 10) +
-					((lut[i].blue >> 6) & LUT_10BIT_MASK);
+		lut1_base = regs + DISP_GAMMA_LUT1;
+		for (i = 0; i < table_size; i++) {
+			color.red = (lut[i].red >> shift_bits) & mask;
+			color.green = (lut[i].green >> shift_bits) & mask;
+			color.blue = (lut[i].blue >> shift_bits) & mask;
+			if (lut_diff && (i % 2)) {
+				word = (lut_bits == 12) ?
+						      (((color.green - color_rec.green) << 12) +
+						      (color.red - color_rec.red))
+							:
+						      (((color.red - color_rec.red) << 20) +
+						      ((color.green - color_rec.green) << 10) +
+						      (color.blue - color_rec.blue));
+				word1 = (color.blue - color_rec.blue);
  			} else {
-				diff[0] = (lut[i].red >> 6) - (lut[i - 1].red >> 6);
-				diff[1] = (lut[i].green >> 6) - (lut[i - 1].green >> 6);
-				diff[2] = (lut[i].blue >> 6) - (lut[i - 1].blue >> 6);
-
-				word = ((diff[0] & LUT_10BIT_MASK) << 20) +
-					((diff[1] & LUT_10BIT_MASK) << 10) +
-					(diff[2] & LUT_10BIT_MASK);
+				word = (lut_bits == 12) ?
+						      ((color.green << 12) + color.red)
+							:
+						      ((color.red << 20) +
+						      (color.green << 10) + color.blue);
+				word1 = color.blue;
+				color_rec = color;
  			}
-			writel(word, (lut_base + i * 4));
+			idx = (lut_bits == 12) ? (i % BANK_SIZE) : i;
+			writel(word, (lut_base + idx * 4));
+			if (!(i % BANK_SIZE) && lut_bits == 12)
+				writel((i / BANK_SIZE), regs + DISP_GAMMA_BANK);
+			if (lut_bits == 12)
+				writel(word1, (lut1_base + idx * 4));
  		}
  	}
  }
+unsigned int mtk_gamma_size(struct device *dev)

unsigned int mtk_gamma_get_lut_size(struct device *dev)

that looks a bit more readable and perfectly explains this function :-)

+{
+	struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);
+
+	if (gamma->data)
+		return gamma->data->lut_size;
+	else
+		return 0;
+}
  void mtk_gamma_set(struct device *dev, struct drm_crtc_state *state)
  {
  	struct mtk_disp_gamma *gamma = dev_get_drvdata(dev);

..snip..

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 2d72cc5ddaba..4c6538a17b88 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -323,6 +323,7 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = {
  	.clk_enable = mtk_gamma_clk_enable,
  	.clk_disable = mtk_gamma_clk_disable,
  	.gamma_set = mtk_gamma_set,
+	.gamma_size = mtk_gamma_size,
  	.config = mtk_gamma_config,
  	.start = mtk_gamma_start,
  	.stop = mtk_gamma_stop,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 2d0052c23dcb..bf0cf7f86010 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -59,6 +59,7 @@ struct mtk_ddp_comp_funcs {
  	void (*disable_vblank)(struct device *dev);
  	unsigned int (*supported_rotations)(struct device *dev);
  	unsigned int (*layer_nr)(struct device *dev);
+	unsigned int (*gamma_size)(struct device *dev);

	unsigned int (*gamma_get_lut_size)(struct device *dev);

  	int (*layer_check)(struct device *dev,
  			   unsigned int idx,
  			   struct mtk_plane_state *state);

Regards,
Angelo





[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux