aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem_gtt.c
diff options
context:
space:
mode:
authorBen Widawsky <benjamin.widawsky@intel.com>2015-02-24 11:22:35 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-02-25 10:53:07 -0500
commit7324cc0491e6c9349cc11edbf6085cc20f64c34e (patch)
tree225eef6adc4037d5a096f9d2da8e22ce1138a903 /drivers/gpu/drm/i915/i915_gem_gtt.c
parentd7b3de91213698296f2571d68e20d90883344b68 (diff)
drm/i915: Complete page table structures
Move the remaining members over to the new page table structures. This can be squashed with the previous commit if desire. The reasoning is the same as that patch. I simply felt it is easier to review if split. v2: In lrc: s/ppgtt->pd_dma_addr[i]/ppgtt->pdp.page_directory[i].daddr/ v3: Rebase. v4: Rebased after s/page_tables/page_table/. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Michel Thierry <michel.thierry@intel.com> (v2+) Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_gtt.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c85
1 files changed, 29 insertions, 56 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 874d9ccbe086..ab6f1d483b38 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -311,7 +311,7 @@ static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt,
311 int used_pd = ppgtt->num_pd_entries / GEN8_PDES_PER_PAGE; 311 int used_pd = ppgtt->num_pd_entries / GEN8_PDES_PER_PAGE;
312 312
313 for (i = used_pd - 1; i >= 0; i--) { 313 for (i = used_pd - 1; i >= 0; i--) {
314 dma_addr_t addr = ppgtt->pd_dma_addr[i]; 314 dma_addr_t addr = ppgtt->pdp.page_directory[i].daddr;
315 ret = gen8_write_pdp(ring, i, addr); 315 ret = gen8_write_pdp(ring, i, addr);
316 if (ret) 316 if (ret)
317 return ret; 317 return ret;
@@ -437,7 +437,6 @@ static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
437 437
438 for (i = 0; i < ppgtt->num_pd_pages; i++) { 438 for (i = 0; i < ppgtt->num_pd_pages; i++) {
439 gen8_free_page_directory(&ppgtt->pdp.page_directory[i]); 439 gen8_free_page_directory(&ppgtt->pdp.page_directory[i]);
440 kfree(ppgtt->gen8_pt_dma_addr[i]);
441 } 440 }
442} 441}
443 442
@@ -449,14 +448,14 @@ static void gen8_ppgtt_unmap_pages(struct i915_hw_ppgtt *ppgtt)
449 for (i = 0; i < ppgtt->num_pd_pages; i++) { 448 for (i = 0; i < ppgtt->num_pd_pages; i++) {
450 /* TODO: In the future we'll support sparse mappings, so this 449 /* TODO: In the future we'll support sparse mappings, so this
451 * will have to change. */ 450 * will have to change. */
452 if (!ppgtt->pd_dma_addr[i]) 451 if (!ppgtt->pdp.page_directory[i].daddr)
453 continue; 452 continue;
454 453
455 pci_unmap_page(hwdev, ppgtt->pd_dma_addr[i], PAGE_SIZE, 454 pci_unmap_page(hwdev, ppgtt->pdp.page_directory[i].daddr, PAGE_SIZE,
456 PCI_DMA_BIDIRECTIONAL); 455 PCI_DMA_BIDIRECTIONAL);
457 456
458 for (j = 0; j < GEN8_PDES_PER_PAGE; j++) { 457 for (j = 0; j < GEN8_PDES_PER_PAGE; j++) {
459 dma_addr_t addr = ppgtt->gen8_pt_dma_addr[i][j]; 458 dma_addr_t addr = ppgtt->pdp.page_directory[i].page_table[j].daddr;
460 if (addr) 459 if (addr)
461 pci_unmap_page(hwdev, addr, PAGE_SIZE, 460 pci_unmap_page(hwdev, addr, PAGE_SIZE,
462 PCI_DMA_BIDIRECTIONAL); 461 PCI_DMA_BIDIRECTIONAL);
@@ -473,32 +472,19 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
473 gen8_ppgtt_free(ppgtt); 472 gen8_ppgtt_free(ppgtt);
474} 473}
475 474
476static int gen8_ppgtt_allocate_dma(struct i915_hw_ppgtt *ppgtt)
477{
478 int i;
479
480 for (i = 0; i < ppgtt->num_pd_pages; i++) {
481 ppgtt->gen8_pt_dma_addr[i] = kcalloc(GEN8_PDES_PER_PAGE,
482 sizeof(dma_addr_t),
483 GFP_KERNEL);
484 if (!ppgtt->gen8_pt_dma_addr[i])
485 return -ENOMEM;
486 }
487
488 return 0;
489}
490
491static int gen8_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt) 475static int gen8_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt)
492{ 476{
493 int i, j; 477 int i, j;
494 478
495 for (i = 0; i < ppgtt->num_pd_pages; i++) { 479 for (i = 0; i < ppgtt->num_pd_pages; i++) {
480 struct i915_page_directory_entry *pd = &ppgtt->pdp.page_directory[i];
496 for (j = 0; j < GEN8_PDES_PER_PAGE; j++) { 481 for (j = 0; j < GEN8_PDES_PER_PAGE; j++) {
497 struct i915_page_table_entry *pt = &ppgtt->pdp.page_directory[i].page_table[j]; 482 struct i915_page_table_entry *pt = &pd->page_table[j];
498 483
499 pt->page = alloc_page(GFP_KERNEL | __GFP_ZERO); 484 pt->page = alloc_page(GFP_KERNEL | __GFP_ZERO);
500 if (!pt->page) 485 if (!pt->page)
501 goto unwind_out; 486 goto unwind_out;
487
502 } 488 }
503 } 489 }
504 490
@@ -561,10 +547,6 @@ static int gen8_ppgtt_alloc(struct i915_hw_ppgtt *ppgtt,
561 547
562 ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE; 548 ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE;
563 549
564 ret = gen8_ppgtt_allocate_dma(ppgtt);
565 if (ret)
566 goto err_out;
567
568 return 0; 550 return 0;
569 551
570err_out: 552err_out:
@@ -586,7 +568,7 @@ static int gen8_ppgtt_setup_page_directories(struct i915_hw_ppgtt *ppgtt,
586 if (ret) 568 if (ret)
587 return ret; 569 return ret;
588 570
589 ppgtt->pd_dma_addr[pd] = pd_addr; 571 ppgtt->pdp.page_directory[pd].daddr = pd_addr;
590 572
591 return 0; 573 return 0;
592} 574}
@@ -596,17 +578,18 @@ static int gen8_ppgtt_setup_page_tables(struct i915_hw_ppgtt *ppgtt,
596 const int pt) 578 const int pt)
597{ 579{
598 dma_addr_t pt_addr; 580 dma_addr_t pt_addr;
599 struct page *p; 581 struct i915_page_directory_entry *pdir = &ppgtt->pdp.page_directory[pd];
582 struct i915_page_table_entry *ptab = &pdir->page_table[pt];
583 struct page *p = ptab->page;
600 int ret; 584 int ret;
601 585
602 p = ppgtt->pdp.page_directory[pd].page_table[pt].page;
603 pt_addr = pci_map_page(ppgtt->base.dev->pdev, 586 pt_addr = pci_map_page(ppgtt->base.dev->pdev,
604 p, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 587 p, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
605 ret = pci_dma_mapping_error(ppgtt->base.dev->pdev, pt_addr); 588 ret = pci_dma_mapping_error(ppgtt->base.dev->pdev, pt_addr);
606 if (ret) 589 if (ret)
607 return ret; 590 return ret;
608 591
609 ppgtt->gen8_pt_dma_addr[pd][pt] = pt_addr; 592 ptab->daddr = pt_addr;
610 593
611 return 0; 594 return 0;
612} 595}
@@ -662,7 +645,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size)
662 gen8_ppgtt_pde_t *pd_vaddr; 645 gen8_ppgtt_pde_t *pd_vaddr;
663 pd_vaddr = kmap_atomic(ppgtt->pdp.page_directory[i].page); 646 pd_vaddr = kmap_atomic(ppgtt->pdp.page_directory[i].page);
664 for (j = 0; j < GEN8_PDES_PER_PAGE; j++) { 647 for (j = 0; j < GEN8_PDES_PER_PAGE; j++) {
665 dma_addr_t addr = ppgtt->gen8_pt_dma_addr[i][j]; 648 dma_addr_t addr = ppgtt->pdp.page_directory[i].page_table[j].daddr;
666 pd_vaddr[j] = gen8_pde_encode(ppgtt->base.dev, addr, 649 pd_vaddr[j] = gen8_pde_encode(ppgtt->base.dev, addr,
667 I915_CACHE_LLC); 650 I915_CACHE_LLC);
668 } 651 }
@@ -705,14 +688,15 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
705 scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0); 688 scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0);
706 689
707 pd_addr = (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm + 690 pd_addr = (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm +
708 ppgtt->pd_offset / sizeof(gen6_gtt_pte_t); 691 ppgtt->pd.pd_offset / sizeof(gen6_gtt_pte_t);
709 692
710 seq_printf(m, " VM %p (pd_offset %x-%x):\n", vm, 693 seq_printf(m, " VM %p (pd_offset %x-%x):\n", vm,
711 ppgtt->pd_offset, ppgtt->pd_offset + ppgtt->num_pd_entries); 694 ppgtt->pd.pd_offset,
695 ppgtt->pd.pd_offset + ppgtt->num_pd_entries);
712 for (pde = 0; pde < ppgtt->num_pd_entries; pde++) { 696 for (pde = 0; pde < ppgtt->num_pd_entries; pde++) {
713 u32 expected; 697 u32 expected;
714 gen6_gtt_pte_t *pt_vaddr; 698 gen6_gtt_pte_t *pt_vaddr;
715 dma_addr_t pt_addr = ppgtt->pt_dma_addr[pde]; 699 dma_addr_t pt_addr = ppgtt->pd.page_table[pde].daddr;
716 pd_entry = readl(pd_addr + pde); 700 pd_entry = readl(pd_addr + pde);
717 expected = (GEN6_PDE_ADDR_ENCODE(pt_addr) | GEN6_PDE_VALID); 701 expected = (GEN6_PDE_ADDR_ENCODE(pt_addr) | GEN6_PDE_VALID);
718 702
@@ -756,13 +740,13 @@ static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt)
756 uint32_t pd_entry; 740 uint32_t pd_entry;
757 int i; 741 int i;
758 742
759 WARN_ON(ppgtt->pd_offset & 0x3f); 743 WARN_ON(ppgtt->pd.pd_offset & 0x3f);
760 pd_addr = (gen6_gtt_pte_t __iomem*)dev_priv->gtt.gsm + 744 pd_addr = (gen6_gtt_pte_t __iomem*)dev_priv->gtt.gsm +
761 ppgtt->pd_offset / sizeof(gen6_gtt_pte_t); 745 ppgtt->pd.pd_offset / sizeof(gen6_gtt_pte_t);
762 for (i = 0; i < ppgtt->num_pd_entries; i++) { 746 for (i = 0; i < ppgtt->num_pd_entries; i++) {
763 dma_addr_t pt_addr; 747 dma_addr_t pt_addr;
764 748
765 pt_addr = ppgtt->pt_dma_addr[i]; 749 pt_addr = ppgtt->pd.page_table[i].daddr;
766 pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr); 750 pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr);
767 pd_entry |= GEN6_PDE_VALID; 751 pd_entry |= GEN6_PDE_VALID;
768 752
@@ -773,9 +757,9 @@ static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt)
773 757
774static uint32_t get_pd_offset(struct i915_hw_ppgtt *ppgtt) 758static uint32_t get_pd_offset(struct i915_hw_ppgtt *ppgtt)
775{ 759{
776 BUG_ON(ppgtt->pd_offset & 0x3f); 760 BUG_ON(ppgtt->pd.pd_offset & 0x3f);
777 761
778 return (ppgtt->pd_offset / 64) << 16; 762 return (ppgtt->pd.pd_offset / 64) << 16;
779} 763}
780 764
781static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt, 765static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt,
@@ -988,19 +972,16 @@ static void gen6_ppgtt_unmap_pages(struct i915_hw_ppgtt *ppgtt)
988{ 972{
989 int i; 973 int i;
990 974
991 if (ppgtt->pt_dma_addr) { 975 for (i = 0; i < ppgtt->num_pd_entries; i++)
992 for (i = 0; i < ppgtt->num_pd_entries; i++) 976 pci_unmap_page(ppgtt->base.dev->pdev,
993 pci_unmap_page(ppgtt->base.dev->pdev, 977 ppgtt->pd.page_table[i].daddr,
994 ppgtt->pt_dma_addr[i], 978 4096, PCI_DMA_BIDIRECTIONAL);
995 4096, PCI_DMA_BIDIRECTIONAL);
996 }
997} 979}
998 980
999static void gen6_ppgtt_free(struct i915_hw_ppgtt *ppgtt) 981static void gen6_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
1000{ 982{
1001 int i; 983 int i;
1002 984
1003 kfree(ppgtt->pt_dma_addr);
1004 for (i = 0; i < ppgtt->num_pd_entries; i++) 985 for (i = 0; i < ppgtt->num_pd_entries; i++)
1005 if (ppgtt->pd.page_table[i].page) 986 if (ppgtt->pd.page_table[i].page)
1006 __free_page(ppgtt->pd.page_table[i].page); 987 __free_page(ppgtt->pd.page_table[i].page);
@@ -1095,14 +1076,6 @@ static int gen6_ppgtt_alloc(struct i915_hw_ppgtt *ppgtt)
1095 return ret; 1076 return ret;
1096 } 1077 }
1097 1078
1098 ppgtt->pt_dma_addr = kcalloc(ppgtt->num_pd_entries, sizeof(dma_addr_t),
1099 GFP_KERNEL);
1100 if (!ppgtt->pt_dma_addr) {
1101 drm_mm_remove_node(&ppgtt->node);
1102 gen6_ppgtt_free(ppgtt);
1103 return -ENOMEM;
1104 }
1105
1106 return 0; 1079 return 0;
1107} 1080}
1108 1081
@@ -1124,7 +1097,7 @@ static int gen6_ppgtt_setup_page_tables(struct i915_hw_ppgtt *ppgtt)
1124 return -EIO; 1097 return -EIO;
1125 } 1098 }
1126 1099
1127 ppgtt->pt_dma_addr[i] = pt_addr; 1100 ppgtt->pd.page_table[i].daddr = pt_addr;
1128 } 1101 }
1129 1102
1130 return 0; 1103 return 0;
@@ -1166,7 +1139,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
1166 ppgtt->base.total = ppgtt->num_pd_entries * I915_PPGTT_PT_ENTRIES * PAGE_SIZE; 1139 ppgtt->base.total = ppgtt->num_pd_entries * I915_PPGTT_PT_ENTRIES * PAGE_SIZE;
1167 ppgtt->debug_dump = gen6_dump_ppgtt; 1140 ppgtt->debug_dump = gen6_dump_ppgtt;
1168 1141
1169 ppgtt->pd_offset = 1142 ppgtt->pd.pd_offset =
1170 ppgtt->node.start / PAGE_SIZE * sizeof(gen6_gtt_pte_t); 1143 ppgtt->node.start / PAGE_SIZE * sizeof(gen6_gtt_pte_t);
1171 1144
1172 ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true); 1145 ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true);
@@ -1177,7 +1150,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
1177 1150
1178 gen6_write_pdes(ppgtt); 1151 gen6_write_pdes(ppgtt);
1179 DRM_DEBUG("Adding PPGTT at offset %x\n", 1152 DRM_DEBUG("Adding PPGTT at offset %x\n",
1180 ppgtt->pd_offset << 10); 1153 ppgtt->pd.pd_offset << 10);
1181 1154
1182 return 0; 1155 return 0;
1183} 1156}