Alexandre Courbot | a4d4bbf | 2014-05-02 18:32:41 +0900 | [diff] [blame] | 1 | /* |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 2 | * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. |
Alexandre Courbot | a4d4bbf | 2014-05-02 18:32:41 +0900 | [diff] [blame] | 3 | * |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 5 | * copy of this software and associated documentation files (the "Software"), |
| 6 | * to deal in the Software without restriction, including without limitation |
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 8 | * and/or sell copies of the Software, and to permit persons to whom the |
| 9 | * Software is furnished to do so, subject to the following conditions: |
| 10 | * |
| 11 | * The above copyright notice and this permission notice shall be included in |
| 12 | * all copies or substantial portions of the Software. |
| 13 | * |
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
| 20 | * DEALINGS IN THE SOFTWARE. |
| 21 | */ |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 22 | #include "gf100.h" |
Ben Skeggs | e3c71eb | 2015-01-14 15:29:43 +1000 | [diff] [blame] | 23 | #include "ctxgf100.h" |
Alexandre Courbot | a4d4bbf | 2014-05-02 18:32:41 +0900 | [diff] [blame] | 24 | |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 25 | #include <subdev/timer.h> |
Alexandre Courbot | a4d4bbf | 2014-05-02 18:32:41 +0900 | [diff] [blame] | 26 | |
Ben Skeggs | 27f3d6c | 2015-08-20 14:54:19 +1000 | [diff] [blame] | 27 | #include <nvif/class.h> |
Alexandre Courbot | a4d4bbf | 2014-05-02 18:32:41 +0900 | [diff] [blame] | 28 | |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 29 | struct gk20a_fw_av |
| 30 | { |
| 31 | u32 addr; |
| 32 | u32 data; |
| 33 | }; |
| 34 | |
Alexandre Courbot | 2e404b0 | 2016-02-24 14:42:18 +0900 | [diff] [blame] | 35 | int |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 36 | gk20a_gr_av_to_init(struct gf100_gr *gr, const char *fw_name, |
| 37 | struct gf100_gr_pack **ppack) |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 38 | { |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 39 | struct gf100_gr_fuc fuc; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 40 | struct gf100_gr_init *init; |
| 41 | struct gf100_gr_pack *pack; |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 42 | int nent; |
| 43 | int ret; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 44 | int i; |
| 45 | |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 46 | ret = gf100_gr_ctor_fw(gr, fw_name, &fuc); |
| 47 | if (ret) |
| 48 | return ret; |
| 49 | |
| 50 | nent = (fuc.size / sizeof(struct gk20a_fw_av)); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 51 | pack = vzalloc((sizeof(*pack) * 2) + (sizeof(*init) * (nent + 1))); |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 52 | if (!pack) { |
| 53 | ret = -ENOMEM; |
| 54 | goto end; |
| 55 | } |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 56 | |
| 57 | init = (void *)(pack + 2); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 58 | pack[0].init = init; |
| 59 | |
| 60 | for (i = 0; i < nent; i++) { |
| 61 | struct gf100_gr_init *ent = &init[i]; |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 62 | struct gk20a_fw_av *av = &((struct gk20a_fw_av *)fuc.data)[i]; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 63 | |
| 64 | ent->addr = av->addr; |
| 65 | ent->data = av->data; |
| 66 | ent->count = 1; |
| 67 | ent->pitch = 1; |
| 68 | } |
| 69 | |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 70 | *ppack = pack; |
| 71 | |
| 72 | end: |
| 73 | gf100_gr_dtor_fw(&fuc); |
| 74 | return ret; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 75 | } |
| 76 | |
| 77 | struct gk20a_fw_aiv |
| 78 | { |
| 79 | u32 addr; |
| 80 | u32 index; |
| 81 | u32 data; |
| 82 | }; |
| 83 | |
Alexandre Courbot | 2e404b0 | 2016-02-24 14:42:18 +0900 | [diff] [blame] | 84 | int |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 85 | gk20a_gr_aiv_to_init(struct gf100_gr *gr, const char *fw_name, |
| 86 | struct gf100_gr_pack **ppack) |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 87 | { |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 88 | struct gf100_gr_fuc fuc; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 89 | struct gf100_gr_init *init; |
| 90 | struct gf100_gr_pack *pack; |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 91 | int nent; |
| 92 | int ret; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 93 | int i; |
| 94 | |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 95 | ret = gf100_gr_ctor_fw(gr, fw_name, &fuc); |
| 96 | if (ret) |
| 97 | return ret; |
| 98 | |
| 99 | nent = (fuc.size / sizeof(struct gk20a_fw_aiv)); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 100 | pack = vzalloc((sizeof(*pack) * 2) + (sizeof(*init) * (nent + 1))); |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 101 | if (!pack) { |
| 102 | ret = -ENOMEM; |
| 103 | goto end; |
| 104 | } |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 105 | |
| 106 | init = (void *)(pack + 2); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 107 | pack[0].init = init; |
| 108 | |
| 109 | for (i = 0; i < nent; i++) { |
| 110 | struct gf100_gr_init *ent = &init[i]; |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 111 | struct gk20a_fw_aiv *av = &((struct gk20a_fw_aiv *)fuc.data)[i]; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 112 | |
| 113 | ent->addr = av->addr; |
| 114 | ent->data = av->data; |
| 115 | ent->count = 1; |
| 116 | ent->pitch = 1; |
| 117 | } |
| 118 | |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 119 | *ppack = pack; |
| 120 | |
| 121 | end: |
| 122 | gf100_gr_dtor_fw(&fuc); |
| 123 | return ret; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 124 | } |
| 125 | |
Alexandre Courbot | 2e404b0 | 2016-02-24 14:42:18 +0900 | [diff] [blame] | 126 | int |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 127 | gk20a_gr_av_to_method(struct gf100_gr *gr, const char *fw_name, |
| 128 | struct gf100_gr_pack **ppack) |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 129 | { |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 130 | struct gf100_gr_fuc fuc; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 131 | struct gf100_gr_init *init; |
| 132 | struct gf100_gr_pack *pack; |
| 133 | /* We don't suppose we will initialize more than 16 classes here... */ |
| 134 | static const unsigned int max_classes = 16; |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 135 | u32 classidx = 0, prevclass = 0; |
| 136 | int nent; |
| 137 | int ret; |
| 138 | int i; |
| 139 | |
| 140 | ret = gf100_gr_ctor_fw(gr, fw_name, &fuc); |
| 141 | if (ret) |
| 142 | return ret; |
| 143 | |
| 144 | nent = (fuc.size / sizeof(struct gk20a_fw_av)); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 145 | |
Ben Skeggs | d07d4aa | 2020-01-09 11:46:15 +1000 | [diff] [blame^] | 146 | pack = vzalloc((sizeof(*pack) * (max_classes + 1)) + |
| 147 | (sizeof(*init) * (nent + max_classes + 1))); |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 148 | if (!pack) { |
| 149 | ret = -ENOMEM; |
| 150 | goto end; |
| 151 | } |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 152 | |
Ben Skeggs | d07d4aa | 2020-01-09 11:46:15 +1000 | [diff] [blame^] | 153 | init = (void *)(pack + max_classes + 1); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 154 | |
Ben Skeggs | d07d4aa | 2020-01-09 11:46:15 +1000 | [diff] [blame^] | 155 | for (i = 0; i < nent; i++, init++) { |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 156 | struct gk20a_fw_av *av = &((struct gk20a_fw_av *)fuc.data)[i]; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 157 | u32 class = av->addr & 0xffff; |
| 158 | u32 addr = (av->addr & 0xffff0000) >> 14; |
| 159 | |
| 160 | if (prevclass != class) { |
Ben Skeggs | d07d4aa | 2020-01-09 11:46:15 +1000 | [diff] [blame^] | 161 | if (prevclass) /* Add terminator to the method list. */ |
| 162 | init++; |
| 163 | pack[classidx].init = init; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 164 | pack[classidx].type = class; |
| 165 | prevclass = class; |
| 166 | if (++classidx >= max_classes) { |
| 167 | vfree(pack); |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 168 | ret = -ENOSPC; |
| 169 | goto end; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 170 | } |
| 171 | } |
| 172 | |
Ben Skeggs | d07d4aa | 2020-01-09 11:46:15 +1000 | [diff] [blame^] | 173 | init->addr = addr; |
| 174 | init->data = av->data; |
| 175 | init->count = 1; |
| 176 | init->pitch = 1; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 177 | } |
| 178 | |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 179 | *ppack = pack; |
| 180 | |
| 181 | end: |
| 182 | gf100_gr_dtor_fw(&fuc); |
| 183 | return ret; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 184 | } |
| 185 | |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 186 | static int |
Ben Skeggs | bfee3f3 | 2015-08-20 14:54:08 +1000 | [diff] [blame] | 187 | gk20a_gr_wait_mem_scrubbing(struct gf100_gr *gr) |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 188 | { |
Ben Skeggs | 109c2f2 | 2015-08-20 14:54:13 +1000 | [diff] [blame] | 189 | struct nvkm_subdev *subdev = &gr->base.engine.subdev; |
| 190 | struct nvkm_device *device = subdev->device; |
Ben Skeggs | c4584ad | 2015-08-20 14:54:11 +1000 | [diff] [blame] | 191 | |
| 192 | if (nvkm_msec(device, 2000, |
| 193 | if (!(nvkm_rd32(device, 0x40910c) & 0x00000006)) |
| 194 | break; |
| 195 | ) < 0) { |
Ben Skeggs | 109c2f2 | 2015-08-20 14:54:13 +1000 | [diff] [blame] | 196 | nvkm_error(subdev, "FECS mem scrubbing timeout\n"); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 197 | return -ETIMEDOUT; |
| 198 | } |
| 199 | |
Ben Skeggs | c4584ad | 2015-08-20 14:54:11 +1000 | [diff] [blame] | 200 | if (nvkm_msec(device, 2000, |
| 201 | if (!(nvkm_rd32(device, 0x41a10c) & 0x00000006)) |
| 202 | break; |
| 203 | ) < 0) { |
Ben Skeggs | 109c2f2 | 2015-08-20 14:54:13 +1000 | [diff] [blame] | 204 | nvkm_error(subdev, "GPCCS mem scrubbing timeout\n"); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 205 | return -ETIMEDOUT; |
| 206 | } |
| 207 | |
| 208 | return 0; |
| 209 | } |
| 210 | |
| 211 | static void |
Ben Skeggs | bfee3f3 | 2015-08-20 14:54:08 +1000 | [diff] [blame] | 212 | gk20a_gr_set_hww_esr_report_mask(struct gf100_gr *gr) |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 213 | { |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 214 | struct nvkm_device *device = gr->base.engine.subdev.device; |
| 215 | nvkm_wr32(device, 0x419e44, 0x1ffffe); |
| 216 | nvkm_wr32(device, 0x419e4c, 0x7f); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 217 | } |
| 218 | |
Alexandre Courbot | a032fb9 | 2015-06-23 15:16:04 +0900 | [diff] [blame] | 219 | int |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 220 | gk20a_gr_init(struct gf100_gr *gr) |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 221 | { |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 222 | struct nvkm_device *device = gr->base.engine.subdev.device; |
Ben Skeggs | bfee3f3 | 2015-08-20 14:54:08 +1000 | [diff] [blame] | 223 | const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 224 | u32 data[TPC_MAX / 8] = {}; |
| 225 | u8 tpcnr[GPC_MAX]; |
| 226 | int gpc, tpc; |
| 227 | int ret, i; |
| 228 | |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 229 | /* Clear SCC RAM */ |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 230 | nvkm_wr32(device, 0x40802c, 0x1); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 231 | |
Ben Skeggs | bfee3f3 | 2015-08-20 14:54:08 +1000 | [diff] [blame] | 232 | gf100_gr_mmio(gr, gr->fuc_sw_nonctx); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 233 | |
Ben Skeggs | bfee3f3 | 2015-08-20 14:54:08 +1000 | [diff] [blame] | 234 | ret = gk20a_gr_wait_mem_scrubbing(gr); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 235 | if (ret) |
| 236 | return ret; |
| 237 | |
Ben Skeggs | bfee3f3 | 2015-08-20 14:54:08 +1000 | [diff] [blame] | 238 | ret = gf100_gr_wait_idle(gr); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 239 | if (ret) |
| 240 | return ret; |
| 241 | |
| 242 | /* MMU debug buffer */ |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 243 | if (gr->func->init_gpc_mmu) |
| 244 | gr->func->init_gpc_mmu(gr); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 245 | |
| 246 | /* Set the PE as stream master */ |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 247 | nvkm_mask(device, 0x503018, 0x1, 0x1); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 248 | |
| 249 | /* Zcull init */ |
| 250 | memset(data, 0x00, sizeof(data)); |
Ben Skeggs | bfee3f3 | 2015-08-20 14:54:08 +1000 | [diff] [blame] | 251 | memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); |
| 252 | for (i = 0, gpc = -1; i < gr->tpc_total; i++) { |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 253 | do { |
Ben Skeggs | bfee3f3 | 2015-08-20 14:54:08 +1000 | [diff] [blame] | 254 | gpc = (gpc + 1) % gr->gpc_nr; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 255 | } while (!tpcnr[gpc]); |
Ben Skeggs | bfee3f3 | 2015-08-20 14:54:08 +1000 | [diff] [blame] | 256 | tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 257 | |
| 258 | data[i / 8] |= tpc << ((i % 8) * 4); |
| 259 | } |
| 260 | |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 261 | nvkm_wr32(device, GPC_BCAST(0x0980), data[0]); |
| 262 | nvkm_wr32(device, GPC_BCAST(0x0984), data[1]); |
| 263 | nvkm_wr32(device, GPC_BCAST(0x0988), data[2]); |
| 264 | nvkm_wr32(device, GPC_BCAST(0x098c), data[3]); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 265 | |
Ben Skeggs | bfee3f3 | 2015-08-20 14:54:08 +1000 | [diff] [blame] | 266 | for (gpc = 0; gpc < gr->gpc_nr; gpc++) { |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 267 | nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), |
Ben Skeggs | 5ec3def | 2016-04-14 14:08:25 +1000 | [diff] [blame] | 268 | gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 269 | nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | |
| 270 | gr->tpc_total); |
| 271 | nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 272 | } |
| 273 | |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 274 | nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 275 | |
Ben Skeggs | 87ac331 | 2016-04-19 11:10:38 +1000 | [diff] [blame] | 276 | gr->func->init_rop_active_fbps(gr); |
| 277 | |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 278 | /* Enable FIFO access */ |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 279 | nvkm_wr32(device, 0x400500, 0x00010001); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 280 | |
| 281 | /* Enable interrupts */ |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 282 | nvkm_wr32(device, 0x400100, 0xffffffff); |
| 283 | nvkm_wr32(device, 0x40013c, 0xffffffff); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 284 | |
| 285 | /* Enable FECS error interrupts */ |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 286 | nvkm_wr32(device, 0x409c24, 0x000f0000); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 287 | |
| 288 | /* Enable hardware warning exceptions */ |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 289 | nvkm_wr32(device, 0x404000, 0xc0000000); |
| 290 | nvkm_wr32(device, 0x404600, 0xc0000000); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 291 | |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 292 | if (gr->func->set_hww_esr_report_mask) |
| 293 | gr->func->set_hww_esr_report_mask(gr); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 294 | |
| 295 | /* Enable TPC exceptions per GPC */ |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 296 | nvkm_wr32(device, 0x419d0c, 0x2); |
| 297 | nvkm_wr32(device, 0x41ac94, (((1 << gr->tpc_total) - 1) & 0xff) << 16); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 298 | |
| 299 | /* Reset and enable all exceptions */ |
Ben Skeggs | 276836d | 2015-08-20 14:54:10 +1000 | [diff] [blame] | 300 | nvkm_wr32(device, 0x400108, 0xffffffff); |
| 301 | nvkm_wr32(device, 0x400138, 0xffffffff); |
| 302 | nvkm_wr32(device, 0x400118, 0xffffffff); |
| 303 | nvkm_wr32(device, 0x400130, 0xffffffff); |
| 304 | nvkm_wr32(device, 0x40011c, 0xffffffff); |
| 305 | nvkm_wr32(device, 0x400134, 0xffffffff); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 306 | |
Ben Skeggs | bfee3f3 | 2015-08-20 14:54:08 +1000 | [diff] [blame] | 307 | gf100_gr_zbc_init(gr); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 308 | |
Ben Skeggs | bfee3f3 | 2015-08-20 14:54:08 +1000 | [diff] [blame] | 309 | return gf100_gr_init_ctxctl(gr); |
Alexandre Courbot | c4d0f8f | 2015-06-23 15:16:02 +0900 | [diff] [blame] | 310 | } |
| 311 | |
Alexandre Courbot | f008d8c | 2016-02-24 14:42:19 +0900 | [diff] [blame] | 312 | static const struct gf100_gr_func |
| 313 | gk20a_gr = { |
| 314 | .init = gk20a_gr_init, |
Ben Skeggs | 87ac331 | 2016-04-19 11:10:38 +1000 | [diff] [blame] | 315 | .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, |
Alexandre Courbot | f008d8c | 2016-02-24 14:42:19 +0900 | [diff] [blame] | 316 | .set_hww_esr_report_mask = gk20a_gr_set_hww_esr_report_mask, |
Ben Skeggs | 64cb5a3 | 2016-04-14 14:26:18 +1000 | [diff] [blame] | 317 | .rops = gf100_gr_rops, |
Alexandre Courbot | f008d8c | 2016-02-24 14:42:19 +0900 | [diff] [blame] | 318 | .ppc_nr = 1, |
| 319 | .grctx = &gk20a_grctx, |
| 320 | .sclass = { |
| 321 | { -1, -1, FERMI_TWOD_A }, |
| 322 | { -1, -1, KEPLER_INLINE_TO_MEMORY_A }, |
| 323 | { -1, -1, KEPLER_C, &gf100_fermi }, |
| 324 | { -1, -1, KEPLER_COMPUTE_A }, |
| 325 | {} |
| 326 | } |
| 327 | }; |
| 328 | |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 329 | int |
Alexandre Courbot | f008d8c | 2016-02-24 14:42:19 +0900 | [diff] [blame] | 330 | gk20a_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr) |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 331 | { |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 332 | struct gf100_gr *gr; |
| 333 | int ret; |
| 334 | |
| 335 | if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL))) |
| 336 | return -ENOMEM; |
| 337 | *pgr = &gr->base; |
| 338 | |
Alexandre Courbot | f008d8c | 2016-02-24 14:42:19 +0900 | [diff] [blame] | 339 | ret = gf100_gr_ctor(&gk20a_gr, device, index, gr); |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 340 | if (ret) |
| 341 | return ret; |
| 342 | |
Alexandre Courbot | 18cd5bc | 2016-02-24 14:42:16 +0900 | [diff] [blame] | 343 | if (gf100_gr_ctor_fw(gr, "fecs_inst", &gr->fuc409c) || |
| 344 | gf100_gr_ctor_fw(gr, "fecs_data", &gr->fuc409d) || |
| 345 | gf100_gr_ctor_fw(gr, "gpccs_inst", &gr->fuc41ac) || |
| 346 | gf100_gr_ctor_fw(gr, "gpccs_data", &gr->fuc41ad)) |
| 347 | return -ENODEV; |
| 348 | |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 349 | ret = gk20a_gr_av_to_init(gr, "sw_nonctx", &gr->fuc_sw_nonctx); |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 350 | if (ret) |
| 351 | return ret; |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 352 | |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 353 | ret = gk20a_gr_aiv_to_init(gr, "sw_ctx", &gr->fuc_sw_ctx); |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 354 | if (ret) |
| 355 | return ret; |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 356 | |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 357 | ret = gk20a_gr_av_to_init(gr, "sw_bundle_init", &gr->fuc_bundle); |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 358 | if (ret) |
| 359 | return ret; |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 360 | |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 361 | ret = gk20a_gr_av_to_method(gr, "sw_method_init", &gr->fuc_method); |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 362 | if (ret) |
| 363 | return ret; |
Alexandre Courbot | 5986d3e | 2016-02-24 14:42:17 +0900 | [diff] [blame] | 364 | |
Ben Skeggs | c85ee6c | 2015-08-20 14:54:22 +1000 | [diff] [blame] | 365 | return 0; |
| 366 | } |