linux/drivers/gpu/drm/amd/display/dc/core/dc.c

/*
 * 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
 */

#include "dm_services.h"

#include "amdgpu.h"

#include "dc.h"

#include "core_status.h"
#include "core_types.h"
#include "hw_sequencer.h"
#include "dce/dce_hwseq.h"

#include "resource.h"
#include "dc_state.h"
#include "dc_state_priv.h"
#include "dc_plane_priv.h"

#include "gpio_service_interface.h"
#include "clk_mgr.h"
#include "clock_source.h"
#include "dc_bios_types.h"

#include "bios_parser_interface.h"
#include "bios/bios_parser_helper.h"
#include "include/irq_service_interface.h"
#include "transform.h"
#include "dmcu.h"
#include "dpp.h"
#include "timing_generator.h"
#include "abm.h"
#include "virtual/virtual_link_encoder.h"
#include "hubp.h"

#include "link_hwss.h"
#include "link_encoder.h"
#include "link_enc_cfg.h"

#include "link.h"
#include "dm_helpers.h"
#include "mem_input.h"

#include "dc_dmub_srv.h"

#include "dsc.h"

#include "vm_helper.h"

#include "dce/dce_i2c.h"

#include "dmub/dmub_srv.h"

#include "dce/dmub_psr.h"

#include "dce/dmub_hw_lock_mgr.h"

#include "dc_trace.h"

#include "hw_sequencer_private.h"

#if defined(CONFIG_DRM_AMD_DC_FP)
#include "dml2/dml2_internal_types.h"
#endif

#include "dce/dmub_outbox.h"

#define CTX

#define DC_LOGGER

static const char DC_BUILD_ID[] =;

/**
 * DOC: Overview
 *
 * DC is the OS-agnostic component of the amdgpu DC driver.
 *
 * DC maintains and validates a set of structs representing the state of the
 * driver and writes that state to AMD hardware
 *
 * Main DC HW structs:
 *
 * struct dc - The central struct.  One per driver.  Created on driver load,
 * destroyed on driver unload.
 *
 * struct dc_context - One per driver.
 * Used as a backpointer by most other structs in dc.
 *
 * struct dc_link - One per connector (the physical DP, HDMI, miniDP, or eDP
 * plugpoints).  Created on driver load, destroyed on driver unload.
 *
 * struct dc_sink - One per display.  Created on boot or hotplug.
 * Destroyed on shutdown or hotunplug.  A dc_link can have a local sink
 * (the display directly attached).  It may also have one or more remote
 * sinks (in the Multi-Stream Transport case)
 *
 * struct resource_pool - One per driver.  Represents the hw blocks not in the
 * main pipeline.  Not directly accessible by dm.
 *
 * Main dc state structs:
 *
 * These structs can be created and destroyed as needed.  There is a full set of
 * these structs in dc->current_state representing the currently programmed state.
 *
 * struct dc_state - The global DC state to track global state information,
 * such as bandwidth values.
 *
 * struct dc_stream_state - Represents the hw configuration for the pipeline from
 * a framebuffer to a display.  Maps one-to-one with dc_sink.
 *
 * struct dc_plane_state - Represents a framebuffer.  Each stream has at least one,
 * and may have more in the Multi-Plane Overlay case.
 *
 * struct resource_context - Represents the programmable state of everything in
 * the resource_pool.  Not directly accessible by dm.
 *
 * struct pipe_ctx - A member of struct resource_context.  Represents the
 * internal hardware pipeline components.  Each dc_plane_state has either
 * one or two (in the pipe-split case).
 */

/* Private functions */

static inline void elevate_update_type(enum surface_update_type *original, enum surface_update_type new)
{}

static void destroy_links(struct dc *dc)
{}

static uint32_t get_num_of_internal_disp(struct dc_link **links, uint32_t num_links)
{}

static int get_seamless_boot_stream_count(struct dc_state *ctx)
{}

static bool create_links(
		struct dc *dc,
		uint32_t num_virtual_links)
{}

/* Create additional DIG link encoder objects if fewer than the platform
 * supports were created during link construction. This can happen if the
 * number of physical connectors is less than the number of DIGs.
 */
static bool create_link_encoders(struct dc *dc)
{}

/* Destroy any additional DIG link encoder objects created by
 * create_link_encoders().
 * NB: Must only be called after destroy_links().
 */
