/*
* 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 "core_types.h"
#include "dm_services.h"
#include "dcn20_opp.h"
#include "reg_helper.h"
#define REG(reg) \
(oppn20->regs->reg)
#undef FN
#define FN(reg_name, field_name) \
oppn20->opp_shift->field_name, oppn20->opp_mask->field_name
#define CTX \
oppn20->base.ctx
void opp2_set_disp_pattern_generator(
struct output_pixel_processor *opp,
enum controller_dp_test_pattern test_pattern,
enum controller_dp_color_space color_space,
enum dc_color_depth color_depth,
const struct tg_color *solid_color,
int width,
int height,
int offset)
{
struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
enum test_pattern_color_format bit_depth;
enum test_pattern_dyn_range dyn_range;
enum test_pattern_mode mode;
/* color ramp generator mixes 16-bits color */
uint32_t src_bpc = 16 ;
/* requested bpc */
uint32_t dst_bpc;
uint32_t index;
/* RGB values of the color bars.
* Produce two RGB colors : RGB0 - white ( all Fs )
* and RGB1 - black ( all 0 s )
* ( three RGB components for two colors )
*/
uint16_t src_color[6 ] = {0 xFFFF, 0 xFFFF, 0 xFFFF, 0 x0000,
0 x0000, 0 x0000};
/* dest color (converted to the specified color format) */
uint16_t dst_color[6 ];
uint32_t inc_base;
/* translate to bit depth */
switch (color_depth) {
case COLOR_DEPTH_666:
bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
break ;
case COLOR_DEPTH_888:
bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
break ;
case COLOR_DEPTH_101010:
bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
break ;
case COLOR_DEPTH_121212:
bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
break ;
default :
bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
break ;
}
/* set DPG dimentions */
REG_SET_2(DPG_DIMENSIONS, 0 ,
DPG_ACTIVE_WIDTH, width,
DPG_ACTIVE_HEIGHT, height);
/* set DPG offset */
REG_SET_2(DPG_OFFSET_SEGMENT, 0 ,
DPG_X_OFFSET, offset,
DPG_SEGMENT_WIDTH, 0 );
switch (test_pattern) {
case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
{
dyn_range = (test_pattern ==
CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
TEST_PATTERN_DYN_RANGE_CEA :
TEST_PATTERN_DYN_RANGE_VESA);
switch (color_space) {
case CONTROLLER_DP_COLOR_SPACE_YCBCR601:
mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR601;
break ;
case CONTROLLER_DP_COLOR_SPACE_YCBCR709:
mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR709;
break ;
case CONTROLLER_DP_COLOR_SPACE_RGB:
default :
mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
break ;
}
REG_UPDATE_6(DPG_CONTROL,
DPG_EN, 1 ,
DPG_MODE, mode,
DPG_DYNAMIC_RANGE, dyn_range,
DPG_BIT_DEPTH, bit_depth,
DPG_VRES, 6 ,
DPG_HRES, 6 );
}
break ;
case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
{
mode = (test_pattern ==
CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
TEST_PATTERN_MODE_VERTICALBARS :
TEST_PATTERN_MODE_HORIZONTALBARS);
switch (bit_depth) {
case TEST_PATTERN_COLOR_FORMAT_BPC_6:
dst_bpc = 6 ;
break ;
case TEST_PATTERN_COLOR_FORMAT_BPC_8:
dst_bpc = 8 ;
break ;
case TEST_PATTERN_COLOR_FORMAT_BPC_10:
dst_bpc = 10 ;
break ;
default :
dst_bpc = 8 ;
break ;
}
/* adjust color to the required colorFormat */
for (index = 0 ; index < 6 ; index++) {
/* dst = 2^dstBpc * src / 2^srcBpc = src >>
* ( srcBpc - dstBpc ) ;
*/
dst_color[index] =
src_color[index] >> (src_bpc - dst_bpc);
/* DPG_COLOUR registers are 16-bit MSB aligned value with bits 3:0 hardwired to ZERO.
* XXXXXXXXXX000000 for 10 bit ,
* XXXXXXXX00000000 for 8 bit ,
* XXXXXX0000000000 for 6 bits
*/
dst_color[index] <<= (16 - dst_bpc);
}
REG_SET_2(DPG_COLOUR_R_CR, 0 ,
DPG_COLOUR1_R_CR, dst_color[0 ],
DPG_COLOUR0_R_CR, dst_color[3 ]);
REG_SET_2(DPG_COLOUR_G_Y, 0 ,
DPG_COLOUR1_G_Y, dst_color[1 ],
DPG_COLOUR0_G_Y, dst_color[4 ]);
REG_SET_2(DPG_COLOUR_B_CB, 0 ,
DPG_COLOUR1_B_CB, dst_color[2 ],
DPG_COLOUR0_B_CB, dst_color[5 ]);
/* enable test pattern */
REG_UPDATE_6(DPG_CONTROL,
DPG_EN, 1 ,
DPG_MODE, mode,
DPG_DYNAMIC_RANGE, 0 ,
DPG_BIT_DEPTH, bit_depth,
DPG_VRES, 0 ,
DPG_HRES, 0 );
}
break ;
case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
{
mode = (bit_depth ==
TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
TEST_PATTERN_MODE_DUALRAMP_RGB :
TEST_PATTERN_MODE_SINGLERAMP_RGB);
switch (bit_depth) {
case TEST_PATTERN_COLOR_FORMAT_BPC_6:
dst_bpc = 6 ;
break ;
case TEST_PATTERN_COLOR_FORMAT_BPC_8:
dst_bpc = 8 ;
break ;
case TEST_PATTERN_COLOR_FORMAT_BPC_10:
dst_bpc = 10 ;
break ;
default :
dst_bpc = 8 ;
break ;
}
/* increment for the first ramp for one color gradation
* 1 gradation for 6 - bit color is 2 ^ 10
* gradations in 16 - bit color
*/
inc_base = (src_bpc - dst_bpc);
switch (bit_depth) {
case TEST_PATTERN_COLOR_FORMAT_BPC_6:
{
REG_SET_3(DPG_RAMP_CONTROL, 0 ,
DPG_RAMP0_OFFSET, 0 ,
DPG_INC0, inc_base,
DPG_INC1, 0 );
REG_UPDATE_2(DPG_CONTROL,
DPG_VRES, 6 ,
DPG_HRES, 6 );
}
break ;
case TEST_PATTERN_COLOR_FORMAT_BPC_8:
{
REG_SET_3(DPG_RAMP_CONTROL, 0 ,
DPG_RAMP0_OFFSET, 0 ,
DPG_INC0, inc_base,
DPG_INC1, 0 );
REG_UPDATE_2(DPG_CONTROL,
DPG_VRES, 6 ,
DPG_HRES, 8 );
}
break ;
case TEST_PATTERN_COLOR_FORMAT_BPC_10:
{
REG_SET_3(DPG_RAMP_CONTROL, 0 ,
DPG_RAMP0_OFFSET, 384 << 6 ,
DPG_INC0, inc_base,
DPG_INC1, inc_base + 2 );
REG_UPDATE_2(DPG_CONTROL,
DPG_VRES, 5 ,
DPG_HRES, 8 );
}
break ;
default :
break ;
}
/* enable test pattern */
REG_UPDATE_4(DPG_CONTROL,
DPG_EN, 1 ,
DPG_MODE, mode,
DPG_DYNAMIC_RANGE, 0 ,
DPG_BIT_DEPTH, bit_depth);
}
break ;
case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
{
REG_WRITE(DPG_CONTROL, 0 );
REG_WRITE(DPG_COLOUR_R_CR, 0 );
REG_WRITE(DPG_COLOUR_G_Y, 0 );
REG_WRITE(DPG_COLOUR_B_CB, 0 );
REG_WRITE(DPG_RAMP_CONTROL, 0 );
}
break ;
case CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR:
{
opp2_dpg_set_blank_color(opp, solid_color);
REG_UPDATE_2(DPG_CONTROL,
DPG_EN, 1 ,
DPG_MODE, TEST_PATTERN_MODE_HORIZONTALBARS);
REG_SET_2(DPG_DIMENSIONS, 0 ,
DPG_ACTIVE_WIDTH, width,
DPG_ACTIVE_HEIGHT, height);
}
break ;
default :
break ;
}
}
void opp2_program_dpg_dimensions(
struct output_pixel_processor *opp,
int width, int height)
{
struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
REG_SET_2(DPG_DIMENSIONS, 0 ,
DPG_ACTIVE_WIDTH, width,
DPG_ACTIVE_HEIGHT, height);
}
void opp2_dpg_set_blank_color(
struct output_pixel_processor *opp,
const struct tg_color *color)
{
struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
/* 16-bit MSB aligned value. Bits 3:0 of this field are hardwired to ZERO */
ASSERT(color);
REG_SET_2(DPG_COLOUR_B_CB, 0 ,
DPG_COLOUR1_B_CB, color->color_b_cb << 6 ,
DPG_COLOUR0_B_CB, color->color_b_cb << 6 );
REG_SET_2(DPG_COLOUR_G_Y, 0 ,
DPG_COLOUR1_G_Y, color->color_g_y << 6 ,
DPG_COLOUR0_G_Y, color->color_g_y << 6 );
REG_SET_2(DPG_COLOUR_R_CR, 0 ,
DPG_COLOUR1_R_CR, color->color_r_cr << 6 ,
DPG_COLOUR0_R_CR, color->color_r_cr << 6 );
}
bool opp2_dpg_is_blanked(struct output_pixel_processor *opp)
{
struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
uint32_t dpg_en, dpg_mode;
uint32_t double_buffer_pending;
REG_GET_2(DPG_CONTROL,
DPG_EN, &dpg_en,
DPG_MODE, &dpg_mode);
REG_GET(DPG_STATUS,
DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending);
return (dpg_en == 1 ) &&
(double_buffer_pending == 0 );
}
bool opp2_dpg_is_pending(struct output_pixel_processor *opp)
{
struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
uint32_t double_buffer_pending;
uint32_t dpg_en;
REG_GET(DPG_CONTROL, DPG_EN, &dpg_en);
REG_GET(DPG_STATUS, DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending);
return (dpg_en == 1 && double_buffer_pending == 1 );
}
void opp2_program_left_edge_extra_pixel(
struct output_pixel_processor *opp,
enum dc_pixel_encoding pixel_encoding,
bool is_primary)
{
struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
uint32_t count = opp2_get_left_edge_extra_pixel_count(opp, pixel_encoding, is_primary);
/*
* Specifies the number of extra left edge pixels that are supplied to
* the 422 horizontal chroma sub - sample filter .
*/
REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count);
}
uint32_t opp2_get_left_edge_extra_pixel_count(struct output_pixel_processor *opp,
enum dc_pixel_encoding pixel_encoding, bool is_primary)
{
if ((pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == PIXEL_ENCODING_YCBCR420) &&
!opp->ctx->dc->debug.force_chroma_subsampling_1tap &&
!is_primary)
return 1 ;
else
return 0 ;
}
/*****************************************/
/* Constructor, Destructor */
/*****************************************/
static struct opp_funcs dcn20_opp_funcs = {
.opp_set_dyn_expansion = opp1_set_dyn_expansion,
.opp_program_fmt = opp1_program_fmt,
.opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction,
.opp_program_stereo = opp1_program_stereo,
.opp_pipe_clock_control = opp1_pipe_clock_control,
.opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator,
.opp_program_dpg_dimensions = opp2_program_dpg_dimensions,
.dpg_is_blanked = opp2_dpg_is_blanked,
.dpg_is_pending = opp2_dpg_is_pending,
.opp_dpg_set_blank_color = opp2_dpg_set_blank_color,
.opp_destroy = opp1_destroy,
.opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel,
.opp_get_left_edge_extra_pixel_count = opp2_get_left_edge_extra_pixel_count,
};
void dcn20_opp_construct(struct dcn20_opp *oppn20,
struct dc_context *ctx,
uint32_t inst,
const struct dcn20_opp_registers *regs,
const struct dcn20_opp_shift *opp_shift,
const struct dcn20_opp_mask *opp_mask)
{
oppn20->base.ctx = ctx;
oppn20->base.inst = inst;
oppn20->base.funcs = &dcn20_opp_funcs;
oppn20->regs = regs;
oppn20->opp_shift = opp_shift;
oppn20->opp_mask = opp_mask;
}
Messung V0.5 in Prozent C=96 H=99 G=97
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.11Bemerkung:
(vorverarbeitet am 2026-10-11)
¤
*Bot Zugriff