Remove UMS support code from radeonkms.

The code is unreachable since the entries of radeon_ioctls[] are not
associated with any device: we provide only the KMS entry points.
Moreover, r600_cp_dispatch_texture() contains an integer overflow bug
that can be triggered from userspace.[1]

Reported by:	Anonymous of the Shellphish Grill Team[1]
Reviewed by:	dumbbell
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D18516
This commit is contained in:
Mark Johnston 2018-12-17 21:48:20 +00:00
parent e710f8caf5
commit fd930cdbd0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=342182
10 changed files with 33 additions and 10818 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,876 +0,0 @@
/*
* Copyright 2009 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 (including the next
* paragraph) 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) AND/OR ITS SUPPLIERS 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 <alexander.deucher@amd.com>
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <dev/drm2/drmP.h>
#include <dev/drm2/radeon/radeon_drm.h>
#include "radeon_drv.h"
#include "r600_blit_shaders.h"
#define DI_PT_RECTLIST 0x11
#define DI_INDEX_SIZE_16_BIT 0x0
#define DI_SRC_SEL_AUTO_INDEX 0x2
#define FMT_8 0x1
#define FMT_5_6_5 0x8
#define FMT_8_8_8_8 0x1a
#define COLOR_8 0x1
#define COLOR_5_6_5 0x8
#define COLOR_8_8_8_8 0x1a
static void
set_render_target(drm_radeon_private_t *dev_priv, int format, int w, int h, u64 gpu_addr)
{
u32 cb_color_info;
int pitch, slice;
RING_LOCALS;
DRM_DEBUG("\n");
h = roundup2(h, 8);
if (h < 8)
h = 8;
cb_color_info = ((format << 2) | (1 << 27));
pitch = (w / 8) - 1;
slice = ((w * h) / 64) - 1;
if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600) &&
((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) {
BEGIN_RING(21 + 2);
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(gpu_addr >> 8);
OUT_RING(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0));
OUT_RING(2 << 0);
} else {
BEGIN_RING(21);
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(gpu_addr >> 8);
}
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_CB_COLOR0_SIZE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING((pitch << 0) | (slice << 10));
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_CB_COLOR0_VIEW - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(0);
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_CB_COLOR0_INFO - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(cb_color_info);
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_CB_COLOR0_TILE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(0);
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_CB_COLOR0_FRAG - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(0);
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_CB_COLOR0_MASK - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(0);
ADVANCE_RING();
}
static void
cp_set_surface_sync(drm_radeon_private_t *dev_priv,
u32 sync_type, u32 size, u64 mc_addr)
{
u32 cp_coher_size;
RING_LOCALS;
DRM_DEBUG("\n");
if (size == 0xffffffff)
cp_coher_size = 0xffffffff;
else
cp_coher_size = ((size + 255) >> 8);
BEGIN_RING(5);
OUT_RING(CP_PACKET3(R600_IT_SURFACE_SYNC, 3));
OUT_RING(sync_type);
OUT_RING(cp_coher_size);
OUT_RING((mc_addr >> 8));
OUT_RING(10); /* poll interval */
ADVANCE_RING();
}
static void
set_shaders(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
u64 gpu_addr;
int i;
u32 *vs, *ps;
uint32_t sq_pgm_resources;
RING_LOCALS;
DRM_DEBUG("\n");
/* load shaders */
vs = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset);
ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256);
for (i = 0; i < r6xx_vs_size; i++)
vs[i] = cpu_to_le32(r6xx_vs[i]);
for (i = 0; i < r6xx_ps_size; i++)
ps[i] = cpu_to_le32(r6xx_ps[i]);
dev_priv->blit_vb->used = 512;
gpu_addr = dev_priv->gart_buffers_offset + dev_priv->blit_vb->offset;
/* setup shader regs */
sq_pgm_resources = (1 << 0);
BEGIN_RING(9 + 12);
/* VS */
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_SQ_PGM_START_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(gpu_addr >> 8);
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_SQ_PGM_RESOURCES_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(sq_pgm_resources);
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_SQ_PGM_CF_OFFSET_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(0);
/* PS */
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_SQ_PGM_START_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING((gpu_addr + 256) >> 8);
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_SQ_PGM_RESOURCES_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(sq_pgm_resources | (1 << 28));
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_SQ_PGM_EXPORTS_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(2);
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
OUT_RING((R600_SQ_PGM_CF_OFFSET_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING(0);
ADVANCE_RING();
cp_set_surface_sync(dev_priv,
R600_SH_ACTION_ENA, 512, gpu_addr);
}
static void
set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr)
{
uint32_t sq_vtx_constant_word2;
RING_LOCALS;
DRM_DEBUG("\n");
sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8));
#ifdef __BIG_ENDIAN
sq_vtx_constant_word2 |= (2U << 30);
#endif
BEGIN_RING(9);
OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
OUT_RING(0x460);
OUT_RING(gpu_addr & 0xffffffff);
OUT_RING(48 - 1);
OUT_RING(sq_vtx_constant_word2);
OUT_RING(1 << 0);
OUT_RING(0);
OUT_RING(0);
OUT_RING(R600_SQ_TEX_VTX_VALID_BUFFER << 30);
ADVANCE_RING();
if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710))
cp_set_surface_sync(dev_priv,
R600_TC_ACTION_ENA, 48, gpu_addr);
else
cp_set_surface_sync(dev_priv,
R600_VC_ACTION_ENA, 48, gpu_addr);
}
static void
set_tex_resource(drm_radeon_private_t *dev_priv,
int format, int w, int h, int pitch, u64 gpu_addr)
{
uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4;
RING_LOCALS;
DRM_DEBUG("\n");
if (h < 1)
h = 1;
sq_tex_resource_word0 = (1 << 0);
sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) |
((w - 1) << 19));
sq_tex_resource_word1 = (format << 26);
sq_tex_resource_word1 |= ((h - 1) << 0);
sq_tex_resource_word4 = ((1 << 14) |
(0 << 16) |
(1 << 19) |
(2 << 22) |
(3 << 25));
BEGIN_RING(9);
OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
OUT_RING(0);
OUT_RING(sq_tex_resource_word0);
OUT_RING(sq_tex_resource_word1);
OUT_RING(gpu_addr >> 8);
OUT_RING(gpu_addr >> 8);
OUT_RING(sq_tex_resource_word4);
OUT_RING(0);
OUT_RING(R600_SQ_TEX_VTX_VALID_TEXTURE << 30);
ADVANCE_RING();
}
static void
set_scissors(drm_radeon_private_t *dev_priv, int x1, int y1, int x2, int y2)
{
RING_LOCALS;
DRM_DEBUG("\n");
BEGIN_RING(12);
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2));
OUT_RING((R600_PA_SC_SCREEN_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING((x1 << 0) | (y1 << 16));
OUT_RING((x2 << 0) | (y2 << 16));
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2));
OUT_RING((R600_PA_SC_GENERIC_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING((x1 << 0) | (y1 << 16) | (1U << 31));
OUT_RING((x2 << 0) | (y2 << 16));
OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2));
OUT_RING((R600_PA_SC_WINDOW_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2);
OUT_RING((x1 << 0) | (y1 << 16) | (1U << 31));
OUT_RING((x2 << 0) | (y2 << 16));
ADVANCE_RING();
}
static void
draw_auto(drm_radeon_private_t *dev_priv)
{
RING_LOCALS;
DRM_DEBUG("\n");
BEGIN_RING(10);
OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
OUT_RING((R600_VGT_PRIMITIVE_TYPE - R600_SET_CONFIG_REG_OFFSET) >> 2);
OUT_RING(DI_PT_RECTLIST);
OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
#ifdef __BIG_ENDIAN
OUT_RING((2 << 2) | DI_INDEX_SIZE_16_BIT);
#else
OUT_RING(DI_INDEX_SIZE_16_BIT);
#endif
OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
OUT_RING(1);
OUT_RING(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1));
OUT_RING(3);
OUT_RING(DI_SRC_SEL_AUTO_INDEX);
ADVANCE_RING();
COMMIT_RING();
}
static void
set_default_state(drm_radeon_private_t *dev_priv)
{
int i;
u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2;
u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2;
int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs;
int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads;
int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries;
RING_LOCALS;
switch ((dev_priv->flags & RADEON_FAMILY_MASK)) {
case CHIP_R600:
num_ps_gprs = 192;
num_vs_gprs = 56;
num_temp_gprs = 4;
num_gs_gprs = 0;
num_es_gprs = 0;
num_ps_threads = 136;
num_vs_threads = 48;
num_gs_threads = 4;
num_es_threads = 4;
num_ps_stack_entries = 128;
num_vs_stack_entries = 128;
num_gs_stack_entries = 0;
num_es_stack_entries = 0;
break;
case CHIP_RV630:
case CHIP_RV635:
num_ps_gprs = 84;
num_vs_gprs = 36;
num_temp_gprs = 4;
num_gs_gprs = 0;
num_es_gprs = 0;
num_ps_threads = 144;
num_vs_threads = 40;
num_gs_threads = 4;
num_es_threads = 4;
num_ps_stack_entries = 40;
num_vs_stack_entries = 40;
num_gs_stack_entries = 32;
num_es_stack_entries = 16;
break;
case CHIP_RV610:
case CHIP_RV620:
case CHIP_RS780:
case CHIP_RS880:
default:
num_ps_gprs = 84;
num_vs_gprs = 36;
num_temp_gprs = 4;
num_gs_gprs = 0;
num_es_gprs = 0;
num_ps_threads = 136;
num_vs_threads = 48;
num_gs_threads = 4;
num_es_threads = 4;
num_ps_stack_entries = 40;
num_vs_stack_entries = 40;
num_gs_stack_entries = 32;
num_es_stack_entries = 16;
break;
case CHIP_RV670:
num_ps_gprs = 144;
num_vs_gprs = 40;
num_temp_gprs = 4;
num_gs_gprs = 0;
num_es_gprs = 0;
num_ps_threads = 136;
num_vs_threads = 48;
num_gs_threads = 4;
num_es_threads = 4;
num_ps_stack_entries = 40;
num_vs_stack_entries = 40;
num_gs_stack_entries = 32;
num_es_stack_entries = 16;
break;
case CHIP_RV770:
num_ps_gprs = 192;
num_vs_gprs = 56;
num_temp_gprs = 4;
num_gs_gprs = 0;
num_es_gprs = 0;
num_ps_threads = 188;
num_vs_threads = 60;
num_gs_threads = 0;
num_es_threads = 0;
num_ps_stack_entries = 256;
num_vs_stack_entries = 256;
num_gs_stack_entries = 0;
num_es_stack_entries = 0;
break;
case CHIP_RV730:
case CHIP_RV740:
num_ps_gprs = 84;
num_vs_gprs = 36;
num_temp_gprs = 4;
num_gs_gprs = 0;
num_es_gprs = 0;
num_ps_threads = 188;
num_vs_threads = 60;
num_gs_threads = 0;
num_es_threads = 0;
num_ps_stack_entries = 128;
num_vs_stack_entries = 128;
num_gs_stack_entries = 0;
num_es_stack_entries = 0;
break;
case CHIP_RV710:
num_ps_gprs = 192;
num_vs_gprs = 56;
num_temp_gprs = 4;
num_gs_gprs = 0;
num_es_gprs = 0;
num_ps_threads = 144;
num_vs_threads = 48;
num_gs_threads = 0;
num_es_threads = 0;
num_ps_stack_entries = 128;
num_vs_stack_entries = 128;
num_gs_stack_entries = 0;
num_es_stack_entries = 0;
break;
}
if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710))
sq_config = 0;
else
sq_config = R600_VC_ENABLE;
sq_config |= (R600_DX9_CONSTS |
R600_ALU_INST_PREFER_VECTOR |
R600_PS_PRIO(0) |
R600_VS_PRIO(1) |
R600_GS_PRIO(2) |
R600_ES_PRIO(3));
sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(num_ps_gprs) |
R600_NUM_VS_GPRS(num_vs_gprs) |
R600_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs));
sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(num_gs_gprs) |
R600_NUM_ES_GPRS(num_es_gprs));
sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(num_ps_threads) |
R600_NUM_VS_THREADS(num_vs_threads) |
R600_NUM_GS_THREADS(num_gs_threads) |
R600_NUM_ES_THREADS(num_es_threads));
sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(num_ps_stack_entries) |
R600_NUM_VS_STACK_ENTRIES(num_vs_stack_entries));
sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(num_gs_stack_entries) |
R600_NUM_ES_STACK_ENTRIES(num_es_stack_entries));
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) {
BEGIN_RING(r7xx_default_size + 10);
for (i = 0; i < r7xx_default_size; i++)
OUT_RING(r7xx_default_state[i]);
} else {
BEGIN_RING(r6xx_default_size + 10);
for (i = 0; i < r6xx_default_size; i++)
OUT_RING(r6xx_default_state[i]);
}
OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT);
/* SQ config */
OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 6));
OUT_RING((R600_SQ_CONFIG - R600_SET_CONFIG_REG_OFFSET) >> 2);
OUT_RING(sq_config);
OUT_RING(sq_gpr_resource_mgmt_1);
OUT_RING(sq_gpr_resource_mgmt_2);
OUT_RING(sq_thread_resource_mgmt);
OUT_RING(sq_stack_resource_mgmt_1);
OUT_RING(sq_stack_resource_mgmt_2);
ADVANCE_RING();
}
/* 23 bits of float fractional data */
#define I2F_FRAC_BITS 23
#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
/*
* Converts unsigned integer into 32-bit IEEE floating point representation.
* Will be exact from 0 to 2^24. Above that, we round towards zero
* as the fractional bits will not fit in a float. (It would be better to
* round towards even as the fpu does, but that is slower.)
*/
__pure uint32_t int2float(uint32_t x)
{
uint32_t msb, exponent, fraction;
/* Zero is special */
if (!x) return 0;
/* Get location of the most significant bit */
msb = fls(x);
/*
* Use a rotate instead of a shift because that works both leftwards
* and rightwards due to the mod(32) behaviour. This means we don't
* need to check to see if we are above 2^24 or not.
*/
fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
exponent = (127 + msb) << I2F_FRAC_BITS;
return fraction + exponent;
}
static int r600_nomm_get_vb(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
dev_priv->blit_vb = radeon_freelist_get(dev);
if (!dev_priv->blit_vb) {
DRM_ERROR("Unable to allocate vertex buffer for blit\n");
return -EAGAIN;
}
return 0;
}
static void r600_nomm_put_vb(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
dev_priv->blit_vb->used = 0;
radeon_cp_discard_buffer(dev, dev_priv->blit_vb->file_priv->master, dev_priv->blit_vb);
}
static void *r600_nomm_get_vb_ptr(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
return (((char *)dev->agp_buffer_map->handle +
dev_priv->blit_vb->offset + dev_priv->blit_vb->used));
}
int
r600_prepare_blit_copy(struct drm_device *dev, struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
int ret;
DRM_DEBUG("\n");
ret = r600_nomm_get_vb(dev);
if (ret)
return ret;
dev_priv->blit_vb->file_priv = file_priv;
set_default_state(dev_priv);
set_shaders(dev);
return 0;
}
void
r600_done_blit_copy(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
DRM_DEBUG("\n");
BEGIN_RING(5);
OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT);
/* wait for 3D idle clean */
OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2);
OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN);
ADVANCE_RING();
COMMIT_RING();
r600_nomm_put_vb(dev);
}
void
r600_blit_copy(struct drm_device *dev,
uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
int size_bytes)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
int max_bytes;
u64 vb_addr;
u32 *vb;
vb = r600_nomm_get_vb_ptr(dev);
if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
max_bytes = 8192;
while (size_bytes) {
int cur_size = size_bytes;
int src_x = src_gpu_addr & 255;
int dst_x = dst_gpu_addr & 255;
int h = 1;
src_gpu_addr = src_gpu_addr & ~255;
dst_gpu_addr = dst_gpu_addr & ~255;
if (!src_x && !dst_x) {
h = (cur_size / max_bytes);
if (h > 8192)
h = 8192;
if (h == 0)
h = 1;
else
cur_size = max_bytes;
} else {
if (cur_size > max_bytes)
cur_size = max_bytes;
if (cur_size > (max_bytes - dst_x))
cur_size = (max_bytes - dst_x);
if (cur_size > (max_bytes - src_x))
cur_size = (max_bytes - src_x);
}
if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
r600_nomm_put_vb(dev);
r600_nomm_get_vb(dev);
if (!dev_priv->blit_vb)
return;
set_shaders(dev);
vb = r600_nomm_get_vb_ptr(dev);
}
vb[0] = int2float(dst_x);
vb[1] = 0;
vb[2] = int2float(src_x);
vb[3] = 0;
vb[4] = int2float(dst_x);
vb[5] = int2float(h);
vb[6] = int2float(src_x);
vb[7] = int2float(h);
vb[8] = int2float(dst_x + cur_size);
vb[9] = int2float(h);
vb[10] = int2float(src_x + cur_size);
vb[11] = int2float(h);
/* src */
set_tex_resource(dev_priv, FMT_8,
src_x + cur_size, h, src_x + cur_size,
src_gpu_addr);
cp_set_surface_sync(dev_priv,
R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr);
/* dst */
set_render_target(dev_priv, COLOR_8,
dst_x + cur_size, h,
dst_gpu_addr);
/* scissors */
set_scissors(dev_priv, dst_x, 0, dst_x + cur_size, h);
/* Vertex buffer setup */
vb_addr = dev_priv->gart_buffers_offset +
dev_priv->blit_vb->offset +
dev_priv->blit_vb->used;
set_vtx_resource(dev_priv, vb_addr);
/* draw */
draw_auto(dev_priv);
cp_set_surface_sync(dev_priv,
R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
cur_size * h, dst_gpu_addr);
vb += 12;
dev_priv->blit_vb->used += 12 * 4;
src_gpu_addr += cur_size * h;
dst_gpu_addr += cur_size * h;
size_bytes -= cur_size * h;
}
} else {
max_bytes = 8192 * 4;
while (size_bytes) {
int cur_size = size_bytes;
int src_x = (src_gpu_addr & 255);
int dst_x = (dst_gpu_addr & 255);
int h = 1;
src_gpu_addr = src_gpu_addr & ~255;
dst_gpu_addr = dst_gpu_addr & ~255;
if (!src_x && !dst_x) {
h = (cur_size / max_bytes);
if (h > 8192)
h = 8192;
if (h == 0)
h = 1;
else
cur_size = max_bytes;
} else {
if (cur_size > max_bytes)
cur_size = max_bytes;
if (cur_size > (max_bytes - dst_x))
cur_size = (max_bytes - dst_x);
if (cur_size > (max_bytes - src_x))
cur_size = (max_bytes - src_x);
}
if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
r600_nomm_put_vb(dev);
r600_nomm_get_vb(dev);
if (!dev_priv->blit_vb)
return;
set_shaders(dev);
vb = r600_nomm_get_vb_ptr(dev);
}
vb[0] = int2float(dst_x / 4);
vb[1] = 0;
vb[2] = int2float(src_x / 4);
vb[3] = 0;
vb[4] = int2float(dst_x / 4);
vb[5] = int2float(h);
vb[6] = int2float(src_x / 4);
vb[7] = int2float(h);
vb[8] = int2float((dst_x + cur_size) / 4);
vb[9] = int2float(h);
vb[10] = int2float((src_x + cur_size) / 4);
vb[11] = int2float(h);
/* src */
set_tex_resource(dev_priv, FMT_8_8_8_8,
(src_x + cur_size) / 4,
h, (src_x + cur_size) / 4,
src_gpu_addr);
cp_set_surface_sync(dev_priv,
R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr);
/* dst */
set_render_target(dev_priv, COLOR_8_8_8_8,
(dst_x + cur_size) / 4, h,
dst_gpu_addr);
/* scissors */
set_scissors(dev_priv, (dst_x / 4), 0, (dst_x + cur_size / 4), h);
/* Vertex buffer setup */
vb_addr = dev_priv->gart_buffers_offset +
dev_priv->blit_vb->offset +
dev_priv->blit_vb->used;
set_vtx_resource(dev_priv, vb_addr);
/* draw */
draw_auto(dev_priv);
cp_set_surface_sync(dev_priv,
R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
cur_size * h, dst_gpu_addr);
vb += 12;
dev_priv->blit_vb->used += 12 * 4;
src_gpu_addr += cur_size * h;
dst_gpu_addr += cur_size * h;
size_bytes -= cur_size * h;
}
}
}
void
r600_blit_swap(struct drm_device *dev,
uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
int sx, int sy, int dx, int dy,
int w, int h, int src_pitch, int dst_pitch, int cpp)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
int cb_format, tex_format;
int sx2, sy2, dx2, dy2;
u64 vb_addr;
u32 *vb;
if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
r600_nomm_put_vb(dev);
r600_nomm_get_vb(dev);
if (!dev_priv->blit_vb)
return;
set_shaders(dev);
}
vb = r600_nomm_get_vb_ptr(dev);
sx2 = sx + w;
sy2 = sy + h;
dx2 = dx + w;
dy2 = dy + h;
vb[0] = int2float(dx);
vb[1] = int2float(dy);
vb[2] = int2float(sx);
vb[3] = int2float(sy);
vb[4] = int2float(dx);
vb[5] = int2float(dy2);
vb[6] = int2float(sx);
vb[7] = int2float(sy2);
vb[8] = int2float(dx2);
vb[9] = int2float(dy2);
vb[10] = int2float(sx2);
vb[11] = int2float(sy2);
switch(cpp) {
case 4:
cb_format = COLOR_8_8_8_8;
tex_format = FMT_8_8_8_8;
break;
case 2:
cb_format = COLOR_5_6_5;
tex_format = FMT_5_6_5;
break;
default:
cb_format = COLOR_8;
tex_format = FMT_8;
break;
}
/* src */
set_tex_resource(dev_priv, tex_format,
src_pitch / cpp,
sy2, src_pitch / cpp,
src_gpu_addr);
cp_set_surface_sync(dev_priv,
R600_TC_ACTION_ENA, src_pitch * sy2, src_gpu_addr);
/* dst */
set_render_target(dev_priv, cb_format,
dst_pitch / cpp, dy2,
dst_gpu_addr);
/* scissors */
set_scissors(dev_priv, dx, dy, dx2, dy2);
/* Vertex buffer setup */
vb_addr = dev_priv->gart_buffers_offset +
dev_priv->blit_vb->offset +
dev_priv->blit_vb->used;
set_vtx_resource(dev_priv, vb_addr);
/* draw */
draw_auto(dev_priv);
cp_set_surface_sync(dev_priv,
R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
dst_pitch * dy2, dst_gpu_addr);
dev_priv->blit_vb->used += 12 * 4;
}

