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
Pull drm fixes from Dave Airlie:
 "Ben was on holidays for a week so a few nouveau regression fixes
  backed up, but they all seem necessary.

  Otherwise one i915 and one gma500 fix"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  gma500: Fix SDVO turning off randomly
  drm/nv04/disp: fix framebuffer pin refcounting
  drm/nouveau/mc: fix race condition between constructor and request_irq()
  drm/nouveau: fix reclocking on nv40
  drm/nouveau/ltcg: fix allocating memory as free
  drm/nouveau/ltcg: fix ltcg memory initialization after suspend
  drm/nouveau/fb: fix null derefs in nv49 and nv4e init
  drm/i915: Invalidate TLBs for the rings after a reset
  • Loading branch information
Linus Torvalds committed Aug 23, 2013
2 parents 41a00f7 + 4dd17ee commit f07823e
Show file tree
Hide file tree
Showing 18 changed files with 114 additions and 49 deletions.
3 changes: 2 additions & 1 deletion drivers/gpu/drm/gma500/psb_intel_sdvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,8 @@ static bool psb_intel_sdvo_read_response(struct psb_intel_sdvo *psb_intel_sdvo,
&status))
goto log_fail;

while (status == SDVO_CMD_STATUS_PENDING && retry--) {
while ((status == SDVO_CMD_STATUS_PENDING ||
status == SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED) && retry--) {
udelay(15);
if (!psb_intel_sdvo_read_byte(psb_intel_sdvo,
SDVO_I2C_CMD_STATUS,
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,8 @@
will not assert AGPBUSY# and will only
be delivered when out of C3. */
#define INSTPM_FORCE_ORDERING (1<<7) /* GEN6+ */
#define INSTPM_TLB_INVALIDATE (1<<9)
#define INSTPM_SYNC_FLUSH (1<<5)
#define ACTHD 0x020c8
#define FW_BLC 0x020d8
#define FW_BLC2 0x020dc
Expand Down
12 changes: 12 additions & 0 deletions drivers/gpu/drm/i915/intel_ringbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,18 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring)

I915_WRITE(mmio, (u32)ring->status_page.gfx_addr);
POSTING_READ(mmio);

/* Flush the TLB for this page */
if (INTEL_INFO(dev)->gen >= 6) {
u32 reg = RING_INSTPM(ring->mmio_base);
I915_WRITE(reg,
_MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE |
INSTPM_SYNC_FLUSH));
if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0,
1000))
DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n",
ring->name);
}
}

static int
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/nouveau/core/core/mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ nouveau_mm_head(struct nouveau_mm *mm, u8 type, u32 size_max, u32 size_min,
u32 splitoff;
u32 s, e;

BUG_ON(!type);

list_for_each_entry(this, &mm->free, fl_entry) {
e = this->offset + this->length;
s = this->offset;
Expand Down Expand Up @@ -162,6 +164,8 @@ nouveau_mm_tail(struct nouveau_mm *mm, u8 type, u32 size_max, u32 size_min,
struct nouveau_mm_node *prev, *this, *next;
u32 mask = align - 1;

BUG_ON(!type);

list_for_each_entry_reverse(this, &mm->free, fl_entry) {
u32 e = this->offset + this->length;
u32 s = this->offset;
Expand Down
7 changes: 4 additions & 3 deletions drivers/gpu/drm/nouveau/core/include/subdev/mc.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ nouveau_mc(void *obj)
return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MC];
}

#define nouveau_mc_create(p,e,o,d) \
nouveau_mc_create_((p), (e), (o), sizeof(**d), (void **)d)
#define nouveau_mc_create(p,e,o,m,d) \
nouveau_mc_create_((p), (e), (o), (m), sizeof(**d), (void **)d)
#define nouveau_mc_destroy(p) ({ \
struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc)); \
})
Expand All @@ -33,7 +33,8 @@ nouveau_mc(void *obj)
})

int nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, int, void **);
struct nouveau_oclass *, const struct nouveau_mc_intr *,
int, void **);
void _nouveau_mc_dtor(struct nouveau_object *);
int _nouveau_mc_init(struct nouveau_object *);
int _nouveau_mc_fini(struct nouveau_object *, bool);
Expand Down
12 changes: 6 additions & 6 deletions drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;

switch (pfb914 & 0x00000003) {
case 0x00000000: pfb->ram->type = NV_MEM_TYPE_DDR1; break;
case 0x00000001: pfb->ram->type = NV_MEM_TYPE_DDR2; break;
case 0x00000002: pfb->ram->type = NV_MEM_TYPE_GDDR3; break;
case 0x00000000: ram->type = NV_MEM_TYPE_DDR1; break;
case 0x00000001: ram->type = NV_MEM_TYPE_DDR2; break;
case 0x00000002: ram->type = NV_MEM_TYPE_GDDR3; break;
case 0x00000003: break;
}

pfb->ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
pfb->ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
pfb->ram->tags = nv_rd32(pfb, 0x100320);
ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
ram->tags = nv_rd32(pfb, 0x100320);
return 0;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/nouveau/core/subdev/fb/ramnv4e.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ nv4e_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;