static void destroy_link_encoders(struct dc *dc)
{}

static struct dc_perf_trace *dc_perf_trace_create(void)
{}

static void dc_perf_trace_destroy(struct dc_perf_trace **perf_trace)
{}

static bool set_long_vtotal(struct dc *dc, struct dc_stream_state *stream, struct dc_crtc_timing_adjust *adjust)
{}

/**
 *  dc_stream_adjust_vmin_vmax - look up pipe context & update parts of DRR
 *  @dc:     dc reference
 *  @stream: Initial dc stream state
 *  @adjust: Updated parameters for vertical_total_min and vertical_total_max
 *
 *  Looks up the pipe context of dc_stream_state and updates the
 *  vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh
 *  Rate, which is a power-saving feature that targets reducing panel
 *  refresh rate while the screen is static
 *
 *  Return: %true if the pipe context is found and adjusted;
 *          %false if the pipe context is not found.
 */
bool dc_stream_adjust_vmin_vmax(struct dc *dc,
		struct dc_stream_state *stream,
		struct dc_crtc_timing_adjust *adjust)
{}

/**
 * dc_stream_get_last_used_drr_vtotal - Looks up the pipe context of
 * dc_stream_state and gets the last VTOTAL used by DRR (Dynamic Refresh Rate)
 *
 * @dc: [in] dc reference
 * @stream: [in] Initial dc stream state
 * @refresh_rate: [in] new refresh_rate
 *
 * Return: %true if the pipe context is found and there is an associated
 *         timing_generator for the DC;
 *         %false if the pipe context is not found or there is no
 *         timing_generator for the DC.
 */
bool dc_stream_get_last_used_drr_vtotal(struct dc *dc,
		struct dc_stream_state *stream,
		uint32_t *refresh_rate)
{}

bool dc_stream_get_crtc_position(struct dc *dc,
		struct dc_stream_state **streams, int num_streams,
		unsigned int *v_pos, unsigned int *nom_v_pos)
{}

#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
static inline void
dc_stream_forward_dmub_crc_window(struct dc_dmub_srv *dmub_srv,
		struct rect *rect, struct otg_phy_mux *mux_mapping, bool is_stop)
{}

static inline void
dc_stream_forward_dmcu_crc_window(struct dmcu *dmcu,
		struct rect *rect, struct otg_phy_mux *mux_mapping, bool is_stop)
{}

bool
dc_stream_forward_crc_window(struct dc_stream_state *stream,
		struct rect *rect, bool is_stop)
{}
#endif /* CONFIG_DRM_AMD_SECURE_DISPLAY */

/**
 * dc_stream_configure_crc() - Configure CRC capture for the given stream.
 * @dc: DC Object
 * @stream: The stream to configure CRC on.
 * @enable: Enable CRC if true, disable otherwise.
 * @crc_window: CRC window (x/y start/end) information
 * @continuous: Capture CRC on every frame if true. Otherwise, only capture
 *              once.
 *
 * By default, only CRC0 is configured, and the entire frame is used to
 * calculate the CRC.
 *
 * Return: %false if the stream is not found or CRC capture is not supported;
 *         %true if the stream has been configured.
 */
bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
			     struct crc_params *crc_window, bool enable, bool continuous)
{}

/**
 * dc_stream_get_crc() - Get CRC values for the given stream.
 *
 * @dc: DC object.
 * @stream: The DC stream state of the stream to get CRCs from.
 * @r_cr: CRC value for the red component.
 * @g_y:  CRC value for the green component.
 * @b_cb: CRC value for the blue component.
 *
 * dc_stream_configure_crc needs to be called beforehand to enable CRCs.
 *
 * Return:
 * %false if stream is not found, or if CRCs are not enabled.
 */
bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
		       uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
{}

void dc_stream_set_dyn_expansion(struct dc *dc, struct dc_stream_state *stream,
		enum dc_dynamic_expansion option)
{}

void dc_stream_set_dither_option(struct dc_stream_state *stream,
		enum dc_dither_option option)
{}

bool dc_stream_set_gamut_remap(struct dc *dc, const struct dc_stream_state *stream)
{}

bool dc_stream_program_csc_matrix(struct dc *dc, struct dc_stream_state *stream)
{}

void dc_stream_set_static_screen_params(struct dc *dc,
		struct dc_stream_state **streams,
		int num_streams,
		const struct dc_static_screen_params *params)
{}

