diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3043-drm-amd-display-Fix-some-HUBP-programming-issues.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3043-drm-amd-display-Fix-some-HUBP-programming-issues.patch | 823 |
1 files changed, 823 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3043-drm-amd-display-Fix-some-HUBP-programming-issues.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3043-drm-amd-display-Fix-some-HUBP-programming-issues.patch new file mode 100644 index 00000000..10ad6b4a --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3043-drm-amd-display-Fix-some-HUBP-programming-issues.patch @@ -0,0 +1,823 @@ +From f3bf57204740b59d66274fcf5a8c41aa7650d86a Mon Sep 17 00:00:00 2001 +From: Ilya Bakoulin <Ilya.Bakoulin@amd.com> +Date: Wed, 12 Jun 2019 12:40:42 -0400 +Subject: [PATCH 3043/4256] drm/amd/display: Fix some HUBP programming issues + +[Why] +A hubp pointer was being passed to DCN1 functions, which +expect the enclosing structure (for the purpose of container_of macros) +to be dcn10_hubp, but the actual type was dcn20_hubp. + +[How] +Copy existing DCN1 functions and alter them slightly for use with +dcn20_hubp. + +Signed-off-by: Ilya Bakoulin <Ilya.Bakoulin@amd.com> +Reviewed-by: Charlene Liu <Charlene.Liu@amd.com> +Acked-by: Leo Li <sunpeng.li@amd.com> +--- + .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c | 682 +++++++++++++++++- + .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h | 37 + + 2 files changed, 705 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c +index d3f7dd374d50..02e8c0c6a233 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c +@@ -156,7 +156,85 @@ void hubp2_program_deadline( + { + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); + +- hubp1_program_deadline(hubp, dlg_attr, ttu_attr); ++ /* DLG - Per hubp */ ++ REG_SET_2(BLANK_OFFSET_0, 0, ++ REFCYC_H_BLANK_END, dlg_attr->refcyc_h_blank_end, ++ DLG_V_BLANK_END, dlg_attr->dlg_vblank_end); ++ ++ REG_SET(BLANK_OFFSET_1, 0, ++ MIN_DST_Y_NEXT_START, dlg_attr->min_dst_y_next_start); ++ ++ REG_SET(DST_DIMENSIONS, 0, ++ REFCYC_PER_HTOTAL, dlg_attr->refcyc_per_htotal); ++ ++ REG_SET_2(DST_AFTER_SCALER, 0, ++ REFCYC_X_AFTER_SCALER, dlg_attr->refcyc_x_after_scaler, ++ DST_Y_AFTER_SCALER, dlg_attr->dst_y_after_scaler); ++ ++ REG_SET(REF_FREQ_TO_PIX_FREQ, 0, ++ REF_FREQ_TO_PIX_FREQ, dlg_attr->ref_freq_to_pix_freq); ++ ++ /* DLG - Per luma/chroma */ ++ REG_SET(VBLANK_PARAMETERS_1, 0, ++ REFCYC_PER_PTE_GROUP_VBLANK_L, dlg_attr->refcyc_per_pte_group_vblank_l); ++ ++ if (REG(NOM_PARAMETERS_0)) ++ REG_SET(NOM_PARAMETERS_0, 0, ++ DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l); ++ ++ if (REG(NOM_PARAMETERS_1)) ++ REG_SET(NOM_PARAMETERS_1, 0, ++ REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l); ++ ++ REG_SET(NOM_PARAMETERS_4, 0, ++ DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l); ++ ++ REG_SET(NOM_PARAMETERS_5, 0, ++ REFCYC_PER_META_CHUNK_NOM_L, dlg_attr->refcyc_per_meta_chunk_nom_l); ++ ++ REG_SET_2(PER_LINE_DELIVERY, 0, ++ REFCYC_PER_LINE_DELIVERY_L, dlg_attr->refcyc_per_line_delivery_l, ++ REFCYC_PER_LINE_DELIVERY_C, dlg_attr->refcyc_per_line_delivery_c); ++ ++ REG_SET(VBLANK_PARAMETERS_2, 0, ++ REFCYC_PER_PTE_GROUP_VBLANK_C, dlg_attr->refcyc_per_pte_group_vblank_c); ++ ++ if (REG(NOM_PARAMETERS_2)) ++ REG_SET(NOM_PARAMETERS_2, 0, ++ DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c); ++ ++ if (REG(NOM_PARAMETERS_3)) ++ REG_SET(NOM_PARAMETERS_3, 0, ++ REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c); ++ ++ REG_SET(NOM_PARAMETERS_6, 0, ++ DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c); ++ ++ REG_SET(NOM_PARAMETERS_7, 0, ++ REFCYC_PER_META_CHUNK_NOM_C, dlg_attr->refcyc_per_meta_chunk_nom_c); ++ ++ /* TTU - per hubp */ ++ REG_SET_2(DCN_TTU_QOS_WM, 0, ++ QoS_LEVEL_LOW_WM, ttu_attr->qos_level_low_wm, ++ QoS_LEVEL_HIGH_WM, ttu_attr->qos_level_high_wm); ++ ++ /* TTU - per luma/chroma */ ++ /* Assumed surf0 is luma and 1 is chroma */ ++ ++ REG_SET_3(DCN_SURF0_TTU_CNTL0, 0, ++ REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_l, ++ QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_l, ++ QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_l); ++ ++ REG_SET_3(DCN_SURF1_TTU_CNTL0, 0, ++ REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_c, ++ QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_c, ++ QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_c); ++ ++ REG_SET_3(DCN_CUR0_TTU_CNTL0, 0, ++ REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_cur0, ++ QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_cur0, ++ QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_cur0); + + REG_SET(FLIP_PARAMETERS_1, 0, + REFCYC_PER_PTE_GROUP_FLIP_L, dlg_attr->refcyc_per_pte_group_flip_l); +@@ -184,6 +262,39 @@ void hubp2_vready_at_or_After_vsync(struct hubp *hubp, + REG_UPDATE(DCHUBP_CNTL, HUBP_VREADY_AT_OR_AFTER_VSYNC, value); + } + ++void hubp2_program_requestor( ++ struct hubp *hubp, ++ struct _vcs_dpi_display_rq_regs_st *rq_regs) ++{ ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ ++ REG_UPDATE(HUBPRET_CONTROL, ++ DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address); ++ REG_SET_4(DCN_EXPANSION_MODE, 0, ++ DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode, ++ 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_SET_8(DCHUBP_REQ_SIZE_CONFIG, 0, ++ 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_SET_8(DCHUBP_REQ_SIZE_CONFIG_C, 0, ++ 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); ++} ++ + static void hubp2_setup( + struct hubp *hubp, + struct _vcs_dpi_display_dlg_regs_st *dlg_attr, +@@ -196,7 +307,7 @@ static void hubp2_setup( + */ + + hubp2_vready_at_or_After_vsync(hubp, pipe_dest); +- hubp1_program_requestor(hubp, rq_regs); ++ hubp2_program_requestor(hubp, rq_regs); + hubp2_program_deadline(hubp, dlg_attr, ttu_attr); + + } +@@ -283,6 +394,196 @@ static void hubp2_program_tiling( + PIPE_ALIGNED, 0); + } + ++void hubp2_program_size( ++ struct hubp *hubp, ++ enum surface_pixel_format format, ++ const union plane_size *plane_size, ++ struct dc_plane_dcc_param *dcc) ++{ ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ uint32_t pitch, meta_pitch, pitch_c, meta_pitch_c; ++ ++ /* Program data and meta surface pitch (calculation from addrlib) ++ * 444 or 420 luma ++ */ ++ if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN && format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END) { ++ ASSERT(plane_size->video.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; ++ } else { ++ pitch = plane_size->grph.surface_pitch - 1; ++ meta_pitch = dcc->grph.meta_pitch - 1; ++ pitch_c = 0; ++ meta_pitch_c = 0; ++ } ++ ++ if (!dcc->enable) { ++ meta_pitch = 0; ++ meta_pitch_c = 0; ++ } ++ ++ REG_UPDATE_2(DCSURF_SURFACE_PITCH, ++ PITCH, pitch, META_PITCH, meta_pitch); ++ ++ if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) ++ REG_UPDATE_2(DCSURF_SURFACE_PITCH_C, ++ PITCH_C, pitch_c, META_PITCH_C, meta_pitch_c); ++} ++ ++void hubp2_program_rotation( ++ struct hubp *hubp, ++ enum dc_rotation_angle rotation, ++ bool horizontal_mirror) ++{ ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ uint32_t mirror; ++ ++ ++ if (horizontal_mirror) ++ mirror = 1; ++ else ++ mirror = 0; ++ ++ /* Program rotation angle and horz mirror - no mirror */ ++ if (rotation == ROTATION_ANGLE_0) ++ REG_UPDATE_2(DCSURF_SURFACE_CONFIG, ++ ROTATION_ANGLE, 0, ++ H_MIRROR_EN, mirror); ++ else if (rotation == ROTATION_ANGLE_90) ++ REG_UPDATE_2(DCSURF_SURFACE_CONFIG, ++ ROTATION_ANGLE, 1, ++ H_MIRROR_EN, mirror); ++ else if (rotation == ROTATION_ANGLE_180) ++ REG_UPDATE_2(DCSURF_SURFACE_CONFIG, ++ ROTATION_ANGLE, 2, ++ H_MIRROR_EN, mirror); ++ else if (rotation == ROTATION_ANGLE_270) ++ REG_UPDATE_2(DCSURF_SURFACE_CONFIG, ++ ROTATION_ANGLE, 3, ++ H_MIRROR_EN, mirror); ++} ++ ++void hubp2_dcc_control(struct hubp *hubp, bool enable, ++ bool independent_64b_blks) ++{ ++ uint32_t dcc_en = enable ? 1 : 0; ++ uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0; ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ ++ REG_UPDATE_4(DCSURF_SURFACE_CONTROL, ++ PRIMARY_SURFACE_DCC_EN, dcc_en, ++ PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk, ++ SECONDARY_SURFACE_DCC_EN, dcc_en, ++ SECONDARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk); ++} ++ ++void hubp2_program_pixel_format( ++ struct hubp *hubp, ++ enum surface_pixel_format format) ++{ ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ uint32_t red_bar = 3; ++ uint32_t blue_bar = 2; ++ ++ /* swap for ABGR format */ ++ if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 ++ || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 ++ || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS ++ || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) { ++ red_bar = 2; ++ blue_bar = 3; ++ } ++ ++ REG_UPDATE_2(HUBPRET_CONTROL, ++ CROSSBAR_SRC_CB_B, blue_bar, ++ CROSSBAR_SRC_CR_R, red_bar); ++ ++ /* Mapping is same as ipp programming (cnvc) */ ++ ++ switch (format) { ++ case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 1); ++ break; ++ case SURFACE_PIXEL_FORMAT_GRPH_RGB565: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 3); ++ break; ++ case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: ++ case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 8); ++ break; ++ case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: ++ case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: ++ case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 10); ++ break; ++ case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 22); ++ break; ++ case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: ++ case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:/*we use crossbar already*/ ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 24); ++ break; ++ ++ case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 65); ++ break; ++ case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 64); ++ break; ++ case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 67); ++ break; ++ case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 66); ++ break; ++ case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 12); ++ break; ++#if defined(CONFIG_DRM_AMD_DC_DCN2_0) ++ case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 112); ++ break; ++ case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 113); ++ break; ++ case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 114); ++ break; ++ case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 118); ++ break; ++ case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT: ++ REG_UPDATE(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, 119); ++ break; ++#endif ++ default: ++ BREAK_TO_DEBUGGER(); ++ break; ++ } ++ ++ /* don't see the need of program the xbar in DCN 1.0 */ ++} ++ + void hubp2_program_surface_config( + struct hubp *hubp, + enum surface_pixel_format format, +@@ -295,11 +596,11 @@ void hubp2_program_surface_config( + { + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); + +- hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks); ++ hubp2_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks); + hubp2_program_tiling(hubp2, tiling_info, format); +- hubp1_program_size(hubp, format, plane_size, dcc); +- hubp1_program_rotation(hubp, rotation, horizontal_mirror); +- hubp1_program_pixel_format(hubp, format); ++ hubp2_program_size(hubp, format, plane_size, dcc); ++ hubp2_program_rotation(hubp, rotation, horizontal_mirror); ++ hubp2_program_pixel_format(hubp, format); + } + + enum cursor_lines_per_chunk hubp2_get_lines_per_chunk( +@@ -652,28 +953,381 @@ void hubp2_set_flip_control_surface_gsl(struct hubp *hubp, bool enable) + REG_UPDATE(DCSURF_FLIP_CONTROL2, SURFACE_GSL_ENABLE, enable ? 1 : 0); + } + ++bool hubp2_is_flip_pending(struct hubp *hubp) ++{ ++ uint32_t flip_pending = 0; ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ struct dc_plane_address earliest_inuse_address; ++ ++ REG_GET(DCSURF_FLIP_CONTROL, ++ SURFACE_FLIP_PENDING, &flip_pending); ++ ++ REG_GET(DCSURF_SURFACE_EARLIEST_INUSE, ++ SURFACE_EARLIEST_INUSE_ADDRESS, &earliest_inuse_address.grph.addr.low_part); ++ ++ REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH, ++ SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &earliest_inuse_address.grph.addr.high_part); ++ ++ if (flip_pending) ++ return true; ++ ++ if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part) ++ return true; ++ ++ return false; ++} ++ ++void hubp2_set_blank(struct hubp *hubp, bool blank) ++{ ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ uint32_t blank_en = blank ? 1 : 0; ++ ++ REG_UPDATE_2(DCHUBP_CNTL, ++ HUBP_BLANK_EN, blank_en, ++ HUBP_TTU_DISABLE, blank_en); ++ ++ if (blank) { ++ uint32_t reg_val = REG_READ(DCHUBP_CNTL); ++ ++ if (reg_val) { ++ /* init sequence workaround: in case HUBP is ++ * power gated, this wait would timeout. ++ * ++ * we just wrote reg_val to non-0, if it stay 0 ++ * it means HUBP is gated ++ */ ++ REG_WAIT(DCHUBP_CNTL, ++ HUBP_NO_OUTSTANDING_REQ, 1, ++ 1, 200); ++ } ++ ++ hubp->mpcc_id = 0xf; ++ hubp->opp_id = OPP_ID_INVALID; ++ } ++} ++ ++void hubp2_cursor_set_position( ++ struct hubp *hubp, ++ const struct dc_cursor_position *pos, ++ const struct dc_cursor_mi_param *param) ++{ ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; ++ int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y; ++ int x_hotspot = pos->x_hotspot; ++ int y_hotspot = pos->y_hotspot; ++ uint32_t dst_x_offset; ++ uint32_t cur_en = pos->enable ? 1 : 0; ++ ++ /* ++ * Guard aganst cursor_set_position() from being called with invalid ++ * attributes ++ * ++ * TODO: Look at combining cursor_set_position() and ++ * cursor_set_attributes() into cursor_update() ++ */ ++ if (hubp->curs_attr.address.quad_part == 0) ++ return; ++ ++ if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) { ++ src_x_offset = pos->y - pos->y_hotspot - param->viewport.x; ++ y_hotspot = pos->x_hotspot; ++ x_hotspot = pos->y_hotspot; ++ } ++ ++ if (param->mirror) { ++ x_hotspot = param->viewport.width - x_hotspot; ++ src_x_offset = param->viewport.x + param->viewport.width - src_x_offset; ++ } ++ ++ dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; ++ dst_x_offset *= param->ref_clk_khz; ++ dst_x_offset /= param->pixel_clk_khz; ++ ++ ASSERT(param->h_scale_ratio.value); ++ ++ if (param->h_scale_ratio.value) ++ dst_x_offset = dc_fixpt_floor(dc_fixpt_div( ++ dc_fixpt_from_int(dst_x_offset), ++ param->h_scale_ratio)); ++ ++ if (src_x_offset >= (int)param->viewport.width) ++ cur_en = 0; /* not visible beyond right edge*/ ++ ++ if (src_x_offset + (int)hubp->curs_attr.width <= 0) ++ cur_en = 0; /* not visible beyond left edge*/ ++ ++ if (src_y_offset >= (int)param->viewport.height) ++ cur_en = 0; /* not visible beyond bottom edge*/ ++ ++ if (src_y_offset + (int)hubp->curs_attr.height <= 0) ++ cur_en = 0; /* not visible beyond top edge*/ ++ ++ if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) ++ hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr); ++ ++ REG_UPDATE(CURSOR_CONTROL, ++ CURSOR_ENABLE, cur_en); ++ ++ REG_SET_2(CURSOR_POSITION, 0, ++ CURSOR_X_POSITION, pos->x, ++ CURSOR_Y_POSITION, pos->y); ++ ++ REG_SET_2(CURSOR_HOT_SPOT, 0, ++ CURSOR_HOT_SPOT_X, x_hotspot, ++ CURSOR_HOT_SPOT_Y, y_hotspot); ++ ++ REG_SET(CURSOR_DST_OFFSET, 0, ++ CURSOR_DST_X_OFFSET, dst_x_offset); ++ /* TODO Handle surface pixel formats other than 4:4:4 */ ++} ++ ++void hubp2_clk_cntl(struct hubp *hubp, bool enable) ++{ ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ uint32_t clk_enable = enable ? 1 : 0; ++ ++ REG_UPDATE(HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, clk_enable); ++} ++ ++void hubp2_vtg_sel(struct hubp *hubp, uint32_t otg_inst) ++{ ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ ++ REG_UPDATE(DCHUBP_CNTL, HUBP_VTG_SEL, otg_inst); ++} ++ ++void hubp2_clear_underflow(struct hubp *hubp) ++{ ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ ++ REG_UPDATE(DCHUBP_CNTL, HUBP_UNDERFLOW_CLEAR, 1); ++} ++ ++void hubp2_read_state_common(struct hubp *hubp) ++{ ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ struct dcn_hubp_state *s = &hubp2->state; ++ struct _vcs_dpi_display_dlg_regs_st *dlg_attr = &s->dlg_attr; ++ struct _vcs_dpi_display_ttu_regs_st *ttu_attr = &s->ttu_attr; ++ struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs; ++ ++ /* Requester */ ++ REG_GET(HUBPRET_CONTROL, ++ DET_BUF_PLANE1_BASE_ADDRESS, &rq_regs->plane1_base_address); ++ REG_GET_4(DCN_EXPANSION_MODE, ++ DRQ_EXPANSION_MODE, &rq_regs->drq_expansion_mode, ++ PRQ_EXPANSION_MODE, &rq_regs->prq_expansion_mode, ++ MRQ_EXPANSION_MODE, &rq_regs->mrq_expansion_mode, ++ CRQ_EXPANSION_MODE, &rq_regs->crq_expansion_mode); ++ ++ /* DLG - Per hubp */ ++ REG_GET_2(BLANK_OFFSET_0, ++ REFCYC_H_BLANK_END, &dlg_attr->refcyc_h_blank_end, ++ DLG_V_BLANK_END, &dlg_attr->dlg_vblank_end); ++ ++ REG_GET(BLANK_OFFSET_1, ++ MIN_DST_Y_NEXT_START, &dlg_attr->min_dst_y_next_start); ++ ++ REG_GET(DST_DIMENSIONS, ++ REFCYC_PER_HTOTAL, &dlg_attr->refcyc_per_htotal); ++ ++ REG_GET_2(DST_AFTER_SCALER, ++ REFCYC_X_AFTER_SCALER, &dlg_attr->refcyc_x_after_scaler, ++ DST_Y_AFTER_SCALER, &dlg_attr->dst_y_after_scaler); ++ ++ if (REG(PREFETCH_SETTINS)) ++ REG_GET_2(PREFETCH_SETTINS, ++ DST_Y_PREFETCH, &dlg_attr->dst_y_prefetch, ++ VRATIO_PREFETCH, &dlg_attr->vratio_prefetch); ++ else ++ REG_GET_2(PREFETCH_SETTINGS, ++ DST_Y_PREFETCH, &dlg_attr->dst_y_prefetch, ++ VRATIO_PREFETCH, &dlg_attr->vratio_prefetch); ++ ++ REG_GET_2(VBLANK_PARAMETERS_0, ++ DST_Y_PER_VM_VBLANK, &dlg_attr->dst_y_per_vm_vblank, ++ DST_Y_PER_ROW_VBLANK, &dlg_attr->dst_y_per_row_vblank); ++ ++ REG_GET(REF_FREQ_TO_PIX_FREQ, ++ REF_FREQ_TO_PIX_FREQ, &dlg_attr->ref_freq_to_pix_freq); ++ ++ /* DLG - Per luma/chroma */ ++ REG_GET(VBLANK_PARAMETERS_1, ++ REFCYC_PER_PTE_GROUP_VBLANK_L, &dlg_attr->refcyc_per_pte_group_vblank_l); ++ ++ REG_GET(VBLANK_PARAMETERS_3, ++ REFCYC_PER_META_CHUNK_VBLANK_L, &dlg_attr->refcyc_per_meta_chunk_vblank_l); ++ ++ if (REG(NOM_PARAMETERS_0)) ++ REG_GET(NOM_PARAMETERS_0, ++ DST_Y_PER_PTE_ROW_NOM_L, &dlg_attr->dst_y_per_pte_row_nom_l); ++ ++ if (REG(NOM_PARAMETERS_1)) ++ REG_GET(NOM_PARAMETERS_1, ++ REFCYC_PER_PTE_GROUP_NOM_L, &dlg_attr->refcyc_per_pte_group_nom_l); ++ ++ REG_GET(NOM_PARAMETERS_4, ++ DST_Y_PER_META_ROW_NOM_L, &dlg_attr->dst_y_per_meta_row_nom_l); ++ ++ REG_GET(NOM_PARAMETERS_5, ++ REFCYC_PER_META_CHUNK_NOM_L, &dlg_attr->refcyc_per_meta_chunk_nom_l); ++ ++ REG_GET_2(PER_LINE_DELIVERY_PRE, ++ REFCYC_PER_LINE_DELIVERY_PRE_L, &dlg_attr->refcyc_per_line_delivery_pre_l, ++ REFCYC_PER_LINE_DELIVERY_PRE_C, &dlg_attr->refcyc_per_line_delivery_pre_c); ++ ++ REG_GET_2(PER_LINE_DELIVERY, ++ REFCYC_PER_LINE_DELIVERY_L, &dlg_attr->refcyc_per_line_delivery_l, ++ REFCYC_PER_LINE_DELIVERY_C, &dlg_attr->refcyc_per_line_delivery_c); ++ ++ if (REG(PREFETCH_SETTINS_C)) ++ REG_GET(PREFETCH_SETTINS_C, ++ VRATIO_PREFETCH_C, &dlg_attr->vratio_prefetch_c); ++ else ++ REG_GET(PREFETCH_SETTINGS_C, ++ VRATIO_PREFETCH_C, &dlg_attr->vratio_prefetch_c); ++ ++ REG_GET(VBLANK_PARAMETERS_2, ++ REFCYC_PER_PTE_GROUP_VBLANK_C, &dlg_attr->refcyc_per_pte_group_vblank_c); ++ ++ REG_GET(VBLANK_PARAMETERS_4, ++ REFCYC_PER_META_CHUNK_VBLANK_C, &dlg_attr->refcyc_per_meta_chunk_vblank_c); ++ ++ if (REG(NOM_PARAMETERS_2)) ++ REG_GET(NOM_PARAMETERS_2, ++ DST_Y_PER_PTE_ROW_NOM_C, &dlg_attr->dst_y_per_pte_row_nom_c); ++ ++ if (REG(NOM_PARAMETERS_3)) ++ REG_GET(NOM_PARAMETERS_3, ++ REFCYC_PER_PTE_GROUP_NOM_C, &dlg_attr->refcyc_per_pte_group_nom_c); ++ ++ REG_GET(NOM_PARAMETERS_6, ++ DST_Y_PER_META_ROW_NOM_C, &dlg_attr->dst_y_per_meta_row_nom_c); ++ ++ REG_GET(NOM_PARAMETERS_7, ++ REFCYC_PER_META_CHUNK_NOM_C, &dlg_attr->refcyc_per_meta_chunk_nom_c); ++ ++ /* TTU - per hubp */ ++ REG_GET_2(DCN_TTU_QOS_WM, ++ QoS_LEVEL_LOW_WM, &ttu_attr->qos_level_low_wm, ++ QoS_LEVEL_HIGH_WM, &ttu_attr->qos_level_high_wm); ++ ++ REG_GET_2(DCN_GLOBAL_TTU_CNTL, ++ MIN_TTU_VBLANK, &ttu_attr->min_ttu_vblank, ++ QoS_LEVEL_FLIP, &ttu_attr->qos_level_flip); ++ ++ /* TTU - per luma/chroma */ ++ /* Assumed surf0 is luma and 1 is chroma */ ++ ++ REG_GET_3(DCN_SURF0_TTU_CNTL0, ++ REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_l, ++ QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_l, ++ QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_l); ++ ++ REG_GET(DCN_SURF0_TTU_CNTL1, ++ REFCYC_PER_REQ_DELIVERY_PRE, ++ &ttu_attr->refcyc_per_req_delivery_pre_l); ++ ++ REG_GET_3(DCN_SURF1_TTU_CNTL0, ++ REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_c, ++ QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_c, ++ QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_c); ++ ++ REG_GET(DCN_SURF1_TTU_CNTL1, ++ REFCYC_PER_REQ_DELIVERY_PRE, ++ &ttu_attr->refcyc_per_req_delivery_pre_c); ++ ++ /* Rest of hubp */ ++ REG_GET(DCSURF_SURFACE_CONFIG, ++ SURFACE_PIXEL_FORMAT, &s->pixel_format); ++ ++ REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH, ++ SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &s->inuse_addr_hi); ++ ++ REG_GET(DCSURF_SURFACE_EARLIEST_INUSE, ++ SURFACE_EARLIEST_INUSE_ADDRESS, &s->inuse_addr_lo); ++ ++ REG_GET_2(DCSURF_PRI_VIEWPORT_DIMENSION, ++ PRI_VIEWPORT_WIDTH, &s->viewport_width, ++ PRI_VIEWPORT_HEIGHT, &s->viewport_height); ++ ++ REG_GET_2(DCSURF_SURFACE_CONFIG, ++ ROTATION_ANGLE, &s->rotation_angle, ++ H_MIRROR_EN, &s->h_mirror_en); ++ ++ REG_GET(DCSURF_TILING_CONFIG, ++ SW_MODE, &s->sw_mode); ++ ++ REG_GET(DCSURF_SURFACE_CONTROL, ++ PRIMARY_SURFACE_DCC_EN, &s->dcc_en); ++ ++ REG_GET_3(DCHUBP_CNTL, ++ HUBP_BLANK_EN, &s->blank_en, ++ HUBP_TTU_DISABLE, &s->ttu_disable, ++ HUBP_UNDERFLOW_STATUS, &s->underflow_status); ++ ++ REG_GET(DCN_GLOBAL_TTU_CNTL, ++ MIN_TTU_VBLANK, &s->min_ttu_vblank); ++ ++ 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 hubp2_read_state(struct hubp *hubp) ++{ ++ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); ++ struct dcn_hubp_state *s = &hubp2->state; ++ struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs; ++ ++ hubp2_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); ++ ++} ++ + static struct hubp_funcs dcn20_hubp_funcs = { + .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, + .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled, + .hubp_program_surface_flip_and_addr = hubp2_program_surface_flip_and_addr, + .hubp_program_surface_config = hubp2_program_surface_config, +- .hubp_is_flip_pending = hubp1_is_flip_pending, ++ .hubp_is_flip_pending = hubp2_is_flip_pending, + .hubp_setup = hubp2_setup, + .hubp_setup_interdependent = hubp2_setup_interdependent, + .hubp_set_vm_system_aperture_settings = hubp2_set_vm_system_aperture_settings, +- .set_blank = hubp1_set_blank, +- .dcc_control = hubp1_dcc_control, ++ .set_blank = hubp2_set_blank, ++ .dcc_control = hubp2_dcc_control, + .hubp_update_dchub = hubp2_update_dchub, + .mem_program_viewport = min_set_viewport, + .set_cursor_attributes = hubp2_cursor_set_attributes, +- .set_cursor_position = hubp1_cursor_set_position, +- .hubp_clk_cntl = hubp1_clk_cntl, +- .hubp_vtg_sel = hubp1_vtg_sel, ++ .set_cursor_position = hubp2_cursor_set_position, ++ .hubp_clk_cntl = hubp2_clk_cntl, ++ .hubp_vtg_sel = hubp2_vtg_sel, + .dmdata_set_attributes = hubp2_dmdata_set_attributes, + .dmdata_load = hubp2_dmdata_load, + .dmdata_status_done = hubp2_dmdata_status_done, +- .hubp_read_state = hubp1_read_state, +- .hubp_clear_underflow = hubp1_clear_underflow, ++ .hubp_read_state = hubp2_read_state, ++ .hubp_clear_underflow = hubp2_clear_underflow, + .hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl, + .hubp_init = hubp1_init, + }; +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h +index 2c6405a62fc1..c8418235e154 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h +@@ -267,6 +267,24 @@ bool hubp2_program_surface_flip_and_addr( + const struct dc_plane_address *address, + bool flip_immediate); + ++void hubp2_dcc_control(struct hubp *hubp, bool enable, ++ bool independent_64b_blks); ++ ++void hubp2_program_size( ++ struct hubp *hubp, ++ enum surface_pixel_format format, ++ const union plane_size *plane_size, ++ struct dc_plane_dcc_param *dcc); ++ ++void hubp2_program_rotation( ++ struct hubp *hubp, ++ enum dc_rotation_angle rotation, ++ bool horizontal_mirror); ++ ++void hubp2_program_pixel_format( ++ struct hubp *hubp, ++ enum surface_pixel_format format); ++ + void hubp2_program_surface_config( + struct hubp *hubp, + enum surface_pixel_format format, +@@ -277,6 +295,25 @@ void hubp2_program_surface_config( + bool horizontal_mirror, + unsigned int compat_level); + ++bool hubp2_is_flip_pending(struct hubp *hubp); ++ ++void hubp2_set_blank(struct hubp *hubp, bool blank); ++ ++void hubp2_cursor_set_position( ++ struct hubp *hubp, ++ const struct dc_cursor_position *pos, ++ const struct dc_cursor_mi_param *param); ++ ++void hubp2_clk_cntl(struct hubp *hubp, bool enable); ++ ++void hubp2_vtg_sel(struct hubp *hubp, uint32_t otg_inst); ++ ++void hubp2_clear_underflow(struct hubp *hubp); ++ ++void hubp2_read_state_common(struct hubp *hubp); ++ ++void hubp2_read_state(struct hubp *hubp); ++ + #endif /* __DC_MEM_INPUT_DCN20_H__ */ + + +-- +2.17.1 + |