diff options
author | Dave Airlie <airlied@redhat.com> | 2020-05-08 06:31:06 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2020-05-08 06:31:08 +0300 |
commit | 370fb6b0aaf07c66a3317d5b35fba4345b31035c (patch) | |
tree | b68550f0d7b340440dc4048ed007b59ffa563e60 /drivers/gpu/drm/amd/display | |
parent | 937eea297e26effac6809a0bf8c20e6ca9d90b9a (diff) | |
parent | b8020b0304c8f44e5e29f0b1a04d31e0bf68d26a (diff) | |
download | linux-370fb6b0aaf07c66a3317d5b35fba4345b31035c.tar.xz |
Merge tag 'amd-drm-next-5.8-2020-04-30' of git://people.freedesktop.org/~agd5f/linux into drm-next
amd-drm-next-5.8-2020-04-30:
amdgpu:
- SR-IOV fixes
- SDMA fix for Navi
- VCN 2.5 DPG fixes
- Display fixes
- Display stuttering fixes for pageflip and cursor
- Add support for handling encrypted GPU memory
- Add UAPI for encrypted GPU memory
- Rework IB pool handling
amdkfd:
- Expose asic revision in topology
- Add UAPI for GWS (Global Wave Sync) resource management
UAPI:
- Add amdgpu UAPI for encrypted GPU memory
Used by: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4401
- Add amdkfd UAPI for GWS (Global Wave Sync) resource management
Thunk usage of KFD ioctl: https://github.com/RadeonOpenCompute/ROCT-Thunk-Interface/blob/roc-2.8.0/src/queues.c#L840
ROCr usage of Thunk API: https://github.com/RadeonOpenCompute/ROCR-Runtime/blob/roc-3.1.0/src/core/runtime/amd_gpu_agent.cpp#L597
HCC code using ROCr API: https://github.com/RadeonOpenCompute/hcc/blob/98ee9f34945d3b5f572d7a4c15cbffa506487734/lib/hsa/mcwamp_hsa.cpp#L2161
HIP code using HCC API: https://github.com/ROCm-Developer-Tools/HIP/blob/cf8589b8c8a40ddcc55fa3a51e23390a49824130/src/hip_module.cpp#L567
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200430212951.3902-1-alexander.deucher@amd.com
Diffstat (limited to 'drivers/gpu/drm/amd/display')
47 files changed, 550 insertions, 239 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 4c8b1bc98913..71309ee3aca3 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3309,7 +3309,7 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state, } static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb, - uint64_t *tiling_flags) + uint64_t *tiling_flags, bool *tmz_surface) { struct amdgpu_bo *rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]); int r = amdgpu_bo_reserve(rbo, false); @@ -3324,6 +3324,9 @@ static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb, if (tiling_flags) amdgpu_bo_get_tiling_flags(rbo, tiling_flags); + if (tmz_surface) + *tmz_surface = amdgpu_bo_encrypted(rbo); + amdgpu_bo_unreserve(rbo); return r; @@ -3411,6 +3414,7 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, struct plane_size *plane_size, struct dc_plane_dcc_param *dcc, struct dc_plane_address *address, + bool tmz_surface, bool force_disable_dcc) { const struct drm_framebuffer *fb = &afb->base; @@ -3421,6 +3425,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, memset(dcc, 0, sizeof(*dcc)); memset(address, 0, sizeof(*address)); + address->tmz_surface = tmz_surface; + if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { plane_size->surface_size.x = 0; plane_size->surface_size.y = 0; @@ -3611,6 +3617,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, const uint64_t tiling_flags, struct dc_plane_info *plane_info, struct dc_plane_address *address, + bool tmz_surface, bool force_disable_dcc) { const struct drm_framebuffer *fb = plane_state->fb; @@ -3693,7 +3700,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, plane_info->rotation, tiling_flags, &plane_info->tiling_info, &plane_info->plane_size, - &plane_info->dcc, address, + &plane_info->dcc, address, tmz_surface, force_disable_dcc); if (ret) return ret; @@ -3717,6 +3724,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, struct dc_plane_info plane_info; uint64_t tiling_flags; int ret; + bool tmz_surface = false; bool force_disable_dcc = false; ret = fill_dc_scaling_info(plane_state, &scaling_info); @@ -3728,7 +3736,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, dc_plane_state->clip_rect = scaling_info.clip_rect; dc_plane_state->scaling_quality = scaling_info.scaling_quality; - ret = get_fb_info(amdgpu_fb, &tiling_flags); + ret = get_fb_info(amdgpu_fb, &tiling_flags, &tmz_surface); if (ret) return ret; @@ -3736,6 +3744,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags, &plane_info, &dc_plane_state->address, + tmz_surface, force_disable_dcc); if (ret) return ret; @@ -5354,6 +5363,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, uint64_t tiling_flags; uint32_t domain; int r; + bool tmz_surface = false; bool force_disable_dcc = false; dm_plane_state_old = to_dm_plane_state(plane->state); @@ -5403,6 +5413,8 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, amdgpu_bo_get_tiling_flags(rbo, &tiling_flags); + tmz_surface = amdgpu_bo_encrypted(rbo); + ttm_eu_backoff_reservation(&ticket, &list); afb->address = amdgpu_bo_gpu_offset(rbo); @@ -5418,7 +5430,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, adev, afb, plane_state->format, plane_state->rotation, tiling_flags, &plane_state->tiling_info, &plane_state->plane_size, &plane_state->dcc, - &plane_state->address, + &plane_state->address, tmz_surface, force_disable_dcc); } @@ -6592,6 +6604,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, unsigned long flags; struct amdgpu_bo *abo; uint64_t tiling_flags; + bool tmz_surface = false; uint32_t target_vblank, last_flip_vblank; bool vrr_active = amdgpu_dm_vrr_active(acrtc_state); bool pflip_present = false; @@ -6687,12 +6700,15 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, amdgpu_bo_get_tiling_flags(abo, &tiling_flags); + tmz_surface = amdgpu_bo_encrypted(abo); + amdgpu_bo_unreserve(abo); fill_dc_plane_info_and_addr( dm->adev, new_plane_state, tiling_flags, &bundle->plane_infos[planes_count], &bundle->flip_addrs[planes_count].address, + tmz_surface, false); DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n", @@ -8065,6 +8081,7 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, struct dc_flip_addrs *flip_addr = &bundle->flip_addrs[num_plane]; struct dc_scaling_info *scaling_info = &bundle->scaling_infos[num_plane]; uint64_t tiling_flags; + bool tmz_surface = false; new_plane_crtc = new_plane_state->crtc; new_dm_plane_state = to_dm_plane_state(new_plane_state); @@ -8112,14 +8129,14 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, bundle->surface_updates[num_plane].scaling_info = scaling_info; if (amdgpu_fb) { - ret = get_fb_info(amdgpu_fb, &tiling_flags); + ret = get_fb_info(amdgpu_fb, &tiling_flags, &tmz_surface); if (ret) goto cleanup; ret = fill_dc_plane_info_and_addr( dm->adev, new_plane_state, tiling_flags, plane_info, - &flip_addr->address, + &flip_addr->address, tmz_surface, false); if (ret) goto cleanup; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c index 838f35668f12..4dfb6b55bb2e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c @@ -239,7 +239,8 @@ static int __set_output_tf(struct dc_transfer_func *func, * instead to simulate this. */ gamma->type = GAMMA_CUSTOM; - res = mod_color_calculate_degamma_params(func, gamma, true); + res = mod_color_calculate_degamma_params(NULL, func, + gamma, true); } else { /* * Assume sRGB. The actual mapping will depend on whether the @@ -271,7 +272,7 @@ static int __set_input_tf(struct dc_transfer_func *func, __drm_lut_to_dc_gamma(lut, gamma, false); - res = mod_color_calculate_degamma_params(func, gamma, true); + res = mod_color_calculate_degamma_params(NULL, func, gamma, true); dc_gamma_release(&gamma); return res ? 0 : -ENOMEM; @@ -485,7 +486,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, dc_plane_state->in_transfer_func->tf = tf; if (tf != TRANSFER_FUNCTION_SRGB && - !mod_color_calculate_degamma_params( + !mod_color_calculate_degamma_params(NULL, dc_plane_state->in_transfer_func, NULL, false)) return -ENOMEM; } else { diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c index 8edc2506d49e..bed91572f82a 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c @@ -113,13 +113,19 @@ static void encoder_control_dmcub( struct dc_dmub_srv *dmcub, struct dig_encoder_stream_setup_parameters_v1_5 *dig) { - struct dmub_rb_cmd_digx_encoder_control encoder_control = { 0 }; + union dmub_rb_cmd cmd; - encoder_control.header.type = DMUB_CMD__VBIOS; - encoder_control.header.sub_type = DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL; - encoder_control.encoder_control.dig.stream_param = *dig; + memset(&cmd, 0, sizeof(cmd)); - dc_dmub_srv_cmd_queue(dmcub, &encoder_control.header); + cmd.digx_encoder_control.header.type = DMUB_CMD__VBIOS; + cmd.digx_encoder_control.header.sub_type = + DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL; + cmd.digx_encoder_control.header.payload_bytes = + sizeof(cmd.digx_encoder_control) - + sizeof(cmd.digx_encoder_control.header); + cmd.digx_encoder_control.encoder_control.dig.stream_param = *dig; + + dc_dmub_srv_cmd_queue(dmcub, &cmd); dc_dmub_srv_cmd_execute(dmcub); dc_dmub_srv_wait_idle(dmcub); } @@ -238,14 +244,19 @@ static void transmitter_control_dmcub( struct dc_dmub_srv *dmcub, struct dig_transmitter_control_parameters_v1_6 *dig) { - struct dmub_rb_cmd_dig1_transmitter_control transmitter_control; + union dmub_rb_cmd cmd; + + memset(&cmd, 0, sizeof(cmd)); - transmitter_control.header.type = DMUB_CMD__VBIOS; - transmitter_control.header.sub_type = + cmd.dig1_transmitter_control.header.type = DMUB_CMD__VBIOS; + cmd.dig1_transmitter_control.header.sub_type = DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL; - transmitter_control.transmitter_control.dig = *dig; + cmd.dig1_transmitter_control.header.payload_bytes = + sizeof(cmd.dig1_transmitter_control) - + sizeof(cmd.dig1_transmitter_control.header); + cmd.dig1_transmitter_control.transmitter_control.dig = *dig; - dc_dmub_srv_cmd_queue(dmcub, &transmitter_control.header); + dc_dmub_srv_cmd_queue(dmcub, &cmd); dc_dmub_srv_cmd_execute(dmcub); dc_dmub_srv_wait_idle(dmcub); } @@ -339,13 +350,18 @@ static void set_pixel_clock_dmcub( struct dc_dmub_srv *dmcub, struct set_pixel_clock_parameter_v1_7 *clk) { - struct dmub_rb_cmd_set_pixel_clock pixel_clock = { 0 }; + union dmub_rb_cmd cmd; - pixel_clock.header.type = DMUB_CMD__VBIOS; - pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK; - pixel_clock.pixel_clock.clk = *clk; + memset(&cmd, 0, sizeof(cmd)); - dc_dmub_srv_cmd_queue(dmcub, &pixel_clock.header); + cmd.set_pixel_clock.header.type = DMUB_CMD__VBIOS; + cmd.set_pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK; + cmd.set_pixel_clock.header.payload_bytes = + sizeof(cmd.set_pixel_clock) - + sizeof(cmd.set_pixel_clock.header); + cmd.set_pixel_clock.pixel_clock.clk = *clk; + + dc_dmub_srv_cmd_queue(dmcub, &cmd); dc_dmub_srv_cmd_execute(dmcub); dc_dmub_srv_wait_idle(dmcub); } @@ -705,13 +721,19 @@ static void enable_disp_power_gating_dmcub( struct dc_dmub_srv *dmcub, struct enable_disp_power_gating_parameters_v2_1 *pwr) { - struct dmub_rb_cmd_enable_disp_power_gating power_gating; + union dmub_rb_cmd cmd; + + memset(&cmd, 0, sizeof(cmd)); - power_gating.header.type = DMUB_CMD__VBIOS; - power_gating.header.sub_type = DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING; - power_gating.power_gating.pwr = *pwr; + cmd.enable_disp_power_gating.header.type = DMUB_CMD__VBIOS; + cmd.enable_disp_power_gating.header.sub_type = + DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING; + cmd.enable_disp_power_gating.header.payload_bytes = + sizeof(cmd.enable_disp_power_gating) - + sizeof(cmd.enable_disp_power_gating.header); + cmd.enable_disp_power_gating.power_gating.pwr = *pwr; - dc_dmub_srv_cmd_queue(dmcub, &power_gating.header); + dc_dmub_srv_cmd_queue(dmcub, &cmd); dc_dmub_srv_cmd_execute(dmcub); dc_dmub_srv_wait_idle(dmcub); } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 0f7810571be3..ad817bd74586 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2210,7 +2210,9 @@ static void commit_planes_do_stream_update(struct dc *dc, if (should_program_abm) { if (*stream_update->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE) { - pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm); + pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable( + pipe_ctx->stream_res.abm, + pipe_ctx->stream->link->panel_cntl->inst); } else { pipe_ctx->stream_res.abm->funcs->set_abm_level( pipe_ctx->stream_res.abm, stream->abm_level); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 9c4686edcf3e..67c5342cf89a 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2509,35 +2509,21 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t frame_ramp) { struct dc *dc = link->ctx->dc; - struct abm *abm = get_abm_from_stream_res(link); - struct dmcu *dmcu = dc->res_pool->dmcu; - unsigned int controller_id = 0; - bool fw_set_brightness = true; int i; - DC_LOGGER_INIT(link->ctx->logger); - - if (abm == NULL || (abm->funcs->set_backlight_level_pwm == NULL)) - return false; - - if (dmcu) - fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu); + DC_LOGGER_INIT(link->ctx->logger); DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", backlight_pwm_u16_16, backlight_pwm_u16_16); if (dc_is_embedded_signal(link->connector_signal)) { + struct pipe_ctx *pipe_ctx = NULL; + for (i = 0; i < MAX_PIPES; i++) { if (dc->current_state->res_ctx.pipe_ctx[i].stream) { if (dc->current_state->res_ctx. pipe_ctx[i].stream->link == link) { - /* DMCU -1 for all controller id values, - * therefore +1 here - */ - controller_id = - dc->current_state-> - res_ctx.pipe_ctx[i].stream_res.tg->inst + - 1; + pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; /* Disable brightness ramping when the display is blanked * as it can hang the DMCU @@ -2547,12 +2533,14 @@ bool dc_link_set_backlight_level(const struct dc_link *link, } } } - abm->funcs->set_backlight_level_pwm( - abm, + + if (pipe_ctx == NULL) + ASSERT(false); + + dc->hwss.set_backlight_level( + pipe_ctx, backlight_pwm_u16_16, - frame_ramp, - controller_id, - fw_set_brightness); + frame_ramp); } return true; @@ -2564,7 +2552,7 @@ bool dc_link_set_abm_disable(const struct dc_link *link) bool success = false; if (abm) - success = abm->funcs->set_abm_immediate_disable(abm); + success = abm->funcs->set_abm_immediate_disable(abm, link->panel_cntl->inst); return success; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c index 256889eed93e..aefd29a440b5 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c @@ -599,7 +599,7 @@ bool dal_ddc_submit_aux_command(struct ddc_service *ddc, do { struct aux_payload current_payload; bool is_end_of_payload = (retrieved + DEFAULT_AUX_MAX_DATA_SIZE) > - payload->length ? true : false; + payload->length; current_payload.address = payload->address; current_payload.data = &payload->data[retrieved]; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index d5b306384d79..9ef9e50a34fa 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -4231,7 +4231,7 @@ void dpcd_set_source_specific_data(struct dc_link *link) { const uint32_t post_oui_delay = 30; // 30ms uint8_t dspc = 0; - enum dc_status ret = DC_ERROR_UNEXPECTED; + enum dc_status ret; ret = core_link_read_dpcd(link, DP_DOWN_STREAM_PORT_COUNT, &dspc, sizeof(dspc)); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 12f5c6881cd0..1a01c038632b 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1064,8 +1064,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) calculate_viewport(pipe_ctx); - if (pipe_ctx->plane_res.scl_data.viewport.height < 16 || - pipe_ctx->plane_res.scl_data.viewport.width < 16) { + if (pipe_ctx->plane_res.scl_data.viewport.height < 12 || + pipe_ctx->plane_res.scl_data.viewport.width < 12) { if (store_h_border_left) { restore_border_left_from_dst(pipe_ctx, store_h_border_left); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 6ddbb00ed37a..4f0e7203dba4 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -231,34 +231,6 @@ struct dc_stream_status *dc_stream_get_status( return dc_stream_get_status_from_state(dc->current_state, stream); } -static void delay_cursor_until_vupdate(struct pipe_ctx *pipe_ctx, struct dc *dc) -{ -#if defined(CONFIG_DRM_AMD_DC_DCN) - unsigned int vupdate_line; - unsigned int lines_to_vupdate, us_to_vupdate, vpos, nvpos; - struct dc_stream_state *stream = pipe_ctx->stream; - unsigned int us_per_line; - - if (stream->ctx->asic_id.chip_family == FAMILY_RV && - ASICREV_IS_RAVEN(stream->ctx->asic_id.hw_internal_rev)) { - - vupdate_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx); - if (!dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos)) - return; - - if (vpos >= vupdate_line) - return; - - us_per_line = stream->timing.h_total * 10000 / stream->timing.pix_clk_100hz; - lines_to_vupdate = vupdate_line - vpos; - us_to_vupdate = lines_to_vupdate * us_per_line; - - /* 70 us is a conservative estimate of cursor update time*/ - if (us_to_vupdate < 70) - udelay(us_to_vupdate); - } -#endif -} /** * dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address @@ -298,9 +270,7 @@ bool dc_stream_set_cursor_attributes( if (!pipe_to_program) { pipe_to_program = pipe_ctx; - - delay_cursor_until_vupdate(pipe_ctx, dc); - dc->hwss.pipe_control_lock(dc, pipe_to_program, true); + dc->hwss.cursor_lock(dc, pipe_to_program, true); } dc->hwss.set_cursor_attribute(pipe_ctx); @@ -309,7 +279,7 @@ bool dc_stream_set_cursor_attributes( } if (pipe_to_program) - dc->hwss.pipe_control_lock(dc, pipe_to_program, false); + dc->hwss.cursor_lock(dc, pipe_to_program, false); return true; } @@ -349,16 +319,14 @@ bool dc_stream_set_cursor_position( if (!pipe_to_program) { pipe_to_program = pipe_ctx; - - delay_cursor_until_vupdate(pipe_ctx, dc); - dc->hwss.pipe_control_lock(dc, pipe_to_program, true); + dc->hwss.cursor_lock(dc, pipe_to_program, true); } dc->hwss.set_cursor_position(pipe_ctx); } if (pipe_to_program) - dc->hwss.pipe_control_lock(dc, pipe_to_program, false); + dc->hwss.cursor_lock(dc, pipe_to_program, false); return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 5432ca1657b1..17075f99bc54 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -42,7 +42,7 @@ #include "inc/hw/dmcu.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.2.81" +#define DC_VER "3.2.83.1" #define MAX_SURFACES 3 #define MAX_PLANES 6 @@ -98,6 +98,49 @@ struct dc_plane_cap { } max_downscale_factor; }; +// Color management caps (DPP and MPC) +struct rom_curve_caps { + uint16_t srgb : 1; + uint16_t bt2020 : 1; + uint16_t gamma2_2 : 1; + uint16_t pq : 1; + uint16_t hlg : 1; +}; + +struct dpp_color_caps { + uint16_t dcn_arch : 1; // all DCE generations treated the same + // input lut is different than most LUTs, just plain 256-entry lookup + uint16_t input_lut_shared : 1; // shared with DGAM + uint16_t icsc : 1; + uint16_t dgam_ram : 1; + uint16_t post_csc : 1; // before gamut remap + uint16_t gamma_corr : 1; + + // hdr_mult and gamut remap always available in DPP (in that order) + // 3d lut implies shaper LUT, + // it may be shared with MPC - check MPC:shared_3d_lut flag + uint16_t hw_3d_lut : 1; + uint16_t ogam_ram : 1; // blnd gam + uint16_t ocsc : 1; + struct rom_curve_caps dgam_rom_caps; + struct rom_curve_caps ogam_rom_caps; +}; + +struct mpc_color_caps { + uint16_t gamut_remap : 1; + uint16_t ogam_ram : 1; + uint16_t ocsc : 1; + uint16_t num_3dluts : 3; //3d lut always assumes a preceding shaper LUT + uint16_t shared_3d_lut:1; //can be in either DPP or MPC, but single instance + + struct rom_curve_caps ogam_rom_caps; +}; + +struct dc_color_caps { + struct dpp_color_caps dpp; + struct mpc_color_caps mpc; +}; + struct dc_caps { uint32_t max_streams; uint32_t max_links; @@ -120,9 +163,9 @@ struct dc_caps { bool psp_setup_panel_mode; bool extended_aux_timeout_support; bool dmcub_support; - bool hw_3d_lut; enum dp_protocol_version max_dp_protocol_version; struct dc_plane_cap planes[MAX_PLANES]; + struct dc_color_caps color; }; struct dc_bug_wa { @@ -478,6 +521,7 @@ struct dc_bounding_box_overrides { int urgent_latency_ns; int percent_of_ideal_drambw; int dram_clock_change_latency_ns; + int dummy_clock_change_latency_ns; /* This forces a hard min on the DCFCLK we use * for DML. Unlike the debug option for forcing * DCFCLK, this override affects watermark calculations diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 59c298a6484f..907e0c5374bb 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -58,7 +58,7 @@ void dc_dmub_srv_destroy(struct dc_dmub_srv **dmub_srv) } void dc_dmub_srv_cmd_queue(struct dc_dmub_srv *dc_dmub_srv, - struct dmub_cmd_header *cmd) + union dmub_rb_cmd *cmd) { struct dmub_srv *dmub = dc_dmub_srv->dmub; struct dc_context *dc_ctx = dc_dmub_srv->ctx; diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h index 754b6077539c..6689ae33dee8 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h @@ -27,10 +27,9 @@ #define _DMUB_DC_SRV_H_ #include "os_types.h" -#include "../dmub/inc/dmub_cmd.h" +#include "dmub/inc/dmub_cmd.h" struct dmub_srv; -struct dmub_cmd_header; struct dc_reg_helper_state { bool gather_in_progress; @@ -49,7 +48,7 @@ struct dc_dmub_srv { }; void dc_dmub_srv_cmd_queue(struct dc_dmub_srv *dc_dmub_srv, - struct dmub_cmd_header *cmd); + union dmub_rb_cmd *cmd); void dc_dmub_srv_cmd_execute(struct dc_dmub_srv *dc_dmub_srv); diff --git a/drivers/gpu/drm/amd/display/dc/dc_helper.c b/drivers/gpu/drm/amd/display/dc/dc_helper.c index 737048d8a96c..85a0170be544 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dc_helper.c @@ -50,7 +50,7 @@ static inline void submit_dmub_read_modify_write( gather = ctx->dmub_srv->reg_helper_offload.gather_in_progress; ctx->dmub_srv->reg_helper_offload.gather_in_progress = false; - dc_dmub_srv_cmd_queue(ctx->dmub_srv, &cmd_buf->header); + dc_dmub_srv_cmd_queue(ctx->dmub_srv, &offload->cmd_data); ctx->dmub_srv->reg_helper_offload.gather_in_progress = gather; @@ -73,7 +73,7 @@ static inline void submit_dmub_burst_write( gather = ctx->dmub_srv->reg_helper_offload.gather_in_progress; ctx->dmub_srv->reg_helper_offload.gather_in_progress = false; - dc_dmub_srv_cmd_queue(ctx->dmub_srv, &cmd_buf->header); + dc_dmub_srv_cmd_queue(ctx->dmub_srv, &offload->cmd_data); ctx->dmub_srv->reg_helper_offload.gather_in_progress = gather; @@ -92,7 +92,7 @@ static inline void submit_dmub_reg_wait( gather = ctx->dmub_srv->reg_helper_offload.gather_in_progress; ctx->dmub_srv->reg_helper_offload.gather_in_progress = false; - dc_dmub_srv_cmd_queue(ctx->dmub_srv, &cmd_buf->header); + dc_dmub_srv_cmd_queue(ctx->dmub_srv, &offload->cmd_data); memset(cmd_buf, 0, sizeof(*cmd_buf)); offload->reg_seq_count = 0; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c index 4dae9efebb6f..c15e60fb5ebc 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c @@ -55,7 +55,7 @@ #define MCP_DISABLE_ABM_IMMEDIATELY 255 -static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id) +static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id, uint32_t panel_inst) { struct dce_abm *abm_dce = TO_DCE_ABM(abm); uint32_t rampingBoundary = 0xFFFF; @@ -201,7 +201,8 @@ static void dmcu_set_backlight_level( struct dce_abm *abm_dce, uint32_t backlight_pwm_u16_16, uint32_t frame_ramp, - uint32_t controller_id) + uint32_t controller_id, + uint32_t panel_id) { unsigned int backlight_8_bit = 0; uint32_t s2; @@ -213,7 +214,7 @@ static void dmcu_set_backlight_level( // Take MSB of fractional part since backlight is not max backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF; - dce_abm_set_pipe(&abm_dce->base, controller_id); + dce_abm_set_pipe(&abm_dce->base, controller_id, panel_id); /* waitDMCUReadyForCmd */ REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, @@ -331,14 +332,14 @@ static bool dce_abm_set_level(struct abm *abm, uint32_t level) return true; } -static bool dce_abm_immediate_disable(struct abm *abm) +static bool dce_abm_immediate_disable(struct abm *abm, uint32_t panel_inst) { struct dce_abm *abm_dce = TO_DCE_ABM(abm); if (abm->dmcu_is_running == false) return true; - dce_abm_set_pipe(abm, MCP_DISABLE_ABM_IMMEDIATELY); + dce_abm_set_pipe(abm, MCP_DISABLE_ABM_IMMEDIATELY, panel_inst); abm->stored_backlight_registers.BL_PWM_CNTL = REG_READ(BL_PWM_CNTL); @@ -420,6 +421,7 @@ static bool dce_abm_set_backlight_level_pwm( unsigned int backlight_pwm_u16_16, unsigned int frame_ramp, unsigned int controller_id, + unsigned int panel_inst, bool fw_set_brightness) { struct dce_abm *abm_dce = TO_DCE_ABM(abm); @@ -432,7 +434,8 @@ static bool dce_abm_set_backlight_level_pwm( dmcu_set_backlight_level(abm_dce, backlight_pwm_u16_16, frame_ramp, - controller_id); + controller_id, + panel_inst); else driver_set_backlight_level(abm_dce, backlight_pwm_u16_16); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c index a19f359e45d7..06d39d529c09 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c @@ -27,7 +27,7 @@ #include "dce_abm.h" #include "dc.h" #include "dc_dmub_srv.h" -#include "../../dmub/inc/dmub_srv.h" +#include "dmub/inc/dmub_srv.h" #include "core_types.h" #include "dm_services.h" #include "reg_helper.h" @@ -50,7 +50,7 @@ #define DISABLE_ABM_IMMEDIATELY 255 -static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst) +static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t panel_inst) { union dmub_rb_cmd cmd; struct dc_context *dc = abm->ctx; @@ -59,10 +59,11 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst) cmd.abm_set_pipe.header.type = DMUB_CMD__ABM; cmd.abm_set_pipe.header.sub_type = DMUB_CMD__ABM_SET_PIPE; cmd.abm_set_pipe.abm_set_pipe_data.otg_inst = otg_inst; + cmd.abm_set_pipe.abm_set_pipe_data.panel_inst = panel_inst; cmd.abm_set_pipe.abm_set_pipe_data.ramping_boundary = ramping_boundary; cmd.abm_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pipe_data); - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_set_pipe.header); + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); dc_dmub_srv_cmd_execute(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv); @@ -120,7 +121,8 @@ static void dmcub_set_backlight_level( struct dce_abm *dce_abm, uint32_t backlight_pwm_u16_16, uint32_t frame_ramp, - uint32_t otg_inst) + uint32_t otg_inst, + uint32_t panel_inst) { union dmub_rb_cmd cmd; struct dc_context *dc = dce_abm->base.ctx; @@ -134,7 +136,7 @@ static void dmcub_set_backlight_level( // Take MSB of fractional part since backlight is not max backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF; - dmub_abm_set_pipe(&dce_abm->base, otg_inst); + dmub_abm_set_pipe(&dce_abm->base, otg_inst, panel_inst); REG_UPDATE(BL1_PWM_USER_LEVEL, BL1_PWM_USER_LEVEL, backlight_pwm_u16_16); @@ -146,7 +148,7 @@ static void dmcub_set_backlight_level( cmd.abm_set_backlight.abm_set_backlight_data.frame_ramp = frame_ramp; cmd.abm_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_backlight_data); - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_set_backlight.header); + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); dc_dmub_srv_cmd_execute(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv); @@ -171,7 +173,7 @@ static void dmub_abm_enable_fractional_pwm(struct dc_context *dc) cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.fractional_pwm = fractional_pwm; cmd.abm_set_pwm_frac.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pwm_frac_data); - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_set_pwm_frac.header); + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); dc_dmub_srv_cmd_execute(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv); } @@ -250,18 +252,18 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level) cmd.abm_set_level.abm_set_level_data.level = level; cmd.abm_set_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_level_data); - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_set_level.header); + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); dc_dmub_srv_cmd_execute(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv); return true; } -static bool dmub_abm_immediate_disable(struct abm *abm) +static bool dmub_abm_immediate_disable(struct abm *abm, uint32_t panel_inst) { struct dce_abm *dce_abm = TO_DMUB_ABM(abm); - dmub_abm_set_pipe(abm, DISABLE_ABM_IMMEDIATELY); + dmub_abm_set_pipe(abm, DISABLE_ABM_IMMEDIATELY, panel_inst); abm->stored_backlight_registers.BL_PWM_CNTL = REG_READ(BL_PWM_CNTL); @@ -338,6 +340,7 @@ static bool dmub_abm_set_backlight_level_pwm( unsigned int backlight_pwm_u16_16, unsigned int frame_ramp, unsigned int otg_inst, + uint32_t panel_inst, bool fw_set_brightness) { struct dce_abm *dce_abm = TO_DMUB_ABM(abm); @@ -345,7 +348,8 @@ static bool dmub_abm_set_backlight_level_pwm( dmcub_set_backlight_level(dce_abm, backlight_pwm_u16_16, frame_ramp, - otg_inst); + otg_inst, + panel_inst); return true; } @@ -370,7 +374,7 @@ static bool dmub_abm_init_config(struct abm *abm, cmd.abm_init_config.abm_init_config_data.bytes = bytes; cmd.abm_init_config.header.payload_bytes = sizeof(struct dmub_cmd_abm_init_config_data); - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_init_config.header); + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); dc_dmub_srv_cmd_execute(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 3b8a49e8e665..9f12c76f21ab 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -26,8 +26,8 @@ #include "dmub_psr.h" #include "dc.h" #include "dc_dmub_srv.h" -#include "../../dmub/inc/dmub_srv.h" -#include "../../dmub/inc/dmub_gpint_cmd.h" +#include "dmub/inc/dmub_srv.h" +#include "dmub/inc/dmub_gpint_cmd.h" #include "core_types.h" #define MAX_PIPES 6 @@ -102,7 +102,7 @@ static bool dmub_psr_set_version(struct dmub_psr *dmub, struct dc_stream_state * cmd.psr_set_version.psr_set_version_data.version = stream->link->psr_settings.psr_version; cmd.psr_set_version.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_version_data); - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.psr_set_version.header); + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); dc_dmub_srv_cmd_execute(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv); @@ -126,7 +126,7 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable) cmd.psr_enable.header.payload_bytes = 0; // Send header only - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.psr_enable.header); + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); dc_dmub_srv_cmd_execute(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv); } @@ -150,7 +150,7 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level) cmd.psr_set_level.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_level_data); cmd.psr_set_level.psr_set_level_data.psr_level = psr_level; - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.psr_set_level.header); + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); dc_dmub_srv_cmd_execute(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv); } @@ -227,7 +227,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub, copy_settings_data->debug.visual_confirm = dc->dc->debug.visual_confirm == VISUAL_CONFIRM_PSR ? true : false; - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.psr_copy_settings.header); + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); dc_dmub_srv_cmd_execute(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv); diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 9cd130c8894a..6bd8d4e1c294 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -2714,6 +2714,37 @@ void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) pipe_ctx->plane_res.xfm, attributes); } +bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx, + uint32_t backlight_pwm_u16_16, + uint32_t frame_ramp) +{ + struct dc_link *link = pipe_ctx->stream->link; + struct dc *dc = link->ctx->dc; + struct abm *abm = pipe_ctx->stream_res.abm; + struct dmcu *dmcu = dc->res_pool->dmcu; + bool fw_set_brightness = true; + /* DMCU -1 for all controller id values, + * therefore +1 here + */ + uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1; + + if (abm == NULL || (abm->funcs->set_backlight_level_pwm == NULL)) + return false; + + if (dmcu) + fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu); + + abm->funcs->set_backlight_level_pwm( + abm, + backlight_pwm_u16_16, + frame_ramp, + controller_id, + link->panel_cntl->inst, + fw_set_brightness); + + return true; +} + static const struct hw_sequencer_funcs dce110_funcs = { .program_gamut_remap = program_gamut_remap, .program_output_csc = program_output_csc, @@ -2736,6 +2767,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { .disable_plane = dce110_power_down_fe, .pipe_control_lock = dce_pipe_control_lock, .interdependent_update_lock = NULL, + .cursor_lock = dce_pipe_control_lock, .prepare_bandwidth = dce110_prepare_bandwidth, .optimize_bandwidth = dce110_optimize_bandwidth, .set_drr = set_drr, @@ -2747,7 +2779,8 @@ static const struct hw_sequencer_funcs dce110_funcs = { .edp_power_control = dce110_edp_power_control, .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready, .set_cursor_position = dce110_set_cursor_position, - .set_cursor_attribute = dce110_set_cursor_attribute + .set_cursor_attribute = dce110_set_cursor_attribute, + .set_backlight_level = dce110_set_backlight_level, }; static const struct hwseq_private_funcs dce110_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h index 26a9c14a58b1..e609a72b4634 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h @@ -85,5 +85,9 @@ void dce110_edp_wait_for_hpd_ready( struct dc_link *link, bool power_up); +bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx, + uint32_t backlight_pwm_u16_16, + uint32_t frame_ramp); + #endif /* __DC_HWSS_DCE110_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c index 4245e1f818a3..e096d2b95ef9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c @@ -679,8 +679,7 @@ void dce110_opp_v_set_csc_default( if (default_adjust->force_hw_default == false) { const struct out_csc_color_matrix *elm; /* currently parameter not in use */ - enum grph_color_adjust_option option = - GRPH_COLOR_MATRIX_HW_DEFAULT; + enum grph_color_adjust_option option; uint32_t i; /* * HW default false we program locally defined matrix 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 0d53e1d6d6b7..2eb5d0e3e425 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 @@ -903,7 +903,8 @@ static void dcn10_reset_back_end_for_pipe( if (pipe_ctx->top_pipe == NULL) { if (pipe_ctx->stream_res.abm) - pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm); + pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm, + pipe_ctx->stream->link->panel_cntl->inst); pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg); @@ -1668,6 +1669,16 @@ void dcn10_pipe_control_lock( hws->funcs.verify_allow_pstate_change_high(dc); } +void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock) +{ + /* cursor lock is per MPCC tree, so only need to lock one pipe per stream */ + if (!pipe || pipe->top_pipe) + return; + + dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc, + pipe->stream_res.opp->inst, lock); +} + static bool wait_for_reset_trigger_to_occur( struct dc_context *dc_ctx, struct timing_generator *tg) @@ -2474,12 +2485,14 @@ void dcn10_blank_pixel_data( if (stream_res->tg->funcs->set_blank) stream_res->tg->funcs->set_blank(stream_res->tg, blank); if (stream_res->abm) { - stream_res->abm->funcs->set_pipe(stream_res->abm, stream_res->tg->inst + 1); + stream_res->abm->funcs->set_pipe(stream_res->abm, stream_res->tg->inst + 1, + stream->link->panel_cntl->inst); stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level); } } else if (blank) { if (stream_res->abm) - stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm); + stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm, + stream->link->panel_cntl->inst); if (stream_res->tg->funcs->set_blank) stream_res->tg->funcs->set_blank(stream_res->tg, blank); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h index 16a50e05ffbf..af51424315d5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h @@ -49,6 +49,7 @@ void dcn10_pipe_control_lock( struct dc *dc, struct pipe_ctx *pipe, bool lock); +void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock); void dcn10_blank_pixel_data( struct dc *dc, struct pipe_ctx *pipe_ctx, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c index b88ef9703b2b..6ff7e2bd1d4a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c @@ -50,6 +50,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { .disable_audio_stream = dce110_disable_audio_stream, .disable_plane = dcn10_disable_plane, .pipe_control_lock = dcn10_pipe_control_lock, + .cursor_lock = dcn10_cursor_lock, .interdependent_update_lock = dcn10_lock_all_pipes, .prepare_bandwidth = dcn10_prepare_bandwidth, .optimize_bandwidth = dcn10_optimize_bandwidth, @@ -71,6 +72,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { .set_clock = dcn10_set_clock, .get_clock = dcn10_get_clock, .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, + .set_backlight_level = dce110_set_backlight_level, }; static const struct hwseq_private_funcs dcn10_private_funcs = { 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 04f863499cfb..3fcd408e9103 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c @@ -223,6 +223,9 @@ struct mpcc *mpc1_insert_plane( 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); + /* Configure VUPDATE lock set for this MPCC to map to the OPP */ + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, tree->opp_id); + /* update mpc tree mux setting */ if (tree->opp_list == insert_above_mpcc) { /* insert the toppest mpcc */ @@ -318,6 +321,7 @@ void mpc1_remove_mpcc( 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); + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); /* mark this mpcc as not in use */ mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id); @@ -328,6 +332,7 @@ void mpc1_remove_mpcc( 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); + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); } } @@ -361,6 +366,7 @@ void mpc1_mpc_init(struct mpc *mpc) 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); + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); } @@ -381,6 +387,7 @@ void mpc1_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_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); + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); @@ -453,6 +460,13 @@ void mpc1_read_mpcc_state( MPCC_BUSY, &s->busy); } +void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock) +{ + struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); + + REG_SET(CUR[opp_id], 0, CUR_VUPDATE_LOCK_SET, lock ? 1 : 0); +} + static const struct mpc_funcs dcn10_mpc_funcs = { .read_mpcc_state = mpc1_read_mpcc_state, .insert_plane = mpc1_insert_plane, @@ -464,6 +478,7 @@ static const struct mpc_funcs dcn10_mpc_funcs = { .assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect, .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw, .update_blending = mpc1_update_blending, + .cursor_lock = mpc1_cursor_lock, .set_denorm = NULL, .set_denorm_clamp = NULL, .set_output_csc = NULL, 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 962a68e322ee..66a4719c22a0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h @@ -39,11 +39,12 @@ SRII(MPCC_BG_G_Y, MPCC, inst),\ SRII(MPCC_BG_R_CR, MPCC, inst),\ SRII(MPCC_BG_B_CB, MPCC, inst),\ - SRII(MPCC_BG_B_CB, MPCC, inst),\ - SRII(MPCC_SM_CONTROL, MPCC, inst) + SRII(MPCC_SM_CONTROL, MPCC, inst),\ + SRII(MPCC_UPDATE_LOCK_SEL, MPCC, inst) #define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \ - SRII(MUX, MPC_OUT, inst) + SRII(MUX, MPC_OUT, inst),\ + VUPDATE_SRII(CUR, VUPDATE_LOCK_SET, inst) #define MPC_COMMON_REG_VARIABLE_LIST \ uint32_t MPCC_TOP_SEL[MAX_MPCC]; \ @@ -55,7 +56,9 @@ uint32_t MPCC_BG_R_CR[MAX_MPCC]; \ uint32_t MPCC_BG_B_CB[MAX_MPCC]; \ uint32_t MPCC_SM_CONTROL[MAX_MPCC]; \ - uint32_t MUX[MAX_OPP]; + uint32_t MUX[MAX_OPP]; \ + uint32_t MPCC_UPDATE_LOCK_SEL[MAX_MPCC]; \ + uint32_t CUR[MAX_OPP]; #define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\ @@ -78,7 +81,8 @@ SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FIELD_ALT, mask_sh),\ SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_FRAME_POL, mask_sh),\ SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_TOP_POL, mask_sh),\ - SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh) + SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh),\ + SF(MPCC0_MPCC_UPDATE_LOCK_SEL, MPCC_UPDATE_LOCK_SEL, mask_sh) #define MPC_REG_FIELD_LIST(type) \ type MPCC_TOP_SEL;\ @@ -101,7 +105,9 @@ type MPCC_SM_FIELD_ALT;\ type MPCC_SM_FORCE_NEXT_FRAME_POL;\ type MPCC_SM_FORCE_NEXT_TOP_POL;\ - type MPC_OUT_MUX; + type MPC_OUT_MUX;\ + type MPCC_UPDATE_LOCK_SEL;\ + type CUR_VUPDATE_LOCK_SET; struct dcn_mpc_registers { MPC_COMMON_REG_VARIABLE_LIST @@ -192,4 +198,6 @@ void mpc1_read_mpcc_state( int mpcc_inst, struct mpcc_state *s); +void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock); + #endif 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 43116749af9f..bacf865f55c0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -182,6 +182,14 @@ enum dcn10_clk_src_array_id { .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ mm ## block ## id ## _ ## reg_name +#define VUPDATE_SRII(reg_name, block, id)\ + .reg_name[id] = BASE(mm ## reg_name ## 0 ## _ ## block ## id ## _BASE_IDX) + \ + mm ## reg_name ## 0 ## _ ## block ## id + +/* set field/register/bitfield name */ +#define SFRB(field_name, reg_name, bitfield, post_fix)\ + .field_name = reg_name ## __ ## bitfield ## post_fix + /* NBIO */ #define NBIO_BASE_INNER(seg) \ NBIF_BASE__INST0_SEG ## seg @@ -432,11 +440,13 @@ static const struct dcn_mpc_registers mpc_regs = { }; static const struct dcn_mpc_shift mpc_shift = { - MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT) + MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT),\ + SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, __SHIFT) }; static const struct dcn_mpc_mask mpc_mask = { - MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK), + MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),\ + SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, _MASK) }; #define tg_regs(id)\ @@ -1384,6 +1394,40 @@ static bool dcn10_resource_construct( /* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */ dc->caps.force_dp_tps4_for_cp2520 = true; + /* Color pipeline capabilities */ + dc->caps.color.dpp.dcn_arch = 1; + dc->caps.color.dpp.input_lut_shared = 1; + dc->caps.color.dpp.icsc = 1; + dc->caps.color.dpp.dgam_ram = 1; + dc->caps.color.dpp.dgam_rom_caps.srgb = 1; + dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1; + dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 0; + dc->caps.color.dpp.dgam_rom_caps.pq = 0; + dc->caps.color.dpp.dgam_rom_caps.hlg = 0; + dc->caps.color.dpp.post_csc = 0; + dc->caps.color.dpp.gamma_corr = 0; + + dc->caps.color.dpp.hw_3d_lut = 0; + dc->caps.color.dpp.ogam_ram = 1; // RGAM on DCN1 + dc->caps.color.dpp.ogam_rom_caps.srgb = 1; + dc->caps.color.dpp.ogam_rom_caps.bt2020 = 1; + dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0; + dc->caps.color.dpp.ogam_rom_caps.pq = 0; + dc->caps.color.dpp.ogam_rom_caps.hlg = 0; + dc->caps.color.dpp.ocsc = 1; + + /* no post-blend color operations */ + dc->caps.color.mpc.gamut_remap = 0; + dc->caps.color.mpc.num_3dluts = 0; + dc->caps.color.mpc.shared_3d_lut = 0; + dc->caps.color.mpc.ogam_ram = 0; + dc->caps.color.mpc.ogam_rom_caps.srgb = 0; + dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0; + dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0; + dc->caps.color.mpc.ogam_rom_caps.pq = 0; + dc->caps.color.mpc.ogam_rom_caps.hlg = 0; + dc->caps.color.mpc.ocsc = 0; + if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) dc->debug = debug_defaults_drv; else diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 6ad4ed7da629..3a290ccaeb82 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -962,7 +962,8 @@ void dcn20_blank_pixel_data( if (blank) { if (stream_res->abm) - stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm); + stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm, + stream->link->panel_cntl->inst); if (dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) { test_pattern = CONTROLLER_DP_TEST_PATTERN_COLORSQUARES; @@ -997,7 +998,8 @@ void dcn20_blank_pixel_data( if (!blank) if (stream_res->abm) { - stream_res->abm->funcs->set_pipe(stream_res->abm, stream_res->tg->inst + 1); + stream_res->abm->funcs->set_pipe(stream_res->abm, stream_res->tg->inst + 1, + stream->link->panel_cntl->inst); stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level); } } @@ -2041,7 +2043,8 @@ static void dcn20_reset_back_end_for_pipe( if (pipe_ctx->top_pipe == NULL) { if (pipe_ctx->stream_res.abm) - pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm); + pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm, + pipe_ctx->stream->link->panel_cntl->inst); pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg); @@ -2304,7 +2307,8 @@ void dcn20_fpga_init_hw(struct dc *dc) REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2); REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1); - REG_WRITE(REFCLK_CNTL, 0); + if (REG(REFCLK_CNTL)) + REG_WRITE(REFCLK_CNTL, 0); // diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c index 1642bf546ceb..c83d98e0d211 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c @@ -52,6 +52,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { .disable_plane = dcn20_disable_plane, .pipe_control_lock = dcn20_pipe_control_lock, .interdependent_update_lock = dcn10_lock_all_pipes, + .cursor_lock = dcn10_cursor_lock, .prepare_bandwidth = dcn20_prepare_bandwidth, .optimize_bandwidth = dcn20_optimize_bandwidth, .update_bandwidth = dcn20_update_bandwidth, @@ -82,6 +83,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { .init_vm_ctx = dcn20_init_vm_ctx, .set_flip_control_gsl = dcn20_set_flip_control_gsl, .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, + .set_backlight_level = dce110_set_backlight_level, }; static const struct hwseq_private_funcs dcn20_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c index de9c857ab3e9..99cc095dc33c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c @@ -452,7 +452,7 @@ void mpc2_set_output_gamma( next_mode = LUT_RAM_A; mpc20_power_on_ogam_lut(mpc, mpcc_id, true); - mpc20_configure_ogam_lut(mpc, mpcc_id, next_mode == LUT_RAM_A ? true:false); + mpc20_configure_ogam_lut(mpc, mpcc_id, next_mode == LUT_RAM_A); if (next_mode == LUT_RAM_A) mpc2_program_luta(mpc, mpcc_id, params); @@ -545,6 +545,7 @@ const struct mpc_funcs dcn20_mpc_funcs = { .mpc_init = mpc1_mpc_init, .mpc_init_single_inst = mpc1_mpc_init_single_inst, .update_blending = mpc2_update_blending, + .cursor_lock = mpc1_cursor_lock, .get_mpcc_for_dpp = mpc2_get_mpcc_for_dpp, .wait_for_idle = mpc2_assert_idle_mpcc, .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h index c78fd5123497..496658f420db 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h @@ -179,7 +179,8 @@ SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MAX_G_Y, mask_sh),\ SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MIN_G_Y, mask_sh),\ SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MAX_B_CB, mask_sh),\ - SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh) + SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh),\ + SF(CUR_VUPDATE_LOCK_SET0, CUR_VUPDATE_LOCK_SET, mask_sh) /* * DCN2 MPC_OCSC debug status register: diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 63044ae06327..60ea499c1ca8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -509,6 +509,10 @@ enum dcn20_clk_src_array_id { .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ mm ## block ## id ## _ ## reg_name +#define VUPDATE_SRII(reg_name, block, id)\ + .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ + mm ## reg_name ## _ ## block ## id + /* NBIO */ #define NBIO_BASE_INNER(seg) \ NBIO_BASE__INST0_SEG ## seg @@ -1936,7 +1940,7 @@ bool dcn20_split_stream_for_odm( return true; } -void dcn20_split_stream_for_mpc( +bool dcn20_split_stream_for_mpc( struct resource_context *res_ctx, const struct resource_pool *pool, struct pipe_ctx *primary_pipe, @@ -1965,8 +1969,11 @@ void dcn20_split_stream_for_mpc( secondary_pipe->top_pipe = primary_pipe; ASSERT(primary_pipe->plane_state); - resource_build_scaling_params(primary_pipe); - resource_build_scaling_params(secondary_pipe); + if (!resource_build_scaling_params(primary_pipe) || + !resource_build_scaling_params(secondary_pipe)) + return false; + + return true; } void dcn20_populate_dml_writeback_from_context( @@ -2623,19 +2630,24 @@ int dcn20_validate_apply_pipe_split_flags( /* Avoid split loop looks for lowest voltage level that allows most unsplit pipes possible */ if (avoid_split) { + int max_mpc_comb = context->bw_ctx.dml.vba.maxMpcComb; + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { if (!context->res_ctx.pipe_ctx[i].stream) continue; for (vlevel_split = vlevel; vlevel <= context->bw_ctx.dml.soc.num_states; vlevel++) - if (context->bw_ctx.dml.vba.NoOfDPP[vlevel][0][pipe_idx] == 1) + if (context->bw_ctx.dml.vba.NoOfDPP[vlevel][0][pipe_idx] == 1 && + context->bw_ctx.dml.vba.ModeSupport[vlevel][0]) break; /* Impossible to not split this pipe */ if (vlevel > context->bw_ctx.dml.soc.num_states) vlevel = vlevel_split; + else + max_mpc_comb = 0; pipe_idx++; } - context->bw_ctx.dml.vba.maxMpcComb = 0; + context->bw_ctx.dml.vba.maxMpcComb = max_mpc_comb; } /* Split loop sets which pipe should be split based on dml outputs and dc flags */ @@ -2791,9 +2803,10 @@ bool dcn20_fast_validate_bw( goto validate_fail; dcn20_build_mapped_resource(dc, context, pipe->stream); } else - dcn20_split_stream_for_mpc( - &context->res_ctx, dc->res_pool, - pipe, hsplit_pipe); + if (!dcn20_split_stream_for_mpc( + &context->res_ctx, dc->res_pool, + pipe, hsplit_pipe)) + goto validate_fail; pipe_split_from[hsplit_pipe->pipe_idx] = pipe_idx; } } else if (hsplit_pipe && hsplit_pipe->plane_state == pipe->plane_state) { @@ -3458,6 +3471,13 @@ void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st bb->dram_clock_change_latency_us = dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; } + + if ((int)(bb->dummy_pstate_latency_us * 1000) + != dc->bb_overrides.dummy_clock_change_latency_ns + && dc->bb_overrides.dummy_clock_change_latency_ns) { + bb->dummy_pstate_latency_us = + dc->bb_overrides.dummy_clock_change_latency_ns / 1000.0; + } } static struct _vcs_dpi_soc_bounding_box_st *get_asic_rev_soc_bb( @@ -3693,9 +3713,42 @@ static bool dcn20_resource_construct( dc->caps.max_slave_planes = 1; dc->caps.post_blend_color_processing = true; dc->caps.force_dp_tps4_for_cp2520 = true; - dc->caps.hw_3d_lut = true; dc->caps.extended_aux_timeout_support = true; + /* Color pipeline capabilities */ + dc->caps.color.dpp.dcn_arch = 1; + dc->caps.color.dpp.input_lut_shared = 0; + dc->caps.color.dpp.icsc = 1; + dc->caps.color.dpp.dgam_ram = 1; + dc->caps.color.dpp.dgam_rom_caps.srgb = 1; + dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1; + dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 0; + dc->caps.color.dpp.dgam_rom_caps.pq = 0; + dc->caps.color.dpp.dgam_rom_caps.hlg = 0; + dc->caps.color.dpp.post_csc = 0; + dc->caps.color.dpp.gamma_corr = 0; + + dc->caps.color.dpp.hw_3d_lut = 1; + dc->caps.color.dpp.ogam_ram = 1; + // no OGAM ROM on DCN2, only MPC ROM + dc->caps.color.dpp.ogam_rom_caps.srgb = 0; + dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0; + dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0; + dc->caps.color.dpp.ogam_rom_caps.pq = 0; + dc->caps.color.dpp.ogam_rom_caps.hlg = 0; + dc->caps.color.dpp.ocsc = 0; + + dc->caps.color.mpc.gamut_remap = 0; + dc->caps.color.mpc.num_3dluts = 0; + dc->caps.color.mpc.shared_3d_lut = 0; + dc->caps.color.mpc.ogam_ram = 1; + dc->caps.color.mpc.ogam_rom_caps.srgb = 0; + dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0; + dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0; + dc->caps.color.mpc.ogam_rom_caps.pq = 0; + dc->caps.color.mpc.ogam_rom_caps.hlg = 0; + dc->caps.color.mpc.ocsc = 1; + if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) { dc->debug = debug_defaults_drv; } else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h index 9d5bff9455fd..578265ccbf5b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h @@ -129,7 +129,7 @@ void dcn20_release_dsc(struct resource_context *res_ctx, const struct resource_pool *pool, struct display_stream_compressor **dsc); bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx); -void dcn20_split_stream_for_mpc( +bool dcn20_split_stream_for_mpc( struct resource_context *res_ctx, const struct resource_pool *pool, struct pipe_ctx *primary_pipe, diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c index d285ba622d61..960a0716dde5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c @@ -778,21 +778,28 @@ void dmcub_PLAT_54186_wa(struct hubp *hubp, struct surface_flip_registers *flip_ { struct dc_dmub_srv *dmcub = hubp->ctx->dmub_srv; struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); - struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa = { 0 }; - - PLAT_54186_wa.header.type = DMUB_CMD__PLAT_54186_WA; - PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS; - PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_C; - PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH; - PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C; - PLAT_54186_wa.flip.flip_params.grph_stereo = flip_regs->grph_stereo; - PLAT_54186_wa.flip.flip_params.hubp_inst = hubp->inst; - PLAT_54186_wa.flip.flip_params.immediate = flip_regs->immediate; - PLAT_54186_wa.flip.flip_params.tmz_surface = flip_regs->tmz_surface; - PLAT_54186_wa.flip.flip_params.vmid = flip_regs->vmid; + union dmub_rb_cmd cmd; + + memset(&cmd, 0, sizeof(cmd)); + + cmd.PLAT_54186_wa.header.type = DMUB_CMD__PLAT_54186_WA; + cmd.PLAT_54186_wa.header.payload_bytes = sizeof(cmd.PLAT_54186_wa.flip); + cmd.PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS = + flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS; + cmd.PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C = + flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_C; + cmd.PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH = + flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH; + cmd.PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C = + flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C; + cmd.PLAT_54186_wa.flip.flip_params.grph_stereo = flip_regs->grph_stereo; + cmd.PLAT_54186_wa.flip.flip_params.hubp_inst = hubp->inst; + cmd.PLAT_54186_wa.flip.flip_params.immediate = flip_regs->immediate; + cmd.PLAT_54186_wa.flip.flip_params.tmz_surface = flip_regs->tmz_surface; + cmd.PLAT_54186_wa.flip.flip_params.vmid = flip_regs->vmid; PERF_TRACE(); // TODO: remove after performance is stable. - dc_dmub_srv_cmd_queue(dmcub, &PLAT_54186_wa.header); + dc_dmub_srv_cmd_queue(dmcub, &cmd); PERF_TRACE(); // TODO: remove after performance is stable. dc_dmub_srv_cmd_execute(dmcub); PERF_TRACE(); // TODO: remove after performance is stable. diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c index 8410a6305a9a..ae05a8bfdae1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c @@ -53,6 +53,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { .disable_plane = dcn20_disable_plane, .pipe_control_lock = dcn20_pipe_control_lock, .interdependent_update_lock = dcn10_lock_all_pipes, + .cursor_lock = dcn10_cursor_lock, .prepare_bandwidth = dcn20_prepare_bandwidth, .optimize_bandwidth = dcn20_optimize_bandwidth, .update_bandwidth = dcn20_update_bandwidth, @@ -91,6 +92,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { .optimize_pwr_state = dcn21_optimize_pwr_state, .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, .power_down = dce110_power_down, + .set_backlight_level = dce110_set_backlight_level, }; static const struct hwseq_private_funcs dcn21_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index 78e6259b4ac9..ceaf70a934c3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -286,7 +286,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { .dram_channel_width_bytes = 4, .fabric_datapath_to_dcn_data_return_bytes = 32, .dcn_downspread_percent = 0.5, - .downspread_percent = 0.5, + .downspread_percent = 0.38, .dram_page_open_time_ns = 50.0, .dram_rw_turnaround_time_ns = 17.5, .dram_return_buffer_per_channel_bytes = 8192, @@ -342,6 +342,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ mm ## block ## id ## _ ## reg_name +#define VUPDATE_SRII(reg_name, block, id)\ + .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ + mm ## reg_name ## _ ## block ## id + /* NBIO */ #define NBIO_BASE_INNER(seg) \ NBIF0_BASE__INST0_SEG ## seg @@ -1379,64 +1383,49 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param { struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool); struct clk_limit_table *clk_table = &bw_params->clk_table; - unsigned int i, j, k; - int closest_clk_lvl; + struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES]; + unsigned int i, j, closest_clk_lvl; // Default clock levels are used for diags, which may lead to overclocking. - if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) && !IS_DIAG_DC(dc->ctx->dce_environment)) { + if (!IS_DIAG_DC(dc->ctx->dce_environment)) { dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; dcn2_1_ip.max_num_dpp = pool->base.pipe_count; dcn2_1_soc.num_chans = bw_params->num_channels; - /* Vmin: leave lowest DCN clocks, override with dcfclk, fclk, memclk from fuse */ - dcn2_1_soc.clock_limits[0].state = 0; - dcn2_1_soc.clock_limits[0].dcfclk_mhz = clk_table->entries[0].dcfclk_mhz; - dcn2_1_soc.clock_limits[0].fabricclk_mhz = clk_table->entries[0].fclk_mhz; - dcn2_1_soc.clock_limits[0].socclk_mhz = clk_table->entries[0].socclk_mhz; - dcn2_1_soc.clock_limits[0].dram_speed_mts = clk_table->entries[0].memclk_mhz * 2; - - /* - * Other levels: find closest DCN clocks that fit the given clock limit using dcfclk - * as indicator - */ - - closest_clk_lvl = -1; - /* index currently being filled */ - k = 1; - for (i = 1; i < clk_table->num_entries; i++) { - /* loop backwards, skip duplicate state*/ - for (j = dcn2_1_soc.num_states - 1; j >= k; j--) { + ASSERT(clk_table->num_entries); + for (i = 0; i < clk_table->num_entries; i++) { + /* loop backwards*/ + for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) { if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { closest_clk_lvl = j; break; } } - /* if found a lvl that fits, use the DCN clks from it, if not, go to next clk limit*/ - if (closest_clk_lvl != -1) { - dcn2_1_soc.clock_limits[k].state = i; - dcn2_1_soc.clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; - dcn2_1_soc.clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz; - dcn2_1_soc.clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz; - dcn2_1_soc.clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; - - dcn2_1_soc.clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; - dcn2_1_soc.clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; - dcn2_1_soc.clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; - dcn2_1_soc.clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; - dcn2_1_soc.clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; - dcn2_1_soc.clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; - dcn2_1_soc.clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; - k++; - } + clock_limits[i].state = i; + clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; + clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; + clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; + clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; + + clock_limits[i].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; + clock_limits[i].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; + clock_limits[i].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; + clock_limits[i].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; + clock_limits[i].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; + clock_limits[i].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; + clock_limits[i].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; + } + for (i = 0; i < clk_table->num_entries; i++) + dcn2_1_soc.clock_limits[i] = clock_limits[i]; + if (clk_table->num_entries) { + dcn2_1_soc.num_states = clk_table->num_entries; + /* duplicate last level */ + dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1]; + dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states; } - dcn2_1_soc.num_states = k; } - /* duplicate last level */ - dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1]; - dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states; - dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); } @@ -1813,7 +1802,6 @@ static bool dcn21_resource_construct( dc->caps.i2c_speed_in_khz = 100; dc->caps.max_cursor_size = 256; dc->caps.dmdata_alloc_size = 2048; - dc->caps.hw_3d_lut = true; dc->caps.max_slave_planes = 1; dc->caps.post_blend_color_processing = true; @@ -1822,6 +1810,40 @@ static bool dcn21_resource_construct( dc->caps.dmcub_support = true; dc->caps.is_apu = true; + /* Color pipeline capabilities */ + dc->caps.color.dpp.dcn_arch = 1; + dc->caps.color.dpp.input_lut_shared = 0; + dc->caps.color.dpp.icsc = 1; + dc->caps.color.dpp.dgam_ram = 1; + dc->caps.color.dpp.dgam_rom_caps.srgb = 1; + dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1; + dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 0; + dc->caps.color.dpp.dgam_rom_caps.pq = 0; + dc->caps.color.dpp.dgam_rom_caps.hlg = 0; + dc->caps.color.dpp.post_csc = 0; + dc->caps.color.dpp.gamma_corr = 0; + + dc->caps.color.dpp.hw_3d_lut = 1; + dc->caps.color.dpp.ogam_ram = 1; + // no OGAM ROM on DCN2 + dc->caps.color.dpp.ogam_rom_caps.srgb = 0; + dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0; + dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0; + dc->caps.color.dpp.ogam_rom_caps.pq = 0; + dc->caps.color.dpp.ogam_rom_caps.hlg = 0; + dc->caps.color.dpp.ocsc = 0; + + dc->caps.color.mpc.gamut_remap = 0; + dc->caps.color.mpc.num_3dluts = 0; + dc->caps.color.mpc.shared_3d_lut = 0; + dc->caps.color.mpc.ogam_ram = 1; + dc->caps.color.mpc.ogam_rom_caps.srgb = 0; + dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0; + dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0; + dc->caps.color.mpc.ogam_rom_caps.pq = 0; + dc->caps.color.mpc.ogam_rom_caps.hlg = 0; + dc->caps.color.mpc.ocsc = 1; + if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) dc->debug = debug_defaults_drv; else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) { diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h index 687010c17324..b2ecb174a93f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h @@ -121,6 +121,7 @@ struct _vcs_dpi_soc_bounding_box_st { }; struct _vcs_dpi_ip_params_st { + bool use_min_dcfclk; bool gpuvm_enable; bool hostvm_enable; unsigned int gpuvm_max_page_table_levels; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index 6b525c52124c..6e4e8a452e66 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -280,6 +280,7 @@ static void fetch_ip_params(struct display_mode_lib *mode_lib) ip_params_st *ip = &mode_lib->vba.ip; // IP Parameters + mode_lib->vba.UseMinimumRequiredDCFCLK = ip->use_min_dcfclk; mode_lib->vba.MaxNumDPP = ip->max_num_dpp; mode_lib->vba.MaxNumOTG = ip->max_num_otg; mode_lib->vba.MaxNumHDMIFRLOutputs = ip->max_num_hdmi_frl_outputs; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h index 5d82fc5a7ed7..a1884ffe63ae 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h @@ -898,6 +898,7 @@ struct vba_vars_st { bool dummystring[DC__NUM_DPP__MAX]; double BPP; enum odm_combine_policy ODMCombinePolicy; + bool UseMinimumRequiredDCFCLK; }; bool CalculateMinAndMaxPrefetchMode( diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h index 0dd12c4fc23c..91a42f0f1fc4 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h @@ -45,8 +45,8 @@ struct abm { struct abm_funcs { void (*abm_init)(struct abm *abm); bool (*set_abm_level)(struct abm *abm, unsigned int abm_level); - bool (*set_abm_immediate_disable)(struct abm *abm); - bool (*set_pipe)(struct abm *abm, unsigned int controller_id); + bool (*set_abm_immediate_disable)(struct abm *abm, unsigned int panel_inst); + bool (*set_pipe)(struct abm *abm, unsigned int controller_id, unsigned int panel_inst); bool (*init_backlight)(struct abm *abm); /* backlight_pwm_u16_16 is unsigned 32 bit, @@ -56,6 +56,7 @@ struct abm_funcs { unsigned int backlight_pwm_u16_16, unsigned int frame_ramp, unsigned int controller_id, + unsigned int panel_inst, bool fw_set_brightness); unsigned int (*get_current_backlight)(struct abm *abm); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h index 094afc4c8173..50ee8aa7ec3b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h @@ -210,6 +210,22 @@ struct mpc_funcs { struct mpcc_blnd_cfg *blnd_cfg, int mpcc_id); + /* + * Lock cursor updates for the specified OPP. + * OPP defines the set of MPCC that are locked together for cursor. + * + * Parameters: + * [in] mpc - MPC context. + * [in] opp_id - The OPP to lock cursor updates on + * [in] lock - lock/unlock the OPP + * + * Return: void + */ + void (*cursor_lock)( + struct mpc *mpc, + int opp_id, + bool lock); + struct mpcc* (*get_mpcc_for_dpp)( struct mpc_tree *tree, int dpp_id); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 9380721f28b8..1570fed20de0 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -90,6 +90,7 @@ struct hw_sequencer_funcs { struct dc_state *context, bool lock); void (*set_flip_control_gsl)(struct pipe_ctx *pipe_ctx, bool flip_immediate); + void (*cursor_lock)(struct dc *dc, struct pipe_ctx *pipe, bool lock); /* Timing Related */ void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes, @@ -191,6 +192,10 @@ struct hw_sequencer_funcs { unsigned int bufSize, unsigned int mask); void (*clear_status_bits)(struct dc *dc, unsigned int mask); + bool (*set_backlight_level)(struct pipe_ctx *pipe_ctx, + uint32_t backlight_pwm_u16_16, + uint32_t frame_ramp); + }; diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 7c7a3561b6aa..eb10518dc058 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -215,11 +215,6 @@ struct dmub_rb_cmd_dpphy_init { uint8_t reserved[60]; }; -struct dmub_psr_debug_flags { - uint8_t visual_confirm : 1; - uint8_t reserved : 7; -}; - struct dmub_cmd_psr_copy_settings_data { uint16_t psr_level; uint8_t dpp_inst; @@ -266,6 +261,7 @@ struct dmub_rb_cmd_psr_set_version { struct dmub_cmd_abm_set_pipe_data { uint32_t ramping_boundary; uint32_t otg_inst; + uint32_t panel_inst; }; struct dmub_rb_cmd_abm_set_pipe { diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_rb.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_rb.h index df875fdd2ab0..2ae48c18bb5b 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_rb.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_rb.h @@ -33,8 +33,6 @@ extern "C" { #endif -struct dmub_cmd_header; - struct dmub_rb_init_params { void *ctx; void *base_address; @@ -71,7 +69,7 @@ static inline bool dmub_rb_full(struct dmub_rb *rb) } static inline bool dmub_rb_push_front(struct dmub_rb *rb, - const struct dmub_cmd_header *cmd) + const union dmub_rb_cmd *cmd) { uint64_t volatile *dst = (uint64_t volatile *)(rb->base_address) + rb->wrpt / sizeof(uint64_t); const uint64_t *src = (const uint64_t *)cmd; @@ -93,7 +91,7 @@ static inline bool dmub_rb_push_front(struct dmub_rb *rb, } static inline bool dmub_rb_front(struct dmub_rb *rb, - struct dmub_cmd_header *cmd) + union dmub_rb_cmd *cmd) { uint8_t *rd_ptr = (uint8_t *)rb->base_address + rb->rptr; diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h index e40d1cdbcfaa..9f10bfe3d2df 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h @@ -75,7 +75,6 @@ extern "C" { /* Forward declarations */ struct dmub_srv; -struct dmub_cmd_header; struct dmub_srv_common_regs; /* enum dmub_status - return code for dmcub functions */ @@ -458,7 +457,7 @@ enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub); * DMUB_STATUS_INVALID - unspecified error */ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub, - const struct dmub_cmd_header *cmd); + const union dmub_rb_cmd *cmd); /** * dmub_srv_cmd_execute() - Executes a queued sequence to the dmub diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_types.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_types.h index 41d524b0db2f..bed5b023a396 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_types.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_types.h @@ -49,6 +49,12 @@ extern "C" { #define dmub_udelay(microseconds) udelay(microseconds) #endif +/* Maximum number of streams on any ASIC. */ +#define DMUB_MAX_STREAMS 6 + +/* Maximum number of planes on any ASIC. */ +#define DMUB_MAX_PLANES 6 + union dmub_addr { struct { uint32_t low_part; @@ -57,6 +63,11 @@ union dmub_addr { uint64_t quad_part; }; +struct dmub_psr_debug_flags { + uint8_t visual_confirm : 1; + uint8_t reserved : 7; +}; + #if defined(__cplusplus) } #endif diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 0a1a851741c5..66ba0b2d80d2 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -96,25 +96,27 @@ dmub_get_fw_meta_info(const struct dmub_srv_region_params *params) const union dmub_fw_meta *meta; const uint8_t *blob = NULL; uint32_t blob_size = 0; + uint32_t meta_offset = 0; if (params->fw_bss_data) { /* Legacy metadata region. */ blob = params->fw_bss_data; blob_size = params->bss_data_size; + meta_offset = DMUB_FW_META_OFFSET; } else if (params->fw_inst_const) { /* Combined metadata region. */ blob = params->fw_inst_const; blob_size = params->inst_const_size; + meta_offset = 0; } if (!blob || !blob_size) return NULL; - if (blob_size < sizeof(union dmub_fw_meta) + DMUB_FW_META_OFFSET) + if (blob_size < sizeof(union dmub_fw_meta) + meta_offset) return NULL; - meta = (const union dmub_fw_meta *)(blob + blob_size - - DMUB_FW_META_OFFSET - + meta = (const union dmub_fw_meta *)(blob + blob_size - meta_offset - sizeof(union dmub_fw_meta)); if (meta->info.magic_value != DMUB_FW_META_MAGIC) @@ -460,7 +462,7 @@ enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub) } enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub, - const struct dmub_cmd_header *cmd) + const union dmub_rb_cmd *cmd) { if (!dmub->hw_init) return DMUB_STATUS_INVALID; diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c index d47253cdcc4e..9431b48aecb4 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c @@ -1782,7 +1782,8 @@ rgb_user_alloc_fail: return ret; } -bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, +bool mod_color_calculate_degamma_params(struct dc_color_caps *dc_caps, + struct dc_transfer_func *input_tf, const struct dc_gamma *ramp, bool mapUserRamp) { struct dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts; @@ -1801,11 +1802,29 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, /* we can use hardcoded curve for plain SRGB TF * If linear, it's bypass if on user ramp */ - if (input_tf->type == TF_TYPE_PREDEFINED && - (input_tf->tf == TRANSFER_FUNCTION_SRGB || - input_tf->tf == TRANSFER_FUNCTION_LINEAR) && - !mapUserRamp) - return true; + if (input_tf->type == TF_TYPE_PREDEFINED) { + if ((input_tf->tf == TRANSFER_FUNCTION_SRGB || + input_tf->tf == TRANSFER_FUNCTION_LINEAR) && + !mapUserRamp) + return true; + + if (dc_caps != NULL && + dc_caps->dpp.dcn_arch == 1) { + + if (input_tf->tf == TRANSFER_FUNCTION_PQ && + dc_caps->dpp.dgam_rom_caps.pq == 1) + return true; + + if (input_tf->tf == TRANSFER_FUNCTION_GAMMA22 && + dc_caps->dpp.dgam_rom_caps.gamma2_2 == 1) + return true; + + // HLG OOTF not accounted for + if (input_tf->tf == TRANSFER_FUNCTION_HLG && + dc_caps->dpp.dgam_rom_caps.hlg == 1) + return true; + } + } input_tf->type = TF_TYPE_DISTRIBUTED_POINTS; diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h index 9994817a9a03..7f56226ba77a 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h @@ -30,6 +30,7 @@ struct dc_transfer_func; struct dc_gamma; struct dc_transfer_func_distributed_points; struct dc_rgb_fixed; +struct dc_color_caps; enum dc_transfer_func_predefined; /* For SetRegamma ADL interface support @@ -100,7 +101,8 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed, const struct freesync_hdr_tf_params *fs_params); -bool mod_color_calculate_degamma_params(struct dc_transfer_func *output_tf, +bool mod_color_calculate_degamma_params(struct dc_color_caps *dc_caps, + struct dc_transfer_func *output_tf, const struct dc_gamma *ramp, bool mapUserRamp); bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans, |