diff options
| author | Benet Clark <benetc@codeaurora.org> | 2016-06-27 14:43:06 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-11-30 11:33:22 -0800 |
| commit | 199f759f35072acf46170da61fecbb422fe9cfcd (patch) | |
| tree | 0870a43e8c01c48c6f4557bda23ca6c0f24a91d8 /drivers/gpu | |
| parent | f547c0a044b2568a0be1a37822a3174cdd25bcb1 (diff) | |
drm/msm/sde: Add PA global adjustment properties to plane
Add support for hue, saturation, intensity, and contrast adjustment
in planes that have color processing support.
Change-Id: I4c794deb7a5a1c0cc30cc0d64fbffd967eb1d399
Signed-off-by: Benet Clark <benetc@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/msm/Makefile | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_drv.h | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_color_processing.h | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_color_processing_v1_7.c | 121 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_color_processing_v1_7.h | 46 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_sspp.c | 40 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_sspp.h | 29 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_plane.c | 57 |
8 files changed, 304 insertions, 14 deletions
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index bb95fad7d7b8..1bc2044d3fc7 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -107,7 +107,8 @@ msm_drm-$(CONFIG_DRM_MSM) += \ sde/sde_hw_interrupts.o \ sde/sde_hw_vbif.o \ sde/sde_formats.o \ - sde_power_handle.o + sde_power_handle.o \ + sde/sde_hw_color_processing_v1_7.o msm_drm-$(CONFIG_DRM_SDE_WB) += sde/sde_wb.o \ sde/sde_encoder_phys_wb.o diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 847a6e82fe33..095f25b48f19 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -98,6 +98,10 @@ enum msm_mdp_plane_property { PLANE_PROP_H_DECIMATE, PLANE_PROP_V_DECIMATE, PLANE_PROP_INPUT_FENCE, + PLANE_PROP_HUE_ADJUST, + PLANE_PROP_SATURATION_ADJUST, + PLANE_PROP_VALUE_ADJUST, + PLANE_PROP_CONTRAST_ADJUST, /* enum/bitmask properties */ PLANE_PROP_ROTATION, diff --git a/drivers/gpu/drm/msm/sde/sde_hw_color_processing.h b/drivers/gpu/drm/msm/sde/sde_hw_color_processing.h new file mode 100644 index 000000000000..a30e1a52b046 --- /dev/null +++ b/drivers/gpu/drm/msm/sde/sde_hw_color_processing.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SDE_HW_COLOR_PROCESSING_H +#define _SDE_HW_COLOR_PROCESSING_H + +#include "sde_hw_color_processing_v1_7.h" + +#endif diff --git a/drivers/gpu/drm/msm/sde/sde_hw_color_processing_v1_7.c b/drivers/gpu/drm/msm/sde/sde_hw_color_processing_v1_7.c new file mode 100644 index 000000000000..9f496251520e --- /dev/null +++ b/drivers/gpu/drm/msm/sde/sde_hw_color_processing_v1_7.c @@ -0,0 +1,121 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "sde_hw_color_processing_v1_7.h" + +#define PA_HUE_OFF 0x110 +#define PA_HUE_MASK 0xFFF +#define PA_SAT_OFF 0x114 +#define PA_SAT_MASK 0xFFFF +#define PA_VAL_OFF 0x118 +#define PA_VAL_MASK 0xFF +#define PA_CONT_OFF 0x11C +#define PA_CONT_MASK 0xFF + +#define VIG_OP_PA_EN BIT(4) +#define VIG_OP_PA_SKIN_EN BIT(5) +#define VIG_OP_PA_FOL_EN BIT(6) +#define VIG_OP_PA_SKY_EN BIT(7) +#define VIG_OP_PA_HUE_EN BIT(25) +#define VIG_OP_PA_SAT_EN BIT(26) +#define VIG_OP_PA_VAL_EN BIT(27) +#define VIG_OP_PA_CONT_EN BIT(28) + +#define PA_DISABLE_REQUIRED(x) !((x) & \ + (VIG_OP_PA_SKIN_EN | VIG_OP_PA_SKY_EN | \ + VIG_OP_PA_FOL_EN | VIG_OP_PA_HUE_EN | \ + VIG_OP_PA_SAT_EN | VIG_OP_PA_VAL_EN | \ + VIG_OP_PA_CONT_EN)) + +void sde_setup_pipe_pa_hue_v1_7(struct sde_hw_pipe *ctx, void *cfg) +{ + uint32_t hue = *((uint32_t *)cfg); + u32 base = ctx->cap->sblk->hsic_blk.base; + u32 opmode = 0; + + SDE_REG_WRITE(&ctx->hw, base + PA_HUE_OFF, hue & PA_HUE_MASK); + + opmode = SDE_REG_READ(&ctx->hw, base); + + if (!hue) { + opmode &= ~VIG_OP_PA_HUE_EN; + if (PA_DISABLE_REQUIRED(opmode)) + opmode &= ~VIG_OP_PA_EN; + } else { + opmode |= VIG_OP_PA_HUE_EN | VIG_OP_PA_EN; + } + + SDE_REG_WRITE(&ctx->hw, base, opmode); +} + +void sde_setup_pipe_pa_sat_v1_7(struct sde_hw_pipe *ctx, void *cfg) +{ + uint32_t sat = *((uint32_t *)cfg); + u32 base = ctx->cap->sblk->hsic_blk.base; + u32 opmode = 0; + + SDE_REG_WRITE(&ctx->hw, base + PA_SAT_OFF, sat & PA_SAT_MASK); + + opmode = SDE_REG_READ(&ctx->hw, base); + + if (!sat) { + opmode &= ~VIG_OP_PA_SAT_EN; + if (PA_DISABLE_REQUIRED(opmode)) + opmode &= ~VIG_OP_PA_EN; + } else { + opmode |= VIG_OP_PA_SAT_EN | VIG_OP_PA_EN; + } + + SDE_REG_WRITE(&ctx->hw, base, opmode); +} + +void sde_setup_pipe_pa_val_v1_7(struct sde_hw_pipe *ctx, void *cfg) +{ + uint32_t value = *((uint32_t *)cfg); + u32 base = ctx->cap->sblk->hsic_blk.base; + u32 opmode = 0; + + SDE_REG_WRITE(&ctx->hw, base + PA_VAL_OFF, value & PA_VAL_MASK); + + opmode = SDE_REG_READ(&ctx->hw, base); + + if (!value) { + opmode &= ~VIG_OP_PA_VAL_EN; + if (PA_DISABLE_REQUIRED(opmode)) + opmode &= ~VIG_OP_PA_EN; + } else { + opmode |= VIG_OP_PA_VAL_EN | VIG_OP_PA_EN; + } + + SDE_REG_WRITE(&ctx->hw, base, opmode); +} + +void sde_setup_pipe_pa_cont_v1_7(struct sde_hw_pipe *ctx, void *cfg) +{ + uint32_t contrast = *((uint32_t *)cfg); + u32 base = ctx->cap->sblk->hsic_blk.base; + u32 opmode = 0; + + SDE_REG_WRITE(&ctx->hw, base + PA_CONT_OFF, contrast & PA_CONT_MASK); + + opmode = SDE_REG_READ(&ctx->hw, base); + + if (!contrast) { + opmode &= ~VIG_OP_PA_CONT_EN; + if (PA_DISABLE_REQUIRED(opmode)) + opmode &= ~VIG_OP_PA_EN; + } else { + opmode |= VIG_OP_PA_CONT_EN | VIG_OP_PA_EN; + } + + SDE_REG_WRITE(&ctx->hw, base, opmode); +} diff --git a/drivers/gpu/drm/msm/sde/sde_hw_color_processing_v1_7.h b/drivers/gpu/drm/msm/sde/sde_hw_color_processing_v1_7.h new file mode 100644 index 000000000000..788bde0e9d80 --- /dev/null +++ b/drivers/gpu/drm/msm/sde/sde_hw_color_processing_v1_7.h @@ -0,0 +1,46 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SDE_HW_COLOR_PROCESSING_V1_7_H +#define _SDE_HW_COLOR_PROCESSING_V1_7_H + +#include "sde_hw_sspp.h" + +/** + * sde_setup_pipe_pa_hue_v1_7 - setup SSPP hue feature in v1.7 hardware + * @ctx: Pointer to pipe context + * @cfg: Pointer to hue data + */ +void sde_setup_pipe_pa_hue_v1_7(struct sde_hw_pipe *ctx, void *cfg); + +/** + * sde_setup_pipe_pa_sat_v1_7 - setup SSPP saturation feature in v1.7 hardware + * @ctx: Pointer to pipe context + * @cfg: Pointer to saturation data + */ +void sde_setup_pipe_pa_sat_v1_7(struct sde_hw_pipe *ctx, void *cfg); + +/** + * sde_setup_pipe_pa_val_v1_7 - setup SSPP value feature in v1.7 hardware + * @ctx: Pointer to pipe context + * @cfg: Pointer to value data + */ +void sde_setup_pipe_pa_val_v1_7(struct sde_hw_pipe *ctx, void *cfg); + +/** + * sde_setup_pipe_pa_cont_v1_7 - setup SSPP contrast feature in v1.7 hardware + * @ctx: Pointer to pipe context + * @cfg: Pointer to contrast data + */ +void sde_setup_pipe_pa_cont_v1_7(struct sde_hw_pipe *ctx, void *cfg); + +#endif diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c index 6020e46f9d8d..c9b9fe08a226 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c @@ -14,6 +14,7 @@ #include "sde_hw_catalog.h" #include "sde_hw_lm.h" #include "sde_hw_sspp.h" +#include "sde_hw_color_processing.h" #define SDE_FETCH_CONFIG_RESET_VALUE 0x00000087 @@ -840,31 +841,44 @@ static void sde_hw_sspp_setup_qos_ctrl(struct sde_hw_pipe *ctx, SDE_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL + idx, qos_ctrl); } -static void _setup_layer_ops(struct sde_hw_sspp_ops *ops, +static void _setup_layer_ops(struct sde_hw_pipe *c, unsigned long features) { if (test_bit(SDE_SSPP_SRC, &features)) { - ops->setup_format = sde_hw_sspp_setup_format; - ops->setup_rects = sde_hw_sspp_setup_rects; - ops->setup_sourceaddress = sde_hw_sspp_setup_sourceaddress; - ops->setup_solidfill = sde_hw_sspp_setup_solidfill; + c->ops.setup_format = sde_hw_sspp_setup_format; + c->ops.setup_rects = sde_hw_sspp_setup_rects; + c->ops.setup_sourceaddress = sde_hw_sspp_setup_sourceaddress; + c->ops.setup_solidfill = sde_hw_sspp_setup_solidfill; } if (test_bit(SDE_SSPP_QOS, &features)) { - ops->setup_danger_safe_lut = sde_hw_sspp_setup_danger_safe_lut; - ops->setup_creq_lut = sde_hw_sspp_setup_creq_lut; - ops->setup_qos_ctrl = sde_hw_sspp_setup_qos_ctrl; + c->ops.setup_danger_safe_lut = + sde_hw_sspp_setup_danger_safe_lut; + c->ops.setup_creq_lut = sde_hw_sspp_setup_creq_lut; + c->ops.setup_qos_ctrl = sde_hw_sspp_setup_qos_ctrl; } + if (test_bit(SDE_SSPP_CSC, &features) || test_bit(SDE_SSPP_CSC_10BIT, &features)) - ops->setup_csc = sde_hw_sspp_setup_csc; + c->ops.setup_csc = sde_hw_sspp_setup_csc; if (test_bit(SDE_SSPP_SCALER_QSEED2, &features)) - ops->setup_sharpening = sde_hw_sspp_setup_sharpening; + c->ops.setup_sharpening = sde_hw_sspp_setup_sharpening; if (test_bit(SDE_SSPP_SCALER_QSEED3, &features)) - ops->setup_scaler = _sde_hw_sspp_setup_scaler3; + c->ops.setup_scaler = _sde_hw_sspp_setup_scaler3; else - ops->setup_scaler = _sde_hw_sspp_setup_scaler; + c->ops.setup_scaler = _sde_hw_sspp_setup_scaler; + + if (test_bit(SDE_SSPP_HSIC, &features)) { + /* TODO: add version based assignment here as inline or macro */ + if (c->cap->sblk->hsic_blk.version == + (SDE_COLOR_PROCESS_VER(0x1, 0x7))) { + c->ops.setup_pa_hue = sde_setup_pipe_pa_hue_v1_7; + c->ops.setup_pa_sat = sde_setup_pipe_pa_sat_v1_7; + c->ops.setup_pa_val = sde_setup_pipe_pa_val_v1_7; + c->ops.setup_pa_cont = sde_setup_pipe_pa_cont_v1_7; + } + } } static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp, @@ -909,7 +923,7 @@ struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx, /* Assign ops */ ctx->idx = idx; ctx->cap = cfg; - _setup_layer_ops(&ctx->ops, ctx->cap->features); + _setup_layer_ops(ctx, ctx->cap->features); ctx->highest_bank_bit = catalog->mdp[0].highest_bank_bit; return ctx; diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.h b/drivers/gpu/drm/msm/sde/sde_hw_sspp.h index 488936e24895..85f2ae62f2a8 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.h @@ -326,6 +326,35 @@ struct sde_hw_sspp_ops { void (*setup_sharpening)(struct sde_hw_pipe *ctx, struct sde_hw_sharp_cfg *cfg); + + /** + * setup_pa_hue(): Setup source hue adjustment + * @ctx: Pointer to pipe context + * @cfg: Pointer to hue data + */ + void (*setup_pa_hue)(struct sde_hw_pipe *ctx, void *cfg); + + /** + * setup_pa_sat(): Setup source saturation adjustment + * @ctx: Pointer to pipe context + * @cfg: Pointer to saturation data + */ + void (*setup_pa_sat)(struct sde_hw_pipe *ctx, void *cfg); + + /** + * setup_pa_val(): Setup source value adjustment + * @ctx: Pointer to pipe context + * @cfg: Pointer to value data + */ + void (*setup_pa_val)(struct sde_hw_pipe *ctx, void *cfg); + + /** + * setup_pa_cont(): Setup source contrast adjustment + * @ctx: Pointer to pipe context + * @cfg: Pointer contrast data + */ + void (*setup_pa_cont)(struct sde_hw_pipe *ctx, void *cfg); + /** * setup_pa_memcolor - setup source color processing * @ctx: Pointer to pipe context diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index 2f7a26490876..84140cf216eb 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -774,6 +774,33 @@ static inline void _sde_plane_setup_csc(struct sde_plane *psde) psde->csc_ptr->csc_mv[2]); } +static void sde_color_process_plane_setup(struct drm_plane *plane) +{ + struct sde_plane *psde; + struct sde_plane_state *pstate; + uint32_t hue, saturation, value, contrast; + + psde = to_sde_plane(plane); + pstate = to_sde_plane_state(plane->state); + + hue = (uint32_t) sde_plane_get_property(pstate, PLANE_PROP_HUE_ADJUST); + if (psde->pipe_hw->ops.setup_pa_hue) + psde->pipe_hw->ops.setup_pa_hue(psde->pipe_hw, &hue); + saturation = (uint32_t) sde_plane_get_property(pstate, + PLANE_PROP_SATURATION_ADJUST); + if (psde->pipe_hw->ops.setup_pa_sat) + psde->pipe_hw->ops.setup_pa_sat(psde->pipe_hw, &saturation); + value = (uint32_t) sde_plane_get_property(pstate, + PLANE_PROP_VALUE_ADJUST); + if (psde->pipe_hw->ops.setup_pa_val) + psde->pipe_hw->ops.setup_pa_val(psde->pipe_hw, &value); + contrast = (uint32_t) sde_plane_get_property(pstate, + PLANE_PROP_CONTRAST_ADJUST); + if (psde->pipe_hw->ops.setup_pa_cont) + psde->pipe_hw->ops.setup_pa_cont(psde->pipe_hw, &contrast); +} + + static void _sde_plane_setup_scaler(struct sde_plane *psde, const struct sde_format *fmt, struct sde_plane_state *pstate) @@ -1081,6 +1108,8 @@ static int _sde_plane_mode_set(struct drm_plane *plane, psde->csc_ptr = 0; } + sde_color_process_plane_setup(plane); + /* update sharpening */ if ((pstate->dirty & SDE_PLANE_DIRTY_SHARPEN) && psde->pipe_hw->ops.setup_sharpening) { @@ -1429,6 +1458,7 @@ static void _sde_plane_install_properties(struct drm_plane *plane, struct sde_plane *psde = to_sde_plane(plane); int zpos_max = 255; int zpos_def = 0; + char feature_name[256]; if (!plane || !psde) { SDE_ERROR("invalid plane\n"); @@ -1495,6 +1525,33 @@ static void _sde_plane_install_properties(struct drm_plane *plane, "csc_v1", 0x0, 0, ~0, 0, PLANE_PROP_CSC_V1); } + if (psde->features & BIT(SDE_SSPP_HSIC)) { + snprintf(feature_name, sizeof(feature_name), "%s%d", + "SDE_SSPP_HUE_V", + psde->pipe_sblk->hsic_blk.version >> 16); + msm_property_install_range(&psde->property_info, + feature_name, 0, 0, 0xFFFFFFFF, 0, + PLANE_PROP_HUE_ADJUST); + snprintf(feature_name, sizeof(feature_name), "%s%d", + "SDE_SSPP_SATURATION_V", + psde->pipe_sblk->hsic_blk.version >> 16); + msm_property_install_range(&psde->property_info, + feature_name, 0, 0, 0xFFFFFFFF, 0, + PLANE_PROP_SATURATION_ADJUST); + snprintf(feature_name, sizeof(feature_name), "%s%d", + "SDE_SSPP_VALUE_V", + psde->pipe_sblk->hsic_blk.version >> 16); + msm_property_install_range(&psde->property_info, + feature_name, 0, 0, 0xFFFFFFFF, 0, + PLANE_PROP_VALUE_ADJUST); + snprintf(feature_name, sizeof(feature_name), "%s%d", + "SDE_SSPP_CONTRAST_V", + psde->pipe_sblk->hsic_blk.version >> 16); + msm_property_install_range(&psde->property_info, + feature_name, 0, 0, 0xFFFFFFFF, 0, + PLANE_PROP_CONTRAST_ADJUST); + } + /* standard properties */ msm_property_install_rotation(&psde->property_info, BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y), PLANE_PROP_ROTATION); |
