0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "nouveau_bo.h"
0030 #include "nouveau_dma.h"
0031 #include "nouveau_drv.h"
0032
0033 #include <nvif/push006c.h>
0034
0035 #include <nvhw/class/cl0039.h>
0036
0037 static inline uint32_t
0038 nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo,
0039 struct nouveau_channel *chan, struct ttm_resource *reg)
0040 {
0041 if (reg->mem_type == TTM_PL_TT)
0042 return NvDmaTT;
0043 return chan->vram.handle;
0044 }
0045
0046 int
0047 nv04_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
0048 struct ttm_resource *old_reg, struct ttm_resource *new_reg)
0049 {
0050 struct nvif_push *push = chan->chan.push;
0051 u32 src_ctxdma = nouveau_bo_mem_ctxdma(bo, chan, old_reg);
0052 u32 src_offset = old_reg->start << PAGE_SHIFT;
0053 u32 dst_ctxdma = nouveau_bo_mem_ctxdma(bo, chan, new_reg);
0054 u32 dst_offset = new_reg->start << PAGE_SHIFT;
0055 u32 page_count = new_reg->num_pages;
0056 int ret;
0057
0058 ret = PUSH_WAIT(push, 3);
0059 if (ret)
0060 return ret;
0061
0062 PUSH_MTHD(push, NV039, SET_CONTEXT_DMA_BUFFER_IN, src_ctxdma,
0063 SET_CONTEXT_DMA_BUFFER_OUT, dst_ctxdma);
0064
0065 page_count = new_reg->num_pages;
0066 while (page_count) {
0067 int line_count = (page_count > 2047) ? 2047 : page_count;
0068
0069 ret = PUSH_WAIT(push, 11);
0070 if (ret)
0071 return ret;
0072
0073 PUSH_MTHD(push, NV039, OFFSET_IN, src_offset,
0074 OFFSET_OUT, dst_offset,
0075 PITCH_IN, PAGE_SIZE,
0076 PITCH_OUT, PAGE_SIZE,
0077 LINE_LENGTH_IN, PAGE_SIZE,
0078 LINE_COUNT, line_count,
0079
0080 FORMAT,
0081 NVVAL(NV039, FORMAT, IN, 1) |
0082 NVVAL(NV039, FORMAT, OUT, 1),
0083
0084 BUFFER_NOTIFY, NV039_BUFFER_NOTIFY_WRITE_ONLY);
0085
0086 PUSH_MTHD(push, NV039, NO_OPERATION, 0x00000000);
0087
0088 page_count -= line_count;
0089 src_offset += (PAGE_SIZE * line_count);
0090 dst_offset += (PAGE_SIZE * line_count);
0091 }
0092
0093 return 0;
0094 }
0095
0096 int
0097 nv04_bo_move_init(struct nouveau_channel *chan, u32 handle)
0098 {
0099 struct nvif_push *push = chan->chan.push;
0100 int ret;
0101
0102 ret = PUSH_WAIT(push, 4);
0103 if (ret)
0104 return ret;
0105
0106 PUSH_MTHD(push, NV039, SET_OBJECT, handle);
0107 PUSH_MTHD(push, NV039, SET_CONTEXT_DMA_NOTIFIES, chan->drm->ntfy.handle);
0108 return 0;
0109 }