drm/amd/display: Add DCN3 Resource

Add support for managing resources for DCN3

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Bhawanpreet Lakha 2020-05-21 12:51:51 -04:00 committed by Alex Deucher
parent 790373245e
commit 5dba4991fd
9 changed files with 2931 additions and 1 deletions

View File

@ -52,6 +52,9 @@
#include "dcn20/dcn20_resource.h"
#include "dcn21/dcn21_resource.h"
#endif
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
#include "../dcn30/dcn30_resource.h"
#endif
#define DC_LOGGER_INIT(logger)
@ -107,6 +110,10 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
case FAMILY_NV:
dc_version = DCN_VERSION_2_0;
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev))
dc_version = DCN_VERSION_3_0;
#endif
break;
default:
dc_version = DCE_VERSION_UNKNOWN;
@ -168,6 +175,11 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc,
res_pool = dcn21_create_resource_pool(init_data, dc);
break;
#endif
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
case DCN_VERSION_3_0:
res_pool = dcn30_create_resource_pool(init_data, dc);
break;
#endif
default:
break;
@ -282,6 +294,16 @@ bool resource_construct(
}
}
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
for (i = 0; i < caps->num_mpc_3dlut; i++) {
pool->mpc_lut[i] = dc_create_3dlut_func();
if (pool->mpc_lut[i] == NULL)
DC_ERR("DC: failed to create MPC 3dlut!\n");
pool->mpc_shaper[i] = dc_create_transfer_func();
if (pool->mpc_shaper[i] == NULL)
DC_ERR("DC: failed to create MPC shaper!\n");
}
#endif
dc->caps.dynamic_audio = false;
if (pool->audio_count < pool->stream_enc_count) {
dc->caps.dynamic_audio = true;
@ -2049,8 +2071,16 @@ enum dc_status resource_map_pool_resources(
}
/* Add ABM to the resource if on EDP */
if (pipe_ctx->stream && dc_is_embedded_signal(pipe_ctx->stream->signal))
if (pipe_ctx->stream && dc_is_embedded_signal(pipe_ctx->stream->signal)) {
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
if (pool->abm)
pipe_ctx->stream_res.abm = pool->abm;
else
pipe_ctx->stream_res.abm = pool->multiple_abms[pipe_ctx->stream_res.tg->inst];
#else
pipe_ctx->stream_res.abm = pool->abm;
#endif
}
for (i = 0; i < context->stream_count; i++)
if (context->streams[i] == stream) {
@ -2867,6 +2897,10 @@ unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format)
case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
case SURFACE_PIXEL_FORMAT_GRPH_RGBE:
case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
#endif
return 32;
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:

View File

@ -287,6 +287,9 @@ struct dc_config {
bool multi_mon_pp_mclk_switch;
bool disable_dmcu;
bool enable_4to1MPC;
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
bool clamp_min_dcfclk;
#endif
};
enum visual_confirm {
@ -464,6 +467,9 @@ struct dc_debug_options {
bool skip_detection_link_training;
bool remove_disconnect_edp;
unsigned int force_odm_combine; //bit vector based on otg inst
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
unsigned int force_odm_combine_4to1; //bit vector based on otg inst
#endif
unsigned int force_fclk_khz;
bool disable_tri_buf;
bool dmub_offload_enabled;
@ -479,6 +485,9 @@ struct dc_debug_options {
* watermarks are not affected.
*/
unsigned int force_min_dcfclk_mhz;
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
int dwb_fi_phase;
#endif
bool disable_timing_sync;
bool cm_in_bypass;
int force_clock_mode;/*every mode change.*/
@ -839,6 +848,9 @@ struct dc_plane_state {
struct dc_transfer_func *in_shaper_func;
struct dc_transfer_func *blend_tf;
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
struct dc_transfer_func *gamcor_tf;
#endif
enum surface_pixel_format format;
enum dc_rotation_angle rotation;
enum plane_stereo_format stereo_format;
@ -984,6 +996,14 @@ void dc_resource_state_construct(
const struct dc *dc,
struct dc_state *dst_ctx);
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
bool dc_acquire_release_mpc_3dlut(
struct dc *dc, bool acquire,
struct dc_stream_state *stream,
struct dc_3dlut **lut,
struct dc_transfer_func **shaper);
#endif
void dc_resource_state_copy_construct(
const struct dc_state *src_ctx,
struct dc_state *dst_ctx);
@ -1103,6 +1123,10 @@ struct hdcp_caps {
#include "dc_link.h"
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane);
#endif
/*******************************************************************************
* Sink Interfaces - A sink corresponds to a display output device
******************************************************************************/

View File

@ -76,6 +76,22 @@
SR(DC_ABM1_HGLS_REG_READ_PROGRESS), \
NBIO_SR(BIOS_SCRATCH_2)
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
#define ABM_DCN301_REG_LIST(id)\
ABM_COMMON_REG_LIST_DCE_BASE(), \
SRI(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \
SRI(DC_ABM1_LS_SAMPLE_RATE, ABM, id), \
SRI(BL1_PWM_BL_UPDATE_SAMPLE_RATE, ABM, id), \
SRI(DC_ABM1_HG_MISC_CTRL, ABM, id), \
SRI(DC_ABM1_IPCSC_COEFF_SEL, ABM, id), \
SRI(BL1_PWM_CURRENT_ABM_LEVEL, ABM, id), \
SRI(BL1_PWM_TARGET_ABM_LEVEL, ABM, id), \
SRI(BL1_PWM_USER_LEVEL, ABM, id), \
SRI(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, ABM, id), \
SRI(DC_ABM1_HGLS_REG_READ_PROGRESS, ABM, id), \
NBIO_SR(BIOS_SCRATCH_2)
#endif
#define ABM_SF(reg_name, field_name, post_fix)\
.field_name = reg_name ## __ ## field_name ## post_fix
@ -149,6 +165,10 @@
#define ABM_MASK_SH_LIST_DCN20(mask_sh) ABM_MASK_SH_LIST_DCE110(mask_sh)
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
#define ABM_MASK_SH_LIST_DCN301(mask_sh) ABM_MASK_SH_LIST_DCN10(mask_sh)
#endif
#define ABM_REG_FIELD_LIST(type) \
type ABM1_HG_NUM_OF_BINS_SEL; \
type ABM1_HG_VMAX_SEL; \

View File

@ -2033,6 +2033,9 @@ int dcn20_populate_dml_pipes_from_context(
unsigned int front_porch;
int output_bpc;
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
struct audio_check aud_check = {0};
#endif
if (!res_ctx->pipe_ctx[i].stream)
continue;
@ -2087,6 +2090,11 @@ int dcn20_populate_dml_pipes_from_context(
case 1:
pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1;
break;
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
case 3:
pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_4to1;
break;
#endif
default:
pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_disabled;
}
@ -2183,6 +2191,11 @@ int dcn20_populate_dml_pipes_from_context(
/* todo: default max for now, until there is logic reflecting this in dc*/
pipes[pipe_cnt].dout.output_bpc = 12;
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
/*fill up the audio sample rate*/
get_audio_check(&res_ctx->pipe_ctx[i].stream->audio_info, &aud_check);
pipes[pipe_cnt].dout.max_audio_sample_rate = aud_check.max_audiosample_rate;
#endif
/*
* For graphic plane, cursor number is 1, nv12 is 0
* bw calculations due to cursor on/off
@ -2230,6 +2243,12 @@ int dcn20_populate_dml_pipes_from_context(
pipes[pipe_cnt].pipe.src.viewport_width /= 2;
pipes[pipe_cnt].pipe.dest.recout_width /= 2;
}
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) {
pipes[pipe_cnt].pipe.src.viewport_width /= 4;
pipes[pipe_cnt].pipe.dest.recout_width /= 4;
}
#endif
} else {
struct dc_plane_state *pln = res_ctx->pipe_ctx[i].plane_state;
struct scaler_data *scl = &res_ctx->pipe_ctx[i].plane_res.scl_data;
@ -2250,7 +2269,12 @@ int dcn20_populate_dml_pipes_from_context(
pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height;
pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width;
pipes[pipe_cnt].pipe.src.surface_height_c = pln->plane_size.chroma_size.height;
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
if (pln->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA
|| pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
#else
if (pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
#endif
pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.chroma_pitch;
pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
@ -2266,6 +2290,10 @@ int dcn20_populate_dml_pipes_from_context(
pipes[pipe_cnt].pipe.dest.full_recout_width = scl->recout.width;
if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1)
pipes[pipe_cnt].pipe.dest.full_recout_width *= 2;
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1)
pipes[pipe_cnt].pipe.dest.full_recout_width *= 4;
#endif
else {
struct pipe_ctx *split_pipe = res_ctx->pipe_ctx[i].bottom_pipe;
@ -2322,6 +2350,11 @@ int dcn20_populate_dml_pipes_from_context(
case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
pipes[pipe_cnt].pipe.src.source_format = dm_444_8;
break;
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
pipes[pipe_cnt].pipe.src.source_format = dm_rgbe_alpha;
break;
#endif
default:
pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
break;
@ -2682,6 +2715,12 @@ int dcn20_validate_apply_pipe_split_flags(
split[i] = 2;
v->ODMCombineEnablePerState[vlevel][pipe_plane] = dm_odm_combine_mode_2to1;
}
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
if (dc->debug.force_odm_combine_4to1 & (1 << pipe->stream_res.tg->inst)) {
split[i] = 4;
v->ODMCombineEnablePerState[vlevel][pipe_plane] = dm_odm_combine_mode_4to1;
}
#endif
v->ODMCombineEnabled[pipe_plane] =
v->ODMCombineEnablePerState[vlevel][pipe_plane];

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,82 @@
/*
* Copyright 2020 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 _DCN30_RESOURCE_H_
#define _DCN30_RESOURCE_H_
#include "core_types.h"
#define TO_DCN30_RES_POOL(pool)\
container_of(pool, struct dcn30_resource_pool, base)
struct dc;
struct resource_pool;
struct _vcs_dpi_display_pipe_params_st;
struct dcn30_resource_pool {
struct resource_pool base;
};
struct resource_pool *dcn30_create_resource_pool(
const struct dc_init_data *init_data,
struct dc *dc);
void dcn30_set_mcif_arb_params(
struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt);
unsigned int dcn30_calc_max_scaled_time(
unsigned int time_per_pixel,
enum mmhubbub_wbif_mode mode,
unsigned int urgent_watermark);
bool dcn30_validate_bandwidth(struct dc *dc, struct dc_state *context,
bool fast_validate);
void dcn30_populate_dml_writeback_from_context(
struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes);
int dcn30_populate_dml_pipes_from_context(
struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes);
bool dcn30_acquire_post_bldn_3dlut(
struct resource_context *res_ctx,
const struct resource_pool *pool,
int mpcc_id,
struct dc_3dlut **lut,
struct dc_transfer_func **shaper);
bool dcn30_release_post_bldn_3dlut(
struct resource_context *res_ctx,
const struct resource_pool *pool,
struct dc_3dlut **lut,
struct dc_transfer_func **shaper);
enum dc_status dcn30_add_stream_to_ctx(
struct dc *dc,
struct dc_state *new_ctx,
struct dc_stream_state *dc_stream);
#endif /* _DCN30_RESOURCE_H_ */

View File

@ -147,6 +147,20 @@ struct resource_funcs {
void (*update_bw_bounding_box)(
struct dc *dc,
struct clk_bw_params *bw_params);
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
bool (*acquire_post_bldn_3dlut)(
struct resource_context *res_ctx,
const struct resource_pool *pool,
int mpcc_id,
struct dc_3dlut **lut,
struct dc_transfer_func **shaper);
bool (*release_post_bldn_3dlut)(
struct resource_context *res_ctx,
const struct resource_pool *pool,
struct dc_3dlut **lut,
struct dc_transfer_func **shaper);
#endif
};
@ -189,6 +203,10 @@ struct resource_pool {
unsigned int underlay_pipe_index;
unsigned int stream_enc_count;
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
struct dc_3dlut *mpc_lut[MAX_PIPES];
struct dc_transfer_func *mpc_shaper[MAX_PIPES];
#endif
struct {
unsigned int xtalin_clock_inKhz;
unsigned int dccg_ref_clock_inKhz;
@ -316,6 +334,9 @@ struct resource_context {
uint8_t clock_source_ref_count[MAX_CLOCK_SOURCES];
uint8_t dp_clock_source_ref_count;
bool is_dsc_acquired[MAX_PIPES];
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
bool is_mpc_3dlut_acquired[MAX_PIPES];
#endif
};
struct dce_bw_output {

View File

@ -150,6 +150,15 @@ enum ipp_degamma_mode {
IPP_DEGAMMA_MODE_USER_PWL
};
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
enum gamcor_mode {
GAMCOR_MODE_BYPASS,
GAMCOR_MODE_RESERVED_1,
GAMCOR_MODE_USER_PWL,
GAMCOR_MODE_RESERVED_3
};
#endif
enum ipp_output_format {
IPP_OUTPUT_FORMAT_12_BIT_FIX,
IPP_OUTPUT_FORMAT_16_BIT_BYPASS,

View File

@ -48,6 +48,9 @@ struct resource_caps {
int num_ddc;
int num_vmid;
int num_dsc;
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
int num_mpc_3dlut;
#endif
};
struct resource_straps {