diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 48 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 3 |
2 files changed, 36 insertions, 15 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index b53d53a3..c3895a53 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c | |||
@@ -98,7 +98,7 @@ static int update_gmmu_ptes_locked(struct vm_gk20a *vm, | |||
98 | struct sg_table *sgt, u64 buffer_offset, | 98 | struct sg_table *sgt, u64 buffer_offset, |
99 | u64 first_vaddr, u64 last_vaddr, | 99 | u64 first_vaddr, u64 last_vaddr, |
100 | u8 kind_v, u32 ctag_offset, bool cacheable, | 100 | u8 kind_v, u32 ctag_offset, bool cacheable, |
101 | int rw_flag, | 101 | bool umapped_pte, int rw_flag, |
102 | bool sparse); | 102 | bool sparse); |
103 | static int __must_check gk20a_init_system_vm(struct mm_gk20a *mm); | 103 | static int __must_check gk20a_init_system_vm(struct mm_gk20a *mm); |
104 | static int __must_check gk20a_init_bar1_vm(struct mm_gk20a *mm); | 104 | static int __must_check gk20a_init_bar1_vm(struct mm_gk20a *mm); |
@@ -1115,6 +1115,8 @@ u64 gk20a_locked_gmmu_map(struct vm_gk20a *vm, | |||
1115 | ctag_offset, | 1115 | ctag_offset, |
1116 | flags & | 1116 | flags & |
1117 | NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE, | 1117 | NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE, |
1118 | flags & | ||
1119 | NVGPU_GPU_FLAGS_SUPPORT_UNMAPPED_PTE, | ||
1118 | rw_flag, | 1120 | rw_flag, |
1119 | sparse); | 1121 | sparse); |
1120 | if (err) { | 1122 | if (err) { |
@@ -1161,7 +1163,7 @@ void gk20a_locked_gmmu_unmap(struct vm_gk20a *vm, | |||
1161 | vaddr, | 1163 | vaddr, |
1162 | vaddr + size, | 1164 | vaddr + size, |
1163 | 0, 0, false /* n/a for unmap */, | 1165 | 0, 0, false /* n/a for unmap */, |
1164 | rw_flag, | 1166 | false, rw_flag, |
1165 | sparse); | 1167 | sparse); |
1166 | if (err) | 1168 | if (err) |
1167 | dev_err(dev_from_vm(vm), | 1169 | dev_err(dev_from_vm(vm), |
@@ -1729,7 +1731,8 @@ static int update_gmmu_pde_locked(struct vm_gk20a *vm, | |||
1729 | u32 i, u32 gmmu_pgsz_idx, | 1731 | u32 i, u32 gmmu_pgsz_idx, |
1730 | u64 iova, | 1732 | u64 iova, |
1731 | u32 kind_v, u32 *ctag, | 1733 | u32 kind_v, u32 *ctag, |
1732 | bool cacheable, int rw_flag, bool sparse) | 1734 | bool cacheable, bool unammped_pte, |
1735 | int rw_flag, bool sparse) | ||
1733 | { | 1736 | { |
1734 | bool small_valid, big_valid; | 1737 | bool small_valid, big_valid; |
1735 | u64 pte_addr_small = 0, pte_addr_big = 0; | 1738 | u64 pte_addr_small = 0, pte_addr_big = 0; |
@@ -1775,7 +1778,8 @@ static int update_gmmu_pte_locked(struct vm_gk20a *vm, | |||
1775 | u32 i, u32 gmmu_pgsz_idx, | 1778 | u32 i, u32 gmmu_pgsz_idx, |
1776 | u64 iova, | 1779 | u64 iova, |
1777 | u32 kind_v, u32 *ctag, | 1780 | u32 kind_v, u32 *ctag, |
1778 | bool cacheable, int rw_flag, bool sparse) | 1781 | bool cacheable, bool unmapped_pte, |
1782 | int rw_flag, bool sparse) | ||
1779 | { | 1783 | { |
1780 | struct gk20a *g = gk20a_from_vm(vm); | 1784 | struct gk20a *g = gk20a_from_vm(vm); |
1781 | u32 ctag_granularity = g->ops.fb.compression_page_size(g); | 1785 | u32 ctag_granularity = g->ops.fb.compression_page_size(g); |
@@ -1783,9 +1787,15 @@ static int update_gmmu_pte_locked(struct vm_gk20a *vm, | |||
1783 | u32 pte_w[2] = {0, 0}; /* invalid pte */ | 1787 | u32 pte_w[2] = {0, 0}; /* invalid pte */ |
1784 | 1788 | ||
1785 | if (iova) { | 1789 | if (iova) { |
1786 | pte_w[0] = gmmu_pte_valid_true_f() | | 1790 | if (unmapped_pte) |
1787 | gmmu_pte_address_sys_f(iova | 1791 | pte_w[0] = gmmu_pte_valid_false_f() | |
1792 | gmmu_pte_address_sys_f(iova | ||
1793 | >> gmmu_pte_address_shift_v()); | ||
1794 | else | ||
1795 | pte_w[0] = gmmu_pte_valid_true_f() | | ||
1796 | gmmu_pte_address_sys_f(iova | ||
1788 | >> gmmu_pte_address_shift_v()); | 1797 | >> gmmu_pte_address_shift_v()); |
1798 | |||
1789 | pte_w[1] = gmmu_pte_aperture_video_memory_f() | | 1799 | pte_w[1] = gmmu_pte_aperture_video_memory_f() | |
1790 | gmmu_pte_kind_f(kind_v) | | 1800 | gmmu_pte_kind_f(kind_v) | |
1791 | gmmu_pte_comptagline_f(*ctag / ctag_granularity); | 1801 | gmmu_pte_comptagline_f(*ctag / ctag_granularity); |
@@ -1799,8 +1809,18 @@ static int update_gmmu_pte_locked(struct vm_gk20a *vm, | |||
1799 | pte_w[1] |= | 1809 | pte_w[1] |= |
1800 | gmmu_pte_read_disable_true_f(); | 1810 | gmmu_pte_read_disable_true_f(); |
1801 | } | 1811 | } |
1802 | if (!cacheable) | 1812 | if (!unmapped_pte) { |
1803 | pte_w[1] |= gmmu_pte_vol_true_f(); | 1813 | if (!cacheable) |
1814 | pte_w[1] |= | ||
1815 | gmmu_pte_vol_true_f(); | ||
1816 | else { | ||
1817 | /* Store cachable value behind | ||
1818 | * gmmu_pte_write_disable_true_f */ | ||
1819 | if (!cacheable) | ||
1820 | pte_w[1] |= | ||
1821 | gmmu_pte_write_disable_true_f(); | ||
1822 | } | ||
1823 | } | ||
1804 | 1824 | ||
1805 | gk20a_dbg(gpu_dbg_pte, | 1825 | gk20a_dbg(gpu_dbg_pte, |
1806 | "pte=%d iova=0x%llx kind=%d ctag=%d vol=%d [0x%08x, 0x%08x]", | 1826 | "pte=%d iova=0x%llx kind=%d ctag=%d vol=%d [0x%08x, 0x%08x]", |
@@ -1829,7 +1849,7 @@ static int update_gmmu_level_locked(struct vm_gk20a *vm, | |||
1829 | u64 iova, | 1849 | u64 iova, |
1830 | u64 gpu_va, u64 gpu_end, | 1850 | u64 gpu_va, u64 gpu_end, |
1831 | u8 kind_v, u32 *ctag, | 1851 | u8 kind_v, u32 *ctag, |
1832 | bool cacheable, | 1852 | bool cacheable, bool unmapped_pte, |
1833 | int rw_flag, | 1853 | int rw_flag, |
1834 | bool sparse, | 1854 | bool sparse, |
1835 | int lvl) | 1855 | int lvl) |
@@ -1877,7 +1897,7 @@ static int update_gmmu_level_locked(struct vm_gk20a *vm, | |||
1877 | } | 1897 | } |
1878 | 1898 | ||
1879 | err = l->update_entry(vm, pte, pde_i, pgsz_idx, | 1899 | err = l->update_entry(vm, pte, pde_i, pgsz_idx, |
1880 | iova, kind_v, ctag, cacheable, | 1900 | iova, kind_v, ctag, cacheable, unmapped_pte, |
1881 | rw_flag, sparse); | 1901 | rw_flag, sparse); |
1882 | if (err) | 1902 | if (err) |
1883 | return err; | 1903 | return err; |
@@ -1896,8 +1916,8 @@ static int update_gmmu_level_locked(struct vm_gk20a *vm, | |||
1896 | iova, | 1916 | iova, |
1897 | gpu_va, | 1917 | gpu_va, |
1898 | next, | 1918 | next, |
1899 | kind_v, ctag, | 1919 | kind_v, ctag, cacheable, unmapped_pte, |
1900 | cacheable, rw_flag, sparse, lvl+1); | 1920 | rw_flag, sparse, lvl+1); |
1901 | unmap_gmmu_pages(next_pte); | 1921 | unmap_gmmu_pages(next_pte); |
1902 | 1922 | ||
1903 | if (err) | 1923 | if (err) |
@@ -1921,7 +1941,7 @@ static int update_gmmu_ptes_locked(struct vm_gk20a *vm, | |||
1921 | u64 buffer_offset, | 1941 | u64 buffer_offset, |
1922 | u64 gpu_va, u64 gpu_end, | 1942 | u64 gpu_va, u64 gpu_end, |
1923 | u8 kind_v, u32 ctag_offset, | 1943 | u8 kind_v, u32 ctag_offset, |
1924 | bool cacheable, | 1944 | bool cacheable, bool unmapped_pte, |
1925 | int rw_flag, | 1945 | int rw_flag, |
1926 | bool sparse) | 1946 | bool sparse) |
1927 | { | 1947 | { |
@@ -1956,7 +1976,7 @@ static int update_gmmu_ptes_locked(struct vm_gk20a *vm, | |||
1956 | iova, | 1976 | iova, |
1957 | gpu_va, gpu_end, | 1977 | gpu_va, gpu_end, |
1958 | kind_v, &ctag, | 1978 | kind_v, &ctag, |
1959 | cacheable, rw_flag, sparse, 0); | 1979 | cacheable, unmapped_pte, rw_flag, sparse, 0); |
1960 | unmap_gmmu_pages(&vm->pdb); | 1980 | unmap_gmmu_pages(&vm->pdb); |
1961 | 1981 | ||
1962 | smp_mb(); | 1982 | smp_mb(); |
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index 7bb13484..54028e73 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h | |||
@@ -276,7 +276,8 @@ struct gk20a_mmu_level { | |||
276 | u32 i, u32 gmmu_pgsz_idx, | 276 | u32 i, u32 gmmu_pgsz_idx, |
277 | u64 iova, | 277 | u64 iova, |
278 | u32 kind_v, u32 *ctag, | 278 | u32 kind_v, u32 *ctag, |
279 | bool cacheable, int rw_flag, bool sparse); | 279 | bool cacheable, bool unmapped_pte, |
280 | int rw_flag, bool sparse); | ||
280 | size_t entry_size; | 281 | size_t entry_size; |
281 | }; | 282 | }; |
282 | 283 | ||