static void dc_destruct(struct dc *dc)
{}

static bool dc_construct_ctx(struct dc *dc,
		const struct dc_init_data *init_params)
{}

static bool dc_construct(struct dc *dc,
		const struct dc_init_data *init_params)
{}

static void disable_all_writeback_pipes_for_stream(
		const struct dc *dc,
		struct dc_stream_state *stream,
		struct dc_state *context)
{}

static void apply_ctx_interdependent_lock(struct dc *dc,
					  struct dc_state *context,
					  struct dc_stream_state *stream,
					  bool lock)
{}

static void dc_update_visual_confirm_color(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
{}

static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
{}

static void disable_vbios_mode_if_required(
		struct dc *dc,
		struct dc_state *context)
{}

/**
 * wait_for_blank_complete - wait for all active OPPs to finish pending blank
 * pattern updates
 *
 * @dc: [in] dc reference
 * @context: [in] hardware context in use
 */
static void wait_for_blank_complete(struct dc *dc,
		struct dc_state *context)
{}

static void wait_for_odm_update_pending_complete(struct dc *dc, struct dc_state *context)
{}

static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
{}

/* Public functions */

struct dc *dc_create(const struct dc_init_data *init_params)
{}

static void detect_edp_presence(struct dc *dc)
{}

void dc_hardware_init(struct dc *dc)
{}

void dc_init_callbacks(struct dc *dc,
		const struct dc_callback_init *init_params)
{}

void dc_deinit_callbacks(struct dc *dc)
{}

void dc_destroy(struct dc **dc)
{}

static void enable_timing_multisync(
		struct dc *dc,
		struct dc_state *ctx)
{}

static void program_timing_sync(
		struct dc *dc,
		struct dc_state *ctx)
{}

static bool streams_changed(struct dc *dc,
			    struct dc_stream_state *streams[],
			    uint8_t stream_count)
{}

bool dc_validate_boot_timing(const struct dc *dc,
				const struct dc_sink *sink,
				struct dc_crtc_timing *crtc_timing)
{}

static inline bool should_update_pipe_for_stream(
		struct dc_state *context,
		struct pipe_ctx *pipe_ctx,
		struct dc_stream_state *stream)
{}

static inline bool should_update_pipe_for_plane(
		struct dc_state *context,
		struct pipe_ctx *pipe_ctx,
		struct dc_plane_state *plane_state)
{}

void dc_enable_stereo(
	struct dc *dc,
	struct dc_state *context,
	struct dc_stream_state *streams[],
	uint8_t stream_count)
{}

void dc_trigger_sync(struct dc *dc, struct dc_state *context)
{}

static uint8_t get_stream_mask(struct dc *dc, struct dc_state *context)
{}

void dc_z10_restore(const struct dc *dc)
{}

void dc_z10_save_init(struct dc *dc)
{}

/**
 * dc_commit_state_no_check - Apply context to the hardware
 *
 * @dc: DC object with the current status to be updated
 * @context: New state that will become the current status at the end of this function
 *
 * Applies given context to the hardware and copy it into current context.
 * It's up to the user to release the src context afterwards.
 *
 * Return: an enum dc_status result code for the operation
 */
static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
{}

static bool commit_minimal_transition_state(struct dc *dc,
		struct dc_state *transition_base_context);

/**
 * dc_commit_streams - Commit current stream state
 *
 * @dc: DC object with the commit state to be configured in the hardware
 * @params: Parameters for the commit, including the streams to be committed
 *
 * Function responsible for commit streams change to the hardware.
 *
 * Return:
 * Return DC_OK if everything work as expected, otherwise, return a dc_status
 * code.
 */
enum dc_status dc_commit_streams(struct dc *dc, struct dc_commit_streams_params *params)
{}

bool dc_acquire_release_mpc_3dlut(
		struct dc *dc, bool acquire,
		struct dc_stream_state *stream,
		struct dc_3dlut **lut,
		struct dc_transfer_func **shaper)
{}

static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context)
{}

/* Perform updates here which need to be deferred until next vupdate
 *
 * i.e. blnd lut, 3dlut, and shaper lut bypass regs are double buffered
 * but forcing lut memory to shutdown state is immediate. This causes
 * single frame corruption as lut gets disabled mid-frame unless shutdown
 * is deferred until after entering bypass.
 */
static void process_deferred_updates(struct dc *dc)
{}

void dc_post_update_surfaces_to_stream(struct dc *dc)
{}

bool dc_set_generic_gpio_for_stereo(bool enable,
		struct gpio_service *gpio_service)
{}

static bool is_surface_in_context(
		const struct dc_state *context,
		const struct dc_plane_state *plane_state)
{}

static enum surface_update_type get_plane_info_update_type(const struct dc_surface_update *u)
{}

static enum surface_update_type get_scaling_info_update_type(
		const struct dc *dc,
		const struct dc_surface_update *u)
{}

static enum surface_update_type det_surface_update(const struct dc *dc,
		const struct dc_surface_update *u)
{}

static enum surface_update_type check_update_surfaces_for_stream(
		struct dc *dc,
		struct dc_surface_update *updates,
		int surface_count,
		struct dc_stream_update *stream_update,
		const struct dc_stream_status *stream_status)
{}

/*
 * dc_check_update_surfaces_for_stream() - Determine update type (fast, med, or full)
 *
 * See :c:type:`enum surface_update_type <surface_update_type>` for explanation of update types
 */
enum surface_update_type dc_check_update_surfaces_for_stream(
		struct dc *dc,
		struct dc_surface_update *updates,
		int surface_count,
		struct dc_stream_update *stream_update,
		const struct dc_stream_status *stream_status)
{}

static struct dc_stream_status *stream_get_status(
	struct dc_state *ctx,
	struct dc_stream_state *stream)
{}

static const enum surface_update_type update_surface_trace_level =;

static void copy_surface_update_to_plane(
		struct dc_plane_state *surface,
		struct dc_surface_update *srf_update)
{}

static void copy_stream_update_to_stream(struct dc *dc,
					 struct dc_state *context,
					 struct dc_stream_state *stream,
					 struct dc_stream_update *update)
{}

static void backup_planes_and_stream_state(
		struct dc_scratch_space *scratch,
		struct dc_stream_state *stream)
{}

static void restore_planes_and_stream_state(
		struct dc_scratch_space *scratch,
		struct dc_stream_state *stream)
{}

/**
 * update_seamless_boot_flags() - Helper function for updating seamless boot flags
 *
 * @dc: Current DC state
 * @context: New DC state to be programmed
 * @surface_count: Number of surfaces that have an updated
 * @stream: Corresponding stream to be updated in the current flip
 *
 * Updating seamless boot flags do not need to be part of the commit sequence. This
 * helper function will update the seamless boot flags on each flip (if required)
 * outside of the HW commit sequence (fast or slow).
 *
 * Return: void
 */
static void update_seamless_boot_flags(struct dc *dc,
		struct dc_state *context,
		int surface_count,
		struct dc_stream_state *stream)
{}

/**
 * update_planes_and_stream_state() - The function takes planes and stream
 * updates as inputs and determines the appropriate update type. If update type
 * is FULL, the function allocates a new context, populates and validates it.
 * Otherwise, it updates current dc context. The function will return both
 * new_context and new_update_type back to the caller. The function also backs
 * up both current and new contexts into corresponding dc state scratch memory.
 * TODO: The function does too many things, and even conditionally allocates dc
 * context memory implicitly. We should consider to break it down.
 *
 * @dc: Current DC state
 * @srf_updates: an array of surface updates
 * @surface_count: surface update count
 * @stream: Corresponding stream to be updated
 * @stream_update: stream update
 * @new_update_type: [out] determined update type by the function
 * @new_context: [out] new context allocated and validated if update type is
 * FULL, reference to current context if update type is less than FULL.
 *
 * Return: true if a valid update is populated into new_context, false
 * otherwise.
 */
static bool update_planes_and_stream_state(struct dc *dc,
		struct dc_surface_update *srf_updates, int surface_count,
		struct dc_stream_state *stream,
		struct dc_stream_update *stream_update,
		enum surface_update_type *new_update_type,
		struct dc_state **new_context)
{}

static void commit_planes_do_stream_update(struct dc *dc,
		struct dc_stream_state *stream,
		struct dc_stream_update *stream_update,
		enum surface_update_type update_type,
		struct dc_state *context)
{}

static bool dc_dmub_should_send_dirty_rect_cmd(struct dc *dc, struct dc_stream_state *stream)
{}

void dc_dmub_update_dirty_rect(struct dc *dc,
			       int surface_count,
			       struct dc_stream_state *stream,
			       struct dc_surface_update *srf_updates,
			       struct dc_state *context)
{}

static void build_dmub_update_dirty_rect(
		struct dc *dc,
		int surface_count,
		struct dc_stream_state *stream,
		struct dc_surface_update *srf_updates,
		struct dc_state *context,
		struct dc_dmub_cmd dc_dmub_cmd[],
		unsigned int *dmub_cmd_count)
{}

static bool check_address_only_update(union surface_update_flags update_flags)
{}

/**
 * build_dmub_cmd_list() - Build an array of DMCUB commands to be sent to DMCUB
 *
 * @dc: Current DC state
 * @srf_updates: Array of surface updates
 * @surface_count: Number of surfaces that have an updated
 * @stream: Corresponding stream to be updated in the current flip
 * @context: New DC state to be programmed
 *
 * @dc_dmub_cmd: Array of DMCUB commands to be sent to DMCUB
 * @dmub_cmd_count: Count indicating the number of DMCUB commands in dc_dmub_cmd array
 *
 * This function builds an array of DMCUB commands to be sent to DMCUB. This function is required
 * to build an array of commands and have them sent while the OTG lock is acquired.
 *
 * Return: void
 */
static void build_dmub_cmd_list(struct dc *dc,
		struct dc_surface_update *srf_updates,
		int surface_count,
		struct dc_stream_state *stream,
		struct dc_state *context,
		struct dc_dmub_cmd dc_dmub_cmd[],
		unsigned int *dmub_cmd_count)
{}

static void commit_plane_for_stream_offload_fams2_flip(struct dc *dc,
		struct dc_surface_update *srf_updates,
		int surface_count,
		struct dc_stream_state *stream,
		struct dc_state *context)
{}

static void commit_planes_for_stream_fast(struct dc *dc,
		struct dc_surface_update *srf_updates,
		int surface_count,
		struct dc_stream_state *stream,
		struct dc_stream_update *stream_update,
		enum surface_update_type update_type,
		struct dc_state *context)
{}

static void wait_for_outstanding_hw_updates(struct dc *dc, struct dc_state *dc_context)
{}

static void commit_planes_for_stream(struct dc *dc,
		struct dc_surface_update *srf_updates,
		int surface_count,
		struct dc_stream_state *stream,
		struct dc_stream_update *stream_update,
		enum surface_update_type update_type,
		struct dc_state *context)
{}

/**
 * could_mpcc_tree_change_for_active_pipes - Check if an OPP associated with MPCC might change
 *
 * @dc: Used to get the current state status
 * @stream: Target stream, which we want to remove the attached planes
 * @srf_updates: Array of surface updates
 * @surface_count: Number of surface update
 * @is_plane_addition: [in] Fill out with true if it is a plane addition case
 *
 * DCN32x and newer support a feature named Dynamic ODM which can conflict with
 * the MPO if used simultaneously in some specific configurations (e.g.,
 * 4k@144). This function checks if the incoming context requires applying a
 * transition state with unnecessary pipe splitting and ODM disabled to
 * circumvent our hardware limitations to prevent this edge case. If the OPP
 * associated with an MPCC might change due to plane additions, this function
 * returns true.
 *
 * Return:
 * Return true if OPP and MPCC might change, otherwise, return false.
 */
static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
		struct dc_stream_state *stream,
		struct dc_surface_update *srf_updates,
		int surface_count,
		bool *is_plane_addition)
{}

struct pipe_split_policy_backup {};

static void backup_and_set_minimal_pipe_split_policy(struct dc *dc,
		struct dc_state *context,
		struct pipe_split_policy_backup *policy)
{}

static void restore_minimal_pipe_split_policy(struct dc *dc,
		struct dc_state *context,
		struct pipe_split_policy_backup *policy)
{}

static void release_minimal_transition_state(struct dc *dc,
		struct dc_state *minimal_transition_context,
		struct dc_state *base_context,
		struct pipe_split_policy_backup *policy)
{}

static void force_vsync_flip_in_minimal_transition_context(struct dc_state *context)
{}

static struct dc_state *create_minimal_transition_state(struct dc *dc,
		struct dc_state *base_context, struct pipe_split_policy_backup *policy)
{}

