From 3343d6569e713492ee79adfec2e4c1a67cf94126 Mon Sep 17 00:00:00 2001 From: Mark Yao Date: Thu, 3 Aug 2017 14:46:59 +0800 Subject: [PATCH] drm/rockchip: vop: support parse dsp-lut from dts Change-Id: I2d827f44457aa06250a672e421cf31347254b57c Signed-off-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 70 ++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 533da27ff30f..357c64905773 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -3002,6 +3002,63 @@ static int vop_plane_init(struct vop *vop, struct vop_win *win, return 0; } +static int vop_of_init_display_lut(struct vop *vop) +{ + struct device_node *node = vop->dev->of_node; + struct device_node *dsp_lut; + u32 lut_len = vop->lut_len; + struct property *prop; + int length, i, j; + int ret; + + if (!vop->lut) + return -ENOMEM; + + dsp_lut = of_parse_phandle(node, "dsp-lut", 0); + if (!dsp_lut) + return -ENXIO; + + prop = of_find_property(dsp_lut, "gamma-lut", &length); + if (!prop) { + dev_err(vop->dev, "failed to find gamma_lut\n"); + return -ENXIO; + } + + length >>= 2; + + if (length != lut_len) { + u32 r, g, b; + u32 *lut = kmalloc_array(length, sizeof(*lut), GFP_KERNEL); + + if (!lut) + return -ENOMEM; + ret = of_property_read_u32_array(dsp_lut, "gamma-lut", lut, + length); + if (ret) { + dev_err(vop->dev, "load gamma-lut failed\n"); + kfree(lut); + return -EINVAL; + } + + for (i = 0; i < lut_len; i++) { + j = i * length / lut_len; + r = lut[j] / length / length * lut_len / length; + g = lut[j] / length % length * lut_len / length; + b = lut[j] % length * lut_len / length; + + vop->lut[i] = r * lut_len * lut_len + g * lut_len + b; + } + + kfree(lut); + } else { + of_property_read_u32_array(dsp_lut, "gamma-lut", + vop->lut, vop->lut_len); + } + vop->lut_active = true; + + return 0; +} + static int vop_create_crtc(struct vop *vop) { struct device *dev = vop->dev; @@ -3103,18 +3160,27 @@ static int vop_create_crtc(struct vop *vop) u16 *r_base, *g_base, *b_base; u32 lut_len = vop->lut_len; - drm_mode_crtc_set_gamma_size(crtc, lut_len); vop->lut = devm_kmalloc_array(dev, lut_len, sizeof(*vop->lut), GFP_KERNEL); if (!vop->lut) goto err_unregister_crtc_funcs; + if (vop_of_init_display_lut(vop)) { + for (i = 0; i < lut_len; i++) { + u32 r = i * lut_len * lut_len; + u32 g = i * lut_len; + u32 b = i; + + vop->lut[i] = r | g | b; + } + } + + drm_mode_crtc_set_gamma_size(crtc, lut_len); r_base = crtc->gamma_store; g_base = r_base + crtc->gamma_size; b_base = g_base + crtc->gamma_size; for (i = 0; i < lut_len; i++) { - vop->lut[i] = i * lut_len * lut_len | i * lut_len | i; rockchip_vop_crtc_fb_gamma_get(crtc, &r_base[i], &g_base[i], &b_base[i], i);