diff options
author | Dave Airlie <airlied@redhat.com> | 2018-03-09 10:50:45 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-03-09 10:50:45 +1000 |
commit | 128ccceaba8656573b8b0f86d3ab6e38094cc754 (patch) | |
tree | 289d877fe471cc89e1f08350a0e8c7e064c322ee /drivers/gpu/drm/amd/display | |
parent | 2ec360bbc319903f878135adeed85bb648ef95cf (diff) | |
parent | f6c3b601bd490eda08c27b03607448abd4b4841b (diff) |
Merge branch 'drm-next-4.17' of git://people.freedesktop.org/~agd5f/linux into drm-next
More stuff for 4.17. Highlights:
- More fixes for "wattman" like functionality (fine grained clk/voltage control)
- Add more power profile infrastucture (context based dpm)
- SR-IOV fixes
- Add iomem debugging interface for use with umr
- Powerplay and cgs cleanups
- DC fixes and cleanups
- ttm improvements
- Misc cleanups all over
* 'drm-next-4.17' of git://people.freedesktop.org/~agd5f/linux: (143 commits)
drm/amdgpu:Always save uvd vcpu_bo in VM Mode
drm/amdgpu:Correct max uvd handles
drm/amdgpu: replace iova debugfs file with iomem (v3)
drm/amd/display: validate plane format on primary plane
drm/amdgpu: Clean sdma wptr register when only enable wptr polling
drm/amd/amdgpu: re-add missing GC 9.1 and SDMA0 4.1 sh_mask header files
drm/amdgpu: give warning before sleep in kiq_r/wreg
drm/amdgpu: further mitigate workaround for i915
drm/amdgpu: drop gtt->adev
drm/amdgpu: add amdgpu_evict_gtt debugfs entry
drm/amd/pp: Add #ifdef checks for CONFIG_ACPI
drm/amd/pp: fix "Delete the wrapper layer of smu_allocate/free_memory"
drm/amd/pp: Drop wrapper functions for upper/lower_32_bits
drm/amdgpu: Delete cgs wrapper functions for gpu memory manager
drm/amd/pp: Delete the wrapper layer of smu_allocate/free_memory
drm/amd/pp: Remove cgs wrapper function for temperature update
Revert "drm/amd/pp: Add a pp feature mask bit for AutoWattman feature"
drm/amd/pp: Add auto power profilng switch based on workloads (v2)
drm/amd/pp: Revert gfx/compute profile switch sysfs
drm/amd/pp: Fix sclk in highest two levels when compute on smu7
...
Diffstat (limited to 'drivers/gpu/drm/amd/display')
55 files changed, 894 insertions, 552 deletions
diff --git a/drivers/gpu/drm/amd/display/Makefile b/drivers/gpu/drm/amd/display/Makefile index 3d14478913de..a2c5be493555 100644 --- a/drivers/gpu/drm/amd/display/Makefile +++ b/drivers/gpu/drm/amd/display/Makefile @@ -26,8 +26,6 @@ AMDDALPATH = $(RELATIVE_AMD_DISPLAY_PATH) -subdir-ccflags-y += -I$(AMDDALPATH)/ -I$(AMDDALPATH)/include - subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/inc/ subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/inc/hw subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/inc 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 246fff33c7bf..7e5c5c9eeb4f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -374,7 +374,7 @@ static void amdgpu_dm_fbc_init(struct drm_connector *connector) if (max_size) { int r = amdgpu_bo_create_kernel(adev, max_size * 4, PAGE_SIZE, - AMDGPU_GEM_DOMAIN_VRAM, &compressor->bo_ptr, + AMDGPU_GEM_DOMAIN_GTT, &compressor->bo_ptr, &compressor->gpu_addr, &compressor->cpu_addr); if (r) @@ -1058,6 +1058,10 @@ static void handle_hpd_rx_irq(void *param) !is_mst_root_connector) { /* Downstream Port status changed. */ if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) { + + if (aconnector->fake_enable) + aconnector->fake_enable = false; + amdgpu_dm_update_connector_after_detect(aconnector); @@ -2486,6 +2490,27 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc) return &state->base; } + +static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) +{ + enum dc_irq_source irq_source; + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); + struct amdgpu_device *adev = crtc->dev->dev_private; + + irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst; + return dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY; +} + +static int dm_enable_vblank(struct drm_crtc *crtc) +{ + return dm_set_vblank(crtc, true); +} + +static void dm_disable_vblank(struct drm_crtc *crtc) +{ + dm_set_vblank(crtc, false); +} + /* Implemented only the options currently availible for the driver */ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { .reset = dm_crtc_reset_state, @@ -2496,6 +2521,8 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { .atomic_duplicate_state = dm_crtc_duplicate_state, .atomic_destroy_state = dm_crtc_destroy_state, .set_crc_source = amdgpu_dm_crtc_set_crc_source, + .enable_vblank = dm_enable_vblank, + .disable_vblank = dm_disable_vblank, }; static enum drm_connector_status @@ -3059,6 +3086,9 @@ static int dm_plane_atomic_check(struct drm_plane *plane, if (!dm_plane_state->dc_state) return 0; + if (!fill_rects_from_plane_state(state, dm_plane_state->dc_state)) + return -EINVAL; + if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK) return 0; @@ -3193,7 +3223,7 @@ static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, dm->adev->mode_info.crtcs[crtc_index] = acrtc; drm_crtc_enable_color_mgmt(&acrtc->base, MAX_COLOR_LUT_ENTRIES, true, MAX_COLOR_LUT_ENTRIES); - drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LUT_ENTRIES); + drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES); return 0; @@ -4660,8 +4690,6 @@ static int dm_update_planes_state(struct dc *dc, bool pflip_needed = !state->allow_modeset; int ret = 0; - if (pflip_needed) - return ret; /* Add new planes */ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { @@ -4676,6 +4704,8 @@ static int dm_update_planes_state(struct dc *dc, /* Remove any changed/removed planes */ if (!enable) { + if (pflip_needed) + continue; if (!old_plane_crtc) continue; @@ -4720,6 +4750,8 @@ static int dm_update_planes_state(struct dc *dc, if (!dm_new_crtc_state->stream) continue; + if (pflip_needed) + continue; WARN_ON(dm_new_plane_state->dc_state); @@ -4764,6 +4796,30 @@ static int dm_update_planes_state(struct dc *dc, return ret; } +static int dm_atomic_check_plane_state_fb(struct drm_atomic_state *state, + struct drm_crtc *crtc) +{ + struct drm_plane *plane; + struct drm_crtc_state *crtc_state; + + WARN_ON(!drm_atomic_get_new_crtc_state(state, crtc)); + + drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) { + struct drm_plane_state *plane_state = + drm_atomic_get_plane_state(state, plane); + + if (IS_ERR(plane_state)) + return -EDEADLK; + + crtc_state = drm_atomic_get_crtc_state(plane_state->state, crtc); + if (crtc->primary == plane && crtc_state->active) { + if (!plane_state->fb) + return -EINVAL; + } + } + return 0; +} + static int amdgpu_dm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) { @@ -4787,6 +4843,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, goto fail; for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + ret = dm_atomic_check_plane_state_fb(state, crtc); + if (ret) + goto fail; + if (!drm_atomic_crtc_needs_modeset(new_crtc_state) && !new_crtc_state->color_mgmt_changed) continue; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index aa7df5775545..b68400c1154b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -268,7 +268,9 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc); #define amdgpu_dm_crtc_handle_crc_irq(x) #endif -#define MAX_COLOR_LUT_ENTRIES 256 +#define MAX_COLOR_LUT_ENTRIES 4096 +/* Legacy gamm LUT users such as X doesn't like large LUT sizes */ +#define MAX_COLOR_LEGACY_LUT_ENTRIES 256 void amdgpu_dm_init_color_mod(void); int amdgpu_dm_set_degamma_lut(struct drm_crtc_state *crtc_state, 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 62bb72fe9aa5..e845c511656e 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 @@ -27,6 +27,8 @@ #include "amdgpu_dm.h" #include "modules/color/color_gamma.h" +#define MAX_DRM_LUT_VALUE 0xFFFF + /* * Initialize the color module. * @@ -47,19 +49,18 @@ void amdgpu_dm_init_color_mod(void) * f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in * [0, MAX_COLOR_LUT_ENTRIES) */ -static bool __is_lut_linear(struct drm_color_lut *lut) +static bool __is_lut_linear(struct drm_color_lut *lut, uint32_t size) { int i; - uint32_t max_os = 0xFF00; uint32_t expected; int delta; - for (i = 0; i < MAX_COLOR_LUT_ENTRIES; i++) { + for (i = 0; i < size; i++) { /* All color values should equal */ if ((lut[i].red != lut[i].green) || (lut[i].green != lut[i].blue)) return false; - expected = i * max_os / (MAX_COLOR_LUT_ENTRIES-1); + expected = i * MAX_DRM_LUT_VALUE / (size-1); /* Allow a +/-1 error. */ delta = lut[i].red - expected; @@ -70,6 +71,42 @@ static bool __is_lut_linear(struct drm_color_lut *lut) } /** + * Convert the drm_color_lut to dc_gamma. The conversion depends on the size + * of the lut - whether or not it's legacy. + */ +static void __drm_lut_to_dc_gamma(struct drm_color_lut *lut, + struct dc_gamma *gamma, + bool is_legacy) +{ + uint32_t r, g, b; + int i; + + if (is_legacy) { + for (i = 0; i < MAX_COLOR_LEGACY_LUT_ENTRIES; i++) { + r = drm_color_lut_extract(lut[i].red, 16); + g = drm_color_lut_extract(lut[i].green, 16); + b = drm_color_lut_extract(lut[i].blue, 16); + + gamma->entries.red[i] = dal_fixed31_32_from_int(r); + gamma->entries.green[i] = dal_fixed31_32_from_int(g); + gamma->entries.blue[i] = dal_fixed31_32_from_int(b); + } + return; + } + + /* else */ + for (i = 0; i < MAX_COLOR_LUT_ENTRIES; i++) { + r = drm_color_lut_extract(lut[i].red, 16); + g = drm_color_lut_extract(lut[i].green, 16); + b = drm_color_lut_extract(lut[i].blue, 16); + + gamma->entries.red[i] = dal_fixed31_32_from_fraction(r, MAX_DRM_LUT_VALUE); + gamma->entries.green[i] = dal_fixed31_32_from_fraction(g, MAX_DRM_LUT_VALUE); + gamma->entries.blue[i] = dal_fixed31_32_from_fraction(b, MAX_DRM_LUT_VALUE); + } +} + +/** * amdgpu_dm_set_regamma_lut: Set regamma lut for the given CRTC. * @crtc: amdgpu_dm crtc state * @@ -85,11 +122,10 @@ int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc) struct drm_property_blob *blob = crtc->base.gamma_lut; struct dc_stream_state *stream = crtc->stream; struct drm_color_lut *lut; + uint32_t lut_size; struct dc_gamma *gamma; enum dc_transfer_func_type old_type = stream->out_transfer_func->type; - uint32_t r, g, b; - int i; bool ret; if (!blob) { @@ -100,8 +136,9 @@ int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc) } lut = (struct drm_color_lut *)blob->data; + lut_size = blob->length / sizeof(struct drm_color_lut); - if (__is_lut_linear(lut)) { + if (__is_lut_linear(lut, lut_size)) { /* Set to bypass if lut is set to linear */ stream->out_transfer_func->type = TF_TYPE_BYPASS; stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; @@ -112,20 +149,20 @@ int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc) if (!gamma) return -ENOMEM; - gamma->num_entries = MAX_COLOR_LUT_ENTRIES; - gamma->type = GAMMA_RGB_256; - - /* Truncate, and store in dc_gamma for output tf calculation */ - for (i = 0; i < gamma->num_entries; i++) { - r = drm_color_lut_extract(lut[i].red, 16); - g = drm_color_lut_extract(lut[i].green, 16); - b = drm_color_lut_extract(lut[i].blue, 16); - - gamma->entries.red[i] = dal_fixed31_32_from_int(r); - gamma->entries.green[i] = dal_fixed31_32_from_int(g); - gamma->entries.blue[i] = dal_fixed31_32_from_int(b); + gamma->num_entries = lut_size; + if (gamma->num_entries == MAX_COLOR_LEGACY_LUT_ENTRIES) + gamma->type = GAMMA_RGB_256; + else if (gamma->num_entries == MAX_COLOR_LUT_ENTRIES) + gamma->type = GAMMA_CS_TFM_1D; + else { + /* Invalid lut size */ + dc_gamma_release(&gamma); + return -EINVAL; } + /* Convert drm_lut into dc_gamma */ + __drm_lut_to_dc_gamma(lut, gamma, gamma->type == GAMMA_RGB_256); + /* Call color module to translate into something DC understands. Namely * a transfer function. */ @@ -212,7 +249,7 @@ int amdgpu_dm_set_degamma_lut(struct drm_crtc_state *crtc_state, } lut = (struct drm_color_lut *)blob->data; - if (__is_lut_linear(lut)) { + if (__is_lut_linear(lut, MAX_COLOR_LUT_ENTRIES)) { dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS; dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; return 0; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 9bd142f65f9b..9ab69b22b989 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -258,6 +258,15 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( return true; } + +/* + * Clear payload allocation table before enable MST DP link. + */ +void dm_helpers_dp_mst_clear_payload_allocation_table( + struct dc_context *ctx, + const struct dc_link *link) +{} + /* * Polls for ACT (allocation change trigger) handled and sends * ALLOCATE_PAYLOAD message. @@ -496,3 +505,8 @@ enum dc_edid_status dm_helpers_read_local_edid( return edid_status; } + +void dm_set_dcn_clocks(struct dc_context *ctx, struct dc_clocks *clks) +{ + /* TODO: something */ +} diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 1e8a21b67df7..39cfe0fbf1b9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -83,17 +83,18 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, enum i2c_mot_mode mot = (msg->request & DP_AUX_I2C_MOT) ? I2C_MOT_TRUE : I2C_MOT_FALSE; enum ddc_result res; + ssize_t read_bytes; switch (msg->request & ~DP_AUX_I2C_MOT) { case DP_AUX_NATIVE_READ: - res = dal_ddc_service_read_dpcd_data( + read_bytes = dal_ddc_service_read_dpcd_data( TO_DM_AUX(aux)->ddc_service, false, I2C_MOT_UNDEF, msg->address, msg->buffer, msg->size); - break; + return read_bytes; case DP_AUX_NATIVE_WRITE: res = dal_ddc_service_write_dpcd_data( TO_DM_AUX(aux)->ddc_service, @@ -104,14 +105,14 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, msg->size); break; case DP_AUX_I2C_READ: - res = dal_ddc_service_read_dpcd_data( + read_bytes = dal_ddc_service_read_dpcd_data( TO_DM_AUX(aux)->ddc_service, true, mot, msg->address, msg->buffer, msg->size); - break; + return read_bytes; case DP_AUX_I2C_WRITE: res = dal_ddc_service_write_dpcd_data( TO_DM_AUX(aux)->ddc_service, diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c index 69c59e050a96..c7f0b27e457e 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c @@ -49,6 +49,9 @@ #define LAST_RECORD_TYPE 0xff +#define DC_LOGGER \ + bp->base.ctx->logger + /* GUID to validate external display connection info table (aka OPM module) */ static const uint8_t ext_display_connection_guid[NUMBER_OF_UCHAR_FOR_GUID] = { 0x91, 0x6E, 0x57, 0x09, @@ -3079,8 +3082,7 @@ static enum bp_result patch_bios_image_from_ext_display_connection_info( opm_object, &ext_display_connection_info_tbl) != BP_RESULT_OK) { - dm_logger_write(bp->base.ctx->logger, LOG_WARNING, - "%s: Failed to read Connection Info Table", __func__); + DC_LOG_WARNING("%s: Failed to read Connection Info Table", __func__); return BP_RESULT_UNSUPPORTED; } 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 fea5e83736fd..e362658aa3ce 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c @@ -34,6 +34,8 @@ #include "command_table_helper2.h" #include "bios_parser_helper.h" #include "bios_parser_types_internal2.h" +#define DC_LOGGER \ + bp->base.ctx->logger #define GET_INDEX_INTO_MASTER_TABLE(MasterOrData, FieldName)\ (((char *)(&((\ @@ -239,8 +241,7 @@ static enum bp_result transmitter_control_v1_6( if (cntl->action == TRANSMITTER_CONTROL_ENABLE || cntl->action == TRANSMITTER_CONTROL_ACTIAVATE || cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) { - dm_logger_write(bp->base.ctx->logger, LOG_BIOS,\ - "%s:ps.param.symclk_10khz = %d\n",\ + DC_LOG_BIOS("%s:ps.param.symclk_10khz = %d\n",\ __func__, ps.param.symclk_10khz); } @@ -331,8 +332,7 @@ static enum bp_result set_pixel_clock_v7( (uint8_t) bp->cmd_helper-> transmitter_color_depth_to_atom( bp_params->color_depth); - dm_logger_write(bp->base.ctx->logger, LOG_BIOS,\ - "%s:program display clock = %d"\ + DC_LOG_BIOS("%s:program display clock = %d"\ "colorDepth = %d\n", __func__,\ bp_params->target_pixel_clock, bp_params->color_depth); @@ -772,8 +772,7 @@ static enum bp_result set_dce_clock_v2_1( */ params.param.dceclk_10khz = cpu_to_le32( bp_params->target_clock_frequency / 10); - dm_logger_write(bp->base.ctx->logger, LOG_BIOS, - "%s:target_clock_frequency = %d"\ + DC_LOG_BIOS("%s:target_clock_frequency = %d"\ "clock_type = %d \n", __func__,\ bp_params->target_clock_frequency,\ bp_params->clock_type); diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index c9aa686d16b9..8020bc7742c1 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -33,6 +33,8 @@ #include "dcn10/dcn10_resource.h" #include "dcn_calc_math.h" +#define DC_LOGGER \ + dc->ctx->logger /* * NOTE: * This file is gcc-parseable HW gospel, coming straight from HW engineers. @@ -996,7 +998,7 @@ bool dcn_validate_bandwidth( dc->debug.min_disp_clk_khz; } - context->bw.dcn.calc_clk.dppclk_div = (int)(v->dispclk_dppclk_ratio) == 2; + context->bw.dcn.calc_clk.max_dppclk_khz = context->bw.dcn.calc_clk.dispclk_khz / v->dispclk_dppclk_ratio; for (i = 0, input_idx = 0; i < pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; @@ -1242,8 +1244,7 @@ unsigned int dcn_find_dcfclk_suits_all( else dcf_clk = dc->dcn_soc->dcfclkv_min0p65*1000; - dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS, - "\tdcf_clk for voltage = %d\n", dcf_clk); + DC_LOG_BANDWIDTH_CALCS("\tdcf_clk for voltage = %d\n", dcf_clk); return dcf_clk; } @@ -1441,8 +1442,7 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc) void dcn_bw_sync_calcs_and_dml(struct dc *dc) { kernel_fpu_begin(); - dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS, - "sr_exit_time: %d ns\n" + DC_LOG_BANDWIDTH_CALCS("sr_exit_time: %d ns\n" "sr_enter_plus_exit_time: %d ns\n" "urgent_latency: %d ns\n" "write_back_latency: %d ns\n" @@ -1510,8 +1510,7 @@ void dcn_bw_sync_calcs_and_dml(struct dc *dc) dc->dcn_soc->vmm_page_size, dc->dcn_soc->dram_clock_change_latency * 1000, dc->dcn_soc->return_bus_width); - dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS, - "rob_buffer_size_in_kbyte: %d\n" + DC_LOG_BANDWIDTH_CALCS("rob_buffer_size_in_kbyte: %d\n" "det_buffer_size_in_kbyte: %d\n" "dpp_output_buffer_pixels: %d\n" "opp_output_buffer_lines: %d\n" diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 77a1bf233c3c..8394d69b963f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -51,6 +51,8 @@ #include "dm_helpers.h" #include "mem_input.h" #include "hubp.h" +#define DC_LOGGER \ + dc->ctx->logger /******************************************************************************* @@ -264,7 +266,7 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, /* Only call if supported */ if (tg->funcs->configure_crc) return tg->funcs->configure_crc(tg, ¶m); - dm_logger_write(dc->ctx->logger, LOG_WARNING, "CRC capture not supported."); + DC_LOG_WARNING("CRC capture not supported."); return false; } @@ -297,7 +299,7 @@ bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream, if (tg->funcs->get_crc) return tg->funcs->get_crc(tg, r_cr, g_y, b_cb); - dm_logger_write(dc->ctx->logger, LOG_WARNING, "CRC capture not supported."); + DC_LOG_WARNING("CRC capture not supported."); return false; } @@ -618,8 +620,7 @@ struct dc *dc_create(const struct dc_init_data *init_params) dc->config = init_params->flags; - dm_logger_write(dc->ctx->logger, LOG_DC, - "Display Core initialized\n"); + DC_LOG_DC("Display Core initialized\n"); /* TODO: missing feature to be enabled */ @@ -888,7 +889,7 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context) if (false == context_changed(dc, context)) return DC_OK; - dm_logger_write(dc->ctx->logger, LOG_DC, "%s: %d streams\n", + DC_LOG_DC("%s: %d streams\n", __func__, context->stream_count); for (i = 0; i < context->stream_count; i++) { @@ -1515,13 +1516,13 @@ enum dc_irq_source dc_interrupt_to_irq_source( return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id); } -void dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable) +bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable) { if (dc == NULL) - return; + return false; - dal_irq_service_set(dc->res_pool->irqs, src, enable); + return dal_irq_service_set(dc->res_pool->irqs, src, enable); } void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c index 1babac07bcc9..c15565092ca8 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c @@ -361,21 +361,22 @@ void context_clock_trace( struct dc *core_dc = dc; struct dal_logger *logger = core_dc->ctx->logger; - CLOCK_TRACE("Current: dispclk_khz:%d dppclk_div:%d dcfclk_khz:%d\n" - "dcfclk_deep_sleep_khz:%d fclk_khz:%d\n" + CLOCK_TRACE("Current: dispclk_khz:%d max_dppclk_khz:%d dcfclk_khz:%d\n" + "dcfclk_deep_sleep_khz:%d fclk_khz:%d socclk_khz:%d\n" "dram_ccm_us:%d min_active_dram_ccm_us:%d\n", context->bw.dcn.calc_clk.dispclk_khz, - context->bw.dcn.calc_clk.dppclk_div, + context->bw.dcn.calc_clk.max_dppclk_khz, context->bw.dcn.calc_clk.dcfclk_khz, context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz, context->bw.dcn.calc_clk.fclk_khz, + context->bw.dcn.calc_clk.socclk_khz, context->bw.dcn.calc_clk.dram_ccm_us, context->bw.dcn.calc_clk.min_active_dram_ccm_us); - CLOCK_TRACE("Calculated: dispclk_khz:%d dppclk_div:%d dcfclk_khz:%d\n" - "dcfclk_deep_sleep_khz:%d fclk_khz:%d\n" + CLOCK_TRACE("Calculated: dispclk_khz:%d max_dppclk_khz:%d dcfclk_khz:%d\n" + "dcfclk_deep_sleep_khz:%d fclk_khz:%d socclk_khz:%d\n" "dram_ccm_us:%d min_active_dram_ccm_us:%d\n", context->bw.dcn.calc_clk.dispclk_khz, - context->bw.dcn.calc_clk.dppclk_div, + context->bw.dcn.calc_clk.max_dppclk_khz, context->bw.dcn.calc_clk.dcfclk_khz, context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz, context->bw.dcn.calc_clk.fclk_khz, 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 95955ade4012..f8c09273e0f1 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -45,9 +45,11 @@ #include "dce/dce_11_0_d.h" #include "dce/dce_11_0_enum.h" #include "dce/dce_11_0_sh_mask.h" +#define DC_LOGGER \ + dc_ctx->logger #define LINK_INFO(...) \ - dm_logger_write(dc_ctx->logger, LOG_HW_HOTPLUG, \ + DC_LOG_HW_HOTPLUG( \ __VA_ARGS__) /******************************************************************************* @@ -677,12 +679,10 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) switch (edid_status) { case EDID_BAD_CHECKSUM: - dm_logger_write(link->ctx->logger, LOG_ERROR, - "EDID checksum invalid.\n"); + DC_LOG_ERROR("EDID checksum invalid.\n"); break; case EDID_NO_RESPONSE: - dm_logger_write(link->ctx->logger, LOG_ERROR, - "No EDID read.\n"); + DC_LOG_ERROR("No EDID read.\n"); default: break; } @@ -712,8 +712,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) "%s: [Block %d] ", sink->edid_caps.display_name, i); } - dm_logger_write(link->ctx->logger, LOG_DETECTION_EDID_PARSER, - "%s: " + DC_LOG_DETECTION_EDID_PARSER("%s: " "manufacturer_id = %X, " "product_id = %X, " "serial_number = %X, " @@ -733,8 +732,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) sink->edid_caps.audio_mode_count); for (i = 0; i < sink->edid_caps.audio_mode_count; i++) { - dm_logger_write(link->ctx->logger, LOG_DETECTION_EDID_PARSER, - "%s: mode number = %d, " + DC_LOG_DETECTION_EDID_PARSER("%s: mode number = %d, " "format_code = %d, " "channel_count = %d, " "sample_rate = %d, " @@ -984,8 +982,7 @@ static bool construct( } break; default: - dm_logger_write(dc_ctx->logger, LOG_WARNING, - "Unsupported Connector type:%d!\n", link->link_id.id); + DC_LOG_WARNING("Unsupported Connector type:%d!\n", link->link_id.id); goto create_fail; } @@ -1138,7 +1135,7 @@ static void dpcd_configure_panel_mode( { union dpcd_edp_config edp_config_set; bool panel_mode_edp = false; - + struct dc_context *dc_ctx = link->ctx; memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config)); if (DP_PANEL_MODE_DEFAULT != panel_mode) { @@ -1175,8 +1172,7 @@ static void dpcd_configure_panel_mode( ASSERT(result == DDC_RESULT_SUCESSFULL); } } - dm_logger_write(link->ctx->logger, LOG_DETECTION_DP_CAPS, - "Link: %d eDP panel mode supported: %d " + DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d " "eDP panel mode enabled: %d \n", link->link_index, link->dpcd_caps.panel_mode_edp, @@ -1311,6 +1307,9 @@ static enum dc_status enable_link_dp_mst( if (link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) return DC_OK; + /* clear payload table */ + dm_helpers_dp_mst_clear_payload_allocation_table(link->ctx, link); + /* set the sink to MST mode before enabling the link */ dp_enable_mst_on_sink(link, true); @@ -1951,6 +1950,7 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level, struct dc *core_dc = link->ctx->dc; struct abm *abm = core_dc->res_pool->abm; struct dmcu *dmcu = core_dc->res_pool->dmcu; + struct dc_context *dc_ctx = link->ctx; unsigned int controller_id = 0; bool use_smooth_brightness = true; int i; @@ -1962,8 +1962,7 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level, use_smooth_brightness = dmcu->funcs->is_dmcu_initialized(dmcu); - dm_logger_write(link->ctx->logger, LOG_BACKLIGHT, - "New Backlight level: %d (0x%X)\n", level, level); + DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", level, level); if (dc_is_embedded_signal(link->connector_signal)) { if (stream != NULL) { @@ -2130,6 +2129,7 @@ static enum dc_status allocate_mst_payload(struct pipe_ctx *pipe_ctx) struct fixed31_32 avg_time_slots_per_mtp; struct fixed31_32 pbn; struct fixed31_32 pbn_per_slot; + struct dc_context *dc_ctx = link->ctx; uint8_t i; /* enable_link_dp_mst already check link->enabled_stream_count @@ -2147,21 +2147,18 @@ static enum dc_status allocate_mst_payload(struct pipe_ctx *pipe_ctx) link, pipe_ctx->stream_res.stream_enc, &proposed_table); } else - dm_logger_write(link->ctx->logger, LOG_WARNING, - "Failed to update" + DC_LOG_WARNING("Failed to update" "MST allocation table for" "pipe idx:%d\n", pipe_ctx->pipe_idx); - dm_logger_write(link->ctx->logger, LOG_MST, - "%s " + DC_LOG_MST("%s " "stream_count: %d: \n ", __func__, link->mst_stream_alloc_table.stream_count); for (i = 0; i < MAX_CONTROLLER_NUM; i++) { - dm_logger_write(link->ctx->logger, LOG_MST, - "stream_enc[%d]: 0x%x " + DC_LOG_MST("stream_enc[%d]: 0x%x " "stream[%d].vcp_id: %d " "stream[%d].slot_count: %d\n", i, @@ -2212,6 +2209,7 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx) struct fixed31_32 avg_time_slots_per_mtp = dal_fixed31_32_from_int(0); uint8_t i; bool mst_mode = (link->type == dc_connection_mst_branch); + struct dc_context *dc_ctx = link->ctx; /* deallocate_mst_payload is called before disable link. When mode or * disable/enable monitor, new stream is created which is not in link @@ -2237,23 +2235,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx) link, pipe_ctx->stream_res.stream_enc, &proposed_table); } else { - dm_logger_write(link->ctx->logger, LOG_WARNING, - "Failed to update" + DC_LOG_WARNING("Failed to update" "MST allocation table for" "pipe idx:%d\n", pipe_ctx->pipe_idx); } } - dm_logger_write(link->ctx->logger, LOG_MST, - "%s" + DC_LOG_MST("%s" "stream_count: %d: ", __func__, link->mst_stream_alloc_table.stream_count); for (i = 0; i < MAX_CONTROLLER_NUM; i++) { - dm_logger_write(link->ctx->logger, LOG_MST, - "stream_enc[%d]: 0x%x " + DC_LOG_MST("stream_enc[%d]: 0x%x " "stream[%d].vcp_id: %d " "stream[%d].slot_count: %d\n", i, @@ -2287,21 +2282,24 @@ void core_link_enable_stream( struct pipe_ctx *pipe_ctx) { struct dc *core_dc = pipe_ctx->stream->ctx->dc; - + struct dc_context *dc_ctx = pipe_ctx->stream->ctx; enum dc_status status; /* eDP lit up by bios already, no need to enable again. */ if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP && core_dc->apply_edp_fast_boot_optimization) { core_dc->apply_edp_fast_boot_optimization = false; + pipe_ctx->stream->dpms_off = false; return; } + if (pipe_ctx->stream->dpms_off) + return; + status = enable_link(state, pipe_ctx); if (status != DC_OK) { - dm_logger_write(pipe_ctx->stream->ctx->logger, - LOG_WARNING, "enabling link %u failed: %d\n", + DC_LOG_WARNING("enabling link %u failed: %d\n", pipe_ctx->stream->sink->link->link_index, status); @@ -2355,11 +2353,14 @@ void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) core_dc->hwss.set_avmute(pipe_ctx, enable); } -void dc_link_disable_hpd_filter(struct dc_link *link) +void dc_link_enable_hpd_filter(struct dc_link *link, bool enable) { struct gpio *hpd; - if (!link->is_hpd_filter_disabled) { + if (enable) { + link->is_hpd_filter_disabled = false; + program_hpd_filter(link); + } else { link->is_hpd_filter_disabled = true; /* Obtain HPD handle */ hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service); 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 d5294798b0a5..49c2face1e7a 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 @@ -629,7 +629,7 @@ bool dal_ddc_service_query_ddc_data( return ret; } -enum ddc_result dal_ddc_service_read_dpcd_data( +ssize_t dal_ddc_service_read_dpcd_data( struct ddc_service *ddc, bool i2c, enum i2c_mot_mode mot, @@ -660,8 +660,9 @@ enum ddc_result dal_ddc_service_read_dpcd_data( if (dal_i2caux_submit_aux_command( ddc->ctx->i2caux, ddc->ddc_pin, - &command)) - return DDC_RESULT_SUCESSFULL; + &command)) { + return (ssize_t)command.payloads->length; + } return DDC_RESULT_FAILED_OPERATION; } 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 604fb0171ee3..3b5053570229 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 @@ -11,6 +11,8 @@ #include "dpcd_defs.h" #include "resource.h" +#define DC_LOGGER \ + link->ctx->logger /* maximum pre emphasis level allowed for each voltage swing level*/ static const enum dc_pre_emphasis voltage_swing_to_pre_emphasis[] = { @@ -63,8 +65,7 @@ static void wait_for_training_aux_rd_interval( udelay(default_wait_in_micro_secs); - dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING, - "%s:\n wait = %d\n", + DC_LOG_HW_LINK_TRAINING("%s:\n wait = %d\n", __func__, default_wait_in_micro_secs); } @@ -79,8 +80,7 @@ static void dpcd_set_training_pattern( &dpcd_pattern.raw, 1); - dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING, - "%s\n %x pattern = %x\n", + DC_LOG_HW_LINK_TRAINING("%s\n %x pattern = %x\n", __func__, DP_TRAINING_PATTERN_SET, dpcd_pattern.v1_4.TRAINING_PATTERN_SET); @@ -116,8 +116,7 @@ static void dpcd_set_link_settings( core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL, &downspread.raw, sizeof(downspread)); - dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING, - "%s\n %x rate = %x\n %x lane = %x\n %x spread = %x\n", + DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x\n %x spread = %x\n", __func__, DP_LINK_BW_SET, lt_settings->link_settings.link_rate, @@ -151,8 +150,7 @@ static enum dpcd_training_patterns break; default: ASSERT(0); - dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING, - "%s: Invalid HW Training pattern: %d\n", + DC_LOG_HW_LINK_TRAINING("%s: Invalid HW Training pattern: %d\n", __func__, pattern); break; } @@ -184,8 +182,7 @@ static void dpcd_set_lt_pattern_and_lane_settings( dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - dpcd_base_lt_offset] = dpcd_pattern.raw; - dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING, - "%s\n %x pattern = %x\n", + DC_LOG_HW_LINK_TRAINING("%s\n %x pattern = %x\n", __func__, DP_TRAINING_PATTERN_SET, dpcd_pattern.v1_4.TRAINING_PATTERN_SET); @@ -219,8 +216,7 @@ static void dpcd_set_lt_pattern_and_lane_settings( dpcd_lane, size_in_bytes); - dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING, - "%s:\n %x VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n", + DC_LOG_HW_LINK_TRAINING("%s:\n %x VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n", __func__, DP_TRAINING_LANE0_SET, dpcd_lane[0].bits.VOLTAGE_SWING_SET, @@ -456,14 +452,12 @@ static void get_lane_status_and_drive_settings( ln_status_updated->raw = dpcd_buf[2]; - dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING, - "%s:\n%x Lane01Status = %x\n %x Lane23Status = %x\n ", + DC_LOG_HW_LINK_TRAINING("%s:\n%x Lane01Status = %x\n %x Lane23Status = %x\n ", __func__, DP_LANE0_1_STATUS, dpcd_buf[0], DP_LANE2_3_STATUS, dpcd_buf[1]); - dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING, - "%s:\n %x Lane01AdjustRequest = %x\n %x Lane23AdjustRequest = %x\n", + DC_LOG_HW_LINK_TRAINING("%s:\n %x Lane01AdjustRequest = %x\n %x Lane23AdjustRequest = %x\n", __func__, DP_ADJUST_REQUEST_LANE0_1, dpcd_buf[4], @@ -556,8 +550,7 @@ static void dpcd_set_lane_settings( } */ - dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING, - "%s\n %x VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n", + DC_LOG_HW_LINK_TRAINING("%s\n %x VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n", __func__, DP_TRAINING_LANE0_SET, dpcd_lane[0].bits.VOLTAGE_SWING_SET, @@ -669,16 +662,14 @@ static bool perform_post_lt_adj_req_sequence( } if (!req_drv_setting_changed) { - dm_logger_write(link->ctx->logger, LOG_WARNING, - "%s: Post Link Training Adjust Request Timed out\n", + DC_LOG_WARNING("%s: Post Link Training Adjust Request Timed out\n", __func__); ASSERT(0); return true; } } - dm_logger_write(link->ctx->logger, LOG_WARNING, - "%s: Post Link Training Adjust Request limit reached\n", + DC_LOG_WARNING("%s: Post Link Training Adjust Request limit reached\n", __func__); ASSERT(0); @@ -709,6 +700,22 @@ static enum hw_dp_training_pattern get_supported_tp(struct dc_link *link) return HW_DP_TRAINING_PATTERN_2; } +static enum link_training_result get_cr_failure(enum dc_lane_count ln_count, + union lane_status *dpcd_lane_status) +{ + enum link_training_result result = LINK_TRAINING_SUCCESS; + + if (ln_count >= LANE_COUNT_ONE && !dpcd_lane_status[0].bits.CR_DONE_0) + result = LINK_TRAINING_CR_FAIL_LANE0; + else if (ln_count >= LANE_COUNT_TWO && !dpcd_lane_status[1].bits.CR_DONE_0) + result = LINK_TRAINING_CR_FAIL_LANE1; + else if (ln_count >= LANE_COUNT_FOUR && !dpcd_lane_status[2].bits.CR_DONE_0) + result = LINK_TRAINING_CR_FAIL_LANE23; + else if (ln_count >= LANE_COUNT_FOUR && !dpcd_lane_status[3].bits.CR_DONE_0) + result = LINK_TRAINING_CR_FAIL_LANE23; + return result; +} + static enum link_training_result perform_channel_equalization_sequence( struct dc_link *link, struct link_training_settings *lt_settings) @@ -771,7 +778,7 @@ static enum link_training_result perform_channel_equalization_sequence( } -static bool perform_clock_recovery_sequence( +static enum link_training_result perform_clock_recovery_sequence( struct dc_link *link, struct link_training_settings *lt_settings) { @@ -846,11 +853,11 @@ static bool perform_clock_recovery_sequence( /* 5. check CR done*/ if (is_cr_done(lane_count, dpcd_lane_status)) - return true; + return LINK_TRAINING_SUCCESS; /* 6. max VS reached*/ if (is_max_vs_reached(lt_settings)) - return false; + break; /* 7. same voltage*/ /* Note: VS same for all lanes, @@ -869,20 +876,19 @@ static bool perform_clock_recovery_sequence( if (retry_count >= LINK_TRAINING_MAX_CR_RETRY) { ASSERT(0); - dm_logger_write(link->ctx->logger, LOG_ERROR, - "%s: Link Training Error, could not get CR after %d tries. Possibly voltage swing issue", + DC_LOG_ERROR("%s: Link Training Error, could not get CR after %d tries. Possibly voltage swing issue", __func__, LINK_TRAINING_MAX_CR_RETRY); } - return false; + return get_cr_failure(lane_count, dpcd_lane_status); } -static inline bool perform_link_training_int( +static inline enum link_training_result perform_link_training_int( struct dc_link *link, struct link_training_settings *lt_settings, - bool status) + enum link_training_result status) { union lane_count_set lane_count_set = { {0} }; union dpcd_training_pattern dpcd_pattern = { {0} }; @@ -903,9 +909,9 @@ static inline bool perform_link_training_int( get_supported_tp(link) == HW_DP_TRAINING_PATTERN_4) return status; - if (status && + if (status == LINK_TRAINING_SUCCESS && perform_post_lt_adj_req_sequence(link, lt_settings) == false) - status = false; + status = LINK_TRAINING_LQA_FAIL; lane_count_set.bits.LANE_COUNT_SET = lt_settings->link_settings.lane_count; lane_count_set.bits.ENHANCED_FRAMING = 1; @@ -928,6 +934,8 @@ enum link_training_result dc_link_dp_perform_link_training( enum link_training_result status = LINK_TRAINING_SUCCESS; char *link_rate = "Unknown"; + char *lt_result = "Unknown"; + struct link_training_settings lt_settings; memset(<_settings, '\0', sizeof(lt_settings)); @@ -951,22 +959,16 @@ enum link_training_result dc_link_dp_perform_link_training( /* 2. perform link training (set link training done * to false is done as well)*/ - if (!perform_clock_recovery_sequence(link, <_settings)) { - status = LINK_TRAINING_CR_FAIL; - } else { + status = perform_clock_recovery_sequence(link, <_settings); + if (status == LINK_TRAINING_SUCCESS) { status = perform_channel_equalization_sequence(link, <_settings); } if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern) { - if (!perform_link_training_int(link, + status = perform_link_training_int(link, <_settings, - status == LINK_TRAINING_SUCCESS)) { - /* the next link training setting in this case - * would be the same as CR failure case. - */ - status = LINK_TRAINING_CR_FAIL; - } + status); } /* 6. print status message*/ @@ -991,13 +993,37 @@ enum link_training_result dc_link_dp_perform_link_training( break; } + switch (status) { + case LINK_TRAINING_SUCCESS: + lt_result = "pass"; + break; + case LINK_TRAINING_CR_FAIL_LANE0: + lt_result = "CR failed lane0"; + break; + case LINK_TRAINING_CR_FAIL_LANE1: + lt_result = "CR failed lane1"; + break; + case LINK_TRAINING_CR_FAIL_LANE23: + lt_result = "CR failed lane23"; + break; + case LINK_TRAINING_EQ_FAIL_CR: + lt_result = "CR failed in EQ"; + break; + case LINK_TRAINING_EQ_FAIL_EQ: + lt_result = "EQ failed"; + break; + case LINK_TRAINING_LQA_FAIL: + lt_result = "LQA failed"; + break; + default: + break; + } + /* Connectivity log: link training */ CONN_MSG_LT(link, "%sx%d %s VS=%d, PE=%d", link_rate, lt_settings.link_settings.lane_count, - (status == LINK_TRAINING_SUCCESS) ? "pass" : - ((status == LINK_TRAINING_CR_FAIL) ? "CR failed" : - "EQ failed"), + lt_result, lt_settings.lane_settings[0].VOLTAGE_SWING, lt_settings.lane_settings[0].PRE_EMPHASIS); @@ -1115,6 +1141,7 @@ bool dp_hbr_verify_link_cap( dp_cs_id, cur); + if (skip_link_training) success = true; else { @@ -1279,7 +1306,10 @@ static bool decide_fallback_link_setting( return false; switch (training_result) { - case LINK_TRAINING_CR_FAIL: + case LINK_TRAINING_CR_FAIL_LANE0: + case LINK_TRAINING_CR_FAIL_LANE1: + case LINK_TRAINING_CR_FAIL_LANE23: + case LINK_TRAINING_LQA_FAIL: { if (!reached_minimum_link_rate (current_link_setting->link_rate)) { @@ -1290,8 +1320,18 @@ static bool decide_fallback_link_setting( (current_link_setting->lane_count)) { current_link_setting->link_rate = initial_link_settings.link_rate; - current_link_setting->lane_count = - reduce_lane_count( + if (training_result == LINK_TRAINING_CR_FAIL_LANE0) + return false; + else if (training_result == LINK_TRAINING_CR_FAIL_LANE1) + current_link_setting->lane_count = + LANE_COUNT_ONE; + else if (training_result == + LINK_TRAINING_CR_FAIL_LANE23) + current_link_setting->lane_count = + LANE_COUNT_TWO; + else + current_link_setting->lane_count = + reduce_lane_count( current_link_setting->lane_count); } else { return false; @@ -1556,8 +1596,7 @@ static bool hpd_rx_irq_check_link_loss_status( if (sink_status_changed || !hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) { - dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ, - "%s: Link Status changed.\n", __func__); + DC_LOG_HW_HPD_IRQ("%s: Link Status changed.\n", __func__); return_code = true; @@ -1570,8 +1609,7 @@ static bool hpd_rx_irq_check_link_loss_status( sizeof(irq_reg_rx_power_state)); if (dpcd_result != DC_OK) { - dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ, - "%s: DPCD read failed to obtain power state.\n", + DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain power state.\n", __func__); } else { if (irq_reg_rx_power_state != DP_SET_POWER_D0) @@ -1932,8 +1970,7 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd * PSR and device auto test, refer to function handle_sst_hpd_irq * in DAL2.1*/ - dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ, - "%s: Got short pulse HPD on link %d\n", + DC_LOG_HW_HPD_IRQ("%s: Got short pulse HPD on link %d\n", __func__, link->link_index); @@ -1947,8 +1984,7 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd *out_hpd_irq_dpcd_data = hpd_irq_dpcd_data; if (result != DC_OK) { - dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ, - "%s: DPCD read failed to obtain irq data\n", + DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain irq data\n", __func__); return false; } @@ -1966,8 +2002,7 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd } if (!allow_hpd_rx_irq(link)) { - dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ, - "%s: skipping HPD handling on %d\n", + DC_LOG_HW_HPD_IRQ("%s: skipping HPD handling on %d\n", __func__, link->link_index); return false; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c index bae9b0587e12..7c866a7d5e77 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c @@ -279,6 +279,7 @@ void dp_retrain_link_dp_test(struct dc_link *link, for (i = 0; i < MAX_PIPES; i++) { if (pipes[i].stream != NULL && + !pipes[i].top_pipe && pipes[i].stream->sink != NULL && pipes[i].stream->sink->link != NULL && pipes[i].stream_res.stream_enc != NULL && 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 ce0e9e76eb35..b9fc6d842931 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -45,7 +45,8 @@ #include "dcn10/dcn10_resource.h" #endif #include "dce120/dce120_resource.h" - +#define DC_LOGGER \ + ctx->logger enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) { enum dce_version dc_version = DCE_VERSION_UNKNOWN; @@ -834,7 +835,7 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; struct view recout_skip = { 0 }; bool res = false; - + struct dc_context *ctx = pipe_ctx->stream->ctx; /* Important: scaling ratio calculation requires pixel format, * lb depth calculation requires recout and taps require scaling ratios. * Inits require viewport, taps, ratios and recout of split pipe @@ -893,7 +894,7 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) /* May need to re-check lb size after this in some obscure scenario */ calculate_inits_and_adj_vp(pipe_ctx, &recout_skip); - dm_logger_write(pipe_ctx->stream->ctx->logger, LOG_SCALER, + DC_LOG_SCALER( "%s: Viewport:\nheight:%d width:%d x:%d " "y:%d\n dst_rect:\nheight:%d width:%d x:%d " "y:%d\n", @@ -2436,7 +2437,7 @@ static void set_vsc_info_packet( unsigned int i; /*VSC packet set to 2 when DP revision >= 1.2*/ - if (stream->sink->link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) { + if (stream->psr_version != 0) { vscPacketRevision = 2; } 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 87a193ac2883..cd5819789d76 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -198,7 +198,8 @@ bool dc_stream_set_cursor_attributes( for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; - if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp)) + if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.xfm && + !pipe_ctx->plane_res.dpp) || !pipe_ctx->plane_res.ipp) continue; if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) continue; @@ -237,7 +238,8 @@ bool dc_stream_set_cursor_position( if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) || !pipe_ctx->plane_state || - (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp)) + (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp) || + !pipe_ctx->plane_res.ipp) continue; core_dc->hwss.set_cursor_position(pipe_ctx); diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 5bb0e5defaf4..2cd97342bf0f 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.34" +#define DC_VER "3.1.37" #define MAX_SURFACES 3 #define MAX_STREAMS 6 @@ -184,6 +184,17 @@ enum wm_report_mode { WM_REPORT_OVERRIDE = 1, }; +struct dc_clocks { + int dispclk_khz; + int max_dppclk_khz; + int dcfclk_khz; + int socclk_khz; + int dcfclk_deep_sleep_khz; + int fclk_khz; + int dram_ccm_us; + int min_active_dram_ccm_us; +}; + struct dc_debug { bool surface_visual_confirm; bool sanity_checks; @@ -694,7 +705,7 @@ enum dc_irq_source dc_interrupt_to_irq_source( struct dc *dc, uint32_t src_id, uint32_t ext_id); -void dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable); +bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable); void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src); enum dc_irq_source dc_get_hpd_irq_source_at_index( struct dc *dc, uint32_t link_index); diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index ac0f617b43c9..fb4d9eafdc6e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -197,7 +197,7 @@ bool dc_link_dp_set_test_pattern( const unsigned char *p_custom_pattern, unsigned int cust_pattern_size); -void dc_link_disable_hpd_filter(struct dc_link *link); +void dc_link_enable_hpd_filter(struct dc_link *link, bool enable); /* * DPCD access interfaces diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 78a2bbe0b272..f44cd4d87b79 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -70,7 +70,8 @@ struct dc_stream_state { bool ignore_msa_timing_param; /* TODO: custom INFO packets */ /* TODO: ABM info (DMCU) */ - /* TODO: PSR info */ + /* PSR info */ + unsigned char psr_version; /* TODO: CEA VIC */ /* from core_stream struct */ 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 b231bd53613e..fe92a1222803 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c @@ -42,6 +42,8 @@ #define FN(reg_name, field_name) \ abm_dce->abm_shift->field_name, abm_dce->abm_mask->field_name +#define DC_LOGGER \ + abm->ctx->logger #define CTX \ abm_dce->base.ctx @@ -403,8 +405,7 @@ static bool dce_abm_set_backlight_level( { struct dce_abm *abm_dce = TO_DCE_ABM(abm); - dm_logger_write(abm->ctx->logger, LOG_BACKLIGHT, - "New Backlight level: %d (0x%X)\n", + DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", backlight_level, backlight_level); /* If DMCU is in reset state, DMCU is uninitialized */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c index e366bfd7cf6f..6d5cdcdc8ec9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c @@ -33,6 +33,8 @@ #define CTX \ aud->base.ctx +#define DC_LOGGER \ + aud->base.ctx->logger #define REG(reg)\ (aud->regs->reg) @@ -63,8 +65,7 @@ static void write_indirect_azalia_reg(struct audio *audio, REG_SET(AZALIA_F0_CODEC_ENDPOINT_DATA, 0, AZALIA_ENDPOINT_REG_DATA, reg_data); - dm_logger_write(CTX->logger, LOG_HW_AUDIO, - "AUDIO:write_indirect_azalia_reg: index: %u data: %u\n", + DC_LOG_HW_AUDIO("AUDIO:write_indirect_azalia_reg: index: %u data: %u\n", reg_index, reg_data); } @@ -81,8 +82,7 @@ static uint32_t read_indirect_azalia_reg(struct audio *audio, uint32_t reg_index /* AZALIA_F0_CODEC_ENDPOINT_DATA endpoint data */ value = REG_READ(AZALIA_F0_CODEC_ENDPOINT_DATA); - dm_logger_write(CTX->logger, LOG_HW_AUDIO, - "AUDIO:read_indirect_azalia_reg: index: %u data: %u\n", + DC_LOG_HW_AUDIO("AUDIO:read_indirect_azalia_reg: index: %u data: %u\n", reg_index, value); return value; @@ -364,8 +364,7 @@ void dce_aud_az_enable(struct audio *audio) CLOCK_GATING_DISABLE); AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value); - dm_logger_write(CTX->logger, LOG_HW_AUDIO, - "\n\t========= AUDIO:dce_aud_az_enable: index: %u data: 0x%x\n", + DC_LOG_HW_AUDIO("\n\t========= AUDIO:dce_aud_az_enable: index: %u data: 0x%x\n", audio->inst, value); } @@ -390,8 +389,7 @@ void dce_aud_az_disable(struct audio *audio) CLOCK_GATING_DISABLE); AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value); value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL); - dm_logger_write(CTX->logger, LOG_HW_AUDIO, - "\n\t========= AUDIO:dce_aud_az_disable: index: %u data: 0x%x\n", + DC_LOG_HW_AUDIO("\n\t========= AUDIO:dce_aud_az_disable: index: %u data: 0x%x\n", audio->inst, value); } @@ -795,8 +793,7 @@ void dce_aud_wall_dto_setup( crtc_info->calculated_pixel_clock, &clock_info); - dm_logger_write(audio->ctx->logger, LOG_HW_AUDIO,\ - "\n%s:Input::requested_pixel_clock = %d"\ + DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock = %d"\ "calculated_pixel_clock =%d\n"\ "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\ crtc_info->requested_pixel_clock,\ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c index 5036b674f68b..0aa2cda60890 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -41,7 +41,8 @@ #define CTX \ clk_src->base.ctx - +#define DC_LOGGER \ + calc_pll_cs->ctx->logger #undef FN #define FN(reg_name, field_name) \ clk_src->cs_shift->field_name, clk_src->cs_mask->field_name @@ -288,7 +289,7 @@ static uint32_t calculate_pixel_clock_pll_dividers( uint32_t max_ref_divider; if (pll_settings->adjusted_pix_clk == 0) { - dm_logger_write(calc_pll_cs->ctx->logger, LOG_ERROR, + DC_LOG_ERROR( "%s Bad requested pixel clock", __func__); return MAX_PLL_CALC_ERROR; } @@ -349,13 +350,13 @@ static uint32_t calculate_pixel_clock_pll_dividers( * ## SVS Wed 15 Jul 2009 */ if (min_post_divider > max_post_divider) { - dm_logger_write(calc_pll_cs->ctx->logger, LOG_ERROR, + DC_LOG_ERROR( "%s Post divider range is invalid", __func__); return MAX_PLL_CALC_ERROR; } if (min_ref_divider > max_ref_divider) { - dm_logger_write(calc_pll_cs->ctx->logger, LOG_ERROR, + DC_LOG_ERROR( "%s Reference divider range is invalid", __func__); return MAX_PLL_CALC_ERROR; } @@ -466,7 +467,7 @@ static uint32_t dce110_get_pix_clk_dividers_helper ( { uint32_t field = 0; uint32_t pll_calc_error = MAX_PLL_CALC_ERROR; - + struct calc_pll_clock_source *calc_pll_cs = &clk_src->calc_pll; /* Check if reference clock is external (not pcie/xtalin) * HW Dce80 spec: * 00 - PCIE_REFCLK, 01 - XTALIN, 02 - GENERICA, 03 - GENERICB @@ -493,7 +494,7 @@ static uint32_t dce110_get_pix_clk_dividers_helper ( if (!pll_adjust_pix_clk(clk_src, pix_clk_params, pll_settings)) { /* Should never happen, ASSERT and fill up values to be able * to continue. */ - dm_logger_write(clk_src->base.ctx->logger, LOG_ERROR, + DC_LOG_ERROR( "%s: Failed to adjust pixel clock!!", __func__); pll_settings->actual_pix_clk = pix_clk_params->requested_pix_clk; @@ -556,11 +557,12 @@ static uint32_t dce110_get_pix_clk_dividers( struct pll_settings *pll_settings) { struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs); + struct calc_pll_clock_source *calc_pll_cs = &clk_src->calc_pll; uint32_t pll_calc_error = MAX_PLL_CALC_ERROR; if (pix_clk_params == NULL || pll_settings == NULL || pix_clk_params->requested_pix_clk == 0) { - dm_logger_write(clk_src->base.ctx->logger, LOG_ERROR, + DC_LOG_ERROR( "%s: Invalid parameters!!\n", __func__); return pll_calc_error; } @@ -1052,14 +1054,14 @@ static void get_ss_info_from_atombios( struct spread_spectrum_info *ss_info_cur; struct spread_spectrum_data *ss_data_cur; uint32_t i; - + struct calc_pll_clock_source *calc_pll_cs = &clk_src->calc_pll; if (ss_entries_num == NULL) { - dm_logger_write(clk_src->base.ctx->logger, LOG_SYNC, + DC_LOG_SYNC( "Invalid entry !!!\n"); return; } if (spread_spectrum_data == NULL) { - dm_logger_write(clk_src->base.ctx->logger, LOG_SYNC, + DC_LOG_SYNC( "Invalid array pointer!!!\n"); return; } @@ -1104,7 +1106,7 @@ static void get_ss_info_from_atombios( ++i, ++ss_info_cur, ++ss_data_cur) { if (ss_info_cur->type.STEP_AND_DELAY_INFO != false) { - dm_logger_write(clk_src->base.ctx->logger, LOG_SYNC, + DC_LOG_SYNC( "Invalid ATOMBIOS SS Table!!!\n"); goto out_free_data; } @@ -1114,9 +1116,9 @@ static void get_ss_info_from_atombios( if (as_signal == AS_SIGNAL_TYPE_HDMI && ss_info_cur->spread_spectrum_percentage > 6){ /* invalid input, do nothing */ - dm_logger_write(clk_src->base.ctx->logger, LOG_SYNC, + DC_LOG_SYNC( "Invalid SS percentage "); - dm_logger_write(clk_src->base.ctx->logger, LOG_SYNC, + DC_LOG_SYNC( "for HDMI in ATOMBIOS info Table!!!\n"); continue; } @@ -1228,12 +1230,12 @@ static bool calc_pll_max_vco_construct( if (init_data->num_fract_fb_divider_decimal_point == 0 || init_data->num_fract_fb_divider_decimal_point_precision > init_data->num_fract_fb_divider_decimal_point) { - dm_logger_write(calc_pll_cs->ctx->logger, LOG_ERROR, + DC_LOG_ERROR( "The dec point num or precision is incorrect!"); return false; } if (init_data->num_fract_fb_divider_decimal_point_precision == 0) { - dm_logger_write(calc_pll_cs->ctx->logger, LOG_ERROR, + DC_LOG_ERROR( "Incorrect fract feedback divider precision num!"); return false; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 046658c8498a..78e6beb6cf26 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -49,6 +49,8 @@ #define CTX \ clk_dce->base.ctx +#define DC_LOGGER \ + clk->ctx->logger /* Max clock values for each state indexed by "enum clocks_state": */ static const struct state_dependent_clocks dce80_max_clks_by_state[] = { @@ -292,8 +294,7 @@ static enum dm_pp_clocks_state dce_get_required_clocks_state( low_req_clk = i + 1; if (low_req_clk > clk->max_clks_state) { - dm_logger_write(clk->ctx->logger, LOG_WARNING, - "%s: clocks unsupported disp_clk %d pix_clk %d", + DC_LOG_WARNING("%s: clocks unsupported disp_clk %d pix_clk %d", __func__, req_clocks->display_clk_khz, req_clocks->pixel_clk_khz); @@ -312,8 +313,7 @@ static bool dce_clock_set_min_clocks_state( if (clocks_state > clk->max_clks_state) { /*Requested state exceeds max supported state.*/ - dm_logger_write(clk->ctx->logger, LOG_WARNING, - "Requested state exceeds max supported state"); + DC_LOG_WARNING("Requested state exceeds max supported state"); return false; } else if (clocks_state == clk->cur_min_clks_state) { /*if we're trying to set the same state, we can just return diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 11f50588b3f4..81776e4797ed 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -56,6 +56,8 @@ #define CTX \ enc110->base.ctx +#define DC_LOGGER \ + enc110->base.ctx->logger #define REG(reg)\ (enc110->link_regs->reg) @@ -676,6 +678,7 @@ void dce110_link_encoder_construct( { struct bp_encoder_cap_info bp_cap_info = {0}; const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs; + enum bp_result result = BP_RESULT_OK; enc110->base.funcs = &dce110_lnk_enc_funcs; enc110->base.ctx = init_data->ctx; @@ -750,15 +753,24 @@ void dce110_link_encoder_construct( enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; } + /* default to one to mirror Windows behavior */ + enc110->base.features.flags.bits.HDMI_6GB_EN = 1; + + result = bp_funcs->get_encoder_cap_info(enc110->base.ctx->dc_bios, + enc110->base.id, &bp_cap_info); + /* Override features with DCE-specific values */ - if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info( - enc110->base.ctx->dc_bios, enc110->base.id, - &bp_cap_info)) { + if (BP_RESULT_OK == result) { enc110->base.features.flags.bits.IS_HBR2_CAPABLE = bp_cap_info.DP_HBR2_EN; enc110->base.features.flags.bits.IS_HBR3_CAPABLE = bp_cap_info.DP_HBR3_EN; enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; + } else { + dm_logger_write(enc110->base.ctx->logger, LOG_WARNING, + "%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", + __func__, + result); } } @@ -809,7 +821,6 @@ void dce110_link_encoder_hw_init( struct link_encoder *enc) { struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); - struct dc_context *ctx = enc110->base.ctx; struct bp_transmitter_control cntl = { 0 }; enum bp_result result; @@ -827,8 +838,7 @@ void dce110_link_encoder_hw_init( result = link_transmitter_control(enc110, &cntl); if (result != BP_RESULT_OK) { - dm_logger_write(ctx->logger, LOG_ERROR, - "%s: Failed to execute VBIOS command table!\n", + DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", __func__); BREAK_TO_DEBUGGER(); return; @@ -904,7 +914,6 @@ void dce110_link_encoder_enable_tmds_output( uint32_t pixel_clock) { struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); - struct dc_context *ctx = enc110->base.ctx; struct bp_transmitter_control cntl = { 0 }; enum bp_result result; @@ -928,8 +937,7 @@ void dce110_link_encoder_enable_tmds_output( result = link_transmitter_control(enc110, &cntl); if (result != BP_RESULT_OK) { - dm_logger_write(ctx->logger, LOG_ERROR, - "%s: Failed to execute VBIOS command table!\n", + DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", __func__); BREAK_TO_DEBUGGER(); } @@ -942,7 +950,6 @@ void dce110_link_encoder_enable_dp_output( enum clock_source_id clock_source) { struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); - struct dc_context *ctx = enc110->base.ctx; struct bp_transmitter_control cntl = { 0 }; enum bp_result result; @@ -969,8 +976,7 @@ void dce110_link_encoder_enable_dp_output( result = link_transmitter_control(enc110, &cntl); if (result != BP_RESULT_OK) { - dm_logger_write(ctx->logger, LOG_ERROR, - "%s: Failed to execute VBIOS command table!\n", + DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", __func__); BREAK_TO_DEBUGGER(); } @@ -983,7 +989,6 @@ void dce110_link_encoder_enable_dp_mst_output( enum clock_source_id clock_source) { struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); - struct dc_context *ctx = enc110->base.ctx; struct bp_transmitter_control cntl = { 0 }; enum bp_result result; @@ -1010,8 +1015,7 @@ void dce110_link_encoder_enable_dp_mst_output( result = link_transmitter_control(enc110, &cntl); if (result != BP_RESULT_OK) { - dm_logger_write(ctx->logger, LOG_ERROR, - "%s: Failed to execute VBIOS command table!\n", + DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", __func__); BREAK_TO_DEBUGGER(); } @@ -1025,7 +1029,6 @@ void dce110_link_encoder_disable_output( enum signal_type signal) { struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); - struct dc_context *ctx = enc110->base.ctx; struct bp_transmitter_control cntl = { 0 }; enum bp_result result; @@ -1053,8 +1056,7 @@ void dce110_link_encoder_disable_output( result = link_transmitter_control(enc110, &cntl); if (result != BP_RESULT_OK) { - dm_logger_write(ctx->logger, LOG_ERROR, - "%s: Failed to execute VBIOS command table!\n", + DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", __func__); BREAK_TO_DEBUGGER(); return; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c index 8146b9079d51..444558ca6533 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c @@ -26,7 +26,8 @@ #include "dc_bios_types.h" #include "dce_stream_encoder.h" #include "reg_helper.h" - +#define DC_LOGGER \ + enc110->base.ctx->logger enum DP_PIXEL_ENCODING { DP_PIXEL_ENCODING_RGB444 = 0x00000000, DP_PIXEL_ENCODING_YCBCR422 = 0x00000001, @@ -197,7 +198,6 @@ static void dce110_update_hdmi_info_packet( uint32_t packet_index, const struct encoder_info_packet *info_packet) { - struct dc_context *ctx = enc110->base.ctx; uint32_t cont, send, line; if (info_packet->valid) { @@ -277,8 +277,7 @@ static void dce110_update_hdmi_info_packet( #endif default: /* invalid HW packet index */ - dm_logger_write( - ctx->logger, LOG_WARNING, + DC_LOG_WARNING( "Invalid HW packet index: %s()\n", __func__); return; @@ -1386,7 +1385,7 @@ static void dce110_se_setup_hdmi_audio( crtc_info->requested_pixel_clock, crtc_info->calculated_pixel_clock, &audio_clock_info); - dm_logger_write(enc->ctx->logger, LOG_HW_AUDIO, + DC_LOG_HW_AUDIO( "\n%s:Input::requested_pixel_clock = %d" \ "calculated_pixel_clock = %d \n", __func__, \ crtc_info->requested_pixel_clock, \ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c index ad411dac5639..832c5daada35 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c @@ -38,6 +38,8 @@ #define CTX \ xfm_dce->base.ctx +#define DC_LOGGER \ + xfm_dce->base.ctx->logger #define IDENTITY_RATIO(ratio) (dal_fixed31_32_u2d19(ratio) == (1 << 19)) #define GAMUT_MATRIX_SIZE 12 @@ -693,8 +695,7 @@ static int dce_transform_get_max_num_of_supported_lines( break; default: - dm_logger_write(xfm_dce->base.ctx->logger, LOG_WARNING, - "%s: Invalid LB pixel depth", + DC_LOG_WARNING("%s: Invalid LB pixel depth", __func__); BREAK_TO_DEBUGGER(); break; @@ -791,8 +792,7 @@ static void dce_transform_set_pixel_storage_depth( if (!(xfm_dce->lb_pixel_depth_supported & depth)) { /*we should use unsupported capabilities * unless it is required by w/a*/ - dm_logger_write(xfm->ctx->logger, LOG_WARNING, - "%s: Capability not supported", + DC_LOG_WARNING("%s: Capability not supported", __func__); } } @@ -1172,8 +1172,7 @@ static void program_pwl(struct dce_transform *xfm_dce, } if (counter == max_tries) { - dm_logger_write(xfm_dce->base.ctx->logger, LOG_WARNING, - "%s: regamma lut was not powered on " + DC_LOG_WARNING("%s: regamma lut was not powered on " "in a timely manner," " programming still proceeds\n", __func__); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.h b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.h index bfc94b4927b9..948281d8b6af 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.h @@ -248,6 +248,7 @@ XFM_SF(DCP0_REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, mask_sh),\ XFM_SF(DCP0_REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, mask_sh),\ XFM_SF(DCP0_REGAMMA_CONTROL, GRPH_REGAMMA_MODE, mask_sh),\ + XFM_SF(DCP0_REGAMMA_LUT_WRITE_EN_MASK, REGAMMA_LUT_WRITE_EN_MASK, mask_sh),\ XFM_SF(SCL0_SCL_MODE, SCL_MODE, mask_sh), \ XFM_SF(SCL0_SCL_TAP_CONTROL, SCL_H_NUM_OF_TAPS, mask_sh), \ XFM_SF(SCL0_SCL_TAP_CONTROL, SCL_V_NUM_OF_TAPS, mask_sh), \ diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c index 6923662413cd..775d3bf0bd39 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c @@ -34,6 +34,8 @@ #include "dce110_compressor.h" +#define DC_LOGGER \ + cp110->base.ctx->logger #define DCP_REG(reg)\ (reg + cp110->offsets.dcp_offset) #define DMIF_REG(reg)\ @@ -120,14 +122,10 @@ static void wait_for_fbc_state_changed( } if (counter == 10) { - dm_logger_write( - cp110->base.ctx->logger, LOG_WARNING, - "%s: wait counter exceeded, changes to HW not applied", + DC_LOG_WARNING("%s: wait counter exceeded, changes to HW not applied", __func__); } else { - dm_logger_write( - cp110->base.ctx->logger, LOG_SYNC, - "FBC status changed to %d", enabled); + DC_LOG_SYNC("FBC status changed to %d", enabled); } @@ -310,9 +308,7 @@ void dce110_compressor_program_compressed_surface_address_and_pitch( if (compressor->min_compress_ratio == FBC_COMPRESS_RATIO_1TO1) fbc_pitch = fbc_pitch / 8; else - dm_logger_write( - compressor->ctx->logger, LOG_WARNING, - "%s: Unexpected DCE11 compression ratio", + DC_LOG_WARNING("%s: Unexpected DCE11 compression ratio", __func__); /* Clear content first. */ 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 0422c72a7579..c2041a63cccd 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 @@ -70,6 +70,8 @@ #define CTX \ hws->ctx +#define DC_LOGGER \ + ctx->logger #define REG(reg)\ hws->regs->reg @@ -682,15 +684,22 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx) struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; struct dc_link *link = pipe_ctx->stream->sink->link; - /* 1. update AVI info frame (HDMI, DP) - * we always need to update info frame - */ + uint32_t active_total_with_borders; uint32_t early_control = 0; struct timing_generator *tg = pipe_ctx->stream_res.tg; - /* TODOFPGA may change to hwss.update_info_frame */ + /* For MST, there are multiply stream go to only one link. + * connect DIG back_end to front_end while enable_stream and + * disconnect them during disable_stream + * BY this, it is logic clean to separate stream and link */ + link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, + pipe_ctx->stream_res.stream_enc->id, true); + + /* update AVI info frame (HDMI, DP)*/ + /* TODO: FPGA may change to hwss.update_info_frame */ dce110_update_info_frame(pipe_ctx); + /* enable early control to avoid corruption on DP monitor*/ active_total_with_borders = timing->h_addressable @@ -711,12 +720,8 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx) pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc); } - /* For MST, there are multiply stream go to only one link. - * connect DIG back_end to front_end while enable_stream and - * disconnect them during disable_stream - * BY this, it is logic clean to separate stream and link */ - link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, - pipe_ctx->stream_res.stream_enc->id, true); + + } @@ -816,7 +821,7 @@ void hwss_edp_wait_for_hpd_ready( dal_gpio_destroy_irq(&hpd); if (false == edp_hpd_high) { - dm_logger_write(ctx->logger, LOG_ERROR, + DC_LOG_ERROR( "%s: wait timed out!\n", __func__); } } @@ -840,7 +845,7 @@ void hwss_edp_power_control( if (power_up != is_panel_powered_on(hwseq)) { /* Send VBIOS command to prompt eDP panel power */ - dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, + DC_LOG_HW_RESUME_S3( "%s: Panel Power action: %s\n", __func__, (power_up ? "On":"Off")); @@ -856,11 +861,11 @@ void hwss_edp_power_control( bp_result = link_transmitter_control(ctx->dc_bios, &cntl); if (bp_result != BP_RESULT_OK) - dm_logger_write(ctx->logger, LOG_ERROR, + DC_LOG_ERROR( "%s: Panel Power bp_result: %d\n", __func__, bp_result); } else { - dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, + DC_LOG_HW_RESUME_S3( "%s: Skipping Panel Power action: %s\n", __func__, (power_up ? "On":"Off")); } @@ -886,7 +891,7 @@ void hwss_edp_backlight_control( } if (enable && is_panel_backlight_on(hws)) { - dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, + DC_LOG_HW_RESUME_S3( "%s: panel already powered up. Do nothing.\n", __func__); return; @@ -894,7 +899,7 @@ void hwss_edp_backlight_control( /* Send VBIOS command to control eDP panel backlight */ - dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, + DC_LOG_HW_RESUME_S3( "%s: backlight action: %s\n", __func__, (enable ? "On":"Off")); @@ -1320,10 +1325,8 @@ static enum dc_status apply_single_controller_ctx_to_hw( resource_build_info_frame(pipe_ctx); dce110_update_info_frame(pipe_ctx); - if (!pipe_ctx_old->stream) { - if (!pipe_ctx->stream->dpms_off) - core_link_enable_stream(context, pipe_ctx); - } + if (!pipe_ctx_old->stream) + core_link_enable_stream(context, pipe_ctx); pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; @@ -2689,7 +2692,7 @@ static void dce110_program_front_end_for_pipe( struct xfm_grph_csc_adjustment adjust; struct out_csc_color_matrix tbl_entry; unsigned int i; - + struct dc_context *ctx = dc->ctx; memset(&tbl_entry, 0, sizeof(tbl_entry)); if (dc->current_state) @@ -2764,7 +2767,7 @@ static void dce110_program_front_end_for_pipe( if (pipe_ctx->plane_state->update_flags.bits.full_update) dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream); - dm_logger_write(dc->ctx->logger, LOG_SURFACE, + DC_LOG_SURFACE( "Pipe:%d 0x%x: addr hi:0x%x, " "addr low:0x%x, " "src: %d, %d, %d," @@ -2787,7 +2790,7 @@ static void dce110_program_front_end_for_pipe( pipe_ctx->plane_state->clip_rect.width, pipe_ctx->plane_state->clip_rect.height); - dm_logger_write(dc->ctx->logger, LOG_SURFACE, + DC_LOG_SURFACE( "Pipe %d: width, height, x, y\n" "viewport:%d, %d, %d, %d\n" "recout: %d, %d, %d, %d\n", diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index c4e877ac95d3..b1f14be20fdf 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -52,6 +52,8 @@ #include "dce/dce_abm.h" #include "dce/dce_dmcu.h" +#define DC_LOGGER \ + dc->ctx->logger #if defined(CONFIG_DRM_AMD_DC_FBC) #include "dce110/dce110_compressor.h" #endif @@ -771,8 +773,7 @@ static bool dce110_validate_bandwidth( { bool result = false; - dm_logger_write( - dc->ctx->logger, LOG_BANDWIDTH_CALCS, + DC_LOG_BANDWIDTH_CALCS( "%s: start", __func__); @@ -786,8 +787,7 @@ static bool dce110_validate_bandwidth( result = true; if (!result) - dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_VALIDATION, - "%s: %dx%d@%d Bandwidth validation failed!\n", + DC_LOG_BANDWIDTH_VALIDATION("%s: %dx%d@%d Bandwidth validation failed!\n", __func__, context->streams[0]->timing.h_addressable, context->streams[0]->timing.v_addressable, @@ -846,6 +846,16 @@ static bool dce110_validate_bandwidth( return result; } +enum dc_status dce110_validate_plane(const struct dc_plane_state *plane_state, + struct dc_caps *caps) +{ + if (((plane_state->dst_rect.width * 2) < plane_state->src_rect.width) || + ((plane_state->dst_rect.height * 2) < plane_state->src_rect.height)) + return DC_FAIL_SURFACE_VALIDATE; + + return DC_OK; +} + static bool dce110_validate_surface_sets( struct dc_state *context) { @@ -869,6 +879,13 @@ static bool dce110_validate_surface_sets( plane->src_rect.height > 1080)) return false; + /* we don't have the logic to support underlay + * only yet so block the use case where we get + * NV12 plane as top layer + */ + if (j == 0) + return false; + /* irrespective of plane format, * stream should be RGB encoded */ @@ -1021,6 +1038,7 @@ static const struct resource_funcs dce110_res_pool_funcs = { .link_enc_create = dce110_link_encoder_create, .validate_guaranteed = dce110_validate_guaranteed, .validate_bandwidth = dce110_validate_bandwidth, + .validate_plane = dce110_validate_plane, .acquire_idle_pipe_for_layer = dce110_acquire_underlay, .add_stream_to_ctx = dce110_add_stream_to_ctx, .validate_global = dce110_validate_global diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c index 59b4cd329715..8ad04816e7d3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c @@ -38,6 +38,8 @@ #include "timing_generator.h" +#define DC_LOGGER \ + tg->ctx->logger /** ******************************************************************************** * * DCE11 Timing Generator Implementation @@ -606,8 +608,7 @@ static uint32_t dce110_timing_generator_v_get_vblank_counter(struct timing_gener static bool dce110_timing_generator_v_did_triggered_reset_occur( struct timing_generator *tg) { - dm_logger_write(tg->ctx->logger, LOG_ERROR, - "Timing Sync not supported on underlay pipe\n"); + DC_LOG_ERROR("Timing Sync not supported on underlay pipe\n"); return false; } @@ -615,8 +616,7 @@ static void dce110_timing_generator_v_setup_global_swap_lock( struct timing_generator *tg, const struct dcp_gsl_params *gsl_params) { - dm_logger_write(tg->ctx->logger, LOG_ERROR, - "Timing Sync not supported on underlay pipe\n"); + DC_LOG_ERROR("Timing Sync not supported on underlay pipe\n"); return; } @@ -624,24 +624,21 @@ static void dce110_timing_generator_v_enable_reset_trigger( struct timing_generator *tg, int source_tg_inst) { - dm_logger_write(tg->ctx->logger, LOG_ERROR, - "Timing Sync not supported on underlay pipe\n"); + DC_LOG_ERROR("Timing Sync not supported on underlay pipe\n"); return; } static void dce110_timing_generator_v_disable_reset_trigger( struct timing_generator *tg) { - dm_logger_write(tg->ctx->logger, LOG_ERROR, - "Timing Sync not supported on underlay pipe\n"); + DC_LOG_ERROR("Timing Sync not supported on underlay pipe\n"); return; } static void dce110_timing_generator_v_tear_down_global_swap_lock( struct timing_generator *tg) { - dm_logger_write(tg->ctx->logger, LOG_ERROR, - "Timing Sync not supported on underlay pipe\n"); + DC_LOG_ERROR("Timing Sync not supported on underlay pipe\n"); return; } diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c index 47390dc58306..8ba3c12fc608 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c @@ -30,6 +30,8 @@ #include "dce/dce_11_0_sh_mask.h" #define SCLV_PHASES 64 +#define DC_LOGGER \ + xfm->ctx->logger struct sclv_ratios_inits { uint32_t h_int_scale_ratio_luma; @@ -670,8 +672,7 @@ static void dce110_xfmv_set_pixel_storage_depth( if (!(xfm_dce->lb_pixel_depth_supported & depth)) { /*we should use unsupported capabilities * unless it is required by w/a*/ - dm_logger_write(xfm->ctx->logger, LOG_WARNING, - "%s: Capability not supported", + DC_LOG_WARNING("%s: Capability not supported", __func__); } } diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_compressor.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_compressor.c index 69649928768c..faae12cf7968 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_compressor.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_compressor.c @@ -33,7 +33,8 @@ #include "include/logger_interface.h" #include "dce112_compressor.h" - +#define DC_LOGGER \ + cp110->base.ctx->logger #define DCP_REG(reg)\ (reg + cp110->offsets.dcp_offset) #define DMIF_REG(reg)\ @@ -129,8 +130,7 @@ static uint32_t lpt_memory_control_config(struct dce112_compressor *cp110, LOW_POWER_TILING_NUM_PIPES); break; default: - dm_logger_write( - cp110->base.ctx->logger, LOG_WARNING, + DC_LOG_WARNING( "%s: Invalid LPT NUM_PIPES!!!", __func__); break; @@ -175,8 +175,7 @@ static uint32_t lpt_memory_control_config(struct dce112_compressor *cp110, LOW_POWER_TILING_NUM_BANKS); break; default: - dm_logger_write( - cp110->base.ctx->logger, LOG_WARNING, + DC_LOG_WARNING( "%s: Invalid LPT NUM_BANKS!!!", __func__); break; @@ -209,8 +208,7 @@ static uint32_t lpt_memory_control_config(struct dce112_compressor *cp110, LOW_POWER_TILING_PIPE_INTERLEAVE_SIZE); break; default: - dm_logger_write( - cp110->base.ctx->logger, LOG_WARNING, + DC_LOG_WARNING( "%s: Invalid LPT INTERLEAVE_SIZE!!!", __func__); break; @@ -253,15 +251,13 @@ static uint32_t lpt_memory_control_config(struct dce112_compressor *cp110, LOW_POWER_TILING_ROW_SIZE); break; default: - dm_logger_write( - cp110->base.ctx->logger, LOG_WARNING, + DC_LOG_WARNING( "%s: Invalid LPT ROW_SIZE!!!", __func__); break; } } else { - dm_logger_write( - cp110->base.ctx->logger, LOG_WARNING, + DC_LOG_WARNING( "%s: LPT MC Configuration is not provided", __func__); } @@ -311,8 +307,7 @@ static void wait_for_fbc_state_changed( } if (counter == 10) { - dm_logger_write( - cp110->base.ctx->logger, LOG_WARNING, + DC_LOG_WARNING( "%s: wait counter exceeded, changes to HW not applied", __func__); } @@ -525,8 +520,7 @@ void dce112_compressor_program_compressed_surface_address_and_pitch( if (compressor->min_compress_ratio == FBC_COMPRESS_RATIO_1TO1) fbc_pitch = fbc_pitch / 8; else - dm_logger_write( - compressor->ctx->logger, LOG_WARNING, + DC_LOG_WARNING( "%s: Unexpected DCE11 compression ratio", __func__); @@ -690,8 +684,7 @@ void dce112_compressor_program_lpt_control( LOW_POWER_TILING_MODE); break; default: - dm_logger_write( - compressor->ctx->logger, LOG_WARNING, + DC_LOG_WARNING( "%s: Invalid selected DRAM channels for LPT!!!", __func__); break; diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index c0757dd6c03c..cd1e3f72c44e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -56,6 +56,8 @@ #include "dce/dce_11_2_sh_mask.h" #include "dce100/dce100_resource.h" +#define DC_LOGGER \ + dc->ctx->logger #ifndef mmDP_DPHY_INTERNAL_CTRL #define mmDP_DPHY_INTERNAL_CTRL 0x4aa7 @@ -722,8 +724,7 @@ bool dce112_validate_bandwidth( { bool result = false; - dm_logger_write( - dc->ctx->logger, LOG_BANDWIDTH_CALCS, + DC_LOG_BANDWIDTH_CALCS( "%s: start", __func__); @@ -737,7 +738,7 @@ bool dce112_validate_bandwidth( result = true; if (!result) - dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_VALIDATION, + DC_LOG_BANDWIDTH_VALIDATION( "%s: Bandwidth validation failed!", __func__); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c index b3db6397d353..881a1bff94d2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c @@ -416,3 +416,156 @@ bool cm_helper_translate_curve_to_hw_format( return true; } + +#define NUM_DEGAMMA_REGIONS 12 + + +bool cm_helper_translate_curve_to_degamma_hw_format( + const struct dc_transfer_func *output_tf, + struct pwl_params *lut_params) +{ + struct curve_points *arr_points; + struct pwl_result_data *rgb_resulted; + struct pwl_result_data *rgb; + struct pwl_result_data *rgb_plus_1; + struct fixed31_32 y_r; + struct fixed31_32 y_g; + struct fixed31_32 y_b; + struct fixed31_32 y1_min; + struct fixed31_32 y3_max; + + int32_t region_start, region_end; + int32_t i; + uint32_t j, k, seg_distr[MAX_REGIONS_NUMBER], increment, start_index, hw_points; + + if (output_tf == NULL || lut_params == NULL || output_tf->type == TF_TYPE_BYPASS) + return false; + + PERF_TRACE(); + + arr_points = lut_params->arr_points; + rgb_resulted = lut_params->rgb_resulted; + hw_points = 0; + + memset(lut_params, 0, sizeof(struct pwl_params)); + memset(seg_distr, 0, sizeof(seg_distr)); + + region_start = -NUM_DEGAMMA_REGIONS; + region_end = 0; + + + for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) + seg_distr[i] = -1; + /* 12 segments + * segments are from 2^-12 to 0 + */ + for (i = 0; i < NUM_DEGAMMA_REGIONS ; i++) + seg_distr[i] = 4; + + for (k = 0; k < MAX_REGIONS_NUMBER; k++) { + if (seg_distr[k] != -1) + hw_points += (1 << seg_distr[k]); + } + + j = 0; + for (k = 0; k < (region_end - region_start); k++) { + increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); + start_index = (region_start + k + MAX_LOW_POINT) * + NUMBER_SW_SEGMENTS; + for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS; + i += increment) { + if (j == hw_points - 1) + break; + rgb_resulted[j].red = output_tf->tf_pts.red[i]; + rgb_resulted[j].green = output_tf->tf_pts.green[i]; + rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; + j++; + } + } + + /* last point */ + start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS; + rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index]; + rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; + rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; + + arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), + dal_fixed31_32_from_int(region_start)); + arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), + dal_fixed31_32_from_int(region_end)); + + y_r = rgb_resulted[0].red; + y_g = rgb_resulted[0].green; + y_b = rgb_resulted[0].blue; + + y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b)); + + arr_points[0].y = y1_min; + arr_points[0].slope = dal_fixed31_32_div(arr_points[0].y, arr_points[0].x); + y_r = rgb_resulted[hw_points - 1].red; + y_g = rgb_resulted[hw_points - 1].green; + y_b = rgb_resulted[hw_points - 1].blue; + + /* see comment above, m_arrPoints[1].y should be the Y value for the + * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) + */ + y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b)); + + arr_points[1].y = y3_max; + + arr_points[1].slope = dal_fixed31_32_zero; + + if (output_tf->tf == TRANSFER_FUNCTION_PQ) { + /* for PQ, we want to have a straight line from last HW X point, + * and the slope to be such that we hit 1.0 at 10000 nits. + */ + const struct fixed31_32 end_value = + dal_fixed31_32_from_int(125); + + arr_points[1].slope = dal_fixed31_32_div( + dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y), + dal_fixed31_32_sub(end_value, arr_points[1].x)); + } + + lut_params->hw_points_num = hw_points; + + i = 1; + for (k = 0; k < MAX_REGIONS_NUMBER && i < MAX_REGIONS_NUMBER; k++) { + if (seg_distr[k] != -1) { + lut_params->arr_curve_points[k].segments_num = + seg_distr[k]; + lut_params->arr_curve_points[i].offset = + lut_params->arr_curve_points[k].offset + (1 << seg_distr[k]); + } + i++; + } + + if (seg_distr[k] != -1) + lut_params->arr_curve_points[k].segments_num = seg_distr[k]; + + rgb = rgb_resulted; + rgb_plus_1 = rgb_resulted + 1; + + i = 1; + while (i != hw_points + 1) { + if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red)) + rgb_plus_1->red = rgb->red; + if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green)) + rgb_plus_1->green = rgb->green; + if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue)) + rgb_plus_1->blue = rgb->blue; + + rgb->delta_red = dal_fixed31_32_sub(rgb_plus_1->red, rgb->red); + rgb->delta_green = dal_fixed31_32_sub(rgb_plus_1->green, rgb->green); + rgb->delta_blue = dal_fixed31_32_sub(rgb_plus_1->blue, rgb->blue); + + ++rgb_plus_1; + ++rgb; + ++i; + } + cm_helper_convert_to_custom_float(rgb_resulted, + lut_params->arr_points, + hw_points, false); + + return true; +} diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h index 64e476b83bcb..7a531b02871f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h @@ -106,4 +106,9 @@ bool cm_helper_translate_curve_to_hw_format( const struct dc_transfer_func *output_tf, struct pwl_params *lut_params, bool fixpoint); +bool cm_helper_translate_curve_to_degamma_hw_format( + const struct dc_transfer_func *output_tf, + struct pwl_params *lut_params); + + #endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index 8725cab9ec00..f0b798930b51 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c @@ -432,14 +432,12 @@ void dpp1_dppclk_control( struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); if (enable) { - if (dpp->tf_mask->DPPCLK_RATE_CONTROL) { + if (dpp->tf_mask->DPPCLK_RATE_CONTROL) REG_UPDATE_2(DPP_CONTROL, DPPCLK_RATE_CONTROL, dppclk_div, DPP_CLOCK_ENABLE, 1); - } else { - ASSERT(dppclk_div == false); + else REG_UPDATE(DPP_CONTROL, DPP_CLOCK_ENABLE, 1); - } } else REG_UPDATE(DPP_CONTROL, DPP_CLOCK_ENABLE, 0); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c index eb8317187f30..738f67ffd1b4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c @@ -30,6 +30,8 @@ #define CTX \ hubbub->ctx +#define DC_LOGGER \ + hubbub->ctx->logger #define REG(reg)\ hubbub->regs->reg @@ -100,7 +102,6 @@ bool hubbub1_verify_allow_pstate_change_high( static unsigned int max_sampled_pstate_wait_us; /* data collection */ static bool forced_pstate_allow; /* help with revert wa */ - unsigned int debug_index = 0x7; unsigned int debug_data; unsigned int i; @@ -115,7 +116,9 @@ bool hubbub1_verify_allow_pstate_change_high( forced_pstate_allow = false; } - /* description "3-0: Pipe0 cursor0 QOS + /* RV1: + * dchubbubdebugind, at: 0x7 + * description "3-0: Pipe0 cursor0 QOS * 7-4: Pipe1 cursor0 QOS * 11-8: Pipe2 cursor0 QOS * 15-12: Pipe3 cursor0 QOS @@ -137,7 +140,8 @@ bool hubbub1_verify_allow_pstate_change_high( * 31: SOC pstate change request */ - REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, debug_index); + + REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, hubbub->debug_test_index_pstate); for (i = 0; i < pstate_wait_timeout_us; i++) { debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA); @@ -145,8 +149,7 @@ bool hubbub1_verify_allow_pstate_change_high( if (debug_data & (1 << 30)) { if (i > pstate_wait_expected_timeout_us) - dm_logger_write(hubbub->ctx->logger, LOG_WARNING, - "pstate took longer than expected ~%dus\n", + DC_LOG_WARNING("pstate took longer than expected ~%dus\n", i); return true; @@ -165,8 +168,7 @@ bool hubbub1_verify_allow_pstate_change_high( DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1); forced_pstate_allow = true; - dm_logger_write(hubbub->ctx->logger, LOG_WARNING, - "pstate TEST_DEBUG_DATA: 0x%X\n", + DC_LOG_WARNING("pstate TEST_DEBUG_DATA: 0x%X\n", debug_data); return false; @@ -209,16 +211,14 @@ void hubbub1_program_watermarks( refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "URGENCY_WATERMARK_A calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n", watermarks->a.urgent_ns, prog_wm_value); prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "PTE_META_URGENCY_WATERMARK_A calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n", watermarks->a.pte_meta_urgent_ns, prog_wm_value); @@ -227,8 +227,7 @@ void hubbub1_program_watermarks( watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n", watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); @@ -237,8 +236,7 @@ void hubbub1_program_watermarks( watermarks->a.cstate_pstate.cstate_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_EXIT_WATERMARK_A calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n", watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); } @@ -247,8 +245,7 @@ void hubbub1_program_watermarks( watermarks->a.cstate_pstate.pstate_change_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n\n", watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); @@ -257,8 +254,7 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->b.urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "URGENCY_WATERMARK_B calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" "HW register value = 0x%x\n", watermarks->b.urgent_ns, prog_wm_value); @@ -267,8 +263,7 @@ void hubbub1_program_watermarks( watermarks->b.pte_meta_urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "PTE_META_URGENCY_WATERMARK_B calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n" "HW register value = 0x%x\n", watermarks->b.pte_meta_urgent_ns, prog_wm_value); @@ -278,8 +273,7 @@ void hubbub1_program_watermarks( watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_ENTER_WATERMARK_B calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_B calculated =%d\n" "HW register value = 0x%x\n", watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); @@ -288,8 +282,7 @@ void hubbub1_program_watermarks( watermarks->b.cstate_pstate.cstate_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_EXIT_WATERMARK_B calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" "HW register value = 0x%x\n", watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); } @@ -298,8 +291,7 @@ void hubbub1_program_watermarks( watermarks->b.cstate_pstate.pstate_change_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n" + DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n" "HW register value = 0x%x\n", watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); @@ -307,8 +299,7 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->c.urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "URGENCY_WATERMARK_C calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" "HW register value = 0x%x\n", watermarks->c.urgent_ns, prog_wm_value); @@ -317,8 +308,7 @@ void hubbub1_program_watermarks( watermarks->c.pte_meta_urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "PTE_META_URGENCY_WATERMARK_C calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n" "HW register value = 0x%x\n", watermarks->c.pte_meta_urgent_ns, prog_wm_value); @@ -328,8 +318,7 @@ void hubbub1_program_watermarks( watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_ENTER_WATERMARK_C calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_C calculated =%d\n" "HW register value = 0x%x\n", watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); @@ -338,8 +327,7 @@ void hubbub1_program_watermarks( watermarks->c.cstate_pstate.cstate_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_EXIT_WATERMARK_C calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" "HW register value = 0x%x\n", watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); } @@ -348,8 +336,7 @@ void hubbub1_program_watermarks( watermarks->c.cstate_pstate.pstate_change_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n" + DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n" "HW register value = 0x%x\n", watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); @@ -357,8 +344,7 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->d.urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "URGENCY_WATERMARK_D calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n", watermarks->d.urgent_ns, prog_wm_value); @@ -366,8 +352,7 @@ void hubbub1_program_watermarks( watermarks->d.pte_meta_urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "PTE_META_URGENCY_WATERMARK_D calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n", watermarks->d.pte_meta_urgent_ns, prog_wm_value); @@ -377,8 +362,7 @@ void hubbub1_program_watermarks( watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_ENTER_WATERMARK_D calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n", watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); @@ -387,8 +371,7 @@ void hubbub1_program_watermarks( watermarks->d.cstate_pstate.cstate_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_EXIT_WATERMARK_D calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n", watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); } @@ -398,8 +381,7 @@ void hubbub1_program_watermarks( watermarks->d.cstate_pstate.pstate_change_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); - dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, - "DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n\n", watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); @@ -512,5 +494,6 @@ void hubbub1_construct(struct hubbub *hubbub, hubbub->shifts = hubbub_shift; hubbub->masks = hubbub_mask; + hubbub->debug_test_index_pstate = 0x7; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h index d5c97844312f..a16e908821a0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h @@ -185,6 +185,7 @@ struct hubbub { const struct dcn_hubbub_registers *regs; const struct dcn_hubbub_shift *shifts; const struct dcn_hubbub_mask *masks; + unsigned int debug_test_index_pstate; }; void hubbub1_update_dchub( 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 29dc37fbdb26..1907ade1574a 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 @@ -45,6 +45,8 @@ #include "dcn10_hubbub.h" #include "dcn10_cm_common.h" +#define DC_LOGGER \ + ctx->logger #define CTX \ hws->ctx #define REG(reg)\ @@ -328,6 +330,7 @@ static void power_on_plane( struct dce_hwseq *hws, int plane_id) { + struct dc_context *ctx = hws->ctx; if (REG(DC_IP_REQUEST_CNTL)) { REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); @@ -335,7 +338,7 @@ static void power_on_plane( hubp_pg_control(hws, plane_id, true); REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); - dm_logger_write(hws->ctx->logger, LOG_DEBUG, + DC_LOG_DEBUG( "Un-gated front end for pipe %d\n", plane_id); } } @@ -526,7 +529,7 @@ static void reset_back_end_for_pipe( struct dc_state *context) { int i; - + struct dc_context *ctx = dc->ctx; if (pipe_ctx->stream_res.stream_enc == NULL) { pipe_ctx->stream = NULL; return; @@ -536,6 +539,22 @@ static void reset_back_end_for_pipe( /* DPMS may already disable */ if (!pipe_ctx->stream->dpms_off) core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE); + else if (pipe_ctx->stream_res.audio) { + /* + * if stream is already disabled outside of commit streams path, + * audio disable was skipped. Need to do it here + */ + pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); + + if (dc->caps.dynamic_audio == true) { + /*we have to dynamic arbitrate the audio endpoints*/ + pipe_ctx->stream_res.audio = NULL; + /*we free the resource, need reset is_audio_acquired*/ + update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false); + } + + } + } /* by upper caller loop, parent pipe: pipe0, will be reset last. @@ -556,8 +575,7 @@ static void reset_back_end_for_pipe( return; pipe_ctx->stream = NULL; - dm_logger_write(dc->ctx->logger, LOG_DEBUG, - "Reset back end for pipe %d, tg:%d\n", + DC_LOG_DEBUG("Reset back end for pipe %d, tg:%d\n", pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst); } @@ -607,6 +625,7 @@ static void plane_atomic_power_down(struct dc *dc, struct pipe_ctx *pipe_ctx) { struct dce_hwseq *hws = dc->hwseq; struct dpp *dpp = pipe_ctx->plane_res.dpp; + struct dc_context *ctx = dc->ctx; if (REG(DC_IP_REQUEST_CNTL)) { REG_SET(DC_IP_REQUEST_CNTL, 0, @@ -616,7 +635,7 @@ static void plane_atomic_power_down(struct dc *dc, struct pipe_ctx *pipe_ctx) dpp->funcs->dpp_reset(dpp); REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); - dm_logger_write(dc->ctx->logger, LOG_DEBUG, + DC_LOG_DEBUG( "Power gated front end %d\n", pipe_ctx->pipe_idx); } } @@ -656,6 +675,8 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx) static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx) { + struct dc_context *ctx = dc->ctx; + if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated) return; @@ -663,8 +684,7 @@ static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx) apply_DEGVIDCN10_253_wa(dc); - dm_logger_write(dc->ctx->logger, LOG_DC, - "Power down front end %d\n", + DC_LOG_DC("Power down front end %d\n", pipe_ctx->pipe_idx); } @@ -1086,7 +1106,7 @@ static void dcn10_enable_per_frame_crtc_position_reset( struct dc *core_dc, struct pipe_ctx *pipe_ctx) { - dm_logger_write(core_dc->ctx->logger, LOG_BANDWIDTH_CALCS, + DC_LOG_BANDWIDTH_CALCS(core_dc->ctx->logger, "\n============== DML TTU Output parameters [%d] ==============\n" "qos_level_low_wm: %d, \n" "qos_level_high_wm: %d, \n" @@ -1116,7 +1136,7 @@ static void dcn10_enable_per_frame_crtc_position_reset( pipe_ctx->ttu_regs.refcyc_per_req_delivery_pre_c ); - dm_logger_write(core_dc->ctx->logger, LOG_BANDWIDTH_CALCS, + DC_LOG_BANDWIDTH_CALCS(core_dc->ctx->logger, "\n============== DML DLG Output parameters [%d] ==============\n" "refcyc_h_blank_end: %d, \n" "dlg_vblank_end: %d, \n" @@ -1151,7 +1171,7 @@ static void dcn10_enable_per_frame_crtc_position_reset( pipe_ctx->dlg_regs.refcyc_per_pte_group_nom_l ); - dm_logger_write(core_dc->ctx->logger, LOG_BANDWIDTH_CALCS, + DC_LOG_BANDWIDTH_CALCS(core_dc->ctx->logger, "\ndst_y_per_meta_row_nom_l: %d, \n" "refcyc_per_meta_chunk_nom_l: %d, \n" "refcyc_per_line_delivery_pre_l: %d, \n" @@ -1181,7 +1201,7 @@ static void dcn10_enable_per_frame_crtc_position_reset( pipe_ctx->dlg_regs.refcyc_per_line_delivery_c ); - dm_logger_write(core_dc->ctx->logger, LOG_BANDWIDTH_CALCS, + DC_LOG_BANDWIDTH_CALCS(core_dc->ctx->logger, "\n============== DML RQ Output parameters [%d] ==============\n" "chunk_size: %d \n" "min_chunk_size: %d \n" @@ -1314,7 +1334,7 @@ static void dcn10_enable_plane( /* TODO: enable/disable in dm as per update type. if (plane_state) { - dm_logger_write(dc->ctx->logger, LOG_DC, + DC_LOG_DC(dc->ctx->logger, "Pipe:%d 0x%x: addr hi:0x%x, " "addr low:0x%x, " "src: %d, %d, %d," @@ -1332,7 +1352,7 @@ static void dcn10_enable_plane( plane_state->dst_rect.width, plane_state->dst_rect.height); - dm_logger_write(dc->ctx->logger, LOG_DC, + DC_LOG_DC(dc->ctx->logger, "Pipe %d: width, height, x, y format:%d\n" "viewport:%d, %d, %d, %d\n" "recout: %d, %d, %d, %d\n", @@ -1568,6 +1588,7 @@ static void update_dpp(struct dpp *dpp, struct dc_plane_state *plane_state) dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params); } + static void update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) { struct hubp *hubp = pipe_ctx->plane_res.hubp; @@ -1667,12 +1688,13 @@ static void update_dchubp_dpp( if (plane_state->update_flags.bits.full_update) { dpp->funcs->dpp_dppclk_control( dpp, - context->bw.dcn.calc_clk.dppclk_div, + context->bw.dcn.calc_clk.max_dppclk_khz < + context->bw.dcn.calc_clk.dispclk_khz, true); - dc->current_state->bw.dcn.cur_clk.dppclk_div = - context->bw.dcn.calc_clk.dppclk_div; - context->bw.dcn.cur_clk.dppclk_div = context->bw.dcn.calc_clk.dppclk_div; + dc->current_state->bw.dcn.cur_clk.max_dppclk_khz = + context->bw.dcn.calc_clk.max_dppclk_khz; + context->bw.dcn.cur_clk.max_dppclk_khz = context->bw.dcn.calc_clk.max_dppclk_khz; } /* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG @@ -1803,8 +1825,9 @@ static void program_all_pipe_in_tree( dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream); } - if (pipe_ctx->bottom_pipe != NULL && pipe_ctx->bottom_pipe != pipe_ctx) + if (pipe_ctx->bottom_pipe != NULL && pipe_ctx->bottom_pipe != pipe_ctx) { program_all_pipe_in_tree(dc, pipe_ctx->bottom_pipe, context); + } } static void dcn10_pplib_apply_display_requirements( @@ -1889,6 +1912,7 @@ static void dcn10_apply_ctx_for_surface( bool removed_pipe[4] = { false }; unsigned int ref_clk_mhz = dc->res_pool->ref_clock_inKhz/1000; bool program_water_mark = false; + struct dc_context *ctx = dc->ctx; struct pipe_ctx *top_pipe_to_program = find_top_pipe_for_stream(dc, context, stream); @@ -1924,7 +1948,7 @@ static void dcn10_apply_ctx_for_surface( if (old_pipe_ctx->stream_res.tg == tg && old_pipe_ctx->plane_res.hubp && old_pipe_ctx->plane_res.hubp->opp_id != 0xf) { - dcn10_disable_plane(dc, pipe_ctx); + dcn10_disable_plane(dc, old_pipe_ctx); /* * power down fe will unlock when calling reset, need * to lock it back here. Messy, need rework. @@ -1940,7 +1964,7 @@ static void dcn10_apply_ctx_for_surface( plane_atomic_disconnect(dc, old_pipe_ctx); removed_pipe[i] = true; - dm_logger_write(dc->ctx->logger, LOG_DC, + DC_LOG_DC( "Reset mpcc for pipe %d\n", old_pipe_ctx->pipe_idx); } @@ -1983,7 +2007,7 @@ static void dcn10_apply_ctx_for_surface( dcn10_verify_allow_pstate_change_high(dc); } } -/* dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS, +/* DC_LOG_BANDWIDTH_CALCS(dc->ctx->logger, "\n============== Watermark parameters ==============\n" "a.urgent_ns: %d \n" "a.cstate_enter_plus_exit: %d \n" @@ -2006,7 +2030,7 @@ static void dcn10_apply_ctx_for_surface( context->bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns, context->bw.dcn.watermarks.b.pte_meta_urgent_ns ); - dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS, + DC_LOG_BANDWIDTH_CALCS(dc->ctx->logger, "\nc.urgent_ns: %d \n" "c.cstate_enter_plus_exit: %d \n" "c.cstate_exit: %d \n" @@ -2054,22 +2078,24 @@ static void dcn10_set_bandwidth( dc->res_pool->display_clock->funcs->set_clock( dc->res_pool->display_clock, context->bw.dcn.calc_clk.dispclk_khz); - dc->current_state->bw.dcn.cur_clk.dispclk_khz = + context->bw.dcn.cur_clk.dispclk_khz = context->bw.dcn.calc_clk.dispclk_khz; } if (decrease_allowed || context->bw.dcn.calc_clk.dcfclk_khz > dc->current_state->bw.dcn.cur_clk.dcfclk_khz) { + context->bw.dcn.cur_clk.dcfclk_khz = + context->bw.dcn.calc_clk.dcfclk_khz; smu_req.hard_min_dcefclk_khz = context->bw.dcn.calc_clk.dcfclk_khz; } if (decrease_allowed || context->bw.dcn.calc_clk.fclk_khz > dc->current_state->bw.dcn.cur_clk.fclk_khz) { + context->bw.dcn.cur_clk.fclk_khz = + context->bw.dcn.calc_clk.fclk_khz; smu_req.hard_min_fclk_khz = context->bw.dcn.calc_clk.fclk_khz; } if (decrease_allowed || context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz > dc->current_state->bw.dcn.cur_clk.dcfclk_deep_sleep_khz) { - dc->current_state->bw.dcn.calc_clk.dcfclk_deep_sleep_khz = - context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz; context->bw.dcn.cur_clk.dcfclk_deep_sleep_khz = context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz; } @@ -2084,15 +2110,11 @@ static void dcn10_set_bandwidth( /* Decrease in freq is increase in period so opposite comparison for dram_ccm */ if (decrease_allowed || context->bw.dcn.calc_clk.dram_ccm_us < dc->current_state->bw.dcn.cur_clk.dram_ccm_us) { - dc->current_state->bw.dcn.calc_clk.dram_ccm_us = - context->bw.dcn.calc_clk.dram_ccm_us; context->bw.dcn.cur_clk.dram_ccm_us = context->bw.dcn.calc_clk.dram_ccm_us; } if (decrease_allowed || context->bw.dcn.calc_clk.min_active_dram_ccm_us < dc->current_state->bw.dcn.cur_clk.min_active_dram_ccm_us) { - dc->current_state->bw.dcn.calc_clk.min_active_dram_ccm_us = - context->bw.dcn.calc_clk.min_active_dram_ccm_us; context->bw.dcn.cur_clk.min_active_dram_ccm_us = context->bw.dcn.calc_clk.min_active_dram_ccm_us; } @@ -2251,7 +2273,7 @@ static void dcn10_wait_for_mpcc_disconnect( res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst); pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false; hubp->funcs->set_blank(hubp, true); - /*dm_logger_write(dc->ctx->logger, LOG_ERROR, + /*DC_LOG_ERROR(dc->ctx->logger, "[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n", i);*/ } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h index 014543235df8..d25e7bf0d0d7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h @@ -83,6 +83,8 @@ struct dcn_optc_registers { + uint32_t OTG_GLOBAL_CONTROL1; + uint32_t OTG_GLOBAL_CONTROL2; uint32_t OTG_VERT_SYNC_CONTROL; uint32_t OTG_MASTER_UPDATE_MODE; uint32_t OTG_GSL_CONTROL; @@ -126,6 +128,7 @@ struct dcn_optc_registers { uint32_t OTG_VERTICAL_INTERRUPT2_POSITION; uint32_t OPTC_INPUT_CLOCK_CONTROL; uint32_t OPTC_DATA_SOURCE_SELECT; + uint32_t OPTC_MEMORY_CONFIG; uint32_t OPTC_INPUT_GLOBAL_CONTROL; uint32_t CONTROL; uint32_t OTG_GSL_WINDOW_X; @@ -325,10 +328,9 @@ struct dcn_optc_registers { type OPTC_INPUT_CLK_EN;\ type OPTC_INPUT_CLK_ON;\ type OPTC_INPUT_CLK_GATE_DIS;\ - type OPTC_SRC_SEL;\ - type OPTC_SEG0_SRC_SEL;\ type OPTC_UNDERFLOW_OCCURRED_STATUS;\ type OPTC_UNDERFLOW_CLEAR;\ + type OPTC_SRC_SEL;\ type VTG0_ENABLE;\ type VTG0_FP2;\ type VTG0_VCOUNT_INIT;\ diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h index ab88f07772a3..034369fbb9e2 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h @@ -50,6 +50,13 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( bool enable); /* + * Clear payload allocation table before enable MST DP link. + */ +void dm_helpers_dp_mst_clear_payload_allocation_table( + struct dc_context *ctx, + const struct dc_link *link); + +/* * Polls for ACT (allocation change trigger) handled and */ bool dm_helpers_dp_mst_poll_for_allocation_change_trigger( @@ -101,5 +108,8 @@ enum dc_edid_status dm_helpers_read_local_edid( struct dc_link *link, struct dc_sink *sink); +void dm_set_dcn_clocks( + struct dc_context *ctx, + struct dc_clocks *clks); #endif /* __DM_HELPERS__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dm_services_types.h b/drivers/gpu/drm/amd/display/dc/dm_services_types.h index fa26cf488b3c..ab8c77d4e6df 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_services_types.h +++ b/drivers/gpu/drm/amd/display/dc/dm_services_types.h @@ -29,7 +29,7 @@ #include "os_types.h" #include "dc_types.h" -#include "dm_pp_smu.h" +struct pp_smu_funcs_rv; struct dm_pp_clock_range { int min_khz; @@ -239,25 +239,8 @@ enum dm_acpi_display_type { AcpiDisplayType_DFP6 = 12 }; -enum dm_pp_power_level { - DM_PP_POWER_LEVEL_INVALID, - DM_PP_POWER_LEVEL_ULTRA_LOW, - DM_PP_POWER_LEVEL_LOW, - DM_PP_POWER_LEVEL_NOMINAL, - DM_PP_POWER_LEVEL_PERFORMANCE, - - DM_PP_POWER_LEVEL_0 = DM_PP_POWER_LEVEL_ULTRA_LOW, - DM_PP_POWER_LEVEL_1 = DM_PP_POWER_LEVEL_LOW, - DM_PP_POWER_LEVEL_2 = DM_PP_POWER_LEVEL_NOMINAL, - DM_PP_POWER_LEVEL_3 = DM_PP_POWER_LEVEL_PERFORMANCE, - DM_PP_POWER_LEVEL_4 = DM_PP_CLOCKS_DPM_STATE_LEVEL_3 + 1, - DM_PP_POWER_LEVEL_5 = DM_PP_CLOCKS_DPM_STATE_LEVEL_4 + 1, - DM_PP_POWER_LEVEL_6 = DM_PP_CLOCKS_DPM_STATE_LEVEL_5 + 1, - DM_PP_POWER_LEVEL_7 = DM_PP_CLOCKS_DPM_STATE_LEVEL_6 + 1, -}; - struct dm_pp_power_level_change_request { - enum dm_pp_power_level power_level; + enum dm_pp_clocks_state power_level; }; struct dm_pp_clock_for_voltage_req { diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c index 0b1db48fef36..bb526ad326e5 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c @@ -55,6 +55,8 @@ enum { #define FROM_ENGINE(ptr) \ container_of((ptr), struct aux_engine, base) +#define DC_LOGGER \ + engine->base.ctx->logger enum i2caux_engine_type dal_aux_engine_get_engine_type( const struct engine *engine) @@ -126,20 +128,8 @@ static void process_read_reply( ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR; ctx->operation_succeeded = false; - } else if (ctx->returned_byte < ctx->current_read_length) { - ctx->current_read_length -= ctx->returned_byte; - - ctx->offset += ctx->returned_byte; - - ++ctx->invalid_reply_retry_aux_on_ack; - - if (ctx->invalid_reply_retry_aux_on_ack > - AUX_INVALID_REPLY_RETRY_COUNTER) { - ctx->status = - I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR; - ctx->operation_succeeded = false; - } } else { + ctx->current_read_length = ctx->returned_byte; ctx->status = I2CAUX_TRANSACTION_STATUS_SUCCEEDED; ctx->transaction_complete = true; ctx->operation_succeeded = true; @@ -286,12 +276,13 @@ static bool read_command( if (request->payload.address_space == I2CAUX_TRANSACTION_ADDRESS_SPACE_DPCD) { - dm_logger_write(engine->base.ctx->logger, LOG_I2C_AUX, "READ: addr:0x%x value:0x%x Result:%d", + DC_LOG_I2C_AUX("READ: addr:0x%x value:0x%x Result:%d", request->payload.address, request->payload.data[0], ctx.operation_succeeded); } + request->payload.length = ctx.reply.length; return ctx.operation_succeeded; } @@ -494,7 +485,7 @@ static bool write_command( if (request->payload.address_space == I2CAUX_TRANSACTION_ADDRESS_SPACE_DPCD) { - dm_logger_write(engine->base.ctx->logger, LOG_I2C_AUX, "WRITE: addr:0x%x value:0x%x Result:%d", + DC_LOG_I2C_AUX("WRITE: addr:0x%x value:0x%x Result:%d", request->payload.address, request->payload.data[0], ctx.operation_succeeded); diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c index 56e25b3d65fd..abd0095ced30 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c @@ -48,6 +48,8 @@ /* * This unit */ +#define DC_LOGGER \ + hw_engine->base.base.base.ctx->logger enum dc_i2c_status { DC_I2C_STATUS__DC_I2C_STATUS_IDLE, @@ -525,9 +527,7 @@ static void construct( REG_GET(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, &xtal_ref_div); if (xtal_ref_div == 0) { - dm_logger_write( - hw_engine->base.base.base.ctx->logger, LOG_WARNING, - "Invalid base timer divider\n", + DC_LOG_WARNING("Invalid base timer divider\n", __func__); xtal_ref_div = 2; } diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c b/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c index e1593ffe5a2b..5cbf6626b8d4 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c @@ -253,6 +253,7 @@ bool dal_i2caux_submit_aux_command( break; } + cmd->payloads->length = request.payload.length; ++index_of_payload; } diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 5509e13e7edf..b8f05384a897 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -177,6 +177,15 @@ struct resource_pool { const struct resource_caps *res_cap; }; +struct dcn_fe_clocks { + int dppclk_khz; +}; + +struct dcn_fe_bandwidth { + struct dcn_fe_clocks calc; + struct dcn_fe_clocks cur; +}; + struct stream_resource { struct output_pixel_processor *opp; struct timing_generator *tg; @@ -195,6 +204,8 @@ struct plane_resource { struct transform *xfm; struct dpp *dpp; uint8_t mpcc_inst; + + struct dcn_fe_bandwidth bw; }; struct pipe_ctx { @@ -245,20 +256,9 @@ struct dce_bw_output { int blackout_recovery_time_us; }; -struct dcn_bw_clocks { - int dispclk_khz; - int dppclk_khz; - bool dppclk_div; - int dcfclk_khz; - int dcfclk_deep_sleep_khz; - int fclk_khz; - int dram_ccm_us; - int min_active_dram_ccm_us; -}; - struct dcn_bw_output { - struct dcn_bw_clocks cur_clk; - struct dcn_bw_clocks calc_clk; + struct dc_clocks cur_clk; + struct dc_clocks calc_clk; struct dcn_watermark_set watermarks; }; diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h index 0bf73b742f1f..090b7a8dd67b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h @@ -102,7 +102,7 @@ bool dal_ddc_service_query_ddc_data( uint8_t *read_buf, uint32_t read_size); -enum ddc_result dal_ddc_service_read_dpcd_data( +ssize_t dal_ddc_service_read_dpcd_data( struct ddc_service *ddc, bool i2c, enum i2c_mot_mode mot, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h index 78abc16ec4dc..c5aae2daf442 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h @@ -35,6 +35,8 @@ struct dpp { int inst; struct dpp_caps *caps; struct pwl_params regamma_params; + struct pwl_params degamma_params; + }; struct dpp_grph_csc_adjustment { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c index f7e40b292dfb..afe0876fe6f8 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c @@ -36,27 +36,25 @@ #include "dc.h" #include "core_types.h" -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) +#define DC_LOGGER \ + irq_service->ctx->logger + +static bool hpd_ack(struct irq_service *irq_service, + const struct irq_source_info *info) { uint32_t addr = info->status_reg; uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); + uint32_t current_status = get_reg_field_value(value, + DC_HPD_INT_STATUS, + DC_HPD_SENSE_DELAYED); dal_irq_service_ack_generic(irq_service, info); value = dm_read_reg(irq_service->ctx, info->enable_reg); - set_reg_field_value( - value, - current_status ? 0 : 1, - DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); + set_reg_field_value(value, current_status ? 0 : 1, + DC_HPD_INT_CONTROL, + DC_HPD_INT_POLARITY); dm_write_reg(irq_service->ctx, info->enable_reg, value); @@ -176,48 +174,41 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { #define dc_underflow_int_entry(reg_num) \ [DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW] = dummy_irq_entry() -bool dal_irq_service_dummy_set( - struct irq_service *irq_service, - const struct irq_source_info *info, - bool enable) +bool dal_irq_service_dummy_set(struct irq_service *irq_service, + const struct irq_source_info *info, + bool enable) { - dm_logger_write( - irq_service->ctx->logger, LOG_ERROR, - "%s: called for non-implemented irq source\n", - __func__); + DC_LOG_ERROR("%s: called for non-implemented irq source\n", + __func__); return false; } -bool dal_irq_service_dummy_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) +bool dal_irq_service_dummy_ack(struct irq_service *irq_service, + const struct irq_source_info *info) { - dm_logger_write( - irq_service->ctx->logger, LOG_ERROR, - "%s: called for non-implemented irq source\n", - __func__); + DC_LOG_ERROR("%s: called for non-implemented irq source\n", + __func__); return false; } -bool dce110_vblank_set( - struct irq_service *irq_service, - const struct irq_source_info *info, - bool enable) +bool dce110_vblank_set(struct irq_service *irq_service, + const struct irq_source_info *info, + bool enable) { struct dc_context *dc_ctx = irq_service->ctx; struct dc *core_dc = irq_service->ctx->dc; - enum dc_irq_source dal_irq_src = dc_interrupt_to_irq_source( - irq_service->ctx->dc, - info->src_id, - info->ext_id); + enum dc_irq_source dal_irq_src = + dc_interrupt_to_irq_source(irq_service->ctx->dc, + info->src_id, + info->ext_id); uint8_t pipe_offset = dal_irq_src - IRQ_TYPE_VBLANK; struct timing_generator *tg = core_dc->current_state->res_ctx.pipe_ctx[pipe_offset].stream_res.tg; if (enable) { - if (!tg->funcs->arm_vert_intr(tg, 2)) { + if (!tg || !tg->funcs->arm_vert_intr(tg, 2)) { DC_ERROR("Failed to get VBLANK!\n"); return false; } @@ -225,7 +216,6 @@ bool dce110_vblank_set( dal_irq_service_set_generic(irq_service, info, enable); return true; - } static const struct irq_source_info_funcs dummy_irq_info_funcs = { @@ -406,9 +396,8 @@ static const struct irq_service_funcs irq_service_funcs_dce110 = { .to_dal_irq_source = to_dal_irq_source_dce110 }; -static void construct( - struct irq_service *irq_service, - struct irq_service_init_data *init_data) +static void construct(struct irq_service *irq_service, + struct irq_service_init_data *init_data) { dal_irq_service_construct(irq_service, init_data); @@ -416,8 +405,8 @@ static void construct( irq_service->funcs = &irq_service_funcs_dce110; } -struct irq_service *dal_irq_service_dce110_create( - struct irq_service_init_data *init_data) +struct irq_service * +dal_irq_service_dce110_create(struct irq_service_init_data *init_data) { struct irq_service *irq_service = kzalloc(sizeof(*irq_service), GFP_KERNEL); diff --git a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c index b106513fc2dc..dcdfa0f01551 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c +++ b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c @@ -47,6 +47,8 @@ #define CTX \ irq_service->ctx +#define DC_LOGGER \ + irq_service->ctx->logger void dal_irq_service_construct( struct irq_service *irq_service, @@ -104,9 +106,7 @@ bool dal_irq_service_set( find_irq_source_info(irq_service, source); if (!info) { - dm_logger_write( - irq_service->ctx->logger, LOG_ERROR, - "%s: cannot find irq info table entry for %d\n", + DC_LOG_ERROR("%s: cannot find irq info table entry for %d\n", __func__, source); return false; @@ -142,9 +142,7 @@ bool dal_irq_service_ack( find_irq_source_info(irq_service, source); if (!info) { - dm_logger_write( - irq_service->ctx->logger, LOG_ERROR, - "%s: cannot find irq info table entry for %d\n", + DC_LOG_ERROR("%s: cannot find irq info table entry for %d\n", __func__, source); return false; diff --git a/drivers/gpu/drm/amd/display/include/link_service_types.h b/drivers/gpu/drm/amd/display/include/link_service_types.h index adea1a59f620..80f0d93cfd94 100644 --- a/drivers/gpu/drm/amd/display/include/link_service_types.h +++ b/drivers/gpu/drm/amd/display/include/link_service_types.h @@ -58,11 +58,14 @@ enum { enum link_training_result { LINK_TRAINING_SUCCESS, - LINK_TRAINING_CR_FAIL, + LINK_TRAINING_CR_FAIL_LANE0, + LINK_TRAINING_CR_FAIL_LANE1, + LINK_TRAINING_CR_FAIL_LANE23, /* CR DONE bit is cleared during EQ step */ LINK_TRAINING_EQ_FAIL_CR, /* other failure during EQ step */ LINK_TRAINING_EQ_FAIL_EQ, + LINK_TRAINING_LQA_FAIL, }; struct link_training_settings { diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h b/drivers/gpu/drm/amd/display/include/logger_types.h index e2ff8cd423d6..b727f5eeb3a9 100644 --- a/drivers/gpu/drm/amd/display/include/logger_types.h +++ b/drivers/gpu/drm/amd/display/include/logger_types.h @@ -29,6 +29,39 @@ #include "os_types.h" #define MAX_NAME_LEN 32 +#define DC_LOG_ERROR(a, ...) dm_logger_write(DC_LOGGER, LOG_ERROR, a, ## __VA_ARGS__) +#define DC_LOG_WARNING(a, ...) dm_logger_write(DC_LOGGER, LOG_WARNING, a, ## __VA_ARGS__) +#define DC_LOG_DEBUG(a, ...) dm_logger_write(DC_LOGGER, LOG_DEBUG, a, ## __VA_ARGS__) +#define DC_LOG_DC(a, ...) dm_logger_write(DC_LOGGER, LOG_DC, a, ## __VA_ARGS__) +#define DC_LOG_DTN(a, ...) dm_logger_write(DC_LOGGER, LOG_DTN, a, ## __VA_ARGS__) +#define DC_LOG_SURFACE(a, ...) dm_logger_write(DC_LOGGER, LOG_SURFACE, a, ## __VA_ARGS__) +#define DC_LOG_HW_HOTPLUG(a, ...) dm_logger_write(DC_LOGGER, LOG_HW_HOTPLUG, a, ## __VA_ARGS__) +#define DC_LOG_HW_LINK_TRAINING(a, ...) dm_logger_write(DC_LOGGER, LOG_HW_LINK_TRAINING, a, ## __VA_ARGS__) +#define DC_LOG_HW_SET_MODE(a, ...) dm_logger_write(DC_LOGGER, LOG_HW_SET_MODE, a, ## __VA_ARGS__) +#define DC_LOG_HW_RESUME_S3(a, ...) dm_logger_write(DC_LOGGER, LOG_HW_RESUME_S3, a, ## __VA_ARGS__) +#define DC_LOG_HW_AUDIO(a, ...) dm_logger_write(DC_LOGGER, LOG_HW_AUDIO, a, ## __VA_ARGS__) +#define DC_LOG_HW_HPD_IRQ(a, ...) dm_logger_write(DC_LOGGER, LOG_HW_HPD_IRQ, a, ## __VA_ARGS__) +#define DC_LOG_MST(a, ...) dm_logger_write(DC_LOGGER, LOG_MST, a, ## __VA_ARGS__) +#define DC_LOG_SCALER(a, ...) dm_logger_write(DC_LOGGER, LOG_SCALER, a, ## __VA_ARGS__) +#define DC_LOG_BIOS(a, ...) dm_logger_write(DC_LOGGER, LOG_BIOS, a, ## __VA_ARGS__) +#define DC_LOG_BANDWIDTH_CALCS(a, ...) dm_logger_write(DC_LOGGER, LOG_BANDWIDTH_CALCS, a, ## __VA_ARGS__) +#define DC_LOG_BANDWIDTH_VALIDATION(a, ...) dm_logger_write(DC_LOGGER, LOG_BANDWIDTH_VALIDATION, a, ## __VA_ARGS__) +#define DC_LOG_I2C_AUX(a, ...) dm_logger_write(DC_LOGGER, LOG_I2C_AUX, a, ## __VA_ARGS__) +#define DC_LOG_SYNC(a, ...) dm_logger_write(DC_LOGGER, LOG_SYNC, a, ## __VA_ARGS__) +#define DC_LOG_BACKLIGHT(a, ...) dm_logger_write(DC_LOGGER, LOG_BACKLIGHT, a, ## __VA_ARGS__) +#define DC_LOG_FEATURE_OVERRIDE(a, ...) dm_logger_write(DC_LOGGER, LOG_FEATURE_OVERRIDE, a, ## __VA_ARGS__) +#define DC_LOG_DETECTION_EDID_PARSER(a, ...) dm_logger_write(DC_LOGGER, LOG_DETECTION_EDID_PARSER, a, ## __VA_ARGS__) +#define DC_LOG_DETECTION_DP_CAPS(a, ...) dm_logger_write(DC_LOGGER, LOG_DETECTION_DP_CAPS, a, ## __VA_ARGS__) +#define DC_LOG_RESOURCE(a, ...) dm_logger_write(DC_LOGGER, LOG_RESOURCE, a, ## __VA_ARGS__) +#define DC_LOG_DML(a, ...) dm_logger_write(DC_LOGGER, LOG_DML, a, ## __VA_ARGS__) +#define DC_LOG_EVENT_MODE_SET(a, ...) dm_logger_write(DC_LOGGER, LOG_EVENT_MODE_SET, a, ## __VA_ARGS__) +#define DC_LOG_EVENT_DETECTION(a, ...) dm_logger_write(DC_LOGGER, LOG_EVENT_DETECTION, a, ## __VA_ARGS__) +#define DC_LOG_EVENT_LINK_TRAINING(a, ...) dm_logger_write(DC_LOGGER, LOG_EVENT_LINK_TRAINING, a, ## __VA_ARGS__) +#define DC_LOG_EVENT_LINK_LOSS(a, ...) dm_logger_write(DC_LOGGER, LOG_EVENT_LINK_LOSS, a, ## __VA_ARGS__) +#define DC_LOG_EVENT_UNDERFLOW(a, ...) dm_logger_write(DC_LOGGER, LOG_EVENT_UNDERFLOW, a, ## __VA_ARGS__) +#define DC_LOG_IF_TRACE(a, ...) dm_logger_write(DC_LOGGER, LOG_IF_TRACE, a, ## __VA_ARGS__) +#define DC_LOG_PERF_TRACE(a, ...) dm_logger_write(DC_LOGGER, LOG_PERF_TRACE, a, ## __VA_ARGS__) + struct dal_logger; 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 a5fd14a4016f..57d5c2575de1 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c @@ -30,15 +30,12 @@ #define NUM_PTS_IN_REGION 16 #define NUM_REGIONS 32 -#define NUM_DEGAMMA_REGIONS 12 #define MAX_HW_POINTS (NUM_PTS_IN_REGION*NUM_REGIONS) -#define MAX_HW_DEGAMMA_POINTS (NUM_PTS_IN_REGION*NUM_DEGAMMA_REGIONS) static struct hw_x_point coordinates_x[MAX_HW_POINTS + 2]; -static struct hw_x_point degamma_coordinates_x[MAX_HW_DEGAMMA_POINTS + 2]; static struct fixed31_32 pq_table[MAX_HW_POINTS + 2]; -static struct fixed31_32 de_pq_table[MAX_HW_DEGAMMA_POINTS + 2]; +static struct fixed31_32 de_pq_table[MAX_HW_POINTS + 2]; static bool pq_initialized; /* = false; */ static bool de_pq_initialized; /* = false; */ @@ -69,26 +66,6 @@ void setup_x_points_distribution(void) (coordinates_x[index-1].x, increment); } } - - region_size = dal_fixed31_32_from_int(1); - degamma_coordinates_x[MAX_HW_DEGAMMA_POINTS].x = region_size; - degamma_coordinates_x[MAX_HW_DEGAMMA_POINTS + 1].x = region_size; - - for (segment = -1; segment > -(NUM_DEGAMMA_REGIONS + 1); segment--) { - region_size = dal_fixed31_32_div_int(region_size, 2); - increment = dal_fixed31_32_div_int(region_size, - NUM_PTS_IN_REGION); - seg_offset = (segment + NUM_DEGAMMA_REGIONS) * NUM_PTS_IN_REGION; - degamma_coordinates_x[seg_offset].x = region_size; - - for (index = seg_offset + 1; - index < seg_offset + NUM_PTS_IN_REGION; - index++) { - degamma_coordinates_x[index].x = dal_fixed31_32_add - (degamma_coordinates_x[index-1].x, increment); - } - } - } static void compute_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y) @@ -179,15 +156,26 @@ void precompute_de_pq(void) { int i; struct fixed31_32 y; - const struct hw_x_point *coord_x = degamma_coordinates_x; + uint32_t begin_index, end_index; + struct fixed31_32 scaling_factor = dal_fixed31_32_from_int(125); + /* X points is 2^-25 to 2^7 + * De-gamma X is 2^-12 to 2^0 – we are skipping first -12-(-25) = 13 regions + */ + begin_index = 13 * NUM_PTS_IN_REGION; + end_index = begin_index + 12 * NUM_PTS_IN_REGION; - for (i = 0; i <= MAX_HW_DEGAMMA_POINTS; i++) { - compute_de_pq(coord_x->x, &y); + for (i = 0; i <= begin_index; i++) + de_pq_table[i] = dal_fixed31_32_zero; + + for (; i <= end_index; i++) { + compute_de_pq(coordinates_x[i].x, &y); de_pq_table[i] = dal_fixed31_32_mul(y, scaling_factor); - ++coord_x; } + + for (; i <= MAX_HW_POINTS; i++) + de_pq_table[i] = de_pq_table[i-1]; } struct dividers { struct fixed31_32 divider1; @@ -617,8 +605,6 @@ static void build_de_pq(struct pwl_float_data_ex *de_pq, uint32_t i; struct fixed31_32 output; - struct pwl_float_data_ex *rgb = de_pq; - const struct hw_x_point *coord_x = degamma_coordinates_x; struct fixed31_32 scaling_factor = dal_fixed31_32_from_int(125); if (!de_pq_initialized) { @@ -634,13 +620,9 @@ static void build_de_pq(struct pwl_float_data_ex *de_pq, output = dal_fixed31_32_zero; else if (dal_fixed31_32_lt(scaling_factor, output)) output = scaling_factor; - - rgb->r = output; - rgb->g = output; - rgb->b = output; - - ++coord_x; - ++rgb; + de_pq[i].r = output; + de_pq[i].g = output; + de_pq[i].b = output; } } @@ -675,24 +657,37 @@ static void build_degamma(struct pwl_float_data_ex *curve, const struct hw_x_point *coordinate_x, bool is_2_4) { uint32_t i; - struct gamma_coefficients coeff; - struct pwl_float_data_ex *rgb = curve; - const struct hw_x_point *coord_x = degamma_coordinates_x; + uint32_t begin_index, end_index; build_coefficients(&coeff, is_2_4); - i = 0; + /* X points is 2^-25 to 2^7 + * De-gamma X is 2^-12 to 2^0 – we are skipping first -12-(-25) = 13 regions + */ + begin_index = 13 * NUM_PTS_IN_REGION; + end_index = begin_index + 12 * NUM_PTS_IN_REGION; + + while (i != begin_index) { + curve[i].r = dal_fixed31_32_zero; + curve[i].g = dal_fixed31_32_zero; + curve[i].b = dal_fixed31_32_zero; + i++; + } + + while (i != end_index) { + curve[i].r = translate_to_linear_space_ex( + coordinate_x[i].x, &coeff, 0); + curve[i].g = curve[i].r; + curve[i].b = curve[i].r; + i++; + } while (i != hw_points_num + 1) { - /*TODO use y vs r,g,b*/ - rgb->r = translate_to_linear_space_ex( - coord_x->x, &coeff, 0); - rgb->g = rgb->r; - rgb->b = rgb->r; - ++coord_x; - ++rgb; - ++i; + curve[i].r = dal_fixed31_32_one; + curve[i].g = dal_fixed31_32_one; + curve[i].b = dal_fixed31_32_one; + i++; } } @@ -1173,10 +1168,6 @@ rgb_user_alloc_fail: return ret; } - -/*TODO fix me should be 2*/ -#define _EXTRA_POINTS 3 - bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, const struct dc_gamma *ramp, bool mapUserRamp) { @@ -1205,7 +1196,7 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, GFP_KERNEL); if (!rgb_user) goto rgb_user_alloc_fail; - curve = kzalloc(sizeof(*curve) * (MAX_HW_DEGAMMA_POINTS + _EXTRA_POINTS), + curve = kzalloc(sizeof(*curve) * (MAX_HW_POINTS + _EXTRA_POINTS), GFP_KERNEL); if (!curve) goto curve_alloc_fail; @@ -1213,7 +1204,7 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, GFP_KERNEL); if (!axix_x) goto axix_x_alloc_fail; - coeff = kzalloc(sizeof(*coeff) * (MAX_HW_DEGAMMA_POINTS + _EXTRA_POINTS), GFP_KERNEL); + coeff = kzalloc(sizeof(*coeff) * (MAX_HW_POINTS + _EXTRA_POINTS), GFP_KERNEL); if (!coeff) goto coeff_alloc_fail; @@ -1235,12 +1226,12 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, if (tf == TRANSFER_FUNCTION_PQ) build_de_pq(curve, - MAX_HW_DEGAMMA_POINTS, - degamma_coordinates_x); + MAX_HW_POINTS, + coordinates_x); else build_degamma(curve, - MAX_HW_DEGAMMA_POINTS, - degamma_coordinates_x, + MAX_HW_POINTS, + coordinates_x, tf == TRANSFER_FUNCTION_SRGB ? true:false); tf_pts->end_exponent = 0; @@ -1249,8 +1240,8 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, tf_pts->x_point_at_y1_blue = 1; map_regamma_hw_to_x_user(ramp, coeff, rgb_user, - degamma_coordinates_x, axix_x, curve, - MAX_HW_DEGAMMA_POINTS, tf_pts, + coordinates_x, axix_x, curve, + MAX_HW_POINTS, tf_pts, mapUserRamp); ret = true; @@ -1282,7 +1273,7 @@ bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans, points->x_point_at_y1_green = 1; points->x_point_at_y1_blue = 1; - for (i = 0; i < MAX_HW_POINTS ; i++) { + for (i = 0; i <= MAX_HW_POINTS ; i++) { points->red[i] = coordinates_x[i].x; points->green[i] = coordinates_x[i].x; points->blue[i] = coordinates_x[i].x; @@ -1303,7 +1294,7 @@ bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans, MAX_HW_POINTS, coordinates_x, 80); - for (i = 0; i < MAX_HW_POINTS ; i++) { + for (i = 0; i <= MAX_HW_POINTS ; i++) { points->red[i] = rgb_regamma[i].r; points->green[i] = rgb_regamma[i].g; points->blue[i] = rgb_regamma[i].b; @@ -1325,7 +1316,7 @@ bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans, build_regamma(rgb_regamma, MAX_HW_POINTS, coordinates_x, trans == TRANSFER_FUNCTION_SRGB ? true:false); - for (i = 0; i < MAX_HW_POINTS ; i++) { + for (i = 0; i <= MAX_HW_POINTS ; i++) { points->red[i] = rgb_regamma[i].r; points->green[i] = rgb_regamma[i].g; points->blue[i] = rgb_regamma[i].b; @@ -1348,23 +1339,23 @@ bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans, if (trans == TRANSFER_FUNCTION_UNITY) { - for (i = 0; i < MAX_HW_DEGAMMA_POINTS ; i++) { - points->red[i] = degamma_coordinates_x[i].x; - points->green[i] = degamma_coordinates_x[i].x; - points->blue[i] = degamma_coordinates_x[i].x; + for (i = 0; i <= MAX_HW_POINTS ; i++) { + points->red[i] = coordinates_x[i].x; + points->green[i] = coordinates_x[i].x; + points->blue[i] = coordinates_x[i].x; } ret = true; } else if (trans == TRANSFER_FUNCTION_PQ) { - rgb_degamma = kzalloc(sizeof(*rgb_degamma) * (MAX_HW_DEGAMMA_POINTS + + rgb_degamma = kzalloc(sizeof(*rgb_degamma) * (MAX_HW_POINTS + _EXTRA_POINTS), GFP_KERNEL); if (!rgb_degamma) goto rgb_degamma_alloc_fail; build_de_pq(rgb_degamma, - MAX_HW_DEGAMMA_POINTS, - degamma_coordinates_x); - for (i = 0; i < MAX_HW_DEGAMMA_POINTS ; i++) { + MAX_HW_POINTS, + coordinates_x); + for (i = 0; i <= MAX_HW_POINTS ; i++) { points->red[i] = rgb_degamma[i].r; points->green[i] = rgb_degamma[i].g; points->blue[i] = rgb_degamma[i].b; @@ -1374,15 +1365,15 @@ bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans, kfree(rgb_degamma); } else if (trans == TRANSFER_FUNCTION_SRGB || trans == TRANSFER_FUNCTION_BT709) { - rgb_degamma = kzalloc(sizeof(*rgb_degamma) * (MAX_HW_DEGAMMA_POINTS + + rgb_degamma = kzalloc(sizeof(*rgb_degamma) * (MAX_HW_POINTS + _EXTRA_POINTS), GFP_KERNEL); if (!rgb_degamma) goto rgb_degamma_alloc_fail; build_degamma(rgb_degamma, - MAX_HW_DEGAMMA_POINTS, - degamma_coordinates_x, trans == TRANSFER_FUNCTION_SRGB ? true:false); - for (i = 0; i < MAX_HW_DEGAMMA_POINTS ; i++) { + MAX_HW_POINTS, + coordinates_x, trans == TRANSFER_FUNCTION_SRGB ? true:false); + for (i = 0; i <= MAX_HW_POINTS ; i++) { points->red[i] = rgb_degamma[i].r; points->green[i] = rgb_degamma[i].g; points->blue[i] = rgb_degamma[i].b; |