diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/inc')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/core_types.h | 57 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/hw/abm.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/link.h | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/resource.h | 231 |
8 files changed, 290 insertions, 42 deletions
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 034610b74a37..027aec70c070 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -125,39 +125,15 @@ struct resource_funcs { struct dc *dc, struct dc_state *context); - /* - * Acquires a free pipe for the head pipe. - * The head pipe is first pipe in the current context that matches the stream - * and does not have a top pipe or prev_odm_pipe. - */ - struct pipe_ctx *(*acquire_idle_pipe_for_layer)( - struct dc_state *context, - const struct resource_pool *pool, - struct dc_stream_state *stream); - - /* - * Acquires a free pipe for the head pipe with some additional checks for odm. - * The head pipe is passed in as an argument unlike acquire_idle_pipe_for_layer - * where it is read from the context. So this allows us look for different - * idle_pipe if the head_pipes are different ( ex. in odm 2:1 when we have - * a left and right pipe ). - * - * It also checks the old context to see if: - * - * 1. a pipe has already been allocated for the head pipe. If so, it will - * try to select that pipe as the idle pipe if it is available in the current - * context. - * 2. if the head_pipe is on the left, it will check if the right pipe has - * a pipe already allocated. If so, it will not use that pipe if it is - * selected as the idle pipe. - */ - struct pipe_ctx *(*acquire_idle_pipe_for_head_pipe_in_layer)( - struct dc_state *context, + struct pipe_ctx *(*acquire_free_pipe_as_secondary_dpp_pipe)( + const struct dc_state *cur_ctx, + struct dc_state *new_ctx, const struct resource_pool *pool, - struct dc_stream_state *stream, - struct pipe_ctx *head_pipe); + const struct pipe_ctx *opp_head_pipe); - enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state, struct dc_caps *caps); + enum dc_status (*validate_plane)( + const struct dc_plane_state *plane_state, + struct dc_caps *caps); enum dc_status (*add_stream_to_ctx)( struct dc *dc, @@ -304,6 +280,8 @@ struct resource_pool { struct dmcu *dmcu; struct dmub_psr *psr; + struct dmub_replay *replay; + struct abm *multiple_abms[MAX_PIPES]; const struct resource_funcs *funcs; @@ -572,6 +550,23 @@ struct dc_state { } perf_params; }; +struct replay_context { + /* ddc line */ + enum channel_id aux_inst; + /* Transmitter id */ + enum transmitter digbe_inst; + /* Engine Id is used for Dig Be source select */ + enum engine_id digfe_inst; + /* Controller Id used for Dig Fe source select */ + enum controller_id controllerId; + unsigned int line_time_in_ns; +}; + +enum dc_replay_enable { + DC_REPLAY_DISABLE = 0, + DC_REPLAY_ENABLE = 1, +}; + struct dc_bounding_box_max_clk { int max_dcfclk_mhz; int max_dispclk_mhz; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h index d2190a3320f6..33db15d69f23 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h @@ -27,6 +27,8 @@ #include "dm_services_types.h" +struct abm_save_restore; + struct abm { struct dc_context *ctx; const struct abm_funcs *funcs; @@ -55,6 +57,10 @@ struct abm_funcs { unsigned int bytes, unsigned int inst); bool (*set_abm_pause)(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int otg_inst); + bool (*save_restore)( + struct abm *abm, + unsigned int panel_inst, + struct abm_save_restore *pData); bool (*set_pipe_ex)(struct abm *abm, unsigned int otg_inst, unsigned int option, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h b/drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h index 7254182b7c72..af6b9509d09d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h @@ -172,8 +172,6 @@ struct aux_engine_funcs { struct aux_engine *engine, uint8_t *returned_bytes); bool (*is_engine_available)(struct aux_engine *engine); - enum i2caux_engine_type (*get_engine_type)( - const struct aux_engine *engine); bool (*acquire)( struct aux_engine *engine, struct ddc *ddc); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h index 8dc804bbe98b..3e2f0f64c98c 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h @@ -123,6 +123,11 @@ struct dccg_funcs { struct dccg *dccg, int hpo_le_inst); + void (*set_symclk32_le_root_clock_gating)( + struct dccg *dccg, + int hpo_le_inst, + bool enable); + void (*set_physymclk)( struct dccg *dccg, int phy_inst, @@ -167,6 +172,16 @@ struct dccg_funcs { struct dccg *dccg, unsigned int dpp_inst, bool clock_on); + + void (*enable_symclk_se)( + struct dccg *dccg, + uint32_t stream_enc_inst, + uint32_t link_enc_inst); + + void (*disable_symclk_se)( + struct dccg *dccg, + uint32_t stream_enc_inst, + uint32_t link_enc_inst); }; #endif //__DAL_DCCG_H__ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h index aaa293613846..f5677dbb4e7d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h @@ -49,6 +49,8 @@ struct dcn_hubbub_wm_set { uint32_t dram_clk_change; uint32_t usr_retrain; uint32_t fclk_pstate_change; + uint32_t sr_enter_exit_Z8; + uint32_t sr_enter_Z8; }; struct dcn_hubbub_wm { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h index c4fbbf08ef86..a6dedf3c7d74 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h @@ -269,6 +269,7 @@ struct stream_encoder_funcs { struct stream_encoder *enc, unsigned int pix_per_container); void (*enable_fifo)(struct stream_encoder *enc); void (*disable_fifo)(struct stream_encoder *enc); + void (*map_stream_to_link)(struct stream_encoder *enc, uint32_t stream_enc_inst, uint32_t link_enc_inst); }; struct hpo_dp_stream_encoder_state { diff --git a/drivers/gpu/drm/amd/display/dc/inc/link.h b/drivers/gpu/drm/amd/display/dc/inc/link.h index f839494d59d8..e3e8c76c17cf 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link.h @@ -179,6 +179,10 @@ struct link_service { int (*aux_transfer_raw)(struct ddc_service *ddc, struct aux_payload *payload, enum aux_return_code_type *operation_result); + bool (*configure_fixed_vs_pe_retimer)( + struct ddc_service *ddc, + const uint8_t *data, + uint32_t len); bool (*aux_transfer_with_retries_no_mutex)(struct ddc_service *ddc, struct aux_payload *payload); bool (*is_in_aux_transaction_mode)(struct ddc_service *ddc); @@ -269,6 +273,20 @@ struct link_service { uint16_t psr_vtotal_su); void (*edp_get_psr_residency)( const struct dc_link *link, uint32_t *residency); + + bool (*edp_get_replay_state)( + const struct dc_link *link, uint64_t *state); + bool (*edp_set_replay_allow_active)(struct dc_link *dc_link, + const bool *enable, bool wait, bool force_static, + const unsigned int *power_opts); + bool (*edp_setup_replay)(struct dc_link *link, + const struct dc_stream_state *stream); + bool (*edp_set_coasting_vtotal)( + struct dc_link *link, uint16_t coasting_vtotal); + bool (*edp_replay_residency)(const struct dc_link *link, + unsigned int *residency, const bool is_start, + const bool is_alpm); + bool (*edp_wait_for_t12)(struct dc_link *link); bool (*edp_is_ilr_optimization_required)(struct dc_link *link, struct dc_crtc_timing *crtc_timing); diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index eaeb684c8a48..e546b9c506c1 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -142,10 +142,6 @@ struct clock_source *dc_resource_find_first_free_pll( struct resource_context *res_ctx, const struct resource_pool *pool); -struct pipe_ctx *resource_get_head_pipe_for_stream( - struct resource_context *res_ctx, - struct dc_stream_state *stream); - bool resource_attach_surfaces_to_context( struct dc_plane_state *const *plane_state, int surface_count, @@ -153,11 +149,232 @@ bool resource_attach_surfaces_to_context( struct dc_state *context, const struct resource_pool *pool); -struct pipe_ctx *find_idle_secondary_pipe( +#define FREE_PIPE_INDEX_NOT_FOUND -1 + +/* + * pipe types are identified based on MUXes in DCN front end that are capable + * of taking input from one DCN pipeline to another DCN pipeline. The name is + * in a form of XXXX_YYYY, where XXXX is the DCN front end hardware block the + * pipeline ends with and YYYY is the rendering role that the pipe is in. + * + * For instance OTG_MASTER is a pipe ending with OTG hardware block in its + * pipeline and it is in a role of a master pipe for timing generation. + * + * For quick reference a diagram of each pipe type's areas of responsibility + * for outputting timings on the screen is shown below: + * + * Timing Active for Stream 0 + * __________________________________________________ + * |OTG master 0 (OPP head 0)|OPP head 2 (DPP pipe 2) | + * | (DPP pipe 0)| | + * | Top Plane 0 | | + * | ______________|____ | + * | |DPP pipe 1 |DPP | | + * | | |pipe| | + * | | Bottom |3 | | + * | | Plane 1 | | | + * | | | | | + * | |______________|____| | + * | | | + * | | | + * | ODM slice 0 | ODM slice 1 | + * |_________________________|________________________| + * + * Timing Active for Stream 1 + * __________________________________________________ + * |OTG master 4 (OPP head 4) | + * | | + * | | + * | | + * | | + * | | + * | Blank Pixel Data | + * | (generated by DPG4) | + * | | + * | | + * | | + * | | + * | | + * |__________________________________________________| + * + * Inter-pipe Relation + * __________________________________________________ + * |PIPE IDX| DPP PIPES | OPP HEADS | OTG MASTER | + * | | plane 0 | slice 0 | | + * | 0 | -------------MPC---------ODM----------- | + * | | plane 1 | | | | | + * | 1 | ------------- | | | | + * | | plane 0 | slice 1 | | | + * | 2 | -------------MPC--------- | | + * | | plane 1 | | | | + * | 3 | ------------- | | | + * | | | blank | | + * | 4 | | ----------------------- | + * | | | | | + * | 5 | (FREE) | | | + * |________|_______________|___________|_____________| + */ +enum pipe_type { + /* free pipe - free pipe is an uninitialized pipe without a stream + * associated with it. It is a free DCN pipe resource. It can be + * acquired as any type of pipe. + */ + FREE_PIPE, + + /* OTG master pipe - the master pipe of its OPP head pipes with a + * functional OTG. It merges all its OPP head pipes pixel data in ODM + * block and output to backend DIG. OTG master pipe is responsible for + * generating entire crtc timing to backend DIG. An OTG master pipe may + * or may not have a plane. If it has a plane it blends it as the left + * most MPC slice of the top most layer. If it doesn't have a plane it + * can output pixel data from its OPP head pipes' test pattern + * generators (DPG) such as solid black pixel data to blank the screen. + */ + OTG_MASTER, + + /* OPP head pipe - the head pipe of an MPC blending tree with a + * functional OPP outputting to an OTG. OPP head pipe is responsible for + * processing output pixels in its own ODM slice. It may or may not have + * a plane. If it has a plane it blends it as the top most layer within + * its own ODM slice. If it doesn't have a plane it can output pixel + * data from its DPG such as solid black pixel data to blank the pixel + * data in its own ODM slice. OTG master pipe is also an OPP head pipe + * but with more responsibility. + */ + OPP_HEAD, + + /* DPP pipe - the pipe with a functional DPP outputting to an OPP head + * pipe's MPC. DPP pipe is responsible for processing pixel data from + * its own MPC slice of a plane. It must be connected to an OPP head + * pipe and it must have a plane associated with it. + */ + DPP_PIPE, +}; + +/* + * Determine if the input pipe ctx is of a pipe type. + * return - true if pipe ctx is of the input type. + */ +bool resource_is_pipe_type(const struct pipe_ctx *pipe_ctx, enum pipe_type type); + +/* + * Determine if the input pipe ctx is used for rendering a plane with MPCC + * combine. MPCC combine is a hardware feature to combine multiple DPP pipes + * into a single plane. It is typically used for bypassing pipe bandwidth + * limitation for rendering a very large plane or saving power by reducing UCLK + * and DPPCLK speeds. + * + * For instance in the Inter-pipe Relation diagram shown below, both PIPE 0 and + * 1 are for MPCC combine for plane 0 + * + * Inter-pipe Relation + * __________________________________________________ + * |PIPE IDX| DPP PIPES | OPP HEADS | OTG MASTER | + * | | plane 0 | | | + * | 0 | -------------MPC----------------------- | + * | | plane 0 | | | | + * | 1 | ------------- | | | + * |________|_______________|___________|_____________| + * + * return - true if pipe ctx is used for mpcc combine. + */ +bool resource_is_for_mpcc_combine(const struct pipe_ctx *pipe_ctx); + +/* + * Look for a free pipe in new resource context that is used as a secondary DPP + * pipe in MPC blending tree associated with input OPP head pipe. + * + * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise + * pipe idx of the free pipe + */ +int resource_find_free_pipe_used_in_cur_mpc_blending_tree( + const struct resource_context *cur_res_ctx, + struct resource_context *new_res_ctx, + const struct pipe_ctx *cur_opp_head); + +/* + * Look for a free pipe in new resource context that is not used in current + * resource context. + * + * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise + * pipe idx of the free pipe + */ +int recource_find_free_pipe_not_used_in_cur_res_ctx( + const struct resource_context *cur_res_ctx, + struct resource_context *new_res_ctx, + const struct resource_pool *pool); + +/* + * Look for a free pipe in new resource context that is used as a secondary DPP + * pipe in any MPCC combine in current resource context. + * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise + * pipe idx of the free pipe + */ +int resource_find_free_pipe_used_as_cur_sec_dpp_in_mpcc_combine( + const struct resource_context *cur_res_ctx, + struct resource_context *new_res_ctx, + const struct resource_pool *pool); + +/* + * Look for any free pipe in new resource context. + * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise + * pipe idx of the free pipe + */ +int resource_find_any_free_pipe(struct resource_context *new_res_ctx, + const struct resource_pool *pool); + +/* + * Legacy find free secondary pipe logic deprecated for newer DCNs as it doesn't + * find the most optimal free pipe to prevent from time consuming hardware state + * transitions. + */ +struct pipe_ctx *resource_find_free_secondary_pipe_legacy( struct resource_context *res_ctx, const struct resource_pool *pool, const struct pipe_ctx *primary_pipe); +/* + * Get number of MPC "cuts" of the plane associated with the pipe. MPC slice + * count is equal to MPC splits + 1. For example if a plane is cut 3 times, it + * will have 4 pieces of slice. + * return - 0 if pipe is not used for a plane with MPCC combine. otherwise + * the number of MPC "cuts" for the plane. + */ +int resource_get_num_mpc_splits(const struct pipe_ctx *pipe); + +/* + * Get number of ODM "cuts" of the timing associated with the pipe. ODM slice + * count is equal to ODM splits + 1. For example if a timing is cut 3 times, it + * will have 4 pieces of slice. + * return - 0 if pipe is not used for ODM combine. otherwise + * the number of ODM "cuts" for the timing. + */ +int resource_get_num_odm_splits(const struct pipe_ctx *pipe); + +/* + * Get the OTG master pipe in resource context associated with the stream. + * return - NULL if not found. Otherwise the OTG master pipe associated with the + * stream. + */ +struct pipe_ctx *resource_get_otg_master_for_stream( + struct resource_context *res_ctx, + struct dc_stream_state *stream); + +/* + * Get the OTG master pipe for the input pipe context. + * return - the OTG master pipe for the input pipe + * context. + */ +struct pipe_ctx *resource_get_otg_master(const struct pipe_ctx *pipe_ctx); + +/* + * Get the OPP head pipe for the input pipe context. + * return - the OPP head pipe for the input pipe + * context. + */ +struct pipe_ctx *resource_get_opp_head(const struct pipe_ctx *pipe_ctx); + + bool resource_validate_attach_surfaces( const struct dc_validation_set set[], int set_count, @@ -193,10 +410,6 @@ unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format); void get_audio_check(struct audio_info *aud_modes, struct audio_check *aud_chk); -int get_num_mpc_splits(struct pipe_ctx *pipe); - -int get_num_odm_splits(struct pipe_ctx *pipe); - bool get_temp_dp_link_res(struct dc_link *link, struct link_resource *link_res, struct dc_link_settings *link_settings); |