summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp_gamma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp_gamma.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp_gamma.c304
1 files changed, 82 insertions, 222 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp_gamma.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp_gamma.c
index 79a6a6dd72fc..c68914bf7af0 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp_gamma.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp_gamma.c
@@ -32,21 +32,39 @@
#include "dce/dce_11_0_sh_mask.h"
#include "dce110_ipp.h"
-#include "gamma_types.h"
#define DCP_REG(reg)\
- (reg + ipp110->offsets.dcp_offset)
+ (mm##reg + ipp110->offsets.dcp_offset)
+
+#define DCP_REG_SET_N(reg_name, n, ...) \
+ generic_reg_update_ex(ipp110->base.ctx, \
+ DCP_REG(reg_name), \
+ 0, n, __VA_ARGS__)
+
+#define DCP_REG_SET(reg, field1, val1) \
+ DCP_REG_SET_N(reg, 1, FD(reg##__##field1), val1)
+
+#define DCP_REG_SET_2(reg, field1, val1, field2, val2) \
+ DCP_REG_SET_N(reg, 2, \
+ FD(reg##__##field1), val1, \
+ FD(reg##__##field2), val2)
+
+#define DCP_REG_SET_3(reg, field1, val1, field2, val2, field3, val3) \
+ DCP_REG_SET_N(reg, 3, \
+ FD(reg##__##field1), val1, \
+ FD(reg##__##field2), val2, \
+ FD(reg##__##field3), val3)
+
+#define DCP_REG_UPDATE_N(reg_name, n, ...) \
+ generic_reg_update_ex(ipp110->base.ctx, \
+ DCP_REG(reg_name), \
+ dm_read_reg(ipp110->base.ctx, DCP_REG(reg_name)), \
+ n, __VA_ARGS__)
+
+#define DCP_REG_UPDATE(reg, field, val) \
+ DCP_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)
-enum {
- MAX_INPUT_LUT_ENTRY = 256
-};
-/*PROTOTYPE DECLARATIONS*/
-static void set_lut_inc(
- struct dce110_ipp *ipp110,
- uint8_t inc,
- bool is_float,
- bool is_signed);
bool dce110_ipp_set_degamma(
struct input_pixel_processor *ipp,
@@ -61,25 +79,11 @@ bool dce110_ipp_set_degamma(
ASSERT(mode == IPP_DEGAMMA_MODE_BYPASS ||
mode == IPP_DEGAMMA_MODE_HW_sRGB);
- set_reg_field_value(
- value,
- degamma_type,
- DEGAMMA_CONTROL,
- GRPH_DEGAMMA_MODE);
-
- set_reg_field_value(
- value,
- degamma_type,
- DEGAMMA_CONTROL,
- CURSOR_DEGAMMA_MODE);
-
- set_reg_field_value(
- value,
- degamma_type,
+ DCP_REG_SET_3(
DEGAMMA_CONTROL,
- CURSOR2_DEGAMMA_MODE);
-
- dm_write_reg(ipp110->base.ctx, DCP_REG(mmDEGAMMA_CONTROL), value);
+ GRPH_DEGAMMA_MODE, degamma_type,
+ CURSOR_DEGAMMA_MODE, degamma_type,
+ CURSOR2_DEGAMMA_MODE, degamma_type);
return true;
}
@@ -90,214 +94,70 @@ void dce110_ipp_program_prescale(
{
struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
- uint32_t prescale_control = 0;
- uint32_t prescale_value = 0;
- uint32_t legacy_lut_control = 0;
+ /* set to bypass mode first before change */
+ DCP_REG_UPDATE(PRESCALE_GRPH_CONTROL,
+ GRPH_PRESCALE_BYPASS, 1);
- prescale_control = dm_read_reg(ipp110->base.ctx,
- DCP_REG(mmPRESCALE_GRPH_CONTROL));
+ DCP_REG_SET_2(PRESCALE_VALUES_GRPH_R,
+ GRPH_PRESCALE_SCALE_R, params->scale,
+ GRPH_PRESCALE_BIAS_R, params->bias);
- if (params->mode != IPP_PRESCALE_MODE_BYPASS) {
+ DCP_REG_SET_2(PRESCALE_VALUES_GRPH_G,
+ GRPH_PRESCALE_SCALE_G, params->scale,
+ GRPH_PRESCALE_BIAS_G, params->bias);
- set_reg_field_value(
- prescale_control,
- 0,
- PRESCALE_GRPH_CONTROL,
- GRPH_PRESCALE_BYPASS);
-
- /*
- * If prescale is in use, then legacy lut should
- * be bypassed
- */
- legacy_lut_control = dm_read_reg(ipp110->base.ctx,
- DCP_REG(mmINPUT_GAMMA_CONTROL));
-
- set_reg_field_value(
- legacy_lut_control,
- 1,
- INPUT_GAMMA_CONTROL,
- GRPH_INPUT_GAMMA_MODE);
-
- dm_write_reg(ipp110->base.ctx,
- DCP_REG(mmINPUT_GAMMA_CONTROL),
- legacy_lut_control);
- } else {
- set_reg_field_value(
- prescale_control,
- 1,
- PRESCALE_GRPH_CONTROL,
- GRPH_PRESCALE_BYPASS);
- }
+ DCP_REG_SET_2(PRESCALE_VALUES_GRPH_B,
+ GRPH_PRESCALE_SCALE_B, params->scale,
+ GRPH_PRESCALE_BIAS_B, params->bias);
- set_reg_field_value(
- prescale_value,
- params->scale,
- PRESCALE_VALUES_GRPH_R,
- GRPH_PRESCALE_SCALE_R);
-
- set_reg_field_value(
- prescale_value,
- params->bias,
- PRESCALE_VALUES_GRPH_R,
- GRPH_PRESCALE_BIAS_R);
-
- dm_write_reg(ipp110->base.ctx,
- DCP_REG(mmPRESCALE_GRPH_CONTROL),
- prescale_control);
-
- dm_write_reg(ipp110->base.ctx,
- DCP_REG(mmPRESCALE_VALUES_GRPH_R),
- prescale_value);
-
- dm_write_reg(ipp110->base.ctx,
- DCP_REG(mmPRESCALE_VALUES_GRPH_G),
- prescale_value);
-
- dm_write_reg(ipp110->base.ctx,
- DCP_REG(mmPRESCALE_VALUES_GRPH_B),
- prescale_value);
-}
-
-static void set_lut_inc(
- struct dce110_ipp *ipp110,
- uint8_t inc,
- bool is_float,
- bool is_signed)
-{
- const uint32_t addr = DCP_REG(mmDC_LUT_CONTROL);
-
- uint32_t value = dm_read_reg(ipp110->base.ctx, addr);
-
- set_reg_field_value(
- value,
- inc,
- DC_LUT_CONTROL,
- DC_LUT_INC_R);
-
- set_reg_field_value(
- value,
- inc,
- DC_LUT_CONTROL,
- DC_LUT_INC_G);
-
- set_reg_field_value(
- value,
- inc,
- DC_LUT_CONTROL,
- DC_LUT_INC_B);
-
- set_reg_field_value(
- value,
- is_float,
- DC_LUT_CONTROL,
- DC_LUT_DATA_R_FLOAT_POINT_EN);
-
- set_reg_field_value(
- value,
- is_float,
- DC_LUT_CONTROL,
- DC_LUT_DATA_G_FLOAT_POINT_EN);
-
- set_reg_field_value(
- value,
- is_float,
- DC_LUT_CONTROL,
- DC_LUT_DATA_B_FLOAT_POINT_EN);
-
- set_reg_field_value(
- value,
- is_signed,
- DC_LUT_CONTROL,
- DC_LUT_DATA_R_SIGNED_EN);
-
- set_reg_field_value(
- value,
- is_signed,
- DC_LUT_CONTROL,
- DC_LUT_DATA_G_SIGNED_EN);
-
- set_reg_field_value(
- value,
- is_signed,
- DC_LUT_CONTROL,
- DC_LUT_DATA_B_SIGNED_EN);
-
- dm_write_reg(ipp110->base.ctx, addr, value);
+ if (params->mode != IPP_PRESCALE_MODE_BYPASS) {
+ /* If prescale is in use, then legacy lut should be bypassed */
+ DCP_REG_UPDATE(PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_BYPASS, 0);
+ DCP_REG_UPDATE(INPUT_GAMMA_CONTROL, GRPH_INPUT_GAMMA_MODE, 1);
+ }
}
-void dce110_helper_select_lut(struct dce110_ipp *ipp110)
+static void dce110_helper_select_lut(struct dce110_ipp *ipp110)
{
- uint32_t value = 0;
-
- set_lut_inc(ipp110, 0, false, false);
-
- {
- const uint32_t addr = DCP_REG(mmDC_LUT_WRITE_EN_MASK);
-
- value = dm_read_reg(ipp110->base.ctx, addr);
-
- /* enable all */
- set_reg_field_value(
- value,
- 0x7,
- DC_LUT_WRITE_EN_MASK,
- DC_LUT_WRITE_EN_MASK);
-
- dm_write_reg(ipp110->base.ctx, addr, value);
- }
-
- {
- const uint32_t addr = DCP_REG(mmDC_LUT_RW_MODE);
-
- value = dm_read_reg(ipp110->base.ctx, addr);
+ /* enable all */
+ DCP_REG_SET(DC_LUT_WRITE_EN_MASK, DC_LUT_WRITE_EN_MASK, 0x7);
- set_reg_field_value(
- value,
- 0,
- DC_LUT_RW_MODE,
- DC_LUT_RW_MODE);
+ /* 256 entry mode */
+ DCP_REG_UPDATE(DC_LUT_RW_MODE, DC_LUT_RW_MODE, 0);
- dm_write_reg(ipp110->base.ctx, addr, value);
- }
-
- {
- const uint32_t addr = DCP_REG(mmDC_LUT_CONTROL);
+ /* LUT-256, unsigned, integer, new u0.12 format */
+ DCP_REG_SET_3(DC_LUT_CONTROL,
+ DC_LUT_DATA_R_FORMAT, 3,
+ DC_LUT_DATA_G_FORMAT, 3,
+ DC_LUT_DATA_B_FORMAT, 3);
- value = dm_read_reg(ipp110->base.ctx, addr);
+ /* start from index 0 */
+ DCP_REG_SET(DC_LUT_RW_INDEX, DC_LUT_RW_INDEX, 0);
+}
- /* 00 - new u0.12 */
- set_reg_field_value(
- value,
- 3,
- DC_LUT_CONTROL,
- DC_LUT_DATA_R_FORMAT);
+void dce110_ipp_program_input_lut(
+ struct input_pixel_processor *ipp,
+ const struct dc_gamma *gamma)
+{
+ int i;
+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
- set_reg_field_value(
- value,
- 3,
- DC_LUT_CONTROL,
- DC_LUT_DATA_G_FORMAT);
+ dce110_helper_select_lut(ipp110);
- set_reg_field_value(
- value,
- 3,
- DC_LUT_CONTROL,
- DC_LUT_DATA_B_FORMAT);
+ /* power on LUT memory and give it time to settle */
+ DCP_REG_SET(DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, 1);
+ udelay(10);
- dm_write_reg(ipp110->base.ctx, addr, value);
+ for (i = 0; i < INPUT_LUT_ENTRIES; i++) {
+ DCP_REG_SET(DC_LUT_SEQ_COLOR, DC_LUT_SEQ_COLOR, gamma->red[i]);
+ DCP_REG_SET(DC_LUT_SEQ_COLOR, DC_LUT_SEQ_COLOR, gamma->green[i]);
+ DCP_REG_SET(DC_LUT_SEQ_COLOR, DC_LUT_SEQ_COLOR, gamma->blue[i]);
}
- {
- const uint32_t addr = DCP_REG(mmDC_LUT_RW_INDEX);
-
- value = dm_read_reg(ipp110->base.ctx, addr);
+ /* power off LUT memory */
+ DCP_REG_SET(DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, 0);
- set_reg_field_value(
- value,
- 0,
- DC_LUT_RW_INDEX,
- DC_LUT_RW_INDEX);
-
- dm_write_reg(ipp110->base.ctx, addr, value);
- }
+ /* bypass prescale, enable legacy LUT */
+ DCP_REG_UPDATE(PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_BYPASS, 1);
+ DCP_REG_UPDATE(INPUT_GAMMA_CONTROL, GRPH_INPUT_GAMMA_MODE, 0);
}