650 lines · c
1/*2 * Copyright 2015 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 */24 25#ifndef DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_26#define DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_27 28#include "core_types.h"29#include "core_status.h"30#include "dal_asic_id.h"31#include "dm_pp_smu.h"32#include "spl/dc_spl.h"33 34#define MEMORY_TYPE_MULTIPLIER_CZ 435#define MEMORY_TYPE_HBM 236 37 38#define IS_PIPE_SYNCD_VALID(pipe) ((((pipe)->pipe_idx_syncd) & 0x80)?1:0)39#define GET_PIPE_SYNCD_FROM_PIPE(pipe) ((pipe)->pipe_idx_syncd & 0x7F)40#define SET_PIPE_SYNCD_TO_PIPE(pipe, pipe_syncd) ((pipe)->pipe_idx_syncd = (0x80 | pipe_syncd))41 42enum dce_version resource_parse_asic_id(43 struct hw_asic_id asic_id);44 45struct resource_caps {46 int num_timing_generator;47 int num_opp;48 int num_video_plane;49 int num_audio;50 int num_stream_encoder;51 int num_pll;52 int num_dwb;53 int num_ddc;54 int num_vmid;55 int num_dsc;56 unsigned int num_dig_link_enc; // Total number of DIGs (digital encoders) in DIO (Display Input/Output).57 unsigned int num_usb4_dpia; // Total number of USB4 DPIA (DisplayPort Input Adapters).58 int num_hpo_dp_stream_encoder;59 int num_hpo_dp_link_encoder;60 int num_mpc_3dlut;61};62 63struct resource_straps {64 uint32_t hdmi_disable;65 uint32_t dc_pinstraps_audio;66 uint32_t audio_stream_number;67};68 69struct resource_create_funcs {70 void (*read_dce_straps)(71 struct dc_context *ctx, struct resource_straps *straps);72 73 struct audio *(*create_audio)(74 struct dc_context *ctx, unsigned int inst);75 76 struct stream_encoder *(*create_stream_encoder)(77 enum engine_id eng_id, struct dc_context *ctx);78 79 struct hpo_dp_stream_encoder *(*create_hpo_dp_stream_encoder)(80 enum engine_id eng_id, struct dc_context *ctx);81 struct hpo_dp_link_encoder *(*create_hpo_dp_link_encoder)(82 uint8_t inst,83 struct dc_context *ctx);84 struct dce_hwseq *(*create_hwseq)(85 struct dc_context *ctx);86};87 88bool resource_construct(89 unsigned int num_virtual_links,90 struct dc *dc,91 struct resource_pool *pool,92 const struct resource_create_funcs *create_funcs);93 94struct resource_pool *dc_create_resource_pool(struct dc *dc,95 const struct dc_init_data *init_data,96 enum dce_version dc_version);97 98void dc_destroy_resource_pool(struct dc *dc);99 100enum dc_status resource_map_pool_resources(101 const struct dc *dc,102 struct dc_state *context,103 struct dc_stream_state *stream);104 105void resource_build_test_pattern_params(106 struct resource_context *res_ctx,107 struct pipe_ctx *pipe_ctx);108 109bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx);110 111enum dc_status resource_build_scaling_params_for_context(112 const struct dc *dc,113 struct dc_state *context);114 115void resource_build_info_frame(struct pipe_ctx *pipe_ctx);116 117void resource_unreference_clock_source(118 struct resource_context *res_ctx,119 const struct resource_pool *pool,120 struct clock_source *clock_source);121 122void resource_reference_clock_source(123 struct resource_context *res_ctx,124 const struct resource_pool *pool,125 struct clock_source *clock_source);126 127int resource_get_clock_source_reference(128 struct resource_context *res_ctx,129 const struct resource_pool *pool,130 struct clock_source *clock_source);131 132bool resource_are_streams_timing_synchronizable(133 struct dc_stream_state *stream1,134 struct dc_stream_state *stream2);135 136bool resource_are_vblanks_synchronizable(137 struct dc_stream_state *stream1,138 struct dc_stream_state *stream2);139 140struct clock_source *resource_find_used_clk_src_for_sharing(141 struct resource_context *res_ctx,142 struct pipe_ctx *pipe_ctx);143 144struct clock_source *dc_resource_find_first_free_pll(145 struct resource_context *res_ctx,146 const struct resource_pool *pool);147 148bool resource_attach_surfaces_to_context(149 struct dc_plane_state *const *plane_state,150 int surface_count,151 struct dc_stream_state *dc_stream,152 struct dc_state *context,153 const struct resource_pool *pool);154 155#define FREE_PIPE_INDEX_NOT_FOUND -1156 157/*158 * pipe types are identified based on MUXes in DCN front end that are capable159 * of taking input from one DCN pipeline to another DCN pipeline. The name is160 * in a form of XXXX_YYYY, where XXXX is the DCN front end hardware block the161 * pipeline ends with and YYYY is the rendering role that the pipe is in.162 *163 * For instance OTG_MASTER is a pipe ending with OTG hardware block in its164 * pipeline and it is in a role of a master pipe for timing generation.165 *166 * For quick reference a diagram of each pipe type's areas of responsibility167 * for outputting timings on the screen is shown below:168 *169 * Timing Active for Stream 0170 * __________________________________________________171 * |OTG master 0 (OPP head 0)|OPP head 2 (DPP pipe 2) |172 * | (DPP pipe 0)| |173 * | Top Plane 0 | |174 * | ______________|____ |175 * | |DPP pipe 1 |DPP | |176 * | | |pipe| |177 * | | Bottom |3 | |178 * | | Plane 1 | | |179 * | | | | |180 * | |______________|____| |181 * | | |182 * | | |183 * | ODM slice 0 | ODM slice 1 |184 * |_________________________|________________________|185 *186 * Timing Active for Stream 1187 * __________________________________________________188 * |OTG master 4 (OPP head 4) |189 * | |190 * | |191 * | |192 * | |193 * | |194 * | Blank Pixel Data |195 * | (generated by DPG4) |196 * | |197 * | |198 * | |199 * | |200 * | |201 * |__________________________________________________|202 *203 * Inter-pipe Relation204 * __________________________________________________205 * |PIPE IDX| DPP PIPES | OPP HEADS | OTG MASTER |206 * | | plane 0 | slice 0 | |207 * | 0 | -------------MPC---------ODM----------- |208 * | | plane 1 | | | | |209 * | 1 | ------------- | | | |210 * | | plane 0 | slice 1 | | |211 * | 2 | -------------MPC--------- | |212 * | | plane 1 | | | |213 * | 3 | ------------- | | |214 * | | | blank | |215 * | 4 | | ----------------------- |216 * | | | | |217 * | 5 | (FREE) | | |218 * |________|_______________|___________|_____________|219 *220 * The following is a quick reference of the class relation:221 *222 * DC state ---1--------0..N--- streams223 *224 * stream ---1-----------1--- OTG Master pipe225 *226 * OTG Master pipe ---1--------1..N--- OPP Head pipes227 *228 * OPP Head pipe ---1--------0..N--- DPP pipes229 *230 * stream ---1--------0..N--- Planes231 *232 * Plane ---1--------1..N--- DPP pipes233 *234 */235enum pipe_type {236 /* free pipe - free pipe is an uninitialized pipe without a stream237 * associated with it. It is a free DCN pipe resource. It can be238 * acquired as any type of pipe.239 */240 FREE_PIPE,241 242 /* OTG master pipe - the master pipe of its OPP head pipes with a243 * functional OTG. It merges all its OPP head pipes pixel data in ODM244 * block and output to back end DIG. OTG master pipe is responsible for245 * generating entire CRTC timing to back end DIG. An OTG master pipe may246 * or may not have a plane. If it has a plane it blends it as the left247 * most MPC slice of the top most layer. If it doesn't have a plane it248 * can output pixel data from its OPP head pipes' test pattern249 * generators (DPG) such as solid black pixel data to blank the screen.250 */251 OTG_MASTER,252 253 /* OPP head pipe - the head pipe of an MPC blending tree with a254 * functional OPP outputting to an OTG. OPP head pipe is responsible for255 * processing output pixels in its own ODM slice. It may or may not have256 * a plane. If it has a plane it blends it as the top most layer within257 * its own ODM slice. If it doesn't have a plane it can output pixel258 * data from its DPG such as solid black pixel data to blank the pixel259 * data in its own ODM slice. OTG master pipe is also an OPP head pipe260 * but with more responsibility.261 */262 OPP_HEAD,263 264 /* DPP pipe - the pipe with a functional DPP outputting to an OPP head265 * pipe's MPC. DPP pipe is responsible for processing pixel data from266 * its own MPC slice of a plane. It must be connected to an OPP head267 * pipe and it must have a plane associated with it.268 */269 DPP_PIPE,270};271 272/*273 * Determine if the input pipe_ctx is of a pipe type.274 * return - true if pipe_ctx is of the input type.275 */276bool resource_is_pipe_type(const struct pipe_ctx *pipe_ctx, enum pipe_type type);277 278/*279 * Acquire a pipe as OTG master pipe and allocate pipe resources required to280 * enable stream output.281 */282enum dc_status resource_add_otg_master_for_stream_output(struct dc_state *new_ctx,283 const struct resource_pool *pool,284 struct dc_stream_state *stream);285 286/*287 * Release pipe resources and the OTG master pipe associated with the stream288 * The stream must have all planes removed and ODM/MPC slice counts are reset289 * to 1 before invoking this interface.290 */291void resource_remove_otg_master_for_stream_output(struct dc_state *new_ctx,292 const struct resource_pool *pool,293 struct dc_stream_state *stream);294 295/*296 * Add plane to the bottom most layer in plane composition and allocate DPP pipe297 * resources as needed.298 * return - true if plane is added in plane composition, false otherwise.299 */300bool resource_append_dpp_pipes_for_plane_composition(301 struct dc_state *new_ctx,302 struct dc_state *cur_ctx,303 struct resource_pool *pool,304 struct pipe_ctx *otg_master_pipe,305 struct dc_plane_state *plane_state);306 307/*308 * Add plane to the bottom most layer in plane composition and allocate DPP pipe309 * resources as needed.310 * return - true if plane is added in plane composition, false otherwise.311 */312void resource_remove_dpp_pipes_for_plane_composition(313 struct dc_state *context,314 const struct resource_pool *pool,315 const struct dc_plane_state *plane_state);316 317/*318 * Update ODM slice count by acquiring or releasing pipes. If new slices need319 * to be added, it is going to add them to the last ODM index. If existing320 * slices need to be removed, it is going to remove them from the last ODM321 * index.322 *323 * return - true if ODM slices are updated and required pipes are acquired. All324 * affected pipe parameters are updated.325 *326 * false if resource fails to complete this update. The function is not designed327 * to recover the creation of invalid topologies. Returning false is typically328 * an indication of insufficient validation in caller's stack. new_ctx will be329 * invalid. Caller may attempt to restore new_ctx by calling this function330 * again with original slice count.331 */332bool resource_update_pipes_for_stream_with_slice_count(333 struct dc_state *new_ctx,334 const struct dc_state *cur_ctx,335 const struct resource_pool *pool,336 const struct dc_stream_state *stream,337 int new_slice_count);338 339/*340 * Update MPC slice count by acquiring or releasing DPP pipes. If new slices341 * need to be added it is going to add to the last MPC index. If existing342 * slices need to be removed, it is going to remove them from the last MPC343 * index.344 *345 * @dpp_pipe - top most dpp pipe for MPCC combine.346 *347 * return - true if MPC slices are updated and required pipes are acquired. All348 * affected pipe parameters are updated.349 *350 * false if resource fails to complete this update. The function is not designed351 * to recover the creation of invalid topologies. Returning false is typically352 * an indication of insufficient validation in caller's stack. new_ctx will be353 * invalid. Caller may attempt to restore new_ctx by calling this function354 * again with original slice count.355 */356bool resource_update_pipes_for_plane_with_slice_count(357 struct dc_state *new_ctx,358 const struct dc_state *cur_ctx,359 const struct resource_pool *pool,360 const struct dc_plane_state *plane,361 int slice_count);362 363/*364 * Get the OTG master pipe in resource context associated with the stream.365 * return - NULL if not found. Otherwise the OTG master pipe associated with the366 * stream.367 */368struct pipe_ctx *resource_get_otg_master_for_stream(369 struct resource_context *res_ctx,370 const struct dc_stream_state *stream);371 372/*373 * Get an array of OPP heads in opp_heads ordered with index low to high for OTG374 * master pipe in res_ctx.375 * return - number of OPP heads in the array. If otg_master passed in is not376 * an OTG master, the function returns 0.377 */378int resource_get_opp_heads_for_otg_master(const struct pipe_ctx *otg_master,379 struct resource_context *res_ctx,380 struct pipe_ctx *opp_heads[MAX_PIPES]);381 382/*383 * Get an array of DPP pipes in dpp_pipes ordered with index low to high for OPP384 * head pipe in res_ctx.385 * return - number of DPP pipes in the array. If opp_head passed in is not386 * an OPP pipe, the function returns 0.387 */388int resource_get_dpp_pipes_for_opp_head(const struct pipe_ctx *opp_head,389 struct resource_context *res_ctx,390 struct pipe_ctx *dpp_pipes[MAX_PIPES]);391 392/*393 * Get an array of DPP pipes in dpp_pipes ordered with index low to high for394 * plane in res_ctx.395 * return - number of DPP pipes in the array.396 */397int resource_get_dpp_pipes_for_plane(const struct dc_plane_state *plane,398 struct resource_context *res_ctx,399 struct pipe_ctx *dpp_pipes[MAX_PIPES]);400 401/*402 * Get the OTG master pipe for the input pipe context.403 * return - the OTG master pipe for the input pipe404 * context.405 */406struct pipe_ctx *resource_get_otg_master(const struct pipe_ctx *pipe_ctx);407 408/*409 * Get the OPP head pipe for the input pipe context.410 * return - the OPP head pipe for the input pipe411 * context.412 */413struct pipe_ctx *resource_get_opp_head(const struct pipe_ctx *pipe_ctx);414 415/*416 * Get the DPP pipe allocated for MPC slice 0 and ODM slice 0 of the plane417 * associated with dpp_pipe.418 */419struct pipe_ctx *resource_get_primary_dpp_pipe(const struct pipe_ctx *dpp_pipe);420 421/*422 * Get the MPC slice index counting from 0 from left most slice423 * For example, if a DPP pipe is used as a secondary pipe in MPCC combine, MPC424 * split index is greater than 0.425 */426int resource_get_mpc_slice_index(const struct pipe_ctx *dpp_pipe);427 428/*429 * Get the number of MPC slices associated with the pipe.430 * The function returns 0 if the pipe is not associated with an MPC combine431 * pipe topology.432 */433int resource_get_mpc_slice_count(const struct pipe_ctx *pipe);434 435/*436 * Get the number of ODM slices associated with the pipe.437 * The function returns 0 if the pipe is not associated with an ODM combine438 * pipe topology.439 */440int resource_get_odm_slice_count(const struct pipe_ctx *pipe);441 442/* Get the ODM slice index counting from 0 from left most slice */443int resource_get_odm_slice_index(const struct pipe_ctx *opp_head);444 445/* Get ODM slice source rect in timing active as input to OPP block */446struct rect resource_get_odm_slice_src_rect(struct pipe_ctx *pipe_ctx);447 448/* Get ODM slice destination rect in timing active as output from OPP block */449struct rect resource_get_odm_slice_dst_rect(struct pipe_ctx *pipe_ctx);450 451/* Get ODM slice destination width in timing active as output from OPP block */452int resource_get_odm_slice_dst_width(struct pipe_ctx *otg_master,453 bool is_last_segment);454 455/* determine if pipe topology is changed between state a and state b */456bool resource_is_pipe_topology_changed(const struct dc_state *state_a,457 const struct dc_state *state_b);458 459/*460 * determine if the two OTG master pipes have the same ODM topology461 * return462 * false - if pipes passed in are not OTG masters or ODM topology is463 * changed.464 * true - otherwise465 */466bool resource_is_odm_topology_changed(const struct pipe_ctx *otg_master_a,467 const struct pipe_ctx *otg_master_b);468 469/* log the pipe topology update in state */470void resource_log_pipe_topology_update(struct dc *dc, struct dc_state *state);471 472/*473 * Look for a free pipe in new resource context that is used as a secondary OPP474 * head by cur_otg_master.475 *476 * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise477 * pipe idx of the free pipe478 */479int resource_find_free_pipe_used_as_sec_opp_head_by_cur_otg_master(480 const struct resource_context *cur_res_ctx,481 struct resource_context *new_res_ctx,482 const struct pipe_ctx *cur_otg_master);483 484/*485 * Look for a free pipe in new resource context that is used as a secondary DPP486 * pipe in MPC blending tree associated with input OPP head pipe.487 *488 * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise489 * pipe idx of the free pipe490 */491int resource_find_free_pipe_used_in_cur_mpc_blending_tree(492 const struct resource_context *cur_res_ctx,493 struct resource_context *new_res_ctx,494 const struct pipe_ctx *cur_opp_head);495 496/*497 * Look for a free pipe in new resource context that is not used in current498 * resource context.499 *500 * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise501 * pipe idx of the free pipe502 */503int recource_find_free_pipe_not_used_in_cur_res_ctx(504 const struct resource_context *cur_res_ctx,505 struct resource_context *new_res_ctx,506 const struct resource_pool *pool);507 508/*509 * Look for a free pipe in new resource context that is used in current resource510 * context as an OTG master pipe.511 *512 * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise513 * pipe idx of the free pipe514 */515int recource_find_free_pipe_used_as_otg_master_in_cur_res_ctx(516 const struct resource_context *cur_res_ctx,517 struct resource_context *new_res_ctx,518 const struct resource_pool *pool);519 520/*521 * Look for a free pipe in new resource context that is used as a secondary DPP522 * pipe in current resource context.523 * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise524 * pipe idx of the free pipe525 */526int resource_find_free_pipe_used_as_cur_sec_dpp(527 const struct resource_context *cur_res_ctx,528 struct resource_context *new_res_ctx,529 const struct resource_pool *pool);530 531/*532 * Look for a free pipe in new resource context that is used as a secondary DPP533 * pipe in any MPCC combine in current resource context.534 * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise535 * pipe idx of the free pipe536 */537int resource_find_free_pipe_used_as_cur_sec_dpp_in_mpcc_combine(538 const struct resource_context *cur_res_ctx,539 struct resource_context *new_res_ctx,540 const struct resource_pool *pool);541 542/*543 * Look for any free pipe in new resource context.544 * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise545 * pipe idx of the free pipe546 */547int resource_find_any_free_pipe(struct resource_context *new_res_ctx,548 const struct resource_pool *pool);549 550/*551 * Legacy find free secondary pipe logic deprecated for newer DCNs as it doesn't552 * find the most optimal free pipe to prevent from time consuming hardware state553 * transitions.554 */555struct pipe_ctx *resource_find_free_secondary_pipe_legacy(556 struct resource_context *res_ctx,557 const struct resource_pool *pool,558 const struct pipe_ctx *primary_pipe);559 560bool resource_validate_attach_surfaces(561 const struct dc_validation_set set[],562 int set_count,563 const struct dc_state *old_context,564 struct dc_state *context,565 const struct resource_pool *pool);566 567enum dc_status resource_map_clock_resources(568 const struct dc *dc,569 struct dc_state *context,570 struct dc_stream_state *stream);571 572enum dc_status resource_map_phy_clock_resources(573 const struct dc *dc,574 struct dc_state *context,575 struct dc_stream_state *stream);576 577bool pipe_need_reprogram(578 struct pipe_ctx *pipe_ctx_old,579 struct pipe_ctx *pipe_ctx);580 581void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,582 struct bit_depth_reduction_params *fmt_bit_depth);583 584void update_audio_usage(585 struct resource_context *res_ctx,586 const struct resource_pool *pool,587 struct audio *audio,588 bool acquired);589 590unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format);591 592bool get_temp_dp_link_res(struct dc_link *link,593 struct link_resource *link_res,594 struct dc_link_settings *link_settings);595 596void reset_syncd_pipes_from_disabled_pipes(struct dc *dc,597 struct dc_state *context);598 599void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc,600 struct dc_state *context,601 uint8_t disabled_master_pipe_idx);602 603void reset_sync_context_for_pipe(const struct dc *dc,604 struct dc_state *context,605 uint8_t pipe_idx);606 607uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter transmitter);608 609const struct link_hwss *get_link_hwss(const struct dc_link *link,610 const struct link_resource *link_res);611 612bool is_h_timing_divisible_by_2(struct dc_stream_state *stream);613 614bool dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy(615 const struct dc *dc,616 struct dc_state *state,617 struct pipe_ctx *pri_pipe,618 struct pipe_ctx *sec_pipe,619 bool odm);620 621/* A test harness interface that modifies dp encoder resources in the given dc622 * state and bypasses the need to revalidate. The interface assumes that the623 * test harness interface is called with pre-validated link config stored in the624 * pipe_ctx and updates dp encoder resources according to the link config.625 */626enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,627 struct dc_state *context,628 struct pipe_ctx *pipe_ctx);629 630bool check_subvp_sw_cursor_fallback_req(const struct dc *dc, struct dc_stream_state *stream);631 632/* Get hw programming parameters container from pipe context633 * @pipe_ctx: pipe context634 * @dscl_prog_data: struct to hold programmable hw reg values635 */636struct dscl_prog_data *resource_get_dscl_prog_data(struct pipe_ctx *pipe_ctx);637/* Setup dc callbacks for dml2638 * @dc: the display core structure639 * @dml2_options: struct to hold callbacks640 */641void resource_init_common_dml2_callbacks(struct dc *dc, struct dml2_configuration_options *dml2_options);642 643/*644 *Calculate total DET allocated for all pipes for a given OTG_MASTER pipe645 */646int resource_calculate_det_for_stream(struct dc_state *state, struct pipe_ctx *otg_master);647 648bool resource_is_hpo_acquired(struct dc_state *context);649#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */650