drm/amd/display: OPP refactor and consolidation for DCE.
Signed-off-by: Zeyu Fan <Zeyu.Fan@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> Acked-by: Harry Wentland <Harry.Wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
e63d86dc9b
commit
ab3ee7a556
@ -7,7 +7,7 @@
|
||||
|
||||
DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o \
|
||||
dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \
|
||||
dce_clocks.o
|
||||
dce_clocks.o dce_opp.o
|
||||
|
||||
|
||||
AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE))
|
||||
|
996
drivers/gpu/drm/amd/display/dc/dce/dce_opp.c
Normal file
996
drivers/gpu/drm/amd/display/dc/dce/dce_opp.c
Normal file
@ -0,0 +1,996 @@
|
||||
/*
|
||||
* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "basics/conversion.h"
|
||||
|
||||
#include "dce_opp.h"
|
||||
|
||||
#include "gamma_types.h"
|
||||
|
||||
#include "reg_helper.h"
|
||||
|
||||
#define REG(reg)\
|
||||
(opp110->regs->reg)
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
opp110->opp_shift->field_name, opp110->opp_mask->field_name
|
||||
|
||||
#define CTX \
|
||||
opp110->base.ctx
|
||||
|
||||
enum {
|
||||
MAX_PWL_ENTRY = 128,
|
||||
MAX_REGIONS_NUMBER = 16
|
||||
};
|
||||
|
||||
enum {
|
||||
MAX_LUT_ENTRY = 256,
|
||||
MAX_NUMBER_OF_ENTRIES = 256
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
OUTPUT_CSC_MATRIX_SIZE = 12
|
||||
};
|
||||
|
||||
static const struct out_csc_color_matrix global_color_matrix[] = {
|
||||
{ COLOR_SPACE_SRGB,
|
||||
{ 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
|
||||
{ COLOR_SPACE_SRGB_LIMITED,
|
||||
{ 0x1B60, 0, 0, 0x200, 0, 0x1B60, 0, 0x200, 0, 0, 0x1B60, 0x200} },
|
||||
{ COLOR_SPACE_YCBCR601,
|
||||
{ 0xE00, 0xF447, 0xFDB9, 0x1000, 0x82F, 0x1012, 0x31F, 0x200, 0xFB47,
|
||||
0xF6B9, 0xE00, 0x1000} },
|
||||
{ COLOR_SPACE_YCBCR709, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x5D2, 0x1394, 0x1FA,
|
||||
0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
|
||||
/* TODO: correct values below */
|
||||
{ COLOR_SPACE_YCBCR601_LIMITED, { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
|
||||
0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
|
||||
{ COLOR_SPACE_YCBCR709_LIMITED, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
|
||||
0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }
|
||||
};
|
||||
|
||||
enum csc_color_mode {
|
||||
/* 00 - BITS2:0 Bypass */
|
||||
CSC_COLOR_MODE_GRAPHICS_BYPASS,
|
||||
/* 01 - hard coded coefficient TV RGB */
|
||||
CSC_COLOR_MODE_GRAPHICS_PREDEFINED,
|
||||
/* 04 - programmable OUTPUT CSC coefficient */
|
||||
CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function: regamma_config_regions_and_segments
|
||||
*
|
||||
* build regamma curve by using predefined hw points
|
||||
* uses interface parameters ,like EDID coeff.
|
||||
*
|
||||
* @param : parameters interface parameters
|
||||
* @return void
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* @see
|
||||
*
|
||||
*****************************************************************************
|
||||
*/
|
||||
static void regamma_config_regions_and_segments(
|
||||
struct dce110_opp *opp110,
|
||||
const struct pwl_params *params)
|
||||
{
|
||||
const struct gamma_curve *curve;
|
||||
uint32_t value = 0;
|
||||
|
||||
{
|
||||
REG_SET_2(REGAMMA_CNTLA_START_CNTL, 0,
|
||||
REGAMMA_CNTLA_EXP_REGION_START, params->arr_points[0].custom_float_x,
|
||||
REGAMMA_CNTLA_EXP_REGION_START_SEGMENT, 0);
|
||||
}
|
||||
{
|
||||
REG_SET(REGAMMA_CNTLA_SLOPE_CNTL, 0,
|
||||
REGAMMA_CNTLA_EXP_REGION_LINEAR_SLOPE, params->arr_points[0].custom_float_slope);
|
||||
|
||||
}
|
||||
{
|
||||
REG_SET(REGAMMA_CNTLA_END_CNTL1, 0,
|
||||
REGAMMA_CNTLA_EXP_REGION_END, params->arr_points[1].custom_float_x);
|
||||
}
|
||||
{
|
||||
REG_SET_2(REGAMMA_CNTLA_END_CNTL2, 0,
|
||||
REGAMMA_CNTLA_EXP_REGION_END_BASE, params->arr_points[2].custom_float_slope,
|
||||
REGAMMA_CNTLA_EXP_REGION_END_SLOPE, params->arr_points[1].custom_float_y);
|
||||
}
|
||||
|
||||
curve = params->arr_curve_points;
|
||||
|
||||
{
|
||||
REG_SET_4(REGAMMA_CNTLA_REGION_0_1, 0,
|
||||
REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
|
||||
{
|
||||
REG_SET_4(REGAMMA_CNTLA_REGION_2_3, 0,
|
||||
REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
|
||||
{
|
||||
REG_SET_4(REGAMMA_CNTLA_REGION_4_5, 0,
|
||||
REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
|
||||
{
|
||||
REG_SET_4(REGAMMA_CNTLA_REGION_6_7, 0,
|
||||
REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
|
||||
{
|
||||
REG_SET_4(REGAMMA_CNTLA_REGION_8_9, 0,
|
||||
REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
|
||||
{
|
||||
REG_SET_4(REGAMMA_CNTLA_REGION_10_11, 0,
|
||||
REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
|
||||
{
|
||||
REG_SET_4(REGAMMA_CNTLA_REGION_12_13, 0,
|
||||
REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
|
||||
{
|
||||
REG_SET_4(REGAMMA_CNTLA_REGION_14_15, 0,
|
||||
REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
|
||||
REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
|
||||
REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
|
||||
}
|
||||
}
|
||||
|
||||
static void program_pwl(
|
||||
struct dce110_opp *opp110,
|
||||
const struct pwl_params *params)
|
||||
{
|
||||
uint32_t value;
|
||||
int retval;
|
||||
|
||||
{
|
||||
uint8_t max_tries = 10;
|
||||
uint8_t counter = 0;
|
||||
|
||||
/* Power on LUT memory */
|
||||
if (REG(DCFE_MEM_PWR_CTRL))
|
||||
REG_UPDATE(DCFE_MEM_PWR_CTRL,
|
||||
DCP_REGAMMA_MEM_PWR_DIS, 1);
|
||||
else
|
||||
REG_UPDATE(DCFE_MEM_LIGHT_SLEEP_CNTL,
|
||||
REGAMMA_LUT_LIGHT_SLEEP_DIS, 1);
|
||||
|
||||
while (counter < max_tries) {
|
||||
if (REG(DCFE_MEM_PWR_STATUS)) {
|
||||
value = REG_READ(DCFE_MEM_PWR_STATUS);
|
||||
REG_GET(DCFE_MEM_PWR_STATUS,
|
||||
DCP_REGAMMA_MEM_PWR_STATE,
|
||||
&retval);
|
||||
|
||||
if (retval == 0)
|
||||
break;
|
||||
++counter;
|
||||
} else {
|
||||
value = REG_READ(DCFE_MEM_LIGHT_SLEEP_CNTL);
|
||||
REG_GET(DCFE_MEM_LIGHT_SLEEP_CNTL,
|
||||
REGAMMA_LUT_MEM_PWR_STATE,
|
||||
&retval);
|
||||
|
||||
if (retval == 0)
|
||||
break;
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
|
||||
if (counter == max_tries) {
|
||||
dm_logger_write(opp110->base.ctx->logger, LOG_WARNING,
|
||||
"%s: regamma lut was not powered on "
|
||||
"in a timely manner,"
|
||||
" programming still proceeds\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
|
||||
REG_UPDATE(REGAMMA_LUT_WRITE_EN_MASK,
|
||||
REGAMMA_LUT_WRITE_EN_MASK, 7);
|
||||
|
||||
REG_WRITE(REGAMMA_LUT_INDEX, 0);
|
||||
|
||||
/* Program REGAMMA_LUT_DATA */
|
||||
{
|
||||
uint32_t i = 0;
|
||||
const struct pwl_result_data *rgb = params->rgb_resulted;
|
||||
|
||||
while (i != params->hw_points_num) {
|
||||
|
||||
REG_WRITE(REGAMMA_LUT_DATA, rgb->red_reg);
|
||||
REG_WRITE(REGAMMA_LUT_DATA, rgb->green_reg);
|
||||
REG_WRITE(REGAMMA_LUT_DATA, rgb->blue_reg);
|
||||
REG_WRITE(REGAMMA_LUT_DATA, rgb->delta_red_reg);
|
||||
REG_WRITE(REGAMMA_LUT_DATA, rgb->delta_green_reg);
|
||||
REG_WRITE(REGAMMA_LUT_DATA, rgb->delta_blue_reg);
|
||||
|
||||
++rgb;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
/* we are done with DCP LUT memory; re-enable low power mode */
|
||||
if (REG(DCFE_MEM_PWR_CTRL))
|
||||
REG_UPDATE(DCFE_MEM_PWR_CTRL,
|
||||
DCP_REGAMMA_MEM_PWR_DIS, 0);
|
||||
else
|
||||
REG_UPDATE(DCFE_MEM_LIGHT_SLEEP_CNTL,
|
||||
REGAMMA_LUT_LIGHT_SLEEP_DIS, 0);
|
||||
}
|
||||
|
||||
bool dce110_opp_program_regamma_pwl(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct pwl_params *params)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
|
||||
/* Setup regions */
|
||||
regamma_config_regions_and_segments(opp110, params);
|
||||
|
||||
/* Program PWL */
|
||||
program_pwl(opp110, params);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dce110_opp_power_on_regamma_lut(
|
||||
struct output_pixel_processor *opp,
|
||||
bool power_on)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
|
||||
if (REG(DCFE_MEM_PWR_CTRL))
|
||||
REG_UPDATE_2(DCFE_MEM_PWR_CTRL,
|
||||
DCP_REGAMMA_MEM_PWR_DIS, power_on,
|
||||
DCP_LUT_MEM_PWR_DIS, power_on);
|
||||
else
|
||||
REG_UPDATE_2(DCFE_MEM_LIGHT_SLEEP_CNTL,
|
||||
REGAMMA_LUT_LIGHT_SLEEP_DIS, power_on,
|
||||
DCP_LUT_LIGHT_SLEEP_DIS, power_on);
|
||||
|
||||
}
|
||||
|
||||
void dce110_opp_set_regamma_mode(struct output_pixel_processor *opp,
|
||||
enum opp_regamma mode)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
|
||||
REG_SET(REGAMMA_CONTROL, 0,
|
||||
GRPH_REGAMMA_MODE, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* set_truncation
|
||||
* 1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp
|
||||
* 2) enable truncation
|
||||
* 3) HW remove 12bit FMT support for DCE11 power saving reason.
|
||||
*/
|
||||
static void set_truncation(
|
||||
struct dce110_opp *opp110,
|
||||
const struct bit_depth_reduction_params *params)
|
||||
{
|
||||
/*Disable truncation*/
|
||||
REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TRUNCATE_EN, 0,
|
||||
FMT_TRUNCATE_DEPTH, 0,
|
||||
FMT_TRUNCATE_MODE, 0);
|
||||
/* no 10bpc trunc on DCE11*/
|
||||
if (params->flags.TRUNCATE_ENABLED == 0 ||
|
||||
params->flags.TRUNCATE_DEPTH == 2)
|
||||
return;
|
||||
|
||||
/*Set truncation depth and Enable truncation*/
|
||||
REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TRUNCATE_EN, 1,
|
||||
FMT_TRUNCATE_DEPTH, params->flags.TRUNCATE_MODE,
|
||||
FMT_TRUNCATE_MODE, params->flags.TRUNCATE_DEPTH);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* set_spatial_dither
|
||||
* 1) set spatial dithering mode: pattern of seed
|
||||
* 2) set spatical dithering depth: 0 for 18bpp or 1 for 24bpp
|
||||
* 3) set random seed
|
||||
* 4) set random mode
|
||||
* lfsr is reset every frame or not reset
|
||||
* RGB dithering method
|
||||
* 0: RGB data are all dithered with x^28+x^3+1
|
||||
* 1: R data is dithered with x^28+x^3+1
|
||||
* G data is dithered with x^28+X^9+1
|
||||
* B data is dithered with x^28+x^13+1
|
||||
* enable high pass filter or not
|
||||
* 5) enable spatical dithering
|
||||
*/
|
||||
static void set_spatial_dither(
|
||||
struct dce110_opp *opp110,
|
||||
const struct bit_depth_reduction_params *params)
|
||||
{
|
||||
/*Disable spatial (random) dithering*/
|
||||
REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_SPATIAL_DITHER_EN, 0,
|
||||
FMT_SPATIAL_DITHER_DEPTH, 0,
|
||||
FMT_SPATIAL_DITHER_MODE, 0);
|
||||
|
||||
REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_HIGHPASS_RANDOM_ENABLE, 0,
|
||||
FMT_FRAME_RANDOM_ENABLE, 0,
|
||||
FMT_RGB_RANDOM_ENABLE, 0);
|
||||
|
||||
REG_UPDATE(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_EN, 0);
|
||||
|
||||
/* no 10bpc on DCE11*/
|
||||
if (params->flags.SPATIAL_DITHER_ENABLED == 0 ||
|
||||
params->flags.SPATIAL_DITHER_DEPTH == 2)
|
||||
return;
|
||||
|
||||
/* only use FRAME_COUNTER_MAX if frameRandom == 1*/
|
||||
|
||||
if (opp110->opp_mask->FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX &&
|
||||
opp110->opp_mask->FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP) {
|
||||
if (params->flags.FRAME_RANDOM == 1) {
|
||||
if (params->flags.SPATIAL_DITHER_DEPTH == 0 ||
|
||||
params->flags.SPATIAL_DITHER_DEPTH == 1) {
|
||||
REG_UPDATE_2(FMT_CONTROL,
|
||||
FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 15,
|
||||
FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 2);
|
||||
} else if (params->flags.SPATIAL_DITHER_DEPTH == 2) {
|
||||
REG_UPDATE_2(FMT_CONTROL,
|
||||
FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 3,
|
||||
FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 1);
|
||||
} else
|
||||
return;
|
||||
} else {
|
||||
REG_UPDATE_2(FMT_CONTROL,
|
||||
FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 0,
|
||||
FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 0);
|
||||
}
|
||||
}
|
||||
/* Set seed for random values for
|
||||
* spatial dithering for R,G,B channels
|
||||
*/
|
||||
REG_UPDATE(FMT_DITHER_RAND_R_SEED,
|
||||
FMT_RAND_R_SEED, params->r_seed_value);
|
||||
|
||||
REG_UPDATE(FMT_DITHER_RAND_G_SEED,
|
||||
FMT_RAND_G_SEED, params->g_seed_value);
|
||||
|
||||
REG_UPDATE(FMT_DITHER_RAND_B_SEED,
|
||||
FMT_RAND_B_SEED, params->b_seed_value);
|
||||
|
||||
/* FMT_OFFSET_R_Cr 31:16 0x0 Setting the zero
|
||||
* offset for the R/Cr channel, lower 4LSB
|
||||
* is forced to zeros. Typically set to 0
|
||||
* RGB and 0x80000 YCbCr.
|
||||
*/
|
||||
/* FMT_OFFSET_G_Y 31:16 0x0 Setting the zero
|
||||
* offset for the G/Y channel, lower 4LSB is
|
||||
* forced to zeros. Typically set to 0 RGB
|
||||
* and 0x80000 YCbCr.
|
||||
*/
|
||||
/* FMT_OFFSET_B_Cb 31:16 0x0 Setting the zero
|
||||
* offset for the B/Cb channel, lower 4LSB is
|
||||
* forced to zeros. Typically set to 0 RGB and
|
||||
* 0x80000 YCbCr.
|
||||
*/
|
||||
|
||||
/* Disable High pass filter
|
||||
* Reset only at startup
|
||||
* Set RGB data dithered with x^28+x^3+1
|
||||
*/
|
||||
REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_HIGHPASS_RANDOM_ENABLE, params->flags.HIGHPASS_RANDOM,
|
||||
FMT_FRAME_RANDOM_ENABLE, params->flags.FRAME_RANDOM,
|
||||
FMT_RGB_RANDOM_ENABLE, params->flags.RGB_RANDOM);
|
||||
|
||||
/* Set spatial dithering bit depth
|
||||
* Set spatial dithering mode
|
||||
* (default is Seed patterrn AAAA...)
|
||||
* Enable spatial dithering
|
||||
*/
|
||||
REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_SPATIAL_DITHER_DEPTH, params->flags.SPATIAL_DITHER_DEPTH,
|
||||
FMT_SPATIAL_DITHER_MODE, params->flags.SPATIAL_DITHER_MODE,
|
||||
FMT_SPATIAL_DITHER_EN, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* SetTemporalDither (Frame Modulation)
|
||||
* 1) set temporal dither depth
|
||||
* 2) select pattern: from hard-coded pattern or programmable pattern
|
||||
* 3) select optimized strips for BGR or RGB LCD sub-pixel
|
||||
* 4) set s matrix
|
||||
* 5) set t matrix
|
||||
* 6) set grey level for 0.25, 0.5, 0.75
|
||||
* 7) enable temporal dithering
|
||||
*/
|
||||
|
||||
static void set_temporal_dither(
|
||||
struct dce110_opp *opp110,
|
||||
const struct bit_depth_reduction_params *params)
|
||||
{
|
||||
/*Disable temporal (frame modulation) dithering first*/
|
||||
REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_EN, 0,
|
||||
FMT_TEMPORAL_DITHER_RESET, 0,
|
||||
FMT_TEMPORAL_DITHER_OFFSET, 0);
|
||||
|
||||
REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_DEPTH, 0,
|
||||
FMT_TEMPORAL_LEVEL, 0);
|
||||
|
||||
REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_25FRC_SEL, 0,
|
||||
FMT_50FRC_SEL, 0,
|
||||
FMT_75FRC_SEL, 0);
|
||||
|
||||
/* no 10bpc dither on DCE11*/
|
||||
if (params->flags.FRAME_MODULATION_ENABLED == 0 ||
|
||||
params->flags.FRAME_MODULATION_DEPTH == 2)
|
||||
return;
|
||||
|
||||
/* Set temporal dithering depth*/
|
||||
REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_DEPTH, params->flags.FRAME_MODULATION_DEPTH,
|
||||
FMT_TEMPORAL_DITHER_RESET, 0,
|
||||
FMT_TEMPORAL_DITHER_OFFSET, 0);
|
||||
|
||||
/*Select legacy pattern based on FRC and Temporal level*/
|
||||
if (REG(FMT_TEMPORAL_DITHER_PATTERN_CONTROL)) {
|
||||
REG_WRITE(FMT_TEMPORAL_DITHER_PATTERN_CONTROL, 0);
|
||||
/*Set s matrix*/
|
||||
REG_WRITE(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX, 0);
|
||||
/*Set t matrix*/
|
||||
REG_WRITE(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX, 0);
|
||||
}
|
||||
|
||||
/*Select patterns for 0.25, 0.5 and 0.75 grey level*/
|
||||
REG_UPDATE(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_LEVEL, params->flags.TEMPORAL_LEVEL);
|
||||
|
||||
REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_25FRC_SEL, params->flags.FRC25,
|
||||
FMT_50FRC_SEL, params->flags.FRC50,
|
||||
FMT_75FRC_SEL, params->flags.FRC75);
|
||||
|
||||
/*Enable bit reduction by temporal (frame modulation) dithering*/
|
||||
REG_UPDATE(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_EN, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Clamping
|
||||
* 1) Set clamping format based on bpc - 0 for 6bpc (No clamping)
|
||||
* 1 for 8 bpc
|
||||
* 2 for 10 bpc
|
||||
* 3 for 12 bpc
|
||||
* 7 for programable
|
||||
* 2) Enable clamp if Limited range requested
|
||||
*/
|
||||
void dce110_opp_set_clamping(
|
||||
struct dce110_opp *opp110,
|
||||
const struct clamping_and_pixel_encoding_params *params)
|
||||
{
|
||||
uint32_t clamp_cntl_value = 0;
|
||||
|
||||
REG_SET_2(FMT_CLAMP_CNTL, 0,
|
||||
FMT_CLAMP_DATA_EN, 0,
|
||||
FMT_CLAMP_COLOR_FORMAT, 0);
|
||||
|
||||
switch (params->clamping_level) {
|
||||
case CLAMPING_FULL_RANGE:
|
||||
break;
|
||||
case CLAMPING_LIMITED_RANGE_8BPC:
|
||||
REG_SET_2(FMT_CLAMP_CNTL, 0,
|
||||
FMT_CLAMP_DATA_EN, 1,
|
||||
FMT_CLAMP_COLOR_FORMAT, 1);
|
||||
break;
|
||||
case CLAMPING_LIMITED_RANGE_10BPC:
|
||||
REG_SET_2(FMT_CLAMP_CNTL, 0,
|
||||
FMT_CLAMP_DATA_EN, 1,
|
||||
FMT_CLAMP_COLOR_FORMAT, 2);
|
||||
break;
|
||||
case CLAMPING_LIMITED_RANGE_12BPC:
|
||||
REG_SET_2(FMT_CLAMP_CNTL, 0,
|
||||
FMT_CLAMP_DATA_EN, 1,
|
||||
FMT_CLAMP_COLOR_FORMAT, 3);
|
||||
break;
|
||||
case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:
|
||||
/*Set clamp control*/
|
||||
REG_SET_2(FMT_CLAMP_CNTL, 0,
|
||||
FMT_CLAMP_DATA_EN, 1,
|
||||
FMT_CLAMP_COLOR_FORMAT, 7);
|
||||
|
||||
/*set the defaults*/
|
||||
REG_SET_2(FMT_CLAMP_COMPONENT_R, 0,
|
||||
FMT_CLAMP_LOWER_R, 0x10,
|
||||
FMT_CLAMP_UPPER_R, 0xFEF);
|
||||
|
||||
REG_SET_2(FMT_CLAMP_COMPONENT_G, 0,
|
||||
FMT_CLAMP_LOWER_G, 0x10,
|
||||
FMT_CLAMP_UPPER_G, 0xFEF);
|
||||
|
||||
REG_SET_2(FMT_CLAMP_COMPONENT_B, 0,
|
||||
FMT_CLAMP_LOWER_B, 0x10,
|
||||
FMT_CLAMP_UPPER_B, 0xFEF);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set_pixel_encoding
|
||||
*
|
||||
* Set Pixel Encoding
|
||||
* 0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly
|
||||
* 1: YCbCr 4:2:2
|
||||
*/
|
||||
static void set_pixel_encoding(
|
||||
struct dce110_opp *opp110,
|
||||
const struct clamping_and_pixel_encoding_params *params)
|
||||
{
|
||||
if (opp110->opp_mask->FMT_CBCR_BIT_REDUCTION_BYPASS)
|
||||
REG_UPDATE_3(FMT_CONTROL,
|
||||
FMT_PIXEL_ENCODING, 0,
|
||||
FMT_SUBSAMPLING_MODE, 0,
|
||||
FMT_CBCR_BIT_REDUCTION_BYPASS, 0);
|
||||
else
|
||||
REG_UPDATE_2(FMT_CONTROL,
|
||||
FMT_PIXEL_ENCODING, 0,
|
||||
FMT_SUBSAMPLING_MODE, 0);
|
||||
|
||||
if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
|
||||
REG_UPDATE_2(FMT_CONTROL,
|
||||
FMT_PIXEL_ENCODING, 1,
|
||||
FMT_SUBSAMPLING_ORDER, 0);
|
||||
}
|
||||
if (params->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
|
||||
REG_UPDATE_3(FMT_CONTROL,
|
||||
FMT_PIXEL_ENCODING, 2,
|
||||
FMT_SUBSAMPLING_MODE, 2,
|
||||
FMT_CBCR_BIT_REDUCTION_BYPASS, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void dce110_opp_program_bit_depth_reduction(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct bit_depth_reduction_params *params)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
|
||||
set_truncation(opp110, params);
|
||||
set_spatial_dither(opp110, params);
|
||||
set_temporal_dither(opp110, params);
|
||||
}
|
||||
|
||||
void dce110_opp_program_clamping_and_pixel_encoding(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct clamping_and_pixel_encoding_params *params)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
|
||||
dce110_opp_set_clamping(opp110, params);
|
||||
set_pixel_encoding(opp110, params);
|
||||
}
|
||||
|
||||
static void program_formatter_420_memory(struct output_pixel_processor *opp)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
uint32_t fmt_mem_cntl_value;
|
||||
|
||||
/* Program source select*/
|
||||
/* Use HW default source select for FMT_MEMORYx_CONTROL */
|
||||
/* Use that value for FMT_SRC_SELECT as well*/
|
||||
REG_GET(CONTROL,
|
||||
FMT420_MEM0_SOURCE_SEL, &fmt_mem_cntl_value);
|
||||
|
||||
REG_UPDATE(FMT_CONTROL,
|
||||
FMT_SRC_SELECT, fmt_mem_cntl_value);
|
||||
|
||||
/* Turn on the memory */
|
||||
REG_UPDATE(CONTROL,
|
||||
FMT420_MEM0_PWR_FORCE, 0);
|
||||
}
|
||||
|
||||
void dce110_opp_set_dyn_expansion(
|
||||
struct output_pixel_processor *opp,
|
||||
enum dc_color_space color_sp,
|
||||
enum dc_color_depth color_dpth,
|
||||
enum signal_type signal)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
bool enable_dyn_exp = false;
|
||||
|
||||
REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
|
||||
FMT_DYNAMIC_EXP_EN, 0,
|
||||
FMT_DYNAMIC_EXP_MODE, 0);
|
||||
/* From HW programming guide:
|
||||
FMT_DYNAMIC_EXP_EN = 0 for limited RGB or YCbCr output
|
||||
FMT_DYNAMIC_EXP_EN = 1 for RGB full range only*/
|
||||
if (color_sp == COLOR_SPACE_SRGB)
|
||||
enable_dyn_exp = true;
|
||||
|
||||
/*00 - 10-bit -> 12-bit dynamic expansion*/
|
||||
/*01 - 8-bit -> 12-bit dynamic expansion*/
|
||||
if (signal == SIGNAL_TYPE_HDMI_TYPE_A) {
|
||||
switch (color_dpth) {
|
||||
case COLOR_DEPTH_888:
|
||||
REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
|
||||
FMT_DYNAMIC_EXP_EN, enable_dyn_exp ? 1:0,
|
||||
FMT_DYNAMIC_EXP_MODE, 1);
|
||||
break;
|
||||
case COLOR_DEPTH_101010:
|
||||
REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
|
||||
FMT_DYNAMIC_EXP_EN, enable_dyn_exp ? 1:0,
|
||||
FMT_DYNAMIC_EXP_MODE, 0);
|
||||
break;
|
||||
case COLOR_DEPTH_121212:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void program_formatter_reset_dig_resync_fifo(struct output_pixel_processor *opp)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
uint8_t counter = 10;
|
||||
|
||||
/* clear previous phase lock status*/
|
||||
REG_UPDATE(FMT_CONTROL,
|
||||
FMT_420_PIXEL_PHASE_LOCKED_CLEAR, 1);
|
||||
|
||||
/* poll until FMT_420_PIXEL_PHASE_LOCKED become 1*/
|
||||
REG_WAIT(FMT_CONTROL, FMT_420_PIXEL_PHASE_LOCKED, 1, 10, 10);
|
||||
|
||||
}
|
||||
|
||||
void dce110_opp_program_fmt(
|
||||
struct output_pixel_processor *opp,
|
||||
struct bit_depth_reduction_params *fmt_bit_depth,
|
||||
struct clamping_and_pixel_encoding_params *clamping)
|
||||
{
|
||||
/* dithering is affected by <CrtcSourceSelect>, hence should be
|
||||
* programmed afterwards */
|
||||
|
||||
if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
|
||||
program_formatter_420_memory(opp);
|
||||
|
||||
dce110_opp_program_bit_depth_reduction(
|
||||
opp,
|
||||
fmt_bit_depth);
|
||||
|
||||
dce110_opp_program_clamping_and_pixel_encoding(
|
||||
opp,
|
||||
clamping);
|
||||
|
||||
if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
|
||||
program_formatter_reset_dig_resync_fifo(opp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void program_color_matrix(
|
||||
struct dce110_opp *opp110,
|
||||
const struct out_csc_color_matrix *tbl_entry,
|
||||
enum grph_color_adjust_option options)
|
||||
{
|
||||
{
|
||||
REG_SET_2(OUTPUT_CSC_C11_C12, 0,
|
||||
OUTPUT_CSC_C11, tbl_entry->regval[0],
|
||||
OUTPUT_CSC_C12, tbl_entry->regval[1]);
|
||||
}
|
||||
{
|
||||
REG_SET_2(OUTPUT_CSC_C13_C14, 0,
|
||||
OUTPUT_CSC_C11, tbl_entry->regval[2],
|
||||
OUTPUT_CSC_C12, tbl_entry->regval[3]);
|
||||
}
|
||||
{
|
||||
REG_SET_2(OUTPUT_CSC_C21_C22, 0,
|
||||
OUTPUT_CSC_C11, tbl_entry->regval[4],
|
||||
OUTPUT_CSC_C12, tbl_entry->regval[5]);
|
||||
}
|
||||
{
|
||||
REG_SET_2(OUTPUT_CSC_C23_C24, 0,
|
||||
OUTPUT_CSC_C11, tbl_entry->regval[6],
|
||||
OUTPUT_CSC_C12, tbl_entry->regval[7]);
|
||||
}
|
||||
{
|
||||
REG_SET_2(OUTPUT_CSC_C31_C32, 0,
|
||||
OUTPUT_CSC_C11, tbl_entry->regval[8],
|
||||
OUTPUT_CSC_C12, tbl_entry->regval[9]);
|
||||
}
|
||||
{
|
||||
REG_SET_2(OUTPUT_CSC_C33_C34, 0,
|
||||
OUTPUT_CSC_C11, tbl_entry->regval[10],
|
||||
OUTPUT_CSC_C12, tbl_entry->regval[11]);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
REG_SET(OUTPUT_CSC_CONTROL, 0,
|
||||
OUTPUT_CSC_GRPH_MODE, 0);
|
||||
|
||||
if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_SW) {
|
||||
if (config == CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC) {
|
||||
REG_SET(OUTPUT_CSC_CONTROL, 0,
|
||||
OUTPUT_CSC_GRPH_MODE, 4);
|
||||
} else {
|
||||
|
||||
switch (color_space) {
|
||||
case COLOR_SPACE_SRGB:
|
||||
/* by pass */
|
||||
REG_SET(OUTPUT_CSC_CONTROL, 0,
|
||||
OUTPUT_CSC_GRPH_MODE, 0);
|
||||
break;
|
||||
case COLOR_SPACE_SRGB_LIMITED:
|
||||
/* TV RGB */
|
||||
REG_SET(OUTPUT_CSC_CONTROL, 0,
|
||||
OUTPUT_CSC_GRPH_MODE, 1);
|
||||
break;
|
||||
case COLOR_SPACE_YCBCR601:
|
||||
case COLOR_SPACE_YPBPR601:
|
||||
case COLOR_SPACE_YCBCR601_LIMITED:
|
||||
/* YCbCr601 */
|
||||
REG_SET(OUTPUT_CSC_CONTROL, 0,
|
||||
OUTPUT_CSC_GRPH_MODE, 2);
|
||||
break;
|
||||
case COLOR_SPACE_YCBCR709:
|
||||
case COLOR_SPACE_YPBPR709:
|
||||
case COLOR_SPACE_YCBCR709_LIMITED:
|
||||
/* YCbCr709 */
|
||||
REG_SET(OUTPUT_CSC_CONTROL, 0,
|
||||
OUTPUT_CSC_GRPH_MODE, 3);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_HW) {
|
||||
switch (color_space) {
|
||||
case COLOR_SPACE_SRGB:
|
||||
/* by pass */
|
||||
REG_SET(OUTPUT_CSC_CONTROL, 0,
|
||||
OUTPUT_CSC_GRPH_MODE, 0);
|
||||
break;
|
||||
break;
|
||||
case COLOR_SPACE_SRGB_LIMITED:
|
||||
/* TV RGB */
|
||||
REG_SET(OUTPUT_CSC_CONTROL, 0,
|
||||
OUTPUT_CSC_GRPH_MODE, 1);
|
||||
break;
|
||||
case COLOR_SPACE_YCBCR601:
|
||||
case COLOR_SPACE_YPBPR601:
|
||||
case COLOR_SPACE_YCBCR601_LIMITED:
|
||||
/* YCbCr601 */
|
||||
REG_SET(OUTPUT_CSC_CONTROL, 0,
|
||||
OUTPUT_CSC_GRPH_MODE, 2);
|
||||
break;
|
||||
case COLOR_SPACE_YCBCR709:
|
||||
case COLOR_SPACE_YPBPR709:
|
||||
case COLOR_SPACE_YCBCR709_LIMITED:
|
||||
/* YCbCr709 */
|
||||
REG_SET(OUTPUT_CSC_CONTROL, 0,
|
||||
OUTPUT_CSC_GRPH_MODE, 3);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
} else
|
||||
/* by pass */
|
||||
REG_SET(OUTPUT_CSC_CONTROL, 0,
|
||||
OUTPUT_CSC_GRPH_MODE, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dce110_opp_set_csc_adjustment(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct out_csc_color_matrix *tbl_entry)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
enum csc_color_mode config =
|
||||
CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
|
||||
|
||||
program_color_matrix(
|
||||
opp110, tbl_entry, GRAPHICS_CSC_ADJUST_TYPE_SW);
|
||||
|
||||
/* We did everything ,now program DxOUTPUT_CSC_CONTROL */
|
||||
configure_graphics_mode(opp110, config, GRAPHICS_CSC_ADJUST_TYPE_SW,
|
||||
tbl_entry->color_space);
|
||||
}
|
||||
|
||||
void dce110_opp_set_csc_default(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct default_adjustment *default_adjust)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
enum csc_color_mode config =
|
||||
CSC_COLOR_MODE_GRAPHICS_PREDEFINED;
|
||||
|
||||
if (default_adjust->force_hw_default == false) {
|
||||
const struct out_csc_color_matrix *elm;
|
||||
/* currently parameter not in use */
|
||||
enum grph_color_adjust_option option =
|
||||
GRPH_COLOR_MATRIX_HW_DEFAULT;
|
||||
uint32_t i;
|
||||
/*
|
||||
* HW default false we program locally defined matrix
|
||||
* HW default true we use predefined hw matrix and we
|
||||
* do not need to program matrix
|
||||
* OEM wants the HW default via runtime parameter.
|
||||
*/
|
||||
option = GRPH_COLOR_MATRIX_SW;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(global_color_matrix); ++i) {
|
||||
elm = &global_color_matrix[i];
|
||||
if (elm->color_space != default_adjust->out_color_space)
|
||||
continue;
|
||||
/* program the matrix with default values from this
|
||||
* file */
|
||||
program_color_matrix(opp110, elm, option);
|
||||
config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* configure the what we programmed :
|
||||
* 1. Default values from this file
|
||||
* 2. Use hardware default from ROM_A and we do not need to program
|
||||
* matrix */
|
||||
|
||||
configure_graphics_mode(opp110, config,
|
||||
default_adjust->csc_adjust_type,
|
||||
default_adjust->out_color_space);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************/
|
||||
/* Constructor, Destructor */
|
||||
/*****************************************/
|
||||
|
||||
static const struct opp_funcs funcs = {
|
||||
.opp_power_on_regamma_lut = dce110_opp_power_on_regamma_lut,
|
||||
.opp_set_csc_adjustment = dce110_opp_set_csc_adjustment,
|
||||
.opp_set_csc_default = dce110_opp_set_csc_default,
|
||||
.opp_set_dyn_expansion = dce110_opp_set_dyn_expansion,
|
||||
.opp_program_regamma_pwl = dce110_opp_program_regamma_pwl,
|
||||
.opp_set_regamma_mode = dce110_opp_set_regamma_mode,
|
||||
.opp_destroy = dce110_opp_destroy,
|
||||
.opp_program_fmt = dce110_opp_program_fmt,
|
||||
.opp_program_bit_depth_reduction = dce110_opp_program_bit_depth_reduction
|
||||
};
|
||||
|
||||
bool dce110_opp_construct(struct dce110_opp *opp110,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dce_opp_registers *regs,
|
||||
const struct dce_opp_shift *opp_shift,
|
||||
const struct dce_opp_mask *opp_mask)
|
||||
{
|
||||
opp110->base.funcs = &funcs;
|
||||
|
||||
opp110->base.ctx = ctx;
|
||||
|
||||
opp110->base.inst = inst;
|
||||
|
||||
opp110->regs = regs;
|
||||
opp110->opp_shift = opp_shift;
|
||||
opp110->opp_mask = opp_mask;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dce110_opp_destroy(struct output_pixel_processor **opp)
|
||||
{
|
||||
dm_free(FROM_DCE11_OPP(*opp));
|
||||
*opp = NULL;
|
||||
}
|
||||
|
418
drivers/gpu/drm/amd/display/dc/dce/dce_opp.h
Normal file
418
drivers/gpu/drm/amd/display/dc/dce/dce_opp.h
Normal file
@ -0,0 +1,418 @@
|
||||
/* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_OPP_DCE_H__
|
||||
#define __DC_OPP_DCE_H__
|
||||
|
||||
#include "dc_types.h"
|
||||
#include "opp.h"
|
||||
#include "core_types.h"
|
||||
|
||||
#include "gamma_types.h" /* decprecated */
|
||||
|
||||
struct gamma_parameters;
|
||||
|
||||
#define FROM_DCE11_OPP(opp)\
|
||||
container_of(opp, struct dce110_opp, base)
|
||||
|
||||
enum dce110_opp_reg_type {
|
||||
DCE110_OPP_REG_DCP = 0,
|
||||
DCE110_OPP_REG_DCFE,
|
||||
DCE110_OPP_REG_FMT,
|
||||
|
||||
DCE110_OPP_REG_MAX
|
||||
};
|
||||
|
||||
#define OPP_COMMON_REG_LIST_BASE(id) \
|
||||
SRI(REGAMMA_CNTLA_START_CNTL, DCP, id), \
|
||||
SRI(REGAMMA_CNTLA_SLOPE_CNTL, DCP, id), \
|
||||
SRI(REGAMMA_CNTLA_END_CNTL1, DCP, id), \
|
||||
SRI(REGAMMA_CNTLA_END_CNTL2, DCP, id), \
|
||||
SRI(REGAMMA_CNTLA_REGION_0_1, DCP, id), \
|
||||
SRI(REGAMMA_CNTLA_REGION_2_3, DCP, id), \
|
||||
SRI(REGAMMA_CNTLA_REGION_4_5, DCP, id), \
|
||||
SRI(REGAMMA_CNTLA_REGION_6_7, DCP, id), \
|
||||
SRI(REGAMMA_CNTLA_REGION_8_9, DCP, id), \
|
||||
SRI(REGAMMA_CNTLA_REGION_10_11, DCP, id), \
|
||||
SRI(REGAMMA_CNTLA_REGION_12_13, DCP, id), \
|
||||
SRI(REGAMMA_CNTLA_REGION_14_15, DCP, id), \
|
||||
SRI(REGAMMA_LUT_WRITE_EN_MASK, DCP, id), \
|
||||
SRI(REGAMMA_LUT_INDEX, DCP, id), \
|
||||
SRI(REGAMMA_LUT_DATA, DCP, id), \
|
||||
SRI(REGAMMA_CONTROL, DCP, id), \
|
||||
SRI(OUTPUT_CSC_C11_C12, DCP, id), \
|
||||
SRI(OUTPUT_CSC_C13_C14, DCP, id), \
|
||||
SRI(OUTPUT_CSC_C21_C22, DCP, id), \
|
||||
SRI(OUTPUT_CSC_C23_C24, DCP, id), \
|
||||
SRI(OUTPUT_CSC_C31_C32, DCP, id), \
|
||||
SRI(OUTPUT_CSC_C33_C34, DCP, id), \
|
||||
SRI(OUTPUT_CSC_CONTROL, DCP, id), \
|
||||
SRI(FMT_DYNAMIC_EXP_CNTL, FMT, id), \
|
||||
SRI(FMT_BIT_DEPTH_CONTROL, FMT, id), \
|
||||
SRI(FMT_CONTROL, FMT, id), \
|
||||
SRI(FMT_DITHER_RAND_R_SEED, FMT, id), \
|
||||
SRI(FMT_DITHER_RAND_G_SEED, FMT, id), \
|
||||
SRI(FMT_DITHER_RAND_B_SEED, FMT, id), \
|
||||
SRI(FMT_CLAMP_CNTL, FMT, id), \
|
||||
SRI(FMT_CLAMP_COMPONENT_R, FMT, id), \
|
||||
SRI(FMT_CLAMP_COMPONENT_G, FMT, id), \
|
||||
SRI(FMT_CLAMP_COMPONENT_B, FMT, id)
|
||||
|
||||
#define OPP_DCE_80_REG_LIST(id) \
|
||||
OPP_COMMON_REG_LIST_BASE(id), \
|
||||
SRI(DCFE_MEM_LIGHT_SLEEP_CNTL, CRTC, id), \
|
||||
SRI(FMT_TEMPORAL_DITHER_PATTERN_CONTROL, FMT, id), \
|
||||
SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX, FMT, id), \
|
||||
SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX, FMT, id)
|
||||
|
||||
#define OPP_DCE_100_REG_LIST(id) \
|
||||
OPP_COMMON_REG_LIST_BASE(id), \
|
||||
SRI(DCFE_MEM_PWR_CTRL, CRTC, id), \
|
||||
SRI(DCFE_MEM_PWR_STATUS, CRTC, id), \
|
||||
SRI(FMT_TEMPORAL_DITHER_PATTERN_CONTROL, FMT, id), \
|
||||
SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX, FMT, id), \
|
||||
SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX, FMT, id)
|
||||
|
||||
#define OPP_DCE_110_REG_LIST(id) \
|
||||
OPP_COMMON_REG_LIST_BASE(id), \
|
||||
SRI(DCFE_MEM_PWR_CTRL, DCFE, id), \
|
||||
SRI(DCFE_MEM_PWR_STATUS, DCFE, id), \
|
||||
SRI(FMT_TEMPORAL_DITHER_PATTERN_CONTROL, FMT, id), \
|
||||
SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX, FMT, id), \
|
||||
SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX, FMT, id)
|
||||
|
||||
#define OPP_DCE_112_REG_LIST(id) \
|
||||
OPP_COMMON_REG_LIST_BASE(id), \
|
||||
SRI(DCFE_MEM_PWR_CTRL, DCFE, id), \
|
||||
SRI(DCFE_MEM_PWR_STATUS, DCFE, id), \
|
||||
SRI(FMT_TEMPORAL_DITHER_PATTERN_CONTROL, FMT, id), \
|
||||
SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX, FMT, id), \
|
||||
SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX, FMT, id), \
|
||||
SRI(CONTROL, FMT_MEMORY, id)
|
||||
|
||||
#define OPP_SF(reg_name, field_name, post_fix)\
|
||||
.field_name = reg_name ## __ ## field_name ## post_fix
|
||||
|
||||
#define OPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh)\
|
||||
OPP_SF(REGAMMA_CNTLA_START_CNTL, REGAMMA_CNTLA_EXP_REGION_START, mask_sh),\
|
||||
OPP_SF(REGAMMA_CNTLA_START_CNTL, REGAMMA_CNTLA_EXP_REGION_START_SEGMENT, mask_sh),\
|
||||
OPP_SF(REGAMMA_CNTLA_SLOPE_CNTL, REGAMMA_CNTLA_EXP_REGION_LINEAR_SLOPE, mask_sh),\
|
||||
OPP_SF(REGAMMA_CNTLA_END_CNTL1, REGAMMA_CNTLA_EXP_REGION_END, mask_sh),\
|
||||
OPP_SF(REGAMMA_CNTLA_END_CNTL2, REGAMMA_CNTLA_EXP_REGION_END_BASE, mask_sh),\
|
||||
OPP_SF(REGAMMA_CNTLA_END_CNTL2, REGAMMA_CNTLA_EXP_REGION_END_SLOPE, mask_sh),\
|
||||
OPP_SF(REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, mask_sh),\
|
||||
OPP_SF(REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, mask_sh),\
|
||||
OPP_SF(REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, mask_sh),\
|
||||
OPP_SF(REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, mask_sh),\
|
||||
OPP_SF(REGAMMA_LUT_WRITE_EN_MASK, REGAMMA_LUT_WRITE_EN_MASK, mask_sh),\
|
||||
OPP_SF(REGAMMA_CONTROL, GRPH_REGAMMA_MODE, mask_sh),\
|
||||
OPP_SF(OUTPUT_CSC_C11_C12, OUTPUT_CSC_C11, mask_sh),\
|
||||
OPP_SF(OUTPUT_CSC_C11_C12, OUTPUT_CSC_C12, mask_sh),\
|
||||
OPP_SF(OUTPUT_CSC_CONTROL, OUTPUT_CSC_GRPH_MODE, mask_sh),\
|
||||
OPP_SF(FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN, mask_sh),\
|
||||
OPP_SF(FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_DEPTH, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_MODE, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_EN, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_DEPTH, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_MODE, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_HIGHPASS_RANDOM_ENABLE, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_FRAME_RANDOM_ENABLE, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_RGB_RANDOM_ENABLE, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_EN, mask_sh),\
|
||||
OPP_SF(FMT_DITHER_RAND_R_SEED, FMT_RAND_R_SEED, mask_sh),\
|
||||
OPP_SF(FMT_DITHER_RAND_G_SEED, FMT_RAND_G_SEED, mask_sh),\
|
||||
OPP_SF(FMT_DITHER_RAND_B_SEED, FMT_RAND_B_SEED, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_EN, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_RESET, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_OFFSET, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_DEPTH, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_LEVEL, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_25FRC_SEL, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_50FRC_SEL, mask_sh),\
|
||||
OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_75FRC_SEL, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_SRC_SELECT, mask_sh),\
|
||||
OPP_SF(FMT_CLAMP_CNTL, FMT_CLAMP_DATA_EN, mask_sh),\
|
||||
OPP_SF(FMT_CLAMP_CNTL, FMT_CLAMP_COLOR_FORMAT, mask_sh),\
|
||||
OPP_SF(FMT_CLAMP_COMPONENT_R, FMT_CLAMP_LOWER_R, mask_sh),\
|
||||
OPP_SF(FMT_CLAMP_COMPONENT_R, FMT_CLAMP_UPPER_R, mask_sh),\
|
||||
OPP_SF(FMT_CLAMP_COMPONENT_G, FMT_CLAMP_LOWER_G, mask_sh),\
|
||||
OPP_SF(FMT_CLAMP_COMPONENT_G, FMT_CLAMP_UPPER_G, mask_sh),\
|
||||
OPP_SF(FMT_CLAMP_COMPONENT_B, FMT_CLAMP_LOWER_B, mask_sh),\
|
||||
OPP_SF(FMT_CLAMP_COMPONENT_B, FMT_CLAMP_UPPER_B, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_PIXEL_ENCODING, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_SUBSAMPLING_MODE, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_SUBSAMPLING_ORDER, mask_sh)
|
||||
|
||||
#define OPP_COMMON_MASK_SH_LIST_DCE_110(mask_sh)\
|
||||
OPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh),\
|
||||
OPP_SF(DCFE_MEM_PWR_CTRL, DCP_REGAMMA_MEM_PWR_DIS, mask_sh),\
|
||||
OPP_SF(DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, mask_sh),\
|
||||
OPP_SF(DCFE_MEM_PWR_STATUS, DCP_REGAMMA_MEM_PWR_STATE, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, mask_sh)
|
||||
|
||||
#define OPP_COMMON_MASK_SH_LIST_DCE_100(mask_sh)\
|
||||
OPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh),\
|
||||
OPP_SF(DCFE_MEM_PWR_CTRL, DCP_REGAMMA_MEM_PWR_DIS, mask_sh),\
|
||||
OPP_SF(DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, mask_sh),\
|
||||
OPP_SF(DCFE_MEM_PWR_STATUS, DCP_REGAMMA_MEM_PWR_STATE, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, mask_sh)
|
||||
|
||||
#define OPP_COMMON_MASK_SH_LIST_DCE_112(mask_sh)\
|
||||
OPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh),\
|
||||
OPP_SF(DCFE_MEM_PWR_CTRL, DCP_REGAMMA_MEM_PWR_DIS, mask_sh),\
|
||||
OPP_SF(DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, mask_sh),\
|
||||
OPP_SF(DCFE_MEM_PWR_STATUS, DCP_REGAMMA_MEM_PWR_STATE, mask_sh),\
|
||||
OPP_SF(FMT_MEMORY0_CONTROL, FMT420_MEM0_SOURCE_SEL, mask_sh),\
|
||||
OPP_SF(FMT_MEMORY0_CONTROL, FMT420_MEM0_PWR_FORCE, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_420_PIXEL_PHASE_LOCKED_CLEAR, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_420_PIXEL_PHASE_LOCKED, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_CBCR_BIT_REDUCTION_BYPASS, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, mask_sh),\
|
||||
OPP_SF(FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, mask_sh)
|
||||
|
||||
#define OPP_COMMON_MASK_SH_LIST_DCE_80(mask_sh)\
|
||||
OPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh),\
|
||||
OPP_SF(DCFE_MEM_LIGHT_SLEEP_CNTL, REGAMMA_LUT_LIGHT_SLEEP_DIS, mask_sh),\
|
||||
OPP_SF(DCFE_MEM_LIGHT_SLEEP_CNTL, DCP_LUT_LIGHT_SLEEP_DIS, mask_sh),\
|
||||
OPP_SF(DCFE_MEM_LIGHT_SLEEP_CNTL, REGAMMA_LUT_MEM_PWR_STATE, mask_sh)
|
||||
|
||||
#define OPP_REG_FIELD_LIST(type) \
|
||||
type DCP_REGAMMA_MEM_PWR_DIS; \
|
||||
type DCP_LUT_MEM_PWR_DIS; \
|
||||
type REGAMMA_LUT_LIGHT_SLEEP_DIS; \
|
||||
type DCP_LUT_LIGHT_SLEEP_DIS; \
|
||||
type REGAMMA_CNTLA_EXP_REGION_START; \
|
||||
type REGAMMA_CNTLA_EXP_REGION_START_SEGMENT; \
|
||||
type REGAMMA_CNTLA_EXP_REGION_LINEAR_SLOPE; \
|
||||
type REGAMMA_CNTLA_EXP_REGION_END; \
|
||||
type REGAMMA_CNTLA_EXP_REGION_END_BASE; \
|
||||
type REGAMMA_CNTLA_EXP_REGION_END_SLOPE; \
|
||||
type REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET; \
|
||||
type REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS; \
|
||||
type REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET; \
|
||||
type REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS; \
|
||||
type DCP_REGAMMA_MEM_PWR_STATE; \
|
||||
type REGAMMA_LUT_MEM_PWR_STATE; \
|
||||
type REGAMMA_LUT_WRITE_EN_MASK; \
|
||||
type GRPH_REGAMMA_MODE; \
|
||||
type OUTPUT_CSC_C11; \
|
||||
type OUTPUT_CSC_C12; \
|
||||
type OUTPUT_CSC_GRPH_MODE; \
|
||||
type FMT_DYNAMIC_EXP_EN; \
|
||||
type FMT_DYNAMIC_EXP_MODE; \
|
||||
type FMT_TRUNCATE_EN; \
|
||||
type FMT_TRUNCATE_DEPTH; \
|
||||
type FMT_TRUNCATE_MODE; \
|
||||
type FMT_SPATIAL_DITHER_EN; \
|
||||
type FMT_SPATIAL_DITHER_DEPTH; \
|
||||
type FMT_SPATIAL_DITHER_MODE; \
|
||||
type FMT_TEMPORAL_DITHER_EN; \
|
||||
type FMT_TEMPORAL_DITHER_RESET; \
|
||||
type FMT_TEMPORAL_DITHER_OFFSET; \
|
||||
type FMT_TEMPORAL_DITHER_DEPTH; \
|
||||
type FMT_TEMPORAL_LEVEL; \
|
||||
type FMT_25FRC_SEL; \
|
||||
type FMT_50FRC_SEL; \
|
||||
type FMT_75FRC_SEL; \
|
||||
type FMT_HIGHPASS_RANDOM_ENABLE; \
|
||||
type FMT_FRAME_RANDOM_ENABLE; \
|
||||
type FMT_RGB_RANDOM_ENABLE; \
|
||||
type FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX; \
|
||||
type FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP; \
|
||||
type FMT_RAND_R_SEED; \
|
||||
type FMT_RAND_G_SEED; \
|
||||
type FMT_RAND_B_SEED; \
|
||||
type FMT420_MEM0_SOURCE_SEL; \
|
||||
type FMT420_MEM0_PWR_FORCE; \
|
||||
type FMT_SRC_SELECT; \
|
||||
type FMT_420_PIXEL_PHASE_LOCKED_CLEAR; \
|
||||
type FMT_420_PIXEL_PHASE_LOCKED; \
|
||||
type FMT_CLAMP_DATA_EN; \
|
||||
type FMT_CLAMP_COLOR_FORMAT; \
|
||||
type FMT_CLAMP_LOWER_R; \
|
||||
type FMT_CLAMP_UPPER_R; \
|
||||
type FMT_CLAMP_LOWER_G; \
|
||||
type FMT_CLAMP_UPPER_G; \
|
||||
type FMT_CLAMP_LOWER_B; \
|
||||
type FMT_CLAMP_UPPER_B; \
|
||||
type FMT_PIXEL_ENCODING; \
|
||||
type FMT_SUBSAMPLING_ORDER; \
|
||||
type FMT_SUBSAMPLING_MODE; \
|
||||
type FMT_CBCR_BIT_REDUCTION_BYPASS;\
|
||||
|
||||
struct dce_opp_shift {
|
||||
OPP_REG_FIELD_LIST(uint8_t)
|
||||
};
|
||||
|
||||
struct dce_opp_mask {
|
||||
OPP_REG_FIELD_LIST(uint32_t)
|
||||
};
|
||||
|
||||
struct dce_opp_registers {
|
||||
uint32_t DCFE_MEM_PWR_CTRL;
|
||||
uint32_t DCFE_MEM_LIGHT_SLEEP_CNTL;
|
||||
uint32_t REGAMMA_CNTLA_START_CNTL;
|
||||
uint32_t REGAMMA_CNTLA_SLOPE_CNTL;
|
||||
uint32_t REGAMMA_CNTLA_END_CNTL1;
|
||||
uint32_t REGAMMA_CNTLA_END_CNTL2;
|
||||
uint32_t REGAMMA_CNTLA_REGION_0_1;
|
||||
uint32_t REGAMMA_CNTLA_REGION_2_3;
|
||||
uint32_t REGAMMA_CNTLA_REGION_4_5;
|
||||
uint32_t REGAMMA_CNTLA_REGION_6_7;
|
||||
uint32_t REGAMMA_CNTLA_REGION_8_9;
|
||||
uint32_t REGAMMA_CNTLA_REGION_10_11;
|
||||
uint32_t REGAMMA_CNTLA_REGION_12_13;
|
||||
uint32_t REGAMMA_CNTLA_REGION_14_15;
|
||||
uint32_t REGAMMA_LUT_WRITE_EN_MASK;
|
||||
uint32_t REGAMMA_LUT_INDEX;
|
||||
uint32_t DCFE_MEM_PWR_STATUS;
|
||||
uint32_t REGAMMA_LUT_DATA;
|
||||
uint32_t REGAMMA_CONTROL;
|
||||
uint32_t OUTPUT_CSC_C11_C12;
|
||||
uint32_t OUTPUT_CSC_C13_C14;
|
||||
uint32_t OUTPUT_CSC_C21_C22;
|
||||
uint32_t OUTPUT_CSC_C23_C24;
|
||||
uint32_t OUTPUT_CSC_C31_C32;
|
||||
uint32_t OUTPUT_CSC_C33_C34;
|
||||
uint32_t OUTPUT_CSC_CONTROL;
|
||||
uint32_t FMT_DYNAMIC_EXP_CNTL;
|
||||
uint32_t FMT_BIT_DEPTH_CONTROL;
|
||||
uint32_t FMT_CONTROL;
|
||||
uint32_t FMT_DITHER_RAND_R_SEED;
|
||||
uint32_t FMT_DITHER_RAND_G_SEED;
|
||||
uint32_t FMT_DITHER_RAND_B_SEED;
|
||||
uint32_t FMT_TEMPORAL_DITHER_PATTERN_CONTROL;
|
||||
uint32_t FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX;
|
||||
uint32_t FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX;
|
||||
uint32_t CONTROL;
|
||||
uint32_t FMT_CLAMP_CNTL;
|
||||
uint32_t FMT_CLAMP_COMPONENT_R;
|
||||
uint32_t FMT_CLAMP_COMPONENT_G;
|
||||
uint32_t FMT_CLAMP_COMPONENT_B;
|
||||
};
|
||||
|
||||
struct dce110_regamma {
|
||||
struct gamma_curve arr_curve_points[16];
|
||||
struct curve_points arr_points[3];
|
||||
uint32_t hw_points_num;
|
||||
struct hw_x_point *coordinates_x;
|
||||
struct pwl_result_data *rgb_resulted;
|
||||
|
||||
/* re-gamma curve */
|
||||
struct pwl_float_data_ex *rgb_regamma;
|
||||
/* coeff used to map user evenly distributed points
|
||||
* to our hardware points (predefined) for gamma 256 */
|
||||
struct pixel_gamma_point *coeff128;
|
||||
struct pixel_gamma_point *coeff128_oem;
|
||||
/* coeff used to map user evenly distributed points
|
||||
* to our hardware points (predefined) for gamma 1025 */
|
||||
struct pixel_gamma_point *coeff128_dx;
|
||||
/* evenly distributed points, gamma 256 software points 0-255 */
|
||||
struct gamma_pixel *axis_x_256;
|
||||
/* evenly distributed points, gamma 1025 software points 0-1025 */
|
||||
struct gamma_pixel *axis_x_1025;
|
||||
/* OEM supplied gamma for regamma LUT */
|
||||
struct pwl_float_data *rgb_oem;
|
||||
/* user supplied gamma */
|
||||
struct pwl_float_data *rgb_user;
|
||||
uint32_t extra_points;
|
||||
bool use_half_points;
|
||||
struct fixed31_32 x_max1;
|
||||
struct fixed31_32 x_max2;
|
||||
struct fixed31_32 x_min;
|
||||
struct fixed31_32 divider1;
|
||||
struct fixed31_32 divider2;
|
||||
struct fixed31_32 divider3;
|
||||
};
|
||||
|
||||
/* OPP RELATED */
|
||||
#define TO_DCE110_OPP(opp)\
|
||||
container_of(opp, struct dce110_opp, base)
|
||||
|
||||
struct dce110_opp {
|
||||
struct output_pixel_processor base;
|
||||
const struct dce_opp_registers *regs;
|
||||
const struct dce_opp_shift *opp_shift;
|
||||
const struct dce_opp_mask *opp_mask;
|
||||
struct dce110_regamma regamma;
|
||||
};
|
||||
|
||||
bool dce110_opp_construct(struct dce110_opp *opp110,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dce_opp_registers *regs,
|
||||
const struct dce_opp_shift *opp_shift,
|
||||
const struct dce_opp_mask *opp_mask);
|
||||
|
||||
void dce110_opp_destroy(struct output_pixel_processor **opp);
|
||||
|
||||
/* REGAMMA RELATED */
|
||||
void dce110_opp_power_on_regamma_lut(
|
||||
struct output_pixel_processor *opp,
|
||||
bool power_on);
|
||||
|
||||
bool dce110_opp_program_regamma_pwl(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct pwl_params *params);
|
||||
|
||||
void dce110_opp_set_regamma_mode(struct output_pixel_processor *opp,
|
||||
enum opp_regamma mode);
|
||||
|
||||
void dce110_opp_set_csc_adjustment(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct out_csc_color_matrix *tbl_entry);
|
||||
|
||||
void dce110_opp_set_csc_default(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct default_adjustment *default_adjust);
|
||||
|
||||
/* FORMATTER RELATED */
|
||||
void dce110_opp_program_bit_depth_reduction(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct bit_depth_reduction_params *params);
|
||||
|
||||
void dce110_opp_program_clamping_and_pixel_encoding(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct clamping_and_pixel_encoding_params *params);
|
||||
|
||||
void dce110_opp_set_dyn_expansion(
|
||||
struct output_pixel_processor *opp,
|
||||
enum dc_color_space color_sp,
|
||||
enum dc_color_depth color_dpth,
|
||||
enum signal_type signal);
|
||||
|
||||
void dce110_opp_program_fmt(
|
||||
struct output_pixel_processor *opp,
|
||||
struct bit_depth_reduction_params *fmt_bit_depth,
|
||||
struct clamping_and_pixel_encoding_params *clamping);
|
||||
|
||||
void dce110_opp_set_clamping(
|
||||
struct dce110_opp *opp110,
|
||||
const struct clamping_and_pixel_encoding_params *params);
|
||||
|
||||
#endif
|
@ -39,7 +39,7 @@
|
||||
#include "dce110/dce110_mem_input_v.h"
|
||||
#include "dce110/dce110_ipp.h"
|
||||
#include "dce/dce_transform.h"
|
||||
#include "dce110/dce110_opp.h"
|
||||
#include "dce/dce_opp.h"
|
||||
#include "dce/dce_clocks.h"
|
||||
#include "dce/dce_clock_source.h"
|
||||
#include "dce/dce_audio.h"
|
||||
@ -302,6 +302,29 @@ static const struct dce_stream_encoder_mask se_mask = {
|
||||
SE_COMMON_MASK_SH_LIST_DCE80_100(_MASK)
|
||||
};
|
||||
|
||||
#define opp_regs(id)\
|
||||
[id] = {\
|
||||
OPP_DCE_100_REG_LIST(id),\
|
||||
}
|
||||
|
||||
static const struct dce_opp_registers opp_regs[] = {
|
||||
opp_regs(0),
|
||||
opp_regs(1),
|
||||
opp_regs(2),
|
||||
opp_regs(3),
|
||||
opp_regs(4),
|
||||
opp_regs(5)
|
||||
};
|
||||
|
||||
static const struct dce_opp_shift opp_shift = {
|
||||
OPP_COMMON_MASK_SH_LIST_DCE_100(__SHIFT)
|
||||
};
|
||||
|
||||
static const struct dce_opp_mask opp_mask = {
|
||||
OPP_COMMON_MASK_SH_LIST_DCE_100(_MASK)
|
||||
};
|
||||
|
||||
|
||||
#define audio_regs(id)\
|
||||
[id] = {\
|
||||
AUD_COMMON_REG_LIST(id)\
|
||||
@ -348,35 +371,6 @@ static const struct dce110_clk_src_mask cs_mask = {
|
||||
|
||||
#define DCFE_MEM_PWR_CTRL_REG_BASE 0x1b03
|
||||
|
||||
static const struct dce110_opp_reg_offsets dce100_opp_reg_offsets[] = {
|
||||
{
|
||||
.fmt_offset = (mmFMT0_FMT_CONTROL - mmFMT_CONTROL),
|
||||
.dcfe_offset = (mmCRTC0_DCFE_MEM_PWR_CTRL - DCFE_MEM_PWR_CTRL_REG_BASE),
|
||||
.dcp_offset = (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT1_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.dcfe_offset = (mmCRTC1_DCFE_MEM_PWR_CTRL - DCFE_MEM_PWR_CTRL_REG_BASE),
|
||||
.dcp_offset = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT2_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.dcfe_offset = (mmCRTC2_DCFE_MEM_PWR_CTRL - DCFE_MEM_PWR_CTRL_REG_BASE),
|
||||
.dcp_offset = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{
|
||||
.fmt_offset = (mmFMT3_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.dcfe_offset = (mmCRTC3_DCFE_MEM_PWR_CTRL - DCFE_MEM_PWR_CTRL_REG_BASE),
|
||||
.dcp_offset = (mmDCP3_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT4_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.dcfe_offset = (mmCRTC4_DCFE_MEM_PWR_CTRL - DCFE_MEM_PWR_CTRL_REG_BASE),
|
||||
.dcp_offset = (mmDCP4_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT5_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.dcfe_offset = (mmCRTC5_DCFE_MEM_PWR_CTRL - DCFE_MEM_PWR_CTRL_REG_BASE),
|
||||
.dcp_offset = (mmDCP5_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct bios_registers bios_regs = {
|
||||
.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
|
||||
};
|
||||
@ -615,8 +609,7 @@ struct link_encoder *dce100_link_encoder_create(
|
||||
|
||||
struct output_pixel_processor *dce100_opp_create(
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dce110_opp_reg_offsets *offset)
|
||||
uint32_t inst)
|
||||
{
|
||||
struct dce110_opp *opp =
|
||||
dm_alloc(sizeof(struct dce110_opp));
|
||||
@ -625,7 +618,7 @@ struct output_pixel_processor *dce100_opp_create(
|
||||
return NULL;
|
||||
|
||||
if (dce110_opp_construct(opp,
|
||||
ctx, inst, offset))
|
||||
ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask))
|
||||
return &opp->base;
|
||||
|
||||
BREAK_TO_DEBUGGER();
|
||||
@ -1052,7 +1045,7 @@ static bool construct(
|
||||
goto res_create_fail;
|
||||
}
|
||||
|
||||
pool->base.opps[i] = dce100_opp_create(ctx, i, &dce100_opp_reg_offsets[i]);
|
||||
pool->base.opps[i] = dce100_opp_create(ctx, i);
|
||||
if (pool->base.opps[i] == NULL) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
dm_error(
|
||||
|
@ -3,8 +3,8 @@
|
||||
# It provides the control and status of HW CRTC block.
|
||||
|
||||
DCE110 = dce110_ipp.o dce110_ipp_cursor.o \
|
||||
dce110_ipp_gamma.o dce110_opp.o dce110_opp_csc.o \
|
||||
dce110_timing_generator.o dce110_opp_formatter.o dce110_opp_regamma.o \
|
||||
dce110_ipp_gamma.o \
|
||||
dce110_timing_generator.o \
|
||||
dce110_compressor.o dce110_mem_input.o dce110_hw_sequencer.o \
|
||||
dce110_resource.o \
|
||||
dce110_opp_regamma_v.o dce110_opp_csc_v.o dce110_timing_generator_v.o \
|
||||
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
/* include DCE11 register header files */
|
||||
#include "dce/dce_11_0_d.h"
|
||||
#include "dce/dce_11_0_sh_mask.h"
|
||||
|
||||
#include "dce110_opp.h"
|
||||
|
||||
#include "gamma_types.h"
|
||||
|
||||
enum {
|
||||
MAX_LUT_ENTRY = 256,
|
||||
MAX_NUMBER_OF_ENTRIES = 256
|
||||
};
|
||||
|
||||
/*****************************************/
|
||||
/* Constructor, Destructor */
|
||||
/*****************************************/
|
||||
|
||||
static const struct opp_funcs funcs = {
|
||||
.opp_power_on_regamma_lut = dce110_opp_power_on_regamma_lut,
|
||||
.opp_set_csc_adjustment = dce110_opp_set_csc_adjustment,
|
||||
.opp_set_csc_default = dce110_opp_set_csc_default,
|
||||
.opp_set_dyn_expansion = dce110_opp_set_dyn_expansion,
|
||||
.opp_program_regamma_pwl = dce110_opp_program_regamma_pwl,
|
||||
.opp_set_regamma_mode = dce110_opp_set_regamma_mode,
|
||||
.opp_destroy = dce110_opp_destroy,
|
||||
.opp_program_fmt = dce110_opp_program_fmt,
|
||||
};
|
||||
|
||||
bool dce110_opp_construct(struct dce110_opp *opp110,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dce110_opp_reg_offsets *offsets)
|
||||
{
|
||||
opp110->base.funcs = &funcs;
|
||||
|
||||
opp110->base.ctx = ctx;
|
||||
|
||||
opp110->base.inst = inst;
|
||||
|
||||
opp110->offsets = *offsets;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dce110_opp_destroy(struct output_pixel_processor **opp)
|
||||
{
|
||||
dm_free(FROM_DCE11_OPP(*opp));
|
||||
*opp = NULL;
|
||||
}
|
||||
|
@ -1,149 +0,0 @@
|
||||
/* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_OPP_DCE110_H__
|
||||
#define __DC_OPP_DCE110_H__
|
||||
|
||||
#include "dc_types.h"
|
||||
#include "opp.h"
|
||||
#include "core_types.h"
|
||||
|
||||
#include "gamma_types.h" /* decprecated */
|
||||
|
||||
struct gamma_parameters;
|
||||
|
||||
#define FROM_DCE11_OPP(opp)\
|
||||
container_of(opp, struct dce110_opp, base)
|
||||
|
||||
enum dce110_opp_reg_type {
|
||||
DCE110_OPP_REG_DCP = 0,
|
||||
DCE110_OPP_REG_DCFE,
|
||||
DCE110_OPP_REG_FMT,
|
||||
|
||||
DCE110_OPP_REG_MAX
|
||||
};
|
||||
|
||||
struct dce110_regamma {
|
||||
struct gamma_curve arr_curve_points[16];
|
||||
struct curve_points arr_points[3];
|
||||
uint32_t hw_points_num;
|
||||
struct hw_x_point *coordinates_x;
|
||||
struct pwl_result_data *rgb_resulted;
|
||||
|
||||
/* re-gamma curve */
|
||||
struct pwl_float_data_ex *rgb_regamma;
|
||||
/* coeff used to map user evenly distributed points
|
||||
* to our hardware points (predefined) for gamma 256 */
|
||||
struct pixel_gamma_point *coeff128;
|
||||
struct pixel_gamma_point *coeff128_oem;
|
||||
/* coeff used to map user evenly distributed points
|
||||
* to our hardware points (predefined) for gamma 1025 */
|
||||
struct pixel_gamma_point *coeff128_dx;
|
||||
/* evenly distributed points, gamma 256 software points 0-255 */
|
||||
struct gamma_pixel *axis_x_256;
|
||||
/* evenly distributed points, gamma 1025 software points 0-1025 */
|
||||
struct gamma_pixel *axis_x_1025;
|
||||
/* OEM supplied gamma for regamma LUT */
|
||||
struct pwl_float_data *rgb_oem;
|
||||
/* user supplied gamma */
|
||||
struct pwl_float_data *rgb_user;
|
||||
uint32_t extra_points;
|
||||
bool use_half_points;
|
||||
struct fixed31_32 x_max1;
|
||||
struct fixed31_32 x_max2;
|
||||
struct fixed31_32 x_min;
|
||||
struct fixed31_32 divider1;
|
||||
struct fixed31_32 divider2;
|
||||
struct fixed31_32 divider3;
|
||||
};
|
||||
|
||||
/* OPP RELATED */
|
||||
#define TO_DCE110_OPP(opp)\
|
||||
container_of(opp, struct dce110_opp, base)
|
||||
|
||||
struct dce110_opp_reg_offsets {
|
||||
uint32_t fmt_offset;
|
||||
uint32_t fmt_mem_offset;
|
||||
uint32_t dcp_offset;
|
||||
uint32_t dcfe_offset;
|
||||
};
|
||||
|
||||
struct dce110_opp {
|
||||
struct output_pixel_processor base;
|
||||
struct dce110_opp_reg_offsets offsets;
|
||||
struct dce110_regamma regamma;
|
||||
};
|
||||
|
||||
bool dce110_opp_construct(struct dce110_opp *opp110,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dce110_opp_reg_offsets *offsets);
|
||||
|
||||
void dce110_opp_destroy(struct output_pixel_processor **opp);
|
||||
|
||||
/* REGAMMA RELATED */
|
||||
void dce110_opp_power_on_regamma_lut(
|
||||
struct output_pixel_processor *opp,
|
||||
bool power_on);
|
||||
|
||||
bool dce110_opp_program_regamma_pwl(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct pwl_params *params);
|
||||
|
||||
void dce110_opp_set_regamma_mode(struct output_pixel_processor *opp,
|
||||
enum opp_regamma mode);
|
||||
|
||||
void dce110_opp_set_csc_adjustment(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct out_csc_color_matrix *tbl_entry);
|
||||
|
||||
void dce110_opp_set_csc_default(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct default_adjustment *default_adjust);
|
||||
|
||||
/* FORMATTER RELATED */
|
||||
void dce110_opp_program_bit_depth_reduction(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct bit_depth_reduction_params *params);
|
||||
|
||||
void dce110_opp_program_clamping_and_pixel_encoding(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct clamping_and_pixel_encoding_params *params);
|
||||
|
||||
void dce110_opp_set_dyn_expansion(
|
||||
struct output_pixel_processor *opp,
|
||||
enum dc_color_space color_sp,
|
||||
enum dc_color_depth color_dpth,
|
||||
enum signal_type signal);
|
||||
|
||||
void dce110_opp_program_fmt(
|
||||
struct output_pixel_processor *opp,
|
||||
struct bit_depth_reduction_params *fmt_bit_depth,
|
||||
struct clamping_and_pixel_encoding_params *clamping);
|
||||
|
||||
void dce110_opp_set_clamping(
|
||||
struct dce110_opp *opp110,
|
||||
const struct clamping_and_pixel_encoding_params *params);
|
||||
|
||||
#endif
|
@ -1,363 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "dce110_opp.h"
|
||||
#include "basics/conversion.h"
|
||||
|
||||
/* include DCE11 register header files */
|
||||
#include "dce/dce_11_0_d.h"
|
||||
#include "dce/dce_11_0_sh_mask.h"
|
||||
|
||||
#define DCP_REG(reg)\
|
||||
(reg + opp110->offsets.dcp_offset)
|
||||
|
||||
enum {
|
||||
OUTPUT_CSC_MATRIX_SIZE = 12
|
||||
};
|
||||
|
||||
static const struct out_csc_color_matrix global_color_matrix[] = {
|
||||
{ COLOR_SPACE_SRGB,
|
||||
{ 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
|
||||
{ COLOR_SPACE_SRGB_LIMITED,
|
||||
{ 0x1B60, 0, 0, 0x200, 0, 0x1B60, 0, 0x200, 0, 0, 0x1B60, 0x200} },
|
||||
{ COLOR_SPACE_YCBCR601,
|
||||
{ 0xE00, 0xF447, 0xFDB9, 0x1000, 0x82F, 0x1012, 0x31F, 0x200, 0xFB47,
|
||||
0xF6B9, 0xE00, 0x1000} },
|
||||
{ COLOR_SPACE_YCBCR709, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x5D2, 0x1394, 0x1FA,
|
||||
0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
|
||||
/* TODO: correct values below */
|
||||
{ COLOR_SPACE_YCBCR601_LIMITED, { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
|
||||
0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
|
||||
{ COLOR_SPACE_YCBCR709_LIMITED, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
|
||||
0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }
|
||||
};
|
||||
|
||||
enum csc_color_mode {
|
||||
/* 00 - BITS2:0 Bypass */
|
||||
CSC_COLOR_MODE_GRAPHICS_BYPASS,
|
||||
/* 01 - hard coded coefficient TV RGB */
|
||||
CSC_COLOR_MODE_GRAPHICS_PREDEFINED,
|
||||
/* 04 - programmable OUTPUT CSC coefficient */
|
||||
CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC,
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void dce110_opp_set_csc_adjustment(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct out_csc_color_matrix *tbl_entry)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
enum csc_color_mode config =
|
||||
CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
|
||||
|
||||
program_color_matrix(
|
||||
opp110, tbl_entry, GRAPHICS_CSC_ADJUST_TYPE_SW);
|
||||
|
||||
/* We did everything ,now program DxOUTPUT_CSC_CONTROL */
|
||||
configure_graphics_mode(opp110, config, GRAPHICS_CSC_ADJUST_TYPE_SW,
|
||||
tbl_entry->color_space);
|
||||
}
|
||||
|
||||
void dce110_opp_set_csc_default(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct default_adjustment *default_adjust)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
enum csc_color_mode config =
|
||||
CSC_COLOR_MODE_GRAPHICS_PREDEFINED;
|
||||
|
||||
if (default_adjust->force_hw_default == false) {
|
||||
const struct out_csc_color_matrix *elm;
|
||||
/* currently parameter not in use */
|
||||
enum grph_color_adjust_option option =
|
||||
GRPH_COLOR_MATRIX_HW_DEFAULT;
|
||||
uint32_t i;
|
||||
/*
|
||||
* HW default false we program locally defined matrix
|
||||
* HW default true we use predefined hw matrix and we
|
||||
* do not need to program matrix
|
||||
* OEM wants the HW default via runtime parameter.
|
||||
*/
|
||||
option = GRPH_COLOR_MATRIX_SW;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(global_color_matrix); ++i) {
|
||||
elm = &global_color_matrix[i];
|
||||
if (elm->color_space != default_adjust->out_color_space)
|
||||
continue;
|
||||
/* program the matrix with default values from this
|
||||
* file */
|
||||
program_color_matrix(opp110, elm, option);
|
||||
config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* configure the what we programmed :
|
||||
* 1. Default values from this file
|
||||
* 2. Use hardware default from ROM_A and we do not need to program
|
||||
* matrix */
|
||||
|
||||
configure_graphics_mode(opp110, config,
|
||||
default_adjust->csc_adjust_type,
|
||||
default_adjust->out_color_space);
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "dce110_opp.h"
|
||||
#include "dce/dce_opp.h"
|
||||
#include "basics/conversion.h"
|
||||
|
||||
/* include DCE11 register header files */
|
||||
|
@ -1,627 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
#include "dce/dce_11_0_d.h"
|
||||
#include "dce/dce_11_0_sh_mask.h"
|
||||
|
||||
#include "dce110_opp.h"
|
||||
|
||||
#define FMT_REG(reg)\
|
||||
(reg + opp110->offsets.fmt_offset)
|
||||
/**
|
||||
* set_truncation
|
||||
* 1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp
|
||||
* 2) enable truncation
|
||||
* 3) HW remove 12bit FMT support for DCE11 power saving reason.
|
||||
*/
|
||||
static void set_truncation(
|
||||
struct dce110_opp *opp110,
|
||||
const struct bit_depth_reduction_params *params)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
uint32_t addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
|
||||
|
||||
/*Disable truncation*/
|
||||
value = dm_read_reg(opp110->base.ctx, addr);
|
||||
set_reg_field_value(value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN);
|
||||
set_reg_field_value(value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_DEPTH);
|
||||
set_reg_field_value(value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_MODE);
|
||||
|
||||
dm_write_reg(opp110->base.ctx, addr, value);
|
||||
|
||||
/* no 10bpc trunc on DCE11*/
|
||||
if (params->flags.TRUNCATE_ENABLED == 0 ||
|
||||
params->flags.TRUNCATE_DEPTH == 2)
|
||||
return;
|
||||
|
||||
/*Set truncation depth and Enable truncation*/
|
||||
set_reg_field_value(value, 1,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN);
|
||||
set_reg_field_value(value, params->flags.TRUNCATE_MODE,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_MODE);
|
||||
set_reg_field_value(value, params->flags.TRUNCATE_DEPTH,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_DEPTH);
|
||||
|
||||
dm_write_reg(opp110->base.ctx, addr, value);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* set_spatial_dither
|
||||
* 1) set spatial dithering mode: pattern of seed
|
||||
* 2) set spatical dithering depth: 0 for 18bpp or 1 for 24bpp
|
||||
* 3) set random seed
|
||||
* 4) set random mode
|
||||
* lfsr is reset every frame or not reset
|
||||
* RGB dithering method
|
||||
* 0: RGB data are all dithered with x^28+x^3+1
|
||||
* 1: R data is dithered with x^28+x^3+1
|
||||
* G data is dithered with x^28+X^9+1
|
||||
* B data is dithered with x^28+x^13+1
|
||||
* enable high pass filter or not
|
||||
* 5) enable spatical dithering
|
||||
*/
|
||||
static void set_spatial_dither(
|
||||
struct dce110_opp *opp110,
|
||||
const struct bit_depth_reduction_params *params)
|
||||
{
|
||||
uint32_t addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
|
||||
uint32_t depth_cntl_value = 0;
|
||||
uint32_t fmt_cntl_value = 0;
|
||||
uint32_t dither_r_value = 0;
|
||||
uint32_t dither_g_value = 0;
|
||||
uint32_t dither_b_value = 0;
|
||||
|
||||
/*Disable spatial (random) dithering*/
|
||||
depth_cntl_value = dm_read_reg(opp110->base.ctx, addr);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_EN);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_MODE);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_DEPTH);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_EN);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_HIGHPASS_RANDOM_ENABLE);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_FRAME_RANDOM_ENABLE);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_RGB_RANDOM_ENABLE);
|
||||
|
||||
dm_write_reg(opp110->base.ctx, addr, depth_cntl_value);
|
||||
|
||||
/* no 10bpc on DCE11*/
|
||||
if (params->flags.SPATIAL_DITHER_ENABLED == 0 ||
|
||||
params->flags.SPATIAL_DITHER_DEPTH == 2)
|
||||
return;
|
||||
|
||||
addr = FMT_REG(mmFMT_CONTROL);
|
||||
fmt_cntl_value = dm_read_reg(opp110->base.ctx, addr);
|
||||
/* only use FRAME_COUNTER_MAX if frameRandom == 1*/
|
||||
if (params->flags.FRAME_RANDOM == 1) {
|
||||
if (params->flags.SPATIAL_DITHER_DEPTH == 0 ||
|
||||
params->flags.SPATIAL_DITHER_DEPTH == 1) {
|
||||
set_reg_field_value(fmt_cntl_value, 15,
|
||||
FMT_CONTROL,
|
||||
FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX);
|
||||
set_reg_field_value(fmt_cntl_value, 2,
|
||||
FMT_CONTROL,
|
||||
FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP);
|
||||
} else if (params->flags.SPATIAL_DITHER_DEPTH == 2) {
|
||||
set_reg_field_value(fmt_cntl_value, 3,
|
||||
FMT_CONTROL,
|
||||
FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX);
|
||||
set_reg_field_value(fmt_cntl_value, 1,
|
||||
FMT_CONTROL,
|
||||
FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP);
|
||||
} else
|
||||
return;
|
||||
} else {
|
||||
set_reg_field_value(fmt_cntl_value, 0,
|
||||
FMT_CONTROL,
|
||||
FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX);
|
||||
set_reg_field_value(fmt_cntl_value, 0,
|
||||
FMT_CONTROL,
|
||||
FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP);
|
||||
}
|
||||
|
||||
dm_write_reg(opp110->base.ctx, addr, fmt_cntl_value);
|
||||
|
||||
/*Set seed for random values for
|
||||
* spatial dithering for R,G,B channels*/
|
||||
addr = FMT_REG(mmFMT_DITHER_RAND_R_SEED);
|
||||
set_reg_field_value(dither_r_value, params->r_seed_value,
|
||||
FMT_DITHER_RAND_R_SEED,
|
||||
FMT_RAND_R_SEED);
|
||||
dm_write_reg(opp110->base.ctx, addr, dither_r_value);
|
||||
|
||||
addr = FMT_REG(mmFMT_DITHER_RAND_G_SEED);
|
||||
set_reg_field_value(dither_g_value,
|
||||
params->g_seed_value,
|
||||
FMT_DITHER_RAND_G_SEED,
|
||||
FMT_RAND_G_SEED);
|
||||
dm_write_reg(opp110->base.ctx, addr, dither_g_value);
|
||||
|
||||
addr = FMT_REG(mmFMT_DITHER_RAND_B_SEED);
|
||||
set_reg_field_value(dither_b_value, params->b_seed_value,
|
||||
FMT_DITHER_RAND_B_SEED,
|
||||
FMT_RAND_B_SEED);
|
||||
dm_write_reg(opp110->base.ctx, addr, dither_b_value);
|
||||
|
||||
/* FMT_OFFSET_R_Cr 31:16 0x0 Setting the zero
|
||||
* offset for the R/Cr channel, lower 4LSB
|
||||
* is forced to zeros. Typically set to 0
|
||||
* RGB and 0x80000 YCbCr.
|
||||
*/
|
||||
/* FMT_OFFSET_G_Y 31:16 0x0 Setting the zero
|
||||
* offset for the G/Y channel, lower 4LSB is
|
||||
* forced to zeros. Typically set to 0 RGB
|
||||
* and 0x80000 YCbCr.
|
||||
*/
|
||||
/* FMT_OFFSET_B_Cb 31:16 0x0 Setting the zero
|
||||
* offset for the B/Cb channel, lower 4LSB is
|
||||
* forced to zeros. Typically set to 0 RGB and
|
||||
* 0x80000 YCbCr.
|
||||
*/
|
||||
|
||||
/*Set spatial dithering bit depth*/
|
||||
set_reg_field_value(depth_cntl_value,
|
||||
params->flags.SPATIAL_DITHER_DEPTH,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_SPATIAL_DITHER_DEPTH);
|
||||
|
||||
/* Set spatial dithering mode
|
||||
* (default is Seed patterrn AAAA...)
|
||||
*/
|
||||
set_reg_field_value(depth_cntl_value,
|
||||
params->flags.SPATIAL_DITHER_MODE,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_SPATIAL_DITHER_MODE);
|
||||
|
||||
/*Reset only at startup*/
|
||||
set_reg_field_value(depth_cntl_value,
|
||||
params->flags.FRAME_RANDOM,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_FRAME_RANDOM_ENABLE);
|
||||
|
||||
/*Set RGB data dithered with x^28+x^3+1*/
|
||||
set_reg_field_value(depth_cntl_value,
|
||||
params->flags.RGB_RANDOM,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_RGB_RANDOM_ENABLE);
|
||||
|
||||
/*Disable High pass filter*/
|
||||
set_reg_field_value(depth_cntl_value,
|
||||
params->flags.HIGHPASS_RANDOM,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_HIGHPASS_RANDOM_ENABLE);
|
||||
|
||||
/*Enable spatial dithering*/
|
||||
set_reg_field_value(depth_cntl_value,
|
||||
1,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_SPATIAL_DITHER_EN);
|
||||
|
||||
addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
|
||||
dm_write_reg(opp110->base.ctx, addr, depth_cntl_value);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* SetTemporalDither (Frame Modulation)
|
||||
* 1) set temporal dither depth
|
||||
* 2) select pattern: from hard-coded pattern or programmable pattern
|
||||
* 3) select optimized strips for BGR or RGB LCD sub-pixel
|
||||
* 4) set s matrix
|
||||
* 5) set t matrix
|
||||
* 6) set grey level for 0.25, 0.5, 0.75
|
||||
* 7) enable temporal dithering
|
||||
*/
|
||||
static void set_temporal_dither(
|
||||
struct dce110_opp *opp110,
|
||||
const struct bit_depth_reduction_params *params)
|
||||
{
|
||||
uint32_t addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
|
||||
uint32_t value;
|
||||
|
||||
/*Disable temporal (frame modulation) dithering first*/
|
||||
value = dm_read_reg(opp110->base.ctx, addr);
|
||||
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_EN);
|
||||
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_RESET);
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_OFFSET);
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_DEPTH);
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_LEVEL);
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_25FRC_SEL);
|
||||
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_50FRC_SEL);
|
||||
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_75FRC_SEL);
|
||||
|
||||
dm_write_reg(opp110->base.ctx, addr, value);
|
||||
|
||||
/* no 10bpc dither on DCE11*/
|
||||
if (params->flags.FRAME_MODULATION_ENABLED == 0 ||
|
||||
params->flags.FRAME_MODULATION_DEPTH == 2)
|
||||
return;
|
||||
|
||||
/* Set temporal dithering depth*/
|
||||
set_reg_field_value(value,
|
||||
params->flags.FRAME_MODULATION_DEPTH,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_DEPTH);
|
||||
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_RESET);
|
||||
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_OFFSET);
|
||||
|
||||
/*Select legacy pattern based on FRC and Temporal level*/
|
||||
addr = FMT_REG(mmFMT_TEMPORAL_DITHER_PATTERN_CONTROL);
|
||||
dm_write_reg(opp110->base.ctx, addr, 0);
|
||||
/*Set s matrix*/
|
||||
addr = FMT_REG(
|
||||
mmFMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX);
|
||||
dm_write_reg(opp110->base.ctx, addr, 0);
|
||||
/*Set t matrix*/
|
||||
addr = FMT_REG(
|
||||
mmFMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX);
|
||||
dm_write_reg(opp110->base.ctx, addr, 0);
|
||||
|
||||
/*Select patterns for 0.25, 0.5 and 0.75 grey level*/
|
||||
set_reg_field_value(value,
|
||||
params->flags.TEMPORAL_LEVEL,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_LEVEL);
|
||||
|
||||
set_reg_field_value(value,
|
||||
params->flags.FRC25,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_25FRC_SEL);
|
||||
|
||||
set_reg_field_value(value,
|
||||
params->flags.FRC50,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_50FRC_SEL);
|
||||
|
||||
set_reg_field_value(value,
|
||||
params->flags.FRC75,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_75FRC_SEL);
|
||||
|
||||
/*Enable bit reduction by temporal (frame modulation) dithering*/
|
||||
set_reg_field_value(value,
|
||||
1,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_EN);
|
||||
|
||||
addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
|
||||
dm_write_reg(opp110->base.ctx, addr, value);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Clamping
|
||||
* 1) Set clamping format based on bpc - 0 for 6bpc (No clamping)
|
||||
* 1 for 8 bpc
|
||||
* 2 for 10 bpc
|
||||
* 3 for 12 bpc
|
||||
* 7 for programable
|
||||
* 2) Enable clamp if Limited range requested
|
||||
*/
|
||||
void dce110_opp_set_clamping(
|
||||
struct dce110_opp *opp110,
|
||||
const struct clamping_and_pixel_encoding_params *params)
|
||||
{
|
||||
uint32_t clamp_cntl_value = 0;
|
||||
uint32_t red_clamp_value = 0;
|
||||
uint32_t green_clamp_value = 0;
|
||||
uint32_t blue_clamp_value = 0;
|
||||
uint32_t addr = FMT_REG(mmFMT_CLAMP_CNTL);
|
||||
|
||||
clamp_cntl_value = dm_read_reg(opp110->base.ctx, addr);
|
||||
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
0,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_DATA_EN);
|
||||
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
0,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_COLOR_FORMAT);
|
||||
|
||||
switch (params->clamping_level) {
|
||||
case CLAMPING_FULL_RANGE:
|
||||
break;
|
||||
|
||||
case CLAMPING_LIMITED_RANGE_8BPC:
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
1,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_DATA_EN);
|
||||
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
1,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_COLOR_FORMAT);
|
||||
|
||||
break;
|
||||
|
||||
case CLAMPING_LIMITED_RANGE_10BPC:
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
1,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_DATA_EN);
|
||||
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
2,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_COLOR_FORMAT);
|
||||
|
||||
break;
|
||||
case CLAMPING_LIMITED_RANGE_12BPC:
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
1,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_DATA_EN);
|
||||
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
3,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_COLOR_FORMAT);
|
||||
|
||||
break;
|
||||
case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
1,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_DATA_EN);
|
||||
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
7,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_COLOR_FORMAT);
|
||||
|
||||
/*set the defaults*/
|
||||
set_reg_field_value(red_clamp_value,
|
||||
0x10,
|
||||
FMT_CLAMP_COMPONENT_R,
|
||||
FMT_CLAMP_LOWER_R);
|
||||
|
||||
set_reg_field_value(red_clamp_value,
|
||||
0xFEF,
|
||||
FMT_CLAMP_COMPONENT_R,
|
||||
FMT_CLAMP_UPPER_R);
|
||||
|
||||
addr = FMT_REG(mmFMT_CLAMP_COMPONENT_R);
|
||||
dm_write_reg(opp110->base.ctx, addr, red_clamp_value);
|
||||
|
||||
set_reg_field_value(green_clamp_value,
|
||||
0x10,
|
||||
FMT_CLAMP_COMPONENT_G,
|
||||
FMT_CLAMP_LOWER_G);
|
||||
|
||||
set_reg_field_value(green_clamp_value,
|
||||
0xFEF,
|
||||
FMT_CLAMP_COMPONENT_G,
|
||||
FMT_CLAMP_UPPER_G);
|
||||
|
||||
addr = FMT_REG(mmFMT_CLAMP_COMPONENT_G);
|
||||
dm_write_reg(opp110->base.ctx, addr, green_clamp_value);
|
||||
|
||||
set_reg_field_value(blue_clamp_value,
|
||||
0x10,
|
||||
FMT_CLAMP_COMPONENT_B,
|
||||
FMT_CLAMP_LOWER_B);
|
||||
|
||||
set_reg_field_value(blue_clamp_value,
|
||||
0xFEF,
|
||||
FMT_CLAMP_COMPONENT_B,
|
||||
FMT_CLAMP_UPPER_B);
|
||||
|
||||
addr = FMT_REG(mmFMT_CLAMP_COMPONENT_B);
|
||||
dm_write_reg(opp110->base.ctx, addr, blue_clamp_value);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
addr = FMT_REG(mmFMT_CLAMP_CNTL);
|
||||
/*Set clamp control*/
|
||||
dm_write_reg(opp110->base.ctx, addr, clamp_cntl_value);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* set_pixel_encoding
|
||||
*
|
||||
* Set Pixel Encoding
|
||||
* 0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly
|
||||
* 1: YCbCr 4:2:2
|
||||
*/
|
||||
static void set_pixel_encoding(
|
||||
struct dce110_opp *opp110,
|
||||
const struct clamping_and_pixel_encoding_params *params)
|
||||
{
|
||||
uint32_t fmt_cntl_value;
|
||||
uint32_t addr = FMT_REG(mmFMT_CONTROL);
|
||||
|
||||
/*RGB 4:4:4 or YCbCr 4:4:4 - 0; YCbCr 4:2:2 -1.*/
|
||||
fmt_cntl_value = dm_read_reg(opp110->base.ctx, addr);
|
||||
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
0,
|
||||
FMT_CONTROL,
|
||||
FMT_PIXEL_ENCODING);
|
||||
|
||||
if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
1,
|
||||
FMT_CONTROL,
|
||||
FMT_PIXEL_ENCODING);
|
||||
|
||||
/*00 - Pixels drop mode ,01 - Pixels average mode*/
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
0,
|
||||
FMT_CONTROL,
|
||||
FMT_SUBSAMPLING_MODE);
|
||||
|
||||
/*00 - Cb before Cr ,01 - Cr before Cb*/
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
0,
|
||||
FMT_CONTROL,
|
||||
FMT_SUBSAMPLING_ORDER);
|
||||
}
|
||||
dm_write_reg(opp110->base.ctx, addr, fmt_cntl_value);
|
||||
|
||||
}
|
||||
|
||||
void dce110_opp_program_bit_depth_reduction(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct bit_depth_reduction_params *params)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
|
||||
set_truncation(opp110, params);
|
||||
set_spatial_dither(opp110, params);
|
||||
set_temporal_dither(opp110, params);
|
||||
}
|
||||
|
||||
void dce110_opp_program_clamping_and_pixel_encoding(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct clamping_and_pixel_encoding_params *params)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
|
||||
dce110_opp_set_clamping(opp110, params);
|
||||
set_pixel_encoding(opp110, params);
|
||||
}
|
||||
|
||||
void dce110_opp_set_dyn_expansion(
|
||||
struct output_pixel_processor *opp,
|
||||
enum dc_color_space color_sp,
|
||||
enum dc_color_depth color_dpth,
|
||||
enum signal_type signal)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
uint32_t value;
|
||||
bool enable_dyn_exp = false;
|
||||
uint32_t addr = FMT_REG(mmFMT_DYNAMIC_EXP_CNTL);
|
||||
|
||||
value = dm_read_reg(opp->ctx, addr);
|
||||
|
||||
set_reg_field_value(value, 0,
|
||||
FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN);
|
||||
set_reg_field_value(value, 0,
|
||||
FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE);
|
||||
|
||||
/* From HW programming guide:
|
||||
FMT_DYNAMIC_EXP_EN = 0 for limited RGB or YCbCr output
|
||||
FMT_DYNAMIC_EXP_EN = 1 for RGB full range only*/
|
||||
if (color_sp == COLOR_SPACE_SRGB)
|
||||
enable_dyn_exp = true;
|
||||
|
||||
/*00 - 10-bit -> 12-bit dynamic expansion*/
|
||||
/*01 - 8-bit -> 12-bit dynamic expansion*/
|
||||
if (signal == SIGNAL_TYPE_HDMI_TYPE_A) {
|
||||
switch (color_dpth) {
|
||||
case COLOR_DEPTH_888:
|
||||
set_reg_field_value(value, enable_dyn_exp ? 1:0,
|
||||
FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN);
|
||||
set_reg_field_value(value, 1,
|
||||
FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE);
|
||||
break;
|
||||
case COLOR_DEPTH_101010:
|
||||
set_reg_field_value(value, enable_dyn_exp ? 1:0,
|
||||
FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN);
|
||||
set_reg_field_value(value, 0,
|
||||
FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE);
|
||||
break;
|
||||
case COLOR_DEPTH_121212:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dm_write_reg(opp->ctx, addr, value);
|
||||
}
|
||||
|
||||
void dce110_opp_program_fmt(
|
||||
struct output_pixel_processor *opp,
|
||||
struct bit_depth_reduction_params *fmt_bit_depth,
|
||||
struct clamping_and_pixel_encoding_params *clamping)
|
||||
{
|
||||
/* dithering is affected by <CrtcSourceSelect>, hence should be
|
||||
* programmed afterwards */
|
||||
dce110_opp_program_bit_depth_reduction(
|
||||
opp,
|
||||
fmt_bit_depth);
|
||||
|
||||
dce110_opp_program_clamping_and_pixel_encoding(
|
||||
opp,
|
||||
clamping);
|
||||
|
||||
return;
|
||||
}
|
@ -1,537 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
/* include DCE11 register header files */
|
||||
#include "dce/dce_11_0_d.h"
|
||||
#include "dce/dce_11_0_sh_mask.h"
|
||||
|
||||
#include "dce110_opp.h"
|
||||
#include "gamma_types.h"
|
||||
|
||||
#define DCP_REG(reg)\
|
||||
(reg + opp110->offsets.dcp_offset)
|
||||
|
||||
#define DCFE_REG(reg)\
|
||||
(reg + opp110->offsets.dcfe_offset)
|
||||
|
||||
enum {
|
||||
MAX_PWL_ENTRY = 128,
|
||||
MAX_REGIONS_NUMBER = 16
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function: regamma_config_regions_and_segments
|
||||
*
|
||||
* build regamma curve by using predefined hw points
|
||||
* uses interface parameters ,like EDID coeff.
|
||||
*
|
||||
* @param : parameters interface parameters
|
||||
* @return void
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* @see
|
||||
*
|
||||
*****************************************************************************
|
||||
*/
|
||||
static void regamma_config_regions_and_segments(
|
||||
struct dce110_opp *opp110,
|
||||
const struct pwl_params *params)
|
||||
{
|
||||
const struct gamma_curve *curve;
|
||||
uint32_t value = 0;
|
||||
|
||||
{
|
||||
set_reg_field_value(
|
||||
value,
|
||||
params->arr_points[0].custom_float_x,
|
||||
REGAMMA_CNTLA_START_CNTL,
|
||||
REGAMMA_CNTLA_EXP_REGION_START);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
0,
|
||||
REGAMMA_CNTLA_START_CNTL,
|
||||
REGAMMA_CNTLA_EXP_REGION_START_SEGMENT);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_START_CNTL),
|
||||
value);
|
||||
}
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
params->arr_points[0].custom_float_slope,
|
||||
REGAMMA_CNTLA_SLOPE_CNTL,
|
||||
REGAMMA_CNTLA_EXP_REGION_LINEAR_SLOPE);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_SLOPE_CNTL), value);
|
||||
}
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
params->arr_points[1].custom_float_x,
|
||||
REGAMMA_CNTLA_END_CNTL1,
|
||||
REGAMMA_CNTLA_EXP_REGION_END);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_END_CNTL1), value);
|
||||
}
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
params->arr_points[2].custom_float_slope,
|
||||
REGAMMA_CNTLA_END_CNTL2,
|
||||
REGAMMA_CNTLA_EXP_REGION_END_BASE);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
params->arr_points[1].custom_float_y,
|
||||
REGAMMA_CNTLA_END_CNTL2,
|
||||
REGAMMA_CNTLA_EXP_REGION_END_SLOPE);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_END_CNTL2), value);
|
||||
}
|
||||
|
||||
curve = params->arr_curve_points;
|
||||
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_0_1,
|
||||
REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_0_1,
|
||||
REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_0_1,
|
||||
REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_0_1,
|
||||
REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(
|
||||
opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_0_1),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_2_3,
|
||||
REGAMMA_CNTLA_EXP_REGION2_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_2_3,
|
||||
REGAMMA_CNTLA_EXP_REGION2_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_2_3,
|
||||
REGAMMA_CNTLA_EXP_REGION3_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_2_3,
|
||||
REGAMMA_CNTLA_EXP_REGION3_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_2_3),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_4_5,
|
||||
REGAMMA_CNTLA_EXP_REGION4_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_4_5,
|
||||
REGAMMA_CNTLA_EXP_REGION4_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_4_5,
|
||||
REGAMMA_CNTLA_EXP_REGION5_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_4_5,
|
||||
REGAMMA_CNTLA_EXP_REGION5_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_4_5),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_6_7,
|
||||
REGAMMA_CNTLA_EXP_REGION6_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_6_7,
|
||||
REGAMMA_CNTLA_EXP_REGION6_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_6_7,
|
||||
REGAMMA_CNTLA_EXP_REGION7_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_6_7,
|
||||
REGAMMA_CNTLA_EXP_REGION7_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_6_7),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_8_9,
|
||||
REGAMMA_CNTLA_EXP_REGION8_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_8_9,
|
||||
REGAMMA_CNTLA_EXP_REGION8_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_8_9,
|
||||
REGAMMA_CNTLA_EXP_REGION9_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_8_9,
|
||||
REGAMMA_CNTLA_EXP_REGION9_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_8_9),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_10_11,
|
||||
REGAMMA_CNTLA_EXP_REGION10_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_10_11,
|
||||
REGAMMA_CNTLA_EXP_REGION10_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_10_11,
|
||||
REGAMMA_CNTLA_EXP_REGION11_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_10_11,
|
||||
REGAMMA_CNTLA_EXP_REGION11_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_10_11),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_12_13,
|
||||
REGAMMA_CNTLA_EXP_REGION12_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_12_13,
|
||||
REGAMMA_CNTLA_EXP_REGION12_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_12_13,
|
||||
REGAMMA_CNTLA_EXP_REGION13_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_12_13,
|
||||
REGAMMA_CNTLA_EXP_REGION13_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_12_13),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_14_15,
|
||||
REGAMMA_CNTLA_EXP_REGION14_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_14_15,
|
||||
REGAMMA_CNTLA_EXP_REGION14_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_14_15,
|
||||
REGAMMA_CNTLA_EXP_REGION15_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_14_15,
|
||||
REGAMMA_CNTLA_EXP_REGION15_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_14_15),
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
static void program_pwl(
|
||||
struct dce110_opp *opp110,
|
||||
const struct pwl_params *params)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
{
|
||||
uint8_t max_tries = 10;
|
||||
uint8_t counter = 0;
|
||||
|
||||
/* Power on LUT memory */
|
||||
value = dm_read_reg(opp110->base.ctx,
|
||||
DCFE_REG(mmDCFE_MEM_PWR_CTRL));
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
1,
|
||||
DCFE_MEM_PWR_CTRL,
|
||||
DCP_REGAMMA_MEM_PWR_DIS);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCFE_REG(mmDCFE_MEM_PWR_CTRL), value);
|
||||
|
||||
while (counter < max_tries) {
|
||||
value =
|
||||
dm_read_reg(
|
||||
opp110->base.ctx,
|
||||
DCFE_REG(mmDCFE_MEM_PWR_STATUS));
|
||||
|
||||
if (get_reg_field_value(
|
||||
value,
|
||||
DCFE_MEM_PWR_STATUS,
|
||||
DCP_REGAMMA_MEM_PWR_STATE) == 0)
|
||||
break;
|
||||
|
||||
++counter;
|
||||
}
|
||||
|
||||
if (counter == max_tries) {
|
||||
dm_logger_write(opp110->base.ctx->logger, LOG_WARNING,
|
||||
"%s: regamma lut was not powered on "
|
||||
"in a timely manner,"
|
||||
" programming still proceeds\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
|
||||
value = 0;
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
7,
|
||||
REGAMMA_LUT_WRITE_EN_MASK,
|
||||
REGAMMA_LUT_WRITE_EN_MASK);
|
||||
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_LUT_WRITE_EN_MASK), value);
|
||||
dm_write_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_LUT_INDEX), 0);
|
||||
|
||||
/* Program REGAMMA_LUT_DATA */
|
||||
{
|
||||
const uint32_t addr = DCP_REG(mmREGAMMA_LUT_DATA);
|
||||
|
||||
uint32_t i = 0;
|
||||
|
||||
const struct pwl_result_data *rgb = params->rgb_resulted;
|
||||
|
||||
while (i != params->hw_points_num) {
|
||||
dm_write_reg(opp110->base.ctx, addr, rgb->red_reg);
|
||||
dm_write_reg(opp110->base.ctx, addr, rgb->green_reg);
|
||||
dm_write_reg(opp110->base.ctx, addr, rgb->blue_reg);
|
||||
|
||||
dm_write_reg(opp110->base.ctx, addr,
|
||||
rgb->delta_red_reg);
|
||||
dm_write_reg(opp110->base.ctx, addr,
|
||||
rgb->delta_green_reg);
|
||||
dm_write_reg(opp110->base.ctx, addr,
|
||||
rgb->delta_blue_reg);
|
||||
|
||||
++rgb;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
/* we are done with DCP LUT memory; re-enable low power mode */
|
||||
value = dm_read_reg(opp110->base.ctx, DCFE_REG(mmDCFE_MEM_PWR_CTRL));
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
0,
|
||||
DCFE_MEM_PWR_CTRL,
|
||||
DCP_REGAMMA_MEM_PWR_DIS);
|
||||
|
||||
dm_write_reg(opp110->base.ctx, DCFE_REG(mmDCFE_MEM_PWR_CTRL), value);
|
||||
}
|
||||
|
||||
bool dce110_opp_program_regamma_pwl(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct pwl_params *params)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
|
||||
/* Setup regions */
|
||||
regamma_config_regions_and_segments(opp110, params);
|
||||
|
||||
/* Program PWL */
|
||||
program_pwl(opp110, params);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dce110_opp_power_on_regamma_lut(
|
||||
struct output_pixel_processor *opp,
|
||||
bool power_on)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
|
||||
uint32_t value =
|
||||
dm_read_reg(opp->ctx, DCFE_REG(mmDCFE_MEM_PWR_CTRL));
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
power_on,
|
||||
DCFE_MEM_PWR_CTRL,
|
||||
DCP_REGAMMA_MEM_PWR_DIS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
power_on,
|
||||
DCFE_MEM_PWR_CTRL,
|
||||
DCP_LUT_MEM_PWR_DIS);
|
||||
|
||||
dm_write_reg(opp->ctx, DCFE_REG(mmDCFE_MEM_PWR_CTRL), value);
|
||||
}
|
||||
|
||||
void dce110_opp_set_regamma_mode(struct output_pixel_processor *opp,
|
||||
enum opp_regamma mode)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
uint32_t value = dm_read_reg(opp110->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CONTROL));
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
mode,
|
||||
REGAMMA_CONTROL,
|
||||
GRPH_REGAMMA_MODE);
|
||||
|
||||
dm_write_reg(opp110->base.ctx, DCP_REG(mmREGAMMA_CONTROL),
|
||||
value);
|
||||
}
|
@ -29,7 +29,7 @@
|
||||
#include "dce/dce_11_0_d.h"
|
||||
#include "dce/dce_11_0_sh_mask.h"
|
||||
|
||||
#include "dce110_opp.h"
|
||||
#include "dce/dce_opp.h"
|
||||
#include "gamma_types.h"
|
||||
|
||||
static void power_on_lut(struct output_pixel_processor *opp,
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "dce/dce_11_0_d.h"
|
||||
#include "dce/dce_11_0_sh_mask.h"
|
||||
|
||||
#include "dce110_opp.h"
|
||||
#include "dce/dce_opp.h"
|
||||
#include "dce110_opp_v.h"
|
||||
|
||||
#include "gamma_types.h"
|
||||
|
@ -43,7 +43,7 @@
|
||||
#include "dce110/dce110_ipp.h"
|
||||
#include "dce/dce_transform.h"
|
||||
#include "dce110/dce110_transform_v.h"
|
||||
#include "dce110/dce110_opp.h"
|
||||
#include "dce/dce_opp.h"
|
||||
#include "dce110/dce110_opp_v.h"
|
||||
#include "dce/dce_clocks.h"
|
||||
#include "dce/dce_clock_source.h"
|
||||
@ -283,6 +283,28 @@ static const struct dce_stream_encoder_mask se_mask = {
|
||||
SE_COMMON_MASK_SH_LIST_DCE110(_MASK)
|
||||
};
|
||||
|
||||
#define opp_regs(id)\
|
||||
[id] = {\
|
||||
OPP_DCE_110_REG_LIST(id),\
|
||||
}
|
||||
|
||||
static const struct dce_opp_registers opp_regs[] = {
|
||||
opp_regs(0),
|
||||
opp_regs(1),
|
||||
opp_regs(2),
|
||||
opp_regs(3),
|
||||
opp_regs(4),
|
||||
opp_regs(5)
|
||||
};
|
||||
|
||||
static const struct dce_opp_shift opp_shift = {
|
||||
OPP_COMMON_MASK_SH_LIST_DCE_110(__SHIFT)
|
||||
};
|
||||
|
||||
static const struct dce_opp_mask opp_mask = {
|
||||
OPP_COMMON_MASK_SH_LIST_DCE_110(_MASK)
|
||||
};
|
||||
|
||||
#define audio_regs(id)\
|
||||
[id] = {\
|
||||
AUD_COMMON_REG_LIST(id)\
|
||||
@ -307,34 +329,7 @@ static const struct dce_aduio_mask audio_mask = {
|
||||
};
|
||||
|
||||
/* AG TBD Needs to be reduced back to 3 pipes once dce10 hw sequencer implemented. */
|
||||
static const struct dce110_opp_reg_offsets dce110_opp_reg_offsets[] = {
|
||||
{
|
||||
.fmt_offset = (mmFMT0_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.dcfe_offset = (mmDCFE0_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
|
||||
.dcp_offset = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT1_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.dcfe_offset = (mmDCFE1_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
|
||||
.dcp_offset = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT2_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.dcfe_offset = (mmDCFE2_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
|
||||
.dcp_offset = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{
|
||||
.fmt_offset = (mmFMT3_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.dcfe_offset = (mmDCFE3_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
|
||||
.dcp_offset = (mmDCP3_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT4_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.dcfe_offset = (mmDCFE4_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
|
||||
.dcp_offset = (mmDCP4_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT5_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.dcfe_offset = (mmDCFE5_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
|
||||
.dcp_offset = (mmDCP5_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define clk_src_regs(id)\
|
||||
[id] = {\
|
||||
@ -603,8 +598,7 @@ struct link_encoder *dce110_link_encoder_create(
|
||||
|
||||
static struct output_pixel_processor *dce110_opp_create(
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dce110_opp_reg_offsets *offsets)
|
||||
uint32_t inst)
|
||||
{
|
||||
struct dce110_opp *opp =
|
||||
dm_alloc(sizeof(struct dce110_opp));
|
||||
@ -613,7 +607,7 @@ static struct output_pixel_processor *dce110_opp_create(
|
||||
return NULL;
|
||||
|
||||
if (dce110_opp_construct(opp,
|
||||
ctx, inst, offsets))
|
||||
ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask))
|
||||
return &opp->base;
|
||||
|
||||
BREAK_TO_DEBUGGER();
|
||||
@ -1329,7 +1323,7 @@ static bool construct(
|
||||
goto res_create_fail;
|
||||
}
|
||||
|
||||
pool->base.opps[i] = dce110_opp_create(ctx, i, &dce110_opp_reg_offsets[i]);
|
||||
pool->base.opps[i] = dce110_opp_create(ctx, i);
|
||||
if (pool->base.opps[i] == NULL) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
dm_error(
|
||||
|
@ -3,8 +3,7 @@
|
||||
# It provides the control and status of HW CRTC block.
|
||||
|
||||
DCE112 = dce112_compressor.o dce112_hw_sequencer.o \
|
||||
dce112_resource.o dce112_mem_input.o dce112_opp_formatter.o \
|
||||
dce112_opp.o
|
||||
dce112_resource.o dce112_mem_input.o
|
||||
|
||||
AMD_DAL_DCE112 = $(addprefix $(AMDDALPATH)/dc/dce112/,$(DCE112))
|
||||
|
||||
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
/* include DCE11 register header files */
|
||||
#include "dce/dce_11_2_d.h"
|
||||
#include "dce/dce_11_2_sh_mask.h"
|
||||
|
||||
#include "dce112_opp.h"
|
||||
|
||||
#include "gamma_types.h"
|
||||
|
||||
enum {
|
||||
MAX_LUT_ENTRY = 256,
|
||||
MAX_NUMBER_OF_ENTRIES = 256
|
||||
};
|
||||
|
||||
/*****************************************/
|
||||
/* Constructor, Destructor */
|
||||
/*****************************************/
|
||||
|
||||
static struct opp_funcs funcs = {
|
||||
.opp_power_on_regamma_lut = dce110_opp_power_on_regamma_lut,
|
||||
.opp_set_csc_adjustment = dce110_opp_set_csc_adjustment,
|
||||
.opp_set_csc_default = dce110_opp_set_csc_default,
|
||||
.opp_set_dyn_expansion = dce110_opp_set_dyn_expansion,
|
||||
.opp_program_regamma_pwl = dce110_opp_program_regamma_pwl,
|
||||
.opp_set_regamma_mode = dce110_opp_set_regamma_mode,
|
||||
.opp_destroy = dce110_opp_destroy,
|
||||
.opp_program_fmt = dce112_opp_program_fmt,
|
||||
.opp_program_bit_depth_reduction =
|
||||
dce110_opp_program_bit_depth_reduction
|
||||
};
|
||||
|
||||
bool dce112_opp_construct(struct dce110_opp *opp110,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dce110_opp_reg_offsets *offsets)
|
||||
{
|
||||
opp110->base.funcs = &funcs;
|
||||
|
||||
opp110->base.ctx = ctx;
|
||||
|
||||
opp110->base.inst = inst;
|
||||
|
||||
opp110->offsets = *offsets;
|
||||
|
||||
return true;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_OPP_DCE112_H__
|
||||
#define __DC_OPP_DCE112_H__
|
||||
|
||||
#include "dc_types.h"
|
||||
#include "opp.h"
|
||||
#include "../dce110/dce110_opp.h"
|
||||
#include "core_types.h"
|
||||
|
||||
void dce112_opp_program_clamping_and_pixel_encoding(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct clamping_and_pixel_encoding_params *params);
|
||||
|
||||
void dce112_opp_program_fmt(
|
||||
struct output_pixel_processor *opp,
|
||||
struct bit_depth_reduction_params *fmt_bit_depth,
|
||||
struct clamping_and_pixel_encoding_params *clamping);
|
||||
|
||||
bool dce112_opp_construct(struct dce110_opp *opp110,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dce110_opp_reg_offsets *offsets);
|
||||
|
||||
|
||||
#endif
|
@ -1,215 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
#include "dce/dce_11_2_d.h"
|
||||
#include "dce/dce_11_2_sh_mask.h"
|
||||
|
||||
#include "dce112_opp.h"
|
||||
|
||||
#define FMT_REG(reg)\
|
||||
(reg + opp110->offsets.fmt_offset)
|
||||
#define FMT_MEM_REG(reg)\
|
||||
(reg + opp110->offsets.fmt_mem_offset)
|
||||
|
||||
/**
|
||||
* Set Clamping
|
||||
* 1) Set clamping format based on bpc - 0 for 6bpc (No clamping)
|
||||
* 1 for 8 bpc
|
||||
* 2 for 10 bpc
|
||||
* 3 for 12 bpc
|
||||
* 7 for programable
|
||||
* 2) Enable clamp if Limited range requested
|
||||
*/
|
||||
|
||||
/**
|
||||
* set_pixel_encoding
|
||||
*
|
||||
* Set Pixel Encoding
|
||||
* 0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly
|
||||
* 1: YCbCr 4:2:2
|
||||
* 2: YCbCr 4:2:0
|
||||
*/
|
||||
static void set_pixel_encoding(
|
||||
struct dce110_opp *opp110,
|
||||
const struct clamping_and_pixel_encoding_params *params)
|
||||
{
|
||||
uint32_t fmt_cntl_value;
|
||||
uint32_t addr = FMT_REG(mmFMT_CONTROL);
|
||||
|
||||
/*RGB 4:4:4 or YCbCr 4:4:4 - 0; YCbCr 4:2:2 -1.*/
|
||||
fmt_cntl_value = dm_read_reg(opp110->base.ctx, addr);
|
||||
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
0,
|
||||
FMT_CONTROL,
|
||||
FMT_PIXEL_ENCODING);
|
||||
|
||||
/*00 - Pixels drop mode HW default*/
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
0,
|
||||
FMT_CONTROL,
|
||||
FMT_SUBSAMPLING_MODE);
|
||||
|
||||
/* By default no bypass*/
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
0,
|
||||
FMT_CONTROL,
|
||||
FMT_CBCR_BIT_REDUCTION_BYPASS);
|
||||
|
||||
if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
1,
|
||||
FMT_CONTROL,
|
||||
FMT_PIXEL_ENCODING);
|
||||
|
||||
/*00 - Cb before Cr ,01 - Cr before Cb*/
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
0,
|
||||
FMT_CONTROL,
|
||||
FMT_SUBSAMPLING_ORDER);
|
||||
}
|
||||
|
||||
if (params->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
2,
|
||||
FMT_CONTROL,
|
||||
FMT_PIXEL_ENCODING);
|
||||
|
||||
/* 02 - Subsampling mode, 3 taps*/
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
2,
|
||||
FMT_CONTROL,
|
||||
FMT_SUBSAMPLING_MODE);
|
||||
|
||||
/* 00 - Enable CbCr bit reduction bypass to preserve precision*/
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
1,
|
||||
FMT_CONTROL,
|
||||
FMT_CBCR_BIT_REDUCTION_BYPASS);
|
||||
}
|
||||
dm_write_reg(opp110->base.ctx, addr, fmt_cntl_value);
|
||||
|
||||
}
|
||||
|
||||
void dce112_opp_program_clamping_and_pixel_encoding(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct clamping_and_pixel_encoding_params *params)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
|
||||
dce110_opp_set_clamping(opp110, params);
|
||||
set_pixel_encoding(opp110, params);
|
||||
}
|
||||
|
||||
static void program_formatter_420_memory(struct output_pixel_processor *opp)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
uint32_t fmt_cntl_value;
|
||||
uint32_t fmt_mem_cntl_value;
|
||||
uint32_t fmt_cntl_addr = FMT_REG(mmFMT_CONTROL);
|
||||
uint32_t fmt_mem_cntl_addr = FMT_MEM_REG(mmFMT_MEMORY0_CONTROL);
|
||||
|
||||
fmt_mem_cntl_value = dm_read_reg(opp110->base.ctx, fmt_mem_cntl_addr);
|
||||
fmt_cntl_value = dm_read_reg(opp110->base.ctx, fmt_cntl_addr);
|
||||
/* Program source select*/
|
||||
/* Use HW default source select for FMT_MEMORYx_CONTROL */
|
||||
/* Use that value for FMT_SRC_SELECT as well*/
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
get_reg_field_value(fmt_mem_cntl_value, FMT_MEMORY0_CONTROL, FMT420_MEM0_SOURCE_SEL),
|
||||
FMT_CONTROL,
|
||||
FMT_SRC_SELECT);
|
||||
dm_write_reg(opp110->base.ctx, fmt_cntl_addr, fmt_cntl_value);
|
||||
|
||||
/* Turn on the memory */
|
||||
set_reg_field_value(fmt_mem_cntl_value,
|
||||
0,
|
||||
FMT_MEMORY0_CONTROL,
|
||||
FMT420_MEM0_PWR_FORCE);
|
||||
dm_write_reg(opp110->base.ctx, fmt_mem_cntl_addr, fmt_mem_cntl_value);
|
||||
}
|
||||
|
||||
static void program_formatter_reset_dig_resync_fifo(struct output_pixel_processor *opp)
|
||||
{
|
||||
struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
|
||||
uint32_t value;
|
||||
uint32_t addr = FMT_REG(mmFMT_CONTROL);
|
||||
uint8_t counter = 10;
|
||||
|
||||
|
||||
value = dm_read_reg(opp110->base.ctx, addr);
|
||||
|
||||
/* clear previous phase lock status*/
|
||||
set_reg_field_value(value,
|
||||
1,
|
||||
FMT_CONTROL,
|
||||
FMT_420_PIXEL_PHASE_LOCKED_CLEAR);
|
||||
dm_write_reg(opp110->base.ctx, addr, value);
|
||||
|
||||
/* poll until FMT_420_PIXEL_PHASE_LOCKED become 1*/
|
||||
while (counter > 0) {
|
||||
value = dm_read_reg(opp110->base.ctx, addr);
|
||||
|
||||
if (get_reg_field_value(
|
||||
value,
|
||||
FMT_CONTROL,
|
||||
FMT_420_PIXEL_PHASE_LOCKED) == 1)
|
||||
break;
|
||||
|
||||
msleep(10);
|
||||
counter--;
|
||||
}
|
||||
|
||||
if (counter == 0)
|
||||
dm_logger_write(opp->ctx->logger, LOG_ERROR,
|
||||
"%s:opp program formattter reset dig resync info time out.\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
void dce112_opp_program_fmt(
|
||||
struct output_pixel_processor *opp,
|
||||
struct bit_depth_reduction_params *fmt_bit_depth,
|
||||
struct clamping_and_pixel_encoding_params *clamping)
|
||||
{
|
||||
/* dithering is affected by <CrtcSourceSelect>, hence should be
|
||||
* programmed afterwards */
|
||||
|
||||
if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
|
||||
program_formatter_420_memory(opp);
|
||||
|
||||
dce110_opp_program_bit_depth_reduction(
|
||||
opp,
|
||||
fmt_bit_depth);
|
||||
|
||||
dce112_opp_program_clamping_and_pixel_encoding(
|
||||
opp,
|
||||
clamping);
|
||||
|
||||
if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
|
||||
program_formatter_reset_dig_resync_fifo(opp);
|
||||
|
||||
return;
|
||||
}
|
@ -39,7 +39,7 @@
|
||||
#include "dce/dce_link_encoder.h"
|
||||
#include "dce/dce_stream_encoder.h"
|
||||
#include "dce/dce_audio.h"
|
||||
#include "dce112/dce112_opp.h"
|
||||
#include "dce/dce_opp.h"
|
||||
#include "dce110/dce110_ipp.h"
|
||||
#include "dce/dce_clocks.h"
|
||||
#include "dce/dce_clock_source.h"
|
||||
@ -306,6 +306,28 @@ static const struct dce_stream_encoder_mask se_mask = {
|
||||
SE_COMMON_MASK_SH_LIST_DCE112(_MASK)
|
||||
};
|
||||
|
||||
#define opp_regs(id)\
|
||||
[id] = {\
|
||||
OPP_DCE_112_REG_LIST(id),\
|
||||
}
|
||||
|
||||
static const struct dce_opp_registers opp_regs[] = {
|
||||
opp_regs(0),
|
||||
opp_regs(1),
|
||||
opp_regs(2),
|
||||
opp_regs(3),
|
||||
opp_regs(4),
|
||||
opp_regs(5)
|
||||
};
|
||||
|
||||
static const struct dce_opp_shift opp_shift = {
|
||||
OPP_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)
|
||||
};
|
||||
|
||||
static const struct dce_opp_mask opp_mask = {
|
||||
OPP_COMMON_MASK_SH_LIST_DCE_112(_MASK)
|
||||
};
|
||||
|
||||
#define audio_regs(id)\
|
||||
[id] = {\
|
||||
AUD_COMMON_REG_LIST(id)\
|
||||
@ -328,42 +350,6 @@ static const struct dce_aduio_mask audio_mask = {
|
||||
AUD_COMMON_MASK_SH_LIST(_MASK)
|
||||
};
|
||||
|
||||
|
||||
static const struct dce110_opp_reg_offsets dce112_opp_reg_offsets[] = {
|
||||
{
|
||||
.fmt_offset = (mmFMT0_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.fmt_mem_offset = (mmFMT_MEMORY0_CONTROL - mmFMT_MEMORY0_CONTROL),
|
||||
.dcfe_offset = (mmDCFE0_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
|
||||
.dcp_offset = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT1_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.fmt_mem_offset = (mmFMT_MEMORY1_CONTROL - mmFMT_MEMORY0_CONTROL),
|
||||
.dcfe_offset = (mmDCFE1_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
|
||||
.dcp_offset = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT2_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.fmt_mem_offset = (mmFMT_MEMORY2_CONTROL - mmFMT_MEMORY0_CONTROL),
|
||||
.dcfe_offset = (mmDCFE2_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
|
||||
.dcp_offset = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{
|
||||
.fmt_offset = (mmFMT3_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.fmt_mem_offset = (mmFMT_MEMORY3_CONTROL - mmFMT_MEMORY0_CONTROL),
|
||||
.dcfe_offset = (mmDCFE3_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
|
||||
.dcp_offset = (mmDCP3_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT4_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.fmt_mem_offset = (mmFMT_MEMORY4_CONTROL - mmFMT_MEMORY0_CONTROL),
|
||||
.dcfe_offset = (mmDCFE4_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
|
||||
.dcp_offset = (mmDCP4_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT5_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.fmt_mem_offset = (mmFMT_MEMORY5_CONTROL - mmFMT_MEMORY0_CONTROL),
|
||||
.dcfe_offset = (mmDCFE5_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
|
||||
.dcp_offset = (mmDCP5_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
}
|
||||
};
|
||||
|
||||
#define clk_src_regs(index, id)\
|
||||
[index] = {\
|
||||
CS_COMMON_REG_LIST_DCE_112(id),\
|
||||
@ -631,8 +617,7 @@ void dce112_ipp_destroy(struct input_pixel_processor **ipp)
|
||||
|
||||
struct output_pixel_processor *dce112_opp_create(
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dce110_opp_reg_offsets *offset)
|
||||
uint32_t inst)
|
||||
{
|
||||
struct dce110_opp *opp =
|
||||
dm_alloc(sizeof(struct dce110_opp));
|
||||
@ -640,8 +625,8 @@ struct output_pixel_processor *dce112_opp_create(
|
||||
if (!opp)
|
||||
return NULL;
|
||||
|
||||
if (dce112_opp_construct(opp,
|
||||
ctx, inst, offset))
|
||||
if (dce110_opp_construct(opp,
|
||||
ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask))
|
||||
return &opp->base;
|
||||
|
||||
BREAK_TO_DEBUGGER();
|
||||
@ -1381,8 +1366,7 @@ static bool construct(
|
||||
|
||||
pool->base.opps[i] = dce112_opp_create(
|
||||
ctx,
|
||||
i,
|
||||
&dce112_opp_reg_offsets[i]);
|
||||
i);
|
||||
if (pool->base.opps[i] == NULL) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
dm_error(
|
||||
|
@ -2,9 +2,8 @@
|
||||
# Makefile for the 'controller' sub-component of DAL.
|
||||
# It provides the control and status of HW CRTC block.
|
||||
|
||||
DCE80 = dce80_ipp.o dce80_ipp_gamma.o dce80_opp.o \
|
||||
dce80_opp_formatter.o dce80_opp_regamma.o \
|
||||
dce80_timing_generator.o dce80_opp_csc.o\
|
||||
DCE80 = dce80_ipp.o dce80_ipp_gamma.o \
|
||||
dce80_timing_generator.o \
|
||||
dce80_compressor.o dce80_mem_input.o dce80_hw_sequencer.o \
|
||||
dce80_resource.o
|
||||
|
||||
|
@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
/* include DCE8 register header files */
|
||||
#include "dce/dce_8_0_d.h"
|
||||
#include "dce/dce_8_0_sh_mask.h"
|
||||
|
||||
#include "dce80_opp.h"
|
||||
|
||||
#define FROM_OPP(opp)\
|
||||
container_of(opp, struct dce80_opp, base)
|
||||
|
||||
enum {
|
||||
MAX_LUT_ENTRY = 256,
|
||||
MAX_NUMBER_OF_ENTRIES = 256
|
||||
};
|
||||
|
||||
static const struct dce80_opp_reg_offsets reg_offsets[] = {
|
||||
{
|
||||
.fmt_offset = (mmFMT0_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.crtc_offset = (mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL -
|
||||
mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
|
||||
.dcp_offset = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT1_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.crtc_offset = (mmCRTC1_DCFE_MEM_LIGHT_SLEEP_CNTL -
|
||||
mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
|
||||
.dcp_offset = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{ .fmt_offset = (mmFMT2_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.crtc_offset = (mmCRTC2_DCFE_MEM_LIGHT_SLEEP_CNTL -
|
||||
mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
|
||||
.dcp_offset = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{
|
||||
.fmt_offset = (mmFMT3_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.crtc_offset = (mmCRTC3_DCFE_MEM_LIGHT_SLEEP_CNTL -
|
||||
mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
|
||||
.dcp_offset = (mmDCP3_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{
|
||||
.fmt_offset = (mmFMT4_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.crtc_offset = (mmCRTC4_DCFE_MEM_LIGHT_SLEEP_CNTL -
|
||||
mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
|
||||
.dcp_offset = (mmDCP4_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
},
|
||||
{
|
||||
.fmt_offset = (mmFMT5_FMT_CONTROL - mmFMT0_FMT_CONTROL),
|
||||
.crtc_offset = (mmCRTC5_DCFE_MEM_LIGHT_SLEEP_CNTL -
|
||||
mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
|
||||
.dcp_offset = (mmDCP5_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct opp_funcs funcs = {
|
||||
.opp_power_on_regamma_lut = dce80_opp_power_on_regamma_lut,
|
||||
.opp_set_csc_adjustment = dce80_opp_set_csc_adjustment,
|
||||
.opp_set_csc_default = dce80_opp_set_csc_default,
|
||||
.opp_set_dyn_expansion = dce80_opp_set_dyn_expansion,
|
||||
.opp_program_regamma_pwl = dce80_opp_program_regamma_pwl,
|
||||
.opp_set_regamma_mode = dce80_opp_set_regamma_mode,
|
||||
.opp_destroy = dce80_opp_destroy,
|
||||
.opp_program_fmt = dce110_opp_program_fmt,
|
||||
};
|
||||
|
||||
/*****************************************/
|
||||
/* Constructor, Destructor */
|
||||
/*****************************************/
|
||||
|
||||
bool dce80_opp_construct(struct dce80_opp *opp80,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst)
|
||||
{
|
||||
if (inst >= ARRAY_SIZE(reg_offsets))
|
||||
return false;
|
||||
|
||||
opp80->base.funcs = &funcs;
|
||||
|
||||
opp80->base.ctx = ctx;
|
||||
|
||||
opp80->base.inst = inst;
|
||||
|
||||
opp80->offsets = reg_offsets[inst];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dce80_opp_destroy(struct output_pixel_processor **opp)
|
||||
{
|
||||
dm_free(FROM_OPP(*opp));
|
||||
*opp = NULL;
|
||||
}
|
||||
|
||||
struct output_pixel_processor *dce80_opp_create(
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst)
|
||||
{
|
||||
struct dce80_opp *opp =
|
||||
dm_alloc(sizeof(struct dce80_opp));
|
||||
|
||||
if (!opp)
|
||||
return NULL;
|
||||
|
||||
if (dce80_opp_construct(opp,
|
||||
ctx, inst))
|
||||
return &opp->base;
|
||||
|
||||
BREAK_TO_DEBUGGER();
|
||||
dm_free(opp);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,130 +0,0 @@
|
||||
/* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_OPP_DCE80_H__
|
||||
#define __DC_OPP_DCE80_H__
|
||||
|
||||
#include "dc_types.h"
|
||||
#include "opp.h"
|
||||
#include "gamma_types.h"
|
||||
#include "../dce110/dce110_opp.h"
|
||||
|
||||
struct gamma_parameters;
|
||||
|
||||
struct dce80_regamma {
|
||||
struct gamma_curve arr_curve_points[16];
|
||||
struct curve_points arr_points[3];
|
||||
uint32_t hw_points_num;
|
||||
struct hw_x_point *coordinates_x;
|
||||
struct pwl_result_data *rgb_resulted;
|
||||
|
||||
/* re-gamma curve */
|
||||
struct pwl_float_data_ex *rgb_regamma;
|
||||
/* coeff used to map user evenly distributed points
|
||||
* to our hardware points (predefined) for gamma 256 */
|
||||
struct pixel_gamma_point *coeff128;
|
||||
struct pixel_gamma_point *coeff128_oem;
|
||||
/* coeff used to map user evenly distributed points
|
||||
* to our hardware points (predefined) for gamma 1025 */
|
||||
struct pixel_gamma_point *coeff128_dx;
|
||||
/* evenly distributed points, gamma 256 software points 0-255 */
|
||||
struct gamma_pixel *axis_x_256;
|
||||
/* evenly distributed points, gamma 1025 software points 0-1025 */
|
||||
struct gamma_pixel *axis_x_1025;
|
||||
/* OEM supplied gamma for regamma LUT */
|
||||
struct pwl_float_data *rgb_oem;
|
||||
/* user supplied gamma */
|
||||
struct pwl_float_data *rgb_user;
|
||||
uint32_t extra_points;
|
||||
bool use_half_points;
|
||||
struct fixed31_32 x_max1;
|
||||
struct fixed31_32 x_max2;
|
||||
struct fixed31_32 x_min;
|
||||
struct fixed31_32 divider1;
|
||||
struct fixed31_32 divider2;
|
||||
struct fixed31_32 divider3;
|
||||
};
|
||||
|
||||
/* OPP RELATED */
|
||||
#define TO_DCE80_OPP(opp)\
|
||||
container_of(opp, struct dce80_opp, base)
|
||||
|
||||
struct dce80_opp_reg_offsets {
|
||||
uint32_t fmt_offset;
|
||||
uint32_t dcp_offset;
|
||||
uint32_t crtc_offset;
|
||||
};
|
||||
|
||||
struct dce80_opp {
|
||||
struct output_pixel_processor base;
|
||||
struct dce80_opp_reg_offsets offsets;
|
||||
struct dce80_regamma regamma;
|
||||
};
|
||||
|
||||
bool dce80_opp_construct(struct dce80_opp *opp80,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst);
|
||||
|
||||
void dce80_opp_destroy(struct output_pixel_processor **opp);
|
||||
|
||||
struct output_pixel_processor *dce80_opp_create(
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst);
|
||||
|
||||
/* REGAMMA RELATED */
|
||||
void dce80_opp_power_on_regamma_lut(
|
||||
struct output_pixel_processor *opp,
|
||||
bool power_on);
|
||||
|
||||
bool dce80_opp_program_regamma_pwl(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct pwl_params *pamras);
|
||||
|
||||
void dce80_opp_set_regamma_mode(struct output_pixel_processor *opp,
|
||||
enum opp_regamma mode);
|
||||
|
||||
void dce80_opp_set_csc_adjustment(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct out_csc_color_matrix *tbl_entry);
|
||||
|
||||
void dce80_opp_set_csc_default(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct default_adjustment *default_adjust);
|
||||
|
||||
/* FORMATTER RELATED */
|
||||
void dce80_opp_program_bit_depth_reduction(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct bit_depth_reduction_params *params);
|
||||
|
||||
void dce80_opp_program_clamping_and_pixel_encoding(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct clamping_and_pixel_encoding_params *params);
|
||||
|
||||
void dce80_opp_set_dyn_expansion(
|
||||
struct output_pixel_processor *opp,
|
||||
enum dc_color_space color_sp,
|
||||
enum dc_color_depth color_dpth,
|
||||
enum signal_type signal);
|
||||
|
||||
#endif
|
@ -1,363 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
#include "dce80_opp.h"
|
||||
#include "basics/conversion.h"
|
||||
|
||||
/* include DCE8 register header files */
|
||||
#include "dce/dce_8_0_d.h"
|
||||
#include "dce/dce_8_0_sh_mask.h"
|
||||
|
||||
#define DCP_REG(reg)\
|
||||
(reg + opp80->offsets.dcp_offset)
|
||||
|
||||
enum {
|
||||
OUTPUT_CSC_MATRIX_SIZE = 12
|
||||
};
|
||||
|
||||
static const struct out_csc_color_matrix global_color_matrix[] = {
|
||||
{ COLOR_SPACE_SRGB,
|
||||
{ 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
|
||||
{ COLOR_SPACE_SRGB_LIMITED,
|
||||
{ 0x1B60, 0, 0, 0x200, 0, 0x1B60, 0, 0x200, 0, 0, 0x1B60, 0x200} },
|
||||
{ COLOR_SPACE_YCBCR601,
|
||||
{ 0xE00, 0xF447, 0xFDB9, 0x1000, 0x82F, 0x1012, 0x31F, 0x200, 0xFB47,
|
||||
0xF6B9, 0xE00, 0x1000} },
|
||||
{ COLOR_SPACE_YCBCR709, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x5D2, 0x1394, 0x1FA,
|
||||
0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
|
||||
/* TODO: correct values below */
|
||||
{ COLOR_SPACE_YCBCR601_LIMITED, { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
|
||||
0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
|
||||
{ COLOR_SPACE_YCBCR709_LIMITED, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
|
||||
0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }
|
||||
};
|
||||
|
||||
enum csc_color_mode {
|
||||
/* 00 - BITS2:0 Bypass */
|
||||
CSC_COLOR_MODE_GRAPHICS_BYPASS,
|
||||
/* 01 - hard coded coefficient TV RGB */
|
||||
CSC_COLOR_MODE_GRAPHICS_PREDEFINED,
|
||||
/* 04 - programmable OUTPUT CSC coefficient */
|
||||
CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC,
|
||||
};
|
||||
|
||||
static void program_color_matrix(
|
||||
struct dce80_opp *opp80,
|
||||
const struct out_csc_color_matrix *tbl_entry,
|
||||
enum grph_color_adjust_option options)
|
||||
{
|
||||
struct dc_context *ctx = opp80->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 dce80_opp *opp80,
|
||||
enum csc_color_mode config,
|
||||
enum graphics_csc_adjust_type csc_adjust_type,
|
||||
enum dc_color_space color_space)
|
||||
{
|
||||
struct dc_context *ctx = opp80->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;
|
||||
}
|
||||
|
||||
void dce80_opp_set_csc_adjustment(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct out_csc_color_matrix *tbl_entry)
|
||||
{
|
||||
struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
|
||||
enum csc_color_mode config =
|
||||
CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
|
||||
|
||||
program_color_matrix(opp80, tbl_entry, GRAPHICS_CSC_ADJUST_TYPE_SW);
|
||||
|
||||
/* We did everything ,now program DxOUTPUT_CSC_CONTROL */
|
||||
configure_graphics_mode(opp80, config, GRAPHICS_CSC_ADJUST_TYPE_SW,
|
||||
tbl_entry->color_space);
|
||||
}
|
||||
|
||||
void dce80_opp_set_csc_default(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct default_adjustment *default_adjust)
|
||||
{
|
||||
struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
|
||||
enum csc_color_mode config =
|
||||
CSC_COLOR_MODE_GRAPHICS_PREDEFINED;
|
||||
|
||||
if (default_adjust->force_hw_default == false) {
|
||||
const struct out_csc_color_matrix *elm;
|
||||
/* currently parameter not in use */
|
||||
enum grph_color_adjust_option option =
|
||||
GRPH_COLOR_MATRIX_HW_DEFAULT;
|
||||
uint32_t i;
|
||||
/*
|
||||
* HW default false we program locally defined matrix
|
||||
* HW default true we use predefined hw matrix and we
|
||||
* do not need to program matrix
|
||||
* OEM wants the HW default via runtime parameter.
|
||||
*/
|
||||
option = GRPH_COLOR_MATRIX_SW;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(global_color_matrix); ++i) {
|
||||
elm = &global_color_matrix[i];
|
||||
if (elm->color_space != default_adjust->out_color_space)
|
||||
continue;
|
||||
/* program the matrix with default values from this
|
||||
* file */
|
||||
program_color_matrix(opp80, elm, option);
|
||||
config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* configure the what we programmed :
|
||||
* 1. Default values from this file
|
||||
* 2. Use hardware default from ROM_A and we do not need to program
|
||||
* matrix */
|
||||
|
||||
configure_graphics_mode(opp80, config,
|
||||
default_adjust->csc_adjust_type,
|
||||
default_adjust->out_color_space);
|
||||
}
|
@ -1,577 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
#include "dce/dce_8_0_d.h"
|
||||
#include "dce/dce_8_0_sh_mask.h"
|
||||
|
||||
#include "dce80_opp.h"
|
||||
|
||||
#define FMT_REG(reg)\
|
||||
(reg + opp80->offsets.fmt_offset)
|
||||
|
||||
/**
|
||||
* set_truncation
|
||||
* 1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp
|
||||
* 2) enable truncation
|
||||
* 3) HW remove 12bit FMT support for DCE8 power saving reason.
|
||||
*/
|
||||
static void set_truncation(
|
||||
struct dce80_opp *opp80,
|
||||
const struct bit_depth_reduction_params *params)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
uint32_t addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
|
||||
|
||||
/*Disable truncation*/
|
||||
value = dm_read_reg(opp80->base.ctx, addr);
|
||||
set_reg_field_value(value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN);
|
||||
set_reg_field_value(value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_DEPTH);
|
||||
set_reg_field_value(value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_MODE);
|
||||
|
||||
dm_write_reg(opp80->base.ctx, addr, value);
|
||||
|
||||
/* no 10bpc trunc on DCE8*/
|
||||
if (params->flags.TRUNCATE_ENABLED == 0 ||
|
||||
params->flags.TRUNCATE_DEPTH == 2)
|
||||
return;
|
||||
|
||||
/*Set truncation depth and Enable truncation*/
|
||||
set_reg_field_value(value, 1,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN);
|
||||
set_reg_field_value(value, params->flags.TRUNCATE_MODE,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_MODE);
|
||||
set_reg_field_value(value, params->flags.TRUNCATE_DEPTH,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_DEPTH);
|
||||
|
||||
dm_write_reg(opp80->base.ctx, addr, value);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* set_spatial_dither
|
||||
* 1) set spatial dithering mode: pattern of seed
|
||||
* 2) set spatical dithering depth: 0 for 18bpp or 1 for 24bpp
|
||||
* 3) set random seed
|
||||
* 4) set random mode
|
||||
* lfsr is reset every frame or not reset
|
||||
* RGB dithering method
|
||||
* 0: RGB data are all dithered with x^28+x^3+1
|
||||
* 1: R data is dithered with x^28+x^3+1
|
||||
* G data is dithered with x^28+X^9+1
|
||||
* B data is dithered with x^28+x^13+1
|
||||
* enable high pass filter or not
|
||||
* 5) enable spatical dithering
|
||||
*/
|
||||
static void set_spatial_dither(
|
||||
struct dce80_opp *opp80,
|
||||
const struct bit_depth_reduction_params *params)
|
||||
{
|
||||
uint32_t addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
|
||||
uint32_t depth_cntl_value = 0;
|
||||
uint32_t dither_r_value = 0;
|
||||
uint32_t dither_g_value = 0;
|
||||
uint32_t dither_b_value = 0;
|
||||
|
||||
/*Disable spatial (random) dithering*/
|
||||
depth_cntl_value = dm_read_reg(opp80->base.ctx, addr);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_EN);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_MODE);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_DEPTH);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_EN);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_HIGHPASS_RANDOM_ENABLE);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_FRAME_RANDOM_ENABLE);
|
||||
set_reg_field_value(depth_cntl_value, 0,
|
||||
FMT_BIT_DEPTH_CONTROL, FMT_RGB_RANDOM_ENABLE);
|
||||
|
||||
dm_write_reg(opp80->base.ctx, addr, depth_cntl_value);
|
||||
|
||||
/* no 10bpc on DCE8*/
|
||||
if (params->flags.SPATIAL_DITHER_ENABLED == 0 ||
|
||||
params->flags.SPATIAL_DITHER_DEPTH == 2)
|
||||
return;
|
||||
|
||||
/*Set seed for random values for
|
||||
* spatial dithering for R,G,B channels*/
|
||||
addr = FMT_REG(mmFMT_DITHER_RAND_R_SEED);
|
||||
set_reg_field_value(dither_r_value, params->r_seed_value,
|
||||
FMT_DITHER_RAND_R_SEED,
|
||||
FMT_RAND_R_SEED);
|
||||
dm_write_reg(opp80->base.ctx, addr, dither_r_value);
|
||||
|
||||
addr = FMT_REG(mmFMT_DITHER_RAND_G_SEED);
|
||||
set_reg_field_value(dither_g_value,
|
||||
params->g_seed_value,
|
||||
FMT_DITHER_RAND_G_SEED,
|
||||
FMT_RAND_G_SEED);
|
||||
dm_write_reg(opp80->base.ctx, addr, dither_g_value);
|
||||
|
||||
addr = FMT_REG(mmFMT_DITHER_RAND_B_SEED);
|
||||
set_reg_field_value(dither_b_value, params->b_seed_value,
|
||||
FMT_DITHER_RAND_B_SEED,
|
||||
FMT_RAND_B_SEED);
|
||||
dm_write_reg(opp80->base.ctx, addr, dither_b_value);
|
||||
|
||||
/* FMT_OFFSET_R_Cr 31:16 0x0 Setting the zero
|
||||
* offset for the R/Cr channel, lower 4LSB
|
||||
* is forced to zeros. Typically set to 0
|
||||
* RGB and 0x80000 YCbCr.
|
||||
*/
|
||||
/* FMT_OFFSET_G_Y 31:16 0x0 Setting the zero
|
||||
* offset for the G/Y channel, lower 4LSB is
|
||||
* forced to zeros. Typically set to 0 RGB
|
||||
* and 0x80000 YCbCr.
|
||||
*/
|
||||
/* FMT_OFFSET_B_Cb 31:16 0x0 Setting the zero
|
||||
* offset for the B/Cb channel, lower 4LSB is
|
||||
* forced to zeros. Typically set to 0 RGB and
|
||||
* 0x80000 YCbCr.
|
||||
*/
|
||||
|
||||
/*Set spatial dithering bit depth*/
|
||||
set_reg_field_value(depth_cntl_value,
|
||||
params->flags.SPATIAL_DITHER_DEPTH,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_SPATIAL_DITHER_DEPTH);
|
||||
|
||||
/* Set spatial dithering mode
|
||||
* (default is Seed patterrn AAAA...)
|
||||
*/
|
||||
set_reg_field_value(depth_cntl_value,
|
||||
params->flags.SPATIAL_DITHER_MODE,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_SPATIAL_DITHER_MODE);
|
||||
|
||||
/*Reset only at startup*/
|
||||
set_reg_field_value(depth_cntl_value,
|
||||
params->flags.FRAME_RANDOM,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_FRAME_RANDOM_ENABLE);
|
||||
|
||||
/*Set RGB data dithered with x^28+x^3+1*/
|
||||
set_reg_field_value(depth_cntl_value,
|
||||
params->flags.RGB_RANDOM,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_RGB_RANDOM_ENABLE);
|
||||
|
||||
/*Disable High pass filter*/
|
||||
set_reg_field_value(depth_cntl_value,
|
||||
params->flags.HIGHPASS_RANDOM,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_HIGHPASS_RANDOM_ENABLE);
|
||||
|
||||
/*Enable spatial dithering*/
|
||||
set_reg_field_value(depth_cntl_value,
|
||||
1,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_SPATIAL_DITHER_EN);
|
||||
|
||||
addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
|
||||
dm_write_reg(opp80->base.ctx, addr, depth_cntl_value);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* SetTemporalDither (Frame Modulation)
|
||||
* 1) set temporal dither depth
|
||||
* 2) select pattern: from hard-coded pattern or programmable pattern
|
||||
* 3) select optimized strips for BGR or RGB LCD sub-pixel
|
||||
* 4) set s matrix
|
||||
* 5) set t matrix
|
||||
* 6) set grey level for 0.25, 0.5, 0.75
|
||||
* 7) enable temporal dithering
|
||||
*/
|
||||
static void set_temporal_dither(
|
||||
struct dce80_opp *opp80,
|
||||
const struct bit_depth_reduction_params *params)
|
||||
{
|
||||
uint32_t addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
|
||||
uint32_t value;
|
||||
|
||||
/*Disable temporal (frame modulation) dithering first*/
|
||||
value = dm_read_reg(opp80->base.ctx, addr);
|
||||
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_EN);
|
||||
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_RESET);
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_OFFSET);
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_DEPTH);
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_LEVEL);
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_25FRC_SEL);
|
||||
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_50FRC_SEL);
|
||||
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_75FRC_SEL);
|
||||
|
||||
dm_write_reg(opp80->base.ctx, addr, value);
|
||||
|
||||
/* no 10bpc dither on DCE8*/
|
||||
if (params->flags.FRAME_MODULATION_ENABLED == 0 ||
|
||||
params->flags.FRAME_MODULATION_DEPTH == 2)
|
||||
return;
|
||||
|
||||
/* Set temporal dithering depth*/
|
||||
set_reg_field_value(value,
|
||||
params->flags.FRAME_MODULATION_DEPTH,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_DEPTH);
|
||||
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_RESET);
|
||||
|
||||
set_reg_field_value(value,
|
||||
0,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_OFFSET);
|
||||
|
||||
/*Select legacy pattern based on FRC and Temporal level*/
|
||||
addr = FMT_REG(mmFMT_TEMPORAL_DITHER_PATTERN_CONTROL);
|
||||
dm_write_reg(opp80->base.ctx, addr, 0);
|
||||
/*Set s matrix*/
|
||||
addr = FMT_REG(
|
||||
mmFMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX);
|
||||
dm_write_reg(opp80->base.ctx, addr, 0);
|
||||
/*Set t matrix*/
|
||||
addr = FMT_REG(
|
||||
mmFMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX);
|
||||
dm_write_reg(opp80->base.ctx, addr, 0);
|
||||
|
||||
/*Select patterns for 0.25, 0.5 and 0.75 grey level*/
|
||||
set_reg_field_value(value,
|
||||
params->flags.TEMPORAL_LEVEL,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_LEVEL);
|
||||
|
||||
set_reg_field_value(value,
|
||||
params->flags.FRC25,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_25FRC_SEL);
|
||||
|
||||
set_reg_field_value(value,
|
||||
params->flags.FRC50,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_50FRC_SEL);
|
||||
|
||||
set_reg_field_value(value,
|
||||
params->flags.FRC75,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_75FRC_SEL);
|
||||
|
||||
/*Enable bit reduction by temporal (frame modulation) dithering*/
|
||||
set_reg_field_value(value,
|
||||
1,
|
||||
FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TEMPORAL_DITHER_EN);
|
||||
|
||||
addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
|
||||
dm_write_reg(opp80->base.ctx, addr, value);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Clamping
|
||||
* 1) Set clamping format based on bpc - 0 for 6bpc (No clamping)
|
||||
* 1 for 8 bpc
|
||||
* 2 for 10 bpc
|
||||
* 3 for 12 bpc
|
||||
* 7 for programable
|
||||
* 2) Enable clamp if Limited range requested
|
||||
*/
|
||||
static void set_clamping(
|
||||
struct dce80_opp *opp80,
|
||||
const struct clamping_and_pixel_encoding_params *params)
|
||||
{
|
||||
uint32_t clamp_cntl_value = 0;
|
||||
uint32_t red_clamp_value = 0;
|
||||
uint32_t green_clamp_value = 0;
|
||||
uint32_t blue_clamp_value = 0;
|
||||
uint32_t addr = FMT_REG(mmFMT_CLAMP_CNTL);
|
||||
|
||||
clamp_cntl_value = dm_read_reg(opp80->base.ctx, addr);
|
||||
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
0,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_DATA_EN);
|
||||
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
0,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_COLOR_FORMAT);
|
||||
|
||||
switch (params->clamping_level) {
|
||||
case CLAMPING_FULL_RANGE:
|
||||
break;
|
||||
|
||||
case CLAMPING_LIMITED_RANGE_8BPC:
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
1,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_DATA_EN);
|
||||
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
1,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_COLOR_FORMAT);
|
||||
|
||||
break;
|
||||
|
||||
case CLAMPING_LIMITED_RANGE_10BPC:
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
1,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_DATA_EN);
|
||||
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
2,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_COLOR_FORMAT);
|
||||
|
||||
break;
|
||||
case CLAMPING_LIMITED_RANGE_12BPC:
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
1,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_DATA_EN);
|
||||
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
3,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_COLOR_FORMAT);
|
||||
|
||||
break;
|
||||
case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
1,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_DATA_EN);
|
||||
|
||||
set_reg_field_value(clamp_cntl_value,
|
||||
7,
|
||||
FMT_CLAMP_CNTL,
|
||||
FMT_CLAMP_COLOR_FORMAT);
|
||||
|
||||
/*set the defaults*/
|
||||
set_reg_field_value(red_clamp_value,
|
||||
0x10,
|
||||
FMT_CLAMP_COMPONENT_R,
|
||||
FMT_CLAMP_LOWER_R);
|
||||
|
||||
set_reg_field_value(red_clamp_value,
|
||||
0xFEF,
|
||||
FMT_CLAMP_COMPONENT_R,
|
||||
FMT_CLAMP_UPPER_R);
|
||||
|
||||
addr = FMT_REG(mmFMT_CLAMP_COMPONENT_R);
|
||||
dm_write_reg(opp80->base.ctx, addr, red_clamp_value);
|
||||
|
||||
set_reg_field_value(green_clamp_value,
|
||||
0x10,
|
||||
FMT_CLAMP_COMPONENT_G,
|
||||
FMT_CLAMP_LOWER_G);
|
||||
|
||||
set_reg_field_value(green_clamp_value,
|
||||
0xFEF,
|
||||
FMT_CLAMP_COMPONENT_G,
|
||||
FMT_CLAMP_UPPER_G);
|
||||
|
||||
addr = FMT_REG(mmFMT_CLAMP_COMPONENT_G);
|
||||
dm_write_reg(opp80->base.ctx, addr, green_clamp_value);
|
||||
|
||||
set_reg_field_value(blue_clamp_value,
|
||||
0x10,
|
||||
FMT_CLAMP_COMPONENT_B,
|
||||
FMT_CLAMP_LOWER_B);
|
||||
|
||||
set_reg_field_value(blue_clamp_value,
|
||||
0xFEF,
|
||||
FMT_CLAMP_COMPONENT_B,
|
||||
FMT_CLAMP_UPPER_B);
|
||||
|
||||
addr = FMT_REG(mmFMT_CLAMP_COMPONENT_B);
|
||||
dm_write_reg(opp80->base.ctx, addr, blue_clamp_value);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
addr = FMT_REG(mmFMT_CLAMP_CNTL);
|
||||
/*Set clamp control*/
|
||||
dm_write_reg(opp80->base.ctx, addr, clamp_cntl_value);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* set_pixel_encoding
|
||||
*
|
||||
* Set Pixel Encoding
|
||||
* 0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly
|
||||
* 1: YCbCr 4:2:2
|
||||
*/
|
||||
static void set_pixel_encoding(
|
||||
struct dce80_opp *opp80,
|
||||
const struct clamping_and_pixel_encoding_params *params)
|
||||
{
|
||||
uint32_t fmt_cntl_value;
|
||||
uint32_t addr = FMT_REG(mmFMT_CONTROL);
|
||||
|
||||
/*RGB 4:4:4 or YCbCr 4:4:4 - 0; YCbCr 4:2:2 -1.*/
|
||||
fmt_cntl_value = dm_read_reg(opp80->base.ctx, addr);
|
||||
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
0,
|
||||
FMT_CONTROL,
|
||||
FMT_PIXEL_ENCODING);
|
||||
|
||||
if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
1,
|
||||
FMT_CONTROL,
|
||||
FMT_PIXEL_ENCODING);
|
||||
|
||||
/*00 - Pixels drop mode ,01 - Pixels average mode*/
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
0,
|
||||
FMT_CONTROL,
|
||||
FMT_SUBSAMPLING_MODE);
|
||||
|
||||
/*00 - Cb before Cr ,01 - Cr before Cb*/
|
||||
set_reg_field_value(fmt_cntl_value,
|
||||
0,
|
||||
FMT_CONTROL,
|
||||
FMT_SUBSAMPLING_ORDER);
|
||||
}
|
||||
dm_write_reg(opp80->base.ctx, addr, fmt_cntl_value);
|
||||
|
||||
}
|
||||
|
||||
void dce80_opp_program_bit_depth_reduction(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct bit_depth_reduction_params *params)
|
||||
{
|
||||
struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
|
||||
|
||||
set_truncation(opp80, params);
|
||||
set_spatial_dither(opp80, params);
|
||||
set_temporal_dither(opp80, params);
|
||||
}
|
||||
|
||||
void dce80_opp_program_clamping_and_pixel_encoding(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct clamping_and_pixel_encoding_params *params)
|
||||
{
|
||||
struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
|
||||
|
||||
set_clamping(opp80, params);
|
||||
set_pixel_encoding(opp80, params);
|
||||
}
|
||||
|
||||
void dce80_opp_set_dyn_expansion(
|
||||
struct output_pixel_processor *opp,
|
||||
enum dc_color_space color_sp,
|
||||
enum dc_color_depth color_dpth,
|
||||
enum signal_type signal)
|
||||
{
|
||||
struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
|
||||
uint32_t value;
|
||||
bool enable_dyn_exp = false;
|
||||
uint32_t addr = FMT_REG(mmFMT_DYNAMIC_EXP_CNTL);
|
||||
|
||||
value = dm_read_reg(opp->ctx, addr);
|
||||
|
||||
set_reg_field_value(value, 0,
|
||||
FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN);
|
||||
set_reg_field_value(value, 0,
|
||||
FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE);
|
||||
|
||||
/* From HW programming guide:
|
||||
FMT_DYNAMIC_EXP_EN = 0 for limited RGB or YCbCr output
|
||||
FMT_DYNAMIC_EXP_EN = 1 for RGB full range only*/
|
||||
if (color_sp == COLOR_SPACE_SRGB)
|
||||
enable_dyn_exp = true;
|
||||
|
||||
/*00 - 10-bit -> 12-bit dynamic expansion*/
|
||||
/*01 - 8-bit -> 12-bit dynamic expansion*/
|
||||
if (signal == SIGNAL_TYPE_HDMI_TYPE_A) {
|
||||
switch (color_dpth) {
|
||||
case COLOR_DEPTH_888:
|
||||
set_reg_field_value(value, enable_dyn_exp ? 1:0,
|
||||
FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN);
|
||||
set_reg_field_value(value, 1,
|
||||
FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE);
|
||||
break;
|
||||
case COLOR_DEPTH_101010:
|
||||
set_reg_field_value(value, enable_dyn_exp ? 1:0,
|
||||
FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN);
|
||||
set_reg_field_value(value, 0,
|
||||
FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE);
|
||||
break;
|
||||
case COLOR_DEPTH_121212:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dm_write_reg(opp->ctx, addr, value);
|
||||
}
|
@ -1,543 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
/* include DCE8 register header files */
|
||||
#include "dce/dce_8_0_d.h"
|
||||
#include "dce/dce_8_0_sh_mask.h"
|
||||
|
||||
#include "dce80_opp.h"
|
||||
#include "gamma_types.h"
|
||||
|
||||
#define DCP_REG(reg)\
|
||||
(reg + opp80->offsets.dcp_offset)
|
||||
|
||||
#define DCFE_REG(reg)\
|
||||
(reg + opp80->offsets.crtc_offset)
|
||||
|
||||
enum {
|
||||
MAX_PWL_ENTRY = 128,
|
||||
MAX_REGIONS_NUMBER = 16
|
||||
|
||||
};
|
||||
|
||||
struct curve_config {
|
||||
uint32_t offset;
|
||||
int8_t segments[MAX_REGIONS_NUMBER];
|
||||
int8_t begin;
|
||||
};
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function: regamma_config_regions_and_segments
|
||||
*
|
||||
* build regamma curve by using predefined hw points
|
||||
* uses interface parameters ,like EDID coeff.
|
||||
*
|
||||
* @param : parameters interface parameters
|
||||
* @return void
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* @see
|
||||
*
|
||||
*****************************************************************************
|
||||
*/
|
||||
static void regamma_config_regions_and_segments(
|
||||
struct dce80_opp *opp80, const struct pwl_params *params)
|
||||
{
|
||||
const struct gamma_curve *curve;
|
||||
uint32_t value = 0;
|
||||
|
||||
{
|
||||
set_reg_field_value(
|
||||
value,
|
||||
params->arr_points[0].custom_float_x,
|
||||
REGAMMA_CNTLA_START_CNTL,
|
||||
REGAMMA_CNTLA_EXP_REGION_START);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
0,
|
||||
REGAMMA_CNTLA_START_CNTL,
|
||||
REGAMMA_CNTLA_EXP_REGION_START_SEGMENT);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_START_CNTL),
|
||||
value);
|
||||
}
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
params->arr_points[0].custom_float_slope,
|
||||
REGAMMA_CNTLA_SLOPE_CNTL,
|
||||
REGAMMA_CNTLA_EXP_REGION_LINEAR_SLOPE);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_SLOPE_CNTL), value);
|
||||
}
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
params->arr_points[1].custom_float_x,
|
||||
REGAMMA_CNTLA_END_CNTL1,
|
||||
REGAMMA_CNTLA_EXP_REGION_END);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_END_CNTL1), value);
|
||||
}
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
params->arr_points[2].custom_float_slope,
|
||||
REGAMMA_CNTLA_END_CNTL2,
|
||||
REGAMMA_CNTLA_EXP_REGION_END_BASE);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
params->arr_points[1].custom_float_y,
|
||||
REGAMMA_CNTLA_END_CNTL2,
|
||||
REGAMMA_CNTLA_EXP_REGION_END_SLOPE);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_END_CNTL2), value);
|
||||
}
|
||||
|
||||
curve = params->arr_curve_points;
|
||||
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_0_1,
|
||||
REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_0_1,
|
||||
REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_0_1,
|
||||
REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_0_1,
|
||||
REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(
|
||||
opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_0_1),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_2_3,
|
||||
REGAMMA_CNTLA_EXP_REGION2_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_2_3,
|
||||
REGAMMA_CNTLA_EXP_REGION2_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_2_3,
|
||||
REGAMMA_CNTLA_EXP_REGION3_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_2_3,
|
||||
REGAMMA_CNTLA_EXP_REGION3_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_2_3),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_4_5,
|
||||
REGAMMA_CNTLA_EXP_REGION4_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_4_5,
|
||||
REGAMMA_CNTLA_EXP_REGION4_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_4_5,
|
||||
REGAMMA_CNTLA_EXP_REGION5_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_4_5,
|
||||
REGAMMA_CNTLA_EXP_REGION5_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_4_5),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_6_7,
|
||||
REGAMMA_CNTLA_EXP_REGION6_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_6_7,
|
||||
REGAMMA_CNTLA_EXP_REGION6_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_6_7,
|
||||
REGAMMA_CNTLA_EXP_REGION7_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_6_7,
|
||||
REGAMMA_CNTLA_EXP_REGION7_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_6_7),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_8_9,
|
||||
REGAMMA_CNTLA_EXP_REGION8_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_8_9,
|
||||
REGAMMA_CNTLA_EXP_REGION8_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_8_9,
|
||||
REGAMMA_CNTLA_EXP_REGION9_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_8_9,
|
||||
REGAMMA_CNTLA_EXP_REGION9_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_8_9),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_10_11,
|
||||
REGAMMA_CNTLA_EXP_REGION10_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_10_11,
|
||||
REGAMMA_CNTLA_EXP_REGION10_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_10_11,
|
||||
REGAMMA_CNTLA_EXP_REGION11_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_10_11,
|
||||
REGAMMA_CNTLA_EXP_REGION11_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_10_11),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_12_13,
|
||||
REGAMMA_CNTLA_EXP_REGION12_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_12_13,
|
||||
REGAMMA_CNTLA_EXP_REGION12_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_12_13,
|
||||
REGAMMA_CNTLA_EXP_REGION13_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_12_13,
|
||||
REGAMMA_CNTLA_EXP_REGION13_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_12_13),
|
||||
value);
|
||||
}
|
||||
|
||||
curve += 2;
|
||||
{
|
||||
value = 0;
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].offset,
|
||||
REGAMMA_CNTLA_REGION_14_15,
|
||||
REGAMMA_CNTLA_EXP_REGION14_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[0].segments_num,
|
||||
REGAMMA_CNTLA_REGION_14_15,
|
||||
REGAMMA_CNTLA_EXP_REGION14_NUM_SEGMENTS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].offset,
|
||||
REGAMMA_CNTLA_REGION_14_15,
|
||||
REGAMMA_CNTLA_EXP_REGION15_LUT_OFFSET);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
curve[1].segments_num,
|
||||
REGAMMA_CNTLA_REGION_14_15,
|
||||
REGAMMA_CNTLA_EXP_REGION15_NUM_SEGMENTS);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CNTLA_REGION_14_15),
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
static void program_pwl(
|
||||
struct dce80_opp *opp80,
|
||||
const struct pwl_params *params)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
{
|
||||
uint8_t max_tries = 10;
|
||||
uint8_t counter = 0;
|
||||
|
||||
/* Power on LUT memory */
|
||||
value = dm_read_reg(opp80->base.ctx,
|
||||
DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL));
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
1,
|
||||
DCFE_MEM_LIGHT_SLEEP_CNTL,
|
||||
REGAMMA_LUT_LIGHT_SLEEP_DIS);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL), value);
|
||||
|
||||
while (counter < max_tries) {
|
||||
value =
|
||||
dm_read_reg(
|
||||
opp80->base.ctx,
|
||||
DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL));
|
||||
|
||||
if (get_reg_field_value(
|
||||
value,
|
||||
DCFE_MEM_LIGHT_SLEEP_CNTL,
|
||||
REGAMMA_LUT_MEM_PWR_STATE) == 0)
|
||||
break;
|
||||
|
||||
++counter;
|
||||
}
|
||||
|
||||
if (counter == max_tries) {
|
||||
dm_logger_write(opp80->base.ctx->logger, LOG_WARNING,
|
||||
"%s: regamma lut was not powered on "
|
||||
"in a timely manner,"
|
||||
" programming still proceeds\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
|
||||
value = 0;
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
7,
|
||||
REGAMMA_LUT_WRITE_EN_MASK,
|
||||
REGAMMA_LUT_WRITE_EN_MASK);
|
||||
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_LUT_WRITE_EN_MASK), value);
|
||||
dm_write_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_LUT_INDEX), 0);
|
||||
|
||||
/* Program REGAMMA_LUT_DATA */
|
||||
{
|
||||
const uint32_t addr = DCP_REG(mmREGAMMA_LUT_DATA);
|
||||
|
||||
uint32_t i = 0;
|
||||
|
||||
const struct pwl_result_data *rgb =
|
||||
params->rgb_resulted;
|
||||
|
||||
while (i != params->hw_points_num) {
|
||||
dm_write_reg(opp80->base.ctx, addr, rgb->red_reg);
|
||||
dm_write_reg(opp80->base.ctx, addr, rgb->green_reg);
|
||||
dm_write_reg(opp80->base.ctx, addr, rgb->blue_reg);
|
||||
|
||||
dm_write_reg(opp80->base.ctx, addr,
|
||||
rgb->delta_red_reg);
|
||||
dm_write_reg(opp80->base.ctx, addr,
|
||||
rgb->delta_green_reg);
|
||||
dm_write_reg(opp80->base.ctx, addr,
|
||||
rgb->delta_blue_reg);
|
||||
|
||||
++rgb;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
/* we are done with DCP LUT memory; re-enable low power mode */
|
||||
value = dm_read_reg(opp80->base.ctx,
|
||||
DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL));
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
0,
|
||||
DCFE_MEM_LIGHT_SLEEP_CNTL,
|
||||
REGAMMA_LUT_LIGHT_SLEEP_DIS);
|
||||
|
||||
dm_write_reg(opp80->base.ctx, DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL),
|
||||
value);
|
||||
}
|
||||
|
||||
void dce80_opp_power_on_regamma_lut(
|
||||
struct output_pixel_processor *opp,
|
||||
bool power_on)
|
||||
{
|
||||
struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
|
||||
|
||||
uint32_t value =
|
||||
dm_read_reg(opp->ctx, DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL));
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
power_on,
|
||||
DCFE_MEM_LIGHT_SLEEP_CNTL,
|
||||
REGAMMA_LUT_LIGHT_SLEEP_DIS);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
power_on,
|
||||
DCFE_MEM_LIGHT_SLEEP_CNTL,
|
||||
DCP_LUT_LIGHT_SLEEP_DIS);
|
||||
|
||||
dm_write_reg(opp->ctx, DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL), value);
|
||||
}
|
||||
|
||||
bool dce80_opp_program_regamma_pwl(
|
||||
struct output_pixel_processor *opp,
|
||||
const struct pwl_params *params)
|
||||
{
|
||||
|
||||
struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
|
||||
|
||||
regamma_config_regions_and_segments(opp80, params);
|
||||
|
||||
program_pwl(opp80, params);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dce80_opp_set_regamma_mode(struct output_pixel_processor *opp,
|
||||
enum opp_regamma mode)
|
||||
{
|
||||
struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
|
||||
uint32_t value = dm_read_reg(opp80->base.ctx,
|
||||
DCP_REG(mmREGAMMA_CONTROL));
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
mode,
|
||||
REGAMMA_CONTROL,
|
||||
GRPH_REGAMMA_MODE);
|
||||
|
||||
dm_write_reg(opp80->base.ctx, DCP_REG(mmREGAMMA_CONTROL), value);
|
||||
}
|
@ -43,7 +43,7 @@
|
||||
#include "dce80/dce80_mem_input.h"
|
||||
#include "dce80/dce80_ipp.h"
|
||||
#include "dce/dce_transform.h"
|
||||
#include "dce80/dce80_opp.h"
|
||||
#include "dce/dce_opp.h"
|
||||
#include "dce110/dce110_ipp.h"
|
||||
#include "dce/dce_clocks.h"
|
||||
#include "dce/dce_clock_source.h"
|
||||
@ -317,6 +317,28 @@ static const struct dce_stream_encoder_mask se_mask = {
|
||||
SE_COMMON_MASK_SH_LIST_DCE80_100(_MASK)
|
||||
};
|
||||
|
||||
#define opp_regs(id)\
|
||||
[id] = {\
|
||||
OPP_DCE_80_REG_LIST(id),\
|
||||
}
|
||||
|
||||
static const struct dce_opp_registers opp_regs[] = {
|
||||
opp_regs(0),
|
||||
opp_regs(1),
|
||||
opp_regs(2),
|
||||
opp_regs(3),
|
||||
opp_regs(4),
|
||||
opp_regs(5)
|
||||
};
|
||||
|
||||
static const struct dce_opp_shift opp_shift = {
|
||||
OPP_COMMON_MASK_SH_LIST_DCE_80(__SHIFT)
|
||||
};
|
||||
|
||||
static const struct dce_opp_mask opp_mask = {
|
||||
OPP_COMMON_MASK_SH_LIST_DCE_80(_MASK)
|
||||
};
|
||||
|
||||
#define audio_regs(id)\
|
||||
[id] = {\
|
||||
AUD_COMMON_REG_LIST(id)\
|
||||
@ -419,6 +441,25 @@ static struct timing_generator *dce80_timing_generator_create(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct output_pixel_processor *dce80_opp_create(
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst)
|
||||
{
|
||||
struct dce110_opp *opp =
|
||||
dm_alloc(sizeof(struct dce110_opp));
|
||||
|
||||
if (!opp)
|
||||
return NULL;
|
||||
|
||||
if (dce110_opp_construct(opp,
|
||||
ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask))
|
||||
return &opp->base;
|
||||
|
||||
BREAK_TO_DEBUGGER();
|
||||
dm_free(opp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct stream_encoder *dce80_stream_encoder_create(
|
||||
enum engine_id eng_id,
|
||||
struct dc_context *ctx)
|
||||
@ -631,7 +672,7 @@ static void destruct(struct dce110_resource_pool *pool)
|
||||
|
||||
for (i = 0; i < pool->base.pipe_count; i++) {
|
||||
if (pool->base.opps[i] != NULL)
|
||||
dce80_opp_destroy(&pool->base.opps[i]);
|
||||
dce110_opp_destroy(&pool->base.opps[i]);
|
||||
|
||||
if (pool->base.transforms[i] != NULL)
|
||||
dce80_transform_destroy(&pool->base.transforms[i]);
|
||||
|
Loading…
Reference in New Issue
Block a user