summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
diff options
context:
space:
mode:
authorAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>2023-10-12 12:57:24 +0300
committerChun-Kuang Hu <chunkuang.hu@kernel.org>2023-10-16 02:57:51 +0300
commitc18119dee1919ce60565efd85f63707ceae38420 (patch)
tree5973c731f35682e90b052d1e812c1b8a92189edd /drivers/gpu/drm/mediatek/mtk_disp_gamma.c
parentd243907bb42f6652d88f9f3023d1028a34971465 (diff)
downloadlinux-c18119dee1919ce60565efd85f63707ceae38420.tar.xz
drm/mediatek: gamma: Improve and simplify HW LUT calculation
Use drm_color_lut_extract() to avoid open-coding the bits reduction calculations for each color channel and use a struct drm_color_lut to temporarily store the information instead of an array of u32. Also, slightly improve the precision of the HW LUT calculation in the LUT DIFF case by performing the subtractions on the 16-bits values and doing the 10 bits conversion later. Reviewed-by: Jason-JH.Lin <jason-jh.lin@mediatek.com> Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com> Reviewed-by: CK Hu <ck.hu@mediatek.com> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://patchwork.kernel.org/project/dri-devel/patch/20231012095736.100784-5-angelogioacchino.delregno@collabora.com/ Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Diffstat (limited to 'drivers/gpu/drm/mediatek/mtk_disp_gamma.c')
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_gamma.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
index 326dd69fbf9d..d51367330092 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
@@ -23,8 +23,6 @@
#define DISP_GAMMA_SIZE 0x0030
#define DISP_GAMMA_LUT 0x0700
-#define LUT_10BIT_MASK 0x03ff
-
struct mtk_disp_gamma_data {
bool has_dither;
bool lut_diff;
@@ -73,7 +71,6 @@ void mtk_gamma_set_common(struct device *dev, void __iomem *regs, struct drm_crt
bool lut_diff;
u16 lut_size;
u32 word;
- u32 diff[3] = {0};
/* If there's no gamma lut there's nothing to do here. */
if (!state->gamma_lut)
@@ -96,20 +93,31 @@ void mtk_gamma_set_common(struct device *dev, void __iomem *regs, struct drm_crt
lut_base = regs + DISP_GAMMA_LUT;
lut = (struct drm_color_lut *)state->gamma_lut->data;
for (i = 0; i < lut_size; i++) {
+ struct drm_color_lut diff, hwlut;
+
+ hwlut.red = drm_color_lut_extract(lut[i].red, 10);
+ hwlut.green = drm_color_lut_extract(lut[i].green, 10);
+ hwlut.blue = drm_color_lut_extract(lut[i].blue, 10);
+
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);
+ word = (hwlut.red << 20) +
+ (hwlut.green << 10) +
+ hwlut.red;
} 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);
+ diff.red = lut[i].red - lut[i - 1].red;
+ diff.red = drm_color_lut_extract(diff.red, 10);
+
+ diff.green = lut[i].green - lut[i - 1].green;
+ diff.green = drm_color_lut_extract(diff.green, 10);
+
+ diff.blue = lut[i].blue - lut[i - 1].blue;
+ diff.blue = drm_color_lut_extract(diff.blue, 10);
- word = ((diff[0] & LUT_10BIT_MASK) << 20) +
- ((diff[1] & LUT_10BIT_MASK) << 10) +
- (diff[2] & LUT_10BIT_MASK);
+ word = (diff.blue << 20) +
+ (diff.green << 10) +
+ diff.red;
}
- writel(word, (lut_base + i * 4));
+ writel(word, lut_base + i * 4);
}
}