|
@@ -198,6 +198,22 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
|
|
|
/******************************************************************************
|
|
|
* EVO channel helpers
|
|
|
*****************************************************************************/
|
|
|
+static void
|
|
|
+evo_flush(struct nv50_dmac *dmac)
|
|
|
+{
|
|
|
+ /* Push buffer fetches are not coherent with BAR1, we need to ensure
|
|
|
+ * writes have been flushed right through to VRAM before writing PUT.
|
|
|
+ */
|
|
|
+ if (dmac->push.type & NVIF_MEM_VRAM) {
|
|
|
+ struct nvif_device *device = dmac->base.device;
|
|
|
+ nvif_wr32(&device->object, 0x070000, 0x00000001);
|
|
|
+ nvif_msec(device, 2000,
|
|
|
+ if (!(nvif_rd32(&device->object, 0x070000) & 0x00000002))
|
|
|
+ break;
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
u32 *
|
|
|
evo_wait(struct nv50_dmac *evoc, int nr)
|
|
|
{
|
|
@@ -208,6 +224,7 @@ evo_wait(struct nv50_dmac *evoc, int nr)
|
|
|
mutex_lock(&dmac->lock);
|
|
|
if (put + nr >= (PAGE_SIZE / 4) - 8) {
|
|
|
dmac->ptr[put] = 0x20000000;
|
|
|
+ evo_flush(dmac);
|
|
|
|
|
|
nvif_wr32(&dmac->base.user, 0x0000, 0x00000000);
|
|
|
if (nvif_msec(device, 2000,
|
|
@@ -230,17 +247,7 @@ evo_kick(u32 *push, struct nv50_dmac *evoc)
|
|
|
{
|
|
|
struct nv50_dmac *dmac = evoc;
|
|
|
|
|
|
- /* Push buffer fetches are not coherent with BAR1, we need to ensure
|
|
|
- * writes have been flushed right through to VRAM before writing PUT.
|
|
|
- */
|
|
|
- if (dmac->push.type & NVIF_MEM_VRAM) {
|
|
|
- struct nvif_device *device = dmac->base.device;
|
|
|
- nvif_wr32(&device->object, 0x070000, 0x00000001);
|
|
|
- nvif_msec(device, 2000,
|
|
|
- if (!(nvif_rd32(&device->object, 0x070000) & 0x00000002))
|
|
|
- break;
|
|
|
- );
|
|
|
- }
|
|
|
+ evo_flush(dmac);
|
|
|
|
|
|
nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2);
|
|
|
mutex_unlock(&dmac->lock);
|
|
@@ -1264,6 +1271,7 @@ nv50_mstm_del(struct nv50_mstm **pmstm)
|
|
|
{
|
|
|
struct nv50_mstm *mstm = *pmstm;
|
|
|
if (mstm) {
|
|
|
+ drm_dp_mst_topology_mgr_destroy(&mstm->mgr);
|
|
|
kfree(*pmstm);
|
|
|
*pmstm = NULL;
|
|
|
}
|