linux/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c

/*
 * Copyright 2014 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.
 *
 */

#include <drm/drm_edid.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_vblank.h>

#include "amdgpu.h"
#include "amdgpu_pm.h"
#include "amdgpu_i2c.h"
#include "cikd.h"
#include "atom.h"
#include "amdgpu_atombios.h"
#include "atombios_crtc.h"
#include "atombios_encoders.h"
#include "amdgpu_pll.h"
#include "amdgpu_connectors.h"
#include "amdgpu_display.h"
#include "dce_v8_0.h"

#include "dce/dce_8_0_d.h"
#include "dce/dce_8_0_sh_mask.h"

#include "gca/gfx_7_2_enum.h"

#include "gmc/gmc_7_1_d.h"
#include "gmc/gmc_7_1_sh_mask.h"

#include "oss/oss_2_0_d.h"
#include "oss/oss_2_0_sh_mask.h"

static void dce_v8_0_set_display_funcs(struct amdgpu_device *adev);
static void dce_v8_0_set_irq_funcs(struct amdgpu_device *adev);

static const u32 crtc_offsets[6] =;

static const u32 hpd_offsets[] =;

static const uint32_t dig_offsets[] =;

static const struct {} interrupt_status_offsets[6] =;

static u32 dce_v8_0_audio_endpt_rreg(struct amdgpu_device *adev,
				     u32 block_offset, u32 reg)
{}

static void dce_v8_0_audio_endpt_wreg(struct amdgpu_device *adev,
				      u32 block_offset, u32 reg, u32 v)
{}

static u32 dce_v8_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)
{}

static void dce_v8_0_pageflip_interrupt_init(struct amdgpu_device *adev)
{}

static void dce_v8_0_pageflip_interrupt_fini(struct amdgpu_device *adev)
{}

/**
 * dce_v8_0_page_flip - pageflip callback.
 *
 * @adev: amdgpu_device pointer
 * @crtc_id: crtc to cleanup pageflip on
 * @crtc_base: new address of the crtc (GPU MC address)
 * @async: asynchronous flip
 *
 * Triggers the actual pageflip by updating the primary
 * surface base address.
 */
static void dce_v8_0_page_flip(struct amdgpu_device *adev,
			       int crtc_id, u64 crtc_base, bool async)
{}

static int dce_v8_0_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,
					u32 *vbl, u32 *position)
{}

/**
 * dce_v8_0_hpd_sense - hpd sense callback.
 *
 * @adev: amdgpu_device pointer
 * @hpd: hpd (hotplug detect) pin
 *
 * Checks if a digital monitor is connected (evergreen+).
 * Returns true if connected, false if not connected.
 */
static bool dce_v8_0_hpd_sense(struct amdgpu_device *adev,
			       enum amdgpu_hpd_id hpd)
{}

/**
 * dce_v8_0_hpd_set_polarity - hpd set polarity callback.
 *
 * @adev: amdgpu_device pointer
 * @hpd: hpd (hotplug detect) pin
 *
 * Set the polarity of the hpd pin (evergreen+).
 */
static void dce_v8_0_hpd_set_polarity(struct amdgpu_device *adev,
				      enum amdgpu_hpd_id hpd)
{}

static void dce_v8_0_hpd_int_ack(struct amdgpu_device *adev,
				 int hpd)
{}

/**
 * dce_v8_0_hpd_init - hpd setup callback.
 *
 * @adev: amdgpu_device pointer
 *
 * Setup the hpd pins used by the card (evergreen+).
 * Enable the pin, set the polarity, and enable the hpd interrupts.
 */
static void dce_v8_0_hpd_init(struct amdgpu_device *adev)
{}

/**
 * dce_v8_0_hpd_fini - hpd tear down callback.
 *
 * @adev: amdgpu_device pointer
 *
 * Tear down the hpd pins used by the card (evergreen+).
 * Disable the hpd interrupts.
 */
static void dce_v8_0_hpd_fini(struct amdgpu_device *adev)
{}

static u32 dce_v8_0_hpd_get_gpio_reg(struct amdgpu_device *adev)
{}

static bool dce_v8_0_is_display_hung(struct amdgpu_device *adev)
{}