pfb->ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
pfb->ram->type = NV_MEM_TYPE_STOLEN;
ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
ram->type = NV_MEM_TYPE_STOLEN;
return 0;
}

Expand Down
34 changes: 24 additions & 10 deletions drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ struct nvc0_ltcg_priv {
struct nouveau_ltcg base;
u32 part_nr;
u32 subp_nr;
struct nouveau_mm tags;
u32 num_tags;
u32 tag_base;
struct nouveau_mm tags;
struct nouveau_mm_node *tag_ram;
};

Expand Down Expand Up @@ -117,10 +118,6 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
u32 tag_size, tag_margin, tag_align;
int ret;

nv_wr32(priv, 0x17e8d8, priv->part_nr);
if (nv_device(pfb)->card_type >= NV_E0)
nv_wr32(priv, 0x17e000, priv->part_nr);

/* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
priv->num_tags = (pfb->ram->size >> 17) / 4;
if (priv->num_tags > (1 << 17))
Expand All @@ -142,7 +139,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
tag_size += tag_align;
tag_size = (tag_size + 0xfff) >> 12; /* round up */

ret = nouveau_mm_tail(&pfb->vram, 0, tag_size, tag_size, 1,
ret = nouveau_mm_tail(&pfb->vram, 1, tag_size, tag_size, 1,
&priv->tag_ram);
if (ret) {
priv->num_tags = 0;
Expand All @@ -152,7 +149,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
tag_base += tag_align - 1;
ret = do_div(tag_base, tag_align);

nv_wr32(priv, 0x17e8d4, tag_base);
priv->tag_base = tag_base;
}
ret = nouveau_mm_init(&priv->tags, 0, priv->num_tags, 1);

Expand Down Expand Up @@ -182,8 +179,6 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28;

nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */

ret = nvc0_ltcg_init_tag_ram(pfb, priv);
if (ret)
return ret;
Expand All @@ -209,13 +204,32 @@ nvc0_ltcg_dtor(struct nouveau_object *object)
nouveau_ltcg_destroy(ltcg);
}

static int
nvc0_ltcg_init(struct nouveau_object *object)
{
struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object;
struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
int ret;

ret = nouveau_ltcg_init(ltcg);
if (ret)
return ret;

nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
nv_wr32(priv, 0x17e8d8, priv->part_nr);
if (nv_device(ltcg)->card_type >= NV_E0)
nv_wr32(priv, 0x17e000, priv->part_nr);
nv_wr32(priv, 0x17e8d4, priv->tag_base);
return 0;
}

struct nouveau_oclass
nvc0_ltcg_oclass = {
.handle = NV_SUBDEV(LTCG, 0xc0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_ltcg_ctor,
.dtor = nvc0_ltcg_dtor,
.init = _nouveau_ltcg_init,
.init = nvc0_ltcg_init,
.fini = _nouveau_ltcg_fini,
},
};
6 changes: 5 additions & 1 deletion drivers/gpu/drm/nouveau/core/subdev/mc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ _nouveau_mc_dtor(struct nouveau_object *object)

int
nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, int length, void **pobject)
struct nouveau_oclass *oclass,
const struct nouveau_mc_intr *intr_map,
int length, void **pobject)
{
struct nouveau_device *device = nv_device(parent);
struct nouveau_mc *pmc;
Expand All @@ -92,6 +94,8 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;

pmc->intr_map = intr_map;

ret = request_irq(device->pdev->irq, nouveau_mc_intr,
IRQF_SHARED, "nouveau", pmc);
if (ret < 0)
Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,11 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv04_mc_priv *priv;
int ret;

ret = nouveau_mc_create(parent, engine, oclass, &priv);
ret = nouveau_mc_create(parent, engine, oclass, nv04_mc_intr, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;

priv->base.intr_map = nv04_mc_intr;
return 0;
}

Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,11 @@ nv44_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv44_mc_priv *priv;
int ret;

ret = nouveau_mc_create(parent, engine, oclass, &priv);
ret = nouveau_mc_create(parent, engine, oclass, nv04_mc_intr, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;

priv->base.intr_map = nv04_mc_intr;
return 0;
}

Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,11 @@ nv50_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv50_mc_priv *priv;
int ret;

ret = nouveau_mc_create(parent, engine, oclass, &priv);
ret = nouveau_mc_create(parent, engine, oclass, nv50_mc_intr, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;

priv->base.intr_map = nv50_mc_intr;
return 0;
}

Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,11 @@ nv98_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv98_mc_priv *priv;
int ret;

ret = nouveau_mc_create(parent, engine, oclass, &priv);
ret = nouveau_mc_create(parent, engine, oclass, nv98_mc_intr, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;

priv->base.intr_map = nv98_mc_intr;
return 0;
}

Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,11 @@ nvc0_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nvc0_mc_priv *priv;
int ret;

ret = nouveau_mc_create(parent, engine, oclass, &priv);
ret = nouveau_mc_create(parent, engine, oclass, nvc0_mc_intr, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;

priv->base.intr_map = nvc0_mc_intr;
return 0;
}

Expand Down
Loading

0 comments on commit f07823e

Please sign in to comment.