Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Browse files Browse the repository at this point in the history
* '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
  • Loading branch information
Linus Torvalds committed Dec 2, 2011
2 parents 0efebaa + bab9efc commit c2b5adb
Show file tree
Hide file tree
Showing 20 changed files with 349 additions and 48 deletions.
27 changes: 25 additions & 2 deletions drivers/gpu/drm/drm_crtc_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,30 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
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
* @crtc: CRTC to setup
Expand Down Expand Up @@ -510,8 +534,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
(int)set->num_connectors, set->x, set->y);
} else {
DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
set->mode = NULL;
set->num_connectors = 0;
return drm_crtc_helper_disable(set->crtc);
}

dev = set->crtc->dev;
Expand Down
45 changes: 45 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,3 +369,48 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
spin_unlock_irqrestore(&dev->event_lock, flags);
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;
}
4 changes: 4 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,10 @@ static struct drm_driver driver = {
.gem_open_object = nouveau_gem_object_open,
.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,
.desc = DRIVER_DESC,
#ifdef GIT_REVISION
Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,12 @@ int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event);
int nouveau_finish_page_flip(struct nouveau_channel *,
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 */
int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/nouveau_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
return ret;
}

ret = drm_mm_init(&chan->ramin_heap, base, size);
ret = drm_mm_init(&chan->ramin_heap, base, size - base);
if (ret) {
NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
nouveau_gpuobj_ref(NULL, &chan->ramin);
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_sgdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ nouveau_sgdma_clear(struct ttm_backend *be)
pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages],
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
}
nvbe->unmap_pages = false;
}

nvbe->pages = NULL;
}

static void
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/nouveau/nv50_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ nv50_display_unk10_handler(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nv50_display *disp = nv50_display(dev);
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);
disp->irq.dcb = NULL;
Expand Down Expand Up @@ -708,7 +708,7 @@ nv50_display_unk20_handler(struct drm_device *dev)
struct nv50_display *disp = nv50_display(dev);
u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc = 0;
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);
dcb = disp->irq.dcb;
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/nouveau/nvc0_graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,8 @@ nvc0_graph_init_gpc_0(struct drm_device *dev)
u8 tpnr[GPC_MAX];
int i, gpc, tpc;

nv_wr32(dev, TP_UNIT(0, 0, 0x5c), 1); /* affects TFB offset queries */

/*
* TP ROP UNKVAL(magic_not_rop_nr)
* 450: 4/0/0/0 2 3
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/nvd0_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ nvd0_sor_dpms(struct drm_encoder *encoder, int mode)
continue;

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)
return;
break;
Expand Down
35 changes: 33 additions & 2 deletions drivers/gpu/drm/radeon/atombios_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1107,9 +1107,40 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
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);
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);

switch (radeon_crtc->crtc_id) {
Expand Down
7 changes: 6 additions & 1 deletion drivers/gpu/drm/radeon/evergreen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset);
int i;

/* Lock the graphics update lock */
tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
Expand All @@ -99,7 +100,11 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
(u32)crtc_base);

/* 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");

/* Unlock the lock, so double-buffering can take place inside vblank */
Expand Down
Loading

0 comments on commit c2b5adb

Please sign in to comment.