View file

@ -35,6 +35,39 @@ __FBSDID("$FreeBSD$");
#include "r600_blit_shaders.h"
#include "radeon_blit_common.h"
/* 23 bits of float fractional data */
#define I2F_FRAC_BITS 23
#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
/*
* Converts unsigned integer into 32-bit IEEE floating point representation.
* Will be exact from 0 to 2^24. Above that, we round towards zero
* as the fractional bits will not fit in a float. (It would be better to
* round towards even as the fpu does, but that is slower.)
*
* Moved from r600_blit.c after that file was removed.
*/
__pure uint32_t int2float(uint32_t x)
{
uint32_t msb, exponent, fraction;
/* Zero is special */
if (!x) return 0;
/* Get location of the most significant bit */
msb = fls(x);
/*
* Use a rotate instead of a shift because that works both leftwards
* and rightwards due to the mod(32) behaviour. This means we don't
* need to check to see if we are above 2^24 or not.
*/
fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
exponent = (127 + msb) << I2F_FRAC_BITS;
return fraction + exponent;
}
/* emits 21 on rv770+, 23 on r600 */
static void
set_render_target(struct radeon_device *rdev, int format,

File diff suppressed because it is too large Load diff

View file

@ -39,8 +39,6 @@ __FBSDID("$FreeBSD$");
static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
struct radeon_cs_reloc **cs_reloc);
static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
struct radeon_cs_reloc **cs_reloc);
typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**);
static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm;
#ifdef FREEBSD_WIP /* FreeBSD: to please GCC 4.2. */
@ -884,53 +882,6 @@ static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
return 0;
}
/**
* r600_cs_packet_next_reloc_nomm() - parse next packet which should be reloc packet3
* @parser: parser structure holding parsing context.
* @data: pointer to relocation data
* @offset_start: starting offset
* @offset_mask: offset mask (to align start offset on)
* @reloc: reloc informations
*
* Check next packet is relocation packet3, do bo validation and compute
* GPU offset using the provided start.
**/
static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
struct radeon_cs_reloc **cs_reloc)
{
struct radeon_cs_chunk *relocs_chunk;
struct radeon_cs_packet p3reloc;
unsigned idx;
int r;
if (p->chunk_relocs_idx == -1) {
DRM_ERROR("No relocation chunk !\n");
return -EINVAL;
}
*cs_reloc = NULL;
relocs_chunk = &p->chunks[p->chunk_relocs_idx];
r = r600_cs_packet_parse(p, &p3reloc, p->idx);
if (r) {
return r;
}
p->idx += p3reloc.count + 2;
if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
DRM_ERROR("No packet3 for relocation for packet at %d.\n",
p3reloc.idx);
return -EINVAL;
}
idx = radeon_get_ib_value(p, p3reloc.idx + 1);
if (idx >= relocs_chunk->length_dw) {
DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
idx, relocs_chunk->length_dw);
return -EINVAL;
}
*cs_reloc = p->relocs;
(*cs_reloc)->lobj.gpu_offset = (u64)relocs_chunk->kdata[idx + 3] << 32;
(*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0];
return 0;
}
/**
* r600_cs_packet_next_is_pkt3_nop() - test if next packet is packet3 nop for reloc
* @parser: parser structure holding parsing context.
@ -2458,105 +2409,6 @@ int r600_cs_parse(struct radeon_cs_parser *p)
return 0;
}
static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p)
{
if (p->chunk_relocs_idx == -1) {
return 0;
}
p->relocs = malloc(sizeof(struct radeon_cs_reloc),
DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
if (p->relocs == NULL) {
return -ENOMEM;
}
return 0;
}
/**
* cs_parser_fini() - clean parser states
* @parser: parser structure holding parsing context.
* @error: error number
*
* If error is set than unvalidate buffer, otherwise just free memory
* used by parsing context.
**/
static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error)
{
unsigned i;
free(parser->relocs, DRM_MEM_DRIVER);
for (i = 0; i < parser->nchunks; i++) {
free(parser->chunks[i].kdata, DRM_MEM_DRIVER);
if (parser->rdev && (parser->rdev->flags & RADEON_IS_AGP)) {
free(parser->chunks[i].kpage[0], DRM_MEM_DRIVER);
free(parser->chunks[i].kpage[1], DRM_MEM_DRIVER);
}
}
free(parser->chunks, DRM_MEM_DRIVER);
free(parser->chunks_array, DRM_MEM_DRIVER);
free(parser->track, DRM_MEM_DRIVER);
}
int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp,
unsigned family, u32 *ib, int *l)
{
struct radeon_cs_parser parser;
struct radeon_cs_chunk *ib_chunk;
struct r600_cs_track *track;
int r;
/* initialize tracker */
track = malloc(sizeof(*track), DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
if (track == NULL)
return -ENOMEM;
r600_cs_track_init(track);
r600_cs_legacy_get_tiling_conf(dev, &track->npipes, &track->nbanks, &track->group_size);
/* initialize parser */
memset(&parser, 0, sizeof(struct radeon_cs_parser));
parser.filp = filp;
parser.dev = dev->dev;
parser.rdev = NULL;
parser.family = family;
parser.track = track;
parser.ib.ptr = ib;
r = radeon_cs_parser_init(&parser, data);
if (r) {
DRM_ERROR("Failed to initialize parser !\n");
r600_cs_parser_fini(&parser, r);
return r;
}
r = r600_cs_parser_relocs_legacy(&parser);
if (r) {
DRM_ERROR("Failed to parse relocation !\n");
r600_cs_parser_fini(&parser, r);
return r;
}
/* Copy the packet into the IB, the parser will read from the
* input memory (cached) and write to the IB (which can be
* uncached). */
ib_chunk = &parser.chunks[parser.chunk_ib_idx];
parser.ib.length_dw = ib_chunk->length_dw;
*l = parser.ib.length_dw;
r = r600_cs_parse(&parser);
if (r) {
DRM_ERROR("Invalid command stream !\n");
r600_cs_parser_fini(&parser, r);
return r;
}
r = radeon_cs_finish_pages(&parser);
if (r) {
DRM_ERROR("Invalid command stream !\n");
r600_cs_parser_fini(&parser, r);
return r;
}
r600_cs_parser_fini(&parser, r);
return r;
}
void r600_cs_legacy_init(void)
{
r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_nomm;
}
/*
* DMA
*/

File diff suppressed because it is too large Load diff

View file

@ -1,329 +0,0 @@
/**
* \file radeon_ioc32.c
*
* 32-bit ioctl compatibility routines for the Radeon DRM.
*
* \author Paul Mackerras <paulus@samba.org>
*
* Copyright (C) Paul Mackerras 2005
* All Rights Reserved.
*
* 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 (including the next
* paragraph) 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 AUTHOR 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifdef COMPAT_FREEBSD32
#include <dev/drm2/drmP.h>
#include <dev/drm2/drm.h>
#include <dev/drm2/radeon/radeon_drm.h>
#include "radeon_drv.h"
typedef struct drm_radeon_init32 {
int func;
u32 sarea_priv_offset;
int is_pci;
int cp_mode;
int gart_size;
int ring_size;
int usec_timeout;
unsigned int fb_bpp;
unsigned int front_offset, front_pitch;
unsigned int back_offset, back_pitch;
unsigned int depth_bpp;
unsigned int depth_offset, depth_pitch;
u32 fb_offset;
u32 mmio_offset;
u32 ring_offset;
u32 ring_rptr_offset;
u32 buffers_offset;
u32 gart_textures_offset;
} drm_radeon_init32_t;
static int compat_radeon_cp_init(struct drm_device *dev, void *arg,
struct drm_file *file_priv)
{
drm_radeon_init32_t *init32;
drm_radeon_init_t __user init;
init32 = arg;
init.func = init32->func;
init.sarea_priv_offset = (unsigned long)init32->sarea_priv_offset;
init.is_pci = init32->is_pci;
init.cp_mode = init32->cp_mode;
init.gart_size = init32->gart_size;
init.ring_size = init32->ring_size;
init.usec_timeout = init32->usec_timeout;
init.fb_bpp = init32->fb_bpp;
init.front_offset = init32->front_offset;
init.front_pitch = init32->front_pitch;
init.back_offset = init32->back_offset;
init.back_pitch = init32->back_pitch;
init.depth_bpp = init32->depth_bpp;
init.depth_offset = init32->depth_offset;
init.depth_pitch = init32->depth_pitch;
init.fb_offset = (unsigned long)init32->fb_offset;
init.mmio_offset = (unsigned long)init32->mmio_offset;
init.ring_offset = (unsigned long)init32->ring_offset;
init.ring_rptr_offset = (unsigned long)init32->ring_rptr_offset;
init.buffers_offset = (unsigned long)init32->buffers_offset;
init.gart_textures_offset = (unsigned long)init32->gart_textures_offset;
return radeon_cp_init(dev, &init, file_priv);
}
typedef struct drm_radeon_clear32 {
unsigned int flags;
unsigned int clear_color;
unsigned int clear_depth;
unsigned int color_mask;
unsigned int depth_mask; /* misnamed field: should be stencil */
u32 depth_boxes;
} drm_radeon_clear32_t;
static int compat_radeon_cp_clear(struct drm_device *dev, void *arg,
struct drm_file *file_priv)
{
drm_radeon_clear32_t *clr32;
drm_radeon_clear_t __user clr;
clr32 = arg;
clr.flags = clr32->flags;
clr.clear_color = clr32->clear_color;
clr.clear_depth = clr32->clear_depth;
clr.color_mask = clr32->color_mask;
clr.depth_mask = clr32->depth_mask;
clr.depth_boxes = (drm_radeon_clear_rect_t *)(unsigned long)clr32->depth_boxes;
return radeon_ioctls[DRM_IOCTL_RADEON_CLEAR].func(dev, &clr, file_priv);
}
typedef struct drm_radeon_stipple32 {
u32 mask;
} drm_radeon_stipple32_t;
static int compat_radeon_cp_stipple(struct drm_device *dev, void *arg,
struct drm_file *file_priv)
{
drm_radeon_stipple32_t __user *argp = (void __user *)arg;
drm_radeon_stipple_t __user request;
request.mask = (unsigned int *)(unsigned long)argp->mask;
return radeon_ioctls[DRM_IOCTL_RADEON_STIPPLE].func(dev, &request, file_priv);
}
typedef struct drm_radeon_tex_image32 {
unsigned int x, y; /* Blit coordinates */
unsigned int width, height;
u32 data;
} drm_radeon_tex_image32_t;
typedef struct drm_radeon_texture32 {
unsigned int offset;
int pitch;
int format;
int width; /* Texture image coordinates */
int height;
u32 image;
} drm_radeon_texture32_t;
static int compat_radeon_cp_texture(struct drm_device *dev, void *arg,
struct drm_file *file_priv)
{
drm_radeon_texture32_t *req32;
drm_radeon_texture_t __user request;
drm_radeon_tex_image32_t *img32;
drm_radeon_tex_image_t __user image;
req32 = arg;
if (req32->image == 0)
return -EINVAL;
img32 = (drm_radeon_tex_image32_t *)(unsigned long)req32->image;
request.offset = req32->offset;
request.pitch = req32->pitch;
request.format = req32->format;
request.width = req32->width;
request.height = req32->height;
request.image = &image;
image.x = img32->x;
image.y = img32->y;
image.width = img32->width;
image.height = img32->height;
image.data = (void *)(unsigned long)img32->data;
return radeon_ioctls[DRM_IOCTL_RADEON_TEXTURE].func(dev, &request, file_priv);
}
typedef struct drm_radeon_vertex2_32 {
int idx; /* Index of vertex buffer */
int discard; /* Client finished with buffer? */
int nr_states;
u32 state;
int nr_prims;
u32 prim;
} drm_radeon_vertex2_32_t;
static int compat_radeon_cp_vertex2(struct drm_device *dev, void *arg,
struct drm_file *file_priv)
{
drm_radeon_vertex2_32_t *req32;
drm_radeon_vertex2_t __user request;
req32 = arg;
request.idx = req32->idx;
request.discard = req32->discard;
request.nr_states = req32->nr_states;
request.state = (drm_radeon_state_t *)(unsigned long)req32->state;
request.nr_prims = req32->nr_prims;
request.prim = (drm_radeon_prim_t *)(unsigned long)req32->prim;
return radeon_ioctls[DRM_IOCTL_RADEON_VERTEX2].func(dev, &request, file_priv);
}
typedef struct drm_radeon_cmd_buffer32 {
int bufsz;
u32 buf;
int nbox;
u32 boxes;
} drm_radeon_cmd_buffer32_t;
static int compat_radeon_cp_cmdbuf(struct drm_device *dev, void *arg,
struct drm_file *file_priv)
{
drm_radeon_cmd_buffer32_t *req32;
drm_radeon_cmd_buffer_t __user request;
req32 = arg;
request.bufsz = req32->bufsz;
request.buf = (char *)(unsigned long)req32->buf;
request.nbox = req32->nbox;
request.boxes = (struct drm_clip_rect *)(unsigned long)req32->boxes;
return radeon_ioctls[DRM_IOCTL_RADEON_CMDBUF].func(dev, &request, file_priv);
}
typedef struct drm_radeon_getparam32 {
int param;
u32 value;
} drm_radeon_getparam32_t;
static int compat_radeon_cp_getparam(struct drm_device *dev, void *arg,
struct drm_file *file_priv)
{
drm_radeon_getparam32_t *req32;
drm_radeon_getparam_t __user request;
req32 = arg;
request.param = req32->param;
request.value = (void *)(unsigned long)req32->value;
return radeon_ioctls[DRM_IOCTL_RADEON_GETPARAM].func(dev, &request, file_priv);
}
typedef struct drm_radeon_mem_alloc32 {
int region;
int alignment;
int size;
u32 region_offset; /* offset from start of fb or GART */
} drm_radeon_mem_alloc32_t;
static int compat_radeon_mem_alloc(struct drm_device *dev, void *arg,
struct drm_file *file_priv)
{
drm_radeon_mem_alloc32_t *req32;
drm_radeon_mem_alloc_t __user request;
req32 = arg;
request.region = req32->region;
request.alignment = req32->alignment;
request.size = req32->size;
request.region_offset = (int *)(unsigned long)req32->region_offset;
return radeon_mem_alloc(dev, &request, file_priv);
}
typedef struct drm_radeon_irq_emit32 {
u32 irq_seq;
} drm_radeon_irq_emit32_t;
static int compat_radeon_irq_emit(struct drm_device *dev, void *arg,
struct drm_file *file_priv)
{
drm_radeon_irq_emit32_t *req32;
drm_radeon_irq_emit_t __user request;
req32 = arg;
request.irq_seq = (int *)(unsigned long)req32->irq_seq;
return radeon_irq_emit(dev, &request, file_priv);
}
/* The two 64-bit arches where alignof(u64)==4 in 32-bit code */
#if defined (CONFIG_X86_64) || defined(CONFIG_IA64)
typedef struct drm_radeon_setparam32 {
int param;
u64 value;
} __attribute__((packed)) drm_radeon_setparam32_t;
static int compat_radeon_cp_setparam(struct drm_device *dev, void *arg,
struct drm_file *file_priv)
{
drm_radeon_setparam32_t *req32;
drm_radeon_setparam_t __user request;
req32 = arg;
request.param = req32->param;
request.value = req32->value;
return radeon_ioctls[DRM_IOCTL_RADEON_SETPARAM].func(dev, &request, file_priv);
}
#else
#define compat_radeon_cp_setparam NULL
#endif /* X86_64 || IA64 */
struct drm_ioctl_desc radeon_compat_ioctls[] = {
DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, compat_radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_RADEON_CLEAR, compat_radeon_cp_clear, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, compat_radeon_cp_stipple, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, compat_radeon_cp_texture, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, compat_radeon_cp_vertex2, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, compat_radeon_cp_cmdbuf, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, compat_radeon_cp_getparam, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, compat_radeon_cp_setparam, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_ALLOC, compat_radeon_mem_alloc, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, compat_radeon_irq_emit, DRM_AUTH)
};
int radeon_num_compat_ioctls = ARRAY_SIZE(radeon_compat_ioctls);
#endif

