Skip to content

Commit

Permalink
Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/airlied/drm-2.6

* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm/radeon/kms: fix bo's fence association
  drm/radeon/kms: fix indirect buffer management V2
  drm/edid: Fix interlaced detailed timings to be frame size, not field.
  drm/vmwgfx: Use fb handover mechanism instead of stealth mode.
  drm/radeon/kms: use udelay for short delays
  drm/nouveau: Force TV encoder DPMS reinit after resume.
  drm/nouveau: use mutex for vbios lock
  • Loading branch information
Linus Torvalds committed Feb 18, 2010
2 parents ab320af + 6b15835 commit 86404ab
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 142 deletions.
47 changes: 45 additions & 2 deletions drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,50 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
return mode;
}

/*
* EDID is delightfully ambiguous about how interlaced modes are to be
* encoded. Our internal representation is of frame height, but some
* HDTV detailed timings are encoded as field height.
*
* The format list here is from CEA, in frame size. Technically we
* should be checking refresh rate too. Whatever.
*/
static void
drm_mode_do_interlace_quirk(struct drm_display_mode *mode,
struct detailed_pixel_timing *pt)
{
int i;
static const struct {
int w, h;
} cea_interlaced[] = {
{ 1920, 1080 },
{ 720, 480 },
{ 1440, 480 },
{ 2880, 480 },
{ 720, 576 },
{ 1440, 576 },
{ 2880, 576 },
};
static const int n_sizes =
sizeof(cea_interlaced)/sizeof(cea_interlaced[0]);

if (!(pt->misc & DRM_EDID_PT_INTERLACED))
return;

for (i = 0; i < n_sizes; i++) {
if ((mode->hdisplay == cea_interlaced[i].w) &&
(mode->vdisplay == cea_interlaced[i].h / 2)) {
mode->vdisplay *= 2;
mode->vsync_start *= 2;
mode->vsync_end *= 2;
mode->vtotal *= 2;
mode->vtotal |= 1;
}
}

mode->flags |= DRM_MODE_FLAG_INTERLACE;
}

/**
* drm_mode_detailed - create a new mode from an EDID detailed timing section
* @dev: DRM device (needed to create new mode)
Expand Down Expand Up @@ -680,8 +724,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,

drm_mode_set_name(mode);

if (pt->misc & DRM_EDID_PT_INTERLACED)
mode->flags |= DRM_MODE_FLAG_INTERLACE;
drm_mode_do_interlace_quirk(mode, pt);

if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE;
Expand Down
7 changes: 3 additions & 4 deletions drivers/gpu/drm/nouveau/nouveau_bios.c
Original file line number Diff line number Diff line change
Expand Up @@ -5861,13 +5861,12 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table,
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nvbios *bios = &dev_priv->VBIOS;
struct init_exec iexec = { true, false };
unsigned long flags;

spin_lock_irqsave(&bios->lock, flags);
mutex_lock(&bios->lock);
bios->display.output = dcbent;
parse_init_table(bios, table, &iexec);
bios->display.output = NULL;
spin_unlock_irqrestore(&bios->lock, flags);
mutex_unlock(&bios->lock);
}

static bool NVInitVBIOS(struct drm_device *dev)
Expand All @@ -5876,7 +5875,7 @@ static bool NVInitVBIOS(struct drm_device *dev)
struct nvbios *bios = &dev_priv->VBIOS;

memset(bios, 0, sizeof(struct nvbios));
spin_lock_init(&bios->lock);
mutex_init(&bios->lock);
bios->dev = dev;

if (!NVShadowVBIOS(dev, bios->data))
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/nouveau_bios.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ struct nvbios {
struct drm_device *dev;
struct nouveau_bios_info pub;

spinlock_t lock;
struct mutex lock;

uint8_t data[NV_PROM_SIZE];
unsigned int length;
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/nouveau/nv17_tv.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,8 @@ static void nv17_tv_restore(struct drm_encoder *encoder)
nouveau_encoder(encoder)->restore.output);

nv17_tv_state_load(dev, &to_tv_enc(encoder)->saved_state);

nouveau_encoder(encoder)->last_dpms = NV_DPMS_CLEARED;
}

static int nv17_tv_create_resources(struct drm_encoder *encoder,
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/radeon/atom.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ static void atom_op_delay(atom_exec_context *ctx, int *ptr, int arg)
uint8_t count = U8((*ptr)++);
SDEBUG(" count: %d\n", count);
if (arg == ATOM_UNIT_MICROSEC)
schedule_timeout_uninterruptible(usecs_to_jiffies(count));
udelay(count);
else
schedule_timeout_uninterruptible(msecs_to_jiffies(count));
}
Expand Down
3 changes: 0 additions & 3 deletions drivers/gpu/drm/radeon/r600_blit_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,6 @@ int r600_vb_ib_get(struct radeon_device *rdev)
void r600_vb_ib_put(struct radeon_device *rdev)
{
radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence);
mutex_lock(&rdev->ib_pool.mutex);
list_add_tail(&rdev->r600_blit.vb_ib->list, &rdev->ib_pool.scheduled_ibs);
mutex_unlock(&rdev->ib_pool.mutex);
radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
}

Expand Down
9 changes: 5 additions & 4 deletions drivers/gpu/drm/radeon/radeon.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ extern int radeon_audio;
* symbol;
*/
#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
/* RADEON_IB_POOL_SIZE must be a power of 2 */
#define RADEON_IB_POOL_SIZE 16
#define RADEON_DEBUGFS_MAX_NUM_FILES 32
#define RADEONFB_CONN_LIMIT 4
Expand Down Expand Up @@ -363,11 +364,12 @@ void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev);
*/
struct radeon_ib {
struct list_head list;
unsigned long idx;
unsigned idx;
uint64_t gpu_addr;
struct radeon_fence *fence;
uint32_t *ptr;
uint32_t *ptr;
uint32_t length_dw;
bool free;
};

/*
Expand All @@ -377,10 +379,9 @@ struct radeon_ib {
struct radeon_ib_pool {
struct mutex mutex;
struct radeon_bo *robj;
struct list_head scheduled_ibs;
struct radeon_ib ibs[RADEON_IB_POOL_SIZE];
bool ready;
DECLARE_BITMAP(alloc_bm, RADEON_IB_POOL_SIZE);
unsigned head_id;
};

struct radeon_cp {
Expand Down
10 changes: 4 additions & 6 deletions drivers/gpu/drm/radeon/radeon_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
&p->validated);
}
}
return radeon_bo_list_validate(&p->validated, p->ib->fence);
return radeon_bo_list_validate(&p->validated);
}

int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
Expand Down Expand Up @@ -189,12 +189,10 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
{
unsigned i;

if (error && parser->ib) {
radeon_bo_list_unvalidate(&parser->validated,
parser->ib->fence);
} else {
radeon_bo_list_unreserve(&parser->validated);
if (!error && parser->ib) {
radeon_bo_list_fence(&parser->validated, parser->ib->fence);
}
radeon_bo_list_unreserve(&parser->validated);
for (i = 0; i < parser->nrelocs; i++) {
if (parser->relocs[i].gobj) {
mutex_lock(&parser->rdev->ddev->struct_mutex);
Expand Down
36 changes: 15 additions & 21 deletions drivers/gpu/drm/radeon/radeon_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,10 @@ void radeon_bo_list_unreserve(struct list_head *head)
}
}

int radeon_bo_list_validate(struct list_head *head, void *fence)
int radeon_bo_list_validate(struct list_head *head)
{
struct radeon_bo_list *lobj;
struct radeon_bo *bo;
struct radeon_fence *old_fence = NULL;
int r;

r = radeon_bo_list_reserve(head);
Expand All @@ -334,32 +333,27 @@ int radeon_bo_list_validate(struct list_head *head, void *fence)
}
lobj->gpu_offset = radeon_bo_gpu_offset(bo);
lobj->tiling_flags = bo->tiling_flags;
if (fence) {
old_fence = (struct radeon_fence *)bo->tbo.sync_obj;
bo->tbo.sync_obj = radeon_fence_ref(fence);
bo->tbo.sync_obj_arg = NULL;
}
if (old_fence) {
radeon_fence_unref(&old_fence);
}
}
return 0;
}

void radeon_bo_list_unvalidate(struct list_head *head, void *fence)
void radeon_bo_list_fence(struct list_head *head, void *fence)
{
struct radeon_bo_list *lobj;
struct radeon_fence *old_fence;

if (fence)
list_for_each_entry(lobj, head, list) {
old_fence = to_radeon_fence(lobj->bo->tbo.sync_obj);
if (old_fence == fence) {
lobj->bo->tbo.sync_obj = NULL;
radeon_fence_unref(&old_fence);
}
struct radeon_bo *bo;
struct radeon_fence *old_fence = NULL;

list_for_each_entry(lobj, head, list) {
bo = lobj->bo;
spin_lock(&bo->tbo.lock);
old_fence = (struct radeon_fence *)bo->tbo.sync_obj;
bo->tbo.sync_obj = radeon_fence_ref(fence);
bo->tbo.sync_obj_arg = NULL;
spin_unlock(&bo->tbo.lock);
if (old_fence) {
radeon_fence_unref(&old_fence);
}
radeon_bo_list_unreserve(head);
}
}

int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/radeon/radeon_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj,
struct list_head *head);
extern int radeon_bo_list_reserve(struct list_head *head);
extern void radeon_bo_list_unreserve(struct list_head *head);
extern int radeon_bo_list_validate(struct list_head *head, void *fence);
extern void radeon_bo_list_unvalidate(struct list_head *head, void *fence);
extern int radeon_bo_list_validate(struct list_head *head);
extern void radeon_bo_list_fence(struct list_head *head, void *fence);
extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
struct vm_area_struct *vma);
extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
Expand Down
Loading

0 comments on commit 86404ab

Please sign in to comment.