diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index 2874567c..798b6405 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/vmalloc.h> | 27 | #include <linux/vmalloc.h> |
28 | #include <linux/dma-buf.h> | 28 | #include <linux/dma-buf.h> |
29 | #include <uapi/linux/nvgpu.h> | 29 | #include <uapi/linux/nvgpu.h> |
30 | #include <trace/events/gk20a.h> | ||
30 | 31 | ||
31 | #include "gk20a.h" | 32 | #include "gk20a.h" |
32 | #include "mm_gk20a.h" | 33 | #include "mm_gk20a.h" |
@@ -2816,6 +2817,9 @@ int gk20a_mm_fb_flush(struct gk20a *g) | |||
2816 | /* Make sure all previous writes are committed to the L2. There's no | 2817 | /* Make sure all previous writes are committed to the L2. There's no |
2817 | guarantee that writes are to DRAM. This will be a sysmembar internal | 2818 | guarantee that writes are to DRAM. This will be a sysmembar internal |
2818 | to the L2. */ | 2819 | to the L2. */ |
2820 | |||
2821 | trace_gk20a_mm_fb_flush(g->dev->name); | ||
2822 | |||
2819 | gk20a_writel(g, flush_fb_flush_r(), | 2823 | gk20a_writel(g, flush_fb_flush_r(), |
2820 | flush_fb_flush_pending_busy_f()); | 2824 | flush_fb_flush_pending_busy_f()); |
2821 | 2825 | ||
@@ -2828,7 +2832,7 @@ int gk20a_mm_fb_flush(struct gk20a *g) | |||
2828 | flush_fb_flush_pending_busy_v()) { | 2832 | flush_fb_flush_pending_busy_v()) { |
2829 | gk20a_dbg_info("fb_flush 0x%x", data); | 2833 | gk20a_dbg_info("fb_flush 0x%x", data); |
2830 | retry--; | 2834 | retry--; |
2831 | usleep_range(20, 40); | 2835 | udelay(5); |
2832 | } else | 2836 | } else |
2833 | break; | 2837 | break; |
2834 | } while (retry >= 0 || !tegra_platform_is_silicon()); | 2838 | } while (retry >= 0 || !tegra_platform_is_silicon()); |
@@ -2839,6 +2843,8 @@ int gk20a_mm_fb_flush(struct gk20a *g) | |||
2839 | ret = -EBUSY; | 2843 | ret = -EBUSY; |
2840 | } | 2844 | } |
2841 | 2845 | ||
2846 | trace_gk20a_mm_fb_flush_done(g->dev->name); | ||
2847 | |||
2842 | mutex_unlock(&mm->l2_op_lock); | 2848 | mutex_unlock(&mm->l2_op_lock); |
2843 | 2849 | ||
2844 | return ret; | 2850 | return ret; |
@@ -2849,6 +2855,8 @@ static void gk20a_mm_l2_invalidate_locked(struct gk20a *g) | |||
2849 | u32 data; | 2855 | u32 data; |
2850 | s32 retry = 200; | 2856 | s32 retry = 200; |
2851 | 2857 | ||
2858 | trace_gk20a_mm_l2_invalidate(g->dev->name); | ||
2859 | |||
2852 | /* Invalidate any clean lines from the L2 so subsequent reads go to | 2860 | /* Invalidate any clean lines from the L2 so subsequent reads go to |
2853 | DRAM. Dirty lines are not affected by this operation. */ | 2861 | DRAM. Dirty lines are not affected by this operation. */ |
2854 | gk20a_writel(g, flush_l2_system_invalidate_r(), | 2862 | gk20a_writel(g, flush_l2_system_invalidate_r(), |
@@ -2864,7 +2872,7 @@ static void gk20a_mm_l2_invalidate_locked(struct gk20a *g) | |||
2864 | gk20a_dbg_info("l2_system_invalidate 0x%x", | 2872 | gk20a_dbg_info("l2_system_invalidate 0x%x", |
2865 | data); | 2873 | data); |
2866 | retry--; | 2874 | retry--; |
2867 | usleep_range(20, 40); | 2875 | udelay(5); |
2868 | } else | 2876 | } else |
2869 | break; | 2877 | break; |
2870 | } while (retry >= 0 || !tegra_platform_is_silicon()); | 2878 | } while (retry >= 0 || !tegra_platform_is_silicon()); |
@@ -2872,6 +2880,8 @@ static void gk20a_mm_l2_invalidate_locked(struct gk20a *g) | |||
2872 | if (retry < 0) | 2880 | if (retry < 0) |
2873 | gk20a_warn(dev_from_gk20a(g), | 2881 | gk20a_warn(dev_from_gk20a(g), |
2874 | "l2_system_invalidate too many retries"); | 2882 | "l2_system_invalidate too many retries"); |
2883 | |||
2884 | trace_gk20a_mm_l2_invalidate_done(g->dev->name); | ||
2875 | } | 2885 | } |
2876 | 2886 | ||
2877 | void gk20a_mm_l2_invalidate(struct gk20a *g) | 2887 | void gk20a_mm_l2_invalidate(struct gk20a *g) |
@@ -2900,6 +2910,8 @@ void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate) | |||
2900 | 2910 | ||
2901 | mutex_lock(&mm->l2_op_lock); | 2911 | mutex_lock(&mm->l2_op_lock); |
2902 | 2912 | ||
2913 | trace_gk20a_mm_l2_flush(g->dev->name); | ||
2914 | |||
2903 | /* Flush all dirty lines from the L2 to DRAM. Lines are left in the L2 | 2915 | /* Flush all dirty lines from the L2 to DRAM. Lines are left in the L2 |
2904 | as clean, so subsequent reads might hit in the L2. */ | 2916 | as clean, so subsequent reads might hit in the L2. */ |
2905 | gk20a_writel(g, flush_l2_flush_dirty_r(), | 2917 | gk20a_writel(g, flush_l2_flush_dirty_r(), |
@@ -2914,7 +2926,7 @@ void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate) | |||
2914 | flush_l2_flush_dirty_pending_busy_v()) { | 2926 | flush_l2_flush_dirty_pending_busy_v()) { |
2915 | gk20a_dbg_info("l2_flush_dirty 0x%x", data); | 2927 | gk20a_dbg_info("l2_flush_dirty 0x%x", data); |
2916 | retry--; | 2928 | retry--; |
2917 | usleep_range(20, 40); | 2929 | udelay(5); |
2918 | } else | 2930 | } else |
2919 | break; | 2931 | break; |
2920 | } while (retry >= 0 || !tegra_platform_is_silicon()); | 2932 | } while (retry >= 0 || !tegra_platform_is_silicon()); |
@@ -2923,6 +2935,8 @@ void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate) | |||
2923 | gk20a_warn(dev_from_gk20a(g), | 2935 | gk20a_warn(dev_from_gk20a(g), |
2924 | "l2_flush_dirty too many retries"); | 2936 | "l2_flush_dirty too many retries"); |
2925 | 2937 | ||
2938 | trace_gk20a_mm_l2_flush_done(g->dev->name); | ||
2939 | |||
2926 | if (invalidate) | 2940 | if (invalidate) |
2927 | gk20a_mm_l2_invalidate_locked(g); | 2941 | gk20a_mm_l2_invalidate_locked(g); |
2928 | 2942 | ||
@@ -2964,7 +2978,7 @@ void gk20a_mm_tlb_invalidate(struct vm_gk20a *vm) | |||
2964 | u32 addr_lo = u64_lo32(gk20a_mm_iova_addr(vm->mm->g, | 2978 | u32 addr_lo = u64_lo32(gk20a_mm_iova_addr(vm->mm->g, |
2965 | vm->pdes.sgt->sgl) >> 12); | 2979 | vm->pdes.sgt->sgl) >> 12); |
2966 | u32 data; | 2980 | u32 data; |
2967 | s32 retry = 200; | 2981 | s32 retry = 2000; |
2968 | static DEFINE_MUTEX(tlb_lock); | 2982 | static DEFINE_MUTEX(tlb_lock); |
2969 | 2983 | ||
2970 | gk20a_dbg_fn(""); | 2984 | gk20a_dbg_fn(""); |
@@ -2986,11 +3000,14 @@ void gk20a_mm_tlb_invalidate(struct vm_gk20a *vm) | |||
2986 | } | 3000 | } |
2987 | 3001 | ||
2988 | mutex_lock(&tlb_lock); | 3002 | mutex_lock(&tlb_lock); |
3003 | |||
3004 | trace_gk20a_mm_tlb_invalidate(g->dev->name); | ||
3005 | |||
2989 | do { | 3006 | do { |
2990 | data = gk20a_readl(g, fb_mmu_ctrl_r()); | 3007 | data = gk20a_readl(g, fb_mmu_ctrl_r()); |
2991 | if (fb_mmu_ctrl_pri_fifo_space_v(data) != 0) | 3008 | if (fb_mmu_ctrl_pri_fifo_space_v(data) != 0) |
2992 | break; | 3009 | break; |
2993 | usleep_range(20, 40); | 3010 | udelay(2); |
2994 | retry--; | 3011 | retry--; |
2995 | } while (retry >= 0 || !tegra_platform_is_silicon()); | 3012 | } while (retry >= 0 || !tegra_platform_is_silicon()); |
2996 | 3013 | ||
@@ -3014,13 +3031,15 @@ void gk20a_mm_tlb_invalidate(struct vm_gk20a *vm) | |||
3014 | fb_mmu_ctrl_pri_fifo_empty_false_f()) | 3031 | fb_mmu_ctrl_pri_fifo_empty_false_f()) |
3015 | break; | 3032 | break; |
3016 | retry--; | 3033 | retry--; |
3017 | usleep_range(20, 40); | 3034 | udelay(2); |
3018 | } while (retry >= 0 || !tegra_platform_is_silicon()); | 3035 | } while (retry >= 0 || !tegra_platform_is_silicon()); |
3019 | 3036 | ||
3020 | if (retry < 0) | 3037 | if (retry < 0) |
3021 | gk20a_warn(dev_from_gk20a(g), | 3038 | gk20a_warn(dev_from_gk20a(g), |
3022 | "mmu invalidate too many retries"); | 3039 | "mmu invalidate too many retries"); |
3023 | 3040 | ||
3041 | trace_gk20a_mm_tlb_invalidate_done(g->dev->name); | ||
3042 | |||
3024 | out: | 3043 | out: |
3025 | mutex_unlock(&tlb_lock); | 3044 | mutex_unlock(&tlb_lock); |
3026 | vm->tlb_dirty = false; | 3045 | vm->tlb_dirty = false; |