static bool is_pipe_topology_transition_seamless_with_intermediate_step(
		struct dc *dc,
		struct dc_state *initial_state,
		struct dc_state *intermediate_state,
		struct dc_state *final_state)
{}

static void swap_and_release_current_context(struct dc *dc,
		struct dc_state *new_context, struct dc_stream_state *stream)
{}

static int initialize_empty_surface_updates(
		struct dc_stream_state *stream,
		struct dc_surface_update *srf_updates)
{}

static bool commit_minimal_transition_based_on_new_context(struct dc *dc,
		struct dc_state *new_context,
		struct dc_stream_state *stream,
		struct dc_surface_update *srf_updates,
		int surface_count)
{}

static bool commit_minimal_transition_based_on_current_context(struct dc *dc,
		struct dc_state *new_context, struct dc_stream_state *stream)
{}

/**
 * commit_minimal_transition_state_in_dc_update - Commit a minimal state based
 * on current or new context
 *
 * @dc: DC structure, used to get the current state
 * @new_context: New context
 * @stream: Stream getting the update for the flip
 * @srf_updates: Surface updates
 * @surface_count: Number of surfaces
 *
 * The function takes in current state and new state and determine a minimal
 * transition state as the intermediate step which could make the transition
 * between current and new states seamless. If found, it will commit the minimal
 * transition state and update current state to this minimal transition state
 * and return true, if not, it will return false.
 *
 * Return:
 * Return True if the minimal transition succeeded, false otherwise
 */
static bool commit_minimal_transition_state_in_dc_update(struct dc *dc,
		struct dc_state *new_context,
		struct dc_stream_state *stream,
		struct dc_surface_update *srf_updates,
		int surface_count)
{}

/**
 * commit_minimal_transition_state - Create a transition pipe split state
 *
 * @dc: Used to get the current state status
 * @transition_base_context: New transition state
 *
 * In some specific configurations, such as pipe split on multi-display with
 * MPO and/or Dynamic ODM, removing a plane may cause unsupported pipe
 * programming when moving to new planes. To mitigate those types of problems,
 * this function adds a transition state that minimizes pipe usage before
 * programming the new configuration. When adding a new plane, the current
 * state requires the least pipes, so it is applied without splitting. When
 * removing a plane, the new state requires the least pipes, so it is applied
 * without splitting.
 *
 * Return:
 * Return false if something is wrong in the transition state.
 */
static bool commit_minimal_transition_state(struct dc *dc,
		struct dc_state *transition_base_context)
{}

static void populate_fast_updates(struct dc_fast_update *fast_update,
		struct dc_surface_update *srf_updates,
		int surface_count,
		struct dc_stream_update *stream_update)
{}

static bool fast_updates_exist(struct dc_fast_update *fast_update, int surface_count)
{}

static bool full_update_required(struct dc *dc,
		struct dc_surface_update *srf_updates,
		int surface_count,
		struct dc_stream_update *stream_update,
		struct dc_stream_state *stream)
{}

static bool fast_update_only(struct dc *dc,
		struct dc_fast_update *fast_update,
		struct dc_surface_update *srf_updates,
		int surface_count,
		struct dc_stream_update *stream_update,
		struct dc_stream_state *stream)
{}

static bool update_planes_and_stream_v1(struct dc *dc,
		struct dc_surface_update *srf_updates, int surface_count,
		struct dc_stream_state *stream,
		struct dc_stream_update *stream_update,
		struct dc_state *state)
{}

static bool update_planes_and_stream_v2(struct dc *dc,
		struct dc_surface_update *srf_updates, int surface_count,
		struct dc_stream_state *stream,
		struct dc_stream_update *stream_update)
{}

static void commit_planes_and_stream_update_on_current_context(struct dc *dc,
		struct dc_surface_update *srf_updates, int surface_count,
		struct dc_stream_state *stream,
		struct dc_stream_update *stream_update,
		enum surface_update_type update_type)
{}

static void commit_planes_and_stream_update_with_new_context(struct dc *dc,
		struct dc_surface_update *srf_updates, int surface_count,
		struct dc_stream_state *stream,
		struct dc_stream_update *stream_update,
		enum surface_update_type update_type,
		struct dc_state *new_context)
{}

static bool update_planes_and_stream_v3(struct dc *dc,
		struct dc_surface_update *srf_updates, int surface_count,
		struct dc_stream_state *stream,
		struct dc_stream_update *stream_update)
{}

bool dc_update_planes_and_stream(struct dc *dc,
		struct dc_surface_update *srf_updates, int surface_count,
		struct dc_stream_state *stream,
		struct dc_stream_update *stream_update)
{}

void dc_commit_updates_for_stream(struct dc *dc,
		struct dc_surface_update *srf_updates,
		int surface_count,
		struct dc_stream_state *stream,
		struct dc_stream_update *stream_update,
		struct dc_state *state)
{}

uint8_t dc_get_current_stream_count(struct dc *dc)
{}

struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i)
{}

enum dc_irq_source dc_interrupt_to_irq_source(
		struct dc *dc,
		uint32_t src_id,
		uint32_t ext_id)
{}

/*
 * dc_interrupt_set() - Enable/disable an AMD hw interrupt source
 */
bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable)
{}

void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src)
{}

void dc_power_down_on_boot(struct dc *dc)
{}

void dc_set_power_state(struct dc *dc, enum dc_acpi_cm_power_state power_state)
{}

void dc_resume(struct dc *dc)
{}

bool dc_is_dmcu_initialized(struct dc *dc)
{}

void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info)
{}
enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping)
{}
void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg)
{}

/* enable/disable eDP PSR without specify stream for eDP */
bool dc_set_psr_allow_active(struct dc *dc, bool enable)
{}

/* enable/disable eDP Replay without specify stream for eDP */
bool dc_set_replay_allow_active(struct dc *dc, bool active)
{}

/* set IPS disable state */
bool dc_set_ips_disable(struct dc *dc, unsigned int disable_ips)
{}

void dc_allow_idle_optimizations_internal(struct dc *dc, bool allow, char const *caller_name)
{}

void dc_exit_ips_for_hw_access_internal(struct dc *dc, const char *caller_name)
{}

bool dc_dmub_is_ips_idle_state(struct dc *dc)
{}

/* set min and max memory clock to lowest and highest DPM level, respectively */
void dc_unlock_memory_clock_frequency(struct dc *dc)
{}

/* set min memory clock to the min required for current mode, max to maxDPM */
void dc_lock_memory_clock_frequency(struct dc *dc)
{}

static void blank_and_force_memclk(struct dc *dc, bool apply, unsigned int memclk_mhz)
{}


/**
 * dc_enable_dcmode_clk_limit() - lower clocks in dc (battery) mode
 * @dc: pointer to dc of the dm calling this
 * @enable: True = transition to DC mode, false = transition back to AC mode
 *
 * Some SoCs define additional clock limits when in DC mode, DM should
 * invoke this function when the platform undergoes a power source transition
 * so DC can apply/unapply the limit. This interface may be disruptive to
 * the onscreen content.
 *
 * Context: Triggered by OS through DM interface, or manually by escape calls.
 * Need to hold a dclock when doing so.
 *
 * Return: none (void function)
 *
 */
void dc_enable_dcmode_clk_limit(struct dc *dc, bool enable)
{}
bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc,
		unsigned int pitch,
		unsigned int height,
		enum surface_pixel_format format,
		struct dc_cursor_attributes *cursor_attr)
{}

/* cleanup on driver unload */
void dc_hardware_release(struct dc *dc)
{}

void dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(struct dc *dc)
{}

/**
 * dc_is_dmub_outbox_supported - Check if DMUB firmware support outbox notification
 *
 * @dc: [in] dc structure
 *
 * Checks whether DMUB FW supports outbox notifications, if supported DM
 * should register outbox interrupt prior to actually enabling interrupts
 * via dc_enable_dmub_outbox
 *
 * Return:
 * True if DMUB FW supports outbox notifications, False otherwise
 */
bool dc_is_dmub_outbox_supported(struct dc *dc)
{}

/**
 * dc_enable_dmub_notifications - Check if dmub fw supports outbox
 *
 * @dc: [in] dc structure
 *
 * Calls dc_is_dmub_outbox_supported to check if dmub fw supports outbox
 * notifications. All DMs shall switch to dc_is_dmub_outbox_supported.  This
 * API shall be removed after switching.
 *
 * Return:
 * True if DMUB FW supports outbox notifications, False otherwise
 */
bool dc_enable_dmub_notifications(struct dc *dc)
{}

/**
 * dc_enable_dmub_outbox - Enables DMUB unsolicited notification
 *
 * @dc: [in] dc structure
 *
 * Enables DMUB unsolicited notifications to x86 via outbox.
 */
void dc_enable_dmub_outbox(struct dc *dc)
{}

/**
 * dc_process_dmub_aux_transfer_async - Submits aux command to dmub via inbox message
 *                                      Sets port index appropriately for legacy DDC
 * @dc: dc structure
 * @link_index: link index
 * @payload: aux payload
 *
 * Returns: True if successful, False if failure
 */
bool dc_process_dmub_aux_transfer_async(struct dc *dc,
				uint32_t link_index,
				struct aux_payload *payload)
{}

uint8_t get_link_index_from_dpia_port_index(const struct dc *dc,
					    uint8_t dpia_port_index)
{}

/**
 * dc_process_dmub_set_config_async - Submits set_config command
 *
 * @dc: [in] dc structure
 * @link_index: [in] link_index: link index
 * @payload: [in] aux payload
 * @notify: [out] set_config immediate reply
 *
 * Submits set_config command to dmub via inbox message.
 *
 * Return:
 * True if successful, False if failure
 */
bool dc_process_dmub_set_config_async(struct dc *dc,
				uint32_t link_index,
				struct set_config_cmd_payload *payload,
				struct dmub_notification *notify)
{}

/**
 * dc_process_dmub_set_mst_slots - Submits MST solt allocation
 *
 * @dc: [in] dc structure
 * @link_index: [in] link index
 * @mst_alloc_slots: [in] mst slots to be allotted
 * @mst_slots_in_use: [out] mst slots in use returned in failure case
 *
 * Submits mst slot allocation command to dmub via inbox message
 *
 * Return:
 * DC_OK if successful, DC_ERROR if failure
 */
enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc,
				uint32_t link_index,
				uint8_t mst_alloc_slots,
				uint8_t *mst_slots_in_use)
{}

/**
 * dc_process_dmub_dpia_hpd_int_enable - Submits DPIA DPD interruption
 *
 * @dc: [in] dc structure
 * @hpd_int_enable: [in] 1 for hpd int enable, 0 to disable
 *
 * Submits dpia hpd int enable command to dmub via inbox message
 */
void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc,
				uint32_t hpd_int_enable)
{}

/**
 * dc_print_dmub_diagnostic_data - Print DMUB diagnostic data for debugging
 *
 * @dc: [in] dc structure
 *
 *
 */
void dc_print_dmub_diagnostic_data(const struct dc *dc)
{}

/**
 * dc_disable_accelerated_mode - disable accelerated mode
 * @dc: dc structure
 */
void dc_disable_accelerated_mode(struct dc *dc)
{}


/**
 *  dc_notify_vsync_int_state - notifies vsync enable/disable state
 *  @dc: dc structure
 *  @stream: stream where vsync int state changed
 *  @enable: whether vsync is enabled or disabled
 *
 *  Called when vsync is enabled/disabled Will notify DMUB to start/stop ABM
 *  interrupts after steady state is reached.
 */
void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bool enable)
{}

/*****************************************************************************
 *  dc_abm_save_restore() - Interface to DC for save+pause and restore+un-pause
 *                          ABM
 *  @dc: dc structure
 *	@stream: stream where vsync int state changed
 *  @pData: abm hw states
 *
 ****************************************************************************/
bool dc_abm_save_restore(
		struct dc *dc,
		struct dc_stream_state *stream,
		struct abm_save_restore *pData)
{}

void dc_query_current_properties(struct dc *dc, struct dc_current_properties *properties)
{}

/**
 * dc_set_edp_power() - DM controls eDP power to be ON/OFF
 *
 * Called when DM wants to power on/off eDP.
 *     Only work on links with flag skip_implict_edp_power_control is set.
 *
 * @dc: Current DC state
 * @edp_link: a link with eDP connector signal type
 * @powerOn: power on/off eDP
 *
 * Return: void
 */
void dc_set_edp_power(const struct dc *dc, struct dc_link *edp_link,
				 bool powerOn)
{}

/*
 *****************************************************************************
 * dc_get_power_profile_for_dc_state() - extracts power profile from dc state
 *
 * Called when DM wants to make power policy decisions based on dc_state
 *
 *****************************************************************************
 */
struct dc_power_profile dc_get_power_profile_for_dc_state(const struct dc_state *context)
{}