View file

@ -221,41 +221,6 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
return IRQ_HANDLED;
}
static int radeon_emit_irq(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
unsigned int ret;
RING_LOCALS;
atomic_inc(&dev_priv->swi_emitted);
ret = atomic_read(&dev_priv->swi_emitted);
BEGIN_RING(4);
OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
ADVANCE_RING();
COMMIT_RING();
return ret;
}
static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
int ret = 0;
if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr)
return 0;
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ,
RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr);
return ret;
}
u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
@ -283,52 +248,6 @@ u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
}
}
/* Needs the lock as it touches the ring.
*/
int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_irq_emit_t *emit = data;
int result;
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
return -EINVAL;
LOCK_TEST_WITH_RETURN(dev, file_priv);
result = radeon_emit_irq(dev);
if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
DRM_ERROR("copy_to_user\n");
return -EFAULT;
}
return 0;
}
/* Doesn't need the hardware lock.
*/
int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_irq_wait_t *irqwait = data;
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
return -EINVAL;
return radeon_wait_irq(dev, irqwait->irq_seq);
}
/* drm_dma.h hooks
*/
void radeon_driver_irq_preinstall(struct drm_device * dev)

File diff suppressed because it is too large Load diff

View file

@ -25,7 +25,6 @@ SRCS += \
radeon_clocks.c \
radeon_combios.c \
radeon_connectors.c \
radeon_cp.c \
radeon_cs.c \
radeon_cursor.c \
radeon_device.c \
@ -50,7 +49,6 @@ SRCS += \
radeon_ring.c \
radeon_sa.c \
radeon_semaphore.c \
radeon_state.c \
radeon_test.c \
radeon_ttm.c \
atom.c \
@ -61,7 +59,6 @@ SRCS += \
r100.c \
r200.c \
r300.c \
r300_cmdbuf.c \
r420.c \
rs400.c \
rs600.c \
@ -70,10 +67,8 @@ SRCS += \
r520.c \
r600.c \
r600_audio.c \
r600_blit.c \
r600_blit_kms.c \
r600_blit_shaders.c \
r600_cp.c \
r600_cs.c \
r600_hdmi.c \
rv770.c \
@ -92,10 +87,6 @@ radeon_acpi= radeon_acpi.c
#radeon_atpx_handler= radeon_atpx_handler.c
.endif
.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_ARCH} == "powerpc64"
radeon_ioc32= radeon_ioc32.c
.endif
#radeon_prime.c
#--radeon_trace_points.c
@ -115,7 +106,5 @@ SRCS += \
CFLAGS+= -I${SRCTOP}/sys/dev/drm2/radeon
CWARNFLAGS.radeon_cp.c= -Wno-unused-value
CWARNFLAGS.r600_cp.c= -Wno-unused-value
CWARNFLAGS+= ${CWARNFLAGS.${.IMPSRC:T}}
CWARNFLAGS+= ${NO_WUNUSED_BUT_SET_VARIABLE}