mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-05 07:48:02 +02:00
Merge branch 'modesetting-gem' of ssh://git.freedesktop.org/git/mesa/drm into modesetting-gem
This commit is contained in:
commit
ddfb12b32e
28 changed files with 754 additions and 303 deletions
|
|
@ -44,7 +44,7 @@ nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \
|
|||
radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o radeon_gem.o \
|
||||
radeon_buffer.o radeon_fence.o atom.o radeon_display.o radeon_atombios.o radeon_i2c.o radeon_connectors.o radeon_cs.o \
|
||||
atombios_crtc.o radeon_encoders.o radeon_fb.o radeon_combios.o radeon_legacy_crtc.o radeon_legacy_encoders.o \
|
||||
radeon_cursor.o radeon_pm.o
|
||||
radeon_cursor.o radeon_pm.o radeon_gem_proc.o
|
||||
sis-objs := sis_drv.o sis_mm.o
|
||||
ffb-objs := ffb_drv.o ffb_context.o
|
||||
savage-objs := savage_drv.o savage_bci.o savage_state.o
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#define ATI_PCIE_WRITE 0x4
|
||||
#define ATI_PCIE_READ 0x8
|
||||
|
||||
static __inline__ void gart_insert_page_into_table(struct drm_ati_pcigart_info *gart_info, dma_addr_t addr, u32 *pci_gart)
|
||||
static __inline__ void gart_insert_page_into_table(struct drm_ati_pcigart_info *gart_info, dma_addr_t addr, volatile u32 *pci_gart)
|
||||
{
|
||||
u32 page_base;
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ static __inline__ void gart_insert_page_into_table(struct drm_ati_pcigart_info *
|
|||
*pci_gart = cpu_to_le32(page_base);
|
||||
}
|
||||
|
||||
static __inline__ dma_addr_t gart_get_page_from_table(struct drm_ati_pcigart_info *gart_info, u32 *pci_gart)
|
||||
static __inline__ dma_addr_t gart_get_page_from_table(struct drm_ati_pcigart_info *gart_info, volatile u32 *pci_gart)
|
||||
{
|
||||
dma_addr_t retval;
|
||||
switch(gart_info->gart_reg_if) {
|
||||
|
|
@ -93,7 +93,7 @@ int drm_ati_alloc_pcigart_table(struct drm_device *dev,
|
|||
#ifdef CONFIG_X86
|
||||
/* IGPs only exist on x86 in any case */
|
||||
if (gart_info->gart_reg_if == DRM_ATI_GART_IGP)
|
||||
set_memory_uc(gart_info->table_handle->vaddr, gart_info->table_size >> PAGE_SHIFT);
|
||||
set_memory_uc((unsigned long)gart_info->table_handle->vaddr, gart_info->table_size >> PAGE_SHIFT);
|
||||
#endif
|
||||
|
||||
memset(gart_info->table_handle->vaddr, 0, gart_info->table_size);
|
||||
|
|
@ -107,7 +107,7 @@ static void drm_ati_free_pcigart_table(struct drm_device *dev,
|
|||
#ifdef CONFIG_X86
|
||||
/* IGPs only exist on x86 in any case */
|
||||
if (gart_info->gart_reg_if == DRM_ATI_GART_IGP)
|
||||
set_memory_wb(gart_info->table_handle->vaddr, gart_info->table_size >> PAGE_SHIFT);
|
||||
set_memory_wb((unsigned long)gart_info->table_handle->vaddr, gart_info->table_size >> PAGE_SHIFT);
|
||||
#endif
|
||||
drm_pci_free(dev, gart_info->table_handle);
|
||||
gart_info->table_handle = NULL;
|
||||
|
|
@ -260,7 +260,7 @@ static int ati_pcigart_bind_ttm(struct drm_ttm_backend *backend,
|
|||
|
||||
j = offset;
|
||||
while (j < (offset + atipci_be->num_pages)) {
|
||||
if (gart_get_page_from_table(info, pci_gart+j))
|
||||
if (gart_get_page_from_table(info, pci_gart + j))
|
||||
return -EBUSY;
|
||||
j++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ void atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y)
|
|||
|
||||
radeon_fb = to_radeon_framebuffer(crtc->fb);
|
||||
|
||||
obj = radeon_fb->base.mm_private;
|
||||
obj = radeon_fb->obj;
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
fb_location = obj_priv->bo->offset + dev_priv->fb_location;
|
||||
|
|
|
|||
|
|
@ -1544,7 +1544,6 @@ int drm_mapbufs(struct drm_device *dev, void *data,
|
|||
goto done;
|
||||
}
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
DRM_DEBUG("%x %d\n", token, map->size);
|
||||
virtual = do_mmap(file_priv->filp, 0, map->size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
|
|
|
|||
|
|
@ -240,7 +240,6 @@ struct drm_framebuffer {
|
|||
void *fbdev;
|
||||
u32 pseudo_palette[17];
|
||||
struct list_head filp_head;
|
||||
void *mm_private;
|
||||
};
|
||||
|
||||
struct drm_property_blob {
|
||||
|
|
|
|||
|
|
@ -771,15 +771,13 @@ int drm_helper_hotplug_stage_two(struct drm_device *dev)
|
|||
EXPORT_SYMBOL(drm_helper_hotplug_stage_two);
|
||||
|
||||
int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
|
||||
struct drm_mode_fb_cmd *mode_cmd,
|
||||
void *mm_private)
|
||||
struct drm_mode_fb_cmd *mode_cmd)
|
||||
{
|
||||
fb->width = mode_cmd->width;
|
||||
fb->height = mode_cmd->height;
|
||||
fb->pitch = mode_cmd->pitch;
|
||||
fb->bits_per_pixel = mode_cmd->bpp;
|
||||
fb->depth = mode_cmd->depth;
|
||||
fb->mm_private = mm_private;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,8 +75,7 @@ extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_m
|
|||
extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
|
||||
|
||||
extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
|
||||
struct drm_mode_fb_cmd *mode_cmd,
|
||||
void *mm_private);
|
||||
struct drm_mode_fb_cmd *mode_cmd);
|
||||
|
||||
static inline void drm_crtc_helper_add(struct drm_crtc *crtc, const struct drm_crtc_helper_funcs *funcs)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -170,10 +170,12 @@ void radeon_emit_copy_blit(struct drm_device * dev,
|
|||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
BEGIN_RING(4);
|
||||
BEGIN_RING(6);
|
||||
OUT_RING(CP_PACKET0(RADEON_RB2D_DSTCACHE_CTLSTAT, 0));
|
||||
OUT_RING(RADEON_RB2D_DC_FLUSH_ALL);
|
||||
RADEON_WAIT_UNTIL_2D_IDLE();
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
ADVANCE_RING();
|
||||
|
||||
COMMIT_RING();
|
||||
|
|
@ -252,7 +254,8 @@ void radeon_emit_solid_fill(struct drm_device * dev,
|
|||
RADEON_GMC_DST_CLIPPING |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
(format << 8) |
|
||||
RADEON_ROP3_S |
|
||||
RADEON_ROP3_P |
|
||||
RADEON_CLR_CMP_SRC_SOURCE |
|
||||
RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
|
||||
OUT_RING((pitch << 22) | (dst_offset >> 10)); // PITCH
|
||||
OUT_RING(0); // SC_TOP_LEFT // DST CLIPPING
|
||||
|
|
@ -265,10 +268,14 @@ void radeon_emit_solid_fill(struct drm_device * dev,
|
|||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
BEGIN_RING(4);
|
||||
BEGIN_RING(8);
|
||||
OUT_RING(CP_PACKET0(RADEON_RB2D_DSTCACHE_CTLSTAT, 0));
|
||||
OUT_RING(RADEON_RB2D_DC_FLUSH_ALL);
|
||||
RADEON_WAIT_UNTIL_2D_IDLE();
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
ADVANCE_RING();
|
||||
|
||||
COMMIT_RING();
|
||||
|
|
@ -350,7 +357,6 @@ static int radeon_move_vram(struct drm_buffer_object * bo,
|
|||
struct drm_bo_mem_reg tmp_mem;
|
||||
struct drm_bo_mem_reg *old_mem = &bo->mem;
|
||||
int ret;
|
||||
bool was_local = false;
|
||||
|
||||
/* old - LOCAL memory node bo->mem
|
||||
tmp - TT type memory node
|
||||
|
|
@ -398,7 +404,6 @@ int radeon_move(struct drm_buffer_object * bo,
|
|||
int evict, int no_wait, struct drm_bo_mem_reg *new_mem)
|
||||
{
|
||||
struct drm_device *dev = bo->dev;
|
||||
struct drm_bo_mem_reg *old_mem = &bo->mem;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
if (!dev_priv->cp_running)
|
||||
|
|
|
|||
|
|
@ -87,19 +87,23 @@ static int radeon_lvds_get_modes(struct drm_connector *connector)
|
|||
|
||||
if (radeon_connector->ddc_bus) {
|
||||
radeon_i2c_do_lock(radeon_connector, 1);
|
||||
edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
|
||||
edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
|
||||
radeon_i2c_do_lock(radeon_connector, 0);
|
||||
if (edid) {
|
||||
drm_mode_connector_update_edid_property(&radeon_connector->base, edid);
|
||||
ret = drm_add_edid_modes(&radeon_connector->base, edid);
|
||||
kfree(edid);
|
||||
if (ret == 0)
|
||||
goto native;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
native:
|
||||
encoder = radeon_best_single_encoder(connector);
|
||||
if (!encoder)
|
||||
return connector_status_disconnected;
|
||||
return 0;
|
||||
|
||||
/* we have no EDID modes */
|
||||
mode = radeon_fp_native_mode(encoder);
|
||||
if (mode) {
|
||||
|
|
@ -301,8 +305,11 @@ static struct connector_funcs {
|
|||
{ CONNECTOR_LVDS, &radeon_lvds_connector_funcs, &radeon_lvds_connector_helper_funcs, DRM_MODE_CONNECTOR_LVDS, "LVDS" },
|
||||
{ CONNECTOR_DVI_A, &radeon_vga_connector_funcs, &radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_DVIA, "DVI" },
|
||||
{ CONNECTOR_DVI_I, &radeon_dvi_connector_funcs, &radeon_dvi_connector_helper_funcs, DRM_MODE_CONNECTOR_DVII, "DVI" },
|
||||
|
||||
{ CONNECTOR_DVI_D, &radeon_dvi_connector_funcs, &radeon_dvi_connector_helper_funcs, DRM_MODE_CONNECTOR_DVID, "DVI" },
|
||||
{ CONNECTOR_HDMI_TYPE_A, &radeon_dvi_connector_funcs, &radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_HDMIA, "HDMI" },
|
||||
{ CONNECTOR_HDMI_TYPE_B, &radeon_dvi_connector_funcs, &radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_HDMIB, "HDMI" },
|
||||
#if 0
|
||||
{ CONNECTOR_HDMI_TYPE_A, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_DVI_D, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
|
||||
{ CONNECTOR_STV, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
|
|
@ -310,7 +317,6 @@ static struct connector_funcs {
|
|||
{ CONNECTOR_DIGITAL, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_SCART, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
|
||||
{ CONNECTOR_HDMI_TYPE_A, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_HDMI_TYPE_B, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_HDMI_TYPE_B, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_HDMI_TYPE_B, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
|
|
|
|||
|
|
@ -263,7 +263,9 @@ bool radeon_setup_enc_conn(struct drm_device *dev)
|
|||
|
||||
/* TMDS on DVI */
|
||||
if ((mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_I) ||
|
||||
(mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_D)) {
|
||||
(mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_D) ||
|
||||
(mode_info->bios_connector[i].connector_type == CONNECTOR_HDMI_TYPE_A) ||
|
||||
(mode_info->bios_connector[i].connector_type == CONNECTOR_HDMI_TYPE_B)) {
|
||||
if (radeon_is_avivo(dev_priv) || radeon_r4xx_atom)
|
||||
encoder = radeon_encoder_atom_tmds_add(dev, i, mode_info->bios_connector[i].tmds_type);
|
||||
else {
|
||||
|
|
@ -601,17 +603,22 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
|
|||
if (fb->fbdev)
|
||||
radeonfb_remove(dev, fb);
|
||||
|
||||
if (radeon_fb->obj) {
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_gem_object_unreference(radeon_fb->obj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
}
|
||||
drm_framebuffer_cleanup(fb);
|
||||
kfree(radeon_fb);
|
||||
}
|
||||
|
||||
static int radeon_user_framebuffer_create_handle(struct drm_framebuffer *fb,
|
||||
struct drm_file *file_priv,
|
||||
unsigned int *handle)
|
||||
struct drm_file *file_priv,
|
||||
unsigned int *handle)
|
||||
{
|
||||
struct drm_gem_object *object = fb->mm_private;
|
||||
struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
|
||||
|
||||
return drm_gem_handle_create(file_priv, object, handle);
|
||||
return drm_gem_handle_create(file_priv, radeon_fb->obj, handle);
|
||||
}
|
||||
|
||||
static const struct drm_framebuffer_funcs radeon_fb_funcs = {
|
||||
|
|
@ -622,7 +629,7 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = {
|
|||
struct drm_framebuffer *
|
||||
radeon_framebuffer_create(struct drm_device *dev,
|
||||
struct drm_mode_fb_cmd *mode_cmd,
|
||||
void *mm_private)
|
||||
struct drm_gem_object *obj)
|
||||
{
|
||||
struct radeon_framebuffer *radeon_fb;
|
||||
|
||||
|
|
@ -631,7 +638,10 @@ radeon_framebuffer_create(struct drm_device *dev,
|
|||
return NULL;
|
||||
|
||||
drm_framebuffer_init(dev, &radeon_fb->base, &radeon_fb_funcs);
|
||||
drm_helper_mode_fill_fb_struct(&radeon_fb->base, mode_cmd, mm_private);
|
||||
drm_helper_mode_fill_fb_struct(&radeon_fb->base, mode_cmd);
|
||||
|
||||
radeon_fb->obj = obj;
|
||||
|
||||
return &radeon_fb->base;
|
||||
}
|
||||
|
||||
|
|
@ -641,10 +651,11 @@ radeon_user_framebuffer_create(struct drm_device *dev,
|
|||
struct drm_mode_fb_cmd *mode_cmd)
|
||||
{
|
||||
struct radeon_framebuffer *radeon_fb;
|
||||
void *mm_private;
|
||||
struct drm_gem_object *obj;
|
||||
|
||||
mm_private = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
|
||||
return radeon_framebuffer_create(dev, mode_cmd, mm_private);
|
||||
obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
|
||||
|
||||
return radeon_framebuffer_create(dev, mode_cmd, obj);
|
||||
}
|
||||
|
||||
static const struct drm_mode_config_funcs radeon_mode_funcs = {
|
||||
|
|
|
|||
|
|
@ -37,14 +37,14 @@
|
|||
#include "drm_pciids.h"
|
||||
|
||||
int radeon_no_wb;
|
||||
int radeon_dynclks = 1;
|
||||
int radeon_dynclks = -1;
|
||||
int radeon_r4xx_atom = 0;
|
||||
int radeon_agpmode = 0;
|
||||
|
||||
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n");
|
||||
module_param_named(no_wb, radeon_no_wb, int, 0444);
|
||||
|
||||
unsigned int radeon_modeset = 0;
|
||||
int radeon_modeset = 0;
|
||||
module_param_named(modeset, radeon_modeset, int, 0400);
|
||||
|
||||
MODULE_PARM_DESC(dynclks, "Disable/Enable dynamic clocks");
|
||||
|
|
@ -60,8 +60,12 @@ module_param_named(agpmode, radeon_agpmode, int, 0444);
|
|||
static int dri_library_name(struct drm_device * dev, char * buf)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
int family = dev_priv->flags & RADEON_FAMILY_MASK;
|
||||
int family;
|
||||
|
||||
if (!dev_priv)
|
||||
return 0;
|
||||
|
||||
family = dev_priv->flags & RADEON_FAMILY_MASK;
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
(family < CHIP_R200) ? "radeon" :
|
||||
((family < CHIP_R300) ? "r200" :
|
||||
|
|
@ -122,6 +126,8 @@ static struct drm_driver driver = {
|
|||
.dma_ioctl = radeon_cp_buffers,
|
||||
.master_create = radeon_master_create,
|
||||
.master_destroy = radeon_master_destroy,
|
||||
.proc_init = radeon_gem_proc_init,
|
||||
.proc_cleanup = radeon_gem_proc_cleanup,
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
|
|
|
|||
|
|
@ -1148,7 +1148,8 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
|
|||
unregister_framebuffer(info);
|
||||
drm_bo_kunmap(&radeon_fb->kmap_obj);
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_gem_object_unreference(fb->mm_private);
|
||||
drm_gem_object_unreference(radeon_fb->obj);
|
||||
radeon_fb->obj = NULL;
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
framebuffer_release(info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ int radeon_fence_emit_sequence(struct drm_device *dev, uint32_t class,
|
|||
uint32_t *native_type)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = (struct drm_radeon_private *) dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
if (!dev_priv)
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -126,7 +126,6 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
|
|||
struct drm_radeon_gem_object *obj_priv;
|
||||
struct drm_gem_object *obj;
|
||||
int ret = 0;
|
||||
uint32_t flags;
|
||||
int handle;
|
||||
|
||||
/* create a gem object to contain this object in */
|
||||
|
|
@ -157,8 +156,6 @@ fail:
|
|||
|
||||
int radeon_gem_set_domain(struct drm_gem_object *obj, uint32_t read_domains, uint32_t write_domain, uint32_t *flags_p, bool unfenced)
|
||||
{
|
||||
struct drm_device *dev = obj->dev;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
uint32_t flags = 0;
|
||||
int ret;
|
||||
|
|
@ -419,24 +416,14 @@ int radeon_gem_busy(struct drm_device *dev, void *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int radeon_gem_execbuffer(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
return -ENOSYS;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data,
|
||||
int radeon_gem_wait_rendering(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_radeon_gem_indirect *args = data;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_gem_wait_rendering *args = data;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
uint32_t start, end;
|
||||
int ret;
|
||||
RING_LOCALS;
|
||||
|
||||
|
||||
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
|
||||
if (obj == NULL)
|
||||
|
|
@ -444,64 +431,18 @@ int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data,
|
|||
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
DRM_DEBUG("got here %p %d\n", obj, args->used);
|
||||
//RING_SPACE_TEST_WITH_RETURN(dev_priv);
|
||||
//VB_AGE_TEST_WITH_RETURN(dev_priv);
|
||||
|
||||
ret = drm_bo_do_validate(obj_priv->bo, 0, DRM_BO_FLAG_NO_EVICT,
|
||||
0 , 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Wait for the 3D stream to idle before the indirect buffer
|
||||
* containing 2D acceleration commands is processed.
|
||||
*/
|
||||
BEGIN_RING(2);
|
||||
|
||||
RADEON_WAIT_UNTIL_3D_IDLE();
|
||||
|
||||
ADVANCE_RING();
|
||||
mutex_lock(&obj_priv->bo->mutex);
|
||||
ret = drm_bo_wait(obj_priv->bo, 0, 1, 1, 0);
|
||||
mutex_unlock(&obj_priv->bo->mutex);
|
||||
|
||||
start = 0;
|
||||
end = args->used;
|
||||
|
||||
if (start != end) {
|
||||
int offset = (dev_priv->gart_vm_start +
|
||||
+ obj_priv->bo->offset + start);
|
||||
int dwords = (end - start + 3) / sizeof(u32);
|
||||
|
||||
/* Fire off the indirect buffer */
|
||||
BEGIN_RING(3);
|
||||
|
||||
OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
|
||||
OUT_RING(offset);
|
||||
OUT_RING(dwords);
|
||||
|
||||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
COMMIT_RING();
|
||||
|
||||
/* we need to fence the buffer */
|
||||
ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &obj_priv->fence);
|
||||
if (ret) {
|
||||
|
||||
drm_putback_buffer_objects(dev);
|
||||
ret = 0;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* dereference he fence object */
|
||||
drm_fence_usage_deref_unlocked(&obj_priv->fence);
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_gem_object_unreference(obj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
ret = 0;
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Depending on card genertation, chipset bugs, etc... the amount of vram
|
||||
* accessible to the CPU can vary. This function is our best shot at figuring
|
||||
|
|
@ -525,6 +466,7 @@ static uint32_t radeon_get_accessible_vram(struct drm_device *dev)
|
|||
dev_priv->chip_family == CHIP_RV350 ||
|
||||
dev_priv->chip_family == CHIP_RV380 ||
|
||||
dev_priv->chip_family == CHIP_R420 ||
|
||||
dev_priv->chip_family == CHIP_R423 ||
|
||||
dev_priv->chip_family == CHIP_RV410 ||
|
||||
radeon_is_avivo(dev_priv)) {
|
||||
uint32_t temp = RADEON_READ(RADEON_HOST_PATH_CNTL);
|
||||
|
|
@ -585,6 +527,9 @@ void radeon_vram_setup(struct drm_device *dev)
|
|||
if (accessible > bar_size)
|
||||
accessible = bar_size;
|
||||
|
||||
if (accessible > vram)
|
||||
accessible = vram;
|
||||
|
||||
DRM_INFO("Detected VRAM RAM=%dK, accessible=%uK, BAR=%uK\n",
|
||||
vram, accessible, bar_size);
|
||||
|
||||
|
|
@ -612,7 +557,7 @@ static int radeon_gart_init(struct drm_device *dev)
|
|||
base = dev->agp->base;
|
||||
if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location &&
|
||||
base < (dev_priv->fb_location + dev_priv->fb_size - 1)) {
|
||||
DRM_INFO("Can't use agp base @0x%08xlx, won't fit\n",
|
||||
DRM_INFO("Can't use agp base @0x%08lx, won't fit\n",
|
||||
dev->agp->base);
|
||||
base = 0;
|
||||
}
|
||||
|
|
@ -728,7 +673,7 @@ int radeon_alloc_gart_objects(struct drm_device *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG("Ring ptr %p mapped at %d %p, read ptr %p maped at %d %p\n",
|
||||
DRM_DEBUG("Ring ptr %p mapped at %ld %p, read ptr %p maped at %ld %p\n",
|
||||
dev_priv->mm.ring.bo, dev_priv->mm.ring.bo->offset, dev_priv->mm.ring.kmap.virtual,
|
||||
dev_priv->mm.ring_read.bo, dev_priv->mm.ring_read.bo->offset, dev_priv->mm.ring_read.kmap.virtual);
|
||||
|
||||
|
|
@ -825,7 +770,6 @@ static void radeon_wait_for_vsync(struct drm_device *dev)
|
|||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t crtc_gen_cntl;
|
||||
int ret;
|
||||
|
||||
crtc_gen_cntl = RADEON_READ(RADEON_CRTC_GEN_CNTL);
|
||||
if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) ||
|
||||
|
|
@ -844,7 +788,6 @@ static void radeon_wait_for_vsync2(struct drm_device *dev)
|
|||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t crtc2_gen_cntl;
|
||||
struct timeval timeout;
|
||||
|
||||
crtc2_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL);
|
||||
if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) ||
|
||||
|
|
@ -913,7 +856,6 @@ void radeon_init_memory_map(struct drm_device *dev)
|
|||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
u32 mem_size, aper_size;
|
||||
u32 tmp;
|
||||
|
||||
dev_priv->mc_fb_location = radeon_read_fb_location(dev_priv);
|
||||
radeon_read_agp_location(dev_priv, &dev_priv->mc_agp_loc_lo, &dev_priv->mc_agp_loc_hi);
|
||||
|
|
@ -960,6 +902,7 @@ void radeon_init_memory_map(struct drm_device *dev)
|
|||
dev_priv->chip_family == CHIP_RV350 ||
|
||||
dev_priv->chip_family == CHIP_RV380 ||
|
||||
dev_priv->chip_family == CHIP_R420 ||
|
||||
dev_priv->chip_family == CHIP_R423 ||
|
||||
dev_priv->chip_family == CHIP_RV410)
|
||||
aper0_base &= ~(mem_size - 1);
|
||||
|
||||
|
|
@ -1004,6 +947,10 @@ void radeon_init_memory_map(struct drm_device *dev)
|
|||
- dev_priv->fb_location;
|
||||
}
|
||||
|
||||
/* add an MTRR for the VRAM */
|
||||
dev_priv->aper_size = aper_size;
|
||||
dev_priv->vram_mtrr = mtrr_add(dev_priv->fb_aper_offset, dev_priv->aper_size, MTRR_TYPE_WRCOMB, 1);
|
||||
|
||||
}
|
||||
|
||||
/* init memory manager - start with all of VRAM and a 32MB GART aperture for now */
|
||||
|
|
@ -1094,6 +1041,8 @@ void radeon_gem_mm_fini(struct drm_device *dev)
|
|||
DRM_DEBUG("delaying takedown of VRAM memory\n");
|
||||
}
|
||||
|
||||
if (dev_priv->vram_mtrr)
|
||||
mtrr_del(dev_priv->vram_mtrr, dev_priv->fb_aper_offset, dev_priv->aper_size);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
drm_bo_driver_finish(dev);
|
||||
|
|
@ -1143,11 +1092,11 @@ int radeon_gem_object_unpin(struct drm_gem_object *obj)
|
|||
|
||||
#define RADEON_NUM_IB (RADEON_IB_MEMORY / RADEON_IB_SIZE)
|
||||
|
||||
int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords, uint32_t *card_offset)
|
||||
int radeon_gem_ib_get(struct drm_radeon_cs_parser *parser)
|
||||
{
|
||||
int i, index = -1;
|
||||
int ret;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_private_t *dev_priv = parser->dev->dev_private;
|
||||
|
||||
for (i = 0; i < RADEON_NUM_IB; i++) {
|
||||
if (!(dev_priv->ib_alloc_bitmap & (1 << i))){
|
||||
|
|
@ -1173,12 +1122,12 @@ int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords, uint32
|
|||
}
|
||||
|
||||
if (index == -1) {
|
||||
DRM_ERROR("Major case fail to allocate IB from freelist %x\n", dev_priv->ib_alloc_bitmap);
|
||||
DRM_ERROR("Major case fail to allocate IB from freelist %llx\n", dev_priv->ib_alloc_bitmap);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
if (dwords > RADEON_IB_SIZE / sizeof(uint32_t))
|
||||
if (parser->chunks[parser->ib_index].length_dw > RADEON_IB_SIZE / sizeof(uint32_t))
|
||||
return -EINVAL;
|
||||
|
||||
ret = drm_bo_do_validate(dev_priv->ib_objs[index]->bo, 0,
|
||||
|
|
@ -1189,26 +1138,26 @@ int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords, uint32
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
*card_offset = dev_priv->gart_vm_start + dev_priv->ib_objs[index]->bo->offset;
|
||||
*ib = dev_priv->ib_objs[index]->kmap.virtual;
|
||||
parser->ib = dev_priv->ib_objs[index]->kmap.virtual;
|
||||
parser->card_offset = dev_priv->gart_vm_start + dev_priv->ib_objs[index]->bo->offset;
|
||||
dev_priv->ib_alloc_bitmap |= (1 << i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void radeon_gem_ib_free(struct drm_device *dev, void *ib, uint32_t dwords)
|
||||
static void radeon_gem_ib_free(struct drm_radeon_cs_parser *parser)
|
||||
{
|
||||
struct drm_device *dev = parser->dev;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_fence_object *fence;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RADEON_NUM_IB; i++) {
|
||||
|
||||
if (dev_priv->ib_objs[i]->kmap.virtual == ib) {
|
||||
if (dev_priv->ib_objs[i]->kmap.virtual == parser->ib) {
|
||||
/* emit a fence object */
|
||||
ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence);
|
||||
dev_priv->irq_emitted = 0;
|
||||
if (ret) {
|
||||
|
||||
drm_putback_buffer_objects(dev);
|
||||
}
|
||||
/* dereference the fence object */
|
||||
|
|
@ -1238,21 +1187,58 @@ static int radeon_gem_ib_destroy(struct drm_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_gem_relocate(struct drm_device *dev, struct drm_file *file_priv,
|
||||
uint32_t *reloc, uint32_t *offset)
|
||||
static int radeon_gem_find_reloc(struct drm_radeon_cs_parser *parser,
|
||||
uint32_t offset, uint32_t *handle,
|
||||
uint32_t *read_domains, uint32_t *write_domain)
|
||||
{
|
||||
struct drm_device *dev = parser->dev;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_kernel_chunk *reloc_chunk = &parser->chunks[parser->reloc_index];
|
||||
|
||||
if (!reloc_chunk->kdata)
|
||||
return -EINVAL;
|
||||
|
||||
if (offset > reloc_chunk->length_dw){
|
||||
DRM_ERROR("Offset larger than chunk %d %d\n", offset, reloc_chunk->length_dw);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*handle = reloc_chunk->kdata[offset];
|
||||
*read_domains = reloc_chunk->kdata[offset + 1];
|
||||
*write_domain = reloc_chunk->kdata[offset + 2];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_gem_relocate(struct drm_radeon_cs_parser *parser,
|
||||
uint32_t *reloc, uint32_t *offset)
|
||||
{
|
||||
struct drm_device *dev = parser->dev;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
/* relocate the handle */
|
||||
uint32_t read_domains = reloc[2];
|
||||
uint32_t write_domain = reloc[3];
|
||||
uint32_t read_domains, write_domain;
|
||||
struct drm_gem_object *obj;
|
||||
int flags = 0;
|
||||
int ret;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
|
||||
obj = drm_gem_object_lookup(dev, file_priv, reloc[1]);
|
||||
if (!obj)
|
||||
return -EINVAL;
|
||||
if (parser->reloc_index == -1) {
|
||||
obj = drm_gem_object_lookup(dev, parser->file_priv, reloc[1]);
|
||||
if (!obj)
|
||||
return -EINVAL;
|
||||
read_domains = reloc[2];
|
||||
write_domain = reloc[3];
|
||||
} else {
|
||||
uint32_t handle;
|
||||
|
||||
/* have to lookup handle in other chunk */
|
||||
ret = radeon_gem_find_reloc(parser, reloc[1], &handle, &read_domains, &write_domain);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
obj = drm_gem_object_lookup(dev, parser->file_priv, handle);
|
||||
if (!obj)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
obj_priv = obj->driver_private;
|
||||
radeon_gem_set_domain(obj, read_domains, write_domain, &flags, false);
|
||||
|
|
@ -1522,7 +1508,7 @@ static int radeon_gem_dma_bufs_init(struct drm_device *dev)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = drm_buffer_object_create(dev, size, drm_bo_type_device,
|
||||
ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel,
|
||||
DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_NO_EVICT |
|
||||
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MAPPABLE, 0,
|
||||
0, 0, &dev_priv->mm.dma_bufs.bo);
|
||||
|
|
@ -1540,7 +1526,7 @@ static int radeon_gem_dma_bufs_init(struct drm_device *dev)
|
|||
DRM_DEBUG("\n");
|
||||
radeon_gem_addbufs(dev);
|
||||
|
||||
DRM_DEBUG("%x %d\n", dev_priv->mm.dma_bufs.bo->map_list.hash.key, size);
|
||||
DRM_DEBUG("%lx %d\n", dev_priv->mm.dma_bufs.bo->map_list.hash.key, size);
|
||||
dev->agp_buffer_token = dev_priv->mm.dma_bufs.bo->map_list.hash.key << PAGE_SHIFT;
|
||||
dev_priv->mm.fake_agp_map.handle = dev_priv->mm.dma_bufs.kmap.virtual;
|
||||
dev_priv->mm.fake_agp_map.size = size;
|
||||
|
|
|
|||
146
linux-core/radeon_gem_proc.c
Normal file
146
linux-core/radeon_gem_proc.c
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright © 2008 Intel Corporation
|
||||
*
|
||||
* 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 AUTHORS OR COPYRIGHT HOLDERS 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:
|
||||
* Eric Anholt <eric@anholt.net>
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
|
||||
static int radeon_ring_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data)
|
||||
{
|
||||
struct drm_minor *minor = (struct drm_minor *) data;
|
||||
struct drm_device *dev = minor->dev;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
int len = 0;
|
||||
|
||||
if (offset > DRM_PROC_LIMIT) {
|
||||
*eof = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*start = &buf[offset];
|
||||
*eof = 0;
|
||||
DRM_PROC_PRINT("RADEON_CP_RB_WPTR %08x\n",
|
||||
RADEON_READ(RADEON_CP_RB_WPTR));
|
||||
|
||||
DRM_PROC_PRINT("RADEON_CP_RB_RPTR %08x\n",
|
||||
RADEON_READ(RADEON_CP_RB_RPTR));
|
||||
|
||||
|
||||
if (len > request + offset)
|
||||
return request;
|
||||
*eof = 1;
|
||||
return len - offset;
|
||||
}
|
||||
|
||||
static int radeon_interrupt_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data)
|
||||
{
|
||||
struct drm_minor *minor = (struct drm_minor *) data;
|
||||
struct drm_device *dev = minor->dev;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
int len = 0;
|
||||
|
||||
if (offset > DRM_PROC_LIMIT) {
|
||||
*eof = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*start = &buf[offset];
|
||||
*eof = 0;
|
||||
DRM_PROC_PRINT("Interrupt enable: %08x\n",
|
||||
RADEON_READ(RADEON_GEN_INT_CNTL));
|
||||
|
||||
if (dev_priv->chip_family >= CHIP_RS690) {
|
||||
DRM_PROC_PRINT("DxMODE_INT_MASK: %08x\n",
|
||||
RADEON_READ(R500_DxMODE_INT_MASK));
|
||||
}
|
||||
DRM_PROC_PRINT("Interrupts received: %d\n",
|
||||
atomic_read(&dev_priv->irq_received));
|
||||
DRM_PROC_PRINT("Current sequence: %d %d\n",
|
||||
READ_BREADCRUMB(dev_priv), RADEON_READ(RADEON_SCRATCH_REG3));
|
||||
DRM_PROC_PRINT("Counter sequence: %d\n",
|
||||
dev_priv->counter);
|
||||
if (dev_priv->chip_family >= CHIP_R300)
|
||||
DRM_PROC_PRINT("CS: %d\n",
|
||||
GET_SCRATCH(6));
|
||||
|
||||
|
||||
if (len > request + offset)
|
||||
return request;
|
||||
*eof = 1;
|
||||
return len - offset;
|
||||
}
|
||||
|
||||
static struct drm_proc_list {
|
||||
/** file name */
|
||||
const char *name;
|
||||
/** proc callback*/
|
||||
int (*f) (char *, char **, off_t, int, int *, void *);
|
||||
} radeon_gem_proc_list[] = {
|
||||
{"radeon_gem_interrupt", radeon_interrupt_info},
|
||||
{"radeon_gem_ring", radeon_ring_info},
|
||||
};
|
||||
|
||||
|
||||
#define RADEON_GEM_PROC_ENTRIES ARRAY_SIZE(radeon_gem_proc_list)
|
||||
|
||||
int radeon_gem_proc_init(struct drm_minor *minor)
|
||||
{
|
||||
struct proc_dir_entry *ent;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < RADEON_GEM_PROC_ENTRIES; i++) {
|
||||
ent = create_proc_entry(radeon_gem_proc_list[i].name,
|
||||
S_IFREG | S_IRUGO, minor->dev_root);
|
||||
if (!ent) {
|
||||
DRM_ERROR("Cannot create /proc/dri/.../%s\n",
|
||||
radeon_gem_proc_list[i].name);
|
||||
for (j = 0; j < i; j++)
|
||||
remove_proc_entry(radeon_gem_proc_list[i].name,
|
||||
minor->dev_root);
|
||||
return -1;
|
||||
}
|
||||
ent->read_proc = radeon_gem_proc_list[i].f;
|
||||
ent->data = minor;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_gem_proc_cleanup(struct drm_minor *minor)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!minor->dev_root)
|
||||
return;
|
||||
|
||||
for (i = 0; i < RADEON_GEM_PROC_ENTRIES; i++)
|
||||
remove_proc_entry(radeon_gem_proc_list[i].name, minor->dev_root);
|
||||
}
|
||||
|
|
@ -231,7 +231,7 @@ static bool radeon_set_crtc1_base(struct drm_crtc *crtc, int x, int y)
|
|||
|
||||
radeon_fb = to_radeon_framebuffer(crtc->fb);
|
||||
|
||||
obj = radeon_fb->base.mm_private;
|
||||
obj = radeon_fb->obj;
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
crtc_offset = obj_priv->bo->offset;
|
||||
|
|
@ -654,7 +654,7 @@ static bool radeon_set_crtc2_base(struct drm_crtc *crtc, int x, int y)
|
|||
|
||||
radeon_fb = to_radeon_framebuffer(crtc->fb);
|
||||
|
||||
obj = radeon_fb->base.mm_private;
|
||||
obj = radeon_fb->obj;
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
crtc2_offset = obj_priv->bo->offset;
|
||||
|
|
|
|||
|
|
@ -1070,6 +1070,7 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
|
|||
crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
|
||||
//tv_master_cntl |= RADEON_TV_ON;
|
||||
if (dev_priv->chip_family == CHIP_R420 ||
|
||||
dev_priv->chip_family == CHIP_R423 ||
|
||||
dev_priv->chip_family == CHIP_RV410)
|
||||
tv_dac_cntl &= ~(R420_TV_DAC_RDACPD |
|
||||
R420_TV_DAC_GDACPD |
|
||||
|
|
@ -1095,6 +1096,7 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
|
|||
crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
|
||||
//tv_master_cntl &= ~RADEON_TV_ON;
|
||||
if (dev_priv->chip_family == CHIP_R420 ||
|
||||
dev_priv->chip_family == CHIP_R423 ||
|
||||
dev_priv->chip_family == CHIP_RV410)
|
||||
tv_dac_cntl |= (R420_TV_DAC_RDACPD |
|
||||
R420_TV_DAC_GDACPD |
|
||||
|
|
@ -1158,6 +1160,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
|
|||
if (dev_priv->chip_family != CHIP_R200) {
|
||||
tv_dac_cntl = RADEON_READ(RADEON_TV_DAC_CNTL);
|
||||
if (dev_priv->chip_family == CHIP_R420 ||
|
||||
dev_priv->chip_family == CHIP_R423 ||
|
||||
dev_priv->chip_family == CHIP_RV410) {
|
||||
tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
|
||||
RADEON_TV_DAC_BGADJ_MASK |
|
||||
|
|
|
|||
|
|
@ -255,6 +255,7 @@ struct radeon_connector {
|
|||
struct radeon_framebuffer {
|
||||
struct drm_framebuffer base;
|
||||
struct drm_bo_kmap_obj kmap_obj;
|
||||
struct drm_gem_object *obj;
|
||||
};
|
||||
|
||||
extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
|
||||
|
|
@ -323,7 +324,7 @@ extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
|||
u16 blue, int regno);
|
||||
struct drm_framebuffer *radeon_framebuffer_create(struct drm_device *dev,
|
||||
struct drm_mode_fb_cmd *mode_cmd,
|
||||
void *mm_private);
|
||||
struct drm_gem_object *obj);
|
||||
|
||||
int radeonfb_probe(struct drm_device *dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -54,10 +54,10 @@ int radeon_suspend(struct drm_device *dev, pm_message_t state)
|
|||
if (!radeon_fb)
|
||||
continue;
|
||||
|
||||
if (!radeon_fb->base.mm_private)
|
||||
if (!radeon_fb->obj)
|
||||
continue;
|
||||
|
||||
radeon_gem_object_unpin(radeon_fb->base.mm_private);
|
||||
radeon_gem_object_unpin(radeon_fb->obj);
|
||||
}
|
||||
|
||||
if (!(dev_priv->flags & RADEON_IS_IGP))
|
||||
|
|
@ -93,7 +93,6 @@ int radeon_resume(struct drm_device *dev)
|
|||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct drm_framebuffer *fb;
|
||||
int i;
|
||||
u32 tmp;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
return 0;
|
||||
|
|
@ -104,10 +103,7 @@ int radeon_resume(struct drm_device *dev)
|
|||
return -1;
|
||||
|
||||
/* Turn on bus mastering -todo fix properly */
|
||||
if (dev_priv->chip_family < CHIP_RV380) {
|
||||
tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
|
||||
RADEON_WRITE(RADEON_BUS_CNTL, tmp);
|
||||
}
|
||||
radeon_enable_bm(dev_priv);
|
||||
|
||||
DRM_ERROR("\n");
|
||||
/* on atom cards re init the whole card
|
||||
|
|
@ -179,10 +175,10 @@ int radeon_resume(struct drm_device *dev)
|
|||
if (!radeon_fb)
|
||||
continue;
|
||||
|
||||
if (!radeon_fb->base.mm_private)
|
||||
if (!radeon_fb->obj)
|
||||
continue;
|
||||
|
||||
radeon_gem_object_pin(radeon_fb->base.mm_private,
|
||||
radeon_gem_object_pin(radeon_fb->obj,
|
||||
PAGE_SIZE, RADEON_GEM_DOMAIN_VRAM);
|
||||
}
|
||||
/* blat the mode back in */
|
||||
|
|
|
|||
|
|
@ -356,6 +356,9 @@ void r300_init_reg_flags(struct drm_device *dev)
|
|||
|
||||
} else {
|
||||
|
||||
ADD_RANGE(RADEON_SE_COORD_FMT, 1);
|
||||
ADD_RANGE(RADEON_SE_CNTL_STATUS, 1);
|
||||
|
||||
ADD_RANGE(RADEON_PP_TXFILTER_0, 1);
|
||||
ADD_RANGE(RADEON_PP_TXFORMAT_0, 1);
|
||||
ADD_RANGE(RADEON_PP_TEX_SIZE_0, 1);
|
||||
|
|
|
|||
|
|
@ -1353,7 +1353,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
|
||||
#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */
|
||||
|
||||
#define R300_RB3D_AARESOLVE_CTL 0x4E88
|
||||
//#define R300_RB3D_AARESOLVE_CTL 0x4E88
|
||||
/* gap */
|
||||
|
||||
/* Guess by Vladimir.
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *
|
|||
*agp_lo = RADEON_READ(R600_MC_VM_AGP_BOT);
|
||||
*agp_hi = RADEON_READ(R600_MC_VM_AGP_TOP);
|
||||
} else if (dev_priv->chip_family == CHIP_RV515) {
|
||||
*agp_lo = radeon_read_mc_reg(dev_priv, RV515_MC_FB_LOCATION);
|
||||
*agp_lo = radeon_read_mc_reg(dev_priv, RV515_MC_AGP_LOCATION);
|
||||
*agp_hi = 0;
|
||||
} else if (dev_priv->chip_family == CHIP_RS600) {
|
||||
*agp_lo = 0;
|
||||
|
|
@ -133,7 +133,7 @@ void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *
|
|||
*agp_lo = radeon_read_mc_reg(dev_priv, R520_MC_AGP_LOCATION);
|
||||
*agp_hi = 0;
|
||||
} else {
|
||||
*agp_lo = RADEON_READ(RADEON_MC_FB_LOCATION);
|
||||
*agp_lo = RADEON_READ(RADEON_MC_AGP_LOCATION);
|
||||
*agp_hi = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -194,6 +194,24 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
|
|||
}
|
||||
}
|
||||
|
||||
void radeon_enable_bm(struct drm_radeon_private *dev_priv)
|
||||
{
|
||||
u32 tmp;
|
||||
/* Turn on bus mastering */
|
||||
if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
|
||||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
|
||||
/* rs600/rs690/rs740 */
|
||||
tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
|
||||
RADEON_WRITE(RADEON_BUS_CNTL, tmp);
|
||||
} else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) ||
|
||||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
|
||||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
|
||||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
|
||||
/* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
|
||||
tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
|
||||
RADEON_WRITE(RADEON_BUS_CNTL, tmp);
|
||||
} /* PCIE cards appears to not need this */
|
||||
}
|
||||
|
||||
void radeon_pll_errata_after_index(struct drm_radeon_private *dev_priv)
|
||||
{
|
||||
|
|
@ -573,10 +591,15 @@ static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
|
|||
BEGIN_RING(8);
|
||||
/* isync can only be written through cp on r5xx write it here */
|
||||
OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0));
|
||||
if (dev_priv->chip_family > CHIP_RV280)
|
||||
OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D |
|
||||
RADEON_ISYNC_ANY3D_IDLE2D |
|
||||
RADEON_ISYNC_WAIT_IDLEGUI |
|
||||
dev_priv->mm_enabled ? 0 : RADEON_ISYNC_CPSCRATCH_IDLEGUI);
|
||||
else
|
||||
OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D |
|
||||
RADEON_ISYNC_ANY3D_IDLE2D |
|
||||
RADEON_ISYNC_WAIT_IDLEGUI |
|
||||
RADEON_ISYNC_CPSCRATCH_IDLEGUI);
|
||||
RADEON_ISYNC_WAIT_IDLEGUI);
|
||||
RADEON_PURGE_CACHE();
|
||||
RADEON_PURGE_ZCACHE();
|
||||
RADEON_WAIT_UNTIL_IDLE();
|
||||
|
|
@ -686,7 +709,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
|
|||
drm_radeon_private_t * dev_priv)
|
||||
{
|
||||
u32 ring_start, cur_read_ptr;
|
||||
u32 tmp;
|
||||
|
||||
/* Initialize the memory controller. With new memory map, the fb location
|
||||
* is not changed, it should have been properly initialized already. Part
|
||||
|
|
@ -791,11 +813,12 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
|
|||
dev_priv->ring_rptr->handle +
|
||||
(RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
|
||||
|
||||
RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
|
||||
if (dev_priv->chip_family >= CHIP_R300)
|
||||
RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7f);
|
||||
else
|
||||
RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x1f);
|
||||
|
||||
/* Turn on bus mastering */
|
||||
tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
|
||||
RADEON_WRITE(RADEON_BUS_CNTL, tmp);
|
||||
radeon_enable_bm(dev_priv);
|
||||
|
||||
dev_priv->scratch[0] = 0;
|
||||
RADEON_WRITE(RADEON_LAST_FRAME_REG, 0);
|
||||
|
|
@ -806,6 +829,15 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
|
|||
dev_priv->scratch[2] = 0;
|
||||
RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0);
|
||||
|
||||
dev_priv->scratch[3] = 0;
|
||||
RADEON_WRITE(RADEON_LAST_SWI_REG, 0);
|
||||
|
||||
dev_priv->scratch[4] = 0;
|
||||
RADEON_WRITE(RADEON_SCRATCH_REG4, 0);
|
||||
|
||||
dev_priv->scratch[6] = 0;
|
||||
RADEON_WRITE(RADEON_SCRATCH_REG6, 0);
|
||||
|
||||
radeon_do_wait_for_idle(dev_priv);
|
||||
|
||||
/* Sync everything up */
|
||||
|
|
@ -825,7 +857,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
|
|||
|
||||
static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
|
||||
{
|
||||
u32 tmp;
|
||||
u32 tmp, scratch1_store;
|
||||
void *ring_read_ptr;
|
||||
|
||||
if (dev_priv->mm.ring_read.bo)
|
||||
|
|
@ -833,6 +865,7 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
|
|||
else
|
||||
ring_read_ptr = dev_priv->ring_rptr->handle;
|
||||
|
||||
scratch1_store = RADEON_READ(RADEON_SCRATCH_REG1);
|
||||
/* Writeback doesn't seem to work everywhere, test it here and possibly
|
||||
* enable it if it appears to work
|
||||
*/
|
||||
|
|
@ -858,6 +891,9 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
|
|||
DRM_INFO("writeback forced off\n");
|
||||
}
|
||||
|
||||
/* write back previous value */
|
||||
RADEON_WRITE(RADEON_SCRATCH_REG1, scratch1_store);
|
||||
|
||||
if (!dev_priv->writeback_works) {
|
||||
/* Disable writeback to avoid unnecessary bus master transfers */
|
||||
RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | RADEON_RB_NO_UPDATE);
|
||||
|
|
@ -2353,6 +2389,8 @@ int radeon_modeset_cp_resume(struct drm_device *dev)
|
|||
|
||||
radeon_do_engine_reset(dev);
|
||||
|
||||
radeon_test_writeback(dev_priv);
|
||||
|
||||
radeon_do_cp_start(dev_priv);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2434,16 +2472,22 @@ int radeon_modeset_agp_init(struct drm_device *dev)
|
|||
|
||||
ret = drm_agp_enable(dev, mode);
|
||||
if (ret) {
|
||||
DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode);
|
||||
DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* workaround some hw issues */
|
||||
if (dev_priv->chip_family <= CHIP_R200) {
|
||||
if (dev_priv->chip_family < CHIP_R200) {
|
||||
RADEON_WRITE(RADEON_AGP_CNTL, RADEON_READ(RADEON_AGP_CNTL) | 0x000e0000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_modeset_agp_destroy(struct drm_device *dev)
|
||||
{
|
||||
if (dev->agp->acquired)
|
||||
drm_agp_release(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
int radeon_modeset_cp_init(struct drm_device *dev)
|
||||
|
|
@ -2457,7 +2501,7 @@ int radeon_modeset_cp_init(struct drm_device *dev)
|
|||
dev_priv->writeback_works = 0;
|
||||
|
||||
if (dev_priv->chip_family > CHIP_R600)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT;
|
||||
dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE;
|
||||
|
|
@ -2562,15 +2606,23 @@ int radeon_static_clocks_init(struct drm_device *dev)
|
|||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) {
|
||||
radeon_set_dynamic_clock(dev, radeon_dynclks);
|
||||
} else if (radeon_is_avivo(dev_priv)) {
|
||||
if (radeon_dynclks) {
|
||||
radeon_atom_static_pwrmgt_setup(dev, 1);
|
||||
radeon_atom_dyn_clk_setup(dev, 1);
|
||||
if (radeon_dynclks != -1) {
|
||||
|
||||
if (dev_priv->chip_family == CHIP_RS400 ||
|
||||
dev_priv->chip_family == CHIP_RS480)
|
||||
radeon_dynclks = 0;
|
||||
|
||||
if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) {
|
||||
radeon_set_dynamic_clock(dev, radeon_dynclks);
|
||||
} else if (radeon_is_avivo(dev_priv)) {
|
||||
if (radeon_dynclks) {
|
||||
radeon_atom_static_pwrmgt_setup(dev, 1);
|
||||
radeon_atom_dyn_clk_setup(dev, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
radeon_force_some_clocks(dev);
|
||||
if (radeon_is_r300(dev_priv) || radeon_is_rv100(dev_priv))
|
||||
radeon_force_some_clocks(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2617,9 +2669,16 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
DRM_DEBUG("%s card detected\n",
|
||||
((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
|
||||
|
||||
if ((dev_priv->flags & RADEON_IS_AGP) && (radeon_agpmode == -1)) {
|
||||
DRM_INFO("Forcing AGP to PCI mode\n");
|
||||
dev_priv->flags &= ~RADEON_IS_AGP;
|
||||
if (dev_priv->flags & RADEON_IS_AGP) {
|
||||
|
||||
/* disable AGP for any chips after RV280 if not specified */
|
||||
if ((dev_priv->chip_family > CHIP_RV280) && (radeon_agpmode == 0))
|
||||
radeon_agpmode = -1;
|
||||
|
||||
if (radeon_agpmode == -1) {
|
||||
DRM_INFO("Forcing AGP to PCI mode\n");
|
||||
dev_priv->flags &= ~RADEON_IS_AGP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2709,7 +2768,6 @@ int radeon_master_create(struct drm_device *dev, struct drm_master *master)
|
|||
void radeon_master_destroy(struct drm_device *dev, struct drm_master *master)
|
||||
{
|
||||
struct drm_radeon_master_private *master_priv = master->driver_priv;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
|
||||
if (!master_priv)
|
||||
return;
|
||||
|
|
@ -2731,21 +2789,10 @@ void radeon_master_destroy(struct drm_device *dev, struct drm_master *master)
|
|||
*/
|
||||
int radeon_driver_firstopen(struct drm_device *dev)
|
||||
{
|
||||
int ret;
|
||||
drm_local_map_t *map;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
radeon_gem_mm_init(dev);
|
||||
|
||||
ret = drm_addmap(dev, dev_priv->fb_aper_offset,
|
||||
drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
|
||||
_DRM_WRITE_COMBINING, &map);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2757,6 +2804,10 @@ int radeon_driver_unload(struct drm_device *dev)
|
|||
drm_irq_uninstall(dev);
|
||||
radeon_modeset_cleanup(dev);
|
||||
radeon_gem_mm_fini(dev);
|
||||
#if __OS_HAS_AGP
|
||||
if (dev_priv->flags & RADEON_IS_AGP)
|
||||
radeon_modeset_agp_destroy(dev);
|
||||
#endif
|
||||
}
|
||||
|
||||
drm_bo_driver_finish(dev);
|
||||
|
|
|
|||
|
|
@ -29,21 +29,165 @@
|
|||
#include "radeon_drv.h"
|
||||
#include "r300_reg.h"
|
||||
|
||||
int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
|
||||
{
|
||||
struct drm_radeon_cs_parser parser;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_cs2 *cs = data;
|
||||
uint32_t cs_id;
|
||||
struct drm_radeon_cs_chunk __user **chunk_ptr = NULL;
|
||||
uint64_t *chunk_array;
|
||||
uint64_t *chunk_array_ptr;
|
||||
long size;
|
||||
int r, i;
|
||||
|
||||
/* set command stream id to 0 which is fake id */
|
||||
cs_id = 0;
|
||||
cs->cs_id = cs_id;
|
||||
|
||||
if (dev_priv == NULL) {
|
||||
DRM_ERROR("called with no initialization\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!cs->num_chunks) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
chunk_array = drm_calloc(cs->num_chunks, sizeof(uint64_t), DRM_MEM_DRIVER);
|
||||
if (!chunk_array) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks);
|
||||
|
||||
if (DRM_COPY_FROM_USER(chunk_array, chunk_array_ptr, sizeof(uint64_t)*cs->num_chunks)) {
|
||||
r = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
parser.dev = dev;
|
||||
parser.file_priv = fpriv;
|
||||
parser.reloc_index = -1;
|
||||
parser.ib_index = -1;
|
||||
parser.num_chunks = cs->num_chunks;
|
||||
/* copy out the chunk headers */
|
||||
parser.chunks = drm_calloc(parser.num_chunks, sizeof(struct drm_radeon_kernel_chunk), DRM_MEM_DRIVER);
|
||||
if (!parser.chunks) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < parser.num_chunks; i++) {
|
||||
struct drm_radeon_cs_chunk user_chunk;
|
||||
|
||||
chunk_ptr = (void __user *)(unsigned long)chunk_array[i];
|
||||
|
||||
if (DRM_COPY_FROM_USER(&user_chunk, chunk_ptr, sizeof(struct drm_radeon_cs_chunk))){
|
||||
r = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
parser.chunks[i].chunk_id = user_chunk.chunk_id;
|
||||
|
||||
if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS)
|
||||
parser.reloc_index = i;
|
||||
|
||||
if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_IB)
|
||||
parser.ib_index = i;
|
||||
|
||||
if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_OLD) {
|
||||
parser.ib_index = i;
|
||||
parser.reloc_index = -1;
|
||||
}
|
||||
|
||||
parser.chunks[i].length_dw = user_chunk.length_dw;
|
||||
parser.chunks[i].chunk_data = (uint32_t *)(unsigned long)user_chunk.chunk_data;
|
||||
|
||||
parser.chunks[i].kdata = NULL;
|
||||
size = parser.chunks[i].length_dw * sizeof(uint32_t);
|
||||
|
||||
switch(parser.chunks[i].chunk_id) {
|
||||
case RADEON_CHUNK_ID_IB:
|
||||
case RADEON_CHUNK_ID_OLD:
|
||||
if (size == 0) {
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
case RADEON_CHUNK_ID_RELOCS:
|
||||
if (size) {
|
||||
parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER);
|
||||
if (!parser.chunks[i].kdata) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) {
|
||||
r = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
parser.chunks[i].kdata = NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
DRM_DEBUG("chunk %d %d %d %p\n", i, parser.chunks[i].chunk_id, parser.chunks[i].length_dw,
|
||||
parser.chunks[i].chunk_data);
|
||||
}
|
||||
|
||||
|
||||
if (parser.chunks[parser.ib_index].length_dw > (16 * 1024)) {
|
||||
DRM_ERROR("cs->dwords too big: %d\n", parser.chunks[parser.ib_index].length_dw);
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* get ib */
|
||||
r = dev_priv->cs.ib_get(&parser);
|
||||
if (r) {
|
||||
DRM_ERROR("ib_get failed\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* now parse command stream */
|
||||
r = dev_priv->cs.parse(&parser);
|
||||
if (r) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* emit cs id sequence */
|
||||
dev_priv->cs.id_emit(&parser, &cs_id);
|
||||
|
||||
cs->cs_id = cs_id;
|
||||
|
||||
out:
|
||||
dev_priv->cs.ib_free(&parser);
|
||||
|
||||
for (i = 0; i < parser.num_chunks; i++) {
|
||||
if (parser.chunks[i].kdata)
|
||||
drm_free(parser.chunks[i].kdata, parser.chunks[i].length_dw * sizeof(uint32_t), DRM_MEM_DRIVER);
|
||||
}
|
||||
|
||||
drm_free(parser.chunks, sizeof(struct drm_radeon_kernel_chunk)*parser.num_chunks, DRM_MEM_DRIVER);
|
||||
drm_free(chunk_array, sizeof(uint64_t)*parser.num_chunks, DRM_MEM_DRIVER);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
|
||||
{
|
||||
struct drm_radeon_cs_parser parser;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_cs *cs = data;
|
||||
uint32_t *packets = NULL;
|
||||
uint32_t cs_id;
|
||||
uint32_t card_offset;
|
||||
void *ib = NULL;
|
||||
long size;
|
||||
int r;
|
||||
RING_LOCALS;
|
||||
struct drm_radeon_kernel_chunk chunk_fake[1];
|
||||
|
||||
/* set command stream id to 0 which is fake id */
|
||||
cs_id = 0;
|
||||
DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t));
|
||||
cs->cs_id = cs_id;
|
||||
|
||||
if (dev_priv == NULL) {
|
||||
DRM_ERROR("called with no initialization\n");
|
||||
|
|
@ -69,68 +213,89 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
|
|||
r = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
chunk_fake[0].chunk_id = RADEON_CHUNK_ID_OLD;
|
||||
chunk_fake[0].length_dw = cs->dwords;
|
||||
chunk_fake[0].kdata = packets;
|
||||
|
||||
parser.dev = dev;
|
||||
parser.file_priv = fpriv;
|
||||
parser.num_chunks = 1;
|
||||
parser.chunks = chunk_fake;
|
||||
parser.ib_index = 0;
|
||||
parser.reloc_index = -1;
|
||||
|
||||
/* get ib */
|
||||
r = dev_priv->cs.ib_get(dev, &ib, cs->dwords, &card_offset);
|
||||
r = dev_priv->cs.ib_get(&parser);
|
||||
if (r) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* now parse command stream */
|
||||
r = dev_priv->cs.parse(dev, fpriv, ib, packets, cs->dwords);
|
||||
r = dev_priv->cs.parse(&parser);
|
||||
if (r) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
BEGIN_RING(4);
|
||||
OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
|
||||
OUT_RING(card_offset);
|
||||
OUT_RING(cs->dwords);
|
||||
OUT_RING(CP_PACKET2());
|
||||
ADVANCE_RING();
|
||||
|
||||
/* emit cs id sequence */
|
||||
dev_priv->cs.id_emit(dev, &cs_id);
|
||||
dev_priv->cs.id_emit(&parser, &cs_id);
|
||||
COMMIT_RING();
|
||||
|
||||
DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t));
|
||||
cs->cs_id = cs_id;
|
||||
out:
|
||||
dev_priv->cs.ib_free(dev, ib, cs->dwords);
|
||||
dev_priv->cs.ib_free(&parser);
|
||||
drm_free(packets, size, DRM_MEM_DRIVER);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* for non-mm */
|
||||
static int radeon_nomm_relocate(struct drm_device *dev, struct drm_file *file_priv, uint32_t *reloc, uint32_t *offset)
|
||||
static int radeon_nomm_relocate(struct drm_radeon_cs_parser *parser, uint32_t *reloc, uint32_t *offset)
|
||||
{
|
||||
*offset = reloc[1];
|
||||
return 0;
|
||||
}
|
||||
#define RELOC_SIZE 2
|
||||
#define RELOC_SIZE_NEW 0
|
||||
#define RADEON_2D_OFFSET_MASK 0x3fffff
|
||||
|
||||
static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct drm_file *file_priv,
|
||||
uint32_t *packets, uint32_t offset_dw)
|
||||
static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw)
|
||||
{
|
||||
struct drm_device *dev = parser->dev;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t hdr = packets[offset_dw];
|
||||
uint32_t reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
|
||||
uint32_t val = packets[offset_dw + 1];
|
||||
uint32_t packet3_hdr = packets[offset_dw+2];
|
||||
uint32_t hdr, reg, val, packet3_hdr;
|
||||
uint32_t tmp, offset;
|
||||
struct drm_radeon_kernel_chunk *ib_chunk;
|
||||
int ret;
|
||||
|
||||
ib_chunk = &parser->chunks[parser->ib_index];
|
||||
// if (parser->reloc_index == -1)
|
||||
// is_old = 1;
|
||||
|
||||
hdr = ib_chunk->kdata[offset_dw];
|
||||
reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
|
||||
val = ib_chunk->kdata[offset_dw + 1];
|
||||
packet3_hdr = ib_chunk->kdata[offset_dw + 2];
|
||||
|
||||
/* this is too strict we may want to expand the length in the future and have
|
||||
old kernels ignore it. */
|
||||
if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) {
|
||||
DRM_ERROR("Packet 3 was %x should have been %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16));
|
||||
return -EINVAL;
|
||||
if (parser->reloc_index == -1) {
|
||||
if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) {
|
||||
DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16), reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16))) {
|
||||
DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16), reg);
|
||||
return -EINVAL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
switch(reg) {
|
||||
case RADEON_DST_PITCH_OFFSET:
|
||||
case RADEON_SRC_PITCH_OFFSET:
|
||||
/* pass in the start of the reloc */
|
||||
ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset);
|
||||
ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + 2, &offset);
|
||||
if (ret)
|
||||
return ret;
|
||||
tmp = (val & RADEON_2D_OFFSET_MASK) << 10;
|
||||
|
|
@ -148,7 +313,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct
|
|||
case R200_PP_TXOFFSET_1:
|
||||
case RADEON_PP_TXOFFSET_0:
|
||||
case RADEON_PP_TXOFFSET_1:
|
||||
ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset);
|
||||
ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + 2, &offset);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -159,25 +324,32 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct
|
|||
break;
|
||||
}
|
||||
|
||||
packets[offset_dw + 1] = val;
|
||||
ib_chunk->kdata[offset_dw + 1] = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *file_priv,
|
||||
uint32_t *packets, uint32_t offset_dw)
|
||||
static int radeon_cs_relocate_packet3(struct drm_radeon_cs_parser *parser,
|
||||
uint32_t offset_dw)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t hdr = packets[offset_dw];
|
||||
int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16;
|
||||
uint32_t reg = hdr & 0xff00;
|
||||
drm_radeon_private_t *dev_priv = parser->dev->dev_private;
|
||||
uint32_t hdr, num_dw, reg;
|
||||
uint32_t offset, val, tmp;
|
||||
int ret;
|
||||
struct drm_radeon_kernel_chunk *ib_chunk;
|
||||
|
||||
ib_chunk = &parser->chunks[parser->ib_index];
|
||||
// if (parser->reloc_index == -1)
|
||||
// is_old = 1;
|
||||
|
||||
hdr = ib_chunk->kdata[offset_dw];
|
||||
num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16;
|
||||
reg = hdr & 0xff00;
|
||||
|
||||
switch(reg) {
|
||||
case RADEON_CNTL_HOSTDATA_BLT:
|
||||
{
|
||||
val = packets[offset_dw + 2];
|
||||
ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + num_dw + 2, &offset);
|
||||
val = ib_chunk->kdata[offset_dw + 2];
|
||||
ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + num_dw + 2, &offset);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -187,7 +359,7 @@ static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *f
|
|||
offset >>= 10;
|
||||
val |= offset;
|
||||
|
||||
packets[offset_dw + 2] = val;
|
||||
ib_chunk->kdata[offset_dw + 2] = val;
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
@ -195,41 +367,16 @@ static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *f
|
|||
return 0;
|
||||
}
|
||||
|
||||
static __inline__ int radeon_cs_check_offset(struct drm_device *dev,
|
||||
uint32_t reg, uint32_t val)
|
||||
int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw)
|
||||
{
|
||||
uint32_t offset;
|
||||
|
||||
switch(reg) {
|
||||
case RADEON_DST_PITCH_OFFSET:
|
||||
case RADEON_SRC_PITCH_OFFSET:
|
||||
offset = val & ((1 << 22) - 1);
|
||||
offset <<= 10;
|
||||
break;
|
||||
case R300_RB3D_COLOROFFSET0:
|
||||
case R300_ZB_DEPTHOFFSET:
|
||||
offset = val;
|
||||
break;
|
||||
case R300_TX_OFFSET_0:
|
||||
case R300_TX_OFFSET_0+4:
|
||||
offset = val & 0xffffffe0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv,
|
||||
uint32_t *packets, uint32_t offset_dw)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t hdr = packets[offset_dw];
|
||||
int num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2;
|
||||
int need_reloc = 0;
|
||||
int reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
|
||||
uint32_t hdr, num_dw, reg;
|
||||
int count_dw = 1;
|
||||
int ret;
|
||||
|
||||
hdr = parser->chunks[parser->ib_index].kdata[offset_dw];
|
||||
num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2;
|
||||
reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
|
||||
|
||||
while (count_dw < num_dw) {
|
||||
/* need to have something like the r300 validation here -
|
||||
list of allowed registers */
|
||||
|
|
@ -250,7 +397,7 @@ int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = radeon_cs_relocate_packet0(dev, file_priv, packets, offset_dw);
|
||||
ret = radeon_cs_relocate_packet0(parser, offset_dw);
|
||||
if (ret)
|
||||
return ret;
|
||||
DRM_DEBUG("need to relocate %x %d\n", reg, flags);
|
||||
|
|
@ -269,24 +416,25 @@ int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv,
|
||||
void *ib, uint32_t *packets, uint32_t dwords)
|
||||
int radeon_cs_parse(struct drm_radeon_cs_parser *parser)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
volatile int rb;
|
||||
int size_dw = dwords;
|
||||
struct drm_radeon_kernel_chunk *ib_chunk;
|
||||
/* scan the packet for various things */
|
||||
int count_dw = 0;
|
||||
int count_dw = 0, size_dw;
|
||||
int ret = 0;
|
||||
|
||||
ib_chunk = &parser->chunks[parser->ib_index];
|
||||
size_dw = ib_chunk->length_dw;
|
||||
|
||||
while (count_dw < size_dw && ret == 0) {
|
||||
int hdr = packets[count_dw];
|
||||
int hdr = ib_chunk->kdata[count_dw];
|
||||
int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16;
|
||||
int reg;
|
||||
|
||||
switch (hdr & RADEON_CP_PACKET_MASK) {
|
||||
case RADEON_CP_PACKET0:
|
||||
ret = radeon_cs_packet0(dev, file_priv, packets, count_dw);
|
||||
ret = radeon_cs_packet0(parser, count_dw);
|
||||
break;
|
||||
case RADEON_CP_PACKET1:
|
||||
case RADEON_CP_PACKET2:
|
||||
|
|
@ -299,7 +447,7 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv,
|
|||
|
||||
switch(reg) {
|
||||
case RADEON_CNTL_HOSTDATA_BLT:
|
||||
radeon_cs_relocate_packet3(dev, file_priv, packets, count_dw);
|
||||
radeon_cs_relocate_packet3(parser, count_dw);
|
||||
break;
|
||||
|
||||
case RADEON_CNTL_BITBLT_MULTI:
|
||||
|
|
@ -308,6 +456,7 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv,
|
|||
DRM_ERROR("need relocate packet 3 for %x\n", reg);
|
||||
break;
|
||||
|
||||
case RADEON_3D_DRAW_IMMD: /* triggers drawing using in-packet vertex data */
|
||||
case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
|
||||
case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
|
||||
case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
|
||||
|
|
@ -329,10 +478,10 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv,
|
|||
|
||||
|
||||
/* copy the packet into the IB */
|
||||
memcpy(ib, packets, dwords * sizeof(uint32_t));
|
||||
memcpy(parser->ib, ib_chunk->kdata, ib_chunk->length_dw * sizeof(uint32_t));
|
||||
|
||||
/* read back last byte to flush WC buffers */
|
||||
rb = readl((ib + (dwords-1) * sizeof(uint32_t)));
|
||||
rb = readl((parser->ib + (ib_chunk->length_dw-1) * sizeof(uint32_t)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -351,51 +500,89 @@ uint32_t radeon_cs_id_get(struct drm_radeon_private *radeon)
|
|||
return (radeon->cs.id_scnt | radeon->cs.id_wcnt);
|
||||
}
|
||||
|
||||
void r100_cs_id_emit(struct drm_device *dev, uint32_t *id)
|
||||
void r100_cs_id_emit(struct drm_radeon_cs_parser *parser, uint32_t *id)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_private_t *dev_priv = parser->dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
dev_priv->irq_emitted = radeon_update_breadcrumb(parser->dev);
|
||||
/* ISYNC_CNTL should have CPSCRACTH bit set */
|
||||
*id = radeon_cs_id_get(dev_priv);
|
||||
/* emit id in SCRATCH4 (not used yet in old drm) */
|
||||
BEGIN_RING(2);
|
||||
BEGIN_RING(10);
|
||||
OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
|
||||
OUT_RING(parser->card_offset);
|
||||
OUT_RING(parser->chunks[parser->ib_index].length_dw);
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET0(RADEON_SCRATCH_REG4, 0));
|
||||
OUT_RING(*id);
|
||||
OUT_RING_REG(RADEON_LAST_SWI_REG, dev_priv->irq_emitted);
|
||||
OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
|
||||
ADVANCE_RING();
|
||||
COMMIT_RING();
|
||||
|
||||
}
|
||||
|
||||
void r300_cs_id_emit(struct drm_device *dev, uint32_t *id)
|
||||
void r300_cs_id_emit(struct drm_radeon_cs_parser *parser, uint32_t *id)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_private_t *dev_priv = parser->dev->dev_private;
|
||||
int i;
|
||||
RING_LOCALS;
|
||||
|
||||
dev_priv->irq_emitted = radeon_update_breadcrumb(parser->dev);
|
||||
|
||||
/* ISYNC_CNTL should not have CPSCRACTH bit set */
|
||||
*id = radeon_cs_id_get(dev_priv);
|
||||
|
||||
/* emit id in SCRATCH6 */
|
||||
BEGIN_RING(8);
|
||||
OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 0));
|
||||
OUT_RING(6);
|
||||
OUT_RING(CP_PACKET0(R300_CP_RESYNC_DATA, 0));
|
||||
OUT_RING(*id);
|
||||
BEGIN_RING(16);
|
||||
OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
|
||||
OUT_RING(parser->card_offset);
|
||||
OUT_RING(parser->chunks[parser->ib_index].length_dw);
|
||||
OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
|
||||
OUT_RING(R300_RB3D_DC_FINISH);
|
||||
OUT_RING(0);
|
||||
for (i = 0; i < 11; i++) /* emit fillers like fglrx */
|
||||
OUT_RING(CP_PACKET2());
|
||||
ADVANCE_RING();
|
||||
COMMIT_RING();
|
||||
|
||||
BEGIN_RING(16);
|
||||
OUT_RING_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH);
|
||||
OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1));
|
||||
OUT_RING(6);
|
||||
OUT_RING(*id);
|
||||
OUT_RING_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FINISH|R300_RB3D_DC_FLUSH);
|
||||
/* emit inline breadcrumb for TTM fencing */
|
||||
#if 1
|
||||
RADEON_WAIT_UNTIL_3D_IDLE();
|
||||
OUT_RING_REG(RADEON_LAST_SWI_REG, dev_priv->irq_emitted);
|
||||
#else
|
||||
OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1));
|
||||
OUT_RING(3); /* breadcrumb register */
|
||||
OUT_RING(dev_priv->irq_emitted);
|
||||
OUT_RING(CP_PACKET2());
|
||||
#endif
|
||||
OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
ADVANCE_RING();
|
||||
COMMIT_RING();
|
||||
|
||||
}
|
||||
|
||||
uint32_t r100_cs_id_last_get(struct drm_device *dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
return RADEON_READ(RADEON_SCRATCH_REG4);
|
||||
return GET_SCRATCH(4);
|
||||
}
|
||||
|
||||
uint32_t r300_cs_id_last_get(struct drm_device *dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
return RADEON_READ(RADEON_SCRATCH_REG6);
|
||||
return GET_SCRATCH(6);
|
||||
}
|
||||
|
||||
int radeon_cs_init(struct drm_device *dev)
|
||||
|
|
|
|||
|
|
@ -511,9 +511,10 @@ typedef struct {
|
|||
#define DRM_RADEON_GEM_PREAD 0x21
|
||||
#define DRM_RADEON_GEM_PWRITE 0x22
|
||||
#define DRM_RADEON_GEM_SET_DOMAIN 0x23
|
||||
#define DRM_RADEON_GEM_INDIRECT 0x24 // temporary for X server
|
||||
#define DRM_RADEON_GEM_WAIT_RENDERING 0x24
|
||||
|
||||
#define DRM_RADEON_CS 0x25
|
||||
#define DRM_RADEON_CS2 0x26
|
||||
|
||||
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
|
||||
#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
|
||||
|
|
@ -551,9 +552,9 @@ typedef struct {
|
|||
#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread)
|
||||
#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite)
|
||||
#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain)
|
||||
#define DRM_IOCTL_RADEON_GEM_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INDIRECT, struct drm_radeon_gem_indirect)
|
||||
|
||||
#define DRM_IOCTL_RADEON_GEM_WAIT_RENDERING DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_RENDERING, struct drm_radeon_gem_wait_rendering)
|
||||
#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
|
||||
#define DRM_IOCTL_RADEON_CS2 DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS2, struct drm_radeon_cs2)
|
||||
|
||||
|
||||
typedef struct drm_radeon_init {
|
||||
|
|
@ -820,7 +821,8 @@ struct drm_radeon_gem_set_domain {
|
|||
uint32_t write_domain;
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_exec_buffer {
|
||||
struct drm_radeon_gem_wait_rendering {
|
||||
uint32_t handle;
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_pin {
|
||||
|
|
@ -864,21 +866,32 @@ struct drm_radeon_gem_pwrite {
|
|||
uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_indirect {
|
||||
uint32_t handle;
|
||||
uint32_t used;
|
||||
};
|
||||
|
||||
/* New interface which obsolete all previous interface.
|
||||
*/
|
||||
|
||||
|
||||
struct drm_radeon_cs {
|
||||
// uint32_t __user *packets;
|
||||
uint32_t dwords;
|
||||
uint32_t cs_id;
|
||||
uint64_t packets;
|
||||
};
|
||||
|
||||
#define RADEON_CHUNK_ID_RELOCS 0x01
|
||||
#define RADEON_CHUNK_ID_IB 0x02
|
||||
#define RADEON_CHUNK_ID_OLD 0xff
|
||||
|
||||
struct drm_radeon_cs_chunk {
|
||||
uint32_t chunk_id;
|
||||
uint32_t length_dw;
|
||||
uint64_t chunk_data;
|
||||
};
|
||||
|
||||
struct drm_radeon_cs2 {
|
||||
uint32_t num_chunks;
|
||||
uint32_t cs_id;
|
||||
uint64_t chunks; /* this points to uint64_t * which point to
|
||||
cs chunks */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ enum radeon_family {
|
|||
CHIP_RV350,
|
||||
CHIP_RV380,
|
||||
CHIP_R420,
|
||||
CHIP_R423,
|
||||
CHIP_RV410,
|
||||
CHIP_RS400,
|
||||
CHIP_RS480,
|
||||
|
|
@ -294,6 +295,24 @@ struct drm_radeon_master_private {
|
|||
#define RADEON_FLUSH_EMITED (1 < 0)
|
||||
#define RADEON_PURGE_EMITED (1 < 1)
|
||||
|
||||
struct drm_radeon_kernel_chunk {
|
||||
uint32_t chunk_id;
|
||||
uint32_t length_dw;
|
||||
uint32_t __user *chunk_data;
|
||||
uint32_t *kdata;
|
||||
};
|
||||
|
||||
struct drm_radeon_cs_parser {
|
||||
struct drm_device *dev;
|
||||
struct drm_file *file_priv;
|
||||
uint32_t num_chunks;
|
||||
struct drm_radeon_kernel_chunk *chunks;
|
||||
int ib_index;
|
||||
int reloc_index;
|
||||
uint32_t card_offset;
|
||||
void *ib;
|
||||
};
|
||||
|
||||
/* command submission struct */
|
||||
struct drm_radeon_cs_priv {
|
||||
uint32_t id_wcnt;
|
||||
|
|
@ -301,21 +320,22 @@ struct drm_radeon_cs_priv {
|
|||
uint32_t id_last_wcnt;
|
||||
uint32_t id_last_scnt;
|
||||
|
||||
int (*parse)(struct drm_device *dev, struct drm_file *file_priv,
|
||||
void *ib, uint32_t *packets, uint32_t dwords);
|
||||
void (*id_emit)(struct drm_device *dev, uint32_t *id);
|
||||
int (*parse)(struct drm_radeon_cs_parser *parser);
|
||||
void (*id_emit)(struct drm_radeon_cs_parser *parser, uint32_t *id);
|
||||
uint32_t (*id_last_get)(struct drm_device *dev);
|
||||
/* this ib handling callback are for hidding memory manager drm
|
||||
* from memory manager less drm, free have to emit ib discard
|
||||
* sequence into the ring */
|
||||
int (*ib_get)(struct drm_device *dev, void **ib, uint32_t dwords, uint32_t *card_offset);
|
||||
int (*ib_get)(struct drm_radeon_cs_parser *parser);
|
||||
uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib);
|
||||
void (*ib_free)(struct drm_device *dev, void *ib, uint32_t dwords);
|
||||
void (*ib_free)(struct drm_radeon_cs_parser *parser);
|
||||
/* do a relocation either MM or non-MM */
|
||||
int (*relocate)(struct drm_device *dev, struct drm_file *file_priv,
|
||||
uint32_t *reloc, uint32_t *offset);
|
||||
int (*relocate)(struct drm_radeon_cs_parser *parser,
|
||||
uint32_t *reloc, uint32_t *offset);
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct radeon_pm_regs {
|
||||
uint32_t crtc_ext_cntl;
|
||||
uint32_t bios_scratch[8];
|
||||
|
|
@ -441,6 +461,11 @@ typedef struct drm_radeon_private {
|
|||
struct drm_radeon_cs_priv cs;
|
||||
|
||||
struct radeon_pm_regs pmregs;
|
||||
int irq_emitted;
|
||||
atomic_t irq_received;
|
||||
|
||||
uint32_t aper_size;
|
||||
int vram_mtrr;
|
||||
} drm_radeon_private_t;
|
||||
|
||||
typedef struct drm_radeon_buf_priv {
|
||||
|
|
@ -460,6 +485,7 @@ extern int radeon_r4xx_atom;
|
|||
extern struct drm_ioctl_desc radeon_ioctls[];
|
||||
extern int radeon_max_ioctl;
|
||||
extern int radeon_agpmode;
|
||||
extern int radeon_modeset;
|
||||
|
||||
/* Check whether the given hardware address is inside the framebuffer or the
|
||||
* GART area.
|
||||
|
|
@ -572,7 +598,11 @@ int radeon_resume(struct drm_device *dev);
|
|||
# define RADEON_SCISSOR_2_ENABLE (1 << 30)
|
||||
|
||||
#define RADEON_BUS_CNTL 0x0030
|
||||
/* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
|
||||
# define RADEON_BUS_MASTER_DIS (1 << 6)
|
||||
/* rs600/rs690/rs740 */
|
||||
# define RS600_BUS_MASTER_DIS (1 << 14)
|
||||
# define RS600_MSI_REARM (1 << 20)
|
||||
|
||||
#define RADEON_CLOCK_CNTL_DATA 0x000c
|
||||
# define RADEON_PLL_WR_EN (1 << 7)
|
||||
|
|
@ -732,11 +762,11 @@ int radeon_resume(struct drm_device *dev);
|
|||
|
||||
#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x))
|
||||
|
||||
#define GET_SCRATCH( x ) (dev_priv->writeback_works ? \
|
||||
(dev_priv->mm.ring_read.bo ? \
|
||||
readl(dev_priv->mm.ring_read.kmap.virtual + RADEON_SCRATCHOFF(x)) : \
|
||||
DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(x))) : \
|
||||
RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x)))
|
||||
#define GET_SCRATCH( x ) (dev_priv->writeback_works ? \
|
||||
(dev_priv->mm.ring_read.bo ? \
|
||||
readl(dev_priv->mm.ring_read.kmap.virtual + RADEON_SCRATCHOFF(x)) : \
|
||||
DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(x))) : \
|
||||
RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x)))
|
||||
|
||||
#define RADEON_CRTC_CRNT_FRAME 0x0214
|
||||
#define RADEON_CRTC2_CRNT_FRAME 0x0314
|
||||
|
|
@ -1034,6 +1064,7 @@ int radeon_resume(struct drm_device *dev);
|
|||
|
||||
#define RADEON_AIC_CNTL 0x01d0
|
||||
# define RADEON_PCIGART_TRANSLATE_EN (1 << 0)
|
||||
# define RS400_MSI_REARM (1 << 3)
|
||||
#define RADEON_AIC_STAT 0x01d4
|
||||
#define RADEON_AIC_PT_BASE 0x01d8
|
||||
#define RADEON_AIC_LO_ADDR 0x01dc
|
||||
|
|
@ -1606,7 +1637,7 @@ extern uint64_t radeon_evict_flags(struct drm_buffer_object *bo);
|
|||
#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
|
||||
|
||||
/* Breadcrumb - swi irq */
|
||||
#define READ_BREADCRUMB(dev_priv) RADEON_READ(RADEON_LAST_SWI_REG)
|
||||
#define READ_BREADCRUMB(dev_priv) GET_SCRATCH(3)
|
||||
|
||||
static inline int radeon_update_breadcrumb(struct drm_device *dev)
|
||||
{
|
||||
|
|
@ -1643,6 +1674,7 @@ static inline int radeon_update_breadcrumb(struct drm_device *dev)
|
|||
(dev_priv->chip_family == CHIP_R350) || \
|
||||
(dev_priv->chip_family == CHIP_RV380) || \
|
||||
(dev_priv->chip_family == CHIP_R420) || \
|
||||
(dev_priv->chip_family == CHIP_R423) || \
|
||||
(dev_priv->chip_family == CHIP_RV410) || \
|
||||
(dev_priv->chip_family == CHIP_RS400) || \
|
||||
(dev_priv->chip_family == CHIP_RS480))
|
||||
|
|
@ -1668,10 +1700,10 @@ extern int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data,
|
|||
int radeon_gem_object_pin(struct drm_gem_object *obj,
|
||||
uint32_t alignment, uint32_t pin_domain);
|
||||
int radeon_gem_object_unpin(struct drm_gem_object *obj);
|
||||
int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int radeon_gem_wait_rendering(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
struct drm_gem_object *radeon_gem_object_alloc(struct drm_device *dev, int size, int alignment,
|
||||
int initial_domain, bool discardable);
|
||||
int radeon_modeset_init(struct drm_device *dev);
|
||||
|
|
@ -1687,11 +1719,14 @@ extern int radeon_master_create(struct drm_device *dev, struct drm_master *maste
|
|||
extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master);
|
||||
extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master);
|
||||
extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
|
||||
extern int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
|
||||
extern int radeon_cs_init(struct drm_device *dev);
|
||||
void radeon_gem_update_offsets(struct drm_device *dev, struct drm_master *master);
|
||||
void radeon_init_memory_map(struct drm_device *dev);
|
||||
void radeon_enable_bm(struct drm_radeon_private *dev_priv);
|
||||
|
||||
|
||||
extern int radeon_gem_proc_init(struct drm_minor *minor);
|
||||
extern void radeon_gem_proc_cleanup(struct drm_minor *minor);
|
||||
#define MARK_SAFE 1
|
||||
#define MARK_CHECK_OFFSET 2
|
||||
#define MARK_CHECK_SCISSOR 3
|
||||
|
|
|
|||
|
|
@ -195,6 +195,7 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
if (!stat)
|
||||
return IRQ_NONE;
|
||||
|
||||
atomic_inc(&dev_priv->irq_received);
|
||||
stat &= dev_priv->irq_enable_reg;
|
||||
|
||||
/* SW interrupt */
|
||||
|
|
@ -222,15 +223,19 @@ int radeon_emit_irq(struct drm_device * dev)
|
|||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
unsigned int ret;
|
||||
int i;
|
||||
RING_LOCALS;
|
||||
|
||||
ret = radeon_update_breadcrumb(dev);
|
||||
if (!dev_priv->irq_emitted) {
|
||||
ret = radeon_update_breadcrumb(dev);
|
||||
|
||||
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();
|
||||
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();
|
||||
} else
|
||||
ret = dev_priv->irq_emitted;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *fi
|
|||
return -EFAULT;
|
||||
|
||||
if (*heap) {
|
||||
DRM_ERROR("heap already initialized?");
|
||||
DRM_DEBUG("heap already initialized?");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1884,10 +1884,11 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
|
|||
OUT_RING((image->width << 16) | height);
|
||||
RADEON_WAIT_UNTIL_2D_IDLE();
|
||||
ADVANCE_RING();
|
||||
COMMIT_RING();
|
||||
|
||||
radeon_cp_discard_buffer(dev, file_priv->master, buf);
|
||||
|
||||
COMMIT_RING();
|
||||
|
||||
/* Update the input parameters for next time */
|
||||
image->y += height;
|
||||
image->height -= height;
|
||||
|
|
@ -3288,8 +3289,9 @@ struct drm_ioctl_desc radeon_ioctls[] = {
|
|||
DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_INDIRECT, radeon_gem_indirect_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_RENDERING, radeon_gem_wait_rendering, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_CS2, radeon_cs2_ioctl, DRM_AUTH),
|
||||
};
|
||||
|
||||
int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue