gpu: nvgpu: Add GPCPLL DVFS state to debug prints
[linux-3.10.git] / drivers / gpu / nvgpu / gm20b / fifo_gm20b.c
1 /*
2  * GM20B Fifo
3  *
4  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  */
15
16 #include <linux/delay.h>
17 #include "gk20a/gk20a.h"
18 #include "fifo_gm20b.h"
19 #include "hw_ccsr_gm20b.h"
20 #include "hw_ram_gm20b.h"
21 #include "hw_fifo_gm20b.h"
22
23 static void channel_gm20b_bind(struct channel_gk20a *ch_gk20a)
24 {
25         struct gk20a *g = ch_gk20a->g;
26
27         u32 inst_ptr = ch_gk20a->inst_block.cpu_pa
28                 >> ram_in_base_shift_v();
29
30         gk20a_dbg_info("bind channel %d inst ptr 0x%08x",
31                 ch_gk20a->hw_chid, inst_ptr);
32
33         ch_gk20a->bound = true;
34
35         gk20a_writel(g, ccsr_channel_inst_r(ch_gk20a->hw_chid),
36                 ccsr_channel_inst_ptr_f(inst_ptr) |
37                 ccsr_channel_inst_target_vid_mem_f() |
38                 ccsr_channel_inst_bind_true_f());
39
40         gk20a_writel(g, ccsr_channel_r(ch_gk20a->hw_chid),
41                 (gk20a_readl(g, ccsr_channel_r(ch_gk20a->hw_chid)) &
42                  ~ccsr_channel_enable_set_f(~0)) |
43                  ccsr_channel_enable_set_true_f());
44 }
45
46 static inline u32 gm20b_engine_id_to_mmu_id(u32 engine_id)
47 {
48         switch (engine_id) {
49         case ENGINE_GR_GK20A:
50                 return 0;
51         case ENGINE_CE2_GK20A:
52                 return 1;
53         default:
54                 return ~0;
55         }
56 }
57
58 static void gm20b_fifo_trigger_mmu_fault(struct gk20a *g,
59                 unsigned long engine_ids)
60 {
61         unsigned long end_jiffies = jiffies +
62                 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
63         unsigned long delay = GR_IDLE_CHECK_DEFAULT;
64         unsigned long engine_id;
65         int ret = -EBUSY;
66
67         /* trigger faults for all bad engines */
68         for_each_set_bit(engine_id, &engine_ids, 32) {
69                 u32 engine_mmu_id;
70
71                 if (engine_id > g->fifo.max_engines) {
72                         gk20a_err(dev_from_gk20a(g),
73                                   "faulting unknown engine %ld", engine_id);
74                 } else {
75                         engine_mmu_id = gm20b_engine_id_to_mmu_id(engine_id);
76                         gk20a_writel(g, fifo_trigger_mmu_fault_r(engine_mmu_id),
77                                      fifo_trigger_mmu_fault_enable_f(1));
78                 }
79         }
80
81         /* Wait for MMU fault to trigger */
82         do {
83                 if (gk20a_readl(g, fifo_intr_0_r()) &
84                                 fifo_intr_0_mmu_fault_pending_f()) {
85                         ret = 0;
86                         break;
87                 }
88
89                 usleep_range(delay, delay * 2);
90                 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX);
91         } while (time_before(jiffies, end_jiffies) ||
92                         !tegra_platform_is_silicon());
93
94         if (ret)
95                 gk20a_err(dev_from_gk20a(g), "mmu fault timeout");
96
97         /* release mmu fault trigger */
98         for_each_set_bit(engine_id, &engine_ids, 32)
99                 gk20a_writel(g, fifo_trigger_mmu_fault_r(engine_id), 0);
100 }
101
102 static u32 gm20b_fifo_get_num_fifos(struct gk20a *g)
103 {
104         return ccsr_channel__size_1_v();
105 }
106
107 void gm20b_init_fifo(struct gpu_ops *gops)
108 {
109         gops->fifo.bind_channel = channel_gm20b_bind;
110         gops->fifo.unbind_channel = channel_gk20a_unbind;
111         gops->fifo.disable_channel = channel_gk20a_disable;
112         gops->fifo.alloc_inst = channel_gk20a_alloc_inst;
113         gops->fifo.free_inst = channel_gk20a_free_inst;
114         gops->fifo.setup_ramfc = channel_gk20a_setup_ramfc;
115
116         gops->fifo.preempt_channel = gk20a_fifo_preempt_channel;
117         gops->fifo.update_runlist = gk20a_fifo_update_runlist;
118         gops->fifo.trigger_mmu_fault = gm20b_fifo_trigger_mmu_fault;
119         gops->fifo.wait_engine_idle = gk20a_fifo_wait_engine_idle;
120         gops->fifo.get_num_fifos = gm20b_fifo_get_num_fifos;
121 }