diff options
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 109 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 8 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 23 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h | 10 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mc_gk20a.c | 15 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/hw_top_gm20b.h | 8 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/fifo_vgpu.c | 2 |
7 files changed, 99 insertions, 76 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index df6b84c5..64203027 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -72,8 +72,6 @@ static int init_engine_info(struct fifo_gk20a *f) | |||
72 | { | 72 | { |
73 | struct gk20a *g = f->g; | 73 | struct gk20a *g = f->g; |
74 | struct device *d = dev_from_gk20a(g); | 74 | struct device *d = dev_from_gk20a(g); |
75 | struct fifo_engine_info_gk20a *gr_info; | ||
76 | const u32 gr_sw_id = ENGINE_GR_GK20A; | ||
77 | u32 i; | 75 | u32 i; |
78 | u32 max_info_entries = top_device_info__size_1_v(); | 76 | u32 max_info_entries = top_device_info__size_1_v(); |
79 | 77 | ||
@@ -81,77 +79,80 @@ static int init_engine_info(struct fifo_gk20a *f) | |||
81 | 79 | ||
82 | /* all we really care about finding is the graphics entry */ | 80 | /* all we really care about finding is the graphics entry */ |
83 | /* especially early on in sim it probably thinks it has more */ | 81 | /* especially early on in sim it probably thinks it has more */ |
84 | f->num_engines = 1; | 82 | f->num_engines = 2; |
85 | |||
86 | gr_info = f->engine_info + gr_sw_id; | ||
87 | |||
88 | gr_info->sw_id = gr_sw_id; | ||
89 | gr_info->name = "gr"; | ||
90 | gr_info->dev_info_id = top_device_info_type_enum_graphics_v(); | ||
91 | gr_info->mmu_fault_id = fifo_intr_mmu_fault_eng_id_graphics_v(); | ||
92 | gr_info->runlist_id = ~0; | ||
93 | gr_info->pbdma_id = ~0; | ||
94 | gr_info->engine_id = ~0; | ||
95 | 83 | ||
96 | for (i = 0; i < max_info_entries; i++) { | 84 | for (i = 0; i < max_info_entries; i++) { |
85 | struct fifo_engine_info_gk20a *info = NULL; | ||
97 | u32 table_entry = gk20a_readl(f->g, top_device_info_r(i)); | 86 | u32 table_entry = gk20a_readl(f->g, top_device_info_r(i)); |
98 | u32 entry = top_device_info_entry_v(table_entry); | 87 | u32 entry = top_device_info_entry_v(table_entry); |
99 | u32 engine_enum = top_device_info_type_enum_v(table_entry); | 88 | u32 engine_enum; |
100 | u32 table_entry2 = 0; | 89 | int pbdma_id; |
90 | u32 runlist_bit; | ||
101 | 91 | ||
102 | if (entry == top_device_info_entry_not_valid_v()) | 92 | if (entry != top_device_info_entry_enum_v()) |
103 | continue; | 93 | continue; |
104 | 94 | ||
105 | if (top_device_info_chain_v(table_entry) == | 95 | /* we only care about GR engine here */ |
106 | top_device_info_chain_enable_v()) { | 96 | engine_enum = top_device_info_engine_enum_v(table_entry); |
97 | if (engine_enum >= ENGINE_INVAL_GK20A) | ||
98 | continue; | ||
107 | 99 | ||
108 | table_entry2 = gk20a_readl(f->g, | 100 | gk20a_dbg_info("info: engine_id %d", |
109 | top_device_info_r(++i)); | 101 | top_device_info_engine_enum_v(table_entry)); |
102 | info = &g->fifo.engine_info[engine_enum]; | ||
110 | 103 | ||
111 | engine_enum = top_device_info_type_enum_v(table_entry2); | 104 | info->runlist_id = |
112 | } | 105 | top_device_info_runlist_enum_v(table_entry); |
106 | gk20a_dbg_info("gr info: runlist_id %d", info->runlist_id); | ||
113 | 107 | ||
114 | /* we only care about GR engine here */ | 108 | info->engine_id = |
115 | if (entry == top_device_info_entry_enum_v() && | 109 | top_device_info_engine_enum_v(table_entry); |
116 | engine_enum == gr_info->dev_info_id) { | 110 | gk20a_dbg_info("gr info: engine_id %d", info->engine_id); |
117 | int pbdma_id; | ||
118 | u32 runlist_bit; | ||
119 | |||
120 | gr_info->runlist_id = | ||
121 | top_device_info_runlist_enum_v(table_entry); | ||
122 | gk20a_dbg_info("gr info: runlist_id %d", gr_info->runlist_id); | ||
123 | |||
124 | gr_info->engine_id = | ||
125 | top_device_info_engine_enum_v(table_entry); | ||
126 | gk20a_dbg_info("gr info: engine_id %d", gr_info->engine_id); | ||
127 | |||
128 | runlist_bit = 1 << gr_info->runlist_id; | ||
129 | |||
130 | for (pbdma_id = 0; pbdma_id < f->num_pbdma; pbdma_id++) { | ||
131 | gk20a_dbg_info("gr info: pbdma_map[%d]=%d", | ||
132 | pbdma_id, f->pbdma_map[pbdma_id]); | ||
133 | if (f->pbdma_map[pbdma_id] & runlist_bit) | ||
134 | break; | ||
135 | } | ||
136 | 111 | ||
137 | if (pbdma_id == f->num_pbdma) { | 112 | runlist_bit = 1 << info->runlist_id; |
138 | gk20a_err(d, "busted pbmda map"); | ||
139 | return -EINVAL; | ||
140 | } | ||
141 | gr_info->pbdma_id = pbdma_id; | ||
142 | 113 | ||
143 | break; | 114 | for (pbdma_id = 0; pbdma_id < f->num_pbdma; pbdma_id++) { |
115 | gk20a_dbg_info("gr info: pbdma_map[%d]=%d", | ||
116 | pbdma_id, f->pbdma_map[pbdma_id]); | ||
117 | if (f->pbdma_map[pbdma_id] & runlist_bit) | ||
118 | break; | ||
144 | } | 119 | } |
145 | } | ||
146 | 120 | ||
147 | if (gr_info->runlist_id == ~0) { | 121 | if (pbdma_id == f->num_pbdma) { |
148 | gk20a_err(d, "busted device info"); | 122 | gk20a_err(d, "busted pbmda map"); |
149 | return -EINVAL; | 123 | return -EINVAL; |
124 | } | ||
125 | info->pbdma_id = pbdma_id; | ||
126 | |||
127 | info->intr_id = | ||
128 | top_device_info_intr_enum_v(table_entry); | ||
129 | gk20a_dbg_info("gr info: intr_id %d", info->intr_id); | ||
130 | |||
131 | info->reset_id = | ||
132 | top_device_info_reset_enum_v(table_entry); | ||
133 | gk20a_dbg_info("gr info: reset_id %d", | ||
134 | info->reset_id); | ||
135 | |||
150 | } | 136 | } |
151 | 137 | ||
152 | return 0; | 138 | return 0; |
153 | } | 139 | } |
154 | 140 | ||
141 | u32 gk20a_fifo_engine_interrupt_mask(struct gk20a *g) | ||
142 | { | ||
143 | u32 eng_intr_mask = 0; | ||
144 | int i = 0; | ||
145 | |||
146 | for (i = 0; i < g->fifo.max_engines; i++) { | ||
147 | u32 intr_id = g->fifo.engine_info[i].intr_id; | ||
148 | |||
149 | if (intr_id) | ||
150 | eng_intr_mask |= BIT(intr_id); | ||
151 | } | ||
152 | |||
153 | return eng_intr_mask; | ||
154 | } | ||
155 | |||
155 | static void gk20a_remove_fifo_support(struct fifo_gk20a *f) | 156 | static void gk20a_remove_fifo_support(struct fifo_gk20a *f) |
156 | { | 157 | { |
157 | struct gk20a *g = f->g; | 158 | struct gk20a *g = f->g; |
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h index 61783c7d..ecae970f 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | |||
@@ -77,14 +77,11 @@ struct fifo_mmu_fault_info_gk20a { | |||
77 | }; | 77 | }; |
78 | 78 | ||
79 | struct fifo_engine_info_gk20a { | 79 | struct fifo_engine_info_gk20a { |
80 | u32 sw_id; | ||
81 | const char *name; | ||
82 | u32 dev_info_id; | ||
83 | u32 engine_id; | 80 | u32 engine_id; |
84 | u32 runlist_id; | 81 | u32 runlist_id; |
82 | u32 intr_id; | ||
83 | u32 reset_id; | ||
85 | u32 pbdma_id; | 84 | u32 pbdma_id; |
86 | u32 mmu_fault_id; | ||
87 | u32 rc_mask; | ||
88 | struct fifo_pbdma_exception_info_gk20a pbdma_exception_info; | 85 | struct fifo_pbdma_exception_info_gk20a pbdma_exception_info; |
89 | struct fifo_engine_exception_info_gk20a engine_exception_info; | 86 | struct fifo_engine_exception_info_gk20a engine_exception_info; |
90 | struct fifo_mmu_fault_info_gk20a mmu_fault_info; | 87 | struct fifo_mmu_fault_info_gk20a mmu_fault_info; |
@@ -171,4 +168,5 @@ void gk20a_init_fifo(struct gpu_ops *gops); | |||
171 | void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, | 168 | void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, |
172 | unsigned long fault_id); | 169 | unsigned long fault_id); |
173 | int gk20a_fifo_wait_engine_idle(struct gk20a *g); | 170 | int gk20a_fifo_wait_engine_idle(struct gk20a *g); |
171 | u32 gk20a_fifo_engine_interrupt_mask(struct gk20a *g); | ||
174 | #endif /*__GR_GK20A_H__*/ | 172 | #endif /*__GR_GK20A_H__*/ |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 1bd1c898..91cd5834 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c | |||
@@ -757,11 +757,6 @@ static int gk20a_pm_finalize_poweron(struct device *dev) | |||
757 | if (err) | 757 | if (err) |
758 | goto done; | 758 | goto done; |
759 | 759 | ||
760 | enable_irq(g->irq_stall); | ||
761 | enable_irq(g->irq_nonstall); | ||
762 | |||
763 | g->ops.mc.intr_enable(g); | ||
764 | |||
765 | if (!tegra_platform_is_silicon()) | 760 | if (!tegra_platform_is_silicon()) |
766 | gk20a_writel(g, bus_intr_en_0_r(), 0x0); | 761 | gk20a_writel(g, bus_intr_en_0_r(), 0x0); |
767 | else | 762 | else |
@@ -814,6 +809,14 @@ static int gk20a_pm_finalize_poweron(struct device *dev) | |||
814 | goto done; | 809 | goto done; |
815 | } | 810 | } |
816 | 811 | ||
812 | err = gk20a_init_fifo_support(g); | ||
813 | if (err) { | ||
814 | gk20a_err(dev, "failed to init gk20a fifo"); | ||
815 | goto done; | ||
816 | } | ||
817 | |||
818 | g->ops.mc.intr_enable(g); | ||
819 | |||
817 | err = gk20a_enable_gr_hw(g); | 820 | err = gk20a_enable_gr_hw(g); |
818 | if (err) { | 821 | if (err) { |
819 | gk20a_err(dev, "failed to enable gr"); | 822 | gk20a_err(dev, "failed to enable gr"); |
@@ -833,12 +836,6 @@ static int gk20a_pm_finalize_poweron(struct device *dev) | |||
833 | goto done; | 836 | goto done; |
834 | } | 837 | } |
835 | 838 | ||
836 | err = gk20a_init_fifo_support(g); | ||
837 | if (err) { | ||
838 | gk20a_err(dev, "failed to init gk20a fifo"); | ||
839 | goto done; | ||
840 | } | ||
841 | |||
842 | err = gk20a_init_gr_support(g); | 839 | err = gk20a_init_gr_support(g); |
843 | if (err) { | 840 | if (err) { |
844 | gk20a_err(dev, "failed to init gk20a gr"); | 841 | gk20a_err(dev, "failed to init gk20a gr"); |
@@ -857,7 +854,6 @@ static int gk20a_pm_finalize_poweron(struct device *dev) | |||
857 | goto done; | 854 | goto done; |
858 | } | 855 | } |
859 | 856 | ||
860 | |||
861 | gk20a_channel_resume(g); | 857 | gk20a_channel_resume(g); |
862 | set_user_nice(current, nice_value); | 858 | set_user_nice(current, nice_value); |
863 | 859 | ||
@@ -868,6 +864,9 @@ static int gk20a_pm_finalize_poweron(struct device *dev) | |||
868 | if (platform->has_cde) | 864 | if (platform->has_cde) |
869 | gk20a_init_cde_support(g); | 865 | gk20a_init_cde_support(g); |
870 | 866 | ||
867 | enable_irq(g->irq_stall); | ||
868 | enable_irq(g->irq_nonstall); | ||
869 | |||
871 | #ifdef CONFIG_INPUT_CFBOOST | 870 | #ifdef CONFIG_INPUT_CFBOOST |
872 | if (!g->boost_added) { | 871 | if (!g->boost_added) { |
873 | gk20a_dbg_info("add touch boost"); | 872 | gk20a_dbg_info("add touch boost"); |
diff --git a/drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h index ab527d25..f3ca7498 100644 --- a/drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved. | 2 | * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms and conditions of the GNU General Public License, | 5 | * under the terms and conditions of the GNU General Public License, |
@@ -98,6 +98,14 @@ static inline u32 top_device_info_runlist_enum_v(u32 r) | |||
98 | { | 98 | { |
99 | return (r >> 21) & 0xf; | 99 | return (r >> 21) & 0xf; |
100 | } | 100 | } |
101 | static inline u32 top_device_info_intr_enum_v(u32 r) | ||
102 | { | ||
103 | return (r >> 15) & 0x1f; | ||
104 | } | ||
105 | static inline u32 top_device_info_reset_enum_v(u32 r) | ||
106 | { | ||
107 | return (r >> 9) & 0x1f; | ||
108 | } | ||
101 | static inline u32 top_device_info_type_enum_v(u32 r) | 109 | static inline u32 top_device_info_type_enum_v(u32 r) |
102 | { | 110 | { |
103 | return (r >> 2) & 0x1fffffff; | 111 | return (r >> 2) & 0x1fffffff; |
diff --git a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c index 53701605..4d176403 100644 --- a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c | |||
@@ -71,7 +71,7 @@ irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g) | |||
71 | 71 | ||
72 | gk20a_dbg(gpu_dbg_intr, "stall intr %08x\n", mc_intr_0); | 72 | gk20a_dbg(gpu_dbg_intr, "stall intr %08x\n", mc_intr_0); |
73 | 73 | ||
74 | if (mc_intr_0 & mc_intr_0_pgraph_pending_f()) | 74 | if (mc_intr_0 & BIT(g->fifo.engine_info[ENGINE_GR_GK20A].intr_id)) |
75 | gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g)); | 75 | gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g)); |
76 | if (mc_intr_0 & mc_intr_0_pfifo_pending_f()) | 76 | if (mc_intr_0 & mc_intr_0_pfifo_pending_f()) |
77 | gk20a_fifo_isr(g); | 77 | gk20a_fifo_isr(g); |
@@ -105,7 +105,7 @@ irqreturn_t mc_gk20a_intr_thread_nonstall(struct gk20a *g) | |||
105 | 105 | ||
106 | if (mc_intr_1 & mc_intr_0_pfifo_pending_f()) | 106 | if (mc_intr_1 & mc_intr_0_pfifo_pending_f()) |
107 | gk20a_fifo_nonstall_isr(g); | 107 | gk20a_fifo_nonstall_isr(g); |
108 | if (mc_intr_1 & mc_intr_0_pgraph_pending_f()) | 108 | if (mc_intr_1 & BIT(g->fifo.engine_info[ENGINE_GR_GK20A].intr_id)) |
109 | gk20a_gr_nonstall_isr(g); | 109 | gk20a_gr_nonstall_isr(g); |
110 | 110 | ||
111 | gk20a_writel(g, mc_intr_en_1_r(), | 111 | gk20a_writel(g, mc_intr_en_1_r(), |
@@ -119,9 +119,20 @@ irqreturn_t mc_gk20a_intr_thread_nonstall(struct gk20a *g) | |||
119 | 119 | ||
120 | void mc_gk20a_intr_enable(struct gk20a *g) | 120 | void mc_gk20a_intr_enable(struct gk20a *g) |
121 | { | 121 | { |
122 | u32 eng_intr_mask = gk20a_fifo_engine_interrupt_mask(g); | ||
123 | |||
124 | gk20a_writel(g, mc_intr_mask_1_r(), | ||
125 | mc_intr_0_pfifo_pending_f() | ||
126 | | eng_intr_mask); | ||
122 | gk20a_writel(g, mc_intr_en_1_r(), | 127 | gk20a_writel(g, mc_intr_en_1_r(), |
123 | mc_intr_en_1_inta_hardware_f()); | 128 | mc_intr_en_1_inta_hardware_f()); |
124 | 129 | ||
130 | gk20a_writel(g, mc_intr_mask_0_r(), | ||
131 | mc_intr_0_pfifo_pending_f() | ||
132 | | mc_intr_0_priv_ring_pending_f() | ||
133 | | mc_intr_0_ltc_pending_f() | ||
134 | | mc_intr_0_pbus_pending_f() | ||
135 | | eng_intr_mask); | ||
125 | gk20a_writel(g, mc_intr_en_0_r(), | 136 | gk20a_writel(g, mc_intr_en_0_r(), |
126 | mc_intr_en_0_inta_hardware_f()); | 137 | mc_intr_en_0_inta_hardware_f()); |
127 | } | 138 | } |
diff --git a/drivers/gpu/nvgpu/gm20b/hw_top_gm20b.h b/drivers/gpu/nvgpu/gm20b/hw_top_gm20b.h index a2405a04..42a82a12 100644 --- a/drivers/gpu/nvgpu/gm20b/hw_top_gm20b.h +++ b/drivers/gpu/nvgpu/gm20b/hw_top_gm20b.h | |||
@@ -102,6 +102,14 @@ static inline u32 top_device_info_runlist_enum_v(u32 r) | |||
102 | { | 102 | { |
103 | return (r >> 21) & 0xf; | 103 | return (r >> 21) & 0xf; |
104 | } | 104 | } |
105 | static inline u32 top_device_info_intr_enum_v(u32 r) | ||
106 | { | ||
107 | return (r >> 15) & 0x1f; | ||
108 | } | ||
109 | static inline u32 top_device_info_reset_enum_v(u32 r) | ||
110 | { | ||
111 | return (r >> 9) & 0x1f; | ||
112 | } | ||
105 | static inline u32 top_device_info_type_enum_v(u32 r) | 113 | static inline u32 top_device_info_type_enum_v(u32 r) |
106 | { | 114 | { |
107 | return (r >> 2) & 0x1fffffff; | 115 | return (r >> 2) & 0x1fffffff; |
diff --git a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c index 9bbb39f0..80a89e1e 100644 --- a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c | |||
@@ -162,8 +162,6 @@ static int init_engine_info(struct fifo_gk20a *f) | |||
162 | 162 | ||
163 | gr_info = f->engine_info + gr_sw_id; | 163 | gr_info = f->engine_info + gr_sw_id; |
164 | 164 | ||
165 | gr_info->sw_id = gr_sw_id; | ||
166 | gr_info->name = "gr"; | ||
167 | /* FIXME: retrieve this from server */ | 165 | /* FIXME: retrieve this from server */ |
168 | gr_info->runlist_id = 0; | 166 | gr_info->runlist_id = 0; |
169 | return 0; | 167 | return 0; |