summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/dcn10
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn10')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c16
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h81
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c72
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h53
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c416
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c72
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c25
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h14
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c59
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h22
18 files changed, 692 insertions, 192 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index 7469333a2c8a..01c7e30b9ce1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -343,8 +343,8 @@ bool cm_helper_translate_curve_to_hw_format(
region_start = -MAX_LOW_POINT;
region_end = NUMBER_REGIONS - MAX_LOW_POINT;
} else {
- /* 10 segments
- * segment is from 2^-10 to 2^0
+ /* 11 segments
+ * segment is from 2^-10 to 2^1
* There are less than 256 points, for optimization
*/
seg_distr[0] = 3;
@@ -357,9 +357,10 @@ bool cm_helper_translate_curve_to_hw_format(
seg_distr[7] = 4;
seg_distr[8] = 4;
seg_distr[9] = 4;
+ seg_distr[10] = 1;
region_start = -10;
- region_end = 0;
+ region_end = 1;
}
for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
index b95ec73fcae3..d8b2da18db39 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
@@ -426,8 +426,9 @@ void dpp1_cnv_setup (
void dpp1_set_cursor_attributes(
struct dpp *dpp_base,
- enum dc_cursor_color_format color_format)
+ struct dc_cursor_attributes *cursor_attributes)
{
+ enum dc_cursor_color_format color_format = cursor_attributes->color_format;
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_UPDATE_2(CURSOR0_CONTROL,
@@ -456,6 +457,19 @@ void dpp1_set_cursor_position(
int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
uint32_t cur_en = pos->enable ? 1 : 0;
+ // Cursor width/height and hotspots need to be rotated for offset calculation
+ if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) {
+ swap(width, height);
+ if (param->rotation == ROTATION_ANGLE_90) {
+ src_x_offset = pos->x - pos->y_hotspot - param->viewport.x;
+ src_y_offset = pos->y - pos->x_hotspot - param->viewport.y;
+ }
+ } else if (param->rotation == ROTATION_ANGLE_180) {
+ src_x_offset = pos->x - param->viewport.x;
+ src_y_offset = pos->y - param->viewport.y;
+ }
+
+
if (src_x_offset >= (int)param->viewport.width)
cur_en = 0; /* not visible beyond right edge*/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
index 8a5517eebb7c..e2c613611ac9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
@@ -1368,7 +1368,7 @@ enum dcn10_input_csc_select {
void dpp1_set_cursor_attributes(
struct dpp *dpp_base,
- enum dc_cursor_color_format color_format);
+ struct dc_cursor_attributes *cursor_attributes);
void dpp1_set_cursor_position(
struct dpp *dpp_base,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
index a780057e2dbc..a02c10e23e0d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
@@ -104,7 +104,7 @@ void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow)
DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, !allow);
}
-bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubbub)
+bool hubbub1_is_allow_self_refresh_enabled(struct hubbub *hubbub)
{
struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
uint32_t enable = 0;
@@ -945,6 +945,8 @@ static const struct hubbub_funcs hubbub1_funcs = {
.get_dcc_compression_cap = hubbub1_get_dcc_compression_cap,
.wm_read_state = hubbub1_wm_read_state,
.program_watermarks = hubbub1_program_watermarks,
+ .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
+ .allow_self_refresh_control = hubbub1_allow_self_refresh_control,
};
void hubbub1_construct(struct hubbub *hubbub,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
index 7c2559c9ae23..69d903d68661 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
@@ -119,6 +119,28 @@ struct dcn_hubbub_registers {
uint32_t DCN_VM_AGP_BOT;
uint32_t DCN_VM_AGP_TOP;
uint32_t DCN_VM_AGP_BASE;
+ uint32_t DCN_VM_PROTECTION_FAULT_DEFAULT_ADDR_MSB;
+ uint32_t DCN_VM_PROTECTION_FAULT_DEFAULT_ADDR_LSB;
+#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
+ uint32_t DCHUBBUB_ARB_FRAC_URG_BW_NOM_A;
+ uint32_t DCHUBBUB_ARB_FRAC_URG_BW_NOM_B;
+ uint32_t DCHUBBUB_ARB_FRAC_URG_BW_NOM_C;
+ uint32_t DCHUBBUB_ARB_FRAC_URG_BW_NOM_D;
+ uint32_t DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A;
+ uint32_t DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B;
+ uint32_t DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C;
+ uint32_t DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D;
+ uint32_t DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A;
+ uint32_t DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B;
+ uint32_t DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C;
+ uint32_t DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D;
+ uint32_t DCHUBBUB_ARB_HOSTVM_CNTL;
+ uint32_t DCHVM_CTRL0;
+ uint32_t DCHVM_MEM_CTRL;
+ uint32_t DCHVM_CLK_CTRL;
+ uint32_t DCHVM_RIOMMU_CTRL0;
+ uint32_t DCHVM_RIOMMU_STAT0;
+#endif
};
/* set field name */
@@ -196,7 +218,9 @@ struct dcn_hubbub_registers {
type DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A;\
type DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B;\
type DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C;\
- type DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D
+ type DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D;\
+ type DCN_VM_PROTECTION_FAULT_DEFAULT_ADDR_MSB;\
+ type DCN_VM_PROTECTION_FAULT_DEFAULT_ADDR_LSB
#define HUBBUB_STUTTER_REG_FIELD_LIST(type) \
type DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A;\
@@ -208,15 +232,68 @@ struct dcn_hubbub_registers {
type DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C;\
type DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D
+#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
+#define HUBBUB_HVM_REG_FIELD_LIST(type) \
+ type DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD;\
+ type DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_A;\
+ type DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_B;\
+ type DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_C;\
+ type DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_D;\
+ type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_A;\
+ type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_B;\
+ type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_C;\
+ type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_D;\
+ type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A;\
+ type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_B;\
+ type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_C;\
+ type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_D;\
+ type DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A;\
+ type DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B;\
+ type DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C;\
+ type DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D;\
+ type DCHUBBUB_ARB_FRAC_URG_BW_NOM_A;\
+ type DCHUBBUB_ARB_FRAC_URG_BW_NOM_B;\
+ type DCHUBBUB_ARB_FRAC_URG_BW_NOM_C;\
+ type DCHUBBUB_ARB_FRAC_URG_BW_NOM_D;\
+ type DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A;\
+ type DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B;\
+ type DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C;\
+ type DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D;\
+ type DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A;\
+ type DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B;\
+ type DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C;\
+ type DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D;\
+ type DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD;\
+ type HOSTVM_INIT_REQ; \
+ type HVM_GPUVMRET_PWR_REQ_DIS; \
+ type HVM_GPUVMRET_FORCE_REQ; \
+ type HVM_GPUVMRET_POWER_STATUS; \
+ type HVM_DISPCLK_R_GATE_DIS; \
+ type HVM_DISPCLK_G_GATE_DIS; \
+ type HVM_DCFCLK_R_GATE_DIS; \
+ type HVM_DCFCLK_G_GATE_DIS; \
+ type TR_REQ_REQCLKREQ_MODE; \
+ type TW_RSP_COMPCLKREQ_MODE; \
+ type HOSTVM_PREFETCH_REQ; \
+ type HOSTVM_POWERSTATUS; \
+ type RIOMMU_ACTIVE; \
+ type HOSTVM_PREFETCH_DONE
+#endif
struct dcn_hubbub_shift {
DCN_HUBBUB_REG_FIELD_LIST(uint8_t);
HUBBUB_STUTTER_REG_FIELD_LIST(uint8_t);
+#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
+ HUBBUB_HVM_REG_FIELD_LIST(uint8_t);
+#endif
};
struct dcn_hubbub_mask {
DCN_HUBBUB_REG_FIELD_LIST(uint32_t);
HUBBUB_STUTTER_REG_FIELD_LIST(uint32_t);
+#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
+ HUBBUB_HVM_REG_FIELD_LIST(uint32_t);
+#endif
};
struct dc;
@@ -247,7 +324,7 @@ void hubbub1_program_watermarks(
void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow);
-bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubub);
+bool hubbub1_is_allow_self_refresh_enabled(struct hubbub *hubub);
void hubbub1_toggle_watermark_change_req(
struct hubbub *hubbub);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index 934bacc0c6ad..001db49e4bb2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -163,7 +163,7 @@ void hubp1_program_tiling(
void hubp1_program_size(
struct hubp *hubp,
enum surface_pixel_format format,
- const union plane_size *plane_size,
+ const struct plane_size *plane_size,
struct dc_plane_dcc_param *dcc)
{
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
@@ -173,16 +173,16 @@ void hubp1_program_size(
* 444 or 420 luma
*/
if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN && format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END) {
- ASSERT(plane_size->video.chroma_pitch != 0);
+ ASSERT(plane_size->chroma_pitch != 0);
/* Chroma pitch zero can cause system hang! */
- pitch = plane_size->video.luma_pitch - 1;
- meta_pitch = dcc->video.meta_pitch_l - 1;
- pitch_c = plane_size->video.chroma_pitch - 1;
- meta_pitch_c = dcc->video.meta_pitch_c - 1;
+ pitch = plane_size->surface_pitch - 1;
+ meta_pitch = dcc->meta_pitch - 1;
+ pitch_c = plane_size->chroma_pitch - 1;
+ meta_pitch_c = dcc->meta_pitch_c - 1;
} else {
- pitch = plane_size->grph.surface_pitch - 1;
- meta_pitch = dcc->grph.meta_pitch - 1;
+ pitch = plane_size->surface_pitch - 1;
+ meta_pitch = dcc->meta_pitch - 1;
pitch_c = 0;
meta_pitch_c = 0;
}
@@ -509,7 +509,7 @@ bool hubp1_program_surface_flip_and_addr(
}
void hubp1_dcc_control(struct hubp *hubp, bool enable,
- bool independent_64b_blks)
+ enum hubp_ind_block_size independent_64b_blks)
{
uint32_t dcc_en = enable ? 1 : 0;
uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0;
@@ -526,13 +526,13 @@ void hubp1_program_surface_config(
struct hubp *hubp,
enum surface_pixel_format format,
union dc_tiling_info *tiling_info,
- union plane_size *plane_size,
+ struct plane_size *plane_size,
enum dc_rotation_angle rotation,
struct dc_plane_dcc_param *dcc,
bool horizontal_mirror,
unsigned int compat_level)
{
- hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks);
+ hubp1_dcc_control(hubp, dcc->enable, dcc->independent_64b_blks);
hubp1_program_tiling(hubp, tiling_info, format);
hubp1_program_size(hubp, format, plane_size, dcc);
hubp1_program_rotation(hubp, rotation, horizontal_mirror);
@@ -843,7 +843,7 @@ void min_set_viewport(
PRI_VIEWPORT_Y_START_C, viewport_c->y);
}
-void hubp1_read_state(struct hubp *hubp)
+void hubp1_read_state_common(struct hubp *hubp)
{
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
struct dcn_hubp_state *s = &hubp1->state;
@@ -859,24 +859,6 @@ void hubp1_read_state(struct hubp *hubp)
PRQ_EXPANSION_MODE, &rq_regs->prq_expansion_mode,
MRQ_EXPANSION_MODE, &rq_regs->mrq_expansion_mode,
CRQ_EXPANSION_MODE, &rq_regs->crq_expansion_mode);
- REG_GET_8(DCHUBP_REQ_SIZE_CONFIG,
- CHUNK_SIZE, &rq_regs->rq_regs_l.chunk_size,
- MIN_CHUNK_SIZE, &rq_regs->rq_regs_l.min_chunk_size,
- META_CHUNK_SIZE, &rq_regs->rq_regs_l.meta_chunk_size,
- MIN_META_CHUNK_SIZE, &rq_regs->rq_regs_l.min_meta_chunk_size,
- DPTE_GROUP_SIZE, &rq_regs->rq_regs_l.dpte_group_size,
- MPTE_GROUP_SIZE, &rq_regs->rq_regs_l.mpte_group_size,
- SWATH_HEIGHT, &rq_regs->rq_regs_l.swath_height,
- PTE_ROW_HEIGHT_LINEAR, &rq_regs->rq_regs_l.pte_row_height_linear);
- REG_GET_8(DCHUBP_REQ_SIZE_CONFIG_C,
- CHUNK_SIZE_C, &rq_regs->rq_regs_c.chunk_size,
- MIN_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_chunk_size,
- META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.meta_chunk_size,
- MIN_META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_meta_chunk_size,
- DPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.dpte_group_size,
- MPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.mpte_group_size,
- SWATH_HEIGHT_C, &rq_regs->rq_regs_c.swath_height,
- PTE_ROW_HEIGHT_LINEAR_C, &rq_regs->rq_regs_c.pte_row_height_linear);
/* DLG - Per hubp */
REG_GET_2(BLANK_OFFSET_0,
@@ -1030,8 +1012,38 @@ void hubp1_read_state(struct hubp *hubp)
REG_GET_2(DCN_TTU_QOS_WM,
QoS_LEVEL_LOW_WM, &s->qos_level_low_wm,
QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
+
}
+void hubp1_read_state(struct hubp *hubp)
+{
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+ struct dcn_hubp_state *s = &hubp1->state;
+ struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
+
+ hubp1_read_state_common(hubp);
+
+ REG_GET_8(DCHUBP_REQ_SIZE_CONFIG,
+ CHUNK_SIZE, &rq_regs->rq_regs_l.chunk_size,
+ MIN_CHUNK_SIZE, &rq_regs->rq_regs_l.min_chunk_size,
+ META_CHUNK_SIZE, &rq_regs->rq_regs_l.meta_chunk_size,
+ MIN_META_CHUNK_SIZE, &rq_regs->rq_regs_l.min_meta_chunk_size,
+ DPTE_GROUP_SIZE, &rq_regs->rq_regs_l.dpte_group_size,
+ MPTE_GROUP_SIZE, &rq_regs->rq_regs_l.mpte_group_size,
+ SWATH_HEIGHT, &rq_regs->rq_regs_l.swath_height,
+ PTE_ROW_HEIGHT_LINEAR, &rq_regs->rq_regs_l.pte_row_height_linear);
+
+ REG_GET_8(DCHUBP_REQ_SIZE_CONFIG_C,
+ CHUNK_SIZE_C, &rq_regs->rq_regs_c.chunk_size,
+ MIN_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_chunk_size,
+ META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.meta_chunk_size,
+ MIN_META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_meta_chunk_size,
+ DPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.dpte_group_size,
+ MPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.mpte_group_size,
+ SWATH_HEIGHT_C, &rq_regs->rq_regs_c.swath_height,
+ PTE_ROW_HEIGHT_LINEAR_C, &rq_regs->rq_regs_c.pte_row_height_linear);
+
+}
enum cursor_pitch hubp1_get_cursor_pitch(unsigned int pitch)
{
enum cursor_pitch hw_pitch;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
index 31c8fdd3206c..cb20d10288c0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
@@ -125,8 +125,6 @@
SRI(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, HUBPREQ, id),\
SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, HUBPREQ, id),\
SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, HUBPREQ, id),\
- SR(DCHUBBUB_SDPIF_FB_BASE),\
- SR(DCHUBBUB_SDPIF_FB_OFFSET),\
SRI(CURSOR_SETTINS, HUBPREQ, id), \
SRI(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR, id), \
SRI(CURSOR_SURFACE_ADDRESS, CURSOR, id), \
@@ -226,14 +224,6 @@
uint32_t DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB; \
uint32_t DCN_VM_SYSTEM_APERTURE_LOW_ADDR; \
uint32_t DCN_VM_SYSTEM_APERTURE_HIGH_ADDR; \
- uint32_t DCHUBBUB_SDPIF_FB_BASE; \
- uint32_t DCHUBBUB_SDPIF_FB_OFFSET; \
- uint32_t DCN_VM_FB_LOCATION_TOP; \
- uint32_t DCN_VM_FB_LOCATION_BASE; \
- uint32_t DCN_VM_FB_OFFSET; \
- uint32_t DCN_VM_AGP_BASE; \
- uint32_t DCN_VM_AGP_BOT; \
- uint32_t DCN_VM_AGP_TOP; \
uint32_t CURSOR_SETTINS; \
uint32_t CURSOR_SETTINGS; \
uint32_t CURSOR_SURFACE_ADDRESS_HIGH; \
@@ -249,7 +239,8 @@
.field_name = reg_name ## __ ## field_name ## post_fix
/* Mask/shift struct generation macro for all ASICs (including those with reduced functionality) */
-#define HUBP_MASK_SH_LIST_DCN_COMMON(mask_sh)\
+/*1.x, 2.x, and 3.x*/
+#define HUBP_MASK_SH_LIST_DCN_SHARE_COMMON(mask_sh)\
HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_BLANK_EN, mask_sh),\
HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_TTU_DISABLE, mask_sh),\
HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_UNDERFLOW_STATUS, mask_sh),\
@@ -265,7 +256,6 @@
HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, MAX_COMPRESSED_FRAGS, mask_sh),\
HUBP_SF(HUBP0_DCSURF_TILING_CONFIG, SW_MODE, mask_sh),\
HUBP_SF(HUBP0_DCSURF_TILING_CONFIG, META_LINEAR, mask_sh),\
- HUBP_SF(HUBP0_DCSURF_TILING_CONFIG, RB_ALIGNED, mask_sh),\
HUBP_SF(HUBP0_DCSURF_TILING_CONFIG, PIPE_ALIGNED, mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_SURFACE_PITCH, PITCH, mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_SURFACE_PITCH, META_PITCH, mask_sh),\
@@ -372,12 +362,17 @@
HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL0, QoS_RAMP_DISABLE, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL1, REFCYC_PER_REQ_DELIVERY_PRE, mask_sh),\
HUBP_SF(HUBP0_HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, mask_sh)
-
-#define HUBP_MASK_SH_LIST_DCN(mask_sh)\
- HUBP_MASK_SH_LIST_DCN_COMMON(mask_sh),\
+/*2.x and 1.x only*/
+#define HUBP_MASK_SH_LIST_DCN_COMMON(mask_sh)\
+ HUBP_MASK_SH_LIST_DCN_SHARE_COMMON(mask_sh),\
+ HUBP_SF(HUBP0_DCSURF_TILING_CONFIG, RB_ALIGNED, mask_sh),\
HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, MPTE_GROUP_SIZE, mask_sh),\
HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, MPTE_GROUP_SIZE_C, mask_sh)
+/*2.x and 1.x only*/
+#define HUBP_MASK_SH_LIST_DCN(mask_sh)\
+ HUBP_MASK_SH_LIST_DCN_COMMON(mask_sh)
+
/* Mask/shift struct generation macro for ASICs with VM */
#define HUBP_MASK_SH_LIST_DCN_VM(mask_sh)\
HUBP_SF(HUBPREQ0_NOM_PARAMETERS_0, DST_Y_PER_PTE_ROW_NOM_L, mask_sh),\
@@ -412,8 +407,6 @@
HUBP_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, MC_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mask_sh),\
- HUBP_SF(DCHUBBUB_SDPIF_FB_BASE, SDPIF_FB_BASE, mask_sh),\
- HUBP_SF(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh),\
@@ -434,7 +427,7 @@
HUBP_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \
HUBP_SF(CURSOR0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh)
-#define DCN_HUBP_REG_FIELD_LIST(type) \
+#define DCN_HUBP_REG_FIELD_BASE_LIST(type) \
type HUBP_BLANK_EN;\
type HUBP_DISABLE;\
type HUBP_TTU_DISABLE;\
@@ -459,7 +452,6 @@
type ROTATION_ANGLE;\
type H_MIRROR_EN;\
type SURFACE_PIXEL_FORMAT;\
- type ALPHA_PLANE_EN;\
type SURFACE_FLIP_TYPE;\
type SURFACE_FLIP_MODE_FOR_STEREOSYNC;\
type SURFACE_FLIP_IN_STEREOSYNC;\
@@ -589,18 +581,6 @@
type MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB;\
type MC_VM_SYSTEM_APERTURE_LOW_ADDR;\
type MC_VM_SYSTEM_APERTURE_HIGH_ADDR;\
- type SDPIF_FB_TOP;\
- type SDPIF_FB_BASE;\
- type SDPIF_FB_OFFSET;\
- type SDPIF_AGP_BASE;\
- type SDPIF_AGP_BOT;\
- type SDPIF_AGP_TOP;\
- type FB_TOP;\
- type FB_BASE;\
- type FB_OFFSET;\
- type AGP_BASE;\
- type AGP_BOT;\
- type AGP_TOP;\
type DCN_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM;\
type DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB;\
type DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB;\
@@ -632,6 +612,10 @@
type CURSOR_DST_X_OFFSET; \
type OUTPUT_FP
+#define DCN_HUBP_REG_FIELD_LIST(type) \
+ DCN_HUBP_REG_FIELD_BASE_LIST(type);\
+ type ALPHA_PLANE_EN
+
struct dcn_mi_registers {
HUBP_COMMON_REG_VARIABLE_LIST;
};
@@ -677,7 +661,7 @@ void hubp1_program_surface_config(
struct hubp *hubp,
enum surface_pixel_format format,
union dc_tiling_info *tiling_info,
- union plane_size *plane_size,
+ struct plane_size *plane_size,
enum dc_rotation_angle rotation,
struct dc_plane_dcc_param *dcc,
bool horizontal_mirror,
@@ -699,7 +683,7 @@ void hubp1_program_pixel_format(
void hubp1_program_size(
struct hubp *hubp,
enum surface_pixel_format format,
- const union plane_size *plane_size,
+ const struct plane_size *plane_size,
struct dc_plane_dcc_param *dcc);
void hubp1_program_rotation(
@@ -714,7 +698,7 @@ void hubp1_program_tiling(
void hubp1_dcc_control(struct hubp *hubp,
bool enable,
- bool independent_64b_blks);
+ enum hubp_ind_block_size independent_64b_blks);
#ifdef CONFIG_DRM_AMD_DC_DCN2_0
bool hubp1_program_surface_flip_and_addr(
@@ -760,5 +744,6 @@ void hubp1_vready_workaround(struct hubp *hubp,
struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest);
void hubp1_init(struct hubp *hubp);
+void hubp1_read_state_common(struct hubp *hubp);
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 2118ea21d7e9..60123db7ba02 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -438,7 +438,7 @@ bool dcn10_did_underflow_occur(struct dc *dc, struct pipe_ctx *pipe_ctx)
return false;
}
-static void enable_power_gating_plane(
+static void dcn10_enable_power_gating_plane(
struct dce_hwseq *hws,
bool enable)
{
@@ -460,7 +460,7 @@ static void enable_power_gating_plane(
REG_UPDATE(DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, force_on);
}
-static void disable_vga(
+static void dcn10_disable_vga(
struct dce_hwseq *hws)
{
unsigned int in_vga1_mode = 0;
@@ -493,7 +493,7 @@ static void disable_vga(
REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_RENDER_START, 1);
}
-static void dpp_pg_control(
+static void dcn10_dpp_pg_control(
struct dce_hwseq *hws,
unsigned int dpp_inst,
bool power_on)
@@ -545,7 +545,7 @@ static void dpp_pg_control(
}
}
-static void hubp_pg_control(
+static void dcn10_hubp_pg_control(
struct dce_hwseq *hws,
unsigned int hubp_inst,
bool power_on)
@@ -605,8 +605,8 @@ static void power_on_plane(
if (REG(DC_IP_REQUEST_CNTL)) {
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
- dpp_pg_control(hws, plane_id, true);
- hubp_pg_control(hws, plane_id, true);
+ hws->ctx->dc->hwss.dpp_pg_control(hws, plane_id, true);
+ hws->ctx->dc->hwss.hubp_pg_control(hws, plane_id, true);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
DC_LOG_DEBUG(
@@ -627,7 +627,7 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc)
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
- hubp_pg_control(hws, 0, false);
+ dc->hwss.hubp_pg_control(hws, 0, false);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
@@ -656,7 +656,7 @@ static void apply_DEGVIDCN10_253_wa(struct dc *dc)
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
- hubp_pg_control(hws, 0, true);
+ dc->hwss.hubp_pg_control(hws, 0, true);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
@@ -664,10 +664,23 @@ static void apply_DEGVIDCN10_253_wa(struct dc *dc)
hws->wa_state.DEGVIDCN10_253_applied = true;
}
-static void bios_golden_init(struct dc *dc)
+static void dcn10_bios_golden_init(struct dc *dc)
{
struct dc_bios *bp = dc->ctx->dc_bios;
int i;
+ bool allow_self_fresh_force_enable = true;
+
+ if (dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled)
+ allow_self_fresh_force_enable =
+ dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub);
+
+
+ /* WA for making DF sleep when idle after resume from S0i3.
+ * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by
+ * command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0
+ * before calling command table and it changed to 1 after,
+ * it should be set back to 0.
+ */
/* initialize dcn global */
bp->funcs->enable_disp_power_gating(bp,
@@ -678,6 +691,12 @@ static void bios_golden_init(struct dc *dc)
bp->funcs->enable_disp_power_gating(bp,
CONTROLLER_ID_D0 + i, ASIC_PIPE_DISABLE);
}
+
+ if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
+ if (allow_self_fresh_force_enable == false &&
+ dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub))
+ dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, true);
+
}
static void false_optc_underflow_wa(
@@ -702,7 +721,8 @@ static void false_optc_underflow_wa(
dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, old_pipe_ctx);
}
- tg->funcs->set_blank_data_double_buffer(tg, true);
+ if (tg->funcs->set_blank_data_double_buffer)
+ tg->funcs->set_blank_data_double_buffer(tg, true);
if (tg->funcs->is_optc_underflow_occurred(tg) && !underflow)
tg->funcs->clear_optc_underflow(tg);
@@ -808,11 +828,23 @@ static void dcn10_reset_back_end_for_pipe(
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
/* DPMS may already disable */
if (!pipe_ctx->stream->dpms_off)
- core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE);
- else if (pipe_ctx->stream_res.audio) {
- dc->hwss.disable_audio_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE);
+ core_link_disable_stream(pipe_ctx);
+ else if (pipe_ctx->stream_res.audio)
+ dc->hwss.disable_audio_stream(pipe_ctx);
+
+ if (pipe_ctx->stream_res.audio) {
+ /*disable az_endpoint*/
+ pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
+
+ /*free audio*/
+ if (dc->caps.dynamic_audio == true) {
+ /*we have to dynamic arbitrate the audio endpoints*/
+ /*we free the resource, need reset is_audio_acquired*/
+ update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
+ pipe_ctx->stream_res.audio, false);
+ pipe_ctx->stream_res.audio = NULL;
+ }
}
-
}
/* by upper caller loop, parent pipe: pipe0, will be reset last.
@@ -823,6 +855,9 @@ static void dcn10_reset_back_end_for_pipe(
pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
+ if (pipe_ctx->stream_res.tg->funcs->set_drr)
+ pipe_ctx->stream_res.tg->funcs->set_drr(
+ pipe_ctx->stream_res.tg, NULL);
}
for (i = 0; i < dc->res_pool->pipe_count; i++)
@@ -968,7 +1003,7 @@ void hwss1_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
dcn10_verify_allow_pstate_change_high(dc);
}
-static void plane_atomic_power_down(struct dc *dc,
+static void dcn10_plane_atomic_power_down(struct dc *dc,
struct dpp *dpp,
struct hubp *hubp)
{
@@ -978,8 +1013,8 @@ static void plane_atomic_power_down(struct dc *dc,
if (REG(DC_IP_REQUEST_CNTL)) {
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
- dpp_pg_control(hws, dpp->inst, false);
- hubp_pg_control(hws, hubp->inst, false);
+ dc->hwss.dpp_pg_control(hws, dpp->inst, false);
+ dc->hwss.hubp_pg_control(hws, hubp->inst, false);
dpp->funcs->dpp_reset(dpp);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
@@ -991,7 +1026,7 @@ static void plane_atomic_power_down(struct dc *dc,
/* disable HW used by plane.
* note: cannot disable until disconnect is complete
*/
-static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
+static void dcn10_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
struct hubp *hubp = pipe_ctx->plane_res.hubp;
struct dpp *dpp = pipe_ctx->plane_res.dpp;
@@ -1011,7 +1046,7 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
hubp->power_gated = true;
dc->optimized_required = false; /* We're powering off, no need to optimize */
- plane_atomic_power_down(dc,
+ dc->hwss.plane_atomic_power_down(dc,
pipe_ctx->plane_res.dpp,
pipe_ctx->plane_res.hubp);
@@ -1030,7 +1065,7 @@ static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
return;
- plane_atomic_disable(dc, pipe_ctx);
+ dc->hwss.plane_atomic_disable(dc, pipe_ctx);
apply_DEGVIDCN10_253_wa(dc);
@@ -1065,15 +1100,27 @@ static void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
* command table.
*/
if (tg->funcs->is_tg_enabled(tg)) {
- tg->funcs->lock(tg);
- tg->funcs->set_blank(tg, true);
- hwss_wait_for_blank_complete(tg);
+ if (dc->hwss.init_blank != NULL) {
+ dc->hwss.init_blank(dc, tg);
+ tg->funcs->lock(tg);
+ } else {
+ tg->funcs->lock(tg);
+ tg->funcs->set_blank(tg, true);
+ hwss_wait_for_blank_complete(tg);
+ }
}
}
- /* Cannot reset the MPC mux if seamless boot */
- if (!can_apply_seamless_boot)
- dc->res_pool->mpc->funcs->mpc_init(dc->res_pool->mpc);
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+ /* Cannot reset the MPC mux if seamless boot */
+ if (pipe_ctx->stream != NULL && can_apply_seamless_boot)
+ continue;
+
+ dc->res_pool->mpc->funcs->mpc_init_single_inst(
+ dc->res_pool->mpc, i);
+ }
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct timing_generator *tg = dc->res_pool->timing_generators[i];
@@ -1111,12 +1158,12 @@ static void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
- hwss1_plane_atomic_disconnect(dc, pipe_ctx);
+ dc->hwss.plane_atomic_disconnect(dc, pipe_ctx);
if (tg->funcs->is_tg_enabled(tg))
tg->funcs->unlock(tg);
- dcn10_disable_plane(dc, pipe_ctx);
+ dc->hwss.disable_plane(dc, pipe_ctx);
pipe_ctx->stream_res.tg = NULL;
pipe_ctx->plane_res.hubp = NULL;
@@ -1132,8 +1179,17 @@ static void dcn10_init_hw(struct dc *dc)
struct dmcu *dmcu = dc->res_pool->dmcu;
struct dce_hwseq *hws = dc->hwseq;
struct dc_bios *dcb = dc->ctx->dc_bios;
+ struct resource_pool *res_pool = dc->res_pool;
+
+ if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+ dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
+
+ // Initialize the dccg
+ if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->dccg_init)
+ dc->res_pool->dccg->funcs->dccg_init(res_pool->dccg);
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
+
REG_WRITE(REFCLK_CNTL, 0);
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
REG_WRITE(DIO_MEM_PWR_CTRL, 0);
@@ -1147,31 +1203,40 @@ static void dcn10_init_hw(struct dc *dc)
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
- enable_power_gating_plane(dc->hwseq, true);
+ //Enable ability to power gate / don't force power on permanently
+ dc->hwss.enable_power_gating_plane(hws, true);
- /* end of FPGA. Below if real ASIC */
return;
}
- if (!dcb->funcs->is_accelerated_mode(dcb)) {
- bool allow_self_fresh_force_enable =
- hububu1_is_allow_self_refresh_enabled(
- dc->res_pool->hubbub);
+ if (!dcb->funcs->is_accelerated_mode(dcb))
+ dc->hwss.disable_vga(dc->hwseq);
- bios_golden_init(dc);
+ dc->hwss.bios_golden_init(dc);
+ if (dc->ctx->dc_bios->fw_info_valid) {
+ res_pool->ref_clocks.xtalin_clock_inKhz =
+ dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
- /* WA for making DF sleep when idle after resume from S0i3.
- * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by
- * command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0
- * before calling command table and it changed to 1 after,
- * it should be set back to 0.
- */
- if (allow_self_fresh_force_enable == false &&
- hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub))
- hubbub1_allow_self_refresh_control(dc->res_pool->hubbub, true);
+ if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
+ if (res_pool->dccg && res_pool->hubbub) {
- disable_vga(dc->hwseq);
- }
+ (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
+ dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
+ &res_pool->ref_clocks.dccg_ref_clock_inKhz);
+
+ (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
+ res_pool->ref_clocks.dccg_ref_clock_inKhz,
+ &res_pool->ref_clocks.dchub_ref_clock_inKhz);
+ } else {
+ // Not all ASICs have DCCG sw component
+ res_pool->ref_clocks.dccg_ref_clock_inKhz =
+ res_pool->ref_clocks.xtalin_clock_inKhz;
+ res_pool->ref_clocks.dchub_ref_clock_inKhz =
+ res_pool->ref_clocks.xtalin_clock_inKhz;
+ }
+ }
+ } else
+ ASSERT_CRITICAL(false);
for (i = 0; i < dc->link_count; i++) {
/* Power up AND update implementation according to the
@@ -1188,6 +1253,13 @@ static void dcn10_init_hw(struct dc *dc)
link->link_status.link_active = true;
}
+ /* Power gate DSCs */
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+ for (i = 0; i < res_pool->res_cap->num_dsc; i++)
+ if (dc->hwss.dsc_pg_control != NULL)
+ dc->hwss.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
+#endif
+
/* If taking control over from VBIOS, we may want to optimize our first
* mode set, so we need to skip powering down pipes until we know which
* pipes we want to use.
@@ -1198,8 +1270,8 @@ static void dcn10_init_hw(struct dc *dc)
dc->hwss.init_pipes(dc, dc->current_state);
}
- for (i = 0; i < dc->res_pool->audio_count; i++) {
- struct audio *audio = dc->res_pool->audios[i];
+ for (i = 0; i < res_pool->audio_count; i++) {
+ struct audio *audio = res_pool->audios[i];
audio->funcs->hw_init(audio);
}
@@ -1227,9 +1299,7 @@ static void dcn10_init_hw(struct dc *dc)
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
- enable_power_gating_plane(dc->hwseq, true);
-
- memset(&dc->clk_mgr->clks, 0, sizeof(dc->clk_mgr->clks));
+ dc->hwss.enable_power_gating_plane(dc->hwseq, true);
}
static void dcn10_reset_hw_ctx_wrap(
@@ -1366,6 +1436,34 @@ static bool dcn10_set_input_transfer_func(struct pipe_ctx *pipe_ctx,
return result;
}
+#define MAX_NUM_HW_POINTS 0x200
+
+static void log_tf(struct dc_context *ctx,
+ struct dc_transfer_func *tf, uint32_t hw_points_num)
+{
+ // DC_LOG_GAMMA is default logging of all hw points
+ // DC_LOG_ALL_GAMMA logs all points, not only hw points
+ // DC_LOG_ALL_TF_POINTS logs all channels of the tf
+ int i = 0;
+
+ DC_LOGGER_INIT(ctx->logger);
+ DC_LOG_GAMMA("Gamma Correction TF");
+ DC_LOG_ALL_GAMMA("Logging all tf points...");
+ DC_LOG_ALL_TF_CHANNELS("Logging all channels...");
+
+ for (i = 0; i < hw_points_num; i++) {
+ DC_LOG_GAMMA("R\t%d\t%llu\n", i, tf->tf_pts.red[i].value);
+ DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu\n", i, tf->tf_pts.green[i].value);
+ DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu\n", i, tf->tf_pts.blue[i].value);
+ }
+
+ for (i = hw_points_num; i < MAX_NUM_HW_POINTS; i++) {
+ DC_LOG_ALL_GAMMA("R\t%d\t%llu\n", i, tf->tf_pts.red[i].value);
+ DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu\n", i, tf->tf_pts.green[i].value);
+ DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu\n", i, tf->tf_pts.blue[i].value);
+ }
+}
+
static bool
dcn10_set_output_transfer_func(struct pipe_ctx *pipe_ctx,
const struct dc_stream_state *stream)
@@ -1394,6 +1492,13 @@ dcn10_set_output_transfer_func(struct pipe_ctx *pipe_ctx,
} else
dpp->funcs->dpp_program_regamma_pwl(dpp, NULL, OPP_REGAMMA_BYPASS);
+ if (stream != NULL && stream->ctx != NULL &&
+ stream->out_transfer_func != NULL) {
+ log_tf(stream->ctx,
+ stream->out_transfer_func,
+ dpp->regamma_params.hw_points_num);
+ }
+
return true;
}
@@ -1786,7 +1891,7 @@ static void dcn10_enable_plane(
}
}
-static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
+static void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx)
{
int i = 0;
struct dpp_grph_csc_adjustment adjust;
@@ -1804,6 +1909,36 @@ static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust);
}
+
+static bool dcn10_is_rear_mpo_fix_required(struct pipe_ctx *pipe_ctx, enum dc_color_space colorspace)
+{
+ if (pipe_ctx->plane_state && pipe_ctx->plane_state->layer_index > 0 && is_rgb_cspace(colorspace)) {
+ if (pipe_ctx->top_pipe) {
+ struct pipe_ctx *top = pipe_ctx->top_pipe;
+
+ while (top->top_pipe)
+ top = top->top_pipe; // Traverse to top pipe_ctx
+ if (top->plane_state && top->plane_state->layer_index == 0)
+ return true; // Front MPO plane not hidden
+ }
+ }
+ return false;
+}
+
+static void dcn10_set_csc_adjustment_rgb_mpo_fix(struct pipe_ctx *pipe_ctx, uint16_t *matrix)
+{
+ // Override rear plane RGB bias to fix MPO brightness
+ uint16_t rgb_bias = matrix[3];
+
+ matrix[3] = 0;
+ matrix[7] = 0;
+ matrix[11] = 0;
+ pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix);
+ matrix[3] = rgb_bias;
+ matrix[7] = rgb_bias;
+ matrix[11] = rgb_bias;
+}
+
static void dcn10_program_output_csc(struct dc *dc,
struct pipe_ctx *pipe_ctx,
enum dc_color_space colorspace,
@@ -1811,8 +1946,25 @@ static void dcn10_program_output_csc(struct dc *dc,
int opp_id)
{
if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
- if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL)
- pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix);
+ if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL) {
+
+ /* MPO is broken with RGB colorspaces when OCSC matrix
+ * brightness offset >= 0 on DCN1 due to OCSC before MPC
+ * Blending adds offsets from front + rear to rear plane
+ *
+ * Fix is to set RGB bias to 0 on rear plane, top plane
+ * black value pixels add offset instead of rear + front
+ */
+
+ int16_t rgb_bias = matrix[3];
+ // matrix[3/7/11] are all the same offset value
+
+ if (rgb_bias > 0 && dcn10_is_rear_mpo_fix_required(pipe_ctx, colorspace)) {
+ dcn10_set_csc_adjustment_rgb_mpo_fix(pipe_ctx, matrix);
+ } else {
+ pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix);
+ }
+ }
} else {
if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default != NULL)
pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default(pipe_ctx->plane_res.dpp, colorspace);
@@ -2132,7 +2284,7 @@ void update_dchubp_dpp(
struct hubp *hubp = pipe_ctx->plane_res.hubp;
struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
- union plane_size size = plane_state->plane_size;
+ struct plane_size size = plane_state->plane_size;
unsigned int compat_level = 0;
/* depends on DML calculation, DPP clock value may change dynamically */
@@ -2152,7 +2304,8 @@ void update_dchubp_dpp(
dc->res_pool->dccg->funcs->update_dpp_dto(
dc->res_pool->dccg,
dpp->inst,
- pipe_ctx->plane_res.bw.dppclk_khz);
+ pipe_ctx->plane_res.bw.dppclk_khz,
+ false);
else
dc->clk_mgr->clks.dppclk_khz = should_divided_by_2 ?
dc->clk_mgr->clks.dispclk_khz / 2 :
@@ -2178,7 +2331,7 @@ void update_dchubp_dpp(
&pipe_ctx->ttu_regs);
}
- size.grph.surface_size = pipe_ctx->plane_res.scl_data.viewport;
+ size.surface_size = pipe_ctx->plane_res.scl_data.viewport;
if (plane_state->update_flags.bits.full_update ||
plane_state->update_flags.bits.bpp_change)
@@ -2216,7 +2369,7 @@ void update_dchubp_dpp(
if (plane_state->update_flags.bits.full_update) {
/*gamut remap*/
- program_gamut_remap(pipe_ctx);
+ dc->hwss.program_gamut_remap(pipe_ctx);
dc->hwss.program_output_csc(dc,
pipe_ctx,
@@ -2388,7 +2541,7 @@ struct pipe_ctx *find_top_pipe_for_stream(
if (pipe_ctx->stream != stream)
continue;
- if (!pipe_ctx->top_pipe)
+ if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe)
return pipe_ctx;
}
return NULL;
@@ -2453,7 +2606,7 @@ static void dcn10_apply_ctx_for_surface(
if (old_pipe_ctx->stream_res.tg == tg &&
old_pipe_ctx->plane_res.hubp &&
old_pipe_ctx->plane_res.hubp->opp_id != OPP_ID_INVALID)
- dcn10_disable_plane(dc, old_pipe_ctx);
+ dc->hwss.disable_plane(dc, old_pipe_ctx);
}
if ((!pipe_ctx->plane_state ||
@@ -2501,7 +2654,7 @@ static void dcn10_apply_ctx_for_surface(
for (i = 0; i < dc->res_pool->pipe_count; i++)
if (removed_pipe[i])
- dcn10_disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
+ dc->hwss.disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
for (i = 0; i < dc->res_pool->pipe_count; i++)
if (removed_pipe[i]) {
@@ -2593,8 +2746,9 @@ static void dcn10_optimize_bandwidth(
dcn10_verify_allow_pstate_change_high(dc);
}
-static void set_drr(struct pipe_ctx **pipe_ctx,
- int num_pipes, int vmin, int vmax)
+static void dcn10_set_drr(struct pipe_ctx **pipe_ctx,
+ int num_pipes, unsigned int vmin, unsigned int vmax,
+ unsigned int vmid, unsigned int vmid_frame_number)
{
int i = 0;
struct drr_params params = {0};
@@ -2603,6 +2757,8 @@ static void set_drr(struct pipe_ctx **pipe_ctx,
params.vertical_total_max = vmax;
params.vertical_total_min = vmin;
+ params.vertical_total_mid = vmid;
+ params.vertical_total_mid_frame_num = vmid_frame_number;
/* TODO: If multiple pipes are to be supported, you need
* some GSL stuff. Static screen triggers may be programmed differently
@@ -2618,7 +2774,7 @@ static void set_drr(struct pipe_ctx **pipe_ctx,
}
}
-static void get_position(struct pipe_ctx **pipe_ctx,
+static void dcn10_get_position(struct pipe_ctx **pipe_ctx,
int num_pipes,
struct crtc_position *position)
{
@@ -2630,7 +2786,7 @@ static void get_position(struct pipe_ctx **pipe_ctx,
pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position);
}
-static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
+static void dcn10_set_static_screen_control(struct pipe_ctx **pipe_ctx,
int num_pipes, const struct dc_static_screen_events *events)
{
unsigned int i;
@@ -2692,6 +2848,13 @@ static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc)
dcn10_config_stereo_parameters(stream, &flags);
+ if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
+ if (!dc_set_generic_gpio_for_stereo(true, dc->ctx->gpio_service))
+ dc_set_generic_gpio_for_stereo(false, dc->ctx->gpio_service);
+ } else {
+ dc_set_generic_gpio_for_stereo(false, dc->ctx->gpio_service);
+ }
+
pipe_ctx->stream_res.opp->funcs->opp_program_stereo(
pipe_ctx->stream_res.opp,
flags.PROGRAM_STEREO == 1 ? true:false,
@@ -2782,14 +2945,10 @@ static void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
static void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
{
- if (hws->ctx->dc->res_pool->hubbub != NULL) {
- struct hubp *hubp = hws->ctx->dc->res_pool->hubps[0];
+ struct hubbub *hubbub = hws->ctx->dc->res_pool->hubbub;
- if (hubp->funcs->hubp_update_dchub)
- hubp->funcs->hubp_update_dchub(hubp, dh_data);
- else
- hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data);
- }
+ /* In DCN, this programming sequence is owned by the hubbub */
+ hubbub->funcs->update_dchub(hubbub, dh_data);
}
static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
@@ -2820,6 +2979,40 @@ static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
== PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
pos_cpy.enable = false;
+ // Swap axis and mirror horizontally
+ if (param.rotation == ROTATION_ANGLE_90) {
+ uint32_t temp_x = pos_cpy.x;
+ pos_cpy.x = pipe_ctx->plane_res.scl_data.viewport.width -
+ (pos_cpy.y - pipe_ctx->plane_res.scl_data.viewport.x) + pipe_ctx->plane_res.scl_data.viewport.x;
+ pos_cpy.y = temp_x;
+ }
+ // Swap axis and mirror vertically
+ else if (param.rotation == ROTATION_ANGLE_270) {
+ uint32_t temp_y = pos_cpy.y;
+ if (pos_cpy.x > pipe_ctx->plane_res.scl_data.viewport.height) {
+ pos_cpy.x = pos_cpy.x - pipe_ctx->plane_res.scl_data.viewport.height;
+ pos_cpy.y = pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.x;
+ } else {
+ pos_cpy.y = 2 * pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.x;
+ }
+ pos_cpy.x = temp_y;
+ }
+ // Mirror horizontally and vertically
+ else if (param.rotation == ROTATION_ANGLE_180) {
+ if (pos_cpy.x >= pipe_ctx->plane_res.scl_data.viewport.width + pipe_ctx->plane_res.scl_data.viewport.x) {
+ pos_cpy.x = 2 * pipe_ctx->plane_res.scl_data.viewport.width
+ - pos_cpy.x + 2 * pipe_ctx->plane_res.scl_data.viewport.x;
+ } else {
+ uint32_t temp_x = pos_cpy.x;
+ pos_cpy.x = 2 * pipe_ctx->plane_res.scl_data.viewport.x - pos_cpy.x;
+ if (temp_x >= pipe_ctx->plane_res.scl_data.viewport.x + (int)hubp->curs_attr.width
+ || pos_cpy.x <= (int)hubp->curs_attr.width + pipe_ctx->plane_state->src_rect.x) {
+ pos_cpy.x = temp_x + pipe_ctx->plane_res.scl_data.viewport.width;
+ }
+ }
+ pos_cpy.y = pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.y;
+ }
+
hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width, hubp->curs_attr.height);
}
@@ -2831,7 +3024,7 @@ static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
pipe_ctx->plane_res.hubp, attributes);
pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
- pipe_ctx->plane_res.dpp, attributes->color_format);
+ pipe_ctx->plane_res.dpp, attributes);
}
static void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx)
@@ -3062,9 +3255,59 @@ static void dcn10_send_immediate_sdp_message(struct pipe_ctx *pipe_ctx,
sdp_message_size);
}
}
+static enum dc_status dcn10_set_clock(struct dc *dc,
+ enum dc_clock_type clock_type,
+ uint32_t clk_khz,
+ uint32_t stepping)
+{
+ struct dc_state *context = dc->current_state;
+ struct dc_clock_config clock_cfg = {0};
+ struct dc_clocks *current_clocks = &context->bw_ctx.bw.dcn.clk;
+
+ if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock)
+ dc->clk_mgr->funcs->get_clock(dc->clk_mgr,
+ context, clock_type, &clock_cfg);
+
+ if (!dc->clk_mgr->funcs->get_clock)
+ return DC_FAIL_UNSUPPORTED_1;
+
+ if (clk_khz > clock_cfg.max_clock_khz)
+ return DC_FAIL_CLK_EXCEED_MAX;
+
+ if (clk_khz < clock_cfg.min_clock_khz)
+ return DC_FAIL_CLK_BELOW_MIN;
+
+ if (clk_khz < clock_cfg.bw_requirequired_clock_khz)
+ return DC_FAIL_CLK_BELOW_CFG_REQUIRED;
+
+ /*update internal request clock for update clock use*/
+ if (clock_type == DC_CLOCK_TYPE_DISPCLK)
+ current_clocks->dispclk_khz = clk_khz;
+ else if (clock_type == DC_CLOCK_TYPE_DPPCLK)
+ current_clocks->dppclk_khz = clk_khz;
+ else
+ return DC_ERROR_UNEXPECTED;
+
+ if (dc->clk_mgr && dc->clk_mgr->funcs->update_clocks)
+ dc->clk_mgr->funcs->update_clocks(dc->clk_mgr,
+ context, true);
+ return DC_OK;
+
+}
+
+static void dcn10_get_clock(struct dc *dc,
+ enum dc_clock_type clock_type,
+ struct dc_clock_config *clock_cfg)
+{
+ struct dc_state *context = dc->current_state;
+
+ if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock)
+ dc->clk_mgr->funcs->get_clock(dc->clk_mgr, context, clock_type, clock_cfg);
+
+}
static const struct hw_sequencer_funcs dcn10_funcs = {
- .program_gamut_remap = program_gamut_remap,
+ .program_gamut_remap = dcn10_program_gamut_remap,
.init_hw = dcn10_init_hw,
.init_pipes = dcn10_init_pipes,
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
@@ -3097,18 +3340,18 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.optimize_bandwidth = dcn10_optimize_bandwidth,
.reset_hw_ctx_wrap = dcn10_reset_hw_ctx_wrap,
.enable_stream_timing = dcn10_enable_stream_timing,
- .set_drr = set_drr,
- .get_position = get_position,
- .set_static_screen_control = set_static_screen_control,
+ .set_drr = dcn10_set_drr,
+ .get_position = dcn10_get_position,
+ .set_static_screen_control = dcn10_set_static_screen_control,
.setup_stereo = dcn10_setup_stereo,
.set_avmute = dce110_set_avmute,
.log_hw_state = dcn10_log_hw_state,
.get_hw_state = dcn10_get_hw_state,
.clear_status_bits = dcn10_clear_status_bits,
.wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect,
- .edp_backlight_control = hwss_edp_backlight_control,
- .edp_power_control = hwss_edp_power_control,
- .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
+ .edp_backlight_control = dce110_edp_backlight_control,
+ .edp_power_control = dce110_edp_power_control,
+ .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
.set_cursor_position = dcn10_set_cursor_position,
.set_cursor_attribute = dcn10_set_cursor_attribute,
.set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level,
@@ -3116,7 +3359,18 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.enable_stream_gating = NULL,
.setup_periodic_interrupt = dcn10_setup_periodic_interrupt,
.setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt,
- .did_underflow_occur = dcn10_did_underflow_occur
+ .set_clock = dcn10_set_clock,
+ .get_clock = dcn10_get_clock,
+ .did_underflow_occur = dcn10_did_underflow_occur,
+ .init_blank = NULL,
+ .disable_vga = dcn10_disable_vga,
+ .bios_golden_init = dcn10_bios_golden_init,
+ .plane_atomic_disable = dcn10_plane_atomic_disable,
+ .plane_atomic_power_down = dcn10_plane_atomic_power_down,
+ .enable_power_gating_plane = dcn10_enable_power_gating_plane,
+ .dpp_pg_control = dcn10_dpp_pg_control,
+ .hubp_pg_control = dcn10_hubp_pg_control,
+ .dsc_pg_control = NULL,
};
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c
index 6e47444109d7..7f4766e45dff 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c
@@ -45,7 +45,7 @@
#include "dcn10_cm_common.h"
#include "clk_mgr.h"
-static unsigned int snprintf_count(char *pBuf, unsigned int bufSize, char *fmt, ...)
+unsigned int snprintf_count(char *pBuf, unsigned int bufSize, char *fmt, ...)
{
unsigned int ret_vsnprintf;
unsigned int chars_printed;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
index 549d423a01f6..1a37c90e9d43 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
@@ -89,6 +89,7 @@ static const struct link_encoder_funcs dcn10_lnk_enc_funcs = {
.disable_hpd = dcn10_link_encoder_disable_hpd,
.is_dig_enabled = dcn10_is_dig_enabled,
.get_dig_frontend = dcn10_get_dig_frontend,
+ .get_dig_mode = dcn10_get_dig_mode,
.destroy = dcn10_link_encoder_destroy
};
@@ -446,6 +447,46 @@ static uint8_t get_frontend_source(
}
}
+unsigned int dcn10_get_dig_frontend(struct link_encoder *enc)
+{
+ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+ int32_t value;
+ enum engine_id result;
+
+ REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &value);
+
+ switch (value) {
+ case DCN10_DIG_FE_SOURCE_SELECT_DIGA:
+ result = ENGINE_ID_DIGA;
+ break;
+ case DCN10_DIG_FE_SOURCE_SELECT_DIGB:
+ result = ENGINE_ID_DIGB;
+ break;
+ case DCN10_DIG_FE_SOURCE_SELECT_DIGC:
+ result = ENGINE_ID_DIGC;
+ break;
+ case DCN10_DIG_FE_SOURCE_SELECT_DIGD:
+ result = ENGINE_ID_DIGD;
+ break;
+ case DCN10_DIG_FE_SOURCE_SELECT_DIGE:
+ result = ENGINE_ID_DIGE;
+ break;
+ case DCN10_DIG_FE_SOURCE_SELECT_DIGF:
+ result = ENGINE_ID_DIGF;
+ break;
+ case DCN10_DIG_FE_SOURCE_SELECT_DIGG:
+ result = ENGINE_ID_DIGG;
+ break;
+ default:
+ // invalid source select DIG
+ ASSERT(false);
+ result = ENGINE_ID_UNKNOWN;
+ }
+
+ return result;
+
+}
+
void enc1_configure_encoder(
struct dcn10_link_encoder *enc10,
const struct dc_link_settings *link_settings)
@@ -501,15 +542,6 @@ bool dcn10_is_dig_enabled(struct link_encoder *enc)
return value;
}
-unsigned int dcn10_get_dig_frontend(struct link_encoder *enc)
-{
- struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
- uint32_t value;
-
- REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &value);
- return value;
-}
-
static void link_encoder_disable(struct dcn10_link_encoder *enc10)
{
/* reset training pattern */
@@ -1366,3 +1398,25 @@ void dcn10_aux_initialize(struct dcn10_link_encoder *enc10)
AUX_REG_UPDATE(AUX_DPHY_RX_CONTROL0,
AUX_RX_RECEIVE_WINDOW, 0);
}
+
+enum signal_type dcn10_get_dig_mode(
+ struct link_encoder *enc)
+{
+ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+ uint32_t value;
+ REG_GET(DIG_BE_CNTL, DIG_MODE, &value);
+ switch (value) {
+ case 1:
+ return SIGNAL_TYPE_DISPLAY_PORT;
+ case 2:
+ return SIGNAL_TYPE_DVI_SINGLE_LINK;
+ case 3:
+ return SIGNAL_TYPE_HDMI_TYPE_A;
+ case 5:
+ return SIGNAL_TYPE_DISPLAY_PORT_MST;
+ default:
+ return SIGNAL_TYPE_NONE;
+ }
+ return SIGNAL_TYPE_NONE;
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
index 33b2af1a181c..8bf5f0f2301d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
@@ -337,6 +337,7 @@ struct dcn10_link_enc_registers {
type RDPCS_TX_FIFO_ERROR_MASK;\
type RDPCS_DPALT_DISABLE_TOGGLE_MASK;\
type RDPCS_DPALT_4LANE_TOGGLE_MASK;\
+ type RDPCS_PHY_DPALT_DISABLE;\
type RDPCS_PHY_DPALT_DISABLE_ACK;\
type RDPCS_PHY_DP_MPLLB_V2I;\
type RDPCS_PHY_DP_MPLLB_FREQ_VCO;\
@@ -514,4 +515,6 @@ unsigned int dcn10_get_dig_frontend(struct link_encoder *enc);
void dcn10_aux_initialize(struct dcn10_link_encoder *enc10);
+enum signal_type dcn10_get_dig_mode(
+ struct link_encoder *enc);
#endif /* __DC_LINK_ENCODER__DCN10_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
index 0bca011ed7c9..8b2f29f6dabd 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
@@ -211,7 +211,7 @@ struct mpcc *mpc1_insert_plane(
} else {
new_mpcc->mpcc_bot = NULL;
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
- REG_UPDATE(MPCC_CONTROL[mpcc_id], MPCC_MODE, MPCC_BLEND_MODE_TOP_LAYER_PASSTHROUGH);
+ REG_UPDATE(MPCC_CONTROL[mpcc_id], MPCC_MODE, MPCC_BLEND_MODE_TOP_LAYER_ONLY);
}
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id);
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id);
@@ -364,6 +364,24 @@ void mpc1_mpc_init(struct mpc *mpc)
}
}
+void mpc1_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id)
+{
+ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
+ int opp_id;
+
+ REG_GET(MPCC_OPP_ID[mpcc_id], MPCC_OPP_ID, &opp_id);
+
+ REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
+ REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
+ REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
+
+ mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
+
+ if (opp_id < MAX_OPP && REG(MUX[opp_id]))
+ REG_UPDATE(MUX[opp_id], MPC_OUT_MUX, 0xf);
+}
+
+
void mpc1_init_mpcc_list_from_hw(
struct mpc *mpc,
struct mpc_tree *tree)
@@ -433,6 +451,7 @@ static const struct mpc_funcs dcn10_mpc_funcs = {
.insert_plane = mpc1_insert_plane,
.remove_mpcc = mpc1_remove_mpcc,
.mpc_init = mpc1_mpc_init,
+ .mpc_init_single_inst = mpc1_mpc_init_single_inst,
.get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
.wait_for_idle = mpc1_assert_idle_mpcc,
.assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
index d3d16c4cbea3..962a68e322ee 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
@@ -149,6 +149,10 @@ void mpc1_remove_mpcc(
void mpc1_mpc_init(
struct mpc *mpc);
+void mpc1_mpc_init_single_inst(
+ struct mpc *mpc,
+ unsigned int mpcc_id);
+
void mpc1_assert_idle_mpcc(
struct mpc *mpc,
int id);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
index a546c2bc9129..e74a07d03fde 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
@@ -154,7 +154,7 @@ void optc1_program_timing(
uint32_t h_sync_polarity, v_sync_polarity;
uint32_t start_point = 0;
uint32_t field_num = 0;
- uint32_t h_div_2;
+ enum h_timing_div_mode h_div = H_TIMING_NO_DIV;
struct optc *optc1 = DCN10TG_FROM_TG(optc);
@@ -285,10 +285,11 @@ void optc1_program_timing(
* of stereo handled in explicit call
*/
- h_div_2 = optc1_is_two_pixels_per_containter(&patched_crtc_timing);
- REG_UPDATE(OTG_H_TIMING_CNTL,
- OTG_H_TIMING_DIV_BY2, h_div_2 || optc1->comb_opp_id != 0xf);
+ if (optc1_is_two_pixels_per_containter(&patched_crtc_timing) || optc1->opp_count == 2)
+ h_div = H_TIMING_DIV_BY2;
+ REG_UPDATE(OTG_H_TIMING_CNTL,
+ OTG_H_TIMING_DIV_BY2, h_div);
}
void optc1_set_vtg_params(struct timing_generator *optc,
@@ -824,6 +825,9 @@ void optc1_program_manual_trigger(struct timing_generator *optc)
REG_SET(OTG_MANUAL_FLOW_CONTROL, 0,
MANUAL_FLOW_CONTROL, 1);
+
+ REG_SET(OTG_MANUAL_FLOW_CONTROL, 0,
+ MANUAL_FLOW_CONTROL, 0);
}
@@ -846,6 +850,18 @@ void optc1_set_drr(
params->vertical_total_max > 0 &&
params->vertical_total_min > 0) {
+ if (params->vertical_total_mid != 0) {
+
+ REG_SET(OTG_V_TOTAL_MID, 0,
+ OTG_V_TOTAL_MID, params->vertical_total_mid - 1);
+
+ REG_UPDATE_2(OTG_V_TOTAL_CONTROL,
+ OTG_VTOTAL_MID_REPLACING_MAX_EN, 1,
+ OTG_VTOTAL_MID_FRAME_NUM,
+ (uint8_t)params->vertical_total_mid_frame_num);
+
+ }
+
REG_SET(OTG_V_TOTAL_MAX, 0,
OTG_V_TOTAL_MAX, params->vertical_total_max - 1);
@@ -1513,7 +1529,6 @@ void dcn10_timing_generator_init(struct optc *optc1)
optc1->min_v_blank_interlace = 5;
optc1->min_h_sync_width = 8;
optc1->min_v_sync_width = 1;
- optc1->comb_opp_id = 0xf;
}
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
index 02599eb92ca6..83575599672e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
@@ -54,6 +54,7 @@
SRI(OTG_3D_STRUCTURE_CONTROL, OTG, inst),\
SRI(OTG_STEREO_STATUS, OTG, inst),\
SRI(OTG_V_TOTAL_MAX, OTG, inst),\
+ SRI(OTG_V_TOTAL_MID, OTG, inst),\
SRI(OTG_V_TOTAL_MIN, OTG, inst),\
SRI(OTG_V_TOTAL_CONTROL, OTG, inst),\
SRI(OTG_TRIGA_CNTL, OTG, inst),\
@@ -125,6 +126,7 @@ struct dcn_optc_registers {
uint32_t OTG_3D_STRUCTURE_CONTROL;
uint32_t OTG_STEREO_STATUS;
uint32_t OTG_V_TOTAL_MAX;
+ uint32_t OTG_V_TOTAL_MID;
uint32_t OTG_V_TOTAL_MIN;
uint32_t OTG_V_TOTAL_CONTROL;
uint32_t OTG_TRIGA_CNTL;
@@ -214,12 +216,15 @@ struct dcn_optc_registers {
SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_V_UPDATE_MODE, mask_sh),\
SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_STEREO_SEL_OVR, mask_sh),\
SF(OTG0_OTG_V_TOTAL_MAX, OTG_V_TOTAL_MAX, mask_sh),\
+ SF(OTG0_OTG_V_TOTAL_MID, OTG_V_TOTAL_MID, mask_sh),\
SF(OTG0_OTG_V_TOTAL_MIN, OTG_V_TOTAL_MIN, mask_sh),\
SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_V_TOTAL_MIN_SEL, mask_sh),\
SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_V_TOTAL_MAX_SEL, mask_sh),\
SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_FORCE_LOCK_ON_EVENT, mask_sh),\
SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_SET_V_TOTAL_MIN_MASK_EN, mask_sh),\
SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_SET_V_TOTAL_MIN_MASK, mask_sh),\
+ SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_VTOTAL_MID_REPLACING_MAX_EN, mask_sh),\
+ SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_VTOTAL_MID_FRAME_NUM, mask_sh),\
SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_CLEAR, mask_sh),\
SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_MODE, mask_sh),\
SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_OCCURRED, mask_sh),\
@@ -348,9 +353,12 @@ struct dcn_optc_registers {
type OTG_3D_STRUCTURE_V_UPDATE_MODE;\
type OTG_3D_STRUCTURE_STEREO_SEL_OVR;\
type OTG_V_TOTAL_MAX;\
+ type OTG_V_TOTAL_MID;\
type OTG_V_TOTAL_MIN;\
type OTG_V_TOTAL_MIN_SEL;\
type OTG_V_TOTAL_MAX_SEL;\
+ type OTG_VTOTAL_MID_REPLACING_MAX_EN;\
+ type OTG_VTOTAL_MID_FRAME_NUM;\
type OTG_FORCE_LOCK_ON_EVENT;\
type OTG_SET_V_TOTAL_MIN_MASK_EN;\
type OTG_SET_V_TOTAL_MIN_MASK;\
@@ -494,7 +502,7 @@ struct optc {
const struct dcn_optc_shift *tg_shift;
const struct dcn_optc_mask *tg_mask;
- int comb_opp_id;
+ int opp_count;
uint32_t max_h_total;
uint32_t max_v_total;
@@ -539,6 +547,10 @@ struct dcn_otg_state {
void optc1_read_otg_state(struct optc *optc1,
struct dcn_otg_state *s);
+bool optc1_is_matching_timing(
+ struct timing_generator *tg,
+ const struct dc_crtc_timing *otg_timing);
+
bool optc1_validate_timing(
struct timing_generator *optc,
const struct dc_crtc_timing *timing);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index a12530a3ab9c..59305e411a66 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -270,7 +270,7 @@ static const struct dce_audio_shift audio_shift = {
DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
};
-static const struct dce_aduio_mask audio_mask = {
+static const struct dce_audio_mask audio_mask = {
DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
};
@@ -1416,6 +1416,14 @@ static bool construct(
pool->base.pp_smu = dcn10_pp_smu_create(ctx);
+ /*
+ * Right now SMU/PPLIB and DAL all have the AZ D3 force PME notification *
+ * implemented. So AZ D3 should work.For issue 197007. *
+ */
+ if (pool->base.pp_smu != NULL
+ && pool->base.pp_smu->rv_funcs.set_pme_wa_enable != NULL)
+ dc->debug.az_endpoint_mute_only = false;
+
if (!dc->debug.disable_pplib_clock_request)
dcn_bw_update_from_pplib(dc);
dcn_bw_sync_calcs_and_dml(dc);
@@ -1562,6 +1570,7 @@ struct resource_pool *dcn10_create_resource_pool(
if (construct(init_data->num_virtual_links, dc, pool))
return &pool->base;
+ kfree(pool);
BREAK_TO_DEBUGGER();
return NULL;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
index b9ffbf6b58ff..9aa258f3550b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
@@ -512,11 +512,12 @@ void enc1_stream_encoder_hdmi_set_stream_attribute(
enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing);
/* setup HDMI engine */
- REG_UPDATE_5(HDMI_CONTROL,
+ REG_UPDATE_6(HDMI_CONTROL,
HDMI_PACKET_GEN_VERSION, 1,
HDMI_KEEPOUT_MODE, 1,
HDMI_DEEP_COLOR_ENABLE, 0,
HDMI_DATA_SCRAMBLE_EN, 0,
+ HDMI_NO_EXTRA_NULL_PACKET_FILLED, 1,
HDMI_CLOCK_CHANNEL_RATE, 0);
@@ -1003,6 +1004,19 @@ void enc1_stream_encoder_set_avmute(
REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, value);
}
+void enc1_reset_hdmi_stream_attribute(
+ struct stream_encoder *enc)
+{
+ struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+
+ REG_UPDATE_5(HDMI_CONTROL,
+ HDMI_PACKET_GEN_VERSION, 1,
+ HDMI_KEEPOUT_MODE, 1,
+ HDMI_DEEP_COLOR_ENABLE, 0,
+ HDMI_DATA_SCRAMBLE_EN, 0,
+ HDMI_CLOCK_CHANNEL_RATE, 0);
+}
+
#define DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT 0x8000
#define DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC 1
@@ -1196,13 +1210,13 @@ static union audio_cea_channels speakers_to_channels(
void get_audio_clock_info(
enum dc_color_depth color_depth,
- uint32_t crtc_pixel_clock_in_khz,
- uint32_t actual_pixel_clock_in_khz,
+ uint32_t crtc_pixel_clock_100Hz,
+ uint32_t actual_pixel_clock_100Hz,
struct audio_clock_info *audio_clock_info)
{
const struct audio_clock_info *clock_info;
uint32_t index;
- uint32_t crtc_pixel_clock_in_10khz = crtc_pixel_clock_in_khz / 10;
+ uint32_t crtc_pixel_clock_in_10khz = crtc_pixel_clock_100Hz / 100;
uint32_t audio_array_size;
switch (color_depth) {
@@ -1239,16 +1253,16 @@ void get_audio_clock_info(
}
/* not found */
- if (actual_pixel_clock_in_khz == 0)
- actual_pixel_clock_in_khz = crtc_pixel_clock_in_khz;
+ if (actual_pixel_clock_100Hz == 0)
+ actual_pixel_clock_100Hz = crtc_pixel_clock_100Hz;
/* See HDMI spec the table entry under
* pixel clock of "Other". */
audio_clock_info->pixel_clock_in_10khz =
- actual_pixel_clock_in_khz / 10;
- audio_clock_info->cts_32khz = actual_pixel_clock_in_khz;
- audio_clock_info->cts_44khz = actual_pixel_clock_in_khz;
- audio_clock_info->cts_48khz = actual_pixel_clock_in_khz;
+ actual_pixel_clock_100Hz / 100;
+ audio_clock_info->cts_32khz = actual_pixel_clock_100Hz / 10;
+ audio_clock_info->cts_44khz = actual_pixel_clock_100Hz / 10;
+ audio_clock_info->cts_48khz = actual_pixel_clock_100Hz / 10;
audio_clock_info->n_32khz = 4096;
audio_clock_info->n_44khz = 6272;
@@ -1308,14 +1322,14 @@ static void enc1_se_setup_hdmi_audio(
/* Program audio clock sample/regeneration parameters */
get_audio_clock_info(crtc_info->color_depth,
- crtc_info->requested_pixel_clock,
- crtc_info->calculated_pixel_clock,
+ crtc_info->requested_pixel_clock_100Hz,
+ crtc_info->calculated_pixel_clock_100Hz,
&audio_clock_info);
DC_LOG_HW_AUDIO(
- "\n%s:Input::requested_pixel_clock = %d" \
- "calculated_pixel_clock = %d \n", __func__, \
- crtc_info->requested_pixel_clock, \
- crtc_info->calculated_pixel_clock);
+ "\n%s:Input::requested_pixel_clock_100Hz = %d" \
+ "calculated_pixel_clock_100Hz = %d \n", __func__, \
+ crtc_info->requested_pixel_clock_100Hz, \
+ crtc_info->calculated_pixel_clock_100Hz);
/* HDMI_ACR_32_0__HDMI_ACR_CTS_32_MASK */
REG_UPDATE(HDMI_ACR_32_0, HDMI_ACR_CTS_32, audio_clock_info.cts_32khz);
@@ -1528,6 +1542,17 @@ void enc1_dig_connect_to_otg(
REG_UPDATE(DIG_FE_CNTL, DIG_SOURCE_SELECT, tg_inst);
}
+unsigned int enc1_dig_source_otg(
+ struct stream_encoder *enc)
+{
+ uint32_t tg_inst = 0;
+ struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+
+ REG_GET(DIG_FE_CNTL, DIG_SOURCE_SELECT, &tg_inst);
+
+ return tg_inst;
+}
+
static const struct stream_encoder_funcs dcn10_str_enc_funcs = {
.dp_set_stream_attribute =
enc1_stream_encoder_dp_set_stream_attribute,
@@ -1562,6 +1587,8 @@ static const struct stream_encoder_funcs dcn10_str_enc_funcs = {
.setup_stereo_sync = enc1_setup_stereo_sync,
.set_avmute = enc1_stream_encoder_set_avmute,
.dig_connect_to_otg = enc1_dig_connect_to_otg,
+ .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
+ .dig_source_otg = enc1_dig_source_otg,
};
void dcn10_stream_encoder_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
index bc2b4af9543b..a512cbea00d1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
@@ -89,7 +89,8 @@
SRI(DP_VID_STREAM_CNTL, DP, id), \
SRI(DP_VID_TIMING, DP, id), \
SRI(DP_SEC_AUD_N, DP, id), \
- SRI(DP_SEC_TIMESTAMP, DP, id)
+ SRI(DP_SEC_TIMESTAMP, DP, id), \
+ SRI(DIG_CLOCK_PATTERN, DIG, id)
#define SE_DCN_REG_LIST(id)\
SE_COMMON_DCN_REG_LIST(id)
@@ -170,6 +171,7 @@ struct dcn10_stream_enc_registers {
uint32_t HDMI_METADATA_PACKET_CONTROL;
uint32_t DP_SEC_FRAMING4;
#endif
+ uint32_t DIG_CLOCK_PATTERN;
};
@@ -189,6 +191,7 @@ struct dcn10_stream_enc_registers {
SE_SF(DIG0_HDMI_CONTROL, HDMI_DEEP_COLOR_ENABLE, mask_sh),\
SE_SF(DIG0_HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, mask_sh),\
SE_SF(DIG0_HDMI_CONTROL, HDMI_DATA_SCRAMBLE_EN, mask_sh),\
+ SE_SF(DIG0_HDMI_CONTROL, HDMI_NO_EXTRA_NULL_PACKET_FILLED, mask_sh),\
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_GC_CONT, mask_sh),\
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_GC_SEND, mask_sh),\
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_NULL_SEND, mask_sh),\
@@ -297,7 +300,8 @@ struct dcn10_stream_enc_registers {
SE_SF(DP0_DP_MSA_TIMING_PARAM4, DP_MSA_VHEIGHT, mask_sh),\
SE_SF(DIG0_HDMI_DB_CONTROL, HDMI_DB_DISABLE, mask_sh),\
SE_SF(DP0_DP_VID_TIMING, DP_VID_N_MUL, mask_sh),\
- SE_SF(DIG0_DIG_FE_CNTL, DIG_SOURCE_SELECT, mask_sh)
+ SE_SF(DIG0_DIG_FE_CNTL, DIG_SOURCE_SELECT, mask_sh),\
+ SE_SF(DIG0_DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, mask_sh)
#define SE_COMMON_MASK_SH_LIST_SOC(mask_sh)\
SE_COMMON_MASK_SH_LIST_SOC_BASE(mask_sh)
@@ -374,6 +378,7 @@ struct dcn10_stream_enc_registers {
type HDMI_GC_SEND;\
type HDMI_NULL_SEND;\
type HDMI_DATA_SCRAMBLE_EN;\
+ type HDMI_NO_EXTRA_NULL_PACKET_FILLED;\
type HDMI_AUDIO_INFO_SEND;\
type AFMT_AUDIO_INFO_UPDATE;\
type HDMI_AUDIO_INFO_LINE;\
@@ -458,7 +463,8 @@ struct dcn10_stream_enc_registers {
type HDMI_DB_DISABLE;\
type DP_VID_N_MUL;\
type DP_VID_M_DOUBLE_VALUE_EN;\
- type DIG_SOURCE_SELECT
+ type DIG_SOURCE_SELECT;\
+ type DIG_CLOCK_PATTERN
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
#define SE_REG_FIELD_LIST_DCN2_0(type) \
@@ -592,6 +598,9 @@ void enc1_dig_connect_to_otg(
struct stream_encoder *enc,
int tg_inst);
+unsigned int enc1_dig_source_otg(
+ struct stream_encoder *enc);
+
void enc1_stream_encoder_set_stream_attribute_helper(
struct dcn10_stream_encoder *enc1,
struct dc_crtc_timing *crtc_timing);
@@ -605,8 +614,11 @@ void enc1_se_enable_dp_audio(
void get_audio_clock_info(
enum dc_color_depth color_depth,
- uint32_t crtc_pixel_clock_in_khz,
- uint32_t actual_pixel_clock_in_khz,
+ uint32_t crtc_pixel_clock_100Hz,
+ uint32_t actual_pixel_clock_100Hz,
struct audio_clock_info *audio_clock_info);
+void enc1_reset_hdmi_stream_attribute(
+ struct stream_encoder *enc);
+
#endif /* __DC_STREAM_ENCODER_DCN10_H__ */