Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  vmwgfx: integer overflow in vmw_kms_update_layout_ioctl()
  drm/radeon/kms: fix 2D tiling CS support on EG/CM
  drm/radeon/kms: fix scanout of 2D tiled buffers on EG/CM
  drm: Fix lack of CRTC disable for drm_crtc_helper_set_config(.fb=NULL)
  drm/radeon/kms: add some new pci ids
  drm/radeon/kms: Skip ACPI call to ATIF when possible
  drm/radeon/kms: Hide debugging message
  drm/radeon/kms: add some loop timeouts in pageflip code
  drm/nv50/disp: silence compiler warning
  drm/nouveau: fix oopses caused by clear being called on unpopulated ttms
  drm/nouveau: Keep RAMIN heap within the channel.
  drm/nvd0/disp: fix sor dpms typo, preventing dpms on in some situations
  drm/nvc0/gr: fix TP init for transform feedback offset queries
  drm/nouveau: add dumb ioctl support
This commit is contained in:
Linus Torvalds 2011-12-02 08:25:04 -08:00
commit c2b5adb486
20 changed files with 349 additions and 48 deletions

View file

@ -456,6 +456,30 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
EXPORT_SYMBOL(drm_crtc_helper_set_mode); EXPORT_SYMBOL(drm_crtc_helper_set_mode);
static int
drm_crtc_helper_disable(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_connector *connector;
struct drm_encoder *encoder;
/* Decouple all encoders and their attached connectors from this crtc */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (encoder->crtc != crtc)
continue;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->encoder != encoder)
continue;
connector->encoder = NULL;
}
}
drm_helper_disable_unused_functions(dev);
return 0;
}
/** /**
* drm_crtc_helper_set_config - set a new config from userspace * drm_crtc_helper_set_config - set a new config from userspace
* @crtc: CRTC to setup * @crtc: CRTC to setup
@ -510,8 +534,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
(int)set->num_connectors, set->x, set->y); (int)set->num_connectors, set->x, set->y);
} else { } else {
DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
set->mode = NULL; return drm_crtc_helper_disable(set->crtc);
set->num_connectors = 0;
} }
dev = set->crtc->dev; dev = set->crtc->dev;

View file

@ -369,3 +369,48 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
spin_unlock_irqrestore(&dev->event_lock, flags); spin_unlock_irqrestore(&dev->event_lock, flags);
return 0; return 0;
} }
int
nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
struct drm_mode_create_dumb *args)
{
struct nouveau_bo *bo;
int ret;
args->pitch = roundup(args->width * (args->bpp / 8), 256);
args->size = args->pitch * args->height;
args->size = roundup(args->size, PAGE_SIZE);
ret = nouveau_gem_new(dev, args->size, 0, TTM_PL_FLAG_VRAM, 0, 0, &bo);
if (ret)
return ret;
ret = drm_gem_handle_create(file_priv, bo->gem, &args->handle);
drm_gem_object_unreference_unlocked(bo->gem);
return ret;
}
int
nouveau_display_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev,
uint32_t handle)
{
return drm_gem_handle_delete(file_priv, handle);
}
int
nouveau_display_dumb_map_offset(struct drm_file *file_priv,
struct drm_device *dev,
uint32_t handle, uint64_t *poffset)
{
struct drm_gem_object *gem;
gem = drm_gem_object_lookup(dev, file_priv, handle);
if (gem) {
struct nouveau_bo *bo = gem->driver_private;
*poffset = bo->bo.addr_space_offset;
drm_gem_object_unreference_unlocked(gem);
return 0;
}
return -ENOENT;
}

View file

@ -433,6 +433,10 @@ static struct drm_driver driver = {
.gem_open_object = nouveau_gem_object_open, .gem_open_object = nouveau_gem_object_open,
.gem_close_object = nouveau_gem_object_close, .gem_close_object = nouveau_gem_object_close,
.dumb_create = nouveau_display_dumb_create,
.dumb_map_offset = nouveau_display_dumb_map_offset,
.dumb_destroy = nouveau_display_dumb_destroy,
.name = DRIVER_NAME, .name = DRIVER_NAME,
.desc = DRIVER_DESC, .desc = DRIVER_DESC,
#ifdef GIT_REVISION #ifdef GIT_REVISION

View file

@ -1418,6 +1418,12 @@ int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event); struct drm_pending_vblank_event *event);
int nouveau_finish_page_flip(struct nouveau_channel *, int nouveau_finish_page_flip(struct nouveau_channel *,
struct nouveau_page_flip_state *); struct nouveau_page_flip_state *);
int nouveau_display_dumb_create(struct drm_file *, struct drm_device *,
struct drm_mode_create_dumb *args);
int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *,
uint32_t handle, uint64_t *offset);
int nouveau_display_dumb_destroy(struct drm_file *, struct drm_device *,
uint32_t handle);
/* nv10_gpio.c */ /* nv10_gpio.c */
int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);

View file

@ -680,7 +680,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
return ret; return ret;
} }
ret = drm_mm_init(&chan->ramin_heap, base, size); ret = drm_mm_init(&chan->ramin_heap, base, size - base);
if (ret) { if (ret) {
NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret); NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
nouveau_gpuobj_ref(NULL, &chan->ramin); nouveau_gpuobj_ref(NULL, &chan->ramin);

View file

@ -67,7 +67,10 @@ nouveau_sgdma_clear(struct ttm_backend *be)
pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages], pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages],
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
} }
nvbe->unmap_pages = false;
} }
nvbe->pages = NULL;
} }
static void static void

View file

@ -616,7 +616,7 @@ nv50_display_unk10_handler(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nv50_display *disp = nv50_display(dev); struct nv50_display *disp = nv50_display(dev);
u32 unk30 = nv_rd32(dev, 0x610030), mc; u32 unk30 = nv_rd32(dev, 0x610030), mc;
int i, crtc, or, type = OUTPUT_ANY; int i, crtc, or = 0, type = OUTPUT_ANY;
NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
disp->irq.dcb = NULL; disp->irq.dcb = NULL;
@ -708,7 +708,7 @@ nv50_display_unk20_handler(struct drm_device *dev)
struct nv50_display *disp = nv50_display(dev); struct nv50_display *disp = nv50_display(dev);
u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc = 0; u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc = 0;
struct dcb_entry *dcb; struct dcb_entry *dcb;
int i, crtc, or, type = OUTPUT_ANY; int i, crtc, or = 0, type = OUTPUT_ANY;
NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
dcb = disp->irq.dcb; dcb = disp->irq.dcb;

View file

@ -381,6 +381,8 @@ nvc0_graph_init_gpc_0(struct drm_device *dev)
u8 tpnr[GPC_MAX]; u8 tpnr[GPC_MAX];
int i, gpc, tpc; int i, gpc, tpc;
nv_wr32(dev, TP_UNIT(0, 0, 0x5c), 1); /* affects TFB offset queries */
/* /*
* TP ROP UNKVAL(magic_not_rop_nr) * TP ROP UNKVAL(magic_not_rop_nr)
* 450: 4/0/0/0 2 3 * 450: 4/0/0/0 2 3

View file

@ -780,7 +780,7 @@ nvd0_sor_dpms(struct drm_encoder *encoder, int mode)
continue; continue;
if (nv_partner != nv_encoder && if (nv_partner != nv_encoder &&
nv_partner->dcb->or == nv_encoder->or) { nv_partner->dcb->or == nv_encoder->dcb->or) {
if (nv_partner->last_dpms == DRM_MODE_DPMS_ON) if (nv_partner->last_dpms == DRM_MODE_DPMS_ON)
return; return;
break; break;

View file

@ -1107,9 +1107,40 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
return -EINVAL; return -EINVAL;
} }
if (tiling_flags & RADEON_TILING_MACRO) if (tiling_flags & RADEON_TILING_MACRO) {
if (rdev->family >= CHIP_CAYMAN)
tmp = rdev->config.cayman.tile_config;
else
tmp = rdev->config.evergreen.tile_config;
switch ((tmp & 0xf0) >> 4) {
case 0: /* 4 banks */
fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK);
break;
case 1: /* 8 banks */
default:
fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK);
break;
case 2: /* 16 banks */
fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK);
break;
}
switch ((tmp & 0xf000) >> 12) {
case 0: /* 1KB rows */
default:
fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB);
break;
case 1: /* 2KB rows */
fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB);
break;
case 2: /* 4KB rows */
fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB);
break;
}
fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
else if (tiling_flags & RADEON_TILING_MICRO) } else if (tiling_flags & RADEON_TILING_MICRO)
fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
switch (radeon_crtc->crtc_id) { switch (radeon_crtc->crtc_id) {

View file

@ -82,6 +82,7 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
{ {
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset); u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset);
int i;
/* Lock the graphics update lock */ /* Lock the graphics update lock */
tmp |= EVERGREEN_GRPH_UPDATE_LOCK; tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
@ -99,7 +100,11 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
(u32)crtc_base); (u32)crtc_base);
/* Wait for update_pending to go high. */ /* Wait for update_pending to go high. */
while (!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)); for (i = 0; i < rdev->usec_timeout; i++) {
if (RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)
break;
udelay(1);
}
DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside vblank */ /* Unlock the lock, so double-buffering can take place inside vblank */

