diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/inc')
41 files changed, 6426 insertions, 757 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/inc/clock_source.h b/drivers/gpu/drm/amd/display/dc/inc/clock_source.h index 47ef90495376..ed2f8005d85e 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/clock_source.h +++ b/drivers/gpu/drm/amd/display/dc/inc/clock_source.h @@ -78,7 +78,7 @@ struct csdp_ref_clk_ds_params { }; struct pixel_clk_params { - uint32_t requested_pix_clk; /* in KHz */ + uint32_t requested_pix_clk_100hz; /*> Requested Pixel Clock * (based on Video Timing standard used for requested mode)*/ uint32_t requested_sym_clk; /* in KHz */ @@ -96,6 +96,7 @@ struct pixel_clk_params { /*> de-spread info, relevant only for on-the-fly tune-up pixel rate*/ enum dc_pixel_encoding pixel_encoding; struct pixel_clk_flags flags; + uint32_t dio_se_pix_per_cycle; }; /** @@ -104,9 +105,9 @@ struct pixel_clk_params { * with actually calculated Clock and reference Crystal frequency */ struct pll_settings { - uint32_t actual_pix_clk; - uint32_t adjusted_pix_clk; - uint32_t calculated_pix_clk; + uint32_t actual_pix_clk_100hz; + uint32_t adjusted_pix_clk_100hz; + uint32_t calculated_pix_clk_100hz; uint32_t vco_freq; uint32_t reference_freq; uint32_t reference_divider; @@ -160,12 +161,24 @@ struct calc_pll_clock_source { struct clock_source_funcs { bool (*cs_power_down)( struct clock_source *); - bool (*program_pix_clk)(struct clock_source *, - struct pixel_clk_params *, struct pll_settings *); + bool (*program_pix_clk)( + struct clock_source *, + struct pixel_clk_params *, + enum dp_link_encoding encoding, + struct pll_settings *); uint32_t (*get_pix_clk_dividers)( struct clock_source *, struct pixel_clk_params *, struct pll_settings *); + bool (*get_pixel_clk_frequency_100hz)( + const struct clock_source *clock_source, + unsigned int inst, + unsigned int *pixel_clk_khz); + bool (*override_dp_pix_clk)( + struct clock_source *clock_source, + unsigned int inst, + unsigned int pixel_clk, + unsigned int ref_clk); }; struct clock_source { diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_status.h b/drivers/gpu/drm/amd/display/dc/inc/core_status.h index 94fc31080fda..82085d9c3f40 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_status.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_status.h @@ -26,11 +26,13 @@ #ifndef _CORE_STATUS_H_ #define _CORE_STATUS_H_ +#include "dc_hw_types.h" + enum dc_status { DC_OK = 1, DC_NO_CONTROLLER_RESOURCE = 2, - DC_NO_STREAM_ENG_RESOURCE = 3, + DC_NO_STREAM_ENC_RESOURCE = 3, DC_NO_CLOCK_SOURCE_RESOURCE = 4, DC_FAIL_CONTROLLER_VALIDATE = 5, DC_FAIL_ENC_VALIDATE = 6, @@ -43,8 +45,26 @@ enum dc_status { DC_FAIL_BANDWIDTH_VALIDATE = 13, /* BW and Watermark validation */ DC_FAIL_SCALING = 14, DC_FAIL_DP_LINK_TRAINING = 15, + DC_FAIL_DSC_VALIDATE = 16, + DC_NO_DSC_RESOURCE = 17, + DC_FAIL_UNSUPPORTED_1 = 18, + DC_FAIL_CLK_EXCEED_MAX = 21, + DC_FAIL_CLK_BELOW_MIN = 22, /*THIS IS MIN PER IP*/ + DC_FAIL_CLK_BELOW_CFG_REQUIRED = 23, /*THIS IS hard_min in PPLIB*/ + + DC_NOT_SUPPORTED = 24, + DC_UNSUPPORTED_VALUE = 25, + DC_NO_LINK_ENC_RESOURCE = 26, + DC_FAIL_DP_PAYLOAD_ALLOCATION = 27, + DC_FAIL_DP_LINK_BANDWIDTH = 28, + DC_FAIL_HW_CURSOR_SUPPORT = 29, + DC_FAIL_DP_TUNNEL_BW_VALIDATE = 30, DC_ERROR_UNEXPECTED = -1 }; +char *dc_status_to_str(enum dc_status status); +char *dc_pixel_encoding_to_str(enum dc_pixel_encoding pixel_encoding); +char *dc_color_depth_to_str(enum dc_color_depth color_depth); + #endif /* _CORE_STATUS_H_ */ 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 b168a5e9dd9d..5ed2cd344804 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -33,14 +33,17 @@ #include "dc_bios_types.h" #include "mem_input.h" #include "hubp.h" -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) #include "mpc.h" -#endif +#include "dwb.h" +#include "mcif_wb.h" +#include "panel_cntl.h" +#include "dmub/inc/dmub_cmd.h" +#include "pg_cntl.h" +#include "sspl/dc_spl.h" #define MAX_CLOCK_SOURCES 7 - -void enable_surface_flip_reporting(struct dc_plane_state *plane_state, - uint32_t controller_id); +#define MAX_SVP_PHANTOM_STREAMS 2 +#define MAX_SVP_PHANTOM_PLANES 2 #include "grph_object_id.h" #include "link_encoder.h" @@ -48,68 +51,110 @@ void enable_surface_flip_reporting(struct dc_plane_state *plane_state, #include "clock_source.h" #include "audio.h" #include "dm_pp_smu.h" +#include "dm_cp_psp.h" +#include "link_hwss.h" - -/************ link *****************/ -struct link_init_data { - const struct dc *dc; - struct dc_context *ctx; /* TODO: remove 'dal' when DC is complete. */ - uint32_t connector_index; /* this will be mapped to the HPD pins */ - uint32_t link_index; /* this is mapped to DAL display_index - TODO: remove it when DC is complete. */ -}; - -enum { - FREE_ACQUIRED_RESOURCE = 0, - KEEP_ACQUIRED_RESOURCE = 1, -}; - -struct dc_link *link_create(const struct link_init_data *init_params); -void link_destroy(struct dc_link **link); - -enum dc_status dc_link_validate_mode_timing( - const struct dc_stream_state *stream, - struct dc_link *link, - const struct dc_crtc_timing *timing); - -void core_link_resume(struct dc_link *link); - -void core_link_enable_stream( - struct dc_state *state, - struct pipe_ctx *pipe_ctx); - -void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option); - -void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable); /********** DAL Core*********************/ -#include "hw/clk_mgr.h" #include "transform.h" #include "dpp.h" +#include "dml2_0/dml21/inc/dml_top_dchub_registers.h" +#include "dml2_0/dml21/inc/dml_top_types.h" + struct resource_pool; struct dc_state; struct resource_context; +struct clk_bw_params; +struct dc_mcache_params; + +#define MAX_RMCM_INST 2 struct resource_funcs { + enum engine_id (*get_preferred_eng_id_dpia)(unsigned int dpia_index); void (*destroy)(struct resource_pool **pool); void (*link_init)(struct dc_link *link); + struct panel_cntl*(*panel_cntl_create)( + const struct panel_cntl_init_data *panel_cntl_init_data); struct link_encoder *(*link_enc_create)( + struct dc_context *ctx, const struct encoder_init_data *init); - - bool (*validate_bandwidth)( + /* Create a minimal link encoder object with no dc_link object + * associated with it. */ + struct link_encoder *(*link_enc_create_minimal)(struct dc_context *ctx, enum engine_id eng_id); + enum dc_status (*validate_bandwidth)( + struct dc *dc, + struct dc_state *context, + enum dc_validate_mode validate_mode); + void (*calculate_wm_and_dlg)( + struct dc *dc, struct dc_state *context, + display_e2e_pipe_params_st *pipes, + int pipe_cnt, + int vlevel); + void (*update_soc_for_wm_a)( + struct dc *dc, struct dc_state *context); + + unsigned int (*calculate_mall_ways_from_bytes)( + const struct dc *dc, + unsigned int total_size_in_mall_bytes); + void (*prepare_mcache_programming)( struct dc *dc, struct dc_state *context); + /** + * @populate_dml_pipes - Populate pipe data struct + * + * Returns: + * Total of pipes available in the specific ASIC. + */ + int (*populate_dml_pipes)( + struct dc *dc, + struct dc_state *context, + display_e2e_pipe_params_st *pipes, + enum dc_validate_mode validate_mode); + + /* + * Algorithm for assigning available link encoders to links. + * + * Update link_enc_assignments table and link_enc_avail list accordingly in + * struct resource_context. + */ + void (*link_encs_assign)( + struct dc *dc, + struct dc_state *state, + struct dc_stream_state *streams[], + uint8_t stream_count); + /* + * Unassign a link encoder from a stream. + * + * Update link_enc_assignments table and link_enc_avail list accordingly in + * struct resource_context. + */ + void (*link_enc_unassign)( + struct dc_state *state, + struct dc_stream_state *stream); enum dc_status (*validate_global)( struct dc *dc, struct dc_state *context); - struct pipe_ctx *(*acquire_idle_pipe_for_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); + const struct pipe_ctx *opp_head_pipe); + + struct pipe_ctx *(*acquire_free_pipe_as_secondary_opp_head)( + const struct dc_state *cur_ctx, + struct dc_state *new_ctx, + const struct resource_pool *pool, + const struct pipe_ctx *otg_master); - enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state, struct dc_caps *caps); + void (*release_pipe)(struct dc_state *context, + struct pipe_ctx *pipe, + const struct resource_pool *pool); + + 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, @@ -120,9 +165,71 @@ struct resource_funcs { struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *stream); - enum dc_status (*get_default_swizzle_mode)( + + enum dc_status (*patch_unknown_plane_state)( struct dc_plane_state *plane_state); + struct stream_encoder *(*find_first_free_match_stream_enc_for_link)( + struct resource_context *res_ctx, + const struct resource_pool *pool, + struct dc_stream_state *stream); + + void (*populate_dml_writeback_from_context)( + struct dc *dc, + struct resource_context *res_ctx, + display_e2e_pipe_params_st *pipes); + + void (*set_mcif_arb_params)( + struct dc *dc, + struct dc_state *context, + display_e2e_pipe_params_st *pipes, + int pipe_cnt); + + void (*update_bw_bounding_box)( + struct dc *dc, + struct clk_bw_params *bw_params); + bool (*acquire_post_bldn_3dlut)( + struct resource_context *res_ctx, + const struct resource_pool *pool, + int mpcc_id, + struct dc_3dlut **lut, + struct dc_transfer_func **shaper); + + bool (*release_post_bldn_3dlut)( + struct resource_context *res_ctx, + const struct resource_pool *pool, + struct dc_3dlut **lut, + struct dc_transfer_func **shaper); + + enum dc_status (*add_dsc_to_stream_resource)( + struct dc *dc, struct dc_state *state, + struct dc_stream_state *stream); + + void (*add_phantom_pipes)( + struct dc *dc, + struct dc_state *context, + display_e2e_pipe_params_st *pipes, + unsigned int pipe_cnt, + unsigned int index); + + void (*get_panel_config_defaults)(struct dc_panel_config *panel_config); + void (*build_pipe_pix_clk_params)(struct pipe_ctx *pipe_ctx); + /* + * Get indicator of power from a context that went through full validation + */ + int (*get_power_profile)(const struct dc_state *context); + unsigned int (*get_det_buffer_size)(const struct dc_state *context); + unsigned int (*get_vstartup_for_pipe)(struct pipe_ctx *pipe_ctx); + unsigned int (*get_max_hw_cursor_size)(const struct dc *dc, + struct dc_state *state, + const struct dc_stream_state *stream); + bool (*program_mcache_pipe_config)(struct dc_state *context, + const struct dc_mcache_params *mcache_params); + enum dc_status (*update_dc_state_for_encoder_switch)(struct dc_link *link, + struct dc_link_settings *link_setting, + uint8_t pipe_count, + struct pipe_ctx *pipes, + struct audio_output *audio_output); }; struct audio_support{ @@ -144,19 +251,54 @@ struct resource_pool { struct stream_encoder *stream_enc[MAX_PIPES * 2]; struct hubbub *hubbub; struct mpc *mpc; - struct pp_smu_funcs_rv *pp_smu; - struct pp_smu_display_requirement_rv pp_smu_req; - struct aux_engine *engines[MAX_PIPES]; + struct pp_smu_funcs *pp_smu; + struct dce_aux *engines[MAX_PIPES]; struct dce_i2c_hw *hw_i2cs[MAX_PIPES]; struct dce_i2c_sw *sw_i2cs[MAX_PIPES]; bool i2c_hw_buffer_in_use; + struct dwbc *dwbc[MAX_DWB_PIPES]; + struct mcif_wb *mcif_wb[MAX_DWB_PIPES]; + struct { + unsigned int gsl_0:1; + unsigned int gsl_1:1; + unsigned int gsl_2:1; + } gsl_groups; + + struct display_stream_compressor *dscs[MAX_PIPES]; + unsigned int pipe_count; unsigned int underlay_pipe_index; unsigned int stream_enc_count; - unsigned int ref_clock_inKhz; + + /* An array for accessing the link encoder objects that have been created. + * Index in array corresponds to engine ID - viz. 0: ENGINE_ID_DIGA + */ + struct link_encoder *link_encoders[MAX_LINK_ENCODERS]; + /* Number of DIG link encoder objects created - i.e. number of valid + * entries in link_encoders array. + */ + unsigned int dig_link_enc_count; + /* Number of USB4 DPIA (DisplayPort Input Adapter) link objects created.*/ + unsigned int usb4_dpia_count; + + unsigned int hpo_dp_stream_enc_count; + struct hpo_dp_stream_encoder *hpo_dp_stream_enc[MAX_HPO_DP2_ENCODERS]; + unsigned int hpo_dp_link_enc_count; + struct hpo_dp_link_encoder *hpo_dp_link_enc[MAX_HPO_DP2_LINK_ENCODERS]; + struct dc_3dlut *mpc_lut[MAX_PIPES]; + struct dc_transfer_func *mpc_shaper[MAX_PIPES]; + struct dc_rmcm_3dlut rmcm_3dlut[MAX_RMCM_INST]; + + struct { + unsigned int xtalin_clock_inKhz; + unsigned int dccg_ref_clock_inKhz; + unsigned int dchub_ref_clock_inKhz; + } ref_clocks; unsigned int timing_generator_count; + unsigned int mpcc_count; + unsigned int writeback_pipe_count; /* * reserved clock source for DP */ @@ -165,44 +307,73 @@ struct resource_pool { struct clock_source *clock_sources[MAX_CLOCK_SOURCES]; unsigned int clk_src_count; - struct audio *audios[MAX_PIPES]; + struct audio *audios[MAX_AUDIOS]; unsigned int audio_count; struct audio_support audio_support; - struct clk_mgr *clk_mgr; struct dccg *dccg; + struct pg_cntl *pg_cntl; struct irq_service *irqs; struct abm *abm; struct dmcu *dmcu; + struct dmub_psr *psr; + struct dmub_replay *replay; + + struct abm *multiple_abms[MAX_PIPES]; const struct resource_funcs *funcs; const struct resource_caps *res_cap; + + struct ddc_service *oem_device; }; -struct dcn_fe_clocks { +struct dcn_fe_bandwidth { int dppclk_khz; + }; -struct dcn_fe_bandwidth { - struct dcn_fe_clocks calc; - struct dcn_fe_clocks cur; +/* Parameters needed to call set_disp_pattern_generator */ +struct test_pattern_params { + enum controller_dp_test_pattern test_pattern; + enum controller_dp_color_space color_space; + enum dc_color_depth color_depth; + int width; + int height; + int offset; }; struct stream_resource { struct output_pixel_processor *opp; + struct display_stream_compressor *dsc; struct timing_generator *tg; struct stream_encoder *stream_enc; + struct hpo_dp_stream_encoder *hpo_dp_stream_enc; struct audio *audio; struct pixel_clk_params pix_clk_params; struct encoder_info_frame encoder_info_frame; struct abm *abm; + /* There are only (num_pipes+1)/2 groups. 0 means unassigned, + * otherwise it's using group number 'gsl_group-1' + */ + uint8_t gsl_group; + + struct test_pattern_params test_pattern_params; }; struct plane_resource { + /* scl_data is scratch space required to program a plane */ struct scaler_data scl_data; + /* Below pointers to hw objects are required to enable the plane */ + /* spl_in and spl_out are the input and output structures for SPL + * which are required when using Scaler Programming Library + * these are scratch spaces needed when programming a plane + */ + struct spl_in spl_in; + struct spl_out spl_out; + /* Below pointers to hw objects are required to enable the plane */ struct hubp *hubp; struct mem_input *mi; struct input_pixel_processor *ipp; @@ -213,28 +384,138 @@ struct plane_resource { struct dcn_fe_bandwidth bw; }; +#define LINK_RES_HPO_DP_REC_MAP__MASK 0xFFFF +#define LINK_RES_HPO_DP_REC_MAP__SHIFT 0 + +/* all mappable hardware resources used to enable a link */ +struct link_resource { + struct link_encoder *dio_link_enc; + struct hpo_dp_link_encoder *hpo_dp_link_enc; +}; + +struct link_config { + struct dc_link_settings dp_link_settings; + struct dc_tunnel_settings dp_tunnel_settings; +}; + +union pipe_update_flags { + struct { + uint32_t enable : 1; + uint32_t disable : 1; + uint32_t odm : 1; + uint32_t global_sync : 1; + uint32_t opp_changed : 1; + uint32_t tg_changed : 1; + uint32_t mpcc : 1; + uint32_t dppclk : 1; + uint32_t hubp_interdependent : 1; + uint32_t hubp_rq_dlg_ttu : 1; + uint32_t gamut_remap : 1; + uint32_t scaler : 1; + uint32_t viewport : 1; + uint32_t plane_changed : 1; + uint32_t det_size : 1; + uint32_t unbounded_req : 1; + uint32_t test_pattern_changed : 1; + } bits; + uint32_t raw; +}; + +struct pixel_rate_divider { + uint32_t div_factor1; + uint32_t div_factor2; +}; + +enum p_state_switch_method { + P_STATE_UNKNOWN = 0, + P_STATE_V_BLANK = 1, + P_STATE_FPO, + P_STATE_V_ACTIVE, + P_STATE_SUB_VP, + P_STATE_DRR_SUB_VP, + P_STATE_V_BLANK_SUB_VP, +}; + +struct dsc_padding_params { + /* pixels borrowed from hblank to hactive */ + uint8_t dsc_hactive_padding; + uint32_t dsc_htotal_padding; + uint32_t dsc_pix_clk_100hz; +}; + struct pipe_ctx { struct dc_plane_state *plane_state; struct dc_stream_state *stream; struct plane_resource plane_res; + + /** + * @stream_res: Reference to DCN resource components such OPP and DSC. + */ struct stream_resource stream_res; + struct link_resource link_res; struct clock_source *clock_source; struct pll_settings pll_settings; + /** + * @link_config: + * + * link config records software decision for what link config should be + * enabled given current link capability and stream during hw resource + * mapping. This is to decouple the dependency on link capability during + * dc commit or update. + */ + struct link_config link_config; + uint8_t pipe_idx; + uint8_t pipe_idx_syncd; struct pipe_ctx *top_pipe; struct pipe_ctx *bottom_pipe; + struct pipe_ctx *next_odm_pipe; + struct pipe_ctx *prev_odm_pipe; -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 struct _vcs_dpi_display_dlg_regs_st dlg_regs; struct _vcs_dpi_display_ttu_regs_st ttu_regs; struct _vcs_dpi_display_rq_regs_st rq_regs; struct _vcs_dpi_display_pipe_dest_params_st pipe_dlg_param; -#endif + struct _vcs_dpi_display_rq_params_st dml_rq_param; + struct _vcs_dpi_display_dlg_sys_params_st dml_dlg_sys_param; + struct _vcs_dpi_display_e2e_pipe_params_st dml_input; + int det_buffer_size_kb; + bool unbounded_req; + unsigned int surface_size_in_mall_bytes; + struct dml2_dchub_per_pipe_register_set hubp_regs; + struct dml2_hubp_pipe_mcache_regs mcache_regs; + union dml2_global_sync_programming global_sync; + + struct dwbc *dwbc; + struct mcif_wb *mcif_wb; + union pipe_update_flags update_flags; + enum p_state_switch_method p_state_type; + struct tg_color visual_confirm_color; + bool has_vactive_margin; + /* subvp_index: only valid if the pipe is a SUBVP_MAIN*/ + uint8_t subvp_index; + struct pixel_rate_divider pixel_rate_divider; + struct dsc_padding_params dsc_padding_params; + /* next vupdate */ + uint32_t next_vupdate; + uint32_t wait_frame_count; + bool wait_is_required; +}; + +/* Data used for dynamic link encoder assignment. + * Tracks current and future assignments; available link encoders; + * and mode of operation (whether to use current or future assignments). + */ +struct link_enc_cfg_context { + enum link_enc_cfg_mode mode; + struct link_enc_assignment link_enc_assignments[MAX_PIPES]; + enum engine_id link_enc_avail[MAX_LINK_ENCODERS]; + struct link_enc_assignment transient_assignments[MAX_PIPES]; }; struct resource_context { @@ -243,6 +524,16 @@ struct resource_context { bool is_audio_acquired[MAX_PIPES]; uint8_t clock_source_ref_count[MAX_CLOCK_SOURCES]; uint8_t dp_clock_source_ref_count; + bool is_dsc_acquired[MAX_PIPES]; + struct link_enc_cfg_context link_enc_cfg_ctx; + unsigned int dio_link_enc_to_link_idx[MAX_LINK_ENCODERS]; + int dio_link_enc_ref_cnts[MAX_LINK_ENCODERS]; + bool is_hpo_dp_stream_enc_acquired[MAX_HPO_DP2_ENCODERS]; + unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS]; + int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS]; + bool is_mpc_3dlut_acquired[MAX_PIPES]; + /* used to build scalar data in dml2 and for edp backlight programming */ + struct pipe_ctx temp_pipe; }; struct dce_bw_output { @@ -262,45 +553,155 @@ struct dce_bw_output { int blackout_recovery_time_us; }; +struct dcn_bw_writeback { + struct mcif_arb_params mcif_wb_arb[MAX_DWB_PIPES]; +}; + struct dcn_bw_output { struct dc_clocks clk; - struct dcn_watermark_set watermarks; + union dcn_watermark_set watermarks; + struct dcn_bw_writeback bw_writeback; + int compbuf_size_kb; + unsigned int mall_ss_size_bytes; + unsigned int mall_ss_psr_active_size_bytes; + unsigned int mall_subvp_size_bytes; + unsigned int legacy_svp_drr_stream_index; + bool legacy_svp_drr_stream_index_valid; + struct dml2_mcache_surface_allocation mcache_allocations[DML2_MAX_PLANES]; + struct dmub_cmd_fams2_global_config fams2_global_config; + union dmub_cmd_fams2_config fams2_stream_base_params[DML2_MAX_PLANES]; + union { + union dmub_cmd_fams2_config fams2_stream_sub_params[DML2_MAX_PLANES]; + union dmub_fams2_stream_static_sub_state_v2 fams2_stream_sub_params_v2[DML2_MAX_PLANES]; + }; + struct dml2_display_arb_regs arb_regs; }; -union bw_context { +union bw_output { struct dcn_bw_output dcn; struct dce_bw_output dce; }; +struct bw_context { + union bw_output bw; + struct display_mode_lib dml; + struct dml2_context *dml2; + struct dml2_context *dml2_dc_power_source; +}; + +struct dc_dmub_cmd { + union dmub_rb_cmd dmub_cmd; + enum dm_dmub_wait_type wait_type; +}; + /** - * struct dc_state - The full description of a state requested by a user - * - * @streams: Stream properties - * @stream_status: The planes on a given stream - * @res_ctx: Persistent state of resources - * @bw: The output from bandwidth and watermark calculations - * @pp_display_cfg: PowerPlay clocks and settings - * @dcn_bw_vars: non-stack memory to support bandwidth calculations - * + * struct dc_state - The full description of a state requested by users */ struct dc_state { + /** + * @streams: Stream state properties + */ struct dc_stream_state *streams[MAX_PIPES]; + + /** + * @stream_status: Planes status on a given stream + */ struct dc_stream_status stream_status[MAX_PIPES]; + /** + * @phantom_streams: Stream state properties for phantoms + */ + struct dc_stream_state *phantom_streams[MAX_PHANTOM_PIPES]; + /** + * @phantom_planes: Planes state properties for phantoms + */ + struct dc_plane_state *phantom_planes[MAX_PHANTOM_PIPES]; + + /** + * @stream_count: Total of streams in use + */ uint8_t stream_count; + uint8_t stream_mask; + /** + * @stream_count: Total phantom streams in use + */ + uint8_t phantom_stream_count; + /** + * @stream_count: Total phantom planes in use + */ + uint8_t phantom_plane_count; + /** + * @res_ctx: Persistent state of resources + */ struct resource_context res_ctx; - union bw_context bw; - - /* Note: these are big structures, do *not* put on stack! */ + /** + * @pp_display_cfg: PowerPlay clocks and settings + * Note: this is a big struct, do *not* put on stack! + */ struct dm_pp_display_configuration pp_display_cfg; -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 + + /** + * @dcn_bw_vars: non-stack memory to support bandwidth calculations + * Note: this is a big struct, do *not* put on stack! + */ struct dcn_bw_internal_vars dcn_bw_vars; -#endif - struct clk_mgr *dccg; + struct clk_mgr *clk_mgr; + /** + * @bw_ctx: The output from bandwidth and watermark calculations and the DML + * + * Each context must have its own instance of VBA, and in order to + * initialize and obtain IP and SOC, the base DML instance from DC is + * initially copied into every context. + */ + struct bw_context bw_ctx; + + struct block_sequence block_sequence[MAX_HWSS_BLOCK_SEQUENCE_SIZE]; + unsigned int block_sequence_steps; + struct dc_dmub_cmd dc_dmub_cmd[10]; + unsigned int dmub_cmd_count; + + /** + * @refcount: refcount reference + * + * Notice that dc_state is used around the code to capture the current + * context, so we need to pass it everywhere. That's why we want to use + * kref in this struct. + */ struct kref refcount; + + struct { + unsigned int stutter_period_us; + } perf_params; + + enum dc_power_source_type power_source; +}; + +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; + bool os_request_force_ffu; +}; + +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; + int max_dppclk_mhz; + int max_phyclk_mhz; }; #endif /* _CORE_TYPES_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h deleted file mode 100644 index 538b83303b86..000000000000 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2012-15 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 __DAL_DDC_SERVICE_H__ -#define __DAL_DDC_SERVICE_H__ - -#include "include/ddc_service_types.h" -#include "include/i2caux_interface.h" - -#define EDID_SEGMENT_SIZE 256 - -/* Address range from 0x00 to 0x1F.*/ -#define DP_ADAPTOR_TYPE2_SIZE 0x20 -#define DP_ADAPTOR_TYPE2_REG_ID 0x10 -#define DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK 0x1D -/* Identifies adaptor as Dual-mode adaptor */ -#define DP_ADAPTOR_TYPE2_ID 0xA0 -/* MHz*/ -#define DP_ADAPTOR_TYPE2_MAX_TMDS_CLK 600 -/* MHz*/ -#define DP_ADAPTOR_TYPE2_MIN_TMDS_CLK 25 -/* kHZ*/ -#define DP_ADAPTOR_DVI_MAX_TMDS_CLK 165000 -/* kHZ*/ -#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 165000 - -#define DDC_I2C_COMMAND_ENGINE I2C_COMMAND_ENGINE_SW - -struct ddc_service; -struct graphics_object_id; -enum ddc_result; -struct av_sync_data; -struct dp_receiver_id_info; - -struct i2c_payloads; -struct aux_payloads; - -void dal_ddc_i2c_payloads_add( - struct i2c_payloads *payloads, - uint32_t address, - uint32_t len, - uint8_t *data, - bool write); - -void dal_ddc_aux_payloads_add( - struct aux_payloads *payloads, - uint32_t address, - uint32_t len, - uint8_t *data, - bool write); - -struct ddc_service_init_data { - struct graphics_object_id id; - struct dc_context *ctx; - struct dc_link *link; -}; - -struct ddc_service *dal_ddc_service_create( - struct ddc_service_init_data *ddc_init_data); - -void dal_ddc_service_destroy(struct ddc_service **ddc); - -enum ddc_service_type dal_ddc_service_get_type(struct ddc_service *ddc); - -void dal_ddc_service_set_transaction_type( - struct ddc_service *ddc, - enum ddc_transaction_type type); - -bool dal_ddc_service_is_in_aux_transaction_mode(struct ddc_service *ddc); - -void dal_ddc_service_i2c_query_dp_dual_mode_adaptor( - struct ddc_service *ddc, - struct display_sink_capability *sink_cap); - -bool dal_ddc_service_query_ddc_data( - struct ddc_service *ddc, - uint32_t address, - uint8_t *write_buf, - uint32_t write_size, - uint8_t *read_buf, - uint32_t read_size); - -int dc_link_aux_transfer(struct ddc_service *ddc, - unsigned int address, - uint8_t *reply, - void *buffer, - unsigned int size, - enum aux_transaction_type type, - enum i2caux_transaction_action action); - -void dal_ddc_service_write_scdc_data( - struct ddc_service *ddc_service, - uint32_t pix_clk, - bool lte_340_scramble); - -void dal_ddc_service_read_scdc_data( - struct ddc_service *ddc_service); - -void ddc_service_set_dongle_type(struct ddc_service *ddc, - enum display_dongle_type dongle_type); - -void dal_ddc_service_set_ddc_pin( - struct ddc_service *ddc_service, - struct ddc *ddc); - -struct ddc *dal_ddc_service_get_ddc_pin(struct ddc_service *ddc_service); - -uint32_t get_defer_delay(struct ddc_service *ddc); - -#endif /* __DAL_DDC_SERVICE_H__ */ - diff --git a/drivers/gpu/drm/amd/display/dc/inc/dcn_calc_math.h b/drivers/gpu/drm/amd/display/dc/inc/dcn_calc_math.h new file mode 100644 index 000000000000..45a07eeffbb6 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/dcn_calc_math.h @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef _DCN_CALC_MATH_H_ +#define _DCN_CALC_MATH_H_ + +float dcn_bw_mod(const float arg1, const float arg2); +float dcn_bw_min2(const float arg1, const float arg2); +unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2); +float dcn_bw_max2(const float arg1, const float arg2); +float dcn_bw_floor2(const float arg, const float significance); +float dcn_bw_floor(const float arg); +float dcn_bw_ceil2(const float arg, const float significance); +float dcn_bw_ceil(const float arg); +float dcn_bw_max3(float v1, float v2, float v3); +float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5); +float dcn_bw_pow(float a, float exp); +float dcn_bw_log(float a, float b); +double dcn_bw_fabs(double a); + +#endif /* _DCN_CALC_MATH_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h index ece954a40a8e..134091d5842d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h @@ -31,8 +31,8 @@ #define __DCN_CALCS_H__ #include "bw_fixed.h" -#include "../dml/display_mode_lib.h" -#include "hw/clk_mgr.h" +#include "dml/display_mode_lib.h" + struct dc; struct dc_state; @@ -621,15 +621,29 @@ extern const struct dcn_ip_params dcn10_ip_defaults; bool dcn_validate_bandwidth( struct dc *dc, - struct dc_state *context); + struct dc_state *context, + enum dc_validate_mode validate_mode); -unsigned int dcn_find_dcfclk_suits_all( - const struct dc *dc, - struct dc_clocks *clocks); +void dcn_get_soc_clks( + struct dc *dc, + int *min_fclk_khz, + int *min_dcfclk_khz, + int *socclk_khz); -void dcn_bw_update_from_pplib(struct dc *dc); -void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc); +void dcn_bw_update_from_pplib_fclks( + struct dc *dc, + struct dm_pp_clock_levels_with_voltage *fclks); +void dcn_bw_update_from_pplib_dcfclks( + struct dc *dc, + struct dm_pp_clock_levels_with_voltage *dcfclks); +void dcn_bw_notify_pplib_of_wm_ranges( + struct dc *dc, + int min_fclk_khz, + int min_dcfclk_khz, + int socclk_khz); void dcn_bw_sync_calcs_and_dml(struct dc *dc); +enum source_macro_tile_size swizzle_mode_to_macro_tile_size(enum swizzle_mode_values sw_mode); + #endif /* __DCN_CALCS_H__ */ 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 abc961c0906e..3f0161d64675 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h @@ -27,26 +27,19 @@ #include "dm_services_types.h" -struct abm_backlight_registers { - unsigned int BL_PWM_CNTL; - unsigned int BL_PWM_CNTL2; - unsigned int BL_PWM_PERIOD_CNTL; - unsigned int LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV; -}; +struct abm_save_restore; struct abm { struct dc_context *ctx; const struct abm_funcs *funcs; - - /* registers setting needs to be saved and restored at InitBacklight */ - struct abm_backlight_registers stored_backlight_registers; + bool dmcu_is_running; }; struct abm_funcs { - void (*abm_init)(struct abm *abm); + void (*abm_init)(struct abm *abm, uint32_t back_light, uint32_t user_level); bool (*set_abm_level)(struct abm *abm, unsigned int abm_level); - bool (*set_abm_immediate_disable)(struct abm *abm); - bool (*init_backlight)(struct abm *abm); + bool (*set_abm_immediate_disable)(struct abm *abm, unsigned int panel_inst); + bool (*set_pipe)(struct abm *abm, unsigned int controller_id, unsigned int panel_inst); /* backlight_pwm_u16_16 is unsigned 32 bit, * 16 bit integer + 16 fractional, where 1.0 is max backlight value. @@ -55,10 +48,24 @@ struct abm_funcs { unsigned int backlight_pwm_u16_16, unsigned int frame_ramp, unsigned int controller_id, - bool use_smooth_brightness); + unsigned int panel_inst); unsigned int (*get_current_backlight)(struct abm *abm); unsigned int (*get_target_backlight)(struct abm *abm); + bool (*init_abm_config)(struct abm *abm, + const char *src, + 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, + unsigned int panel_inst, + unsigned int pwrseq_inst); }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h b/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h index 925204f49717..8c18efc2aa70 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h @@ -43,7 +43,10 @@ struct audio_funcs { void (*az_configure)(struct audio *audio, enum signal_type signal, const struct audio_crtc_info *crtc_info, - const struct audio_info *audio_info); + const struct audio_info *audio_info, + const struct audio_dp_link_info *dp_link_info); + + void (*az_disable_hbr_audio)(struct audio *audio); void (*wall_dto_setup)(struct audio *audio, enum signal_type signal, @@ -57,6 +60,7 @@ struct audio { const struct audio_funcs *funcs; struct dc_context *ctx; unsigned int inst; + bool enabled; }; #endif /* __DAL_AUDIO__ */ 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 e79cd4e92919..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 @@ -27,7 +27,8 @@ #define __DAL_AUX_ENGINE_H__ #include "dc_ddc_types.h" -#include "include/i2caux_interface.h" + +enum aux_return_code_type; enum i2caux_transaction_operation { I2CAUX_TRANSACTION_READ, @@ -79,7 +80,12 @@ enum i2c_default_speed { I2CAUX_DEFAULT_I2C_SW_SPEED = 50 }; -union aux_config; +union aux_config { + struct { + uint32_t ALLOW_AUX_WHEN_HPD_LOW:1; + } bits; + uint32_t raw; +}; struct aux_engine { uint32_t inst; @@ -140,6 +146,9 @@ struct write_command_context { struct aux_engine_funcs { + bool (*configure_timeout)( + struct ddc_service *ddc, + uint32_t timeout); void (*destroy)( struct aux_engine **ptr); bool (*acquire_engine)( @@ -159,12 +168,10 @@ struct aux_engine_funcs { uint8_t *buffer, uint8_t *reply_result, uint32_t *sw_status); - enum aux_channel_operation_result (*get_channel_status)( + enum aux_return_code_type (*get_channel_status)( 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/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h index 23a4b18e5fee..2c9a4a12bd8a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h @@ -26,22 +26,346 @@ #ifndef __DAL_CLK_MGR_H__ #define __DAL_CLK_MGR_H__ -#include "dm_services_types.h" #include "dc.h" +#include "dm_pp_smu.h" -struct clk_mgr { - struct dc_context *ctx; - const struct clk_mgr_funcs *funcs; +/* Constants */ +#define DDR4_DRAM_WIDTH 64 +#define WM_A 0 +#define WM_B 1 +#define WM_C 2 +#define WM_D 3 +#define WM_SET_COUNT 4 +#define WM_1A 2 +#define WM_1B 3 + +#define DCN_MINIMUM_DISPCLK_Khz 100000 +#define DCN_MINIMUM_DPPCLK_Khz 100000 + +struct dcn3_clk_internal { + int dummy; +// TODO: + uint32_t CLK1_CLK0_CURRENT_CNT; //dispclk + uint32_t CLK1_CLK1_CURRENT_CNT; //dppclk + uint32_t CLK1_CLK2_CURRENT_CNT; //dprefclk + uint32_t CLK1_CLK3_CURRENT_CNT; //dcfclk + uint32_t CLK1_CLK4_CURRENT_CNT; + uint32_t CLK1_CLK3_DS_CNTL; //dcf_deep_sleep_divider + uint32_t CLK1_CLK3_ALLOW_DS; //dcf_deep_sleep_allow + + uint32_t CLK1_CLK0_BYPASS_CNTL; //dispclk bypass + uint32_t CLK1_CLK1_BYPASS_CNTL; //dppclk bypass + uint32_t CLK1_CLK2_BYPASS_CNTL; //dprefclk bypass + uint32_t CLK1_CLK3_BYPASS_CNTL; //dcfclk bypass + + uint32_t CLK4_CLK0_CURRENT_CNT; //fclk +}; + +struct dcn35_clk_internal { + int dummy; + uint32_t CLK1_CLK0_CURRENT_CNT; //dispclk + uint32_t CLK1_CLK1_CURRENT_CNT; //dppclk + uint32_t CLK1_CLK2_CURRENT_CNT; //dprefclk + uint32_t CLK1_CLK3_CURRENT_CNT; //dcfclk + uint32_t CLK1_CLK4_CURRENT_CNT; //dtbclk + //uint32_t CLK1_CLK5_CURRENT_CNT; //dpiaclk + //uint32_t CLK1_CLK6_CURRENT_CNT; //srdbgclk + uint32_t CLK1_CLK3_DS_CNTL; //dcf_deep_sleep_divider + uint32_t CLK1_CLK3_ALLOW_DS; //dcf_deep_sleep_allow + + uint32_t CLK1_CLK0_BYPASS_CNTL; //dispclk bypass + uint32_t CLK1_CLK1_BYPASS_CNTL; //dppclk bypass + uint32_t CLK1_CLK2_BYPASS_CNTL; //dprefclk bypass + uint32_t CLK1_CLK3_BYPASS_CNTL; //dcfclk bypass + uint32_t CLK1_CLK4_BYPASS_CNTL; //dtbclk bypass +}; + +struct dcn301_clk_internal { + int dummy; + uint32_t CLK1_CLK0_CURRENT_CNT; //dispclk + uint32_t CLK1_CLK1_CURRENT_CNT; //dppclk + uint32_t CLK1_CLK2_CURRENT_CNT; //dprefclk + uint32_t CLK1_CLK3_CURRENT_CNT; //dcfclk + uint32_t CLK1_CLK3_DS_CNTL; //dcf_deep_sleep_divider + uint32_t CLK1_CLK3_ALLOW_DS; //dcf_deep_sleep_allow + + uint32_t CLK1_CLK0_BYPASS_CNTL; //dispclk bypass + uint32_t CLK1_CLK1_BYPASS_CNTL; //dppclk bypass + uint32_t CLK1_CLK2_BYPASS_CNTL; //dprefclk bypass + uint32_t CLK1_CLK3_BYPASS_CNTL; //dcfclk bypass +}; + +/* Will these bw structures be ASIC specific? */ + +#define MAX_NUM_DPM_LVL 8 +#define WM_SET_COUNT 4 + +enum clk_type { + CLK_TYPE_DCFCLK, + CLK_TYPE_FCLK, + CLK_TYPE_MCLK, + CLK_TYPE_SOCCLK, + CLK_TYPE_DTBCLK, + CLK_TYPE_DISPCLK, + CLK_TYPE_DPPCLK, + CLK_TYPE_DSCCLK, + CLK_TYPE_COUNT +}; + +struct clk_limit_table_entry { + unsigned int voltage; /* milivolts withh 2 fractional bits */ + unsigned int dcfclk_mhz; + unsigned int fclk_mhz; + unsigned int memclk_mhz; + unsigned int socclk_mhz; + unsigned int dtbclk_mhz; + unsigned int dispclk_mhz; + unsigned int dppclk_mhz; + unsigned int phyclk_mhz; + unsigned int phyclk_d18_mhz; + unsigned int wck_ratio; +}; + +struct clk_limit_num_entries { + unsigned int num_dcfclk_levels; + unsigned int num_fclk_levels; + unsigned int num_memclk_levels; + unsigned int num_socclk_levels; + unsigned int num_dtbclk_levels; + unsigned int num_dispclk_levels; + unsigned int num_dppclk_levels; + unsigned int num_phyclk_levels; + unsigned int num_phyclk_d18_levels; +}; + +/* This table is contiguous */ +struct clk_limit_table { + struct clk_limit_table_entry entries[MAX_NUM_DPM_LVL]; + struct clk_limit_num_entries num_entries_per_clk; + unsigned int num_entries; /* highest populated dpm level for back compatibility */ +}; + +struct wm_range_table_entry { + unsigned int wm_inst; + unsigned int wm_type; + double pstate_latency_us; + double sr_exit_time_us; + double sr_enter_plus_exit_time_us; + bool valid; +}; + +struct nv_wm_range_entry { + bool valid; + + struct { + uint8_t wm_type; + uint16_t min_dcfclk; + uint16_t max_dcfclk; + uint16_t min_uclk; + uint16_t max_uclk; + } pmfw_breakdown; + + struct { + double pstate_latency_us; + double sr_exit_time_us; + double sr_enter_plus_exit_time_us; + double fclk_change_latency_us; + } dml_input; +}; + +struct clk_log_info { + bool enabled; + char *pBuf; + unsigned int bufSize; + unsigned int *sum_chars_printed; +}; + +struct clk_state_registers_and_bypass { + uint32_t dcfclk; + uint32_t dcf_deep_sleep_divider; + uint32_t dcf_deep_sleep_allow; + uint32_t dprefclk; + uint32_t dispclk; + uint32_t dppclk; + uint32_t dtbclk; + uint32_t fclk; + + uint32_t dppclk_bypass; + uint32_t dcfclk_bypass; + uint32_t dprefclk_bypass; + uint32_t dispclk_bypass; +}; + +struct rv1_clk_internal { + uint32_t CLK0_CLK8_CURRENT_CNT; //dcfclk + uint32_t CLK0_CLK8_DS_CNTL; //dcf_deep_sleep_divider + uint32_t CLK0_CLK8_ALLOW_DS; //dcf_deep_sleep_allow + uint32_t CLK0_CLK10_CURRENT_CNT; //dprefclk + uint32_t CLK0_CLK11_CURRENT_CNT; //dispclk + + uint32_t CLK0_CLK8_BYPASS_CNTL; //dcfclk bypass + uint32_t CLK0_CLK10_BYPASS_CNTL; //dprefclk bypass + uint32_t CLK0_CLK11_BYPASS_CNTL; //dispclk bypass +}; + +struct rn_clk_internal { + uint32_t CLK1_CLK0_CURRENT_CNT; //dispclk + uint32_t CLK1_CLK1_CURRENT_CNT; //dppclk + uint32_t CLK1_CLK2_CURRENT_CNT; //dprefclk + uint32_t CLK1_CLK3_CURRENT_CNT; //dcfclk + uint32_t CLK1_CLK3_DS_CNTL; //dcf_deep_sleep_divider + uint32_t CLK1_CLK3_ALLOW_DS; //dcf_deep_sleep_allow + + uint32_t CLK1_CLK0_BYPASS_CNTL; //dispclk bypass + uint32_t CLK1_CLK1_BYPASS_CNTL; //dppclk bypass + uint32_t CLK1_CLK2_BYPASS_CNTL; //dprefclk bypass + uint32_t CLK1_CLK3_BYPASS_CNTL; //dcfclk bypass - struct dc_clocks clks; +}; + +/* For dtn logging and debugging */ +struct clk_state_registers { + uint32_t CLK0_CLK8_CURRENT_CNT; //dcfclk + uint32_t CLK0_CLK8_DS_CNTL; //dcf_deep_sleep_divider + uint32_t CLK0_CLK8_ALLOW_DS; //dcf_deep_sleep_allow + uint32_t CLK0_CLK10_CURRENT_CNT; //dprefclk + uint32_t CLK0_CLK11_CURRENT_CNT; //dispclk +}; + +/* TODO: combine this with the above */ +struct clk_bypass { + uint32_t dcfclk_bypass; + uint32_t dispclk_pypass; + uint32_t dprefclk_bypass; +}; +/* + * This table is not contiguous, can have holes, each + * entry correspond to one set of WM. For example if + * we have 2 DPM and LPDDR, we will WM set A, B and + * D occupied, C will be emptry. + */ +struct wm_table { + union { + struct nv_wm_range_entry nv_entries[WM_SET_COUNT]; + struct wm_range_table_entry entries[WM_SET_COUNT]; + }; +}; + +struct dummy_pstate_entry { + unsigned int dram_speed_mts; + unsigned int dummy_pstate_latency_us; +}; + +struct clk_bw_params { + unsigned int vram_type; + unsigned int num_channels; + unsigned int dram_channel_width_bytes; + unsigned int dispclk_vco_khz; + unsigned int dc_mode_softmax_memclk; + unsigned int max_memclk_mhz; + struct clk_limit_table clk_table; + struct wm_table wm_table; + struct dummy_pstate_entry dummy_pstate_table[4]; + struct clk_limit_table_entry dc_mode_limit; +}; +/* Public interfaces */ + +struct clk_states { + uint32_t dprefclk_khz; }; struct clk_mgr_funcs { + /* + * This function should set new clocks based on the input "safe_to_lower". + * If safe_to_lower == false, then only clocks which are to be increased + * should changed. + * If safe_to_lower == true, then only clocks which are to be decreased + * should be changed. + */ void (*update_clocks)(struct clk_mgr *clk_mgr, struct dc_state *context, bool safe_to_lower); int (*get_dp_ref_clk_frequency)(struct clk_mgr *clk_mgr); + int (*get_dtb_ref_clk_frequency)(struct clk_mgr *clk_mgr); + + void (*set_low_power_state)(struct clk_mgr *clk_mgr); + void (*exit_low_power_state)(struct clk_mgr *clk_mgr); + bool (*is_ips_supported)(struct clk_mgr *clk_mgr); + + void (*init_clocks)(struct clk_mgr *clk_mgr); + + void (*dump_clk_registers)(struct clk_state_registers_and_bypass *regs_and_bypass, + struct clk_mgr *clk_mgr_base, struct clk_log_info *log_info); + + void (*enable_pme_wa) (struct clk_mgr *clk_mgr); + void (*get_clock)(struct clk_mgr *clk_mgr, + struct dc_state *context, + enum dc_clock_type clock_type, + struct dc_clock_config *clock_cfg); + + bool (*are_clock_states_equal) (struct dc_clocks *a, + struct dc_clocks *b); + void (*notify_wm_ranges)(struct clk_mgr *clk_mgr); + + /* Notify clk_mgr of a change in link rate, update phyclk frequency if necessary */ + void (*notify_link_rate_change)(struct clk_mgr *clk_mgr, struct dc_link *link); + /* + * Send message to PMFW to set hard min memclk frequency + * When current_mode = false, set DPM0 + * When current_mode = true, set required clock for current mode + */ + void (*set_hard_min_memclk)(struct clk_mgr *clk_mgr, bool current_mode); + + int (*get_hard_min_memclk)(struct clk_mgr *clk_mgr); + int (*get_hard_min_fclk)(struct clk_mgr *clk_mgr); + + /* Send message to PMFW to set hard max memclk frequency to highest DPM */ + void (*set_hard_max_memclk)(struct clk_mgr *clk_mgr); + + /* Custom set a memclk freq range*/ + void (*set_max_memclk)(struct clk_mgr *clk_mgr, unsigned int memclk_mhz); + void (*set_min_memclk)(struct clk_mgr *clk_mgr, unsigned int memclk_mhz); + + /* Get current memclk states from PMFW, update relevant structures */ + void (*get_memclk_states_from_smu)(struct clk_mgr *clk_mgr); + + /* Get SMU present */ + bool (*is_smu_present)(struct clk_mgr *clk_mgr); + + int (*get_dispclk_from_dentist)(struct clk_mgr *clk_mgr_base); + + bool (*is_dc_mode_present)(struct clk_mgr *clk_mgr); + + uint32_t (*set_smartmux_switch)(struct clk_mgr *clk_mgr, uint32_t pins_to_set); + + unsigned int (*get_max_clock_khz)(struct clk_mgr *clk_mgr_base, enum clk_type clk_type); }; +struct clk_mgr { + struct dc_context *ctx; + struct clk_mgr_funcs *funcs; + struct dc_clocks clks; + bool psr_allow_active_cache; + bool force_smu_not_present; + bool dc_mode_softmax_enabled; + int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes + int dp_dto_source_clock_in_khz; // Used to program DP DTO with ss adjustment on DCN314 + int dentist_vco_freq_khz; + struct clk_state_registers_and_bypass boot_snapshot; + struct clk_bw_params *bw_params; + struct pp_smu_wm_range_sets ranges; +}; + +/* forward declarations */ +struct dccg; + +struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg); + +void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr); + +void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr); + +void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr); + #endif /* __DAL_CLK_MGR_H__ */ 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 new file mode 100644 index 000000000000..bac8febad69a --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h @@ -0,0 +1,474 @@ +/* + * Copyright 2018 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 __DAL_CLK_MGR_INTERNAL_H__ +#define __DAL_CLK_MGR_INTERNAL_H__ + +#include "clk_mgr.h" +#include "dc.h" + +/* + * only thing needed from here is MEMORY_TYPE_MULTIPLIER_CZ, which is also + * used in resource, perhaps this should be defined somewhere more common. + */ +#include "resource.h" + + +/* Starting DID for each range */ +enum dentist_base_divider_id { + DENTIST_BASE_DID_1 = 0x08, + DENTIST_BASE_DID_2 = 0x40, + DENTIST_BASE_DID_3 = 0x60, + DENTIST_BASE_DID_4 = 0x7e, + DENTIST_MAX_DID = 0x7f +}; + +/* Starting point and step size for each divider range.*/ +enum dentist_divider_range { + DENTIST_DIVIDER_RANGE_1_START = 8, /* 2.00 */ + DENTIST_DIVIDER_RANGE_1_STEP = 1, /* 0.25 */ + DENTIST_DIVIDER_RANGE_2_START = 64, /* 16.00 */ + DENTIST_DIVIDER_RANGE_2_STEP = 2, /* 0.50 */ + DENTIST_DIVIDER_RANGE_3_START = 128, /* 32.00 */ + DENTIST_DIVIDER_RANGE_3_STEP = 4, /* 1.00 */ + DENTIST_DIVIDER_RANGE_4_START = 248, /* 62.00 */ + DENTIST_DIVIDER_RANGE_4_STEP = 264, /* 66.00 */ + DENTIST_DIVIDER_RANGE_SCALE_FACTOR = 4 +}; + +/* + *************************************************************************************** + ****************** Clock Manager Private Macros and Defines *************************** + *************************************************************************************** + */ + +/* Macros */ + +#define TO_CLK_MGR_INTERNAL(clk_mgr)\ + container_of(clk_mgr, struct clk_mgr_internal, base) + +#define CTX \ + clk_mgr->base.ctx + +#define DC_LOGGER \ + dc->ctx->logger + + + + +#define CLK_BASE(inst) \ + CLK_BASE_INNER(inst) + +#define CLK_SRI(reg_name, block, inst)\ + .reg_name = CLK_BASE(mm ## block ## _ ## inst ## _ ## reg_name ## _BASE_IDX) + \ + mm ## block ## _ ## inst ## _ ## reg_name + +#define CLK_COMMON_REG_LIST_DCE_BASE() \ + .DPREFCLK_CNTL = mmDPREFCLK_CNTL, \ + .DENTIST_DISPCLK_CNTL = mmDENTIST_DISPCLK_CNTL + +#if defined(CONFIG_DRM_AMD_DC_SI) +#define CLK_COMMON_REG_LIST_DCE60_BASE() \ + SR(DENTIST_DISPCLK_CNTL) +#endif + +#define CLK_COMMON_REG_LIST_DCN_BASE() \ + SR(DENTIST_DISPCLK_CNTL) + +#define CLK_COMMON_REG_LIST_DCN_201() \ + SR(DENTIST_DISPCLK_CNTL), \ + CLK_SRI(CLK4_CLK_PLL_REQ, CLK4, 0), \ + CLK_SRI(CLK4_CLK2_CURRENT_CNT, CLK4, 0) + +#define CLK_REG_LIST_NV10() \ + SR(DENTIST_DISPCLK_CNTL), \ + CLK_SRI(CLK3_CLK_PLL_REQ, CLK3, 0), \ + CLK_SRI(CLK3_CLK2_DFS_CNTL, CLK3, 0) + +#define CLK_REG_LIST_DCN3() \ + SR(DENTIST_DISPCLK_CNTL), \ + CLK_SRI(CLK0_CLK_PLL_REQ, CLK02, 0), \ + CLK_SRI(CLK0_CLK2_DFS_CNTL, CLK02, 0) + +#define CLK_SF(reg_name, field_name, post_fix)\ + .field_name = reg_name ## __ ## field_name ## post_fix + +#define CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) \ + CLK_SF(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, mask_sh), \ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, mask_sh) + +#if defined(CONFIG_DRM_AMD_DC_SI) +#define CLK_COMMON_MASK_SH_LIST_DCE60_COMMON_BASE(mask_sh) \ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh) +#endif + +#define CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh) \ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh) + +#define CLK_MASK_SH_LIST_RV1(mask_sh) \ + CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\ + CLK_SF(MP1_SMN_C2PMSG_67, CONTENT, mask_sh),\ + CLK_SF(MP1_SMN_C2PMSG_83, CONTENT, mask_sh),\ + CLK_SF(MP1_SMN_C2PMSG_91, CONTENT, mask_sh), + +#define CLK_COMMON_MASK_SH_LIST_DCN20_BASE(mask_sh) \ + CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, mask_sh),\ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, mask_sh) + +#define CLK_MASK_SH_LIST_NV10(mask_sh) \ + CLK_COMMON_MASK_SH_LIST_DCN20_BASE(mask_sh),\ + CLK_SF(CLK3_0_CLK3_CLK_PLL_REQ, FbMult_int, mask_sh),\ + CLK_SF(CLK3_0_CLK3_CLK_PLL_REQ, FbMult_frac, mask_sh) + +#define CLK_COMMON_MASK_SH_LIST_DCN201_BASE(mask_sh) \ + CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, mask_sh),\ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, mask_sh),\ + CLK_SF(CLK4_0_CLK4_CLK_PLL_REQ, FbMult_int, mask_sh) + +#define CLK_REG_LIST_DCN32() \ + SR(DENTIST_DISPCLK_CNTL), \ + CLK_SR_DCN32(CLK1_CLK_PLL_REQ), \ + CLK_SR_DCN32(CLK1_CLK0_DFS_CNTL), \ + CLK_SR_DCN32(CLK1_CLK1_DFS_CNTL), \ + CLK_SR_DCN32(CLK1_CLK2_DFS_CNTL), \ + CLK_SR_DCN32(CLK1_CLK3_DFS_CNTL), \ + CLK_SR_DCN32(CLK1_CLK4_DFS_CNTL), \ + CLK_SR_DCN32(CLK1_CLK0_CURRENT_CNT), \ + CLK_SR_DCN32(CLK1_CLK1_CURRENT_CNT), \ + CLK_SR_DCN32(CLK1_CLK2_CURRENT_CNT), \ + CLK_SR_DCN32(CLK1_CLK3_CURRENT_CNT), \ + CLK_SR_DCN32(CLK1_CLK4_CURRENT_CNT), \ + CLK_SR_DCN32(CLK4_CLK0_CURRENT_CNT) + +#define CLK_REG_LIST_DCN35() \ + CLK_SR_DCN35(CLK1_CLK_PLL_REQ), \ + CLK_SR_DCN35(CLK1_CLK0_DFS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK1_DFS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK2_DFS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK3_DFS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK4_DFS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK5_DFS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK0_CURRENT_CNT), \ + CLK_SR_DCN35(CLK1_CLK1_CURRENT_CNT), \ + CLK_SR_DCN35(CLK1_CLK2_CURRENT_CNT), \ + CLK_SR_DCN35(CLK1_CLK3_CURRENT_CNT), \ + CLK_SR_DCN35(CLK1_CLK4_CURRENT_CNT), \ + CLK_SR_DCN35(CLK1_CLK5_CURRENT_CNT), \ + CLK_SR_DCN35(CLK1_CLK0_BYPASS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK1_BYPASS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK2_BYPASS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK3_BYPASS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK4_BYPASS_CNTL),\ + CLK_SR_DCN35(CLK1_CLK5_BYPASS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK0_DS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK1_DS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK2_DS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK3_DS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK4_DS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK5_DS_CNTL), \ + CLK_SR_DCN35(CLK1_CLK0_ALLOW_DS), \ + CLK_SR_DCN35(CLK1_CLK1_ALLOW_DS), \ + CLK_SR_DCN35(CLK1_CLK2_ALLOW_DS), \ + CLK_SR_DCN35(CLK1_CLK3_ALLOW_DS), \ + CLK_SR_DCN35(CLK1_CLK4_ALLOW_DS), \ + CLK_SR_DCN35(CLK1_CLK5_ALLOW_DS), \ + CLK_SR_DCN35(CLK5_spll_field_8), \ + CLK_SR_DCN35(CLK6_spll_field_8), \ + SR(DENTIST_DISPCLK_CNTL), \ + +#define CLK_COMMON_MASK_SH_LIST_DCN32(mask_sh) \ + CLK_COMMON_MASK_SH_LIST_DCN20_BASE(mask_sh),\ + CLK_SF(CLK1_CLK_PLL_REQ, FbMult_int, mask_sh),\ + CLK_SF(CLK1_CLK_PLL_REQ, FbMult_frac, mask_sh) + +#define CLK_REG_LIST_DCN321() \ + SR(DENTIST_DISPCLK_CNTL), \ + CLK_SR_DCN321(CLK0_CLK_PLL_REQ, CLK01, 0), \ + CLK_SR_DCN321(CLK0_CLK0_DFS_CNTL, CLK01, 0), \ + CLK_SR_DCN321(CLK0_CLK1_DFS_CNTL, CLK01, 0), \ + CLK_SR_DCN321(CLK0_CLK2_DFS_CNTL, CLK01, 0), \ + CLK_SR_DCN321(CLK0_CLK3_DFS_CNTL, CLK01, 0), \ + CLK_SR_DCN321(CLK0_CLK4_DFS_CNTL, CLK01, 0) + +#define CLK_COMMON_MASK_SH_LIST_DCN321(mask_sh) \ + CLK_COMMON_MASK_SH_LIST_DCN20_BASE(mask_sh),\ + CLK_SF(CLK0_CLK_PLL_REQ, FbMult_int, mask_sh),\ + CLK_SF(CLK0_CLK_PLL_REQ, FbMult_frac, mask_sh) + +#define CLK_REG_LIST_DCN401() \ + SR(DENTIST_DISPCLK_CNTL), \ + CLK_SR_DCN401(CLK0_CLK_PLL_REQ, CLK01, 0), \ + CLK_SR_DCN401(CLK0_CLK0_DFS_CNTL, CLK01, 0), \ + CLK_SR_DCN401(CLK0_CLK1_DFS_CNTL, CLK01, 0), \ + CLK_SR_DCN401(CLK0_CLK2_DFS_CNTL, CLK01, 0), \ + CLK_SR_DCN401(CLK0_CLK3_DFS_CNTL, CLK01, 0), \ + CLK_SR_DCN401(CLK0_CLK4_DFS_CNTL, CLK01, 0), \ + CLK_SR_DCN401(CLK2_CLK2_DFS_CNTL, CLK20, 0) + +#define CLK_COMMON_MASK_SH_LIST_DCN401(mask_sh) \ + CLK_COMMON_MASK_SH_LIST_DCN321(mask_sh) + +#define CLK_REG_FIELD_LIST(type) \ + type DPREFCLK_SRC_SEL; \ + type DENTIST_DPREFCLK_WDIVIDER; \ + type DENTIST_DISPCLK_WDIVIDER; \ + type DENTIST_DISPCLK_CHG_DONE; + +#define CLK20_REG_FIELD_LIST(type) \ + type DENTIST_DPPCLK_WDIVIDER; \ + type DENTIST_DPPCLK_CHG_DONE; \ + type FbMult_int; \ + type FbMult_frac; + +/* + *************************************************************************************** + ****************** Clock Manager Private Structures *********************************** + *************************************************************************************** + */ + +struct clk_mgr_registers { + uint32_t DPREFCLK_CNTL; + uint32_t DENTIST_DISPCLK_CNTL; + + uint32_t CLK4_CLK2_CURRENT_CNT; + uint32_t CLK4_CLK_PLL_REQ; + + uint32_t CLK4_CLK0_CURRENT_CNT; + + uint32_t CLK3_CLK2_DFS_CNTL; + uint32_t CLK3_CLK_PLL_REQ; + + uint32_t CLK0_CLK2_DFS_CNTL; + uint32_t CLK0_CLK_PLL_REQ; + + uint32_t CLK1_CLK_PLL_REQ; + uint32_t CLK1_CLK0_DFS_CNTL; + uint32_t CLK1_CLK1_DFS_CNTL; + uint32_t CLK1_CLK2_DFS_CNTL; + uint32_t CLK1_CLK3_DFS_CNTL; + uint32_t CLK1_CLK4_DFS_CNTL; + uint32_t CLK1_CLK5_DFS_CNTL; + uint32_t CLK2_CLK2_DFS_CNTL; + + uint32_t CLK1_CLK0_CURRENT_CNT; + uint32_t CLK1_CLK1_CURRENT_CNT; + uint32_t CLK1_CLK2_CURRENT_CNT; + uint32_t CLK1_CLK3_CURRENT_CNT; + uint32_t CLK1_CLK4_CURRENT_CNT; + uint32_t CLK1_CLK5_CURRENT_CNT; + + uint32_t CLK0_CLK0_DFS_CNTL; + uint32_t CLK0_CLK1_DFS_CNTL; + uint32_t CLK0_CLK3_DFS_CNTL; + uint32_t CLK0_CLK4_DFS_CNTL; + uint32_t CLK1_CLK0_BYPASS_CNTL; + uint32_t CLK1_CLK1_BYPASS_CNTL; + uint32_t CLK1_CLK2_BYPASS_CNTL; + uint32_t CLK1_CLK3_BYPASS_CNTL; + uint32_t CLK1_CLK4_BYPASS_CNTL; + uint32_t CLK1_CLK5_BYPASS_CNTL; + + uint32_t CLK1_CLK0_DS_CNTL; + uint32_t CLK1_CLK1_DS_CNTL; + uint32_t CLK1_CLK2_DS_CNTL; + uint32_t CLK1_CLK3_DS_CNTL; + uint32_t CLK1_CLK4_DS_CNTL; + uint32_t CLK1_CLK5_DS_CNTL; + + uint32_t CLK1_CLK0_ALLOW_DS; + uint32_t CLK1_CLK1_ALLOW_DS; + uint32_t CLK1_CLK2_ALLOW_DS; + uint32_t CLK1_CLK3_ALLOW_DS; + uint32_t CLK1_CLK4_ALLOW_DS; + uint32_t CLK1_CLK5_ALLOW_DS; + uint32_t CLK5_spll_field_8; + uint32_t CLK6_spll_field_8; +}; + +struct clk_mgr_shift { + CLK_REG_FIELD_LIST(uint8_t) + CLK20_REG_FIELD_LIST(uint8_t) +}; + +struct clk_mgr_mask { + CLK_REG_FIELD_LIST(uint32_t) + CLK20_REG_FIELD_LIST(uint32_t) +}; + +enum clock_type { + clock_type_dispclk = 1, + clock_type_dcfclk, + clock_type_socclk, + clock_type_pixelclk, + clock_type_phyclk, + clock_type_dppclk, + clock_type_fclk, + clock_type_dcfdsclk, + clock_type_dscclk, + clock_type_uclk, + clock_type_dramclk, +}; + + +struct state_dependent_clocks { + int display_clk_khz; + int pixel_clk_khz; +}; + +struct clk_mgr_internal { + struct clk_mgr base; + int smu_ver; + struct pp_smu_funcs *pp_smu; + struct clk_mgr_internal_funcs *funcs; + + struct dccg *dccg; + + /* + * For backwards compatbility with previous implementation + * TODO: remove these after everything transitions to new pattern + * Rationale is that clk registers change a lot across DCE versions + * and a shared data structure doesn't really make sense. + */ + const struct clk_mgr_registers *regs; + const struct clk_mgr_shift *clk_mgr_shift; + const struct clk_mgr_mask *clk_mgr_mask; + + struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES]; + + /*TODO: figure out which of the below fields should be here vs in asic specific portion */ + /* Cache the status of DFS-bypass feature*/ + bool dfs_bypass_enabled; + /* True if the DFS-bypass feature is enabled and active. */ + bool dfs_bypass_active; + + uint32_t dfs_ref_freq_khz; + /* + * Cache the display clock returned by VBIOS if DFS-bypass is enabled. + * This is basically "Crystal Frequency In KHz" (XTALIN) frequency + */ + int dfs_bypass_disp_clk; + + /** + * @ss_on_dprefclk: + * + * True if spread spectrum is enabled on the DP ref clock. + */ + bool ss_on_dprefclk; + + /** + * @xgmi_enabled: + * + * True if xGMI is enabled. On VG20, both audio and display clocks need + * to be adjusted with the WAFL link's SS info if xGMI is enabled. + */ + bool xgmi_enabled; + + /** + * @dprefclk_ss_percentage: + * + * DPREFCLK SS percentage (if down-spread enabled). + * + * Note that if XGMI is enabled, the SS info (percentage and divider) + * from the WAFL link is used instead. This is decided during + * dce_clk_mgr initialization. + */ + int dprefclk_ss_percentage; + + /** + * @dprefclk_ss_divider: + * + * DPREFCLK SS percentage Divider (100 or 1000). + */ + int dprefclk_ss_divider; + + enum dm_pp_clocks_state max_clks_state; + enum dm_pp_clocks_state cur_min_clks_state; + bool periodic_retraining_disabled; + + unsigned int cur_phyclk_req_table[MAX_LINKS]; + + bool smu_present; + void *wm_range_table; + long long wm_range_table_addr; + + bool dpm_present; + bool pme_trigger_pending; +}; + +struct clk_mgr_internal_funcs { + int (*set_dispclk)(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz); + int (*set_dprefclk)(struct clk_mgr_internal *clk_mgr); +}; + + +/* + *************************************************************************************** + ****************** Clock Manager Level Helper functions ******************************* + *************************************************************************************** + */ + + +static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_clk) +{ + return ((safe_to_lower && calc_clk < cur_clk) || calc_clk > cur_clk); +} + +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 && safe_to_lower) + return true; + else if (!calc_support && !safe_to_lower) + return true; + } + + return false; +} + +static inline int khz_to_mhz_ceil(int khz) +{ + return (khz + 999) / 1000; +} + +static inline int khz_to_mhz_floor(int khz) +{ + return khz / 1000; +} + +int clk_mgr_helper_get_active_display_cnt( + struct dc *dc, + struct dc_state *context); + +int clk_mgr_helper_get_active_plane_cnt( + struct dc *dc, + struct dc_state *context); + + + +#endif //__DAL_CLK_MGR_INTERNAL_H__ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/cursor_reg_cache.h b/drivers/gpu/drm/amd/display/dc/inc/hw/cursor_reg_cache.h new file mode 100644 index 000000000000..7ce2f417f86a --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/cursor_reg_cache.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2022 Advanced Micro Devices, Inc. All rights reserved. */ + +#ifndef __DAL_CURSOR_CACHE_H__ +#define __DAL_CURSOR_CACHE_H__ + +union reg_cursor_control_cfg { + struct { + uint32_t cur_enable: 1; + uint32_t reser0: 3; + uint32_t cur_2x_magnify: 1; + uint32_t reser1: 3; + uint32_t mode: 3; + uint32_t reser2: 5; + uint32_t pitch: 2; + uint32_t reser3: 6; + uint32_t line_per_chunk: 5; + uint32_t reser4: 3; + } bits; + uint32_t raw; +}; +struct cursor_position_cache_hubp { + union reg_cursor_control_cfg cur_ctl; + union reg_position_cfg { + struct { + uint32_t x_pos: 16; + uint32_t y_pos: 16; + } bits; + uint32_t raw; + } position; + union reg_hot_spot_cfg { + struct { + uint32_t x_hot: 16; + uint32_t y_hot: 16; + } bits; + uint32_t raw; + } hot_spot; + union reg_dst_offset_cfg { + struct { + uint32_t dst_x_offset: 13; + uint32_t reserved: 19; + } bits; + uint32_t raw; + } dst_offset; +}; + +struct cursor_attribute_cache_hubp { + uint32_t SURFACE_ADDR_HIGH; + uint32_t SURFACE_ADDR; + union reg_cursor_control_cfg cur_ctl; + union reg_cursor_size_cfg { + struct { + uint32_t width: 16; + uint32_t height: 16; + } bits; + uint32_t raw; + } size; + union reg_cursor_settings_cfg { + struct { + uint32_t dst_y_offset: 8; + uint32_t chunk_hdl_adjust: 2; + uint32_t reserved: 22; + } bits; + uint32_t raw; + } settings; +}; + +struct cursor_rect { + uint32_t x; + uint32_t y; + uint32_t w; + uint32_t h; +}; + +union reg_cur0_control_cfg { + struct { + uint32_t cur0_enable: 1; + uint32_t expansion_mode: 1; + uint32_t reser0: 1; + uint32_t cur0_rom_en: 1; + uint32_t mode: 3; + uint32_t reserved: 25; + } bits; + uint32_t raw; +}; + +struct cursor_position_cache_dpp { + union reg_cur0_control_cfg cur0_ctl; +}; + +struct cursor_attribute_cache_dpp { + union reg_cur0_control_cfg cur0_ctl; + union reg_cur0_fp_scale_bias { + struct { + uint32_t fp_bias: 16; + uint32_t fp_scale: 16; + } bits; + uint32_t raw; + } fp_scale_bias; + union reg_cur0_fp_scale_bias_g_y { + struct { + uint32_t fp_bias_g_y: 16; + uint32_t fp_scale_g_y: 16; + } bits; + uint32_t raw; + } fp_scale_bias_g_y; + union reg_cur0_fp_scale_bias_rb_crcb { + struct { + uint32_t fp_bias_rb_crcb: 16; + uint32_t fp_scale_rb_crcb: 16; + } bits; + uint32_t raw; + } fp_scale_bias_rb_crcb; +}; + +struct cursor_attributes_cfg { + struct cursor_attribute_cache_hubp aHubp; + struct cursor_attribute_cache_dpp aDpp; +}; + +#endif 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 95a56d012626..500a601e99b5 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h @@ -27,18 +27,312 @@ #define __DAL_DCCG_H__ #include "dc_types.h" +#include "hw_shared.h" + +enum phyd32clk_clock_source { + PHYD32CLKA, + PHYD32CLKB, + PHYD32CLKC, + PHYD32CLKD, + PHYD32CLKE, + PHYD32CLKF, + PHYD32CLKG, +}; + +enum physymclk_clock_source { + PHYSYMCLK_FORCE_SRC_SYMCLK, // Select symclk as source of clock which is output to PHY through DCIO. + PHYSYMCLK_FORCE_SRC_PHYD18CLK, // Select phyd18clk as the source of clock which is output to PHY through DCIO. + PHYSYMCLK_FORCE_SRC_PHYD32CLK, // Select phyd32clk as the source of clock which is output to PHY through DCIO. +}; + +enum streamclk_source { + REFCLK, // Selects REFCLK as source for hdmistreamclk. + DTBCLK0, // Selects DTBCLK0 as source for hdmistreamclk. + DPREFCLK, // Selects DPREFCLK as source for hdmistreamclk +}; + +enum dentist_dispclk_change_mode { + DISPCLK_CHANGE_MODE_IMMEDIATE, + DISPCLK_CHANGE_MODE_RAMPING, +}; + +struct dp_dto_params { + int otg_inst; + enum signal_type signal; + enum streamclk_source clk_src; + uint64_t pixclk_hz; + uint64_t refclk_hz; +}; + +enum pixel_rate_div { + PIXEL_RATE_DIV_BY_1 = 0, + PIXEL_RATE_DIV_BY_2 = 1, + PIXEL_RATE_DIV_BY_4 = 3, + PIXEL_RATE_DIV_NA = 0xF +}; + +struct dcn_dccg_reg_state { + uint32_t dc_mem_global_pwr_req_cntl; + uint32_t dccg_audio_dtbclk_dto_modulo; + uint32_t dccg_audio_dtbclk_dto_phase; + uint32_t dccg_audio_dto_source; + uint32_t dccg_audio_dto0_module; + uint32_t dccg_audio_dto0_phase; + uint32_t dccg_audio_dto1_module; + uint32_t dccg_audio_dto1_phase; + uint32_t dccg_cac_status; + uint32_t dccg_cac_status2; + uint32_t dccg_disp_cntl_reg; + uint32_t dccg_ds_cntl; + uint32_t dccg_ds_dto_incr; + uint32_t dccg_ds_dto_modulo; + uint32_t dccg_ds_hw_cal_interval; + uint32_t dccg_gate_disable_cntl; + uint32_t dccg_gate_disable_cntl2; + uint32_t dccg_gate_disable_cntl3; + uint32_t dccg_gate_disable_cntl4; + uint32_t dccg_gate_disable_cntl5; + uint32_t dccg_gate_disable_cntl6; + uint32_t dccg_global_fgcg_rep_cntl; + uint32_t dccg_gtc_cntl; + uint32_t dccg_gtc_current; + uint32_t dccg_gtc_dto_incr; + uint32_t dccg_gtc_dto_modulo; + uint32_t dccg_perfmon_cntl; + uint32_t dccg_perfmon_cntl2; + uint32_t dccg_soft_reset; + uint32_t dccg_test_clk_sel; + uint32_t dccg_vsync_cnt_ctrl; + uint32_t dccg_vsync_cnt_int_ctrl; + uint32_t dccg_vsync_otg0_latch_value; + uint32_t dccg_vsync_otg1_latch_value; + uint32_t dccg_vsync_otg2_latch_value; + uint32_t dccg_vsync_otg3_latch_value; + uint32_t dccg_vsync_otg4_latch_value; + uint32_t dccg_vsync_otg5_latch_value; + uint32_t dispclk_cgtt_blk_ctrl_reg; + uint32_t dispclk_freq_change_cntl; + uint32_t dp_dto_dbuf_en; + uint32_t dp_dto0_modulo; + uint32_t dp_dto0_phase; + uint32_t dp_dto1_modulo; + uint32_t dp_dto1_phase; + uint32_t dp_dto2_modulo; + uint32_t dp_dto2_phase; + uint32_t dp_dto3_modulo; + uint32_t dp_dto3_phase; + uint32_t dpiaclk_540m_dto_modulo; + uint32_t dpiaclk_540m_dto_phase; + uint32_t dpiaclk_810m_dto_modulo; + uint32_t dpiaclk_810m_dto_phase; + uint32_t dpiaclk_dto_cntl; + uint32_t dpiasymclk_cntl; + uint32_t dppclk_cgtt_blk_ctrl_reg; + uint32_t dppclk_ctrl; + uint32_t dppclk_dto_ctrl; + uint32_t dppclk0_dto_param; + uint32_t dppclk1_dto_param; + uint32_t dppclk2_dto_param; + uint32_t dppclk3_dto_param; + uint32_t dprefclk_cgtt_blk_ctrl_reg; + uint32_t dprefclk_cntl; + uint32_t dpstreamclk_cntl; + uint32_t dscclk_dto_ctrl; + uint32_t dscclk0_dto_param; + uint32_t dscclk1_dto_param; + uint32_t dscclk2_dto_param; + uint32_t dscclk3_dto_param; + uint32_t dtbclk_dto_dbuf_en; + uint32_t dtbclk_dto0_modulo; + uint32_t dtbclk_dto0_phase; + uint32_t dtbclk_dto1_modulo; + uint32_t dtbclk_dto1_phase; + uint32_t dtbclk_dto2_modulo; + uint32_t dtbclk_dto2_phase; + uint32_t dtbclk_dto3_modulo; + uint32_t dtbclk_dto3_phase; + uint32_t dtbclk_p_cntl; + uint32_t force_symclk_disable; + uint32_t hdmicharclk0_clock_cntl; + uint32_t hdmistreamclk_cntl; + uint32_t hdmistreamclk0_dto_param; + uint32_t microsecond_time_base_div; + uint32_t millisecond_time_base_div; + uint32_t otg_pixel_rate_div; + uint32_t otg0_phypll_pixel_rate_cntl; + uint32_t otg0_pixel_rate_cntl; + uint32_t otg1_phypll_pixel_rate_cntl; + uint32_t otg1_pixel_rate_cntl; + uint32_t otg2_phypll_pixel_rate_cntl; + uint32_t otg2_pixel_rate_cntl; + uint32_t otg3_phypll_pixel_rate_cntl; + uint32_t otg3_pixel_rate_cntl; + uint32_t phyasymclk_clock_cntl; + uint32_t phybsymclk_clock_cntl; + uint32_t phycsymclk_clock_cntl; + uint32_t phydsymclk_clock_cntl; + uint32_t phyesymclk_clock_cntl; + uint32_t phyplla_pixclk_resync_cntl; + uint32_t phypllb_pixclk_resync_cntl; + uint32_t phypllc_pixclk_resync_cntl; + uint32_t phyplld_pixclk_resync_cntl; + uint32_t phyplle_pixclk_resync_cntl; + uint32_t refclk_cgtt_blk_ctrl_reg; + uint32_t socclk_cgtt_blk_ctrl_reg; + uint32_t symclk_cgtt_blk_ctrl_reg; + uint32_t symclk_psp_cntl; + uint32_t symclk32_le_cntl; + uint32_t symclk32_se_cntl; + uint32_t symclka_clock_enable; + uint32_t symclkb_clock_enable; + uint32_t symclkc_clock_enable; + uint32_t symclkd_clock_enable; + uint32_t symclke_clock_enable; +}; struct dccg { struct dc_context *ctx; const struct dccg_funcs *funcs; - + int pipe_dppclk_khz[MAX_PIPES]; int ref_dppclk; + bool dpp_clock_gated[MAX_PIPES]; + //int dtbclk_khz[MAX_PIPES];/* TODO needs to be removed */ + //int audio_dtbclk_khz;/* TODO needs to be removed */ + //int ref_dtbclk_khz;/* TODO needs to be removed */ +}; +struct dtbclk_dto_params { + const struct dc_crtc_timing *timing; + int otg_inst; + int pixclk_khz; + int req_audio_dtbclk_khz; + int num_odm_segments; + int ref_dtbclk_khz; + bool is_hdmi; }; struct dccg_funcs { void (*update_dpp_dto)(struct dccg *dccg, int dpp_inst, int req_dppclk); + void (*get_dccg_ref_freq)(struct dccg *dccg, + unsigned int xtalin_freq_inKhz, + unsigned int *dccg_ref_freq_inKhz); + void (*set_fifo_errdet_ovr_en)(struct dccg *dccg, + bool en); + void (*otg_add_pixel)(struct dccg *dccg, + uint32_t otg_inst); + void (*otg_drop_pixel)(struct dccg *dccg, + uint32_t otg_inst); + void (*dccg_init)(struct dccg *dccg); + void (*set_dpstreamclk_root_clock_gating)( + struct dccg *dccg, + int dp_hpo_inst, + bool enable); + + void (*set_dpstreamclk)( + struct dccg *dccg, + enum streamclk_source src, + int otg_inst, + int dp_hpo_inst); + + void (*enable_symclk32_se)( + struct dccg *dccg, + int hpo_se_inst, + enum phyd32clk_clock_source phyd32clk); + + void (*disable_symclk32_se)( + struct dccg *dccg, + int hpo_se_inst); + + void (*enable_symclk32_le)( + struct dccg *dccg, + int hpo_le_inst, + enum phyd32clk_clock_source phyd32clk); + + void (*disable_symclk32_le)( + 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, + enum physymclk_clock_source clk_src, + bool force_enable); + + void (*set_physymclk_root_clock_gating)( + struct dccg *dccg, + int phy_inst, + bool enable); + + void (*set_dtbclk_dto)( + struct dccg *dccg, + const struct dtbclk_dto_params *params); + + void (*set_audio_dtbclk_dto)( + struct dccg *dccg, + const struct dtbclk_dto_params *params); + + void (*set_dispclk_change_mode)( + struct dccg *dccg, + enum dentist_dispclk_change_mode change_mode); + + void (*disable_dsc)( + struct dccg *dccg, + int inst); + + void (*enable_dsc)( + struct dccg *dccg, + int inst); + + void (*set_pixel_rate_div)(struct dccg *dccg, + uint32_t otg_inst, + enum pixel_rate_div k1, + enum pixel_rate_div k2); + + void (*get_pixel_rate_div)(struct dccg *dccg, + uint32_t otg_inst, + uint32_t *div_factor1, + uint32_t *div_factor2); + + void (*set_valid_pixel_rate)( + struct dccg *dccg, + int ref_dtbclk_khz, + int otg_inst, + int pixclk_khz); + + void (*trigger_dio_fifo_resync)( + struct dccg *dccg); + + void (*dpp_root_clock_control)( + 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); + void (*set_dp_dto)( + struct dccg *dccg, + const struct dp_dto_params *params); + void (*set_dtbclk_p_src)( + struct dccg *dccg, + enum streamclk_source src, + uint32_t otg_inst); + void (*set_dto_dscclk)(struct dccg *dccg, uint32_t dsc_inst, uint32_t num_slices_h); + void (*set_ref_dscclk)(struct dccg *dccg, uint32_t dsc_inst); + void (*dccg_root_gate_disable_control)(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating); + void (*dccg_read_reg_state)(struct dccg *dccg, struct dcn_dccg_reg_state *dccg_reg_state); }; #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 02f757dd70d4..1ddfa30411c8 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h @@ -26,11 +26,24 @@ #ifndef __DAL_DCHUBBUB_H__ #define __DAL_DCHUBBUB_H__ +/** + * DOC: overview + * + * There is only one common DCHUBBUB. It contains the common request and return + * blocks for the Data Fabric Interface that are not clock/power gated. + */ + +#include "dc/dc_hw_types.h" enum dcc_control { dcc_control__256_256_xxx, dcc_control__128_128_xxx, dcc_control__256_64_64, + dcc_control__256_128_128, + dcc_control__256_256, + dcc_control__256_128, + dcc_control__256_64, + }; enum segment_order { @@ -39,12 +52,125 @@ enum segment_order { segment_order__non_contiguous, }; +struct dcn_hubbub_wm_set { + uint32_t wm_set; + uint32_t data_urgent; + uint32_t pte_meta_urgent; + uint32_t sr_enter; + uint32_t sr_exit; + 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 { + struct dcn_hubbub_wm_set sets[4]; +}; + +enum dcn_hubbub_page_table_depth { + DCN_PAGE_TABLE_DEPTH_1_LEVEL, + DCN_PAGE_TABLE_DEPTH_2_LEVEL, + DCN_PAGE_TABLE_DEPTH_3_LEVEL, + DCN_PAGE_TABLE_DEPTH_4_LEVEL +}; + +enum dcn_hubbub_page_table_block_size { + DCN_PAGE_TABLE_BLOCK_SIZE_4KB = 0, + DCN_PAGE_TABLE_BLOCK_SIZE_8KB = 1, + DCN_PAGE_TABLE_BLOCK_SIZE_16KB = 2, + DCN_PAGE_TABLE_BLOCK_SIZE_32KB = 3, + DCN_PAGE_TABLE_BLOCK_SIZE_64KB = 4, + DCN_PAGE_TABLE_BLOCK_SIZE_128KB = 5, + DCN_PAGE_TABLE_BLOCK_SIZE_256KB = 6, + DCN_PAGE_TABLE_BLOCK_SIZE_512KB = 7, + DCN_PAGE_TABLE_BLOCK_SIZE_1024KB = 8, + DCN_PAGE_TABLE_BLOCK_SIZE_2048KB = 9 +}; + +struct dcn_hubbub_phys_addr_config { + struct { + uint64_t fb_top; + uint64_t fb_offset; + uint64_t fb_base; + uint64_t agp_top; + uint64_t agp_bot; + uint64_t agp_base; + } system_aperture; + + struct { + uint64_t page_table_start_addr; + uint64_t page_table_end_addr; + uint64_t page_table_base_addr; + } gart_config; + + uint64_t page_table_default_page_addr; +}; + +struct dcn_hubbub_virt_addr_config { + uint64_t page_table_start_addr; + uint64_t page_table_end_addr; + enum dcn_hubbub_page_table_block_size page_table_block_size; + enum dcn_hubbub_page_table_depth page_table_depth; + uint64_t page_table_base_addr; +}; + +struct hubbub_addr_config { + struct dcn_hubbub_phys_addr_config pa_config; + struct dcn_hubbub_virt_addr_config va_config; + struct { + uint64_t aperture_check_fault; + uint64_t generic_fault; + } default_addrs; +}; + +struct dcn_hubbub_state { + uint32_t vm_fault_addr_msb; + uint32_t vm_fault_addr_lsb; + uint32_t vm_error_status; + uint32_t vm_error_vmid; + uint32_t vm_error_pipe; + uint32_t vm_error_mode; + uint32_t test_debug_data; + uint32_t watermark_change_cntl; + uint32_t dram_state_cntl; +}; + +struct dcn_hubbub_reg_state { + uint32_t det0_ctrl; + uint32_t det1_ctrl; + uint32_t det2_ctrl; + uint32_t det3_ctrl; + uint32_t compbuf_ctrl; +}; + +struct hubbub_system_latencies { + uint32_t max_latency_ns; + uint32_t avg_latency_ns; + uint32_t min_latency_ns; +}; + +struct hubbub_urgent_latency_params { + uint32_t refclk_mhz; + uint32_t t_win_ns; + uint32_t bandwidth_mbps; + uint32_t bw_factor_x1000; +}; struct hubbub_funcs { void (*update_dchub)( struct hubbub *hubbub, struct dchub_init_data *dh_data); + int (*init_dchub_sys_ctx)( + struct hubbub *hubbub, + struct dcn_hubbub_phys_addr_config *pa_config); + void (*init_vm_ctx)( + struct hubbub *hubbub, + struct dcn_hubbub_virt_addr_config *va_config, + int vmid); + bool (*get_dcc_compression_cap)(struct hubbub *hubbub, const struct dc_dcc_surface_param *input, struct dc_surface_dcc_cap *output); @@ -55,10 +181,116 @@ struct hubbub_funcs { enum segment_order *segment_order_horz, enum segment_order *segment_order_vert); + bool (*dcc_support_swizzle_addr3)( + enum swizzle_mode_addr3_values swizzle, + unsigned int plane_pitch, + unsigned int bytes_per_element, + enum segment_order *segment_order_horz, + enum segment_order *segment_order_vert); + + bool (*dcc_support_pixel_format_plane0_plane1)( + enum surface_pixel_format format, + unsigned int *plane0_bpe, + unsigned int *plane1_bpe); bool (*dcc_support_pixel_format)( enum surface_pixel_format format, unsigned int *bytes_per_element); + + void (*wm_read_state)(struct hubbub *hubbub, + struct dcn_hubbub_wm *wm); + + void (*get_dchub_ref_freq)(struct hubbub *hubbub, + unsigned int dccg_ref_freq_inKhz, + unsigned int *dchub_ref_freq_inKhz); + + bool (*program_watermarks)( + struct hubbub *hubbub, + union dcn_watermark_set *watermarks, + unsigned int refclk_mhz, + bool safe_to_lower); + + bool (*is_allow_self_refresh_enabled)(struct hubbub *hubbub); + void (*allow_self_refresh_control)(struct hubbub *hubbub, bool allow); + + bool (*verify_allow_pstate_change_high)(struct hubbub *hubbub); + + void (*apply_DEDCN21_147_wa)(struct hubbub *hubbub); + + void (*force_wm_propagate_to_pipes)(struct hubbub *hubbub); + + void (*hubbub_read_state)(struct hubbub *hubbub, struct dcn_hubbub_state *hubbub_state); + + void (*force_pstate_change_control)(struct hubbub *hubbub, bool force, bool allow); + + void (*init_watermarks)(struct hubbub *hubbub); + + void (*hubbub_read_reg_state)(struct hubbub *hubbub, struct dcn_hubbub_reg_state *hubbub_reg_state); + + /** + * @program_det_size: + * + * DE-Tile buffers (DET) is a memory that is used to convert the tiled + * data into linear, which the rest of the display can use to generate + * the graphics output. One of the main features of this component is + * that each pipe has a configurable DET buffer which means that when a + * pipe is not enabled, the device can assign the memory to other + * enabled pipes to try to be more efficient. + * + * DET logic is handled by dchubbub. Some ASICs provide a feature named + * Configurable Return Buffer (CRB) segments which can be allocated to + * compressed or detiled buffers. + */ + void (*program_det_size)(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_in_kbyte); + void (*wait_for_det_apply)(struct hubbub *hubbub, int hubp_inst); + void (*program_compbuf_size)(struct hubbub *hubbub, unsigned compbuf_size_kb, bool safe_to_increase); + void (*init_crb)(struct hubbub *hubbub); + void (*force_usr_retraining_allow)(struct hubbub *hubbub, bool allow); + void (*set_request_limit)(struct hubbub *hubbub, int memory_channel_count, int words_per_channel); + void (*dchubbub_init)(struct hubbub *hubbub); + void (*get_mall_en)(struct hubbub *hubbub, unsigned int *mall_in_use); + void (*program_det_segments)(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_seg); + void (*program_compbuf_segments)(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase); + void (*wait_for_det_update)(struct hubbub *hubbub, int hubp_inst); + bool (*program_arbiter)(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs, bool safe_to_lower); + void (*dchvm_init)(struct hubbub *hubbub); + + struct hubbub_perfmon_funcs { + void (*reset)(struct hubbub *hubbub); + void (*start_measuring_max_memory_latency_ns)( + struct hubbub *hubbub); + uint32_t (*get_max_memory_latency_ns)(struct hubbub *hubbub, + uint32_t refclk_mhz, uint32_t *sample_count); + void (*start_measuring_average_memory_latency_ns)( + struct hubbub *hubbub); + uint32_t (*get_average_memory_latency_ns)(struct hubbub *hubbub, + uint32_t refclk_mhz, uint32_t *sample_count); + void (*start_measuring_urgent_ramp_latency_ns)( + struct hubbub *hubbub, + const struct hubbub_urgent_latency_params *params); + uint32_t (*get_urgent_ramp_latency_ns)(struct hubbub *hubbub, + uint32_t refclk_mhz); + void (*start_measuring_unbounded_bandwidth_mbps)( + struct hubbub *hubbub); + uint32_t (*get_unbounded_bandwidth_mbps)(struct hubbub *hubbub, + uint32_t refclk_mhz, uint32_t *duration_ns); + void (*start_measuring_average_bandwidth_mbps)( + struct hubbub *hubbub); + uint32_t (*get_average_bandwidth_mbps)(struct hubbub *hubbub, + uint32_t refclk_mhz, uint32_t min_duration_ns, + uint32_t *duration_ns); + } perfmon; + + struct hubbub_qos_funcs { + void (*force_display_nominal_profile)(struct hubbub *hubbub); + void (*force_display_urgent_profile)(struct hubbub *hubbub); + void (*reset_display_qos_profile)(struct hubbub *hubbub); + } qos; }; +struct hubbub { + const struct hubbub_funcs *funcs; + struct dc_context *ctx; + bool riommu_active; +}; #endif 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 cb85eaa9857f..de3113ecbc77 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h @@ -27,16 +27,22 @@ #include "dm_services_types.h" +/* If HW itself ever powered down it will be 0. + * fwDmcuInit will write to 1. + * Driver will only call MCP init if current state is 1, + * and the MCP command will transition this to 2. + */ enum dmcu_state { - DMCU_NOT_INITIALIZED = 0, - DMCU_RUNNING = 1 + DMCU_UNLOADED = 0, + DMCU_LOADED_UNINITIALIZED = 1, + DMCU_RUNNING = 2, }; struct dmcu_version { - unsigned int date; - unsigned int month; - unsigned int year; unsigned int interface_version; + unsigned int abm_version; + unsigned int psr_version; + unsigned int build_version; }; struct dmcu { @@ -46,6 +52,8 @@ struct dmcu { enum dmcu_state dmcu_state; struct dmcu_version dmcu_version; unsigned int cached_wait_loop_number; + uint32_t psp_version; + bool auto_load_dmcu; }; struct dmcu_funcs { @@ -58,12 +66,31 @@ struct dmcu_funcs { bool (*setup_psr)(struct dmcu *dmcu, struct dc_link *link, struct psr_context *psr_context); - void (*get_psr_state)(struct dmcu *dmcu, uint32_t *psr_state); + void (*get_psr_state)(struct dmcu *dmcu, enum dc_psr_state *dc_psr_state); void (*set_psr_wait_loop)(struct dmcu *dmcu, unsigned int wait_loop_number); void (*get_psr_wait_loop)(struct dmcu *dmcu, unsigned int *psr_wait_loop_number); 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); +#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) + void (*forward_crc_window)(struct dmcu *dmcu, + struct rect *rect, + struct otg_phy_mux *mux_mapping); + void (*stop_crc_win_update)(struct dmcu *dmcu, + struct otg_phy_mux *mux_mapping); +#endif }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h index e894e649ce5a..d88b57d4f512 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h @@ -27,16 +27,110 @@ #ifndef __DAL_DPP_H__ #define __DAL_DPP_H__ -#include "transform.h" +/** + * DOC: overview + * + * The DPP (Display Pipe and Plane) block is the unified display data + * processing engine in DCN for processing graphic or video data on per DPP + * rectangle base. This rectangle can be a part of SLS (Single Large Surface), + * or a layer to be blended with other DPP, or a rectangle associated with a + * display tile. + * + * It provides various functions including: + * - graphic color keyer + * - graphic cursor compositing + * - graphic or video image source to destination scaling + * - image sharping + * - video format conversion from 4:2:0 or 4:2:2 to 4:4:4 + * - Color Space Conversion + * - Host LUT gamma adjustment + * - Color Gamut Remap + * - brightness and contrast adjustment. + * + * DPP pipe consists of Converter and Cursor (CNVC), Scaler (DSCL), Color + * Management (CM), Output Buffer (OBUF) and Digital Bypass (DPB) module + * connected in a video/graphics pipeline. + */ +#include "transform.h" +#include "cursor_reg_cache.h" + +union defer_reg_writes { + struct { + bool disable_blnd_lut:1; + bool disable_3dlut:1; + bool disable_shaper:1; + bool disable_gamcor:1; + bool disable_dscl:1; + } bits; + uint32_t raw; +}; struct dpp { const struct dpp_funcs *funcs; struct dc_context *ctx; + /** + * @inst: + * + * inst stands for "instance," and it is an id number that references a + * specific DPP. + */ int inst; struct dpp_caps *caps; struct pwl_params regamma_params; struct pwl_params degamma_params; + struct dpp_cursor_attributes cur_attr; + union defer_reg_writes deferred_reg_writes; + + struct pwl_params shaper_params; + bool cm_bypass_mode; + bool cursor_offload; + + struct cursor_position_cache_dpp pos; + struct cursor_attribute_cache_dpp att; +}; +struct dpp_input_csc_matrix { + enum dc_color_space color_space; + uint16_t regval[12]; +}; + +static const struct dpp_input_csc_matrix __maybe_unused dpp_input_csc_matrix[] = { + { COLOR_SPACE_SRGB, + { 0x2000, 0, 0, 0, + 0, 0x2000, 0, 0, + 0, 0, 0x2000, 0 } }, + { COLOR_SPACE_SRGB_LIMITED, + { 0x2000, 0, 0, 0, + 0, 0x2000, 0, 0, + 0, 0, 0x2000, 0 } }, + { COLOR_SPACE_YCBCR601, + { 0x2cdd, 0x2000, 0, 0xe991, + 0xe926, 0x2000, 0xf4fd, 0x10ef, + 0, 0x2000, 0x38b4, 0xe3a6 } }, + { COLOR_SPACE_YCBCR601_LIMITED, + { 0x3353, 0x2568, 0, 0xe400, + 0xe5dc, 0x2568, 0xf367, 0x1108, + 0, 0x2568, 0x40de, 0xdd3a } }, + { COLOR_SPACE_YCBCR709, + { 0x3265, 0x2000, 0, 0xe6ce, + 0xf105, 0x2000, 0xfa01, 0xa7d, + 0, 0x2000, 0x3b61, 0xe24f } }, + { COLOR_SPACE_YCBCR709_LIMITED, + { 0x39a6, 0x2568, 0, 0xe0d6, + 0xeedd, 0x2568, 0xf925, 0x9a8, + 0, 0x2568, 0x43ee, 0xdbb2 } }, + { COLOR_SPACE_2020_YCBCR_FULL, + { 0x2F30, 0x2000, 0, 0xE869, + 0xEDB7, 0x2000, 0xFABC, 0xBC6, + 0, 0x2000, 0x3C34, 0xE1E6 } }, + { COLOR_SPACE_2020_YCBCR_LIMITED, + { 0x35B9, 0x2543, 0, 0xE2B2, + 0xEB2F, 0x2543, 0xFA01, 0x0B1F, + 0, 0x2543, 0x4489, 0xDB42 } }, + { COLOR_SPACE_2020_RGB_LIMITEDRANGE, + { 0x35E0, 0x255F, 0, 0xE2B3, + 0xEB20, 0x255F, 0xF9FD, 0xB1E, + 0, 0x255F, 0x44BD, 0xDB43 } } }; struct dpp_grph_csc_adjustment { @@ -44,12 +138,51 @@ struct dpp_grph_csc_adjustment { enum graphics_gamut_adjust_type gamut_adjust_type; }; +struct cnv_color_keyer_params { + int color_keyer_en; + int color_keyer_mode; + int color_keyer_alpha_low; + int color_keyer_alpha_high; + int color_keyer_red_low; + int color_keyer_red_high; + int color_keyer_green_low; + int color_keyer_green_high; + int color_keyer_blue_low; + int color_keyer_blue_high; +}; + +/** + * struct cnv_alpha_2bit_lut - Set the 8bit alpha values based on the 2 bit alpha + */ +struct cnv_alpha_2bit_lut { + /** + * @lut0: ALPHA_2BIT_LUT. ALPHA_2BIT_LUT0. Default: 0b00000000 + */ + int lut0; + + /** + * @lut1: ALPHA_2BIT_LUT. ALPHA_2BIT_LUT1. Default: 0b01010101 + */ + int lut1; + + /** + * @lut2: ALPHA_2BIT_LUT. ALPHA_2BIT_LUT2. Default: 0b10101010 + */ + int lut2; + + /** + * @lut3: ALPHA_2BIT_LUT. ALPHA_2BIT_LUT3. Default: 0b11111111 + */ + int lut3; +}; + struct dcn_dpp_state { uint32_t is_enabled; uint32_t igam_lut_mode; uint32_t igam_input_format; uint32_t dgam_lut_mode; uint32_t rgam_lut_mode; + // gamut_remap data for dcn10_get_cm_states() uint32_t gamut_remap_mode; uint32_t gamut_remap_c11_c12; uint32_t gamut_remap_c13_c14; @@ -57,11 +190,56 @@ struct dcn_dpp_state { uint32_t gamut_remap_c23_c24; uint32_t gamut_remap_c31_c32; uint32_t gamut_remap_c33_c34; + // gamut_remap data for dcn*_log_color_state() + struct dpp_grph_csc_adjustment gamut_remap; + uint32_t shaper_lut_mode; + uint32_t lut3d_mode; + uint32_t lut3d_bit_depth; + uint32_t lut3d_size; + uint32_t blnd_lut_mode; + uint32_t pre_dgam_mode; + uint32_t pre_dgam_select; + uint32_t gamcor_mode; +}; + +struct dcn_dpp_reg_state { + uint32_t recout_start; + uint32_t recout_size; + uint32_t scl_horz_filter_scale_ratio; + uint32_t scl_vert_filter_scale_ratio; + uint32_t scl_mode; + uint32_t cm_control; + uint32_t dpp_control; + uint32_t dscl_control; + uint32_t obuf_control; + uint32_t mpc_size; +}; + +struct CM_bias_params { + uint32_t cm_bias_cr_r; + uint32_t cm_bias_y_g; + uint32_t cm_bias_cb_b; + uint32_t cm_bias_format; }; struct dpp_funcs { + bool (*dpp_program_gamcor_lut)( + struct dpp *dpp_base, const struct pwl_params *params); + + void (*dpp_set_pre_degam)(struct dpp *dpp_base, + enum dc_transfer_func_predefined tr); + + void (*dpp_program_cm_dealpha)(struct dpp *dpp_base, + uint32_t enable, uint32_t additive_blending); + + void (*dpp_program_cm_bias)( + struct dpp *dpp_base, + struct CM_bias_params *bias_params); + void (*dpp_read_state)(struct dpp *dpp, struct dcn_dpp_state *s); + void (*dpp_read_reg_state)(struct dpp *dpp, struct dcn_dpp_reg_state *dpp_reg_state); + void (*dpp_reset)(struct dpp *dpp); void (*dpp_set_scaler)(struct dpp *dpp, @@ -135,13 +313,14 @@ struct dpp_funcs { enum surface_pixel_format format, enum expansion_mode mode, struct dc_csc_transform input_csc_color_matrix, - enum dc_color_space input_color_space); + enum dc_color_space input_color_space, + struct cnv_alpha_2bit_lut *alpha_2bit_lut); void (*dpp_full_bypass)(struct dpp *dpp_base); void (*set_cursor_attributes)( struct dpp *dpp_base, - enum dc_cursor_color_format color_format); + struct dc_cursor_attributes *cursor_attributes); void (*set_cursor_position)( struct dpp *dpp_base, @@ -150,9 +329,11 @@ struct dpp_funcs { uint32_t width, uint32_t height ); + void (*dpp_set_hdr_multiplier)( struct dpp *dpp_base, uint32_t multiplier); + void (*set_optional_cursor_attributes)( struct dpp *dpp_base, struct dpp_cursor_attributes *attr); @@ -162,6 +343,30 @@ struct dpp_funcs { bool dppclk_div, bool enable); + void (*dpp_deferred_update)( + struct dpp *dpp); + bool (*dpp_program_blnd_lut)( + struct dpp *dpp, + const struct pwl_params *params); + bool (*dpp_program_shaper_lut)( + struct dpp *dpp, + const struct pwl_params *params); + bool (*dpp_program_3dlut)( + struct dpp *dpp, + const struct tetrahedral_params *params); + void (*dpp_cnv_set_alpha_keyer)( + struct dpp *dpp_base, + struct cnv_color_keyer_params *color_keyer); + + void (*dpp_get_gamut_remap)(struct dpp *dpp_base, + struct dpp_grph_csc_adjustment *adjust); + void (*set_cursor_matrix)( + struct dpp *dpp_base, + enum dc_color_space color_space, + struct dc_csc_transform cursor_csc_color_matrix); + + void (*dpp_force_disable_cursor)(struct dpp *dpp_base); + }; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h new file mode 100644 index 000000000000..063efc8128a7 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h @@ -0,0 +1,240 @@ +/* Copyright 2012-17 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_DWBC_H__ +#define __DC_DWBC_H__ + +#include "dal_types.h" +#include "dc_hw_types.h" + +#define DWB_SW_V2 1 +#define DWB_MCIF_BUF_COUNT 4 + +/* forward declaration of mcif_wb struct */ +struct mcif_wb; + + +enum dwb_sw_version { + dwb_ver_1_0 = 1, + dwb_ver_2_0 = 2, +}; + +enum dwb_source { + dwb_src_scl = 0, /* for DCE7x/9x, DCN won't support. */ + dwb_src_blnd, /* for DCE7x/9x */ + dwb_src_fmt, /* for DCE7x/9x */ + dwb_src_otg0 = 0x100, /* for DCN1.x/DCN2.x, register: mmDWB_SOURCE_SELECT */ + dwb_src_otg1, /* for DCN1.x/DCN2.x */ + dwb_src_otg2, /* for DCN1.x/DCN2.x */ + dwb_src_otg3, /* for DCN1.x/DCN2.x */ +}; + +/* DCN1.x, DCN2.x support 2 pipes */ +enum dwb_pipe { + dwb_pipe0 = 0, + dwb_pipe1, + dwb_pipe_max_num, +}; + +enum dwb_frame_capture_enable { + DWB_FRAME_CAPTURE_DISABLE = 0, + DWB_FRAME_CAPTURE_ENABLE = 1, +}; + +enum wbscl_coef_filter_type_sel { + WBSCL_COEF_LUMA_VERT_FILTER = 0, + WBSCL_COEF_CHROMA_VERT_FILTER = 1, + WBSCL_COEF_LUMA_HORZ_FILTER = 2, + WBSCL_COEF_CHROMA_HORZ_FILTER = 3 +}; + + +enum dwb_boundary_mode { + DWBSCL_BOUNDARY_MODE_EDGE = 0, + DWBSCL_BOUNDARY_MODE_BLACK = 1 +}; + +enum dwb_output_csc_mode { + DWB_OUTPUT_CSC_DISABLE = 0, + DWB_OUTPUT_CSC_COEF_A = 1, + DWB_OUTPUT_CSC_COEF_B = 2 +}; + +enum dwb_ogam_lut_mode { + DWB_OGAM_MODE_BYPASS, + DWB_OGAM_RAMA_LUT, + DWB_OGAM_RAMB_LUT +}; + +enum dwb_color_volume { + DWB_SRGB_BT709 = 0, //SDR + DWB_PQ = 1, //HDR + DWB_HLG = 2, //HDR +}; + +enum dwb_color_space { + DWB_SRGB = 0, //SDR + DWB_BT709 = 1, //SDR + DWB_BT2020 = 2, //HDR +}; + +struct dwb_efc_hdr_metadata { + /*display chromaticities and white point in units of 0.00001 */ + unsigned int chromaticity_green_x; + unsigned int chromaticity_green_y; + unsigned int chromaticity_blue_x; + unsigned int chromaticity_blue_y; + unsigned int chromaticity_red_x; + unsigned int chromaticity_red_y; + unsigned int chromaticity_white_point_x; + unsigned int chromaticity_white_point_y; + + /*in units of candelas per square meter */ + unsigned int min_luminance; + unsigned int max_luminance; + + /*in units of nits */ + unsigned int maximum_content_light_level; + unsigned int maximum_frame_average_light_level; +}; + +struct dwb_efc_display_settings { + unsigned int inputColorVolume; + unsigned int inputColorSpace; + unsigned int inputBitDepthMinus8; + struct dwb_efc_hdr_metadata hdr_metadata; + unsigned int dwbOutputBlack; // 0 - Normal, 1 - Output Black +}; + +struct dwb_warmup_params { + bool warmup_en; /* false: normal mode, true: enable pattern generator */ + bool warmup_mode; /* false: 420, true: 444 */ + bool warmup_depth; /* false: 8bit, true: 10bit */ + int warmup_data; /* Data to be sent by pattern generator (same for each pixel component) */ + int warmup_width; /* Pattern width (pixels) */ + int warmup_height; /* Pattern height (lines) */ +}; + +struct dwb_caps { + enum dce_version hw_version; /* DCN engine version. */ + enum dwb_sw_version sw_version; /* DWB sw implementation version. */ + unsigned int reserved[6]; /* Reserved for future use, MUST BE 0. */ + unsigned int adapter_id; + unsigned int num_pipes; /* number of DWB pipes */ + struct { + unsigned int support_dwb :1; + unsigned int support_ogam :1; + unsigned int support_wbscl :1; + unsigned int support_ocsc :1; + unsigned int support_stereo :1; + unsigned int support_4k_120p :1; + } caps; + unsigned int reserved2[10]; /* Reserved for future use, MUST BE 0. */ +}; + +struct dwbc { + const struct dwbc_funcs *funcs; + struct dc_context *ctx; + int inst; + struct mcif_wb *mcif; + bool status; + int inputSrcSelect; + bool dwb_output_black; + enum dc_transfer_func_predefined tf; + enum dc_color_space output_color_space; + bool dwb_is_efc_transition; + bool dwb_is_drc; + int wb_src_plane_inst;/*hubp, mpcc, inst*/ + uint32_t mask_id; + int otg_inst; + bool mvc_cfg; + struct dc_dwb_params params; +}; + +struct dwbc_funcs { + bool (*get_caps)( + struct dwbc *dwbc, + struct dwb_caps *caps); + + bool (*enable)( + struct dwbc *dwbc, + struct dc_dwb_params *params); + + bool (*disable)(struct dwbc *dwbc); + + bool (*update)( + struct dwbc *dwbc, + struct dc_dwb_params *params); + + bool (*is_enabled)( + struct dwbc *dwbc); + + void (*set_fc_enable)( + struct dwbc *dwbc, + enum dwb_frame_capture_enable enable); + + void (*dwb_set_scaler)( + struct dwbc *dwbc, + struct dc_dwb_params *params); + + void (*set_stereo)( + struct dwbc *dwbc, + struct dwb_stereo_params *stereo_params); + + void (*set_new_content)( + struct dwbc *dwbc, + bool is_new_content); + + + void (*set_warmup)( + struct dwbc *dwbc, + struct dwb_warmup_params *warmup_params); + + bool (*dwb_get_mcifbuf_line)( + struct dwbc *dwbc, unsigned int *buf_idx, + unsigned int *cur_line, + unsigned int *over_run); +#if defined(CONFIG_DRM_AMD_DC_FP) + void (*dwb_program_output_csc)( + struct dwbc *dwbc, + enum dc_color_space color_space, + enum dwb_output_csc_mode mode); + + bool (*dwb_ogam_set_output_transfer_func)( + struct dwbc *dwbc, + const struct dc_transfer_func *in_transfer_func_dwb_ogam); +#endif + //TODO: merge with output_transfer_func? + bool (*dwb_ogam_set_input_transfer_func)( + struct dwbc *dwbc, + const struct dc_transfer_func *in_transfer_func_dwb_ogam); + + void (*get_drr_time_stamp)( + struct dwbc *dwbc, uint32_t *time_stamp); + + bool (*get_dwb_status)( + struct dwbc *dwbc); +}; + +#endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/gpio.h b/drivers/gpu/drm/amd/display/dc/inc/hw/gpio.h index 90d0148430fb..5253dc8b15f8 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/gpio.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/gpio.h @@ -28,12 +28,22 @@ #include "gpio_types.h" + +union gpio_hw_container { + struct hw_ddc *ddc; + struct hw_generic *generic; + struct hw_hpd *hpd; +}; + struct gpio { struct gpio_service *service; struct hw_gpio_pin *pin; enum gpio_id id; uint32_t en; + + union gpio_hw_container hw_container; enum gpio_mode mode; + /* when GPIO comes from VBIOS, it has defined output state */ enum gpio_pin_output_state output_state; }; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h index 04c6989aac58..a79019365af8 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h @@ -26,8 +26,26 @@ #ifndef __DAL_HUBP_H__ #define __DAL_HUBP_H__ +/** + * DOC: overview + * + * Display Controller Hub (DCHUB) is the gateway between the Scalable Data Port + * (SDP) and DCN. This component has multiple features, such as memory + * arbitration, rotation, and cursor manipulation. + * + * There is one HUBP allocated per pipe, which fetches data and converts + * different pixel formats (i.e. ARGB8888, NV12, etc) into linear, interleaved + * and fixed-depth streams of pixel data. + */ + #include "mem_input.h" +#include "cursor_reg_cache.h" + +#include "dml2_0/dml21/inc/dml_top_dchub_registers.h" +#include "dml2_0/dml21/inc/dml_top_types.h" +#define OPP_ID_INVALID 0xf +#define MAX_TTU 0xffffff enum cursor_pitch { CURSOR_PITCH_64_PIXELS = 0, @@ -36,12 +54,67 @@ enum cursor_pitch { }; enum cursor_lines_per_chunk { + CURSOR_LINE_PER_CHUNK_1 = 0, /* new for DCN2 */ CURSOR_LINE_PER_CHUNK_2 = 1, CURSOR_LINE_PER_CHUNK_4, CURSOR_LINE_PER_CHUNK_8, CURSOR_LINE_PER_CHUNK_16 }; +enum hubp_ind_block_size { + hubp_ind_block_unconstrained = 0, + hubp_ind_block_64b, + hubp_ind_block_128b, + hubp_ind_block_64b_no_128bcl, +}; + +enum hubp_3dlut_fl_mode { + hubp_3dlut_fl_mode_disable = 0, + hubp_3dlut_fl_mode_native_1 = 1, + hubp_3dlut_fl_mode_native_2 = 2, + hubp_3dlut_fl_mode_transform = 3 +}; + +enum hubp_3dlut_fl_format { + hubp_3dlut_fl_format_unorm_12msb_bitslice = 0, + hubp_3dlut_fl_format_unorm_12lsb_bitslice = 1, + hubp_3dlut_fl_format_float_fp1_5_10 = 2 +}; + +enum hubp_3dlut_fl_addressing_mode { + hubp_3dlut_fl_addressing_mode_sw_linear = 0, + hubp_3dlut_fl_addressing_mode_simple_linear = 1 +}; + +enum hubp_3dlut_fl_width { + hubp_3dlut_fl_width_17 = 17, + hubp_3dlut_fl_width_33 = 33, + hubp_3dlut_fl_width_transformed = 4916, //mpc default +}; + +enum hubp_3dlut_fl_crossbar_bit_slice { + hubp_3dlut_fl_crossbar_bit_slice_0_15 = 0, + hubp_3dlut_fl_crossbar_bit_slice_16_31 = 1, + hubp_3dlut_fl_crossbar_bit_slice_32_47 = 2, + hubp_3dlut_fl_crossbar_bit_slice_48_63 = 3 +}; + +struct hubp_fl_3dlut_config { + bool enabled; + enum hubp_3dlut_fl_width width; + enum hubp_3dlut_fl_mode mode; + enum hubp_3dlut_fl_format format; + uint16_t bias; + uint16_t scale; + struct dc_plane_address address; + enum hubp_3dlut_fl_addressing_mode addr_mode; + enum dc_cm2_gpu_mem_layout layout; + uint8_t protection_bits; + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g; + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b; + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r; +}; + struct hubp { const struct hubp_funcs *funcs; struct dc_context *ctx; @@ -52,7 +125,34 @@ struct hubp { int opp_id; int mpcc_id; struct dc_cursor_attributes curs_attr; + struct dc_cursor_position curs_pos; + bool cursor_offload; bool power_gated; + + struct cursor_position_cache_hubp pos; + struct cursor_attribute_cache_hubp att; + struct cursor_rect cur_rect; + bool use_mall_for_cursor; +}; + +struct surface_flip_registers { + uint32_t DCSURF_SURFACE_CONTROL; + uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH; + uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS; + uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH; + uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS; + uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C; + uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_C; + uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C; + uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_C; + uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH; + uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS; + uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH; + uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS; + bool tmz_surface; + bool immediate; + uint8_t vmid; + bool grph_stereo; }; struct hubp_funcs { @@ -63,13 +163,26 @@ struct hubp_funcs { struct _vcs_dpi_display_rq_regs_st *rq_regs, struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest); + void (*hubp_setup2)( + struct hubp *hubp, + struct dml2_dchub_per_pipe_register_set *pipe_regs, + union dml2_global_sync_programming *pipe_global_sync, + struct dc_crtc_timing *timing); + void (*hubp_setup_interdependent)( struct hubp *hubp, struct _vcs_dpi_display_dlg_regs_st *dlg_regs, struct _vcs_dpi_display_ttu_regs_st *ttu_regs); + void (*hubp_setup_interdependent2)( + struct hubp *hubp, + struct dml2_dchub_per_pipe_register_set *pipe_regs); + void (*dcc_control)(struct hubp *hubp, bool enable, - bool independent_64b_blks); + enum hubp_ind_block_size blk_size); + + void (*hubp_reset)(struct hubp *hubp); + void (*mem_program_viewport)( struct hubp *hubp, const struct rect *viewport, @@ -83,7 +196,7 @@ struct hubp_funcs { void (*hubp_program_pte_vm)( struct hubp *hubp, enum surface_pixel_format format, - union dc_tiling_info *tiling_info, + struct dc_tiling_info *tiling_info, enum dc_rotation_angle rotation); void (*hubp_set_vm_system_aperture_settings)( @@ -97,8 +210,8 @@ struct hubp_funcs { void (*hubp_program_surface_config)( struct hubp *hubp, enum surface_pixel_format format, - union dc_tiling_info *tiling_info, - union plane_size *plane_size, + struct dc_tiling_info *tiling_info, + struct plane_size *plane_size, enum dc_rotation_angle rotation, struct dc_plane_dcc_param *dcc, bool horizontal_mirror, @@ -106,10 +219,9 @@ struct hubp_funcs { bool (*hubp_is_flip_pending)(struct hubp *hubp); - void (*hubp_update_dchub)(struct hubp *hubp, - struct dchub_init_data *dh_data); - void (*set_blank)(struct hubp *hubp, bool blank); + void (*set_blank_regs)(struct hubp *hubp, bool blank); + void (*phantom_hubp_post_enable)(struct hubp *hubp); void (*set_hubp_blank_en)(struct hubp *hubp, bool blank); void (*set_cursor_attributes)( @@ -126,10 +238,79 @@ struct hubp_funcs { void (*hubp_clk_cntl)(struct hubp *hubp, bool enable); void (*hubp_vtg_sel)(struct hubp *hubp, uint32_t otg_inst); void (*hubp_read_state)(struct hubp *hubp); + void (*hubp_read_reg_state)(struct hubp *hubp, struct dcn_hubp_reg_state *reg_state); void (*hubp_clear_underflow)(struct hubp *hubp); void (*hubp_disable_control)(struct hubp *hubp, bool disable_hubp); unsigned int (*hubp_get_underflow_status)(struct hubp *hubp); + void (*hubp_init)(struct hubp *hubp); + + void (*dmdata_set_attributes)( + struct hubp *hubp, + const struct dc_dmdata_attributes *attr); + + void (*dmdata_load)( + struct hubp *hubp, + uint32_t dmdata_sw_size, + const uint32_t *dmdata_sw_data); + bool (*dmdata_status_done)(struct hubp *hubp); + void (*hubp_enable_tripleBuffer)( + struct hubp *hubp, + bool enable); + + bool (*hubp_is_triplebuffer_enabled)( + struct hubp *hubp); + + void (*hubp_set_flip_control_surface_gsl)( + struct hubp *hubp, + bool enable); + + void (*validate_dml_output)( + struct hubp *hubp, + struct dc_context *ctx, + struct _vcs_dpi_display_rq_regs_st *dml_rq_regs, + struct _vcs_dpi_display_dlg_regs_st *dml_dlg_attr, + struct _vcs_dpi_display_ttu_regs_st *dml_ttu_attr); + void (*set_unbounded_requesting)( + struct hubp *hubp, + bool enable); + bool (*hubp_in_blank)(struct hubp *hubp); + void (*hubp_soft_reset)(struct hubp *hubp, bool reset); + + void (*hubp_set_flip_int)(struct hubp *hubp); + + void (*hubp_update_force_pstate_disallow)(struct hubp *hubp, bool allow); + void (*hubp_update_force_cursor_pstate_disallow)(struct hubp *hubp, bool allow); + void (*hubp_update_mall_sel)(struct hubp *hubp, uint32_t mall_sel, bool c_cursor); + void (*hubp_prepare_subvp_buffering)(struct hubp *hubp, bool enable); + void (*hubp_surface_update_lock)(struct hubp *hubp, + bool lock); + + void (*program_extended_blank)(struct hubp *hubp, + unsigned int min_dst_y_next_start_optimized); + void (*hubp_wait_pipe_read_start)(struct hubp *hubp); + void (*hubp_program_mcache_id_and_split_coordinate)(struct hubp *hubp, struct dml2_hubp_pipe_mcache_regs *mcache_regs); + void (*hubp_update_3dlut_fl_bias_scale)(struct hubp *hubp, uint16_t bias, uint16_t scale); + void (*hubp_program_3dlut_fl_mode)(struct hubp *hubp, + enum hubp_3dlut_fl_mode mode); + void (*hubp_program_3dlut_fl_format)(struct hubp *hubp, + enum hubp_3dlut_fl_format format); + void (*hubp_program_3dlut_fl_addr)(struct hubp *hubp, + const struct dc_plane_address address); + void (*hubp_program_3dlut_fl_dlg_param)(struct hubp *hubp, int refcyc_per_3dlut_group); + void (*hubp_enable_3dlut_fl)(struct hubp *hubp, bool enable); + void (*hubp_program_3dlut_fl_addressing_mode)(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode); + void (*hubp_program_3dlut_fl_width)(struct hubp *hubp, enum hubp_3dlut_fl_width width); + void (*hubp_program_3dlut_fl_tmz_protected)(struct hubp *hubp, uint8_t protection_bits); + void (*hubp_program_3dlut_fl_crossbar)(struct hubp *hubp, + enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g, + enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b, + enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r); + int (*hubp_get_3dlut_fl_done)(struct hubp *hubp); + void (*hubp_program_3dlut_fl_config)(struct hubp *hubp, struct hubp_fl_3dlut_config *cfg); + void (*hubp_clear_tiling)(struct hubp *hubp); + uint32_t (*hubp_get_current_read_line)(struct hubp *hubp); + uint32_t (*hubp_get_det_config_error)(struct hubp *hubp); }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h index da85537a4488..a61d12ec61bc 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h @@ -34,7 +34,76 @@ * Data types shared between different Virtual HW blocks ******************************************************************************/ +#define MAX_AUDIOS 7 + +/** + * @MAX_PIPES: + * + * Every ASIC support a fixed number of pipes; MAX_PIPES defines a large number + * to be used inside loops and for determining array sizes. + */ #define MAX_PIPES 6 +#define MAX_PHANTOM_PIPES (MAX_PIPES / 2) + +#define MAX_DPIA 6 +#define MAX_CONNECTOR 6 +#define MAX_VIRTUAL_LINKS 4 + +#define MAX_LINKS (MAX_DPIA + MAX_CONNECTOR + MAX_VIRTUAL_LINKS) + +/** + * define MAX_DIG_LINK_ENCODERS - maximum number of digital encoders + * + * Digital encoders are ENGINE_ID_DIGA...G, there are at most 7, + * although not every GPU may have that many. + */ +#define MAX_DIG_LINK_ENCODERS 7 + +/** + * define MAX_DAC_LINK_ENCODERS - maximum number of analog link encoders + * + * Analog encoders are ENGINE_ID_DACA/B, there are at most 2, + * although not every GPU may have that many. Modern GPUs typically + * don't have analog encoders. + */ +#define MAX_DAC_LINK_ENCODERS 2 + +/** + * define MAX_LINK_ENCODERS - maximum number link encoders in total + * + * This includes both analog and digital encoders. + */ +#define MAX_LINK_ENCODERS (MAX_DIG_LINK_ENCODERS + MAX_DAC_LINK_ENCODERS) + +#define MAX_DWB_PIPES 1 +#define MAX_HPO_DP2_ENCODERS 4 +#define MAX_HPO_DP2_LINK_ENCODERS 4 + +/* Pipe topology snapshot structures */ +#define MAX_TOPOLOGY_SNAPSHOTS 4 + +struct pipe_topology_line { + bool is_phantom_pipe; + int plane_idx; + int slice_idx; + int stream_idx; + int dpp_inst; + int opp_inst; + int tg_inst; +}; + +struct pipe_topology_snapshot { + struct pipe_topology_line pipe_log_lines[MAX_PIPES]; + int line_count; + uint64_t timestamp_us; + int stream_count; + int phantom_stream_count; +}; + +struct pipe_topology_history { + struct pipe_topology_snapshot snapshots[MAX_TOPOLOGY_SNAPSHOTS]; + int current_snapshot_index; +}; struct gamma_curve { uint32_t offset; @@ -77,6 +146,35 @@ struct pwl_result_data { uint32_t delta_blue_reg; }; +struct dc_rgb { + uint32_t red; + uint32_t green; + uint32_t blue; +}; + +struct tetrahedral_17x17x17 { + struct dc_rgb lut0[1229]; + struct dc_rgb lut1[1228]; + struct dc_rgb lut2[1228]; + struct dc_rgb lut3[1228]; +}; +struct tetrahedral_9x9x9 { + struct dc_rgb lut0[183]; + struct dc_rgb lut1[182]; + struct dc_rgb lut2[182]; + struct dc_rgb lut3[182]; +}; + +struct tetrahedral_params { + union { + struct tetrahedral_17x17x17 tetrahedral_17; + struct tetrahedral_9x9x9 tetrahedral_9; + }; + bool use_tetrahedral_9; + bool use_12bits; + +}; + /* arr_curve_points - regamma regions/segments specification * arr_points - beginning and end point specified separately (only one on DCE) * corner_points - beginning and end point for all 3 colors (DCN) @@ -119,6 +217,13 @@ enum ipp_degamma_mode { IPP_DEGAMMA_MODE_USER_PWL }; +enum gamcor_mode { + GAMCOR_MODE_BYPASS, + GAMCOR_MODE_RESERVED_1, + GAMCOR_MODE_USER_PWL, + GAMCOR_MODE_RESERVED_3 +}; + enum ipp_output_format { IPP_OUTPUT_FORMAT_12_BIT_FIX, IPP_OUTPUT_FORMAT_16_BIT_BYPASS, @@ -146,6 +251,12 @@ struct out_csc_color_matrix { uint16_t regval[12]; }; +enum gamut_remap_select { + GAMUT_REMAP_BYPASS = 0, + GAMUT_REMAP_COEFF, + GAMUT_REMAP_COMA_COEFF, + GAMUT_REMAP_COMB_COEFF +}; enum opp_regamma { OPP_REGAMMA_BYPASS = 0, @@ -154,13 +265,20 @@ enum opp_regamma { OPP_REGAMMA_USER }; +enum optc_dsc_mode { + OPTC_DSC_DISABLED = 0, + OPTC_DSC_ENABLED_444 = 1, /* 'RGB 444' or 'Simple YCbCr 4:2:2' (4:2:2 upsampled to 4:4:4) */ + OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED = 2 /* Native 4:2:2 or 4:2:0 */ +}; + struct dc_bias_and_scale { - uint16_t scale_red; - uint16_t bias_red; - uint16_t scale_green; - uint16_t bias_green; - uint16_t scale_blue; - uint16_t bias_blue; + uint32_t scale_red; + uint32_t bias_red; + uint32_t scale_green; + uint32_t bias_green; + uint32_t scale_blue; + uint32_t bias_blue; + bool bias_and_scale_valid; }; enum test_pattern_dyn_range { @@ -175,7 +293,8 @@ enum test_pattern_mode { TEST_PATTERN_MODE_VERTICALBARS, TEST_PATTERN_MODE_HORIZONTALBARS, TEST_PATTERN_MODE_SINGLERAMP_RGB, - TEST_PATTERN_MODE_DUALRAMP_RGB + TEST_PATTERN_MODE_DUALRAMP_RGB, + TEST_PATTERN_MODE_XR_BIAS_RGB }; enum test_pattern_color_format { @@ -197,7 +316,15 @@ enum controller_dp_test_pattern { CONTROLLER_DP_TEST_PATTERN_RESERVED_8, CONTROLLER_DP_TEST_PATTERN_RESERVED_9, CONTROLLER_DP_TEST_PATTERN_RESERVED_A, - CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA + CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA, + CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR +}; + +enum controller_dp_color_space { + CONTROLLER_DP_COLOR_SPACE_RGB, + CONTROLLER_DP_COLOR_SPACE_YCBCR601, + CONTROLLER_DP_COLOR_SPACE_YCBCR709, + CONTROLLER_DP_COLOR_SPACE_UDEFINED }; enum dc_lut_mode { @@ -205,4 +332,88 @@ enum dc_lut_mode { LUT_RAM_A, LUT_RAM_B }; + +/** + * speakersToChannels + * + * @brief + * translate speakers to channels + * + * FL - Front Left + * FR - Front Right + * RL - Rear Left + * RR - Rear Right + * RC - Rear Center + * FC - Front Center + * FLC - Front Left Center + * FRC - Front Right Center + * RLC - Rear Left Center + * RRC - Rear Right Center + * LFE - Low Freq Effect + * + * FC + * FLC FRC + * FL FR + * + * LFE + * () + * + * + * RL RR + * RLC RRC + * RC + * + * ch 8 7 6 5 4 3 2 1 + * 0b00000011 - - - - - - FR FL + * 0b00000111 - - - - - LFE FR FL + * 0b00001011 - - - - FC - FR FL + * 0b00001111 - - - - FC LFE FR FL + * 0b00010011 - - - RC - - FR FL + * 0b00010111 - - - RC - LFE FR FL + * 0b00011011 - - - RC FC - FR FL + * 0b00011111 - - - RC FC LFE FR FL + * 0b00110011 - - RR RL - - FR FL + * 0b00110111 - - RR RL - LFE FR FL + * 0b00111011 - - RR RL FC - FR FL + * 0b00111111 - - RR RL FC LFE FR FL + * 0b01110011 - RC RR RL - - FR FL + * 0b01110111 - RC RR RL - LFE FR FL + * 0b01111011 - RC RR RL FC - FR FL + * 0b01111111 - RC RR RL FC LFE FR FL + * 0b11110011 RRC RLC RR RL - - FR FL + * 0b11110111 RRC RLC RR RL - LFE FR FL + * 0b11111011 RRC RLC RR RL FC - FR FL + * 0b11111111 RRC RLC RR RL FC LFE FR FL + * 0b11000011 FRC FLC - - - - FR FL + * 0b11000111 FRC FLC - - - LFE FR FL + * 0b11001011 FRC FLC - - FC - FR FL + * 0b11001111 FRC FLC - - FC LFE FR FL + * 0b11010011 FRC FLC - RC - - FR FL + * 0b11010111 FRC FLC - RC - LFE FR FL + * 0b11011011 FRC FLC - RC FC - FR FL + * 0b11011111 FRC FLC - RC FC LFE FR FL + * 0b11110011 FRC FLC RR RL - - FR FL + * 0b11110111 FRC FLC RR RL - LFE FR FL + * 0b11111011 FRC FLC RR RL FC - FR FL + * 0b11111111 FRC FLC RR RL FC LFE FR FL + * + * @param + * speakers - speaker information as it comes from CEA audio block + */ +/* translate speakers to channels */ + +union audio_cea_channels { + uint8_t all; + struct audio_cea_channels_bits { + uint32_t FL:1; + uint32_t FR:1; + uint32_t LFE:1; + uint32_t FC:1; + uint32_t RL_RC:1; + uint32_t RR:1; + uint32_t RC_RLC_FLC:1; + uint32_t RRC_FRC:1; + } channels; +}; + #endif /* __DAL_HW_SHARED_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h index c20fdcaac53b..df512920a9fa 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h @@ -47,6 +47,7 @@ struct encoder_init_data { enum hpd_source_id hpd_source; /* TODO: in DAL2, here was pointer to EventManagerInterface */ struct graphics_object_id encoder; + enum engine_id analog_engine; struct dc_context *ctx; enum transmitter transmitter; }; @@ -59,6 +60,11 @@ struct encoder_feature_support { uint32_t IS_TPS3_CAPABLE:1; uint32_t IS_TPS4_CAPABLE:1; uint32_t HDMI_6GB_EN:1; + uint32_t IS_DP2_CAPABLE:1; + uint32_t IS_UHBR10_CAPABLE:1; + uint32_t IS_UHBR13_5_CAPABLE:1; + uint32_t IS_UHBR20_CAPABLE:1; + uint32_t DP_IS_USB_C:1; } bits; uint32_t raw; } flags; @@ -67,38 +73,7 @@ struct encoder_feature_support { unsigned int max_hdmi_pixel_clock; bool hdmi_ycbcr420_supported; bool dp_ycbcr420_supported; -}; - -union dpcd_psr_configuration { - struct { - unsigned char ENABLE : 1; - unsigned char TRANSMITTER_ACTIVE_IN_PSR : 1; - unsigned char CRC_VERIFICATION : 1; - unsigned char FRAME_CAPTURE_INDICATION : 1; - /* For eDP 1.4, PSR v2*/ - unsigned char LINE_CAPTURE_INDICATION : 1; - /* For eDP 1.4, PSR v2*/ - unsigned char IRQ_HPD_WITH_CRC_ERROR : 1; - unsigned char RESERVED : 2; - } bits; - unsigned char raw; -}; - -union psr_error_status { - struct { - unsigned char LINK_CRC_ERROR :1; - unsigned char RFB_STORAGE_ERROR :1; - unsigned char RESERVED :6; - } bits; - unsigned char raw; -}; - -union psr_sink_psr_status { - struct { - unsigned char SINK_SELF_REFRESH_STATUS :3; - unsigned char RESERVED :5; - } bits; - unsigned char raw; + bool fec_supported; }; struct link_encoder { @@ -109,12 +84,31 @@ struct link_encoder { struct graphics_object_id connector; uint32_t output_signals; enum engine_id preferred_engine; + enum engine_id analog_engine; struct encoder_feature_support features; enum transmitter transmitter; enum hpd_source_id hpd_source; + bool usbc_combo_phy; +}; + +struct link_enc_state { + + uint32_t dphy_fec_en; + uint32_t dphy_fec_ready_shadow; + uint32_t dphy_fec_active_status; + uint32_t dp_link_training_complete; + +}; + +enum encoder_type_select { + ENCODER_TYPE_DIG = 0, + ENCODER_TYPE_HDMI_FRL = 1, + ENCODER_TYPE_DP_128B132B = 2 }; struct link_encoder_funcs { + void (*read_state)( + struct link_encoder *enc, struct link_enc_state *s); bool (*validate_output_with_stream)( struct link_encoder *enc, const struct dc_stream_state *stream); void (*hw_init)(struct link_encoder *enc); @@ -137,7 +131,8 @@ struct link_encoder_funcs { void (*disable_output)(struct link_encoder *link_enc, enum signal_type signal); void (*dp_set_lane_settings)(struct link_encoder *enc, - const struct link_training_settings *link_settings); + const struct dc_link_settings *link_settings, + const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]); void (*dp_set_phy_pattern)(struct link_encoder *enc, const struct encoder_set_dp_phy_pattern_param *para); void (*update_mst_stream_allocation_table)( @@ -153,7 +148,141 @@ struct link_encoder_funcs { void (*enable_hpd)(struct link_encoder *enc); void (*disable_hpd)(struct link_encoder *enc); bool (*is_dig_enabled)(struct link_encoder *enc); + unsigned int (*get_dig_frontend)(struct link_encoder *enc); void (*destroy)(struct link_encoder **enc); + + void (*fec_set_enable)(struct link_encoder *enc, + bool enable); + + void (*fec_set_ready)(struct link_encoder *enc, + bool ready); + + bool (*fec_is_active)(struct link_encoder *enc); + bool (*is_in_alt_mode) (struct link_encoder *enc); + + void (*get_max_link_cap)(struct link_encoder *enc, + struct dc_link_settings *link_settings); + + enum signal_type (*get_dig_mode)( + struct link_encoder *enc); + + void (*set_dio_phy_mux)( + struct link_encoder *enc, + enum encoder_type_select sel, + uint32_t hpo_inst); + void (*enable_dpia_output)(struct link_encoder *enc, + const struct dc_link_settings *link_settings, + uint8_t dpia_id, + uint8_t digmode, + uint8_t fec_rdy); + void (*disable_dpia_output)(struct link_encoder *link_enc, + uint8_t dpia_id, + uint8_t digmode); +}; + +/* + * Used to track assignments of links (display endpoints) to link encoders. + * + * Entry in link_enc_assignments table in struct resource_context. + * Entries only marked valid once encoder assigned to a link and invalidated once unassigned. + * Uses engine ID as identifier since PHY ID not relevant for USB4 DPIA endpoint. + */ +struct link_enc_assignment { + bool valid; + struct display_endpoint_id ep_id; + enum engine_id eng_id; + struct dc_stream_state *stream; +}; + +enum link_enc_cfg_mode { + LINK_ENC_CFG_STEADY, /* Normal operation - use current_state. */ + LINK_ENC_CFG_TRANSIENT /* During commit state - use state to be committed. */ +}; + +enum dp2_link_mode { + DP2_LINK_TRAINING_TPS1, + DP2_LINK_TRAINING_TPS2, + DP2_LINK_ACTIVE, + DP2_TEST_PATTERN +}; + +enum dp2_phy_tp_select { + DP_DPHY_TP_SELECT_TPS1, + DP_DPHY_TP_SELECT_TPS2, + DP_DPHY_TP_SELECT_PRBS, + DP_DPHY_TP_SELECT_CUSTOM, + DP_DPHY_TP_SELECT_SQUARE +}; + +enum dp2_phy_tp_prbs { + DP_DPHY_TP_PRBS7, + DP_DPHY_TP_PRBS9, + DP_DPHY_TP_PRBS11, + DP_DPHY_TP_PRBS15, + DP_DPHY_TP_PRBS23, + DP_DPHY_TP_PRBS31 +}; + +struct hpo_dp_link_enc_state { + uint32_t link_enc_enabled; + uint32_t link_mode; + uint32_t lane_count; + uint32_t slot_count[4]; + uint32_t stream_src[4]; + uint32_t vc_rate_x[4]; + uint32_t vc_rate_y[4]; +}; + +struct hpo_dp_link_encoder { + const struct hpo_dp_link_encoder_funcs *funcs; + struct dc_context *ctx; + int inst; + enum engine_id preferred_engine; + enum transmitter transmitter; + enum hpd_source_id hpd_source; +}; + +struct hpo_dp_link_encoder_funcs { + + void (*enable_link_phy)(struct hpo_dp_link_encoder *enc, + const struct dc_link_settings *link_settings, + enum transmitter transmitter, + enum hpd_source_id hpd_source); + + void (*disable_link_phy)(struct hpo_dp_link_encoder *link_enc, + enum signal_type signal); + + void (*link_enable)( + struct hpo_dp_link_encoder *enc, + enum dc_lane_count num_lanes); + + void (*link_disable)( + struct hpo_dp_link_encoder *enc); + + void (*set_link_test_pattern)( + struct hpo_dp_link_encoder *enc, + struct encoder_set_dp_phy_pattern_param *tp_params); + + void (*update_stream_allocation_table)( + struct hpo_dp_link_encoder *enc, + const struct link_mst_stream_allocation_table *table); + + void (*set_throttled_vcp_size)( + struct hpo_dp_link_encoder *enc, + uint32_t stream_encoder_inst, + struct fixed31_32 avg_time_slots_per_mtp); + + bool (*is_in_alt_mode) ( + struct hpo_dp_link_encoder *enc); + + void (*read_state)( + struct hpo_dp_link_encoder *enc, + struct hpo_dp_link_enc_state *state); + + void (*set_ffe)( + struct hpo_dp_link_encoder *enc, + const struct dc_link_settings *link_settings, + uint8_t ffe_preset); }; #endif /* LINK_ENCODER_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mcif_wb.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mcif_wb.h new file mode 100644 index 000000000000..15cb782f129b --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mcif_wb.h @@ -0,0 +1,109 @@ +/* Copyright 2012-17 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_MCIF_WB_H__ +#define __DC_MCIF_WB_H__ + +#include "dc_hw_types.h" + + +enum mmhubbub_wbif_mode { + PACKED_444 = 0, + PACKED_444_FP16 = 1, + PLANAR_420_8BPC = 2, + PLANAR_420_10BPC = 3 +}; + +struct mcif_arb_params { + + unsigned int time_per_pixel; + unsigned int cli_watermark[4]; + unsigned int pstate_watermark[4]; + unsigned int arbitration_slice; + unsigned int slice_lines; + unsigned int max_scaled_time; + unsigned int dram_speed_change_duration; +}; + +struct mcif_irq_params { + unsigned int sw_int_en; + unsigned int sw_slice_int_en; + unsigned int sw_overrun_int_en; + unsigned int vce_int_en; + unsigned int vce_slice_int_en; +}; + + +/* / - mcif_wb_frame_dump_info is the info of the dumping WB data */ +struct mcif_wb_frame_dump_info { + unsigned int size; + unsigned int width; + unsigned int height; + unsigned int luma_pitch; + unsigned int chroma_pitch; + enum dwb_scaler_mode format; +}; + +struct mcif_wb { + const struct mcif_wb_funcs *funcs; + struct dc_context *ctx; + int inst; +}; + +struct mcif_wb_funcs { + + void (*warmup_mcif)( + struct mcif_wb *mcif_wb, + struct mcif_warmup_params *params); + void (*enable_mcif)(struct mcif_wb *mcif_wb); + + void (*disable_mcif)(struct mcif_wb *mcif_wb); + + void (*config_mcif_buf)( + struct mcif_wb *mcif_wb, + struct mcif_buf_params *params, + unsigned int dest_height); + + void (*config_mcif_arb)( + struct mcif_wb *mcif_wb, + struct mcif_arb_params *params); + + void (*config_mcif_irq)( + struct mcif_wb *mcif_wb, + struct mcif_irq_params *params); + + void (*dump_frame)( + struct mcif_wb *mcif_wb, + struct mcif_buf_params *mcif_params, + enum dwb_scaler_mode out_format, + unsigned int dest_width, + unsigned int dest_height, + struct mcif_wb_frame_dump_info *dump_info, + unsigned char *luma_buffer, + unsigned char *chroma_buffer, + unsigned char *dest_luma_buffer, + unsigned char *dest_chroma_buffer); +}; + +#endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h index 06df02ddff6a..d468bc85566a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h @@ -29,25 +29,41 @@ #include "include/grph_object_id.h" #include "dml/display_mode_structs.h" +#include "dml2_0/dml21/inc/dml_top_dchub_registers.h" struct dchub_init_data; -struct cstate_pstate_watermarks_st1 { +struct cstate_pstate_watermarks_st { uint32_t cstate_exit_ns; + uint32_t cstate_exit_z8_ns; + uint32_t cstate_enter_plus_exit_z8_ns; uint32_t cstate_enter_plus_exit_ns; uint32_t pstate_change_ns; + uint32_t fclk_pstate_change_ns; }; struct dcn_watermarks { uint32_t pte_meta_urgent_ns; uint32_t urgent_ns; - struct cstate_pstate_watermarks_st1 cstate_pstate; + uint32_t frac_urg_bw_nom; + uint32_t frac_urg_bw_flip; + uint32_t urgent_latency_ns; + struct cstate_pstate_watermarks_st cstate_pstate; + uint32_t usr_retraining_ns; }; -struct dcn_watermark_set { - struct dcn_watermarks a; - struct dcn_watermarks b; - struct dcn_watermarks c; - struct dcn_watermarks d; +union dcn_watermark_set { + struct { + struct dcn_watermarks a; + struct dcn_watermarks b; + struct dcn_watermarks c; + struct dcn_watermarks d; + }; // legacy + struct { + struct dml2_dchub_watermark_regs a; + struct dml2_dchub_watermark_regs b; + struct dml2_dchub_watermark_regs c; + struct dml2_dchub_watermark_regs d; + } dcn4x; //dcn4+ }; struct dce_watermarks { @@ -134,7 +150,7 @@ struct mem_input_funcs { void (*mem_input_program_pte_vm)( struct mem_input *mem_input, enum surface_pixel_format format, - union dc_tiling_info *tiling_info, + struct dc_tiling_info *tiling_info, enum dc_rotation_angle rotation); void (*mem_input_set_vm_system_aperture_settings)( @@ -148,8 +164,8 @@ struct mem_input_funcs { void (*mem_input_program_surface_config)( struct mem_input *mem_input, enum surface_pixel_format format, - union dc_tiling_info *tiling_info, - union plane_size *plane_size, + struct dc_tiling_info *tiling_info, + struct plane_size *plane_size, enum dc_rotation_angle rotation, struct dc_plane_dcc_param *dcc, bool horizontal_mirror); @@ -171,6 +187,8 @@ struct mem_input_funcs { const struct dc_cursor_position *pos, const struct dc_cursor_mi_param *param); + void (*mem_input_clear_tiling)( + struct mem_input *mem_input); }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h index caf74e3c836f..a8d1abe20f62 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h @@ -1,4 +1,5 @@ -/* Copyright 2012-15 Advanced Micro Devices, Inc. +/* + * Copyright 2012-15 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"), @@ -22,15 +23,43 @@ * */ +/** + * DOC: overview + * + * Multiple Pipe/Plane Combiner (MPC) is a component in the hardware pipeline + * that performs blending of multiple planes, using global and per-pixel alpha. + * It also performs post-blending color correction operations according to the + * hardware capabilities, such as color transformation matrix and gamma 1D and + * 3D LUT. + * + * MPC receives output from all DPP pipes and combines them to multiple outputs + * supporting "M MPC inputs -> N MPC outputs" flexible composition + * architecture. It features: + * + * - Programmable blending structure to allow software controlled blending and + * cascading; + * - Programmable window location of each DPP in active region of display; + * - Combining multiple DPP pipes in one active region when a single DPP pipe + * cannot process very large surface; + * - Combining multiple DPP from different SLS with blending; + * - Stereo formats from single DPP in top-bottom or side-by-side modes; + * - Stereo formats from 2 DPPs; + * - Alpha blending of multiple layers from different DPP pipes; + * - Programmable background color; + */ + #ifndef __DC_MPCC_H__ #define __DC_MPCC_H__ #include "dc_hw_types.h" #include "hw_shared.h" +#include "transform.h" #define MAX_MPCC 6 #define MAX_OPP 6 +#define MAX_DWB 2 + enum mpc_output_csc_mode { MPC_OUTPUT_CSC_DISABLE = 0, MPC_OUTPUT_CSC_COEF_A, @@ -45,23 +74,166 @@ enum mpcc_blend_mode { MPCC_BLEND_MODE_TOP_BOT_BLENDING }; +/** + * enum mpcc_alpha_blend_mode - define the alpha blend mode regarding pixel + * alpha and plane alpha values + */ enum mpcc_alpha_blend_mode { + /** + * @MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA: per pixel alpha using DPP + * alpha value + */ MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA, + /** + * @MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN: per + * pixel alpha using DPP alpha value multiplied by a global gain (plane + * alpha) + */ MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN, + /** + * @MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA: global alpha value, ignores + * pixel alpha and consider only plane alpha + */ MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA }; -/* - * MPCC blending configuration +enum mpcc_movable_cm_location { + MPCC_MOVABLE_CM_LOCATION_BEFORE, + MPCC_MOVABLE_CM_LOCATION_AFTER, +}; + +enum MCM_LUT_XABLE { + MCM_LUT_DISABLE, + MCM_LUT_DISABLED = MCM_LUT_DISABLE, + MCM_LUT_ENABLE, + MCM_LUT_ENABLED = MCM_LUT_ENABLE, +}; + +enum MCM_LUT_ID { + MCM_LUT_3DLUT, + MCM_LUT_1DLUT, + MCM_LUT_SHAPER +}; + +struct mpc_fl_3dlut_config { + bool enabled; + uint16_t width; + bool select_lut_bank_a; + uint16_t bit_depth; + int hubp_index; + uint16_t bias; + uint16_t scale; +}; + +union mcm_lut_params { + const struct pwl_params *pwl; + const struct tetrahedral_params *lut3d; +}; + +/** + * struct mpcc_blnd_cfg - MPCC blending configuration */ struct mpcc_blnd_cfg { - struct tg_color black_color; /* background color */ - enum mpcc_alpha_blend_mode alpha_mode; /* alpha blend mode */ - bool pre_multiplied_alpha; /* alpha pre-multiplied mode flag */ + /** + * @black_color: background color. + */ + struct tg_color black_color; + + /** + * @alpha_mode: alpha blend mode (MPCC_ALPHA_BLND_MODE). + */ + enum mpcc_alpha_blend_mode alpha_mode; + + /** + * @pre_multiplied_alpha: + * Whether pixel color values were pre-multiplied by the alpha channel + * (MPCC_ALPHA_MULTIPLIED_MODE). + */ + bool pre_multiplied_alpha; + + /** + * @global_gain: Used when blend mode considers both pixel alpha and plane. + */ int global_gain; + + /** + * @global_alpha: Plane alpha value. + */ int global_alpha; + + /** + * @overlap_only: Whether overlapping of different planes is allowed. + */ bool overlap_only; + /* MPCC top/bottom gain settings */ + + /** + * @bottom_gain_mode: Blend mode for bottom gain setting. + */ + int bottom_gain_mode; + + /** + * @background_color_bpc: Background color for bpc. + */ + int background_color_bpc; + + /** + * @top_gain: Top gain setting. + */ + int top_gain; + + /** + * @bottom_inside_gain: Blend mode for bottom inside. + */ + int bottom_inside_gain; + + /** + * @bottom_outside_gain: Blend mode for bottom outside. + */ + int bottom_outside_gain; +}; + +struct mpc_grph_gamut_adjustment { + struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE]; + enum graphics_gamut_adjust_type gamut_adjust_type; + enum mpcc_gamut_remap_id mpcc_gamut_remap_block_id; +}; + +struct mpc_rmcm_regs { + uint32_t rmcm_3dlut_mem_pwr_state; + uint32_t rmcm_3dlut_mem_pwr_force; + uint32_t rmcm_3dlut_mem_pwr_dis; + uint32_t rmcm_3dlut_mem_pwr_mode; + uint32_t rmcm_3dlut_size; + uint32_t rmcm_3dlut_mode; + uint32_t rmcm_3dlut_mode_cur; + uint32_t rmcm_3dlut_read_sel; + uint32_t rmcm_3dlut_30bit_en; + uint32_t rmcm_3dlut_wr_en_mask; + uint32_t rmcm_3dlut_ram_sel; + uint32_t rmcm_3dlut_out_norm_factor; + uint32_t rmcm_3dlut_fl_sel; + uint32_t rmcm_3dlut_out_offset_r; + uint32_t rmcm_3dlut_out_scale_r; + uint32_t rmcm_3dlut_fl_done; + uint32_t rmcm_3dlut_fl_soft_underflow; + uint32_t rmcm_3dlut_fl_hard_underflow; + uint32_t rmcm_cntl; + uint32_t rmcm_shaper_mem_pwr_state; + uint32_t rmcm_shaper_mem_pwr_force; + uint32_t rmcm_shaper_mem_pwr_dis; + uint32_t rmcm_shaper_mem_pwr_mode; + uint32_t rmcm_shaper_lut_mode; + uint32_t rmcm_shaper_mode_cur; + uint32_t rmcm_shaper_lut_write_en_mask; + uint32_t rmcm_shaper_lut_write_sel; + uint32_t rmcm_shaper_offset_b; + uint32_t rmcm_shaper_scale_b; + uint32_t rmcm_shaper_rama_exp_region_start_b; + uint32_t rmcm_shaper_rama_exp_region_start_seg_b; + uint32_t rmcm_shaper_rama_exp_region_end_b; + uint32_t rmcm_shaper_rama_exp_region_end_base_b; }; struct mpcc_sm_cfg { @@ -78,24 +250,75 @@ struct mpcc_sm_cfg { int force_next_field_polarity; }; -/* - * MPCC connection and blending configuration for a single MPCC instance. +struct mpc_denorm_clamp { + int clamp_max_r_cr; + int clamp_min_r_cr; + int clamp_max_g_y; + int clamp_min_g_y; + int clamp_max_b_cb; + int clamp_min_b_cb; +}; + +struct mpc_dwb_flow_control { + int flow_ctrl_mode; + int flow_ctrl_cnt0; + int flow_ctrl_cnt1; +}; + +/** + * struct mpcc - MPCC connection and blending configuration for a single MPCC instance. + * * This struct is used as a node in an MPC tree. */ struct mpcc { - int mpcc_id; /* MPCC physical instance */ - int dpp_id; /* DPP input to this MPCC */ - struct mpcc *mpcc_bot; /* pointer to bottom layer MPCC. NULL when not connected */ - struct mpcc_blnd_cfg blnd_cfg; /* The blending configuration for this MPCC */ - struct mpcc_sm_cfg sm_cfg; /* stereo mix setting for this MPCC */ + /** + * @mpcc_id: MPCC physical instance. + */ + int mpcc_id; + + /** + * @dpp_id: DPP input to this MPCC + */ + int dpp_id; + + /** + * @mpcc_bot: Pointer to bottom layer MPCC. NULL when not connected. + */ + struct mpcc *mpcc_bot; + + /** + * @blnd_cfg: The blending configuration for this MPCC. + */ + struct mpcc_blnd_cfg blnd_cfg; + + /** + * @sm_cfg: stereo mix setting for this MPCC + */ + struct mpcc_sm_cfg sm_cfg; + + /** + * @shared_bottom: + * + * If MPCC output to both OPP and DWB endpoints, true. Otherwise, false. + */ + bool shared_bottom; }; -/* - * MPC tree represents all MPCC connections for a pipe. +/** + * struct mpc_tree - MPC tree represents all MPCC connections for a pipe. + * + * */ struct mpc_tree { - int opp_id; /* The OPP instance that owns this MPC tree */ - struct mpcc *opp_list; /* The top MPCC layer of the MPC tree that outputs to OPP endpoint */ + /** + * @opp_id: The OPP instance that owns this MPC tree. + */ + int opp_id; + + /** + * @opp_list: the top MPCC layer of the MPC tree that outputs to OPP endpoint + */ + struct mpcc *opp_list; }; struct mpc { @@ -103,6 +326,8 @@ struct mpc { struct dc_context *ctx; struct mpcc mpcc_array[MAX_MPCC]; + struct pwl_params blender_params; + bool cm_bypass_mode; }; struct mpcc_state { @@ -115,30 +340,89 @@ struct mpcc_state { uint32_t overlap_only; uint32_t idle; uint32_t busy; + uint32_t shaper_lut_mode; + uint32_t lut3d_mode; + uint32_t lut3d_bit_depth; + uint32_t lut3d_size; + uint32_t rgam_mode; + uint32_t rgam_lut; + struct mpc_grph_gamut_adjustment gamut_remap; + struct mpc_rmcm_regs rmcm_regs; }; +struct dcn_mpc_reg_state { + uint32_t mpcc_bot_sel; + uint32_t mpcc_control; + uint32_t mpcc_status; + uint32_t mpcc_top_sel; + uint32_t mpcc_opp_id; + uint32_t mpcc_ogam_control; +}; + +/** + * struct mpc_funcs - funcs + */ struct mpc_funcs { + /** + * @read_mpcc_state: + * + * Read register content from given MPCC physical instance. + * + * Parameters: + * + * - [in/out] mpc - MPC context + * - [in] mpcc_instance - MPC context instance + * - [in] mpcc_state - MPC context state + * + * Return: + * + * void + */ void (*read_mpcc_state)( struct mpc *mpc, int mpcc_inst, struct mpcc_state *s); + /** + * @mpc_read_reg_state: + * + * Read MPC register state for debugging underflow purposes. + * + * Parameters: + * + * - [in] mpc - MPC context + * - [out] reg_state - MPC register state structure + * + * Return: + * + * void + */ + void (*mpc_read_reg_state)( + struct mpc *mpc, + int mpcc_inst, + struct dcn_mpc_reg_state *mpc_reg_state); - /* - * Insert DPP into MPC tree based on specified blending position. - * Only used for planes that are part of blending chain for OPP output - * - * Parameters: - * [in/out] mpc - MPC context. - * [in/out] tree - MPC tree structure that plane will be added to. - * [in] blnd_cfg - MPCC blending configuration for the new blending layer. - * [in] sm_cfg - MPCC stereo mix configuration for the new blending layer. - * stereo mix must disable for the very bottom layer of the tree config. - * [in] insert_above_mpcc - Insert new plane above this MPCC. If NULL, insert as bottom plane. - * [in] dpp_id - DPP instance for the plane to be added. - * [in] mpcc_id - The MPCC physical instance to use for blending. - * - * Return: struct mpcc* - MPCC that was added. - */ + /** + * @insert_plane: + * + * Insert DPP into MPC tree based on specified blending position. + * Only used for planes that are part of blending chain for OPP output + * + * Parameters: + * + * - [in/out] mpc - MPC context. + * - [in/out] tree - MPC tree structure that plane will be added to. + * - [in] blnd_cfg - MPCC blending configuration for the new blending layer. + * - [in] sm_cfg - MPCC stereo mix configuration for the new blending layer. + * stereo mix must disable for the very bottom layer of the tree config. + * - [in] insert_above_mpcc - Insert new plane above this MPCC. + * If NULL, insert as bottom plane. + * - [in] dpp_id - DPP instance for the plane to be added. + * - [in] mpcc_id - The MPCC physical instance to use for blending. + * + * Return: + * + * struct mpcc* - MPCC that was added. + */ struct mpcc* (*insert_plane)( struct mpc *mpc, struct mpc_tree *tree, @@ -148,58 +432,710 @@ struct mpc_funcs { int dpp_id, int mpcc_id); - /* - * Remove a specified MPCC from the MPC tree. - * - * Parameters: - * [in/out] mpc - MPC context. - * [in/out] tree - MPC tree structure that plane will be removed from. - * [in/out] mpcc - MPCC to be removed from tree. - * - * Return: void - */ + /** + * @remove_mpcc: + * + * Remove a specified MPCC from the MPC tree. + * + * Parameters: + * + * - [in/out] mpc - MPC context. + * - [in/out] tree - MPC tree structure that plane will be removed from. + * - [in/out] mpcc - MPCC to be removed from tree. + * + * Return: + * + * void + */ void (*remove_mpcc)( struct mpc *mpc, struct mpc_tree *tree, struct mpcc *mpcc); - /* - * Reset the MPCC HW status by disconnecting all muxes. - * - * Parameters: - * [in/out] mpc - MPC context. - * - * Return: void - */ + /** + * @mpc_init: + * + * Reset the MPCC HW status by disconnecting all muxes. + * + * Parameters: + * + * - [in/out] mpc - MPC context. + * + * Return: + * + * void + */ void (*mpc_init)(struct mpc *mpc); - /* - * Update the blending configuration for a specified MPCC. - * - * Parameters: - * [in/out] mpc - MPC context. - * [in] blnd_cfg - MPCC blending configuration. - * [in] mpcc_id - The MPCC physical instance. - * - * Return: void - */ + /** + * @mpc_init_single_inst: + * + * Initialize given MPCC physical instance. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] mpcc_id - The MPCC physical instance to be initialized. + */ + void (*mpc_init_single_inst)( + struct mpc *mpc, + unsigned int mpcc_id); + + /** + * @update_blending: + * + * Update the blending configuration for a specified MPCC. + * + * Parameters: + * + * - [in/out] mpc - MPC context. + * - [in] blnd_cfg - MPCC blending configuration. + * - [in] mpcc_id - The MPCC physical instance. + * + * Return: + * + * void + */ void (*update_blending)( struct mpc *mpc, struct mpcc_blnd_cfg *blnd_cfg, int mpcc_id); + /** + * @cursor_lock: + * + * Lock cursor updates for the specified OPP. OPP defines the set of + * MPCC that are locked together for cursor. + * + * Parameters: + * + * - [in] mpc - MPC context. + * - [in] opp_id - The OPP to lock cursor updates on + * - [in] lock - lock/unlock the OPP + * + * Return: + * + * void + */ + void (*cursor_lock)( + struct mpc *mpc, + int opp_id, + bool lock); + + /** + * @insert_plane_to_secondary: + * + * Add DPP into secondary MPC tree based on specified blending + * position. Only used for planes that are part of blending chain for + * DWB output + * + * Parameters: + * + * - [in/out] mpc - MPC context. + * - [in/out] tree - MPC tree structure that plane will be added to. + * - [in] blnd_cfg - MPCC blending configuration for the new blending layer. + * - [in] sm_cfg - MPCC stereo mix configuration for the new blending layer. + * stereo mix must disable for the very bottom layer of the tree config. + * - [in] insert_above_mpcc - Insert new plane above this MPCC. If + * NULL, insert as bottom plane. + * - [in] dpp_id - DPP instance for the plane to be added. + * - [in] mpcc_id - The MPCC physical instance to use for blending. + * + * Return: + * + * struct mpcc* - MPCC that was added. + */ + struct mpcc* (*insert_plane_to_secondary)( + struct mpc *mpc, + struct mpc_tree *tree, + struct mpcc_blnd_cfg *blnd_cfg, + struct mpcc_sm_cfg *sm_cfg, + struct mpcc *insert_above_mpcc, + int dpp_id, + int mpcc_id); + + /** + * @remove_mpcc_from_secondary: + * + * Remove a specified DPP from the 'secondary' MPC tree. + * + * Parameters: + * + * - [in/out] mpc - MPC context. + * - [in/out] tree - MPC tree structure that plane will be removed from. + * - [in] mpcc - MPCC to be removed from tree. + * + * Return: + * + * void + */ + void (*remove_mpcc_from_secondary)( + struct mpc *mpc, + struct mpc_tree *tree, + struct mpcc *mpcc); + + /** + * @get_mpcc_for_dpp_from_secondary: + * + * Find, if it exists, a MPCC from a given 'secondary' MPC tree that + * is associated with specified plane. + * + * Parameters: + * - [in/out] tree - MPC tree structure to search for plane. + * - [in] dpp_id - DPP to be searched. + * + * Return: + * + * struct mpcc* - pointer to plane or NULL if no plane found. + */ + struct mpcc* (*get_mpcc_for_dpp_from_secondary)( + struct mpc_tree *tree, + int dpp_id); + + /** + * @get_mpcc_for_dpp: + * + * Find, if it exists, a MPCC from a given MPC tree that + * is associated with specified plane. + * + * Parameters: + * - [in/out] tree - MPC tree structure to search for plane. + * - [in] dpp_id - DPP to be searched. + * + * Return: + * + * struct mpcc* - pointer to plane or NULL if no plane found. + */ struct mpcc* (*get_mpcc_for_dpp)( struct mpc_tree *tree, int dpp_id); + /** + * @wait_for_idle: + * + * Wait for a MPCC in MPC context to enter idle state. + * + * Parameters: + * - [in/out] mpc - MPC Context. + * - [in] id - MPCC to wait for idle state. + * + * Return: + * + * void + */ void (*wait_for_idle)(struct mpc *mpc, int id); + /** + * @assert_mpcc_idle_before_connect: + * + * Assert if MPCC in MPC context is in idle state. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] id - MPCC to assert idle state. + * + * Return: + * + * void + */ void (*assert_mpcc_idle_before_connect)(struct mpc *mpc, int mpcc_id); + /** + * @init_mpcc_list_from_hw: + * + * Iterate through the MPCC array from a given MPC context struct + * and configure each MPCC according to its registers' values. + * + * Parameters: + * - [in/out] mpc - MPC context to initialize MPCC array. + * - [in/out] tree - MPC tree structure containing MPCC contexts to initialize. + * + * Return: + * + * void + */ void (*init_mpcc_list_from_hw)( struct mpc *mpc, struct mpc_tree *tree); + /** + * @set_denorm: + * + * Set corresponding OPP DENORM_CONTROL register value to specific denorm_mode + * based on given color depth. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] opp_id - Corresponding OPP to update register. + * - [in] output_depth - Arbitrary color depth to set denorm_mode. + * + * Return: + * + * void + */ + void (*set_denorm)(struct mpc *mpc, + int opp_id, + enum dc_color_depth output_depth); + + /** + * @set_denorm_clamp: + * + * Set denorm clamp values on corresponding OPP DENORM CONTROL register. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] opp_id - Corresponding OPP to update register. + * - [in] denorm_clamp - Arbitrary denorm clamp to be set. + * + * Return: + * + * void + */ + void (*set_denorm_clamp)( + struct mpc *mpc, + int opp_id, + struct mpc_denorm_clamp denorm_clamp); + + /** + * @set_output_csc: + * + * Set the Output Color Space Conversion matrix + * with given values and mode. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] opp_id - Corresponding OPP to update register. + * - [in] regval - Values to set in CSC matrix. + * - [in] ocsc_mode - Mode to set CSC. + * + * Return: + * + * void + */ + void (*set_output_csc)(struct mpc *mpc, + int opp_id, + const uint16_t *regval, + enum mpc_output_csc_mode ocsc_mode); + + /** + * @set_ocsc_default: + * + * Set the Output Color Space Conversion matrix + * to default values according to color space. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] opp_id - Corresponding OPP to update register. + * - [in] color_space - OCSC color space. + * - [in] ocsc_mode - Mode to set CSC. + * + * Return: + * + * void + * + */ + void (*set_ocsc_default)(struct mpc *mpc, + int opp_id, + enum dc_color_space color_space, + enum mpc_output_csc_mode ocsc_mode); + + /** + * @set_output_gamma: + * + * Set Output Gamma with given curve parameters. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] mpcc_id - Corresponding MPC to update registers. + * - [in] params - Parameters. + * + * Return: + * + * void + * + */ + void (*set_output_gamma)( + struct mpc *mpc, + int mpcc_id, + const struct pwl_params *params); + /** + * @power_on_mpc_mem_pwr: + * + * Power on/off memory LUT for given MPCC. + * Powering on enables LUT to be updated. + * Powering off allows entering low power mode. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] mpcc_id - MPCC to power on. + * - [in] power_on + * + * Return: + * + * void + */ + void (*power_on_mpc_mem_pwr)( + struct mpc *mpc, + int mpcc_id, + bool power_on); + /** + * @set_dwb_mux: + * + * Set corresponding Display Writeback mux + * MPC register field to given MPCC id. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] dwb_id - DWB to be set. + * - [in] mpcc_id - MPCC id to be stored in DWB mux register. + * + * Return: + * + * void + */ + void (*set_dwb_mux)( + struct mpc *mpc, + int dwb_id, + int mpcc_id); + + /** + * @disable_dwb_mux: + * + * Reset corresponding Display Writeback mux + * MPC register field. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] dwb_id - DWB to be set. + * + * Return: + * + * void + */ + void (*disable_dwb_mux)( + struct mpc *mpc, + int dwb_id); + + /** + * @is_dwb_idle: + * + * Check DWB status on MPC_DWB0_MUX_STATUS register field. + * Return if it is null. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] dwb_id - DWB to be checked. + * + * Return: + * + * bool - wheter DWB is idle or not + */ + bool (*is_dwb_idle)( + struct mpc *mpc, + int dwb_id); + + /** + * @set_out_rate_control: + * + * Set display output rate control. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] opp_id - OPP to be set. + * - [in] enable + * - [in] rate_2x_mode + * - [in] flow_control + * + * Return: + * + * void + */ + void (*set_out_rate_control)( + struct mpc *mpc, + int opp_id, + bool enable, + bool rate_2x_mode, + struct mpc_dwb_flow_control *flow_control); + + /** + * @set_gamut_remap: + * + * Set post-blending CTM for given MPCC. + * + * Parameters: + * - [in] mpc - MPC context. + * - [in] mpcc_id - MPCC to set gamut map. + * - [in] adjust + * + * Return: + * + * void + */ + void (*set_gamut_remap)( + struct mpc *mpc, + int mpcc_id, + const struct mpc_grph_gamut_adjustment *adjust); + + /** + * @program_1dlut: + * + * Set 1 dimensional Lookup Table. + * + * Parameters: + * - [in/out] mpc - MPC context + * - [in] params - curve parameters for the LUT configuration + * - [in] rmu_idx + * + * bool - wheter LUT was set (set with given parameters) or not (params is NULL and LUT is disabled). + */ + bool (*program_1dlut)( + struct mpc *mpc, + const struct pwl_params *params, + uint32_t rmu_idx); + + /** + * @program_shaper: + * + * Set shaper. + * + * Parameters: + * - [in/out] mpc - MPC context + * - [in] params - curve parameters to be set + * - [in] rmu_idx + * + * Return: + * + * bool - wheter shaper was set (set with given parameters) or not (params is NULL and LUT is disabled). + */ + bool (*program_shaper)( + struct mpc *mpc, + const struct pwl_params *params, + uint32_t rmu_idx); + + /** + * @acquire_rmu: + * + * Set given MPCC to be multiplexed to given RMU unit. + * + * Parameters: + * - [in/out] mpc - MPC context + * - [in] mpcc_id - MPCC + * - [in] rmu_idx - Given RMU unit to set MPCC to be multiplexed to. + * + * Return: + * + * unit32_t - rmu_idx if operation was successful, -1 else. + */ + uint32_t (*acquire_rmu)(struct mpc *mpc, int mpcc_id, int rmu_idx); + + /** + * @program_3dlut: + * + * Set 3 dimensional Lookup Table. + * + * Parameters: + * - [in/out] mpc - MPC context + * - [in] params - tetrahedral parameters for the LUT configuration + * - [in] rmu_idx + * + * bool - wheter LUT was set (set with given parameters) or not (params is NULL and LUT is disabled). + */ + bool (*program_3dlut)( + struct mpc *mpc, + const struct tetrahedral_params *params, + int rmu_idx); + + /** + * @release_rmu: + * + * For a given MPCC, release the RMU unit it muliplexes to. + * + * Parameters: + * - [in/out] mpc - MPC context + * - [in] mpcc_id - MPCC + * + * Return: + * + * int - a valid rmu_idx representing released RMU unit or -1 if there was no RMU unit to release. + */ + int (*release_rmu)(struct mpc *mpc, int mpcc_id); + + /** + * @get_mpc_out_mux: + * + * Return MPC out mux. + * + * Parameters: + * - [in] mpc - MPC context. + * - [in] opp_id - OPP + * + * Return: + * + * unsigned int - Out Mux + */ + unsigned int (*get_mpc_out_mux)( + struct mpc *mpc, + int opp_id); + + /** + * @set_bg_color: + * + * Find corresponding bottommost MPCC and + * set its bg color. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] bg_color - background color to be set. + * - [in] mpcc_id + * + * Return: + * + * void + */ + void (*set_bg_color)(struct mpc *mpc, + struct tg_color *bg_color, + int mpcc_id); + + /** + * @set_mpc_mem_lp_mode: + * + * Set mpc_mem_lp_mode. + * + * Parameters: + * - [in/out] mpc - MPC context. + * + * Return: + * + * void + */ + + void (*set_mpc_mem_lp_mode)(struct mpc *mpc); + /** + * @set_movable_cm_location: + * + * Set Movable CM Location. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] location + * - [in] mpcc_id + * + * Return: + * + * void + */ + + void (*set_movable_cm_location)(struct mpc *mpc, enum mpcc_movable_cm_location location, int mpcc_id); + /** + * @update_3dlut_fast_load_select: + * + * Update 3D LUT fast load select. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] mpcc_id + * - [in] hubp_idx + * + * Return: + * + * void + */ + + void (*update_3dlut_fast_load_select)(struct mpc *mpc, int mpcc_id, int hubp_idx); + + /** + * @populate_lut: + * + * Populate LUT with given tetrahedral parameters. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] id + * - [in] params + * - [in] lut_bank_a + * - [in] mpcc_id + * + * Return: + * + * void + */ + void (*populate_lut)(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params, + bool lut_bank_a, int mpcc_id); + + /** + * @program_lut_read_write_control: + * + * Program LUT RW control. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] id + * - [in] lut_bank_a + * - [in] mpcc_id + * + * Return: + * + * void + */ + void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id); + + /** + * @program_lut_mode: + * + * Program LUT mode. + * + * Parameters: + * - [in/out] mpc - MPC context. + * - [in] id + * - [in] xable + * - [in] lut_bank_a + * - [in] mpcc_id + * + * Return: + * + * void + */ + void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_ID id, const enum MCM_LUT_XABLE xable, + bool lut_bank_a, int mpcc_id); + + /** + * @mcm: + * + * MPC MCM new HW sequential programming functions + */ + struct { + void (*program_3dlut_size)(struct mpc *mpc, uint32_t width, int mpcc_id); + void (*program_bias_scale)(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id); + void (*program_bit_depth)(struct mpc *mpc, uint16_t bit_depth, int mpcc_id); + bool (*is_config_supported)(uint32_t width); + void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id, + bool lut_bank_a, bool enabled, int mpcc_id); + + void (*populate_lut)(struct mpc *mpc, const union mcm_lut_params params, + bool lut_bank_a, int mpcc_id); + } mcm; + + /** + * @rmcm: + * + * MPC RMCM new HW sequential programming functions + */ + struct { + void (*fl_3dlut_configure)(struct mpc *mpc, struct mpc_fl_3dlut_config *cfg, int mpcc_id); + void (*enable_3dlut_fl)(struct mpc *mpc, bool enable, int mpcc_id); + void (*update_3dlut_fast_load_select)(struct mpc *mpc, int mpcc_id, int hubp_idx); + void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id, + bool lut_bank_a, bool enabled, int mpcc_id); + void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_XABLE xable, + bool lut_bank_a, int mpcc_id); + void (*program_3dlut_size)(struct mpc *mpc, uint32_t width, int mpcc_id); + void (*program_bias_scale)(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id); + void (*program_bit_depth)(struct mpc *mpc, uint16_t bit_depth, int mpcc_id); + bool (*is_config_supported)(uint32_t width); + + void (*power_on_shaper_3dlut)(struct mpc *mpc, uint32_t mpcc_id, bool power_on); + void (*populate_lut)(struct mpc *mpc, const union mcm_lut_params params, + bool lut_bank_a, int mpcc_id); + } rmcm; }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h index d974d9e18612..e1428a83ecbc 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h @@ -23,6 +23,22 @@ * */ +/** + * DOC: overview + * + * The Output Plane Processor (OPP) block groups have functions that format + * pixel streams such that they are suitable for display at the display device. + * The key functions contained in the OPP are: + * + * - Adaptive Backlight Modulation (ABM) + * - Formatter (FMT) which provide pixel-by-pixel operations for format the + * incoming pixel stream. + * - Output Buffer that provide pixel replication, and overlapping. + * - Interface between MPC and OPTC. + * - Clock and reset generation. + * - CRC generation. + */ + #ifndef __DAL_OPP_H__ #define __DAL_OPP_H__ @@ -189,9 +205,24 @@ struct gamma_coefficients { struct fixed31_32 user_brightness; }; +/** + * struct pwl_float_data - Fixed point RGB color + */ struct pwl_float_data { + /** + * @r: Component Red. + */ struct fixed31_32 r; + + /** + * @g: Component Green. + */ + struct fixed31_32 g; + + /** + * @b: Component Blue. + */ struct fixed31_32 b; }; @@ -208,6 +239,7 @@ struct output_pixel_processor { struct mpc_tree mpc_tree_params; bool mpcc_disconnect_pending[MAX_PIPES]; const struct opp_funcs *funcs; + uint32_t dyn_expansion; }; enum fmt_stereo_action { @@ -262,6 +294,17 @@ struct oppbuf_params { enum oppbuf_display_segmentation mso_segmentation; uint32_t mso_overlap_pixel_num; uint32_t pixel_repetition; + uint32_t num_segment_padded_pixels; +}; + +struct dcn_opp_reg_state { + uint32_t dpg_control; + uint32_t fmt_control; + uint32_t oppbuf_control; + uint32_t opp_pipe_control; + uint32_t opp_pipe_crc_control; + uint32_t opp_abm_control; + uint32_t dscrm_dsc_forward_config; }; struct opp_funcs { @@ -301,6 +344,43 @@ struct opp_funcs { struct output_pixel_processor *opp, bool enable); + void (*opp_set_disp_pattern_generator)( + struct output_pixel_processor *opp, + enum controller_dp_test_pattern test_pattern, + enum controller_dp_color_space color_space, + enum dc_color_depth color_depth, + const struct tg_color *solid_color, + int width, + int height, + int offset); + + void (*opp_program_dpg_dimensions)( + struct output_pixel_processor *opp, + int width, + int height); + + bool (*dpg_is_blanked)( + struct output_pixel_processor *opp); + + bool (*dpg_is_pending)(struct output_pixel_processor *opp); + + + void (*opp_dpg_set_blank_color)( + struct output_pixel_processor *opp, + const struct tg_color *color); + + void (*opp_program_left_edge_extra_pixel)( + struct output_pixel_processor *opp, + enum dc_pixel_encoding pixel_encoding, + bool is_primary); + + uint32_t (*opp_get_left_edge_extra_pixel_count)( + struct output_pixel_processor *opp, + enum dc_pixel_encoding pixel_encoding, + bool is_primary); + + void (*opp_read_reg_state)( + struct output_pixel_processor *opp, struct dcn_opp_reg_state *opp_reg_state); }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/optc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/optc.h new file mode 100644 index 000000000000..0d5a8358a778 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/optc.h @@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright 2023 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 + * + */ + +/** + * DOC: overview + * + * Output Pipe Timing Combiner (OPTC) includes two major functional blocks: + * Output Data Mapper (ODM) and Output Timing Generator (OTG). + * + * - ODM: It is Output Data Mapping block. It can combine input data from + * multiple OPP data pipes into one single data stream or split data from one + * OPP data pipe into multiple data streams or just bypass OPP data to DIO. + * - OTG: It is Output Timing Generator. It generates display timing signals to + * drive the display output. + */ + +#ifndef __DC_OPTC_H__ +#define __DC_OPTC_H__ + +#include "timing_generator.h" + +struct optc { + struct timing_generator base; + + const struct dcn_optc_registers *tg_regs; + const struct dcn_optc_shift *tg_shift; + const struct dcn_optc_mask *tg_mask; + + int opp_count; + + uint32_t max_h_total; + uint32_t max_v_total; + + uint32_t min_h_blank; + + uint32_t min_h_sync_width; + uint32_t min_v_sync_width; + uint32_t min_v_blank; + uint32_t min_v_blank_interlace; + + int vstartup_start; + int vupdate_offset; + int vupdate_width; + int vready_offset; + int pstate_keepout; + struct dc_crtc_timing orginal_patched_timing; + enum signal_type signal; + uint32_t max_frame_count; +}; + +void optc1_read_otg_state(struct timing_generator *optc, struct dcn_otg_state *s); + +bool optc1_get_hw_timing(struct timing_generator *tg, struct dc_crtc_timing *hw_crtc_timing); + +bool optc1_validate_timing(struct timing_generator *optc, + const struct dc_crtc_timing *timing); + +void optc1_program_timing(struct timing_generator *optc, + const struct dc_crtc_timing *dc_crtc_timing, + int vready_offset, + int vstartup_start, + int vupdate_offset, + int vupdate_width, + int pstate_keepout, + const enum signal_type signal, + bool use_vbios); + +void optc1_setup_vertical_interrupt0(struct timing_generator *optc, + uint32_t start_line, + uint32_t end_line); + +void optc1_setup_vertical_interrupt1(struct timing_generator *optc, + uint32_t start_line); + +void optc1_setup_vertical_interrupt2(struct timing_generator *optc, + uint32_t start_line); + +void optc1_program_global_sync(struct timing_generator *optc, + int vready_offset, + int vstartup_start, + int vupdate_offset, + int vupdate_width, + int pstate_keepout); + +bool optc1_disable_crtc(struct timing_generator *optc); + +bool optc1_is_counter_moving(struct timing_generator *optc); + +void optc1_get_position(struct timing_generator *optc, + struct crtc_position *position); + +uint32_t optc1_get_vblank_counter(struct timing_generator *optc); + +void optc1_get_crtc_scanoutpos(struct timing_generator *optc, + uint32_t *v_blank_start, + uint32_t *v_blank_end, + uint32_t *h_position, + uint32_t *v_position); + +void optc1_set_early_control(struct timing_generator *optc, + uint32_t early_cntl); + +void optc1_wait_for_state(struct timing_generator *optc, + enum crtc_state state); + +void optc1_set_blank(struct timing_generator *optc, + bool enable_blanking); + +bool optc1_is_blanked(struct timing_generator *optc); + +void optc1_program_blank_color(struct timing_generator *optc, + const struct tg_color *black_color); + +bool optc1_did_triggered_reset_occur(struct timing_generator *optc); + +void optc1_enable_reset_trigger(struct timing_generator *optc, int source_tg_inst); + +void optc1_disable_reset_trigger(struct timing_generator *optc); + +void optc1_lock(struct timing_generator *optc); + +void optc1_unlock(struct timing_generator *optc); + +void optc1_enable_optc_clock(struct timing_generator *optc, bool enable); + +void optc1_set_drr(struct timing_generator *optc, + const struct drr_params *params); + +void optc1_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, int vtotal_max); + +void optc1_set_static_screen_control(struct timing_generator *optc, + uint32_t event_triggers, + uint32_t num_frames); + +void optc1_program_stereo(struct timing_generator *optc, + const struct dc_crtc_timing *timing, + struct crtc_stereo_flags *flags); + +bool optc1_is_stereo_left_eye(struct timing_generator *optc); + +void optc1_clear_optc_underflow(struct timing_generator *optc); + +void optc1_tg_init(struct timing_generator *optc); + +bool optc1_is_tg_enabled(struct timing_generator *optc); + +bool optc1_is_optc_underflow_occurred(struct timing_generator *optc); + +void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable); + +void optc1_set_timing_double_buffer(struct timing_generator *optc, bool enable); + +bool optc1_get_otg_active_size(struct timing_generator *optc, + uint32_t *otg_active_width, + uint32_t *otg_active_height); + +void optc1_enable_crtc_reset(struct timing_generator *optc, + int source_tg_inst, + struct crtc_trigger_info *crtc_tp); + +bool optc1_configure_crc(struct timing_generator *optc, const struct crc_params *params); + +bool optc1_get_crc(struct timing_generator *optc, uint8_t idx, + uint32_t *r_cr, + uint32_t *g_y, + uint32_t *b_cb); + +void optc1_set_vtg_params(struct timing_generator *optc, + const struct dc_crtc_timing *dc_crtc_timing, + bool program_fp2); + +bool optc1_is_two_pixels_per_container(const struct dc_crtc_timing *timing); + +#endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/panel_cntl.h b/drivers/gpu/drm/amd/display/dc/inc/hw/panel_cntl.h new file mode 100644 index 000000000000..e97d964a1791 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/panel_cntl.h @@ -0,0 +1,72 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ +/* + * panel_cntl.h + * + * Created on: Oct 6, 2015 + * Author: yonsun + */ + +#ifndef DC_PANEL_CNTL_H_ +#define DC_PANEL_CNTL_H_ + +#include "dc_types.h" + +#define MAX_BACKLIGHT_LEVEL 0xFFFF + +struct panel_cntl_backlight_registers { + unsigned int BL_PWM_CNTL; + unsigned int BL_PWM_CNTL2; + unsigned int BL_PWM_PERIOD_CNTL; + unsigned int LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV; + unsigned int PANEL_PWRSEQ_REF_DIV2; + unsigned int USER_LEVEL; +}; + +struct panel_cntl_funcs { + void (*destroy)(struct panel_cntl **panel_cntl); + uint32_t (*hw_init)(struct panel_cntl *panel_cntl); + bool (*is_panel_backlight_on)(struct panel_cntl *panel_cntl); + bool (*is_panel_powered_on)(struct panel_cntl *panel_cntl); + void (*store_backlight_level)(struct panel_cntl *panel_cntl); + void (*driver_set_backlight)(struct panel_cntl *panel_cntl, + uint32_t backlight_pwm_u16_16); + uint32_t (*get_current_backlight)(struct panel_cntl *panel_cntl); +}; + +struct panel_cntl_init_data { + struct dc_context *ctx; + uint32_t inst; + uint32_t eng_id; +}; + +struct panel_cntl { + const struct panel_cntl_funcs *funcs; + struct dc_context *ctx; + uint32_t inst; + uint32_t pwrseq_inst; + /* registers setting needs to be saved and restored at InitBacklight */ + struct panel_cntl_backlight_registers stored_backlight_registers; +}; + +#endif /* DC_PANEL_CNTL_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/pg_cntl.h b/drivers/gpu/drm/amd/display/dc/inc/hw/pg_cntl.h new file mode 100644 index 000000000000..227e3f8d7e5f --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/pg_cntl.h @@ -0,0 +1,55 @@ +/* Copyright 2023 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_PG_CNTL_H__ +#define __DC_PG_CNTL_H__ + +#include "dc.h" +#include "dc_types.h" +#include "hw_shared.h" + +struct pg_cntl { + struct dc_context *ctx; + const struct pg_cntl_funcs *funcs; + bool pg_pipe_res_enable[PG_HW_PIPE_RESOURCES_NUM_ELEMENT][MAX_PIPES]; + bool pg_res_enable[PG_HW_RESOURCES_NUM_ELEMENT]; +}; + +struct pg_cntl_funcs { + void (*dsc_pg_control)(struct pg_cntl *pg_cntl, unsigned int dsc_inst, bool power_on); + void (*hubp_dpp_pg_control)(struct pg_cntl *pg_cntl, unsigned int hubp_dpp_inst, bool power_on); + void (*hpo_pg_control)(struct pg_cntl *pg_cntl, bool power_on); + void (*io_clk_pg_control)(struct pg_cntl *pg_cntl, bool power_on); + void (*plane_otg_pg_control)(struct pg_cntl *pg_cntl, bool power_on); + void (*mpcc_pg_control)(struct pg_cntl *pg_cntl, unsigned int mpcc_inst, bool power_on); + void (*opp_pg_control)(struct pg_cntl *pg_cntl, unsigned int opp_inst, bool power_on); + void (*optc_pg_control)(struct pg_cntl *pg_cntl, unsigned int optc_inst, bool power_on); + void (*dwb_pg_control)(struct pg_cntl *pg_cntl, bool power_on); + void (*mem_pg_control)(struct pg_cntl *pg_cntl, bool power_on); + void (*dio_pg_control)(struct pg_cntl *pg_cntl, bool power_on); + void (*init_pg_status)(struct pg_cntl *pg_cntl); + void (*print_pg_status)(struct pg_cntl *pg_cntl, const char *debug_func, const char *debug_log); +}; + +#endif //__DC_PG_CNTL_H__ 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 53a9b64df11a..27f950ae45ee 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 @@ -52,22 +52,54 @@ enum dp_component_depth { DP_COMPONENT_PIXEL_DEPTH_16BPC = 0x00000004 }; +struct audio_clock_info { + /* pixel clock frequency*/ + uint32_t pixel_clock_in_10khz; + /* N - 32KHz audio */ + uint32_t n_32khz; + /* CTS - 32KHz audio*/ + uint32_t cts_32khz; + uint32_t n_44khz; + uint32_t cts_44khz; + uint32_t n_48khz; + uint32_t cts_48khz; +}; + +enum dynamic_metadata_mode { + dmdata_dp, + dmdata_hdmi, + dmdata_dolby_vision +}; + +struct enc_sdp_line_num { + /* Adaptive Sync SDP */ + bool adaptive_sync_line_num_valid; + uint32_t adaptive_sync_line_num; +}; + struct encoder_info_frame { /* auxiliary video information */ struct dc_info_packet avi; struct dc_info_packet gamut; struct dc_info_packet vendor; + struct dc_info_packet hfvsif; + struct dc_info_packet vtem; /* source product description */ struct dc_info_packet spd; /* video stream configuration */ struct dc_info_packet vsc; /* HDR Static MetaData */ struct dc_info_packet hdrsmd; + /* Adaptive Sync SDP*/ + struct dc_info_packet adaptive_sync; + struct enc_sdp_line_num sdp_line_num; }; struct encoder_unblank_param { struct dc_link_settings link_settings; - unsigned int pixel_clk_khz; + struct dc_crtc_timing timing; + int opp_cnt; + uint32_t pix_per_cycle; }; struct encoder_set_dp_phy_pattern_param { @@ -82,13 +114,29 @@ struct stream_encoder { struct dc_context *ctx; struct dc_bios *bp; enum engine_id id; + uint32_t stream_enc_inst; + struct vpg *vpg; + struct afmt *afmt; + struct apg *apg; +}; + +struct enc_state { + uint32_t dsc_mode; // DISABLED 0; 1 or 2 indicate enabled state. + uint32_t dsc_slice_width; + uint32_t sec_gsp_pps_line_num; + uint32_t vbid6_line_reference; + uint32_t vbid6_line_num; + uint32_t sec_gsp_pps_enable; + uint32_t sec_stream_enable; }; struct stream_encoder_funcs { void (*dp_set_stream_attribute)( struct stream_encoder *enc, struct dc_crtc_timing *crtc_timing, - enum dc_color_space output_color_space); + enum dc_color_space output_color_space, + bool use_vsc_sdp_for_colorimetry, + uint32_t enable_sdp_splitting); void (*hdmi_set_stream_attribute)( struct stream_encoder *enc, @@ -105,7 +153,7 @@ struct stream_encoder_funcs { struct stream_encoder *enc, struct dc_crtc_timing *crtc_timing); - void (*set_mst_bandwidth)( + void (*set_throttled_vcp_size)( struct stream_encoder *enc, struct fixed31_32 avg_time_slots_per_mtp); @@ -116,17 +164,28 @@ struct stream_encoder_funcs { void (*stop_hdmi_info_packets)( struct stream_encoder *enc); + void (*update_dp_info_packets_sdp_line_num)( + struct stream_encoder *enc, + struct encoder_info_frame *info_frame); + void (*update_dp_info_packets)( struct stream_encoder *enc, const struct encoder_info_frame *info_frame); + void (*send_immediate_sdp_message)( + struct stream_encoder *enc, + const uint8_t *custom_sdp_message, + unsigned int sdp_message_size); + void (*stop_dp_info_packets)( struct stream_encoder *enc); void (*dp_blank)( + struct dc_link *link, struct stream_encoder *enc); void (*dp_unblank)( + struct dc_link *link, struct stream_encoder *enc, const struct encoder_unblank_param *param); @@ -161,6 +220,146 @@ struct stream_encoder_funcs { void (*set_avmute)( struct stream_encoder *enc, bool enable); + void (*dig_connect_to_otg)( + struct stream_encoder *enc, + int tg_inst); + + void (*enable_stream)( + struct stream_encoder *enc, + enum signal_type signal, + bool enable); + + void (*hdmi_reset_stream_attribute)( + struct stream_encoder *enc); + + unsigned int (*dig_source_otg)( + struct stream_encoder *enc); + + bool (*dp_get_pixel_format)( + struct stream_encoder *enc, + enum dc_pixel_encoding *encoding, + enum dc_color_depth *depth); + + void (*enc_read_state)(struct stream_encoder *enc, struct enc_state *s); + + void (*dp_set_dsc_config)( + struct stream_encoder *enc, + enum optc_dsc_mode dsc_mode, + uint32_t dsc_bytes_per_pixel, + uint32_t dsc_slice_width); + + void (*dp_set_dsc_pps_info_packet)(struct stream_encoder *enc, + bool enable, + uint8_t *dsc_packed_pps, + bool immediate_update); + + void (*set_dynamic_metadata)(struct stream_encoder *enc, + bool enable, + uint32_t hubp_requestor_id, + enum dynamic_metadata_mode dmdata_mode); + + /** + * @dp_set_odm_combine: Sets up DP stream encoder for ODM. + */ + void (*dp_set_odm_combine)( + struct stream_encoder *enc, + bool odm_combine); + + uint32_t (*get_fifo_cal_average_level)( + struct stream_encoder *enc); + + void (*set_input_mode)( + struct stream_encoder *enc, unsigned int pix_per_container); + void (*enable_fifo)(struct stream_encoder *enc); + void (*disable_fifo)(struct stream_encoder *enc); + bool (*is_fifo_enabled)(struct stream_encoder *enc); + void (*map_stream_to_link)(struct stream_encoder *enc, uint32_t stream_enc_inst, uint32_t link_enc_inst); + uint32_t (*get_pixels_per_cycle)(struct stream_encoder *enc); +}; + +struct hpo_dp_stream_encoder_state { + uint32_t stream_enc_enabled; + uint32_t vid_stream_enabled; + uint32_t otg_inst; + uint32_t pixel_encoding; + uint32_t component_depth; + uint32_t compressed_format; + uint32_t sdp_enabled; + uint32_t mapped_to_link_enc; +}; + +struct hpo_dp_stream_encoder { + const struct hpo_dp_stream_encoder_funcs *funcs; + struct dc_context *ctx; + struct dc_bios *bp; + uint32_t inst; + enum engine_id id; + struct vpg *vpg; + struct apg *apg; +}; + +struct hpo_dp_stream_encoder_funcs { + void (*enable_stream)( + struct hpo_dp_stream_encoder *enc); + + void (*dp_unblank)( + struct hpo_dp_stream_encoder *enc, + uint32_t stream_source); + + void (*dp_blank)( + struct hpo_dp_stream_encoder *enc); + + void (*disable)( + struct hpo_dp_stream_encoder *enc); + + void (*set_stream_attribute)( + struct hpo_dp_stream_encoder *enc, + struct dc_crtc_timing *crtc_timing, + enum dc_color_space output_color_space, + bool use_vsc_sdp_for_colorimetry, + bool compressed_format, + bool double_buffer_en); + + void (*update_dp_info_packets_sdp_line_num)( + struct hpo_dp_stream_encoder *enc, + struct encoder_info_frame *info_frame); + + void (*update_dp_info_packets)( + struct hpo_dp_stream_encoder *enc, + const struct encoder_info_frame *info_frame); + + void (*stop_dp_info_packets)( + struct hpo_dp_stream_encoder *enc); + + void (*dp_set_dsc_pps_info_packet)( + struct hpo_dp_stream_encoder *enc, + bool enable, + uint8_t *dsc_packed_pps, + bool immediate_update); + + void (*map_stream_to_link)( + struct hpo_dp_stream_encoder *enc, + uint32_t stream_enc_inst, + uint32_t link_enc_inst); + + void (*dp_audio_setup)( + struct hpo_dp_stream_encoder *enc, + unsigned int az_inst, + struct audio_info *info); + + void (*dp_audio_enable)( + struct hpo_dp_stream_encoder *enc); + + void (*dp_audio_disable)( + struct hpo_dp_stream_encoder *enc); + + void (*read_state)( + struct hpo_dp_stream_encoder *enc, + struct hpo_dp_stream_encoder_state *state); + + void (*set_hblank_min_symbol_width)( + struct hpo_dp_stream_encoder *enc, + uint16_t width); }; #endif /* STREAM_ENCODER_H_ */ 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 af700c7dac50..da7bf59c4b9d 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 @@ -59,9 +59,17 @@ struct gsl_params { struct drr_params { uint32_t vertical_total_min; uint32_t vertical_total_max; + uint32_t vertical_total_mid; + uint32_t vertical_total_mid_frame_num; bool immediate_flip; }; +struct long_vtotal_params { + uint32_t vertical_total_min; + uint32_t vertical_total_max; + uint32_t vertical_blank_start; +}; + #define LEFT_EYE_3D_PRIMARY_SURFACE 1 #define RIGHT_EYE_3D_PRIMARY_SURFACE 0 @@ -70,14 +78,6 @@ enum crtc_state { CRTC_STATE_VACTIVE }; -struct _dlg_otg_param { - int vstartup_start; - int vupdate_offset; - int vupdate_width; - int vready_offset; - enum signal_type signal; -}; - struct vupdate_keepout_params { int start_offset; int end_offset; @@ -104,6 +104,24 @@ enum crc_selection { INTERSECT_WINDOW_NOT_A_NOT_B, }; +enum otg_out_mux_dest { + OUT_MUX_DIO = 0, + OUT_MUX_HPO_DP = 2, +}; + +enum h_timing_div_mode { + H_TIMING_NO_DIV, + H_TIMING_DIV_BY2, + H_TIMING_RESERVED, + H_TIMING_DIV_BY4, +}; + +enum timing_synchronization_type { + NOT_SYNCHRONIZABLE, + TIMING_SYNCHRONIZABLE, + VBLANK_SYNCHRONIZABLE +}; + struct crc_params { /* Regions used to calculate CRC*/ uint16_t windowa_x_start; @@ -118,15 +136,184 @@ struct crc_params { enum crc_selection selection; + uint8_t dsc_mode; + uint8_t odm_mode; + bool continuous_mode; bool enable; + + uint8_t crc_eng_inst; + bool reset; +}; + +struct dcn_otg_state { + uint32_t v_blank_start; + uint32_t v_blank_end; + uint32_t v_sync_a_pol; + uint32_t v_total; + uint32_t v_total_max; + uint32_t v_total_min; + uint32_t v_total_min_sel; + uint32_t v_total_max_sel; + uint32_t v_sync_a_start; + uint32_t v_sync_a_end; + uint32_t h_blank_start; + uint32_t h_blank_end; + uint32_t h_sync_a_start; + uint32_t h_sync_a_end; + uint32_t h_sync_a_pol; + uint32_t h_total; + uint32_t underflow_occurred_status; + uint32_t otg_enabled; + uint32_t blank_enabled; + uint32_t vertical_interrupt1_en; + uint32_t vertical_interrupt1_line; + uint32_t vertical_interrupt2_en; + uint32_t vertical_interrupt2_line; + uint32_t vertical_interrupt2_dest; + uint32_t otg_master_update_lock; + uint32_t otg_double_buffer_control; }; +struct dcn_optc_reg_state { + uint32_t optc_bytes_per_pixel; + uint32_t optc_data_format_control; + uint32_t optc_data_source_select; + uint32_t optc_input_clock_control; + uint32_t optc_input_global_control; + uint32_t optc_input_spare_register; + uint32_t optc_memory_config; + uint32_t optc_rsmu_underflow; + uint32_t optc_underflow_threshold; + uint32_t optc_width_control; + + uint32_t otg_3d_structure_control; + uint32_t otg_clock_control; + uint32_t otg_control; + uint32_t otg_count_control; + uint32_t otg_count_reset; + uint32_t otg_crc_cntl; + uint32_t otg_crc_sig_blue_control_mask; + uint32_t otg_crc_sig_red_green_mask; + uint32_t otg_crc0_data_b; + uint32_t otg_crc0_data_rg; + uint32_t otg_crc0_windowa_x_control; + uint32_t otg_crc0_windowa_x_control_readback; + uint32_t otg_crc0_windowa_y_control; + uint32_t otg_crc0_windowa_y_control_readback; + uint32_t otg_crc0_windowb_x_control; + uint32_t otg_crc0_windowb_x_control_readback; + uint32_t otg_crc0_windowb_y_control; + uint32_t otg_crc0_windowb_y_control_readback; + uint32_t otg_crc1_data_b; + uint32_t otg_crc1_data_rg; + uint32_t otg_crc1_windowa_x_control; + uint32_t otg_crc1_windowa_x_control_readback; + uint32_t otg_crc1_windowa_y_control; + uint32_t otg_crc1_windowa_y_control_readback; + uint32_t otg_crc1_windowb_x_control; + uint32_t otg_crc1_windowb_x_control_readback; + uint32_t otg_crc1_windowb_y_control; + uint32_t otg_crc1_windowb_y_control_readback; + uint32_t otg_crc2_data_b; + uint32_t otg_crc2_data_rg; + uint32_t otg_crc3_data_b; + uint32_t otg_crc3_data_rg; + uint32_t otg_dlpc_control; + uint32_t otg_double_buffer_control; + uint32_t otg_drr_control2; + uint32_t otg_drr_control; + uint32_t otg_drr_timing_int_status; + uint32_t otg_drr_trigger_window; + uint32_t otg_drr_v_total_change; + uint32_t otg_drr_v_total_reach_range; + uint32_t otg_dsc_start_position; + uint32_t otg_force_count_now_cntl; + uint32_t otg_global_control0; + uint32_t otg_global_control1; + uint32_t otg_global_control2; + uint32_t otg_global_control3; + uint32_t otg_global_control4; + uint32_t otg_global_sync_status; + uint32_t otg_gsl_control; + uint32_t otg_gsl_vsync_gap; + uint32_t otg_gsl_window_x; + uint32_t otg_gsl_window_y; + uint32_t otg_h_blank_start_end; + uint32_t otg_h_sync_a; + uint32_t otg_h_sync_a_cntl; + uint32_t otg_h_timing_cntl; + uint32_t otg_h_total; + uint32_t otg_interlace_control; + uint32_t otg_interlace_status; + uint32_t otg_interrupt_control; + uint32_t otg_long_vblank_status; + uint32_t otg_m_const_dto0; + uint32_t otg_m_const_dto1; + uint32_t otg_manual_force_vsync_next_line; + uint32_t otg_master_en; + uint32_t otg_master_update_lock; + uint32_t otg_master_update_mode; + uint32_t otg_nom_vert_position; + uint32_t otg_pipe_update_status; + uint32_t otg_pixel_data_readback0; + uint32_t otg_pixel_data_readback1; + uint32_t otg_request_control; + uint32_t otg_snapshot_control; + uint32_t otg_snapshot_frame; + uint32_t otg_snapshot_position; + uint32_t otg_snapshot_status; + uint32_t otg_spare_register; + uint32_t otg_static_screen_control; + uint32_t otg_status; + uint32_t otg_status_frame_count; + uint32_t otg_status_hv_count; + uint32_t otg_status_position; + uint32_t otg_status_vf_count; + uint32_t otg_stereo_control; + uint32_t otg_stereo_force_next_eye; + uint32_t otg_stereo_status; + uint32_t otg_trig_manual_control; + uint32_t otg_triga_cntl; + uint32_t otg_triga_manual_trig; + uint32_t otg_trigb_cntl; + uint32_t otg_trigb_manual_trig; + uint32_t otg_update_lock; + uint32_t otg_v_blank_start_end; + uint32_t otg_v_count_stop_control; + uint32_t otg_v_count_stop_control2; + uint32_t otg_v_sync_a; + uint32_t otg_v_sync_a_cntl; + uint32_t otg_v_total; + uint32_t otg_v_total_control; + uint32_t otg_v_total_int_status; + uint32_t otg_v_total_max; + uint32_t otg_v_total_mid; + uint32_t otg_v_total_min; + uint32_t otg_vert_sync_control; + uint32_t otg_vertical_interrupt0_control; + uint32_t otg_vertical_interrupt0_position; + uint32_t otg_vertical_interrupt1_control; + uint32_t otg_vertical_interrupt1_position; + uint32_t otg_vertical_interrupt2_control; + uint32_t otg_vertical_interrupt2_position; + uint32_t otg_vready_param; + uint32_t otg_vstartup_param; + uint32_t otg_vsync_nom_int_status; + uint32_t otg_vupdate_keepout; + uint32_t otg_vupdate_param; +}; + +/** + * struct timing_generator - Entry point to Output Timing Generator feature. + */ struct timing_generator { + /** + * @funcs: Timing generator control functions + */ const struct timing_generator_funcs *funcs; struct dc_bios *bp; struct dc_context *ctx; - struct _dlg_otg_param dlg_otg_param; int inst; }; @@ -134,17 +321,38 @@ struct dc_crtc_timing; struct drr_params; +/** + * struct timing_generator_funcs - Control timing generator on a given device. + */ struct timing_generator_funcs { bool (*validate_timing)(struct timing_generator *tg, const struct dc_crtc_timing *timing); void (*program_timing)(struct timing_generator *tg, const struct dc_crtc_timing *timing, - bool use_vbios); - void (*program_vline_interrupt)(struct timing_generator *optc, - const struct dc_crtc_timing *dc_crtc_timing, - unsigned long long vsync_delta); + int vready_offset, + int vstartup_start, + int vupdate_offset, + int vupdate_width, + int pstate_keepout, + const enum signal_type signal, + bool use_vbios + ); + void (*setup_vertical_interrupt0)( + struct timing_generator *optc, + uint32_t start_line, + uint32_t end_line); + void (*setup_vertical_interrupt1)( + struct timing_generator *optc, + uint32_t start_line); + void (*setup_vertical_interrupt2)( + struct timing_generator *optc, + uint32_t start_line); + bool (*enable_crtc)(struct timing_generator *tg); bool (*disable_crtc)(struct timing_generator *tg); + void (*phantom_crtc_post_enable)(struct timing_generator *tg); + void (*disable_phantom_crtc)(struct timing_generator *tg); + bool (*immediate_disable_crtc)(struct timing_generator *tg); bool (*is_counter_moving)(struct timing_generator *tg); void (*get_position)(struct timing_generator *tg, struct crtc_position *position); @@ -159,6 +367,8 @@ struct timing_generator_funcs { bool (*get_otg_active_size)(struct timing_generator *optc, uint32_t *otg_active_width, uint32_t *otg_active_height); + bool (*is_matching_timing)(struct timing_generator *tg, + const struct dc_crtc_timing *otg_timing); void (*set_early_control)(struct timing_generator *tg, uint32_t early_cntl); void (*wait_for_state)(struct timing_generator *tg, @@ -178,6 +388,10 @@ struct timing_generator_funcs { const struct dcp_gsl_params *gsl_params); void (*unlock)(struct timing_generator *tg); void (*lock)(struct timing_generator *tg); + void (*lock_doublebuffer_disable)(struct timing_generator *tg); + void (*lock_doublebuffer_enable)(struct timing_generator *tg); + void(*triplebuffer_unlock)(struct timing_generator *tg); + void(*triplebuffer_lock)(struct timing_generator *tg); void (*enable_reset_trigger)(struct timing_generator *tg, int source_tg_inst); void (*enable_crtc_reset)(struct timing_generator *tg, @@ -188,8 +402,11 @@ struct timing_generator_funcs { void (*enable_advanced_request)(struct timing_generator *tg, bool enable, const struct dc_crtc_timing *timing); void (*set_drr)(struct timing_generator *tg, const struct drr_params *params); + void (*set_vtotal_min_max)(struct timing_generator *optc, int vtotal_min, int vtotal_max); + void (*get_last_used_drr_vtotal)(struct timing_generator *optc, uint32_t *refresh_rate); void (*set_static_screen_control)(struct timing_generator *tg, - uint32_t value); + uint32_t event_triggers, + uint32_t num_frames); void (*set_test_pattern)( struct timing_generator *tg, enum controller_dp_test_pattern test_pattern, @@ -197,7 +414,12 @@ struct timing_generator_funcs { bool (*arm_vert_intr)(struct timing_generator *tg, uint8_t width); - void (*program_global_sync)(struct timing_generator *tg); + void (*program_global_sync)(struct timing_generator *tg, + int vready_offset, + int vstartup_start, + int vupdate_offset, + int vupdate_width, + int pstate_keepout); void (*enable_optc_clock)(struct timing_generator *tg, bool enable); void (*program_stereo)(struct timing_generator *tg, const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags); @@ -210,6 +432,15 @@ struct timing_generator_funcs { bool (*is_optc_underflow_occurred)(struct timing_generator *tg); void (*clear_optc_underflow)(struct timing_generator *tg); + void (*set_dwb_source)(struct timing_generator *optc, + uint32_t dwb_pipe_inst); + + void (*get_optc_source)(struct timing_generator *optc, + uint32_t *num_of_input_segments, + uint32_t *seg0_src_sel, + uint32_t *seg1_src_sel); + bool (*is_two_pixels_per_container)(const struct dc_crtc_timing *timing); + /** * Configure CRCs for the given timing generator. Return false if TG is * not on. @@ -218,12 +449,68 @@ struct timing_generator_funcs { const struct crc_params *params); /** - * Get CRCs for the given timing generator. Return false if CRCs are - * not enabled (via configure_crc). + * @get_crc: Get CRCs for the given timing generator. Return false if + * CRCs are not enabled (via configure_crc). */ - bool (*get_crc)(struct timing_generator *tg, + bool (*get_crc)(struct timing_generator *tg, uint8_t idx, uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb); + void (*program_manual_trigger)(struct timing_generator *optc); + void (*setup_manual_trigger)(struct timing_generator *optc); + bool (*get_hw_timing)(struct timing_generator *optc, + struct dc_crtc_timing *hw_crtc_timing); + + void (*set_vtg_params)(struct timing_generator *optc, + const struct dc_crtc_timing *dc_crtc_timing, bool program_fp2); + + void (*set_dsc_config)(struct timing_generator *optc, + enum optc_dsc_mode dsc_mode, + uint32_t dsc_bytes_per_pixel, + uint32_t dsc_slice_width); + void (*get_dsc_status)(struct timing_generator *optc, + uint32_t *dsc_mode); + void (*set_odm_bypass)(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing); + + /** + * @set_odm_combine: Set up the ODM block to read from the correct + * OPP(s) and turn on/off ODM memory. + */ + void (*set_odm_combine)(struct timing_generator *optc, int *opp_id, int opp_cnt, + int segment_width, int last_segment_width); + void (*get_odm_combine_segments)(struct timing_generator *tg, int *odm_segments); + void (*set_h_timing_div_manual_mode)(struct timing_generator *optc, bool manual_mode); + void (*set_gsl)(struct timing_generator *optc, const struct gsl_params *params); + void (*set_gsl_source_select)(struct timing_generator *optc, + int group_idx, + uint32_t gsl_ready_signal); + void (*set_out_mux)(struct timing_generator *tg, enum otg_out_mux_dest dest); + void (*set_drr_trigger_window)(struct timing_generator *optc, + uint32_t window_start, uint32_t window_end); + void (*set_vtotal_change_limit)(struct timing_generator *optc, + uint32_t limit); + void (*align_vblanks)(struct timing_generator *master_optc, + struct timing_generator *slave_optc, + uint32_t master_pixel_clock_100Hz, + uint32_t slave_pixel_clock_100Hz, + uint8_t master_clock_divider, + uint8_t slave_clock_divider); + bool (*validate_vmin_vmax)(struct timing_generator *optc, + int vmin, int vmax); + bool (*validate_vtotal_change_limit)(struct timing_generator *optc, + uint32_t vtotal_change_limit); + + void (*init_odm)(struct timing_generator *tg); + void (*wait_drr_doublebuffer_pending_clear)(struct timing_generator *tg); + void (*set_long_vtotal)(struct timing_generator *optc, const struct long_vtotal_params *params); + void (*wait_odm_doublebuffer_pending_clear)(struct timing_generator *tg); + void (*wait_otg_disable)(struct timing_generator *optc); + bool (*get_optc_double_buffer_pending)(struct timing_generator *tg); + bool (*get_otg_double_buffer_pending)(struct timing_generator *tg); + bool (*get_pipe_update_pending)(struct timing_generator *tg); + void (*set_vupdate_keepout)(struct timing_generator *tg, bool enable); + bool (*wait_update_lock_status)(struct timing_generator *tg, bool locked); + void (*read_otg_state)(struct timing_generator *tg, struct dcn_otg_state *s); + void (*optc_read_reg_state)(struct timing_generator *tg, struct dcn_optc_reg_state *optc_reg_state); }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h index fecc80c47c26..5a1d9b708a9d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h @@ -29,6 +29,7 @@ #include "hw_shared.h" #include "dc_hw_types.h" #include "fixed31_32.h" +#include "sspl/dc_spl_types.h" #define CSC_TEMPERATURE_MATRIX_SIZE 12 @@ -110,22 +111,6 @@ enum graphics_gamut_adjust_type { GRAPHICS_GAMUT_ADJUST_TYPE_SW /* use adjustments */ }; -enum lb_memory_config { - /* Enable all 3 pieces of memory */ - LB_MEMORY_CONFIG_0 = 0, - - /* Enable only the first piece of memory */ - LB_MEMORY_CONFIG_1 = 1, - - /* Enable only the second piece of memory */ - LB_MEMORY_CONFIG_2 = 2, - - /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the - * last piece of chroma memory used for the luma storage - */ - LB_MEMORY_CONFIG_3 = 3 -}; - struct xfm_grph_csc_adjustment { struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE]; enum graphics_gamut_adjust_type gamut_adjust_type; @@ -162,9 +147,7 @@ struct scl_inits { struct fixed31_32 h; struct fixed31_32 h_c; struct fixed31_32 v; - struct fixed31_32 v_bot; struct fixed31_32 v_c; - struct fixed31_32 v_c_bot; }; struct scaler_data { @@ -179,6 +162,8 @@ struct scaler_data { struct sharpness_adj sharpness; enum pixel_format format; struct line_buffer_params lb_params; + // Below struct holds the scaler values to program hw registers + struct dscl_prog_data dscl_prog_data; }; struct transform_funcs { @@ -260,7 +245,6 @@ struct transform_funcs { void (*set_cursor_attributes)( struct transform *xfm_base, const struct dc_cursor_attributes *attr); - }; const uint16_t *get_filter_2tap_16p(void); @@ -291,6 +275,9 @@ struct dpp_caps { /* DSCL processing pixel data in fixed or float format */ enum dscl_data_processing_format dscl_data_proc_format; + /* max LB partitions */ + unsigned int max_lb_partitions; + /* Calculates the number of partitions in the line buffer. * The implementation of this function is overloaded for * different versions of DSCL LB. diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/vmid.h b/drivers/gpu/drm/amd/display/dc/inc/hw/vmid.h new file mode 100644 index 000000000000..76de0e4284e0 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/vmid.h @@ -0,0 +1,50 @@ +/* + * Copyright 2018 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 DAL_DC_INC_HW_VMID_H_ +#define DAL_DC_INC_HW_VMID_H_ + +#include "core_types.h" +#include "dchubbub.h" + +struct dcn_vmid_registers { + uint32_t CNTL; + uint32_t PAGE_TABLE_BASE_ADDR_HI32; + uint32_t PAGE_TABLE_BASE_ADDR_LO32; + uint32_t PAGE_TABLE_START_ADDR_HI32; + uint32_t PAGE_TABLE_START_ADDR_LO32; + uint32_t PAGE_TABLE_END_ADDR_HI32; + uint32_t PAGE_TABLE_END_ADDR_LO32; +}; + +struct dcn_vmid_page_table_config { + uint64_t page_table_start_addr; + uint64_t page_table_end_addr; + enum dcn_hubbub_page_table_depth depth; + enum dcn_hubbub_page_table_block_size block_size; + uint64_t page_table_base_addr; +}; + +#endif /* DAL_DC_INC_HW_VMID_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/vpg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/vpg.h new file mode 100644 index 000000000000..51da368f5c3e --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/vpg.h @@ -0,0 +1,53 @@ +/* + * Copyright 2024 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_VPG_H__ +#define __DC_VPG_H__ + +struct dc_context; +struct dc_info_packet; + +struct vpg; + +struct vpg_funcs { + void (*update_generic_info_packet)( + struct vpg *vpg, + uint32_t packet_index, + const struct dc_info_packet *info_packet, + bool immediate_update); + + void (*vpg_poweron)( + struct vpg *vpg); + + void (*vpg_powerdown)( + struct vpg *vpg); +}; + +struct vpg { + const struct vpg_funcs *funcs; + struct dc_context *ctx; + int inst; +}; + +#endif /* DC_INC_VPG_H_ */
\ No newline at end of file diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h deleted file mode 100644 index d6a85f48b6d1..000000000000 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#ifndef __DC_HW_SEQUENCER_H__ -#define __DC_HW_SEQUENCER_H__ -#include "dc_types.h" -#include "clock_source.h" -#include "inc/hw/timing_generator.h" -#include "inc/hw/opp.h" -#include "inc/hw/link_encoder.h" -#include "core_status.h" - -enum pipe_gating_control { - PIPE_GATING_CONTROL_DISABLE = 0, - PIPE_GATING_CONTROL_ENABLE, - PIPE_GATING_CONTROL_INIT -}; - -struct dce_hwseq_wa { - bool blnd_crtc_trigger; - bool DEGVIDCN10_253; - bool false_optc_underflow; - bool DEGVIDCN10_254; -}; - -struct hwseq_wa_state { - bool DEGVIDCN10_253_applied; -}; - -struct dce_hwseq { - struct dc_context *ctx; - const struct dce_hwseq_registers *regs; - const struct dce_hwseq_shift *shifts; - const struct dce_hwseq_mask *masks; - struct dce_hwseq_wa wa; - struct hwseq_wa_state wa_state; -}; - -struct pipe_ctx; -struct dc_state; -struct dchub_init_data; -struct dc_static_screen_events; -struct resource_pool; -struct resource_context; -struct stream_resource; - -struct hw_sequencer_funcs { - - void (*init_hw)(struct dc *dc); - - enum dc_status (*apply_ctx_to_hw)( - struct dc *dc, struct dc_state *context); - - void (*reset_hw_ctx_wrap)( - struct dc *dc, struct dc_state *context); - - void (*apply_ctx_for_surface)( - struct dc *dc, - const struct dc_stream_state *stream, - int num_planes, - struct dc_state *context); - - void (*program_gamut_remap)( - struct pipe_ctx *pipe_ctx); - - void (*program_output_csc)(struct dc *dc, - struct pipe_ctx *pipe_ctx, - enum dc_color_space colorspace, - uint16_t *matrix, - int opp_id); - - void (*update_plane_addr)( - const struct dc *dc, - struct pipe_ctx *pipe_ctx); - - void (*plane_atomic_disconnect)( - struct dc *dc, - struct pipe_ctx *pipe_ctx); - - void (*update_dchub)( - struct dce_hwseq *hws, - struct dchub_init_data *dh_data); - - void (*update_mpcc)( - struct dc *dc, - struct pipe_ctx *pipe_ctx); - - void (*update_pending_status)( - struct pipe_ctx *pipe_ctx); - - bool (*set_input_transfer_func)( - struct pipe_ctx *pipe_ctx, - const struct dc_plane_state *plane_state); - - bool (*set_output_transfer_func)( - struct pipe_ctx *pipe_ctx, - const struct dc_stream_state *stream); - - void (*power_down)(struct dc *dc); - - void (*enable_accelerated_mode)(struct dc *dc, struct dc_state *context); - - void (*enable_timing_synchronization)( - struct dc *dc, - int group_index, - int group_size, - struct pipe_ctx *grouped_pipes[]); - - void (*enable_per_frame_crtc_position_reset)( - struct dc *dc, - int group_size, - struct pipe_ctx *grouped_pipes[]); - - void (*enable_display_pipe_clock_gating)( - struct dc_context *ctx, - bool clock_gating); - - bool (*enable_display_power_gating)( - struct dc *dc, - uint8_t controller_id, - struct dc_bios *dcb, - enum pipe_gating_control power_gating); - - void (*disable_plane)(struct dc *dc, struct pipe_ctx *pipe_ctx); - - void (*update_info_frame)(struct pipe_ctx *pipe_ctx); - - void (*enable_stream)(struct pipe_ctx *pipe_ctx); - - void (*disable_stream)(struct pipe_ctx *pipe_ctx, - int option); - - void (*unblank_stream)(struct pipe_ctx *pipe_ctx, - struct dc_link_settings *link_settings); - - void (*blank_stream)(struct pipe_ctx *pipe_ctx); - - void (*enable_audio_stream)(struct pipe_ctx *pipe_ctx); - - void (*disable_audio_stream)(struct pipe_ctx *pipe_ctx, int option); - - void (*pipe_control_lock)( - struct dc *dc, - struct pipe_ctx *pipe, - bool lock); - void (*blank_pixel_data)( - struct dc *dc, - struct pipe_ctx *pipe_ctx, - bool blank); - - void (*prepare_bandwidth)( - struct dc *dc, - struct dc_state *context); - void (*optimize_bandwidth)( - struct dc *dc, - struct dc_state *context); - - void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes, - int vmin, int vmax); - - void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes, - struct crtc_position *position); - - void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx, - int num_pipes, const struct dc_static_screen_events *events); - - enum dc_status (*enable_stream_timing)( - struct pipe_ctx *pipe_ctx, - struct dc_state *context, - struct dc *dc); - - void (*setup_stereo)( - struct pipe_ctx *pipe_ctx, - struct dc *dc); - - void (*set_avmute)(struct pipe_ctx *pipe_ctx, bool enable); - - void (*log_hw_state)(struct dc *dc, - struct dc_log_buffer_ctx *log_ctx); - void (*get_hw_state)(struct dc *dc, char *pBuf, unsigned int bufSize, unsigned int mask); - void (*clear_status_bits)(struct dc *dc, unsigned int mask); - - void (*wait_for_mpcc_disconnect)(struct dc *dc, - struct resource_pool *res_pool, - struct pipe_ctx *pipe_ctx); - - void (*edp_power_control)( - struct dc_link *link, - bool enable); - void (*edp_backlight_control)( - struct dc_link *link, - bool enable); - void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up); - - void (*set_cursor_position)(struct pipe_ctx *pipe); - void (*set_cursor_attribute)(struct pipe_ctx *pipe); - void (*set_cursor_sdr_white_level)(struct pipe_ctx *pipe); - -}; - -void color_space_to_black_color( - const struct dc *dc, - enum dc_color_space colorspace, - struct tg_color *black_color); - -bool hwss_wait_for_blank_complete( - struct timing_generator *tg); - -const uint16_t *find_color_matrix( - enum dc_color_space color_space, - uint32_t *array_size); - -#endif /* __DC_HW_SEQUENCER_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h new file mode 100644 index 000000000000..f1afb31ac70b --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h @@ -0,0 +1,120 @@ +/* + * 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_INC_LINK_ENC_CFG_H_ +#define DC_INC_LINK_ENC_CFG_H_ + +/* This module implements functionality for dynamically assigning DIG link + * encoder resources to display endpoints (links). + */ + +#include "core_types.h" + +/* + * Initialise link encoder resource tracking. + */ +void link_enc_cfg_init( + const struct dc *dc, + struct dc_state *state); + +/* + * Copies a link encoder assignment from another state. + */ +void link_enc_cfg_copy(const struct dc_state *src_ctx, struct dc_state *dst_ctx); + +/* + * Algorithm for assigning available DIG link encoders to streams. + * + * Update link_enc_assignments table and link_enc_avail list accordingly in + * struct resource_context. + * + * Loop over all streams twice: + * a) First assign encoders to unmappable endpoints. + * b) Then assign encoders to mappable endpoints. + */ +void link_enc_cfg_link_encs_assign( + struct dc *dc, + struct dc_state *state, + struct dc_stream_state *streams[], + uint8_t stream_count); + +/* + * Unassign a link encoder from a stream. + * + * Update link_enc_assignments table and link_enc_avail list accordingly in + * struct resource_context. + */ +void link_enc_cfg_link_enc_unassign( + struct dc_state *state, + struct dc_stream_state *stream); + +/* + * Check whether the transmitter driven by a link encoder is a mappable + * endpoint. + */ +bool link_enc_cfg_is_transmitter_mappable( + struct dc *dc, + struct link_encoder *link_enc); + +/* Return stream using DIG link encoder resource. NULL if unused. */ +struct dc_stream_state *link_enc_cfg_get_stream_using_link_enc( + struct dc *dc, + enum engine_id eng_id); + +/* Return link using DIG link encoder resource. NULL if unused. */ +struct dc_link *link_enc_cfg_get_link_using_link_enc( + struct dc *dc, + enum engine_id eng_id); + +/* Return DIG link encoder used by link. NULL if unused. */ +struct link_encoder *link_enc_cfg_get_link_enc_used_by_link( + struct dc *dc, + const struct dc_link *link); + +/* Return next available DIG link encoder. NULL if none available. */ +struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc); + +/* Return DIG link encoder. NULL if unused. */ +struct link_encoder *link_enc_cfg_get_link_enc(const struct dc_link *link); + +/* Return DIG link encoder used by stream in current/previous state. NULL if unused. */ +struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream_current( + struct dc *dc, + const struct dc_stream_state *stream); + +/* Return true if encoder available to use. */ +bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link); + +/* Returns true if encoder assignments in supplied state pass validity checks. */ +bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state); + +/* Set the link encoder assignment mode for the current_state to LINK_ENC_CFG_TRANSIENT mode. + * This indicates that a new_state is in the process of being applied to hardware. + * During this transition, old and new encoder assignments should be accessible from the old_state. + * Only allow transition into transient mode if new encoder assignments are valid. + */ +void link_enc_cfg_set_transient_mode(struct dc *dc, struct dc_state *current_state, struct dc_state *new_state); + +#endif /* DC_INC_LINK_ENC_CFG_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h index 30be7bb4a01a..0f69946cce9f 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h @@ -26,56 +26,64 @@ #ifndef __DC_LINK_HWSS_H__ #define __DC_LINK_HWSS_H__ -#include "inc/core_status.h" +/* include basic type headers only */ +#include "dc_dp_types.h" +#include "signal_types.h" +#include "grph_object_id.h" +#include "fixed31_32.h" -enum dc_status core_link_read_dpcd( - struct dc_link *link, - uint32_t address, - uint8_t *data, - uint32_t size); +/* forward declare dc core types */ +struct dc_link; +struct link_resource; +struct pipe_ctx; +struct encoder_set_dp_phy_pattern_param; +struct link_mst_stream_allocation_table; +struct audio_output; -enum dc_status core_link_write_dpcd( - struct dc_link *link, - uint32_t address, - const uint8_t *data, - uint32_t size); +struct link_hwss_ext { + /* function pointers below may require to check for NULL if caller + * considers missing implementation as expected in some cases or none + * critical to be investigated immediately + * ********************************************************************* + */ + void (*set_hblank_min_symbol_width)(struct pipe_ctx *pipe_ctx, + const struct dc_link_settings *link_settings, + struct fixed31_32 throttled_vcp_size); + void (*set_throttled_vcp_size)(struct pipe_ctx *pipe_ctx, + struct fixed31_32 throttled_vcp_size); + void (*enable_dp_link_output)(struct dc_link *link, + const struct link_resource *link_res, + enum signal_type signal, + enum clock_source_id clock_source, + const struct dc_link_settings *link_settings); + void (*set_dp_link_test_pattern)(struct dc_link *link, + const struct link_resource *link_res, + struct encoder_set_dp_phy_pattern_param *tp_params); + void (*set_dp_lane_settings)(struct dc_link *link, + const struct link_resource *link_res, + const struct dc_link_settings *link_settings, + const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]); + void (*update_stream_allocation_table)(struct dc_link *link, + const struct link_resource *link_res, + const struct link_mst_stream_allocation_table *table); +}; -struct gpio *get_hpd_gpio(struct dc_bios *dcb, - struct graphics_object_id link_id, - struct gpio_service *gpio_service); - -void dp_enable_link_phy( - struct dc_link *link, - enum signal_type signal, - enum clock_source_id clock_source, - const struct dc_link_settings *link_settings); - -void dp_receiver_power_ctrl(struct dc_link *link, bool on); -bool edp_receiver_ready_T9(struct dc_link *link); -bool edp_receiver_ready_T7(struct dc_link *link); - -void dp_disable_link_phy(struct dc_link *link, enum signal_type signal); - -void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal); - -bool dp_set_hw_training_pattern( - struct dc_link *link, - enum hw_dp_training_pattern pattern); - -void dp_set_hw_lane_settings( - struct dc_link *link, - const struct link_training_settings *link_settings); - -void dp_set_hw_test_pattern( - struct dc_link *link, - enum dp_test_pattern test_pattern, - uint8_t *custom_pattern, - uint32_t custom_pattern_size); - -enum dp_panel_mode dp_get_panel_mode(struct dc_link *link); - -void dp_retrain_link_dp_test(struct dc_link *link, - struct dc_link_settings *link_setting, - bool skip_video_pattern); +struct link_hwss { + struct link_hwss_ext ext; + /* function pointers below MUST be assigned to all types of link_hwss + * ********************************************************************* + */ + void (*setup_stream_encoder)(struct pipe_ctx *pipe_ctx); + void (*reset_stream_encoder)(struct pipe_ctx *pipe_ctx); + void (*setup_stream_attribute)(struct pipe_ctx *pipe_ctx); + void (*disable_link_output)(struct dc_link *link, + const struct link_resource *link_res, + enum signal_type signal); + void (*setup_audio_output)(struct pipe_ctx *pipe_ctx, + struct audio_output *audio_output, uint32_t audio_inst); + void (*enable_audio_packet)(struct pipe_ctx *pipe_ctx); + void (*disable_audio_packet)(struct pipe_ctx *pipe_ctx); +}; #endif /* __DC_LINK_HWSS_H__ */ + diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_service.h b/drivers/gpu/drm/amd/display/dc/inc/link_service.h new file mode 100644 index 000000000000..6f94e48a24d1 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/link_service.h @@ -0,0 +1,350 @@ +/* + * Copyright 2022 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_LINK_H__ +#define __DC_LINK_H__ + +/* FILE POLICY AND INTENDED USAGE: + * + * This header defines link component function interfaces aka link_service. + * link_service provides the only entry point to link functions with function + * pointer style. This header is strictly private in dc and should never be + * included by DM because it exposes too much dc detail including all dc + * private types defined in core_types.h. Otherwise it will break DM - DC + * encapsulation and turn DM into a maintenance nightmare. + * + * The following shows a link component relation map. + * + * DM to DC: + * DM includes dc.h + * dc_link_exports.c or other dc files implement dc.h + * + * DC to Link: + * dc_link_exports.c or other dc files include link_service.h + * link_factory.c implements link_service.h + * + * Link sub-component to Link sub-component: + * link_factory.c includes --> link_xxx.h + * link_xxx.c implements link_xxx.h + + * As you can see if you ever need to add a new dc link function and call it on + * DM/dc side, it is very difficult because you will need layers of translation. + * The most appropriate approach to implement new requirements on DM/dc side is + * to extend or generalize the functionality of existing link function + * interfaces so minimal modification is needed outside link component to + * achieve your new requirements. This approach reduces or even eliminates the + * effort needed outside link component to support a new link feature. This also + * reduces code discrepancy among DMs to support the same link feature. If we + * test full code path on one version of DM, and there is no feature specific + * modification required on other DMs, then we can have higher confidence that + * the feature will run on other DMs and produce the same result. The following + * are some good examples to start with: + * + * - detect_link --> to add new link detection or capability retrieval routines + * + * - validate_mode_timing --> to add new timing validation conditions + * + * - set_dpms_on/set_dpms_off --> to include new link enablement sequences + * + * If you must add new link functions, you will need to: + * 1. declare the function pointer here under the suitable commented category. + * 2. Implement your function in the suitable link_xxx.c file. + * 3. Assign the function to link_service in link_factory.c + * 4. NEVER include link_xxx.h headers outside link component. + * 5. NEVER include link_service.h on DM side. + */ +#include "core_types.h" + +struct link_service *link_create_link_service(void); +void link_destroy_link_service(struct link_service **link_srv); + +struct link_init_data { + const struct dc *dc; + struct dc_context *ctx; /* TODO: remove 'dal' when DC is complete. */ + uint32_t connector_index; /* this will be mapped to the HPD pins */ + uint32_t link_index; /* this is mapped to DAL display_index + TODO: remove it when DC is complete. */ + bool is_dpia_link; +}; + +struct ddc_service_init_data { + struct graphics_object_id id; + struct dc_context *ctx; + struct dc_link *link; + bool is_dpia_link; +}; + +struct link_service { + /************************** Factory ***********************************/ + struct dc_link *(*create_link)( + const struct link_init_data *init_params); + void (*destroy_link)(struct dc_link **link); + + + /************************** Detection *********************************/ + bool (*detect_link)(struct dc_link *link, enum dc_detect_reason reason); + bool (*detect_connection_type)(struct dc_link *link, + enum dc_connection_type *type); + struct dc_sink *(*add_remote_sink)( + struct dc_link *link, + const uint8_t *edid, + int len, + struct dc_sink_init_data *init_data); + void (*remove_remote_sink)(struct dc_link *link, struct dc_sink *sink); + bool (*get_hpd_state)(struct dc_link *link); + struct gpio *(*get_hpd_gpio)(struct dc_bios *dcb, + struct graphics_object_id link_id, + struct gpio_service *gpio_service); + void (*enable_hpd)(const struct dc_link *link); + void (*disable_hpd)(const struct dc_link *link); + void (*enable_hpd_filter)(struct dc_link *link, bool enable); + bool (*reset_cur_dp_mst_topology)(struct dc_link *link); + const struct dc_link_status *(*get_status)(const struct dc_link *link); + bool (*is_hdcp1x_supported)(struct dc_link *link, + enum signal_type signal); + bool (*is_hdcp2x_supported)(struct dc_link *link, + enum signal_type signal); + void (*clear_dprx_states)(struct dc_link *link); + + + /*************************** Resource *********************************/ + void (*get_cur_res_map)(const struct dc *dc, uint32_t *map); + void (*restore_res_map)(const struct dc *dc, uint32_t *map); + void (*get_cur_link_res)(const struct dc_link *link, + struct link_resource *link_res); + + + /*************************** Validation *******************************/ + enum dc_status (*validate_mode_timing)( + const struct dc_stream_state *stream, + struct dc_link *link, + const struct dc_crtc_timing *timing); + uint32_t (*dp_link_bandwidth_kbps)( + const struct dc_link *link, + const struct dc_link_settings *link_settings); + enum dc_status (*validate_dp_tunnel_bandwidth)( + const struct dc *dc, + const struct dc_state *new_ctx); + + uint32_t (*dp_required_hblank_size_bytes)( + const struct dc_link *link, + struct dp_audio_bandwidth_params *audio_params); + + + /*************************** DPMS *************************************/ + void (*set_dpms_on)(struct dc_state *state, struct pipe_ctx *pipe_ctx); + void (*set_dpms_off)(struct pipe_ctx *pipe_ctx); + void (*resume)(struct dc_link *link); + void (*blank_all_dp_displays)(struct dc *dc); + void (*blank_all_edp_displays)(struct dc *dc); + void (*blank_dp_stream)(struct dc_link *link, bool hw_init); + enum dc_status (*increase_mst_payload)( + struct pipe_ctx *pipe_ctx, uint32_t req_pbn); + enum dc_status (*reduce_mst_payload)( + struct pipe_ctx *pipe_ctx, uint32_t req_pbn); + void (*set_dsc_on_stream)(struct pipe_ctx *pipe_ctx, bool enable); + bool (*set_dsc_enable)(struct pipe_ctx *pipe_ctx, bool enable); + bool (*update_dsc_config)(struct pipe_ctx *pipe_ctx); + + + /*************************** DDC **************************************/ + struct ddc_service *(*create_ddc_service)( + struct ddc_service_init_data *ddc_init_data); + void (*destroy_ddc_service)(struct ddc_service **ddc); + bool (*query_ddc_data)( + struct ddc_service *ddc, + uint32_t address, + uint8_t *write_buf, + uint32_t write_size, + uint8_t *read_buf, + uint32_t read_size); + 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); + uint32_t (*get_aux_defer_delay)(struct ddc_service *ddc); + + + /*************************** DP Capability ****************************/ + bool (*dp_is_sink_present)(struct dc_link *link); + bool (*dp_is_fec_supported)(const struct dc_link *link); + bool (*dp_is_128b_132b_signal)(struct pipe_ctx *pipe_ctx); + bool (*dp_get_max_link_enc_cap)(const struct dc_link *link, + struct dc_link_settings *max_link_enc_cap); + const struct dc_link_settings *(*dp_get_verified_link_cap)( + const struct dc_link *link); + enum dp_link_encoding (*dp_get_encoding_format)( + const struct dc_link_settings *link_settings); + bool (*dp_should_enable_fec)(const struct dc_link *link); + bool (*dp_decide_link_settings)( + struct dc_stream_state *stream, + struct dc_link_settings *link_setting); + void (*dp_decide_tunnel_settings)( + struct dc_stream_state *stream, + struct dc_tunnel_settings *dp_tunnel_setting); + enum dp_link_encoding (*mst_decide_link_encoding_format)( + const struct dc_link *link); + bool (*edp_decide_link_settings)(struct dc_link *link, + struct dc_link_settings *link_setting, uint32_t req_bw); + uint32_t (*bw_kbps_from_raw_frl_link_rate_data)(uint8_t bw); + bool (*dp_overwrite_extended_receiver_cap)(struct dc_link *link); + enum lttpr_mode (*dp_decide_lttpr_mode)(struct dc_link *link, + struct dc_link_settings *link_setting); + uint8_t (*dp_get_lttpr_count)(struct dc_link *link); + void (*edp_get_alpm_support)(struct dc_link *link, + bool *auxless_support, + bool *auxwake_support); + + /*************************** DP DPIA/PHY ******************************/ + void (*dpia_handle_usb4_bandwidth_allocation_for_link)( + struct dc_link *link, int peak_bw); + void (*dp_set_drive_settings)( + struct dc_link *link, + const struct link_resource *link_res, + struct link_training_settings *lt_settings); + void (*dpcd_write_rx_power_ctrl)(struct dc_link *link, bool on); + + + /*************************** DP IRQ Handler ***************************/ + bool (*dp_parse_link_loss_status)( + struct dc_link *link, + union hpd_irq_data *hpd_irq_dpcd_data); + bool (*dp_should_allow_hpd_rx_irq)(const struct dc_link *link); + void (*dp_handle_link_loss)(struct dc_link *link); + enum dc_status (*dp_read_hpd_rx_irq_data)( + struct dc_link *link, + union hpd_irq_data *irq_data); + bool (*dp_handle_hpd_rx_irq)(struct dc_link *link, + union hpd_irq_data *out_hpd_irq_dpcd_data, + bool *out_link_loss, + bool defer_handling, bool *has_left_work); + + + /*************************** eDP Panel Control ************************/ + void (*edp_panel_backlight_power_on)( + struct dc_link *link, bool wait_for_hpd); + int (*edp_get_backlight_level)(const struct dc_link *link); + bool (*edp_get_backlight_level_nits)(struct dc_link *link, + uint32_t *backlight_millinits_avg, + uint32_t *backlight_millinits_peak); + bool (*edp_set_backlight_level)(const struct dc_link *link, + struct set_backlight_level_params *backlight_level_params); + bool (*edp_set_backlight_level_nits)(struct dc_link *link, + bool isHDR, + uint32_t backlight_millinits, + uint32_t transition_time_in_ms); + int (*edp_get_target_backlight_pwm)(const struct dc_link *link); + bool (*edp_get_psr_state)( + const struct dc_link *link, enum dc_psr_state *state); + bool (*edp_set_psr_allow_active)( + struct dc_link *link, + const bool *allow_active, + bool wait, + bool force_static, + const unsigned int *power_opts); + bool (*edp_setup_psr)(struct dc_link *link, + const struct dc_stream_state *stream, + struct psr_config *psr_config, + struct psr_context *psr_context); + bool (*edp_set_sink_vtotal_in_psr_active)( + const struct dc_link *link, + uint16_t psr_vtotal_idle, + uint16_t psr_vtotal_su); + void (*edp_get_psr_residency)( + const struct dc_link *link, uint32_t *residency, enum psr_residency_mode mode); + + 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_send_replay_cmd)(struct dc_link *link, + enum replay_FW_Message_type msg, + union dmub_replay_cmd_set *cmd_data); + bool (*edp_set_coasting_vtotal)( + struct dc_link *link, uint32_t coasting_vtotal, uint16_t frame_skip_number); + bool (*edp_replay_residency)(const struct dc_link *link, + unsigned int *residency, const bool is_start, + const enum pr_residency_mode mode); + bool (*edp_set_replay_power_opt_and_coasting_vtotal)(struct dc_link *link, + const unsigned int *power_opts, uint32_t coasting_vtotal, uint16_t frame_skip_number); + + 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); + bool (*edp_backlight_enable_aux)(struct dc_link *link, bool enable); + void (*edp_add_delay_for_T9)(struct dc_link *link); + bool (*edp_receiver_ready_T9)(struct dc_link *link); + bool (*edp_receiver_ready_T7)(struct dc_link *link); + bool (*edp_power_alpm_dpcd_enable)(struct dc_link *link, bool enable); + void (*edp_set_panel_power)(struct dc_link *link, bool powerOn); + + + /*************************** DP CTS ************************************/ + void (*dp_handle_automated_test)(struct dc_link *link); + bool (*dp_set_test_pattern)( + struct dc_link *link, + enum dp_test_pattern test_pattern, + enum dp_test_pattern_color_space test_pattern_color_space, + const struct link_training_settings *p_link_settings, + const unsigned char *p_custom_pattern, + unsigned int cust_pattern_size); + void (*dp_set_preferred_link_settings)(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link *link); + void (*dp_set_preferred_training_settings)(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link_training_overrides *lt_overrides, + struct dc_link *link, + bool skip_immediate_retrain); + + + /*************************** DP Trace *********************************/ + bool (*dp_trace_is_initialized)(struct dc_link *link); + void (*dp_trace_set_is_logged_flag)(struct dc_link *link, + bool in_detection, + bool is_logged); + bool (*dp_trace_is_logged)(struct dc_link *link, bool in_detection); + unsigned long long (*dp_trace_get_lt_end_timestamp)( + struct dc_link *link, bool in_detection); + const struct dp_trace_lt_counts *(*dp_trace_get_lt_counts)( + struct dc_link *link, bool in_detection); + unsigned int (*dp_trace_get_link_loss_count)(struct dc_link *link); + void (*dp_trace_set_edp_power_timestamp)(struct dc_link *link, + bool power_up); + uint64_t (*dp_trace_get_edp_poweron_timestamp)(struct dc_link *link); + uint64_t (*dp_trace_get_edp_poweroff_timestamp)(struct dc_link *link); + void (*dp_trace_source_sequence)( + struct dc_link *link, uint8_t dp_test_mode); +}; +#endif /* __DC_LINK_HPD_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h b/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h index cf5a84b9e27c..26cb1459b743 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h +++ b/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h @@ -52,7 +52,7 @@ /* macro to set register fields. */ #define REG_SET_N(reg_name, n, initial_val, ...) \ - generic_reg_update_ex(CTX, \ + generic_reg_set_ex(CTX, \ REG(reg_name), \ initial_val, \ n, __VA_ARGS__) @@ -225,7 +225,6 @@ #define REG_UPDATE_N(reg_name, n, ...) \ generic_reg_update_ex(CTX, \ REG(reg_name), \ - REG_READ(reg_name), \ n, __VA_ARGS__) #define REG_UPDATE(reg_name, field, val) \ @@ -380,16 +379,11 @@ /* macro to update a register field to specified values in given sequences. * useful when toggling bits */ -#define REG_UPDATE_SEQ(reg, field, value1, value2) \ -{ uint32_t val = REG_UPDATE(reg, field, value1); \ - REG_SET(reg, val, field, value2); } - -/* macro to update fields in register 1 field at a time in given order */ -#define REG_UPDATE_1BY1_2(reg, f1, v1, f2, v2) \ +#define REG_UPDATE_SEQ_2(reg, f1, v1, f2, v2) \ { uint32_t val = REG_UPDATE(reg, f1, v1); \ REG_SET(reg, val, f2, v2); } -#define REG_UPDATE_1BY1_3(reg, f1, v1, f2, v2, f3, v3) \ +#define REG_UPDATE_SEQ_3(reg, f1, v1, f2, v2, f3, v3) \ { uint32_t val = REG_UPDATE(reg, f1, v1); \ val = REG_SET(reg, val, f2, v2); \ REG_SET(reg, val, f3, v3); } @@ -464,7 +458,14 @@ uint32_t generic_reg_get8(const struct dc_context *ctx, uint32_t addr, #define IX_REG_READ(index_reg_name, data_reg_name, index) \ generic_read_indirect_reg(CTX, REG(index_reg_name), REG(data_reg_name), IND_REG(index)) +#define IX_REG_GET_N(index_reg_name, data_reg_name, index, n, ...) \ + generic_indirect_reg_get(CTX, REG(index_reg_name), REG(data_reg_name), \ + IND_REG(index), \ + n, __VA_ARGS__) +#define IX_REG_GET(index_reg_name, data_reg_name, index, field, val) \ + IX_REG_GET_N(index_reg_name, data_reg_name, index, 1, \ + FN(data_reg_name, field), val) #define IX_REG_UPDATE_N(index_reg_name, data_reg_name, index, n, ...) \ generic_indirect_reg_update_ex(CTX, \ @@ -485,10 +486,73 @@ uint32_t generic_read_indirect_reg(const struct dc_context *ctx, uint32_t addr_index, uint32_t addr_data, uint32_t index); +uint32_t generic_indirect_reg_get(const struct dc_context *ctx, + uint32_t addr_index, uint32_t addr_data, + uint32_t index, int n, + uint8_t shift1, uint32_t mask1, uint32_t *field_value1, + ...); + uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx, uint32_t addr_index, uint32_t addr_data, uint32_t index, uint32_t reg_val, int n, uint8_t shift1, uint32_t mask1, uint32_t field_value1, ...); +/* indirect register access + * underlying implementation determines which index/data pair to be used + * in a synchronous way + */ +#define IX_REG_SET_N_SYNC(index, n, initial_val, ...) \ + generic_indirect_reg_update_ex_sync(CTX, \ + IND_REG(index), \ + initial_val, \ + n, __VA_ARGS__) + +#define IX_REG_SET_SYNC(index, init_value, f1, v1) \ + IX_REG_SET_N_SYNC(index, 1, init_value, \ + FN(reg, f1), v1) + +#define IX_REG_SET_2_SYNC(index, init_value, f1, v1, f2, v2) \ + IX_REG_SET_N_SYNC(index, 2, init_value, \ + FN(reg, f1), v1,\ + FN(reg, f2), v2) + +#define IX_REG_GET_N_SYNC(index, n, ...) \ + generic_indirect_reg_get_sync(CTX, \ + IND_REG(index), \ + n, __VA_ARGS__) + +#define IX_REG_GET_SYNC(index, field, val) \ + IX_REG_GET_N_SYNC(index, 1, \ + FN(data_reg_name, field), val) + +uint32_t generic_indirect_reg_get_sync(const struct dc_context *ctx, + uint32_t index, int n, + uint8_t shift1, uint32_t mask1, uint32_t *field_value1, + ...); + +uint32_t generic_indirect_reg_update_ex_sync(const struct dc_context *ctx, + uint32_t index, uint32_t reg_val, int n, + uint8_t shift1, uint32_t mask1, uint32_t field_value1, + ...); + +/* register offload macros + * + * instead of MMIO to register directly, in some cases we want + * to gather register sequence and execute the register sequence + * from another thread so we optimize time required for lengthy ops + */ + +/* start gathering register sequence */ +#define REG_SEQ_START() \ + reg_sequence_start_gather(CTX) + +/* start execution of register sequence gathered since REG_SEQ_START */ +#define REG_SEQ_SUBMIT() \ + reg_sequence_start_execute(CTX) + +/* wait for the last REG_SEQ_SUBMIT to finish */ +#define REG_SEQ_WAIT_DONE() \ + reg_sequence_wait_done(CTX) + #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index 0086a2f1d21a..79746d931471 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -30,18 +30,36 @@ #include "dal_asic_id.h" #include "dm_pp_smu.h" +#define MEMORY_TYPE_MULTIPLIER_CZ 4 +#define MEMORY_TYPE_HBM 2 +#define MAX_MCACHES 8 + + +#define IS_PIPE_SYNCD_VALID(pipe) ((((pipe)->pipe_idx_syncd) & 0x80)?1:0) +#define GET_PIPE_SYNCD_FROM_PIPE(pipe) ((pipe)->pipe_idx_syncd & 0x7F) +#define SET_PIPE_SYNCD_TO_PIPE(pipe, pipe_syncd) ((pipe)->pipe_idx_syncd = (0x80 | pipe_syncd)) + enum dce_version resource_parse_asic_id( struct hw_asic_id asic_id); struct resource_caps { int num_timing_generator; int num_opp; + int num_dpp; int num_video_plane; int num_audio; int num_stream_encoder; + int num_analog_stream_encoder; int num_pll; int num_dwb; int num_ddc; + int num_vmid; + int num_dsc; + unsigned int num_dig_link_enc; // Total number of DIGs (digital encoders) in DIO (Display Input/Output). + unsigned int num_usb4_dpia; // Total number of USB4 DPIA (DisplayPort Input Adapters). + int num_hpo_dp_stream_encoder; + int num_hpo_dp_link_encoder; + int num_mpc_3dlut; }; struct resource_straps { @@ -50,6 +68,13 @@ struct resource_straps { uint32_t audio_stream_number; }; +struct dc_mcache_allocations { + int global_mcache_ids_plane0[MAX_MCACHES + 1]; + int global_mcache_ids_plane1[MAX_MCACHES + 1]; + int global_mcache_ids_mall_plane0[MAX_MCACHES + 1]; + int global_mcache_ids_mall_plane1[MAX_MCACHES + 1]; +}; + struct resource_create_funcs { void (*read_dce_straps)( struct dc_context *ctx, struct resource_straps *straps); @@ -60,6 +85,11 @@ struct resource_create_funcs { struct stream_encoder *(*create_stream_encoder)( enum engine_id eng_id, struct dc_context *ctx); + struct hpo_dp_stream_encoder *(*create_hpo_dp_stream_encoder)( + enum engine_id eng_id, struct dc_context *ctx); + struct hpo_dp_link_encoder *(*create_hpo_dp_link_encoder)( + uint8_t inst, + struct dc_context *ctx); struct dce_hwseq *(*create_hwseq)( struct dc_context *ctx); }; @@ -70,11 +100,9 @@ bool resource_construct( struct resource_pool *pool, const struct resource_create_funcs *create_funcs); -struct resource_pool *dc_create_resource_pool( - struct dc *dc, - int num_virtual_links, - enum dce_version dc_version, - struct hw_asic_id asic_id); +struct resource_pool *dc_create_resource_pool(struct dc *dc, + const struct dc_init_data *init_data, + enum dce_version dc_version); void dc_destroy_resource_pool(struct dc *dc); @@ -83,6 +111,10 @@ enum dc_status resource_map_pool_resources( struct dc_state *context, struct dc_stream_state *stream); +void resource_build_test_pattern_params( + struct resource_context *res_ctx, + struct pipe_ctx *pipe_ctx); + bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx); enum dc_status resource_build_scaling_params_for_context( @@ -110,6 +142,10 @@ bool resource_are_streams_timing_synchronizable( struct dc_stream_state *stream1, struct dc_stream_state *stream2); +bool resource_are_vblanks_synchronizable( + struct dc_stream_state *stream1, + struct dc_stream_state *stream2); + struct clock_source *resource_find_used_clk_src_for_sharing( struct resource_context *res_ctx, struct pipe_ctx *pipe_ctx); @@ -118,10 +154,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, @@ -129,12 +161,412 @@ bool resource_attach_surfaces_to_context( struct dc_state *context, const struct resource_pool *pool); -struct pipe_ctx *find_idle_secondary_pipe( +bool resource_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx); + +#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) | | | + * |________|_______________|___________|_____________| + * + * The following is a quick reference of the class relation: + * + * DC state ---1--------0..N--- streams + * + * stream ---1-----------1--- OTG Master pipe + * + * OTG Master pipe ---1--------1..N--- OPP Head pipes + * + * OPP Head pipe ---1--------0..N--- DPP pipes + * + * stream ---1--------0..N--- Planes + * + * Plane ---1--------1..N--- DPP pipes + * + */ +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 back end DIG. OTG master pipe is responsible for + * generating entire CRTC timing to back end 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); + +/* + * Acquire a pipe as OTG master pipe and allocate pipe resources required to + * enable stream output. + */ +enum dc_status resource_add_otg_master_for_stream_output(struct dc_state *new_ctx, + const struct resource_pool *pool, + struct dc_stream_state *stream); + +/* + * Release pipe resources and the OTG master pipe associated with the stream + * The stream must have all planes removed and ODM/MPC slice counts are reset + * to 1 before invoking this interface. + */ +void resource_remove_otg_master_for_stream_output(struct dc_state *new_ctx, + const struct resource_pool *pool, + struct dc_stream_state *stream); + +/* + * Add plane to the bottom most layer in plane composition and allocate DPP pipe + * resources as needed. + * return - true if plane is added in plane composition, false otherwise. + */ +bool resource_append_dpp_pipes_for_plane_composition( + struct dc_state *new_ctx, + struct dc_state *cur_ctx, + struct resource_pool *pool, + struct pipe_ctx *otg_master_pipe, + struct dc_plane_state *plane_state); + +/* + * Add plane to the bottom most layer in plane composition and allocate DPP pipe + * resources as needed. + * return - true if plane is added in plane composition, false otherwise. + */ +void resource_remove_dpp_pipes_for_plane_composition( + struct dc_state *context, + const struct resource_pool *pool, + const struct dc_plane_state *plane_state); + +/* + * Update ODM slice count by acquiring or releasing pipes. If new slices need + * to be added, it is going to add them to the last ODM index. If existing + * slices need to be removed, it is going to remove them from the last ODM + * index. + * + * return - true if ODM slices are updated and required pipes are acquired. All + * affected pipe parameters are updated. + * + * false if resource fails to complete this update. The function is not designed + * to recover the creation of invalid topologies. Returning false is typically + * an indication of insufficient validation in caller's stack. new_ctx will be + * invalid. Caller may attempt to restore new_ctx by calling this function + * again with original slice count. + */ +bool resource_update_pipes_for_stream_with_slice_count( + struct dc_state *new_ctx, + const struct dc_state *cur_ctx, + const struct resource_pool *pool, + const struct dc_stream_state *stream, + int new_slice_count); + +/* + * Update MPC slice count by acquiring or releasing DPP pipes. If new slices + * need to be added it is going to add to the last MPC index. If existing + * slices need to be removed, it is going to remove them from the last MPC + * index. + * + * @dpp_pipe - top most dpp pipe for MPCC combine. + * + * return - true if MPC slices are updated and required pipes are acquired. All + * affected pipe parameters are updated. + * + * false if resource fails to complete this update. The function is not designed + * to recover the creation of invalid topologies. Returning false is typically + * an indication of insufficient validation in caller's stack. new_ctx will be + * invalid. Caller may attempt to restore new_ctx by calling this function + * again with original slice count. + */ +bool resource_update_pipes_for_plane_with_slice_count( + struct dc_state *new_ctx, + const struct dc_state *cur_ctx, + const struct resource_pool *pool, + const struct dc_plane_state *plane, + int slice_count); + +/* + * 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, + const struct dc_stream_state *stream); + +/* + * Get an array of OPP heads in opp_heads ordered with index low to high for OTG + * master pipe in res_ctx. + * return - number of OPP heads in the array. If otg_master passed in is not + * an OTG master, the function returns 0. + */ +int resource_get_opp_heads_for_otg_master(const struct pipe_ctx *otg_master, + struct resource_context *res_ctx, + struct pipe_ctx *opp_heads[MAX_PIPES]); + +/* + * Get an array of DPP pipes in dpp_pipes ordered with index low to high for OPP + * head pipe in res_ctx. + * return - number of DPP pipes in the array. If opp_head passed in is not + * an OPP pipe, the function returns 0. + */ +int resource_get_dpp_pipes_for_opp_head(const struct pipe_ctx *opp_head, struct resource_context *res_ctx, + struct pipe_ctx *dpp_pipes[MAX_PIPES]); + +/* + * Get an array of DPP pipes in dpp_pipes ordered with index low to high for + * plane in res_ctx. + * return - number of DPP pipes in the array. + */ +int resource_get_dpp_pipes_for_plane(const struct dc_plane_state *plane, + struct resource_context *res_ctx, + struct pipe_ctx *dpp_pipes[MAX_PIPES]); + +/* + * 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); + +/* + * Get the DPP pipe allocated for MPC slice 0 and ODM slice 0 of the plane + * associated with dpp_pipe. + */ +struct pipe_ctx *resource_get_primary_dpp_pipe(const struct pipe_ctx *dpp_pipe); + +/* + * Get the MPC slice index counting from 0 from left most slice + * For example, if a DPP pipe is used as a secondary pipe in MPCC combine, MPC + * split index is greater than 0. + */ +int resource_get_mpc_slice_index(const struct pipe_ctx *dpp_pipe); + +/* + * Get the number of MPC slices associated with the pipe. + * The function returns 0 if the pipe is not associated with an MPC combine + * pipe topology. + */ +int resource_get_mpc_slice_count(const struct pipe_ctx *pipe); + +/* + * Get the number of ODM slices associated with the pipe. + * The function returns 0 if the pipe is not associated with an ODM combine + * pipe topology. + */ +int resource_get_odm_slice_count(const struct pipe_ctx *pipe); + +/* Get the ODM slice index counting from 0 from left most slice */ +int resource_get_odm_slice_index(const struct pipe_ctx *opp_head); + +/* Get ODM slice source rect in timing active as input to OPP block */ +struct rect resource_get_odm_slice_src_rect(struct pipe_ctx *pipe_ctx); + +/* Get ODM slice destination rect in timing active as output from OPP block */ +struct rect resource_get_odm_slice_dst_rect(struct pipe_ctx *pipe_ctx); + +/* Get ODM slice destination width in timing active as output from OPP block */ +int resource_get_odm_slice_dst_width(struct pipe_ctx *otg_master, + bool is_last_segment); + +/* determine if pipe topology is changed between state a and state b */ +bool resource_is_pipe_topology_changed(const struct dc_state *state_a, + const struct dc_state *state_b); + +/* + * determine if the two OTG master pipes have the same ODM topology + * return + * false - if pipes passed in are not OTG masters or ODM topology is + * changed. + * true - otherwise + */ +bool resource_is_odm_topology_changed(const struct pipe_ctx *otg_master_a, + const struct pipe_ctx *otg_master_b); + +/* log the pipe topology update in state */ +void resource_log_pipe_topology_update(struct dc *dc, struct dc_state *state); + +/* + * Look for a free pipe in new resource context that is used as a secondary OPP + * head by cur_otg_master. + * + * 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_sec_opp_head_by_cur_otg_master( + const struct resource_context *cur_res_ctx, + struct resource_context *new_res_ctx, + const struct pipe_ctx *cur_otg_master); + +/* + * 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); -bool resource_is_stream_unchanged( - struct dc_state *old_context, struct dc_stream_state *stream); +/* + * Look for a free pipe in new resource context that is used in current resource + * context as an OTG master pipe. + * + * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise + * pipe idx of the free pipe + */ +int recource_find_free_pipe_used_as_otg_master_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 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( + 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); bool resource_validate_attach_surfaces( const struct dc_validation_set set[], @@ -143,10 +575,6 @@ bool resource_validate_attach_surfaces( struct dc_state *context, const struct resource_pool *pool); -void resource_validate_ctx_update_pointer_after_copy( - const struct dc_state *src_ctx, - struct dc_state *dst_ctx); - enum dc_status resource_map_clock_resources( const struct dc *dc, struct dc_state *context, @@ -172,4 +600,64 @@ void update_audio_usage( unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format); +bool get_temp_dp_link_res(struct dc_link *link, + struct link_resource *link_res, + struct dc_link_settings *link_settings); + +void reset_syncd_pipes_from_disabled_pipes(struct dc *dc, + struct dc_state *context); + +void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc, + struct dc_state *context, + uint8_t disabled_master_pipe_idx); + +void reset_sync_context_for_pipe(const struct dc *dc, + struct dc_state *context, + uint8_t pipe_idx); + +uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter transmitter); + +const struct link_hwss *get_link_hwss(const struct dc_link *link, + const struct link_resource *link_res); + +bool is_h_timing_divisible_by_2(struct dc_stream_state *stream); + +bool dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy( + const struct dc *dc, + struct dc_state *state, + struct pipe_ctx *pri_pipe, + struct pipe_ctx *sec_pipe, + bool odm); + +/* A test harness interface that modifies dp encoder resources in the given dc + * state and bypasses the need to revalidate. The interface assumes that the + * test harness interface is called with pre-validated link config stored in the + * pipe_ctx and updates dp encoder resources according to the link config. + */ +enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc, + struct dc_state *context, + struct pipe_ctx *pipe_ctx); + +/* Get hw programming parameters container from pipe context + * @pipe_ctx: pipe context + * @dscl_prog_data: struct to hold programmable hw reg values + */ +struct dscl_prog_data *resource_get_dscl_prog_data(struct pipe_ctx *pipe_ctx); +/* Setup dc callbacks for dml2 + * @dc: the display core structure + * @dml2_options: struct to hold callbacks + */ +void resource_init_common_dml2_callbacks(struct dc *dc, struct dml2_configuration_options *dml2_options); + +/* + *Calculate total DET allocated for all pipes for a given OTG_MASTER pipe + */ +int resource_calculate_det_for_stream(struct dc_state *state, struct pipe_ctx *otg_master); + +bool resource_is_hpo_acquired(struct dc_state *context); + +struct link_encoder *get_temp_dio_link_enc( + const struct resource_context *res_ctx, + const struct resource_pool *const pool, + const struct dc_link *link); #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/soc_and_ip_translator.h b/drivers/gpu/drm/amd/display/dc/inc/soc_and_ip_translator.h new file mode 100644 index 000000000000..23daf98b8aa8 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/soc_and_ip_translator.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +// +// Copyright 2025 Advanced Micro Devices, Inc. + +#ifndef __SOC_AND_IP_TRANSLATOR_H__ +#define __SOC_AND_IP_TRANSLATOR_H__ + +#include "dc.h" +#include "dml_top_soc_parameter_types.h" + +struct soc_and_ip_translator_funcs { + void (*get_soc_bb)(struct dml2_soc_bb *soc_bb, const struct dc *dc, const struct dml2_configuration_options *config); + void (*get_ip_caps)(struct dml2_ip_capabilities *dml_ip_caps); +}; + +struct soc_and_ip_translator { + const struct soc_and_ip_translator_funcs *translator_funcs; +}; + +struct soc_and_ip_translator *dc_create_soc_and_ip_translator(enum dce_version dc_version); +void dc_destroy_soc_and_ip_translator(struct soc_and_ip_translator **soc_and_ip_translator); + + +#endif // __SOC_AND_IP_TRANSLATOR_H__ diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/vm_helper.h index a37255c757e0..8bfcef0a3675 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/vm_helper.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 Advanced Micro Devices, Inc. + * Copyright 2018 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"), @@ -23,43 +23,26 @@ * */ -#ifndef __DC_LINK_DP_H__ -#define __DC_LINK_DP_H__ +#ifndef DC_INC_VM_HELPER_H_ +#define DC_INC_VM_HELPER_H_ -#define LINK_TRAINING_ATTEMPTS 4 -#define LINK_TRAINING_RETRY_DELAY 50 /* ms */ +#include "dc_types.h" -struct dc_link; -struct dc_stream_state; -struct dc_link_settings; +#define MAX_HUBP 6 -bool dp_verify_link_cap( - struct dc_link *link, - struct dc_link_settings *known_limit_link_setting, - int *fail_count); +struct vmid_usage { + int vmid_usage[2]; +}; -bool dp_validate_mode_timing( - struct dc_link *link, - const struct dc_crtc_timing *timing); +struct vm_helper { + unsigned int num_vmid; + struct vmid_usage hubp_vmid_usage[MAX_HUBP]; +}; -void decide_link_settings( - struct dc_stream_state *stream, - struct dc_link_settings *link_setting); +void vm_helper_mark_vmid_used(struct vm_helper *vm_helper, unsigned int pos, uint8_t hubp_idx); -bool perform_link_training_with_retries( - struct dc_link *link, - const struct dc_link_settings *link_setting, - bool skip_video_pattern, - int attempts); +void vm_helper_init( + struct vm_helper *vm_helper, + unsigned int num_vmid); -bool is_mst_supported(struct dc_link *link); - -bool detect_dp_sink_caps(struct dc_link *link); - -void detect_edp_sink_caps(struct dc_link *link); - -bool is_dp_active_dongle(const struct dc_link *link); - -void dp_enable_mst_on_sink(struct dc_link *link, bool enable); - -#endif /* __DC_LINK_DP_H__ */ +#endif /* DC_INC_VM_HELPER_H_ */ |