static void dce_v8_0_set_vga_render_state(struct amdgpu_device *adev,
					  bool render)
{}

static int dce_v8_0_get_num_crtc(struct amdgpu_device *adev)
{}

void dce_v8_0_disable_dce(struct amdgpu_device *adev)
{}

static void dce_v8_0_program_fmt(struct drm_encoder *encoder)
{}


/* display watermark setup */
/**
 * dce_v8_0_line_buffer_adjust - Set up the line buffer
 *
 * @adev: amdgpu_device pointer
 * @amdgpu_crtc: the selected display controller
 * @mode: the current display mode on the selected display
 * controller
 *
 * Setup up the line buffer allocation for
 * the selected display controller (CIK).
 * Returns the line buffer size in pixels.
 */
static u32 dce_v8_0_line_buffer_adjust(struct amdgpu_device *adev,
				       struct amdgpu_crtc *amdgpu_crtc,
				       struct drm_display_mode *mode)
{}

/**
 * cik_get_number_of_dram_channels - get the number of dram channels
 *
 * @adev: amdgpu_device pointer
 *
 * Look up the number of video ram channels (CIK).
 * Used for display watermark bandwidth calculations
 * Returns the number of dram channels
 */
static u32 cik_get_number_of_dram_channels(struct amdgpu_device *adev)
{}

struct dce8_wm_params {};

/**
 * dce_v8_0_dram_bandwidth - get the dram bandwidth
 *
 * @wm: watermark calculation data
 *
 * Calculate the raw dram bandwidth (CIK).
 * Used for display watermark bandwidth calculations
 * Returns the dram bandwidth in MBytes/s
 */
static u32 dce_v8_0_dram_bandwidth(struct dce8_wm_params *wm)
{}

/**
 * dce_v8_0_dram_bandwidth_for_display - get the dram bandwidth for display
 *
 * @wm: watermark calculation data
 *
 * Calculate the dram bandwidth used for display (CIK).
 * Used for display watermark bandwidth calculations
 * Returns the dram bandwidth for display in MBytes/s
 */
static u32 dce_v8_0_dram_bandwidth_for_display(struct dce8_wm_params *wm)
{}

/**
 * dce_v8_0_data_return_bandwidth - get the data return bandwidth
 *
 * @wm: watermark calculation data
 *
 * Calculate the data return bandwidth used for display (CIK).
 * Used for display watermark bandwidth calculations
 * Returns the data return bandwidth in MBytes/s
 */
static u32 dce_v8_0_data_return_bandwidth(struct dce8_wm_params *wm)
{}

/**
 * dce_v8_0_dmif_request_bandwidth - get the dmif bandwidth
 *
 * @wm: watermark calculation data
 *
 * Calculate the dmif bandwidth used for display (CIK).
 * Used for display watermark bandwidth calculations
 * Returns the dmif bandwidth in MBytes/s
 */
static u32 dce_v8_0_dmif_request_bandwidth(struct dce8_wm_params *wm)
{}

/**
 * dce_v8_0_available_bandwidth - get the min available bandwidth
 *
 * @wm: watermark calculation data
 *
 * Calculate the min available bandwidth used for display (CIK).
 * Used for display watermark bandwidth calculations
 * Returns the min available bandwidth in MBytes/s
 */
static u32 dce_v8_0_available_bandwidth(struct dce8_wm_params *wm)
{}

/**
 * dce_v8_0_average_bandwidth - get the average available bandwidth
 *
 * @wm: watermark calculation data
 *
 * Calculate the average available bandwidth used for display (CIK).
 * Used for display watermark bandwidth calculations
 * Returns the average available bandwidth in MBytes/s
 */
static u32 dce_v8_0_average_bandwidth(struct dce8_wm_params *wm)
{}

/**
 * dce_v8_0_latency_watermark - get the latency watermark
 *
 * @wm: watermark calculation data
 *
 * Calculate the latency watermark (CIK).
 * Used for display watermark bandwidth calculations
 * Returns the latency watermark in ns
 */
static u32 dce_v8_0_latency_watermark(struct dce8_wm_params *wm)
{}