View file

@ -38,6 +38,7 @@ struct evergreen_cs_track {
u32 group_size; u32 group_size;
u32 nbanks; u32 nbanks;
u32 npipes; u32 npipes;
u32 row_size;
/* value we track */ /* value we track */
u32 nsamples; u32 nsamples;
u32 cb_color_base_last[12]; u32 cb_color_base_last[12];
@ -77,6 +78,44 @@ struct evergreen_cs_track {
struct radeon_bo *db_s_write_bo; struct radeon_bo *db_s_write_bo;
}; };
static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
{
if (tiling_flags & RADEON_TILING_MACRO)
return ARRAY_2D_TILED_THIN1;
else if (tiling_flags & RADEON_TILING_MICRO)
return ARRAY_1D_TILED_THIN1;
else
return ARRAY_LINEAR_GENERAL;
}
static u32 evergreen_cs_get_num_banks(u32 nbanks)
{
switch (nbanks) {
case 2:
return ADDR_SURF_2_BANK;
case 4:
return ADDR_SURF_4_BANK;
case 8:
default:
return ADDR_SURF_8_BANK;
case 16:
return ADDR_SURF_16_BANK;
}
}
static u32 evergreen_cs_get_tile_split(u32 row_size)
{
switch (row_size) {
case 1:
default:
return ADDR_SURF_TILE_SPLIT_1KB;
case 2:
return ADDR_SURF_TILE_SPLIT_2KB;
case 4:
return ADDR_SURF_TILE_SPLIT_4KB;
}
}
static void evergreen_cs_track_init(struct evergreen_cs_track *track) static void evergreen_cs_track_init(struct evergreen_cs_track *track)
{ {
int i; int i;
@ -490,12 +529,11 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
} }
ib[idx] &= ~Z_ARRAY_MODE(0xf); ib[idx] &= ~Z_ARRAY_MODE(0xf);
track->db_z_info &= ~Z_ARRAY_MODE(0xf); track->db_z_info &= ~Z_ARRAY_MODE(0xf);
ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); ib[idx] |= DB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
} else {
ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
} }
} }
break; break;
@ -618,13 +656,8 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
"0x%04X\n", reg); "0x%04X\n", reg);
return -EINVAL; return -EINVAL;
} }
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
} else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
}
} }
break; break;
case CB_COLOR8_INFO: case CB_COLOR8_INFO:
@ -640,13 +673,8 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
"0x%04X\n", reg); "0x%04X\n", reg);
return -EINVAL; return -EINVAL;
} }
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
} else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
}
} }
break; break;
case CB_COLOR0_PITCH: case CB_COLOR0_PITCH:
@ -701,6 +729,16 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
case CB_COLOR9_ATTRIB: case CB_COLOR9_ATTRIB:
case CB_COLOR10_ATTRIB: case CB_COLOR10_ATTRIB:
case CB_COLOR11_ATTRIB: case CB_COLOR11_ATTRIB:
r = evergreen_cs_packet_next_reloc(p, &reloc);
if (r) {
dev_warn(p->dev, "bad SET_CONTEXT_REG "
"0x%04X\n", reg);
return -EINVAL;
}
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
ib[idx] |= CB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
}
break; break;
case CB_COLOR0_DIM: case CB_COLOR0_DIM:
case CB_COLOR1_DIM: case CB_COLOR1_DIM:
@ -1318,10 +1356,14 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
} }
ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
if (!p->keep_tiling_flags) { if (!p->keep_tiling_flags) {
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) ib[idx+1+(i*8)+1] |=
ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); ib[idx+1+(i*8)+6] |=
TEX_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
ib[idx+1+(i*8)+7] |=
TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
}
} }
texture = reloc->robj; texture = reloc->robj;
/* tex mip base */ /* tex mip base */
@ -1422,6 +1464,7 @@ int evergreen_cs_parse(struct radeon_cs_parser *p)
{ {
struct radeon_cs_packet pkt; struct radeon_cs_packet pkt;
struct evergreen_cs_track *track; struct evergreen_cs_track *track;
u32 tmp;
int r; int r;
if (p->track == NULL) { if (p->track == NULL) {
@ -1430,9 +1473,63 @@ int evergreen_cs_parse(struct radeon_cs_parser *p)
if (track == NULL) if (track == NULL)
return -ENOMEM; return -ENOMEM;
evergreen_cs_track_init(track); evergreen_cs_track_init(track);
track->npipes = p->rdev->config.evergreen.tiling_npipes; if (p->rdev->family >= CHIP_CAYMAN)
track->nbanks = p->rdev->config.evergreen.tiling_nbanks; tmp = p->rdev->config.cayman.tile_config;
track->group_size = p->rdev->config.evergreen.tiling_group_size; else
tmp = p->rdev->config.evergreen.tile_config;
switch (tmp & 0xf) {
case 0:
track->npipes = 1;
break;
case 1:
default:
track->npipes = 2;
break;
case 2:
track->npipes = 4;
break;
case 3:
track->npipes = 8;
break;
}
switch ((tmp & 0xf0) >> 4) {
case 0:
track->nbanks = 4;
break;
case 1:
default:
track->nbanks = 8;
break;
case 2:
track->nbanks = 16;
break;
}
switch ((tmp & 0xf00) >> 8) {
case 0:
track->group_size = 256;
break;
case 1:
default:
track->group_size = 512;
break;
}
switch ((tmp & 0xf000) >> 12) {
case 0:
track->row_size = 1;
break;
case 1:
default:
track->row_size = 2;
break;
case 2:
track->row_size = 4;
break;
}
p->track = track; p->track = track;
} }
do { do {

View file

@ -42,6 +42,17 @@
# define EVERGREEN_GRPH_DEPTH_8BPP 0 # define EVERGREEN_GRPH_DEPTH_8BPP 0
# define EVERGREEN_GRPH_DEPTH_16BPP 1 # define EVERGREEN_GRPH_DEPTH_16BPP 1
# define EVERGREEN_GRPH_DEPTH_32BPP 2 # define EVERGREEN_GRPH_DEPTH_32BPP 2
# define EVERGREEN_GRPH_NUM_BANKS(x) (((x) & 0x3) << 2)
# define EVERGREEN_ADDR_SURF_2_BANK 0
# define EVERGREEN_ADDR_SURF_4_BANK 1
# define EVERGREEN_ADDR_SURF_8_BANK 2
# define EVERGREEN_ADDR_SURF_16_BANK 3
# define EVERGREEN_GRPH_Z(x) (((x) & 0x3) << 4)
# define EVERGREEN_GRPH_BANK_WIDTH(x) (((x) & 0x3) << 6)
# define EVERGREEN_ADDR_SURF_BANK_WIDTH_1 0
# define EVERGREEN_ADDR_SURF_BANK_WIDTH_2 1
# define EVERGREEN_ADDR_SURF_BANK_WIDTH_4 2
# define EVERGREEN_ADDR_SURF_BANK_WIDTH_8 3
# define EVERGREEN_GRPH_FORMAT(x) (((x) & 0x7) << 8) # define EVERGREEN_GRPH_FORMAT(x) (((x) & 0x7) << 8)
/* 8 BPP */ /* 8 BPP */
# define EVERGREEN_GRPH_FORMAT_INDEXED 0 # define EVERGREEN_GRPH_FORMAT_INDEXED 0
@ -61,6 +72,24 @@
# define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102 5 # define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102 5
# define EVERGREEN_GRPH_FORMAT_RGB111110 6 # define EVERGREEN_GRPH_FORMAT_RGB111110 6
# define EVERGREEN_GRPH_FORMAT_BGR101111 7 # define EVERGREEN_GRPH_FORMAT_BGR101111 7
# define EVERGREEN_GRPH_BANK_HEIGHT(x) (((x) & 0x3) << 11)
# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_1 0
# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_2 1
# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_4 2
# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_8 3
# define EVERGREEN_GRPH_TILE_SPLIT(x) (((x) & 0x7) << 13)
# define EVERGREEN_ADDR_SURF_TILE_SPLIT_64B 0
# define EVERGREEN_ADDR_SURF_TILE_SPLIT_128B 1
# define EVERGREEN_ADDR_SURF_TILE_SPLIT_256B 2
# define EVERGREEN_ADDR_SURF_TILE_SPLIT_512B 3
# define EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB 4
# define EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB 5
# define EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB 6
# define EVERGREEN_GRPH_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 18)
# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1 0
# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2 1
# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4 2
# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8 3
# define EVERGREEN_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20) # define EVERGREEN_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20)
# define EVERGREEN_GRPH_ARRAY_LINEAR_GENERAL 0 # define EVERGREEN_GRPH_ARRAY_LINEAR_GENERAL 0
# define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED 1 # define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED 1

View file

@ -899,6 +899,10 @@
#define DB_HTILE_DATA_BASE 0x28014 #define DB_HTILE_DATA_BASE 0x28014
#define DB_Z_INFO 0x28040 #define DB_Z_INFO 0x28040
# define Z_ARRAY_MODE(x) ((x) << 4) # define Z_ARRAY_MODE(x) ((x) << 4)
# define DB_TILE_SPLIT(x) (((x) & 0x7) << 8)
# define DB_NUM_BANKS(x) (((x) & 0x3) << 12)
# define DB_BANK_WIDTH(x) (((x) & 0x3) << 16)
# define DB_BANK_HEIGHT(x) (((x) & 0x3) << 20)
#define DB_STENCIL_INFO 0x28044 #define DB_STENCIL_INFO 0x28044
#define DB_Z_READ_BASE 0x28048 #define DB_Z_READ_BASE 0x28048
#define DB_STENCIL_READ_BASE 0x2804c #define DB_STENCIL_READ_BASE 0x2804c
@ -951,6 +955,29 @@
# define CB_SF_EXPORT_FULL 0 # define CB_SF_EXPORT_FULL 0
# define CB_SF_EXPORT_NORM 1 # define CB_SF_EXPORT_NORM 1
#define CB_COLOR0_ATTRIB 0x28c74 #define CB_COLOR0_ATTRIB 0x28c74
# define CB_TILE_SPLIT(x) (((x) & 0x7) << 5)
# define ADDR_SURF_TILE_SPLIT_64B 0
# define ADDR_SURF_TILE_SPLIT_128B 1
# define ADDR_SURF_TILE_SPLIT_256B 2
# define ADDR_SURF_TILE_SPLIT_512B 3
# define ADDR_SURF_TILE_SPLIT_1KB 4
# define ADDR_SURF_TILE_SPLIT_2KB 5
# define ADDR_SURF_TILE_SPLIT_4KB 6
# define CB_NUM_BANKS(x) (((x) & 0x3) << 10)
# define ADDR_SURF_2_BANK 0
# define ADDR_SURF_4_BANK 1
# define ADDR_SURF_8_BANK 2
# define ADDR_SURF_16_BANK 3
# define CB_BANK_WIDTH(x) (((x) & 0x3) << 13)
# define ADDR_SURF_BANK_WIDTH_1 0
# define ADDR_SURF_BANK_WIDTH_2 1
# define ADDR_SURF_BANK_WIDTH_4 2
# define ADDR_SURF_BANK_WIDTH_8 3
# define CB_BANK_HEIGHT(x) (((x) & 0x3) << 16)
# define ADDR_SURF_BANK_HEIGHT_1 0
# define ADDR_SURF_BANK_HEIGHT_2 1
# define ADDR_SURF_BANK_HEIGHT_4 2
# define ADDR_SURF_BANK_HEIGHT_8 3
#define CB_COLOR0_DIM 0x28c78 #define CB_COLOR0_DIM 0x28c78
/* only CB0-7 blocks have these regs */ /* only CB0-7 blocks have these regs */
#define CB_COLOR0_CMASK 0x28c7c #define CB_COLOR0_CMASK 0x28c7c
@ -1137,7 +1164,11 @@
# define SQ_SEL_1 5 # define SQ_SEL_1 5
#define SQ_TEX_RESOURCE_WORD5_0 0x30014 #define SQ_TEX_RESOURCE_WORD5_0 0x30014
#define SQ_TEX_RESOURCE_WORD6_0 0x30018 #define SQ_TEX_RESOURCE_WORD6_0 0x30018
# define TEX_TILE_SPLIT(x) (((x) & 0x7) << 29)
#define SQ_TEX_RESOURCE_WORD7_0 0x3001c #define SQ_TEX_RESOURCE_WORD7_0 0x3001c
# define TEX_BANK_WIDTH(x) (((x) & 0x3) << 8)
# define TEX_BANK_HEIGHT(x) (((x) & 0x3) << 10)
# define TEX_NUM_BANKS(x) (((x) & 0x3) << 16)
#define SQ_VTX_CONSTANT_WORD0_0 0x30000 #define SQ_VTX_CONSTANT_WORD0_0 0x30000
#define SQ_VTX_CONSTANT_WORD1_0 0x30004 #define SQ_VTX_CONSTANT_WORD1_0 0x30004

View file

@ -187,13 +187,18 @@ u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
{ {
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK; u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
int i;
/* Lock the graphics update lock */ /* Lock the graphics update lock */
/* update the scanout addresses */ /* update the scanout addresses */
WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
/* Wait for update_pending to go high. */ /* Wait for update_pending to go high. */
while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)); for (i = 0; i < rdev->usec_timeout; i++) {
if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)
break;
udelay(1);
}
DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside vblank */ /* Unlock the lock, so double-buffering can take place inside vblank */

View file

@ -35,7 +35,8 @@ static int radeon_atif_call(acpi_handle handle)
/* Fail only if calling the method fails and ATIF is supported */ /* Fail only if calling the method fails and ATIF is supported */
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
printk(KERN_DEBUG "failed to evaluate ATIF got %s\n", acpi_format_exception(status)); DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
acpi_format_exception(status));
kfree(buffer.pointer); kfree(buffer.pointer);
return 1; return 1;
} }
@ -50,13 +51,13 @@ int radeon_acpi_init(struct radeon_device *rdev)
acpi_handle handle; acpi_handle handle;
int ret; int ret;
/* No need to proceed if we're sure that ATIF is not supported */
if (!ASIC_IS_AVIVO(rdev) || !rdev->bios)
return 0;
/* Get the device handle */ /* Get the device handle */
handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
/* No need to proceed if we're sure that ATIF is not supported */
if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle)
return 0;
/* Call the ATIF method */ /* Call the ATIF method */
ret = radeon_atif_call(handle); ret = radeon_atif_call(handle);
if (ret) if (ret)

View file

@ -62,6 +62,7 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
{ {
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
int i;
/* Lock the graphics update lock */ /* Lock the graphics update lock */
tmp |= AVIVO_D1GRPH_UPDATE_LOCK; tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
@ -74,7 +75,11 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
(u32)crtc_base); (u32)crtc_base);
/* Wait for update_pending to go high. */ /* Wait for update_pending to go high. */
while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)); for (i = 0; i < rdev->usec_timeout; i++) {
if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
break;
udelay(1);
}
DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside vblank */ /* Unlock the lock, so double-buffering can take place inside vblank */

View file

@ -47,6 +47,7 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
{ {
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
int i;
/* Lock the graphics update lock */ /* Lock the graphics update lock */
tmp |= AVIVO_D1GRPH_UPDATE_LOCK; tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
@ -66,7 +67,11 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
(u32)crtc_base); (u32)crtc_base);
/* Wait for update_pending to go high. */ /* Wait for update_pending to go high. */
while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)); for (i = 0; i < rdev->usec_timeout; i++) {
if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
break;
udelay(1);
}
DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside vblank */ /* Unlock the lock, so double-buffering can take place inside vblank */

View file

@ -1809,7 +1809,8 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
} }
rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
rects = kzalloc(rects_size, GFP_KERNEL); rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect),
GFP_KERNEL);
if (unlikely(!rects)) { if (unlikely(!rects)) {
ret = -ENOMEM; ret = -ENOMEM;
goto out_unlock; goto out_unlock;
@ -1824,10 +1825,10 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
} }
for (i = 0; i < arg->num_outputs; ++i) { for (i = 0; i < arg->num_outputs; ++i) {
if (rects->x < 0 || if (rects[i].x < 0 ||
rects->y < 0 || rects[i].y < 0 ||
rects->x + rects->w > mode_config->max_width || rects[i].x + rects[i].w > mode_config->max_width ||
rects->y + rects->h > mode_config->max_height) { rects[i].y + rects[i].h > mode_config->max_height) {
DRM_ERROR("Invalid GUI layout.\n"); DRM_ERROR("Invalid GUI layout.\n");
ret = -EINVAL; ret = -EINVAL;
goto out_free; goto out_free;

View file

@ -197,6 +197,14 @@
{0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6778, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6778, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6841, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6842, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6843, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6849, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6858, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6859, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6889, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6889, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \