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

/*
 * Copyright 2008 Advanced Micro Devices, Inc.
 * Copyright 2008 Red Hat Inc.
 * Copyright 2009 Jerome Glisse.
 *
 * 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: Dave Airlie
 *          Alex Deucher
 *          Jerome Glisse
 */

#include <linux/debugfs.h>
#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/seq_file.h>
#include <linux/slab.h>

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

#include "atom.h"
#include "r100_reg_safe.h"
#include "r100d.h"
#include "radeon.h"
#include "radeon_asic.h"
#include "radeon_reg.h"
#include "rn50_reg_safe.h"
#include "rs100d.h"
#include "rv200d.h"
#include "rv250d.h"

/* Firmware Names */
#define FIRMWARE_R100
#define FIRMWARE_R200
#define FIRMWARE_R300
#define FIRMWARE_R420
#define FIRMWARE_RS690
#define FIRMWARE_RS600
#define FIRMWARE_R520

MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();

#include "r100_track.h"

/* This files gather functions specifics to:
 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
 * and others in some cases.
 */

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

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

/**
 * r100_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 (r1xx-r4xx).
 */
void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
{}

/**
 * r100_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
 *
 * Does the actual pageflip (r1xx-r4xx).
 * During vblank we take the crtc lock and wait for the update_pending
 * bit to go high, when it does, we release the lock, and allow the
 * double buffered update to take place.
 */
void r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, bool async)
{}

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

/**
 * r100_pm_get_dynpm_state - look up dynpm power state callback.
 *
 * @rdev: radeon_device pointer
 *
 * Look up the optimal power state based on the
 * current state of the GPU (r1xx-r5xx).
 * Used for dynpm only.
 */
void r100_pm_get_dynpm_state(struct radeon_device *rdev)
{}

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

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

/**
 * r100_pm_prepare - pre-power state change callback.
 *
 * @rdev: radeon_device pointer
 *
 * Prepare for a power state change (r1xx-r4xx).
 */
void r100_pm_prepare(struct radeon_device *rdev)
{}

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

/**
 * r100_gui_idle - gui idle callback.
 *
 * @rdev: radeon_device pointer
 *
 * Check of the GUI (2D/3D engines) are idle (r1xx-r5xx).
 * Returns true if idle, false if not.
 */
bool r100_gui_idle(struct radeon_device *rdev)
{}

/* hpd for digital panel detect/disconnect */
/**
 * r100_hpd_sense - hpd sense callback.
 *
 * @rdev: radeon_device pointer
 * @hpd: hpd (hotplug detect) pin
 *
 * Checks if a digital monitor is connected (r1xx-r4xx).
 * Returns true if connected, false if not connected.
 */
bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
{}

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

/**
 * r100_hpd_init - hpd setup callback.
 *
 * @rdev: radeon_device pointer
 *
 * Setup the hpd pins used by the card (r1xx-r4xx).
 * Set the polarity, and enable the hpd interrupts.
 */
void r100_hpd_init(struct radeon_device *rdev)
{}

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

/*
 * PCI GART
 */
void r100_pci_gart_tlb_flush(struct radeon_device *rdev)
{}

int r100_pci_gart_init(struct radeon_device *rdev)
{}

int r100_pci_gart_enable(struct radeon_device *rdev)
{}

void r100_pci_gart_disable(struct radeon_device *rdev)
{}

uint64_t r100_pci_gart_get_page_entry(uint64_t addr, uint32_t flags)
{}

void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i,
			    uint64_t entry)
{}

void r100_pci_gart_fini(struct radeon_device *rdev)
{}

int r100_irq_set(struct radeon_device *rdev)
{}

void r100_irq_disable(struct radeon_device *rdev)
{}

static uint32_t r100_irq_ack(struct radeon_device *rdev)
{}

int r100_irq_process(struct radeon_device *rdev)
{}

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

/**
 * r100_ring_hdp_flush - flush Host Data Path via the ring buffer
 * @rdev: radeon device structure
 * @ring: ring buffer struct for emitting packets
 */
static void r100_ring_hdp_flush(struct radeon_device *rdev, struct radeon_ring *ring)
{}

/* Who ever call radeon_fence_emit should call ring_lock and ask
 * for enough space (today caller are ib schedule and buffer move) */
void r100_fence_ring_emit(struct radeon_device *rdev,
			  struct radeon_fence *fence)
{}

bool r100_semaphore_ring_emit(struct radeon_device *rdev,
			      struct radeon_ring *ring,
			      struct radeon_semaphore *semaphore,
			      bool emit_wait)
{}

struct radeon_fence *r100_copy_blit(struct radeon_device *rdev,
				    uint64_t src_offset,
				    uint64_t dst_offset,
				    unsigned num_gpu_pages,
				    struct dma_resv *resv)
{}

static int r100_cp_wait_for_idle(struct radeon_device *rdev)
{}

void r100_ring_start(struct radeon_device *rdev, struct radeon_ring *ring)
{}


/* Load the microcode for the CP */
static int r100_cp_init_microcode(struct radeon_device *rdev)
{}

u32 r100_gfx_get_rptr(struct radeon_device *rdev,
		      struct radeon_ring *ring)
{}

u32 r100_gfx_get_wptr(struct radeon_device *rdev,
		      struct radeon_ring *ring)
{}

void r100_gfx_set_wptr(struct radeon_device *rdev,
		       struct radeon_ring *ring)
{}

static void r100_cp_load_microcode(struct radeon_device *rdev)
{}

int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
{}

void r100_cp_fini(struct radeon_device *rdev)
{}

void r100_cp_disable(struct radeon_device *rdev)
{}

/*
 * CS functions
 */
int r100_reloc_pitch_offset(struct radeon_cs_parser *p,
			    struct radeon_cs_packet *pkt,
			    unsigned idx,
			    unsigned reg)
{}

int r100_packet3_load_vbpntr(struct radeon_cs_parser *p,
			     struct radeon_cs_packet *pkt,
			     int idx)
{}

int r100_cs_parse_packet0(struct radeon_cs_parser *p,
			  struct radeon_cs_packet *pkt,
			  const unsigned *auth, unsigned n,
			  radeon_packet0_check_t check)
{}

/**
 * r100_cs_packet_parse_vline() - parse userspace VLINE packet
 * @p:		parser structure holding parsing context.
 *
 * Userspace sends a special sequence for VLINE waits.
 * PACKET0 - VLINE_START_END + value
 * PACKET0 - WAIT_UNTIL +_value
 * RELOC (P3) - crtc_id in reloc.
 *
 * This function parses this and relocates the VLINE START END
 * and WAIT UNTIL packets to the correct crtc.
 * It also detects a switched off crtc and nulls out the
 * wait in that case.
 */
int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
{}

static int r100_get_vtx_size(uint32_t vtx_fmt)
{}

static int r100_packet0_check(struct radeon_cs_parser *p,
			      struct radeon_cs_packet *pkt,
			      unsigned idx, unsigned reg)
{}

int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
					 struct radeon_cs_packet *pkt,
					 struct radeon_bo *robj)
{}

static int r100_packet3_check(struct radeon_cs_parser *p,
			      struct radeon_cs_packet *pkt)
{}

int r100_cs_parse(struct radeon_cs_parser *p)
{}

static void r100_cs_track_texture_print(struct r100_cs_track_texture *t)
{}

static int r100_track_compress_size(int compress_format, int w, int h)
{}

static int r100_cs_track_cube(struct radeon_device *rdev,
			      struct r100_cs_track *track, unsigned idx)
{}

static int r100_cs_track_texture_check(struct radeon_device *rdev,
				       struct r100_cs_track *track)
{}

int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
{}

void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track)
{}

/*
 * Global GPU functions
 */
static void r100_errata(struct radeon_device *rdev)
{}

static int r100_rbbm_fifo_wait_for_entry(struct radeon_device *rdev, unsigned n)
{}

int r100_gui_wait_for_idle(struct radeon_device *rdev)
{}

int r100_mc_wait_for_idle(struct radeon_device *rdev)
{}

bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
{}

/* required on r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
void r100_enable_bm(struct radeon_device *rdev)
{}

void r100_bm_disable(struct radeon_device *rdev)
{}

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

void r100_set_common_regs(struct radeon_device *rdev)
{}

/*
 * VRAM info
 */
static void r100_vram_get_type(struct radeon_device *rdev)
{}

static u32 r100_get_accessible_vram(struct radeon_device *rdev)
{}

void r100_vram_init_sizes(struct radeon_device *rdev)
{}

void r100_vga_set_state(struct radeon_device *rdev, bool state)
{}

static void r100_mc_init(struct radeon_device *rdev)
{}


/*
 * Indirect registers accessor
 */
void r100_pll_errata_after_index(struct radeon_device *rdev)
{}

static void r100_pll_errata_after_data(struct radeon_device *rdev)
{}

uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg)
{}

void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
{}

static void r100_set_safe_registers(struct radeon_device *rdev)
{}

/*
 * Debugfs info
 */
#if defined(CONFIG_DEBUG_FS)
static int r100_debugfs_rbbm_info_show(struct seq_file *m, void *unused)
{}

static int r100_debugfs_cp_ring_info_show(struct seq_file *m, void *unused)
{}


static int r100_debugfs_cp_csq_fifo_show(struct seq_file *m, void *unused)
{}

static int r100_debugfs_mc_info_show(struct seq_file *m, void *unused)
{}

DEFINE_SHOW_ATTRIBUTE();
DEFINE_SHOW_ATTRIBUTE();
DEFINE_SHOW_ATTRIBUTE();
DEFINE_SHOW_ATTRIBUTE();

#endif

void  r100_debugfs_rbbm_init(struct radeon_device *rdev)
{}

void r100_debugfs_cp_init(struct radeon_device *rdev)
{}

void  r100_debugfs_mc_info_init(struct radeon_device *rdev)
{}

int r100_set_surface_reg(struct radeon_device *rdev, int reg,
			 uint32_t tiling_flags, uint32_t pitch,
			 uint32_t offset, uint32_t obj_size)
{}

void r100_clear_surface_reg(struct radeon_device *rdev, int reg)
{}

void r100_bandwidth_update(struct radeon_device *rdev)
{}

int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
{}

void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
{}

int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
{}

void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save)
{}

void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save)
{}

void r100_vga_render_disable(struct radeon_device *rdev)
{}

static void r100_mc_program(struct radeon_device *rdev)
{}

static void r100_clock_startup(struct radeon_device *rdev)
{}

static int r100_startup(struct radeon_device *rdev)
{}

int r100_resume(struct radeon_device *rdev)
{}

int r100_suspend(struct radeon_device *rdev)
{}

void r100_fini(struct radeon_device *rdev)
{}

/*
 * Due to how kexec works, it can leave the hw fully initialised when it
 * boots the new kernel. However doing our init sequence with the CP and
 * WB stuff setup causes GPU hangs on the RN50 at least. So at startup
 * do some quick sanity checks and restore sane values to avoid this
 * problem.
 */
void r100_restore_sanity(struct radeon_device *rdev)
{}

int r100_init(struct radeon_device *rdev)
{}

uint32_t r100_mm_rreg_slow(struct radeon_device *rdev, uint32_t reg)
{}

void r100_mm_wreg_slow(struct radeon_device *rdev, uint32_t reg, uint32_t v)
{}

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

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