diff options
author | Dave Airlie <airlied@redhat.com> | 2022-09-12 19:17:40 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2022-09-12 19:17:41 +1000 |
commit | 47519d8224babc9dee489ea96dfeac726fe544cc (patch) | |
tree | ae7ecc2730bb6f15fc45061b424c3d982cc4b67e /drivers/gpu/drm/amd/display | |
parent | 89b03aeaef16f8ab48c10c399f97c836bdbae838 (diff) | |
parent | 780244a2fe8a82424c85f4cb15e45d0bbeec8f26 (diff) | |
download | linux-47519d8224babc9dee489ea96dfeac726fe544cc.tar.gz linux-47519d8224babc9dee489ea96dfeac726fe544cc.tar.bz2 linux-47519d8224babc9dee489ea96dfeac726fe544cc.zip |
Merge tag 'amd-drm-next-6.1-2022-09-08' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-6.1-2022-09-08:
amdgpu:
- Mode2 reset for RDNA2
- Lots of new DC documentation
- Add documentation about different asic families
- DSC improvements
- Aldebaran fixes
- Misc spelling and grammar fixes
- GFXOFF stats support for vangogh
- DC frame size fixes
- NBIO 7.7 updates
- DCN 3.2 updates
- DCN 3.1.4 Updates
- SMU 13.x updates
- Misc bug fixes
- Rework DC register offset handling
- GC 11.x updates
- PSP 13.x updates
- SDMA 6.x updates
- GMC 11.x updates
- SR-IOV updates
- PSP fixes for TA unloading
- DSC passthrough support
- Misc code cleanups
amdkfd:
- ISA fixes for some GC 10.3 IPs
- Misc code cleanups
radeon:
- Delayed work flush fix
- Use time_after for some jiffies calculations
drm:
- DSC passthrough aux support
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220908155202.57862-1-alexander.deucher@amd.com
Diffstat (limited to 'drivers/gpu/drm/amd/display')
74 files changed, 3390 insertions, 3467 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index e702f0d72d53..7a93162633ae 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1530,7 +1530,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) { adev->dm.dc->debug.disable_dsc = true; - adev->dm.dc->debug.disable_dsc_edp = true; } if (amdgpu_dc_debug_mask & DC_DISABLE_CLOCK_GATING) @@ -5604,7 +5603,8 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector, dc_dsc_policy_set_enable_dsc_when_not_needed( aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE); - if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_EDP && !dc->debug.disable_dsc_edp && + if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_EDP && + !aconnector->dc_link->panel_config.dsc.disable_dsc_edp && dc->caps.edp_dsc_support && aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE) { apply_dsc_policy_for_edp(aconnector, sink, stream, dsc_caps, max_dsc_target_bpp_limit_override); @@ -9304,6 +9304,7 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm /** * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM. + * * @dev: The DRM device * @state: The atomic state to commit * @@ -9360,9 +9361,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); /* Skip connectors that are disabled or part of modeset already. */ - if (!old_con_state->crtc && !new_con_state->crtc) - continue; - if (!new_con_state->crtc) continue; @@ -9889,8 +9887,19 @@ static int parse_hdmi_amd_vsdb(struct amdgpu_dm_connector *aconnector, return valid_vsdb_found ? i : -ENODEV; } +/** + * amdgpu_dm_update_freesync_caps - Update Freesync capabilities + * + * @connector: Connector to query. + * @edid: EDID from monitor + * + * Amdgpu supports Freesync in DP and HDMI displays, and it is required to keep + * track of some of the display information in the internal data struct used by + * amdgpu_dm. This function checks which type of connector we need to set the + * FreeSync parameters. + */ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector, - struct edid *edid) + struct edid *edid) { int i = 0; struct detailed_timing *timing; @@ -9903,8 +9912,8 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector, struct drm_device *dev = connector->dev; struct amdgpu_device *adev = drm_to_adev(dev); - bool freesync_capable = false; struct amdgpu_hdmi_vsdb_info vsdb_info = {0}; + bool freesync_capable = false; if (!connector->state) { DRM_ERROR("%s - Connector has no state", __func__); @@ -9933,7 +9942,6 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector, if (!adev->dm.freesync_module) goto update; - if (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT || sink->sink_signal == SIGNAL_TYPE_EDP) { bool edid_check_required = false; 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 90b306a1dd68..b44faaad9b0b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -598,6 +598,10 @@ struct amdgpu_dm_connector { * The 'current' sink is in dc_link->sink. */ struct dc_sink *dc_sink; struct dc_link *dc_link; + + /** + * @dc_em_sink: Reference to the emulated (virtual) sink. + */ struct dc_sink *dc_em_sink; /* DM only */ @@ -610,7 +614,16 @@ struct amdgpu_dm_connector { struct amdgpu_i2c_adapter *i2c; /* Monitor range limits */ - int min_vfreq ; + /** + * @min_vfreq: Minimal frequency supported by the display in Hz. This + * value is set to zero when there is no FreeSync support. + */ + int min_vfreq; + + /** + * @max_vfreq: Maximum frequency supported by the display in Hz. This + * value is set to zero when there is no FreeSync support. + */ int max_vfreq ; int pixel_clock_mhz; @@ -705,11 +718,34 @@ struct dm_connector_state { uint64_t pbn; }; +/** + * struct amdgpu_hdmi_vsdb_info - Keep track of the VSDB info + * + * AMDGPU supports FreeSync over HDMI by using the VSDB section, and this + * struct is useful to keep track of the display-specific information about + * FreeSync. + */ struct amdgpu_hdmi_vsdb_info { - unsigned int amd_vsdb_version; /* VSDB version, should be used to determine which VSIF to send */ - bool freesync_supported; /* FreeSync Supported */ - unsigned int min_refresh_rate_hz; /* FreeSync Minimum Refresh Rate in Hz */ - unsigned int max_refresh_rate_hz; /* FreeSync Maximum Refresh Rate in Hz */ + /** + * @amd_vsdb_version: Vendor Specific Data Block Version, should be + * used to determine which Vendor Specific InfoFrame (VSIF) to send. + */ + unsigned int amd_vsdb_version; + + /** + * @freesync_supported: FreeSync Supported. + */ + bool freesync_supported; + + /** + * @min_refresh_rate_hz: FreeSync Minimum Refresh Rate in Hz. + */ + unsigned int min_refresh_rate_hz; + + /** + * @max_refresh_rate_hz: FreeSync Maximum Refresh Rate in Hz + */ + unsigned int max_refresh_rate_hz; }; 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 a71177305bcd..a4cb23d059bd 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 @@ -29,7 +29,9 @@ #include "modules/color/color_gamma.h" #include "basics/conversion.h" -/* +/** + * DOC: overview + * * The DC interface to HW gives us the following color management blocks * per pipe (surface): * @@ -71,8 +73,8 @@ #define MAX_DRM_LUT_VALUE 0xFFFF -/* - * Initialize the color module. +/** + * amdgpu_dm_init_color_mod - Initialize the color module. * * We're not using the full color module, only certain components. * Only call setup functions for components that we need. @@ -82,7 +84,14 @@ void amdgpu_dm_init_color_mod(void) setup_x_points_distribution(); } -/* Extracts the DRM lut and lut size from a blob. */ +/** + * __extract_blob_lut - Extracts the DRM lut and lut size from a blob. + * @blob: DRM color mgmt property blob + * @size: lut size + * + * Returns: + * DRM LUT or NULL + */ static const struct drm_color_lut * __extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size) { @@ -90,13 +99,18 @@ __extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size) return blob ? (struct drm_color_lut *)blob->data : NULL; } -/* - * Return true if the given lut is a linear mapping of values, i.e. it acts - * like a bypass LUT. +/** + * __is_lut_linear - check if the given lut is a linear mapping of values + * @lut: given lut to check values + * @size: lut size * * It is considered linear if the lut represents: - * f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in - * [0, MAX_COLOR_LUT_ENTRIES) + * f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in [0, + * MAX_COLOR_LUT_ENTRIES) + * + * Returns: + * True if the given lut is a linear mapping of values, i.e. it acts like a + * bypass LUT. Otherwise, false. */ static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size) { @@ -119,9 +133,13 @@ static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size) return true; } -/* - * Convert the drm_color_lut to dc_gamma. The conversion depends on the size - * of the lut - whether or not it's legacy. +/** + * __drm_lut_to_dc_gamma - convert the drm_color_lut to dc_gamma. + * @lut: DRM lookup table for color conversion + * @gamma: DC gamma to set entries + * @is_legacy: legacy or atomic gamma + * + * The conversion depends on the size of the lut - whether or not it's legacy. */ static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut, struct dc_gamma *gamma, bool is_legacy) @@ -154,8 +172,11 @@ static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut, } } -/* - * Converts a DRM CTM to a DC CSC float matrix. +/** + * __drm_ctm_to_dc_matrix - converts a DRM CTM to a DC CSC float matrix + * @ctm: DRM color transformation matrix + * @matrix: DC CSC float matrix + * * The matrix needs to be a 3x4 (12 entry) matrix. */ static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm, @@ -189,7 +210,18 @@ static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm, } } -/* Calculates the legacy transfer function - only for sRGB input space. */ +/** + * __set_legacy_tf - Calculates the legacy transfer function + * @func: transfer function + * @lut: lookup table that defines the color space + * @lut_size: size of respective lut + * @has_rom: if ROM can be used for hardcoded curve + * + * Only for sRGB input space + * + * Returns: + * 0 in case of success, -ENOMEM if fails + */ static int __set_legacy_tf(struct dc_transfer_func *func, const struct drm_color_lut *lut, uint32_t lut_size, bool has_rom) @@ -218,7 +250,16 @@ static int __set_legacy_tf(struct dc_transfer_func *func, return res ? 0 : -ENOMEM; } -/* Calculates the output transfer function based on expected input space. */ +/** + * __set_output_tf - calculates the output transfer function based on expected input space. + * @func: transfer function + * @lut: lookup table that defines the color space + * @lut_size: size of respective lut + * @has_rom: if ROM can be used for hardcoded curve + * + * Returns: + * 0 in case of success. -ENOMEM if fails. + */ static int __set_output_tf(struct dc_transfer_func *func, const struct drm_color_lut *lut, uint32_t lut_size, bool has_rom) @@ -262,7 +303,16 @@ static int __set_output_tf(struct dc_transfer_func *func, return res ? 0 : -ENOMEM; } -/* Caculates the input transfer function based on expected input space. */ +/** + * __set_input_tf - calculates the input transfer function based on expected + * input space. + * @func: transfer function + * @lut: lookup table that defines the color space + * @lut_size: size of respective lut. + * + * Returns: + * 0 in case of success. -ENOMEM if fails. + */ static int __set_input_tf(struct dc_transfer_func *func, const struct drm_color_lut *lut, uint32_t lut_size) { @@ -285,13 +335,14 @@ static int __set_input_tf(struct dc_transfer_func *func, } /** - * amdgpu_dm_verify_lut_sizes + * amdgpu_dm_verify_lut_sizes - verifies if DRM luts match the hw supported sizes * @crtc_state: the DRM CRTC state * - * Verifies that the Degamma and Gamma LUTs attached to the |crtc_state| are of - * the expected size. + * Verifies that the Degamma and Gamma LUTs attached to the &crtc_state + * are of the expected size. * - * Returns 0 on success. + * Returns: + * 0 on success. -EINVAL if any lut sizes are invalid. */ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) { @@ -327,9 +378,9 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) * of the HW blocks as long as the CRTC CTM always comes before the * CRTC RGM and after the CRTC DGM. * - * The CRTC RGM block will be placed in the RGM LUT block if it is non-linear. - * The CRTC DGM block will be placed in the DGM LUT block if it is non-linear. - * The CRTC CTM will be placed in the gamut remap block if it is non-linear. + * - The CRTC RGM block will be placed in the RGM LUT block if it is non-linear. + * - The CRTC DGM block will be placed in the DGM LUT block if it is non-linear. + * - The CRTC CTM will be placed in the gamut remap block if it is non-linear. * * The RGM block is typically more fully featured and accurate across * all ASICs - DCE can't support a custom non-linear CRTC DGM. @@ -338,7 +389,8 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) * management at once we have to either restrict the usage of CRTC properties * or blend adjustments together. * - * Returns 0 on success. + * Returns: + * 0 on success. Error code if setup fails. */ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) { @@ -393,7 +445,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) if (r) return r; } else if (has_regamma) { - /* CRTC RGM goes into RGM LUT. */ + /* If atomic regamma, CRTC RGM goes into RGM LUT. */ stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS; stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; @@ -450,9 +502,10 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) * * Update the underlying dc_stream_state's input transfer function (ITF) in * preparation for hardware commit. The transfer function used depends on - * the prepartion done on the stream for color management. + * the preparation done on the stream for color management. * - * Returns 0 on success. + * Returns: + * 0 on success. -ENOMEM if mem allocation fails. */ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, struct dc_plane_state *dc_plane_state) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 0e48824f55e3..ee242d9d8b06 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -3288,6 +3288,7 @@ void crtc_debugfs_init(struct drm_crtc *crtc) &crc_win_y_end_fops); debugfs_create_file_unsafe("crc_win_update", 0644, dir, crtc, &crc_win_update_fops); + dput(dir); #endif debugfs_create_file("amdgpu_current_bpc", 0644, crtc->debugfs_entry, crtc, &amdgpu_current_bpc_fops); 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 7fa36ff42c0d..b8077fcd4651 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 @@ -691,8 +691,14 @@ bool dm_helpers_dp_write_dsc_enable( const struct dc_stream_state *stream, bool enable) { - uint8_t enable_dsc = enable ? 1 : 0; + static const uint8_t DSC_DISABLE; + static const uint8_t DSC_DECODING = 0x01; + static const uint8_t DSC_PASSTHROUGH = 0x02; + struct amdgpu_dm_connector *aconnector; + struct drm_dp_mst_port *port; + uint8_t enable_dsc = enable ? DSC_DECODING : DSC_DISABLE; + uint8_t enable_passthrough = enable ? DSC_PASSTHROUGH : DSC_DISABLE; uint8_t ret = 0; if (!stream) @@ -712,8 +718,39 @@ bool dm_helpers_dp_write_dsc_enable( aconnector->dsc_aux, stream, enable_dsc); #endif - ret = drm_dp_dpcd_write(aconnector->dsc_aux, DP_DSC_ENABLE, &enable_dsc, 1); - DC_LOG_DC("Send DSC %s to MST RX\n", enable_dsc ? "enable" : "disable"); + port = aconnector->port; + + if (enable) { + if (port->passthrough_aux) { + ret = drm_dp_dpcd_write(port->passthrough_aux, + DP_DSC_ENABLE, + &enable_passthrough, 1); + DC_LOG_DC("Sent DSC pass-through enable to virtual dpcd port, ret = %u\n", + ret); + } + + ret = drm_dp_dpcd_write(aconnector->dsc_aux, + DP_DSC_ENABLE, &enable_dsc, 1); + DC_LOG_DC("Sent DSC decoding enable to %s port, ret = %u\n", + (port->passthrough_aux) ? "remote RX" : + "virtual dpcd", + ret); + } else { + ret = drm_dp_dpcd_write(aconnector->dsc_aux, + DP_DSC_ENABLE, &enable_dsc, 1); + DC_LOG_DC("Sent DSC decoding disable to %s port, ret = %u\n", + (port->passthrough_aux) ? "remote RX" : + "virtual dpcd", + ret); + + if (port->passthrough_aux) { + ret = drm_dp_dpcd_write(port->passthrough_aux, + DP_DSC_ENABLE, + &enable_passthrough, 1); + DC_LOG_DC("Sent DSC pass-through disable to virtual dpcd port, ret = %u\n", + ret); + } + } } if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || stream->signal == SIGNAL_TYPE_EDP) { @@ -730,7 +767,7 @@ bool dm_helpers_dp_write_dsc_enable( #endif } - return (ret > 0); + return ret; } bool dm_helpers_is_dp_sink_present(struct dc_link *link) @@ -841,6 +878,25 @@ void dm_helpers_smu_timeout(struct dc_context *ctx, unsigned int msg_id, unsigne //amdgpu_device_gpu_recover(dc_context->driver-context, NULL); } +void dm_helpers_init_panel_settings( + struct dc_context *ctx, + struct dc_panel_config *panel_config) +{ + // Feature DSC + panel_config->dsc.disable_dsc_edp = false; + panel_config->dsc.force_dsc_edp_policy = 0; +} + +void dm_helpers_override_panel_settings( + struct dc_context *ctx, + struct dc_panel_config *panel_config) +{ + // Feature DSC + if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) { + panel_config->dsc.disable_dsc_edp = true; + } +} + void *dm_helpers_allocate_gpu_mem( struct dc_context *ctx, enum dc_gpu_mem_alloc_type type, 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 bd9606307dc7..6ff96b4bdda5 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 @@ -36,6 +36,7 @@ #include "dm_helpers.h" #include "dc_link_ddc.h" +#include "dc_link_dp.h" #include "ddc_service_types.h" #include "dpcd_defs.h" @@ -1351,19 +1352,90 @@ clean_exit: return (ret == 0); } -#endif +static unsigned int kbps_from_pbn(unsigned int pbn) +{ + unsigned int kbps = pbn; + + kbps *= (1000000 / PEAK_FACTOR_X1000); + kbps *= 8; + kbps *= 54; + kbps /= 64; + + return kbps; +} + +static bool is_dsc_common_config_possible(struct dc_stream_state *stream, + struct dc_dsc_bw_range *bw_range) +{ + struct dc_dsc_policy dsc_policy = {0}; + + dc_dsc_get_policy_for_timing(&stream->timing, 0, &dsc_policy); + dc_dsc_compute_bandwidth_range(stream->sink->ctx->dc->res_pool->dscs[0], + stream->sink->ctx->dc->debug.dsc_min_slice_height_override, + dsc_policy.min_target_bpp * 16, + dsc_policy.max_target_bpp * 16, + &stream->sink->dsc_caps.dsc_dec_caps, + &stream->timing, bw_range); + + return bw_range->max_target_bpp_x16 && bw_range->min_target_bpp_x16; +} +#endif /* CONFIG_DRM_AMD_DC_DCN */ enum dc_status dm_dp_mst_is_port_support_mode( struct amdgpu_dm_connector *aconnector, struct dc_stream_state *stream) { int bpp, pbn, branch_max_throughput_mps = 0; +#if defined(CONFIG_DRM_AMD_DC_DCN) + struct dc_link_settings cur_link_settings; + unsigned int end_to_end_bw_in_kbps = 0; + unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0; + unsigned int max_compressed_bw_in_kbps = 0; + struct dc_dsc_bw_range bw_range = {0}; - /* check if mode could be supported within fUll_pbn */ - bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3; - pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false); - if (pbn > aconnector->port->full_pbn) - return DC_FAIL_BANDWIDTH_VALIDATE; + /* + * check if the mode could be supported if DSC pass-through is supported + * AND check if there enough bandwidth available to support the mode + * with DSC enabled. + */ + if (is_dsc_common_config_possible(stream, &bw_range) && + aconnector->port->passthrough_aux) { + mutex_lock(&aconnector->mst_mgr.lock); + + cur_link_settings = stream->link->verified_link_cap; + + upper_link_bw_in_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, + &cur_link_settings + ); + down_link_bw_in_kbps = kbps_from_pbn(aconnector->port->full_pbn); + + /* pick the bottleneck */ + end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps, + down_link_bw_in_kbps); + + mutex_unlock(&aconnector->mst_mgr.lock); + + /* + * use the maximum dsc compression bandwidth as the required + * bandwidth for the mode + */ + max_compressed_bw_in_kbps = bw_range.min_kbps; + + if (end_to_end_bw_in_kbps < max_compressed_bw_in_kbps) { + DRM_DEBUG_DRIVER("Mode does not fit into DSC pass-through bandwidth validation\n"); + return DC_FAIL_BANDWIDTH_VALIDATE; + } + } else { +#endif + /* check if mode could be supported within full_pbn */ + bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3; + pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false); + + if (pbn > aconnector->port->full_pbn) + return DC_FAIL_BANDWIDTH_VALIDATE; +#if defined(CONFIG_DRM_AMD_DC_DCN) + } +#endif /* check is mst dsc output bandwidth branch_overall_throughput_0_mps */ switch (stream->timing.pixel_encoding) { diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c index c450dd66d194..dfd3be49eac8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -34,6 +34,7 @@ #include "dal_asic_id.h" #include "amdgpu_display.h" #include "amdgpu_dm_trace.h" +#include "amdgpu_dm_plane.h" #include "gc/gc_11_0_0_offset.h" #include "gc/gc_11_0_0_sh_mask.h" @@ -149,12 +150,12 @@ static void add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_ *size += 1; } -bool modifier_has_dcc(uint64_t modifier) +static bool modifier_has_dcc(uint64_t modifier) { return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier); } -unsigned modifier_gfx9_swizzle_mode(uint64_t modifier) +static unsigned modifier_gfx9_swizzle_mode(uint64_t modifier) { if (modifier == DRM_FORMAT_MOD_LINEAR) return 0; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h index 95168c2cfa6f..286981a2dd40 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h @@ -36,17 +36,9 @@ int fill_dc_scaling_info(struct amdgpu_device *adev, const struct drm_plane_state *state, struct dc_scaling_info *scaling_info); -void get_min_max_dc_plane_scaling(struct drm_device *dev, - struct drm_framebuffer *fb, - int *min_downscale, int *max_upscale); - int dm_plane_helper_check_state(struct drm_plane_state *state, struct drm_crtc_state *new_crtc_state); -bool modifier_has_dcc(uint64_t modifier); - -unsigned int modifier_gfx9_swizzle_mode(uint64_t modifier); - int fill_plane_buffer_attributes(struct amdgpu_device *adev, const struct amdgpu_framebuffer *afb, const enum surface_pixel_format format, diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index 09fbb7ad5362..ead4da11a992 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -44,25 +44,6 @@ #include "bios_parser_common.h" -/* Temporarily add in defines until ObjectID.h patch is updated in a few days */ -#ifndef GENERIC_OBJECT_ID_BRACKET_LAYOUT -#define GENERIC_OBJECT_ID_BRACKET_LAYOUT 0x05 -#endif /* GENERIC_OBJECT_ID_BRACKET_LAYOUT */ - -#ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 -#define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT) -#endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 */ - -#ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 -#define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT) -#endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 */ - #define DC_LOGGER \ bp->base.ctx->logger diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c index c09be3f15fe6..d43258e3cd4f 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c @@ -48,6 +48,11 @@ #include "dc_dmub_srv.h" +#include "logger_types.h" +#undef DC_LOGGER +#define DC_LOGGER \ + clk_mgr->base.base.ctx->logger + #include "yellow_carp_offset.h" #define regCLK1_CLK_PLL_REQ 0x0237 @@ -737,8 +742,49 @@ void dcn31_clk_mgr_construct( clk_mgr->base.base.bw_params = &dcn31_bw_params; if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) { + int i; + dcn31_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks); + DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n" + "NumDispClkLevelsEnabled: %d\n" + "NumSocClkLevelsEnabled: %d\n" + "VcnClkLevelsEnabled: %d\n" + "NumDfPst atesEnabled: %d\n" + "MinGfxClk: %d\n" + "MaxGfxClk: %d\n", + smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled, + smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled, + smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled, + smu_dpm_clks.dpm_clks->VcnClkLevelsEnabled, + smu_dpm_clks.dpm_clks->NumDfPstatesEnabled, + smu_dpm_clks.dpm_clks->MinGfxClk, + smu_dpm_clks.dpm_clks->MaxGfxClk); + for (i = 0; i < smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled; i++) { + DC_LOG_SMU("smu_dpm_clks.dpm_clks->DcfClocks[%d] = %d\n", + i, + smu_dpm_clks.dpm_clks->DcfClocks[i]); + } + for (i = 0; i < smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled; i++) { + DC_LOG_SMU("smu_dpm_clks.dpm_clks->DispClocks[%d] = %d\n", + i, smu_dpm_clks.dpm_clks->DispClocks[i]); + } + for (i = 0; i < smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled; i++) { + DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocClocks[%d] = %d\n", + i, smu_dpm_clks.dpm_clks->SocClocks[i]); + } + for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++) + DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocVoltage[%d] = %d\n", + i, smu_dpm_clks.dpm_clks->SocVoltage[i]); + + for (i = 0; i < NUM_DF_PSTATE_LEVELS; i++) { + DC_LOG_SMU("smu_dpm_clks.dpm_clks.DfPstateTable[%d].FClk = %d\n" + "smu_dpm_clks.dpm_clks->DfPstateTable[%d].MemClk= %d\n" + "smu_dpm_clks.dpm_clks->DfPstateTable[%d].Voltage = %d\n", + i, smu_dpm_clks.dpm_clks->DfPstateTable[i].FClk, + i, smu_dpm_clks.dpm_clks->DfPstateTable[i].MemClk, + i, smu_dpm_clks.dpm_clks->DfPstateTable[i].Voltage); + } if (ctx->dc_bios && ctx->dc_bios->integrated_info) { dcn31_clk_mgr_helper_populate_bw_params( &clk_mgr->base, diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c index beb025cd3dc2..171c38fac6a3 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c @@ -51,6 +51,13 @@ #include "dc_link_dp.h" #include "dcn314_smu.h" + +#include "logger_types.h" +#undef DC_LOGGER +#define DC_LOGGER \ + clk_mgr->base.base.ctx->logger + + #define MAX_INSTANCE 7 #define MAX_SEGMENT 8 @@ -614,7 +621,7 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk; bw_params->clk_table.entries[i].wck_ratio = convert_wck_ratio( clock_table->DfPstateTable[min_pstate].WckRatio); - }; + } /* Make sure to include at least one entry at highest pstate */ if (max_pstate != min_pstate || i == 0) { @@ -775,7 +782,48 @@ void dcn314_clk_mgr_construct( clk_mgr->base.base.bw_params = &dcn314_bw_params; if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) { + int i; + dcn314_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks); + DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n" + "NumDispClkLevelsEnabled: %d\n" + "NumSocClkLevelsEnabled: %d\n" + "VcnClkLevelsEnabled: %d\n" + "NumDfPst atesEnabled: %d\n" + "MinGfxClk: %d\n" + "MaxGfxClk: %d\n", + smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled, + smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled, + smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled, + smu_dpm_clks.dpm_clks->VcnClkLevelsEnabled, + smu_dpm_clks.dpm_clks->NumDfPstatesEnabled, + smu_dpm_clks.dpm_clks->MinGfxClk, + smu_dpm_clks.dpm_clks->MaxGfxClk); + for (i = 0; i < smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled; i++) { + DC_LOG_SMU("smu_dpm_clks.dpm_clks->DcfClocks[%d] = %d\n", + i, + smu_dpm_clks.dpm_clks->DcfClocks[i]); + } + for (i = 0; i < smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled; i++) { + DC_LOG_SMU("smu_dpm_clks.dpm_clks->DispClocks[%d] = %d\n", + i, smu_dpm_clks.dpm_clks->DispClocks[i]); + } + for (i = 0; i < smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled; i++) { + DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocClocks[%d] = %d\n", + i, smu_dpm_clks.dpm_clks->SocClocks[i]); + } + for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++) + DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocVoltage[%d] = %d\n", + i, smu_dpm_clks.dpm_clks->SocVoltage[i]); + + for (i = 0; i < NUM_DF_PSTATE_LEVELS; i++) { + DC_LOG_SMU("smu_dpm_clks.dpm_clks.DfPstateTable[%d].FClk = %d\n" + "smu_dpm_clks.dpm_clks->DfPstateTable[%d].MemClk= %d\n" + "smu_dpm_clks.dpm_clks->DfPstateTable[%d].Voltage = %d\n", + i, smu_dpm_clks.dpm_clks->DfPstateTable[i].FClk, + i, smu_dpm_clks.dpm_clks->DfPstateTable[i].MemClk, + i, smu_dpm_clks.dpm_clks->DfPstateTable[i].Voltage); + } if (ctx->dc_bios && ctx->dc_bios->integrated_info && ctx->dc->config.use_default_clock_table == false) { dcn314_clk_mgr_helper_populate_bw_params( diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c index cc076621f5e6..14071aef5eab 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c @@ -41,6 +41,11 @@ #include "dc_dmub_srv.h" +#include "logger_types.h" +#undef DC_LOGGER +#define DC_LOGGER \ + clk_mgr->base.base.ctx->logger + #include "dc_link_dp.h" #define TO_CLK_MGR_DCN315(clk_mgr)\ @@ -507,7 +512,7 @@ static void dcn315_clk_mgr_helper_populate_bw_params( bw_params->clk_table.entries[i].dispclk_mhz = clock_table->DispClocks[i]; bw_params->clk_table.entries[i].dppclk_mhz = clock_table->DppClocks[i]; bw_params->clk_table.entries[i].wck_ratio = 1; - }; + } /* Make sure to include at least one entry and highest pstate */ if (max_pstate != min_pstate || i == 0) { @@ -666,7 +671,48 @@ void dcn315_clk_mgr_construct( clk_mgr->base.base.bw_params = &dcn315_bw_params; if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) { + int i; + dcn315_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks); + DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n" + "NumDispClkLevelsEnabled: %d\n" + "NumSocClkLevelsEnabled: %d\n" + "VcnClkLevelsEnabled: %d\n" + "NumDfPst atesEnabled: %d\n" + "MinGfxClk: %d\n" + "MaxGfxClk: %d\n", + smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled, + smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled, + smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled, + smu_dpm_clks.dpm_clks->VcnClkLevelsEnabled, + smu_dpm_clks.dpm_clks->NumDfPstatesEnabled, + smu_dpm_clks.dpm_clks->MinGfxClk, + smu_dpm_clks.dpm_clks->MaxGfxClk); + for (i = 0; i < smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled; i++) { + DC_LOG_SMU("smu_dpm_clks.dpm_clks->DcfClocks[%d] = %d\n", + i, + smu_dpm_clks.dpm_clks->DcfClocks[i]); + } + for (i = 0; i < smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled; i++) { + DC_LOG_SMU("smu_dpm_clks.dpm_clks->DispClocks[%d] = %d\n", + i, smu_dpm_clks.dpm_clks->DispClocks[i]); + } + for (i = 0; i < smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled; i++) { + DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocClocks[%d] = %d\n", + i, smu_dpm_clks.dpm_clks->SocClocks[i]); + } + for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++) + DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocVoltage[%d] = %d\n", + i, smu_dpm_clks.dpm_clks->SocVoltage[i]); + + for (i = 0; i < NUM_DF_PSTATE_LEVELS; i++) { + DC_LOG_SMU("smu_dpm_clks.dpm_clks.DfPstateTable[%d].FClk = %d\n" + "smu_dpm_clks.dpm_clks->DfPstateTable[%d].MemClk= %d\n" + "smu_dpm_clks.dpm_clks->DfPstateTable[%d].Voltage = %d\n", + i, smu_dpm_clks.dpm_clks->DfPstateTable[i].FClk, + i, smu_dpm_clks.dpm_clks->DfPstateTable[i].MemClk, + i, smu_dpm_clks.dpm_clks->DfPstateTable[i].Voltage); + } if (ctx->dc_bios && ctx->dc_bios->integrated_info) { dcn315_clk_mgr_helper_populate_bw_params( diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index aeecca68dea7..9860bf38c547 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -638,14 +638,17 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, /** * dc_stream_get_crc() - Get CRC values for the given stream. - * @dc: DC object + * + * @dc: DC object. * @stream: The DC stream state of the stream to get CRCs from. - * @r_cr: CRC value for the first of the 3 channels stored here. - * @g_y: CRC value for the second of the 3 channels stored here. - * @b_cb: CRC value for the third of the 3 channels stored here. + * @r_cr: CRC value for the red component. + * @g_y: CRC value for the green component. + * @b_cb: CRC value for the blue component. * * dc_stream_configure_crc needs to be called beforehand to enable CRCs. - * Return false if stream is not found, or if CRCs are not enabled. + * + * Return: + * false if stream is not found, or if CRCs are not enabled. */ bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream, uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb) @@ -1094,7 +1097,8 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) dc->current_state->stream_count != context->stream_count) should_disable = true; - if (old_stream && !dc->current_state->res_ctx.pipe_ctx[i].top_pipe) { + if (old_stream && !dc->current_state->res_ctx.pipe_ctx[i].top_pipe && + !dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe) { struct pipe_ctx *old_pipe, *new_pipe; old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; @@ -1177,7 +1181,11 @@ static void disable_vbios_mode_if_required( pipe->stream_res.pix_clk_params.requested_pix_clk_100hz; if (pix_clk_100hz != requested_pix_clk_100hz) { - core_link_disable_stream(pipe); + if (dc->hwss.update_phy_state) + dc->hwss.update_phy_state(dc->current_state, + pipe, TX_OFF_SYMCLK_OFF); + else + core_link_disable_stream(pipe); pipe->stream->dpms_off = false; } } @@ -3060,7 +3068,11 @@ static void commit_planes_do_stream_update(struct dc *dc, if (stream_update->dpms_off) { if (*stream_update->dpms_off) { - core_link_disable_stream(pipe_ctx); + if (dc->hwss.update_phy_state) + dc->hwss.update_phy_state(dc->current_state, + pipe_ctx, TX_OFF_SYMCLK_ON); + else + core_link_disable_stream(pipe_ctx); /* for dpms, keep acquired resources*/ if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only) pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); @@ -3071,7 +3083,11 @@ static void commit_planes_do_stream_update(struct dc *dc, if (get_seamless_boot_stream_count(context) == 0) dc->hwss.prepare_bandwidth(dc, dc->current_state); - core_link_enable_stream(dc->current_state, pipe_ctx); + if (dc->hwss.update_phy_state) + dc->hwss.update_phy_state(dc->current_state, + pipe_ctx, TX_ON_SYMCLK_ON); + else + core_link_enable_stream(dc->current_state, pipe_ctx); } } @@ -3098,11 +3114,9 @@ static void commit_planes_do_stream_update(struct dc *dc, static bool dc_dmub_should_send_dirty_rect_cmd(struct dc *dc, struct dc_stream_state *stream) { - if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) - return true; - - if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_1 && - dc->debug.enable_sw_cntl_psr) + if ((stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1 + || stream->link->psr_settings.psr_version == DC_PSR_VERSION_1) + && stream->ctx->dce_version >= DCN_VERSION_3_1) return true; return false; @@ -3318,10 +3332,6 @@ static void commit_planes_for_stream(struct dc *dc, if (dc->hwss.program_front_end_for_ctx) dc->hwss.program_front_end_for_ctx(dc, context); - if (update_type != UPDATE_TYPE_FAST) - if (dc->hwss.commit_subvp_config) - dc->hwss.commit_subvp_config(dc, context); - if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { dc->hwss.interdependent_update_lock(dc, context, false); } else { @@ -3329,16 +3339,15 @@ static void commit_planes_for_stream(struct dc *dc, } dc->hwss.post_unlock_program_front_end(dc, context); + if (update_type != UPDATE_TYPE_FAST) + if (dc->hwss.commit_subvp_config) + dc->hwss.commit_subvp_config(dc, context); + /* Since phantom pipe programming is moved to post_unlock_program_front_end, * move the SubVP lock to after the phantom pipes have been setup */ - if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { - if (dc->hwss.subvp_pipe_control_lock) - dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use); - } else { - if (dc->hwss.subvp_pipe_control_lock) - dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use); - } + if (dc->hwss.subvp_pipe_control_lock) + dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use); return; } @@ -3462,10 +3471,6 @@ static void commit_planes_for_stream(struct dc *dc, } - if (update_type != UPDATE_TYPE_FAST) - if (dc->hwss.commit_subvp_config) - dc->hwss.commit_subvp_config(dc, context); - if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { dc->hwss.interdependent_update_lock(dc, context, false); } else { @@ -3503,6 +3508,10 @@ static void commit_planes_for_stream(struct dc *dc, if (update_type != UPDATE_TYPE_FAST) dc->hwss.post_unlock_program_front_end(dc, context); + if (update_type != UPDATE_TYPE_FAST) + if (dc->hwss.commit_subvp_config) + dc->hwss.commit_subvp_config(dc, context); + /* Since phantom pipe programming is moved to post_unlock_program_front_end, * move the SubVP lock to after the phantom pipes have been setup */ @@ -3543,8 +3552,10 @@ static bool commit_minimal_transition_state(struct dc *dc, if (!transition_context) return false; - tmp_policy = dc->debug.pipe_split_policy; - dc->debug.pipe_split_policy = MPC_SPLIT_AVOID; + if (!dc->config.is_vmin_only_asic) { + tmp_policy = dc->debug.pipe_split_policy; + dc->debug.pipe_split_policy = MPC_SPLIT_AVOID; + } dc_resource_state_copy_construct(transition_base_context, transition_context); @@ -3570,7 +3581,8 @@ static bool commit_minimal_transition_state(struct dc *dc, dc_release_state(transition_context); //restore previous pipe split policy - dc->debug.pipe_split_policy = tmp_policy; + if (!dc->config.is_vmin_only_asic) + dc->debug.pipe_split_policy = tmp_policy; if (ret != DC_OK) { //this should never happen @@ -4275,8 +4287,8 @@ void dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(struct dc *dc) /* ***************************************************************************** * Function: dc_is_dmub_outbox_supported - - * - * @brief + * + * @brief * Checks whether DMUB FW supports outbox notifications, if supported * DM should register outbox interrupt prior to actually enabling interrupts * via dc_enable_dmub_outbox diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c index 2a8007928210..9dd705b985b9 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c @@ -402,6 +402,44 @@ void get_hdr_visual_confirm_color( } } +void get_subvp_visual_confirm_color( + struct dc *dc, + struct pipe_ctx *pipe_ctx, + struct tg_color *color) +{ + uint32_t color_value = MAX_TG_COLOR_VALUE; + bool enable_subvp = false; + int i; + + if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx) + return; + + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + + if (pipe->stream && pipe->stream->mall_stream_config.paired_stream && + pipe->stream->mall_stream_config.type == SUBVP_MAIN) { + /* SubVP enable - red */ + color->color_r_cr = color_value; + enable_subvp = true; + + if (pipe_ctx->stream == pipe->stream) + return; + break; + } + } + + if (enable_subvp && pipe_ctx->stream->mall_stream_config.type == SUBVP_NONE) { + color->color_r_cr = 0; + if (pipe_ctx->stream->ignore_msa_timing_param == 1) + /* SubVP enable and DRR on - green */ + color->color_g_y = color_value; + else + /* SubVP enable and No DRR - blue */ + color->color_b_cb = color_value; + } +} + void get_surface_tile_visual_confirm_color( struct pipe_ctx *pipe_ctx, struct tg_color *color) 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 506fdbbc1b60..4ab27e231337 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1311,6 +1311,14 @@ static bool detect_link_and_local_sink(struct dc_link *link, sink->edid_caps.audio_modes[i].sample_rate, sink->edid_caps.audio_modes[i].sample_size); } + + if (link->connector_signal == SIGNAL_TYPE_EDP) { + // Init dc_panel_config + dm_helpers_init_panel_settings(dc_ctx, &link->panel_config); + // Override dc_panel_config if system has specific settings + dm_helpers_override_panel_settings(dc_ctx, &link->panel_config); + } + } else { /* From Connected-to-Disconnected. */ link->type = dc_connection_none; @@ -2069,11 +2077,7 @@ static enum dc_status enable_link_edp( struct dc_state *state, struct pipe_ctx *pipe_ctx) { - enum dc_status status; - - status = enable_link_dp(state, pipe_ctx); - - return status; + return enable_link_dp(state, pipe_ctx); } static enum dc_status enable_link_dp_mst( @@ -4295,18 +4299,6 @@ void core_link_enable_stream( if (pipe_ctx->stream->dpms_off) return; - /* Have to setup DSC before DIG FE and BE are connected (which happens before the - * link training). This is to make sure the bandwidth sent to DIG BE won't be - * bigger than what the link and/or DIG BE can handle. VBID[6]/CompressedStream_flag - * will be automatically set at a later time when the video is enabled - * (DP_VID_STREAM_EN = 1). - */ - if (pipe_ctx->stream->timing.flags.DSC) { - if (dc_is_dp_signal(pipe_ctx->stream->signal) || - dc_is_virtual_signal(pipe_ctx->stream->signal)) - dp_set_dsc_enable(pipe_ctx, true); - } - status = enable_link(state, pipe_ctx); if (status != DC_OK) { @@ -4736,7 +4728,7 @@ bool dc_link_should_enable_fec(const struct dc_link *link) else if (link->connector_signal == SIGNAL_TYPE_EDP && (link->dpcd_caps.dsc_caps.dsc_basic_caps.fields. dsc_support.DSC_SUPPORT == false - || link->dc->debug.disable_dsc_edp + || link->panel_config.dsc.disable_dsc_edp || !link->dc->caps.edp_dsc_support)) force_disable = true; 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 48dad093ae8b..e2413d2908c9 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 @@ -3743,7 +3743,7 @@ static bool decide_edp_link_settings_with_dsc(struct dc_link *link, unsigned int policy = 0; - policy = link->ctx->dc->debug.force_dsc_edp_policy; + policy = link->panel_config.dsc.force_dsc_edp_policy; if (max_link_rate == LINK_RATE_UNKNOWN) max_link_rate = link->verified_link_cap.link_rate; /* @@ -3909,7 +3909,7 @@ bool decide_link_settings(struct dc_stream_state *stream, if (stream->timing.flags.DSC) { enum dc_link_rate max_link_rate = LINK_RATE_UNKNOWN; - if (link->ctx->dc->debug.force_dsc_edp_policy) { + if (link->panel_config.dsc.force_dsc_edp_policy) { /* calculate link max link rate cap*/ struct dc_link_settings tmp_link_setting; struct dc_crtc_timing tmp_timing = stream->timing; @@ -4519,7 +4519,11 @@ void dc_link_dp_handle_link_loss(struct dc_link *link) pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off && pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) { - core_link_disable_stream(pipe_ctx); + if (link->dc->hwss.update_phy_state) + link->dc->hwss.update_phy_state(link->dc->current_state, + pipe_ctx, TX_OFF_SYMCLK_OFF); + else + core_link_disable_stream(pipe_ctx); } } @@ -4527,7 +4531,11 @@ void dc_link_dp_handle_link_loss(struct dc_link *link) pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off && pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) { - core_link_enable_stream(link->dc->current_state, pipe_ctx); + if (link->dc->hwss.update_phy_state) + link->dc->hwss.update_phy_state(link->dc->current_state, + pipe_ctx, TX_ON_SYMCLK_ON); + else + core_link_enable_stream(link->dc->current_state, pipe_ctx); } } } @@ -5024,6 +5032,10 @@ static void determine_lttpr_mode(struct dc_link *link) bool vbios_lttpr_enable = link->dc->caps.vbios_lttpr_enable; bool vbios_lttpr_interop = link->dc->caps.vbios_lttpr_aware; + if (link->ctx->dc->debug.lttpr_mode_override != 0) { + link->lttpr_mode = link->ctx->dc->debug.lttpr_mode_override; + return; + } if ((link->dc->config.allow_lttpr_non_transparent_mode.bits.DP2_0 && link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED)) { @@ -5267,6 +5279,7 @@ static bool retrieve_link_cap(struct dc_link *link) union dp_downstream_port_present ds_port = { 0 }; enum dc_status status = DC_ERROR_UNEXPECTED; uint32_t read_dpcd_retry_cnt = 3; + uint32_t aux_channel_retry_cnt = 0; int i; struct dp_sink_hw_fw_revision dp_hw_fw_revision; const uint32_t post_oui_delay = 30; // 30ms @@ -5294,21 +5307,43 @@ static bool retrieve_link_cap(struct dc_link *link) status = wa_try_to_wake_dprx(link, timeout_ms); } + while (status != DC_OK && aux_channel_retry_cnt < 10) { + status = core_link_read_dpcd(link, DP_SET_POWER, + &dpcd_power_state, sizeof(dpcd_power_state)); + + /* Delay 1 ms if AUX CH is in power down state. Based on spec + * section 2.3.1.2, if AUX CH may be powered down due to + * write to DPCD 600h = 2. Sink AUX CH is monitoring differential + * signal and may need up to 1 ms before being able to reply. + */ + if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3) { + udelay(1000); + aux_channel_retry_cnt++; + } + } + + /* If aux channel is not active, return false and trigger another detect*/ + if (status != DC_OK) { + dpcd_power_state = DP_SET_POWER_D0; + status = core_link_write_dpcd( + link, + DP_SET_POWER, + &dpcd_power_state, + sizeof(dpcd_power_state)); + + dpcd_power_state = DP_SET_POWER_D3; + status = core_link_write_dpcd( + link, + DP_SET_POWER, + &dpcd_power_state, + sizeof(dpcd_power_state)); + return false; + } + is_lttpr_present = dp_retrieve_lttpr_cap(link); /* Read DP tunneling information. */ status = dpcd_get_tunneling_device_data(link); - status = core_link_read_dpcd(link, DP_SET_POWER, - &dpcd_power_state, sizeof(dpcd_power_state)); - - /* Delay 1 ms if AUX CH is in power down state. Based on spec - * section 2.3.1.2, if AUX CH may be powered down due to - * write to DPCD 600h = 2. Sink AUX CH is monitoring differential - * signal and may need up to 1 ms before being able to reply. - */ - if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3) - udelay(1000); - dpcd_set_source_specific_data(link); /* Sink may need to configure internals based on vendor, so allow some * time before proceeding with possibly vendor specific transactions 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 7dbab15bfa68..29f27e3fe3ac 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1904,9 +1904,6 @@ bool dc_is_stream_unchanged( if (memcmp(&old_stream->audio_info, &stream->audio_info, sizeof(stream->audio_info)) != 0) return false; - if (old_stream->odm_2to1_policy_applied != stream->odm_2to1_policy_applied) - return false; - return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 5908b60db313..75dbc665f435 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -47,7 +47,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.198" +#define DC_VER "3.2.201" #define MAX_SURFACES 3 #define MAX_PLANES 6 @@ -118,7 +118,26 @@ struct dc_plane_cap { uint32_t min_height; }; -// Color management caps (DPP and MPC) +/** + * DOC: color-management-caps + * + * **Color management caps (DPP and MPC)** + * + * Modules/color calculates various color operations which are translated to + * abstracted HW. DCE 5-12 had almost no important changes, but starting with + * DCN1, every new generation comes with fairly major differences in color + * pipeline. Therefore, we abstract color pipe capabilities so modules/DM can + * decide mapping to HW block based on logical capabilities. + */ + +/** + * struct rom_curve_caps - predefined transfer function caps for degamma and regamma + * @srgb: RGB color space transfer func + * @bt2020: BT.2020 transfer func + * @gamma2_2: standard gamma + * @pq: perceptual quantizer transfer function + * @hlg: hybrid log–gamma transfer function + */ struct rom_curve_caps { uint16_t srgb : 1; uint16_t bt2020 : 1; @@ -127,36 +146,68 @@ struct rom_curve_caps { uint16_t hlg : 1; }; +/** + * struct dpp_color_caps - color pipeline capabilities for display pipe and + * plane blocks + * + * @dcn_arch: all DCE generations treated the same + * @input_lut_shared: shared with DGAM. Input LUT is different than most LUTs, + * just plain 256-entry lookup + * @icsc: input color space conversion + * @dgam_ram: programmable degamma LUT + * @post_csc: post color space conversion, before gamut remap + * @gamma_corr: degamma correction + * @hw_3d_lut: 3D LUT support. It implies a shaper LUT before. It may be shared + * with MPC by setting mpc:shared_3d_lut flag + * @ogam_ram: programmable out/blend gamma LUT + * @ocsc: output color space conversion + * @dgam_rom_for_yuv: pre-defined degamma LUT for YUV planes + * @dgam_rom_caps: pre-definied curve caps for degamma 1D LUT + * @ogam_rom_caps: pre-definied curve caps for regamma 1D LUT + * + * Note: hdr_mult and gamut remap (CTM) are always available in DPP (in that order) + */ struct dpp_color_caps { - uint16_t dcn_arch : 1; // all DCE generations treated the same - // input lut is different than most LUTs, just plain 256-entry lookup - uint16_t input_lut_shared : 1; // shared with DGAM + uint16_t dcn_arch : 1; + uint16_t input_lut_shared : 1; uint16_t icsc : 1; uint16_t dgam_ram : 1; - uint16_t post_csc : 1; // before gamut remap + uint16_t post_csc : 1; uint16_t gamma_corr : 1; - - // hdr_mult and gamut remap always available in DPP (in that order) - // 3d lut implies shaper LUT, - // it may be shared with MPC - check MPC:shared_3d_lut flag uint16_t hw_3d_lut : 1; - uint16_t ogam_ram : 1; // blnd gam + uint16_t ogam_ram : 1; uint16_t ocsc : 1; uint16_t dgam_rom_for_yuv : 1; struct rom_curve_caps dgam_rom_caps; struct rom_curve_caps ogam_rom_caps; }; +/** + * struct mpc_color_caps - color pipeline capabilities for multiple pipe and + * plane combined blocks + * + * @gamut_remap: color transformation matrix + * @ogam_ram: programmable out gamma LUT + * @ocsc: output color space conversion matrix + * @num_3dluts: MPC 3D LUT; always assumes a preceding shaper LUT + * @shared_3d_lut: shared 3D LUT flag. Can be either DPP or MPC, but single + * instance + * @ogam_rom_caps: pre-definied curve caps for regamma 1D LUT + */ struct mpc_color_caps { uint16_t gamut_remap : 1; uint16_t ogam_ram : 1; uint16_t ocsc : 1; - uint16_t num_3dluts : 3; //3d lut always assumes a preceding shaper LUT - uint16_t shared_3d_lut:1; //can be in either DPP or MPC, but single instance - + uint16_t num_3dluts : 3; + uint16_t shared_3d_lut:1; struct rom_curve_caps ogam_rom_caps; }; +/** + * struct dc_color_caps - color pipes capabilities for DPP and MPC hw blocks + * @dpp: color pipes caps for DPP + * @mpc: color pipes caps for MPC + */ struct dc_color_caps { struct dpp_color_caps dpp; struct mpc_color_caps mpc; @@ -350,6 +401,7 @@ struct dc_config { uint8_t vblank_alignment_max_frame_time_diff; bool is_asymmetric_memory; bool is_single_rank_dimm; + bool is_vmin_only_asic; bool use_pipe_ctx_sync_logic; bool ignore_dpref_ss; bool enable_mipi_converter_optimization; @@ -365,6 +417,7 @@ enum visual_confirm { VISUAL_CONFIRM_SWAPCHAIN = 6, VISUAL_CONFIRM_FAMS = 7, VISUAL_CONFIRM_SWIZZLE = 9, + VISUAL_CONFIRM_SUBVP = 14, }; enum dc_psr_power_opts { @@ -386,9 +439,31 @@ enum dcc_option { DCC_HALF_REQ_DISALBE = 2, }; +/** + * enum pipe_split_policy - Pipe split strategy supported by DCN + * + * This enum is used to define the pipe split policy supported by DCN. By + * default, DC favors MPC_SPLIT_DYNAMIC. + */ enum pipe_split_policy { + /** + * @MPC_SPLIT_DYNAMIC: DC will automatically decide how to split the + * pipe in order to bring the best trade-off between performance and + * power consumption. This is the recommended option. + */ MPC_SPLIT_DYNAMIC = 0, + + /** + * @MPC_SPLIT_DYNAMIC: Avoid pipe split, which means that DC will not + * try any sort of split optimization. + */ MPC_SPLIT_AVOID = 1, + + /** + * @MPC_SPLIT_DYNAMIC: With this option, DC will only try to optimize + * the pipe utilization when using a single display; if the user + * connects to a second display, DC will avoid pipe split. + */ MPC_SPLIT_AVOID_MULT_DISP = 2, }; @@ -623,6 +698,14 @@ struct dc_state; struct resource_pool; struct dce_hwseq; +/** + * struct dc_debug_options - DC debug struct + * + * This struct provides a simple mechanism for developers to change some + * configurations, enable/disable features, and activate extra debug options. + * This can be very handy to narrow down whether some specific feature is + * causing an issue or not. + */ struct dc_debug_options { bool native422_support; bool disable_dsc; @@ -642,6 +725,11 @@ struct dc_debug_options { bool disable_stutter; bool use_max_lb; enum dcc_option disable_dcc; + + /** + * @pipe_split_policy: Define which pipe split policy is used by the + * display core. + */ enum pipe_split_policy pipe_split_policy; bool force_single_disp_pipe_split; bool voltage_align_fclk; @@ -715,8 +803,6 @@ struct dc_debug_options { bool validate_dml_output; bool enable_dmcub_surface_flip; bool usbc_combo_phy_reset_wa; - bool disable_dsc_edp; - unsigned int force_dsc_edp_policy; bool enable_dram_clock_change_one_display_vactive; /* TODO - remove once tested */ bool legacy_dp2_lt; @@ -740,7 +826,6 @@ struct dc_debug_options { int crb_alloc_policy_min_disp_count; bool disable_z10; bool enable_z9_disable_interface; - bool enable_sw_cntl_psr; union dpia_debug_options dpia_debug; bool disable_fixed_vs_aux_timeout_wa; bool force_disable_subvp; @@ -759,6 +844,7 @@ struct dc_debug_options { bool exit_idle_opt_for_cursor_updates; bool enable_single_display_2to1_odm_policy; bool enable_dp_dig_pixel_rate_div_policy; + enum lttpr_mode lttpr_mode_override; }; struct gpu_info_soc_bounding_box_v1_0; @@ -814,6 +900,17 @@ struct dc { uint32_t *dcn_reg_offsets; uint32_t *nbio_reg_offsets; + + /* Scratch memory */ + struct { + struct { + /* + * For matching clock_limits table in driver with table + * from PMFW. + */ + struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES]; + } update_bw_bounding_box; + } scratch; }; enum frame_buffer_mode { @@ -1085,6 +1182,7 @@ struct dc_plane_state { /* private to dc_surface.c */ enum dc_irq_source irq_source; struct kref refcount; + struct tg_color visual_confirm_color; }; struct dc_plane_info { diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 09b304507bad..7b765efe0825 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -323,11 +323,13 @@ bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, stru struct dmub_cmd_fw_assisted_mclk_switch_config *config_data = &cmd.fw_assisted_mclk_switch.config_data; int i = 0; int ramp_up_num_steps = 1; // TODO: Ramp is currently disabled. Reenable it. - uint8_t visual_confirm_enabled = dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS; + uint8_t visual_confirm_enabled; if (dc == NULL) return false; + visual_confirm_enabled = dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS; + // Format command. cmd.fw_assisted_mclk_switch.header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH; cmd.fw_assisted_mclk_switch.header.sub_type = DMUB_CMD__FAMS_SETUP_FW_CTRL; @@ -387,6 +389,37 @@ void dc_dmub_srv_query_caps_cmd(struct dmub_srv *dmub) } } +void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pipe_ctx) +{ + union dmub_rb_cmd cmd = { 0 }; + enum dmub_status status; + unsigned int panel_inst = 0; + + dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, &panel_inst); + + memset(&cmd, 0, sizeof(cmd)); + + // Prepare fw command + cmd.visual_confirm_color.header.type = DMUB_CMD__GET_VISUAL_CONFIRM_COLOR; + cmd.visual_confirm_color.header.sub_type = 0; + cmd.visual_confirm_color.header.ret_status = 1; + cmd.visual_confirm_color.header.payload_bytes = sizeof(struct dmub_cmd_visual_confirm_color_data); + cmd.visual_confirm_color.visual_confirm_color_data.visual_confirm_color.panel_inst = panel_inst; + + // Send command to fw + status = dmub_srv_cmd_with_reply_data(dc->ctx->dmub_srv->dmub, &cmd); + + ASSERT(status == DMUB_STATUS_OK); + + // If command was processed, copy feature caps to dmub srv + if (status == DMUB_STATUS_OK && + cmd.visual_confirm_color.header.ret_status == 0) { + memcpy(&dc->ctx->dmub_srv->dmub->visual_confirm_color, + &cmd.visual_confirm_color.visual_confirm_color_data, + sizeof(struct dmub_visual_confirm_color)); + } +} + #ifdef CONFIG_DRM_AMD_DC_DCN /** * *********************************************************************************************** @@ -601,7 +634,7 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc, &cmd->fw_assisted_mclk_switch_v2.config_data.pipe_data[cmd_pipe_index]; struct dc_crtc_timing *main_timing = &subvp_pipe->stream->timing; struct dc_crtc_timing *phantom_timing = &subvp_pipe->stream->mall_stream_config.paired_stream->timing; - uint32_t out_num, out_den; + uint32_t out_num_stream, out_den_stream, out_num_plane, out_den_plane, out_num, out_den; pipe_data->mode = SUBVP; pipe_data->pipe_config.subvp_data.pix_clk_100hz = subvp_pipe->stream->timing.pix_clk_100hz; @@ -618,11 +651,16 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc, /* Calculate the scaling factor from the src and dst height. * e.g. If 3840x2160 being downscaled to 1920x1080, the scaling factor is 1/2. * Reduce the fraction 1080/2160 = 1/2 for the "scaling factor" + * + * Make sure to combine stream and plane scaling together. */ - reduce_fraction(subvp_pipe->stream->src.height, subvp_pipe->stream->dst.height, &out_num, &out_den); - // TODO: Uncomment below lines once DMCUB include headers are promoted - //pipe_data->pipe_config.subvp_data.scale_factor_numerator = out_num; - //pipe_data->pipe_config.subvp_data.scale_factor_denominator = out_den; + reduce_fraction(subvp_pipe->stream->src.height, subvp_pipe->stream->dst.height, + &out_num_stream, &out_den_stream); + reduce_fraction(subvp_pipe->plane_state->src_rect.height, subvp_pipe->plane_state->dst_rect.height, + &out_num_plane, &out_den_plane); + reduce_fraction(out_num_stream * out_num_plane, out_den_stream * out_den_plane, &out_num, &out_den); + pipe_data->pipe_config.subvp_data.scale_factor_numerator = out_num; + pipe_data->pipe_config.subvp_data.scale_factor_denominator = out_den; // Prefetch lines is equal to VACTIVE + BP + VSYNC pipe_data->pipe_config.subvp_data.prefetch_lines = diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h index 159782cd6659..9f5b47b9a83d 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h @@ -78,6 +78,7 @@ void dc_dmub_srv_set_drr_manual_trigger_cmd(struct dc *dc, uint32_t tg_inst); bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool enable_pstate, struct dc_state *context); void dc_dmub_srv_query_caps_cmd(struct dmub_srv *dmub); +void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pipe_ctx); void dc_dmub_srv_clear_inbox0_ack(struct dc_dmub_srv *dmub_srv); void dc_dmub_srv_wait_for_inbox0_ack(struct dc_dmub_srv *dmub_srv); void dc_dmub_srv_send_inbox0_cmd(struct dc_dmub_srv *dmub_srv, union dmub_inbox0_data_register data); diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h index 584aaf6967fd..848db8676adf 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -417,19 +417,43 @@ enum dc_scan_direction { SCAN_DIRECTION_VERTICAL = 2, /* 90, 270 rotation */ }; +/** + * struct dc_cursor_position: Hardware cursor data. + * + * This struct keeps the action information related to the cursor that will be + * sent and received from our DC core. + */ struct dc_cursor_position { + /** + * @x: It represents the top left abscissa coordinate of the cursor. + */ uint32_t x; + + /** + * @y: It is the top ordinate of the cursor coordinate. + */ uint32_t y; + /** + * @x_hotspot: Define the abscissa point where mouse click happens. + */ uint32_t x_hotspot; + + /** + * @y_hotspot: Define the ordinate point where mouse click happens. + */ uint32_t y_hotspot; - /* - * This parameter indicates whether HW cursor should be enabled + /** + * @enable: This parameter indicates whether hardware cursor should be + * enabled. */ bool enable; - /* Translate cursor x/y by the source rectangle for each plane. */ + /** + * @translate_by_source: Translate cursor x/y by the source rectangle + * for each plane. + */ bool translate_by_source; }; @@ -494,7 +518,9 @@ struct dc_gamma { /* Used by both ipp amd opp functions*/ /* TODO: to be consolidated with enum color_space */ -/* +/** + * enum dc_cursor_color_format - DC cursor programming mode + * * This enum is for programming CURSOR_MODE register field. What this register * should be programmed to depends on OS requested cursor shape flags and what * we stored in the cursor surface. @@ -530,17 +556,39 @@ union dc_cursor_attribute_flags { }; struct dc_cursor_attributes { + /** + * @address: This field represents the framebuffer address associated + * with the cursor. It is important to highlight that this address is + * divided into a high and low parts. + */ PHYSICAL_ADDRESS_LOC address; + + /** + * @pitch: Cursor line stride. + */ uint32_t pitch; - /* Width and height should correspond to cursor surface width x heigh */ + /** + * @width: Width should correspond to cursor surface width. + */ uint32_t width; + /** + * @heigh: Height should correspond to cursor surface heigh. + */ uint32_t height; + /** + * @color_format: DC cursor programming mode. + */ enum dc_cursor_color_format color_format; - uint32_t sdr_white_level; // for boosting (SDR) cursor in HDR mode + /** + * @sdr_white_level: Boosting (SDR) cursor in HDR mode. + */ + uint32_t sdr_white_level; - /* In case we support HW Cursor rotation in the future */ + /** + * @rotation_angle: In case we support HW Cursor rotation in the future + */ enum dc_rotation_angle rotation_angle; union dc_cursor_attribute_flags attribute_flags; @@ -764,22 +812,108 @@ struct dc_dsc_config { bool is_dp; /* indicate if DSC is applied based on DP's capability */ uint32_t mst_pbn; /* pbn of display on dsc mst hub */ }; + +/** + * struct dc_crtc_timing - Timing parameters used to configure DCN blocks + * + * DCN provides multiple signals and parameters that can be used to adjust + * timing parameters, this struct aggregate multiple of these values for easy + * access. In this struct, fields prefixed with h_* are related to horizontal + * timing, and v_* to vertical timing. Keep in mind that when we talk about + * vertical timings, the values, in general, are described in the number of + * lines; on the other hand, the horizontal values are in pixels. + */ struct dc_crtc_timing { + /** + * @h_total: The total number of pixels from the rising edge of HSync + * until the rising edge of the current HSync. + */ uint32_t h_total; + + /** + * @h_border_left: The black pixels related to the left border + */ uint32_t h_border_left; + + /** + * @h_addressable: It is the range of pixels displayed horizontally. + * For example, if the display resolution is 3840@2160, the horizontal + * addressable area is 3840. + */ uint32_t h_addressable; + + /** + * @h_border_right: The black pixels related to the right border + */ uint32_t h_border_right; + + /** + * @h_front_porch: Period (in pixels) between HBlank start and the + * rising edge of HSync. + */ uint32_t h_front_porch; + + /** + * @h_sync_width: HSync duration in pixels. + */ uint32_t h_sync_width; + /** + * @v_total: It is the total number of lines from the rising edge of + * the previous VSync until the rising edge of the current VSync. + * + * |--------------------------| + * +-+ V_TOTAL +-+ + * | | | | + * VSync ---+ +--------- // -----------+ +--- + */ uint32_t v_total; + + /** + * @v_border_top: The black border on the top. + */ uint32_t v_border_top; + + /** + * @v_addressable: It is the range of the scanout at which the + * framebuffer is displayed. For example, if the display resolution is + * 3840@2160, the addressable area is 2160 lines, or if the resolution + * is 1920x1080, the addressable area is 1080 lines. + */ uint32_t v_addressable; + + /** + * @v_border_bottom: The black border on the bottom. + */ uint32_t v_border_bottom; + + /** + * @v_front_porch: Period (in lines) between VBlank start and rising + * edge of VSync. + * +-+ + * VSync | | + * ----------+ +--------... + * +------------------... + * VBlank | + * --+ + * |-------| + * v_front_porch + */ uint32_t v_front_porch; + + /** + * @v_sync_width: VSync signal width in lines. + */ uint32_t v_sync_width; + /** + * @pix_clk_100hz: Pipe pixel precision + * + * This field is used to communicate pixel clocks with 100 Hz accuracy + * from dc_crtc_timing to BIOS command table. + */ uint32_t pix_clk_100hz; + uint32_t min_refresh_in_uhz; uint32_t vic; diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 9544abf75e84..3f64b3092692 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -113,6 +113,16 @@ struct psr_settings { unsigned int psr_power_opt; }; +/* To split out "global" and "per-panel" config settings. + * Add a struct dc_panel_config under dc_link + */ +struct dc_panel_config { + // edp DSC + struct dsc { + bool disable_dsc_edp; + unsigned int force_dsc_edp_policy; + } dsc; +}; /* * A link contains one or more sinks and their connected status. * The currently active signal type (HDMI, DP-SST, DP-MST) is also reported. @@ -224,6 +234,7 @@ struct dc_link { bool dpia_mst_dsc_always_on; /* Forced DPIA into TBT3 compatibility mode. */ bool dpia_forced_tbt3_mode; + bool dongle_mode_timing_override; } wa_flags; struct link_mst_stream_allocation_table mst_stream_alloc_table; @@ -232,6 +243,8 @@ struct dc_link { struct gpio *hpd_gpio; enum dc_link_fec_state fec_state; + struct dc_panel_config panel_config; + enum phy_state phy_state; }; const struct dc_link_status *dc_link_get_status(const struct dc_link *dc_link); diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index f87f852d4829..9fcf9dc5bce4 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -268,8 +268,6 @@ struct dc_stream_state { bool has_non_synchronizable_pclk; bool vblank_synchronized; struct mall_stream_config mall_stream_config; - - bool odm_2to1_policy_applied; }; #define ABM_LEVEL_IMMEDIATE_DISABLE 255 diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c index 919c2c2ba84b..32782ef9ef77 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c @@ -814,12 +814,6 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc, "dce_aux_transfer_with_retries: AUX_RET_SUCCESS: AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER"); retry_on_defer = true; - fallthrough; - case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK: - if (*payload->reply == AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK) - DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, - LOG_FLAG_I2cAux_DceAux, - "dce_aux_transfer_with_retries: AUX_RET_SUCCESS: AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK"); if (aux_defer_retries >= AUX_MIN_DEFER_RETRIES && defer_time_in_ms >= AUX_MAX_DEFER_TIMEOUT_MS) { @@ -848,7 +842,11 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc, } } break; - + case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK: + DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, + LOG_FLAG_I2cAux_DceAux, + "dce_aux_transfer_with_retries: FAILURE: AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK"); + goto fail; case AUX_TRANSACTION_REPLY_I2C_DEFER: DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, LOG_FLAG_I2cAux_DceAux, 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 38a67051d470..fe346e96c2d1 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 @@ -1577,8 +1577,25 @@ static enum dc_status apply_single_controller_ctx_to_hw( if (dc_is_dp_signal(pipe_ctx->stream->signal)) dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG); - if (!stream->dpms_off) - core_link_enable_stream(context, pipe_ctx); + /* Have to setup DSC before DIG FE and BE are connected (which happens before the + * link training). This is to make sure the bandwidth sent to DIG BE won't be + * bigger than what the link and/or DIG BE can handle. VBID[6]/CompressedStream_flag + * will be automatically set at a later time when the video is enabled + * (DP_VID_STREAM_EN = 1). + */ + if (pipe_ctx->stream->timing.flags.DSC) { + if (dc_is_dp_signal(pipe_ctx->stream->signal) || + dc_is_virtual_signal(pipe_ctx->stream->signal)) + dp_set_dsc_enable(pipe_ctx, true); + + } + + if (!stream->dpms_off) { + if (dc->hwss.update_phy_state) + dc->hwss.update_phy_state(context, pipe_ctx, TX_ON_SYMCLK_ON); + else + core_link_enable_stream(context, pipe_ctx); + } /* DCN3.1 FPGA Workaround * Need to enable HPO DP Stream Encoder before setting OTG master enable. 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 db7ca4b0cdb9..897f412f539e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c @@ -448,11 +448,12 @@ void dpp1_set_cursor_position( src_y_offset = pos->y - pos->x_hotspot - param->viewport.y; } } else if (param->rotation == ROTATION_ANGLE_180) { - src_x_offset = pos->x - param->viewport.x; + if (!param->mirror) + src_x_offset = pos->x - param->viewport.x; + src_y_offset = pos->y - param->viewport.y; } - if (src_x_offset >= (int)param->viewport.width) cur_en = 0; /* not visible beyond right edge*/ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c index 564e061ccb58..52e201e9b091 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c @@ -1208,13 +1208,10 @@ void hubp1_cursor_set_position( src_y_offset = pos->y - pos->x_hotspot - param->viewport.y; } } else if (param->rotation == ROTATION_ANGLE_180) { - src_x_offset = pos->x - param->viewport.x; - src_y_offset = pos->y - param->viewport.y; - } + if (!param->mirror) + src_x_offset = pos->x - param->viewport.x; - if (param->mirror) { - x_hotspot = param->viewport.width - x_hotspot; - src_x_offset = param->viewport.x + param->viewport.width - src_x_offset; + src_y_offset = pos->y - param->viewport.y; } dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; 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 5b5d952b2b8c..f26e08032da0 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 @@ -2151,8 +2151,8 @@ static int dcn10_align_pixel_clocks(struct dc *dc, int group_size, dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz( dc->res_pool->dp_clock_source, grouped_pipes[i]->stream_res.tg->inst, &pclk); - grouped_pipes[i]->stream->timing.pix_clk_100hz = - pclk*get_clock_divider(grouped_pipes[i], false); + grouped_pipes[i]->stream->timing.pix_clk_100hz = + pclk*get_clock_divider(grouped_pipes[i], false); if (master == -1) master = i; } @@ -2199,14 +2199,14 @@ void dcn10_enable_vblanks_synchronization( if (master >= 0) { for (i = 0; i < group_size; i++) { if (i != master && !grouped_pipes[i]->stream->has_non_synchronizable_pclk) - grouped_pipes[i]->stream_res.tg->funcs->align_vblanks( - grouped_pipes[master]->stream_res.tg, - grouped_pipes[i]->stream_res.tg, - grouped_pipes[master]->stream->timing.pix_clk_100hz, - grouped_pipes[i]->stream->timing.pix_clk_100hz, - get_clock_divider(grouped_pipes[master], false), - get_clock_divider(grouped_pipes[i], false)); - grouped_pipes[i]->stream->vblank_synchronized = true; + grouped_pipes[i]->stream_res.tg->funcs->align_vblanks( + grouped_pipes[master]->stream_res.tg, + grouped_pipes[i]->stream_res.tg, + grouped_pipes[master]->stream->timing.pix_clk_100hz, + grouped_pipes[i]->stream->timing.pix_clk_100hz, + get_clock_divider(grouped_pipes[master], false), + get_clock_divider(grouped_pipes[i], false)); + grouped_pipes[i]->stream->vblank_synchronized = true; } grouped_pipes[master]->stream->vblank_synchronized = true; DC_SYNC_INFO("Sync complete\n"); @@ -2539,8 +2539,10 @@ void dcn10_update_visual_confirm_color(struct dc *dc, struct pipe_ctx *pipe_ctx, color_space_to_black_color( dc, pipe_ctx->stream->output_color_space, color); - if (mpc->funcs->set_bg_color) + if (mpc->funcs->set_bg_color) { + memcpy(&pipe_ctx->plane_state->visual_confirm_color, color, sizeof(struct tg_color)); mpc->funcs->set_bg_color(mpc, color, mpcc_id); + } } void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) @@ -3340,11 +3342,11 @@ static bool dcn10_dmub_should_update_cursor_data( if (pipe_ctx->plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) return false; - if (pipe_ctx->stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) - return true; + if (dcn10_can_pipe_disable_cursor(pipe_ctx)) + return false; - if (pipe_ctx->stream->link->psr_settings.psr_version == DC_PSR_VERSION_1 && - debug->enable_sw_cntl_psr) + if ((pipe_ctx->stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1 || pipe_ctx->stream->link->psr_settings.psr_version == DC_PSR_VERSION_1) + && pipe_ctx->stream->ctx->dce_version >= DCN_VERSION_3_1) return true; return false; @@ -3468,8 +3470,7 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) .rotation = pipe_ctx->plane_state->rotation, .mirror = pipe_ctx->plane_state->horizontal_mirror }; - bool pipe_split_on = (pipe_ctx->top_pipe != NULL) || - (pipe_ctx->bottom_pipe != NULL); + bool pipe_split_on = false; bool odm_combine_on = (pipe_ctx->next_odm_pipe != NULL) || (pipe_ctx->prev_odm_pipe != NULL); @@ -3478,6 +3479,13 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) int x_pos = pos_cpy.x; int y_pos = pos_cpy.y; + if ((pipe_ctx->top_pipe != NULL) || (pipe_ctx->bottom_pipe != NULL)) { + if ((pipe_ctx->plane_state->src_rect.width != pipe_ctx->plane_res.scl_data.viewport.width) || + (pipe_ctx->plane_state->src_rect.height != pipe_ctx->plane_res.scl_data.viewport.height)) { + pipe_split_on = true; + } + } + /** * DC cursor is stream space, HW cursor is plane space and drawn * as part of the framebuffer. @@ -3549,8 +3557,36 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) if (pos_cpy.enable && dcn10_can_pipe_disable_cursor(pipe_ctx)) pos_cpy.enable = false; + + if (param.rotation == ROTATION_ANGLE_0) { + int viewport_width = + pipe_ctx->plane_res.scl_data.viewport.width; + int viewport_x = + pipe_ctx->plane_res.scl_data.viewport.x; + + if (param.mirror) { + if (pipe_split_on || odm_combine_on) { + if (pos_cpy.x >= viewport_width + viewport_x) { + pos_cpy.x = 2 * viewport_width + - pos_cpy.x + 2 * viewport_x; + } else { + uint32_t temp_x = pos_cpy.x; + + pos_cpy.x = 2 * viewport_x - pos_cpy.x; + if (temp_x >= viewport_x + + (int)hubp->curs_attr.width || pos_cpy.x + <= (int)hubp->curs_attr.width + + pipe_ctx->plane_state->src_rect.x) { + pos_cpy.x = temp_x + viewport_width; + } + } + } else { + pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x; + } + } + } // Swap axis and mirror horizontally - if (param.rotation == ROTATION_ANGLE_90) { + else if (param.rotation == ROTATION_ANGLE_90) { uint32_t temp_x = pos_cpy.x; pos_cpy.x = pipe_ctx->plane_res.scl_data.viewport.width - @@ -3621,23 +3657,25 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) int viewport_x = pipe_ctx->plane_res.scl_data.viewport.x; - if (pipe_split_on || odm_combine_on) { - if (pos_cpy.x >= viewport_width + viewport_x) { - pos_cpy.x = 2 * viewport_width - - pos_cpy.x + 2 * viewport_x; - } else { - uint32_t temp_x = pos_cpy.x; - - pos_cpy.x = 2 * viewport_x - pos_cpy.x; - if (temp_x >= viewport_x + - (int)hubp->curs_attr.width || pos_cpy.x - <= (int)hubp->curs_attr.width + - pipe_ctx->plane_state->src_rect.x) { - pos_cpy.x = temp_x + viewport_width; + if (!param.mirror) { + if (pipe_split_on || odm_combine_on) { + if (pos_cpy.x >= viewport_width + viewport_x) { + pos_cpy.x = 2 * viewport_width + - pos_cpy.x + 2 * viewport_x; + } else { + uint32_t temp_x = pos_cpy.x; + + pos_cpy.x = 2 * viewport_x - pos_cpy.x; + if (temp_x >= viewport_x + + (int)hubp->curs_attr.width || pos_cpy.x + <= (int)hubp->curs_attr.width + + pipe_ctx->plane_state->src_rect.x) { + pos_cpy.x = temp_x + viewport_width; + } } + } else { + pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x; } - } else { - pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x; } /** @@ -3738,7 +3776,6 @@ int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx) int vesa_sync_start; int asic_blank_end; int interlace_factor; - int vertical_line_start; patched_crtc_timing = *dc_crtc_timing; apply_front_porch_workaround(&patched_crtc_timing); @@ -3754,10 +3791,8 @@ int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx) patched_crtc_timing.v_border_top) * interlace_factor; - vertical_line_start = asic_blank_end - + return asic_blank_end - pipe_ctx->pipe_dlg_param.vstartup_start + 1; - - return vertical_line_start; } void dcn10_calc_vupdate_position( diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c index 3fc300cd1ce9..294827906c69 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c @@ -312,6 +312,20 @@ void optc1_program_timing( } } +/** + * optc1_set_vtg_params - Set Vertical Timing Generator (VTG) parameters + * + * @optc: timing_generator struct used to extract the optc parameters + * @dc_crtc_timing: Timing parameters configured + * @program_fp2: Boolean value indicating if FP2 will be programmed or not + * + * OTG is responsible for generating the global sync signals, including + * vertical timing information for each HUBP in the dcfclk domain. Each VTG is + * associated with one OTG that provides HUBP with vertical timing information + * (i.e., there is 1:1 correspondence between OTG and VTG). This function is + * responsible for setting the OTG parameters to the VTG during the pipe + * programming. + */ void optc1_set_vtg_params(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing, bool program_fp2) { @@ -1072,7 +1086,7 @@ static void optc1_set_test_pattern( src_color[index] >> (src_bpc - dst_bpc); /* CRTC_TEST_PATTERN_DATA has 16 bits, * lowest 6 are hardwired to ZERO - * color bits should be left aligned aligned to MSB + * color bits should be left aligned to MSB * XXXXXXXXXX000000 for 10 bit, * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6 */ @@ -1498,8 +1512,23 @@ bool optc1_configure_crc(struct timing_generator *optc, return true; } +/** + * optc1_get_crc - Capture CRC result per component + * + * @optc: timing_generator instance. + * @r_cr: 16-bit primary CRC signature for red data. + * @g_y: 16-bit primary CRC signature for green data. + * @b_cb: 16-bit primary CRC signature for blue data. + * + * This function reads the CRC signature from the OPTC registers. Notice that + * we have three registers to keep the CRC result per color component (RGB). + * + * Returns: + * If CRC is disabled, return false; otherwise, return true, and the CRC + * results in the parameters. + */ bool optc1_get_crc(struct timing_generator *optc, - uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb) + uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb) { uint32_t field = 0; struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -1510,12 +1539,14 @@ bool optc1_get_crc(struct timing_generator *optc, if (!field) return false; + /* OTG_CRC0_DATA_RG has the CRC16 results for the red and green component */ REG_GET_2(OTG_CRC0_DATA_RG, - CRC0_R_CR, r_cr, - CRC0_G_Y, g_y); + CRC0_R_CR, r_cr, + CRC0_G_Y, g_y); + /* OTG_CRC0_DATA_B has the CRC16 results for the blue component */ REG_GET(OTG_CRC0_DATA_B, - CRC0_B_CB, b_cb); + CRC0_B_CB, b_cb); return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 174eebbe8b4f..831080b9eb87 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1495,6 +1495,24 @@ static bool dcn10_resource_construct( /* Other architectures we build for build this with soft-float */ dcn10_resource_construct_fp(dc); + if (!dc->config.is_vmin_only_asic) + if (ASICREV_IS_RAVEN2(dc->ctx->asic_id.hw_internal_rev)) + switch (dc->ctx->asic_id.pci_revision_id) { + case PRID_DALI_DE: + case PRID_DALI_DF: + case PRID_DALI_E3: + case PRID_DALI_E4: + case PRID_POLLOCK_94: + case PRID_POLLOCK_95: + case PRID_POLLOCK_E9: + case PRID_POLLOCK_EA: + case PRID_POLLOCK_EB: + dc->config.is_vmin_only_asic = true; + break; + default: + break; + } + pool->base.pp_smu = dcn10_pp_smu_create(ctx); /* diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c index 9570c2118ccc..b1ec0e6f7f58 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c @@ -987,13 +987,10 @@ void hubp2_cursor_set_position( src_y_offset = pos->y - pos->x_hotspot - param->viewport.y; } } else if (param->rotation == ROTATION_ANGLE_180) { - src_x_offset = pos->x - param->viewport.x; - src_y_offset = pos->y - param->viewport.y; - } + if (!param->mirror) + src_x_offset = pos->x - param->viewport.x; - if (param->mirror) { - x_hotspot = param->viewport.width - x_hotspot; - src_x_offset = param->viewport.x + param->viewport.width - src_x_offset; + src_y_offset = pos->y - param->viewport.y; } dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 884fa060f375..6271caca4d9a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -2361,9 +2361,12 @@ static void dcn20_reset_back_end_for_pipe( * screen only, the dpms_off would be true but * VBIOS lit up eDP, so check link status too. */ - if (!pipe_ctx->stream->dpms_off || link->link_status.link_active) - core_link_disable_stream(pipe_ctx); - else if (pipe_ctx->stream_res.audio) + if (!pipe_ctx->stream->dpms_off || link->link_status.link_active) { + if (dc->hwss.update_phy_state) + dc->hwss.update_phy_state(dc->current_state, pipe_ctx, TX_OFF_SYMCLK_OFF); + else + core_link_disable_stream(pipe_ctx); + } else if (pipe_ctx->stream_res.audio) dc->hwss.disable_audio_stream(pipe_ctx); /* free acquired resources */ @@ -2462,9 +2465,13 @@ void dcn20_update_visual_confirm_color(struct dc *dc, struct pipe_ctx *pipe_ctx, get_mpctree_visual_confirm_color(pipe_ctx, color); else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SWIZZLE) get_surface_tile_visual_confirm_color(pipe_ctx, color); + else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SUBVP) + get_subvp_visual_confirm_color(dc, pipe_ctx, color); - if (mpc->funcs->set_bg_color) + if (mpc->funcs->set_bg_color) { + memcpy(&pipe_ctx->plane_state->visual_confirm_color, color, sizeof(struct tg_color)); mpc->funcs->set_bg_color(mpc, color, mpcc_id); + } } void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c index a788d160953b..ab70ebd8f223 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c @@ -104,6 +104,9 @@ static bool has_query_dp_alt(struct link_encoder *enc) { struct dc_dmub_srv *dc_dmub_srv = enc->ctx->dmub_srv; + if (enc->ctx->dce_version >= DCN_VERSION_3_15) + return true; + /* Supports development firmware and firmware >= 4.0.11 */ return dc_dmub_srv && !(dc_dmub_srv->dmub->fw_version >= DMUB_FW_VERSION(4, 0, 0) && diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c index 1ed1404e969d..8d83b611507a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c @@ -553,9 +553,12 @@ static void dcn31_reset_back_end_for_pipe( * screen only, the dpms_off would be true but * VBIOS lit up eDP, so check link status too. */ - if (!pipe_ctx->stream->dpms_off || link->link_status.link_active) - core_link_disable_stream(pipe_ctx); - else if (pipe_ctx->stream_res.audio) + if (!pipe_ctx->stream->dpms_off || link->link_status.link_active) { + if (dc->hwss.update_phy_state) + dc->hwss.update_phy_state(dc->current_state, pipe_ctx, TX_OFF_SYMCLK_OFF); + else + core_link_disable_stream(pipe_ctx); + } else if (pipe_ctx->stream_res.audio) dc->hwss.disable_audio_stream(pipe_ctx); /* free acquired resources */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c index aedff18aff56..8745132d6374 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c @@ -889,7 +889,6 @@ static const struct dc_debug_options debug_defaults_drv = { }, .disable_z10 = true, .optimize_edp_link_rate = true, - .enable_sw_cntl_psr = true, .enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/ .dml_hostvm_override = DML_HOSTVM_OVERRIDE_FALSE, }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c index b384f30395d3..e3351ddc566c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c @@ -317,6 +317,7 @@ static void enc314_stream_encoder_dp_unblank( /* switch DP encoder to CRTC data, but reset it the fifo first. It may happen * that it overflows during mode transition, and sometimes doesn't recover. */ + REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, 0x7); REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 1); udelay(10); diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c index 0c7980266b85..38aa28ec6b13 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c @@ -98,7 +98,8 @@ static void optc314_set_odm_combine(struct timing_generator *optc, int *opp_id, REG_UPDATE(OPTC_WIDTH_CONTROL, OPTC_SEGMENT_WIDTH, mpcc_hactive); - REG_SET(OTG_H_TIMING_CNTL, 0, OTG_H_TIMING_DIV_MODE, opp_cnt - 1); + REG_UPDATE(OTG_H_TIMING_CNTL, + OTG_H_TIMING_DIV_MODE, opp_cnt - 1); optc1->opp_count = opp_cnt; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c index 85f32206a766..49b7e256d4ea 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c @@ -454,6 +454,7 @@ static const struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs hpo_dp_stream_encoder_reg_list(0), hpo_dp_stream_encoder_reg_list(1), hpo_dp_stream_encoder_reg_list(2), + hpo_dp_stream_encoder_reg_list(3) }; static const struct dcn31_hpo_dp_stream_encoder_shift hpo_dp_se_shift = { @@ -911,7 +912,6 @@ static const struct dc_debug_options debug_defaults_drv = { } }, .optimize_edp_link_rate = true, - .enable_sw_cntl_psr = true, .seamless_boot_odm_combine = true }; @@ -1643,6 +1643,7 @@ static struct clock_source *dcn31_clock_source_create( } BREAK_TO_DEBUGGER(); + kfree(clk_src); return NULL; } @@ -1715,6 +1716,7 @@ static struct clock_source *dcn30_clock_source_create( } BREAK_TO_DEBUGGER(); + kfree(clk_src); return NULL; } @@ -1750,6 +1752,7 @@ static bool dcn314_resource_construct( dc->caps.post_blend_color_processing = true; dc->caps.force_dp_tps4_for_cp2520 = true; dc->caps.dp_hpo = true; + dc->caps.dp_hdmi21_pcon_support = true; dc->caps.edp_dsc_support = true; dc->caps.extended_aux_timeout_support = true; dc->caps.dmcub_support = true; @@ -1813,8 +1816,6 @@ static bool dcn314_resource_construct( if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) dc->debug = debug_defaults_drv; - else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) - dc->debug = debug_defaults_diags; else dc->debug = debug_defaults_diags; // Init the vm_helper diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c index 7463b12ae4a3..eebb42c9ddd6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c @@ -886,7 +886,6 @@ static const struct dc_debug_options debug_defaults_drv = { } }, .optimize_edp_link_rate = true, - .enable_sw_cntl_psr = true, .psr_power_use_phy_fsm = 0, }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c index d56a212e065c..f4b52a35ad84 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c @@ -886,7 +886,6 @@ static const struct dc_debug_options debug_defaults_drv = { } }, .optimize_edp_link_rate = true, - .enable_sw_cntl_psr = true, }; static const struct dc_debug_options debug_defaults_diags = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c index a31c64b50410..0d5e8a441512 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c @@ -225,19 +225,19 @@ void dccg32_set_dpstreamclk( case 0: REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK0_EN, - (src == REFCLK) ? 0 : 1, DPSTREAMCLK0_SRC_SEL, 0); + (src == REFCLK) ? 0 : 1, DPSTREAMCLK0_SRC_SEL, otg_inst); break; case 1: REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK1_EN, - (src == REFCLK) ? 0 : 1, DPSTREAMCLK1_SRC_SEL, 1); + (src == REFCLK) ? 0 : 1, DPSTREAMCLK1_SRC_SEL, otg_inst); break; case 2: REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK2_EN, - (src == REFCLK) ? 0 : 1, DPSTREAMCLK2_SRC_SEL, 2); + (src == REFCLK) ? 0 : 1, DPSTREAMCLK2_SRC_SEL, otg_inst); break; case 3: REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK3_EN, - (src == REFCLK) ? 0 : 1, DPSTREAMCLK3_SRC_SEL, 3); + (src == REFCLK) ? 0 : 1, DPSTREAMCLK3_SRC_SEL, otg_inst); break; default: BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c index 26648ce772da..38a48983f663 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c @@ -310,6 +310,11 @@ static void enc32_stream_encoder_dp_unblank( // TODO: Confirm if we need to wait for DIG_SYMCLK_FE_ON REG_WAIT(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, 1, 10, 5000); + /* read start level = 0 will bring underflow / overflow and DIG_FIFO_ERROR = 1 + * so set it to 1/2 full = 7 before reset as suggested by hardware team. + */ + REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, 0x7); + REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1); REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 10, 5000); diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index ebd3945c71f1..769171ab8ef6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -295,24 +295,38 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c } // Include cursor size for CAB allocation - if (stream->cursor_position.enable && plane->address.grph.cursor_cache_addr.quad_part) { - cursor_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size; - switch (stream->cursor_attributes.color_format) { - case CURSOR_MODE_MONO: - cursor_size /= 2; - break; - case CURSOR_MODE_COLOR_1BIT_AND: - case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA: - case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA: - cursor_size *= 4; - break; + for (j = 0; j < dc->res_pool->pipe_count; j++) { + struct pipe_ctx *pipe = &ctx->res_ctx.pipe_ctx[j]; + struct hubp *hubp = pipe->plane_res.hubp; - case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED: - case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED: - cursor_size *= 8; - break; - } - cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size, + if (pipe->stream && pipe->plane_state && hubp) + /* Find the cursor plane and use the exact size instead of + * using the max for calculation + */ + if (hubp->curs_attr.width > 0) { + cursor_size = hubp->curs_attr.width * hubp->curs_attr.height; + break; + } + } + + switch (stream->cursor_attributes.color_format) { + case CURSOR_MODE_MONO: + cursor_size /= 2; + break; + case CURSOR_MODE_COLOR_1BIT_AND: + case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA: + case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA: + cursor_size *= 4; + break; + + case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED: + case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED: + cursor_size *= 8; + break; + } + + if (stream->cursor_position.enable && plane->address.grph.cursor_cache_addr.quad_part) { + cache_lines_used += dcn32_cache_lines_for_surface(dc, cursor_size, plane->address.grph.cursor_cache_addr.quad_part); } } @@ -325,6 +339,26 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c if (cache_lines_used % lines_per_way > 0) num_ways++; + for (i = 0; i < ctx->stream_count; i++) { + stream = ctx->streams[i]; + for (j = 0; j < ctx->stream_status[i].plane_count; j++) { + plane = ctx->stream_status[i].plane_states[j]; + + if (stream->cursor_position.enable && plane && + !plane->address.grph.cursor_cache_addr.quad_part && + cursor_size > 16384) { + /* Cursor caching is not supported since it won't be on the same line. + * So we need an extra line to accommodate it. With large cursors and a single 4k monitor + * this case triggers corruption. If we're at the edge, then dont trigger display refresh + * from MALL. We only need to cache cursor if its greater that 64x64 at 4 bpp. + */ + num_ways++; + /* We only expect one cursor plane */ + break; + } + } + } + return num_ways; } @@ -641,9 +675,9 @@ bool dcn32_set_output_transfer_func(struct dc *dc, stream->out_transfer_func, &mpc->blender_params, false)) params = &mpc->blender_params; - /* there are no ROM LUTs in OUTGAM */ - if (stream->out_transfer_func->type == TF_TYPE_PREDEFINED) - BREAK_TO_DEBUGGER(); + /* there are no ROM LUTs in OUTGAM */ + if (stream->out_transfer_func->type == TF_TYPE_PREDEFINED) + BREAK_TO_DEBUGGER(); } } @@ -1218,3 +1252,30 @@ bool dcn32_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx) return true; return false; } + +void dcn32_update_phy_state(struct dc_state *state, struct pipe_ctx *pipe_ctx, + enum phy_state target_state) +{ + enum phy_state current_state = pipe_ctx->stream->link->phy_state; + + if (target_state == TX_OFF_SYMCLK_OFF) { + core_link_disable_stream(pipe_ctx); + pipe_ctx->stream->link->phy_state = TX_OFF_SYMCLK_OFF; + } else if (target_state == TX_ON_SYMCLK_ON) { + core_link_enable_stream(state, pipe_ctx); + pipe_ctx->stream->link->phy_state = TX_ON_SYMCLK_ON; + } else if (target_state == TX_OFF_SYMCLK_ON) { + if (current_state == TX_ON_SYMCLK_ON) { + core_link_disable_stream(pipe_ctx); + pipe_ctx->stream->link->phy_state = TX_OFF_SYMCLK_OFF; + } + + pipe_ctx->clock_source->funcs->program_pix_clk( + pipe_ctx->clock_source, + &pipe_ctx->stream_res.pix_clk_params, + dp_get_link_encoding_format(&pipe_ctx->link_config.dp_link_settings), + &pipe_ctx->pll_settings); + pipe_ctx->stream->link->phy_state = TX_OFF_SYMCLK_ON; + } else + BREAK_TO_DEBUGGER(); +} diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h index 083f3aeb54f0..221e31144d50 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h @@ -84,4 +84,7 @@ void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx, bool dcn32_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx); +void dcn32_update_phy_state(struct dc_state *state, struct pipe_ctx *pipe_ctx, + enum phy_state target_state); + #endif /* __DC_HWSS_DCN32_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c index c279a25ea293..28d220218133 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c @@ -104,6 +104,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = { .commit_subvp_config = dcn32_commit_subvp_config, .subvp_pipe_control_lock = dcn32_subvp_pipe_control_lock, .update_visual_confirm_color = dcn20_update_visual_confirm_color, + .update_phy_state = dcn32_update_phy_state, }; static const struct hwseq_private_funcs dcn32_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index 8b887b552f2c..ef0a6d468a10 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -131,79 +131,96 @@ enum dcn32_clk_src_array_id { /* DCN */ /* TODO awful hack. fixup dcn20_dwb.h */ #undef BASE_INNER -#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg +#define BASE_INNER(seg) ctx->dcn_reg_offsets[seg] #define BASE(seg) BASE_INNER(seg) #define SR(reg_name)\ - .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ + REG_STRUCT.reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ reg ## reg_name +#define SR_ARR(reg_name, id) \ + REG_STRUCT[id].reg_name = BASE(reg##reg_name##_BASE_IDX) + reg##reg_name + +#define SR_ARR_INIT(reg_name, id, value) \ + REG_STRUCT[id].reg_name = value #define SRI(reg_name, block, id)\ - .reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ - reg ## block ## id ## _ ## reg_name + REG_STRUCT.reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRI_ARR(reg_name, block, id)\ + REG_STRUCT[id].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRI_ARR_ALPHABET(reg_name, block, index, id)\ + REG_STRUCT[index].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name #define SRI2(reg_name, block, id)\ - .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ - reg ## reg_name + .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ + reg ## reg_name +#define SRI2_ARR(reg_name, block, id)\ + REG_STRUCT[id].reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ + reg ## reg_name #define SRIR(var_name, reg_name, block, id)\ .var_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ - reg ## block ## id ## _ ## reg_name + reg ## block ## id ## _ ## reg_name #define SRII(reg_name, block, id)\ - .reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + REG_STRUCT.reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ reg ## block ## id ## _ ## reg_name +#define SRII_ARR_2(reg_name, block, id, inst)\ + REG_STRUCT[inst].reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + #define SRII_MPC_RMU(reg_name, block, id)\ .RMU##_##reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ - reg ## block ## id ## _ ## reg_name + reg ## block ## id ## _ ## reg_name #define SRII_DWB(reg_name, temp_name, block, id)\ - .reg_name[id] = BASE(reg ## block ## id ## _ ## temp_name ## _BASE_IDX) + \ - reg ## block ## id ## _ ## temp_name + REG_STRUCT.reg_name[id] = BASE(reg ## block ## id ## _ ## temp_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## temp_name #define DCCG_SRII(reg_name, block, id)\ - .block ## _ ## reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ - reg ## block ## id ## _ ## reg_name + REG_STRUCT.block ## _ ## reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name #define VUPDATE_SRII(reg_name, block, id)\ - .reg_name[id] = BASE(reg ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ - reg ## reg_name ## _ ## block ## id + REG_STRUCT.reg_name[id] = BASE(reg ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ + reg ## reg_name ## _ ## block ## id /* NBIO */ -#define NBIO_BASE_INNER(seg) \ - NBIO_BASE__INST0_SEG ## seg +#define NBIO_BASE_INNER(seg) ctx->nbio_reg_offsets[seg] #define NBIO_BASE(seg) \ NBIO_BASE_INNER(seg) #define NBIO_SR(reg_name)\ - .reg_name = NBIO_BASE(regBIF_BX0_ ## reg_name ## _BASE_IDX) + \ - regBIF_BX0_ ## reg_name + REG_STRUCT.reg_name = NBIO_BASE(regBIF_BX0_ ## reg_name ## _BASE_IDX) + \ + regBIF_BX0_ ## reg_name +#define NBIO_SR_ARR(reg_name, id)\ + REG_STRUCT[id].reg_name = NBIO_BASE(regBIF_BX0_ ## reg_name ## _BASE_IDX) + \ + regBIF_BX0_ ## reg_name #undef CTX #define CTX ctx #define REG(reg_name) \ - (DCN_BASE.instance[0].segment[reg ## reg_name ## _BASE_IDX] + reg ## reg_name) + (ctx->dcn_reg_offsets[reg ## reg_name ## _BASE_IDX] + reg ## reg_name) -static const struct bios_registers bios_regs = { - NBIO_SR(BIOS_SCRATCH_3), - NBIO_SR(BIOS_SCRATCH_6) -}; +static struct bios_registers bios_regs; -#define clk_src_regs(index, pllid)\ -[index] = {\ - CS_COMMON_REG_LIST_DCN3_0(index, pllid),\ -} +#define bios_regs_init() \ + ( \ + NBIO_SR(BIOS_SCRATCH_3),\ + NBIO_SR(BIOS_SCRATCH_6)\ + ) -static const struct dce110_clk_src_regs clk_src_regs[] = { - clk_src_regs(0, A), - clk_src_regs(1, B), - clk_src_regs(2, C), - clk_src_regs(3, D), - clk_src_regs(4, E) -}; +#define clk_src_regs_init(index, pllid)\ + CS_COMMON_REG_LIST_DCN3_0_RI(index, pllid) + +static struct dce110_clk_src_regs clk_src_regs[5]; static const struct dce110_clk_src_shift cs_shift = { CS_COMMON_MASK_SH_LIST_DCN3_2(__SHIFT) @@ -213,17 +230,10 @@ static const struct dce110_clk_src_mask cs_mask = { CS_COMMON_MASK_SH_LIST_DCN3_2(_MASK) }; -#define abm_regs(id)\ -[id] = {\ - ABM_DCN32_REG_LIST(id)\ -} +#define abm_regs_init(id)\ + ABM_DCN32_REG_LIST_RI(id) -static const struct dce_abm_registers abm_regs[] = { - abm_regs(0), - abm_regs(1), - abm_regs(2), - abm_regs(3), -}; +static struct dce_abm_registers abm_regs[4]; static const struct dce_abm_shift abm_shift = { ABM_MASK_SH_LIST_DCN32(__SHIFT) @@ -233,18 +243,10 @@ static const struct dce_abm_mask abm_mask = { ABM_MASK_SH_LIST_DCN32(_MASK) }; -#define audio_regs(id)\ -[id] = {\ - AUD_COMMON_REG_LIST(id)\ -} +#define audio_regs_init(id)\ + AUD_COMMON_REG_LIST_RI(id) -static const struct dce_audio_registers audio_regs[] = { - audio_regs(0), - audio_regs(1), - audio_regs(2), - audio_regs(3), - audio_regs(4) -}; +static struct dce_audio_registers audio_regs[5]; #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\ @@ -259,23 +261,10 @@ static const struct dce_audio_mask audio_mask = { DCE120_AUD_COMMON_MASK_SH_LIST(_MASK) }; -#define vpg_regs(id)\ -[id] = {\ - VPG_DCN3_REG_LIST(id)\ -} +#define vpg_regs_init(id)\ + VPG_DCN3_REG_LIST_RI(id) -static const struct dcn30_vpg_registers vpg_regs[] = { - vpg_regs(0), - vpg_regs(1), - vpg_regs(2), - vpg_regs(3), - vpg_regs(4), - vpg_regs(5), - vpg_regs(6), - vpg_regs(7), - vpg_regs(8), - vpg_regs(9), -}; +static struct dcn30_vpg_registers vpg_regs[10]; static const struct dcn30_vpg_shift vpg_shift = { DCN3_VPG_MASK_SH_LIST(__SHIFT) @@ -285,19 +274,10 @@ static const struct dcn30_vpg_mask vpg_mask = { DCN3_VPG_MASK_SH_LIST(_MASK) }; -#define afmt_regs(id)\ -[id] = {\ - AFMT_DCN3_REG_LIST(id)\ -} +#define afmt_regs_init(id)\ + AFMT_DCN3_REG_LIST_RI(id) -static const struct dcn30_afmt_registers afmt_regs[] = { - afmt_regs(0), - afmt_regs(1), - afmt_regs(2), - afmt_regs(3), - afmt_regs(4), - afmt_regs(5) -}; +static struct dcn30_afmt_registers afmt_regs[6]; static const struct dcn30_afmt_shift afmt_shift = { DCN3_AFMT_MASK_SH_LIST(__SHIFT) @@ -307,17 +287,10 @@ static const struct dcn30_afmt_mask afmt_mask = { DCN3_AFMT_MASK_SH_LIST(_MASK) }; -#define apg_regs(id)\ -[id] = {\ - APG_DCN31_REG_LIST(id)\ -} +#define apg_regs_init(id)\ + APG_DCN31_REG_LIST_RI(id) -static const struct dcn31_apg_registers apg_regs[] = { - apg_regs(0), - apg_regs(1), - apg_regs(2), - apg_regs(3) -}; +static struct dcn31_apg_registers apg_regs[4]; static const struct dcn31_apg_shift apg_shift = { DCN31_APG_MASK_SH_LIST(__SHIFT) @@ -327,18 +300,10 @@ static const struct dcn31_apg_mask apg_mask = { DCN31_APG_MASK_SH_LIST(_MASK) }; -#define stream_enc_regs(id)\ -[id] = {\ - SE_DCN32_REG_LIST(id)\ -} +#define stream_enc_regs_init(id)\ + SE_DCN32_REG_LIST_RI(id) -static const struct dcn10_stream_enc_registers stream_enc_regs[] = { - stream_enc_regs(0), - stream_enc_regs(1), - stream_enc_regs(2), - stream_enc_regs(3), - stream_enc_regs(4) -}; +static struct dcn10_stream_enc_registers stream_enc_regs[5]; static const struct dcn10_stream_encoder_shift se_shift = { SE_COMMON_MASK_SH_LIST_DCN32(__SHIFT) @@ -349,46 +314,24 @@ static const struct dcn10_stream_encoder_mask se_mask = { }; -#define aux_regs(id)\ -[id] = {\ - DCN2_AUX_REG_LIST(id)\ -} +#define aux_regs_init(id)\ + DCN2_AUX_REG_LIST_RI(id) -static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = { - aux_regs(0), - aux_regs(1), - aux_regs(2), - aux_regs(3), - aux_regs(4) -}; +static struct dcn10_link_enc_aux_registers link_enc_aux_regs[5]; -#define hpd_regs(id)\ -[id] = {\ - HPD_REG_LIST(id)\ -} +#define hpd_regs_init(id)\ + HPD_REG_LIST_RI(id) -static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = { - hpd_regs(0), - hpd_regs(1), - hpd_regs(2), - hpd_regs(3), - hpd_regs(4) -}; +static struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[5]; -#define link_regs(id, phyid)\ -[id] = {\ - LE_DCN31_REG_LIST(id), \ - UNIPHY_DCN2_REG_LIST(phyid), \ +#define link_regs_init(id, phyid)\ + ( \ + LE_DCN31_REG_LIST_RI(id), \ + UNIPHY_DCN2_REG_LIST_RI(id, phyid)\ + ) /*DPCS_DCN31_REG_LIST(id),*/ \ -} -static const struct dcn10_link_enc_registers link_enc_regs[] = { - link_regs(0, A), - link_regs(1, B), - link_regs(2, C), - link_regs(3, D), - link_regs(4, E) -}; +static struct dcn10_link_enc_registers link_enc_regs[5]; static const struct dcn10_link_enc_shift le_shift = { LINK_ENCODER_MASK_SH_LIST_DCN31(__SHIFT), \ @@ -401,17 +344,10 @@ static const struct dcn10_link_enc_mask le_mask = { //DPCS_DCN31_MASK_SH_LIST(_MASK) }; -#define hpo_dp_stream_encoder_reg_list(id)\ -[id] = {\ - DCN3_1_HPO_DP_STREAM_ENC_REG_LIST(id)\ -} +#define hpo_dp_stream_encoder_reg_init(id)\ + DCN3_1_HPO_DP_STREAM_ENC_REG_LIST_RI(id) -static const struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[] = { - hpo_dp_stream_encoder_reg_list(0), - hpo_dp_stream_encoder_reg_list(1), - hpo_dp_stream_encoder_reg_list(2), - hpo_dp_stream_encoder_reg_list(3), -}; +static struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[4]; static const struct dcn31_hpo_dp_stream_encoder_shift hpo_dp_se_shift = { DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(__SHIFT) @@ -422,20 +358,14 @@ static const struct dcn31_hpo_dp_stream_encoder_mask hpo_dp_se_mask = { }; -#define hpo_dp_link_encoder_reg_list(id)\ -[id] = {\ - DCN3_1_HPO_DP_LINK_ENC_REG_LIST(id),\ - /*DCN3_1_RDPCSTX_REG_LIST(0),*/\ - /*DCN3_1_RDPCSTX_REG_LIST(1),*/\ - /*DCN3_1_RDPCSTX_REG_LIST(2),*/\ - /*DCN3_1_RDPCSTX_REG_LIST(3),*/\ - /*DCN3_1_RDPCSTX_REG_LIST(4)*/\ -} +#define hpo_dp_link_encoder_reg_init(id)\ + DCN3_1_HPO_DP_LINK_ENC_REG_LIST_RI(id) + /*DCN3_1_RDPCSTX_REG_LIST(0),*/ + /*DCN3_1_RDPCSTX_REG_LIST(1),*/ + /*DCN3_1_RDPCSTX_REG_LIST(2),*/ + /*DCN3_1_RDPCSTX_REG_LIST(3),*/ -static const struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[] = { - hpo_dp_link_encoder_reg_list(0), - hpo_dp_link_encoder_reg_list(1), -}; +static struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[2]; static const struct dcn31_hpo_dp_link_encoder_shift hpo_dp_le_shift = { DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(__SHIFT) @@ -445,17 +375,10 @@ static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = { DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(_MASK) }; -#define dpp_regs(id)\ -[id] = {\ - DPP_REG_LIST_DCN30_COMMON(id),\ -} +#define dpp_regs_init(id)\ + DPP_REG_LIST_DCN30_COMMON_RI(id) -static const struct dcn3_dpp_registers dpp_regs[] = { - dpp_regs(0), - dpp_regs(1), - dpp_regs(2), - dpp_regs(3) -}; +static struct dcn3_dpp_registers dpp_regs[4]; static const struct dcn3_dpp_shift tf_shift = { DPP_REG_LIST_SH_MASK_DCN30_COMMON(__SHIFT) @@ -466,17 +389,10 @@ static const struct dcn3_dpp_mask tf_mask = { }; -#define opp_regs(id)\ -[id] = {\ - OPP_REG_LIST_DCN30(id),\ -} +#define opp_regs_init(id)\ + OPP_REG_LIST_DCN30_RI(id) -static const struct dcn20_opp_registers opp_regs[] = { - opp_regs(0), - opp_regs(1), - opp_regs(2), - opp_regs(3) -}; +static struct dcn20_opp_registers opp_regs[4]; static const struct dcn20_opp_shift opp_shift = { OPP_MASK_SH_LIST_DCN20(__SHIFT) @@ -486,21 +402,16 @@ static const struct dcn20_opp_mask opp_mask = { OPP_MASK_SH_LIST_DCN20(_MASK) }; -#define aux_engine_regs(id)\ -[id] = {\ - AUX_COMMON_REG_LIST0(id), \ - .AUXN_IMPCAL = 0, \ - .AUXP_IMPCAL = 0, \ - .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \ -} +#define aux_engine_regs_init(id)\ + ( \ + AUX_COMMON_REG_LIST0_RI(id), \ + SR_ARR_INIT(AUXN_IMPCAL, id, 0), \ + SR_ARR_INIT(AUXP_IMPCAL, id, 0), \ + SR_ARR_INIT(AUX_RESET_MASK, id, DP_AUX0_AUX_CONTROL__AUX_RESET_MASK), \ + SR_ARR_INIT(AUX_RESET_MASK, id, DP_AUX0_AUX_CONTROL__AUX_RESET_MASK)\ + ) -static const struct dce110_aux_registers aux_engine_regs[] = { - aux_engine_regs(0), - aux_engine_regs(1), - aux_engine_regs(2), - aux_engine_regs(3), - aux_engine_regs(4) -}; +static struct dce110_aux_registers aux_engine_regs[5]; static const struct dce110_aux_registers_shift aux_shift = { DCN_AUX_MASK_SH_LIST(__SHIFT) @@ -510,15 +421,10 @@ static const struct dce110_aux_registers_mask aux_mask = { DCN_AUX_MASK_SH_LIST(_MASK) }; +#define dwbc_regs_dcn3_init(id)\ + DWBC_COMMON_REG_LIST_DCN30_RI(id) -#define dwbc_regs_dcn3(id)\ -[id] = {\ - DWBC_COMMON_REG_LIST_DCN30(id),\ -} - -static const struct dcn30_dwbc_registers dwbc30_regs[] = { - dwbc_regs_dcn3(0), -}; +static struct dcn30_dwbc_registers dwbc30_regs[1]; static const struct dcn30_dwbc_shift dwbc30_shift = { DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT) @@ -528,14 +434,10 @@ static const struct dcn30_dwbc_mask dwbc30_mask = { DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK) }; -#define mcif_wb_regs_dcn3(id)\ -[id] = {\ - MCIF_WB_COMMON_REG_LIST_DCN32(id),\ -} +#define mcif_wb_regs_dcn3_init(id)\ + MCIF_WB_COMMON_REG_LIST_DCN32_RI(id) -static const struct dcn30_mmhubbub_registers mcif_wb30_regs[] = { - mcif_wb_regs_dcn3(0) -}; +static struct dcn30_mmhubbub_registers mcif_wb30_regs[1]; static const struct dcn30_mmhubbub_shift mcif_wb30_shift = { MCIF_WB_COMMON_MASK_SH_LIST_DCN32(__SHIFT) @@ -545,17 +447,10 @@ static const struct dcn30_mmhubbub_mask mcif_wb30_mask = { MCIF_WB_COMMON_MASK_SH_LIST_DCN32(_MASK) }; -#define dsc_regsDCN20(id)\ -[id] = {\ - DSC_REG_LIST_DCN20(id)\ -} +#define dsc_regsDCN20_init(id)\ + DSC_REG_LIST_DCN20_RI(id) -static const struct dcn20_dsc_registers dsc_regs[] = { - dsc_regsDCN20(0), - dsc_regsDCN20(1), - dsc_regsDCN20(2), - dsc_regsDCN20(3) -}; +static struct dcn20_dsc_registers dsc_regs[4]; static const struct dcn20_dsc_shift dsc_shift = { DSC_REG_LIST_SH_MASK_DCN20(__SHIFT) @@ -565,17 +460,23 @@ static const struct dcn20_dsc_mask dsc_mask = { DSC_REG_LIST_SH_MASK_DCN20(_MASK) }; -static const struct dcn30_mpc_registers mpc_regs = { - MPC_REG_LIST_DCN3_2(0), - MPC_REG_LIST_DCN3_2(1), - MPC_REG_LIST_DCN3_2(2), - MPC_REG_LIST_DCN3_2(3), - MPC_OUT_MUX_REG_LIST_DCN3_0(0), - MPC_OUT_MUX_REG_LIST_DCN3_0(1), - MPC_OUT_MUX_REG_LIST_DCN3_0(2), - MPC_OUT_MUX_REG_LIST_DCN3_0(3), - MPC_DWB_MUX_REG_LIST_DCN3_0(0), -}; +static struct dcn30_mpc_registers mpc_regs; +#define dcn_mpc_regs_init()\ + ( \ + MPC_REG_LIST_DCN3_0_RI(0),\ + MPC_REG_LIST_DCN3_0_RI(1),\ + MPC_REG_LIST_DCN3_0_RI(2),\ + MPC_REG_LIST_DCN3_0_RI(3),\ + MPC_OUT_MUX_REG_LIST_DCN3_0_RI(0),\ + MPC_OUT_MUX_REG_LIST_DCN3_0_RI(1),\ + MPC_OUT_MUX_REG_LIST_DCN3_0_RI(2),\ + MPC_OUT_MUX_REG_LIST_DCN3_0_RI(3),\ + MPC_MCM_REG_LIST_DCN32_RI(0),\ + MPC_MCM_REG_LIST_DCN32_RI(1),\ + MPC_MCM_REG_LIST_DCN32_RI(2),\ + MPC_MCM_REG_LIST_DCN32_RI(3),\ + MPC_DWB_MUX_REG_LIST_DCN3_0_RI(0)\ + ) static const struct dcn30_mpc_shift mpc_shift = { MPC_COMMON_MASK_SH_LIST_DCN32(__SHIFT) @@ -585,19 +486,10 @@ static const struct dcn30_mpc_mask mpc_mask = { MPC_COMMON_MASK_SH_LIST_DCN32(_MASK) }; -#define optc_regs(id)\ -[id] = {OPTC_COMMON_REG_LIST_DCN3_2(id)} - -//#ifdef DIAGS_BUILD -//static struct dcn_optc_registers optc_regs[] = { -//#else -static const struct dcn_optc_registers optc_regs[] = { -//#endif - optc_regs(0), - optc_regs(1), - optc_regs(2), - optc_regs(3) -}; +#define optc_regs_init(id)\ + OPTC_COMMON_REG_LIST_DCN3_2_RI(id) + +static struct dcn_optc_registers optc_regs[4]; static const struct dcn_optc_shift optc_shift = { OPTC_COMMON_MASK_SH_LIST_DCN3_2(__SHIFT) @@ -607,17 +499,10 @@ static const struct dcn_optc_mask optc_mask = { OPTC_COMMON_MASK_SH_LIST_DCN3_2(_MASK) }; -#define hubp_regs(id)\ -[id] = {\ - HUBP_REG_LIST_DCN32(id)\ -} +#define hubp_regs_init(id)\ + HUBP_REG_LIST_DCN32_RI(id) -static const struct dcn_hubp2_registers hubp_regs[] = { - hubp_regs(0), - hubp_regs(1), - hubp_regs(2), - hubp_regs(3) -}; +static struct dcn_hubp2_registers hubp_regs[4]; static const struct dcn_hubp2_shift hubp_shift = { @@ -627,9 +512,10 @@ static const struct dcn_hubp2_shift hubp_shift = { static const struct dcn_hubp2_mask hubp_mask = { HUBP_MASK_SH_LIST_DCN32(_MASK) }; -static const struct dcn_hubbub_registers hubbub_reg = { - HUBBUB_REG_LIST_DCN32(0) -}; + +static struct dcn_hubbub_registers hubbub_reg; +#define hubbub_reg_init()\ + HUBBUB_REG_LIST_DCN32_RI(0) static const struct dcn_hubbub_shift hubbub_shift = { HUBBUB_MASK_SH_LIST_DCN32(__SHIFT) @@ -639,9 +525,10 @@ static const struct dcn_hubbub_mask hubbub_mask = { HUBBUB_MASK_SH_LIST_DCN32(_MASK) }; -static const struct dccg_registers dccg_regs = { - DCCG_REG_LIST_DCN32() -}; +static struct dccg_registers dccg_regs; + +#define dccg_regs_init()\ + DCCG_REG_LIST_DCN32_RI() static const struct dccg_shift dccg_shift = { DCCG_MASK_SH_LIST_DCN32(__SHIFT) @@ -714,9 +601,10 @@ static const struct dccg_mask dccg_mask = { SR(AZALIA_AUDIO_DTO), \ SR(AZALIA_CONTROLLER_CLOCK_GATING) -static const struct dce_hwseq_registers hwseq_reg = { - HWSEQ_DCN32_REG_LIST() -}; +static struct dce_hwseq_registers hwseq_reg; + +#define hwseq_reg_init()\ + HWSEQ_DCN32_REG_LIST() #define HWSEQ_DCN32_MASK_SH_LIST(mask_sh)\ HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ @@ -759,29 +647,10 @@ static const struct dce_hwseq_shift hwseq_shift = { static const struct dce_hwseq_mask hwseq_mask = { HWSEQ_DCN32_MASK_SH_LIST(_MASK) }; -#define vmid_regs(id)\ -[id] = {\ - DCN20_VMID_REG_LIST(id)\ -} +#define vmid_regs_init(id)\ + DCN20_VMID_REG_LIST_RI(id) -static const struct dcn_vmid_registers vmid_regs[] = { - vmid_regs(0), - vmid_regs(1), - vmid_regs(2), - vmid_regs(3), - vmid_regs(4), - vmid_regs(5), - vmid_regs(6), - vmid_regs(7), - vmid_regs(8), - vmid_regs(9), - vmid_regs(10), - vmid_regs(11), - vmid_regs(12), - vmid_regs(13), - vmid_regs(14), - vmid_regs(15) -}; +static struct dcn_vmid_registers vmid_regs[16]; static const struct dcn20_vmid_shift vmid_shifts = { DCN20_VMID_MASK_SH_LIST(__SHIFT) @@ -903,6 +772,14 @@ static struct dce_aux *dcn32_aux_engine_create( if (!aux_engine) return NULL; +#undef REG_STRUCT +#define REG_STRUCT aux_engine_regs + aux_engine_regs_init(0), + aux_engine_regs_init(1), + aux_engine_regs_init(2), + aux_engine_regs_init(3), + aux_engine_regs_init(4); + dce110_aux_engine_construct(aux_engine, ctx, inst, SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, &aux_engine_regs[inst], @@ -912,15 +789,10 @@ static struct dce_aux *dcn32_aux_engine_create( return &aux_engine->base; } -#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST_DCN30(id) } - -static const struct dce_i2c_registers i2c_hw_regs[] = { - i2c_inst_regs(1), - i2c_inst_regs(2), - i2c_inst_regs(3), - i2c_inst_regs(4), - i2c_inst_regs(5), -}; +#define i2c_inst_regs_init(id)\ + I2C_HW_ENGINE_COMMON_REG_LIST_DCN30_RI(id) + +static struct dce_i2c_registers i2c_hw_regs[6]; static const struct dce_i2c_shift i2c_shifts = { I2C_COMMON_MASK_SH_LIST_DCN30(__SHIFT) @@ -940,6 +812,14 @@ static struct dce_i2c_hw *dcn32_i2c_hw_create( if (!dce_i2c_hw) return NULL; +#undef REG_STRUCT +#define REG_STRUCT i2c_hw_regs + i2c_inst_regs_init(1), + i2c_inst_regs_init(2), + i2c_inst_regs_init(3), + i2c_inst_regs_init(4), + i2c_inst_regs_init(5); + dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst, &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks); @@ -979,6 +859,29 @@ static struct hubbub *dcn32_hubbub_create(struct dc_context *ctx) if (!hubbub2) return NULL; +#undef REG_STRUCT +#define REG_STRUCT hubbub_reg + hubbub_reg_init(); + +#undef REG_STRUCT +#define REG_STRUCT vmid_regs + vmid_regs_init(0), + vmid_regs_init(1), + vmid_regs_init(2), + vmid_regs_init(3), + vmid_regs_init(4), + vmid_regs_init(5), + vmid_regs_init(6), + vmid_regs_init(7), + vmid_regs_init(8), + vmid_regs_init(9), + vmid_regs_init(10), + vmid_regs_init(11), + vmid_regs_init(12), + vmid_regs_init(13), + vmid_regs_init(14), + vmid_regs_init(15); + hubbub32_construct(hubbub2, ctx, &hubbub_reg, &hubbub_shift, @@ -1011,6 +914,13 @@ static struct hubp *dcn32_hubp_create( if (!hubp2) return NULL; +#undef REG_STRUCT +#define REG_STRUCT hubp_regs + hubp_regs_init(0), + hubp_regs_init(1), + hubp_regs_init(2), + hubp_regs_init(3); + if (hubp32_construct(hubp2, ctx, inst, &hubp_regs[inst], &hubp_shift, &hubp_mask)) return &hubp2->base; @@ -1036,6 +946,13 @@ static struct dpp *dcn32_dpp_create( if (!dpp3) return NULL; +#undef REG_STRUCT +#define REG_STRUCT dpp_regs + dpp_regs_init(0), + dpp_regs_init(1), + dpp_regs_init(2), + dpp_regs_init(3); + if (dpp32_construct(dpp3, ctx, inst, &dpp_regs[inst], &tf_shift, &tf_mask)) return &dpp3->base; @@ -1056,6 +973,10 @@ static struct mpc *dcn32_mpc_create( if (!mpc30) return NULL; +#undef REG_STRUCT +#define REG_STRUCT mpc_regs + dcn_mpc_regs_init(); + dcn32_mpc_construct(mpc30, ctx, &mpc_regs, &mpc_shift, @@ -1077,6 +998,13 @@ static struct output_pixel_processor *dcn32_opp_create( return NULL; } +#undef REG_STRUCT +#define REG_STRUCT opp_regs + opp_regs_init(0), + opp_regs_init(1), + opp_regs_init(2), + opp_regs_init(3); + dcn20_opp_construct(opp2, ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask); return &opp2->base; @@ -1093,6 +1021,13 @@ static struct timing_generator *dcn32_timing_generator_create( if (!tgn10) return NULL; +#undef REG_STRUCT +#define REG_STRUCT optc_regs + optc_regs_init(0), + optc_regs_init(1), + optc_regs_init(2), + optc_regs_init(3); + tgn10->base.inst = instance; tgn10->base.ctx = ctx; @@ -1127,6 +1062,30 @@ static struct link_encoder *dcn32_link_encoder_create( if (!enc20) return NULL; +#undef REG_STRUCT +#define REG_STRUCT link_enc_aux_regs + aux_regs_init(0), + aux_regs_init(1), + aux_regs_init(2), + aux_regs_init(3), + aux_regs_init(4); + +#undef REG_STRUCT +#define REG_STRUCT link_enc_hpd_regs + hpd_regs_init(0), + hpd_regs_init(1), + hpd_regs_init(2), + hpd_regs_init(3), + hpd_regs_init(4); + +#undef REG_STRUCT +#define REG_STRUCT link_enc_regs + link_regs_init(0, A), + link_regs_init(1, B), + link_regs_init(2, C), + link_regs_init(3, D), + link_regs_init(4, E); + dcn32_link_encoder_construct(enc20, enc_init_data, &link_enc_feature, @@ -1156,7 +1115,7 @@ static void read_dce_straps( struct dc_context *ctx, struct resource_straps *straps) { - generic_reg_get(ctx, regDC_PINSTRAPS + BASE(regDC_PINSTRAPS_BASE_IDX), + generic_reg_get(ctx, ctx->dcn_reg_offsets[regDC_PINSTRAPS_BASE_IDX] + regDC_PINSTRAPS, FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio); } @@ -1164,6 +1123,15 @@ static void read_dce_straps( static struct audio *dcn32_create_audio( struct dc_context *ctx, unsigned int inst) { + +#undef REG_STRUCT +#define REG_STRUCT audio_regs + audio_regs_init(0), + audio_regs_init(1), + audio_regs_init(2), + audio_regs_init(3), + audio_regs_init(4); + return dce_audio_create(ctx, inst, &audio_regs[inst], &audio_shift, &audio_mask); } @@ -1177,6 +1145,19 @@ static struct vpg *dcn32_vpg_create( if (!vpg3) return NULL; +#undef REG_STRUCT +#define REG_STRUCT vpg_regs + vpg_regs_init(0), + vpg_regs_init(1), + vpg_regs_init(2), + vpg_regs_init(3), + vpg_regs_init(4), + vpg_regs_init(5), + vpg_regs_init(6), + vpg_regs_init(7), + vpg_regs_init(8), + vpg_regs_init(9); + vpg3_construct(vpg3, ctx, inst, &vpg_regs[inst], &vpg_shift, @@ -1194,6 +1175,15 @@ static struct afmt *dcn32_afmt_create( if (!afmt3) return NULL; +#undef REG_STRUCT +#define REG_STRUCT afmt_regs + afmt_regs_init(0), + afmt_regs_init(1), + afmt_regs_init(2), + afmt_regs_init(3), + afmt_regs_init(4), + afmt_regs_init(5); + afmt3_construct(afmt3, ctx, inst, &afmt_regs[inst], &afmt_shift, @@ -1211,6 +1201,13 @@ static struct apg *dcn31_apg_create( if (!apg31) return NULL; +#undef REG_STRUCT +#define REG_STRUCT apg_regs + apg_regs_init(0), + apg_regs_init(1), + apg_regs_init(2), + apg_regs_init(3); + apg31_construct(apg31, ctx, inst, &apg_regs[inst], &apg_shift, @@ -1247,6 +1244,14 @@ static struct stream_encoder *dcn32_stream_encoder_create( return NULL; } +#undef REG_STRUCT +#define REG_STRUCT stream_enc_regs + stream_enc_regs_init(0), + stream_enc_regs_init(1), + stream_enc_regs_init(2), + stream_enc_regs_init(3), + stream_enc_regs_init(4); + dcn32_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, vpg, afmt, &stream_enc_regs[eng_id], @@ -1297,6 +1302,13 @@ static struct hpo_dp_stream_encoder *dcn32_hpo_dp_stream_encoder_create( return NULL; } +#undef REG_STRUCT +#define REG_STRUCT hpo_dp_stream_enc_regs + hpo_dp_stream_encoder_reg_init(0), + hpo_dp_stream_encoder_reg_init(1), + hpo_dp_stream_encoder_reg_init(2), + hpo_dp_stream_encoder_reg_init(3); + dcn31_hpo_dp_stream_encoder_construct(hpo_dp_enc31, ctx, ctx->dc_bios, hpo_dp_inst, eng_id, vpg, apg, &hpo_dp_stream_enc_regs[hpo_dp_inst], @@ -1314,6 +1326,11 @@ static struct hpo_dp_link_encoder *dcn32_hpo_dp_link_encoder_create( /* allocate HPO link encoder */ hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); +#undef REG_STRUCT +#define REG_STRUCT hpo_dp_link_enc_regs + hpo_dp_link_encoder_reg_init(0), + hpo_dp_link_encoder_reg_init(1); + hpo_dp_link_encoder32_construct(hpo_dp_enc31, ctx, inst, &hpo_dp_link_enc_regs[inst], &hpo_dp_le_shift, &hpo_dp_le_mask); @@ -1326,6 +1343,10 @@ static struct dce_hwseq *dcn32_hwseq_create( { struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); +#undef REG_STRUCT +#define REG_STRUCT hwseq_reg + hwseq_reg_init(); + if (hws) { hws->ctx = ctx; hws->regs = &hwseq_reg; @@ -1517,6 +1538,10 @@ static bool dcn32_dwbc_create(struct dc_context *ctx, struct resource_pool *pool return false; } +#undef REG_STRUCT +#define REG_STRUCT dwbc30_regs + dwbc_regs_dcn3_init(0); + dcn30_dwbc_construct(dwbc30, ctx, &dwbc30_regs[i], &dwbc30_shift, @@ -1542,6 +1567,10 @@ static bool dcn32_mmhubbub_create(struct dc_context *ctx, struct resource_pool * return false; } +#undef REG_STRUCT +#define REG_STRUCT mcif_wb30_regs + mcif_wb_regs_dcn3_init(0); + dcn32_mmhubbub_construct(mcif_wb30, ctx, &mcif_wb30_regs[i], &mcif_wb30_shift, @@ -1564,6 +1593,13 @@ static struct display_stream_compressor *dcn32_dsc_create( return NULL; } +#undef REG_STRUCT +#define REG_STRUCT dsc_regs + dsc_regsDCN20_init(0), + dsc_regsDCN20_init(1), + dsc_regsDCN20_init(2), + dsc_regsDCN20_init(3); + dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask); dsc->max_image_width = 6016; @@ -1701,13 +1737,26 @@ bool dcn32_remove_phantom_pipes(struct dc *dc, struct dc_state *context) { int i; bool removed_pipe = false; + struct dc_plane_state *phantom_plane = NULL; + struct dc_stream_state *phantom_stream = NULL; for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; // build scaling params for phantom pipes if (pipe->plane_state && pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) { + phantom_plane = pipe->plane_state; + phantom_stream = pipe->stream; + dc_rem_all_planes_for_stream(dc, pipe->stream, context); dc_remove_stream_from_ctx(dc, context, pipe->stream); + + /* Ref count is incremented on allocation and also when added to the context. + * Therefore we must call release for the the phantom plane and stream once + * they are removed from the ctx to finally decrement the refcount to 0 to free. + */ + dc_plane_state_release(phantom_plane); + dc_stream_release(phantom_stream); + removed_pipe = true; } @@ -1904,13 +1953,11 @@ int dcn32_populate_dml_pipes_from_context( timing = &pipe->stream->timing; pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal; - res_ctx->pipe_ctx[i].stream->odm_2to1_policy_applied = false; - if (context->stream_count == 1 && timing->dsc_cfg.num_slices_h != 1) { + if (context->stream_count == 1 && !dc_is_hdmi_signal(res_ctx->pipe_ctx[i].stream->signal)) { if (dc->debug.enable_single_display_2to1_odm_policy) { if (!((plane_count > 2) && pipe->top_pipe)) pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1; } - res_ctx->pipe_ctx[i].stream->odm_2to1_policy_applied = true; } pipe_cnt++; } @@ -2002,6 +2049,28 @@ static bool dcn32_resource_construct( uint32_t pipe_fuses = 0; uint32_t num_pipes = 4; + #undef REG_STRUCT + #define REG_STRUCT bios_regs + bios_regs_init(); + + #undef REG_STRUCT + #define REG_STRUCT clk_src_regs + clk_src_regs_init(0, A), + clk_src_regs_init(1, B), + clk_src_regs_init(2, C), + clk_src_regs_init(3, D), + clk_src_regs_init(4, E); + #undef REG_STRUCT + #define REG_STRUCT abm_regs + abm_regs_init(0), + abm_regs_init(1), + abm_regs_init(2), + abm_regs_init(3); + + #undef REG_STRUCT + #define REG_STRUCT dccg_regs + dccg_regs_init(); + DC_FP_START(); ctx->dc_bios->regs = &bios_regs; diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h index 1e7e6201c880..60d8fad16eee 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h @@ -109,4 +109,1084 @@ struct pipe_ctx *dcn32_acquire_idle_pipe_for_head_pipe_in_layer( void dcn32_determine_det_override(struct dc_state *context, display_e2e_pipe_params_st *pipes, bool *is_pipe_split_expected, int pipe_cnt); +/* definitions for run time init of reg offsets */ + +/* CLK SRC */ +#define CS_COMMON_REG_LIST_DCN3_0_RI(index, pllid) \ + ( \ + SRI_ARR_ALPHABET(PIXCLK_RESYNC_CNTL, PHYPLL, index, pllid), \ + SRII_ARR_2(PHASE, DP_DTO, 0, index), \ + SRII_ARR_2(PHASE, DP_DTO, 1, index), \ + SRII_ARR_2(PHASE, DP_DTO, 2, index), \ + SRII_ARR_2(PHASE, DP_DTO, 3, index), \ + SRII_ARR_2(MODULO, DP_DTO, 0, index), \ + SRII_ARR_2(MODULO, DP_DTO, 1, index), \ + SRII_ARR_2(MODULO, DP_DTO, 2, index), \ + SRII_ARR_2(MODULO, DP_DTO, 3, index), \ + SRII_ARR_2(PIXEL_RATE_CNTL, OTG, 0, index), \ + SRII_ARR_2(PIXEL_RATE_CNTL, OTG, 1, index), \ + SRII_ARR_2(PIXEL_RATE_CNTL, OTG, 2, index), \ + SRII_ARR_2(PIXEL_RATE_CNTL, OTG, 3, index) \ + ) + +/* ABM */ +#define ABM_DCN32_REG_LIST_RI(id) \ + ( \ + SRI_ARR(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \ + SRI_ARR(DC_ABM1_LS_SAMPLE_RATE, ABM, id), \ + SRI_ARR(BL1_PWM_BL_UPDATE_SAMPLE_RATE, ABM, id), \ + SRI_ARR(DC_ABM1_HG_MISC_CTRL, ABM, id), \ + SRI_ARR(DC_ABM1_IPCSC_COEFF_SEL, ABM, id), \ + SRI_ARR(BL1_PWM_CURRENT_ABM_LEVEL, ABM, id), \ + SRI_ARR(BL1_PWM_TARGET_ABM_LEVEL, ABM, id), \ + SRI_ARR(BL1_PWM_USER_LEVEL, ABM, id), \ + SRI_ARR(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, ABM, id), \ + SRI_ARR(DC_ABM1_HGLS_REG_READ_PROGRESS, ABM, id), \ + SRI_ARR(DC_ABM1_ACE_OFFSET_SLOPE_0, ABM, id), \ + SRI_ARR(DC_ABM1_ACE_THRES_12, ABM, id), NBIO_SR_ARR(BIOS_SCRATCH_2, id) \ + ) + +/* Audio */ +#define AUD_COMMON_REG_LIST_RI(id) \ + ( \ + SRI_ARR(AZALIA_F0_CODEC_ENDPOINT_INDEX, AZF0ENDPOINT, id), \ + SRI_ARR(AZALIA_F0_CODEC_ENDPOINT_DATA, AZF0ENDPOINT, id), \ + SR_ARR(AZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS, id), \ + SR_ARR(AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES, id), \ + SR_ARR(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES, id), \ + SR_ARR(DCCG_AUDIO_DTO_SOURCE, id), SR_ARR(DCCG_AUDIO_DTO0_MODULE, id), \ + SR_ARR(DCCG_AUDIO_DTO0_PHASE, id), SR_ARR(DCCG_AUDIO_DTO1_MODULE, id), \ + SR_ARR(DCCG_AUDIO_DTO1_PHASE, id) \ + ) + +/* VPG */ + +#define VPG_DCN3_REG_LIST_RI(id) \ + ( \ + SRI_ARR(VPG_GENERIC_STATUS, VPG, id), \ + SRI_ARR(VPG_GENERIC_PACKET_ACCESS_CTRL, VPG, id), \ + SRI_ARR(VPG_GENERIC_PACKET_DATA, VPG, id), \ + SRI_ARR(VPG_GSP_FRAME_UPDATE_CTRL, VPG, id), \ + SRI_ARR(VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG, id) \ + ) + +/* AFMT */ +#define AFMT_DCN3_REG_LIST_RI(id) \ + ( \ + SRI_ARR(AFMT_INFOFRAME_CONTROL0, AFMT, id), \ + SRI_ARR(AFMT_VBI_PACKET_CONTROL, AFMT, id), \ + SRI_ARR(AFMT_AUDIO_PACKET_CONTROL, AFMT, id), \ + SRI_ARR(AFMT_AUDIO_PACKET_CONTROL2, AFMT, id), \ + SRI_ARR(AFMT_AUDIO_SRC_CONTROL, AFMT, id), \ + SRI_ARR(AFMT_60958_0, AFMT, id), SRI_ARR(AFMT_60958_1, AFMT, id), \ + SRI_ARR(AFMT_60958_2, AFMT, id), SRI_ARR(AFMT_MEM_PWR, AFMT, id) \ + ) + +/* APG */ +#define APG_DCN31_REG_LIST_RI(id) \ + (\ + SRI_ARR(APG_CONTROL, APG, id), SRI_ARR(APG_CONTROL2, APG, id), \ + SRI_ARR(APG_MEM_PWR, APG, id), SRI_ARR(APG_DBG_GEN_CONTROL, APG, id) \ + ) + +/* Stream encoder */ +#define SE_DCN32_REG_LIST_RI(id) \ + ( \ + SRI_ARR(AFMT_CNTL, DIG, id), SRI_ARR(DIG_FE_CNTL, DIG, id), \ + SRI_ARR(HDMI_CONTROL, DIG, id), SRI_ARR(HDMI_DB_CONTROL, DIG, id), \ + SRI_ARR(HDMI_GC, DIG, id), \ + SRI_ARR(HDMI_GENERIC_PACKET_CONTROL0, DIG, id), \ + SRI_ARR(HDMI_GENERIC_PACKET_CONTROL1, DIG, id), \ + SRI_ARR(HDMI_GENERIC_PACKET_CONTROL2, DIG, id), \ + SRI_ARR(HDMI_GENERIC_PACKET_CONTROL3, DIG, id), \ + SRI_ARR(HDMI_GENERIC_PACKET_CONTROL4, DIG, id), \ + SRI_ARR(HDMI_GENERIC_PACKET_CONTROL5, DIG, id), \ + SRI_ARR(HDMI_GENERIC_PACKET_CONTROL6, DIG, id), \ + SRI_ARR(HDMI_GENERIC_PACKET_CONTROL7, DIG, id), \ + SRI_ARR(HDMI_GENERIC_PACKET_CONTROL8, DIG, id), \ + SRI_ARR(HDMI_GENERIC_PACKET_CONTROL9, DIG, id), \ + SRI_ARR(HDMI_GENERIC_PACKET_CONTROL10, DIG, id), \ + SRI_ARR(HDMI_INFOFRAME_CONTROL0, DIG, id), \ + SRI_ARR(HDMI_INFOFRAME_CONTROL1, DIG, id), \ + SRI_ARR(HDMI_VBI_PACKET_CONTROL, DIG, id), \ + SRI_ARR(HDMI_AUDIO_PACKET_CONTROL, DIG, id), \ + SRI_ARR(HDMI_ACR_PACKET_CONTROL, DIG, id), \ + SRI_ARR(HDMI_ACR_32_0, DIG, id), SRI_ARR(HDMI_ACR_32_1, DIG, id), \ + SRI_ARR(HDMI_ACR_44_0, DIG, id), SRI_ARR(HDMI_ACR_44_1, DIG, id), \ + SRI_ARR(HDMI_ACR_48_0, DIG, id), SRI_ARR(HDMI_ACR_48_1, DIG, id), \ + SRI_ARR(DP_DB_CNTL, DP, id), SRI_ARR(DP_MSA_MISC, DP, id), \ + SRI_ARR(DP_MSA_VBID_MISC, DP, id), SRI_ARR(DP_MSA_COLORIMETRY, DP, id), \ + SRI_ARR(DP_MSA_TIMING_PARAM1, DP, id), \ + SRI_ARR(DP_MSA_TIMING_PARAM2, DP, id), \ + SRI_ARR(DP_MSA_TIMING_PARAM3, DP, id), \ + SRI_ARR(DP_MSA_TIMING_PARAM4, DP, id), \ + SRI_ARR(DP_MSE_RATE_CNTL, DP, id), SRI_ARR(DP_MSE_RATE_UPDATE, DP, id), \ + SRI_ARR(DP_PIXEL_FORMAT, DP, id), SRI_ARR(DP_SEC_CNTL, DP, id), \ + SRI_ARR(DP_SEC_CNTL2, DP, id), SRI_ARR(DP_SEC_CNTL6, DP, id), \ + SRI_ARR(DP_STEER_FIFO, DP, id), SRI_ARR(DP_VID_M, DP, id), \ + SRI_ARR(DP_VID_N, DP, id), SRI_ARR(DP_VID_STREAM_CNTL, DP, id), \ + SRI_ARR(DP_VID_TIMING, DP, id), SRI_ARR(DP_SEC_AUD_N, DP, id), \ + SRI_ARR(DP_SEC_TIMESTAMP, DP, id), SRI_ARR(DP_DSC_CNTL, DP, id), \ + SRI_ARR(DP_SEC_METADATA_TRANSMISSION, DP, id), \ + SRI_ARR(HDMI_METADATA_PACKET_CONTROL, DIG, id), \ + SRI_ARR(DP_SEC_FRAMING4, DP, id), SRI_ARR(DP_GSP11_CNTL, DP, id), \ + SRI_ARR(DME_CONTROL, DME, id), \ + SRI_ARR(DP_SEC_METADATA_TRANSMISSION, DP, id), \ + SRI_ARR(HDMI_METADATA_PACKET_CONTROL, DIG, id), \ + SRI_ARR(DIG_FE_CNTL, DIG, id), SRI_ARR(DIG_CLOCK_PATTERN, DIG, id), \ + SRI_ARR(DIG_FIFO_CTRL0, DIG, id) \ + ) + +/* Aux regs */ + +#define AUX_REG_LIST_RI(id) \ + ( \ + SRI_ARR(AUX_CONTROL, DP_AUX, id), SRI_ARR(AUX_DPHY_RX_CONTROL0, DP_AUX, id), \ + SRI_ARR(AUX_DPHY_RX_CONTROL1, DP_AUX, id) \ + ) + +#define DCN2_AUX_REG_LIST_RI(id) \ + ( \ + AUX_REG_LIST_RI(id), SRI_ARR(AUX_DPHY_TX_CONTROL, DP_AUX, id) \ + ) + +/* HDP */ +#define HPD_REG_LIST_RI(id) SRI_ARR(DC_HPD_CONTROL, HPD, id) + +/* Link encoder */ +#define LE_DCN3_REG_LIST_RI(id) \ + ( \ + SRI_ARR(DIG_BE_CNTL, DIG, id), SRI_ARR(DIG_BE_EN_CNTL, DIG, id), \ + SRI_ARR(TMDS_CTL_BITS, DIG, id), \ + SRI_ARR(TMDS_DCBALANCER_CONTROL, DIG, id), SRI_ARR(DP_CONFIG, DP, id), \ + SRI_ARR(DP_DPHY_CNTL, DP, id), SRI_ARR(DP_DPHY_PRBS_CNTL, DP, id), \ + SRI_ARR(DP_DPHY_SCRAM_CNTL, DP, id), SRI_ARR(DP_DPHY_SYM0, DP, id), \ + SRI_ARR(DP_DPHY_SYM1, DP, id), SRI_ARR(DP_DPHY_SYM2, DP, id), \ + SRI_ARR(DP_DPHY_TRAINING_PATTERN_SEL, DP, id), \ + SRI_ARR(DP_LINK_CNTL, DP, id), SRI_ARR(DP_LINK_FRAMING_CNTL, DP, id), \ + SRI_ARR(DP_MSE_SAT0, DP, id), SRI_ARR(DP_MSE_SAT1, DP, id), \ + SRI_ARR(DP_MSE_SAT2, DP, id), SRI_ARR(DP_MSE_SAT_UPDATE, DP, id), \ + SRI_ARR(DP_SEC_CNTL, DP, id), SRI_ARR(DP_VID_STREAM_CNTL, DP, id), \ + SRI_ARR(DP_DPHY_FAST_TRAINING, DP, id), SRI_ARR(DP_SEC_CNTL1, DP, id), \ + SRI_ARR(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ + SRI_ARR(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id) \ + ) + +#define LE_DCN31_REG_LIST_RI(id) \ + ( \ + LE_DCN3_REG_LIST_RI(id), SRI_ARR(DP_DPHY_INTERNAL_CTRL, DP, id), \ + SR_ARR(DIO_LINKA_CNTL, id), SR_ARR(DIO_LINKB_CNTL, id), \ + SR_ARR(DIO_LINKC_CNTL, id), SR_ARR(DIO_LINKD_CNTL, id), \ + SR_ARR(DIO_LINKE_CNTL, id), SR_ARR(DIO_LINKF_CNTL, id) \ + ) + +#define UNIPHY_DCN2_REG_LIST_RI(id, phyid) \ + ( \ + SRI_ARR_ALPHABET(CLOCK_ENABLE, SYMCLK, id, phyid), \ + SRI_ARR_ALPHABET(CHANNEL_XBAR_CNTL, UNIPHY, id, phyid) \ + ) + +/* HPO DP stream encoder */ +#define DCN3_1_HPO_DP_STREAM_ENC_REG_LIST_RI(id) \ + ( \ + SR_ARR(DP_STREAM_MAPPER_CONTROL0, id), \ + SR_ARR(DP_STREAM_MAPPER_CONTROL1, id), \ + SR_ARR(DP_STREAM_MAPPER_CONTROL2, id), \ + SR_ARR(DP_STREAM_MAPPER_CONTROL3, id), \ + SRI_ARR(DP_STREAM_ENC_CLOCK_CONTROL, DP_STREAM_ENC, id), \ + SRI_ARR(DP_STREAM_ENC_INPUT_MUX_CONTROL, DP_STREAM_ENC, id), \ + SRI_ARR(DP_STREAM_ENC_AUDIO_CONTROL, DP_STREAM_ENC, id), \ + SRI_ARR(DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL0, DP_STREAM_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_CONTROL, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_PIXEL_FORMAT, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_PIXEL_FORMAT_DOUBLE_BUFFER_CONTROL, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_MSA0, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_MSA1, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_MSA2, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_MSA3, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_MSA4, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_MSA5, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_MSA6, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_MSA7, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_MSA8, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_MSA_CONTROL, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_MSA_DOUBLE_BUFFER_CONTROL, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_FIFO_CONTROL, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_STREAM_CONTROL, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_VBID_CONTROL, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_SDP_CONTROL, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_SDP_GSP_CONTROL0, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_SDP_GSP_CONTROL2, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_SDP_GSP_CONTROL3, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_SDP_GSP_CONTROL5, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_SDP_GSP_CONTROL11, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_SDP_METADATA_PACKET_CONTROL, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_SDP_AUDIO_CONTROL0, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_VID_CRC_CONTROL, DP_SYM32_ENC, id), \ + SRI_ARR(DP_SYM32_ENC_HBLANK_CONTROL, DP_SYM32_ENC, id) \ + ) + +/* HPO DP link encoder regs */ +#define DCN3_1_HPO_DP_LINK_ENC_REG_LIST_RI(id) \ + ( \ + SRI_ARR(DP_LINK_ENC_CLOCK_CONTROL, DP_LINK_ENC, id), \ + SRI_ARR(DP_DPHY_SYM32_CONTROL, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_STATUS, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_CONFIG, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_PRBS_SEED0, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_PRBS_SEED1, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_PRBS_SEED2, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_PRBS_SEED3, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_SQ_PULSE, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_CUSTOM0, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_CUSTOM1, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_CUSTOM2, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_CUSTOM3, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_CUSTOM4, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_CUSTOM5, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_CUSTOM6, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_CUSTOM7, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_CUSTOM8, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_CUSTOM9, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_TP_CUSTOM10, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_SAT_VC0, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_SAT_VC1, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_SAT_VC2, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_SAT_VC3, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_VC_RATE_CNTL0, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_VC_RATE_CNTL1, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_VC_RATE_CNTL2, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_VC_RATE_CNTL3, DP_DPHY_SYM32, id), \ + SRI_ARR(DP_DPHY_SYM32_SAT_UPDATE, DP_DPHY_SYM32, id) \ + ) + +/* DPP */ +#define DPP_REG_LIST_DCN30_COMMON_RI(id) \ + ( \ + SRI_ARR(CM_DEALPHA, CM, id), SRI_ARR(CM_MEM_PWR_STATUS, CM, id), \ + SRI_ARR(CM_BIAS_CR_R, CM, id), SRI_ARR(CM_BIAS_Y_G_CB_B, CM, id), \ + SRI_ARR(PRE_DEGAM, CNVC_CFG, id), SRI_ARR(CM_GAMCOR_CONTROL, CM, id), \ + SRI_ARR(CM_GAMCOR_LUT_CONTROL, CM, id), \ + SRI_ARR(CM_GAMCOR_LUT_INDEX, CM, id), \ + SRI_ARR(CM_GAMCOR_LUT_INDEX, CM, id), \ + SRI_ARR(CM_GAMCOR_LUT_DATA, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_START_CNTL_B, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_START_CNTL_G, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_START_CNTL_R, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_START_SLOPE_CNTL_B, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_START_SLOPE_CNTL_G, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_START_SLOPE_CNTL_R, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_END_CNTL1_B, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_END_CNTL2_B, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_END_CNTL1_G, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_END_CNTL2_G, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_END_CNTL1_R, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_END_CNTL2_R, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_REGION_0_1, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_REGION_32_33, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_OFFSET_B, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_OFFSET_G, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_OFFSET_R, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_START_BASE_CNTL_B, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_START_BASE_CNTL_G, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMB_START_BASE_CNTL_R, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_START_CNTL_B, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_START_CNTL_G, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_START_CNTL_R, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_START_SLOPE_CNTL_B, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_START_SLOPE_CNTL_G, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_START_SLOPE_CNTL_R, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_END_CNTL1_B, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_END_CNTL2_B, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_END_CNTL1_G, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_END_CNTL2_G, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_END_CNTL1_R, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_END_CNTL2_R, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_REGION_0_1, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_REGION_32_33, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_OFFSET_B, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_OFFSET_G, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_OFFSET_R, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_START_BASE_CNTL_B, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_START_BASE_CNTL_G, CM, id), \ + SRI_ARR(CM_GAMCOR_RAMA_START_BASE_CNTL_R, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_CONTROL, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_C11_C12, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_C13_C14, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_C21_C22, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_C23_C24, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_C31_C32, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_C33_C34, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_B_C11_C12, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_B_C13_C14, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_B_C21_C22, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_B_C23_C24, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_B_C31_C32, CM, id), \ + SRI_ARR(CM_GAMUT_REMAP_B_C33_C34, CM, id), \ + SRI_ARR(DSCL_EXT_OVERSCAN_LEFT_RIGHT, DSCL, id), \ + SRI_ARR(DSCL_EXT_OVERSCAN_TOP_BOTTOM, DSCL, id), \ + SRI_ARR(OTG_H_BLANK, DSCL, id), SRI_ARR(OTG_V_BLANK, DSCL, id), \ + SRI_ARR(SCL_MODE, DSCL, id), SRI_ARR(LB_DATA_FORMAT, DSCL, id), \ + SRI_ARR(LB_MEMORY_CTRL, DSCL, id), SRI_ARR(DSCL_AUTOCAL, DSCL, id), \ + SRI_ARR(SCL_TAP_CONTROL, DSCL, id), \ + SRI_ARR(SCL_COEF_RAM_TAP_SELECT, DSCL, id), \ + SRI_ARR(SCL_COEF_RAM_TAP_DATA, DSCL, id), \ + SRI_ARR(DSCL_2TAP_CONTROL, DSCL, id), SRI_ARR(MPC_SIZE, DSCL, id), \ + SRI_ARR(SCL_HORZ_FILTER_SCALE_RATIO, DSCL, id), \ + SRI_ARR(SCL_VERT_FILTER_SCALE_RATIO, DSCL, id), \ + SRI_ARR(SCL_HORZ_FILTER_SCALE_RATIO_C, DSCL, id), \ + SRI_ARR(SCL_VERT_FILTER_SCALE_RATIO_C, DSCL, id), \ + SRI_ARR(SCL_HORZ_FILTER_INIT, DSCL, id), \ + SRI_ARR(SCL_HORZ_FILTER_INIT_C, DSCL, id), \ + SRI_ARR(SCL_VERT_FILTER_INIT, DSCL, id), \ + SRI_ARR(SCL_VERT_FILTER_INIT_C, DSCL, id), \ + SRI_ARR(RECOUT_START, DSCL, id), SRI_ARR(RECOUT_SIZE, DSCL, id), \ + SRI_ARR(PRE_DEALPHA, CNVC_CFG, id), SRI_ARR(PRE_REALPHA, CNVC_CFG, id), \ + SRI_ARR(PRE_CSC_MODE, CNVC_CFG, id), \ + SRI_ARR(PRE_CSC_C11_C12, CNVC_CFG, id), \ + SRI_ARR(PRE_CSC_C33_C34, CNVC_CFG, id), \ + SRI_ARR(PRE_CSC_B_C11_C12, CNVC_CFG, id), \ + SRI_ARR(PRE_CSC_B_C33_C34, CNVC_CFG, id), \ + SRI_ARR(CM_POST_CSC_CONTROL, CM, id), \ + SRI_ARR(CM_POST_CSC_C11_C12, CM, id), \ + SRI_ARR(CM_POST_CSC_C33_C34, CM, id), \ + SRI_ARR(CM_POST_CSC_B_C11_C12, CM, id), \ + SRI_ARR(CM_POST_CSC_B_C33_C34, CM, id), \ + SRI_ARR(CM_MEM_PWR_CTRL, CM, id), SRI_ARR(CM_CONTROL, CM, id), \ + SRI_ARR(FORMAT_CONTROL, CNVC_CFG, id), \ + SRI_ARR(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \ + SRI_ARR(CURSOR0_CONTROL, CNVC_CUR, id), \ + SRI_ARR(CURSOR0_COLOR0, CNVC_CUR, id), \ + SRI_ARR(CURSOR0_COLOR1, CNVC_CUR, id), \ + SRI_ARR(CURSOR0_FP_SCALE_BIAS, CNVC_CUR, id), \ + SRI_ARR(DPP_CONTROL, DPP_TOP, id), SRI_ARR(CM_HDR_MULT_COEF, CM, id), \ + SRI_ARR(CURSOR_CONTROL, CURSOR0_, id), \ + SRI_ARR(ALPHA_2BIT_LUT, CNVC_CFG, id), \ + SRI_ARR(FCNV_FP_BIAS_R, CNVC_CFG, id), \ + SRI_ARR(FCNV_FP_BIAS_G, CNVC_CFG, id), \ + SRI_ARR(FCNV_FP_BIAS_B, CNVC_CFG, id), \ + SRI_ARR(FCNV_FP_SCALE_R, CNVC_CFG, id), \ + SRI_ARR(FCNV_FP_SCALE_G, CNVC_CFG, id), \ + SRI_ARR(FCNV_FP_SCALE_B, CNVC_CFG, id), \ + SRI_ARR(COLOR_KEYER_CONTROL, CNVC_CFG, id), \ + SRI_ARR(COLOR_KEYER_ALPHA, CNVC_CFG, id), \ + SRI_ARR(COLOR_KEYER_RED, CNVC_CFG, id), \ + SRI_ARR(COLOR_KEYER_GREEN, CNVC_CFG, id), \ + SRI_ARR(COLOR_KEYER_BLUE, CNVC_CFG, id), \ + SRI_ARR(CURSOR_CONTROL, CURSOR0_, id), \ + SRI_ARR(OBUF_MEM_PWR_CTRL, DSCL, id), \ + SRI_ARR(DSCL_MEM_PWR_STATUS, DSCL, id), \ + SRI_ARR(DSCL_MEM_PWR_CTRL, DSCL, id) \ + ) + +/* OPP */ +#define OPP_REG_LIST_DCN_RI(id) \ + ( \ + SRI_ARR(FMT_BIT_DEPTH_CONTROL, FMT, id), SRI_ARR(FMT_CONTROL, FMT, id), \ + SRI_ARR(FMT_DITHER_RAND_R_SEED, FMT, id), \ + SRI_ARR(FMT_DITHER_RAND_G_SEED, FMT, id), \ + SRI_ARR(FMT_DITHER_RAND_B_SEED, FMT, id), \ + SRI_ARR(FMT_CLAMP_CNTL, FMT, id), \ + SRI_ARR(FMT_DYNAMIC_EXP_CNTL, FMT, id), \ + SRI_ARR(FMT_MAP420_MEMORY_CONTROL, FMT, id), \ + SRI_ARR(OPPBUF_CONTROL, OPPBUF, id), \ + SRI_ARR(OPPBUF_3D_PARAMETERS_0, OPPBUF, id), \ + SRI_ARR(OPPBUF_3D_PARAMETERS_1, OPPBUF, id), \ + SRI_ARR(OPP_PIPE_CONTROL, OPP_PIPE, id) \ + ) + +#define OPP_REG_LIST_DCN10_RI(id) OPP_REG_LIST_DCN_RI(id) + +#define OPP_DPG_REG_LIST_RI(id) \ + ( \ + SRI_ARR(DPG_CONTROL, DPG, id), SRI_ARR(DPG_DIMENSIONS, DPG, id), \ + SRI_ARR(DPG_OFFSET_SEGMENT, DPG, id), SRI_ARR(DPG_COLOUR_B_CB, DPG, id), \ + SRI_ARR(DPG_COLOUR_G_Y, DPG, id), SRI_ARR(DPG_COLOUR_R_CR, DPG, id), \ + SRI_ARR(DPG_RAMP_CONTROL, DPG, id), SRI_ARR(DPG_STATUS, DPG, id) \ + ) + +#define OPP_REG_LIST_DCN30_RI(id) \ + ( \ + OPP_REG_LIST_DCN10_RI(id), OPP_DPG_REG_LIST_RI(id), \ + SRI_ARR(FMT_422_CONTROL, FMT, id) \ + ) + +/* Aux engine regs */ +#define AUX_COMMON_REG_LIST0_RI(id) \ + ( \ + SRI_ARR(AUX_CONTROL, DP_AUX, id), SRI_ARR(AUX_ARB_CONTROL, DP_AUX, id), \ + SRI_ARR(AUX_SW_DATA, DP_AUX, id), SRI_ARR(AUX_SW_CONTROL, DP_AUX, id), \ + SRI_ARR(AUX_INTERRUPT_CONTROL, DP_AUX, id), \ + SRI_ARR(AUX_DPHY_RX_CONTROL1, DP_AUX, id), \ + SRI_ARR(AUX_SW_STATUS, DP_AUX, id) \ + ) + +/* DWBC */ +#define DWBC_COMMON_REG_LIST_DCN30_RI(id) \ + ( \ + SR_ARR(DWB_ENABLE_CLK_CTRL, id), SR_ARR(DWB_MEM_PWR_CTRL, id), \ + SR_ARR(FC_MODE_CTRL, id), SR_ARR(FC_FLOW_CTRL, id), \ + SR_ARR(FC_WINDOW_START, id), SR_ARR(FC_WINDOW_SIZE, id), \ + SR_ARR(FC_SOURCE_SIZE, id), SR_ARR(DWB_UPDATE_CTRL, id), \ + SR_ARR(DWB_CRC_CTRL, id), SR_ARR(DWB_CRC_MASK_R_G, id), \ + SR_ARR(DWB_CRC_MASK_B_A, id), SR_ARR(DWB_CRC_VAL_R_G, id), \ + SR_ARR(DWB_CRC_VAL_B_A, id), SR_ARR(DWB_OUT_CTRL, id), \ + SR_ARR(DWB_MMHUBBUB_BACKPRESSURE_CNT_EN, id), \ + SR_ARR(DWB_MMHUBBUB_BACKPRESSURE_CNT, id), \ + SR_ARR(DWB_HOST_READ_CONTROL, id), SR_ARR(DWB_SOFT_RESET, id), \ + SR_ARR(DWB_HDR_MULT_COEF, id), SR_ARR(DWB_GAMUT_REMAP_MODE, id), \ + SR_ARR(DWB_GAMUT_REMAP_COEF_FORMAT, id), \ + SR_ARR(DWB_GAMUT_REMAPA_C11_C12, id), \ + SR_ARR(DWB_GAMUT_REMAPA_C13_C14, id), \ + SR_ARR(DWB_GAMUT_REMAPA_C21_C22, id), \ + SR_ARR(DWB_GAMUT_REMAPA_C23_C24, id), \ + SR_ARR(DWB_GAMUT_REMAPA_C31_C32, id), \ + SR_ARR(DWB_GAMUT_REMAPA_C33_C34, id), \ + SR_ARR(DWB_GAMUT_REMAPB_C11_C12, id), \ + SR_ARR(DWB_GAMUT_REMAPB_C13_C14, id), \ + SR_ARR(DWB_GAMUT_REMAPB_C21_C22, id), \ + SR_ARR(DWB_GAMUT_REMAPB_C23_C24, id), \ + SR_ARR(DWB_GAMUT_REMAPB_C31_C32, id), \ + SR_ARR(DWB_GAMUT_REMAPB_C33_C34, id), SR_ARR(DWB_OGAM_CONTROL, id), \ + SR_ARR(DWB_OGAM_LUT_INDEX, id), SR_ARR(DWB_OGAM_LUT_DATA, id), \ + SR_ARR(DWB_OGAM_LUT_CONTROL, id), \ + SR_ARR(DWB_OGAM_RAMA_START_CNTL_B, id), \ + SR_ARR(DWB_OGAM_RAMA_START_CNTL_G, id), \ + SR_ARR(DWB_OGAM_RAMA_START_CNTL_R, id), \ + SR_ARR(DWB_OGAM_RAMA_START_BASE_CNTL_B, id), \ + SR_ARR(DWB_OGAM_RAMA_START_SLOPE_CNTL_B, id), \ + SR_ARR(DWB_OGAM_RAMA_START_BASE_CNTL_G, id), \ + SR_ARR(DWB_OGAM_RAMA_START_SLOPE_CNTL_G, id), \ + SR_ARR(DWB_OGAM_RAMA_START_BASE_CNTL_R, id), \ + SR_ARR(DWB_OGAM_RAMA_START_SLOPE_CNTL_R, id), \ + SR_ARR(DWB_OGAM_RAMA_END_CNTL1_B, id), \ + SR_ARR(DWB_OGAM_RAMA_END_CNTL2_B, id), \ + SR_ARR(DWB_OGAM_RAMA_END_CNTL1_G, id), \ + SR_ARR(DWB_OGAM_RAMA_END_CNTL2_G, id), \ + SR_ARR(DWB_OGAM_RAMA_END_CNTL1_R, id), \ + SR_ARR(DWB_OGAM_RAMA_END_CNTL2_R, id), \ + SR_ARR(DWB_OGAM_RAMA_OFFSET_B, id), SR_ARR(DWB_OGAM_RAMA_OFFSET_G, id), \ + SR_ARR(DWB_OGAM_RAMA_OFFSET_R, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_0_1, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_2_3, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_4_5, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_6_7, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_8_9, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_10_11, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_12_13, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_14_15, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_16_17, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_18_19, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_20_21, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_22_23, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_24_25, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_26_27, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_28_29, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_30_31, id), \ + SR_ARR(DWB_OGAM_RAMA_REGION_32_33, id), \ + SR_ARR(DWB_OGAM_RAMB_START_CNTL_B, id), \ + SR_ARR(DWB_OGAM_RAMB_START_CNTL_G, id), \ + SR_ARR(DWB_OGAM_RAMB_START_CNTL_R, id), \ + SR_ARR(DWB_OGAM_RAMB_START_BASE_CNTL_B, id), \ + SR_ARR(DWB_OGAM_RAMB_START_SLOPE_CNTL_B, id), \ + SR_ARR(DWB_OGAM_RAMB_START_BASE_CNTL_G, id), \ + SR_ARR(DWB_OGAM_RAMB_START_SLOPE_CNTL_G, id), \ + SR_ARR(DWB_OGAM_RAMB_START_BASE_CNTL_R, id), \ + SR_ARR(DWB_OGAM_RAMB_START_SLOPE_CNTL_R, id), \ + SR_ARR(DWB_OGAM_RAMB_END_CNTL1_B, id), \ + SR_ARR(DWB_OGAM_RAMB_END_CNTL2_B, id), \ + SR_ARR(DWB_OGAM_RAMB_END_CNTL1_G, id), \ + SR_ARR(DWB_OGAM_RAMB_END_CNTL2_G, id), \ + SR_ARR(DWB_OGAM_RAMB_END_CNTL1_R, id), \ + SR_ARR(DWB_OGAM_RAMB_END_CNTL2_R, id), \ + SR_ARR(DWB_OGAM_RAMB_OFFSET_B, id), SR_ARR(DWB_OGAM_RAMB_OFFSET_G, id), \ + SR_ARR(DWB_OGAM_RAMB_OFFSET_R, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_0_1, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_2_3, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_4_5, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_6_7, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_8_9, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_10_11, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_12_13, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_14_15, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_16_17, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_18_19, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_20_21, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_22_23, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_24_25, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_26_27, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_28_29, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_30_31, id), \ + SR_ARR(DWB_OGAM_RAMB_REGION_32_33, id) \ + ) + +/* MCIF */ + +#define MCIF_WB_COMMON_REG_LIST_DCN32_RI(inst) \ + ( \ + SRI2_ARR(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUFMGR_STATUS, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_PITCH, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_1_STATUS, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_1_STATUS2, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_2_STATUS, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_2_STATUS2, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_3_STATUS, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_3_STATUS2, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_4_STATUS, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_4_STATUS2, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_ARBITRATION_CONTROL, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_SCLK_CHANGE, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_TEST_DEBUG_INDEX, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_TEST_DEBUG_DATA, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_1_ADDR_Y, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_1_ADDR_C, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_2_ADDR_Y, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_2_ADDR_C, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_3_ADDR_Y, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_3_ADDR_C, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_4_ADDR_Y, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_4_ADDR_C, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUFMGR_VCE_CONTROL, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK, MMHUBBUB, inst), \ + SRI2_ARR(MCIF_WB_NB_PSTATE_CONTROL, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_WATERMARK, MMHUBBUB, inst), \ + SRI2_ARR(MCIF_WB_CLOCK_GATER_CONTROL, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_SELF_REFRESH_CONTROL, MCIF_WB, inst), \ + SRI2_ARR(MULTI_LEVEL_QOS_CTRL, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_SECURITY_LEVEL, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_LUMA_SIZE, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_CHROMA_SIZE, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_1_ADDR_Y_HIGH, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_1_ADDR_C_HIGH, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_2_ADDR_Y_HIGH, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_2_ADDR_C_HIGH, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_3_ADDR_Y_HIGH, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_3_ADDR_C_HIGH, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_4_ADDR_Y_HIGH, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_4_ADDR_C_HIGH, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_1_RESOLUTION, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_2_RESOLUTION, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_3_RESOLUTION, MCIF_WB, inst), \ + SRI2_ARR(MCIF_WB_BUF_4_RESOLUTION, MCIF_WB, inst), \ + SRI2_ARR(MMHUBBUB_MEM_PWR_CNTL, MMHUBBUB, inst), \ + SRI2_ARR(MMHUBBUB_WARMUP_ADDR_REGION, MMHUBBUB, inst), \ + SRI2_ARR(MMHUBBUB_WARMUP_BASE_ADDR_HIGH, MMHUBBUB, inst), \ + SRI2_ARR(MMHUBBUB_WARMUP_BASE_ADDR_LOW, MMHUBBUB, inst), \ + SRI2_ARR(MMHUBBUB_WARMUP_CONTROL_STATUS, MMHUBBUB, inst) \ + ) + +/* DSC */ + +#define DSC_REG_LIST_DCN20_RI(id) \ + ( \ + SRI_ARR(DSC_TOP_CONTROL, DSC_TOP, id), \ + SRI_ARR(DSC_DEBUG_CONTROL, DSC_TOP, id), \ + SRI_ARR(DSCC_CONFIG0, DSCC, id), SRI_ARR(DSCC_CONFIG1, DSCC, id), \ + SRI_ARR(DSCC_STATUS, DSCC, id), \ + SRI_ARR(DSCC_INTERRUPT_CONTROL_STATUS, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG0, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG1, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG2, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG3, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG4, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG5, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG6, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG7, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG8, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG9, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG10, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG11, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG12, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG13, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG14, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG15, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG16, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG17, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG18, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG19, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG20, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG21, DSCC, id), \ + SRI_ARR(DSCC_PPS_CONFIG22, DSCC, id), \ + SRI_ARR(DSCC_MEM_POWER_CONTROL, DSCC, id), \ + SRI_ARR(DSCC_R_Y_SQUARED_ERROR_LOWER, DSCC, id), \ + SRI_ARR(DSCC_R_Y_SQUARED_ERROR_UPPER, DSCC, id), \ + SRI_ARR(DSCC_G_CB_SQUARED_ERROR_LOWER, DSCC, id), \ + SRI_ARR(DSCC_G_CB_SQUARED_ERROR_UPPER, DSCC, id), \ + SRI_ARR(DSCC_B_CR_SQUARED_ERROR_LOWER, DSCC, id), \ + SRI_ARR(DSCC_B_CR_SQUARED_ERROR_UPPER, DSCC, id), \ + SRI_ARR(DSCC_MAX_ABS_ERROR0, DSCC, id), \ + SRI_ARR(DSCC_MAX_ABS_ERROR1, DSCC, id), \ + SRI_ARR(DSCC_RATE_BUFFER0_MAX_FULLNESS_LEVEL, DSCC, id), \ + SRI_ARR(DSCC_RATE_BUFFER1_MAX_FULLNESS_LEVEL, DSCC, id), \ + SRI_ARR(DSCC_RATE_BUFFER2_MAX_FULLNESS_LEVEL, DSCC, id), \ + SRI_ARR(DSCC_RATE_BUFFER3_MAX_FULLNESS_LEVEL, DSCC, id), \ + SRI_ARR(DSCC_RATE_CONTROL_BUFFER0_MAX_FULLNESS_LEVEL, DSCC, id), \ + SRI_ARR(DSCC_RATE_CONTROL_BUFFER1_MAX_FULLNESS_LEVEL, DSCC, id), \ + SRI_ARR(DSCC_RATE_CONTROL_BUFFER2_MAX_FULLNESS_LEVEL, DSCC, id), \ + SRI_ARR(DSCC_RATE_CONTROL_BUFFER3_MAX_FULLNESS_LEVEL, DSCC, id), \ + SRI_ARR(DSCCIF_CONFIG0, DSCCIF, id), \ + SRI_ARR(DSCCIF_CONFIG1, DSCCIF, id), \ + SRI_ARR(DSCRM_DSC_FORWARD_CONFIG, DSCRM, id) \ + ) + +/* MPC */ + +#define MPC_DWB_MUX_REG_LIST_DCN3_0_RI(inst) \ + SRII_DWB(DWB_MUX, MUX, MPC_DWB, inst) + +#define MPC_MCM_REG_LIST_DCN32_RI(inst) \ + ( \ + SRII(MPCC_MCM_SHAPER_CONTROL, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_OFFSET_R, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_OFFSET_G, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_OFFSET_B, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_SCALE_R, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_SCALE_G_B, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_LUT_INDEX, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_LUT_DATA, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_START_CNTL_B, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_START_CNTL_G, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_START_CNTL_R, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_END_CNTL_B, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_END_CNTL_G, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_END_CNTL_R, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_0_1, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_2_3, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_4_5, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_6_7, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_8_9, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_10_11, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_12_13, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_14_15, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_16_17, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_18_19, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_20_21, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_22_23, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_24_25, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_26_27, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_28_29, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_30_31, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMA_REGION_32_33, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_START_CNTL_B, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_START_CNTL_G, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_START_CNTL_R, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_END_CNTL_B, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_END_CNTL_G, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_END_CNTL_R, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_0_1, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_2_3, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_4_5, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_6_7, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_8_9, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_10_11, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_12_13, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_14_15, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_16_17, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_18_19, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_20_21, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_22_23, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_24_25, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_26_27, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_28_29, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_30_31, MPCC_MCM, inst), \ + SRII(MPCC_MCM_SHAPER_RAMB_REGION_32_33, MPCC_MCM, inst), \ + SRII(MPCC_MCM_3DLUT_MODE, MPCC_MCM, inst), \ + SRII(MPCC_MCM_3DLUT_INDEX, MPCC_MCM, inst), \ + SRII(MPCC_MCM_3DLUT_DATA, MPCC_MCM, inst), \ + SRII(MPCC_MCM_3DLUT_DATA_30BIT, MPCC_MCM, inst), \ + SRII(MPCC_MCM_3DLUT_READ_WRITE_CONTROL, MPCC_MCM, inst), \ + SRII(MPCC_MCM_3DLUT_OUT_NORM_FACTOR, MPCC_MCM, inst), \ + SRII(MPCC_MCM_3DLUT_OUT_OFFSET_R, MPCC_MCM, inst), \ + SRII(MPCC_MCM_3DLUT_OUT_OFFSET_G, MPCC_MCM, inst), \ + SRII(MPCC_MCM_3DLUT_OUT_OFFSET_B, MPCC_MCM, inst), \ + SRII(MPCC_MCM_MEM_PWR_CTRL, MPCC_MCM, inst) \ + ) + +#define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0_RI(inst) \ + ( \ + SRII(MUX, MPC_OUT, inst), VUPDATE_SRII(CUR, VUPDATE_LOCK_SET, inst) \ + ) + +#define MPC_OUT_MUX_REG_LIST_DCN3_0_RI(inst) \ + ( \ + MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0_RI(inst), SRII(CSC_MODE, MPC_OUT, inst), \ + SRII(CSC_C11_C12_A, MPC_OUT, inst), SRII(CSC_C33_C34_A, MPC_OUT, inst), \ + SRII(CSC_C11_C12_B, MPC_OUT, inst), SRII(CSC_C33_C34_B, MPC_OUT, inst), \ + SRII(DENORM_CONTROL, MPC_OUT, inst), \ + SRII(DENORM_CLAMP_G_Y, MPC_OUT, inst), \ + SRII(DENORM_CLAMP_B_CB, MPC_OUT, inst), SR(MPC_OUT_CSC_COEF_FORMAT) \ + ) + +#define MPC_COMMON_REG_LIST_DCN1_0_RI(inst) \ + ( \ + SRII(MPCC_TOP_SEL, MPCC, inst), SRII(MPCC_BOT_SEL, MPCC, inst), \ + SRII(MPCC_CONTROL, MPCC, inst), SRII(MPCC_STATUS, MPCC, inst), \ + SRII(MPCC_OPP_ID, MPCC, inst), SRII(MPCC_BG_G_Y, MPCC, inst), \ + SRII(MPCC_BG_R_CR, MPCC, inst), SRII(MPCC_BG_B_CB, MPCC, inst), \ + SRII(MPCC_SM_CONTROL, MPCC, inst), \ + SRII(MPCC_UPDATE_LOCK_SEL, MPCC, inst) \ + ) + +#define MPC_REG_LIST_DCN3_0_RI(inst) \ + ( \ + MPC_COMMON_REG_LIST_DCN1_0_RI(inst), SRII(MPCC_TOP_GAIN, MPCC, inst), \ + SRII(MPCC_BOT_GAIN_INSIDE, MPCC, inst), \ + SRII(MPCC_BOT_GAIN_OUTSIDE, MPCC, inst), \ + SRII(MPCC_MEM_PWR_CTRL, MPCC, inst), \ + SRII(MPCC_OGAM_LUT_INDEX, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_LUT_DATA, MPCC_OGAM, inst), \ + SRII(MPCC_GAMUT_REMAP_COEF_FORMAT, MPCC_OGAM, inst), \ + SRII(MPCC_GAMUT_REMAP_MODE, MPCC_OGAM, inst), \ + SRII(MPC_GAMUT_REMAP_C11_C12_A, MPCC_OGAM, inst), \ + SRII(MPC_GAMUT_REMAP_C33_C34_A, MPCC_OGAM, inst), \ + SRII(MPC_GAMUT_REMAP_C11_C12_B, MPCC_OGAM, inst), \ + SRII(MPC_GAMUT_REMAP_C33_C34_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_START_CNTL_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_START_CNTL_G, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_START_CNTL_R, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_START_SLOPE_CNTL_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_START_SLOPE_CNTL_G, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_START_SLOPE_CNTL_R, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_END_CNTL1_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_END_CNTL2_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_END_CNTL1_G, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_END_CNTL2_G, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_END_CNTL1_R, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_END_CNTL2_R, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_REGION_0_1, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_REGION_32_33, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_OFFSET_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_OFFSET_G, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_OFFSET_R, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_START_BASE_CNTL_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_START_BASE_CNTL_G, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMA_START_BASE_CNTL_R, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_START_CNTL_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_START_CNTL_G, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_START_CNTL_R, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_START_SLOPE_CNTL_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_START_SLOPE_CNTL_G, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_START_SLOPE_CNTL_R, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_END_CNTL1_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_END_CNTL2_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_END_CNTL1_G, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_END_CNTL2_G, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_END_CNTL1_R, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_END_CNTL2_R, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_REGION_0_1, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_REGION_32_33, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_OFFSET_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_OFFSET_G, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_OFFSET_R, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_START_BASE_CNTL_B, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_START_BASE_CNTL_G, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_RAMB_START_BASE_CNTL_R, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_CONTROL, MPCC_OGAM, inst), \ + SRII(MPCC_OGAM_LUT_CONTROL, MPCC_OGAM, inst) \ + ) + +/* OPTC */ + +#define OPTC_COMMON_REG_LIST_DCN3_2_RI(inst) \ + ( \ + SRI_ARR(OTG_VSTARTUP_PARAM, OTG, inst), \ + SRI_ARR(OTG_VUPDATE_PARAM, OTG, inst), \ + SRI_ARR(OTG_VREADY_PARAM, OTG, inst), \ + SRI_ARR(OTG_MASTER_UPDATE_LOCK, OTG, inst), \ + SRI_ARR(OTG_GLOBAL_CONTROL0, OTG, inst), \ + SRI_ARR(OTG_GLOBAL_CONTROL1, OTG, inst), \ + SRI_ARR(OTG_GLOBAL_CONTROL2, OTG, inst), \ + SRI_ARR(OTG_GLOBAL_CONTROL4, OTG, inst), \ + SRI_ARR(OTG_DOUBLE_BUFFER_CONTROL, OTG, inst), \ + SRI_ARR(OTG_H_TOTAL, OTG, inst), \ + SRI_ARR(OTG_H_BLANK_START_END, OTG, inst), \ + SRI_ARR(OTG_H_SYNC_A, OTG, inst), SRI_ARR(OTG_H_SYNC_A_CNTL, OTG, inst), \ + SRI_ARR(OTG_H_TIMING_CNTL, OTG, inst), SRI_ARR(OTG_V_TOTAL, OTG, inst), \ + SRI_ARR(OTG_V_BLANK_START_END, OTG, inst), \ + SRI_ARR(OTG_V_SYNC_A, OTG, inst), SRI_ARR(OTG_V_SYNC_A_CNTL, OTG, inst), \ + SRI_ARR(OTG_CONTROL, OTG, inst), SRI_ARR(OTG_STEREO_CONTROL, OTG, inst), \ + SRI_ARR(OTG_3D_STRUCTURE_CONTROL, OTG, inst), \ + SRI_ARR(OTG_STEREO_STATUS, OTG, inst), \ + SRI_ARR(OTG_V_TOTAL_MAX, OTG, inst), \ + SRI_ARR(OTG_V_TOTAL_MIN, OTG, inst), \ + SRI_ARR(OTG_V_TOTAL_CONTROL, OTG, inst), \ + SRI_ARR(OTG_TRIGA_CNTL, OTG, inst), \ + SRI_ARR(OTG_FORCE_COUNT_NOW_CNTL, OTG, inst), \ + SRI_ARR(OTG_STATIC_SCREEN_CONTROL, OTG, inst), \ + SRI_ARR(OTG_STATUS_FRAME_COUNT, OTG, inst), \ + SRI_ARR(OTG_STATUS, OTG, inst), SRI_ARR(OTG_STATUS_POSITION, OTG, inst), \ + SRI_ARR(OTG_NOM_VERT_POSITION, OTG, inst), \ + SRI_ARR(OTG_M_CONST_DTO0, OTG, inst), \ + SRI_ARR(OTG_M_CONST_DTO1, OTG, inst), \ + SRI_ARR(OTG_CLOCK_CONTROL, OTG, inst), \ + SRI_ARR(OTG_VERTICAL_INTERRUPT0_CONTROL, OTG, inst), \ + SRI_ARR(OTG_VERTICAL_INTERRUPT0_POSITION, OTG, inst), \ + SRI_ARR(OTG_VERTICAL_INTERRUPT1_CONTROL, OTG, inst), \ + SRI_ARR(OTG_VERTICAL_INTERRUPT1_POSITION, OTG, inst), \ + SRI_ARR(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst), \ + SRI_ARR(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst), \ + SRI_ARR(OPTC_INPUT_CLOCK_CONTROL, ODM, inst), \ + SRI_ARR(OPTC_DATA_SOURCE_SELECT, ODM, inst), \ + SRI_ARR(OPTC_INPUT_GLOBAL_CONTROL, ODM, inst), \ + SRI_ARR(CONTROL, VTG, inst), SRI_ARR(OTG_VERT_SYNC_CONTROL, OTG, inst), \ + SRI_ARR(OTG_GSL_CONTROL, OTG, inst), SRI_ARR(OTG_CRC_CNTL, OTG, inst), \ + SRI_ARR(OTG_CRC0_DATA_RG, OTG, inst), \ + SRI_ARR(OTG_CRC0_DATA_B, OTG, inst), \ + SRI_ARR(OTG_CRC0_WINDOWA_X_CONTROL, OTG, inst), \ + SRI_ARR(OTG_CRC0_WINDOWA_Y_CONTROL, OTG, inst), \ + SRI_ARR(OTG_CRC0_WINDOWB_X_CONTROL, OTG, inst), \ + SRI_ARR(OTG_CRC0_WINDOWB_Y_CONTROL, OTG, inst), \ + SR_ARR(GSL_SOURCE_SELECT, inst), \ + SRI_ARR(OTG_TRIGA_MANUAL_TRIG, OTG, inst), \ + SRI_ARR(OTG_GLOBAL_CONTROL1, OTG, inst), \ + SRI_ARR(OTG_GLOBAL_CONTROL2, OTG, inst), \ + SRI_ARR(OTG_GSL_WINDOW_X, OTG, inst), \ + SRI_ARR(OTG_GSL_WINDOW_Y, OTG, inst), \ + SRI_ARR(OTG_VUPDATE_KEEPOUT, OTG, inst), \ + SRI_ARR(OTG_DSC_START_POSITION, OTG, inst), \ + SRI_ARR(OTG_DRR_TRIGGER_WINDOW, OTG, inst), \ + SRI_ARR(OTG_DRR_V_TOTAL_CHANGE, OTG, inst), \ + SRI_ARR(OPTC_DATA_FORMAT_CONTROL, ODM, inst), \ + SRI_ARR(OPTC_BYTES_PER_PIXEL, ODM, inst), \ + SRI_ARR(OPTC_WIDTH_CONTROL, ODM, inst), \ + SRI_ARR(OPTC_MEMORY_CONFIG, ODM, inst), \ + SRI_ARR(OTG_DRR_CONTROL, OTG, inst) \ + ) + +/* HUBP */ + +#define HUBP_REG_LIST_DCN_VM_RI(id) \ + ( \ + SRI_ARR(NOM_PARAMETERS_0, HUBPREQ, id), \ + SRI_ARR(NOM_PARAMETERS_1, HUBPREQ, id), \ + SRI_ARR(NOM_PARAMETERS_2, HUBPREQ, id), \ + SRI_ARR(NOM_PARAMETERS_3, HUBPREQ, id), \ + SRI_ARR(DCN_VM_MX_L1_TLB_CNTL, HUBPREQ, id) \ + ) + +#define HUBP_REG_LIST_DCN_RI(id) \ + ( \ + SRI_ARR(DCHUBP_CNTL, HUBP, id), SRI_ARR(HUBPREQ_DEBUG_DB, HUBP, id), \ + SRI_ARR(HUBPREQ_DEBUG, HUBP, id), SRI_ARR(DCSURF_ADDR_CONFIG, HUBP, id), \ + SRI_ARR(DCSURF_TILING_CONFIG, HUBP, id), \ + SRI_ARR(DCSURF_SURFACE_PITCH, HUBPREQ, id), \ + SRI_ARR(DCSURF_SURFACE_PITCH_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_SURFACE_CONFIG, HUBP, id), \ + SRI_ARR(DCSURF_FLIP_CONTROL, HUBPREQ, id), \ + SRI_ARR(DCSURF_PRI_VIEWPORT_DIMENSION, HUBP, id), \ + SRI_ARR(DCSURF_PRI_VIEWPORT_START, HUBP, id), \ + SRI_ARR(DCSURF_SEC_VIEWPORT_DIMENSION, HUBP, id), \ + SRI_ARR(DCSURF_SEC_VIEWPORT_START, HUBP, id), \ + SRI_ARR(DCSURF_PRI_VIEWPORT_DIMENSION_C, HUBP, id), \ + SRI_ARR(DCSURF_PRI_VIEWPORT_START_C, HUBP, id), \ + SRI_ARR(DCSURF_SEC_VIEWPORT_DIMENSION_C, HUBP, id), \ + SRI_ARR(DCSURF_SEC_VIEWPORT_START_C, HUBP, id), \ + SRI_ARR(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, HUBPREQ, id), \ + SRI_ARR(DCSURF_PRIMARY_SURFACE_ADDRESS, HUBPREQ, id), \ + SRI_ARR(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, HUBPREQ, id), \ + SRI_ARR(DCSURF_SECONDARY_SURFACE_ADDRESS, HUBPREQ, id), \ + SRI_ARR(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, HUBPREQ, id), \ + SRI_ARR(DCSURF_PRIMARY_META_SURFACE_ADDRESS, HUBPREQ, id), \ + SRI_ARR(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, HUBPREQ, id), \ + SRI_ARR(DCSURF_SECONDARY_META_SURFACE_ADDRESS, HUBPREQ, id), \ + SRI_ARR(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_PRIMARY_SURFACE_ADDRESS_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_SECONDARY_SURFACE_ADDRESS_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_SECONDARY_META_SURFACE_ADDRESS_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_SURFACE_INUSE, HUBPREQ, id), \ + SRI_ARR(DCSURF_SURFACE_INUSE_HIGH, HUBPREQ, id), \ + SRI_ARR(DCSURF_SURFACE_INUSE_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_SURFACE_INUSE_HIGH_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_SURFACE_EARLIEST_INUSE, HUBPREQ, id), \ + SRI_ARR(DCSURF_SURFACE_EARLIEST_INUSE_HIGH, HUBPREQ, id), \ + SRI_ARR(DCSURF_SURFACE_EARLIEST_INUSE_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C, HUBPREQ, id), \ + SRI_ARR(DCSURF_SURFACE_CONTROL, HUBPREQ, id), \ + SRI_ARR(DCSURF_SURFACE_FLIP_INTERRUPT, HUBPREQ, id), \ + SRI_ARR(HUBPRET_CONTROL, HUBPRET, id), \ + SRI_ARR(HUBPRET_READ_LINE_STATUS, HUBPRET, id), \ + SRI_ARR(DCN_EXPANSION_MODE, HUBPREQ, id), \ + SRI_ARR(DCHUBP_REQ_SIZE_CONFIG, HUBP, id), \ + SRI_ARR(DCHUBP_REQ_SIZE_CONFIG_C, HUBP, id), \ + SRI_ARR(BLANK_OFFSET_0, HUBPREQ, id), \ + SRI_ARR(BLANK_OFFSET_1, HUBPREQ, id), \ + SRI_ARR(DST_DIMENSIONS, HUBPREQ, id), \ + SRI_ARR(DST_AFTER_SCALER, HUBPREQ, id), \ + SRI_ARR(VBLANK_PARAMETERS_0, HUBPREQ, id), \ + SRI_ARR(REF_FREQ_TO_PIX_FREQ, HUBPREQ, id), \ + SRI_ARR(VBLANK_PARAMETERS_1, HUBPREQ, id), \ + SRI_ARR(VBLANK_PARAMETERS_3, HUBPREQ, id), \ + SRI_ARR(NOM_PARAMETERS_4, HUBPREQ, id), \ + SRI_ARR(NOM_PARAMETERS_5, HUBPREQ, id), \ + SRI_ARR(PER_LINE_DELIVERY_PRE, HUBPREQ, id), \ + SRI_ARR(PER_LINE_DELIVERY, HUBPREQ, id), \ + SRI_ARR(VBLANK_PARAMETERS_2, HUBPREQ, id), \ + SRI_ARR(VBLANK_PARAMETERS_4, HUBPREQ, id), \ + SRI_ARR(NOM_PARAMETERS_6, HUBPREQ, id), \ + SRI_ARR(NOM_PARAMETERS_7, HUBPREQ, id), \ + SRI_ARR(DCN_TTU_QOS_WM, HUBPREQ, id), \ + SRI_ARR(DCN_GLOBAL_TTU_CNTL, HUBPREQ, id), \ + SRI_ARR(DCN_SURF0_TTU_CNTL0, HUBPREQ, id), \ + SRI_ARR(DCN_SURF0_TTU_CNTL1, HUBPREQ, id), \ + SRI_ARR(DCN_SURF1_TTU_CNTL0, HUBPREQ, id), \ + SRI_ARR(DCN_SURF1_TTU_CNTL1, HUBPREQ, id), \ + SRI_ARR(DCN_CUR0_TTU_CNTL0, HUBPREQ, id), \ + SRI_ARR(DCN_CUR0_TTU_CNTL1, HUBPREQ, id), \ + SRI_ARR(HUBP_CLK_CNTL, HUBP, id) \ + ) + +#define HUBP_REG_LIST_DCN2_COMMON_RI(id) \ + ( \ + HUBP_REG_LIST_DCN_RI(id), HUBP_REG_LIST_DCN_VM_RI(id), \ + SRI_ARR(PREFETCH_SETTINGS, HUBPREQ, id), \ + SRI_ARR(PREFETCH_SETTINGS_C, HUBPREQ, id), \ + SRI_ARR(DCN_VM_SYSTEM_APERTURE_LOW_ADDR, HUBPREQ, id), \ + SRI_ARR(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR, HUBPREQ, id), \ + SRI_ARR(CURSOR_SETTINGS, HUBPREQ, id), \ + SRI_ARR(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR0_, id), \ + SRI_ARR(CURSOR_SURFACE_ADDRESS, CURSOR0_, id), \ + SRI_ARR(CURSOR_SIZE, CURSOR0_, id), \ + SRI_ARR(CURSOR_CONTROL, CURSOR0_, id), \ + SRI_ARR(CURSOR_POSITION, CURSOR0_, id), \ + SRI_ARR(CURSOR_HOT_SPOT, CURSOR0_, id), \ + SRI_ARR(CURSOR_DST_OFFSET, CURSOR0_, id), \ + SRI_ARR(DMDATA_ADDRESS_HIGH, CURSOR0_, id), \ + SRI_ARR(DMDATA_ADDRESS_LOW, CURSOR0_, id), \ + SRI_ARR(DMDATA_CNTL, CURSOR0_, id), \ + SRI_ARR(DMDATA_SW_CNTL, CURSOR0_, id), \ + SRI_ARR(DMDATA_QOS_CNTL, CURSOR0_, id), \ + SRI_ARR(DMDATA_SW_DATA, CURSOR0_, id), \ + SRI_ARR(DMDATA_STATUS, CURSOR0_, id), \ + SRI_ARR(FLIP_PARAMETERS_0, HUBPREQ, id), \ + SRI_ARR(FLIP_PARAMETERS_1, HUBPREQ, id), \ + SRI_ARR(FLIP_PARAMETERS_2, HUBPREQ, id), \ + SRI_ARR(DCN_CUR1_TTU_CNTL0, HUBPREQ, id), \ + SRI_ARR(DCN_CUR1_TTU_CNTL1, HUBPREQ, id), \ + SRI_ARR(DCSURF_FLIP_CONTROL2, HUBPREQ, id), \ + SRI_ARR(VMID_SETTINGS_0, HUBPREQ, id) \ + ) + +#define HUBP_REG_LIST_DCN21_RI(id) \ + ( \ + HUBP_REG_LIST_DCN2_COMMON_RI(id), SRI_ARR(FLIP_PARAMETERS_3, HUBPREQ, id), \ + SRI_ARR(FLIP_PARAMETERS_4, HUBPREQ, id), \ + SRI_ARR(FLIP_PARAMETERS_5, HUBPREQ, id), \ + SRI_ARR(FLIP_PARAMETERS_6, HUBPREQ, id), \ + SRI_ARR(VBLANK_PARAMETERS_5, HUBPREQ, id), \ + SRI_ARR(VBLANK_PARAMETERS_6, HUBPREQ, id) \ + ) + +#define HUBP_REG_LIST_DCN30_RI(id) \ + ( \ + HUBP_REG_LIST_DCN21_RI(id), SRI_ARR(DCN_DMDATA_VM_CNTL, HUBPREQ, id) \ + ) + +#define HUBP_REG_LIST_DCN32_RI(id) \ + ( \ + HUBP_REG_LIST_DCN30_RI(id), SRI_ARR(DCHUBP_MALL_CONFIG, HUBP, id), \ + SRI_ARR(DCHUBP_VMPG_CONFIG, HUBP, id), \ + SRI_ARR(UCLK_PSTATE_FORCE, HUBPREQ, id) \ + ) + +/* HUBBUB */ + +#define HUBBUB_REG_LIST_DCN32_RI(id) \ + ( \ + SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A), \ + SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B), \ + SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C), \ + SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D), \ + SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL), \ + SR(DCHUBBUB_ARB_DRAM_STATE_CNTL), SR(DCHUBBUB_ARB_SAT_LEVEL), \ + SR(DCHUBBUB_ARB_DF_REQ_OUTSTAND), SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ + SR(DCHUBBUB_SOFT_RESET), SR(DCHUBBUB_CRC_CTRL), \ + SR(DCN_VM_FB_LOCATION_BASE), SR(DCN_VM_FB_LOCATION_TOP), \ + SR(DCN_VM_FB_OFFSET), SR(DCN_VM_AGP_BOT), SR(DCN_VM_AGP_TOP), \ + SR(DCN_VM_AGP_BASE), HUBBUB_SR_WATERMARK_REG_LIST(), \ + SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A), SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B), \ + SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C), SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D), \ + SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A), \ + SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B), \ + SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C), \ + SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D), \ + SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A), \ + SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B), \ + SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C), \ + SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D), SR(DCHUBBUB_DET0_CTRL), \ + SR(DCHUBBUB_DET1_CTRL), SR(DCHUBBUB_DET2_CTRL), SR(DCHUBBUB_DET3_CTRL), \ + SR(DCHUBBUB_COMPBUF_CTRL), SR(COMPBUF_RESERVED_SPACE), \ + SR(DCHUBBUB_ARB_USR_RETRAINING_CNTL), \ + SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A), \ + SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B), \ + SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C), \ + SR(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D), \ + SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A), \ + SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B), \ + SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C), \ + SR(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D), \ + SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A), \ + SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B), \ + SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C), \ + SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D), \ + SR(DCN_VM_FAULT_ADDR_MSB), SR(DCN_VM_FAULT_ADDR_LSB), \ + SR(DCN_VM_FAULT_CNTL), SR(DCN_VM_FAULT_STATUS) \ + ) + +/* DCCG */ + +#define DCCG_REG_LIST_DCN32_RI() \ + ( \ + SR(DPPCLK_DTO_CTRL), DCCG_SRII(DTO_PARAM, DPPCLK, 0), \ + DCCG_SRII(DTO_PARAM, DPPCLK, 1), DCCG_SRII(DTO_PARAM, DPPCLK, 2), \ + DCCG_SRII(DTO_PARAM, DPPCLK, 3), DCCG_SRII(CLOCK_CNTL, HDMICHARCLK, 0), \ + SR(PHYASYMCLK_CLOCK_CNTL), SR(PHYBSYMCLK_CLOCK_CNTL), \ + SR(PHYCSYMCLK_CLOCK_CNTL), SR(PHYDSYMCLK_CLOCK_CNTL), \ + SR(PHYESYMCLK_CLOCK_CNTL), SR(DPSTREAMCLK_CNTL), SR(HDMISTREAMCLK_CNTL), \ + SR(SYMCLK32_SE_CNTL), SR(SYMCLK32_LE_CNTL), \ + DCCG_SRII(PIXEL_RATE_CNTL, OTG, 0), DCCG_SRII(PIXEL_RATE_CNTL, OTG, 1), \ + DCCG_SRII(PIXEL_RATE_CNTL, OTG, 2), DCCG_SRII(PIXEL_RATE_CNTL, OTG, 3), \ + DCCG_SRII(MODULO, DTBCLK_DTO, 0), DCCG_SRII(MODULO, DTBCLK_DTO, 1), \ + DCCG_SRII(MODULO, DTBCLK_DTO, 2), DCCG_SRII(MODULO, DTBCLK_DTO, 3), \ + DCCG_SRII(PHASE, DTBCLK_DTO, 0), DCCG_SRII(PHASE, DTBCLK_DTO, 1), \ + DCCG_SRII(PHASE, DTBCLK_DTO, 2), DCCG_SRII(PHASE, DTBCLK_DTO, 3), \ + SR(DCCG_AUDIO_DTBCLK_DTO_MODULO), SR(DCCG_AUDIO_DTBCLK_DTO_PHASE), \ + SR(OTG_PIXEL_RATE_DIV), SR(DTBCLK_P_CNTL), SR(DCCG_AUDIO_DTO_SOURCE) \ + ) + +/* VMID */ +#define DCN20_VMID_REG_LIST_RI(id) \ + ( \ + SRI_ARR(CNTL, DCN_VM_CONTEXT, id), \ + SRI_ARR(PAGE_TABLE_BASE_ADDR_HI32, DCN_VM_CONTEXT, id), \ + SRI_ARR(PAGE_TABLE_BASE_ADDR_LO32, DCN_VM_CONTEXT, id), \ + SRI_ARR(PAGE_TABLE_START_ADDR_HI32, DCN_VM_CONTEXT, id), \ + SRI_ARR(PAGE_TABLE_START_ADDR_LO32, DCN_VM_CONTEXT, id), \ + SRI_ARR(PAGE_TABLE_END_ADDR_HI32, DCN_VM_CONTEXT, id), \ + SRI_ARR(PAGE_TABLE_END_ADDR_LO32, DCN_VM_CONTEXT, id) \ + ) + +/* I2C HW */ + +#define I2C_HW_ENGINE_COMMON_REG_LIST_RI(id) \ + ( \ + SRI_ARR(SETUP, DC_I2C_DDC, id), SRI_ARR(SPEED, DC_I2C_DDC, id), \ + SRI_ARR(HW_STATUS, DC_I2C_DDC, id), SR_ARR(DC_I2C_ARBITRATION, id), \ + SR_ARR(DC_I2C_CONTROL, id), SR_ARR(DC_I2C_SW_STATUS, id), \ + SR_ARR(DC_I2C_TRANSACTION0, id), SR_ARR(DC_I2C_TRANSACTION1, id), \ + SR_ARR(DC_I2C_TRANSACTION2, id), SR_ARR(DC_I2C_TRANSACTION3, id), \ + SR_ARR(DC_I2C_DATA, id), SR_ARR(MICROSECOND_TIME_BASE_DIV, id) \ + ) + +#define I2C_HW_ENGINE_COMMON_REG_LIST_DCN30_RI(id) \ + ( \ + I2C_HW_ENGINE_COMMON_REG_LIST_RI(id), SR_ARR(DIO_MEM_PWR_CTRL, id), \ + SR_ARR(DIO_MEM_PWR_STATUS, id) \ + ) + #endif /* _DCN32_RESOURCE_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c index 955f52e6064d..ab918fe38f6a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c @@ -144,7 +144,7 @@ bool dcn32_all_pipes_have_stream_and_plane(struct dc *dc, struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; if (!pipe->stream) - continue; + return false; if (!pipe->plane_state) return false; diff --git a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c index c8b7d6ff38f4..a93dc00ebfb5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -138,78 +138,95 @@ enum dcn321_clk_src_array_id { /* DCN */ /* TODO awful hack. fixup dcn20_dwb.h */ #undef BASE_INNER -#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg +#define BASE_INNER(seg) ctx->dcn_reg_offsets[seg] #define BASE(seg) BASE_INNER(seg) #define SR(reg_name)\ - .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ - reg ## reg_name + REG_STRUCT.reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ + reg ## reg_name +#define SR_ARR(reg_name, id)\ + REG_STRUCT[id].reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ + reg ## reg_name +#define SR_ARR_INIT(reg_name, id, value)\ + REG_STRUCT[id].reg_name = value #define SRI(reg_name, block, id)\ - .reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ - reg ## block ## id ## _ ## reg_name + REG_STRUCT.reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRI_ARR(reg_name, block, id)\ + REG_STRUCT[id].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRI_ARR_ALPHABET(reg_name, block, index, id)\ + REG_STRUCT[index].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name #define SRI2(reg_name, block, id)\ .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ - reg ## reg_name + reg ## reg_name +#define SRI2_ARR(reg_name, block, id)\ + REG_STRUCT[id].reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ + reg ## reg_name #define SRIR(var_name, reg_name, block, id)\ .var_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ - reg ## block ## id ## _ ## reg_name + reg ## block ## id ## _ ## reg_name #define SRII(reg_name, block, id)\ - .reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ - reg ## block ## id ## _ ## reg_name + REG_STRUCT.reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name + +#define SRII_ARR_2(reg_name, block, id, inst)\ + REG_STRUCT[inst].reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name #define SRII_MPC_RMU(reg_name, block, id)\ .RMU##_##reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ - reg ## block ## id ## _ ## reg_name + reg ## block ## id ## _ ## reg_name #define SRII_DWB(reg_name, temp_name, block, id)\ - .reg_name[id] = BASE(reg ## block ## id ## _ ## temp_name ## _BASE_IDX) + \ - reg ## block ## id ## _ ## temp_name + REG_STRUCT.reg_name[id] = BASE(reg ## block ## id ## _ ## temp_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## temp_name #define DCCG_SRII(reg_name, block, id)\ - .block ## _ ## reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ - reg ## block ## id ## _ ## reg_name + REG_STRUCT.block ## _ ## reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + reg ## block ## id ## _ ## reg_name #define VUPDATE_SRII(reg_name, block, id)\ - .reg_name[id] = BASE(reg ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ - reg ## reg_name ## _ ## block ## id + REG_STRUCT.reg_name[id] = BASE(reg ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ + reg ## reg_name ## _ ## block ## id /* NBIO */ -#define NBIO_BASE_INNER(seg) \ - NBIO_BASE__INST0_SEG ## seg +#define NBIO_BASE_INNER(seg) ctx->nbio_reg_offsets[seg] #define NBIO_BASE(seg) \ NBIO_BASE_INNER(seg) #define NBIO_SR(reg_name)\ - .reg_name = NBIO_BASE(regBIF_BX0_ ## reg_name ## _BASE_IDX) + \ - regBIF_BX0_ ## reg_name + REG_STRUCT.reg_name = NBIO_BASE(regBIF_BX0_ ## reg_name ## _BASE_IDX) + \ + regBIF_BX0_ ## reg_name +#define NBIO_SR_ARR(reg_name, id)\ + REG_STRUCT[id].reg_name = NBIO_BASE(regBIF_BX0_ ## reg_name ## _BASE_IDX) + \ + regBIF_BX0_ ## reg_name #define CTX ctx #define REG(reg_name) \ - (DCN_BASE.instance[0].segment[reg ## reg_name ## _BASE_IDX] + reg ## reg_name) + (ctx->dcn_reg_offsets[reg ## reg_name ## _BASE_IDX] + reg ## reg_name) -static const struct bios_registers bios_regs = { - NBIO_SR(BIOS_SCRATCH_3), - NBIO_SR(BIOS_SCRATCH_6) -}; +static struct bios_registers bios_regs; -#define clk_src_regs(index, pllid)\ -[index] = {\ - CS_COMMON_REG_LIST_DCN3_0(index, pllid),\ -} +#define bios_regs_init() \ + ( \ + NBIO_SR(BIOS_SCRATCH_3),\ + NBIO_SR(BIOS_SCRATCH_6)\ + ) -static const struct dce110_clk_src_regs clk_src_regs[] = { - clk_src_regs(0, A), - clk_src_regs(1, B), - clk_src_regs(2, C), - clk_src_regs(3, D), - clk_src_regs(4, E) -}; +#define clk_src_regs_init(index, pllid)\ + CS_COMMON_REG_LIST_DCN3_0_RI(index, pllid) + +static struct dce110_clk_src_regs clk_src_regs[5]; static const struct dce110_clk_src_shift cs_shift = { CS_COMMON_MASK_SH_LIST_DCN3_2(__SHIFT) @@ -219,17 +236,10 @@ static const struct dce110_clk_src_mask cs_mask = { CS_COMMON_MASK_SH_LIST_DCN3_2(_MASK) }; -#define abm_regs(id)\ -[id] = {\ - ABM_DCN32_REG_LIST(id)\ -} +#define abm_regs_init(id)\ + ABM_DCN32_REG_LIST_RI(id) -static const struct dce_abm_registers abm_regs[] = { - abm_regs(0), - abm_regs(1), - abm_regs(2), - abm_regs(3), -}; +static struct dce_abm_registers abm_regs[4]; static const struct dce_abm_shift abm_shift = { ABM_MASK_SH_LIST_DCN32(__SHIFT) @@ -239,18 +249,10 @@ static const struct dce_abm_mask abm_mask = { ABM_MASK_SH_LIST_DCN32(_MASK) }; -#define audio_regs(id)\ -[id] = {\ - AUD_COMMON_REG_LIST(id)\ -} +#define audio_regs_init(id)\ + AUD_COMMON_REG_LIST_RI(id) -static const struct dce_audio_registers audio_regs[] = { - audio_regs(0), - audio_regs(1), - audio_regs(2), - audio_regs(3), - audio_regs(4) -}; +static struct dce_audio_registers audio_regs[5]; #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\ @@ -265,23 +267,10 @@ static const struct dce_audio_mask audio_mask = { DCE120_AUD_COMMON_MASK_SH_LIST(_MASK) }; -#define vpg_regs(id)\ -[id] = {\ - VPG_DCN3_REG_LIST(id)\ -} +#define vpg_regs_init(id)\ + VPG_DCN3_REG_LIST_RI(id) -static const struct dcn30_vpg_registers vpg_regs[] = { - vpg_regs(0), - vpg_regs(1), - vpg_regs(2), - vpg_regs(3), - vpg_regs(4), - vpg_regs(5), - vpg_regs(6), - vpg_regs(7), - vpg_regs(8), - vpg_regs(9), -}; +static struct dcn30_vpg_registers vpg_regs[10]; static const struct dcn30_vpg_shift vpg_shift = { DCN3_VPG_MASK_SH_LIST(__SHIFT) @@ -291,19 +280,10 @@ static const struct dcn30_vpg_mask vpg_mask = { DCN3_VPG_MASK_SH_LIST(_MASK) }; -#define afmt_regs(id)\ -[id] = {\ - AFMT_DCN3_REG_LIST(id)\ -} +#define afmt_regs_init(id)\ + AFMT_DCN3_REG_LIST_RI(id) -static const struct dcn30_afmt_registers afmt_regs[] = { - afmt_regs(0), - afmt_regs(1), - afmt_regs(2), - afmt_regs(3), - afmt_regs(4), - afmt_regs(5) -}; +static struct dcn30_afmt_registers afmt_regs[6]; static const struct dcn30_afmt_shift afmt_shift = { DCN3_AFMT_MASK_SH_LIST(__SHIFT) @@ -313,17 +293,10 @@ static const struct dcn30_afmt_mask afmt_mask = { DCN3_AFMT_MASK_SH_LIST(_MASK) }; -#define apg_regs(id)\ -[id] = {\ - APG_DCN31_REG_LIST(id)\ -} +#define apg_regs_init(id)\ + APG_DCN31_REG_LIST_RI(id) -static const struct dcn31_apg_registers apg_regs[] = { - apg_regs(0), - apg_regs(1), - apg_regs(2), - apg_regs(3) -}; +static struct dcn31_apg_registers apg_regs[4]; static const struct dcn31_apg_shift apg_shift = { DCN31_APG_MASK_SH_LIST(__SHIFT) @@ -333,18 +306,10 @@ static const struct dcn31_apg_mask apg_mask = { DCN31_APG_MASK_SH_LIST(_MASK) }; -#define stream_enc_regs(id)\ -[id] = {\ - SE_DCN32_REG_LIST(id)\ -} +#define stream_enc_regs_init(id)\ + SE_DCN32_REG_LIST_RI(id) -static const struct dcn10_stream_enc_registers stream_enc_regs[] = { - stream_enc_regs(0), - stream_enc_regs(1), - stream_enc_regs(2), - stream_enc_regs(3), - stream_enc_regs(4) -}; +static struct dcn10_stream_enc_registers stream_enc_regs[5]; static const struct dcn10_stream_encoder_shift se_shift = { SE_COMMON_MASK_SH_LIST_DCN32(__SHIFT) @@ -355,46 +320,24 @@ static const struct dcn10_stream_encoder_mask se_mask = { }; -#define aux_regs(id)\ -[id] = {\ - DCN2_AUX_REG_LIST(id)\ -} +#define aux_regs_init(id)\ + DCN2_AUX_REG_LIST_RI(id) -static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = { - aux_regs(0), - aux_regs(1), - aux_regs(2), - aux_regs(3), - aux_regs(4) -}; +static struct dcn10_link_enc_aux_registers link_enc_aux_regs[5]; -#define hpd_regs(id)\ -[id] = {\ - HPD_REG_LIST(id)\ -} +#define hpd_regs_init(id)\ + HPD_REG_LIST_RI(id) -static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = { - hpd_regs(0), - hpd_regs(1), - hpd_regs(2), - hpd_regs(3), - hpd_regs(4) -}; +static struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[5]; -#define link_regs(id, phyid)\ -[id] = {\ - LE_DCN31_REG_LIST(id), \ - UNIPHY_DCN2_REG_LIST(phyid), \ +#define link_regs_init(id, phyid)\ + ( \ + LE_DCN31_REG_LIST_RI(id), \ + UNIPHY_DCN2_REG_LIST_RI(id, phyid)\ + ) /*DPCS_DCN31_REG_LIST(id),*/ \ -} -static const struct dcn10_link_enc_registers link_enc_regs[] = { - link_regs(0, A), - link_regs(1, B), - link_regs(2, C), - link_regs(3, D), - link_regs(4, E) -}; +static struct dcn10_link_enc_registers link_enc_regs[5]; static const struct dcn10_link_enc_shift le_shift = { LINK_ENCODER_MASK_SH_LIST_DCN31(__SHIFT), \ @@ -406,17 +349,10 @@ static const struct dcn10_link_enc_mask le_mask = { // DPCS_DCN31_MASK_SH_LIST(_MASK) }; -#define hpo_dp_stream_encoder_reg_list(id)\ -[id] = {\ - DCN3_1_HPO_DP_STREAM_ENC_REG_LIST(id)\ -} +#define hpo_dp_stream_encoder_reg_init(id)\ + DCN3_1_HPO_DP_STREAM_ENC_REG_LIST_RI(id) -static const struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[] = { - hpo_dp_stream_encoder_reg_list(0), - hpo_dp_stream_encoder_reg_list(1), - hpo_dp_stream_encoder_reg_list(2), - hpo_dp_stream_encoder_reg_list(3), -}; +static struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[4]; static const struct dcn31_hpo_dp_stream_encoder_shift hpo_dp_se_shift = { DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(__SHIFT) @@ -427,20 +363,14 @@ static const struct dcn31_hpo_dp_stream_encoder_mask hpo_dp_se_mask = { }; -#define hpo_dp_link_encoder_reg_list(id)\ -[id] = {\ - DCN3_1_HPO_DP_LINK_ENC_REG_LIST(id),\ - /*DCN3_1_RDPCSTX_REG_LIST(0),*/\ - /*DCN3_1_RDPCSTX_REG_LIST(1),*/\ - /*DCN3_1_RDPCSTX_REG_LIST(2),*/\ - /*DCN3_1_RDPCSTX_REG_LIST(3),*/\ - /*DCN3_1_RDPCSTX_REG_LIST(4)*/\ -} +#define hpo_dp_link_encoder_reg_init(id)\ + DCN3_1_HPO_DP_LINK_ENC_REG_LIST_RI(id) + /*DCN3_1_RDPCSTX_REG_LIST(0),*/ + /*DCN3_1_RDPCSTX_REG_LIST(1),*/ + /*DCN3_1_RDPCSTX_REG_LIST(2),*/ + /*DCN3_1_RDPCSTX_REG_LIST(3),*/ -static const struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[] = { - hpo_dp_link_encoder_reg_list(0), - hpo_dp_link_encoder_reg_list(1), -}; +static struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[2]; static const struct dcn31_hpo_dp_link_encoder_shift hpo_dp_le_shift = { DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(__SHIFT) @@ -450,17 +380,10 @@ static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = { DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(_MASK) }; -#define dpp_regs(id)\ -[id] = {\ - DPP_REG_LIST_DCN30_COMMON(id),\ -} +#define dpp_regs_init(id)\ + DPP_REG_LIST_DCN30_COMMON_RI(id) -static const struct dcn3_dpp_registers dpp_regs[] = { - dpp_regs(0), - dpp_regs(1), - dpp_regs(2), - dpp_regs(3) -}; +static struct dcn3_dpp_registers dpp_regs[4]; static const struct dcn3_dpp_shift tf_shift = { DPP_REG_LIST_SH_MASK_DCN30_COMMON(__SHIFT) @@ -471,17 +394,10 @@ static const struct dcn3_dpp_mask tf_mask = { }; -#define opp_regs(id)\ -[id] = {\ - OPP_REG_LIST_DCN30(id),\ -} +#define opp_regs_init(id)\ + OPP_REG_LIST_DCN30_RI(id) -static const struct dcn20_opp_registers opp_regs[] = { - opp_regs(0), - opp_regs(1), - opp_regs(2), - opp_regs(3) -}; +static struct dcn20_opp_registers opp_regs[4]; static const struct dcn20_opp_shift opp_shift = { OPP_MASK_SH_LIST_DCN20(__SHIFT) @@ -491,21 +407,15 @@ static const struct dcn20_opp_mask opp_mask = { OPP_MASK_SH_LIST_DCN20(_MASK) }; -#define aux_engine_regs(id)\ -[id] = {\ - AUX_COMMON_REG_LIST0(id), \ - .AUXN_IMPCAL = 0, \ - .AUXP_IMPCAL = 0, \ - .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \ -} +#define aux_engine_regs_init(id) \ + ( \ + AUX_COMMON_REG_LIST0_RI(id), SR_ARR_INIT(AUXN_IMPCAL, id, 0), \ + SR_ARR_INIT(AUXP_IMPCAL, id, 0), \ + SR_ARR_INIT(AUX_RESET_MASK, id, DP_AUX0_AUX_CONTROL__AUX_RESET_MASK), \ + SR_ARR_INIT(AUX_RESET_MASK, id, DP_AUX0_AUX_CONTROL__AUX_RESET_MASK)\ + ) -static const struct dce110_aux_registers aux_engine_regs[] = { - aux_engine_regs(0), - aux_engine_regs(1), - aux_engine_regs(2), - aux_engine_regs(3), - aux_engine_regs(4) -}; +static struct dce110_aux_registers aux_engine_regs[5]; static const struct dce110_aux_registers_shift aux_shift = { DCN_AUX_MASK_SH_LIST(__SHIFT) @@ -515,15 +425,10 @@ static const struct dce110_aux_registers_mask aux_mask = { DCN_AUX_MASK_SH_LIST(_MASK) }; +#define dwbc_regs_dcn3_init(id)\ + DWBC_COMMON_REG_LIST_DCN30_RI(id) -#define dwbc_regs_dcn3(id)\ -[id] = {\ - DWBC_COMMON_REG_LIST_DCN30(id),\ -} - -static const struct dcn30_dwbc_registers dwbc30_regs[] = { - dwbc_regs_dcn3(0), -}; +static struct dcn30_dwbc_registers dwbc30_regs[1]; static const struct dcn30_dwbc_shift dwbc30_shift = { DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT) @@ -533,14 +438,10 @@ static const struct dcn30_dwbc_mask dwbc30_mask = { DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK) }; -#define mcif_wb_regs_dcn3(id)\ -[id] = {\ - MCIF_WB_COMMON_REG_LIST_DCN32(id),\ -} +#define mcif_wb_regs_dcn3_init(id)\ + MCIF_WB_COMMON_REG_LIST_DCN32_RI(id) -static const struct dcn30_mmhubbub_registers mcif_wb30_regs[] = { - mcif_wb_regs_dcn3(0) -}; +static struct dcn30_mmhubbub_registers mcif_wb30_regs[1]; static const struct dcn30_mmhubbub_shift mcif_wb30_shift = { MCIF_WB_COMMON_MASK_SH_LIST_DCN32(__SHIFT) @@ -550,17 +451,10 @@ static const struct dcn30_mmhubbub_mask mcif_wb30_mask = { MCIF_WB_COMMON_MASK_SH_LIST_DCN32(_MASK) }; -#define dsc_regsDCN20(id)\ -[id] = {\ - DSC_REG_LIST_DCN20(id)\ -} +#define dsc_regsDCN20_init(id)\ + DSC_REG_LIST_DCN20_RI(id) -static const struct dcn20_dsc_registers dsc_regs[] = { - dsc_regsDCN20(0), - dsc_regsDCN20(1), - dsc_regsDCN20(2), - dsc_regsDCN20(3) -}; +static struct dcn20_dsc_registers dsc_regs[4]; static const struct dcn20_dsc_shift dsc_shift = { DSC_REG_LIST_SH_MASK_DCN20(__SHIFT) @@ -570,17 +464,23 @@ static const struct dcn20_dsc_mask dsc_mask = { DSC_REG_LIST_SH_MASK_DCN20(_MASK) }; -static const struct dcn30_mpc_registers mpc_regs = { - MPC_REG_LIST_DCN3_2(0), - MPC_REG_LIST_DCN3_2(1), - MPC_REG_LIST_DCN3_2(2), - MPC_REG_LIST_DCN3_2(3), - MPC_OUT_MUX_REG_LIST_DCN3_0(0), - MPC_OUT_MUX_REG_LIST_DCN3_0(1), - MPC_OUT_MUX_REG_LIST_DCN3_0(2), - MPC_OUT_MUX_REG_LIST_DCN3_0(3), - MPC_DWB_MUX_REG_LIST_DCN3_0(0), -}; +static struct dcn30_mpc_registers mpc_regs; +#define dcn_mpc_regs_init()\ + ( \ + MPC_REG_LIST_DCN3_0_RI(0),\ + MPC_REG_LIST_DCN3_0_RI(1),\ + MPC_REG_LIST_DCN3_0_RI(2),\ + MPC_REG_LIST_DCN3_0_RI(3),\ + MPC_OUT_MUX_REG_LIST_DCN3_0_RI(0),\ + MPC_OUT_MUX_REG_LIST_DCN3_0_RI(1),\ + MPC_OUT_MUX_REG_LIST_DCN3_0_RI(2),\ + MPC_OUT_MUX_REG_LIST_DCN3_0_RI(3),\ + MPC_MCM_REG_LIST_DCN32_RI(0),\ + MPC_MCM_REG_LIST_DCN32_RI(1),\ + MPC_MCM_REG_LIST_DCN32_RI(2),\ + MPC_MCM_REG_LIST_DCN32_RI(3),\ + MPC_DWB_MUX_REG_LIST_DCN3_0_RI(0)\ + ) static const struct dcn30_mpc_shift mpc_shift = { MPC_COMMON_MASK_SH_LIST_DCN32(__SHIFT) @@ -590,15 +490,10 @@ static const struct dcn30_mpc_mask mpc_mask = { MPC_COMMON_MASK_SH_LIST_DCN32(_MASK) }; -#define optc_regs(id)\ -[id] = {OPTC_COMMON_REG_LIST_DCN3_2(id)} +#define optc_regs_init(id)\ + OPTC_COMMON_REG_LIST_DCN3_2_RI(id) -static const struct dcn_optc_registers optc_regs[] = { - optc_regs(0), - optc_regs(1), - optc_regs(2), - optc_regs(3) -}; +static struct dcn_optc_registers optc_regs[4]; static const struct dcn_optc_shift optc_shift = { OPTC_COMMON_MASK_SH_LIST_DCN3_2(__SHIFT) @@ -608,18 +503,10 @@ static const struct dcn_optc_mask optc_mask = { OPTC_COMMON_MASK_SH_LIST_DCN3_2(_MASK) }; -#define hubp_regs(id)\ -[id] = {\ - HUBP_REG_LIST_DCN32(id)\ -} - -static const struct dcn_hubp2_registers hubp_regs[] = { - hubp_regs(0), - hubp_regs(1), - hubp_regs(2), - hubp_regs(3) -}; +#define hubp_regs_init(id) \ + HUBP_REG_LIST_DCN32_RI(id) +static struct dcn_hubp2_registers hubp_regs[4]; static const struct dcn_hubp2_shift hubp_shift = { HUBP_MASK_SH_LIST_DCN32(__SHIFT) @@ -628,9 +515,10 @@ static const struct dcn_hubp2_shift hubp_shift = { static const struct dcn_hubp2_mask hubp_mask = { HUBP_MASK_SH_LIST_DCN32(_MASK) }; -static const struct dcn_hubbub_registers hubbub_reg = { - HUBBUB_REG_LIST_DCN32(0) -}; + +static struct dcn_hubbub_registers hubbub_reg; +#define hubbub_reg_init()\ + HUBBUB_REG_LIST_DCN32_RI(0) static const struct dcn_hubbub_shift hubbub_shift = { HUBBUB_MASK_SH_LIST_DCN32(__SHIFT) @@ -640,9 +528,10 @@ static const struct dcn_hubbub_mask hubbub_mask = { HUBBUB_MASK_SH_LIST_DCN32(_MASK) }; -static const struct dccg_registers dccg_regs = { - DCCG_REG_LIST_DCN32() -}; +static struct dccg_registers dccg_regs; + +#define dccg_regs_init()\ + DCCG_REG_LIST_DCN32_RI() static const struct dccg_shift dccg_shift = { DCCG_MASK_SH_LIST_DCN32(__SHIFT) @@ -715,9 +604,10 @@ static const struct dccg_mask dccg_mask = { SR(AZALIA_AUDIO_DTO), \ SR(AZALIA_CONTROLLER_CLOCK_GATING) -static const struct dce_hwseq_registers hwseq_reg = { - HWSEQ_DCN32_REG_LIST() -}; +static struct dce_hwseq_registers hwseq_reg; + +#define hwseq_reg_init()\ + HWSEQ_DCN32_REG_LIST() #define HWSEQ_DCN32_MASK_SH_LIST(mask_sh)\ HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ @@ -760,29 +650,10 @@ static const struct dce_hwseq_shift hwseq_shift = { static const struct dce_hwseq_mask hwseq_mask = { HWSEQ_DCN32_MASK_SH_LIST(_MASK) }; -#define vmid_regs(id)\ -[id] = {\ - DCN20_VMID_REG_LIST(id)\ -} +#define vmid_regs_init(id)\ + DCN20_VMID_REG_LIST_RI(id) -static const struct dcn_vmid_registers vmid_regs[] = { - vmid_regs(0), - vmid_regs(1), - vmid_regs(2), - vmid_regs(3), - vmid_regs(4), - vmid_regs(5), - vmid_regs(6), - vmid_regs(7), - vmid_regs(8), - vmid_regs(9), - vmid_regs(10), - vmid_regs(11), - vmid_regs(12), - vmid_regs(13), - vmid_regs(14), - vmid_regs(15) -}; +static struct dcn_vmid_registers vmid_regs[16]; static const struct dcn20_vmid_shift vmid_shifts = { DCN20_VMID_MASK_SH_LIST(__SHIFT) @@ -905,6 +776,14 @@ static struct dce_aux *dcn321_aux_engine_create( if (!aux_engine) return NULL; +#undef REG_STRUCT +#define REG_STRUCT aux_engine_regs + aux_engine_regs_init(0), + aux_engine_regs_init(1), + aux_engine_regs_init(2), + aux_engine_regs_init(3), + aux_engine_regs_init(4); + dce110_aux_engine_construct(aux_engine, ctx, inst, SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, &aux_engine_regs[inst], @@ -914,15 +793,10 @@ static struct dce_aux *dcn321_aux_engine_create( return &aux_engine->base; } -#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST_DCN30(id) } - -static const struct dce_i2c_registers i2c_hw_regs[] = { - i2c_inst_regs(1), - i2c_inst_regs(2), - i2c_inst_regs(3), - i2c_inst_regs(4), - i2c_inst_regs(5), -}; +#define i2c_inst_regs_init(id)\ + I2C_HW_ENGINE_COMMON_REG_LIST_DCN30_RI(id) + +static struct dce_i2c_registers i2c_hw_regs[6]; static const struct dce_i2c_shift i2c_shifts = { I2C_COMMON_MASK_SH_LIST_DCN30(__SHIFT) @@ -942,6 +816,14 @@ static struct dce_i2c_hw *dcn321_i2c_hw_create( if (!dce_i2c_hw) return NULL; +#undef REG_STRUCT +#define REG_STRUCT i2c_hw_regs + i2c_inst_regs_init(1), + i2c_inst_regs_init(2), + i2c_inst_regs_init(3), + i2c_inst_regs_init(4), + i2c_inst_regs_init(5); + dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst, &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks); @@ -981,6 +863,29 @@ static struct hubbub *dcn321_hubbub_create(struct dc_context *ctx) if (!hubbub2) return NULL; +#undef REG_STRUCT +#define REG_STRUCT hubbub_reg + hubbub_reg_init(); + +#undef REG_STRUCT +#define REG_STRUCT vmid_regs + vmid_regs_init(0), + vmid_regs_init(1), + vmid_regs_init(2), + vmid_regs_init(3), + vmid_regs_init(4), + vmid_regs_init(5), + vmid_regs_init(6), + vmid_regs_init(7), + vmid_regs_init(8), + vmid_regs_init(9), + vmid_regs_init(10), + vmid_regs_init(11), + vmid_regs_init(12), + vmid_regs_init(13), + vmid_regs_init(14), + vmid_regs_init(15); + hubbub32_construct(hubbub2, ctx, &hubbub_reg, &hubbub_shift, @@ -1013,6 +918,13 @@ static struct hubp *dcn321_hubp_create( if (!hubp2) return NULL; +#undef REG_STRUCT +#define REG_STRUCT hubp_regs + hubp_regs_init(0), + hubp_regs_init(1), + hubp_regs_init(2), + hubp_regs_init(3); + if (hubp32_construct(hubp2, ctx, inst, &hubp_regs[inst], &hubp_shift, &hubp_mask)) return &hubp2->base; @@ -1038,6 +950,13 @@ static struct dpp *dcn321_dpp_create( if (!dpp3) return NULL; +#undef REG_STRUCT +#define REG_STRUCT dpp_regs + dpp_regs_init(0), + dpp_regs_init(1), + dpp_regs_init(2), + dpp_regs_init(3); + if (dpp32_construct(dpp3, ctx, inst, &dpp_regs[inst], &tf_shift, &tf_mask)) return &dpp3->base; @@ -1058,6 +977,10 @@ static struct mpc *dcn321_mpc_create( if (!mpc30) return NULL; +#undef REG_STRUCT +#define REG_STRUCT mpc_regs + dcn_mpc_regs_init(); + dcn32_mpc_construct(mpc30, ctx, &mpc_regs, &mpc_shift, @@ -1079,6 +1002,13 @@ static struct output_pixel_processor *dcn321_opp_create( return NULL; } +#undef REG_STRUCT +#define REG_STRUCT opp_regs + opp_regs_init(0), + opp_regs_init(1), + opp_regs_init(2), + opp_regs_init(3); + dcn20_opp_construct(opp2, ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask); return &opp2->base; @@ -1095,6 +1025,13 @@ static struct timing_generator *dcn321_timing_generator_create( if (!tgn10) return NULL; +#undef REG_STRUCT +#define REG_STRUCT optc_regs + optc_regs_init(0), + optc_regs_init(1), + optc_regs_init(2), + optc_regs_init(3); + tgn10->base.inst = instance; tgn10->base.ctx = ctx; @@ -1129,6 +1066,30 @@ static struct link_encoder *dcn321_link_encoder_create( if (!enc20) return NULL; +#undef REG_STRUCT +#define REG_STRUCT link_enc_aux_regs + aux_regs_init(0), + aux_regs_init(1), + aux_regs_init(2), + aux_regs_init(3), + aux_regs_init(4); + +#undef REG_STRUCT +#define REG_STRUCT link_enc_hpd_regs + hpd_regs_init(0), + hpd_regs_init(1), + hpd_regs_init(2), + hpd_regs_init(3), + hpd_regs_init(4); + +#undef REG_STRUCT +#define REG_STRUCT link_enc_regs + link_regs_init(0, A), + link_regs_init(1, B), + link_regs_init(2, C), + link_regs_init(3, D), + link_regs_init(4, E); + dcn321_link_encoder_construct(enc20, enc_init_data, &link_enc_feature, @@ -1145,7 +1106,7 @@ static void read_dce_straps( struct dc_context *ctx, struct resource_straps *straps) { - generic_reg_get(ctx, regDC_PINSTRAPS + BASE(regDC_PINSTRAPS_BASE_IDX), + generic_reg_get(ctx, ctx->dcn_reg_offsets[regDC_PINSTRAPS_BASE_IDX] + regDC_PINSTRAPS, FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio); } @@ -1153,6 +1114,15 @@ static void read_dce_straps( static struct audio *dcn321_create_audio( struct dc_context *ctx, unsigned int inst) { + +#undef REG_STRUCT +#define REG_STRUCT audio_regs + audio_regs_init(0), + audio_regs_init(1), + audio_regs_init(2), + audio_regs_init(3), + audio_regs_init(4); + return dce_audio_create(ctx, inst, &audio_regs[inst], &audio_shift, &audio_mask); } @@ -1166,6 +1136,19 @@ static struct vpg *dcn321_vpg_create( if (!vpg3) return NULL; +#undef REG_STRUCT +#define REG_STRUCT vpg_regs + vpg_regs_init(0), + vpg_regs_init(1), + vpg_regs_init(2), + vpg_regs_init(3), + vpg_regs_init(4), + vpg_regs_init(5), + vpg_regs_init(6), + vpg_regs_init(7), + vpg_regs_init(8), + vpg_regs_init(9); + vpg3_construct(vpg3, ctx, inst, &vpg_regs[inst], &vpg_shift, @@ -1183,6 +1166,15 @@ static struct afmt *dcn321_afmt_create( if (!afmt3) return NULL; +#undef REG_STRUCT +#define REG_STRUCT afmt_regs + afmt_regs_init(0), + afmt_regs_init(1), + afmt_regs_init(2), + afmt_regs_init(3), + afmt_regs_init(4), + afmt_regs_init(5); + afmt3_construct(afmt3, ctx, inst, &afmt_regs[inst], &afmt_shift, @@ -1200,6 +1192,13 @@ static struct apg *dcn321_apg_create( if (!apg31) return NULL; +#undef REG_STRUCT +#define REG_STRUCT apg_regs + apg_regs_init(0), + apg_regs_init(1), + apg_regs_init(2), + apg_regs_init(3); + apg31_construct(apg31, ctx, inst, &apg_regs[inst], &apg_shift, @@ -1236,6 +1235,14 @@ static struct stream_encoder *dcn321_stream_encoder_create( return NULL; } +#undef REG_STRUCT +#define REG_STRUCT stream_enc_regs + stream_enc_regs_init(0), + stream_enc_regs_init(1), + stream_enc_regs_init(2), + stream_enc_regs_init(3), + stream_enc_regs_init(4); + dcn32_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, vpg, afmt, &stream_enc_regs[eng_id], @@ -1286,6 +1293,13 @@ static struct hpo_dp_stream_encoder *dcn321_hpo_dp_stream_encoder_create( return NULL; } +#undef REG_STRUCT +#define REG_STRUCT hpo_dp_stream_enc_regs + hpo_dp_stream_encoder_reg_init(0), + hpo_dp_stream_encoder_reg_init(1), + hpo_dp_stream_encoder_reg_init(2), + hpo_dp_stream_encoder_reg_init(3); + dcn31_hpo_dp_stream_encoder_construct(hpo_dp_enc31, ctx, ctx->dc_bios, hpo_dp_inst, eng_id, vpg, apg, &hpo_dp_stream_enc_regs[hpo_dp_inst], @@ -1303,6 +1317,11 @@ static struct hpo_dp_link_encoder *dcn321_hpo_dp_link_encoder_create( /* allocate HPO link encoder */ hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); +#undef REG_STRUCT +#define REG_STRUCT hpo_dp_link_enc_regs + hpo_dp_link_encoder_reg_init(0), + hpo_dp_link_encoder_reg_init(1); + hpo_dp_link_encoder32_construct(hpo_dp_enc31, ctx, inst, &hpo_dp_link_enc_regs[inst], &hpo_dp_le_shift, &hpo_dp_le_mask); @@ -1315,6 +1334,10 @@ static struct dce_hwseq *dcn321_hwseq_create( { struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); +#undef REG_STRUCT +#define REG_STRUCT hwseq_reg + hwseq_reg_init(); + if (hws) { hws->ctx = ctx; hws->regs = &hwseq_reg; @@ -1505,6 +1528,10 @@ static bool dcn321_dwbc_create(struct dc_context *ctx, struct resource_pool *poo return false; } +#undef REG_STRUCT +#define REG_STRUCT dwbc30_regs + dwbc_regs_dcn3_init(0); + dcn30_dwbc_construct(dwbc30, ctx, &dwbc30_regs[i], &dwbc30_shift, @@ -1530,6 +1557,10 @@ static bool dcn321_mmhubbub_create(struct dc_context *ctx, struct resource_pool return false; } +#undef REG_STRUCT +#define REG_STRUCT mcif_wb30_regs + mcif_wb_regs_dcn3_init(0); + dcn32_mmhubbub_construct(mcif_wb30, ctx, &mcif_wb30_regs[i], &mcif_wb30_shift, @@ -1552,6 +1583,13 @@ static struct display_stream_compressor *dcn321_dsc_create( return NULL; } +#undef REG_STRUCT +#define REG_STRUCT dsc_regs + dsc_regsDCN20_init(0), + dsc_regsDCN20_init(1), + dsc_regsDCN20_init(2), + dsc_regsDCN20_init(3); + dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask); dsc->max_image_width = 6016; @@ -1616,6 +1654,30 @@ static bool dcn321_resource_construct( uint32_t pipe_fuses = 0; uint32_t num_pipes = 4; +#undef REG_STRUCT +#define REG_STRUCT bios_regs + bios_regs_init(); + +#undef REG_STRUCT +#define REG_STRUCT clk_src_regs + clk_src_regs_init(0, A), + clk_src_regs_init(1, B), + clk_src_regs_init(2, C), + clk_src_regs_init(3, D), + clk_src_regs_init(4, E); + +#undef REG_STRUCT +#define REG_STRUCT abm_regs + abm_regs_init(0), + abm_regs_init(1), + abm_regs_init(2), + abm_regs_init(3); + +#undef REG_STRUCT +#define REG_STRUCT dccg_regs + dccg_regs_init(); + + ctx->dc_bios->regs = &bios_regs; pool->base.res_cap = &res_cap_dcn321; diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h index 8173f4b80424..e93187c06648 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h @@ -171,7 +171,12 @@ void dm_helpers_smu_timeout(struct dc_context *ctx, unsigned int msg_id, unsigne // 0x1 = Result_OK, 0xFE = Result_UnkmownCmd, 0x0 = Status_Busy #define IS_SMU_TIMEOUT(result) \ (result == 0x0) - +void dm_helpers_init_panel_settings( + struct dc_context *ctx, + struct dc_panel_config *config); +void dm_helpers_override_panel_settings( + struct dc_context *ctx, + struct dc_panel_config *config); int dm_helper_dmub_aux_transfer_sync( struct dc_context *ctx, const struct dc_link *link, diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c index 6ca288fb5fb9..3aa8dd0acd5e 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c +++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c @@ -25,12 +25,11 @@ #include "dm_services.h" #include "bw_fixed.h" +#define MAX_I64 \ + ((int64_t)((1ULL << 63) - 1)) #define MIN_I64 \ - (int64_t)(-(1LL << 63)) - -#define MAX_I64 \ - (int64_t)((1ULL << 63) - 1) + (-MAX_I64 - 1) #define FRACTIONAL_PART_MASK \ ((1ULL << BW_FIXED_BITS_PER_FRACTIONAL_PART) - 1) @@ -49,6 +48,7 @@ static uint64_t abs_i64(int64_t arg) struct bw_fixed bw_int_to_fixed_nonconst(int64_t value) { struct bw_fixed res; + ASSERT(value < BW_FIXED_MAX_I32 && value > BW_FIXED_MIN_I32); res.value = value << BW_FIXED_BITS_PER_FRACTIONAL_PART; return res; @@ -78,14 +78,12 @@ struct bw_fixed bw_frc_to_fixed(int64_t numerator, int64_t denominator) { uint32_t i = BW_FIXED_BITS_PER_FRACTIONAL_PART; - do - { + do { remainder <<= 1; res_value <<= 1; - if (remainder >= arg2_value) - { + if (remainder >= arg2_value) { res_value |= 1; remainder -= arg2_value; } diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c index db3b16b77034..d46adc849d2a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c @@ -736,30 +736,13 @@ static void hack_bounding_box(struct dcn_bw_internal_vars *v, hack_force_pipe_split(v, context->streams[0]->timing.pix_clk_100hz); } -static unsigned int get_highest_allowed_voltage_level(uint32_t chip_family, - uint32_t hw_internal_rev, - uint32_t pci_revision_id) +static unsigned int get_highest_allowed_voltage_level(bool is_vmin_only_asic) { /* for low power RV2 variants, the highest voltage level we want is 0 */ - if ((chip_family == FAMILY_RV) && - ASICREV_IS_RAVEN2(hw_internal_rev)) - switch (pci_revision_id) { - case PRID_DALI_DE: - case PRID_DALI_DF: - case PRID_DALI_E3: - case PRID_DALI_E4: - case PRID_POLLOCK_94: - case PRID_POLLOCK_95: - case PRID_POLLOCK_E9: - case PRID_POLLOCK_EA: - case PRID_POLLOCK_EB: - return 0; - default: - break; - } - - /* we are ok with all levels */ - return 4; + if (is_vmin_only_asic) + return 0; + else /* we are ok with all levels */ + return 4; } bool dcn_validate_bandwidth( @@ -1323,10 +1306,7 @@ bool dcn_validate_bandwidth( PERFORMANCE_TRACE_END(); BW_VAL_TRACE_FINISH(); - if (bw_limit_pass && v->voltage_level <= get_highest_allowed_voltage_level( - dc->ctx->asic_id.chip_family, - dc->ctx->asic_id.hw_internal_rev, - dc->ctx->asic_id.pci_revision_id)) + if (bw_limit_pass && v->voltage_level <= get_highest_allowed_voltage_level(dc->config.is_vmin_only_asic)) return true; else return false; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c index d34e0f1314d9..d680f1c5b69f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c @@ -2234,6 +2234,7 @@ static struct _vcs_dpi_voltage_scaling_st construct_low_pstate_lvl(struct clk_li void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) { + struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits; struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool); struct clk_limit_table *clk_table = &bw_params->clk_table; unsigned int i, closest_clk_lvl = 0, k = 0; @@ -2247,8 +2248,7 @@ void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params ASSERT(clk_table->num_entries); /* Copy dcn2_1_soc.clock_limits to clock_limits to avoid copying over null states later */ - memcpy(&dcn2_1_soc._clock_tmp, &dcn2_1_soc.clock_limits, - sizeof(dcn2_1_soc.clock_limits)); + memcpy(s, dcn2_1_soc.clock_limits, sizeof(dcn2_1_soc.clock_limits)); for (i = 0; i < clk_table->num_entries; i++) { /* loop backwards*/ @@ -2263,25 +2263,25 @@ void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params if (i == 1) k++; - dcn2_1_soc._clock_tmp[k].state = k; - dcn2_1_soc._clock_tmp[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; - dcn2_1_soc._clock_tmp[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz; - dcn2_1_soc._clock_tmp[k].socclk_mhz = clk_table->entries[i].socclk_mhz; - dcn2_1_soc._clock_tmp[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; - - dcn2_1_soc._clock_tmp[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; - dcn2_1_soc._clock_tmp[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; - dcn2_1_soc._clock_tmp[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; - dcn2_1_soc._clock_tmp[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; - dcn2_1_soc._clock_tmp[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; - dcn2_1_soc._clock_tmp[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; - dcn2_1_soc._clock_tmp[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; + s[k].state = k; + s[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; + s[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz; + s[k].socclk_mhz = clk_table->entries[i].socclk_mhz; + s[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; + + s[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; + s[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; + s[k].dram_bw_per_chan_gbps = + dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; + s[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; + s[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; + s[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; + s[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; k++; } - memcpy(&dcn2_1_soc.clock_limits, &dcn2_1_soc._clock_tmp, - sizeof(dcn2_1_soc.clock_limits)); + memcpy(dcn2_1_soc.clock_limits, s, sizeof(dcn2_1_soc.clock_limits)); if (clk_table->num_entries) { dcn2_1_soc.num_states = clk_table->num_entries + 1; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c index 876b321b30ca..b7fa003ffe06 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c @@ -396,64 +396,10 @@ static void CalculateUrgentBurstFactor( static void UseMinimumDCFCLK( struct display_mode_lib *mode_lib, - int MaxInterDCNTileRepeaters, + struct vba_vars_st *v, int MaxPrefetchMode, - double FinalDRAMClockChangeLatency, - double SREnterPlusExitTime, - int ReturnBusWidth, - int RoundTripPingLatencyCycles, - int ReorderingBytes, - int PixelChunkSizeInKByte, - int MetaChunkSize, - bool GPUVMEnable, - int GPUVMMaxPageTableLevels, - bool HostVMEnable, - int NumberOfActivePlanes, - double HostVMMinPageSize, - int HostVMMaxNonCachedPageTableLevels, - bool DynamicMetadataVMEnabled, - enum immediate_flip_requirement ImmediateFlipRequirement, - bool ProgressiveToInterlaceUnitInOPP, - double MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation, - double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData, - double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly, - double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly, - int VTotal[], - int VActive[], - int DynamicMetadataTransmittedBytes[], - int DynamicMetadataLinesBeforeActiveRequired[], - bool Interlace[], - double RequiredDPPCLK[][2][DC__NUM_DPP__MAX], - double RequiredDISPCLK[][2], - double UrgLatency[], - unsigned int NoOfDPP[][2][DC__NUM_DPP__MAX], - double ProjectedDCFCLKDeepSleep[][2], - double MaximumVStartup[][2][DC__NUM_DPP__MAX], - double TotalVActivePixelBandwidth[][2], - double TotalVActiveCursorBandwidth[][2], - double TotalMetaRowBandwidth[][2], - double TotalDPTERowBandwidth[][2], - unsigned int TotalNumberOfActiveDPP[][2], - unsigned int TotalNumberOfDCCActiveDPP[][2], - int dpte_group_bytes[], - double PrefetchLinesY[][2][DC__NUM_DPP__MAX], - double PrefetchLinesC[][2][DC__NUM_DPP__MAX], - unsigned int swath_width_luma_ub_all_states[][2][DC__NUM_DPP__MAX], - unsigned int swath_width_chroma_ub_all_states[][2][DC__NUM_DPP__MAX], - int BytePerPixelY[], - int BytePerPixelC[], - int HTotal[], - double PixelClock[], - double PDEAndMetaPTEBytesPerFrame[][2][DC__NUM_DPP__MAX], - double DPTEBytesPerRow[][2][DC__NUM_DPP__MAX], - double MetaRowBytes[][2][DC__NUM_DPP__MAX], - bool DynamicMetadataEnable[], - double VActivePixelBandwidth[][2][DC__NUM_DPP__MAX], - double VActiveCursorBandwidth[][2][DC__NUM_DPP__MAX], - double ReadBandwidthLuma[], - double ReadBandwidthChroma[], - double DCFCLKPerState[], - double DCFCLKState[][2]); + int ReorderingBytes); + static void CalculatePixelDeliveryTimes( unsigned int NumberOfActivePlanes, double VRatio[], @@ -4692,66 +4638,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l } if (v->UseMinimumRequiredDCFCLK == true) { - UseMinimumDCFCLK( - mode_lib, - v->MaxInterDCNTileRepeaters, - MaxPrefetchMode, - v->FinalDRAMClockChangeLatency, - v->SREnterPlusExitTime, - v->ReturnBusWidth, - v->RoundTripPingLatencyCycles, - ReorderingBytes, - v->PixelChunkSizeInKByte, - v->MetaChunkSize, - v->GPUVMEnable, - v->GPUVMMaxPageTableLevels, - v->HostVMEnable, - v->NumberOfActivePlanes, - v->HostVMMinPageSize, - v->HostVMMaxNonCachedPageTableLevels, - v->DynamicMetadataVMEnabled, - v->ImmediateFlipRequirement[0], - v->ProgressiveToInterlaceUnitInOPP, - v->MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation, - v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData, - v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly, - v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly, - v->VTotal, - v->VActive, - v->DynamicMetadataTransmittedBytes, - v->DynamicMetadataLinesBeforeActiveRequired, - v->Interlace, - v->RequiredDPPCLK, - v->RequiredDISPCLK, - v->UrgLatency, - v->NoOfDPP, - v->ProjectedDCFCLKDeepSleep, - v->MaximumVStartup, - v->TotalVActivePixelBandwidth, - v->TotalVActiveCursorBandwidth, - v->TotalMetaRowBandwidth, - v->TotalDPTERowBandwidth, - v->TotalNumberOfActiveDPP, - v->TotalNumberOfDCCActiveDPP, - v->dpte_group_bytes, - v->PrefetchLinesY, - v->PrefetchLinesC, - v->swath_width_luma_ub_all_states, - v->swath_width_chroma_ub_all_states, - v->BytePerPixelY, - v->BytePerPixelC, - v->HTotal, - v->PixelClock, - v->PDEAndMetaPTEBytesPerFrame, - v->DPTEBytesPerRow, - v->MetaRowBytes, - v->DynamicMetadataEnable, - v->VActivePixelBandwidth, - v->VActiveCursorBandwidth, - v->ReadBandwidthLuma, - v->ReadBandwidthChroma, - v->DCFCLKPerState, - v->DCFCLKState); + UseMinimumDCFCLK(mode_lib, v, MaxPrefetchMode, ReorderingBytes); if (v->ClampMinDCFCLK) { /* Clamp calculated values to actual minimum */ @@ -6610,77 +6497,21 @@ static double CalculateUrgentLatency( return ret; } - static void UseMinimumDCFCLK( struct display_mode_lib *mode_lib, - int MaxInterDCNTileRepeaters, + struct vba_vars_st *v, int MaxPrefetchMode, - double FinalDRAMClockChangeLatency, - double SREnterPlusExitTime, - int ReturnBusWidth, - int RoundTripPingLatencyCycles, - int ReorderingBytes, - int PixelChunkSizeInKByte, - int MetaChunkSize, - bool GPUVMEnable, - int GPUVMMaxPageTableLevels, - bool HostVMEnable, - int NumberOfActivePlanes, - double HostVMMinPageSize, - int HostVMMaxNonCachedPageTableLevels, - bool DynamicMetadataVMEnabled, - enum immediate_flip_requirement ImmediateFlipRequirement, - bool ProgressiveToInterlaceUnitInOPP, - double MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation, - double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData, - double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly, - double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly, - int VTotal[], - int VActive[], - int DynamicMetadataTransmittedBytes[], - int DynamicMetadataLinesBeforeActiveRequired[], - bool Interlace[], - double RequiredDPPCLK[][2][DC__NUM_DPP__MAX], - double RequiredDISPCLK[][2], - double UrgLatency[], - unsigned int NoOfDPP[][2][DC__NUM_DPP__MAX], - double ProjectedDCFCLKDeepSleep[][2], - double MaximumVStartup[][2][DC__NUM_DPP__MAX], - double TotalVActivePixelBandwidth[][2], - double TotalVActiveCursorBandwidth[][2], - double TotalMetaRowBandwidth[][2], - double TotalDPTERowBandwidth[][2], - unsigned int TotalNumberOfActiveDPP[][2], - unsigned int TotalNumberOfDCCActiveDPP[][2], - int dpte_group_bytes[], - double PrefetchLinesY[][2][DC__NUM_DPP__MAX], - double PrefetchLinesC[][2][DC__NUM_DPP__MAX], - unsigned int swath_width_luma_ub_all_states[][2][DC__NUM_DPP__MAX], - unsigned int swath_width_chroma_ub_all_states[][2][DC__NUM_DPP__MAX], - int BytePerPixelY[], - int BytePerPixelC[], - int HTotal[], - double PixelClock[], - double PDEAndMetaPTEBytesPerFrame[][2][DC__NUM_DPP__MAX], - double DPTEBytesPerRow[][2][DC__NUM_DPP__MAX], - double MetaRowBytes[][2][DC__NUM_DPP__MAX], - bool DynamicMetadataEnable[], - double VActivePixelBandwidth[][2][DC__NUM_DPP__MAX], - double VActiveCursorBandwidth[][2][DC__NUM_DPP__MAX], - double ReadBandwidthLuma[], - double ReadBandwidthChroma[], - double DCFCLKPerState[], - double DCFCLKState[][2]) + int ReorderingBytes) { double NormalEfficiency = 0; double PTEEfficiency = 0; double TotalMaxPrefetchFlipDPTERowBandwidth[DC__VOLTAGE_STATES][2] = { { 0 } }; unsigned int i, j, k; - NormalEfficiency = (HostVMEnable == true ? PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData - : PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly) / 100.0; - PTEEfficiency = (HostVMEnable == true ? PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly - / PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData : 1.0); + NormalEfficiency = (v->HostVMEnable == true ? v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData + : v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly) / 100.0; + PTEEfficiency = (v->HostVMEnable == true ? v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly + / v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData : 1.0); for (i = 0; i < mode_lib->soc.num_states; ++i) { for (j = 0; j <= 1; ++j) { double PixelDCFCLKCyclesRequiredInPrefetch[DC__NUM_DPP__MAX] = { 0 }; @@ -6698,58 +6529,58 @@ static void UseMinimumDCFCLK( double MinimumTvmPlus2Tr0 = 0; TotalMaxPrefetchFlipDPTERowBandwidth[i][j] = 0; - for (k = 0; k < NumberOfActivePlanes; ++k) { + for (k = 0; k < v->NumberOfActivePlanes; ++k) { TotalMaxPrefetchFlipDPTERowBandwidth[i][j] = TotalMaxPrefetchFlipDPTERowBandwidth[i][j] - + NoOfDPP[i][j][k] * DPTEBytesPerRow[i][j][k] / (15.75 * HTotal[k] / PixelClock[k]); + + v->NoOfDPP[i][j][k] * v->DPTEBytesPerRow[i][j][k] / (15.75 * v->HTotal[k] / v->PixelClock[k]); } - for (k = 0; k <= NumberOfActivePlanes - 1; ++k) { - NoOfDPPState[k] = NoOfDPP[i][j][k]; + for (k = 0; k <= v->NumberOfActivePlanes - 1; ++k) { + NoOfDPPState[k] = v->NoOfDPP[i][j][k]; } - MinimumTWait = CalculateTWait(MaxPrefetchMode, FinalDRAMClockChangeLatency, UrgLatency[i], SREnterPlusExitTime); - NonDPTEBandwidth = TotalVActivePixelBandwidth[i][j] + TotalVActiveCursorBandwidth[i][j] + TotalMetaRowBandwidth[i][j]; - DPTEBandwidth = (HostVMEnable == true || ImmediateFlipRequirement == dm_immediate_flip_required) ? - TotalMaxPrefetchFlipDPTERowBandwidth[i][j] : TotalDPTERowBandwidth[i][j]; - DCFCLKRequiredForAverageBandwidth = dml_max3(ProjectedDCFCLKDeepSleep[i][j], - (NonDPTEBandwidth + TotalDPTERowBandwidth[i][j]) / ReturnBusWidth / (MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation / 100), - (NonDPTEBandwidth + DPTEBandwidth / PTEEfficiency) / NormalEfficiency / ReturnBusWidth); - - ExtraLatencyBytes = CalculateExtraLatencyBytes(ReorderingBytes, TotalNumberOfActiveDPP[i][j], PixelChunkSizeInKByte, TotalNumberOfDCCActiveDPP[i][j], - MetaChunkSize, GPUVMEnable, HostVMEnable, NumberOfActivePlanes, NoOfDPPState, dpte_group_bytes, - PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData, PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly, - HostVMMinPageSize, HostVMMaxNonCachedPageTableLevels); - ExtraLatencyCycles = RoundTripPingLatencyCycles + 32 + ExtraLatencyBytes / NormalEfficiency / ReturnBusWidth; - for (k = 0; k < NumberOfActivePlanes; ++k) { + MinimumTWait = CalculateTWait(MaxPrefetchMode, v->FinalDRAMClockChangeLatency, v->UrgLatency[i], v->SREnterPlusExitTime); + NonDPTEBandwidth = v->TotalVActivePixelBandwidth[i][j] + v->TotalVActiveCursorBandwidth[i][j] + v->TotalMetaRowBandwidth[i][j]; + DPTEBandwidth = (v->HostVMEnable == true || v->ImmediateFlipRequirement[0] == dm_immediate_flip_required) ? + TotalMaxPrefetchFlipDPTERowBandwidth[i][j] : v->TotalDPTERowBandwidth[i][j]; + DCFCLKRequiredForAverageBandwidth = dml_max3(v->ProjectedDCFCLKDeepSleep[i][j], + (NonDPTEBandwidth + v->TotalDPTERowBandwidth[i][j]) / v->ReturnBusWidth / (v->MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation / 100), + (NonDPTEBandwidth + DPTEBandwidth / PTEEfficiency) / NormalEfficiency / v->ReturnBusWidth); + + ExtraLatencyBytes = CalculateExtraLatencyBytes(ReorderingBytes, v->TotalNumberOfActiveDPP[i][j], v->PixelChunkSizeInKByte, v->TotalNumberOfDCCActiveDPP[i][j], + v->MetaChunkSize, v->GPUVMEnable, v->HostVMEnable, v->NumberOfActivePlanes, NoOfDPPState, v->dpte_group_bytes, + v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData, v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly, + v->HostVMMinPageSize, v->HostVMMaxNonCachedPageTableLevels); + ExtraLatencyCycles = v->RoundTripPingLatencyCycles + 32 + ExtraLatencyBytes / NormalEfficiency / v->ReturnBusWidth; + for (k = 0; k < v->NumberOfActivePlanes; ++k) { double DCFCLKCyclesRequiredInPrefetch = { 0 }; double ExpectedPrefetchBWAcceleration = { 0 }; double PrefetchTime = { 0 }; - PixelDCFCLKCyclesRequiredInPrefetch[k] = (PrefetchLinesY[i][j][k] * swath_width_luma_ub_all_states[i][j][k] * BytePerPixelY[k] - + PrefetchLinesC[i][j][k] * swath_width_chroma_ub_all_states[i][j][k] * BytePerPixelC[k]) / NormalEfficiency / ReturnBusWidth; - DCFCLKCyclesRequiredInPrefetch = 2 * ExtraLatencyCycles / NoOfDPPState[k] + PDEAndMetaPTEBytesPerFrame[i][j][k] / PTEEfficiency - / NormalEfficiency / ReturnBusWidth * (GPUVMMaxPageTableLevels > 2 ? 1 : 0) + 2 * DPTEBytesPerRow[i][j][k] / PTEEfficiency - / NormalEfficiency / ReturnBusWidth + 2 * MetaRowBytes[i][j][k] / NormalEfficiency / ReturnBusWidth + PixelDCFCLKCyclesRequiredInPrefetch[k]; - PrefetchPixelLinesTime[k] = dml_max(PrefetchLinesY[i][j][k], PrefetchLinesC[i][j][k]) * HTotal[k] / PixelClock[k]; - ExpectedPrefetchBWAcceleration = (VActivePixelBandwidth[i][j][k] + VActiveCursorBandwidth[i][j][k]) / (ReadBandwidthLuma[k] + ReadBandwidthChroma[k]); - DynamicMetadataVMExtraLatency[k] = (GPUVMEnable == true && DynamicMetadataEnable[k] == true && DynamicMetadataVMEnabled == true) ? - UrgLatency[i] * GPUVMMaxPageTableLevels * (HostVMEnable == true ? HostVMMaxNonCachedPageTableLevels + 1 : 1) : 0; - PrefetchTime = (MaximumVStartup[i][j][k] - 1) * HTotal[k] / PixelClock[k] - MinimumTWait - UrgLatency[i] * ((GPUVMMaxPageTableLevels <= 2 ? GPUVMMaxPageTableLevels - : GPUVMMaxPageTableLevels - 2) * (HostVMEnable == true ? HostVMMaxNonCachedPageTableLevels + 1 : 1) - 1) - DynamicMetadataVMExtraLatency[k]; + PixelDCFCLKCyclesRequiredInPrefetch[k] = (v->PrefetchLinesY[i][j][k] * v->swath_width_luma_ub_all_states[i][j][k] * v->BytePerPixelY[k] + + v->PrefetchLinesC[i][j][k] * v->swath_width_chroma_ub_all_states[i][j][k] * v->BytePerPixelC[k]) / NormalEfficiency / v->ReturnBusWidth; + DCFCLKCyclesRequiredInPrefetch = 2 * ExtraLatencyCycles / NoOfDPPState[k] + v->PDEAndMetaPTEBytesPerFrame[i][j][k] / PTEEfficiency + / NormalEfficiency / v->ReturnBusWidth * (v->GPUVMMaxPageTableLevels > 2 ? 1 : 0) + 2 * v->DPTEBytesPerRow[i][j][k] / PTEEfficiency + / NormalEfficiency / v->ReturnBusWidth + 2 * v->MetaRowBytes[i][j][k] / NormalEfficiency / v->ReturnBusWidth + PixelDCFCLKCyclesRequiredInPrefetch[k]; + PrefetchPixelLinesTime[k] = dml_max(v->PrefetchLinesY[i][j][k], v->PrefetchLinesC[i][j][k]) * v->HTotal[k] / v->PixelClock[k]; + ExpectedPrefetchBWAcceleration = (v->VActivePixelBandwidth[i][j][k] + v->VActiveCursorBandwidth[i][j][k]) / (v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k]); + DynamicMetadataVMExtraLatency[k] = (v->GPUVMEnable == true && v->DynamicMetadataEnable[k] == true && v->DynamicMetadataVMEnabled == true) ? + v->UrgLatency[i] * v->GPUVMMaxPageTableLevels * (v->HostVMEnable == true ? v->HostVMMaxNonCachedPageTableLevels + 1 : 1) : 0; + PrefetchTime = (v->MaximumVStartup[i][j][k] - 1) * v->HTotal[k] / v->PixelClock[k] - MinimumTWait - v->UrgLatency[i] * ((v->GPUVMMaxPageTableLevels <= 2 ? v->GPUVMMaxPageTableLevels + : v->GPUVMMaxPageTableLevels - 2) * (v->HostVMEnable == true ? v->HostVMMaxNonCachedPageTableLevels + 1 : 1) - 1) - DynamicMetadataVMExtraLatency[k]; if (PrefetchTime > 0) { double ExpectedVRatioPrefetch = { 0 }; ExpectedVRatioPrefetch = PrefetchPixelLinesTime[k] / (PrefetchTime * PixelDCFCLKCyclesRequiredInPrefetch[k] / DCFCLKCyclesRequiredInPrefetch); DCFCLKRequiredForPeakBandwidthPerPlane[k] = NoOfDPPState[k] * PixelDCFCLKCyclesRequiredInPrefetch[k] / PrefetchPixelLinesTime[k] * dml_max(1.0, ExpectedVRatioPrefetch) * dml_max(1.0, ExpectedVRatioPrefetch / 4) * ExpectedPrefetchBWAcceleration; - if (HostVMEnable == true || ImmediateFlipRequirement == dm_immediate_flip_required) { + if (v->HostVMEnable == true || v->ImmediateFlipRequirement[0] == dm_immediate_flip_required) { DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKRequiredForPeakBandwidthPerPlane[k] - + NoOfDPPState[k] * DPTEBandwidth / PTEEfficiency / NormalEfficiency / ReturnBusWidth; + + NoOfDPPState[k] * DPTEBandwidth / PTEEfficiency / NormalEfficiency / v->ReturnBusWidth; } } else { - DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKPerState[i]; + DCFCLKRequiredForPeakBandwidthPerPlane[k] = v->DCFCLKPerState[i]; } - if (DynamicMetadataEnable[k] == true) { + if (v->DynamicMetadataEnable[k] == true) { double TsetupPipe = { 0 }; double TdmbfPipe = { 0 }; double TdmsksPipe = { 0 }; @@ -6757,49 +6588,49 @@ static void UseMinimumDCFCLK( double AllowedTimeForUrgentExtraLatency = { 0 }; CalculateDynamicMetadataParameters( - MaxInterDCNTileRepeaters, - RequiredDPPCLK[i][j][k], - RequiredDISPCLK[i][j], - ProjectedDCFCLKDeepSleep[i][j], - PixelClock[k], - HTotal[k], - VTotal[k] - VActive[k], - DynamicMetadataTransmittedBytes[k], - DynamicMetadataLinesBeforeActiveRequired[k], - Interlace[k], - ProgressiveToInterlaceUnitInOPP, + v->MaxInterDCNTileRepeaters, + v->RequiredDPPCLK[i][j][k], + v->RequiredDISPCLK[i][j], + v->ProjectedDCFCLKDeepSleep[i][j], + v->PixelClock[k], + v->HTotal[k], + v->VTotal[k] - v->VActive[k], + v->DynamicMetadataTransmittedBytes[k], + v->DynamicMetadataLinesBeforeActiveRequired[k], + v->Interlace[k], + v->ProgressiveToInterlaceUnitInOPP, &TsetupPipe, &TdmbfPipe, &TdmecPipe, &TdmsksPipe); - AllowedTimeForUrgentExtraLatency = MaximumVStartup[i][j][k] * HTotal[k] / PixelClock[k] - MinimumTWait - TsetupPipe + AllowedTimeForUrgentExtraLatency = v->MaximumVStartup[i][j][k] * v->HTotal[k] / v->PixelClock[k] - MinimumTWait - TsetupPipe - TdmbfPipe - TdmecPipe - TdmsksPipe - DynamicMetadataVMExtraLatency[k]; if (AllowedTimeForUrgentExtraLatency > 0) { DCFCLKRequiredForPeakBandwidthPerPlane[k] = dml_max(DCFCLKRequiredForPeakBandwidthPerPlane[k], ExtraLatencyCycles / AllowedTimeForUrgentExtraLatency); } else { - DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKPerState[i]; + DCFCLKRequiredForPeakBandwidthPerPlane[k] = v->DCFCLKPerState[i]; } } } DCFCLKRequiredForPeakBandwidth = 0; - for (k = 0; k <= NumberOfActivePlanes - 1; ++k) { + for (k = 0; k <= v->NumberOfActivePlanes - 1; ++k) { DCFCLKRequiredForPeakBandwidth = DCFCLKRequiredForPeakBandwidth + DCFCLKRequiredForPeakBandwidthPerPlane[k]; } - MinimumTvmPlus2Tr0 = UrgLatency[i] * (GPUVMEnable == true ? (HostVMEnable == true ? - (GPUVMMaxPageTableLevels + 2) * (HostVMMaxNonCachedPageTableLevels + 1) - 1 : GPUVMMaxPageTableLevels + 1) : 0); - for (k = 0; k < NumberOfActivePlanes; ++k) { + MinimumTvmPlus2Tr0 = v->UrgLatency[i] * (v->GPUVMEnable == true ? (v->HostVMEnable == true ? + (v->GPUVMMaxPageTableLevels + 2) * (v->HostVMMaxNonCachedPageTableLevels + 1) - 1 : v->GPUVMMaxPageTableLevels + 1) : 0); + for (k = 0; k < v->NumberOfActivePlanes; ++k) { double MaximumTvmPlus2Tr0PlusTsw = { 0 }; - MaximumTvmPlus2Tr0PlusTsw = (MaximumVStartup[i][j][k] - 2) * HTotal[k] / PixelClock[k] - MinimumTWait - DynamicMetadataVMExtraLatency[k]; + MaximumTvmPlus2Tr0PlusTsw = (v->MaximumVStartup[i][j][k] - 2) * v->HTotal[k] / v->PixelClock[k] - MinimumTWait - DynamicMetadataVMExtraLatency[k]; if (MaximumTvmPlus2Tr0PlusTsw <= MinimumTvmPlus2Tr0 + PrefetchPixelLinesTime[k] / 4) { - DCFCLKRequiredForPeakBandwidth = DCFCLKPerState[i]; + DCFCLKRequiredForPeakBandwidth = v->DCFCLKPerState[i]; } else { DCFCLKRequiredForPeakBandwidth = dml_max3(DCFCLKRequiredForPeakBandwidth, 2 * ExtraLatencyCycles / (MaximumTvmPlus2Tr0PlusTsw - MinimumTvmPlus2Tr0 - PrefetchPixelLinesTime[k] / 4), (2 * ExtraLatencyCycles + PixelDCFCLKCyclesRequiredInPrefetch[k]) / (MaximumTvmPlus2Tr0PlusTsw - MinimumTvmPlus2Tr0)); } } - DCFCLKState[i][j] = dml_min(DCFCLKPerState[i], 1.05 * (1 + mode_lib->vba.PercentMarginOverMinimumRequiredDCFCLK / 100) + v->DCFCLKState[i][j] = dml_min(v->DCFCLKPerState[i], 1.05 * (1 + mode_lib->vba.PercentMarginOverMinimumRequiredDCFCLK / 100) * dml_max(DCFCLKRequiredForAverageBandwidth, DCFCLKRequiredForPeakBandwidth)); } } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c index d211cf6d234c..241d28d0b7fb 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c @@ -322,6 +322,7 @@ static void calculate_wm_set_for_vlevel(int vlevel, void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) { + struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits; struct dcn301_resource_pool *pool = TO_DCN301_RES_POOL(dc->res_pool); struct clk_limit_table *clk_table = &bw_params->clk_table; unsigned int i, closest_clk_lvl; @@ -329,8 +330,7 @@ void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param dc_assert_fp_enabled(); - memcpy(&dcn3_01_soc._clock_tmp, &dcn3_01_soc.clock_limits, - sizeof(dcn3_01_soc.clock_limits)); + memcpy(s, dcn3_01_soc.clock_limits, sizeof(dcn3_01_soc.clock_limits)); /* Default clock levels are used for diags, which may lead to overclocking. */ if (!IS_DIAG_DC(dc->ctx->dce_environment)) { @@ -348,31 +348,33 @@ void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param } } - dcn3_01_soc._clock_tmp[i].state = i; - dcn3_01_soc._clock_tmp[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; - dcn3_01_soc._clock_tmp[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; - dcn3_01_soc._clock_tmp[i].socclk_mhz = clk_table->entries[i].socclk_mhz; - dcn3_01_soc._clock_tmp[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; - - dcn3_01_soc._clock_tmp[i].dispclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz; - dcn3_01_soc._clock_tmp[i].dppclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz; - dcn3_01_soc._clock_tmp[i].dram_bw_per_chan_gbps = dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; - dcn3_01_soc._clock_tmp[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz; - dcn3_01_soc._clock_tmp[i].dtbclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; - dcn3_01_soc._clock_tmp[i].phyclk_d18_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; - dcn3_01_soc._clock_tmp[i].phyclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_mhz; + s[i].state = i; + s[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; + s[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; + s[i].socclk_mhz = clk_table->entries[i].socclk_mhz; + s[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; + + s[i].dispclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz; + s[i].dppclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz; + s[i].dram_bw_per_chan_gbps = + dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; + s[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz; + s[i].dtbclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; + s[i].phyclk_d18_mhz = + dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; + s[i].phyclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_mhz; } if (clk_table->num_entries) { dcn3_01_soc.num_states = clk_table->num_entries; /* duplicate last level */ - dcn3_01_soc._clock_tmp[dcn3_01_soc.num_states] = dcn3_01_soc.clock_limits[dcn3_01_soc.num_states - 1]; - dcn3_01_soc._clock_tmp[dcn3_01_soc.num_states].state = dcn3_01_soc.num_states; + s[dcn3_01_soc.num_states] = + dcn3_01_soc.clock_limits[dcn3_01_soc.num_states - 1]; + s[dcn3_01_soc.num_states].state = dcn3_01_soc.num_states; } } - memcpy(&dcn3_01_soc.clock_limits, &dcn3_01_soc._clock_tmp, - sizeof(dcn3_01_soc.clock_limits)); + memcpy(dcn3_01_soc.clock_limits, s, sizeof(dcn3_01_soc.clock_limits)); dcn3_01_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c index 149a1b17cdf3..0e62eb823e34 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c @@ -597,14 +597,14 @@ void dcn31_calculate_wm_and_dlg_fp( void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) { + struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits; struct clk_limit_table *clk_table = &bw_params->clk_table; unsigned int i, closest_clk_lvl; int j; dc_assert_fp_enabled(); - memcpy(&dcn3_1_soc._clock_tmp, &dcn3_1_soc.clock_limits, - sizeof(dcn3_1_soc.clock_limits)); + memcpy(s, dcn3_1_soc.clock_limits, sizeof(dcn3_1_soc.clock_limits)); // Default clock levels are used for diags, which may lead to overclocking. if (!IS_DIAG_DC(dc->ctx->dce_environment)) { @@ -633,34 +633,36 @@ void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params } } - dcn3_1_soc._clock_tmp[i].state = i; + s[i].state = i; /* Clocks dependent on voltage level. */ - dcn3_1_soc._clock_tmp[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; - dcn3_1_soc._clock_tmp[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; - dcn3_1_soc._clock_tmp[i].socclk_mhz = clk_table->entries[i].socclk_mhz; - dcn3_1_soc._clock_tmp[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio; + s[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; + s[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; + s[i].socclk_mhz = clk_table->entries[i].socclk_mhz; + s[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * + 2 * clk_table->entries[i].wck_ratio; /* Clocks independent of voltage level. */ - dcn3_1_soc._clock_tmp[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz : + s[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz : dcn3_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; - dcn3_1_soc._clock_tmp[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz : + s[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz : dcn3_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; - dcn3_1_soc._clock_tmp[i].dram_bw_per_chan_gbps = dcn3_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; - dcn3_1_soc._clock_tmp[i].dscclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; - dcn3_1_soc._clock_tmp[i].dtbclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; - dcn3_1_soc._clock_tmp[i].phyclk_d18_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; - dcn3_1_soc._clock_tmp[i].phyclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; + s[i].dram_bw_per_chan_gbps = + dcn3_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; + s[i].dscclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; + s[i].dtbclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; + s[i].phyclk_d18_mhz = + dcn3_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; + s[i].phyclk_mhz = dcn3_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; } if (clk_table->num_entries) { dcn3_1_soc.num_states = clk_table->num_entries; } } - memcpy(&dcn3_1_soc.clock_limits, &dcn3_1_soc._clock_tmp, - sizeof(dcn3_1_soc.clock_limits)); + memcpy(dcn3_1_soc.clock_limits, s, sizeof(dcn3_1_soc.clock_limits)); dcn3_1_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; @@ -727,6 +729,7 @@ void dcn315_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param void dcn316_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) { + struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits; struct clk_limit_table *clk_table = &bw_params->clk_table; unsigned int i, closest_clk_lvl; int max_dispclk_mhz = 0, max_dppclk_mhz = 0; @@ -734,8 +737,7 @@ void dcn316_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param dc_assert_fp_enabled(); - memcpy(&dcn3_16_soc._clock_tmp, &dcn3_16_soc.clock_limits, - sizeof(dcn3_16_soc.clock_limits)); + memcpy(s, dcn3_16_soc.clock_limits, sizeof(dcn3_16_soc.clock_limits)); // Default clock levels are used for diags, which may lead to overclocking. if (!IS_DIAG_DC(dc->ctx->dce_environment)) { @@ -757,7 +759,8 @@ void dcn316_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param for (i = 0; i < clk_table->num_entries; i++) { /* loop backwards*/ for (closest_clk_lvl = 0, j = dcn3_16_soc.num_states - 1; j >= 0; j--) { - if ((unsigned int) dcn3_16_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { + if ((unsigned int) dcn3_16_soc.clock_limits[j].dcfclk_mhz <= + clk_table->entries[i].dcfclk_mhz) { closest_clk_lvl = j; break; } @@ -768,39 +771,43 @@ void dcn316_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param closest_clk_lvl = dcn3_16_soc.num_states - 1; } - dcn3_16_soc._clock_tmp[i].state = i; + s[i].state = i; /* Clocks dependent on voltage level. */ - dcn3_16_soc._clock_tmp[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; + s[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; if (clk_table->num_entries == 1 && - dcn3_16_soc._clock_tmp[i].dcfclk_mhz < dcn3_16_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) { + s[i].dcfclk_mhz < + dcn3_16_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) { /*SMU fix not released yet*/ - dcn3_16_soc._clock_tmp[i].dcfclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dcfclk_mhz; + s[i].dcfclk_mhz = + dcn3_16_soc.clock_limits[closest_clk_lvl].dcfclk_mhz; } - dcn3_16_soc._clock_tmp[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; - dcn3_16_soc._clock_tmp[i].socclk_mhz = clk_table->entries[i].socclk_mhz; - dcn3_16_soc._clock_tmp[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio; + s[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; + s[i].socclk_mhz = clk_table->entries[i].socclk_mhz; + s[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * + 2 * clk_table->entries[i].wck_ratio; /* Clocks independent of voltage level. */ - dcn3_16_soc._clock_tmp[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz : + s[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz : dcn3_16_soc.clock_limits[closest_clk_lvl].dispclk_mhz; - dcn3_16_soc._clock_tmp[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz : + s[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz : dcn3_16_soc.clock_limits[closest_clk_lvl].dppclk_mhz; - dcn3_16_soc._clock_tmp[i].dram_bw_per_chan_gbps = dcn3_16_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; - dcn3_16_soc._clock_tmp[i].dscclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dscclk_mhz; - dcn3_16_soc._clock_tmp[i].dtbclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; - dcn3_16_soc._clock_tmp[i].phyclk_d18_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; - dcn3_16_soc._clock_tmp[i].phyclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_mhz; + s[i].dram_bw_per_chan_gbps = + dcn3_16_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; + s[i].dscclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dscclk_mhz; + s[i].dtbclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; + s[i].phyclk_d18_mhz = + dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; + s[i].phyclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_mhz; } if (clk_table->num_entries) { dcn3_16_soc.num_states = clk_table->num_entries; } } - memcpy(&dcn3_16_soc.clock_limits, &dcn3_16_soc._clock_tmp, - sizeof(dcn3_16_soc.clock_limits)); + memcpy(dcn3_16_soc.clock_limits, s, sizeof(dcn3_16_soc.clock_limits)); if (max_dispclk_mhz) { dcn3_16_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c index 8118cfc5b405..7f6c977c4981 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c @@ -560,6 +560,7 @@ static bool dcn32_assign_subvp_pipe(struct dc *dc, bool valid_assignment_found = false; unsigned int free_pipes = dcn32_get_num_free_pipes(dc, context); bool current_assignment_freesync = false; + struct vba_vars_st *vba = &context->bw_ctx.dml.vba; for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; @@ -573,8 +574,15 @@ static bool dcn32_assign_subvp_pipe(struct dc *dc, refresh_rate = (pipe->stream->timing.pix_clk_100hz * 100 + pipe->stream->timing.v_total * pipe->stream->timing.h_total - 1) / (double)(pipe->stream->timing.v_total * pipe->stream->timing.h_total); + /* SubVP pipe candidate requirements: + * - Refresh rate < 120hz + * - Not able to switch in vactive naturally (switching in active means the + * DET provides enough buffer to hide the P-State switch latency -- trying + * to combine this with SubVP can cause issues with the scheduling). + */ if (pipe->plane_state && !pipe->top_pipe && - pipe->stream->mall_stream_config.type == SUBVP_NONE && refresh_rate < 120) { + pipe->stream->mall_stream_config.type == SUBVP_NONE && refresh_rate < 120 && + vba->ActiveDRAMClockChangeLatencyMarginPerState[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]] <= 0) { while (pipe) { num_pipes++; pipe = pipe->bottom_pipe; @@ -998,8 +1006,10 @@ static void dcn32_full_validate_bw_helper(struct dc *dc, *vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, *pipe_cnt); /* This may adjust vlevel and maxMpcComb */ - if (*vlevel < context->bw_ctx.dml.soc.num_states) + if (*vlevel < context->bw_ctx.dml.soc.num_states) { *vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, *vlevel, split, merge); + vba->VoltageLevel = *vlevel; + } /* Conditions for setting up phantom pipes for SubVP: * 1. Not force disable SubVP @@ -1014,6 +1024,15 @@ static void dcn32_full_validate_bw_helper(struct dc *dc, dc->debug.force_subvp_mclk_switch)) { dcn32_merge_pipes_for_subvp(dc, context); + // to re-initialize viewport after the pipe merge + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; + + if (!pipe_ctx->plane_state || !pipe_ctx->stream) + continue; + + resource_build_scaling_params(pipe_ctx); + } while (!found_supported_config && dcn32_enough_pipes_for_subvp(dc, context) && dcn32_assign_subvp_pipe(dc, context, &dc_pipe_idx)) { @@ -1082,11 +1101,19 @@ static void dcn32_full_validate_bw_helper(struct dc *dc, dc->res_pool->funcs->remove_phantom_pipes(dc, context); vba->DRAMClockChangeSupport[*vlevel][vba->maxMpcComb] = dm_dram_clock_change_unsupported; *pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, false); + + *vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, *pipe_cnt); + /* This may adjust vlevel and maxMpcComb */ + if (*vlevel < context->bw_ctx.dml.soc.num_states) { + *vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, *vlevel, split, merge); + vba->VoltageLevel = *vlevel; + } } else { // only call dcn20_validate_apply_pipe_split_flags if we found a supported config memset(split, 0, MAX_PIPES * sizeof(int)); memset(merge, 0, MAX_PIPES * sizeof(bool)); *vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, *vlevel, split, merge); + vba->VoltageLevel = *vlevel; // Most populate phantom DLG params before programming hardware / timing for phantom pipe DC_FP_START(); @@ -1416,6 +1443,8 @@ bool dcn32_internal_validate_bw(struct dc *dc, memset(split, 0, sizeof(split)); memset(merge, 0, sizeof(merge)); vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge); + // dcn20_validate_apply_pipe_split_flags can modify voltage level outside of DML + vba->VoltageLevel = vlevel; } } @@ -1776,7 +1805,11 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; context->bw_ctx.bw.dcn.watermarks.c.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.fclk_pstate_change_ns = get_fclk_watermark(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + /* On DCN32/321, PMFW will set PSTATE_CHANGE_TYPE = 1 (FCLK) for UCLK dummy p-state. + * In this case we must program FCLK WM Set C to use the UCLK dummy p-state WM + * value. + */ + context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.fclk_pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; context->bw_ctx.bw.dcn.watermarks.c.usr_retraining_ns = get_usr_retraining_watermark(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; if ((!pstate_en) && (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid)) { @@ -2136,13 +2169,16 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) { if (bb_info.dram_clock_change_latency_100ns > 0) - dcn3_2_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10; + dcn3_2_soc.dram_clock_change_latency_us = + bb_info.dram_clock_change_latency_100ns * 10; - if (bb_info.dram_sr_enter_exit_latency_100ns > 0) - dcn3_2_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10; + if (bb_info.dram_sr_enter_exit_latency_100ns > 0) + dcn3_2_soc.sr_enter_plus_exit_time_us = + bb_info.dram_sr_enter_exit_latency_100ns * 10; - if (bb_info.dram_sr_exit_latency_100ns > 0) - dcn3_2_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10; + if (bb_info.dram_sr_exit_latency_100ns > 0) + dcn3_2_soc.sr_exit_time_us = + bb_info.dram_sr_exit_latency_100ns * 10; } } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c index cb2025771646..d8014bfbc3fe 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c @@ -677,9 +677,9 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman dml_ceil((double) v->WritebackDelay[mode_lib->vba.VoltageLevel][k] / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), 1)); - // Clamp to max OTG vstartup register limit - if (v->MaxVStartupLines[k] > 1023) - v->MaxVStartupLines[k] = 1023; + // Clamp to max OTG vstartup register limit + if (v->MaxVStartupLines[k] > 1023) + v->MaxVStartupLines[k] = 1023; #ifdef __DML_VBA_DEBUG__ dml_print("DML::%s: k=%d MaxVStartupLines = %d\n", __func__, k, v->MaxVStartupLines[k]); @@ -2045,6 +2045,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading, mode_lib->vba.DISPCLKRampingMargin, mode_lib->vba.DISPCLKDPPCLKVCOSpeed, + mode_lib->vba.NumberOfDSCSlices[k], /* Output */ &v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.TotalAvailablePipesSupportNoDSC, @@ -2066,6 +2067,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading, mode_lib->vba.DISPCLKRampingMargin, mode_lib->vba.DISPCLKDPPCLKVCOSpeed, + mode_lib->vba.NumberOfDSCSlices[k], /* Output */ &v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.TotalAvailablePipesSupportDSC, @@ -3615,7 +3617,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l &mode_lib->vba.FCLKChangeSupport[i][j], &v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.dummy_single2[1], // double *MinActiveFCLKChangeLatencySupported &mode_lib->vba.USRRetrainingSupport[i][j], - mode_lib->vba.ActiveDRAMClockChangeLatencyMargin); + mode_lib->vba.ActiveDRAMClockChangeLatencyMarginPerState[i][j]); } } } // End of Prefetch Check diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c index 05fc14a47fba..dc501ee7d01a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c @@ -1193,6 +1193,7 @@ void dml32_CalculateODMMode( double DISPCLKDPPCLKDSCCLKDownSpreading, double DISPCLKRampingMargin, double DISPCLKDPPCLKVCOSpeed, + unsigned int NumberOfDSCSlices, /* Output */ bool *TotalAvailablePipesSupport, @@ -1228,7 +1229,8 @@ void dml32_CalculateODMMode( if (!(Output == dm_hdmi || Output == dm_dp || Output == dm_edp) && (ODMUse == dm_odm_combine_policy_4to1 || ((SurfaceRequiredDISPCLKWithODMCombineTwoToOne > StateDispclk || - (DSCEnable && (HActive > 2 * MaximumPixelsPerLinePerDSCUnit)))))) { + (DSCEnable && (HActive > 2 * MaximumPixelsPerLinePerDSCUnit)) + || NumberOfDSCSlices > 8)))) { if (TotalNumberOfActiveDPP + 4 <= MaxNumDPP) { *ODMMode = dm_odm_combine_mode_4to1; *RequiredDISPCLKPerSurface = SurfaceRequiredDISPCLKWithODMCombineFourToOne; @@ -1239,7 +1241,8 @@ void dml32_CalculateODMMode( } else if (Output != dm_hdmi && (ODMUse == dm_odm_combine_policy_2to1 || (((SurfaceRequiredDISPCLKWithoutODMCombine > StateDispclk && SurfaceRequiredDISPCLKWithODMCombineTwoToOne <= StateDispclk) || - (DSCEnable && (HActive > MaximumPixelsPerLinePerDSCUnit)))))) { + (DSCEnable && (HActive > MaximumPixelsPerLinePerDSCUnit)) + || (NumberOfDSCSlices <= 8 && NumberOfDSCSlices > 4))))) { if (TotalNumberOfActiveDPP + 2 <= MaxNumDPP) { *ODMMode = dm_odm_combine_mode_2to1; *RequiredDISPCLKPerSurface = SurfaceRequiredDISPCLKWithODMCombineTwoToOne; @@ -4277,7 +4280,7 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport( double ActiveClockChangeLatencyHidingY; double ActiveClockChangeLatencyHidingC; double ActiveClockChangeLatencyHiding; - double EffectiveDETBufferSizeY; + double EffectiveDETBufferSizeY; double ActiveFCLKChangeLatencyMargin[DC__NUM_DPP__MAX]; double USRRetrainingLatencyMargin[DC__NUM_DPP__MAX]; double TotalPixelBW = 0.0; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h index d293856ba906..626f6605e2d5 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h @@ -226,6 +226,7 @@ void dml32_CalculateODMMode( double DISPCLKDPPCLKDSCCLKDownSpreading, double DISPCLKRampingMargin, double DISPCLKDPPCLKVCOSpeed, + unsigned int NumberOfDSCSlices, /* Output */ bool *TotalAvailablePipesSupport, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c index c87091683b5d..7ebf25e87933 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c @@ -518,13 +518,16 @@ void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_p if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) { if (bb_info.dram_clock_change_latency_100ns > 0) - dcn3_21_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10; + dcn3_21_soc.dram_clock_change_latency_us = + bb_info.dram_clock_change_latency_100ns * 10; - if (bb_info.dram_sr_enter_exit_latency_100ns > 0) - dcn3_21_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10; + if (bb_info.dram_sr_enter_exit_latency_100ns > 0) + dcn3_21_soc.sr_enter_plus_exit_time_us = + bb_info.dram_sr_enter_exit_latency_100ns * 10; - if (bb_info.dram_sr_exit_latency_100ns > 0) - dcn3_21_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10; + if (bb_info.dram_sr_exit_latency_100ns > 0) + dcn3_21_soc.sr_exit_time_us = + bb_info.dram_sr_exit_latency_100ns * 10; } } diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h index e8b094006d95..c596187a1e09 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h @@ -26,6 +26,16 @@ #include "dc_features.h" #include "display_mode_enums.h" +/** + * DOC: overview + * + * Most of the DML code is automatically generated and tested via hardware + * description language. Usually, we use the reference _vcs_dpi in the code + * where VCS means "Verilog Compiled Simulator" and DPI stands for "Direct + * Programmer Interface". In other words, those structs can be used to + * interface with Verilog with other languages such as C. + */ + #ifndef __DISPLAY_MODE_STRUCTS_H__ #define __DISPLAY_MODE_STRUCTS_H__ @@ -159,13 +169,20 @@ struct _vcs_dpi_voltage_scaling_st { double dtbclk_mhz; }; +/** + * _vcs_dpi_soc_bounding_box_st: SOC definitions + * + * This struct maintains the SOC Bounding Box information for the ASIC; it + * defines things such as clock, voltage, performance, etc. Usually, we load + * these values from VBIOS; if something goes wrong, we use some hard-coded + * values, which will enable the ASIC to light up with limitations. + */ struct _vcs_dpi_soc_bounding_box_st { struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES]; - /* - * This is a temporary stash for updating @clock_limits with the PMFW - * clock table. Do not use outside of *update_bw_boudning_box functions. + /** + * @num_states: It represents the total of Display Power Management + * (DPM) supported by the specific ASIC. */ - struct _vcs_dpi_voltage_scaling_st _clock_tmp[DC__VOLTAGE_STATES]; unsigned int num_states; double sr_exit_time_us; double sr_enter_plus_exit_time_us; @@ -231,6 +248,14 @@ struct _vcs_dpi_soc_bounding_box_st { enum self_refresh_affinity allow_dram_self_refresh_or_dram_clock_change_in_vblank; }; +/** + * @_vcs_dpi_ip_params_st: IP configuraion for DCN blocks + * + * In this struct you can find the DCN configuration associated to the specific + * ASIC. For example, here we can save how many DPPs the ASIC is using and it + * is available. + * + */ struct _vcs_dpi_ip_params_st { bool use_min_dcfclk; bool clamp_min_dcfclk; @@ -283,6 +308,9 @@ struct _vcs_dpi_ip_params_st { unsigned int writeback_line_buffer_chroma_buffer_size; unsigned int max_page_table_levels; + /** + * @max_num_dpp: Maximum number of DPP supported in the target ASIC. + */ unsigned int max_num_dpp; unsigned int max_num_otg; unsigned int cursor_chunk_size; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h index 492aec634b68..da8acf59ccac 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h @@ -312,6 +312,7 @@ struct vba_vars_st { unsigned int ActiveDPPs; unsigned int LBLatencyHidingSourceLinesY; unsigned int LBLatencyHidingSourceLinesC; + double ActiveDRAMClockChangeLatencyMarginPerState[DC__VOLTAGE_STATES][2][DC__NUM_DPP__MAX];// DML doesn't save active margin per state double ActiveDRAMClockChangeLatencyMargin[DC__NUM_DPP__MAX]; double CachedActiveDRAMClockChangeLatencyMargin[DC__NUM_DPP__MAX]; // Cache in dml_get_voltage_level for debug purposes only double MinActiveDRAMClockChangeMargin; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c deleted file mode 100644 index b4b51e51fc25..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c +++ /dev/null @@ -1,1884 +0,0 @@ -/* - * Copyright 2017 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#include "resource.h" -#include "core_types.h" -#include "dsc.h" -#include "clk_mgr.h" - -#ifndef DC_LOGGER_INIT -#define DC_LOGGER_INIT -#undef DC_LOG_WARNING -#define DC_LOG_WARNING -#endif - -#define DML_WRAPPER_TRANSLATION_ -#include "dml_wrapper_translation.c" -#undef DML_WRAPPER_TRANSLATION_ - -static bool is_dual_plane(enum surface_pixel_format format) -{ - return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA; -} - -static void build_clamping_params(struct dc_stream_state *stream) -{ - stream->clamping.clamping_level = CLAMPING_FULL_RANGE; - stream->clamping.c_depth = stream->timing.display_color_depth; - stream->clamping.pixel_encoding = stream->timing.pixel_encoding; -} - -static void get_pixel_clock_parameters( - const struct pipe_ctx *pipe_ctx, - struct pixel_clk_params *pixel_clk_params) -{ - const struct dc_stream_state *stream = pipe_ctx->stream; - - /*TODO: is this halved for YCbCr 420? in that case we might want to move - * the pixel clock normalization for hdmi up to here instead of doing it - * in pll_adjust_pix_clk - */ - pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz; - pixel_clk_params->encoder_object_id = stream->link->link_enc->id; - pixel_clk_params->signal_type = pipe_ctx->stream->signal; - pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1; - /* TODO: un-hardcode*/ - pixel_clk_params->requested_sym_clk = LINK_RATE_LOW * - LINK_RATE_REF_FREQ_IN_KHZ; - pixel_clk_params->flags.ENABLE_SS = 0; - pixel_clk_params->color_depth = - stream->timing.display_color_depth; - pixel_clk_params->flags.DISPLAY_BLANKED = 1; - pixel_clk_params->flags.SUPPORT_YCBCR420 = (stream->timing.pixel_encoding == - PIXEL_ENCODING_YCBCR420); - pixel_clk_params->pixel_encoding = stream->timing.pixel_encoding; - if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422) { - pixel_clk_params->color_depth = COLOR_DEPTH_888; - } - if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) { - pixel_clk_params->requested_pix_clk_100hz = pixel_clk_params->requested_pix_clk_100hz / 2; - } - if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING) - pixel_clk_params->requested_pix_clk_100hz *= 2; - -} - -static void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream, - struct bit_depth_reduction_params *fmt_bit_depth) -{ - enum dc_dither_option option = stream->dither_option; - enum dc_pixel_encoding pixel_encoding = - stream->timing.pixel_encoding; - - memset(fmt_bit_depth, 0, sizeof(*fmt_bit_depth)); - - if (option == DITHER_OPTION_DEFAULT) { - switch (stream->timing.display_color_depth) { - case COLOR_DEPTH_666: - option = DITHER_OPTION_SPATIAL6; - break; - case COLOR_DEPTH_888: - option = DITHER_OPTION_SPATIAL8; - break; - case COLOR_DEPTH_101010: - option = DITHER_OPTION_SPATIAL10; - break; - default: - option = DITHER_OPTION_DISABLE; - } - } - - if (option == DITHER_OPTION_DISABLE) - return; - - if (option == DITHER_OPTION_TRUN6) { - fmt_bit_depth->flags.TRUNCATE_ENABLED = 1; - fmt_bit_depth->flags.TRUNCATE_DEPTH = 0; - } else if (option == DITHER_OPTION_TRUN8 || - option == DITHER_OPTION_TRUN8_SPATIAL6 || - option == DITHER_OPTION_TRUN8_FM6) { - fmt_bit_depth->flags.TRUNCATE_ENABLED = 1; - fmt_bit_depth->flags.TRUNCATE_DEPTH = 1; - } else if (option == DITHER_OPTION_TRUN10 || - option == DITHER_OPTION_TRUN10_SPATIAL6 || - option == DITHER_OPTION_TRUN10_SPATIAL8 || - option == DITHER_OPTION_TRUN10_FM8 || - option == DITHER_OPTION_TRUN10_FM6 || - option == DITHER_OPTION_TRUN10_SPATIAL8_FM6) { - fmt_bit_depth->flags.TRUNCATE_ENABLED = 1; - fmt_bit_depth->flags.TRUNCATE_DEPTH = 2; - } - - /* special case - Formatter can only reduce by 4 bits at most. - * When reducing from 12 to 6 bits, - * HW recommends we use trunc with round mode - * (if we did nothing, trunc to 10 bits would be used) - * note that any 12->10 bit reduction is ignored prior to DCE8, - * as the input was 10 bits. - */ - if (option == DITHER_OPTION_SPATIAL6_FRAME_RANDOM || - option == DITHER_OPTION_SPATIAL6 || - option == DITHER_OPTION_FM6) { - fmt_bit_depth->flags.TRUNCATE_ENABLED = 1; - fmt_bit_depth->flags.TRUNCATE_DEPTH = 2; - fmt_bit_depth->flags.TRUNCATE_MODE = 1; - } - - /* spatial dither - * note that spatial modes 1-3 are never used - */ - if (option == DITHER_OPTION_SPATIAL6_FRAME_RANDOM || - option == DITHER_OPTION_SPATIAL6 || - option == DITHER_OPTION_TRUN10_SPATIAL6 || - option == DITHER_OPTION_TRUN8_SPATIAL6) { - fmt_bit_depth->flags.SPATIAL_DITHER_ENABLED = 1; - fmt_bit_depth->flags.SPATIAL_DITHER_DEPTH = 0; - fmt_bit_depth->flags.HIGHPASS_RANDOM = 1; - fmt_bit_depth->flags.RGB_RANDOM = - (pixel_encoding == PIXEL_ENCODING_RGB) ? 1 : 0; - } else if (option == DITHER_OPTION_SPATIAL8_FRAME_RANDOM || - option == DITHER_OPTION_SPATIAL8 || - option == DITHER_OPTION_SPATIAL8_FM6 || - option == DITHER_OPTION_TRUN10_SPATIAL8 || - option == DITHER_OPTION_TRUN10_SPATIAL8_FM6) { - fmt_bit_depth->flags.SPATIAL_DITHER_ENABLED = 1; - fmt_bit_depth->flags.SPATIAL_DITHER_DEPTH = 1; - fmt_bit_depth->flags.HIGHPASS_RANDOM = 1; - fmt_bit_depth->flags.RGB_RANDOM = - (pixel_encoding == PIXEL_ENCODING_RGB) ? 1 : 0; - } else if (option == DITHER_OPTION_SPATIAL10_FRAME_RANDOM || - option == DITHER_OPTION_SPATIAL10 || - option == DITHER_OPTION_SPATIAL10_FM8 || - option == DITHER_OPTION_SPATIAL10_FM6) { - fmt_bit_depth->flags.SPATIAL_DITHER_ENABLED = 1; - fmt_bit_depth->flags.SPATIAL_DITHER_DEPTH = 2; - fmt_bit_depth->flags.HIGHPASS_RANDOM = 1; - fmt_bit_depth->flags.RGB_RANDOM = - (pixel_encoding == PIXEL_ENCODING_RGB) ? 1 : 0; - } - - if (option == DITHER_OPTION_SPATIAL6 || - option == DITHER_OPTION_SPATIAL8 || - option == DITHER_OPTION_SPATIAL10) { - fmt_bit_depth->flags.FRAME_RANDOM = 0; - } else { - fmt_bit_depth->flags.FRAME_RANDOM = 1; - } - - ////////////////////// - //// temporal dither - ////////////////////// - if (option == DITHER_OPTION_FM6 || - option == DITHER_OPTION_SPATIAL8_FM6 || - option == DITHER_OPTION_SPATIAL10_FM6 || - option == DITHER_OPTION_TRUN10_FM6 || - option == DITHER_OPTION_TRUN8_FM6 || - option == DITHER_OPTION_TRUN10_SPATIAL8_FM6) { - fmt_bit_depth->flags.FRAME_MODULATION_ENABLED = 1; - fmt_bit_depth->flags.FRAME_MODULATION_DEPTH = 0; - } else if (option == DITHER_OPTION_FM8 || - option == DITHER_OPTION_SPATIAL10_FM8 || - option == DITHER_OPTION_TRUN10_FM8) { - fmt_bit_depth->flags.FRAME_MODULATION_ENABLED = 1; - fmt_bit_depth->flags.FRAME_MODULATION_DEPTH = 1; - } else if (option == DITHER_OPTION_FM10) { - fmt_bit_depth->flags.FRAME_MODULATION_ENABLED = 1; - fmt_bit_depth->flags.FRAME_MODULATION_DEPTH = 2; - } - - fmt_bit_depth->pixel_encoding = pixel_encoding; -} - -/* Move this after the above function as VS complains about - * declaration issues for resource_build_bit_depth_reduction_params. - */ - -static enum dc_status build_pipe_hw_param(struct pipe_ctx *pipe_ctx) -{ - - get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->stream_res.pix_clk_params); - - if (pipe_ctx->clock_source) - pipe_ctx->clock_source->funcs->get_pix_clk_dividers( - pipe_ctx->clock_source, - &pipe_ctx->stream_res.pix_clk_params, - &pipe_ctx->pll_settings); - - pipe_ctx->stream->clamping.pixel_encoding = pipe_ctx->stream->timing.pixel_encoding; - - resource_build_bit_depth_reduction_params(pipe_ctx->stream, - &pipe_ctx->stream->bit_depth_params); - build_clamping_params(pipe_ctx->stream); - - return DC_OK; -} - -bool dml_validate_dsc(struct dc *dc, struct dc_state *new_ctx) -{ - int i; - - /* Validate DSC config, dsc count validation is already done */ - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe_ctx = &new_ctx->res_ctx.pipe_ctx[i]; - struct dc_stream_state *stream = pipe_ctx->stream; - struct dsc_config dsc_cfg; - struct pipe_ctx *odm_pipe; - int opp_cnt = 1; - - for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) - opp_cnt++; - - /* Only need to validate top pipe */ - if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe || !stream || !stream->timing.flags.DSC) - continue; - - dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left - + stream->timing.h_border_right) / opp_cnt; - dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top - + stream->timing.v_border_bottom; - dsc_cfg.pixel_encoding = stream->timing.pixel_encoding; - dsc_cfg.color_depth = stream->timing.display_color_depth; - dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false; - dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg; - dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt; - - if (pipe_ctx->stream_res.dsc && !pipe_ctx->stream_res.dsc->funcs->dsc_validate_stream(pipe_ctx->stream_res.dsc, &dsc_cfg)) - return false; - } - return true; -} - -enum dc_status dml_build_mapped_resource(const struct dc *dc, struct dc_state *context, struct dc_stream_state *stream) -{ - enum dc_status status = DC_OK; - struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); - - if (!pipe_ctx) - return DC_ERROR_UNEXPECTED; - - - status = build_pipe_hw_param(pipe_ctx); - - return status; -} - -void dml_acquire_dsc(const struct dc *dc, - struct resource_context *res_ctx, - struct display_stream_compressor **dsc, - int pipe_idx) -{ - int i; - const struct resource_pool *pool = dc->res_pool; - struct display_stream_compressor *dsc_old = dc->current_state->res_ctx.pipe_ctx[pipe_idx].stream_res.dsc; - - ASSERT(*dsc == NULL); /* If this ASSERT fails, dsc was not released properly */ - *dsc = NULL; - - /* Always do 1-to-1 mapping when number of DSCs is same as number of pipes */ - if (pool->res_cap->num_dsc == pool->res_cap->num_opp) { - *dsc = pool->dscs[pipe_idx]; - res_ctx->is_dsc_acquired[pipe_idx] = true; - return; - } - - /* Return old DSC to avoid the need for redo it */ - if (dsc_old && !res_ctx->is_dsc_acquired[dsc_old->inst]) { - *dsc = dsc_old; - res_ctx->is_dsc_acquired[dsc_old->inst] = true; - return ; - } - - /* Find first free DSC */ - for (i = 0; i < pool->res_cap->num_dsc; i++) - if (!res_ctx->is_dsc_acquired[i]) { - *dsc = pool->dscs[i]; - res_ctx->is_dsc_acquired[i] = true; - break; - } -} - -static bool dml_split_stream_for_mpc_or_odm( - const struct dc *dc, - struct resource_context *res_ctx, - struct pipe_ctx *pri_pipe, - struct pipe_ctx *sec_pipe, - bool odm) -{ - int pipe_idx = sec_pipe->pipe_idx; - const struct resource_pool *pool = dc->res_pool; - - *sec_pipe = *pri_pipe; - - sec_pipe->pipe_idx = pipe_idx; - sec_pipe->plane_res.mi = pool->mis[pipe_idx]; - sec_pipe->plane_res.hubp = pool->hubps[pipe_idx]; - sec_pipe->plane_res.ipp = pool->ipps[pipe_idx]; - sec_pipe->plane_res.xfm = pool->transforms[pipe_idx]; - sec_pipe->plane_res.dpp = pool->dpps[pipe_idx]; - sec_pipe->plane_res.mpcc_inst = pool->dpps[pipe_idx]->inst; - sec_pipe->stream_res.dsc = NULL; - if (odm) { - if (pri_pipe->next_odm_pipe) { - ASSERT(pri_pipe->next_odm_pipe != sec_pipe); - sec_pipe->next_odm_pipe = pri_pipe->next_odm_pipe; - sec_pipe->next_odm_pipe->prev_odm_pipe = sec_pipe; - } - if (pri_pipe->top_pipe && pri_pipe->top_pipe->next_odm_pipe) { - pri_pipe->top_pipe->next_odm_pipe->bottom_pipe = sec_pipe; - sec_pipe->top_pipe = pri_pipe->top_pipe->next_odm_pipe; - } - if (pri_pipe->bottom_pipe && pri_pipe->bottom_pipe->next_odm_pipe) { - pri_pipe->bottom_pipe->next_odm_pipe->top_pipe = sec_pipe; - sec_pipe->bottom_pipe = pri_pipe->bottom_pipe->next_odm_pipe; - } - pri_pipe->next_odm_pipe = sec_pipe; - sec_pipe->prev_odm_pipe = pri_pipe; - ASSERT(sec_pipe->top_pipe == NULL); - - if (!sec_pipe->top_pipe) - sec_pipe->stream_res.opp = pool->opps[pipe_idx]; - else - sec_pipe->stream_res.opp = sec_pipe->top_pipe->stream_res.opp; - if (sec_pipe->stream->timing.flags.DSC == 1) { - dml_acquire_dsc(dc, res_ctx, &sec_pipe->stream_res.dsc, pipe_idx); - ASSERT(sec_pipe->stream_res.dsc); - if (sec_pipe->stream_res.dsc == NULL) - return false; - } - } else { - if (pri_pipe->bottom_pipe) { - ASSERT(pri_pipe->bottom_pipe != sec_pipe); - sec_pipe->bottom_pipe = pri_pipe->bottom_pipe; - sec_pipe->bottom_pipe->top_pipe = sec_pipe; - } - pri_pipe->bottom_pipe = sec_pipe; - sec_pipe->top_pipe = pri_pipe; - - ASSERT(pri_pipe->plane_state); - } - - return true; -} - -static struct pipe_ctx *dml_find_split_pipe( - struct dc *dc, - struct dc_state *context, - int old_index) -{ - struct pipe_ctx *pipe = NULL; - int i; - - if (old_index >= 0 && context->res_ctx.pipe_ctx[old_index].stream == NULL) { - pipe = &context->res_ctx.pipe_ctx[old_index]; - pipe->pipe_idx = old_index; - } - - if (!pipe) - for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) { - if (dc->current_state->res_ctx.pipe_ctx[i].top_pipe == NULL - && dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe == NULL) { - if (context->res_ctx.pipe_ctx[i].stream == NULL) { - pipe = &context->res_ctx.pipe_ctx[i]; - pipe->pipe_idx = i; - break; - } - } - } - - /* - * May need to fix pipes getting tossed from 1 opp to another on flip - * Add for debugging transient underflow during topology updates: - * ASSERT(pipe); - */ - if (!pipe) - for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) { - if (context->res_ctx.pipe_ctx[i].stream == NULL) { - pipe = &context->res_ctx.pipe_ctx[i]; - pipe->pipe_idx = i; - break; - } - } - - return pipe; -} - -static void dml_release_dsc(struct resource_context *res_ctx, - const struct resource_pool *pool, - struct display_stream_compressor **dsc) -{ - int i; - - for (i = 0; i < pool->res_cap->num_dsc; i++) - if (pool->dscs[i] == *dsc) { - res_ctx->is_dsc_acquired[i] = false; - *dsc = NULL; - break; - } -} - -static int dml_get_num_mpc_splits(struct pipe_ctx *pipe) -{ - int mpc_split_count = 0; - struct pipe_ctx *other_pipe = pipe->bottom_pipe; - - while (other_pipe && other_pipe->plane_state == pipe->plane_state) { - mpc_split_count++; - other_pipe = other_pipe->bottom_pipe; - } - other_pipe = pipe->top_pipe; - while (other_pipe && other_pipe->plane_state == pipe->plane_state) { - mpc_split_count++; - other_pipe = other_pipe->top_pipe; - } - - return mpc_split_count; -} - -static bool dml_enough_pipes_for_subvp(struct dc *dc, - struct dc_state *context) -{ - int i = 0; - int num_pipes = 0; - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - - if (pipe->stream && pipe->plane_state) - num_pipes++; - } - - // Sub-VP only possible if the number of "real" pipes is - // less than or equal to half the number of available pipes - if (num_pipes * 2 > dc->res_pool->pipe_count) - return false; - - return true; -} - -static int dml_validate_apply_pipe_split_flags( - struct dc *dc, - struct dc_state *context, - int vlevel, - int *split, - bool *merge) -{ - int i, pipe_idx, vlevel_split; - int plane_count = 0; - bool force_split = false; - bool avoid_split = dc->debug.pipe_split_policy == MPC_SPLIT_AVOID; - struct vba_vars_st *v = &context->bw_ctx.dml.vba; - int max_mpc_comb = v->maxMpcComb; - - if (context->stream_count > 1) { - if (dc->debug.pipe_split_policy == MPC_SPLIT_AVOID_MULT_DISP) - avoid_split = true; - } else if (dc->debug.force_single_disp_pipe_split) - force_split = true; - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - - /** - * Workaround for avoiding pipe-split in cases where we'd split - * planes that are too small, resulting in splits that aren't - * valid for the scaler. - */ - if (pipe->plane_state && - (pipe->plane_state->dst_rect.width <= 16 || - pipe->plane_state->dst_rect.height <= 16 || - pipe->plane_state->src_rect.width <= 16 || - pipe->plane_state->src_rect.height <= 16)) - avoid_split = true; - - /* TODO: fix dc bugs and remove this split threshold thing */ - if (pipe->stream && !pipe->prev_odm_pipe && - (!pipe->top_pipe || pipe->top_pipe->plane_state != pipe->plane_state)) - ++plane_count; - } - if (plane_count > dc->res_pool->pipe_count / 2) - avoid_split = true; - - /* W/A: Mode timing with borders may not work well with pipe split, avoid for this corner case */ - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - struct dc_crtc_timing timing; - - if (!pipe->stream) - continue; - else { - timing = pipe->stream->timing; - if (timing.h_border_left + timing.h_border_right - + timing.v_border_top + timing.v_border_bottom > 0) { - avoid_split = true; - break; - } - } - } - - /* Avoid split loop looks for lowest voltage level that allows most unsplit pipes possible */ - if (avoid_split) { - for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { - if (!context->res_ctx.pipe_ctx[i].stream) - continue; - - for (vlevel_split = vlevel; vlevel <= context->bw_ctx.dml.soc.num_states; vlevel++) - if (v->NoOfDPP[vlevel][0][pipe_idx] == 1 && - v->ModeSupport[vlevel][0]) - break; - /* Impossible to not split this pipe */ - if (vlevel > context->bw_ctx.dml.soc.num_states) - vlevel = vlevel_split; - else - max_mpc_comb = 0; - pipe_idx++; - } - v->maxMpcComb = max_mpc_comb; - } - - /* Split loop sets which pipe should be split based on dml outputs and dc flags */ - for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - int pipe_plane = v->pipe_plane[pipe_idx]; - bool split4mpc = context->stream_count == 1 && plane_count == 1 - && dc->config.enable_4to1MPC && dc->res_pool->pipe_count >= 4; - - if (!context->res_ctx.pipe_ctx[i].stream) - continue; - - if (split4mpc || v->NoOfDPP[vlevel][max_mpc_comb][pipe_plane] == 4) - split[i] = 4; - else if (force_split || v->NoOfDPP[vlevel][max_mpc_comb][pipe_plane] == 2) - split[i] = 2; - - if ((pipe->stream->view_format == - VIEW_3D_FORMAT_SIDE_BY_SIDE || - pipe->stream->view_format == - VIEW_3D_FORMAT_TOP_AND_BOTTOM) && - (pipe->stream->timing.timing_3d_format == - TIMING_3D_FORMAT_TOP_AND_BOTTOM || - pipe->stream->timing.timing_3d_format == - TIMING_3D_FORMAT_SIDE_BY_SIDE)) - split[i] = 2; - if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) { - split[i] = 2; - v->ODMCombineEnablePerState[vlevel][pipe_plane] = dm_odm_combine_mode_2to1; - } - if (dc->debug.force_odm_combine_4to1 & (1 << pipe->stream_res.tg->inst)) { - split[i] = 4; - v->ODMCombineEnablePerState[vlevel][pipe_plane] = dm_odm_combine_mode_4to1; - } - /*420 format workaround*/ - if (pipe->stream->timing.h_addressable > 7680 && - pipe->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) { - split[i] = 4; - } - - v->ODMCombineEnabled[pipe_plane] = - v->ODMCombineEnablePerState[vlevel][pipe_plane]; - - if (v->ODMCombineEnabled[pipe_plane] == dm_odm_combine_mode_disabled) { - if (dml_get_num_mpc_splits(pipe) == 1) { - /*If need split for mpc but 2 way split already*/ - if (split[i] == 4) - split[i] = 2; /* 2 -> 4 MPC */ - else if (split[i] == 2) - split[i] = 0; /* 2 -> 2 MPC */ - else if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) - merge[i] = true; /* 2 -> 1 MPC */ - } else if (dml_get_num_mpc_splits(pipe) == 3) { - /*If need split for mpc but 4 way split already*/ - if (split[i] == 2 && ((pipe->top_pipe && !pipe->top_pipe->top_pipe) - || !pipe->bottom_pipe)) { - merge[i] = true; /* 4 -> 2 MPC */ - } else if (split[i] == 0 && pipe->top_pipe && - pipe->top_pipe->plane_state == pipe->plane_state) - merge[i] = true; /* 4 -> 1 MPC */ - split[i] = 0; - } else if (dml_get_num_mpc_splits(pipe)) { - /* ODM -> MPC transition */ - if (pipe->prev_odm_pipe) { - split[i] = 0; - merge[i] = true; - } - } - } else { - if (dml_get_num_mpc_splits(pipe) == 1) { - /*If need split for odm but 2 way split already*/ - if (split[i] == 4) - split[i] = 2; /* 2 -> 4 ODM */ - else if (split[i] == 2) - split[i] = 0; /* 2 -> 2 ODM */ - else if (pipe->prev_odm_pipe) { - ASSERT(0); /* NOT expected yet */ - merge[i] = true; /* exit ODM */ - } - } else if (dml_get_num_mpc_splits(pipe) == 3) { - /*If need split for odm but 4 way split already*/ - if (split[i] == 2 && ((pipe->prev_odm_pipe && !pipe->prev_odm_pipe->prev_odm_pipe) - || !pipe->next_odm_pipe)) { - ASSERT(0); /* NOT expected yet */ - merge[i] = true; /* 4 -> 2 ODM */ - } else if (split[i] == 0 && pipe->prev_odm_pipe) { - ASSERT(0); /* NOT expected yet */ - merge[i] = true; /* exit ODM */ - } - split[i] = 0; - } else if (dml_get_num_mpc_splits(pipe)) { - /* MPC -> ODM transition */ - ASSERT(0); /* NOT expected yet */ - if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) { - split[i] = 0; - merge[i] = true; - } - } - } - - /* Adjust dppclk when split is forced, do not bother with dispclk */ - if (split[i] != 0 && v->NoOfDPP[vlevel][max_mpc_comb][pipe_idx] == 1) - v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] /= 2; - pipe_idx++; - } - - return vlevel; -} - -static void dml_set_phantom_stream_timing(struct dc *dc, - struct dc_state *context, - struct pipe_ctx *ref_pipe, - struct dc_stream_state *phantom_stream) -{ - // phantom_vactive = blackout (latency + margin) + fw_processing_delays + pstate allow width - uint32_t phantom_vactive_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us + 60 + - dc->caps.subvp_fw_processing_delay_us + - dc->caps.subvp_pstate_allow_width_us; - uint32_t phantom_vactive = ((double)phantom_vactive_us/1000000) * - (ref_pipe->stream->timing.pix_clk_100hz * 100) / - (double)ref_pipe->stream->timing.h_total; - uint32_t phantom_bp = ref_pipe->pipe_dlg_param.vstartup_start; - - phantom_stream->dst.y = 0; - phantom_stream->dst.height = phantom_vactive; - phantom_stream->src.y = 0; - phantom_stream->src.height = phantom_vactive; - - phantom_stream->timing.v_addressable = phantom_vactive; - phantom_stream->timing.v_front_porch = 1; - phantom_stream->timing.v_total = phantom_stream->timing.v_addressable + - phantom_stream->timing.v_front_porch + - phantom_stream->timing.v_sync_width + - phantom_bp; -} - -static struct dc_stream_state *dml_enable_phantom_stream(struct dc *dc, - struct dc_state *context, - struct pipe_ctx *ref_pipe) -{ - struct dc_stream_state *phantom_stream = NULL; - - phantom_stream = dc_create_stream_for_sink(ref_pipe->stream->sink); - phantom_stream->signal = SIGNAL_TYPE_VIRTUAL; - phantom_stream->dpms_off = true; - phantom_stream->mall_stream_config.type = SUBVP_PHANTOM; - phantom_stream->mall_stream_config.paired_stream = ref_pipe->stream; - ref_pipe->stream->mall_stream_config.type = SUBVP_MAIN; - ref_pipe->stream->mall_stream_config.paired_stream = phantom_stream; - - /* stream has limited viewport and small timing */ - memcpy(&phantom_stream->timing, &ref_pipe->stream->timing, sizeof(phantom_stream->timing)); - memcpy(&phantom_stream->src, &ref_pipe->stream->src, sizeof(phantom_stream->src)); - memcpy(&phantom_stream->dst, &ref_pipe->stream->dst, sizeof(phantom_stream->dst)); - dml_set_phantom_stream_timing(dc, context, ref_pipe, phantom_stream); - - dc_add_stream_to_ctx(dc, context, phantom_stream); - dc->hwss.apply_ctx_to_hw(dc, context); - return phantom_stream; -} - -static void dml_enable_phantom_plane(struct dc *dc, - struct dc_state *context, - struct dc_stream_state *phantom_stream, - struct pipe_ctx *main_pipe) -{ - struct dc_plane_state *phantom_plane = NULL; - struct dc_plane_state *prev_phantom_plane = NULL; - struct pipe_ctx *curr_pipe = main_pipe; - - while (curr_pipe) { - if (curr_pipe->top_pipe && curr_pipe->top_pipe->plane_state == curr_pipe->plane_state) - phantom_plane = prev_phantom_plane; - else - phantom_plane = dc_create_plane_state(dc); - - memcpy(&phantom_plane->address, &curr_pipe->plane_state->address, sizeof(phantom_plane->address)); - memcpy(&phantom_plane->scaling_quality, &curr_pipe->plane_state->scaling_quality, - sizeof(phantom_plane->scaling_quality)); - memcpy(&phantom_plane->src_rect, &curr_pipe->plane_state->src_rect, sizeof(phantom_plane->src_rect)); - memcpy(&phantom_plane->dst_rect, &curr_pipe->plane_state->dst_rect, sizeof(phantom_plane->dst_rect)); - memcpy(&phantom_plane->clip_rect, &curr_pipe->plane_state->clip_rect, sizeof(phantom_plane->clip_rect)); - memcpy(&phantom_plane->plane_size, &curr_pipe->plane_state->plane_size, - sizeof(phantom_plane->plane_size)); - memcpy(&phantom_plane->tiling_info, &curr_pipe->plane_state->tiling_info, - sizeof(phantom_plane->tiling_info)); - memcpy(&phantom_plane->dcc, &curr_pipe->plane_state->dcc, sizeof(phantom_plane->dcc)); - /* Currently compat_level is undefined in dc_state - * phantom_plane->compat_level = curr_pipe->plane_state->compat_level; - */ - phantom_plane->format = curr_pipe->plane_state->format; - phantom_plane->rotation = curr_pipe->plane_state->rotation; - phantom_plane->visible = curr_pipe->plane_state->visible; - - /* Shadow pipe has small viewport. */ - phantom_plane->clip_rect.y = 0; - phantom_plane->clip_rect.height = phantom_stream->timing.v_addressable; - - dc_add_plane_to_context(dc, phantom_stream, phantom_plane, context); - - curr_pipe = curr_pipe->bottom_pipe; - prev_phantom_plane = phantom_plane; - } -} - -static void dml_add_phantom_pipes(struct dc *dc, struct dc_state *context) -{ - int i = 0; - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - struct dc_stream_state *ref_stream = pipe->stream; - // Only construct phantom stream for top pipes that have plane enabled - if (!pipe->top_pipe && pipe->plane_state && pipe->stream && - pipe->stream->mall_stream_config.type == SUBVP_NONE) { - struct dc_stream_state *phantom_stream = NULL; - - phantom_stream = dml_enable_phantom_stream(dc, context, pipe); - dml_enable_phantom_plane(dc, context, phantom_stream, pipe); - } - } - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - - if (pipe->plane_state && pipe->stream && - pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) { - pipe->stream->use_dynamic_meta = false; - pipe->plane_state->flip_immediate = false; - if (!resource_build_scaling_params(pipe)) { - // Log / remove phantom pipes since failed to build scaling params - } - } - } -} - -static void dml_remove_phantom_pipes(struct dc *dc, struct dc_state *context) -{ - int i; - bool removed_pipe = false; - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - // build scaling params for phantom pipes - if (pipe->plane_state && pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) { - dc_rem_all_planes_for_stream(dc, pipe->stream, context); - dc_remove_stream_from_ctx(dc, context, pipe->stream); - removed_pipe = true; - } - - // Clear all phantom stream info - if (pipe->stream) { - pipe->stream->mall_stream_config.type = SUBVP_NONE; - pipe->stream->mall_stream_config.paired_stream = NULL; - } - } - if (removed_pipe) - dc->hwss.apply_ctx_to_hw(dc, context); -} - -/* - * If the input state contains no upstream planes for a particular pipe (i.e. only timing) - * we need to populate some "conservative" plane information as DML cannot handle "no planes" - */ -static void populate_default_plane_from_timing(const struct dc_crtc_timing *timing, struct _vcs_dpi_display_pipe_params_st *pipe) -{ - pipe->src.is_hsplit = pipe->dest.odm_combine != dm_odm_combine_mode_disabled; - pipe->src.source_scan = dm_horz; - pipe->src.sw_mode = dm_sw_4kb_s; - pipe->src.macro_tile_size = dm_64k_tile; - pipe->src.viewport_width = timing->h_addressable; - if (pipe->src.viewport_width > 1920) - pipe->src.viewport_width = 1920; - pipe->src.viewport_height = timing->v_addressable; - if (pipe->src.viewport_height > 1080) - pipe->src.viewport_height = 1080; - pipe->src.surface_height_y = pipe->src.viewport_height; - pipe->src.surface_width_y = pipe->src.viewport_width; - pipe->src.surface_height_c = pipe->src.viewport_height; - pipe->src.surface_width_c = pipe->src.viewport_width; - pipe->src.data_pitch = ((pipe->src.viewport_width + 255) / 256) * 256; - pipe->src.source_format = dm_444_32; - pipe->dest.recout_width = pipe->src.viewport_width; - pipe->dest.recout_height = pipe->src.viewport_height; - pipe->dest.full_recout_width = pipe->dest.recout_width; - pipe->dest.full_recout_height = pipe->dest.recout_height; - pipe->scale_ratio_depth.lb_depth = dm_lb_16; - pipe->scale_ratio_depth.hscl_ratio = 1.0; - pipe->scale_ratio_depth.vscl_ratio = 1.0; - pipe->scale_ratio_depth.scl_enable = 0; - pipe->scale_taps.htaps = 1; - pipe->scale_taps.vtaps = 1; - pipe->dest.vtotal_min = timing->v_total; - pipe->dest.vtotal_max = timing->v_total; - - if (pipe->dest.odm_combine == dm_odm_combine_mode_2to1) { - pipe->src.viewport_width /= 2; - pipe->dest.recout_width /= 2; - } else if (pipe->dest.odm_combine == dm_odm_combine_mode_4to1) { - pipe->src.viewport_width /= 4; - pipe->dest.recout_width /= 4; - } - - pipe->src.dcc = false; - pipe->src.dcc_rate = 1; -} - -/* - * If the pipe is not blending (i.e. pipe_ctx->top pipe == null) then its - * hsplit group is equal to its own pipe ID - * Otherwise, all pipes part of the same blending tree have the same hsplit group - * ID as the top most pipe - * - * If the pipe ctx is ODM combined, then similar logic follows - */ -static void populate_hsplit_group_from_dc_pipe_ctx (const struct pipe_ctx *dc_pipe_ctx, struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe) -{ - e2e_pipe->pipe.src.hsplit_grp = dc_pipe_ctx->pipe_idx; - - if (dc_pipe_ctx->top_pipe && dc_pipe_ctx->top_pipe->plane_state - == dc_pipe_ctx->plane_state) { - struct pipe_ctx *first_pipe = dc_pipe_ctx->top_pipe; - int split_idx = 0; - - while (first_pipe->top_pipe && first_pipe->top_pipe->plane_state - == dc_pipe_ctx->plane_state) { - first_pipe = first_pipe->top_pipe; - split_idx++; - } - - /* Treat 4to1 mpc combine as an mpo of 2 2-to-1 combines */ - if (split_idx == 0) - e2e_pipe->pipe.src.hsplit_grp = first_pipe->pipe_idx; - else if (split_idx == 1) - e2e_pipe->pipe.src.hsplit_grp = dc_pipe_ctx->pipe_idx; - else if (split_idx == 2) - e2e_pipe->pipe.src.hsplit_grp = dc_pipe_ctx->top_pipe->pipe_idx; - - } else if (dc_pipe_ctx->prev_odm_pipe) { - struct pipe_ctx *first_pipe = dc_pipe_ctx->prev_odm_pipe; - - while (first_pipe->prev_odm_pipe) - first_pipe = first_pipe->prev_odm_pipe; - e2e_pipe->pipe.src.hsplit_grp = first_pipe->pipe_idx; - } -} - -static void populate_dml_from_dc_pipe_ctx (const struct pipe_ctx *dc_pipe_ctx, struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe, int always_scale) -{ - const struct dc_plane_state *pln = dc_pipe_ctx->plane_state; - const struct scaler_data *scl = &dc_pipe_ctx->plane_res.scl_data; - - e2e_pipe->pipe.src.immediate_flip = pln->flip_immediate; - e2e_pipe->pipe.src.is_hsplit = (dc_pipe_ctx->bottom_pipe && dc_pipe_ctx->bottom_pipe->plane_state == pln) - || (dc_pipe_ctx->top_pipe && dc_pipe_ctx->top_pipe->plane_state == pln) - || e2e_pipe->pipe.dest.odm_combine != dm_odm_combine_mode_disabled; - - /* stereo is not split */ - if (pln->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE || - pln->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM) { - e2e_pipe->pipe.src.is_hsplit = false; - e2e_pipe->pipe.src.hsplit_grp = dc_pipe_ctx->pipe_idx; - } - - e2e_pipe->pipe.src.source_scan = pln->rotation == ROTATION_ANGLE_90 - || pln->rotation == ROTATION_ANGLE_270 ? dm_vert : dm_horz; - e2e_pipe->pipe.src.viewport_y_y = scl->viewport.y; - e2e_pipe->pipe.src.viewport_y_c = scl->viewport_c.y; - e2e_pipe->pipe.src.viewport_width = scl->viewport.width; - e2e_pipe->pipe.src.viewport_width_c = scl->viewport_c.width; - e2e_pipe->pipe.src.viewport_height = scl->viewport.height; - e2e_pipe->pipe.src.viewport_height_c = scl->viewport_c.height; - e2e_pipe->pipe.src.viewport_width_max = pln->src_rect.width; - e2e_pipe->pipe.src.viewport_height_max = pln->src_rect.height; - e2e_pipe->pipe.src.surface_width_y = pln->plane_size.surface_size.width; - e2e_pipe->pipe.src.surface_height_y = pln->plane_size.surface_size.height; - e2e_pipe->pipe.src.surface_width_c = pln->plane_size.chroma_size.width; - e2e_pipe->pipe.src.surface_height_c = pln->plane_size.chroma_size.height; - - if (pln->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA - || pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { - e2e_pipe->pipe.src.data_pitch = pln->plane_size.surface_pitch; - e2e_pipe->pipe.src.data_pitch_c = pln->plane_size.chroma_pitch; - e2e_pipe->pipe.src.meta_pitch = pln->dcc.meta_pitch; - e2e_pipe->pipe.src.meta_pitch_c = pln->dcc.meta_pitch_c; - } else { - e2e_pipe->pipe.src.data_pitch = pln->plane_size.surface_pitch; - e2e_pipe->pipe.src.meta_pitch = pln->dcc.meta_pitch; - } - e2e_pipe->pipe.src.dcc = pln->dcc.enable; - e2e_pipe->pipe.src.dcc_rate = 1; - e2e_pipe->pipe.dest.recout_width = scl->recout.width; - e2e_pipe->pipe.dest.recout_height = scl->recout.height; - e2e_pipe->pipe.dest.full_recout_height = scl->recout.height; - e2e_pipe->pipe.dest.full_recout_width = scl->recout.width; - if (e2e_pipe->pipe.dest.odm_combine == dm_odm_combine_mode_2to1) - e2e_pipe->pipe.dest.full_recout_width *= 2; - else if (e2e_pipe->pipe.dest.odm_combine == dm_odm_combine_mode_4to1) - e2e_pipe->pipe.dest.full_recout_width *= 4; - else { - struct pipe_ctx *split_pipe = dc_pipe_ctx->bottom_pipe; - - while (split_pipe && split_pipe->plane_state == pln) { - e2e_pipe->pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width; - split_pipe = split_pipe->bottom_pipe; - } - split_pipe = dc_pipe_ctx->top_pipe; - while (split_pipe && split_pipe->plane_state == pln) { - e2e_pipe->pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width; - split_pipe = split_pipe->top_pipe; - } - } - - e2e_pipe->pipe.scale_ratio_depth.lb_depth = dm_lb_16; - e2e_pipe->pipe.scale_ratio_depth.hscl_ratio = (double) scl->ratios.horz.value / (1ULL<<32); - e2e_pipe->pipe.scale_ratio_depth.hscl_ratio_c = (double) scl->ratios.horz_c.value / (1ULL<<32); - e2e_pipe->pipe.scale_ratio_depth.vscl_ratio = (double) scl->ratios.vert.value / (1ULL<<32); - e2e_pipe->pipe.scale_ratio_depth.vscl_ratio_c = (double) scl->ratios.vert_c.value / (1ULL<<32); - e2e_pipe->pipe.scale_ratio_depth.scl_enable = - scl->ratios.vert.value != dc_fixpt_one.value - || scl->ratios.horz.value != dc_fixpt_one.value - || scl->ratios.vert_c.value != dc_fixpt_one.value - || scl->ratios.horz_c.value != dc_fixpt_one.value /*Lb only or Full scl*/ - || always_scale; /*support always scale*/ - e2e_pipe->pipe.scale_taps.htaps = scl->taps.h_taps; - e2e_pipe->pipe.scale_taps.htaps_c = scl->taps.h_taps_c; - e2e_pipe->pipe.scale_taps.vtaps = scl->taps.v_taps; - e2e_pipe->pipe.scale_taps.vtaps_c = scl->taps.v_taps_c; - - /* Currently compat_level is not defined. Commenting it until further resolution - * if (pln->compat_level == DC_LEGACY_TILING_ADDR_GEN_TWO) { - swizzle_to_dml_params(pln->tiling_info.gfx9.swizzle, - &e2e_pipe->pipe.src.sw_mode); - e2e_pipe->pipe.src.macro_tile_size = - swizzle_mode_to_macro_tile_size(pln->tiling_info.gfx9.swizzle); - } else { - gfx10array_mode_to_dml_params(pln->tiling_info.gfx10compatible.array_mode, - pln->compat_level, - &e2e_pipe->pipe.src.sw_mode); - e2e_pipe->pipe.src.macro_tile_size = dm_4k_tile; - }*/ - - e2e_pipe->pipe.src.source_format = dc_source_format_to_dml_source_format(pln->format); -} - -static void populate_dml_cursor_parameters_from_dc_pipe_ctx (const struct pipe_ctx *dc_pipe_ctx, struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe) -{ - /* - * For graphic plane, cursor number is 1, nv12 is 0 - * bw calculations due to cursor on/off - */ - if (dc_pipe_ctx->plane_state && - (dc_pipe_ctx->plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE || - dc_pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM)) - e2e_pipe->pipe.src.num_cursors = 0; - else - e2e_pipe->pipe.src.num_cursors = 1; - - e2e_pipe->pipe.src.cur0_src_width = 256; - e2e_pipe->pipe.src.cur0_bpp = dm_cur_32bit; -} - -static int populate_dml_pipes_from_context_base( - struct dc *dc, - struct dc_state *context, - display_e2e_pipe_params_st *pipes, - bool fast_validate) -{ - int pipe_cnt, i; - bool synchronized_vblank = true; - struct resource_context *res_ctx = &context->res_ctx; - - for (i = 0, pipe_cnt = -1; i < dc->res_pool->pipe_count; i++) { - if (!res_ctx->pipe_ctx[i].stream) - continue; - - if (pipe_cnt < 0) { - pipe_cnt = i; - continue; - } - - if (res_ctx->pipe_ctx[pipe_cnt].stream == res_ctx->pipe_ctx[i].stream) - continue; - - if (dc->debug.disable_timing_sync || - (!resource_are_streams_timing_synchronizable( - res_ctx->pipe_ctx[pipe_cnt].stream, - res_ctx->pipe_ctx[i].stream) && - !resource_are_vblanks_synchronizable( - res_ctx->pipe_ctx[pipe_cnt].stream, - res_ctx->pipe_ctx[i].stream))) { - synchronized_vblank = false; - break; - } - } - - for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { - struct dc_crtc_timing *timing = &res_ctx->pipe_ctx[i].stream->timing; - - struct audio_check aud_check = {0}; - if (!res_ctx->pipe_ctx[i].stream) - continue; - - /* todo: - pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = 0; - pipes[pipe_cnt].pipe.src.dcc = 0; - pipes[pipe_cnt].pipe.src.vm = 0;*/ - - pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0; - - pipes[pipe_cnt].dout.dsc_enable = res_ctx->pipe_ctx[i].stream->timing.flags.DSC; - /* todo: rotation?*/ - pipes[pipe_cnt].dout.dsc_slices = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.num_slices_h; - if (res_ctx->pipe_ctx[i].stream->use_dynamic_meta) { - pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = true; - /* 1/2 vblank */ - pipes[pipe_cnt].pipe.src.dynamic_metadata_lines_before_active = - (timing->v_total - timing->v_addressable - - timing->v_border_top - timing->v_border_bottom) / 2; - /* 36 bytes dp, 32 hdmi */ - pipes[pipe_cnt].pipe.src.dynamic_metadata_xmit_bytes = - dc_is_dp_signal(res_ctx->pipe_ctx[i].stream->signal) ? 36 : 32; - } - pipes[pipe_cnt].pipe.dest.synchronized_vblank_all_planes = synchronized_vblank; - - dc_timing_to_dml_timing(timing, &pipes[pipe_cnt].pipe.dest); - pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min; - pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max; - - pipes[pipe_cnt].pipe.dest.otg_inst = res_ctx->pipe_ctx[i].stream_res.tg->inst; - - pipes[pipe_cnt].pipe.dest.odm_combine = get_dml_odm_combine(&res_ctx->pipe_ctx[i]); - - populate_hsplit_group_from_dc_pipe_ctx(&res_ctx->pipe_ctx[i], &pipes[pipe_cnt]); - - pipes[pipe_cnt].dout.dp_lanes = 4; - pipes[pipe_cnt].dout.is_virtual = 0; - pipes[pipe_cnt].dout.output_type = get_dml_output_type(res_ctx->pipe_ctx[i].stream->signal); - if (pipes[pipe_cnt].dout.output_type < 0) { - pipes[pipe_cnt].dout.output_type = dm_dp; - pipes[pipe_cnt].dout.is_virtual = 1; - } - - populate_color_depth_and_encoding_from_timing(&res_ctx->pipe_ctx[i].stream->timing, &pipes[pipe_cnt].dout); - - if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC) - pipes[pipe_cnt].dout.output_bpp = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.bits_per_pixel / 16.0; - - /* todo: default max for now, until there is logic reflecting this in dc*/ - pipes[pipe_cnt].dout.dsc_input_bpc = 12; - /*fill up the audio sample rate (unit in kHz)*/ - get_audio_check(&res_ctx->pipe_ctx[i].stream->audio_info, &aud_check); - pipes[pipe_cnt].dout.max_audio_sample_rate = aud_check.max_audiosample_rate / 1000; - - populate_dml_cursor_parameters_from_dc_pipe_ctx(&res_ctx->pipe_ctx[i], &pipes[pipe_cnt]); - - if (!res_ctx->pipe_ctx[i].plane_state) { - populate_default_plane_from_timing(timing, &pipes[pipe_cnt].pipe); - } else { - populate_dml_from_dc_pipe_ctx(&res_ctx->pipe_ctx[i], &pipes[pipe_cnt], dc->debug.always_scale); - } - - pipe_cnt++; - } - - /* populate writeback information */ - if (dc->res_pool) - dc->res_pool->funcs->populate_dml_writeback_from_context(dc, res_ctx, pipes); - - return pipe_cnt; -} - -static int dml_populate_dml_pipes_from_context( - struct dc *dc, struct dc_state *context, - display_e2e_pipe_params_st *pipes, - bool fast_validate) -{ - int i, pipe_cnt; - struct resource_context *res_ctx = &context->res_ctx; - struct pipe_ctx *pipe = NULL; // Fix potentially uninitialized error from VS - - populate_dml_pipes_from_context_base(dc, context, pipes, fast_validate); - - for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { - struct dc_crtc_timing *timing; - - if (!res_ctx->pipe_ctx[i].stream) - continue; - pipe = &res_ctx->pipe_ctx[i]; - timing = &pipe->stream->timing; - - pipes[pipe_cnt].pipe.src.gpuvm = true; - pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0; - pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0; - pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch; - - pipes[pipe_cnt].dout.dsc_input_bpc = 0; - if (pipes[pipe_cnt].dout.dsc_enable) { - switch (timing->display_color_depth) { - case COLOR_DEPTH_888: - pipes[pipe_cnt].dout.dsc_input_bpc = 8; - break; - case COLOR_DEPTH_101010: - pipes[pipe_cnt].dout.dsc_input_bpc = 10; - break; - case COLOR_DEPTH_121212: - pipes[pipe_cnt].dout.dsc_input_bpc = 12; - break; - default: - ASSERT(0); - break; - } - } - pipe_cnt++; - } - dc->config.enable_4to1MPC = false; - if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) { - if (is_dual_plane(pipe->plane_state->format) - && pipe->plane_state->src_rect.width <= 1920 && pipe->plane_state->src_rect.height <= 1080) { - dc->config.enable_4to1MPC = true; - } else if (!is_dual_plane(pipe->plane_state->format)) { - context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192; - pipes[0].pipe.src.unbounded_req_mode = true; - } - } - - return pipe_cnt; -} - -static void dml_full_validate_bw_helper(struct dc *dc, - struct dc_state *context, - display_e2e_pipe_params_st *pipes, - int *vlevel, - int *split, - bool *merge, - int *pipe_cnt) -{ - struct vba_vars_st *vba = &context->bw_ctx.dml.vba; - - /* - * DML favors voltage over p-state, but we're more interested in - * supporting p-state over voltage. We can't support p-state in - * prefetch mode > 0 so try capping the prefetch mode to start. - */ - context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank = - dm_allow_self_refresh_and_mclk_switch; - *vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, *pipe_cnt); - /* This may adjust vlevel and maxMpcComb */ - if (*vlevel < context->bw_ctx.dml.soc.num_states) - *vlevel = dml_validate_apply_pipe_split_flags(dc, context, *vlevel, split, merge); - - /* Conditions for setting up phantom pipes for SubVP: - * 1. Not force disable SubVP - * 2. Full update (i.e. !fast_validate) - * 3. Enough pipes are available to support SubVP (TODO: Which pipes will use VACTIVE / VBLANK / SUBVP?) - * 4. Display configuration passes validation - * 5. (Config doesn't support MCLK in VACTIVE/VBLANK || dc->debug.force_subvp_mclk_switch) - */ - if (!dc->debug.force_disable_subvp && - dml_enough_pipes_for_subvp(dc, context) && - *vlevel < context->bw_ctx.dml.soc.num_states && - (vba->DRAMClockChangeSupport[*vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported || - dc->debug.force_subvp_mclk_switch)) { - - dml_add_phantom_pipes(dc, context); - - /* Create input to DML based on new context which includes phantom pipes - * TODO: Input to DML should mark which pipes are phantom - */ - *pipe_cnt = dml_populate_dml_pipes_from_context(dc, context, pipes, false); - *vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, *pipe_cnt); - if (*vlevel < context->bw_ctx.dml.soc.num_states) { - memset(split, 0, MAX_PIPES * sizeof(*split)); - memset(merge, 0, MAX_PIPES * sizeof(*merge)); - *vlevel = dml_validate_apply_pipe_split_flags(dc, context, *vlevel, split, merge); - } - - // If SubVP pipe config is unsupported (or cannot be used for UCLK switching) - // remove phantom pipes and repopulate dml pipes - if (*vlevel == context->bw_ctx.dml.soc.num_states || - vba->DRAMClockChangeSupport[*vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported) { - dml_remove_phantom_pipes(dc, context); - *pipe_cnt = dml_populate_dml_pipes_from_context(dc, context, pipes, false); - } - } -} - -static void dcn20_adjust_adaptive_sync_v_startup( - const struct dc_crtc_timing *dc_crtc_timing, int *vstartup_start) -{ - struct dc_crtc_timing patched_crtc_timing; - uint32_t asic_blank_end = 0; - uint32_t asic_blank_start = 0; - uint32_t newVstartup = 0; - - patched_crtc_timing = *dc_crtc_timing; - - if (patched_crtc_timing.flags.INTERLACE == 1) { - if (patched_crtc_timing.v_front_porch < 2) - patched_crtc_timing.v_front_porch = 2; - } else { - if (patched_crtc_timing.v_front_porch < 1) - patched_crtc_timing.v_front_porch = 1; - } - - /* blank_start = frame end - front porch */ - asic_blank_start = patched_crtc_timing.v_total - - patched_crtc_timing.v_front_porch; - - /* blank_end = blank_start - active */ - asic_blank_end = asic_blank_start - - patched_crtc_timing.v_border_bottom - - patched_crtc_timing.v_addressable - - patched_crtc_timing.v_border_top; - - newVstartup = asic_blank_end + (patched_crtc_timing.v_total - asic_blank_start); - - *vstartup_start = ((newVstartup > *vstartup_start) ? newVstartup : *vstartup_start); -} - -static bool is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx) -{ - return (pipe_ctx->stream_res.hpo_dp_stream_enc && - pipe_ctx->link_res.hpo_dp_link_enc && - dc_is_dp_signal(pipe_ctx->stream->signal)); -} - -static bool is_dtbclk_required(struct dc *dc, struct dc_state *context) -{ - int i; - for (i = 0; i < dc->res_pool->pipe_count; i++) { - if (!context->res_ctx.pipe_ctx[i].stream) - continue; - if (is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i])) - return true; - } - return false; -} - -static void dml_update_soc_for_wm_a(struct dc *dc, struct dc_state *context) -{ - if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].valid) { - context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; - context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us; - context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us; - context->bw_ctx.dml.soc.fclk_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.fclk_change_latency_us; - } -} - -static bool dml_internal_validate( - struct dc *dc, - struct dc_state *context, - display_e2e_pipe_params_st *pipes, - int *pipe_cnt_out, - int *vlevel_out, - bool fast_validate) -{ - bool out = false; - bool repopulate_pipes = false; - int split[MAX_PIPES] = { 0 }; - bool merge[MAX_PIPES] = { false }; - bool newly_split[MAX_PIPES] = { false }; - int pipe_cnt, i, pipe_idx, vlevel; - struct vba_vars_st *vba = &context->bw_ctx.dml.vba; - - ASSERT(pipes); - if (!pipes) - return false; - - // For each full update, remove all existing phantom pipes first - dml_remove_phantom_pipes(dc, context); - - dml_update_soc_for_wm_a(dc, context); - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - - if (pipe->plane_state) { - // On initial pass through DML, we intend to use MALL for SS on all - // (non-PSR) surfaces with none using MALL for P-State - // 'mall_plane_config': is not a member of 'dc_plane_state' - commenting it out till mall_plane_config gets supported in dc_plant_state - //if (pipe->stream && pipe->stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED) - // pipe->plane_state->mall_plane_config.use_mall_for_ss = true; - } - } - pipe_cnt = dml_populate_dml_pipes_from_context(dc, context, pipes, fast_validate); - - if (!pipe_cnt) { - out = true; - goto validate_out; - } - - dml_log_pipe_params(&context->bw_ctx.dml, pipes, pipe_cnt); - - if (!fast_validate) { - dml_full_validate_bw_helper(dc, context, pipes, &vlevel, split, merge, &pipe_cnt); - } - - if (fast_validate || vlevel == context->bw_ctx.dml.soc.num_states || - vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported) { - /* - * If mode is unsupported or there's still no p-state support then - * fall back to favoring voltage. - * - * We don't actually support prefetch mode 2, so require that we - * at least support prefetch mode 1. - */ - context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank = - dm_allow_self_refresh; - - vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt); - if (vlevel < context->bw_ctx.dml.soc.num_states) { - memset(split, 0, sizeof(split)); - memset(merge, 0, sizeof(merge)); - vlevel = dml_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge); - } - } - - dml_log_mode_support_params(&context->bw_ctx.dml); - - if (vlevel == context->bw_ctx.dml.soc.num_states) - goto validate_fail; - - for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - struct pipe_ctx *mpo_pipe = pipe->bottom_pipe; - - if (!pipe->stream) - continue; - - /* We only support full screen mpo with ODM */ - if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled - && pipe->plane_state && mpo_pipe - && memcmp(&mpo_pipe->plane_res.scl_data.recout, - &pipe->plane_res.scl_data.recout, - sizeof(struct rect)) != 0) { - ASSERT(mpo_pipe->plane_state != pipe->plane_state); - goto validate_fail; - } - pipe_idx++; - } - - /* merge pipes if necessary */ - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - - /*skip pipes that don't need merging*/ - if (!merge[i]) - continue; - - /* if ODM merge we ignore mpc tree, mpo pipes will have their own flags */ - if (pipe->prev_odm_pipe) { - /*split off odm pipe*/ - pipe->prev_odm_pipe->next_odm_pipe = pipe->next_odm_pipe; - if (pipe->next_odm_pipe) - pipe->next_odm_pipe->prev_odm_pipe = pipe->prev_odm_pipe; - - pipe->bottom_pipe = NULL; - pipe->next_odm_pipe = NULL; - pipe->plane_state = NULL; - pipe->stream = NULL; - pipe->top_pipe = NULL; - pipe->prev_odm_pipe = NULL; - if (pipe->stream_res.dsc) - dml_release_dsc(&context->res_ctx, dc->res_pool, &pipe->stream_res.dsc); - memset(&pipe->plane_res, 0, sizeof(pipe->plane_res)); - memset(&pipe->stream_res, 0, sizeof(pipe->stream_res)); - repopulate_pipes = true; - } else if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) { - struct pipe_ctx *top_pipe = pipe->top_pipe; - struct pipe_ctx *bottom_pipe = pipe->bottom_pipe; - - top_pipe->bottom_pipe = bottom_pipe; - if (bottom_pipe) - bottom_pipe->top_pipe = top_pipe; - - pipe->top_pipe = NULL; - pipe->bottom_pipe = NULL; - pipe->plane_state = NULL; - pipe->stream = NULL; - memset(&pipe->plane_res, 0, sizeof(pipe->plane_res)); - memset(&pipe->stream_res, 0, sizeof(pipe->stream_res)); - repopulate_pipes = true; - } else - ASSERT(0); /* Should never try to merge master pipe */ - - } - - for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; - struct pipe_ctx *hsplit_pipe = NULL; - bool odm; - int old_index = -1; - - if (!pipe->stream || newly_split[i]) - continue; - - pipe_idx++; - odm = vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled; - - if (!pipe->plane_state && !odm) - continue; - - if (split[i]) { - if (odm) { - if (split[i] == 4 && old_pipe->next_odm_pipe && old_pipe->next_odm_pipe->next_odm_pipe) - old_index = old_pipe->next_odm_pipe->next_odm_pipe->pipe_idx; - else if (old_pipe->next_odm_pipe) - old_index = old_pipe->next_odm_pipe->pipe_idx; - } else { - if (split[i] == 4 && old_pipe->bottom_pipe && old_pipe->bottom_pipe->bottom_pipe && - old_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state) - old_index = old_pipe->bottom_pipe->bottom_pipe->pipe_idx; - else if (old_pipe->bottom_pipe && - old_pipe->bottom_pipe->plane_state == old_pipe->plane_state) - old_index = old_pipe->bottom_pipe->pipe_idx; - } - hsplit_pipe = dml_find_split_pipe(dc, context, old_index); - ASSERT(hsplit_pipe); - if (!hsplit_pipe) - goto validate_fail; - - if (!dml_split_stream_for_mpc_or_odm( - dc, &context->res_ctx, - pipe, hsplit_pipe, odm)) - goto validate_fail; - - newly_split[hsplit_pipe->pipe_idx] = true; - repopulate_pipes = true; - } - if (split[i] == 4) { - struct pipe_ctx *pipe_4to1; - - if (odm && old_pipe->next_odm_pipe) - old_index = old_pipe->next_odm_pipe->pipe_idx; - else if (!odm && old_pipe->bottom_pipe && - old_pipe->bottom_pipe->plane_state == old_pipe->plane_state) - old_index = old_pipe->bottom_pipe->pipe_idx; - else - old_index = -1; - pipe_4to1 = dml_find_split_pipe(dc, context, old_index); - ASSERT(pipe_4to1); - if (!pipe_4to1) - goto validate_fail; - if (!dml_split_stream_for_mpc_or_odm( - dc, &context->res_ctx, - pipe, pipe_4to1, odm)) - goto validate_fail; - newly_split[pipe_4to1->pipe_idx] = true; - - if (odm && old_pipe->next_odm_pipe && old_pipe->next_odm_pipe->next_odm_pipe - && old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe) - old_index = old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe->pipe_idx; - else if (!odm && old_pipe->bottom_pipe && old_pipe->bottom_pipe->bottom_pipe && - old_pipe->bottom_pipe->bottom_pipe->bottom_pipe && - old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state) - old_index = old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->pipe_idx; - else - old_index = -1; - pipe_4to1 = dml_find_split_pipe(dc, context, old_index); - ASSERT(pipe_4to1); - if (!pipe_4to1) - goto validate_fail; - if (!dml_split_stream_for_mpc_or_odm( - dc, &context->res_ctx, - hsplit_pipe, pipe_4to1, odm)) - goto validate_fail; - newly_split[pipe_4to1->pipe_idx] = true; - } - if (odm) - dml_build_mapped_resource(dc, context, pipe->stream); - } - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - - if (pipe->plane_state) { - if (!resource_build_scaling_params(pipe)) - goto validate_fail; - } - } - - /* Actual dsc count per stream dsc validation*/ - if (!dml_validate_dsc(dc, context)) { - vba->ValidationStatus[vba->soc.num_states] = DML_FAIL_DSC_VALIDATION_FAILURE; - goto validate_fail; - } - - if (repopulate_pipes) - pipe_cnt = dml_populate_dml_pipes_from_context(dc, context, pipes, fast_validate); - *vlevel_out = vlevel; - *pipe_cnt_out = pipe_cnt; - - out = true; - goto validate_out; - -validate_fail: - out = false; - -validate_out: - return out; -} - -static void dml_calculate_dlg_params( - struct dc *dc, struct dc_state *context, - display_e2e_pipe_params_st *pipes, - int pipe_cnt, - int vlevel) -{ - int i, pipe_idx; - int plane_count; - - /* Writeback MCIF_WB arbitration parameters */ - if (dc->res_pool) - dc->res_pool->funcs->set_mcif_arb_params(dc, context, pipes, pipe_cnt); - - context->bw_ctx.bw.dcn.clk.dispclk_khz = context->bw_ctx.dml.vba.DISPCLK * 1000; - context->bw_ctx.bw.dcn.clk.dcfclk_khz = context->bw_ctx.dml.vba.DCFCLK * 1000; - context->bw_ctx.bw.dcn.clk.socclk_khz = context->bw_ctx.dml.vba.SOCCLK * 1000; - context->bw_ctx.bw.dcn.clk.dramclk_khz = context->bw_ctx.dml.vba.DRAMSpeed * 1000 / 16; - context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = context->bw_ctx.dml.vba.DCFCLKDeepSleep * 1000; - context->bw_ctx.bw.dcn.clk.fclk_khz = context->bw_ctx.dml.vba.FabricClock * 1000; - context->bw_ctx.bw.dcn.clk.p_state_change_support = - context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] - != dm_dram_clock_change_unsupported; - - context->bw_ctx.bw.dcn.clk.dppclk_khz = 0; - /* 'z9_support': is not a member of 'dc_clocks' - Commenting out till we have this support in dc_clocks - * context->bw_ctx.bw.dcn.clk.z9_support = (context->bw_ctx.dml.vba.StutterPeriod > 5000.0) ? - DCN_Z9_SUPPORT_ALLOW : DCN_Z9_SUPPORT_DISALLOW; - */ - plane_count = 0; - for (i = 0; i < dc->res_pool->pipe_count; i++) { - if (context->res_ctx.pipe_ctx[i].plane_state) - plane_count++; - } - - /* Commented out as per above error for now. - if (plane_count == 0) - context->bw_ctx.bw.dcn.clk.z9_support = DCN_Z9_SUPPORT_ALLOW; - */ - context->bw_ctx.bw.dcn.clk.dtbclk_en = is_dtbclk_required(dc, context); - context->bw_ctx.bw.dcn.clk.fclk_p_state_change_support = - context->bw_ctx.dml.vba.FCLKChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; - if (context->bw_ctx.bw.dcn.clk.dispclk_khz < dc->debug.min_disp_clk_khz) - context->bw_ctx.bw.dcn.clk.dispclk_khz = dc->debug.min_disp_clk_khz; - - for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { - if (!context->res_ctx.pipe_ctx[i].stream) - continue; - pipes[pipe_idx].pipe.dest.vstartup_start = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); - pipes[pipe_idx].pipe.dest.vupdate_offset = get_vupdate_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); - pipes[pipe_idx].pipe.dest.vupdate_width = get_vupdate_width(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); - pipes[pipe_idx].pipe.dest.vready_offset = get_vready_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); - if (context->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) { - // Phantom pipe requires that DET_SIZE = 0 and no unbounded requests - context->res_ctx.pipe_ctx[i].det_buffer_size_kb = 0; - context->res_ctx.pipe_ctx[i].unbounded_req = false; - } else { - context->res_ctx.pipe_ctx[i].det_buffer_size_kb = context->bw_ctx.dml.ip.det_buffer_size_kbytes; - context->res_ctx.pipe_ctx[i].unbounded_req = pipes[pipe_idx].pipe.src.unbounded_req_mode; - } - - if (context->bw_ctx.bw.dcn.clk.dppclk_khz < pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000) - context->bw_ctx.bw.dcn.clk.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000; - context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz = - pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000; - context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest; - pipe_idx++; - } - /*save a original dppclock copy*/ - context->bw_ctx.bw.dcn.clk.bw_dppclk_khz = context->bw_ctx.bw.dcn.clk.dppclk_khz; - context->bw_ctx.bw.dcn.clk.bw_dispclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz; - context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dppclk_mhz * 1000; - context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dispclk_mhz * 1000; - context->bw_ctx.bw.dcn.compbuf_size_kb = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes - - context->bw_ctx.dml.ip.det_buffer_size_kbytes * pipe_idx; - - for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { - bool cstate_en = context->bw_ctx.dml.vba.PrefetchMode[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != 2; - - if (!context->res_ctx.pipe_ctx[i].stream) - continue; - - context->bw_ctx.dml.funcs.rq_dlg_get_dlg_reg(&context->bw_ctx.dml, - &context->res_ctx.pipe_ctx[i].dlg_regs, - &context->res_ctx.pipe_ctx[i].ttu_regs, - pipes, - pipe_cnt, - pipe_idx, - cstate_en, - context->bw_ctx.bw.dcn.clk.p_state_change_support, - false, false, true); - - context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml, - &context->res_ctx.pipe_ctx[i].rq_regs, - &pipes[pipe_idx].pipe); - pipe_idx++; - } -} - -static void dml_calculate_wm_and_dlg( - struct dc *dc, struct dc_state *context, - display_e2e_pipe_params_st *pipes, - int pipe_cnt, - int vlevel) -{ - int i, pipe_idx, vlevel_temp = 0; - - double dcfclk = context->bw_ctx.dml.soc.clock_limits[0].dcfclk_mhz; - double dcfclk_from_validation = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; - unsigned int min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed; - bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != - dm_dram_clock_change_unsupported; - - /* Set B: - * For Set B calculations use clocks from clock_limits[2] when available i.e. when SMU is present, - * otherwise use arbitrary low value from spreadsheet for DCFCLK as lower is safer for watermark - * calculations to cover bootup clocks. - * DCFCLK: soc.clock_limits[2] when available - * UCLK: soc.clock_limits[2] when available - */ - if (context->bw_ctx.dml.soc.num_states > 2) { - vlevel_temp = 2; - dcfclk = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz; - } else - dcfclk = 615; //DCFCLK Vmin_lv - - pipes[0].clks_cfg.voltage = vlevel_temp; - pipes[0].clks_cfg.dcfclk_mhz = dcfclk; - pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel_temp].socclk_mhz; - - if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].valid) { - context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us; - context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us; - context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us; - } - context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.fclk_pstate_change_ns = get_fclk_watermark(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - //context->bw_ctx.bw.dcn.watermarks.b.usr_retraining_ns = get_wm_usr_retraining(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - - /* Temporary, to have some fclk_pstate_change_ns and usr_retraining_ns wm values until DML is implemented */ - //context->bw_ctx.bw.dcn.watermarks.b.usr_retraining = context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns / 8; - - /* Set D: - * All clocks min. - * DCFCLK: Min, as reported by PM FW when available - * UCLK : Min, as reported by PM FW when available - * sr_enter_exit/sr_exit should be lower than used for DRAM (TBD after bringup or later, use as decided in Clk Mgr) - */ - - if (context->bw_ctx.dml.soc.num_states > 2) { - vlevel_temp = 0; - dcfclk = dc->clk_mgr->bw_params->clk_table.entries[0].dcfclk_mhz; - } else - dcfclk = 615; //DCFCLK Vmin_lv - - pipes[0].clks_cfg.voltage = vlevel_temp; - pipes[0].clks_cfg.dcfclk_mhz = dcfclk; - pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel_temp].socclk_mhz; - - if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) { - context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us; - context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us; - context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us; - } - context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.fclk_pstate_change_ns = get_fclk_watermark(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - //context->bw_ctx.bw.dcn.watermarks.d.usr_retraining_ns = get_wm_usr_retraining(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - - /* Temporary, to have some fclk_pstate_change_ns and usr_retraining_ns wm values until DML is implemented */ - //context->bw_ctx.bw.dcn.watermarks.d.usr_retraining = context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns / 8; - /* Set C, for Dummy P-State: - * All clocks min. - * DCFCLK: Min, as reported by PM FW, when available - * UCLK : Min, as reported by PM FW, when available - * pstate latency as per UCLK state dummy pstate latency - */ - if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid) { - unsigned int min_dram_speed_mts_margin = 160; - - if ((!pstate_en)) - min_dram_speed_mts = dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz * 16; - - /* find largest table entry that is lower than dram speed, but lower than DPM0 still uses DPM0 */ - for (i = 3; i > 0; i--) - if (min_dram_speed_mts + min_dram_speed_mts_margin > dc->clk_mgr->bw_params->dummy_pstate_table[i].dram_speed_mts) - break; - - context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->dummy_pstate_table[i].dummy_pstate_latency_us; - context->bw_ctx.dml.soc.dummy_pstate_latency_us = dc->clk_mgr->bw_params->dummy_pstate_table[i].dummy_pstate_latency_us; - context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us; - context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us; - } - context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.fclk_pstate_change_ns = get_fclk_watermark(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - //context->bw_ctx.bw.dcn.watermarks.c.usr_retraining_ns = get_wm_usr_retraining(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - - /* Temporary, to have some fclk_pstate_change_ns and usr_retraining_ns wm values until DML is implemented */ - //context->bw_ctx.bw.dcn.watermarks.c.usr_retraining = context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns / 8; - if ((!pstate_en) && (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid)) { - /* The only difference between A and C is p-state latency, if p-state is not supported - * with full p-state latency we want to calculate DLG based on dummy p-state latency, - * Set A p-state watermark set to 0 previously, when p-state unsupported, for now keep as previous implementation. - */ - context->bw_ctx.bw.dcn.watermarks.a = context->bw_ctx.bw.dcn.watermarks.c; - context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 0; - } else { - /* Set A: - * All clocks min. - * DCFCLK: Min, as reported by PM FW, when available - * UCLK: Min, as reported by PM FW, when available - */ - dml_update_soc_for_wm_a(dc, context); - context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - } - - pipes[0].clks_cfg.voltage = vlevel; - pipes[0].clks_cfg.dcfclk_mhz = dcfclk_from_validation; - pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz; - - for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { - if (!context->res_ctx.pipe_ctx[i].stream) - continue; - - pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt); - pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); - - if (dc->config.forced_clocks) { - pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz; - pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz; - } - if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000) - pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0; - if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000) - pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0; - - pipe_idx++; - } - - context->perf_params.stutter_period_us = context->bw_ctx.dml.vba.StutterPeriod; - - dml_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); - - if (!pstate_en) - /* Restore full p-state latency */ - context->bw_ctx.dml.soc.dram_clock_change_latency_us = - dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; -} - -bool dml_validate(struct dc *dc, - struct dc_state *context, - bool fast_validate) -{ - bool out = false; - - BW_VAL_TRACE_SETUP(); - - int vlevel = 0; - int pipe_cnt = 0; - display_e2e_pipe_params_st *pipes = context->bw_ctx.dml.dml_pipe_state; - DC_LOGGER_INIT(dc->ctx->logger); - - BW_VAL_TRACE_COUNT(); - - out = dml_internal_validate(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate); - - if (pipe_cnt == 0) - goto validate_out; - - if (!out) - goto validate_fail; - - BW_VAL_TRACE_END_VOLTAGE_LEVEL(); - - if (fast_validate) { - BW_VAL_TRACE_SKIP(fast); - goto validate_out; - } - - dml_calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); - - BW_VAL_TRACE_END_WATERMARKS(); - - goto validate_out; - -validate_fail: - DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n", - dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states])); - - BW_VAL_TRACE_SKIP(fail); - out = false; - -validate_out: - BW_VAL_TRACE_FINISH(); - - return out; -} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper_translation.c b/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper_translation.c deleted file mode 100644 index 4ec5310a2962..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper_translation.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright 2017 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#ifdef DML_WRAPPER_TRANSLATION_ - -static void gfx10array_mode_to_dml_params( - enum array_mode_values array_mode, - enum legacy_tiling_compat_level compat_level, - unsigned int *sw_mode) -{ - switch (array_mode) { - case DC_ARRAY_LINEAR_ALLIGNED: - case DC_ARRAY_LINEAR_GENERAL: - *sw_mode = dm_sw_linear; - break; - case DC_ARRAY_2D_TILED_THIN1: -// DC_LEGACY_TILING_ADDR_GEN_ZERO - undefined as per current code hence removed -#if 0 - if (compat_level == DC_LEGACY_TILING_ADDR_GEN_ZERO) - *sw_mode = dm_sw_gfx7_2d_thin_l_vp; - else - *sw_mode = dm_sw_gfx7_2d_thin_gl; -#endif - break; - default: - ASSERT(0); /* Not supported */ - break; - } -} - -static void swizzle_to_dml_params( - enum swizzle_mode_values swizzle, - unsigned int *sw_mode) -{ - switch (swizzle) { - case DC_SW_LINEAR: - *sw_mode = dm_sw_linear; - break; - case DC_SW_4KB_S: - *sw_mode = dm_sw_4kb_s; - break; - case DC_SW_4KB_S_X: - *sw_mode = dm_sw_4kb_s_x; - break; - case DC_SW_4KB_D: - *sw_mode = dm_sw_4kb_d; - break; - case DC_SW_4KB_D_X: - *sw_mode = dm_sw_4kb_d_x; - break; - case DC_SW_64KB_S: - *sw_mode = dm_sw_64kb_s; - break; - case DC_SW_64KB_S_X: - *sw_mode = dm_sw_64kb_s_x; - break; - case DC_SW_64KB_S_T: - *sw_mode = dm_sw_64kb_s_t; - break; - case DC_SW_64KB_D: - *sw_mode = dm_sw_64kb_d; - break; - case DC_SW_64KB_D_X: - *sw_mode = dm_sw_64kb_d_x; - break; - case DC_SW_64KB_D_T: - *sw_mode = dm_sw_64kb_d_t; - break; - case DC_SW_64KB_R_X: - *sw_mode = dm_sw_64kb_r_x; - break; - case DC_SW_VAR_S: - *sw_mode = dm_sw_var_s; - break; - case DC_SW_VAR_S_X: - *sw_mode = dm_sw_var_s_x; - break; - case DC_SW_VAR_D: - *sw_mode = dm_sw_var_d; - break; - case DC_SW_VAR_D_X: - *sw_mode = dm_sw_var_d_x; - break; - - default: - ASSERT(0); /* Not supported */ - break; - } -} - -static void dc_timing_to_dml_timing(const struct dc_crtc_timing *timing, struct _vcs_dpi_display_pipe_dest_params_st *dest) -{ - dest->hblank_start = timing->h_total - timing->h_front_porch; - dest->hblank_end = dest->hblank_start - - timing->h_addressable - - timing->h_border_left - - timing->h_border_right; - dest->vblank_start = timing->v_total - timing->v_front_porch; - dest->vblank_end = dest->vblank_start - - timing->v_addressable - - timing->v_border_top - - timing->v_border_bottom; - dest->htotal = timing->h_total; - dest->vtotal = timing->v_total; - dest->hactive = timing->h_addressable; - dest->vactive = timing->v_addressable; - dest->interlaced = timing->flags.INTERLACE; - dest->pixel_rate_mhz = timing->pix_clk_100hz/10000.0; - if (timing->timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING) - dest->pixel_rate_mhz *= 2; -} - -static enum odm_combine_mode get_dml_odm_combine(const struct pipe_ctx *pipe) -{ - int odm_split_count = 0; - enum odm_combine_mode combine_mode = dm_odm_combine_mode_disabled; - struct pipe_ctx *next_pipe = pipe->next_odm_pipe; - - // Traverse pipe tree to determine odm split count - while (next_pipe) { - odm_split_count++; - next_pipe = next_pipe->next_odm_pipe; - } - pipe = pipe->prev_odm_pipe; - while (pipe) { - odm_split_count++; - pipe = pipe->prev_odm_pipe; - } - - // Translate split to DML odm combine factor - switch (odm_split_count) { - case 1: - combine_mode = dm_odm_combine_mode_2to1; - break; - case 3: - combine_mode = dm_odm_combine_mode_4to1; - break; - default: - combine_mode = dm_odm_combine_mode_disabled; - } - - return combine_mode; -} - -static int get_dml_output_type(enum signal_type dc_signal) -{ - int dml_output_type = -1; - - switch (dc_signal) { - case SIGNAL_TYPE_DISPLAY_PORT_MST: - case SIGNAL_TYPE_DISPLAY_PORT: - dml_output_type = dm_dp; - break; - case SIGNAL_TYPE_EDP: - dml_output_type = dm_edp; - break; - case SIGNAL_TYPE_HDMI_TYPE_A: - case SIGNAL_TYPE_DVI_SINGLE_LINK: - case SIGNAL_TYPE_DVI_DUAL_LINK: - dml_output_type = dm_hdmi; - break; - default: - break; - } - - return dml_output_type; -} - -static void populate_color_depth_and_encoding_from_timing(const struct dc_crtc_timing *timing, struct _vcs_dpi_display_output_params_st *dout) -{ - int output_bpc = 0; - - switch (timing->display_color_depth) { - case COLOR_DEPTH_666: - output_bpc = 6; - break; - case COLOR_DEPTH_888: - output_bpc = 8; - break; - case COLOR_DEPTH_101010: - output_bpc = 10; - break; - case COLOR_DEPTH_121212: - output_bpc = 12; - break; - case COLOR_DEPTH_141414: - output_bpc = 14; - break; - case COLOR_DEPTH_161616: - output_bpc = 16; - break; - case COLOR_DEPTH_999: - output_bpc = 9; - break; - case COLOR_DEPTH_111111: - output_bpc = 11; - break; - default: - output_bpc = 8; - break; - } - - switch (timing->pixel_encoding) { - case PIXEL_ENCODING_RGB: - case PIXEL_ENCODING_YCBCR444: - dout->output_format = dm_444; - dout->output_bpp = output_bpc * 3; - break; - case PIXEL_ENCODING_YCBCR420: - dout->output_format = dm_420; - dout->output_bpp = (output_bpc * 3.0) / 2; - break; - case PIXEL_ENCODING_YCBCR422: - if (timing->flags.DSC && !timing->dsc_cfg.ycbcr422_simple) - dout->output_format = dm_n422; - else - dout->output_format = dm_s422; - dout->output_bpp = output_bpc * 2; - break; - default: - dout->output_format = dm_444; - dout->output_bpp = output_bpc * 3; - } -} - -static enum source_format_class dc_source_format_to_dml_source_format(enum surface_pixel_format dc_format) -{ - enum source_format_class dml_format = dm_444_32; - - switch (dc_format) { - case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: - case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: - dml_format = dm_420_8; - break; - case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: - case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: - dml_format = dm_420_10; - break; - case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: - case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: - case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: - dml_format = dm_444_64; - break; - case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: - case SURFACE_PIXEL_FORMAT_GRPH_RGB565: - dml_format = dm_444_16; - break; - case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS: - dml_format = dm_444_8; - break; - case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: - dml_format = dm_rgbe_alpha; - break; - default: - dml_format = dm_444_32; - break; - } - - return dml_format; -} - -#endif 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 b3d0a4ea2446..8919a2092ac5 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -399,6 +399,10 @@ struct pipe_ctx { struct dc_stream_state *stream; struct plane_resource plane_res; + + /** + * @stream_res: Reference to DCN resource components such OPP and DSC. + */ struct stream_resource stream_res; struct link_resource link_res; diff --git a/drivers/gpu/drm/amd/display/dc/inc/dml_wrapper.h b/drivers/gpu/drm/amd/display/dc/inc/dml_wrapper.h deleted file mode 100644 index 5dcfbd8e2697..000000000000 --- a/drivers/gpu/drm/amd/display/dc/inc/dml_wrapper.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#ifndef DML_WRAPPER_H_ -#define DML_WRAPPER_H_ - -#include "dc.h" -#include "dml/display_mode_vba.h" - -bool dml_validate(struct dc *dc, struct dc_state *context, bool fast_validate); - -#endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h index d89bd55f110f..437b64e87377 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h @@ -268,6 +268,12 @@ enum dc_lut_mode { LUT_RAM_B }; +enum phy_state { + TX_OFF_SYMCLK_OFF, + TX_ON_SYMCLK_ON, + TX_OFF_SYMCLK_ON +}; + /** * speakersToChannels * diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h index 5097037e3962..8d86159d9de0 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h @@ -22,6 +22,16 @@ * */ +/** + * DOC: mpc-overview + * + * Multiple Pipe/Plane Combined (MPC) is a component in the hardware pipeline + * that performs blending of multiple planes, using global and per-pixel alpha. + * It also performs post-blending color correction operations according to the + * hardware capabilities, such as color transformation matrix and gamma 1D and + * 3D LUT. + */ + #ifndef __DC_MPCC_H__ #define __DC_MPCC_H__ @@ -48,14 +58,39 @@ enum mpcc_blend_mode { MPCC_BLEND_MODE_TOP_BOT_BLENDING }; +/** + * enum mpcc_alpha_blend_mode - define the alpha blend mode regarding pixel + * alpha and plane alpha values + */ enum mpcc_alpha_blend_mode { + /** + * @MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA: per pixel alpha using DPP + * alpha value + */ MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA, + /** + * @MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN: per + * pixel alpha using DPP alpha value multiplied by a global gain (plane + * alpha) + */ MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN, + /** + * @MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA: global alpha value, ignores + * pixel alpha and consider only plane alpha + */ MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA }; -/* - * MPCC blending configuration +/** + * struct mpcc_blnd_cfg - MPCC blending configuration + * + * @black_color: background color + * @alpha_mode: alpha blend mode (MPCC_ALPHA_BLND_MODE) + * @pre_multiplied_alpha: whether pixel color values were pre-multiplied by the + * alpha channel (MPCC_ALPHA_MULTIPLIED_MODE) + * @global_gain: used when blend mode considers both pixel alpha and plane + * alpha value and assumes the global alpha value. + * @global_alpha: plane alpha value */ struct mpcc_blnd_cfg { struct tg_color black_color; /* background color */ @@ -107,8 +142,15 @@ struct mpc_dwb_flow_control { int flow_ctrl_cnt1; }; -/* - * MPCC connection and blending configuration for a single MPCC instance. +/** + * struct mpcc - MPCC connection and blending configuration for a single MPCC instance. + * @mpcc_id: MPCC physical instance + * @dpp_id: DPP input to this MPCC + * @mpcc_bot: pointer to bottom layer MPCC. NULL when not connected. + * @blnd_cfg: the blending configuration for this MPCC + * @sm_cfg: stereo mix setting for this MPCC + * @shared_bottom: if MPCC output to both OPP and DWB endpoints, true. Otherwise, false. + * * This struct is used as a node in an MPC tree. */ struct mpcc { @@ -120,8 +162,12 @@ struct mpcc { bool shared_bottom; /* TRUE if MPCC output to both OPP and DWB endpoints, else FALSE */ }; -/* - * MPC tree represents all MPCC connections for a pipe. +/** + * struct mpc_tree - MPC tree represents all MPCC connections for a pipe. + * + * @opp_id: the OPP instance that owns this MPC tree + * @opp_list: the top MPCC layer of the MPC tree that outputs to OPP endpoint + * */ struct mpc_tree { int opp_id; /* The OPP instance that owns this MPC tree */ @@ -149,13 +195,18 @@ struct mpcc_state { uint32_t busy; }; +/** + * struct mpc_funcs - funcs + */ struct mpc_funcs { void (*read_mpcc_state)( struct mpc *mpc, int mpcc_inst, struct mpcc_state *s); - /* + /** + * @insert_plane: + * * Insert DPP into MPC tree based on specified blending position. * Only used for planes that are part of blending chain for OPP output * @@ -180,7 +231,9 @@ struct mpc_funcs { int dpp_id, int mpcc_id); - /* + /** + * @remove_mpcc: + * * Remove a specified MPCC from the MPC tree. * * Parameters: @@ -195,7 +248,9 @@ struct mpc_funcs { struct mpc_tree *tree, struct mpcc *mpcc); - /* + /** + * @mpc_init: + * * Reset the MPCC HW status by disconnecting all muxes. * * Parameters: @@ -208,7 +263,9 @@ struct mpc_funcs { struct mpc *mpc, unsigned int mpcc_id); - /* + /** + * @update_blending: + * * Update the blending configuration for a specified MPCC. * * Parameters: @@ -223,7 +280,9 @@ struct mpc_funcs { struct mpcc_blnd_cfg *blnd_cfg, int mpcc_id); - /* + /** + * @cursor_lock: + * * Lock cursor updates for the specified OPP. * OPP defines the set of MPCC that are locked together for cursor. * @@ -239,8 +298,10 @@ struct mpc_funcs { int opp_id, bool lock); - /* - * Add DPP into 'secondary' MPC tree based on specified blending position. + /** + * @insert_plane_to_secondary: + * + * Add DPP into secondary MPC tree based on specified blending position. * Only used for planes that are part of blending chain for DWB output * * Parameters: @@ -264,7 +325,9 @@ struct mpc_funcs { int dpp_id, int mpcc_id); - /* + /** + * @remove_mpcc_from_secondary: + * * Remove a specified DPP from the 'secondary' MPC tree. * * Parameters: diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h index 4cfa733cf96f..72eef7a5ed83 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h @@ -137,7 +137,13 @@ struct crc_params { bool enable; }; +/** + * struct timing_generator - Entry point to Output Timing Generator feature. + */ struct timing_generator { + /** + * @funcs: Timing generator control functions + */ const struct timing_generator_funcs *funcs; struct dc_bios *bp; struct dc_context *ctx; @@ -148,7 +154,9 @@ struct dc_crtc_timing; struct drr_params; - +/** + * struct timing_generator_funcs - Control timing generator on a given device. + */ struct timing_generator_funcs { bool (*validate_timing)(struct timing_generator *tg, const struct dc_crtc_timing *timing); @@ -273,8 +281,8 @@ struct timing_generator_funcs { const struct crc_params *params); /** - * Get CRCs for the given timing generator. Return false if CRCs are - * not enabled (via configure_crc). + * @get_crc: Get CRCs for the given timing generator. Return false if + * CRCs are not enabled (via configure_crc). */ bool (*get_crc)(struct timing_generator *tg, uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index ccb3c719fc4d..52b4350c9cd8 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -245,6 +245,8 @@ struct hw_sequencer_funcs { struct tg_color *color, int mpcc_id); + void (*update_phy_state)(struct dc_state *state, struct pipe_ctx *pipe_ctx, enum phy_state target_state); + void (*commit_subvp_config)(struct dc *dc, struct dc_state *context); void (*subvp_pipe_control_lock)(struct dc *dc, struct dc_state *context, @@ -271,6 +273,11 @@ void get_surface_visual_confirm_color( const struct pipe_ctx *pipe_ctx, struct tg_color *color); +void get_subvp_visual_confirm_color( + struct dc *dc, + struct pipe_ctx *pipe_ctx, + struct tg_color *color); + void get_hdr_visual_confirm_color( struct pipe_ctx *pipe_ctx, struct tg_color *color); diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c index db7b0b155374..226af06278ce 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c @@ -116,7 +116,7 @@ static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) dto_params.timing = &pipe_ctx->stream->timing; dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr); - dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, link_enc->inst); + dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, stream_enc->inst); dccg->funcs->enable_symclk32_se(dccg, stream_enc->inst, phyd32clk); dccg->funcs->set_dtbclk_dto(dccg, &dto_params); stream_enc->funcs->enable_stream(stream_enc); @@ -137,7 +137,7 @@ static void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) stream_enc->funcs->disable(stream_enc); dccg->funcs->set_dtbclk_dto(dccg, &dto_params); dccg->funcs->disable_symclk32_se(dccg, stream_enc->inst); - dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, pipe_ctx->link_res.hpo_dp_link_enc->inst); + dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, stream_enc->inst); } static void setup_hpo_dp_stream_attribute(struct pipe_ctx *pipe_ctx) diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h index ced176d17bae..f34c45b19fcb 100644 --- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -441,6 +441,7 @@ struct dmub_srv { /* Feature capabilities reported by fw */ struct dmub_feature_caps feature_caps; + struct dmub_visual_confirm_color visual_confirm_color; }; /** diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index d7f3619352f0..7cddbc431b57 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -234,8 +234,7 @@ union dmub_psr_debug_flags { }; /** - * DMUB feature capabilities. - * After DMUB init, driver will query FW capabilities prior to enabling certain features. + * DMUB visual confirm color */ struct dmub_feature_caps { /** @@ -246,6 +245,16 @@ struct dmub_feature_caps { uint8_t reserved[6]; }; +struct dmub_visual_confirm_color { + /** + * Maximum 10 bits color value + */ + uint16_t color_r_cr; + uint16_t color_g_y; + uint16_t color_b_cb; + uint16_t panel_inst; +}; + #if defined(__cplusplus) } #endif @@ -645,6 +654,10 @@ enum dmub_cmd_type { */ DMUB_CMD__QUERY_FEATURE_CAPS = 6, /** + * Command type used to get visual confirm color. + */ + DMUB_CMD__GET_VISUAL_CONFIRM_COLOR = 8, + /** * Command type used for all PSR commands. */ DMUB_CMD__PSR = 64, @@ -976,8 +989,16 @@ struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 { uint16_t vtotal; uint8_t main_pipe_index; uint8_t phantom_pipe_index; + /* Since the microschedule is calculated in terms of OTG lines, + * include any scaling factors to make sure when we get accurate + * conversion when programming MALL_START_LINE (which is in terms + * of HUBP lines). If 4K is being downscaled to 1080p, scale factor + * is 1/2 (numerator = 1, denominator = 2). + */ + uint8_t scale_factor_numerator; + uint8_t scale_factor_denominator; uint8_t is_drr; - uint8_t padding; + uint8_t pad[2]; } subvp_data; struct { @@ -999,7 +1020,11 @@ struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 { } vblank_data; } pipe_config; - enum mclk_switch_mode mode; + /* - subvp_data in the union (pipe_config) takes up 27 bytes. + * - Make the "mode" field a uint8_t instead of enum so we only use 1 byte (only + * for the DMCUB command, cast to enum once we populate the DMCUB subvp state). + */ + uint8_t mode; // enum mclk_switch_mode }; /** @@ -2766,6 +2791,31 @@ struct dmub_rb_cmd_query_feature_caps { struct dmub_cmd_query_feature_caps_data query_feature_caps_data; }; +/** + * Data passed from driver to FW in a DMUB_CMD__GET_VISUAL_CONFIRM_COLOR command. + */ +struct dmub_cmd_visual_confirm_color_data { + /** + * DMUB feature capabilities. + * After DMUB init, driver will query FW capabilities prior to enabling certain features. + */ +struct dmub_visual_confirm_color visual_confirm_color; +}; + +/** + * Definition of a DMUB_CMD__GET_VISUAL_CONFIRM_COLOR command. + */ +struct dmub_rb_cmd_get_visual_confirm_color { + /** + * Command header. + */ + struct dmub_cmd_header header; + /** + * Data passed from driver to FW in a DMUB_CMD__GET_VISUAL_CONFIRM_COLOR command. + */ + struct dmub_cmd_visual_confirm_color_data visual_confirm_color_data; +}; + struct dmub_optc_state { uint32_t v_total_max; uint32_t v_total_min; @@ -3138,6 +3188,11 @@ union dmub_rb_cmd { * Definition of a DMUB_CMD__QUERY_FEATURE_CAPS command. */ struct dmub_rb_cmd_query_feature_caps query_feature_caps; + + /** + * Definition of a DMUB_CMD__GET_VISUAL_CONFIRM_COLOR command. + */ + struct dmub_rb_cmd_get_visual_confirm_color visual_confirm_color; struct dmub_rb_cmd_drr_update drr_update; struct dmub_rb_cmd_fw_assisted_mclk_switch fw_assisted_mclk_switch; |