#include "core_types.h"
#include "core_status.h"
#include "resource.h"
-#include "hw_sequencer.h"
#include "dcn10_hw_sequencer.h"
#include "dce110/dce110_hw_sequencer.h"
+#include "dce/dce_hwseq.h"
#include "abm.h"
#include "dcn10/dcn10_transform.h"
if (surface->public.in_transfer_func)
tf = DC_TRANSFER_FUNC_TO_CORE(surface->public.in_transfer_func);
+ if (surface->public.gamma_correction && dce_use_lut(surface))
+ ipp->funcs->ipp_program_input_lut(ipp,
+ surface->public.gamma_correction);
+
if (tf == NULL)
ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
else if (tf->public.type == TF_TYPE_PREDEFINED) {
uint32_t status_reg = 0;
struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
- status_reg = (REG_READ(CM_IGAM_LUT_RW_CONTROL) & 0x0F00) >>16;
+ REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS,
+ &status_reg);
+
if (status_reg == 9) {
*ram_a_inuse = true;
ret = true;
return ret;
}
+static bool dcn10_ingamma_ram_inuse(struct input_pixel_processor *ipp,
+ bool *ram_a_inuse)
+{
+ bool in_use = false;
+ uint32_t status_reg = 0;
+ struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
+
+ REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS,
+ &status_reg);
+
+ // 1 => IGAM_RAMA, 3 => IGAM_RAMA & DGAM_ROMA, 4 => IGAM_RAMA & DGAM_ROMB
+ if (status_reg == 1 || status_reg == 3 || status_reg == 4) {
+ *ram_a_inuse = true;
+ in_use = true;
+ // 2 => IGAM_RAMB, 5 => IGAM_RAMB & DGAM_ROMA, 6 => IGAM_RAMB & DGAM_ROMB
+ } else if (status_reg == 2 || status_reg == 5 || status_reg == 6) {
+ *ram_a_inuse = false;
+ in_use = true;
+ }
+ return in_use;
+}
+
static void dcn10_degamma_ram_select(struct input_pixel_processor *ipp,
bool use_ram_a)
{
dcn10_degamma_ram_select(ipp, !is_ram_a);
}
+/*
+ * Input gamma LUT currently supports 256 values only. This means input color
+ * can have a maximum of 8 bits per channel (= 256 possible values) in order to
+ * have a one-to-one mapping with the LUT. Truncation will occur with color
+ * values greater than 8 bits.
+ *
+ * In the future, this function should support additional input gamma methods,
+ * such as piecewise linear mapping, and input gamma bypass.
+ */
+void dcn10_ipp_program_input_lut(
+ struct input_pixel_processor *ipp,
+ const struct dc_gamma *gamma)
+{
+ int i;
+ struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
+ bool rama_occupied = false;
+ uint32_t ram_num;
+ // Power on LUT memory.
+ REG_SET(CM_MEM_PWR_CTRL, 0, SHARED_MEM_PWR_DIS, 1);
+ dcn10_ipp_enable_cm_block(ipp);
+ // Determine whether to use RAM A or RAM B
+ dcn10_ingamma_ram_inuse(ipp, &rama_occupied);
+ if (!rama_occupied)
+ REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_SEL, 0);
+ else
+ REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_SEL, 1);
+ // RW mode is 256-entry LUT
+ REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_RW_MODE, 0);
+ // IGAM Input format should be 8 bits per channel.
+ REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_INPUT_FORMAT, 0);
+ // Do not mask any R,G,B values
+ REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_WRITE_EN_MASK, 7);
+ // LUT-256, unsigned, integer, new u0.12 format
+ REG_UPDATE_3(
+ CM_IGAM_CONTROL,
+ CM_IGAM_LUT_FORMAT_R, 3,
+ CM_IGAM_LUT_FORMAT_G, 3,
+ CM_IGAM_LUT_FORMAT_B, 3);
+ // Start at index 0 of IGAM LUT
+ REG_UPDATE(CM_IGAM_LUT_RW_INDEX, CM_IGAM_LUT_RW_INDEX, 0);
+ for (i = 0; i < INPUT_LUT_ENTRIES; i++) {
+ REG_SET(CM_IGAM_LUT_SEQ_COLOR, 0, CM_IGAM_LUT_SEQ_COLOR,
+ gamma->red[i]);
+ REG_SET(CM_IGAM_LUT_SEQ_COLOR, 0, CM_IGAM_LUT_SEQ_COLOR,
+ gamma->green[i]);
+ REG_SET(CM_IGAM_LUT_SEQ_COLOR, 0, CM_IGAM_LUT_SEQ_COLOR,
+ gamma->blue[i]);
+ }
+ // Power off LUT memory
+ REG_SET(CM_MEM_PWR_CTRL, 0, SHARED_MEM_PWR_DIS, 0);
+ // Enable IGAM LUT on ram we just wrote to. 2 => RAMA, 3 => RAMB
+ REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_LUT_MODE, rama_occupied ? 3 : 2);
+ REG_GET(CM_IGAM_CONTROL, CM_IGAM_LUT_MODE, &ram_num);
+}
+
/*****************************************/
/* Constructor, Destructor */
/*****************************************/
.ipp_cursor_set_attributes = dcn10_cursor_set_attributes,
.ipp_cursor_set_position = dcn10_cursor_set_position,
.ipp_set_degamma = dcn10_ipp_set_degamma,
+ .ipp_program_input_lut = dcn10_ipp_program_input_lut,
.ipp_full_bypass = dcn10_ipp_full_bypass,
.ipp_setup = dcn10_ipp_cnv_setup,
.ipp_program_degamma_pwl = dcn10_ipp_set_degamma_pwl,
SRI(CM_DGAM_RAMA_REGION_14_15, CM, id), \
SRI(CM_MEM_PWR_CTRL, CM, id), \
SRI(CM_IGAM_LUT_RW_CONTROL, CM, id), \
+ SRI(CM_IGAM_LUT_RW_INDEX, CM, id), \
+ SRI(CM_IGAM_LUT_SEQ_COLOR, CM, id), \
SRI(CM_DGAM_LUT_WRITE_EN_MASK, CM, id), \
SRI(CM_DGAM_LUT_INDEX, CM, id), \
SRI(CM_DGAM_LUT_DATA, CM, id), \
IPP_SF(CM0_CM_DGAM_RAMA_REGION_14_15, CM_DGAM_RAMA_EXP_REGION15_LUT_OFFSET, mask_sh), \
IPP_SF(CM0_CM_DGAM_RAMA_REGION_14_15, CM_DGAM_RAMA_EXP_REGION15_NUM_SEGMENTS, mask_sh), \
IPP_SF(CM0_CM_MEM_PWR_CTRL, SHARED_MEM_PWR_DIS, mask_sh), \
+ IPP_SF(CM0_CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS, mask_sh), \
IPP_SF(CM0_CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_HOST_EN, mask_sh), \
+ IPP_SF(CM0_CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_RW_MODE, mask_sh), \
+ IPP_SF(CM0_CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_SEL, mask_sh), \
+ IPP_SF(CM0_CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_WRITE_EN_MASK, mask_sh), \
+ IPP_SF(CM0_CM_IGAM_LUT_RW_INDEX, CM_IGAM_LUT_RW_INDEX, mask_sh), \
+ IPP_SF(CM0_CM_IGAM_LUT_SEQ_COLOR, CM_IGAM_LUT_SEQ_COLOR, mask_sh), \
IPP_SF(CM0_CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_EN_MASK, mask_sh), \
IPP_SF(CM0_CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_SEL, mask_sh), \
IPP_SF(CM0_CM_DGAM_LUT_INDEX, CM_DGAM_LUT_INDEX, mask_sh), \
IPP_SF(CNVC_CFG0_FORMAT_CONTROL, FORMAT_EXPANSION_MODE, mask_sh), \
IPP_SF(CM0_CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, mask_sh), \
IPP_SF(CM0_CM_IGAM_CONTROL, CM_IGAM_LUT_MODE, mask_sh), \
+ IPP_SF(CM0_CM_IGAM_CONTROL, CM_IGAM_LUT_FORMAT_R, mask_sh), \
+ IPP_SF(CM0_CM_IGAM_CONTROL, CM_IGAM_LUT_FORMAT_G, mask_sh), \
+ IPP_SF(CM0_CM_IGAM_CONTROL, CM_IGAM_LUT_FORMAT_B, mask_sh), \
IPP_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_DST_Y_OFFSET, mask_sh), \
IPP_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_CHUNK_HDL_ADJUST, mask_sh), \
IPP_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \
type CM_DGAM_RAMA_EXP_REGION15_LUT_OFFSET; \
type CM_DGAM_RAMA_EXP_REGION15_NUM_SEGMENTS; \
type SHARED_MEM_PWR_DIS; \
+ type CM_IGAM_LUT_FORMAT_R; \
+ type CM_IGAM_LUT_FORMAT_G; \
+ type CM_IGAM_LUT_FORMAT_B; \
type CM_IGAM_LUT_HOST_EN; \
+ type CM_IGAM_LUT_RW_INDEX; \
+ type CM_IGAM_LUT_RW_MODE; \
+ type CM_IGAM_LUT_WRITE_EN_MASK; \
+ type CM_IGAM_LUT_SEL; \
+ type CM_IGAM_LUT_SEQ_COLOR; \
+ type CM_IGAM_DGAM_CONFIG_STATUS; \
type CM_DGAM_LUT_WRITE_EN_MASK; \
type CM_DGAM_LUT_WRITE_SEL; \
type CM_DGAM_LUT_INDEX; \
uint32_t CM_DGAM_RAMA_REGION_14_15;
uint32_t CM_MEM_PWR_CTRL;
uint32_t CM_IGAM_LUT_RW_CONTROL;
+ uint32_t CM_IGAM_LUT_RW_INDEX;
+ uint32_t CM_IGAM_LUT_SEQ_COLOR;
uint32_t CM_DGAM_LUT_WRITE_EN_MASK;
uint32_t CM_DGAM_LUT_INDEX;
uint32_t CM_DGAM_LUT_DATA;