diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | 59 |
1 files changed, 40 insertions, 19 deletions
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 c28085be39ff..2138cd3c5d1d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c @@ -152,21 +152,19 @@ void hubp1_program_tiling( PIPE_ALIGNED, info->gfx9.pipe_aligned); } -void hubp1_program_size_and_rotation( +void hubp1_program_size( struct hubp *hubp, - enum dc_rotation_angle rotation, enum surface_pixel_format format, const union plane_size *plane_size, - struct dc_plane_dcc_param *dcc, - bool horizontal_mirror) + struct dc_plane_dcc_param *dcc) { struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); - uint32_t pitch, meta_pitch, pitch_c, meta_pitch_c, mirror; + 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) { + 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! */ @@ -192,13 +190,22 @@ void hubp1_program_size_and_rotation( 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 hubp1_program_rotation( + struct hubp *hubp, + enum dc_rotation_angle rotation, + bool horizontal_mirror) +{ + struct dcn10_hubp *hubp1 = TO_DCN10_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, @@ -287,6 +294,10 @@ void hubp1_program_pixel_format( 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; default: BREAK_TO_DEBUGGER(); break; @@ -450,9 +461,6 @@ bool hubp1_program_surface_flip_and_addr( hubp->request_address = *address; - if (flip_immediate) - hubp->current_address = *address; - return true; } @@ -481,8 +489,8 @@ void hubp1_program_surface_config( { hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks); hubp1_program_tiling(hubp, tiling_info, format); - hubp1_program_size_and_rotation( - hubp, rotation, format, plane_size, dcc, horizontal_mirror); + hubp1_program_size(hubp, format, plane_size, dcc); + hubp1_program_rotation(hubp, rotation, horizontal_mirror); hubp1_program_pixel_format(hubp, format); } @@ -688,7 +696,6 @@ bool hubp1_is_flip_pending(struct hubp *hubp) if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part) return true; - hubp->current_address = hubp->request_address; return false; } @@ -1061,9 +1068,11 @@ void hubp1_cursor_set_position( const struct dc_cursor_mi_param *param) { struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); - int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start; + int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; + 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; - uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; /* * Guard aganst cursor_set_position() from being called with invalid @@ -1075,6 +1084,18 @@ void hubp1_cursor_set_position( 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; @@ -1085,7 +1106,7 @@ void hubp1_cursor_set_position( dc_fixpt_from_int(dst_x_offset), param->h_scale_ratio)); - if (src_x_offset >= (int)param->viewport_width) + 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) @@ -1102,8 +1123,8 @@ void hubp1_cursor_set_position( CURSOR_Y_POSITION, pos->y); REG_SET_2(CURSOR_HOT_SPOT, 0, - CURSOR_HOT_SPOT_X, pos->x_hotspot, - CURSOR_HOT_SPOT_Y, pos->y_hotspot); + 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); @@ -1125,7 +1146,7 @@ void hubp1_vtg_sel(struct hubp *hubp, uint32_t otg_inst) REG_UPDATE(DCHUBP_CNTL, HUBP_VTG_SEL, otg_inst); } -static struct hubp_funcs dcn10_hubp_funcs = { +static const struct hubp_funcs dcn10_hubp_funcs = { .hubp_program_surface_flip_and_addr = hubp1_program_surface_flip_and_addr, .hubp_program_surface_config = |