static void set_legacy_input_gamma_mode( struct dce110_ipp *ipp80, bool is_legacy) { const uint32_t addr = DCP_REG(mmINPUT_GAMMA_CONTROL); uint32_t value = dm_read_reg(ipp80->base.ctx, addr); set_reg_field_value( value, !is_legacy, INPUT_GAMMA_CONTROL, GRPH_INPUT_GAMMA_MODE); dm_write_reg(ipp80->base.ctx, addr, value); }
void dce110_compressor_program_compressed_surface_address_and_pitch( struct compressor *compressor, struct compr_addr_and_pitch_params *params) { struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor); uint32_t value = 0; uint32_t fbc_pitch = 0; uint32_t compressed_surf_address_low_part = compressor->compr_surface_address.addr.low_part; /* Clear content first. */ dm_write_reg( compressor->ctx, DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS_HIGH), 0); dm_write_reg(compressor->ctx, DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS), 0); /* Write address, HIGH has to be first. */ dm_write_reg(compressor->ctx, DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS_HIGH), compressor->compr_surface_address.addr.high_part); dm_write_reg(compressor->ctx, DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS), compressed_surf_address_low_part); fbc_pitch = align_to_chunks_number_per_line(params->source_view_width); if (compressor->min_compress_ratio == FBC_COMPRESS_RATIO_1TO1) fbc_pitch = fbc_pitch / 8; else DC_LOG_WARNING("%s: Unexpected DCE11 compression ratio", __func__); /* Clear content first. */ dm_write_reg(compressor->ctx, DCP_REG(mmGRPH_COMPRESS_PITCH), 0); /* Write FBC Pitch. */ set_reg_field_value( value, fbc_pitch, GRPH_COMPRESS_PITCH, GRPH_COMPRESS_PITCH); dm_write_reg(compressor->ctx, DCP_REG(mmGRPH_COMPRESS_PITCH), value); }
static bool set_dither( struct dce110_transform *xfm110, bool dither_enable, enum dcp_spatial_dither_mode dither_mode, enum dcp_spatial_dither_depth dither_depth, bool frame_random_enable, bool rgb_random_enable, bool highpass_random_enable) { uint32_t dither_depth_bits = 0; uint32_t dither_mode_bits = 0; /* zero out all bits */ uint32_t value = 0; /* set up the fields */ if (dither_enable) set_reg_field_value( value, 1, DCP_SPATIAL_DITHER_CNTL, DCP_SPATIAL_DITHER_EN); switch (dither_mode) { case DCP_SPATIAL_DITHER_MODE_AAAA: dither_mode_bits = 0; break; case DCP_SPATIAL_DITHER_MODE_A_AA_A: dither_mode_bits = 1; break; case DCP_SPATIAL_DITHER_MODE_AABBAABB: dither_mode_bits = 2; break; case DCP_SPATIAL_DITHER_MODE_AABBCCAABBCC: dither_mode_bits = 3; break; default: /* Invalid dcp_spatial_dither_mode */ ASSERT_CRITICAL(false); return false; } set_reg_field_value( value, dither_mode_bits, DCP_SPATIAL_DITHER_CNTL, DCP_SPATIAL_DITHER_MODE); switch (dither_depth) { case DCP_SPATIAL_DITHER_DEPTH_30BPP: dither_depth_bits = 0; break; case DCP_SPATIAL_DITHER_DEPTH_24BPP: dither_depth_bits = 1; break; default: /* Invalid dcp_spatial_dither_depth */ ASSERT_CRITICAL(false); return false; } set_reg_field_value( value, dither_depth_bits, DCP_SPATIAL_DITHER_CNTL, DCP_SPATIAL_DITHER_DEPTH); if (frame_random_enable) set_reg_field_value( value, 1, DCP_SPATIAL_DITHER_CNTL, DCP_FRAME_RANDOM_ENABLE); if (rgb_random_enable) set_reg_field_value( value, 1, DCP_SPATIAL_DITHER_CNTL, DCP_RGB_RANDOM_ENABLE); if (highpass_random_enable) set_reg_field_value( value, 1, DCP_SPATIAL_DITHER_CNTL, DCP_HIGHPASS_RANDOM_ENABLE); /* write the register */ dm_write_reg(xfm110->base.ctx, DCP_REG(mmDCP_SPATIAL_DITHER_CNTL), value); return true; }
/** ******************************************************************************* * set_round * * @brief * Programs Round/Truncate * * @param [in] mode :round or truncate * @param [in] depth :bit depth to round/truncate to OUT_ROUND_TRUNC_MODE 3:0 0xA Output data round or truncate mode POSSIBLE VALUES: 00 - truncate to u0.12 01 - truncate to u0.11 02 - truncate to u0.10 03 - truncate to u0.9 04 - truncate to u0.8 05 - reserved 06 - truncate to u0.14 07 - truncate to u0.13 set_reg_field_value( value, clamp_max, OUT_CLAMP_CONTROL_R_CR, OUT_CLAMP_MAX_R_CR); 08 - round to u0.12 09 - round to u0.11 10 - round to u0.10 11 - round to u0.9 12 - round to u0.8 13 - reserved 14 - round to u0.14 15 - round to u0.13 * @return * true if succeeds. ******************************************************************************* */ static bool set_round( struct dce110_transform *xfm110, enum dcp_out_trunc_round_mode mode, enum dcp_out_trunc_round_depth depth) { uint32_t depth_bits = 0; uint32_t mode_bit = 0; /* zero out all bits */ uint32_t value = 0; /* set up bit depth */ switch (depth) { case DCP_OUT_TRUNC_ROUND_DEPTH_14BIT: depth_bits = 6; break; case DCP_OUT_TRUNC_ROUND_DEPTH_13BIT: depth_bits = 7; break; case DCP_OUT_TRUNC_ROUND_DEPTH_12BIT: depth_bits = 0; break; case DCP_OUT_TRUNC_ROUND_DEPTH_11BIT: depth_bits = 1; break; case DCP_OUT_TRUNC_ROUND_DEPTH_10BIT: depth_bits = 2; break; case DCP_OUT_TRUNC_ROUND_DEPTH_9BIT: depth_bits = 3; break; case DCP_OUT_TRUNC_ROUND_DEPTH_8BIT: depth_bits = 4; break; default: /* Invalid dcp_out_trunc_round_depth */ ASSERT_CRITICAL(false); return false; } set_reg_field_value( value, depth_bits, OUT_ROUND_CONTROL, OUT_ROUND_TRUNC_MODE); /* set up round or truncate */ switch (mode) { case DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE: mode_bit = 0; break; case DCP_OUT_TRUNC_ROUND_MODE_ROUND: mode_bit = 1; break; default: /* Invalid dcp_out_trunc_round_mode */ ASSERT_CRITICAL(false); return false; } depth_bits |= mode_bit << 3; set_reg_field_value( value, depth_bits, OUT_ROUND_CONTROL, OUT_ROUND_TRUNC_MODE); /* write the register */ dm_write_reg(xfm110->base.ctx, DCP_REG(mmOUT_ROUND_CONTROL), value); return true; }
/** ******************************************************************************* * set_clamp * * @param depth : bit depth to set the clamp to (should match denorm) * * @brief * Programs clamp according to panel bit depth. * * @return * true if succeeds * ******************************************************************************* */ static bool set_clamp( struct dce110_transform *xfm110, enum dc_color_depth depth) { uint32_t clamp_max = 0; /* At the clamp block the data will be MSB aligned, so we set the max * clamp accordingly. * For example, the max value for 6 bits MSB aligned (14 bit bus) would * be "11 1111 0000 0000" in binary, so 0x3F00. */ switch (depth) { case COLOR_DEPTH_666: /* 6bit MSB aligned on 14 bit bus '11 1111 0000 0000' */ clamp_max = 0x3F00; break; case COLOR_DEPTH_888: /* 8bit MSB aligned on 14 bit bus '11 1111 1100 0000' */ clamp_max = 0x3FC0; break; case COLOR_DEPTH_101010: /* 10bit MSB aligned on 14 bit bus '11 1111 1111 1100' */ clamp_max = 0x3FFC; break; case COLOR_DEPTH_121212: /* 12bit MSB aligned on 14 bit bus '11 1111 1111 1111' */ clamp_max = 0x3FFF; break; default: ASSERT_CRITICAL(false); /* Invalid clamp bit depth */ return false; } { uint32_t value = 0; /* always set min to 0 */ set_reg_field_value( value, 0, OUT_CLAMP_CONTROL_B_CB, OUT_CLAMP_MIN_B_CB); set_reg_field_value( value, clamp_max, OUT_CLAMP_CONTROL_B_CB, OUT_CLAMP_MAX_B_CB); dm_write_reg(xfm110->base.ctx, DCP_REG(mmOUT_CLAMP_CONTROL_B_CB), value); } { uint32_t value = 0; /* always set min to 0 */ set_reg_field_value( value, 0, OUT_CLAMP_CONTROL_G_Y, OUT_CLAMP_MIN_G_Y); set_reg_field_value( value, clamp_max, OUT_CLAMP_CONTROL_G_Y, OUT_CLAMP_MAX_G_Y); dm_write_reg(xfm110->base.ctx, DCP_REG(mmOUT_CLAMP_CONTROL_G_Y), value); } { uint32_t value = 0; /* always set min to 0 */ set_reg_field_value( value, 0, OUT_CLAMP_CONTROL_R_CR, OUT_CLAMP_MIN_R_CR); set_reg_field_value( value, clamp_max, OUT_CLAMP_CONTROL_R_CR, OUT_CLAMP_MAX_R_CR); dm_write_reg(xfm110->base.ctx, DCP_REG(mmOUT_CLAMP_CONTROL_R_CR), value); } return true; }
static void program_gamut_remap( struct dce80_transform *xfm80, const uint16_t *reg_val) { struct dc_context *ctx = xfm80->base.ctx; uint32_t value = 0; uint32_t addr = DCP_REG(mmGAMUT_REMAP_CONTROL); /* the register controls ovl also */ value = dm_read_reg(ctx, addr); if (reg_val) { { uint32_t reg_data = 0; uint32_t addr = DCP_REG(mmGAMUT_REMAP_C11_C12); /* fixed S2.13 format */ set_reg_field_value( reg_data, reg_val[0], GAMUT_REMAP_C11_C12, GAMUT_REMAP_C11); /* fixed S2.13 format */ set_reg_field_value( reg_data, reg_val[1], GAMUT_REMAP_C11_C12, GAMUT_REMAP_C12); dm_write_reg(ctx, addr, reg_data); } { uint32_t reg_data = 0; uint32_t addr = DCP_REG(mmGAMUT_REMAP_C13_C14); /* fixed S2.13 format */ set_reg_field_value( reg_data, reg_val[2], GAMUT_REMAP_C13_C14, GAMUT_REMAP_C13); /* fixed S0.13 format */ set_reg_field_value( reg_data, reg_val[3], GAMUT_REMAP_C13_C14, GAMUT_REMAP_C14); dm_write_reg(ctx, addr, reg_data); } { uint32_t reg_data = 0; uint32_t addr = DCP_REG(mmGAMUT_REMAP_C21_C22); /* fixed S2.13 format */ set_reg_field_value( reg_data, reg_val[4], GAMUT_REMAP_C21_C22, GAMUT_REMAP_C21); /* fixed S0.13 format */ set_reg_field_value( reg_data, reg_val[5], GAMUT_REMAP_C21_C22, GAMUT_REMAP_C22); dm_write_reg(ctx, addr, reg_data); } { uint32_t reg_data = 0; uint32_t addr = DCP_REG(mmGAMUT_REMAP_C23_C24); /* fixed S2.13 format */ set_reg_field_value( reg_data, reg_val[6], GAMUT_REMAP_C23_C24, GAMUT_REMAP_C23); /* fixed S0.13 format */ set_reg_field_value( reg_data, reg_val[7], GAMUT_REMAP_C23_C24, GAMUT_REMAP_C24); dm_write_reg(ctx, addr, reg_data); } { uint32_t reg_data = 0; uint32_t addr = DCP_REG(mmGAMUT_REMAP_C31_C32); /* fixed S2.13 format */ set_reg_field_value( reg_data, reg_val[8], GAMUT_REMAP_C31_C32, GAMUT_REMAP_C31); /* fixed S0.13 format */ set_reg_field_value( reg_data, reg_val[9], GAMUT_REMAP_C31_C32, GAMUT_REMAP_C32); dm_write_reg(ctx, addr, reg_data); } { uint32_t reg_data = 0; uint32_t addr = DCP_REG(mmGAMUT_REMAP_C33_C34); /* fixed S2.13 format */ set_reg_field_value( reg_data, reg_val[10], GAMUT_REMAP_C33_C34, GAMUT_REMAP_C33); /* fixed S0.13 format */ set_reg_field_value( reg_data, reg_val[11], GAMUT_REMAP_C33_C34, GAMUT_REMAP_C34); dm_write_reg(ctx, addr, reg_data); } set_reg_field_value( value, 1, GAMUT_REMAP_CONTROL, GRPH_GAMUT_REMAP_MODE); } else set_reg_field_value( value, 0, GAMUT_REMAP_CONTROL, GRPH_GAMUT_REMAP_MODE); addr = DCP_REG(mmGAMUT_REMAP_CONTROL); dm_write_reg(ctx, addr, value); }
static void program_color_matrix( struct dce110_opp *opp110, const struct out_csc_color_matrix *tbl_entry, enum grph_color_adjust_option options) { struct dc_context *ctx = opp110->base.ctx; { uint32_t value = 0; uint32_t addr = DCP_REG(mmOUTPUT_CSC_C11_C12); /* fixed S2.13 format */ set_reg_field_value( value, tbl_entry->regval[0], OUTPUT_CSC_C11_C12, OUTPUT_CSC_C11); set_reg_field_value( value, tbl_entry->regval[1], OUTPUT_CSC_C11_C12, OUTPUT_CSC_C12); dm_write_reg(ctx, addr, value); } { uint32_t value = 0; uint32_t addr = DCP_REG(mmOUTPUT_CSC_C13_C14); /* fixed S2.13 format */ set_reg_field_value( value, tbl_entry->regval[2], OUTPUT_CSC_C13_C14, OUTPUT_CSC_C13); /* fixed S0.13 format */ set_reg_field_value( value, tbl_entry->regval[3], OUTPUT_CSC_C13_C14, OUTPUT_CSC_C14); dm_write_reg(ctx, addr, value); } { uint32_t value = 0; uint32_t addr = DCP_REG(mmOUTPUT_CSC_C21_C22); /* fixed S2.13 format */ set_reg_field_value( value, tbl_entry->regval[4], OUTPUT_CSC_C21_C22, OUTPUT_CSC_C21); /* fixed S2.13 format */ set_reg_field_value( value, tbl_entry->regval[5], OUTPUT_CSC_C21_C22, OUTPUT_CSC_C22); dm_write_reg(ctx, addr, value); } { uint32_t value = 0; uint32_t addr = DCP_REG(mmOUTPUT_CSC_C23_C24); /* fixed S2.13 format */ set_reg_field_value( value, tbl_entry->regval[6], OUTPUT_CSC_C23_C24, OUTPUT_CSC_C23); /* fixed S0.13 format */ set_reg_field_value( value, tbl_entry->regval[7], OUTPUT_CSC_C23_C24, OUTPUT_CSC_C24); dm_write_reg(ctx, addr, value); } { uint32_t value = 0; uint32_t addr = DCP_REG(mmOUTPUT_CSC_C31_C32); /* fixed S2.13 format */ set_reg_field_value( value, tbl_entry->regval[8], OUTPUT_CSC_C31_C32, OUTPUT_CSC_C31); /* fixed S0.13 format */ set_reg_field_value( value, tbl_entry->regval[9], OUTPUT_CSC_C31_C32, OUTPUT_CSC_C32); dm_write_reg(ctx, addr, value); } { uint32_t value = 0; uint32_t addr = DCP_REG(mmOUTPUT_CSC_C33_C34); /* fixed S2.13 format */ set_reg_field_value( value, tbl_entry->regval[10], OUTPUT_CSC_C33_C34, OUTPUT_CSC_C33); /* fixed S0.13 format */ set_reg_field_value( value, tbl_entry->regval[11], OUTPUT_CSC_C33_C34, OUTPUT_CSC_C34); dm_write_reg(ctx, addr, value); } }
static bool configure_graphics_mode( struct dce110_opp *opp110, enum csc_color_mode config, enum graphics_csc_adjust_type csc_adjust_type, enum dc_color_space color_space) { struct dc_context *ctx = opp110->base.ctx; uint32_t addr = DCP_REG(mmOUTPUT_CSC_CONTROL); uint32_t value = dm_read_reg(ctx, addr); set_reg_field_value( value, 0, OUTPUT_CSC_CONTROL, OUTPUT_CSC_GRPH_MODE); if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_SW) { if (config == CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC) { set_reg_field_value( value, 4, OUTPUT_CSC_CONTROL, OUTPUT_CSC_GRPH_MODE); } else { switch (color_space) { case COLOR_SPACE_SRGB: /* by pass */ set_reg_field_value( value, 0, OUTPUT_CSC_CONTROL, OUTPUT_CSC_GRPH_MODE); break; case COLOR_SPACE_SRGB_LIMITED: /* TV RGB */ set_reg_field_value( value, 1, OUTPUT_CSC_CONTROL, OUTPUT_CSC_GRPH_MODE); break; case COLOR_SPACE_YCBCR601: case COLOR_SPACE_YPBPR601: case COLOR_SPACE_YCBCR601_LIMITED: /* YCbCr601 */ set_reg_field_value( value, 2, OUTPUT_CSC_CONTROL, OUTPUT_CSC_GRPH_MODE); break; case COLOR_SPACE_YCBCR709: case COLOR_SPACE_YPBPR709: case COLOR_SPACE_YCBCR709_LIMITED: /* YCbCr709 */ set_reg_field_value( value, 3, OUTPUT_CSC_CONTROL, OUTPUT_CSC_GRPH_MODE); break; default: return false; } } } else if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_HW) { switch (color_space) { case COLOR_SPACE_SRGB: /* by pass */ set_reg_field_value( value, 0, OUTPUT_CSC_CONTROL, OUTPUT_CSC_GRPH_MODE); break; case COLOR_SPACE_SRGB_LIMITED: /* TV RGB */ set_reg_field_value( value, 1, OUTPUT_CSC_CONTROL, OUTPUT_CSC_GRPH_MODE); break; case COLOR_SPACE_YCBCR601: case COLOR_SPACE_YPBPR601: case COLOR_SPACE_YCBCR601_LIMITED: /* YCbCr601 */ set_reg_field_value( value, 2, OUTPUT_CSC_CONTROL, OUTPUT_CSC_GRPH_MODE); break; case COLOR_SPACE_YCBCR709: case COLOR_SPACE_YPBPR709: case COLOR_SPACE_YCBCR709_LIMITED: /* YCbCr709 */ set_reg_field_value( value, 3, OUTPUT_CSC_CONTROL, OUTPUT_CSC_GRPH_MODE); break; default: return false; } } else /* by pass */ set_reg_field_value( value, 0, OUTPUT_CSC_CONTROL, OUTPUT_CSC_GRPH_MODE); addr = DCP_REG(mmOUTPUT_CSC_CONTROL); dm_write_reg(ctx, addr, value); return true; }