void (*disable)(struct drm_device *);
void (*enable)(struct drm_device *);
bool (*reassign)(struct drm_device *, bool enable);
+ bool (*cache_flush)(struct drm_device *dev);
+ bool (*cache_pull)(struct drm_device *dev, bool enable);
int (*channel_id)(struct drm_device *);
extern void nv04_fifo_disable(struct drm_device *);
extern void nv04_fifo_enable(struct drm_device *);
extern bool nv04_fifo_reassign(struct drm_device *, bool);
+extern bool nv04_fifo_cache_flush(struct drm_device *);
+extern bool nv04_fifo_cache_pull(struct drm_device *, bool);
extern int nv04_fifo_channel_id(struct drm_device *);
extern int nv04_fifo_create_context(struct nouveau_channel *);
extern void nv04_fifo_destroy_context(struct nouveau_channel *);
engine->fifo.disable = nv04_fifo_disable;
engine->fifo.enable = nv04_fifo_enable;
engine->fifo.reassign = nv04_fifo_reassign;
+ engine->fifo.cache_flush = nv04_fifo_cache_flush;
+ engine->fifo.cache_pull = nv04_fifo_cache_pull;
engine->fifo.channel_id = nv04_fifo_channel_id;
engine->fifo.create_context = nv04_fifo_create_context;
engine->fifo.destroy_context = nv04_fifo_destroy_context;
engine->fifo.disable = nv04_fifo_disable;
engine->fifo.enable = nv04_fifo_enable;
engine->fifo.reassign = nv04_fifo_reassign;
+ engine->fifo.cache_flush = nv04_fifo_cache_flush;
+ engine->fifo.cache_pull = nv04_fifo_cache_pull;
engine->fifo.channel_id = nv10_fifo_channel_id;
engine->fifo.create_context = nv10_fifo_create_context;
engine->fifo.destroy_context = nv10_fifo_destroy_context;
engine->fifo.disable = nv04_fifo_disable;
engine->fifo.enable = nv04_fifo_enable;
engine->fifo.reassign = nv04_fifo_reassign;
+ engine->fifo.cache_flush = nv04_fifo_cache_flush;
+ engine->fifo.cache_pull = nv04_fifo_cache_pull;
engine->fifo.channel_id = nv10_fifo_channel_id;
engine->fifo.create_context = nv10_fifo_create_context;
engine->fifo.destroy_context = nv10_fifo_destroy_context;
engine->fifo.disable = nv04_fifo_disable;
engine->fifo.enable = nv04_fifo_enable;
engine->fifo.reassign = nv04_fifo_reassign;
+ engine->fifo.cache_flush = nv04_fifo_cache_flush;
+ engine->fifo.cache_pull = nv04_fifo_cache_pull;
engine->fifo.channel_id = nv10_fifo_channel_id;
engine->fifo.create_context = nv10_fifo_create_context;
engine->fifo.destroy_context = nv10_fifo_destroy_context;
engine->fifo.disable = nv04_fifo_disable;
engine->fifo.enable = nv04_fifo_enable;
engine->fifo.reassign = nv04_fifo_reassign;
+ engine->fifo.cache_flush = nv04_fifo_cache_flush;
+ engine->fifo.cache_pull = nv04_fifo_cache_pull;
engine->fifo.channel_id = nv10_fifo_channel_id;
engine->fifo.create_context = nv40_fifo_create_context;
engine->fifo.destroy_context = nv40_fifo_destroy_context;
return (reassign == 1);
}
+bool
+nv04_fifo_cache_flush(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
+ uint64_t start = ptimer->read(dev);
+
+ do {
+ if (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) ==
+ nv_rd32(dev, NV03_PFIFO_CACHE1_PUT))
+ return true;
+
+ } while (ptimer->read(dev) - start < 100000000);
+
+ NV_ERROR(dev, "Timeout flushing the PFIFO cache.\n");
+
+ return false;
+}
+
+bool
+nv04_fifo_cache_pull(struct drm_device *dev, bool enable)
+{
+ uint32_t pull = nv_rd32(dev, NV04_PFIFO_CACHE1_PULL0);
+
+ if (enable) {
+ nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, pull | 1);
+ } else {
+ nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, pull & ~1);
+ nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0);
+ }
+
+ return !!(pull & 1);
+}
+
int
nv04_fifo_channel_id(struct drm_device *dev)
{