46
46
47
47
struct nouveau_migrate ;
48
48
49
+ enum nouveau_aper {
50
+ NOUVEAU_APER_VIRT ,
51
+ NOUVEAU_APER_VRAM ,
52
+ NOUVEAU_APER_HOST ,
53
+ };
54
+
49
55
typedef int (* nouveau_migrate_copy_t )(struct nouveau_drm * drm , u64 npages ,
50
- u64 dst_addr , u64 src_addr );
56
+ enum nouveau_aper , u64 dst_addr ,
57
+ enum nouveau_aper , u64 src_addr );
51
58
52
59
struct nouveau_dmem_chunk {
53
60
struct list_head list ;
@@ -267,7 +274,8 @@ nouveau_dmem_fault_alloc_and_copy(struct vm_area_struct *vma,
267
274
src_addr = page_to_pfn (spage ) - chunk -> pfn_first ;
268
275
src_addr = (src_addr << PAGE_SHIFT ) + chunk -> vma .addr ;
269
276
270
- ret = copy (drm , 1 , dst_addr , src_addr );
277
+ ret = copy (drm , 1 , NOUVEAU_APER_VIRT , dst_addr ,
278
+ NOUVEAU_APER_VIRT , src_addr );
271
279
if (ret ) {
272
280
dst_pfns [i ] = MIGRATE_PFN_ERROR ;
273
281
__free_page (dpage );
@@ -588,15 +596,49 @@ nouveau_dmem_fini(struct nouveau_drm *drm)
588
596
589
597
static int
590
598
nvc0b5_migrate_copy (struct nouveau_drm * drm , u64 npages ,
591
- u64 dst_addr , u64 src_addr )
599
+ enum nouveau_aper dst_aper , u64 dst_addr ,
600
+ enum nouveau_aper src_aper , u64 src_addr )
592
601
{
593
602
struct nouveau_channel * chan = drm -> dmem -> migrate .chan ;
603
+ u32 launch_dma = (1 << 9 ) /* MULTI_LINE_ENABLE. */ |
604
+ (1 << 8 ) /* DST_MEMORY_LAYOUT_PITCH. */ |
605
+ (1 << 7 ) /* SRC_MEMORY_LAYOUT_PITCH. */ |
606
+ (1 << 2 ) /* FLUSH_ENABLE_TRUE. */ |
607
+ (2 << 0 ) /* DATA_TRANSFER_TYPE_NON_PIPELINED. */ ;
594
608
int ret ;
595
609
596
- ret = RING_SPACE (chan , 10 );
610
+ ret = RING_SPACE (chan , 13 );
597
611
if (ret )
598
612
return ret ;
599
613
614
+ if (src_aper != NOUVEAU_APER_VIRT ) {
615
+ switch (src_aper ) {
616
+ case NOUVEAU_APER_VRAM :
617
+ BEGIN_IMC0 (chan , NvSubCopy , 0x0260 , 0 );
618
+ break ;
619
+ case NOUVEAU_APER_HOST :
620
+ BEGIN_IMC0 (chan , NvSubCopy , 0x0260 , 1 );
621
+ break ;
622
+ default :
623
+ return - EINVAL ;
624
+ }
625
+ launch_dma |= 0x00001000 ; /* SRC_TYPE_PHYSICAL. */
626
+ }
627
+
628
+ if (dst_aper != NOUVEAU_APER_VIRT ) {
629
+ switch (dst_aper ) {
630
+ case NOUVEAU_APER_VRAM :
631
+ BEGIN_IMC0 (chan , NvSubCopy , 0x0264 , 0 );
632
+ break ;
633
+ case NOUVEAU_APER_HOST :
634
+ BEGIN_IMC0 (chan , NvSubCopy , 0x0264 , 1 );
635
+ break ;
636
+ default :
637
+ return - EINVAL ;
638
+ }
639
+ launch_dma |= 0x00002000 ; /* DST_TYPE_PHYSICAL. */
640
+ }
641
+
600
642
BEGIN_NVC0 (chan , NvSubCopy , 0x0400 , 8 );
601
643
OUT_RING (chan , upper_32_bits (src_addr ));
602
644
OUT_RING (chan , lower_32_bits (src_addr ));
@@ -606,7 +648,8 @@ nvc0b5_migrate_copy(struct nouveau_drm *drm, u64 npages,
606
648
OUT_RING (chan , PAGE_SIZE );
607
649
OUT_RING (chan , PAGE_SIZE );
608
650
OUT_RING (chan , npages );
609
- BEGIN_IMC0 (chan , NvSubCopy , 0x0300 , 0x0386 );
651
+ BEGIN_NVC0 (chan , NvSubCopy , 0x0300 , 1 );
652
+ OUT_RING (chan , launch_dma );
610
653
return 0 ;
611
654
}
612
655
@@ -761,7 +804,8 @@ nouveau_dmem_migrate_alloc_and_copy(struct vm_area_struct *vma,
761
804
src_addr = migrate -> hmem .vma .addr + (c << PAGE_SHIFT );
762
805
c ++ ;
763
806
764
- ret = copy (drm , 1 , dst_addr , src_addr );
807
+ ret = copy (drm , 1 , NOUVEAU_APER_VIRT , dst_addr ,
808
+ NOUVEAU_APER_VIRT , src_addr );
765
809
if (ret ) {
766
810
nouveau_dmem_page_free_locked (drm , dpage );
767
811
dst_pfns [i ] = 0 ;
0 commit comments