/**
 * dce_v8_0_average_bandwidth_vs_dram_bandwidth_for_display - check
 * average and available dram bandwidth
 *
 * @wm: watermark calculation data
 *
 * Check if the display average bandwidth fits in the display
 * dram bandwidth (CIK).
 * Used for display watermark bandwidth calculations
 * Returns true if the display fits, false if not.
 */
static bool dce_v8_0_average_bandwidth_vs_dram_bandwidth_for_display(struct dce8_wm_params *wm)
{}

/**
 * dce_v8_0_average_bandwidth_vs_available_bandwidth - check
 * average and available bandwidth
 *
 * @wm: watermark calculation data
 *
 * Check if the display average bandwidth fits in the display
 * available bandwidth (CIK).
 * Used for display watermark bandwidth calculations
 * Returns true if the display fits, false if not.
 */
static bool dce_v8_0_average_bandwidth_vs_available_bandwidth(struct dce8_wm_params *wm)
{}

/**
 * dce_v8_0_check_latency_hiding - check latency hiding
 *
 * @wm: watermark calculation data
 *
 * Check latency hiding (CIK).
 * Used for display watermark bandwidth calculations
 * Returns true if the display fits, false if not.
 */
static bool dce_v8_0_check_latency_hiding(struct dce8_wm_params *wm)
{}

/**
 * dce_v8_0_program_watermarks - program display watermarks
 *
 * @adev: amdgpu_device pointer
 * @amdgpu_crtc: the selected display controller
 * @lb_size: line buffer size
 * @num_heads: number of display controllers in use
 *
 * Calculate and program the display watermarks for the
 * selected display controller (CIK).
 */
static void dce_v8_0_program_watermarks(struct amdgpu_device *adev,
					struct amdgpu_crtc *amdgpu_crtc,
					u32 lb_size, u32 num_heads)
{}

/**
 * dce_v8_0_bandwidth_update - program display watermarks
 *
 * @adev: amdgpu_device pointer
 *
 * Calculate and program the display watermarks and line
 * buffer allocation (CIK).
 */
static void dce_v8_0_bandwidth_update(struct amdgpu_device *adev)
{}

static void dce_v8_0_audio_get_connected_pins(struct amdgpu_device *adev)
{}

static struct amdgpu_audio_pin *dce_v8_0_audio_get_pin(struct amdgpu_device *adev)
{}

static void dce_v8_0_afmt_audio_select_pin(struct drm_encoder *encoder)
{}

static void dce_v8_0_audio_write_latency_fields(struct drm_encoder *encoder,
						struct drm_display_mode *mode)
{}

static void dce_v8_0_audio_write_speaker_allocation(struct drm_encoder *encoder)
{}

static void dce_v8_0_audio_write_sad_regs(struct drm_encoder *encoder)
{}

static void dce_v8_0_audio_enable(struct amdgpu_device *adev,
				  struct amdgpu_audio_pin *pin,
				  bool enable)
{}

static const u32 pin_offsets[7] =;

static int dce_v8_0_audio_init(struct amdgpu_device *adev)
{}

static void dce_v8_0_audio_fini(struct amdgpu_device *adev)
{}

/*
 * update the N and CTS parameters for a given pixel clock rate
 */
static void dce_v8_0_afmt_update_ACR(struct drm_encoder *encoder, uint32_t clock)
{}

/*
 * build a HDMI Video Info Frame
 */
static void dce_v8_0_afmt_update_avi_infoframe(struct drm_encoder *encoder,
					       void *buffer, size_t size)
{}

static void dce_v8_0_audio_set_dto(struct drm_encoder *encoder, u32 clock)
{}

/*
 * update the info frames with the data from the current display mode
 */
static void dce_v8_0_afmt_setmode(struct drm_encoder *encoder,
				  struct drm_display_mode *mode)
{}

static void dce_v8_0_afmt_enable(struct drm_encoder *encoder, bool enable)
{}

static int dce_v8_0_afmt_init(struct amdgpu_device *adev)
{}

static void dce_v8_0_afmt_fini(struct amdgpu_device *adev)
{}

static const u32 vga_control_regs[6] =;

static void dce_v8_0_vga_enable(struct drm_crtc *crtc, bool enable)
{}

static void dce_v8_0_grph_enable(struct drm_crtc *crtc, bool enable)
{}

static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,
				     struct drm_framebuffer *fb,
				     int x, int y, int atomic)
{}

static void dce_v8_0_set_interleave(struct drm_crtc *crtc,
				    struct drm_display_mode *mode)
{}

static void dce_v8_0_crtc_load_lut(struct drm_crtc *crtc)
{}

static int dce_v8_0_pick_dig_encoder(struct drm_encoder *encoder)
{}

/**
 * dce_v8_0_pick_pll - Allocate a PPLL for use by the crtc.
 *
 * @crtc: drm crtc
 *
 * Returns the PPLL (Pixel PLL) to be used by the crtc.  For DP monitors
 * a single PPLL can be used for all DP crtcs/encoders.  For non-DP
 * monitors a dedicated PPLL must be used.  If a particular board has
 * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming
 * as there is no need to program the PLL itself.  If we are not able to
 * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to
 * avoid messing up an existing monitor.
 *
 * Asic specific PLL information
 *
 * DCE 8.x
 * KB/KV
 * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP)
 * CI
 * - PPLL0, PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
 *
 */
static u32 dce_v8_0_pick_pll(struct drm_crtc *crtc)
{}

static void dce_v8_0_lock_cursor(struct drm_crtc *crtc, bool lock)
{}

static void dce_v8_0_hide_cursor(struct drm_crtc *crtc)
{}

static void dce_v8_0_show_cursor(struct drm_crtc *crtc)
{}

static int dce_v8_0_cursor_move_locked(struct drm_crtc *crtc,
				       int x, int y)
{}

static int dce_v8_0_crtc_cursor_move(struct drm_crtc *crtc,
				     int x, int y)
{}

static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc,
				     struct drm_file *file_priv,
				     uint32_t handle,
				     uint32_t width,
				     uint32_t height,
				     int32_t hot_x,
				     int32_t hot_y)
{}

static void dce_v8_0_cursor_reset(struct drm_crtc *crtc)
{}

static int dce_v8_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
				   u16 *blue, uint32_t size,
				   struct drm_modeset_acquire_ctx *ctx)
{}

static void dce_v8_0_crtc_destroy(struct drm_crtc *crtc)
{}

static const struct drm_crtc_funcs dce_v8_0_crtc_funcs =;

static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode)
{}

static void dce_v8_0_crtc_prepare(struct drm_crtc *crtc)
{}

static void dce_v8_0_crtc_commit(struct drm_crtc *crtc)
{}

static void dce_v8_0_crtc_disable(struct drm_crtc *crtc)
{}

static int dce_v8_0_crtc_mode_set(struct drm_crtc *crtc,
				  struct drm_display_mode *mode,
				  struct drm_display_mode *adjusted_mode,
				  int x, int y, struct drm_framebuffer *old_fb)
{}

static bool dce_v8_0_crtc_mode_fixup(struct drm_crtc *crtc,
				     const struct drm_display_mode *mode,
				     struct drm_display_mode *adjusted_mode)
{}

static int dce_v8_0_crtc_set_base(struct drm_crtc *crtc, int x, int y,
				  struct drm_framebuffer *old_fb)
{}

static int dce_v8_0_crtc_set_base_atomic(struct drm_crtc *crtc,
					 struct drm_framebuffer *fb,
					 int x, int y, enum mode_set_atomic state)
{}

static const struct drm_crtc_helper_funcs dce_v8_0_crtc_helper_funcs =;

static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)
{}

static int dce_v8_0_early_init(void *handle)
{}

static int dce_v8_0_sw_init(void *handle)
{}

static int dce_v8_0_sw_fini(void *handle)
{}

static int dce_v8_0_hw_init(void *handle)
{}

static int dce_v8_0_hw_fini(void *handle)
{}

static int dce_v8_0_suspend(void *handle)
{}

static int dce_v8_0_resume(void *handle)
{}

static bool dce_v8_0_is_idle(void *handle)
{}

static int dce_v8_0_wait_for_idle(void *handle)
{}

static int dce_v8_0_soft_reset(void *handle)
{}

static void dce_v8_0_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev,
						     int crtc,
						     enum amdgpu_interrupt_state state)
{}

static void dce_v8_0_set_crtc_vline_interrupt_state(struct amdgpu_device *adev,
						    int crtc,
						    enum amdgpu_interrupt_state state)
{}

static int dce_v8_0_set_hpd_interrupt_state(struct amdgpu_device *adev,
					    struct amdgpu_irq_src *src,
					    unsigned type,
					    enum amdgpu_interrupt_state state)
{}

static int dce_v8_0_set_crtc_interrupt_state(struct amdgpu_device *adev,
					     struct amdgpu_irq_src *src,
					     unsigned type,
					     enum amdgpu_interrupt_state state)
{}

static int dce_v8_0_crtc_irq(struct amdgpu_device *adev,
			     struct amdgpu_irq_src *source,
			     struct amdgpu_iv_entry *entry)
{}

static int dce_v8_0_set_pageflip_interrupt_state(struct amdgpu_device *adev,
						 struct amdgpu_irq_src *src,
						 unsigned type,
						 enum amdgpu_interrupt_state state)
{}

static int dce_v8_0_pageflip_irq(struct amdgpu_device *adev,
				struct amdgpu_irq_src *source,
				struct amdgpu_iv_entry *entry)
{}

static int dce_v8_0_hpd_irq(struct amdgpu_device *adev,
			    struct amdgpu_irq_src *source,
			    struct amdgpu_iv_entry *entry)
{}

static int dce_v8_0_set_clockgating_state(void *handle,
					  enum amd_clockgating_state state)
{}

static int dce_v8_0_set_powergating_state(void *handle,
					  enum amd_powergating_state state)
{}

static const struct amd_ip_funcs dce_v8_0_ip_funcs =;

static void
dce_v8_0_encoder_mode_set(struct drm_encoder *encoder,
			  struct drm_display_mode *mode,
			  struct drm_display_mode *adjusted_mode)
{}

static void dce_v8_0_encoder_prepare(struct drm_encoder *encoder)
{}

static void dce_v8_0_encoder_commit(struct drm_encoder *encoder)
{}

static void dce_v8_0_encoder_disable(struct drm_encoder *encoder)
{}

/* these are handled by the primary encoders */
static void dce_v8_0_ext_prepare(struct drm_encoder *encoder)
{}

static void dce_v8_0_ext_commit(struct drm_encoder *encoder)
{}

static void
dce_v8_0_ext_mode_set(struct drm_encoder *encoder,
		      struct drm_display_mode *mode,
		      struct drm_display_mode *adjusted_mode)
{}

static void dce_v8_0_ext_disable(struct drm_encoder *encoder)
{}

static void
dce_v8_0_ext_dpms(struct drm_encoder *encoder, int mode)
{}

static const struct drm_encoder_helper_funcs dce_v8_0_ext_helper_funcs =;

static const struct drm_encoder_helper_funcs dce_v8_0_dig_helper_funcs =;

static const struct drm_encoder_helper_funcs dce_v8_0_dac_helper_funcs =;

static void dce_v8_0_encoder_destroy(struct drm_encoder *encoder)
{}

static const struct drm_encoder_funcs dce_v8_0_encoder_funcs =;

static void dce_v8_0_encoder_add(struct amdgpu_device *adev,
				 uint32_t encoder_enum,
				 uint32_t supported_device,
				 u16 caps)
{}

static const struct amdgpu_display_funcs dce_v8_0_display_funcs =;

static void dce_v8_0_set_display_funcs(struct amdgpu_device *adev)
{}

static const struct amdgpu_irq_src_funcs dce_v8_0_crtc_irq_funcs =;

static const struct amdgpu_irq_src_funcs dce_v8_0_pageflip_irq_funcs =;

static const struct amdgpu_irq_src_funcs dce_v8_0_hpd_irq_funcs =;

static void dce_v8_0_set_irq_funcs(struct amdgpu_device *adev)
{}

const struct amdgpu_ip_block_version dce_v8_0_ip_block =;

const struct amdgpu_ip_block_version dce_v8_1_ip_block =;

const struct amdgpu_ip_block_version dce_v8_2_ip_block =;

const struct amdgpu_ip_block_version dce_v8_3_ip_block =;

const struct amdgpu_ip_block_version dce_v8_5_ip_block =;