diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-02-21 14:44:44 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-02-21 14:44:44 -0800 |
commit | d99676af540c2dc829999928fb81c58c80a1dce4 (patch) | |
tree | a78602eb6fa5d46d867c00ee187179ced6c18766 /drivers/gpu/drm/amd/display/dc | |
parent | 10e2ec8edece2566b40f69bae035a555ece71ab4 (diff) | |
parent | f730f39eb981af249d57336b47cfe3925632a7fd (diff) |
Merge tag 'drm-next-2021-02-19' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie:
"A pretty normal tree, lots of refactoring across the board, ttm, i915,
nouveau, and bunch of features in various drivers.
docs:
- lots of updated docs
core:
- require crtc to have unique primary plane
- fourcc macro fix
- PCI bar quirk for bar resizing
- don't sent hotplug on error
- move vm code to legacy
- nuke hose only used on old oboslete alpha
dma-buf:
- kernel doc updates
- improved lock tracking
dp/hdmi:
- DP-HDMI2.1 protocol converter support
ttm:
- bo size handling cleanup
- release a pinned bo warning
- cleanup lru handler
- avoid using pages with drm_prime_sg_to_page_addr_arrays
cma-helper:
- prime/mmap fixes
bridge:
- add DP support
gma500:
- remove gma3600 support
i915:
- try eDP fast/narrow link again with fallback
- Intel eDP backlight control
- replace display register read/write macros
- refactor intel_display.c
- display power improvements
- HPD code cleanup
- Rocketlake display fixes
- Power/backlight/RPM fixes
- DG1 display fix
- IVB/BYT clear residuals security fix again
- make i915 mitigations options via parameter
- HSW GT1 GPU hangs fixes
- DG1 workaround hang fixes
- TGL DMAR hang avoidance
- Lots of GT fixes
- follow on fixes for residuals clear
- gen7 per-engine-reset support
- HDCP2.2 + HDCP1.4 GEN12 DP MST support
- TGL clear color support
- backlight refactoring
- VRR/Adaptive sync enabling on DP/EDP for TGL+
- async flips for all ilk+
amdgpu:
- rework IH ring handling (Vega/Navi)
- rework HDP handling (Vega/Navi)
- swSMU updates for renoir/vangogh
- Sienna Cichild overdrive support
- FP16 on DCE8-11 support
- GPU reset on navy flounder/vangogh
- SMU profile fixes for APU
- SR-IOV fixes
- Vangogh SMU fixes
- fan speed control fixes
amdkfd:
- config handling fix
- buffer free fix
- recursive lock warnings fix
nouveau:
- Turing MMU fault recovery fixes
- mDP connectors reporting fix
- audio locking fixes
- rework engines/instances code to support new scheme
tegra:
- VIC newer firmware support
- display/gr2d fixes for older tegra
- pm reference leak fix
mediatek:
- SOC MT8183 support
- decouple sub driver + share mtk mutex driver
radeon:
- PCI resource fix for some platforms
ingenic:
- pm support
- 8-bit delta RGB panels
vmwgfx:
- managed driver helpers
vc4:
- BCM2711 DSI1 support
- converted to atomic helpers
- enable 10/12 bpc outputs
- gem prime mmap helpers
- CEC fix
omap:
- use degamma table
- CTM support
- rework DSI support
imx:
- stack usage fixes
- drm managed support
- imx-tve clock provider leak fix
-
rcar-du:
- default mode fixes
- conversion to managed API
hisilicon:
- use simple encoder
vkms:
- writeback connector support
d3:
- BT2020 support"
* tag 'drm-next-2021-02-19' of git://anongit.freedesktop.org/drm/drm: (1459 commits)
drm/amdgpu: Set reference clock to 100Mhz on Renoir (v2)
drm/radeon: OLAND boards don't have VCE
drm/amdkfd: Fix recursive lock warnings
drm/amd/display: Add FPU wrappers to dcn21_validate_bandwidth()
drm/amd/display: Fix potential integer overflow
drm/amdgpu/display: remove hdcp_srm sysfs on device removal
drm/amdgpu: fix CGTS_TCC_DISABLE register offset on gfx10.3
drm/i915/gt: Correct surface base address for renderclear
drm/i915: Disallow plane x+w>stride on ilk+ with X-tiling
drm/nouveau/top/ga100: initial support
drm/nouveau/top: add ioctrl/nvjpg
drm/nouveau/privring: rename from ibus
drm/nouveau/nvkm: remove nvkm_subdev.index
drm/nouveau/nvkm: determine subdev id/order from layout
drm/nouveau/vic: switch to instanced constructor
drm/nouveau/sw: switch to instanced constructor
drm/nouveau/sec2: switch to instanced constructor
drm/nouveau/sec: switch to instanced constructor
drm/nouveau/pm: switch to instanced constructor
drm/nouveau/nvenc: switch to instanced constructor
...
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc')
117 files changed, 1771 insertions, 1164 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index bf8fe0471b8f..5bf2f2375b40 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -69,5 +69,7 @@ AMD_DISPLAY_FILES += $(AMD_DISPLAY_CORE) AMD_DISPLAY_FILES += $(AMD_DM_REG_UPDATE) DC_DMUB += dc_dmub_srv.o +DC_EDID += dc_edid_parser.o AMD_DISPLAY_DMUB = $(addprefix $(AMDDALPATH)/dc/,$(DC_DMUB)) -AMD_DISPLAY_FILES += $(AMD_DISPLAY_DMUB) +AMD_DISPLAY_EDID = $(addprefix $(AMDDALPATH)/dc/,$(DC_EDID)) +AMD_DISPLAY_FILES += $(AMD_DISPLAY_DMUB) $(AMD_DISPLAY_EDID) diff --git a/drivers/gpu/drm/amd/display/dc/basics/conversion.c b/drivers/gpu/drm/amd/display/dc/basics/conversion.c index 24ed03d8cda7..6767fab55c26 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/conversion.c +++ b/drivers/gpu/drm/amd/display/dc/basics/conversion.c @@ -73,12 +73,9 @@ uint16_t fixed_point_to_int_frac( return result; } -/** -* convert_float_matrix -* This converts a double into HW register spec defined format S2D13. -* @param : -* @return None -*/ +/* + * convert_float_matrix - This converts a double into HW register spec defined format S2D13. + */ void convert_float_matrix( uint16_t *matrix, struct fixed31_32 *flt, diff --git a/drivers/gpu/drm/amd/display/dc/basics/dc_common.c b/drivers/gpu/drm/amd/display/dc/basics/dc_common.c index b2fc4f8e6482..ad04ef98e652 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/dc_common.c +++ b/drivers/gpu/drm/amd/display/dc/basics/dc_common.c @@ -49,20 +49,24 @@ bool is_rgb_cspace(enum dc_color_space output_color_space) } } -bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx) +bool is_child_pipe_tree_visible(struct pipe_ctx *pipe_ctx) { if (pipe_ctx->plane_state && pipe_ctx->plane_state->visible) return true; - if (pipe_ctx->bottom_pipe && is_lower_pipe_tree_visible(pipe_ctx->bottom_pipe)) + if (pipe_ctx->bottom_pipe && is_child_pipe_tree_visible(pipe_ctx->bottom_pipe)) + return true; + if (pipe_ctx->next_odm_pipe && is_child_pipe_tree_visible(pipe_ctx->next_odm_pipe)) return true; return false; } -bool is_upper_pipe_tree_visible(struct pipe_ctx *pipe_ctx) +bool is_parent_pipe_tree_visible(struct pipe_ctx *pipe_ctx) { if (pipe_ctx->plane_state && pipe_ctx->plane_state->visible) return true; - if (pipe_ctx->top_pipe && is_upper_pipe_tree_visible(pipe_ctx->top_pipe)) + if (pipe_ctx->top_pipe && is_parent_pipe_tree_visible(pipe_ctx->top_pipe)) + return true; + if (pipe_ctx->prev_odm_pipe && is_parent_pipe_tree_visible(pipe_ctx->prev_odm_pipe)) return true; return false; } @@ -71,9 +75,13 @@ bool is_pipe_tree_visible(struct pipe_ctx *pipe_ctx) { if (pipe_ctx->plane_state && pipe_ctx->plane_state->visible) return true; - if (pipe_ctx->top_pipe && is_upper_pipe_tree_visible(pipe_ctx->top_pipe)) + if (pipe_ctx->top_pipe && is_parent_pipe_tree_visible(pipe_ctx->top_pipe)) + return true; + if (pipe_ctx->bottom_pipe && is_child_pipe_tree_visible(pipe_ctx->bottom_pipe)) + return true; + if (pipe_ctx->prev_odm_pipe && is_parent_pipe_tree_visible(pipe_ctx->prev_odm_pipe)) return true; - if (pipe_ctx->bottom_pipe && is_lower_pipe_tree_visible(pipe_ctx->bottom_pipe)) + if (pipe_ctx->next_odm_pipe && is_child_pipe_tree_visible(pipe_ctx->next_odm_pipe)) return true; return false; } diff --git a/drivers/gpu/drm/amd/display/dc/basics/dc_common.h b/drivers/gpu/drm/amd/display/dc/basics/dc_common.h index 7c0cbf47e8ce..b061497480b8 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/dc_common.h +++ b/drivers/gpu/drm/amd/display/dc/basics/dc_common.h @@ -30,9 +30,9 @@ bool is_rgb_cspace(enum dc_color_space output_color_space); -bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx); +bool is_child_pipe_tree_visible(struct pipe_ctx *pipe_ctx); -bool is_upper_pipe_tree_visible(struct pipe_ctx *pipe_ctx); +bool is_parent_pipe_tree_visible(struct pipe_ctx *pipe_ctx); bool is_pipe_tree_visible(struct pipe_ctx *pipe_ctx); diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c index 23a373ca94b5..c67d21a5ee52 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c @@ -911,11 +911,11 @@ static enum bp_result get_ss_info_from_tbl( * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info ver 3.1, * there is only one entry for each signal /ss id. However, there is * no planning of supporting multiple spread Sprectum entry for EverGreen - * @param [in] this - * @param [in] signal, ASSignalType to be converted to info index - * @param [in] index, number of entries that match the converted info index - * @param [out] ss_info, sprectrum information structure, - * @return Bios parser result code + * @dcb: pointer to the DC BIOS + * @signal: ASSignalType to be converted to info index + * @index: number of entries that match the converted info index + * @ss_info: sprectrum information structure, + * return: Bios parser result code */ static enum bp_result bios_parser_get_spread_spectrum_info( struct dc_bios *dcb, @@ -985,10 +985,10 @@ static enum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1( * There can not be more than 1 entry for ASIC_InternalSS_Info Ver 2.1 or * SS_Info. * - * @param this - * @param id, spread sprectrum info index - * @param pSSinfo, sprectrum information structure, - * @return Bios parser result code + * @bp: pointer to the BIOS parser + * @id: spread sprectrum info index + * @ss_info: sprectrum information structure, + * return: BIOS parser result code */ static enum bp_result get_ss_info_from_tbl( struct bios_parser *bp, @@ -1011,9 +1011,10 @@ static enum bp_result get_ss_info_from_tbl( * from the VBIOS * There will not be multiple entry for Ver 2.1 * - * @param id, spread sprectrum info index - * @param pSSinfo, sprectrum information structure, - * @return Bios parser result code + * @bp: pointer to the Bios parser + * @id: spread sprectrum info index + * @info: sprectrum information structure, + * return: Bios parser result code */ static enum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1( struct bios_parser *bp, @@ -1076,9 +1077,10 @@ static enum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1( * of entries that matches the id * for, the SS_Info table, there should not be more than 1 entry match. * - * @param [in] id, spread sprectrum id - * @param [out] pSSinfo, sprectrum information structure, - * @return Bios parser result code + * @bp: pointer to the Bios parser + * @id: spread sprectrum id + * @ss_info: sprectrum information structure, + * return: Bios parser result code */ static enum bp_result get_ss_info_from_ss_info_table( struct bios_parser *bp, @@ -1451,16 +1453,14 @@ static enum bp_result get_embedded_panel_info_v1_3( } /** - * bios_parser_get_encoder_cap_info + * bios_parser_get_encoder_cap_info - get encoder capability + * information of input object id * - * @brief - * Get encoder capability information of input object id - * - * @param object_id, Object id - * @param object_id, encoder cap information structure - * - * @return Bios parser result code + * @dcb: pointer to the DC BIOS + * @object_id: object id + * @info: encoder cap information structure * + * return: Bios parser result code */ static enum bp_result bios_parser_get_encoder_cap_info( struct dc_bios *dcb, @@ -1490,17 +1490,12 @@ static enum bp_result bios_parser_get_encoder_cap_info( } /** - * get_encoder_cap_record - * - * @brief - * Get encoder cap record for the object - * - * @param object, ATOM object + * get_encoder_cap_record - Get encoder cap record for the object * - * @return atom encoder cap record - * - * @note - * search all records to find the ATOM_ENCODER_CAP_RECORD_V2 record + * @bp: pointer to the BIOS parser + * @object: ATOM object + * return: atom encoder cap record + * note: search all records to find the ATOM_ENCODER_CAP_RECORD_V2 record */ static ATOM_ENCODER_CAP_RECORD_V2 *get_encoder_cap_record( struct bios_parser *bp, @@ -1557,8 +1552,9 @@ static uint32_t get_ss_entry_number_from_ss_info_tbl( * Get Number of SpreadSpectrum Entry from the ASIC_InternalSS_Info table from * the VBIOS that match the SSid (to be converted from signal) * - * @param[in] signal, ASSignalType to be converted to SSid - * @return number of SS Entry that match the signal + * @dcb: pointer to the DC BIOS + * @signal: ASSignalType to be converted to SSid + * return: number of SS Entry that match the signal */ static uint32_t bios_parser_get_ss_entry_number( struct dc_bios *dcb, @@ -1608,10 +1604,10 @@ static uint32_t bios_parser_get_ss_entry_number( * get_ss_entry_number_from_ss_info_tbl * Get Number of spread spectrum entry from the SS_Info table from the VBIOS. * - * @note There can only be one entry for each id for SS_Info Table - * - * @param [in] id, spread spectrum id - * @return number of SS Entry that match the id + * @bp: pointer to the BIOS parser + * @id: spread spectrum id + * return: number of SS Entry that match the id + * note: There can only be one entry for each id for SS_Info Table */ static uint32_t get_ss_entry_number_from_ss_info_tbl( struct bios_parser *bp, @@ -1679,8 +1675,9 @@ static uint32_t get_ss_entry_number_from_ss_info_tbl( * There can not be more than 1 entry for ASIC_InternalSS_Info Ver 2.1 or * SS_Info. * - * @param id, spread sprectrum info index - * @return Bios parser result code + * @bp: pointer to the BIOS parser + * @id: spread sprectrum info index + * return: Bios parser result code */ static uint32_t get_ss_entry_number(struct bios_parser *bp, uint32_t id) { @@ -1696,8 +1693,9 @@ static uint32_t get_ss_entry_number(struct bios_parser *bp, uint32_t id) * Ver 2.1 from the VBIOS * There will not be multiple entry for Ver 2.1 * - * @param id, spread sprectrum info index - * @return number of SS Entry that match the id + * @bp: pointer to the BIOS parser + * @id: spread sprectrum info index + * return: number of SS Entry that match the id */ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_v2_1( struct bios_parser *bp, @@ -1731,8 +1729,9 @@ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_v2_1( * Get Number of SpreadSpectrum Entry from the ASIC_InternalSS_Info table of * the VBIOS that matches id * - * @param[in] id, spread sprectrum id - * @return number of SS Entry that match the id + * @bp: pointer to the BIOS parser + * @id: spread sprectrum id + * return: number of SS Entry that match the id */ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_V3_1( struct bios_parser *bp, @@ -1767,10 +1766,11 @@ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_V3_1( * bios_parser_get_gpio_pin_info * Get GpioPin information of input gpio id * - * @param gpio_id, GPIO ID - * @param info, GpioPin information structure - * @return Bios parser result code - * @note + * @dcb: pointer to the DC BIOS + * @gpio_id: GPIO ID + * @info: GpioPin information structure + * return: Bios parser result code + * note: * to get the GPIO PIN INFO, we need: * 1. get the GPIO_ID from other object table, see GetHPDInfo() * 2. in DATA_TABLE.GPIO_Pin_LUT, search all records, to get the registerA @@ -2197,13 +2197,10 @@ static uint32_t get_support_mask_for_device_id(struct device_id device_id) } /** - * bios_parser_set_scratch_critical_state - * - * @brief - * update critical state bit in VBIOS scratch register - * - * @param - * bool - to set or reset state + * bios_parser_set_scratch_critical_state - update critical state + * bit in VBIOS scratch register + * @dcb: pointer to the DC BIOS + * @state: set or reset state */ static void bios_parser_set_scratch_critical_state( struct dc_bios *dcb, @@ -2222,7 +2219,7 @@ static void bios_parser_set_scratch_critical_state( * bios_parser *bp - [in]BIOS parser handler to get master data table * integrated_info *info - [out] store and output integrated info * - * @return + * return: * enum bp_result - BP_RESULT_OK if information is available, * BP_RESULT_BADBIOSTABLE otherwise. */ @@ -2372,7 +2369,7 @@ static enum bp_result get_integrated_info_v8( * bios_parser *bp - [in]BIOS parser handler to get master data table * integrated_info *info - [out] store and output integrated info * - * @return + * return: * enum bp_result - BP_RESULT_OK if information is available, * BP_RESULT_BADBIOSTABLE otherwise. */ @@ -2509,7 +2506,7 @@ static enum bp_result get_integrated_info_v9( * bios_parser *bp - [in]BIOS parser handler to get master data table * integrated_info *info - [out] store and output integrated info * - * @return + * return: * enum bp_result - BP_RESULT_OK if information is available, * BP_RESULT_BADBIOSTABLE otherwise. */ @@ -2585,7 +2582,7 @@ static struct integrated_info *bios_parser_create_integrated_info( return NULL; } -enum bp_result update_slot_layout_info( +static enum bp_result update_slot_layout_info( struct dc_bios *dcb, unsigned int i, struct slot_layout_info *slot_layout_info, @@ -2689,7 +2686,7 @@ enum bp_result update_slot_layout_info( } -enum bp_result get_bracket_layout_record( +static enum bp_result get_bracket_layout_record( struct dc_bios *dcb, unsigned int bracket_layout_id, struct slot_layout_info *slot_layout_info) 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 670c26583817..9f9fda3118d1 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -485,10 +485,11 @@ static struct atom_hpd_int_record *get_hpd_record( * bios_parser_get_gpio_pin_info * Get GpioPin information of input gpio id * - * @param gpio_id, GPIO ID - * @param info, GpioPin information structure - * @return Bios parser result code - * @note + * @dcb: pointer to the DC BIOS + * @gpio_id: GPIO ID + * @info: GpioPin information structure + * return: Bios parser result code + * note: * to get the GPIO PIN INFO, we need: * 1. get the GPIO_ID from other object table, see GetHPDInfo() * 2. in DATA_TABLE.GPIO_Pin_LUT, search all records, @@ -801,11 +802,11 @@ static enum bp_result get_ss_info_v4_2( * ver 3.1, * there is only one entry for each signal /ss id. However, there is * no planning of supporting multiple spread Sprectum entry for EverGreen - * @param [in] this - * @param [in] signal, ASSignalType to be converted to info index - * @param [in] index, number of entries that match the converted info index - * @param [out] ss_info, sprectrum information structure, - * @return Bios parser result code + * @dcb: pointer to the DC BIOS + * @signal: ASSignalType to be converted to info index + * @index: number of entries that match the converted info index + * @ss_info: sprectrum information structure, + * return: Bios parser result code */ static enum bp_result bios_parser_get_spread_spectrum_info( struct dc_bios *dcb, @@ -1196,13 +1197,11 @@ static bool bios_parser_is_accelerated_mode( } /** - * bios_parser_set_scratch_critical_state + * bios_parser_set_scratch_critical_state - update critical state bit + * in VBIOS scratch register * - * @brief - * update critical state bit in VBIOS scratch register - * - * @param - * bool - to set or reset state + * @dcb: pointer to the DC BIO + * @state: set or reset state */ static void bios_parser_set_scratch_critical_state( struct dc_bios *dcb, diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c index 070459e3e407..afc10b954ffa 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c @@ -245,6 +245,23 @@ static enum bp_result encoder_control_digx_v3( cntl->enable_dp_audio); params.ucLaneNum = (uint8_t)(cntl->lanes_number); + switch (cntl->color_depth) { + case COLOR_DEPTH_888: + params.ucBitPerColor = PANEL_8BIT_PER_COLOR; + break; + case COLOR_DEPTH_101010: + params.ucBitPerColor = PANEL_10BIT_PER_COLOR; + break; + case COLOR_DEPTH_121212: + params.ucBitPerColor = PANEL_12BIT_PER_COLOR; + break; + case COLOR_DEPTH_161616: + params.ucBitPerColor = PANEL_16BIT_PER_COLOR; + break; + default: + break; + } + if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params)) result = BP_RESULT_OK; @@ -274,6 +291,23 @@ static enum bp_result encoder_control_digx_v4( cntl->enable_dp_audio)); params.ucLaneNum = (uint8_t)(cntl->lanes_number); + switch (cntl->color_depth) { + case COLOR_DEPTH_888: + params.ucBitPerColor = PANEL_8BIT_PER_COLOR; + break; + case COLOR_DEPTH_101010: + params.ucBitPerColor = PANEL_10BIT_PER_COLOR; + break; + case COLOR_DEPTH_121212: + params.ucBitPerColor = PANEL_12BIT_PER_COLOR; + break; + case COLOR_DEPTH_161616: + params.ucBitPerColor = PANEL_16BIT_PER_COLOR; + break; + default: + break; + } + if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params)) result = BP_RESULT_OK; @@ -1057,6 +1091,19 @@ static enum bp_result set_pixel_clock_v5( * driver choose program it itself, i.e. here we program it * to 888 by default. */ + if (bp_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) + switch (bp_params->color_depth) { + case TRANSMITTER_COLOR_DEPTH_30: + /* yes this is correct, the atom define is wrong */ + clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_32BPP; + break; + case TRANSMITTER_COLOR_DEPTH_36: + /* yes this is correct, the atom define is wrong */ + clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP; + break; + default: + break; + } if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk)) result = BP_RESULT_OK; @@ -1135,6 +1182,20 @@ static enum bp_result set_pixel_clock_v6( * driver choose program it itself, i.e. here we pass required * target rate that includes deep color. */ + if (bp_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) + switch (bp_params->color_depth) { + case TRANSMITTER_COLOR_DEPTH_30: + clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6; + break; + case TRANSMITTER_COLOR_DEPTH_36: + clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6; + break; + case TRANSMITTER_COLOR_DEPTH_48: + clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP; + break; + default: + break; + } if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk)) result = BP_RESULT_OK; diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c index 48b4ef03fc8f..5b77251e0590 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c @@ -114,18 +114,14 @@ bool dal_cmd_table_helper_controller_id_to_atom( } /** -* translate_transmitter_bp_to_atom -* -* @brief -* Translate the Transmitter to the corresponding ATOM BIOS value -* -* @param -* input transmitter -* output digitalTransmitter -* // =00: Digital Transmitter1 ( UNIPHY linkAB ) -* // =01: Digital Transmitter2 ( UNIPHY linkCD ) -* // =02: Digital Transmitter3 ( UNIPHY linkEF ) -*/ + * translate_transmitter_bp_to_atom - Translate the Transmitter to the + * corresponding ATOM BIOS value + * @t: transmitter + * returns: output digitalTransmitter + * // =00: Digital Transmitter1 ( UNIPHY linkAB ) + * // =01: Digital Transmitter2 ( UNIPHY linkCD ) + * // =02: Digital Transmitter3 ( UNIPHY linkEF ) + */ uint8_t dal_cmd_table_helper_transmitter_bp_to_atom( enum transmitter t) { diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c index 7736c92d55c4..455ee2be15a3 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c @@ -128,18 +128,14 @@ bool dal_cmd_table_helper_controller_id_to_atom2( } /** -* translate_transmitter_bp_to_atom -* -* @brief -* Translate the Transmitter to the corresponding ATOM BIOS value -* -* @param -* input transmitter -* output digitalTransmitter -* // =00: Digital Transmitter1 ( UNIPHY linkAB ) -* // =01: Digital Transmitter2 ( UNIPHY linkCD ) -* // =02: Digital Transmitter3 ( UNIPHY linkEF ) -*/ + * translate_transmitter_bp_to_atom2 - Translate the Transmitter to the + * corresponding ATOM BIOS value + * @t: transmitter + * returns: digitalTransmitter + * // =00: Digital Transmitter1 ( UNIPHY linkAB ) + * // =01: Digital Transmitter2 ( UNIPHY linkCD ) + * // =02: Digital Transmitter3 ( UNIPHY linkEF ) + */ uint8_t dal_cmd_table_helper_transmitter_bp_to_atom2( enum transmitter t) { diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c index ef41b287cbe2..e633f8a51edb 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c @@ -106,7 +106,6 @@ static void calculate_bandwidth( bool lpt_enabled; enum bw_defines sclk_message; enum bw_defines yclk_message; - enum bw_defines v_filter_init_mode[maximum_number_of_surfaces]; enum bw_defines tiling_mode[maximum_number_of_surfaces]; enum bw_defines surface_type[maximum_number_of_surfaces]; enum bw_defines voltage; @@ -792,12 +791,8 @@ static void calculate_bandwidth( data->v_filter_init[i] = bw_add(data->v_filter_init[i], bw_int_to_fixed(1)); } if (data->stereo_mode[i] == bw_def_top_bottom) { - v_filter_init_mode[i] = bw_def_manual; data->v_filter_init[i] = bw_min2(data->v_filter_init[i], bw_int_to_fixed(4)); } - else { - v_filter_init_mode[i] = bw_def_auto; - } if (data->stereo_mode[i] == bw_def_top_bottom) { data->num_lines_at_frame_start = bw_int_to_fixed(1); } @@ -2730,7 +2725,7 @@ void bw_calcs_init(struct bw_calcs_dceip *bw_dceip, } -/** +/* * Compare calculated (required) clocks against the clocks available at * maximum voltage (max Performance Level). */ @@ -3001,13 +2996,12 @@ static bool all_displays_in_sync(const struct pipe_ctx pipe[], return true; } -/** +/* * Return: * true - Display(s) configuration supported. * In this case 'calcs_output' contains data for HW programming * false - Display(s) configuration not supported (not enough bandwidth). */ - bool bw_calcs(struct dc_context *ctx, const struct bw_calcs_dceip *dceip, const struct bw_calcs_vbios *vbios, @@ -3028,7 +3022,7 @@ bool bw_calcs(struct dc_context *ctx, calcs_output->all_displays_in_sync = false; if (data->number_of_displays != 0) { - uint8_t yclk_lvl, sclk_lvl; + uint8_t yclk_lvl; struct bw_fixed high_sclk = vbios->high_sclk; struct bw_fixed mid1_sclk = vbios->mid1_sclk; struct bw_fixed mid2_sclk = vbios->mid2_sclk; @@ -3049,7 +3043,6 @@ bool bw_calcs(struct dc_context *ctx, calculate_bandwidth(dceip, vbios, data); yclk_lvl = data->y_clk_level; - sclk_lvl = data->sclk_level; calcs_output->nbp_state_change_enable = data->nbp_state_change_enable; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c index 75b8240ed059..e133edc587d3 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c @@ -187,17 +187,6 @@ static void ramp_up_dispclk_with_dpp( clk_mgr->base.clks.max_supported_dppclk_khz = new_clocks->max_supported_dppclk_khz; } -static bool is_mpo_enabled(struct dc_state *context) -{ - int i; - - for (i = 0; i < context->stream_count; i++) { - if (context->stream_status[i].plane_count > 1) - return true; - } - return false; -} - static void rv1_update_clocks(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool safe_to_lower) @@ -295,22 +284,9 @@ static void rv1_update_clocks(struct clk_mgr *clk_mgr_base, if (pp_smu->set_hard_min_fclk_by_freq && pp_smu->set_hard_min_dcfclk_by_freq && pp_smu->set_min_deep_sleep_dcfclk) { - // Only increase clocks when display is active and MPO is enabled - if (display_count && is_mpo_enabled(context)) { - pp_smu->set_hard_min_fclk_by_freq(&pp_smu->pp_smu, - ((new_clocks->fclk_khz / 1000) * 101) / 100); - pp_smu->set_hard_min_dcfclk_by_freq(&pp_smu->pp_smu, - ((new_clocks->dcfclk_khz / 1000) * 101) / 100); - pp_smu->set_min_deep_sleep_dcfclk(&pp_smu->pp_smu, - (new_clocks->dcfclk_deep_sleep_khz + 999) / 1000); - } else { - pp_smu->set_hard_min_fclk_by_freq(&pp_smu->pp_smu, - new_clocks->fclk_khz / 1000); - pp_smu->set_hard_min_dcfclk_by_freq(&pp_smu->pp_smu, - new_clocks->dcfclk_khz / 1000); - pp_smu->set_min_deep_sleep_dcfclk(&pp_smu->pp_smu, - (new_clocks->dcfclk_deep_sleep_khz + 999) / 1000); - } + pp_smu->set_hard_min_fclk_by_freq(&pp_smu->pp_smu, new_clocks->fclk_khz / 1000); + pp_smu->set_hard_min_dcfclk_by_freq(&pp_smu->pp_smu, new_clocks->dcfclk_khz / 1000); + pp_smu->set_min_deep_sleep_dcfclk(&pp_smu->pp_smu, (new_clocks->dcfclk_deep_sleep_khz + 999) / 1000); } } } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c index f2114bc910bf..ec9dc265cde0 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c @@ -257,8 +257,7 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base, if (update_dppclk || update_dispclk) dcn20_update_clocks_update_dentist(clk_mgr); // always update dtos unless clock is lowered and not safe to lower - if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz) - dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); + dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); } } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c index ab98c259ef69..c7e5a64e06af 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c @@ -146,15 +146,15 @@ static noinline void dcn3_build_wm_range_table(struct clk_mgr_internal *clk_mgr) clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF; /* Set D - MALL - SR enter and exit times adjusted for MALL */ -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].valid = true; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us = pstate_latency_us; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us = 2; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us = 4; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.wm_type = WATERMARKS_MALL; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_dcfclk = 0; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_dcfclk = 0xFFFF; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_uclk = min_uclk_mhz; -// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 0xFFFF; + clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].valid = true; + clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us = pstate_latency_us; + clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us = 2; + clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us = 4; + clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.wm_type = WATERMARKS_MALL; + clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_dcfclk = 0; + clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_dcfclk = 0xFFFF; + clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_uclk = min_uclk_mhz; + clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 0xFFFF; } void dcn3_init_clocks(struct clk_mgr *clk_mgr_base) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c index cfa8e02cf103..68942bbc7472 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c @@ -103,7 +103,7 @@ int dcn301_smu_send_msg_with_param( /* Trigger the message transaction by writing the message ID */ REG_WRITE(MP1_SMN_C2PMSG_67, msg_id); - result = dcn301_smu_wait_for_response(clk_mgr, 10, 1000); + result = dcn301_smu_wait_for_response(clk_mgr, 10, 200000); ASSERT(result == VBIOSSMC_Result_OK); diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c index 991b9c5beaa3..aadb801447a7 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c @@ -75,7 +75,8 @@ int vg_get_active_display_cnt_wa( const struct dc_link *link = dc->links[i]; /* abusing the fact that the dig and phy are coupled to see if the phy is enabled */ - if (link->link_enc->funcs->is_dig_enabled(link->link_enc)) + if (link->link_enc->funcs->is_dig_enabled && + link->link_enc->funcs->is_dig_enabled(link->link_enc)) display_count++; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 6cf1a5a2a5ec..c9aede2f783d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -175,6 +175,8 @@ static bool create_links( connectors_num = bios->funcs->get_connectors_number(bios); + DC_LOG_DC("BIOS object table - number of connectors: %d", connectors_num); + if (connectors_num > ENUM_ID_COUNT) { dm_error( "DC: Number of connectors %d exceeds maximum of %d!\n", @@ -193,6 +195,8 @@ static bool create_links( struct link_init_data link_init_params = {0}; struct dc_link *link; + DC_LOG_DC("BIOS object table - printing link object info for connector number: %d, link_index: %d", i, dc->link_count); + link_init_params.ctx = dc->ctx; /* next BIOS object table connector */ link_init_params.connector_index = i; @@ -201,30 +205,14 @@ static bool create_links( link = link_create(&link_init_params); if (link) { - bool should_destory_link = false; - - if (link->connector_signal == SIGNAL_TYPE_EDP) { - if (dc->config.edp_not_connected) { - if (!IS_DIAG_DC(dc->ctx->dce_environment)) - should_destory_link = true; - } else { - enum dc_connection_type type; - dc_link_detect_sink(link, &type); - if (type == dc_connection_none) - should_destory_link = true; - } - } - - if (dc->config.force_enum_edp || !should_destory_link) { dc->links[dc->link_count] = link; link->dc = dc; ++dc->link_count; - } else { - link_destroy(&link); - } } } + DC_LOG_DC("BIOS object table - end"); + for (i = 0; i < num_virtual_links; i++) { struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL); struct encoder_init_data enc_init = {0}; @@ -284,20 +272,16 @@ static void dc_perf_trace_destroy(struct dc_perf_trace **perf_trace) } /** - ***************************************************************************** - * Function: dc_stream_adjust_vmin_vmax + * dc_stream_adjust_vmin_vmax: * - * @brief - * Looks up the pipe context of dc_stream_state and updates the - * vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh - * Rate, which is a power-saving feature that targets reducing panel - * refresh rate while the screen is static + * Looks up the pipe context of dc_stream_state and updates the + * vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh + * Rate, which is a power-saving feature that targets reducing panel + * refresh rate while the screen is static * - * @param [in] dc: dc reference - * @param [in] stream: Initial dc stream state - * @param [in] adjust: Updated parameters for vertical_total_min and - * vertical_total_max - ***************************************************************************** + * @dc: dc reference + * @stream: Initial dc stream state + * @adjust: Updated parameters for vertical_total_min and vertical_total_max */ bool dc_stream_adjust_vmin_vmax(struct dc *dc, struct dc_stream_state *stream, @@ -355,6 +339,7 @@ bool dc_stream_get_crtc_position(struct dc *dc, * @dc: DC Object * @stream: The stream to configure CRC on. * @enable: Enable CRC if true, disable otherwise. + * @crc_window: CRC window (x/y start/end) information * @continuous: Capture CRC on every frame if true. Otherwise, only capture * once. * @@ -420,7 +405,9 @@ 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 * @stream: The DC stream state of the stream to get CRCs from. - * @r_cr, g_y, b_cb: CRC values for the three channels are stored here. + * @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. * * 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. @@ -707,7 +694,6 @@ static bool dc_construct(struct dc *dc, } dc->dcn_ip = dcn_ip; - dc->soc_bounding_box = init_params->soc_bounding_box; #endif if (!dc_construct_ctx(dc, init_params)) { @@ -757,6 +743,10 @@ static bool dc_construct(struct dc *dc, if (!dc->res_pool) goto fail; + /* set i2c speed if not done by the respective dcnxxx__resource.c */ + if (dc->caps.i2c_speed_in_khz_hdcp == 0) + dc->caps.i2c_speed_in_khz_hdcp = dc->caps.i2c_speed_in_khz; + dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg); if (!dc->clk_mgr) goto fail; @@ -764,8 +754,6 @@ static bool dc_construct(struct dc *dc, dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present; #endif - dc->debug.force_ignore_link_settings = init_params->force_ignore_link_settings; - if (dc->res_pool->funcs->update_bw_bounding_box) dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params); @@ -803,7 +791,8 @@ static void disable_all_writeback_pipes_for_stream( stream->writeback_info[i].wb_enabled = false; } -void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *context, struct dc_stream_state *stream, bool lock) +static void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *context, + struct dc_stream_state *stream, bool lock) { int i = 0; @@ -964,19 +953,15 @@ struct dc *dc_create(const struct dc_init_data *init_params) struct dc *dc = kzalloc(sizeof(*dc), GFP_KERNEL); unsigned int full_pipe_count; - if (NULL == dc) - goto alloc_fail; + if (!dc) + return NULL; if (init_params->dce_environment == DCE_ENV_VIRTUAL_HW) { - if (false == dc_construct_ctx(dc, init_params)) { - dc_destruct(dc); - goto construct_fail; - } + if (!dc_construct_ctx(dc, init_params)) + goto destruct_dc; } else { - if (false == dc_construct(dc, init_params)) { - dc_destruct(dc); - goto construct_fail; - } + if (!dc_construct(dc, init_params)) + goto destruct_dc; full_pipe_count = dc->res_pool->pipe_count; if (dc->res_pool->underlay_pipe_index != NO_UNDERLAY_PIPE) @@ -1007,15 +992,36 @@ struct dc *dc_create(const struct dc_init_data *init_params) return dc; -construct_fail: +destruct_dc: + dc_destruct(dc); kfree(dc); - -alloc_fail: return NULL; } +static void detect_edp_presence(struct dc *dc) +{ + struct dc_link *edp_link = get_edp_link(dc); + bool edp_sink_present = true; + + if (!edp_link) + return; + + if (dc->config.edp_not_connected) { + edp_sink_present = false; + } else { + enum dc_connection_type type; + dc_link_detect_sink(edp_link, &type); + if (type == dc_connection_none) + edp_sink_present = false; + } + + edp_link->edp_sink_present = edp_sink_present; +} + void dc_hardware_init(struct dc *dc) { + + detect_edp_presence(dc); if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW) dc->hwss.init_hw(dc); } @@ -1493,7 +1499,7 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context) enum dc_status result = DC_ERROR_UNEXPECTED; int i; - if (false == context_changed(dc, context)) + if (!context_changed(dc, context)) return DC_OK; DC_LOG_DC("%s: %d streams\n", @@ -1540,7 +1546,7 @@ bool dc_acquire_release_mpc_3dlut( if (found_pipe_idx) { if (acquire && pool->funcs->acquire_post_bldn_3dlut) ret = pool->funcs->acquire_post_bldn_3dlut(res_ctx, pool, mpcc_id, lut, shaper); - else if (acquire == false && pool->funcs->release_post_bldn_3dlut) + else if (!acquire && pool->funcs->release_post_bldn_3dlut) ret = pool->funcs->release_post_bldn_3dlut(res_ctx, pool, lut, shaper); } } @@ -2016,7 +2022,7 @@ static enum surface_update_type check_update_surfaces_for_stream( return overall_type; } -/** +/* * dc_check_update_surfaces_for_stream() - Determine update type (fast, med, or full) * * See :c:type:`enum surface_update_type <surface_update_type>` for explanation of update types @@ -2270,6 +2276,9 @@ static void copy_stream_update_to_stream(struct dc *dc, if (update->dither_option) stream->dither_option = *update->dither_option; + + if (update->pending_test_pattern) + stream->test_pattern = *update->pending_test_pattern; /* update current stream with writeback info */ if (update->wb_update) { int i; @@ -2366,6 +2375,15 @@ static void commit_planes_do_stream_update(struct dc *dc, } } + if (stream_update->pending_test_pattern) { + dc_link_dp_set_test_pattern(stream->link, + stream->test_pattern.type, + stream->test_pattern.color_space, + stream->test_pattern.p_link_settings, + stream->test_pattern.p_custom_pattern, + stream->test_pattern.cust_pattern_size); + } + /* Full fe update*/ if (update_type == UPDATE_TYPE_FAST) continue; @@ -2830,7 +2848,7 @@ enum dc_irq_source dc_interrupt_to_irq_source( return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id); } -/** +/* * dc_interrupt_set() - Enable/disable an AMD hw interrupt source */ bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable) @@ -2964,7 +2982,7 @@ static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink return true; } -/** +/* * dc_link_add_remote_sink() - Create a sink and attach it to an existing link * * EDID length is in bytes @@ -3027,7 +3045,7 @@ fail_add_sink: return NULL; } -/** +/* * dc_link_remove_remote_sink() - Remove a remote sink from a dc_link * * Note that this just removes the struct dc_sink - it doesn't @@ -3154,9 +3172,11 @@ void dc_lock_memory_clock_frequency(struct dc *dc) core_link_enable_stream(dc->current_state, &dc->current_state->res_ctx.pipe_ctx[i]); } -bool dc_is_plane_eligible_for_idle_optimizaitons(struct dc *dc, - struct dc_plane_state *plane) +bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, struct dc_plane_state *plane, + struct dc_cursor_attributes *cursor_attr) { + if (dc->hwss.does_plane_fit_in_mall && dc->hwss.does_plane_fit_in_mall(dc, plane, cursor_attr)) + return true; return false; } 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 f4a2088ab179..fa5059f71727 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -203,9 +203,21 @@ static bool program_hpd_filter(const struct dc_link *link) return result; } +bool dc_link_wait_for_t12(struct dc_link *link) +{ + if (link->connector_signal == SIGNAL_TYPE_EDP && link->dc->hwss.edp_wait_for_T12) { + link->dc->hwss.edp_wait_for_T12(link); + + return true; + } + + return false; +} + /** * dc_link_detect_sink() - Determine if there is a sink connected * + * @link: pointer to the dc link * @type: Returned connection type * Does not detect downstream devices, such as MST sinks * or display connected through active dongles @@ -342,7 +354,7 @@ static enum signal_type get_basic_signal_type(struct graphics_object_id encoder, return SIGNAL_TYPE_NONE; } -/** +/* * dc_link_is_dp_sink_present() - Check if there is a native DP * or passive DP-HDMI dongle connected */ @@ -596,8 +608,6 @@ static void query_hdcp_capability(enum signal_type signal, struct dc_link *link) dc_process_hdcp_msg(signal, link, &msg22); if (signal == SIGNAL_TYPE_DISPLAY_PORT || signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { - enum hdcp_message_status status = HDCP_MESSAGE_UNSUPPORTED; - msg14.data = &link->hdcp_caps.bcaps.raw; msg14.length = sizeof(link->hdcp_caps.bcaps.raw); msg14.msg_id = HDCP_MESSAGE_ID_READ_BCAPS; @@ -605,7 +615,7 @@ static void query_hdcp_capability(enum signal_type signal, struct dc_link *link) msg14.link = HDCP_LINK_PRIMARY; msg14.max_retries = 5; - status = dc_process_hdcp_msg(signal, link, &msg14); + dc_process_hdcp_msg(signal, link, &msg14); } } @@ -830,7 +840,7 @@ static bool wait_for_entering_dp_alt_mode(struct dc_link *link) return false; } -/** +/* * dc_link_detect() - Detect if a sink is attached to a given link * * link->local_sink is created or destroyed as needed. @@ -1065,9 +1075,6 @@ static bool dc_link_detect_helper(struct dc_link *link, break; } - if (link->local_sink->edid_caps.panel_patch.disable_fec) - link->ctx->dc->debug.disable_fec = true; - // Check if edid is the same if ((prev_sink) && (edid_status == EDID_THE_SAME || edid_status == EDID_OK)) @@ -1366,13 +1373,17 @@ static bool dc_link_construct(struct dc_link *link, struct dc_context *dc_ctx = init_params->ctx; struct encoder_init_data enc_init_data = { 0 }; struct panel_cntl_init_data panel_cntl_init_data = { 0 }; - struct integrated_info info = {{{ 0 }}}; + struct integrated_info *info; struct dc_bios *bios = init_params->dc->ctx->dc_bios; const struct dc_vbios_funcs *bp_funcs = bios->funcs; struct bp_disp_connector_caps_info disp_connect_caps_info = { 0 }; DC_LOGGER_INIT(dc_ctx->logger); + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + goto create_fail; + link->irq_source_hpd = DC_IRQ_SOURCE_INVALID; link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID; @@ -1390,10 +1401,12 @@ static bool dc_link_construct(struct dc_link *link, link->link_id = bios->funcs->get_connector_id(bios, init_params->connector_index); + DC_LOG_DC("BIOS object table - link_id: %d", link->link_id.id); if (bios->funcs->get_disp_connector_caps_info) { bios->funcs->get_disp_connector_caps_info(bios, link->link_id, &disp_connect_caps_info); link->is_internal_display = disp_connect_caps_info.INTERNAL_DISPLAY; + DC_LOG_DC("BIOS object table - is_internal_display: %d", link->is_internal_display); } if (link->link_id.type != OBJECT_TYPE_CONNECTOR) { @@ -1408,10 +1421,14 @@ static bool dc_link_construct(struct dc_link *link, link->hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service); + if (link->hpd_gpio) { dal_gpio_open(link->hpd_gpio, GPIO_MODE_INTERRUPT); dal_gpio_unlock_pin(link->hpd_gpio); link->irq_source_hpd = dal_irq_get_source(link->hpd_gpio); + + DC_LOG_DC("BIOS object table - hpd_gpio id: %d", link->hpd_gpio->id); + DC_LOG_DC("BIOS object table - hpd_gpio en: %d", link->hpd_gpio->en); } switch (link->link_id.id) { @@ -1470,6 +1487,11 @@ static bool dc_link_construct(struct dc_link *link, goto ddc_create_fail; } + if (!link->ddc->ddc_pin) { + DC_ERROR("Failed to get I2C info for connector!\n"); + goto ddc_create_fail; + } + link->ddc_hw_inst = dal_ddc_get_line(dal_ddc_service_get_ddc_pin(link->ddc)); @@ -1508,6 +1530,8 @@ static bool dc_link_construct(struct dc_link *link, goto link_enc_create_fail; } + DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C); + link->link_enc_hw_inst = link->link_enc->transmitter; for (i = 0; i < 4; i++) { @@ -1530,16 +1554,20 @@ static bool dc_link_construct(struct dc_link *link, if (link->device_tag.dev_id.device_type == DEVICE_TYPE_LCD && link->connector_signal == SIGNAL_TYPE_RGB) continue; + + DC_LOG_DC("BIOS object table - device_tag.acpi_device: %d", link->device_tag.acpi_device); + DC_LOG_DC("BIOS object table - device_tag.dev_id.device_type: %d", link->device_tag.dev_id.device_type); + DC_LOG_DC("BIOS object table - device_tag.dev_id.enum_id: %d", link->device_tag.dev_id.enum_id); break; } if (bios->integrated_info) - info = *bios->integrated_info; + memcpy(info, bios->integrated_info, sizeof(*info)); /* Look for channel mapping corresponding to connector and device tag */ for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) { struct external_display_path *path = - &info.ext_disp_conn_info.path[i]; + &info->ext_disp_conn_info.path[i]; if (path->device_connector_id.enum_id == link->link_id.enum_id && path->device_connector_id.id == link->link_id.id && @@ -1548,10 +1576,14 @@ static bool dc_link_construct(struct dc_link *link, path->device_acpi_enum == link->device_tag.acpi_device) { link->ddi_channel_mapping = path->channel_mapping; link->chip_caps = path->caps; + DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X", link->ddi_channel_mapping.raw); + DC_LOG_DC("BIOS object table - chip_caps: %d", link->chip_caps); } else if (path->device_tag == link->device_tag.dev_id.raw_device_tag) { link->ddi_channel_mapping = path->channel_mapping; link->chip_caps = path->caps; + DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X", link->ddi_channel_mapping.raw); + DC_LOG_DC("BIOS object table - chip_caps: %d", link->chip_caps); } break; } @@ -1570,6 +1602,7 @@ static bool dc_link_construct(struct dc_link *link, link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; + DC_LOG_DC("BIOS object table - %s finished successfully.\n", __func__); return true; device_tag_fail: link->link_enc->funcs->destroy(&link->link_enc); @@ -1586,6 +1619,9 @@ create_fail: link->hpd_gpio = NULL; } + DC_LOG_DC("BIOS object table - %s failed.\n", __func__); + kfree(info); + return false; } @@ -3133,17 +3169,17 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off) { struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp; if (cp_psp && cp_psp->funcs.update_stream_config) { - struct cp_psp_stream_config config; - - memset(&config, 0, sizeof(config)); + struct cp_psp_stream_config config = {0}; + enum dp_panel_mode panel_mode = + dp_get_panel_mode(pipe_ctx->stream->link); config.otg_inst = (uint8_t) pipe_ctx->stream_res.tg->inst; - /*stream_enc_inst*/ - config.stream_enc_inst = (uint8_t) pipe_ctx->stream_res.stream_enc->stream_enc_inst; - config.link_enc_inst = pipe_ctx->stream->link->link_enc_hw_inst; + config.dig_fe = (uint8_t) pipe_ctx->stream_res.stream_enc->stream_enc_inst; + config.dig_be = pipe_ctx->stream->link->link_enc_hw_inst; config.dpms_off = dpms_off; config.dm_stream_ctx = pipe_ctx->stream->dm_stream_context; - config.mst_supported = (pipe_ctx->stream->signal == + config.assr_enabled = (panel_mode == DP_PANEL_MODE_EDP); + config.mst_enabled = (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST); cp_psp->funcs.update_stream_config(cp_psp->handle, &config); } @@ -3396,10 +3432,7 @@ void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) } /** - ***************************************************************************** - * Function: dc_link_enable_hpd_filter - * - * @brief + * dc_link_enable_hpd_filter: * If enable is true, programs HPD filter on associated HPD line using * delay_on_disconnect/delay_on_connect values dependent on * link->connector_signal @@ -3407,9 +3440,8 @@ void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) * If enable is false, programs HPD filter on associated HPD line with no * delays on connect or disconnect * - * @param [in] link: pointer to the dc link - * @param [in] enable: boolean specifying whether to enable hbd - ***************************************************************************** + * @link: pointer to the dc link + * @enable: boolean specifying whether to enable hbd */ void dc_link_enable_hpd_filter(struct dc_link *link, bool enable) { @@ -3635,7 +3667,7 @@ uint32_t dc_link_bandwidth_kbps( link_bw_kbps *= 8; /* 8 bits per byte*/ link_bw_kbps *= link_setting->lane_count; - if (dc_link_is_fec_supported(link) && !link->dc->debug.disable_fec) { + if (dc_link_should_enable_fec(link)) { /* Account for FEC overhead. * We have to do it based on caps, * and not based on FEC being set ready, @@ -3656,8 +3688,8 @@ uint32_t dc_link_bandwidth_kbps( * but the difference is minimal and is in a safe direction, * which all works well around potential ambiguity of DP 1.4a spec. */ - link_bw_kbps = mul_u64_u32_shr(BIT_ULL(32) * 970LL / 1000, - link_bw_kbps, 32); + long long fec_link_bw_kbps = link_bw_kbps * 970LL; + link_bw_kbps = (uint32_t)(div64_s64(fec_link_bw_kbps, 1000LL)); } return link_bw_kbps; @@ -3687,3 +3719,19 @@ bool dc_link_is_fec_supported(const struct dc_link *link) !IS_FPGA_MAXIMUS_DC(link->ctx->dce_environment)); } +bool dc_link_should_enable_fec(const struct dc_link *link) +{ + bool is_fec_disable = false; + bool ret = false; + + if ((link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT_MST && + link->local_sink && + link->local_sink->edid_caps.panel_patch.disable_fec) || + link->connector_signal == SIGNAL_TYPE_EDP) // Disable FEC for eDP + is_fec_disable = true; + + if (dc_link_is_fec_supported(link) && !link->dc->debug.disable_fec && !is_fec_disable) + ret = true; + + return ret; +} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c index c5936e064360..ae6484ab567b 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c @@ -37,12 +37,16 @@ #include "dc_link_ddc.h" #include "dce/dce_aux.h" -/*DP to Dual link DVI converter*/ +#define DC_LOGGER_INIT(logger) + +static const uint8_t DP_VGA_DONGLE_BRANCH_DEV_NAME[] = "DpVga"; +/* DP to Dual link DVI converter */ static const uint8_t DP_DVI_CONVERTER_ID_4[] = "m2DVIa"; static const uint8_t DP_DVI_CONVERTER_ID_5[] = "3393N2"; #define AUX_POWER_UP_WA_DELAY 500 #define I2C_OVER_AUX_DEFER_WA_DELAY 70 +#define DPVGA_DONGLE_AUX_DEFER_WA_DELAY 40 #define I2C_OVER_AUX_DEFER_WA_DELAY_1MS 1 /* CV smart dongle slave address for retrieving supported HDTV modes*/ @@ -194,6 +198,10 @@ static void ddc_service_construct( if (BP_RESULT_OK != dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info)) { ddc_service->ddc_pin = NULL; } else { + DC_LOGGER_INIT(ddc_service->ctx->logger); + DC_LOG_DC("BIOS object table - i2c_line: %d", i2c_info.i2c_line); + DC_LOG_DC("BIOS object table - i2c_engine_id: %d", i2c_info.i2c_engine_id); + hw_info.ddc_channel = i2c_info.i2c_line; if (ddc_service->link != NULL) hw_info.hw_supported = i2c_info.i2c_hw_assist; @@ -286,6 +294,15 @@ static uint32_t defer_delay_converter_wa( { struct dc_link *link = ddc->link; + if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER && + link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_0080E1 && + !memcmp(link->dpcd_caps.branch_dev_name, + DP_VGA_DONGLE_BRANCH_DEV_NAME, + sizeof(link->dpcd_caps.branch_dev_name))) + + return defer_delay > DPVGA_DONGLE_AUX_DEFER_WA_DELAY ? + defer_delay : DPVGA_DONGLE_AUX_DEFER_WA_DELAY; + if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_0080E1 && !memcmp(link->dpcd_caps.branch_dev_name, DP_DVI_CONVERTER_ID_4, 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 1e4794e2825c..c1391bfb7a9b 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 @@ -126,9 +126,7 @@ static void dpcd_set_training_pattern( static enum dc_dp_training_pattern decide_cr_training_pattern( const struct dc_link_settings *link_settings) { - enum dc_dp_training_pattern pattern = DP_TRAINING_PATTERN_SEQUENCE_1; - - return pattern; + return DP_TRAINING_PATTERN_SEQUENCE_1; } static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *link, @@ -3710,7 +3708,7 @@ bool detect_dp_sink_caps(struct dc_link *link) /* TODO save sink caps in link->sink */ } -enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in_khz) +static enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in_khz) { enum dc_link_rate link_rate; // LinkRate is normally stored as a multiplier of 0.27 Gbps per lane. Do the translation. @@ -4348,7 +4346,7 @@ void dp_set_fec_ready(struct dc_link *link, bool ready) struct link_encoder *link_enc = link->link_enc; uint8_t fec_config = 0; - if (!dc_link_is_fec_supported(link) || link->dc->debug.disable_fec) + if (!dc_link_should_enable_fec(link)) return; if (link_enc->funcs->fec_set_ready && @@ -4383,7 +4381,7 @@ void dp_set_fec_enable(struct dc_link *link, bool enable) { struct link_encoder *link_enc = link->link_enc; - if (!dc_link_is_fec_supported(link) || link->dc->debug.disable_fec) + if (!dc_link_should_enable_fec(link)) return; if (link_enc->funcs->fec_set_enable && @@ -4409,24 +4407,39 @@ void dp_set_fec_enable(struct dc_link *link, bool enable) void dpcd_set_source_specific_data(struct dc_link *link) { if (!link->dc->vendor_signature.is_valid) { - enum dc_status result_write_min_hblank = DC_NOT_SUPPORTED; - struct dpcd_amd_signature amd_signature; - amd_signature.AMD_IEEE_TxSignature_byte1 = 0x0; - amd_signature.AMD_IEEE_TxSignature_byte2 = 0x0; - amd_signature.AMD_IEEE_TxSignature_byte3 = 0x1A; - amd_signature.device_id_byte1 = + enum dc_status __maybe_unused result_write_min_hblank = DC_NOT_SUPPORTED; + struct dpcd_amd_signature amd_signature = {0}; + struct dpcd_amd_device_id amd_device_id = {0}; + + amd_device_id.device_id_byte1 = (uint8_t)(link->ctx->asic_id.chip_id); - amd_signature.device_id_byte2 = + amd_device_id.device_id_byte2 = (uint8_t)(link->ctx->asic_id.chip_id >> 8); - memset(&amd_signature.zero, 0, 4); - amd_signature.dce_version = + amd_device_id.dce_version = (uint8_t)(link->ctx->dce_version); - amd_signature.dal_version_byte1 = 0x0; // needed? where to get? - amd_signature.dal_version_byte2 = 0x0; // needed? where to get? + amd_device_id.dal_version_byte1 = 0x0; // needed? where to get? + amd_device_id.dal_version_byte2 = 0x0; // needed? where to get? - core_link_write_dpcd(link, DP_SOURCE_OUI, + core_link_read_dpcd(link, DP_SOURCE_OUI, + (uint8_t *)(&amd_signature), + sizeof(amd_signature)); + + if (!((amd_signature.AMD_IEEE_TxSignature_byte1 == 0x0) && + (amd_signature.AMD_IEEE_TxSignature_byte2 == 0x0) && + (amd_signature.AMD_IEEE_TxSignature_byte3 == 0x1A))) { + + amd_signature.AMD_IEEE_TxSignature_byte1 = 0x0; + amd_signature.AMD_IEEE_TxSignature_byte2 = 0x0; + amd_signature.AMD_IEEE_TxSignature_byte3 = 0x1A; + + core_link_write_dpcd(link, DP_SOURCE_OUI, (uint8_t *)(&amd_signature), sizeof(amd_signature)); + } + + core_link_write_dpcd(link, DP_SOURCE_OUI+0x03, + (uint8_t *)(&amd_device_id), + sizeof(amd_device_id)); if (link->ctx->dce_version >= DCN_VERSION_2_0 && link->dc->caps.min_horizontal_blanking_period != 0) { 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 07c22556480b..0c26c2ade782 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1117,7 +1117,7 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx) * We also need to make sure pipe_ctx->plane_res.scl_data.h_active uses the * original h_border_left value in its calculation. */ -int shift_border_left_to_dst(struct pipe_ctx *pipe_ctx) +static int shift_border_left_to_dst(struct pipe_ctx *pipe_ctx) { int store_h_border_left = pipe_ctx->stream->timing.h_border_left; @@ -1128,8 +1128,8 @@ int shift_border_left_to_dst(struct pipe_ctx *pipe_ctx) return store_h_border_left; } -void restore_border_left_from_dst(struct pipe_ctx *pipe_ctx, - int store_h_border_left) +static void restore_border_left_from_dst(struct pipe_ctx *pipe_ctx, + int store_h_border_left) { pipe_ctx->stream->dst.x -= store_h_border_left; pipe_ctx->stream->timing.h_border_left = store_h_border_left; @@ -1153,8 +1153,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) calculate_viewport(pipe_ctx); - if (pipe_ctx->plane_res.scl_data.viewport.height < 12 || - pipe_ctx->plane_res.scl_data.viewport.width < 12) { + if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE || + pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE) { if (store_h_border_left) { restore_border_left_from_dst(pipe_ctx, store_h_border_left); @@ -1697,7 +1697,7 @@ static bool are_stream_backends_same( return true; } -/** +/* * dc_is_stream_unchanged() - Compare two stream states for equivalence. * * Checks if there a difference between the two states @@ -1718,7 +1718,7 @@ bool dc_is_stream_unchanged( return true; } -/** +/* * dc_is_stream_scaling_unchanged() - Compare scaling rectangles of two streams. */ bool dc_is_stream_scaling_unchanged( @@ -1833,7 +1833,7 @@ static struct audio *find_first_free_audio( return 0; } -/** +/* * dc_add_stream_to_ctx() - Add a new dc_stream_state to a dc_state. */ enum dc_status dc_add_stream_to_ctx( @@ -1860,7 +1860,7 @@ enum dc_status dc_add_stream_to_ctx( return res; } -/** +/* * dc_remove_stream_from_ctx() - Remove a stream from a dc_state. */ enum dc_status dc_remove_stream_from_ctx( @@ -2075,6 +2075,20 @@ static int acquire_resource_from_hw_enabled_state( return -1; } +static void mark_seamless_boot_stream( + const struct dc *dc, + struct dc_stream_state *stream) +{ + struct dc_bios *dcb = dc->ctx->dc_bios; + + /* TODO: Check Linux */ + if (dc->config.allow_seamless_boot_optimization && + !dcb->funcs->is_accelerated_mode(dcb)) { + if (dc_validate_seamless_boot_timing(dc, stream->sink, &stream->timing)) + stream->apply_seamless_boot_optimization = true; + } +} + enum dc_status resource_map_pool_resources( const struct dc *dc, struct dc_state *context, @@ -2085,22 +2099,20 @@ enum dc_status resource_map_pool_resources( struct dc_context *dc_ctx = dc->ctx; struct pipe_ctx *pipe_ctx = NULL; int pipe_idx = -1; - struct dc_bios *dcb = dc->ctx->dc_bios; calculate_phy_pix_clks(stream); - /* TODO: Check Linux */ - if (dc->config.allow_seamless_boot_optimization && - !dcb->funcs->is_accelerated_mode(dcb)) { - if (dc_validate_seamless_boot_timing(dc, stream->sink, &stream->timing)) - stream->apply_seamless_boot_optimization = true; - } + mark_seamless_boot_stream(dc, stream); - if (stream->apply_seamless_boot_optimization) + if (stream->apply_seamless_boot_optimization) { pipe_idx = acquire_resource_from_hw_enabled_state( &context->res_ctx, pool, stream); + if (pipe_idx < 0) + /* hw resource was assigned to other stream */ + stream->apply_seamless_boot_optimization = false; + } if (pipe_idx < 0) /* acquire new resources */ diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index c103f858375d..25fa712a7847 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -244,7 +244,7 @@ struct dc_stream_status *dc_stream_get_status( } #ifndef TRIM_FSFT -/** +/* * dc_optimize_timing_for_fsft() - dc to optimize timing */ bool dc_optimize_timing_for_fsft( @@ -260,8 +260,7 @@ bool dc_optimize_timing_for_fsft( } #endif - -/** +/* * dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address */ bool dc_stream_set_cursor_attributes( diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c index 3d7d27435f15..e6b9c6a71841 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -115,7 +115,7 @@ struct dc_plane_state *dc_create_plane_state(struct dc *dc) return plane_state; } -/** +/* ***************************************************************************** * Function: dc_plane_get_status * diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 3aedadb34548..4eee3a55fa30 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -42,12 +42,13 @@ #include "inc/hw/dmcu.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.2.116" +#define DC_VER "3.2.122" #define MAX_SURFACES 3 #define MAX_PLANES 6 #define MAX_STREAMS 6 #define MAX_SINKS_PER_LINK 4 +#define MIN_VIEWPORT_SIZE 12 /******************************************************************************* * Display Core Interfaces @@ -171,6 +172,9 @@ struct dc_caps { bool dmcub_support; uint32_t num_of_internal_disp; enum dp_protocol_version max_dp_protocol_version; + unsigned int mall_size_per_mem_channel; + unsigned int mall_size_total; + unsigned int cursor_cache_size; struct dc_plane_cap planes[MAX_PLANES]; struct dc_color_caps color; }; @@ -481,7 +485,6 @@ struct dc_debug_options { bool performance_trace; bool az_endpoint_mute_only; bool always_use_regamma; - bool p010_mpo_support; bool recovery_enabled; bool avoid_vbios_exec_table; bool scl_reset_length10; @@ -499,6 +502,9 @@ struct dc_debug_options { bool dmcub_emulation; #if defined(CONFIG_DRM_AMD_DC_DCN) bool disable_idle_power_optimizations; + unsigned int mall_size_override; + unsigned int mall_additional_timer_percent; + bool mall_error_as_fatal; #endif bool dmub_command_table; /* for testing only */ struct dc_bw_validation_profile bw_val_profile; @@ -521,7 +527,6 @@ struct dc_debug_options { bool usbc_combo_phy_reset_wa; bool disable_dsc; bool enable_dram_clock_change_one_display_vactive; - bool force_ignore_link_settings; union mem_low_power_enable_options enable_mem_low_power; }; @@ -633,7 +638,6 @@ struct dc { const char *build_id; struct vm_helper *vm_helper; - const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box; }; enum frame_buffer_mode { @@ -671,16 +675,10 @@ struct dc_init_data { struct dc_config flags; uint64_t log_mask; - /** - * gpu_info FW provided soc bounding box struct or 0 if not - * available in FW - */ - const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box; struct dpcd_vendor_signature vendor_signature; #if defined(CONFIG_DRM_AMD_DC_DCN) bool force_smu_not_present; #endif - bool force_ignore_link_settings; }; struct dc_callback_init { @@ -1269,8 +1267,8 @@ enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32 void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg); #if defined(CONFIG_DRM_AMD_DC_DCN) -bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, - struct dc_plane_state *plane); +bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, struct dc_plane_state *plane, + struct dc_cursor_attributes *cursor_attr); void dc_allow_idle_optimizations(struct dc *dc, bool allow); diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h index 80a2191a3115..cc6fb838420e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h @@ -451,6 +451,9 @@ struct dpcd_amd_signature { uint8_t AMD_IEEE_TxSignature_byte1; uint8_t AMD_IEEE_TxSignature_byte2; uint8_t AMD_IEEE_TxSignature_byte3; +}; + +struct dpcd_amd_device_id { uint8_t device_id_byte1; uint8_t device_id_byte2; uint8_t zero[4]; diff --git a/drivers/gpu/drm/amd/display/dc/dc_edid_parser.c b/drivers/gpu/drm/amd/display/dc/dc_edid_parser.c new file mode 100644 index 000000000000..0db5b49e9d5e --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dc_edid_parser.c @@ -0,0 +1,80 @@ +/* + * Copyright 2021 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 "dce/dce_dmcu.h" +#include "dc_edid_parser.h" + +bool dc_edid_parser_send_cea(struct dc *dc, + int offset, + int total_length, + uint8_t *data, + int length) +{ + struct dmcu *dmcu = dc->res_pool->dmcu; + + if (dmcu && + dmcu->funcs->is_dmcu_initialized(dmcu) && + dmcu->funcs->send_edid_cea) { + return dmcu->funcs->send_edid_cea(dmcu, + offset, + total_length, + data, + length); + } + + return false; +} + +bool dc_edid_parser_recv_cea_ack(struct dc *dc, int *offset) +{ + struct dmcu *dmcu = dc->res_pool->dmcu; + + if (dmcu && + dmcu->funcs->is_dmcu_initialized(dmcu) && + dmcu->funcs->recv_edid_cea_ack) { + return dmcu->funcs->recv_edid_cea_ack(dmcu, offset); + } + + return false; +} + +bool dc_edid_parser_recv_amd_vsdb(struct dc *dc, + int *version, + int *min_frame_rate, + int *max_frame_rate) +{ + struct dmcu *dmcu = dc->res_pool->dmcu; + + if (dmcu && + dmcu->funcs->is_dmcu_initialized(dmcu) && + dmcu->funcs->recv_amd_vsdb) { + return dmcu->funcs->recv_amd_vsdb(dmcu, + version, + min_frame_rate, + max_frame_rate); + } + + return false; +} diff --git a/drivers/gpu/drm/amd/display/dc/dc_edid_parser.h b/drivers/gpu/drm/amd/display/dc/dc_edid_parser.h new file mode 100644 index 000000000000..da67ec06f0a2 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dc_edid_parser.h @@ -0,0 +1,44 @@ +/* + * Copyright 2021 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 _DC_EDID_PARSER_H_ +#define _DC_EDID_PARSER_H_ + +#include "core_types.h" + +bool dc_edid_parser_send_cea(struct dc *dc, + int offset, + int total_length, + uint8_t *data, + int length); + +bool dc_edid_parser_recv_cea_ack(struct dc *dc, int *offset); + +bool dc_edid_parser_recv_amd_vsdb(struct dc *dc, + int *version, + int *min_frame_rate, + int *max_frame_rate); + +#endif /* _DC_EDID_PARSER_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dc_helper.c b/drivers/gpu/drm/amd/display/dc/dc_helper.c index 57edb25fc381..a612ba6dc389 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dc_helper.c @@ -34,6 +34,7 @@ #include "dc.h" #include "dc_dmub_srv.h" +#include "reg_helper.h" static inline void submit_dmub_read_modify_write( struct dc_reg_helper_state *offload, 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 701aa7178a89..b41e6367b15e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -71,6 +71,7 @@ struct dc_plane_address { union { struct{ PHYSICAL_ADDRESS_LOC addr; + PHYSICAL_ADDRESS_LOC cursor_cache_addr; PHYSICAL_ADDRESS_LOC meta_addr; union large_integer dcc_const_color; } grph; diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 6d9a60c9dcc0..e189f16bc026 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -103,6 +103,8 @@ struct dc_link { bool lttpr_non_transparent_mode; bool is_internal_display; + bool edp_sink_present; + /* caps is the same as reported_link_cap. link_traing use * reported_link_cap. Will clean up. TODO */ @@ -259,6 +261,13 @@ enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link); bool dc_link_handle_hpd_rx_irq(struct dc_link *dc_link, union hpd_irq_data *hpd_irq_dpcd_data, bool *out_link_loss); +/* + * On eDP links this function call will stall until T12 has elapsed. + * If the panel is not in power off state, this function will return + * immediately. + */ +bool dc_link_wait_for_t12(struct dc_link *link); + enum dc_status read_hpd_rx_irq_data( struct dc_link *link, union hpd_irq_data *irq_data); @@ -369,5 +378,6 @@ uint32_t dc_bandwidth_in_kbps_from_timing( const struct dc_crtc_timing *timing); bool dc_link_is_fec_supported(const struct dc_link *link); +bool dc_link_should_enable_fec(const struct dc_link *link); #endif /* DC_LINK_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index e243c01b9672..a4f7ec888c67 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -130,6 +130,14 @@ union stream_update_flags { uint32_t raw; }; +struct test_pattern { + enum dp_test_pattern type; + enum dp_test_pattern_color_space color_space; + struct link_training_settings const *p_link_settings; + unsigned char const *p_custom_pattern; + unsigned int cust_pattern_size; +}; + struct dc_stream_state { // sink is deprecated, new code should not reference // this pointer @@ -227,6 +235,8 @@ struct dc_stream_state { uint32_t stream_id; bool is_dsc_enabled; + + struct test_pattern test_pattern; union stream_update_flags update_flags; }; @@ -261,6 +271,7 @@ struct dc_stream_update { struct dc_dsc_config *dsc_config; struct dc_transfer_func *func_shaper; struct dc_3dlut *lut3d_func; + struct test_pattern *pending_test_pattern; }; bool dc_is_stream_unchanged( diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c index 2a2a0fdb9253..7866cf2a668f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c @@ -868,7 +868,7 @@ void dce_aud_wall_dto_setup( } #if defined(CONFIG_DRM_AMD_DC_SI) -void dce60_aud_wall_dto_setup( +static void dce60_aud_wall_dto_setup( struct audio *audio, enum signal_type signal, const struct audio_crtc_info *crtc_info, 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 cda5fd0464bc..d51b5fe91287 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c @@ -388,12 +388,6 @@ static enum aux_channel_operation_result get_channel_status( } } -enum i2caux_engine_type get_engine_type( - const struct dce_aux *engine) -{ - return I2CAUX_ENGINE_TYPE_AUX; -} - static bool acquire( struct dce_aux *engine, struct ddc *ddc) @@ -582,7 +576,7 @@ int dce_aux_transfer_raw(struct ddc_service *ddc, *operation_result = get_channel_status(aux_engine, &returned_bytes); if (*operation_result == AUX_CHANNEL_OPERATION_SUCCEEDED) { - int bytes_replied = 0; + int __maybe_unused bytes_replied = 0; bytes_replied = read_channel_reply(aux_engine, payload->length, payload->data, payload->reply, &status); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h index 382465862f29..277484cf853e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h @@ -124,7 +124,6 @@ struct dce110_aux_registers { AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ - AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c index fb733f573715..dec58b3c42e4 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -113,20 +113,19 @@ static const struct spread_spectrum_data *get_ss_data_entry( } /** - * Function: calculate_fb_and_fractional_fb_divider + * calculate_fb_and_fractional_fb_divider - Calculates feedback and fractional + * feedback dividers values * - * * DESCRIPTION: Calculates feedback and fractional feedback dividers values + * @calc_pll_cs: Pointer to clock source information + * @target_pix_clk_100hz: Desired frequency in 100 Hz + * @ref_divider: Reference divider (already known) + * @post_divider: Post Divider (already known) + * @feedback_divider_param: Pointer where to store + * calculated feedback divider value + * @fract_feedback_divider_param: Pointer where to store + * calculated fract feedback divider value * - *PARAMETERS: - * targetPixelClock Desired frequency in 100 Hz - * ref_divider Reference divider (already known) - * postDivider Post Divider (already known) - * feedback_divider_param Pointer where to store - * calculated feedback divider value - * fract_feedback_divider_param Pointer where to store - * calculated fract feedback divider value - * - *RETURNS: + * return: * It fills the locations pointed by feedback_divider_param * and fract_feedback_divider_param * It returns - true if feedback divider not 0 @@ -175,22 +174,22 @@ static bool calculate_fb_and_fractional_fb_divider( } /** -*calc_fb_divider_checking_tolerance -* -*DESCRIPTION: Calculates Feedback and Fractional Feedback divider values -* for passed Reference and Post divider, checking for tolerance. -*PARAMETERS: -* pll_settings Pointer to structure -* ref_divider Reference divider (already known) -* postDivider Post Divider (already known) -* tolerance Tolerance for Calculated Pixel Clock to be within -* -*RETURNS: -* It fills the PLLSettings structure with PLL Dividers values -* if calculated values are within required tolerance -* It returns - true if error is within tolerance -* - false if error is not within tolerance -*/ + * calc_fb_divider_checking_tolerance - Calculates Feedback and + * Fractional Feedback divider values + * for passed Reference and Post divider, + * checking for tolerance. + * @calc_pll_cs: Pointer to clock source information + * @pll_settings: Pointer to PLL settings + * @ref_divider: Reference divider (already known) + * @post_divider: Post Divider (already known) + * @tolerance: Tolerance for Calculated Pixel Clock to be within + * + * return: + * It fills the PLLSettings structure with PLL Dividers values + * if calculated values are within required tolerance + * It returns - true if error is within tolerance + * - false if error is not within tolerance + */ static bool calc_fb_divider_checking_tolerance( struct calc_pll_clock_source *calc_pll_cs, struct pll_settings *pll_settings, @@ -241,7 +240,7 @@ static bool calc_fb_divider_checking_tolerance( pll_settings->calculated_pix_clk_100hz = actual_calculated_clock_100hz; pll_settings->vco_freq = - actual_calculated_clock_100hz * post_divider / 10; + div_u64((u64)actual_calculated_clock_100hz * post_divider, 10); return true; } return false; @@ -460,7 +459,7 @@ static bool pll_adjust_pix_clk( return false; } -/** +/* * Calculate PLL Dividers for given Clock Value. * First will call VBIOS Adjust Exec table to check if requested Pixel clock * will be Adjusted based on usage. @@ -871,6 +870,20 @@ static bool dce110_program_pix_clk( bp_pc_params.flags.SET_EXTERNAL_REF_DIV_SRC = pll_settings->use_external_clk; + switch (pix_clk_params->color_depth) { + case COLOR_DEPTH_101010: + bp_pc_params.color_depth = TRANSMITTER_COLOR_DEPTH_30; + break; + case COLOR_DEPTH_121212: + bp_pc_params.color_depth = TRANSMITTER_COLOR_DEPTH_36; + break; + case COLOR_DEPTH_161616: + bp_pc_params.color_depth = TRANSMITTER_COLOR_DEPTH_48; + break; + default: + break; + } + if (clk_src->bios->funcs->set_pixel_clock( clk_src->bios, &bp_pc_params) != BP_RESULT_OK) return false; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index f3ed8b619caf..ddc789daf3b1 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -57,6 +57,9 @@ #define MCP_SYNC_PHY_LOCK 0x90 #define MCP_SYNC_PHY_UNLOCK 0x91 #define MCP_BL_SET_PWM_FRAC 0x6A /* Enable or disable Fractional PWM */ +#define MCP_SEND_EDID_CEA 0xA0 +#define EDID_CEA_CMD_ACK 1 +#define EDID_CEA_CMD_NACK 2 #define MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK 0x00000001L // PSP FW version @@ -65,13 +68,17 @@ //Register access policy version #define mmMP0_SMN_C2PMSG_91 0x1609B +#if defined(CONFIG_DRM_AMD_DC_DCN) +static const uint32_t abm_gain_stepsize = 0x0060; +#endif + static bool dce_dmcu_init(struct dmcu *dmcu) { // Do nothing return true; } -bool dce_dmcu_load_iram(struct dmcu *dmcu, +static bool dce_dmcu_load_iram(struct dmcu *dmcu, unsigned int start_offset, const char *src, unsigned int bytes) @@ -807,6 +814,120 @@ static bool dcn20_unlock_phy(struct dmcu *dmcu) return true; } +static bool dcn10_send_edid_cea(struct dmcu *dmcu, + int offset, + int total_length, + uint8_t *data, + int length) +{ + struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); + uint32_t header, data1, data2; + + /* If microcontroller is not running, do nothing */ + if (dmcu->dmcu_state != DMCU_RUNNING) + return false; + + if (length > 8 || length <= 0) + return false; + + header = ((uint32_t)offset & 0xFFFF) << 16 | (total_length & 0xFFFF); + data1 = (((uint32_t)data[0]) << 24) | (((uint32_t)data[1]) << 16) | + (((uint32_t)data[2]) << 8) | ((uint32_t)data[3]); + data2 = (((uint32_t)data[4]) << 24) | (((uint32_t)data[5]) << 16) | + (((uint32_t)data[6]) << 8) | ((uint32_t)data[7]); + + /* waitDMCUReadyForCmd */ + REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000); + + /* setDMCUParam_Cmd */ + REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, MCP_SEND_EDID_CEA); + + REG_WRITE(MASTER_COMM_DATA_REG1, header); + REG_WRITE(MASTER_COMM_DATA_REG2, data1); + REG_WRITE(MASTER_COMM_DATA_REG3, data2); + + /* notifyDMCUMsg */ + REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); + + /* waitDMCUReadyForCmd */ + REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000); + + return true; +} + +static bool dcn10_get_scp_results(struct dmcu *dmcu, + uint32_t *cmd, + uint32_t *data1, + uint32_t *data2, + uint32_t *data3) +{ + struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); + + /* If microcontroller is not running, do nothing */ + if (dmcu->dmcu_state != DMCU_RUNNING) + return false; + + *cmd = REG_READ(SLAVE_COMM_CMD_REG); + *data1 = REG_READ(SLAVE_COMM_DATA_REG1); + *data2 = REG_READ(SLAVE_COMM_DATA_REG2); + *data3 = REG_READ(SLAVE_COMM_DATA_REG3); + + /* clear SCP interrupt */ + REG_UPDATE(SLAVE_COMM_CNTL_REG, SLAVE_COMM_INTERRUPT, 0); + + return true; +} + +static bool dcn10_recv_amd_vsdb(struct dmcu *dmcu, + int *version, + int *min_frame_rate, + int *max_frame_rate) +{ + uint32_t data[4]; + int cmd, ack, len; + + if (!dcn10_get_scp_results(dmcu, &data[0], &data[1], &data[2], &data[3])) + return false; + + cmd = data[0] & 0x3FF; + len = (data[0] >> 10) & 0x3F; + ack = data[1]; + + if (cmd != MCP_SEND_EDID_CEA || ack != EDID_CEA_CMD_ACK || len != 12) + return false; + + if ((data[2] & 0xFF)) { + *version = (data[2] >> 8) & 0xFF; + *min_frame_rate = (data[3] >> 16) & 0xFFFF; + *max_frame_rate = data[3] & 0xFFFF; + return true; + } + + return false; +} + +static bool dcn10_recv_edid_cea_ack(struct dmcu *dmcu, int *offset) +{ + uint32_t data[4]; + int cmd, ack; + + if (!dcn10_get_scp_results(dmcu, + &data[0], &data[1], &data[2], &data[3])) + return false; + + cmd = data[0] & 0x3FF; + ack = data[1]; + + if (cmd != MCP_SEND_EDID_CEA) + return false; + + if (ack == EDID_CEA_CMD_ACK) + return true; + + *offset = data[2]; /* nack */ + return false; +} + #endif //(CONFIG_DRM_AMD_DC_DCN) static const struct dmcu_funcs dce_funcs = { @@ -829,6 +950,9 @@ static const struct dmcu_funcs dcn10_funcs = { .get_psr_state = dcn10_get_dmcu_psr_state, .set_psr_wait_loop = dcn10_psr_wait_loop, .get_psr_wait_loop = dcn10_get_psr_wait_loop, + .send_edid_cea = dcn10_send_edid_cea, + .recv_amd_vsdb = dcn10_recv_amd_vsdb, + .recv_edid_cea_ack = dcn10_recv_edid_cea_ack, .is_dmcu_initialized = dcn10_is_dmcu_initialized }; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h index 93e7f34d4775..ff726b35ef6a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h @@ -40,6 +40,10 @@ SR(MASTER_COMM_DATA_REG3), \ SR(MASTER_COMM_CMD_REG), \ SR(MASTER_COMM_CNTL_REG), \ + SR(SLAVE_COMM_DATA_REG1), \ + SR(SLAVE_COMM_DATA_REG2), \ + SR(SLAVE_COMM_DATA_REG3), \ + SR(SLAVE_COMM_CMD_REG), \ SR(DMCU_IRAM_RD_CTRL), \ SR(DMCU_IRAM_RD_DATA), \ SR(DMCU_INTERRUPT_TO_UC_EN_MASK), \ @@ -112,6 +116,7 @@ DMCU_SF(MASTER_COMM_CMD_REG, \ MASTER_COMM_CMD_REG_BYTE0, mask_sh), \ DMCU_SF(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, mask_sh), \ + DMCU_SF(SLAVE_COMM_CNTL_REG, SLAVE_COMM_INTERRUPT, mask_sh), \ DMCU_SF(DMCU_INTERRUPT_TO_UC_EN_MASK, \ STATIC_SCREEN1_INT_TO_UC_EN, mask_sh), \ DMCU_SF(DMCU_INTERRUPT_TO_UC_EN_MASK, \ @@ -179,6 +184,7 @@ type UC_IN_RESET; \ type MASTER_COMM_CMD_REG_BYTE0; \ type MASTER_COMM_INTERRUPT; \ + type SLAVE_COMM_INTERRUPT; \ type DPHY_RX_FAST_TRAINING_CAPABLE; \ type DPHY_LOAD_BS_COUNT; \ type STATIC_SCREEN1_INT_TO_UC_EN; \ @@ -211,6 +217,11 @@ struct dce_dmcu_registers { uint32_t MASTER_COMM_DATA_REG3; uint32_t MASTER_COMM_CMD_REG; uint32_t MASTER_COMM_CNTL_REG; + uint32_t SLAVE_COMM_DATA_REG1; + uint32_t SLAVE_COMM_DATA_REG2; + uint32_t SLAVE_COMM_DATA_REG3; + uint32_t SLAVE_COMM_CMD_REG; + uint32_t SLAVE_COMM_CNTL_REG; uint32_t DMCU_IRAM_RD_CTRL; uint32_t DMCU_IRAM_RD_DATA; uint32_t DMCU_INTERRUPT_TO_UC_EN_MASK; @@ -317,6 +328,4 @@ struct dmcu *dcn21_dmcu_create( void dce_dmcu_destroy(struct dmcu **dmcu); -static const uint32_t abm_gain_stepsize = 0x0060; - #endif /* _DCE_ABM_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c index 7fbd92fbc63a..a524f471e0d7 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c @@ -435,7 +435,7 @@ struct dce_i2c_hw *acquire_i2c_hw_engine( return dce_i2c_hw; } -enum i2c_channel_operation_result dce_i2c_hw_engine_wait_on_operation_result( +static enum i2c_channel_operation_result dce_i2c_hw_engine_wait_on_operation_result( struct dce_i2c_hw *dce_i2c_hw, uint32_t timeout, enum i2c_channel_operation_result expected_result) @@ -502,7 +502,7 @@ static uint32_t get_transaction_timeout_hw( return period_timeout * num_of_clock_stretches; } -bool dce_i2c_hw_engine_submit_payload( +static bool dce_i2c_hw_engine_submit_payload( struct dce_i2c_hw *dce_i2c_hw, struct i2c_payload *payload, bool middle_of_transaction, diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.c b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.c index 87d8428df6c4..6846afd83701 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.c @@ -339,7 +339,7 @@ static bool start_sync_sw( return false; } -void dce_i2c_sw_engine_set_speed( +static void dce_i2c_sw_engine_set_speed( struct dce_i2c_sw *engine, uint32_t speed) { @@ -353,7 +353,7 @@ void dce_i2c_sw_engine_set_speed( engine->clock_delay = 12; } -bool dce_i2c_sw_engine_acquire_engine( +static bool dce_i2c_sw_engine_acquire_engine( struct dce_i2c_sw *engine, struct ddc *ddc) { @@ -397,7 +397,7 @@ bool dce_i2c_engine_acquire_sw( -void dce_i2c_sw_engine_submit_channel_request( +static void dce_i2c_sw_engine_submit_channel_request( struct dce_i2c_sw *engine, struct i2c_request_transaction_data *req) { @@ -440,7 +440,8 @@ void dce_i2c_sw_engine_submit_channel_request( I2C_CHANNEL_OPERATION_SUCCEEDED : I2C_CHANNEL_OPERATION_FAILED; } -bool dce_i2c_sw_engine_submit_payload( + +static bool dce_i2c_sw_engine_submit_payload( struct dce_i2c_sw *engine, struct i2c_payload *payload, bool middle_of_transaction) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 210466b2d863..1e77ffee71b3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -1197,7 +1197,7 @@ void dce110_link_encoder_enable_dp_mst_output( #if defined(CONFIG_DRM_AMD_DC_SI) /* enables DP PHY output */ -void dce60_link_encoder_enable_dp_output( +static void dce60_link_encoder_enable_dp_output( struct link_encoder *enc, const struct dc_link_settings *link_settings, enum clock_source_id clock_source) @@ -1236,7 +1236,7 @@ void dce60_link_encoder_enable_dp_output( } /* enables DP PHY output in MST mode */ -void dce60_link_encoder_enable_dp_mst_output( +static void dce60_link_encoder_enable_dp_mst_output( struct link_encoder *enc, const struct dc_link_settings *link_settings, enum clock_source_id clock_source) @@ -1426,7 +1426,7 @@ void dce110_link_encoder_dp_set_phy_pattern( #if defined(CONFIG_DRM_AMD_DC_SI) /* set DP PHY test and training patterns */ -void dce60_link_encoder_dp_set_phy_pattern( +static void dce60_link_encoder_dp_set_phy_pattern( struct link_encoder *enc, const struct encoder_set_dp_phy_pattern_param *param) { @@ -1503,7 +1503,6 @@ void dce110_link_encoder_update_mst_stream_allocation_table( const struct link_mst_stream_allocation_table *table) { struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); - uint32_t value0 = 0; uint32_t value1 = 0; uint32_t value2 = 0; uint32_t slots = 0; @@ -1604,7 +1603,7 @@ void dce110_link_encoder_update_mst_stream_allocation_table( do { udelay(10); - value0 = REG_READ(DP_MSE_SAT_UPDATE); + REG_READ(DP_MSE_SAT_UPDATE); REG_GET(DP_MSE_SAT_UPDATE, DP_MSE_SAT_UPDATE, &value1); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c index e459ae65aaf7..4600231da6cb 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c @@ -97,7 +97,7 @@ enum { -/** +/* * set_truncation * 1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp * 2) enable truncation @@ -142,7 +142,7 @@ static void set_truncation( } #if defined(CONFIG_DRM_AMD_DC_SI) -/** +/* * dce60_set_truncation * 1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp * 2) enable truncation @@ -183,7 +183,7 @@ static void dce60_set_truncation( } #endif -/** +/* * set_spatial_dither * 1) set spatial dithering mode: pattern of seed * 2) set spatial dithering depth: 0 for 18bpp or 1 for 24bpp @@ -291,7 +291,7 @@ static void set_spatial_dither( FMT_SPATIAL_DITHER_EN, 1); } -/** +/* * SetTemporalDither (Frame Modulation) * 1) set temporal dither depth * 2) select pattern: from hard-coded pattern or programmable pattern @@ -355,7 +355,7 @@ static void set_temporal_dither( FMT_TEMPORAL_DITHER_EN, 1); } -/** +/* * Set Clamping * 1) Set clamping format based on bpc - 0 for 6bpc (No clamping) * 1 for 8 bpc @@ -415,7 +415,7 @@ void dce110_opp_set_clamping( } #if defined(CONFIG_DRM_AMD_DC_SI) -/** +/* * Set Clamping for DCE6 parts * 1) Set clamping format based on bpc - 0 for 6bpc (No clamping) * 1 for 8 bpc @@ -424,7 +424,7 @@ void dce110_opp_set_clamping( * 7 for programable * 2) Enable clamp if Limited range requested */ -void dce60_opp_set_clamping( +static void dce60_opp_set_clamping( struct dce110_opp *opp110, const struct clamping_and_pixel_encoding_params *params) { @@ -465,7 +465,7 @@ void dce60_opp_set_clamping( } #endif -/** +/* * set_pixel_encoding * * Set Pixel Encoding @@ -501,7 +501,7 @@ static void set_pixel_encoding( } #if defined(CONFIG_DRM_AMD_DC_SI) -/** +/* * dce60_set_pixel_encoding * DCE6 has no FMT_SUBSAMPLING_{MODE,ORDER} bits in FMT_CONTROL reg * Set Pixel Encoding @@ -545,7 +545,7 @@ void dce110_opp_program_bit_depth_reduction( } #if defined(CONFIG_DRM_AMD_DC_SI) -void dce60_opp_program_bit_depth_reduction( +static void dce60_opp_program_bit_depth_reduction( struct output_pixel_processor *opp, const struct bit_depth_reduction_params *params) { @@ -568,7 +568,7 @@ void dce110_opp_program_clamping_and_pixel_encoding( } #if defined(CONFIG_DRM_AMD_DC_SI) -void dce60_opp_program_clamping_and_pixel_encoding( +static void dce60_opp_program_clamping_and_pixel_encoding( struct output_pixel_processor *opp, const struct clamping_and_pixel_encoding_params *params) { @@ -678,7 +678,7 @@ void dce110_opp_program_fmt( } #if defined(CONFIG_DRM_AMD_DC_SI) -void dce60_opp_program_fmt( +static void dce60_opp_program_fmt( struct output_pixel_processor *opp, struct bit_depth_reduction_params *fmt_bit_depth, struct clamping_and_pixel_encoding_params *clamping) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.h b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.h index 4d484ef60f35..bf1ffc3629c7 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.h @@ -111,7 +111,6 @@ enum dce110_opp_reg_type { OPP_SF(FMT_DITHER_RAND_R_SEED, FMT_RAND_R_SEED, mask_sh),\ OPP_SF(FMT_DITHER_RAND_G_SEED, FMT_RAND_G_SEED, mask_sh),\ OPP_SF(FMT_DITHER_RAND_B_SEED, FMT_RAND_B_SEED, mask_sh),\ - OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_EN, mask_sh),\ OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_RESET, mask_sh),\ OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_OFFSET, mask_sh),\ OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_DEPTH, mask_sh),\ @@ -219,7 +218,6 @@ enum dce110_opp_reg_type { OPP_SF(FMT_DITHER_RAND_R_SEED, FMT_RAND_R_SEED, mask_sh),\ OPP_SF(FMT_DITHER_RAND_G_SEED, FMT_RAND_G_SEED, mask_sh),\ OPP_SF(FMT_DITHER_RAND_B_SEED, FMT_RAND_B_SEED, mask_sh),\ - OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_EN, mask_sh),\ OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_RESET, mask_sh),\ OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_OFFSET, mask_sh),\ OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_DEPTH, mask_sh),\ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_panel_cntl.c b/drivers/gpu/drm/amd/display/dc/dce/dce_panel_cntl.c index 761fdfc1f5bd..e92339235863 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_panel_cntl.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_panel_cntl.c @@ -50,16 +50,16 @@ static unsigned int dce_get_16_bit_backlight_from_pwm(struct panel_cntl *panel_c { uint64_t current_backlight; uint32_t round_result; - uint32_t pwm_period_cntl, bl_period, bl_int_count; - uint32_t bl_pwm_cntl, bl_pwm, fractional_duty_cycle_en; + uint32_t bl_period, bl_int_count; + uint32_t bl_pwm, fractional_duty_cycle_en; uint32_t bl_period_mask, bl_pwm_mask; struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl); - pwm_period_cntl = REG_READ(BL_PWM_PERIOD_CNTL); + REG_READ(BL_PWM_PERIOD_CNTL); REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, &bl_period); REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, &bl_int_count); - bl_pwm_cntl = REG_READ(BL_PWM_CNTL); + REG_READ(BL_PWM_CNTL); REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, (uint32_t *)(&bl_pwm)); REG_GET(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, &fractional_duty_cycle_en); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c index ada57f745fd7..8d4263da59f2 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c @@ -67,7 +67,6 @@ static void dce110_update_generic_info_packet( uint32_t packet_index, const struct dc_info_packet *info_packet) { - uint32_t regval; /* TODOFPGA Figure out a proper number for max_retries polling for lock * use 50 for now. */ @@ -99,7 +98,7 @@ static void dce110_update_generic_info_packet( } /* choose which generic packet to use */ { - regval = REG_READ(AFMT_VBI_PACKET_CONTROL); + REG_READ(AFMT_VBI_PACKET_CONTROL); REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_INDEX, packet_index); } @@ -564,6 +563,7 @@ static void dce110_stream_encoder_hdmi_set_stream_attribute( cntl.enable_dp_audio = enable_audio; cntl.pixel_clock = actual_pix_clk_khz; cntl.lanes_number = LANE_COUNT_FOUR; + cntl.color_depth = crtc_timing->display_color_depth; if (enc110->base.bp->funcs->encoder_control( enc110->base.bp, &cntl) != BP_RESULT_OK) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c index 130a0a0c8332..151dc7bf6d23 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c @@ -493,7 +493,6 @@ static void dce60_transform_set_scaler( { struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm); bool is_scaling_required; - bool filter_updated = false; const uint16_t *coeffs_v, *coeffs_h; /*Use whole line buffer memory always*/ @@ -558,7 +557,6 @@ static void dce60_transform_set_scaler( xfm_dce->filter_v = coeffs_v; xfm_dce->filter_h = coeffs_h; - filter_updated = true; } } @@ -601,12 +599,12 @@ static void set_clamp( clamp_max = 0x3FC0; break; case COLOR_DEPTH_101010: - /* 10bit MSB aligned on 14 bit bus '11 1111 1111 1100' */ - clamp_max = 0x3FFC; + /* 10bit MSB aligned on 14 bit bus '11 1111 1111 0000' */ + clamp_max = 0x3FF0; break; case COLOR_DEPTH_121212: - /* 12bit MSB aligned on 14 bit bus '11 1111 1111 1111' */ - clamp_max = 0x3FFF; + /* 12bit MSB aligned on 14 bit bus '11 1111 1111 1100' */ + clamp_max = 0x3FFC; break; default: clamp_max = 0x3FC0; @@ -1037,34 +1035,23 @@ static void dce60_transform_set_pixel_storage_depth( const struct bit_depth_reduction_params *bit_depth_params) { struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm); - int pixel_depth, expan_mode; enum dc_color_depth color_depth; switch (depth) { case LB_PIXEL_DEPTH_18BPP: color_depth = COLOR_DEPTH_666; - pixel_depth = 2; - expan_mode = 1; break; case LB_PIXEL_DEPTH_24BPP: color_depth = COLOR_DEPTH_888; - pixel_depth = 1; - expan_mode = 1; break; case LB_PIXEL_DEPTH_30BPP: color_depth = COLOR_DEPTH_101010; - pixel_depth = 0; - expan_mode = 1; break; case LB_PIXEL_DEPTH_36BPP: color_depth = COLOR_DEPTH_121212; - pixel_depth = 3; - expan_mode = 0; break; default: color_depth = COLOR_DEPTH_101010; - pixel_depth = 0; - expan_mode = 1; BREAK_TO_DEBUGGER(); break; } @@ -1113,7 +1100,7 @@ static void program_gamut_remap( } -/** +/* ***************************************************************************** * Function: dal_transform_wide_gamut_set_gamut_remap * diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c index 0cf130dc4e52..453aaa5757bd 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c @@ -57,6 +57,7 @@ static void dmub_abm_enable_fractional_pwm(struct dc_context *dc) union dmub_rb_cmd cmd; uint32_t fractional_pwm = (dc->dc->config.disable_fractional_pwm == false) ? 1 : 0; + memset(&cmd, 0, sizeof(cmd)); cmd.abm_set_pwm_frac.header.type = DMUB_CMD__ABM; cmd.abm_set_pwm_frac.header.sub_type = DMUB_CMD__ABM_SET_PWM_FRAC; cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.fractional_pwm = fractional_pwm; @@ -135,6 +136,7 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level) union dmub_rb_cmd cmd; struct dc_context *dc = abm->ctx; + memset(&cmd, 0, sizeof(cmd)); cmd.abm_set_level.header.type = DMUB_CMD__ABM; cmd.abm_set_level.header.sub_type = DMUB_CMD__ABM_SET_LEVEL; cmd.abm_set_level.abm_set_level_data.level = level; @@ -160,6 +162,7 @@ static bool dmub_abm_init_config(struct abm *abm, // Copy iramtable into cw7 memcpy(dc->dmub_srv->dmub->scratch_mem_fb.cpu_addr, (void *)src, bytes); + memset(&cmd, 0, sizeof(cmd)); // Fw will copy from cw7 to fw_state cmd.abm_init_config.header.type = DMUB_CMD__ABM; cmd.abm_init_config.header.sub_type = DMUB_CMD__ABM_INIT_CONFIG; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c index d399270fd17e..c97ee5abc0ef 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c @@ -33,8 +33,9 @@ void dmub_hw_lock_mgr_cmd(struct dc_dmub_srv *dmub_srv, union dmub_hw_lock_flags *hw_locks, struct dmub_hw_lock_inst_flags *inst_flags) { - union dmub_rb_cmd cmd = { 0 }; + union dmub_rb_cmd cmd; + memset(&cmd, 0, sizeof(cmd)); cmd.lock_hw.header.type = DMUB_CMD__HW_LOCK; cmd.lock_hw.header.sub_type = 0; cmd.lock_hw.header.payload_bytes = sizeof(struct dmub_cmd_lock_hw_data); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 17e84f34ceba..69e34bef274c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -31,7 +31,7 @@ #define MAX_PIPES 6 -/** +/* * Convert dmcub psr state to dmcu psr state. */ static enum dc_psr_state convert_psr_state(uint32_t raw_state) @@ -74,7 +74,7 @@ static enum dc_psr_state convert_psr_state(uint32_t raw_state) return state; } -/** +/* * Get PSR state from firmware. */ static void dmub_psr_get_state(struct dmub_psr *dmub, enum dc_psr_state *state) @@ -90,7 +90,7 @@ static void dmub_psr_get_state(struct dmub_psr *dmub, enum dc_psr_state *state) *state = convert_psr_state(raw_state); } -/** +/* * Set PSR version. */ static bool dmub_psr_set_version(struct dmub_psr *dmub, struct dc_stream_state *stream) @@ -101,6 +101,7 @@ static bool dmub_psr_set_version(struct dmub_psr *dmub, struct dc_stream_state * if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED) return false; + memset(&cmd, 0, sizeof(cmd)); cmd.psr_set_version.header.type = DMUB_CMD__PSR; cmd.psr_set_version.header.sub_type = DMUB_CMD__PSR_SET_VERSION; switch (stream->link->psr_settings.psr_version) { @@ -121,7 +122,7 @@ static bool dmub_psr_set_version(struct dmub_psr *dmub, struct dc_stream_state * return true; } -/** +/* * Enable/Disable PSR. */ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait) @@ -131,7 +132,7 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait) uint32_t retry_count; enum dc_psr_state state = PSR_STATE0; - + memset(&cmd, 0, sizeof(cmd)); cmd.psr_enable.header.type = DMUB_CMD__PSR; if (enable) @@ -170,7 +171,7 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait) } } -/** +/* * Set PSR level. */ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level) @@ -184,6 +185,7 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level) if (state == PSR_STATE0) return; + memset(&cmd, 0, sizeof(cmd)); cmd.psr_set_level.header.type = DMUB_CMD__PSR; cmd.psr_set_level.header.sub_type = DMUB_CMD__PSR_SET_LEVEL; cmd.psr_set_level.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_level_data); @@ -194,7 +196,7 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level) dc_dmub_srv_wait_idle(dc->dmub_srv); } -/** +/* * Setup PSR by programming phy registers and sending psr hw context values to firmware. */ static bool dmub_psr_copy_settings(struct dmub_psr *dmub, @@ -233,6 +235,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub, link->link_enc->funcs->psr_program_secondary_packet(link->link_enc, psr_context->sdpTransmitLineNumDeadline); + memset(&cmd, 0, sizeof(cmd)); cmd.psr_copy_settings.header.type = DMUB_CMD__PSR; cmd.psr_copy_settings.header.sub_type = DMUB_CMD__PSR_COPY_SETTINGS; cmd.psr_copy_settings.header.payload_bytes = sizeof(struct dmub_cmd_psr_copy_settings_data); @@ -277,7 +280,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub, return true; } -/** +/* * Send command to PSR to force static ENTER and ignore all state changes until exit */ static void dmub_psr_force_static(struct dmub_psr *dmub) @@ -285,6 +288,7 @@ static void dmub_psr_force_static(struct dmub_psr *dmub) union dmub_rb_cmd cmd; struct dc_context *dc = dmub->ctx; + memset(&cmd, 0, sizeof(cmd)); cmd.psr_force_static.header.type = DMUB_CMD__PSR; cmd.psr_force_static.header.sub_type = DMUB_CMD__PSR_FORCE_STATIC; cmd.psr_enable.header.payload_bytes = 0; @@ -294,7 +298,7 @@ static void dmub_psr_force_static(struct dmub_psr *dmub) dc_dmub_srv_wait_idle(dc->dmub_srv); } -/** +/* * Get PSR residency from firmware. */ static void dmub_psr_get_residency(struct dmub_psr *dmub, uint32_t *residency) @@ -316,7 +320,7 @@ static const struct dmub_psr_funcs psr_funcs = { .psr_get_residency = dmub_psr_get_residency, }; -/** +/* * Construct PSR object. */ static void dmub_psr_construct(struct dmub_psr *psr, struct dc_context *ctx) @@ -325,7 +329,7 @@ static void dmub_psr_construct(struct dmub_psr *psr, struct dc_context *ctx) psr->funcs = &psr_funcs; } -/** +/* * Allocate and initialize PSR object. */ struct dmub_psr *dmub_psr_create(struct dc_context *ctx) @@ -342,7 +346,7 @@ struct dmub_psr *dmub_psr_create(struct dc_context *ctx) return psr; } -/** +/* * Deallocate PSR object. */ void dmub_psr_destroy(struct dmub_psr **dmub) diff --git a/drivers/gpu/drm/amd/display/dc/dce100/Makefile b/drivers/gpu/drm/amd/display/dc/dce100/Makefile index a822d4e2a169..ff20c47f559e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dce100/Makefile @@ -23,6 +23,8 @@ # Makefile for the 'controller' sub-component of DAL. # It provides the control and status of HW CRTC block. +CFLAGS_$(AMDDALPATH)/dc/dce100/dce100_resource.o = $(call cc-disable-warning, override-init) + DCE100 = dce100_resource.o dce100_hw_sequencer.o AMD_DAL_DCE100 = $(addprefix $(AMDDALPATH)/dc/dce100/,$(DCE100)) diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index 8ab9d6c79808..635ef0e7c782 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c @@ -58,6 +58,8 @@ #include "dce/dce_abm.h" #include "dce/dce_i2c.h" +#include "dce100_resource.h" + #ifndef mmMC_HUB_RDREQ_DMIF_LIMIT #include "gmc/gmc_8_2_d.h" #include "gmc/gmc_8_2_sh_mask.h" @@ -385,7 +387,7 @@ static const struct dc_plane_cap plane_cap = { .pixel_format_support = { .argb8888 = true, .nv12 = false, - .fp16 = false + .fp16 = true }, .max_upscale_factor = { @@ -611,7 +613,7 @@ static const struct encoder_feature_support link_enc_feature = { .flags.bits.IS_TPS3_CAPABLE = true }; -struct link_encoder *dce100_link_encoder_create( +static struct link_encoder *dce100_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dce110_link_encoder *enc110 = @@ -650,7 +652,7 @@ static struct panel_cntl *dce100_panel_cntl_create(const struct panel_cntl_init_ return &panel_cntl->base; } -struct output_pixel_processor *dce100_opp_create( +static struct output_pixel_processor *dce100_opp_create( struct dc_context *ctx, uint32_t inst) { @@ -665,7 +667,7 @@ struct output_pixel_processor *dce100_opp_create( return &opp->base; } -struct dce_aux *dce100_aux_engine_create( +static struct dce_aux *dce100_aux_engine_create( struct dc_context *ctx, uint32_t inst) { @@ -703,7 +705,7 @@ static const struct dce_i2c_mask i2c_masks = { I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) }; -struct dce_i2c_hw *dce100_i2c_hw_create( +static struct dce_i2c_hw *dce100_i2c_hw_create( struct dc_context *ctx, uint32_t inst) { @@ -718,7 +720,7 @@ struct dce_i2c_hw *dce100_i2c_hw_create( return dce_i2c_hw; } -struct clock_source *dce100_clock_source_create( +static struct clock_source *dce100_clock_source_create( struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, @@ -742,7 +744,7 @@ struct clock_source *dce100_clock_source_create( return NULL; } -void dce100_clock_source_destroy(struct clock_source **clk_src) +static void dce100_clock_source_destroy(struct clock_source **clk_src) { kfree(TO_DCE110_CLK_SRC(*clk_src)); *clk_src = NULL; @@ -831,7 +833,7 @@ static enum dc_status build_mapped_resource( return DC_OK; } -bool dce100_validate_bandwidth( +static bool dce100_validate_bandwidth( struct dc *dc, struct dc_state *context, bool fast_validate) @@ -876,7 +878,7 @@ static bool dce100_validate_surface_sets( return true; } -enum dc_status dce100_validate_global( +static enum dc_status dce100_validate_global( struct dc *dc, struct dc_state *context) { diff --git a/drivers/gpu/drm/amd/display/dc/dce110/Makefile b/drivers/gpu/drm/amd/display/dc/dce110/Makefile index d564c0eb8b04..84ab48df0c26 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dce110/Makefile @@ -23,6 +23,8 @@ # Makefile for the 'controller' sub-component of DAL. # It provides the control and status of HW CRTC block. +CFLAGS_$(AMDDALPATH)/dc/dce110/dce110_resource.o = $(call cc-disable-warning, override-init) + DCE110 = dce110_timing_generator.o \ dce110_compressor.o dce110_hw_sequencer.o dce110_resource.o \ dce110_opp_regamma_v.o dce110_opp_csc_v.o dce110_timing_generator_v.o \ diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c index 72b580a4eb85..44564a4742b5 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c @@ -412,36 +412,6 @@ void dce110_compressor_destroy(struct compressor **compressor) *compressor = NULL; } -bool dce110_get_required_compressed_surfacesize(struct fbc_input_info fbc_input_info, - struct fbc_requested_compressed_size size) -{ - bool result = false; - - unsigned int max_x = FBC_MAX_X, max_y = FBC_MAX_Y; - - get_max_support_fbc_buffersize(&max_x, &max_y); - - if (fbc_input_info.dynamic_fbc_buffer_alloc == 0) { - /* - * For DCE11 here use Max HW supported size: HW Support up to 3840x2400 resolution - * or 18000 chunks. - */ - size.preferred_size = size.min_size = align_to_chunks_number_per_line(max_x) * max_y * 4; /* (For FBC when LPT not supported). */ - size.preferred_size_alignment = size.min_size_alignment = 0x100; /* For FBC when LPT not supported */ - size.bits.preferred_must_be_framebuffer_pool = 1; - size.bits.min_must_be_framebuffer_pool = 1; - - result = true; - } - /* - * Maybe to add registry key support with optional size here to override above - * for debugging purposes - */ - - return result; -} - - void get_max_support_fbc_buffersize(unsigned int *max_x, unsigned int *max_y) { *max_x = FBC_MAX_X; @@ -455,31 +425,6 @@ void get_max_support_fbc_buffersize(unsigned int *max_x, unsigned int *max_y) */ } - -unsigned int controller_id_to_index(enum controller_id controller_id) -{ - unsigned int index = 0; - - switch (controller_id) { - case CONTROLLER_ID_D0: - index = 0; - break; - case CONTROLLER_ID_D1: - index = 1; - break; - case CONTROLLER_ID_D2: - index = 2; - break; - case CONTROLLER_ID_D3: - index = 3; - break; - default: - break; - } - return index; -} - - static const struct compressor_funcs dce110_compressor_funcs = { .power_up_fbc = dce110_compressor_power_up_fbc, .enable_fbc = dce110_compressor_enable_fbc, 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 4c230f1de9a3..caee1c9f54bd 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 @@ -921,6 +921,37 @@ void dce110_edp_power_control( } } +void dce110_edp_wait_for_T12( + struct dc_link *link) +{ + struct dc_context *ctx = link->ctx; + + if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) + != CONNECTOR_ID_EDP) { + BREAK_TO_DEBUGGER(); + return; + } + + if (!link->panel_cntl) + return; + + if (!link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl) && + link->link_trace.time_stamp.edp_poweroff != 0) { + unsigned int t12_duration = 500; // Default T12 as per spec + unsigned long long current_ts = dm_get_timestamp(ctx); + unsigned long long time_since_edp_poweroff_ms = + div64_u64(dm_get_elapse_time_in_ns( + ctx, + current_ts, + link->link_trace.time_stamp.edp_poweroff), 1000000); + + t12_duration += link->local_sink->edid_caps.panel_patch.extra_t12_ms; // Add extra T12 + + if (time_since_edp_poweroff_ms < t12_duration) + msleep(t12_duration - time_since_edp_poweroff_ms); + } +} + /*todo: cloned in stream enc, fix*/ /* * @brief @@ -1628,7 +1659,7 @@ static struct dc_link *get_edp_link_with_sink( return link; } -/** +/* * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need: * 1. Power down all DC HW blocks * 2. Disable VGA engine on all controllers diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c index d54172d88f5f..8bbb499067f7 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c @@ -34,6 +34,7 @@ #include "inc/dce_calcs.h" #include "dce/dce_mem_input.h" +#include "dce110_mem_input_v.h" static void set_flip_control( struct dce_mem_input *mem_input110, @@ -468,7 +469,7 @@ static void program_pixel_format( } } -bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input) +static bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input) { struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input); uint32_t value; @@ -483,7 +484,7 @@ bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input) return false; } -bool dce_mem_input_v_program_surface_flip_and_addr( +static bool dce_mem_input_v_program_surface_flip_and_addr( struct mem_input *mem_input, const struct dc_plane_address *address, bool flip_immediate) @@ -560,7 +561,7 @@ static const unsigned int *get_dvmm_hw_setting( } } -void dce_mem_input_v_program_pte_vm( +static void dce_mem_input_v_program_pte_vm( struct mem_input *mem_input, enum surface_pixel_format format, union dc_tiling_info *tiling_info, @@ -633,7 +634,7 @@ void dce_mem_input_v_program_pte_vm( dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C, value); } -void dce_mem_input_v_program_surface_config( +static void dce_mem_input_v_program_surface_config( struct mem_input *mem_input, enum surface_pixel_format format, union dc_tiling_info *tiling_info, @@ -919,7 +920,7 @@ static void program_nbp_watermark_c( marks); } -void dce_mem_input_v_program_display_marks( +static void dce_mem_input_v_program_display_marks( struct mem_input *mem_input, struct dce_watermarks nbp, struct dce_watermarks stutter, @@ -942,7 +943,7 @@ void dce_mem_input_v_program_display_marks( } -void dce_mem_input_program_chroma_display_marks( +static void dce_mem_input_program_chroma_display_marks( struct mem_input *mem_input, struct dce_watermarks nbp, struct dce_watermarks stutter, @@ -963,7 +964,7 @@ void dce_mem_input_program_chroma_display_marks( stutter); } -void dce110_allocate_mem_input_v( +static void dce110_allocate_mem_input_v( struct mem_input *mi, uint32_t h_total,/* for current stream */ uint32_t v_total,/* for current stream */ @@ -1005,7 +1006,7 @@ void dce110_allocate_mem_input_v( } -void dce110_free_mem_input_v( +static void dce110_free_mem_input_v( struct mem_input *mi, uint32_t total_stream_num) { diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index 3f63822b8e28..d7fcc5cccdce 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -410,7 +410,7 @@ static const struct dc_plane_cap plane_cap = { .pixel_format_support = { .argb8888 = true, .nv12 = false, - .fp16 = false + .fp16 = true }, .max_upscale_factor = { @@ -715,7 +715,7 @@ static struct output_pixel_processor *dce110_opp_create( return &opp->base; } -struct dce_aux *dce110_aux_engine_create( +static struct dce_aux *dce110_aux_engine_create( struct dc_context *ctx, uint32_t inst) { @@ -753,7 +753,7 @@ static const struct dce_i2c_mask i2c_masks = { I2C_COMMON_MASK_SH_LIST_DCE110(_MASK) }; -struct dce_i2c_hw *dce110_i2c_hw_create( +static struct dce_i2c_hw *dce110_i2c_hw_create( struct dc_context *ctx, uint32_t inst) { @@ -768,7 +768,7 @@ struct dce_i2c_hw *dce110_i2c_hw_create( return dce_i2c_hw; } -struct clock_source *dce110_clock_source_create( +static struct clock_source *dce110_clock_source_create( struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, @@ -792,7 +792,7 @@ struct clock_source *dce110_clock_source_create( return NULL; } -void dce110_clock_source_destroy(struct clock_source **clk_src) +static void dce110_clock_source_destroy(struct clock_source **clk_src) { struct dce110_clk_src *dce110_clk_src; @@ -1034,8 +1034,8 @@ static bool dce110_validate_bandwidth( return result; } -enum dc_status dce110_validate_plane(const struct dc_plane_state *plane_state, - struct dc_caps *caps) +static enum dc_status dce110_validate_plane(const struct dc_plane_state *plane_state, + struct dc_caps *caps) { if (((plane_state->dst_rect.width * 2) < plane_state->src_rect.width) || ((plane_state->dst_rect.height * 2) < plane_state->src_rect.height)) @@ -1089,7 +1089,7 @@ static bool dce110_validate_surface_sets( return true; } -enum dc_status dce110_validate_global( +static enum dc_status dce110_validate_global( struct dc *dc, struct dc_state *context) { @@ -1272,7 +1272,6 @@ static bool underlay_create(struct dc_context *ctx, struct resource_pool *pool) /* update the public caps to indicate an underlay is available */ ctx->dc->caps.max_slave_planes = 1; - ctx->dc->caps.max_slave_planes = 1; return true; } @@ -1333,7 +1332,7 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) 1000); } -const struct resource_caps *dce110_resource_cap( +static const struct resource_caps *dce110_resource_cap( struct hw_asic_id *asic_id) { if (ASIC_REV_IS_STONEY(asic_id->hw_internal_rev)) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c index 1ea7db8eeb98..d88a74559edd 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c @@ -75,7 +75,7 @@ static void dce110_timing_generator_apply_front_porch_workaround( } } -/** +/* ***************************************************************************** * Function: is_in_vertical_blank * @@ -116,7 +116,7 @@ void dce110_timing_generator_set_early_control( dm_write_reg(tg->ctx, address, regval); } -/** +/* * Enable CRTC * Enable CRTC - call ASIC Control Object to enable Timing generator. */ @@ -175,7 +175,7 @@ void dce110_timing_generator_program_blank_color( dm_write_reg(tg->ctx, addr, value); } -/** +/* ***************************************************************************** * Function: disable_stereo * @@ -226,7 +226,7 @@ static void disable_stereo(struct timing_generator *tg) } #endif -/** +/* * disable_crtc - call ASIC Control Object to disable Timing generator. */ bool dce110_timing_generator_disable_crtc(struct timing_generator *tg) @@ -247,11 +247,10 @@ bool dce110_timing_generator_disable_crtc(struct timing_generator *tg) return result == BP_RESULT_OK; } -/** -* program_horz_count_by_2 -* Programs DxCRTC_HORZ_COUNT_BY2_EN - 1 for DVI 30bpp mode, 0 otherwise -* -*/ +/* + * program_horz_count_by_2 + * Programs DxCRTC_HORZ_COUNT_BY2_EN - 1 for DVI 30bpp mode, 0 otherwise + */ static void program_horz_count_by_2( struct timing_generator *tg, const struct dc_crtc_timing *timing) @@ -273,7 +272,7 @@ static void program_horz_count_by_2( CRTC_REG(mmCRTC_COUNT_CONTROL), regval); } -/** +/* * program_timing_generator * Program CRTC Timing Registers - DxCRTC_H_*, DxCRTC_V_*, Pixel repetition. * Call ASIC Control Object to program Timings. @@ -352,7 +351,7 @@ bool dce110_timing_generator_program_timing_generator( return result == BP_RESULT_OK; } -/** +/* ***************************************************************************** * Function: set_drr * @@ -521,7 +520,7 @@ uint32_t dce110_timing_generator_get_vblank_counter(struct timing_generator *tg) return field; } -/** +/* ***************************************************************************** * Function: dce110_timing_generator_get_position * @@ -557,7 +556,7 @@ void dce110_timing_generator_get_position(struct timing_generator *tg, CRTC_VERT_COUNT_NOM); } -/** +/* ***************************************************************************** * Function: get_crtc_scanoutpos * @@ -1106,11 +1105,11 @@ void dce110_timing_generator_set_test_pattern( } } -/** -* dce110_timing_generator_validate_timing -* The timing generators support a maximum display size of is 8192 x 8192 pixels, -* including both active display and blanking periods. Check H Total and V Total. -*/ +/* + * dce110_timing_generator_validate_timing + * The timing generators support a maximum display size of is 8192 x 8192 pixels, + * including both active display and blanking periods. Check H Total and V Total. + */ bool dce110_timing_generator_validate_timing( struct timing_generator *tg, const struct dc_crtc_timing *timing, @@ -1167,9 +1166,9 @@ bool dce110_timing_generator_validate_timing( return true; } -/** -* Wait till we are at the beginning of VBlank. -*/ +/* + * Wait till we are at the beginning of VBlank. + */ void dce110_timing_generator_wait_for_vblank(struct timing_generator *tg) { /* We want to catch beginning of VBlank here, so if the first try are @@ -1191,9 +1190,9 @@ void dce110_timing_generator_wait_for_vblank(struct timing_generator *tg) } } -/** -* Wait till we are in VActive (anywhere in VActive) -*/ +/* + * Wait till we are in VActive (anywhere in VActive) + */ void dce110_timing_generator_wait_for_vactive(struct timing_generator *tg) { while (dce110_timing_generator_is_in_vertical_blank(tg)) { @@ -1204,7 +1203,7 @@ void dce110_timing_generator_wait_for_vactive(struct timing_generator *tg) } } -/** +/* ***************************************************************************** * Function: dce110_timing_generator_setup_global_swap_lock * @@ -1215,7 +1214,6 @@ void dce110_timing_generator_wait_for_vactive(struct timing_generator *tg) * @param [in] gsl_params: setup data ***************************************************************************** */ - void dce110_timing_generator_setup_global_swap_lock( struct timing_generator *tg, const struct dcp_gsl_params *gsl_params) @@ -1351,10 +1349,7 @@ void dce110_timing_generator_tear_down_global_swap_lock( /* Restore DCP_GSL_PURPOSE_SURFACE_FLIP */ { - uint32_t value_crtc_vtotal; - - value_crtc_vtotal = dm_read_reg(tg->ctx, - CRTC_REG(mmCRTC_V_TOTAL)); + dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_V_TOTAL)); set_reg_field_value(value, 0, @@ -1385,7 +1380,7 @@ void dce110_timing_generator_tear_down_global_swap_lock( dm_write_reg(tg->ctx, address, value); } -/** +/* ***************************************************************************** * Function: is_counter_moving * @@ -1767,7 +1762,7 @@ void dce110_timing_generator_disable_reset_trigger( dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value); } -/** +/* ***************************************************************************** * @brief * Checks whether CRTC triggered reset occurred @@ -1794,7 +1789,7 @@ bool dce110_timing_generator_did_triggered_reset_occur( return (force || vert_sync); } -/** +/* * dce110_timing_generator_disable_vga * Turn OFF VGA Mode and Timing - DxVGA_CONTROL * VGA Mode and VGA Timing is used by VBIOS on CRT Monitors; @@ -1840,14 +1835,13 @@ void dce110_timing_generator_disable_vga( dm_write_reg(tg->ctx, addr, value); } -/** -* set_overscan_color_black -* -* @param :black_color is one of the color space -* :this routine will set overscan black color according to the color space. -* @return none -*/ - +/* + * set_overscan_color_black + * + * @param :black_color is one of the color space + * :this routine will set overscan black color according to the color space. + * @return none + */ void dce110_timing_generator_set_overscan_color_black( struct timing_generator *tg, const struct tg_color *color) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c index a13a2f58944e..c509384fff54 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c @@ -46,17 +46,16 @@ * **********************************************************************************/ -/** -* Enable CRTCV -*/ +/* + * Enable CRTCV + */ static bool dce110_timing_generator_v_enable_crtc(struct timing_generator *tg) { /* -* Set MASTER_UPDATE_MODE to 0 -* This is needed for DRR, and also suggested to be default value by Syed. -*/ - + * Set MASTER_UPDATE_MODE to 0 + * This is needed for DRR, and also suggested to be default value by Syed. + */ uint32_t value; value = 0; @@ -209,9 +208,9 @@ static void dce110_timing_generator_v_wait_for_vblank(struct timing_generator *t } } -/** -* Wait till we are in VActive (anywhere in VActive) -*/ +/* + * Wait till we are in VActive (anywhere in VActive) + */ static void dce110_timing_generator_v_wait_for_vactive(struct timing_generator *tg) { while (dce110_timing_generator_v_is_in_vertical_blank(tg)) { diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c index b1aaab5590cc..29438c6050db 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c @@ -217,16 +217,15 @@ static bool setup_scaling_configuration( return is_scaling_needed; } -/** -* Function: -* void program_overscan -* -* Purpose: Programs overscan border -* Input: overscan -* -* Output: - void -*/ +/* + * Function: + * void program_overscan + * + * Purpose: Programs overscan border + * Input: overscan + * + * Output: void + */ static void program_overscan( struct dce_transform *xfm_dce, const struct scaler_data *data) diff --git a/drivers/gpu/drm/amd/display/dc/dce112/Makefile b/drivers/gpu/drm/amd/display/dc/dce112/Makefile index 8e090446d511..9de6501702d2 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dce112/Makefile @@ -23,6 +23,8 @@ # Makefile for the 'controller' sub-component of DAL. # It provides the control and status of HW CRTC block. +CFLAGS_$(AMDDALPATH)/dc/dce112/dce112_resource.o = $(call cc-disable-warning, override-init) + DCE112 = dce112_compressor.o dce112_hw_sequencer.o \ dce112_resource.o diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index f99b1c084590..ee55cda854bf 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -59,7 +59,9 @@ #include "dce/dce_11_2_sh_mask.h" #include "dce100/dce100_resource.h" -#define DC_LOGGER \ +#include "dce112_resource.h" + +#define DC_LOGGER \ dc->ctx->logger #ifndef mmDP_DPHY_INTERNAL_CTRL @@ -617,7 +619,7 @@ static const struct encoder_feature_support link_enc_feature = { .flags.bits.IS_TPS4_CAPABLE = true }; -struct link_encoder *dce112_link_encoder_create( +static struct link_encoder *dce112_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dce110_link_encoder *enc110 = @@ -671,7 +673,7 @@ static struct input_pixel_processor *dce112_ipp_create( return &ipp->base; } -struct output_pixel_processor *dce112_opp_create( +static struct output_pixel_processor *dce112_opp_create( struct dc_context *ctx, uint32_t inst) { @@ -686,7 +688,7 @@ struct output_pixel_processor *dce112_opp_create( return &opp->base; } -struct dce_aux *dce112_aux_engine_create( +static struct dce_aux *dce112_aux_engine_create( struct dc_context *ctx, uint32_t inst) { @@ -724,7 +726,7 @@ static const struct dce_i2c_mask i2c_masks = { I2C_COMMON_MASK_SH_LIST_DCE110(_MASK) }; -struct dce_i2c_hw *dce112_i2c_hw_create( +static struct dce_i2c_hw *dce112_i2c_hw_create( struct dc_context *ctx, uint32_t inst) { @@ -739,7 +741,7 @@ struct dce_i2c_hw *dce112_i2c_hw_create( return dce_i2c_hw; } -struct clock_source *dce112_clock_source_create( +static struct clock_source *dce112_clock_source_create( struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, @@ -763,7 +765,7 @@ struct clock_source *dce112_clock_source_create( return NULL; } -void dce112_clock_source_destroy(struct clock_source **clk_src) +static void dce112_clock_source_destroy(struct clock_source **clk_src) { kfree(TO_DCE110_CLK_SRC(*clk_src)); *clk_src = NULL; @@ -1024,7 +1026,7 @@ enum dc_status dce112_add_stream_to_ctx( return result; } -enum dc_status dce112_validate_global( +static enum dc_status dce112_validate_global( struct dc *dc, struct dc_state *context) { @@ -1202,7 +1204,7 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges); } -const struct resource_caps *dce112_resource_cap( +static const struct resource_caps *dce112_resource_cap( struct hw_asic_id *asic_id) { if (ASIC_REV_IS_POLARIS11_M(asic_id->hw_internal_rev) || diff --git a/drivers/gpu/drm/amd/display/dc/dce120/Makefile b/drivers/gpu/drm/amd/display/dc/dce120/Makefile index 37db1f8d45ea..a9cc4b73270b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dce120/Makefile @@ -24,6 +24,8 @@ # It provides the control and status of HW CRTC block. +CFLAGS_$(AMDDALPATH)/dc/dce120/dce120_resource.o = $(call cc-disable-warning, override-init) + DCE120 = dce120_resource.o dce120_timing_generator.o \ dce120_hw_sequencer.o diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c index 66a13aa39c95..d4afe6c824d2 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c @@ -50,6 +50,7 @@ struct dce120_hw_seq_reg_offsets { uint32_t crtc; }; +#if 0 static const struct dce120_hw_seq_reg_offsets reg_offsets[] = { { .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL), @@ -79,7 +80,6 @@ static const struct dce120_hw_seq_reg_offsets reg_offsets[] = { /******************************************************************************* * Private definitions ******************************************************************************/ -#if 0 static void dce120_init_pte(struct dc_context *ctx, uint8_t controller_id) { uint32_t addr; diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c index f1e3d2888eac..c65e4d125c8e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c @@ -423,7 +423,7 @@ static const struct dce110_clk_src_mask cs_mask = { CS_COMMON_MASK_SH_LIST_DCE_112(_MASK) }; -struct output_pixel_processor *dce120_opp_create( +static struct output_pixel_processor *dce120_opp_create( struct dc_context *ctx, uint32_t inst) { @@ -437,7 +437,7 @@ struct output_pixel_processor *dce120_opp_create( ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask); return &opp->base; } -struct dce_aux *dce120_aux_engine_create( +static struct dce_aux *dce120_aux_engine_create( struct dc_context *ctx, uint32_t inst) { @@ -475,7 +475,7 @@ static const struct dce_i2c_mask i2c_masks = { I2C_COMMON_MASK_SH_LIST_DCE110(_MASK) }; -struct dce_i2c_hw *dce120_i2c_hw_create( +static struct dce_i2c_hw *dce120_i2c_hw_create( struct dc_context *ctx, uint32_t inst) { diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c index 915fbb8e8168..b57c466124e7 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c @@ -69,7 +69,7 @@ #define CRTC_REG_SET_3(reg, field1, val1, field2, val2, field3, val3) \ CRTC_REG_SET_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3) -/** +/* ***************************************************************************** * Function: is_in_vertical_blank * @@ -98,7 +98,7 @@ static bool dce120_timing_generator_is_in_vertical_blank( /* determine if given timing can be supported by TG */ -bool dce120_timing_generator_validate_timing( +static bool dce120_timing_generator_validate_timing( struct timing_generator *tg, const struct dc_crtc_timing *timing, enum signal_type signal) @@ -125,7 +125,7 @@ bool dce120_timing_generator_validate_timing( return true; } -bool dce120_tg_validate_timing(struct timing_generator *tg, +static bool dce120_tg_validate_timing(struct timing_generator *tg, const struct dc_crtc_timing *timing) { return dce120_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE); @@ -133,7 +133,7 @@ bool dce120_tg_validate_timing(struct timing_generator *tg, /******** HW programming ************/ /* Disable/Enable Timing Generator */ -bool dce120_timing_generator_enable_crtc(struct timing_generator *tg) +static bool dce120_timing_generator_enable_crtc(struct timing_generator *tg) { enum bp_result result; struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); @@ -153,7 +153,7 @@ bool dce120_timing_generator_enable_crtc(struct timing_generator *tg) return result == BP_RESULT_OK; } -void dce120_timing_generator_set_early_control( +static void dce120_timing_generator_set_early_control( struct timing_generator *tg, uint32_t early_cntl) { @@ -166,7 +166,7 @@ void dce120_timing_generator_set_early_control( /**************** TG current status ******************/ /* return the current frame counter. Used by Linux kernel DRM */ -uint32_t dce120_timing_generator_get_vblank_counter( +static uint32_t dce120_timing_generator_get_vblank_counter( struct timing_generator *tg) { struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); @@ -181,7 +181,7 @@ uint32_t dce120_timing_generator_get_vblank_counter( } /* Get current H and V position */ -void dce120_timing_generator_get_crtc_position( +static void dce120_timing_generator_get_crtc_position( struct timing_generator *tg, struct crtc_position *position) { @@ -207,7 +207,7 @@ void dce120_timing_generator_get_crtc_position( } /* wait until TG is in beginning of vertical blank region */ -void dce120_timing_generator_wait_for_vblank(struct timing_generator *tg) +static void dce120_timing_generator_wait_for_vblank(struct timing_generator *tg) { /* We want to catch beginning of VBlank here, so if the first try are * in VBlank, we might be very close to Active, in this case wait for @@ -229,7 +229,7 @@ void dce120_timing_generator_wait_for_vblank(struct timing_generator *tg) } /* wait until TG is in beginning of active region */ -void dce120_timing_generator_wait_for_vactive(struct timing_generator *tg) +static void dce120_timing_generator_wait_for_vactive(struct timing_generator *tg) { while (dce120_timing_generator_is_in_vertical_blank(tg)) { if (!tg->funcs->is_counter_moving(tg)) { @@ -242,7 +242,7 @@ void dce120_timing_generator_wait_for_vactive(struct timing_generator *tg) /*********** Timing Generator Synchronization routines ****/ /* Setups Global Swap Lock group, TimingServer or TimingClient*/ -void dce120_timing_generator_setup_global_swap_lock( +static void dce120_timing_generator_setup_global_swap_lock( struct timing_generator *tg, const struct dcp_gsl_params *gsl_params) { @@ -279,7 +279,7 @@ void dce120_timing_generator_setup_global_swap_lock( } /* Clear all the register writes done by setup_global_swap_lock */ -void dce120_timing_generator_tear_down_global_swap_lock( +static void dce120_timing_generator_tear_down_global_swap_lock( struct timing_generator *tg) { struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); @@ -300,7 +300,7 @@ void dce120_timing_generator_tear_down_global_swap_lock( } /* Reset slave controllers on master VSync */ -void dce120_timing_generator_enable_reset_trigger( +static void dce120_timing_generator_enable_reset_trigger( struct timing_generator *tg, int source) { @@ -347,7 +347,7 @@ void dce120_timing_generator_enable_reset_trigger( } /* disabling trigger-reset */ -void dce120_timing_generator_disable_reset_trigger( +static void dce120_timing_generator_disable_reset_trigger( struct timing_generator *tg) { struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); @@ -367,7 +367,7 @@ void dce120_timing_generator_disable_reset_trigger( } /* Checks whether CRTC triggered reset occurred */ -bool dce120_timing_generator_did_triggered_reset_occur( +static bool dce120_timing_generator_did_triggered_reset_occur( struct timing_generator *tg) { struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); @@ -384,7 +384,7 @@ bool dce120_timing_generator_did_triggered_reset_occur( /******** Stuff to move to other virtual HW objects *****************/ /* Move to enable accelerated mode */ -void dce120_timing_generator_disable_vga(struct timing_generator *tg) +static void dce120_timing_generator_disable_vga(struct timing_generator *tg) { uint32_t offset = 0; uint32_t value = 0; @@ -425,7 +425,7 @@ void dce120_timing_generator_disable_vga(struct timing_generator *tg) } /* TODO: Should we move it to transform */ /* Fully program CRTC timing in timing generator */ -void dce120_timing_generator_program_blanking( +static void dce120_timing_generator_program_blanking( struct timing_generator *tg, const struct dc_crtc_timing *timing) { @@ -485,7 +485,7 @@ void dce120_timing_generator_program_blanking( /* TODO: Should we move it to opp? */ /* Combine with below and move YUV/RGB color conversion to SW layer */ -void dce120_timing_generator_program_blank_color( +static void dce120_timing_generator_program_blank_color( struct timing_generator *tg, const struct tg_color *black_color) { @@ -498,7 +498,7 @@ void dce120_timing_generator_program_blank_color( CRTC_BLACK_COLOR_R_CR, black_color->color_r_cr); } /* Combine with above and move YUV/RGB color conversion to SW layer */ -void dce120_timing_generator_set_overscan_color_black( +static void dce120_timing_generator_set_overscan_color_black( struct timing_generator *tg, const struct tg_color *color) { @@ -540,7 +540,7 @@ void dce120_timing_generator_set_overscan_color_black( */ } -void dce120_timing_generator_set_drr( +static void dce120_timing_generator_set_drr( struct timing_generator *tg, const struct drr_params *params) { @@ -589,50 +589,7 @@ void dce120_timing_generator_set_drr( } } -/** - ***************************************************************************** - * Function: dce120_timing_generator_get_position - * - * @brief - * Returns CRTC vertical/horizontal counters - * - * @param [out] position - ***************************************************************************** - */ -void dce120_timing_generator_get_position(struct timing_generator *tg, - struct crtc_position *position) -{ - uint32_t value; - struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); - - value = dm_read_reg_soc15( - tg->ctx, - mmCRTC0_CRTC_STATUS_POSITION, - tg110->offsets.crtc); - - position->horizontal_count = get_reg_field_value( - value, - CRTC0_CRTC_STATUS_POSITION, - CRTC_HORZ_COUNT); - - position->vertical_count = get_reg_field_value( - value, - CRTC0_CRTC_STATUS_POSITION, - CRTC_VERT_COUNT); - - value = dm_read_reg_soc15( - tg->ctx, - mmCRTC0_CRTC_NOM_VERT_POSITION, - tg110->offsets.crtc); - - position->nominal_vcount = get_reg_field_value( - value, - CRTC0_CRTC_NOM_VERT_POSITION, - CRTC_VERT_COUNT_NOM); -} - - -void dce120_timing_generator_get_crtc_scanoutpos( +static void dce120_timing_generator_get_crtc_scanoutpos( struct timing_generator *tg, uint32_t *v_blank_start, uint32_t *v_blank_end, @@ -661,7 +618,7 @@ void dce120_timing_generator_get_crtc_scanoutpos( *v_position = position.vertical_count; } -void dce120_timing_generator_enable_advanced_request( +static void dce120_timing_generator_enable_advanced_request( struct timing_generator *tg, bool enable, const struct dc_crtc_timing *timing) @@ -699,7 +656,7 @@ void dce120_timing_generator_enable_advanced_request( value); } -void dce120_tg_program_blank_color(struct timing_generator *tg, +static void dce120_tg_program_blank_color(struct timing_generator *tg, const struct tg_color *black_color) { struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); @@ -722,7 +679,7 @@ void dce120_tg_program_blank_color(struct timing_generator *tg, value); } -void dce120_tg_set_overscan_color(struct timing_generator *tg, +static void dce120_tg_set_overscan_color(struct timing_generator *tg, const struct tg_color *overscan_color) { struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); @@ -749,7 +706,7 @@ static void dce120_tg_program_timing(struct timing_generator *tg, dce120_timing_generator_program_blanking(tg, timing); } -bool dce120_tg_is_blanked(struct timing_generator *tg) +static bool dce120_tg_is_blanked(struct timing_generator *tg) { struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); uint32_t value = dm_read_reg_soc15( @@ -770,7 +727,7 @@ bool dce120_tg_is_blanked(struct timing_generator *tg) return false; } -void dce120_tg_set_blank(struct timing_generator *tg, +static void dce120_tg_set_blank(struct timing_generator *tg, bool enable_blanking) { struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); @@ -789,7 +746,7 @@ void dce120_tg_set_blank(struct timing_generator *tg, bool dce120_tg_validate_timing(struct timing_generator *tg, const struct dc_crtc_timing *timing); -void dce120_tg_wait_for_state(struct timing_generator *tg, +static void dce120_tg_wait_for_state(struct timing_generator *tg, enum crtc_state state) { switch (state) { @@ -806,7 +763,7 @@ void dce120_tg_wait_for_state(struct timing_generator *tg, } } -void dce120_tg_set_colors(struct timing_generator *tg, +static void dce120_tg_set_colors(struct timing_generator *tg, const struct tg_color *blank_color, const struct tg_color *overscan_color) { @@ -833,7 +790,7 @@ static void dce120_timing_generator_set_static_screen_control( CRTC_STATIC_SCREEN_FRAME_COUNT, num_frames); } -void dce120_timing_generator_set_test_pattern( +static void dce120_timing_generator_set_test_pattern( struct timing_generator *tg, /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode' * because this is not DP-specific (which is probably somewhere in DP diff --git a/drivers/gpu/drm/amd/display/dc/dce60/Makefile b/drivers/gpu/drm/amd/display/dc/dce60/Makefile index 7036c3bd0f87..dda596fa1cd7 100644 --- a/drivers/gpu/drm/amd/display/dc/dce60/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dce60/Makefile @@ -23,6 +23,8 @@ # Makefile for the 'controller' sub-component of DAL. # It provides the control and status of HW CRTC block. +CFLAGS_AMDDALPATH)/dc/dce60/dce60_resource.o = $(call cc-disable-warning, override-init) + DCE60 = dce60_timing_generator.o dce60_hw_sequencer.o \ dce60_resource.o diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c index e9dd78c484d6..dcfa0a3efa00 100644 --- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c @@ -60,6 +60,8 @@ #include "dce/dce_i2c.h" /* TODO remove this include */ +#include "dce60_resource.h" + #ifndef mmMC_HUB_RDREQ_DMIF_LIMIT #include "gmc/gmc_6_0_d.h" #include "gmc/gmc_6_0_sh_mask.h" @@ -519,7 +521,7 @@ static struct output_pixel_processor *dce60_opp_create( return &opp->base; } -struct dce_aux *dce60_aux_engine_create( +static struct dce_aux *dce60_aux_engine_create( struct dc_context *ctx, uint32_t inst) { @@ -557,7 +559,7 @@ static const struct dce_i2c_mask i2c_masks = { I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) }; -struct dce_i2c_hw *dce60_i2c_hw_create( +static struct dce_i2c_hw *dce60_i2c_hw_create( struct dc_context *ctx, uint32_t inst) { @@ -573,7 +575,7 @@ struct dce_i2c_hw *dce60_i2c_hw_create( return dce_i2c_hw; } -struct dce_i2c_sw *dce60_i2c_sw_create( +static struct dce_i2c_sw *dce60_i2c_sw_create( struct dc_context *ctx) { struct dce_i2c_sw *dce_i2c_sw = @@ -707,7 +709,7 @@ static const struct encoder_feature_support link_enc_feature = { .flags.bits.IS_TPS3_CAPABLE = true }; -struct link_encoder *dce60_link_encoder_create( +static struct link_encoder *dce60_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dce110_link_encoder *enc110 = @@ -746,7 +748,7 @@ static struct panel_cntl *dce60_panel_cntl_create(const struct panel_cntl_init_d return &panel_cntl->base; } -struct clock_source *dce60_clock_source_create( +static struct clock_source *dce60_clock_source_create( struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, @@ -770,7 +772,7 @@ struct clock_source *dce60_clock_source_create( return NULL; } -void dce60_clock_source_destroy(struct clock_source **clk_src) +static void dce60_clock_source_destroy(struct clock_source **clk_src) { kfree(TO_DCE110_CLK_SRC(*clk_src)); *clk_src = NULL; @@ -860,7 +862,7 @@ static void dce60_resource_destruct(struct dce110_resource_pool *pool) } } -bool dce60_validate_bandwidth( +static bool dce60_validate_bandwidth( struct dc *dc, struct dc_state *context, bool fast_validate) @@ -905,7 +907,7 @@ static bool dce60_validate_surface_sets( return true; } -enum dc_status dce60_validate_global( +static enum dc_status dce60_validate_global( struct dc *dc, struct dc_state *context) { diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c index fc1af0ff0ca4..c1a85ee374d9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c +++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c @@ -189,8 +189,8 @@ static bool dce60_is_tg_enabled(struct timing_generator *tg) return field == 1; } -bool dce60_configure_crc(struct timing_generator *tg, - const struct crc_params *params) +static bool dce60_configure_crc(struct timing_generator *tg, + const struct crc_params *params) { /* Cannot configure crc on a CRTC that is disabled */ if (!dce60_is_tg_enabled(tg)) diff --git a/drivers/gpu/drm/amd/display/dc/dce80/Makefile b/drivers/gpu/drm/amd/display/dc/dce80/Makefile index 666fcb2bdbba..0a9d1a350d8b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dce80/Makefile @@ -23,6 +23,8 @@ # Makefile for the 'controller' sub-component of DAL. # It provides the control and status of HW CRTC block. +CFLAGS_$(AMDDALPATH)/dc/dce80/dce80_resource.o = $(call cc-disable-warning, override-init) + DCE80 = dce80_timing_generator.o dce80_hw_sequencer.o \ dce80_resource.o diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c index 390a0fa37239..612450f99278 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c @@ -60,6 +60,8 @@ #include "dce/dce_i2c.h" /* TODO remove this include */ +#include "dce80_resource.h" + #ifndef mmMC_HUB_RDREQ_DMIF_LIMIT #include "gmc/gmc_7_1_d.h" #include "gmc/gmc_7_1_sh_mask.h" @@ -402,7 +404,7 @@ static const struct dc_plane_cap plane_cap = { .pixel_format_support = { .argb8888 = true, .nv12 = false, - .fp16 = false + .fp16 = true }, .max_upscale_factor = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c index 4d3f7d5e1473..904c2d278998 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c @@ -577,7 +577,7 @@ void dpp1_power_on_degamma_lut( struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); REG_SET(CM_MEM_PWR_CTRL, 0, - SHARED_MEM_PWR_DIS, power_on == true ? 0:1); + SHARED_MEM_PWR_DIS, power_on ? 0:1); } 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 017b67b830e6..89912bb5014f 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 @@ -1224,6 +1224,7 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context) // signals when OTG blanked. This is to prevent pipe from // requesting data while in PSR. tg->funcs->tg_init(tg); + hubp->power_gated = true; continue; } @@ -2634,7 +2635,7 @@ static void dcn10_update_dchubp_dpp( hws->funcs.update_plane_addr(dc, pipe_ctx); if (is_pipe_tree_visible(pipe_ctx)) - hubp->funcs->set_blank(hubp, false); + dc->hwss.set_hubp_blank(dc, pipe_ctx, false); } void dcn10_blank_pixel_data( @@ -3134,7 +3135,7 @@ void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc) pipe_ctx->stream_res.opp->funcs->opp_program_stereo( pipe_ctx->stream_res.opp, - flags.PROGRAM_STEREO == 1 ? true:false, + flags.PROGRAM_STEREO == 1, &stream->timing); pipe_ctx->stream_res.tg->funcs->program_stereo( @@ -3145,13 +3146,16 @@ void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc) return; } -static struct hubp *get_hubp_by_inst(struct resource_pool *res_pool, int mpcc_inst) +static struct pipe_ctx *get_pipe_ctx_by_hubp_inst(struct dc_state *context, int mpcc_inst) { int i; - for (i = 0; i < res_pool->pipe_count; i++) { - if (res_pool->hubps[i]->inst == mpcc_inst) - return res_pool->hubps[i]; + for (i = 0; i < MAX_PIPES; i++) { + if (context->res_ctx.pipe_ctx[i].plane_res.hubp + && context->res_ctx.pipe_ctx[i].plane_res.hubp->inst == mpcc_inst) { + return &context->res_ctx.pipe_ctx[i]; + } + } ASSERT(false); return NULL; @@ -3174,11 +3178,23 @@ void dcn10_wait_for_mpcc_disconnect( for (mpcc_inst = 0; mpcc_inst < MAX_PIPES; mpcc_inst++) { if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) { - struct hubp *hubp = get_hubp_by_inst(res_pool, mpcc_inst); + struct pipe_ctx *restore_bottom_pipe; + struct pipe_ctx *restore_top_pipe; + struct pipe_ctx *inst_pipe_ctx = get_pipe_ctx_by_hubp_inst(dc->current_state, mpcc_inst); + ASSERT(inst_pipe_ctx); res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst); pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false; - hubp->funcs->set_blank(hubp, true); + /* + * Set top and bottom pipes NULL, as we don't want + * to blank those pipes when disconnecting from MPCC + */ + restore_bottom_pipe = inst_pipe_ctx->bottom_pipe; + restore_top_pipe = inst_pipe_ctx->top_pipe; + inst_pipe_ctx->top_pipe = inst_pipe_ctx->bottom_pipe = NULL; + dc->hwss.set_hubp_blank(dc, inst_pipe_ctx, true); + inst_pipe_ctx->top_pipe = restore_top_pipe; + inst_pipe_ctx->bottom_pipe = restore_bottom_pipe; } } @@ -3731,3 +3747,10 @@ void dcn10_get_clock(struct dc *dc, dc->clk_mgr->funcs->get_clock(dc->clk_mgr, context, clock_type, clock_cfg); } + +void dcn10_set_hubp_blank(const struct dc *dc, + struct pipe_ctx *pipe_ctx, + bool blank_enable) +{ + pipe_ctx->plane_res.hubp->funcs->set_blank(pipe_ctx->plane_res.hubp, blank_enable); +} diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h index e5691e499023..89e6dfb63da0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h @@ -163,6 +163,8 @@ void dcn10_wait_for_mpcc_disconnect( void dce110_edp_backlight_control( struct dc_link *link, bool enable); +void dce110_edp_wait_for_T12( + struct dc_link *link); void dce110_edp_power_control( struct dc_link *link, bool power_up); @@ -202,5 +204,8 @@ void dcn10_wait_for_pending_cleared(struct dc *dc, struct dc_state *context); void dcn10_set_hdr_multiplier(struct pipe_ctx *pipe_ctx); void dcn10_verify_allow_pstate_change_high(struct dc *dc); +void dcn10_set_hubp_blank(const struct dc *dc, + struct pipe_ctx *pipe_ctx, + bool blank_enable); #endif /* __DC_HWSS_DCN10_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c index 7f4766e45dff..e8b6065fffad 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c @@ -47,7 +47,7 @@ unsigned int snprintf_count(char *pBuf, unsigned int bufSize, char *fmt, ...) { - unsigned int ret_vsnprintf; + int ret_vsnprintf; unsigned int chars_printed; va_list args; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c index 254300b06b43..2f1b802e66a1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c @@ -79,6 +79,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { .set_backlight_level = dce110_set_backlight_level, .set_abm_immediate_disable = dce110_set_abm_immediate_disable, .set_pipe = dce110_set_pipe, + .set_hubp_blank = dcn10_set_hubp_blank, }; static const struct hwseq_private_funcs dcn10_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c index 81db0179f7ea..59024653430c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c @@ -956,6 +956,21 @@ void dcn10_link_encoder_enable_tmds_output( } } +void dcn10_link_encoder_enable_tmds_output_with_clk_pattern_wa( + struct link_encoder *enc, + enum clock_source_id clock_source, + enum dc_color_depth color_depth, + enum signal_type signal, + uint32_t pixel_clock) +{ + struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); + + dcn10_link_encoder_enable_tmds_output( + enc, clock_source, color_depth, signal, pixel_clock); + + REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F); +} + /* enables DP PHY output */ void dcn10_link_encoder_enable_dp_output( struct link_encoder *enc, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h index d4caad670855..3e1a582e4b88 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h @@ -42,6 +42,7 @@ #define LE_DCN_COMMON_REG_LIST(id) \ SRI(DIG_BE_CNTL, DIG, id), \ SRI(DIG_BE_EN_CNTL, DIG, id), \ + SRI(DIG_CLOCK_PATTERN, DIG, id), \ SRI(TMDS_CTL_BITS, DIG, id), \ SRI(DP_CONFIG, DP, id), \ SRI(DP_DPHY_CNTL, DP, id), \ @@ -83,6 +84,7 @@ struct dcn10_link_enc_hpd_registers { struct dcn10_link_enc_registers { uint32_t DIG_BE_CNTL; uint32_t DIG_BE_EN_CNTL; + uint32_t DIG_CLOCK_PATTERN; uint32_t DP_CONFIG; uint32_t DP_DPHY_CNTL; uint32_t DP_DPHY_INTERNAL_CTRL; @@ -168,6 +170,7 @@ struct dcn10_link_enc_registers { LE_SF(DIG0_DIG_BE_CNTL, DIG_HPD_SELECT, mask_sh),\ LE_SF(DIG0_DIG_BE_CNTL, DIG_MODE, mask_sh),\ LE_SF(DIG0_DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, mask_sh),\ + LE_SF(DIG0_DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, mask_sh),\ LE_SF(DIG0_TMDS_CTL_BITS, TMDS_CTL0, mask_sh), \ LE_SF(DP0_DP_DPHY_CNTL, DPHY_BYPASS, mask_sh),\ LE_SF(DP0_DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE0, mask_sh),\ @@ -218,6 +221,7 @@ struct dcn10_link_enc_registers { type DIG_HPD_SELECT;\ type DIG_MODE;\ type DIG_FE_SOURCE_SELECT;\ + type DIG_CLOCK_PATTERN;\ type DPHY_BYPASS;\ type DPHY_ATEST_SEL_LANE0;\ type DPHY_ATEST_SEL_LANE1;\ @@ -536,6 +540,13 @@ void dcn10_link_encoder_enable_tmds_output( enum signal_type signal, uint32_t pixel_clock); +void dcn10_link_encoder_enable_tmds_output_with_clk_pattern_wa( + struct link_encoder *enc, + enum clock_source_id clock_source, + enum dc_color_depth color_depth, + enum signal_type signal, + uint32_t pixel_clock); + /* enables DP PHY output */ void dcn10_link_encoder_enable_dp_output( struct link_encoder *enc, 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 f033397a84e9..6138f4887de7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c @@ -659,6 +659,16 @@ void optc1_unlock(struct timing_generator *optc) OTG_MASTER_UPDATE_LOCK, 0); } +bool optc1_is_locked(struct timing_generator *optc) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + uint32_t locked; + + REG_GET(OTG_MASTER_UPDATE_LOCK, UPDATE_LOCK_STATUS, &locked); + + return (locked == 1); +} + void optc1_get_position(struct timing_generator *optc, struct crtc_position *position) { @@ -1513,6 +1523,7 @@ static const struct timing_generator_funcs dcn10_tg_funcs = { .enable_crtc_reset = optc1_enable_crtc_reset, .disable_reset_trigger = optc1_disable_reset_trigger, .lock = optc1_lock, + .is_locked = optc1_is_locked, .unlock = optc1_unlock, .enable_optc_clock = optc1_enable_optc_clock, .set_drr = optc1_set_drr, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h index b12bd9aae52f..b222c67973d4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h @@ -638,6 +638,7 @@ void optc1_set_blank(struct timing_generator *optc, bool enable_blanking); bool optc1_is_blanked(struct timing_generator *optc); +bool optc1_is_locked(struct timing_generator *optc); void optc1_program_blank_color( struct timing_generator *optc, 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 480d928cb1ca..0726fb435e2a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1575,8 +1575,8 @@ static void dcn20_update_dchubp_dpp( - if (pipe_ctx->update_flags.bits.enable) - hubp->funcs->set_blank(hubp, false); + if (is_pipe_tree_visible(pipe_ctx)) + dc->hwss.set_hubp_blank(dc, pipe_ctx, false); } @@ -1770,6 +1770,14 @@ void dcn20_post_unlock_program_front_end( } } + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + + if (pipe->vtp_locked) { + dc->hwss.set_hubp_blank(dc, pipe, true); + pipe->vtp_locked = false; + } + } /* WA to apply WM setting*/ if (hwseq->wa.DEGVIDCN21) dc->res_pool->hubbub->funcs->apply_DEDCN21_147_wa(dc->res_pool->hubbub); diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c index de9dcbeea150..51a4166e9750 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c @@ -94,6 +94,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft, #endif .set_disp_pattern_generator = dcn20_set_disp_pattern_generator, + .set_hubp_blank = dcn10_set_hubp_blank, }; static const struct hwseq_private_funcs dcn20_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c index 15c2ff264ff6..fa013496e26b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c @@ -363,7 +363,7 @@ static const struct link_encoder_funcs dcn20_link_enc_funcs = { dcn10_link_encoder_validate_output_with_stream, .hw_init = enc2_hw_init, .setup = dcn10_link_encoder_setup, - .enable_tmds_output = dcn10_link_encoder_enable_tmds_output, + .enable_tmds_output = dcn10_link_encoder_enable_tmds_output_with_clk_pattern_wa, .enable_dp_output = dcn20_link_encoder_enable_dp_output, .enable_dp_mst_output = dcn10_link_encoder_enable_dp_mst_output, .disable_output = dcn10_link_encoder_disable_output, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index d6b488561871..2c2dbfcd8957 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -2097,6 +2097,7 @@ int dcn20_populate_dml_pipes_from_context( pipes[pipe_cnt].pipe.dest.pixel_rate_mhz *= 2; pipes[pipe_cnt].pipe.dest.otg_inst = res_ctx->pipe_ctx[i].stream_res.tg->inst; pipes[pipe_cnt].dout.dp_lanes = 4; + pipes[pipe_cnt].dout.is_virtual = 0; 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; switch (get_num_odm_splits(&res_ctx->pipe_ctx[i])) { @@ -2150,6 +2151,7 @@ int dcn20_populate_dml_pipes_from_context( break; default: /* In case there is no signal, set dp with 4 lanes to allow max config */ + pipes[pipe_cnt].dout.is_virtual = 1; pipes[pipe_cnt].dout.output_type = dm_dp; pipes[pipe_cnt].dout.dp_lanes = 4; } @@ -3245,7 +3247,7 @@ restore_dml_state: bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate) { - bool voltage_supported = false; + bool voltage_supported; DC_FP_START(); voltage_supported = dcn20_validate_bandwidth_fp(dc, context, fast_validate); DC_FP_END(); @@ -3506,7 +3508,8 @@ void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s calculated_states[i].dram_speed_mts = uclk_states[i] * 16 / 1000; // FCLK:UCLK ratio is 1.08 - min_fclk_required_by_uclk = mul_u64_u32_shr(BIT_ULL(32) * 1080 / 1000000, uclk_states[i], 32); + min_fclk_required_by_uclk = div_u64(((unsigned long long)uclk_states[i]) * 1080, + 1000000); calculated_states[i].fabricclk_mhz = (min_fclk_required_by_uclk < min_dcfclk) ? min_dcfclk : min_fclk_required_by_uclk; @@ -3606,7 +3609,6 @@ static enum dml_project get_dml_project_version(uint32_t hw_internal_rev) static bool init_soc_bounding_box(struct dc *dc, struct dcn20_resource_pool *pool) { - const struct gpu_info_soc_bounding_box_v1_0 *bb = dc->soc_bounding_box; struct _vcs_dpi_soc_bounding_box_st *loaded_bb = get_asic_rev_soc_bb(dc->ctx->asic_id.hw_internal_rev); struct _vcs_dpi_ip_params_st *loaded_ip = @@ -3614,116 +3616,6 @@ static bool init_soc_bounding_box(struct dc *dc, DC_LOGGER_INIT(dc->ctx->logger); - /* TODO: upstream NV12 bounding box when its launched */ - if (!bb && ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev)) { - DC_LOG_ERROR("%s: not valid soc bounding box/n", __func__); - return false; - } - - if (bb && ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev)) { - int i; - - dcn2_0_nv12_soc.sr_exit_time_us = - fixed16_to_double_to_cpu(bb->sr_exit_time_us); - dcn2_0_nv12_soc.sr_enter_plus_exit_time_us = - fixed16_to_double_to_cpu(bb->sr_enter_plus_exit_time_us); - dcn2_0_nv12_soc.urgent_latency_us = - fixed16_to_double_to_cpu(bb->urgent_latency_us); - dcn2_0_nv12_soc.urgent_latency_pixel_data_only_us = - fixed16_to_double_to_cpu(bb->urgent_latency_pixel_data_only_us); - dcn2_0_nv12_soc.urgent_latency_pixel_mixed_with_vm_data_us = - fixed16_to_double_to_cpu(bb->urgent_latency_pixel_mixed_with_vm_data_us); - dcn2_0_nv12_soc.urgent_latency_vm_data_only_us = - fixed16_to_double_to_cpu(bb->urgent_latency_vm_data_only_us); - dcn2_0_nv12_soc.urgent_out_of_order_return_per_channel_pixel_only_bytes = - le32_to_cpu(bb->urgent_out_of_order_return_per_channel_pixel_only_bytes); - dcn2_0_nv12_soc.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = - le32_to_cpu(bb->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes); - dcn2_0_nv12_soc.urgent_out_of_order_return_per_channel_vm_only_bytes = - le32_to_cpu(bb->urgent_out_of_order_return_per_channel_vm_only_bytes); - dcn2_0_nv12_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = - fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_pixel_only); - dcn2_0_nv12_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = - fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm); - dcn2_0_nv12_soc.pct_ideal_dram_sdp_bw_after_urgent_vm_only = - fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_vm_only); - dcn2_0_nv12_soc.max_avg_sdp_bw_use_normal_percent = - fixed16_to_double_to_cpu(bb->max_avg_sdp_bw_use_normal_percent); - dcn2_0_nv12_soc.max_avg_dram_bw_use_normal_percent = - fixed16_to_double_to_cpu(bb->max_avg_dram_bw_use_normal_percent); - dcn2_0_nv12_soc.writeback_latency_us = - fixed16_to_double_to_cpu(bb->writeback_latency_us); - dcn2_0_nv12_soc.ideal_dram_bw_after_urgent_percent = - fixed16_to_double_to_cpu(bb->ideal_dram_bw_after_urgent_percent); - dcn2_0_nv12_soc.max_request_size_bytes = - le32_to_cpu(bb->max_request_size_bytes); - dcn2_0_nv12_soc.dram_channel_width_bytes = - le32_to_cpu(bb->dram_channel_width_bytes); - dcn2_0_nv12_soc.fabric_datapath_to_dcn_data_return_bytes = - le32_to_cpu(bb->fabric_datapath_to_dcn_data_return_bytes); - dcn2_0_nv12_soc.dcn_downspread_percent = - fixed16_to_double_to_cpu(bb->dcn_downspread_percent); - dcn2_0_nv12_soc.downspread_percent = - fixed16_to_double_to_cpu(bb->downspread_percent); - dcn2_0_nv12_soc.dram_page_open_time_ns = - fixed16_to_double_to_cpu(bb->dram_page_open_time_ns); - dcn2_0_nv12_soc.dram_rw_turnaround_time_ns = - fixed16_to_double_to_cpu(bb->dram_rw_turnaround_time_ns); - dcn2_0_nv12_soc.dram_return_buffer_per_channel_bytes = - le32_to_cpu(bb->dram_return_buffer_per_channel_bytes); - dcn2_0_nv12_soc.round_trip_ping_latency_dcfclk_cycles = - le32_to_cpu(bb->round_trip_ping_latency_dcfclk_cycles); - dcn2_0_nv12_soc.urgent_out_of_order_return_per_channel_bytes = - le32_to_cpu(bb->urgent_out_of_order_return_per_channel_bytes); - dcn2_0_nv12_soc.channel_interleave_bytes = - le32_to_cpu(bb->channel_interleave_bytes); - dcn2_0_nv12_soc.num_banks = - le32_to_cpu(bb->num_banks); - dcn2_0_nv12_soc.num_chans = - le32_to_cpu(bb->num_chans); - dcn2_0_nv12_soc.vmm_page_size_bytes = - le32_to_cpu(bb->vmm_page_size_bytes); - dcn2_0_nv12_soc.dram_clock_change_latency_us = - fixed16_to_double_to_cpu(bb->dram_clock_change_latency_us); - // HACK!! Lower uclock latency switch time so we don't switch - dcn2_0_nv12_soc.dram_clock_change_latency_us = 10; - dcn2_0_nv12_soc.writeback_dram_clock_change_latency_us = - fixed16_to_double_to_cpu(bb->writeback_dram_clock_change_latency_us); - dcn2_0_nv12_soc.return_bus_width_bytes = - le32_to_cpu(bb->return_bus_width_bytes); - dcn2_0_nv12_soc.dispclk_dppclk_vco_speed_mhz = - le32_to_cpu(bb->dispclk_dppclk_vco_speed_mhz); - dcn2_0_nv12_soc.xfc_bus_transport_time_us = - le32_to_cpu(bb->xfc_bus_transport_time_us); - dcn2_0_nv12_soc.xfc_xbuf_latency_tolerance_us = - le32_to_cpu(bb->xfc_xbuf_latency_tolerance_us); - dcn2_0_nv12_soc.use_urgent_burst_bw = - le32_to_cpu(bb->use_urgent_burst_bw); - dcn2_0_nv12_soc.num_states = - le32_to_cpu(bb->num_states); - - for (i = 0; i < dcn2_0_nv12_soc.num_states; i++) { - dcn2_0_nv12_soc.clock_limits[i].state = - le32_to_cpu(bb->clock_limits[i].state); - dcn2_0_nv12_soc.clock_limits[i].dcfclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].dcfclk_mhz); - dcn2_0_nv12_soc.clock_limits[i].fabricclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].fabricclk_mhz); - dcn2_0_nv12_soc.clock_limits[i].dispclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].dispclk_mhz); - dcn2_0_nv12_soc.clock_limits[i].dppclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].dppclk_mhz); - dcn2_0_nv12_soc.clock_limits[i].phyclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].phyclk_mhz); - dcn2_0_nv12_soc.clock_limits[i].socclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].socclk_mhz); - dcn2_0_nv12_soc.clock_limits[i].dscclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].dscclk_mhz); - dcn2_0_nv12_soc.clock_limits[i].dram_speed_mts = - fixed16_to_double_to_cpu(bb->clock_limits[i].dram_speed_mts); - } - } - if (pool->base.pp_smu) { struct pp_smu_nv_clock_table max_clocks = {0}; unsigned int uclk_states[8] = {0}; diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c index 96ee0b82f458..d3b643089603 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c @@ -123,7 +123,7 @@ void dcn21_optimize_pwr_state( * PHY will hang on the next mode set attempt. * if enable PLL follow by disable PLL (without executing lane enable/disable), * RDPCS_PHY_DP_MPLLB_STATE remains 1, - * which indicate that PLL disable attempt actually didn’t go through. + * which indicate that PLL disable attempt actually didn't go through. * As a workaround, insert PHY lane enable/disable before PLL disable. */ void dcn21_PLAT_58856_wa(struct dc_state *context, struct pipe_ctx *pipe_ctx) @@ -143,6 +143,7 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t optio struct dc_context *dc = abm->ctx; uint32_t ramping_boundary = 0xFFFF; + memset(&cmd, 0, sizeof(cmd)); cmd.abm_set_pipe.header.type = DMUB_CMD__ABM; cmd.abm_set_pipe.header.sub_type = DMUB_CMD__ABM_SET_PIPE; cmd.abm_set_pipe.abm_set_pipe_data.otg_inst = otg_inst; @@ -212,6 +213,7 @@ bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx, if (abm && panel_cntl) dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst); + memset(&cmd, 0, sizeof(cmd)); cmd.abm_set_backlight.header.type = DMUB_CMD__ABM; cmd.abm_set_backlight.header.sub_type = DMUB_CMD__ABM_SET_BACKLIGHT; cmd.abm_set_backlight.abm_set_backlight_data.frame_ramp = frame_ramp; diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c index 074e2713257f..0597391b2171 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c @@ -99,6 +99,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { #endif .is_abm_supported = dcn21_is_abm_supported, .set_disp_pattern_generator = dcn20_set_disp_pattern_generator, + .set_hubp_blank = dcn10_set_hubp_blank, }; static const struct hwseq_private_funcs dcn21_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index 674376428916..072f8c880924 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -1329,8 +1329,8 @@ validate_out: return out; } -bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, - bool fast_validate) +static noinline bool dcn21_validate_bandwidth_fp(struct dc *dc, + struct dc_state *context, bool fast_validate) { bool out = false; @@ -1383,6 +1383,22 @@ validate_out: return out; } + +/* + * Some of the functions further below use the FPU, so we need to wrap this + * with DC_FP_START()/DC_FP_END(). Use the same approach as for + * dcn20_validate_bandwidth in dcn20_resource.c. + */ +bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, + bool fast_validate) +{ + bool voltage_supported; + DC_FP_START(); + voltage_supported = dcn21_validate_bandwidth_fp(dc, context, fast_validate); + DC_FP_END(); + return voltage_supported; +} + static void dcn21_destroy_resource_pool(struct resource_pool **pool) { struct dcn21_resource_pool *dcn21_pool = TO_DCN21_RES_POOL(*pool); diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c index 9da66e491116..33985401f25c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c @@ -133,7 +133,6 @@ static void dpp3_power_on_gamcor_lut( struct dpp *dpp_base, bool power_on) { - uint32_t power_status; struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { @@ -143,12 +142,6 @@ static void dpp3_power_on_gamcor_lut( } else REG_SET(CM_MEM_PWR_CTRL, 0, GAMCOR_MEM_PWR_DIS, power_on == true ? 0:1); - - REG_GET(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, &power_status); - if (power_status != 0) - BREAK_TO_DEBUGGER(); - - } void dpp3_program_cm_dealpha( diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h index 5fa150f34c60..705fbfc37502 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h @@ -62,6 +62,7 @@ HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_NO_OUTSTANDING_REQ, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_VTG_SEL, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_DISABLE, mask_sh),\ + HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_IN_BLANK, mask_sh),\ HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_PIPES, mask_sh),\ HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, PIPE_INTERLEAVE, mask_sh),\ HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, MAX_COMPRESSED_FRAGS, mask_sh),\ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 3deb3fb1724d..9620fb8a27dc 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -710,8 +710,11 @@ void dcn30_program_dmdata_engine(struct pipe_ctx *pipe_ctx) bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) { union dmub_rb_cmd cmd; - unsigned int surface_size, refresh_hz, denom; uint32_t tmr_delay = 0, tmr_scale = 0; + struct dc_cursor_attributes cursor_attr; + bool cursor_cache_enable = false; + struct dc_stream_state *stream = NULL; + struct dc_plane_state *plane = NULL; if (!dc->ctx->dmub_srv) return false; @@ -722,72 +725,150 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) /* First, check no-memory-requests case */ for (i = 0; i < dc->current_state->stream_count; i++) { - if (dc->current_state->stream_status[i] - .plane_count) + if (dc->current_state->stream_status[i].plane_count) /* Fail eligibility on a visible stream */ break; } - if (dc->current_state->stream_count == 1 // single display only - && dc->current_state->stream_status[0].plane_count == 1 // single surface only - && dc->current_state->stream_status[0].plane_states[0]->address.page_table_base.quad_part == 0 // no VM - // Only 8 and 16 bit formats - && dc->current_state->stream_status[0].plane_states[0]->format <= SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F - && dc->current_state->stream_status[0].plane_states[0]->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB8888) { - surface_size = dc->current_state->stream_status[0].plane_states[0]->plane_size.surface_pitch * - dc->current_state->stream_status[0].plane_states[0]->plane_size.surface_size.height * - (dc->current_state->stream_status[0].plane_states[0]->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? - 8 : 4); - } else { - // TODO: remove hard code size - surface_size = 128 * 1024 * 1024; + if (i == dc->current_state->stream_count) { + /* Enable no-memory-requests case */ + memset(&cmd, 0, sizeof(cmd)); + cmd.mall.header.type = DMUB_CMD__MALL; + cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_NO_DF_REQ; + cmd.mall.header.payload_bytes = sizeof(cmd.mall) - sizeof(cmd.mall.header); + + dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd); + dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv); + + return true; + } + + stream = dc->current_state->streams[0]; + plane = (stream ? dc->current_state->stream_status[0].plane_states[0] : NULL); + + if (stream && plane) { + cursor_cache_enable = stream->cursor_position.enable && + plane->address.grph.cursor_cache_addr.quad_part; + cursor_attr = stream->cursor_attributes; } - // TODO: remove hard code size - if (surface_size < 128 * 1024 * 1024) { - refresh_hz = div_u64((unsigned long long) dc->current_state->streams[0]->timing.pix_clk_100hz * - 100LL, - (dc->current_state->streams[0]->timing.v_total * - dc->current_state->streams[0]->timing.h_total)); + /* + * Second, check MALL eligibility + * + * single display only, single surface only, 8 and 16 bit formats only, no VM, + * do not use MALL for displays that support PSR as they use D0i3.2 in DMCUB FW + * + * TODO: When we implement multi-display, PSR displays will be allowed if there is + * a non-PSR display present, since in that case we can't do D0i3.2 + */ + if (dc->current_state->stream_count == 1 && + stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED && + dc->current_state->stream_status[0].plane_count == 1 && + plane->format <= SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F && + plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB8888 && + plane->address.page_table_base.quad_part == 0 && + dc->hwss.does_plane_fit_in_mall && + dc->hwss.does_plane_fit_in_mall(dc, plane, + cursor_cache_enable ? &cursor_attr : NULL)) { + unsigned int v_total = stream->adjust.v_total_max ? + stream->adjust.v_total_max : stream->timing.v_total; + unsigned int refresh_hz = div_u64((unsigned long long) stream->timing.pix_clk_100hz * + 100LL, (v_total * stream->timing.h_total)); /* - * Delay_Us = 65.28 * (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale - * Delay_Us / 65.28 = (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale - * (Delay_Us / 65.28) / 2^MallFrameCacheTmrScale = 64 + MallFrameCacheTmrDly - * MallFrameCacheTmrDly = ((Delay_Us / 65.28) / 2^MallFrameCacheTmrScale) - 64 - * = (1000000 / refresh) / 65.28 / 2^MallFrameCacheTmrScale - 64 - * = 1000000 / (refresh * 65.28 * 2^MallFrameCacheTmrScale) - 64 - * = (1000000 * 100) / (refresh * 6528 * 2^MallFrameCacheTmrScale) - 64 + * one frame time in microsec: + * Delay_Us = 1000000 / refresh + * dynamic_delay_us = 1000000 / refresh + 2 * stutter_period + * + * one frame time modified by 'additional timer percent' (p): + * Delay_Us_modified = dynamic_delay_us + dynamic_delay_us * p / 100 + * = dynamic_delay_us * (1 + p / 100) + * = (1000000 / refresh + 2 * stutter_period) * (100 + p) / 100 + * = (1000000 + 2 * stutter_period * refresh) * (100 + p) / (100 * refresh) + * + * formula for timer duration based on parameters, from regspec: + * dynamic_delay_us = 65.28 * (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale + * + * dynamic_delay_us / 65.28 = (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale + * (dynamic_delay_us / 65.28) / 2^MallFrameCacheTmrScale = 64 + MallFrameCacheTmrDly + * MallFrameCacheTmrDly = ((dynamic_delay_us / 65.28) / 2^MallFrameCacheTmrScale) - 64 + * = (1000000 + 2 * stutter_period * refresh) * (100 + p) / (100 * refresh) / 65.28 / 2^MallFrameCacheTmrScale - 64 + * = (1000000 + 2 * stutter_period * refresh) * (100 + p) / (refresh * 6528 * 2^MallFrameCacheTmrScale) - 64 * * need to round up the result of the division before the subtraction */ - denom = refresh_hz * 6528; - tmr_delay = div_u64((100000000LL + denom - 1), denom) - 64LL; + unsigned int denom = refresh_hz * 6528; + unsigned int stutter_period = dc->current_state->perf_params.stutter_period_us; + + tmr_delay = div_u64(((1000000LL + 2 * stutter_period * refresh_hz) * + (100LL + dc->debug.mall_additional_timer_percent) + denom - 1), + denom) - 64LL; /* scale should be increased until it fits into 6 bits */ while (tmr_delay & ~0x3F) { tmr_scale++; if (tmr_scale > 3) { - /* The delay exceeds the range of the hystersis timer */ + /* Delay exceeds range of hysteresis timer */ ASSERT(false); return false; } denom *= 2; - tmr_delay = div_u64((100000000LL + denom - 1), denom) - 64LL; + tmr_delay = div_u64(((1000000LL + 2 * stutter_period * refresh_hz) * + (100LL + dc->debug.mall_additional_timer_percent) + denom - 1), + denom) - 64LL; + } + + /* Copy HW cursor */ + if (cursor_cache_enable) { + memset(&cmd, 0, sizeof(cmd)); + cmd.mall.header.type = DMUB_CMD__MALL; + cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_COPY_CURSOR; + cmd.mall.header.payload_bytes = + sizeof(cmd.mall) - sizeof(cmd.mall.header); + + switch (cursor_attr.color_format) { + case CURSOR_MODE_MONO: + cmd.mall.cursor_bpp = 2; + break; + case CURSOR_MODE_COLOR_1BIT_AND: + case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA: + case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA: + cmd.mall.cursor_bpp = 32; + break; + + case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED: + case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED: + cmd.mall.cursor_bpp = 64; + break; + } + + cmd.mall.cursor_copy_src.quad_part = cursor_attr.address.quad_part; + cmd.mall.cursor_copy_dst.quad_part = + plane->address.grph.cursor_cache_addr.quad_part; + cmd.mall.cursor_width = cursor_attr.width; + cmd.mall.cursor_height = cursor_attr.height; + cmd.mall.cursor_pitch = cursor_attr.pitch; + + dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd); + dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv); + dc_dmub_srv_wait_idle(dc->ctx->dmub_srv); + + /* Use copied cursor, and it's okay to not switch back */ + cursor_attr.address.quad_part = + plane->address.grph.cursor_cache_addr.quad_part; + dc_stream_set_cursor_attributes(stream, &cursor_attr); } /* Enable MALL */ memset(&cmd, 0, sizeof(cmd)); cmd.mall.header.type = DMUB_CMD__MALL; - cmd.mall.header.sub_type = - DMUB_CMD__MALL_ACTION_ALLOW; - cmd.mall.header.payload_bytes = - sizeof(cmd.mall) - - sizeof(cmd.mall.header); + cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_ALLOW; + cmd.mall.header.payload_bytes = sizeof(cmd.mall) - sizeof(cmd.mall.header); cmd.mall.tmr_delay = tmr_delay; cmd.mall.tmr_scale = tmr_scale; + cmd.mall.debug_bits = dc->debug.mall_error_as_fatal; dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd); dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv); @@ -814,6 +895,40 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) return true; } +bool dcn30_does_plane_fit_in_mall(struct dc *dc, struct dc_plane_state *plane, struct dc_cursor_attributes *cursor_attr) +{ + // add meta size? + unsigned int surface_size = plane->plane_size.surface_pitch * plane->plane_size.surface_size.height * + (plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4); + unsigned int mall_size = dc->caps.mall_size_total; + unsigned int cursor_size = 0; + + if (dc->debug.mall_size_override) + mall_size = 1024 * 1024 * dc->debug.mall_size_override; + + if (cursor_attr) { + cursor_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size; + + switch (cursor_attr->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; + } + } + + return (surface_size + cursor_size) < mall_size; +} + void dcn30_hardware_release(struct dc *dc) { /* if pstate unsupported, force it supported */ @@ -823,6 +938,53 @@ void dcn30_hardware_release(struct dc *dc) dc->res_pool->hubbub, true, true); } +void dcn30_set_hubp_blank(const struct dc *dc, + struct pipe_ctx *pipe_ctx, + bool blank_enable) +{ + struct pipe_ctx *mpcc_pipe; + struct pipe_ctx *odm_pipe; + + if (blank_enable) { + struct plane_resource *plane_res = &pipe_ctx->plane_res; + struct stream_resource *stream_res = &pipe_ctx->stream_res; + + /* Wait for enter vblank */ + stream_res->tg->funcs->wait_for_state(stream_res->tg, CRTC_STATE_VBLANK); + + /* Blank HUBP to allow p-state during blank on all timings */ + pipe_ctx->plane_res.hubp->funcs->set_blank(pipe_ctx->plane_res.hubp, true); + /* Confirm hubp in blank */ + ASSERT(plane_res->hubp->funcs->hubp_in_blank(plane_res->hubp)); + /* Toggle HUBP_DISABLE */ + plane_res->hubp->funcs->hubp_soft_reset(plane_res->hubp, true); + plane_res->hubp->funcs->hubp_soft_reset(plane_res->hubp, false); + for (mpcc_pipe = pipe_ctx->bottom_pipe; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe) { + mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, true); + /* Confirm hubp in blank */ + ASSERT(mpcc_pipe->plane_res.hubp->funcs->hubp_in_blank(mpcc_pipe->plane_res.hubp)); + /* Toggle HUBP_DISABLE */ + mpcc_pipe->plane_res.hubp->funcs->hubp_soft_reset(mpcc_pipe->plane_res.hubp, true); + mpcc_pipe->plane_res.hubp->funcs->hubp_soft_reset(mpcc_pipe->plane_res.hubp, false); + + } + for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { + odm_pipe->plane_res.hubp->funcs->set_blank(odm_pipe->plane_res.hubp, true); + /* Confirm hubp in blank */ + ASSERT(odm_pipe->plane_res.hubp->funcs->hubp_in_blank(odm_pipe->plane_res.hubp)); + /* Toggle HUBP_DISABLE */ + odm_pipe->plane_res.hubp->funcs->hubp_soft_reset(odm_pipe->plane_res.hubp, true); + odm_pipe->plane_res.hubp->funcs->hubp_soft_reset(odm_pipe->plane_res.hubp, false); + } + } else { + pipe_ctx->plane_res.hubp->funcs->set_blank(pipe_ctx->plane_res.hubp, false); + for (mpcc_pipe = pipe_ctx->bottom_pipe; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe) + mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, false); + for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) + odm_pipe->plane_res.hubp->funcs->set_blank(odm_pipe->plane_res.hubp, false); + } +} + void dcn30_set_disp_pattern_generator(const struct dc *dc, struct pipe_ctx *pipe_ctx, enum controller_dp_test_pattern test_pattern, @@ -831,6 +993,25 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc, const struct tg_color *solid_color, int width, int height, int offset) { - pipe_ctx->stream_res.opp->funcs->opp_set_disp_pattern_generator(pipe_ctx->stream_res.opp, test_pattern, - color_space, color_depth, solid_color, width, height, offset); + struct stream_resource *stream_res = &pipe_ctx->stream_res; + + if (test_pattern != CONTROLLER_DP_TEST_PATTERN_VIDEOMODE) { + pipe_ctx->vtp_locked = false; + /* turning on DPG */ + stream_res->opp->funcs->opp_set_disp_pattern_generator(stream_res->opp, test_pattern, color_space, + color_depth, solid_color, width, height, offset); + + /* Defer hubp blank if tg is locked */ + if (stream_res->tg->funcs->is_tg_enabled(stream_res->tg)) { + if (stream_res->tg->funcs->is_locked(stream_res->tg)) + pipe_ctx->vtp_locked = true; + else + dc->hwss.set_hubp_blank(dc, pipe_ctx, true); + } + } else { + dc->hwss.set_hubp_blank(dc, pipe_ctx, false); + /* turning off DPG */ + stream_res->opp->funcs->opp_set_disp_pattern_generator(stream_res->opp, test_pattern, color_space, + color_depth, solid_color, width, height, offset); + } } diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h index 7d32c43aafe0..3b7d4812e311 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h @@ -65,6 +65,9 @@ void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable); void dcn30_update_info_frame(struct pipe_ctx *pipe_ctx); void dcn30_program_dmdata_engine(struct pipe_ctx *pipe_ctx); +bool dcn30_does_plane_fit_in_mall(struct dc *dc, struct dc_plane_state *plane, + struct dc_cursor_attributes *cursor_attr); + bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable); void dcn30_hardware_release(struct dc *dc); @@ -77,4 +80,8 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc, const struct tg_color *solid_color, int width, int height, int offset); +void dcn30_set_hubp_blank(const struct dc *dc, + struct pipe_ctx *pipe_ctx, + bool blank_enable); + #endif /* __DC_HWSS_DCN30_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c index 6125fe440ad0..204444fead97 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c @@ -71,6 +71,7 @@ static const struct hw_sequencer_funcs dcn30_funcs = { .edp_backlight_control = dce110_edp_backlight_control, .edp_power_control = dce110_edp_power_control, .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready, + .edp_wait_for_T12 = dce110_edp_wait_for_T12, .set_cursor_position = dcn10_set_cursor_position, .set_cursor_attribute = dcn10_set_cursor_attribute, .set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level, @@ -91,11 +92,13 @@ static const struct hw_sequencer_funcs dcn30_funcs = { .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, .calc_vupdate_position = dcn10_calc_vupdate_position, .apply_idle_power_optimizations = dcn30_apply_idle_power_optimizations, + .does_plane_fit_in_mall = dcn30_does_plane_fit_in_mall, .set_backlight_level = dcn21_set_backlight_level, .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, .hardware_release = dcn30_hardware_release, .set_pipe = dcn21_set_pipe, .set_disp_pattern_generator = dcn30_set_disp_pattern_generator, + .set_hubp_blank = dcn30_set_hubp_blank, }; static const struct hwseq_private_funcs dcn30_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c index 3ba3991ee612..8980c90b2277 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c @@ -309,6 +309,7 @@ static struct timing_generator_funcs dcn30_tg_funcs = { .enable_crtc_reset = optc1_enable_crtc_reset, .disable_reset_trigger = optc1_disable_reset_trigger, .lock = optc3_lock, + .is_locked = optc1_is_locked, .unlock = optc1_unlock, .lock_doublebuffer_enable = optc3_lock_doublebuffer_enable, .lock_doublebuffer_disable = optc3_lock_doublebuffer_disable, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 5e126fdf6ec1..8d0f663489ac 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -1716,125 +1716,22 @@ static bool is_soc_bounding_box_valid(struct dc *dc) static bool init_soc_bounding_box(struct dc *dc, struct dcn30_resource_pool *pool) { - const struct gpu_info_soc_bounding_box_v1_0 *bb = dc->soc_bounding_box; struct _vcs_dpi_soc_bounding_box_st *loaded_bb = &dcn3_0_soc; struct _vcs_dpi_ip_params_st *loaded_ip = &dcn3_0_ip; DC_LOGGER_INIT(dc->ctx->logger); - if (!bb && !is_soc_bounding_box_valid(dc)) { + if (!is_soc_bounding_box_valid(dc)) { DC_LOG_ERROR("%s: not valid soc bounding box/n", __func__); return false; } - if (bb && !is_soc_bounding_box_valid(dc)) { - int i; - - dcn3_0_soc.sr_exit_time_us = - fixed16_to_double_to_cpu(bb->sr_exit_time_us); - dcn3_0_soc.sr_enter_plus_exit_time_us = - fixed16_to_double_to_cpu(bb->sr_enter_plus_exit_time_us); - dcn3_0_soc.urgent_latency_us = - fixed16_to_double_to_cpu(bb->urgent_latency_us); - dcn3_0_soc.urgent_latency_pixel_data_only_us = - fixed16_to_double_to_cpu(bb->urgent_latency_pixel_data_only_us); - dcn3_0_soc.urgent_latency_pixel_mixed_with_vm_data_us = - fixed16_to_double_to_cpu(bb->urgent_latency_pixel_mixed_with_vm_data_us); - dcn3_0_soc.urgent_latency_vm_data_only_us = - fixed16_to_double_to_cpu(bb->urgent_latency_vm_data_only_us); - dcn3_0_soc.urgent_out_of_order_return_per_channel_pixel_only_bytes = - le32_to_cpu(bb->urgent_out_of_order_return_per_channel_pixel_only_bytes); - dcn3_0_soc.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = - le32_to_cpu(bb->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes); - dcn3_0_soc.urgent_out_of_order_return_per_channel_vm_only_bytes = - le32_to_cpu(bb->urgent_out_of_order_return_per_channel_vm_only_bytes); - dcn3_0_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = - fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_pixel_only); - dcn3_0_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = - fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm); - dcn3_0_soc.pct_ideal_dram_sdp_bw_after_urgent_vm_only = - fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_vm_only); - dcn3_0_soc.max_avg_sdp_bw_use_normal_percent = - fixed16_to_double_to_cpu(bb->max_avg_sdp_bw_use_normal_percent); - dcn3_0_soc.max_avg_dram_bw_use_normal_percent = - fixed16_to_double_to_cpu(bb->max_avg_dram_bw_use_normal_percent); - dcn3_0_soc.writeback_latency_us = - fixed16_to_double_to_cpu(bb->writeback_latency_us); - dcn3_0_soc.ideal_dram_bw_after_urgent_percent = - fixed16_to_double_to_cpu(bb->ideal_dram_bw_after_urgent_percent); - dcn3_0_soc.max_request_size_bytes = - le32_to_cpu(bb->max_request_size_bytes); - dcn3_0_soc.dram_channel_width_bytes = - le32_to_cpu(bb->dram_channel_width_bytes); - dcn3_0_soc.fabric_datapath_to_dcn_data_return_bytes = - le32_to_cpu(bb->fabric_datapath_to_dcn_data_return_bytes); - dcn3_0_soc.dcn_downspread_percent = - fixed16_to_double_to_cpu(bb->dcn_downspread_percent); - dcn3_0_soc.downspread_percent = - fixed16_to_double_to_cpu(bb->downspread_percent); - dcn3_0_soc.dram_page_open_time_ns = - fixed16_to_double_to_cpu(bb->dram_page_open_time_ns); - dcn3_0_soc.dram_rw_turnaround_time_ns = - fixed16_to_double_to_cpu(bb->dram_rw_turnaround_time_ns); - dcn3_0_soc.dram_return_buffer_per_channel_bytes = - le32_to_cpu(bb->dram_return_buffer_per_channel_bytes); - dcn3_0_soc.round_trip_ping_latency_dcfclk_cycles = - le32_to_cpu(bb->round_trip_ping_latency_dcfclk_cycles); - dcn3_0_soc.urgent_out_of_order_return_per_channel_bytes = - le32_to_cpu(bb->urgent_out_of_order_return_per_channel_bytes); - dcn3_0_soc.channel_interleave_bytes = - le32_to_cpu(bb->channel_interleave_bytes); - dcn3_0_soc.num_banks = - le32_to_cpu(bb->num_banks); - dcn3_0_soc.num_chans = - le32_to_cpu(bb->num_chans); - dcn3_0_soc.gpuvm_min_page_size_bytes = - le32_to_cpu(bb->vmm_page_size_bytes); - dcn3_0_soc.dram_clock_change_latency_us = - fixed16_to_double_to_cpu(bb->dram_clock_change_latency_us); - dcn3_0_soc.writeback_dram_clock_change_latency_us = - fixed16_to_double_to_cpu(bb->writeback_dram_clock_change_latency_us); - dcn3_0_soc.return_bus_width_bytes = - le32_to_cpu(bb->return_bus_width_bytes); - dcn3_0_soc.dispclk_dppclk_vco_speed_mhz = - le32_to_cpu(bb->dispclk_dppclk_vco_speed_mhz); - dcn3_0_soc.xfc_bus_transport_time_us = - le32_to_cpu(bb->xfc_bus_transport_time_us); - dcn3_0_soc.xfc_xbuf_latency_tolerance_us = - le32_to_cpu(bb->xfc_xbuf_latency_tolerance_us); - dcn3_0_soc.use_urgent_burst_bw = - le32_to_cpu(bb->use_urgent_burst_bw); - dcn3_0_soc.num_states = - le32_to_cpu(bb->num_states); - - for (i = 0; i < dcn3_0_soc.num_states; i++) { - dcn3_0_soc.clock_limits[i].state = - le32_to_cpu(bb->clock_limits[i].state); - dcn3_0_soc.clock_limits[i].dcfclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].dcfclk_mhz); - dcn3_0_soc.clock_limits[i].fabricclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].fabricclk_mhz); - dcn3_0_soc.clock_limits[i].dispclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].dispclk_mhz); - dcn3_0_soc.clock_limits[i].dppclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].dppclk_mhz); - dcn3_0_soc.clock_limits[i].phyclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].phyclk_mhz); - dcn3_0_soc.clock_limits[i].socclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].socclk_mhz); - dcn3_0_soc.clock_limits[i].dscclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].dscclk_mhz); - dcn3_0_soc.clock_limits[i].dram_speed_mts = - fixed16_to_double_to_cpu(bb->clock_limits[i].dram_speed_mts); - } - } - loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator; loaded_ip->max_num_dpp = pool->base.pipe_count; loaded_ip->clamp_min_dcfclk = dc->config.clamp_min_dcfclk; dcn20_patch_bounding_box(dc, loaded_bb); - if (!bb && dc->ctx->dc_bios->funcs->get_soc_bb_info) { + if (dc->ctx->dc_bios->funcs->get_soc_bb_info) { struct bp_soc_bb_info bb_info = {0}; if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) { @@ -2292,17 +2189,15 @@ static noinline void dcn30_calculate_wm_and_dlg_fp( unsigned int min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed; unsigned int min_dram_speed_mts_margin = 160; - context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->dummy_pstate_table[0].dummy_pstate_latency_us; - if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] == dm_dram_clock_change_unsupported) 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; - 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) && - (min_dram_speed_mts - min_dram_speed_mts_margin < dc->clk_mgr->bw_params->dummy_pstate_table[i].dram_speed_mts)) - context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->dummy_pstate_table[i].dummy_pstate_latency_us; - } + /* 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.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; } @@ -2437,16 +2332,28 @@ validate_out: return out; } -static noinline void get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts, - unsigned int *optimal_dcfclk, - unsigned int *optimal_fclk) +/* + * This must be noinline to ensure anything that deals with FP registers + * is contained within this call; previously our compiling with hard-float + * would result in fp instructions being emitted outside of the boundaries + * of the DC_FP_START/END macros, which makes sense as the compiler has no + * idea about what is wrapped and what is not + * + * This is largely just a workaround to avoid breakage introduced with 5.6, + * ideally all fp-using code should be moved into its own file, only that + * should be compiled with hard-float, and all code exported from there + * should be strictly wrapped with DC_FP_START/END + */ +static noinline void dcn30_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts, + unsigned int *optimal_dcfclk, + unsigned int *optimal_fclk) { double bw_from_dram, bw_from_dram1, bw_from_dram2; bw_from_dram1 = uclk_mts * dcn3_0_soc.num_chans * - dcn3_0_soc.dram_channel_width_bytes * (dcn3_0_soc.max_avg_dram_bw_use_normal_percent / 100); + dcn3_0_soc.dram_channel_width_bytes * (dcn3_0_soc.max_avg_dram_bw_use_normal_percent / 100); bw_from_dram2 = uclk_mts * dcn3_0_soc.num_chans * - dcn3_0_soc.dram_channel_width_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100); + dcn3_0_soc.dram_channel_width_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100); bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2; @@ -2505,7 +2412,7 @@ void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params // Calculate optimal dcfclk for each uclk for (i = 0; i < num_uclk_states; i++) { DC_FP_START(); - get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16, + dcn30_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16, &optimal_dcfclk_for_uclk[i], NULL); DC_FP_END(); if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz) { @@ -2631,6 +2538,10 @@ static bool dcn30_resource_construct( dc->caps.max_cursor_size = 256; dc->caps.min_horizontal_blanking_period = 80; dc->caps.dmdata_alloc_size = 2048; + dc->caps.mall_size_per_mem_channel = 8; + /* total size = mall per channel * num channels * 1024 * 1024 */ + dc->caps.mall_size_total = dc->caps.mall_size_per_mem_channel * dc->ctx->dc_bios->vram_info.num_chans * 1048576; + dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8; dc->caps.max_slave_planes = 1; dc->caps.post_blend_color_processing = true; diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c index bdad72140cbc..b8bf6d61005b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c @@ -98,6 +98,7 @@ static const struct hw_sequencer_funcs dcn301_funcs = { .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, .set_pipe = dcn21_set_pipe, .set_disp_pattern_generator = dcn30_set_disp_pattern_generator, + .set_hubp_blank = dcn30_set_hubp_blank, }; static const struct hwseq_private_funcs dcn301_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c index 35f5bf08ae96..5d4b2c60192e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c @@ -1489,124 +1489,21 @@ static bool is_soc_bounding_box_valid(struct dc *dc) static bool init_soc_bounding_box(struct dc *dc, struct dcn301_resource_pool *pool) { - const struct gpu_info_soc_bounding_box_v1_0 *bb = dc->soc_bounding_box; struct _vcs_dpi_soc_bounding_box_st *loaded_bb = &dcn3_01_soc; struct _vcs_dpi_ip_params_st *loaded_ip = &dcn3_01_ip; DC_LOGGER_INIT(dc->ctx->logger); - if (!bb && !is_soc_bounding_box_valid(dc)) { + if (!is_soc_bounding_box_valid(dc)) { DC_LOG_ERROR("%s: not valid soc bounding box/n", __func__); return false; } - if (bb && !is_soc_bounding_box_valid(dc)) { - int i; - - dcn3_01_soc.sr_exit_time_us = - fixed16_to_double_to_cpu(bb->sr_exit_time_us); - dcn3_01_soc.sr_enter_plus_exit_time_us = - fixed16_to_double_to_cpu(bb->sr_enter_plus_exit_time_us); - dcn3_01_soc.urgent_latency_us = - fixed16_to_double_to_cpu(bb->urgent_latency_us); - dcn3_01_soc.urgent_latency_pixel_data_only_us = - fixed16_to_double_to_cpu(bb->urgent_latency_pixel_data_only_us); - dcn3_01_soc.urgent_latency_pixel_mixed_with_vm_data_us = - fixed16_to_double_to_cpu(bb->urgent_latency_pixel_mixed_with_vm_data_us); - dcn3_01_soc.urgent_latency_vm_data_only_us = - fixed16_to_double_to_cpu(bb->urgent_latency_vm_data_only_us); - dcn3_01_soc.urgent_out_of_order_return_per_channel_pixel_only_bytes = - le32_to_cpu(bb->urgent_out_of_order_return_per_channel_pixel_only_bytes); - dcn3_01_soc.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = - le32_to_cpu(bb->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes); - dcn3_01_soc.urgent_out_of_order_return_per_channel_vm_only_bytes = - le32_to_cpu(bb->urgent_out_of_order_return_per_channel_vm_only_bytes); - dcn3_01_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = - fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_pixel_only); - dcn3_01_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = - fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm); - dcn3_01_soc.pct_ideal_dram_sdp_bw_after_urgent_vm_only = - fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_vm_only); - dcn3_01_soc.max_avg_sdp_bw_use_normal_percent = - fixed16_to_double_to_cpu(bb->max_avg_sdp_bw_use_normal_percent); - dcn3_01_soc.max_avg_dram_bw_use_normal_percent = - fixed16_to_double_to_cpu(bb->max_avg_dram_bw_use_normal_percent); - dcn3_01_soc.writeback_latency_us = - fixed16_to_double_to_cpu(bb->writeback_latency_us); - dcn3_01_soc.ideal_dram_bw_after_urgent_percent = - fixed16_to_double_to_cpu(bb->ideal_dram_bw_after_urgent_percent); - dcn3_01_soc.max_request_size_bytes = - le32_to_cpu(bb->max_request_size_bytes); - dcn3_01_soc.dram_channel_width_bytes = - le32_to_cpu(bb->dram_channel_width_bytes); - dcn3_01_soc.fabric_datapath_to_dcn_data_return_bytes = - le32_to_cpu(bb->fabric_datapath_to_dcn_data_return_bytes); - dcn3_01_soc.dcn_downspread_percent = - fixed16_to_double_to_cpu(bb->dcn_downspread_percent); - dcn3_01_soc.downspread_percent = - fixed16_to_double_to_cpu(bb->downspread_percent); - dcn3_01_soc.dram_page_open_time_ns = - fixed16_to_double_to_cpu(bb->dram_page_open_time_ns); - dcn3_01_soc.dram_rw_turnaround_time_ns = - fixed16_to_double_to_cpu(bb->dram_rw_turnaround_time_ns); - dcn3_01_soc.dram_return_buffer_per_channel_bytes = - le32_to_cpu(bb->dram_return_buffer_per_channel_bytes); - dcn3_01_soc.round_trip_ping_latency_dcfclk_cycles = - le32_to_cpu(bb->round_trip_ping_latency_dcfclk_cycles); - dcn3_01_soc.urgent_out_of_order_return_per_channel_bytes = - le32_to_cpu(bb->urgent_out_of_order_return_per_channel_bytes); - dcn3_01_soc.channel_interleave_bytes = - le32_to_cpu(bb->channel_interleave_bytes); - dcn3_01_soc.num_banks = - le32_to_cpu(bb->num_banks); - dcn3_01_soc.num_chans = - le32_to_cpu(bb->num_chans); - dcn3_01_soc.gpuvm_min_page_size_bytes = - le32_to_cpu(bb->vmm_page_size_bytes); - dcn3_01_soc.dram_clock_change_latency_us = - fixed16_to_double_to_cpu(bb->dram_clock_change_latency_us); - dcn3_01_soc.writeback_dram_clock_change_latency_us = - fixed16_to_double_to_cpu(bb->writeback_dram_clock_change_latency_us); - dcn3_01_soc.return_bus_width_bytes = - le32_to_cpu(bb->return_bus_width_bytes); - dcn3_01_soc.dispclk_dppclk_vco_speed_mhz = - le32_to_cpu(bb->dispclk_dppclk_vco_speed_mhz); - dcn3_01_soc.xfc_bus_transport_time_us = - le32_to_cpu(bb->xfc_bus_transport_time_us); - dcn3_01_soc.xfc_xbuf_latency_tolerance_us = - le32_to_cpu(bb->xfc_xbuf_latency_tolerance_us); - dcn3_01_soc.use_urgent_burst_bw = - le32_to_cpu(bb->use_urgent_burst_bw); - dcn3_01_soc.num_states = - le32_to_cpu(bb->num_states); - - for (i = 0; i < dcn3_01_soc.num_states; i++) { - dcn3_01_soc.clock_limits[i].state = - le32_to_cpu(bb->clock_limits[i].state); - dcn3_01_soc.clock_limits[i].dcfclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].dcfclk_mhz); - dcn3_01_soc.clock_limits[i].fabricclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].fabricclk_mhz); - dcn3_01_soc.clock_limits[i].dispclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].dispclk_mhz); - dcn3_01_soc.clock_limits[i].dppclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].dppclk_mhz); - dcn3_01_soc.clock_limits[i].phyclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].phyclk_mhz); - dcn3_01_soc.clock_limits[i].socclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].socclk_mhz); - dcn3_01_soc.clock_limits[i].dscclk_mhz = - fixed16_to_double_to_cpu(bb->clock_limits[i].dscclk_mhz); - dcn3_01_soc.clock_limits[i].dram_speed_mts = - fixed16_to_double_to_cpu(bb->clock_limits[i].dram_speed_mts); - } - } - loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator; loaded_ip->max_num_dpp = pool->base.pipe_count; dcn20_patch_bounding_box(dc, loaded_bb); - if (!bb && dc->ctx->dc_bios->funcs->get_soc_bb_info) { + if (dc->ctx->dc_bios->funcs->get_soc_bb_info) { struct bp_soc_bb_info bb_info = {0}; if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c index 808c4dcdb3ac..4b659b63f75b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c @@ -53,6 +53,8 @@ #include "dce/dce_i2c_hw.h" #include "dce/dce_panel_cntl.h" #include "dce/dmub_abm.h" +#include "dce/dmub_psr.h" +#include "clk_mgr.h" #include "hw_sequencer_private.h" #include "reg_helper.h" @@ -162,8 +164,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_02_soc = { .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */ .num_states = 1, - .sr_exit_time_us = 5.20, - .sr_enter_plus_exit_time_us = 9.60, + .sr_exit_time_us = 12, + .sr_enter_plus_exit_time_us = 20, .urgent_latency_us = 4.0, .urgent_latency_pixel_data_only_us = 4.0, .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, @@ -190,7 +192,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_02_soc = { .num_banks = 8, .gpuvm_min_page_size_bytes = 4096, .hostvm_min_page_size_bytes = 4096, - .dram_clock_change_latency_us = 350, + .dram_clock_change_latency_us = 404, .dummy_pstate_latency_us = 5, .writeback_dram_clock_change_latency_us = 23.0, .return_bus_width_bytes = 64, @@ -238,6 +240,7 @@ static const struct dc_debug_options debug_defaults_diags = { .dwb_fi_phase = -1, // -1 = disable .dmub_command_table = true, .enable_tri_buf = true, + .disable_psr = true, }; enum dcn302_clk_src_array_id { @@ -1213,6 +1216,9 @@ static void dcn302_resource_destruct(struct resource_pool *pool) dce_abm_destroy(&pool->multiple_abms[i]); } + if (pool->psr != NULL) + dmub_psr_destroy(&pool->psr); + if (pool->dccg != NULL) dcn_dccg_destroy(&pool->dccg); } @@ -1224,6 +1230,165 @@ static void dcn302_destroy_resource_pool(struct resource_pool **pool) *pool = NULL; } +static void dcn302_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts, + unsigned int *optimal_dcfclk, + unsigned int *optimal_fclk) +{ + double bw_from_dram, bw_from_dram1, bw_from_dram2; + + bw_from_dram1 = uclk_mts * dcn3_02_soc.num_chans * + dcn3_02_soc.dram_channel_width_bytes * (dcn3_02_soc.max_avg_dram_bw_use_normal_percent / 100); + bw_from_dram2 = uclk_mts * dcn3_02_soc.num_chans * + dcn3_02_soc.dram_channel_width_bytes * (dcn3_02_soc.max_avg_sdp_bw_use_normal_percent / 100); + + bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2; + + if (optimal_fclk) + *optimal_fclk = bw_from_dram / + (dcn3_02_soc.fabric_datapath_to_dcn_data_return_bytes * (dcn3_02_soc.max_avg_sdp_bw_use_normal_percent / 100)); + + if (optimal_dcfclk) + *optimal_dcfclk = bw_from_dram / + (dcn3_02_soc.return_bus_width_bytes * (dcn3_02_soc.max_avg_sdp_bw_use_normal_percent / 100)); +} + +void dcn302_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) +{ + unsigned int i, j; + unsigned int num_states = 0; + + unsigned int dcfclk_mhz[DC__VOLTAGE_STATES] = {0}; + unsigned int dram_speed_mts[DC__VOLTAGE_STATES] = {0}; + unsigned int optimal_uclk_for_dcfclk_sta_targets[DC__VOLTAGE_STATES] = {0}; + unsigned int optimal_dcfclk_for_uclk[DC__VOLTAGE_STATES] = {0}; + + unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {694, 875, 1000, 1200}; + unsigned int num_dcfclk_sta_targets = 4; + unsigned int num_uclk_states; + + + if (dc->ctx->dc_bios->vram_info.num_chans) + dcn3_02_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans; + + if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes) + dcn3_02_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes; + + dcn3_02_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; + + if (bw_params->clk_table.entries[0].memclk_mhz) { + int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0; + + for (i = 0; i < MAX_NUM_DPM_LVL; i++) { + if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz) + max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz; + if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz) + max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz; + if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz) + max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz; + if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz) + max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz; + } + if (!max_dcfclk_mhz) + max_dcfclk_mhz = dcn3_02_soc.clock_limits[0].dcfclk_mhz; + if (!max_dispclk_mhz) + max_dispclk_mhz = dcn3_02_soc.clock_limits[0].dispclk_mhz; + if (!max_dppclk_mhz) + max_dppclk_mhz = dcn3_02_soc.clock_limits[0].dppclk_mhz; + if (!max_phyclk_mhz) + max_phyclk_mhz = dcn3_02_soc.clock_limits[0].phyclk_mhz; + + if (max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) { + /* If max DCFCLK is greater than the max DCFCLK STA target, insert into the DCFCLK STA target array */ + dcfclk_sta_targets[num_dcfclk_sta_targets] = max_dcfclk_mhz; + num_dcfclk_sta_targets++; + } else if (max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) { + /* If max DCFCLK is less than the max DCFCLK STA target, cap values and remove duplicates */ + for (i = 0; i < num_dcfclk_sta_targets; i++) { + if (dcfclk_sta_targets[i] > max_dcfclk_mhz) { + dcfclk_sta_targets[i] = max_dcfclk_mhz; + break; + } + } + /* Update size of array since we "removed" duplicates */ + num_dcfclk_sta_targets = i + 1; + } + + num_uclk_states = bw_params->clk_table.num_entries; + + /* Calculate optimal dcfclk for each uclk */ + for (i = 0; i < num_uclk_states; i++) { + dcn302_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16, + &optimal_dcfclk_for_uclk[i], NULL); + if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz) { + optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz; + } + } + + /* Calculate optimal uclk for each dcfclk sta target */ + for (i = 0; i < num_dcfclk_sta_targets; i++) { + for (j = 0; j < num_uclk_states; j++) { + if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) { + optimal_uclk_for_dcfclk_sta_targets[i] = + bw_params->clk_table.entries[j].memclk_mhz * 16; + break; + } + } + } + + i = 0; + j = 0; + /* create the final dcfclk and uclk table */ + while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) { + if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) { + dcfclk_mhz[num_states] = dcfclk_sta_targets[i]; + dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++]; + } else { + if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) { + dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j]; + dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; + } else { + j = num_uclk_states; + } + } + } + + while (i < num_dcfclk_sta_targets && num_states < DC__VOLTAGE_STATES) { + dcfclk_mhz[num_states] = dcfclk_sta_targets[i]; + dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++]; + } + + while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES && + optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) { + dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j]; + dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; + } + + dcn3_02_soc.num_states = num_states; + for (i = 0; i < dcn3_02_soc.num_states; i++) { + dcn3_02_soc.clock_limits[i].state = i; + dcn3_02_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i]; + dcn3_02_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i]; + dcn3_02_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i]; + + /* Fill all states with max values of all other clocks */ + dcn3_02_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz; + dcn3_02_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz; + dcn3_02_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz; + dcn3_02_soc.clock_limits[i].dtbclk_mhz = dcn3_02_soc.clock_limits[0].dtbclk_mhz; + /* These clocks cannot come from bw_params, always fill from dcn3_02_soc[1] */ + /* FCLK, PHYCLK_D18, SOCCLK, DSCCLK */ + dcn3_02_soc.clock_limits[i].phyclk_d18_mhz = dcn3_02_soc.clock_limits[0].phyclk_d18_mhz; + dcn3_02_soc.clock_limits[i].socclk_mhz = dcn3_02_soc.clock_limits[0].socclk_mhz; + dcn3_02_soc.clock_limits[i].dscclk_mhz = dcn3_02_soc.clock_limits[0].dscclk_mhz; + } + /* re-init DML with updated bb */ + dml_init_instance(&dc->dml, &dcn3_02_soc, &dcn3_02_ip, DML_PROJECT_DCN30); + if (dc->current_state) + dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_02_soc, &dcn3_02_ip, DML_PROJECT_DCN30); + } +} + static struct resource_funcs dcn302_res_pool_funcs = { .destroy = dcn302_destroy_resource_pool, .link_enc_create = dcn302_link_encoder_create, @@ -1240,7 +1405,7 @@ static struct resource_funcs dcn302_res_pool_funcs = { .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link, .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut, .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut, - .update_bw_bounding_box = dcn30_update_bw_bounding_box, + .update_bw_bounding_box = dcn302_update_bw_bounding_box, .patch_unknown_plane_state = dcn20_patch_unknown_plane_state, }; @@ -1311,7 +1476,10 @@ static bool dcn302_resource_construct( dc->caps.max_cursor_size = 256; dc->caps.min_horizontal_blanking_period = 80; dc->caps.dmdata_alloc_size = 2048; - + dc->caps.mall_size_per_mem_channel = 4; + /* total size = mall per channel * num channels * 1024 * 1024 */ + dc->caps.mall_size_total = dc->caps.mall_size_per_mem_channel * dc->ctx->dc_bios->vram_info.num_chans * 1048576; + dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8; dc->caps.max_slave_planes = 1; dc->caps.post_blend_color_processing = true; dc->caps.force_dp_tps4_for_cp2520 = true; @@ -1354,8 +1522,6 @@ static bool dcn302_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; @@ -1469,6 +1635,14 @@ static bool dcn302_resource_construct( } pool->timing_generator_count = i; + /* PSR */ + pool->psr = dmub_psr_create(ctx); + if (pool->psr == NULL) { + dm_error("DC: failed to create psr!\n"); + BREAK_TO_DEBUGGER(); + goto create_fail; + } + /* ABMs */ for (i = 0; i < pool->res_cap->num_timing_generator; i++) { pool->multiple_abms[i] = dmub_abm_create(ctx, &abm_regs[i], &abm_shift, &abm_mask); diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.h b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.h index 71f7deed18e3..42d2c73e30bc 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.h @@ -30,4 +30,6 @@ struct resource_pool *dcn302_create_resource_pool(const struct dc_init_data *init_data, struct dc *dc); +void dcn302_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params); + #endif /* _DCN302_RESOURCE_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h b/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h index 5da7677627a1..cac0b2c0d31b 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h +++ b/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h @@ -30,9 +30,10 @@ struct dc_link; struct cp_psp_stream_config { uint8_t otg_inst; - uint8_t link_enc_inst; - uint8_t stream_enc_inst; - uint8_t mst_supported; + uint8_t dig_be; + uint8_t dig_fe; + uint8_t assr_enabled; + uint8_t mst_enabled; void *dm_stream_ctx; bool dpms_off; }; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c index 45f028986a8d..0f3f510fd83b 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c @@ -3138,7 +3138,7 @@ static void CalculateFlipSchedule( 4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125), 1) / 4.0; - if ((GPUVMEnable == true || DCCEnable == true)) { + if ((GPUVMEnable || DCCEnable)) { mode_lib->vba.ImmediateFlipBW[0] = BandwidthAvailableForImmediateFlip * ImmediateFlipBytes / TotImmediateFlipBytes; TimeForFetchingRowInVBlankImmediateFlip = dml_max( @@ -4168,10 +4168,11 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { locals->DIOSupport[i] = true; for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { - if (locals->OutputBppPerState[i][k] == BPP_INVALID - || (mode_lib->vba.OutputFormat[k] == dm_420 + if (!mode_lib->vba.skip_dio_check[k] + && (locals->OutputBppPerState[i][k] == BPP_INVALID + || (mode_lib->vba.OutputFormat[k] == dm_420 && mode_lib->vba.Interlace[k] == true - && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true)) { + && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true))) { locals->DIOSupport[i] = false; } } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c index 80170f9721ce..210c96cd5b03 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c @@ -3263,6 +3263,7 @@ static void CalculateFlipSchedule( static unsigned int TruncToValidBPP( double DecimalBPP, + double DesiredBPP, bool DSCEnabled, enum output_encoder_class Output, enum output_format_class Format, @@ -3270,31 +3271,31 @@ static unsigned int TruncToValidBPP( { if (Output == dm_hdmi) { if (Format == dm_420) { - if (DecimalBPP >= 18) + if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18)) return 18; - else if (DecimalBPP >= 15) + else if (DecimalBPP >= 15 && (DesiredBPP == 0 || DesiredBPP == 15)) return 15; - else if (DecimalBPP >= 12) + else if (DecimalBPP >= 12 && (DesiredBPP == 0 || DesiredBPP == 12)) return 12; else return BPP_INVALID; } else if (Format == dm_444) { - if (DecimalBPP >= 36) + if (DecimalBPP >= 36 && (DesiredBPP == 0 || DesiredBPP == 36)) return 36; - else if (DecimalBPP >= 30) + else if (DecimalBPP >= 30 && (DesiredBPP == 0 || DesiredBPP == 30)) return 30; - else if (DecimalBPP >= 24) + else if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24)) return 24; - else if (DecimalBPP >= 18) + else if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18)) return 18; else return BPP_INVALID; } else { - if (DecimalBPP / 1.5 >= 24) + if (DecimalBPP / 1.5 >= 24 && (DesiredBPP == 0 || DesiredBPP == 24)) return 24; - else if (DecimalBPP / 1.5 >= 20) + else if (DecimalBPP / 1.5 >= 20 && (DesiredBPP == 0 || DesiredBPP == 20)) return 20; - else if (DecimalBPP / 1.5 >= 16) + else if (DecimalBPP / 1.5 >= 16 && (DesiredBPP == 0 || DesiredBPP == 16)) return 16; else return BPP_INVALID; @@ -3302,53 +3303,86 @@ static unsigned int TruncToValidBPP( } else { if (DSCEnabled) { if (Format == dm_420) { - if (DecimalBPP < 6) - return BPP_INVALID; - else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1 / 16) - return 1.5 * DSCInputBitPerComponent - 1 / 16; - else - return dml_floor(16 * DecimalBPP, 1) / 16; + if (DesiredBPP == 0) { + if (DecimalBPP < 6) + return BPP_INVALID; + else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1.0 / 16.0) + return 1.5 * DSCInputBitPerComponent - 1.0 / 16.0; + else + return dml_floor(16 * DecimalBPP, 1) / 16.0; + } else { + if (DecimalBPP < 6 + || DesiredBPP < 6 + || DesiredBPP > 1.5 * DSCInputBitPerComponent - 1.0 / 16.0 + || DecimalBPP < DesiredBPP) { + return BPP_INVALID; + } else { + return DesiredBPP; + } + } } else if (Format == dm_n422) { - if (DecimalBPP < 7) - return BPP_INVALID; - else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1 / 16) - return 2 * DSCInputBitPerComponent - 1 / 16; - else - return dml_floor(16 * DecimalBPP, 1) / 16; + if (DesiredBPP == 0) { + if (DecimalBPP < 7) + return BPP_INVALID; + else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1.0 / 16.0) + return 2 * DSCInputBitPerComponent - 1.0 / 16.0; + else + return dml_floor(16 * DecimalBPP, 1) / 16.0; + } else { + if (DecimalBPP < 7 + || DesiredBPP < 7 + || DesiredBPP > 2 * DSCInputBitPerComponent - 1.0 / 16.0 + || DecimalBPP < DesiredBPP) { + return BPP_INVALID; + } else { + return DesiredBPP; + } + } } else { - if (DecimalBPP < 8) - return BPP_INVALID; - else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1 / 16) - return 3 * DSCInputBitPerComponent - 1 / 16; - else - return dml_floor(16 * DecimalBPP, 1) / 16; + if (DesiredBPP == 0) { + if (DecimalBPP < 8) + return BPP_INVALID; + else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1.0 / 16.0) + return 3 * DSCInputBitPerComponent - 1.0 / 16.0; + else + return dml_floor(16 * DecimalBPP, 1) / 16.0; + } else { + if (DecimalBPP < 8 + || DesiredBPP < 8 + || DesiredBPP > 3 * DSCInputBitPerComponent - 1.0 / 16.0 + || DecimalBPP < DesiredBPP) { + return BPP_INVALID; + } else { + return DesiredBPP; + } + } } } else if (Format == dm_420) { - if (DecimalBPP >= 18) + if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18)) return 18; - else if (DecimalBPP >= 15) + else if (DecimalBPP >= 15 && (DesiredBPP == 0 || DesiredBPP == 15)) return 15; - else if (DecimalBPP >= 12) + else if (DecimalBPP >= 12 && (DesiredBPP == 0 || DesiredBPP == 12)) return 12; else return BPP_INVALID; } else if (Format == dm_s422 || Format == dm_n422) { - if (DecimalBPP >= 24) + if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24)) return 24; - else if (DecimalBPP >= 20) + else if (DecimalBPP >= 20 && (DesiredBPP == 0 || DesiredBPP == 20)) return 20; - else if (DecimalBPP >= 16) + else if (DecimalBPP >= 16 && (DesiredBPP == 0 || DesiredBPP == 16)) return 16; else return BPP_INVALID; } else { - if (DecimalBPP >= 36) + if (DecimalBPP >= 36 && (DesiredBPP == 0 || DesiredBPP == 36)) return 36; - else if (DecimalBPP >= 30) + else if (DecimalBPP >= 30 && (DesiredBPP == 0 || DesiredBPP == 30)) return 30; - else if (DecimalBPP >= 24) + else if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24)) return 24; - else if (DecimalBPP >= 18) + else if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18)) return 18; else return BPP_INVALID; @@ -4137,6 +4171,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode locals->RequiresFEC[i][k] = 0; locals->OutputBppPerState[i][k] = TruncToValidBPP( dml_min(600.0, mode_lib->vba.PHYCLKPerState[i]) / mode_lib->vba.PixelClockBackEnd[k] * 24, + mode_lib->vba.ForcedOutputLinkBPP[k], false, mode_lib->vba.Output[k], mode_lib->vba.OutputFormat[k], @@ -4153,6 +4188,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode mode_lib->vba.Outbpp = TruncToValidBPP( (1.0 - mode_lib->vba.Downspreading / 100.0) * 270.0 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0, + mode_lib->vba.ForcedOutputLinkBPP[k], false, mode_lib->vba.Output[k], mode_lib->vba.OutputFormat[k], @@ -4160,6 +4196,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode mode_lib->vba.OutbppDSC = TruncToValidBPP( (1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 270.0 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0, + mode_lib->vba.ForcedOutputLinkBPP[k], true, mode_lib->vba.Output[k], mode_lib->vba.OutputFormat[k], @@ -4182,6 +4219,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode mode_lib->vba.Outbpp = TruncToValidBPP( (1.0 - mode_lib->vba.Downspreading / 100.0) * 540.0 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0, + mode_lib->vba.ForcedOutputLinkBPP[k], false, mode_lib->vba.Output[k], mode_lib->vba.OutputFormat[k], @@ -4189,6 +4227,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode mode_lib->vba.OutbppDSC = TruncToValidBPP( (1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 540.0 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0, + mode_lib->vba.ForcedOutputLinkBPP[k], true, mode_lib->vba.Output[k], mode_lib->vba.OutputFormat[k], @@ -4213,6 +4252,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode mode_lib->vba.Outbpp = TruncToValidBPP( (1.0 - mode_lib->vba.Downspreading / 100.0) * 810.0 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0, + mode_lib->vba.ForcedOutputLinkBPP[k], false, mode_lib->vba.Output[k], mode_lib->vba.OutputFormat[k], @@ -4220,6 +4260,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode mode_lib->vba.OutbppDSC = TruncToValidBPP( (1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 810.0 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0, + mode_lib->vba.ForcedOutputLinkBPP[k], true, mode_lib->vba.Output[k], mode_lib->vba.OutputFormat[k], @@ -4248,10 +4289,11 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { locals->DIOSupport[i] = true; for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { - if (locals->OutputBppPerState[i][k] == BPP_INVALID - || (mode_lib->vba.OutputFormat[k] == dm_420 + if (!mode_lib->vba.skip_dio_check[k] + && (locals->OutputBppPerState[i][k] == BPP_INVALID + || (mode_lib->vba.OutputFormat[k] == dm_420 && mode_lib->vba.Interlace[k] == true - && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true)) { + && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true))) { locals->DIOSupport[i] = false; } } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c index 86ff24dffc3e..398210d1af34 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c @@ -4257,10 +4257,11 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { locals->DIOSupport[i] = true; for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { - if (locals->OutputBppPerState[i][k] == BPP_INVALID - || (mode_lib->vba.OutputFormat[k] == dm_420 + if (!mode_lib->vba.skip_dio_check[k] + && (locals->OutputBppPerState[i][k] == BPP_INVALID + || (mode_lib->vba.OutputFormat[k] == dm_420 && mode_lib->vba.Interlace[k] == true - && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true)) { + && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true))) { locals->DIOSupport[i] = false; } } @@ -5121,48 +5122,48 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l for (j = 0; j < 2; j++) { enum dm_validation_status status = DML_VALIDATION_OK; - if (mode_lib->vba.ScaleRatioAndTapsSupport != true) { + if (!mode_lib->vba.ScaleRatioAndTapsSupport) { status = DML_FAIL_SCALE_RATIO_TAP; - } else if (mode_lib->vba.SourceFormatPixelAndScanSupport != true) { + } else if (!mode_lib->vba.SourceFormatPixelAndScanSupport) { status = DML_FAIL_SOURCE_PIXEL_FORMAT; - } else if (locals->ViewportSizeSupport[i][0] != true) { + } else if (!locals->ViewportSizeSupport[i][0]) { status = DML_FAIL_VIEWPORT_SIZE; - } else if (locals->DIOSupport[i] != true) { + } else if (!locals->DIOSupport[i]) { status = DML_FAIL_DIO_SUPPORT; - } else if (locals->NotEnoughDSCUnits[i] != false) { + } else if (locals->NotEnoughDSCUnits[i]) { status = DML_FAIL_NOT_ENOUGH_DSC; - } else if (locals->DSCCLKRequiredMoreThanSupported[i] != false) { + } else if (locals->DSCCLKRequiredMoreThanSupported[i]) { status = DML_FAIL_DSC_CLK_REQUIRED; - } else if (locals->ROBSupport[i][0] != true) { + } else if (!locals->ROBSupport[i][0]) { status = DML_FAIL_REORDERING_BUFFER; - } else if (locals->DISPCLK_DPPCLK_Support[i][j] != true) { + } else if (!locals->DISPCLK_DPPCLK_Support[i][j]) { status = DML_FAIL_DISPCLK_DPPCLK; - } else if (locals->TotalAvailablePipesSupport[i][j] != true) { + } else if (!locals->TotalAvailablePipesSupport[i][j]) { status = DML_FAIL_TOTAL_AVAILABLE_PIPES; - } else if (mode_lib->vba.NumberOfOTGSupport != true) { + } else if (!mode_lib->vba.NumberOfOTGSupport) { status = DML_FAIL_NUM_OTG; - } else if (mode_lib->vba.WritebackModeSupport != true) { + } else if (!mode_lib->vba.WritebackModeSupport) { status = DML_FAIL_WRITEBACK_MODE; - } else if (mode_lib->vba.WritebackLatencySupport != true) { + } else if (!mode_lib->vba.WritebackLatencySupport) { status = DML_FAIL_WRITEBACK_LATENCY; - } else if (mode_lib->vba.WritebackScaleRatioAndTapsSupport != true) { + } else if (!mode_lib->vba.WritebackScaleRatioAndTapsSupport) { status = DML_FAIL_WRITEBACK_SCALE_RATIO_TAP; - } else if (mode_lib->vba.CursorSupport != true) { + } else if (!mode_lib->vba.CursorSupport) { status = DML_FAIL_CURSOR_SUPPORT; - } else if (mode_lib->vba.PitchSupport != true) { + } else if (!mode_lib->vba.PitchSupport) { status = DML_FAIL_PITCH_SUPPORT; - } else if (locals->TotalVerticalActiveBandwidthSupport[i][0] != true) { + } else if (!locals->TotalVerticalActiveBandwidthSupport[i][0]) { status = DML_FAIL_TOTAL_V_ACTIVE_BW; - } else if (locals->PTEBufferSizeNotExceeded[i][j] != true) { + } else if (!locals->PTEBufferSizeNotExceeded[i][j]) { status = DML_FAIL_PTE_BUFFER_SIZE; - } else if (mode_lib->vba.NonsupportedDSCInputBPC != false) { + } else if (mode_lib->vba.NonsupportedDSCInputBPC) { status = DML_FAIL_DSC_INPUT_BPC; - } else if ((mode_lib->vba.HostVMEnable != false - && locals->ImmediateFlipSupportedForState[i][j] != true)) { + } else if ((mode_lib->vba.HostVMEnable + && !locals->ImmediateFlipSupportedForState[i][j])) { status = DML_FAIL_HOST_VM_IMMEDIATE_FLIP; - } else if (locals->PrefetchSupported[i][j] != true) { + } else if (!locals->PrefetchSupported[i][j]) { status = DML_FAIL_PREFETCH_SUPPORT; - } else if (locals->VRatioInPrefetchSupported[i][j] != true) { + } else if (!locals->VRatioInPrefetchSupported[i][j]) { status = DML_FAIL_V_RATIO_PREFETCH; } 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 319dec59bcd1..bc07082c1357 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 @@ -1219,13 +1219,13 @@ static bool CalculatePrefetchSchedule( dml_print("DML: prefetch_bw_equ: %f\n", prefetch_bw_equ); if (prefetch_bw_equ > 0) { - if (GPUVMEnable == true) { + if (GPUVMEnable) { Tvm_equ = dml_max3(*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / prefetch_bw_equ, Tvm_trips, LineTime / 4); } else { Tvm_equ = LineTime / 4; } - if ((GPUVMEnable == true || myPipe->DCCEnable == true)) { + if ((GPUVMEnable || myPipe->DCCEnable)) { Tr0_equ = dml_max4( (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / prefetch_bw_equ, Tr0_trips, @@ -4263,7 +4263,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l for (i = 0; i < v->soc.num_states; i++) { v->DIOSupport[i] = true; for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) { - if (v->BlendingAndTiming[k] == k && (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_hdmi) + if (!v->skip_dio_check[k] && v->BlendingAndTiming[k] == k && (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_hdmi) && (v->OutputBppPerState[i][k] == 0 || (v->OutputFormat[k] == dm_420 && v->Interlace[k] == true && v->ProgressiveToInterlaceUnitInOPP == true))) { v->DIOSupport[i] = false; @@ -5558,7 +5558,7 @@ static void CalculateWatermarksAndDRAMSpeedChangeSupport( } } - if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0 && PrefetchMode == 0) { + if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) { *DRAMClockChangeSupport = dm_dram_clock_change_vactive; } else if (((mode_lib->vba.SynchronizedVBlank == true || mode_lib->vba.TotalNumberOfActiveOTG == 1 || SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank > 0) && PrefetchMode == 0)) { *DRAMClockChangeSupport = dm_dram_clock_change_vblank; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c index 5b5916b5bc71..0f14f205ebe5 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c @@ -165,8 +165,8 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, unsigned int swath_bytes_c = 0; unsigned int full_swath_bytes_packed_l = 0; unsigned int full_swath_bytes_packed_c = 0; - bool req128_l = 0; - bool req128_c = 0; + bool req128_l = false; + bool req128_c = false; bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); bool surf_vert = (pipe_src_param.source_scan == dm_vert); unsigned int log2_swath_height_l = 0; @@ -191,37 +191,37 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, total_swath_bytes = 2 * full_swath_bytes_packed_l; if (total_swath_bytes <= detile_buf_size_in_bytes) { //full 256b request - req128_l = 0; - req128_c = 0; + req128_l = false; + req128_c = false; swath_bytes_l = full_swath_bytes_packed_l; swath_bytes_c = full_swath_bytes_packed_c; } else if (!rq_param->yuv420) { - req128_l = 1; - req128_c = 0; + req128_l = true; + req128_c = false; swath_bytes_c = full_swath_bytes_packed_c; swath_bytes_l = full_swath_bytes_packed_l / 2; } else if ((double)full_swath_bytes_packed_l / (double)full_swath_bytes_packed_c < 1.5) { - req128_l = 0; - req128_c = 1; + req128_l = false; + req128_c = true; swath_bytes_l = full_swath_bytes_packed_l; swath_bytes_c = full_swath_bytes_packed_c / 2; total_swath_bytes = 2 * swath_bytes_l + 2 * swath_bytes_c; if (total_swath_bytes > detile_buf_size_in_bytes) { - req128_l = 1; + req128_l = true; swath_bytes_l = full_swath_bytes_packed_l / 2; } } else { - req128_l = 1; - req128_c = 0; + req128_l = true; + req128_c = false; swath_bytes_l = full_swath_bytes_packed_l/2; swath_bytes_c = full_swath_bytes_packed_c; total_swath_bytes = 2 * swath_bytes_l + 2 * swath_bytes_c; if (total_swath_bytes > detile_buf_size_in_bytes) { - req128_c = 1; + req128_c = true; swath_bytes_c = full_swath_bytes_packed_c/2; } } @@ -1006,8 +1006,8 @@ static void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, double min_dst_y_ttu_vblank = 0; unsigned int dlg_vblank_start = 0; - bool dual_plane = 0; - bool mode_422 = 0; + bool dual_plane = false; + bool mode_422 = false; unsigned int access_dir = 0; unsigned int vp_height_l = 0; unsigned int vp_width_l = 0; @@ -1021,7 +1021,7 @@ static void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, double hratio_c = 0; double vratio_l = 0; double vratio_c = 0; - bool scl_enable = 0; + bool scl_enable = false; double line_time_in_us = 0; // double vinit_l; @@ -1156,7 +1156,7 @@ static void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, // Source // dcc_en = src.dcc; dual_plane = is_dual_plane((enum source_format_class)(src->source_format)); - mode_422 = 0; // TODO + mode_422 = false; // TODO access_dir = (src->source_scan == dm_vert); // vp access direction: horizontal or vertical accessed vp_height_l = src->viewport_height; vp_width_l = src->viewport_width; 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 dd0c3b1780d7..0c5128187e08 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 @@ -297,6 +297,7 @@ struct _vcs_dpi_display_output_params_st { int num_active_wb; int output_bpc; int output_type; + int is_virtual; int output_format; int dsc_slices; int max_audio_sample_rate; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index c9fbb33f05a3..bc0485a59018 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -451,6 +451,8 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) dout->output_bpp; mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] = (enum output_encoder_class) (dout->output_type); + mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] = + dout->is_virtual; if (!dout->dsc_enable) mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp; 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 3529fedc4c52..025aa5bd8ea0 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 @@ -340,6 +340,7 @@ struct vba_vars_st { unsigned int DSCInputBitPerComponent[DC__NUM_DPP__MAX]; enum output_format_class OutputFormat[DC__NUM_DPP__MAX]; enum output_encoder_class Output[DC__NUM_DPP__MAX]; + bool skip_dio_check[DC__NUM_DPP__MAX]; unsigned int BlendingAndTiming[DC__NUM_DPP__MAX]; bool SynchronizedVBlank; unsigned int NumberOfCursors[DC__NUM_DPP__MAX]; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c b/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c index df68430aeb0c..c6e28f6bf1a2 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c @@ -28,6 +28,7 @@ */ #include "dm_services.h" +#include "hw_factory_diag.h" #include "include/gpio_types.h" #include "../hw_factory.h" diff --git a/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.h b/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.h index 8a74f6adb8ee..bf68eb1d9a1d 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.h +++ b/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.h @@ -26,6 +26,8 @@ #ifndef __DAL_HW_FACTORY_DIAG_FPGA_H__ #define __DAL_HW_FACTORY_DIAG_FPGA_H__ +struct hw_factory; + /* Initialize HW factory function pointers and pin info */ void dal_hw_factory_diag_fpga_init(struct hw_factory *factory); diff --git a/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_translate_diag.c b/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_translate_diag.c index bf9068846927..e5138a5a8eb5 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_translate_diag.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_translate_diag.c @@ -24,6 +24,7 @@ */ #include "dm_services.h" +#include "hw_translate_diag.h" #include "include/gpio_types.h" #include "../hw_translate.h" diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c index 1ae153eab31d..7a8cec2d7a90 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c @@ -107,13 +107,12 @@ static enum gpio_result set_config( msleep(3); } } else { - uint32_t reg2; uint32_t sda_pd_dis = 0; uint32_t scl_pd_dis = 0; - reg2 = REG_GET_2(gpio.MASK_reg, - DC_GPIO_SDA_PD_DIS, &sda_pd_dis, - DC_GPIO_SCL_PD_DIS, &scl_pd_dis); + REG_GET_2(gpio.MASK_reg, + DC_GPIO_SDA_PD_DIS, &sda_pd_dis, + DC_GPIO_SCL_PD_DIS, &scl_pd_dis); if (sda_pd_dis) { REG_SET(gpio.MASK_reg, regval, diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c index da73bfb3cacd..92c65d2fa7d7 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c @@ -119,17 +119,3 @@ bool dal_hw_factory_init( return false; } } - -void dal_hw_factory_destroy( - struct dc_context *ctx, - struct hw_factory **factory) -{ - if (!factory || !*factory) { - BREAK_TO_DEBUGGER(); - return; - } - - kfree(*factory); - - *factory = NULL; -} 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 2d77eac66cb0..8efa1b80546d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -333,6 +333,7 @@ struct pipe_ctx { union pipe_update_flags update_flags; struct dwbc *dwbc; struct mcif_wb *mcif_wb; + bool vtp_locked; }; struct resource_context { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h index ffd37696b6b9..316301fc1e30 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h @@ -309,9 +309,9 @@ static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_cl static inline bool should_update_pstate_support(bool safe_to_lower, bool calc_support, bool cur_support) { if (cur_support != calc_support) { - if (calc_support == true && safe_to_lower) + if (calc_support && safe_to_lower) return true; - else if (calc_support == false && !safe_to_lower) + else if (!calc_support && !safe_to_lower) return true; } diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h index 69d9fbfb4bec..cd1c0dc32bf8 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h @@ -74,6 +74,16 @@ struct dmcu_funcs { bool (*is_dmcu_initialized)(struct dmcu *dmcu); bool (*lock_phy)(struct dmcu *dmcu); bool (*unlock_phy)(struct dmcu *dmcu); + bool (*send_edid_cea)(struct dmcu *dmcu, + int offset, + int total_length, + uint8_t *data, + int length); + bool (*recv_amd_vsdb)(struct dmcu *dmcu, + int *version, + int *min_frame_rate, + int *max_frame_rate); + bool (*recv_edid_cea_ack)(struct dmcu *dmcu, int *offset); }; #endif 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 f7632fe25976..754832d216fd 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 @@ -190,6 +190,7 @@ struct timing_generator_funcs { void (*set_blank)(struct timing_generator *tg, bool enable_blanking); bool (*is_blanked)(struct timing_generator *tg); + bool (*is_locked)(struct timing_generator *tg); void (*set_overscan_blank_color) (struct timing_generator *tg, const struct tg_color *color); void (*set_blank_color)(struct timing_generator *tg, const struct tg_color *color); void (*set_colors)(struct timing_generator *tg, 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 62804dc7b698..0586ab2ffd6a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -54,6 +54,7 @@ struct hw_sequencer_funcs { /* Embedded Display Related */ void (*edp_power_control)(struct dc_link *link, bool enable); void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up); + void (*edp_wait_for_T12)(struct dc_link *link); /* Pipe Programming Related */ void (*init_hw)(struct dc *dc); @@ -217,6 +218,9 @@ struct hw_sequencer_funcs { /* Idle Optimization Related */ bool (*apply_idle_power_optimizations)(struct dc *dc, bool enable); + bool (*does_plane_fit_in_mall)(struct dc *dc, struct dc_plane_state *plane, + struct dc_cursor_attributes *cursor_attr); + bool (*is_abm_supported)(struct dc *dc, struct dc_state *context, struct dc_stream_state *stream); @@ -227,6 +231,10 @@ struct hw_sequencer_funcs { enum dc_color_depth color_depth, const struct tg_color *solid_color, int width, int height, int offset); + + void (*set_hubp_blank)(const struct dc *dc, + struct pipe_ctx *pipe_ctx, + bool blank_enable); }; void color_space_to_black_color( diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c index f956b3bde680..34f43cb650f8 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c @@ -58,6 +58,18 @@ enum dc_irq_source to_dal_irq_source_dcn10( return DC_IRQ_SOURCE_VBLANK5; case DCN_1_0__SRCID__DC_D6_OTG_VSTARTUP: return DC_IRQ_SOURCE_VBLANK6; + case DCN_1_0__SRCID__OTG1_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC1_VLINE0; + case DCN_1_0__SRCID__OTG2_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC2_VLINE0; + case DCN_1_0__SRCID__OTG3_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC3_VLINE0; + case DCN_1_0__SRCID__OTG4_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC4_VLINE0; + case DCN_1_0__SRCID__OTG5_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC5_VLINE0; + case DCN_1_0__SRCID__OTG6_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC6_VLINE0; case DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT: return DC_IRQ_SOURCE_VUPDATE1; case DCN_1_0__SRCID__OTG1_IHC_V_UPDATE_NO_LOCK_INTERRUPT: @@ -167,6 +179,11 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .ack = NULL }; +static const struct irq_source_info_funcs vline0_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { .set = NULL, .ack = NULL @@ -241,6 +258,14 @@ static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { .funcs = &vblank_irq_info_funcs\ } +#define vline0_int_entry(reg_num)\ + [DC_IRQ_SOURCE_DC1_VLINE0 + reg_num] = {\ + IRQ_REG_ENTRY(OTG, reg_num,\ + OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE,\ + OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_CLEAR),\ + .funcs = &vline0_irq_info_funcs\ + } + #define dummy_irq_entry() \ {\ .funcs = &dummy_irq_info_funcs\ @@ -349,6 +374,12 @@ irq_source_info_dcn10[DAL_IRQ_SOURCES_NUMBER] = { vblank_int_entry(3), vblank_int_entry(4), vblank_int_entry(5), + vline0_int_entry(0), + vline0_int_entry(1), + vline0_int_entry(2), + vline0_int_entry(3), + vline0_int_entry(4), + vline0_int_entry(5), }; static const struct irq_service_funcs irq_service_funcs_dcn10 = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c index 6bf27bde8724..5f245bde54ff 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c +++ b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c @@ -79,7 +79,7 @@ void dal_irq_service_destroy(struct irq_service **irq_service) *irq_service = NULL; } -const struct irq_source_info *find_irq_source_info( +static const struct irq_source_info *find_irq_source_info( struct irq_service *irq_service, enum dc_irq_source source) { diff --git a/drivers/gpu/drm/amd/display/dc/irq_types.h b/drivers/gpu/drm/amd/display/dc/irq_types.h index d0ccd81ad5b4..87812d81fed3 100644 --- a/drivers/gpu/drm/amd/display/dc/irq_types.h +++ b/drivers/gpu/drm/amd/display/dc/irq_types.h @@ -160,6 +160,7 @@ enum irq_type IRQ_TYPE_PFLIP = DC_IRQ_SOURCE_PFLIP1, IRQ_TYPE_VUPDATE = DC_IRQ_SOURCE_VUPDATE1, IRQ_TYPE_VBLANK = DC_IRQ_SOURCE_VBLANK1, + IRQ_TYPE_VLINE0 = DC_IRQ_SOURCE_DC1_VLINE0, }; #define DAL_VALID_IRQ_SRC_NUM(src) \ |