linux/drivers/gpu/drm/radeon/evergreen.c

/*
 * Copyright 2010 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: Alex Deucher
 */

#include <linux/firmware.h>
#include <linux/pci.h>
#include <linux/slab.h>

#include <drm/drm_edid.h>
#include <drm/drm_vblank.h>
#include <drm/radeon_drm.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>

#include "atom.h"
#include "avivod.h"
#include "cik.h"
#include "ni.h"
#include "rv770.h"
#include "evergreen.h"
#include "evergreen_blit_shaders.h"
#include "evergreen_reg.h"
#include "evergreend.h"
#include "radeon.h"
#include "radeon_asic.h"
#include "radeon_audio.h"
#include "radeon_ucode.h"
#include "si.h"

#define DC_HPDx_CONTROL(x)
#define DC_HPDx_INT_CONTROL(x)
#define DC_HPDx_INT_STATUS_REG(x)

/*
 * Indirect registers accessor
 */
u32 eg_cg_rreg(struct radeon_device *rdev, u32 reg)
{}

void eg_cg_wreg(struct radeon_device *rdev, u32 reg, u32 v)
{}

u32 eg_pif_phy0_rreg(struct radeon_device *rdev, u32 reg)
{}

void eg_pif_phy0_wreg(struct radeon_device *rdev, u32 reg, u32 v)
{}

u32 eg_pif_phy1_rreg(struct radeon_device *rdev, u32 reg)
{}

void eg_pif_phy1_wreg(struct radeon_device *rdev, u32 reg, u32 v)
{}

static const u32 crtc_offsets[6] =;

#include "clearstate_evergreen.h"

static const u32 sumo_rlc_save_restore_register_list[] =;

static void evergreen_gpu_init(struct radeon_device *rdev);
void evergreen_fini(struct radeon_device *rdev);
void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
void evergreen_program_aspm(struct radeon_device *rdev);

static const u32 evergreen_golden_registers[] =;

static const u32 evergreen_golden_registers2[] =;

static const u32 cypress_mgcg_init[] =;

static const u32 redwood_mgcg_init[] =;

static const u32 cedar_golden_registers[] =;

static const u32 cedar_mgcg_init[] =;

static const u32 juniper_mgcg_init[] =;

static const u32 supersumo_golden_registers[] =;

static const u32 sumo_golden_registers[] =;

static const u32 wrestler_golden_registers[] =;

static const u32 barts_golden_registers[] =;

static const u32 turks_golden_registers[] =;

static const u32 caicos_golden_registers[] =;

static void evergreen_init_golden_registers(struct radeon_device *rdev)
{}

/**
 * evergreen_get_allowed_info_register - fetch the register for the info ioctl
 *
 * @rdev: radeon_device pointer
 * @reg: register offset in bytes
 * @val: register value
 *
 * Returns 0 for success or -EINVAL for an invalid register
 *
 */
int evergreen_get_allowed_info_register(struct radeon_device *rdev,
					u32 reg, u32 *val)
{}

void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
			     unsigned *bankh, unsigned *mtaspect,
			     unsigned *tile_split)
{}

static int sumo_set_uvd_clock(struct radeon_device *rdev, u32 clock,
			      u32 cntl_reg, u32 status_reg)
{}

int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
{}

int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
{}

void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
{}

void dce4_program_fmt(struct drm_encoder *encoder)
{}

static bool dce4_is_in_vblank(struct radeon_device *rdev, int crtc)
{}

static bool dce4_is_counter_moving(struct radeon_device *rdev, int crtc)
{}

/**
 * dce4_wait_for_vblank - vblank wait asic callback.
 *
 * @rdev: radeon_device pointer
 * @crtc: crtc to wait for vblank on
 *
 * Wait for vblank on the requested crtc (evergreen+).
 */
void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
{}

/**
 * evergreen_page_flip - pageflip callback.
 *
 * @rdev: radeon_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 (evergreen+).
 */
void evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base,
			 bool async)
{}

/**
 * evergreen_page_flip_pending - check if page flip is still pending
 *
 * @rdev: radeon_device pointer
 * @crtc_id: crtc to check
 *
 * Returns the current update pending status.
 */
bool evergreen_page_flip_pending(struct radeon_device *rdev, int crtc_id)
{}

/* get temperature in millidegrees */
int evergreen_get_temp(struct radeon_device *rdev)
{}

int sumo_get_temp(struct radeon_device *rdev)
{}

/**
 * sumo_pm_init_profile - Initialize power profiles callback.
 *
 * @rdev: radeon_device pointer
 *
 * Initialize the power states used in profile mode
 * (sumo, trinity, SI).
 * Used for profile mode only.
 */
void sumo_pm_init_profile(struct radeon_device *rdev)
{}

/**
 * btc_pm_init_profile - Initialize power profiles callback.
 *
 * @rdev: radeon_device pointer
 *
 * Initialize the power states used in profile mode
 * (BTC, cayman).
 * Used for profile mode only.
 */
void btc_pm_init_profile(struct radeon_device *rdev)
{}

/**
 * evergreen_pm_misc - set additional pm hw parameters callback.
 *
 * @rdev: radeon_device pointer
 *
 * Set non-clock parameters associated with a power state
 * (voltage, etc.) (evergreen+).
 */
void evergreen_pm_misc(struct radeon_device *rdev)
{}

/**
 * evergreen_pm_prepare - pre-power state change callback.
 *
 * @rdev: radeon_device pointer
 *
 * Prepare for a power state change (evergreen+).
 */
void evergreen_pm_prepare(struct radeon_device *rdev)
{}

/**
 * evergreen_pm_finish - post-power state change callback.
 *
 * @rdev: radeon_device pointer
 *
 * Clean up after a power state change (evergreen+).
 */
void evergreen_pm_finish(struct radeon_device *rdev)
{}

/**
 * evergreen_hpd_sense - hpd sense callback.
 *
 * @rdev: radeon_device pointer
 * @hpd: hpd (hotplug detect) pin
 *
 * Checks if a digital monitor is connected (evergreen+).
 * Returns true if connected, false if not connected.
 */
bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
{}

/**
 * evergreen_hpd_set_polarity - hpd set polarity callback.
 *
 * @rdev: radeon_device pointer
 * @hpd: hpd (hotplug detect) pin
 *
 * Set the polarity of the hpd pin (evergreen+).
 */
void evergreen_hpd_set_polarity(struct radeon_device *rdev,
				enum radeon_hpd_id hpd)
{}

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

/**
 * evergreen_hpd_fini - hpd tear down callback.
 *
 * @rdev: radeon_device pointer
 *
 * Tear down the hpd pins used by the card (evergreen+).
 * Disable the hpd interrupts.
 */
void evergreen_hpd_fini(struct radeon_device *rdev)
{}

/* watermark setup */

static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev,
					struct radeon_crtc *radeon_crtc,
					struct drm_display_mode *mode,
					struct drm_display_mode *other_mode)
{}

u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev)
{}

struct evergreen_wm_params {};

static u32 evergreen_dram_bandwidth(struct evergreen_wm_params *wm)
{}

static u32 evergreen_dram_bandwidth_for_display(struct evergreen_wm_params *wm)
{}

static u32 evergreen_data_return_bandwidth(struct evergreen_wm_params *wm)
{}

static u32 evergreen_dmif_request_bandwidth(struct evergreen_wm_params *wm)
{}

static u32 evergreen_available_bandwidth(struct evergreen_wm_params *wm)
{}

static u32 evergreen_average_bandwidth(struct evergreen_wm_params *wm)
{}

static u32 evergreen_latency_watermark(struct evergreen_wm_params *wm)
{}

static bool evergreen_average_bandwidth_vs_dram_bandwidth_for_display(struct evergreen_wm_params *wm)
{
	if (evergreen_average_bandwidth(wm) <=
	    (evergreen_dram_bandwidth_for_display(wm) / wm->num_heads))
		return true;
	else
		return false;
};

static bool evergreen_average_bandwidth_vs_available_bandwidth(struct evergreen_wm_params *wm)
{
	if (evergreen_average_bandwidth(wm) <=
	    (evergreen_available_bandwidth(wm) / wm->num_heads))
		return true;
	else
		return false;
};

static bool evergreen_check_latency_hiding(struct evergreen_wm_params *wm)
{}

static void evergreen_program_watermarks(struct radeon_device *rdev,
					 struct radeon_crtc *radeon_crtc,
					 u32 lb_size, u32 num_heads)
{}

/**
 * evergreen_bandwidth_update - update display watermarks callback.
 *
 * @rdev: radeon_device pointer
 *
 * Update the display watermarks based on the requested mode(s)
 * (evergreen+).
 */
void evergreen_bandwidth_update(struct radeon_device *rdev)
{}

/**
 * evergreen_mc_wait_for_idle - wait for MC idle callback.
 *
 * @rdev: radeon_device pointer
 *
 * Wait for the MC (memory controller) to be idle.
 * (evergreen+).
 * Returns 0 if the MC is idle, -1 if not.
 */
int evergreen_mc_wait_for_idle(struct radeon_device *rdev)
{}

/*
 * GART
 */
void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev)
{}

static int evergreen_pcie_gart_enable(struct radeon_device *rdev)
{}

static void evergreen_pcie_gart_disable(struct radeon_device *rdev)
{}

static void evergreen_pcie_gart_fini(struct radeon_device *rdev)
{}


static void evergreen_agp_enable(struct radeon_device *rdev)
{}

static const unsigned ni_dig_offsets[] =;

static const unsigned ni_tx_offsets[] =;

static const unsigned evergreen_dp_offsets[] =;

static const unsigned evergreen_disp_int_status[] =;

/*
 * Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc
 * We go from crtc to connector and it is not relible  since it
 * should be an opposite direction .If crtc is enable then
 * find the dig_fe which selects this crtc and insure that it enable.
 * if such dig_fe is found then find dig_be which selects found dig_be and
 * insure that it enable and in DP_SST mode.
 * if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing
 * from dp symbols clocks .
 */
static bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev,
					       unsigned crtc_id, unsigned *ret_dig_fe)
{}

/*
 * Blank dig when in dp sst mode
 * Dig ignores crtc timing
 */
static void evergreen_blank_dp_output(struct radeon_device *rdev,
				      unsigned dig_fe)
{}

void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
{}

void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
{}

void evergreen_mc_program(struct radeon_device *rdev)
{}

/*
 * CP.
 */
void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
{}


static int evergreen_cp_load_microcode(struct radeon_device *rdev)
{}

static int evergreen_cp_start(struct radeon_device *rdev)
{}

static int evergreen_cp_resume(struct radeon_device *rdev)
{}

/*
 * Core functions
 */
static void evergreen_gpu_init(struct radeon_device *rdev)
{}

int evergreen_mc_init(struct radeon_device *rdev)
{}

void evergreen_print_gpu_status_regs(struct radeon_device *rdev)
{}

bool evergreen_is_display_hung(struct radeon_device *rdev)
{}

u32 evergreen_gpu_check_soft_reset(struct radeon_device *rdev)
{}

static void evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
{}

void evergreen_gpu_pci_config_reset(struct radeon_device *rdev)
{}

int evergreen_asic_reset(struct radeon_device *rdev, bool hard)
{}

/**
 * evergreen_gfx_is_lockup - Check if the GFX engine is locked up
 *
 * @rdev: radeon_device pointer
 * @ring: radeon_ring structure holding ring information
 *
 * Check if the GFX engine is locked up.
 * Returns true if the engine appears to be locked up, false if not.
 */
bool evergreen_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
{}

/*
 * RLC
 */
#define RLC_SAVE_RESTORE_LIST_END_MARKER
#define RLC_CLEAR_STATE_END_MARKER

void sumo_rlc_fini(struct radeon_device *rdev)
{}

#define CP_ME_TABLE_SIZE

int sumo_rlc_init(struct radeon_device *rdev)
{}

static void evergreen_rlc_start(struct radeon_device *rdev)
{}

int evergreen_rlc_resume(struct radeon_device *rdev)
{}

/* Interrupts */

u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc)
{}

void evergreen_disable_interrupt_state(struct radeon_device *rdev)
{}

/* Note that the order we write back regs here is important */
int evergreen_irq_set(struct radeon_device *rdev)
{}

/* Note that the order we write back regs here is important */
static void evergreen_irq_ack(struct radeon_device *rdev)
{}

static void evergreen_irq_disable(struct radeon_device *rdev)
{}

void evergreen_irq_suspend(struct radeon_device *rdev)
{}

static u32 evergreen_get_ih_wptr(struct radeon_device *rdev)
{}

int evergreen_irq_process(struct radeon_device *rdev)
{}

static void evergreen_uvd_init(struct radeon_device *rdev)
{}

static void evergreen_uvd_start(struct radeon_device *rdev)
{}

static void evergreen_uvd_resume(struct radeon_device *rdev)
{}

static int evergreen_startup(struct radeon_device *rdev)
{}

int evergreen_resume(struct radeon_device *rdev)
{}

int evergreen_suspend(struct radeon_device *rdev)
{}

/* Plan is to move initialization in that function and use
 * helper function so that radeon_device_init pretty much
 * do nothing more than calling asic specific function. This
 * should also allow to remove a bunch of callback function
 * like vram_info.
 */
int evergreen_init(struct radeon_device *rdev)
{}

void evergreen_fini(struct radeon_device *rdev)
{}

void evergreen_pcie_gen2_enable(struct radeon_device *rdev)
{}

void evergreen_program_aspm(struct radeon_device *rdev)
{}