summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/Makefile.kernel2
-rw-r--r--linux-core/ati_pcigart.c10
-rw-r--r--linux-core/atombios_crtc.c2
-rw-r--r--linux-core/drm_bufs.c1
-rw-r--r--linux-core/drm_crtc.h1
-rw-r--r--linux-core/drm_crtc_helper.c4
-rw-r--r--linux-core/drm_crtc_helper.h3
-rw-r--r--linux-core/radeon_buffer.c15
-rw-r--r--linux-core/radeon_connectors.c14
-rw-r--r--linux-core/radeon_display.c31
-rw-r--r--linux-core/radeon_drv.c12
-rw-r--r--linux-core/radeon_fb.c3
-rw-r--r--linux-core/radeon_fence.c1
-rw-r--r--linux-core/radeon_gem.c168
-rw-r--r--linux-core/radeon_gem_proc.c146
-rw-r--r--linux-core/radeon_legacy_crtc.c4
-rw-r--r--linux-core/radeon_legacy_encoders.c3
-rw-r--r--linux-core/radeon_mode.h3
-rw-r--r--linux-core/radeon_pm.c14
-rw-r--r--shared-core/r300_cmdbuf.c3
-rw-r--r--shared-core/r300_reg.h2
-rw-r--r--shared-core/radeon_cp.c121
-rw-r--r--shared-core/radeon_cs.c369
-rw-r--r--shared-core/radeon_drm.h31
-rw-r--r--shared-core/radeon_drv.h67
-rw-r--r--shared-core/radeon_irq.c17
-rw-r--r--shared-core/radeon_mem.c2
-rw-r--r--shared-core/radeon_state.c6
28 files changed, 753 insertions, 302 deletions
diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel
index 392abaf9..98616e4b 100644
--- a/linux-core/Makefile.kernel
+++ b/linux-core/Makefile.kernel
@@ -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
diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c
index 50e990f1..6b0d8947 100644
--- a/linux-core/ati_pcigart.c
+++ b/linux-core/ati_pcigart.c
@@ -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++;
}
diff --git a/linux-core/atombios_crtc.c b/linux-core/atombios_crtc.c
index 3856f8ca..2e144c90 100644
--- a/linux-core/atombios_crtc.c
+++ b/linux-core/atombios_crtc.c
@@ -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;
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
index c966badc..15c426cb 100644
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -1544,7 +1544,6 @@ int drm_mapbufs(struct drm_device *dev, void *data,
goto done;
}
down_write(&current->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,
diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h
index 6a73a71b..13fba4f2 100644
--- a/linux-core/drm_crtc.h
+++ b/linux-core/drm_crtc.h
@@ -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 {
diff --git a/linux-core/drm_crtc_helper.c b/linux-core/drm_crtc_helper.c
index b334f5b5..776a98e1 100644
--- a/linux-core/drm_crtc_helper.c
+++ b/linux-core/drm_crtc_helper.c
@@ -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;
}
diff --git a/linux-core/drm_crtc_helper.h b/linux-core/drm_crtc_helper.h
index 01b14239..c0719157 100644
--- a/linux-core/drm_crtc_helper.h
+++ b/linux-core/drm_crtc_helper.h
@@ -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)
{
diff --git a/linux-core/radeon_buffer.c b/linux-core/radeon_buffer.c
index e5a90892..f047b1ac 100644
--- a/linux-core/radeon_buffer.c
+++ b/linux-core/radeon_buffer.c
@@ -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)
diff --git a/linux-core/radeon_connectors.c b/linux-core/radeon_connectors.c
index f217fe77..18873f0f 100644
--- a/linux-core/radeon_connectors.c
+++ b/linux-core/radeon_connectors.c
@@ -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 },
diff --git a/linux-core/radeon_display.c b/linux-core/radeon_display.c
index ddc933cc..0b9467fd 100644
--- a/linux-core/radeon_display.c
+++ b/linux-core/radeon_display.c
@@ -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;
+
+ obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
- mm_private = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
- return radeon_framebuffer_create(dev, mode_cmd, mm_private);
+ return radeon_framebuffer_create(dev, mode_cmd, obj);
}
static const struct drm_mode_config_funcs radeon_mode_funcs = {
diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c
index f1fe3012..f4194688 100644
--- a/linux-core/radeon_drv.c
+++ b/linux-core/radeon_drv.c
@@ -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,
diff --git a/linux-core/radeon_fb.c b/linux-core/radeon_fb.c
index 8d4181e8..d3722c37 100644
--- a/linux-core/radeon_fb.c
+++ b/linux-core/radeon_fb.c
@@ -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);
}
diff --git a/linux-core/radeon_fence.c b/linux-core/radeon_fence.c
index 591ad53b..b662da21 100644
--- a/linux-core/radeon_fence.c
+++ b/linux-core/radeon_fence.c
@@ -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;
diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c
index 5e2ad98b..2e20de3c 100644
--- a/linux-core/radeon_gem.c
+++ b/linux-core/radeon_gem.c
@@ -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;
diff --git a/linux-core/radeon_gem_proc.c b/linux-core/radeon_gem_proc.c
new file mode 100644
index 00000000..04f5a5fc
--- /dev/null
+++ b/linux-core/radeon_gem_proc.c
@@ -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);
+}
diff --git a/linux-core/radeon_legacy_crtc.c b/linux-core/radeon_legacy_crtc.c
index 820bd548..c0a3c0fa 100644
--- a/linux-core/radeon_legacy_crtc.c
+++ b/linux-core/radeon_legacy_crtc.c
@@ -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;
diff --git a/linux-core/radeon_legacy_encoders.c b/linux-core/radeon_legacy_encoders.c
index 261501d1..3df89d30 100644
--- a/linux-core/radeon_legacy_encoders.c
+++ b/linux-core/radeon_legacy_encoders.c
@@ -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 |
diff --git a/linux-core/radeon_mode.h b/linux-core/radeon_mode.h
index 64608e35..23de1088 100644
--- a/linux-core/radeon_mode.h
+++ b/linux-core/radeon_mode.h
@@ -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);
diff --git a/linux-core/radeon_pm.c b/linux-core/radeon_pm.c
index 6b1e6f84..259d42da 100644
--- a/linux-core/radeon_pm.c
+++ b/linux-core/radeon_pm.c
@@ -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 */
diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c
index b15e8928..f39a7afd 100644
--- a/shared-core/r300_cmdbuf.c
+++ b/shared-core/r300_cmdbuf.c
@@ -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);
diff --git a/shared-core/r300_reg.h b/shared-core/r300_reg.h
index 9e9cb526..1e4631db 100644
--- a/shared-core/r300_reg.h
+++ b/shared-core/r300_reg.h
@@ -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.
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index 190b1432..9a1e0e02 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -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);
diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c
index f9147136..3dde321d 100644
--- a/shared-core/radeon_cs.c
+++ b/shared-core/radeon_cs.c
@@ -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));
+ 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(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(CP_PACKET0(R300_CP_RESYNC_DATA, 0));
OUT_RING(*id);
- OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
- OUT_RING(R300_RB3D_DC_FINISH);
+ 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)
diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h
index c924c689..002e4004 100644
--- a/shared-core/radeon_drm.h
+++ b/shared-core/radeon_drm.h
@@ -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 */
};
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index a6ce129d..a95ab152 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -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
diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c
index dcf58e43..46a27943 100644
--- a/shared-core/radeon_irq.c
+++ b/shared-core/radeon_irq.c
@@ -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;
}
diff --git a/shared-core/radeon_mem.c b/shared-core/radeon_mem.c
index dbd73c50..2622cf3c 100644
--- a/shared-core/radeon_mem.c
+++ b/shared-core/radeon_mem.c
@@ -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;
}
diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c
index 7262b2aa..e0a00f02 100644
--- a/shared-core/radeon_state.c
+++ b/shared-core/radeon_state.c
@@ -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);