diff options
Diffstat (limited to 'runlist.c')
| -rw-r--r-- | runlist.c | 69 |
1 files changed, 56 insertions, 13 deletions
| @@ -169,24 +169,35 @@ attempt_pramin_access: | |||
| 169 | 169 | ||
| 170 | /* Trigger a preempt of the specified TSG | 170 | /* Trigger a preempt of the specified TSG |
| 171 | @param tsg_id ID of TSG to preempt. | 171 | @param tsg_id ID of TSG to preempt. |
| 172 | @param rl_id Which channel RAM address space to search? | ||
| 172 | @return 0 or -errno on error | 173 | @return 0 or -errno on error |
| 173 | 174 | ||
| 174 | Note: If no other TSGs exist in the associated runlist, this TSG may | 175 | Note: If no other TSGs exist in the associated runlist, this TSG may |
| 175 | continue executing, unless NV_PFIFO_SCHED_DISABLE is set, or all the | 176 | continue executing, unless NV_PFIFO_SCHED_DISABLE is set, or all the |
| 176 | channels of the TSG to be preempted are disabled. | 177 | channels of the TSG to be preempted are disabled. |
| 177 | */ | 178 | */ |
| 178 | int preempt_tsg(struct nvdebug_state *g, uint32_t tsg_id) { | 179 | int preempt_tsg(struct nvdebug_state *g, uint32_t rl_id, uint32_t tsg_id) { |
| 179 | pfifo_preempt_t pfifo_preempt; | 180 | pfifo_preempt_t preempt; |
| 181 | // Fermi does not support time-slice groups | ||
| 180 | if (g->chip_id < NV_CHIP_ID_KEPLER) | 182 | if (g->chip_id < NV_CHIP_ID_KEPLER) |
| 181 | return -EOPNOTSUPP; | 183 | return -EOPNOTSUPP; |
| 182 | 184 | ||
| 183 | pfifo_preempt.raw = 0; | 185 | preempt.raw = 0; |
| 184 | pfifo_preempt.id = tsg_id; | 186 | preempt.id = tsg_id; |
| 185 | pfifo_preempt.is_pending = 0; | 187 | preempt.type = PREEMPT_TYPE_TSG; |
| 186 | pfifo_preempt.type = PREEMPT_TYPE_TSG; | ||
| 187 | 188 | ||
| 188 | // Actually trigger the preemption | 189 | // Actually trigger the preemption |
| 189 | nvdebug_writel(g, NV_PFIFO_PREEMPT, pfifo_preempt.raw); | 190 | if (g->chip_id < NV_CHIP_ID_AMPERE) { |
| 191 | nvdebug_writel(g, NV_PFIFO_PREEMPT, preempt.raw); | ||
| 192 | } else { | ||
| 193 | uint32_t runlist_reg_base; | ||
| 194 | int err; | ||
| 195 | // As TSG and channel IDs are namespaced per-runlist starting with | ||
| 196 | // Ampere, the PREEMPT register is also per-runlist. | ||
| 197 | if ((err = get_runlist_ram(g, rl_id, &runlist_reg_base))) | ||
| 198 | return err; | ||
| 199 | nvdebug_writel(g, runlist_reg_base + NV_RUNLIST_PREEMPT_GA100, preempt.raw); | ||
| 200 | } | ||
| 190 | return 0; | 201 | return 0; |
| 191 | } | 202 | } |
| 192 | 203 | ||
| @@ -195,18 +206,38 @@ int preempt_tsg(struct nvdebug_state *g, uint32_t tsg_id) { | |||
| 195 | @return 0 or -errno on error | 206 | @return 0 or -errno on error |
| 196 | */ | 207 | */ |
| 197 | int preempt_runlist(struct nvdebug_state *g, uint32_t rl_id) { | 208 | int preempt_runlist(struct nvdebug_state *g, uint32_t rl_id) { |
| 198 | runlist_preempt_t rl_preempt; | 209 | // The runlist preempt register does not exist on Kepler (tested gk104) |
| 199 | if (g->chip_id < NV_CHIP_ID_VOLTA) | 210 | if (g->chip_id < NV_CHIP_ID_MAXWELL) |
| 200 | return -EOPNOTSUPP; | 211 | return -EOPNOTSUPP; |
| 201 | 212 | ||
| 202 | // Overwrite, as the register contains nothing to preserve | 213 | // Write to trigger the preemption (the register contains nothing to |
| 203 | rl_preempt.raw = BIT(rl_id); | 214 | // preserve, and can thus just be overwritten) |
| 204 | nvdebug_writel(g, NV_PFIFO_RUNLIST_PREEMPT, rl_preempt.raw); | 215 | if (g->chip_id < NV_CHIP_ID_AMPERE) { |
| 216 | runlist_preempt_t rl_preempt; | ||
| 217 | rl_preempt.raw = BIT(rl_id); | ||
| 218 | nvdebug_writel(g, NV_PFIFO_RUNLIST_PREEMPT, rl_preempt.raw); | ||
| 219 | } else { | ||
| 220 | int err; | ||
| 221 | uint32_t runlist_regs_base; | ||
| 222 | pfifo_preempt_t preempt; | ||
| 223 | // The RUNLIST_PREEMPT register was deleted, and the _PREEMPT register | ||
| 224 | // was extended to support runlist-level preemptions starting on Ampere | ||
| 225 | preempt.id = rl_id; | ||
| 226 | preempt.type = PREEMPT_TYPE_RUNLIST; | ||
| 227 | // The preempt register is scoped per-runlist on Ampere+ | ||
| 228 | if ((err = get_runlist_ram(g, rl_id, &runlist_regs_base))) | ||
| 229 | return err; | ||
| 230 | nvdebug_writel(g, runlist_regs_base + NV_RUNLIST_PREEMPT_GA100, preempt.raw); | ||
| 231 | } | ||
| 205 | return 0; | 232 | return 0; |
| 206 | } | 233 | } |
| 207 | 234 | ||
| 208 | // Read and write runlist configuration, triggering a resubmit | 235 | // Read and write runlist configuration, triggering a resubmit |
| 209 | int resubmit_runlist(struct nvdebug_state *g, uint32_t rl_id) { | 236 | int resubmit_runlist(struct nvdebug_state *g, uint32_t rl_id) { |
| 237 | // Necessary registers do not exist pre-Fermi | ||
| 238 | if (g->chip_id < NV_CHIP_ID_FERMI) | ||
| 239 | return -EOPNOTSUPP; | ||
| 240 | |||
| 210 | if (g->chip_id < NV_CHIP_ID_TURING) { | 241 | if (g->chip_id < NV_CHIP_ID_TURING) { |
| 211 | eng_runlist_gf100_t rl; | 242 | eng_runlist_gf100_t rl; |
| 212 | if (rl_id > MAX_RUNLISTS_GF100) | 243 | if (rl_id > MAX_RUNLISTS_GF100) |
| @@ -223,7 +254,19 @@ int resubmit_runlist(struct nvdebug_state *g, uint32_t rl_id) { | |||
| 223 | return -EIO; | 254 | return -EIO; |
| 224 | nvdebug_writeq(g, NV_PFIFO_RUNLIST_SUBMIT_TU102(rl_id), submit.raw); | 255 | nvdebug_writeq(g, NV_PFIFO_RUNLIST_SUBMIT_TU102(rl_id), submit.raw); |
| 225 | } else { | 256 | } else { |
| 226 | return -EOPNOTSUPP; | 257 | int err; |
| 258 | uint32_t runlist_pri_base; | ||
| 259 | runlist_submit_tu102_t submit; | ||
| 260 | if ((err = get_runlist_ram(g, rl_id, &runlist_pri_base)) < 0) | ||
| 261 | return err; | ||
| 262 | if ((submit.raw = nvdebug_readq(g, runlist_pri_base + NV_RUNLIST_SUBMIT_GA100)) == -1) | ||
| 263 | return -EIO; | ||
| 264 | // On Ampere, this does not appear to trigger a preempt of the | ||
| 265 | // currently-running channel (even if the currently running channel | ||
| 266 | // becomes disabled), but will cause newly re-enabled channels | ||
| 267 | // (at least if nothing else is pending) to become ready (tested on | ||
| 268 | // Jetson Orin). | ||
| 269 | nvdebug_writeq(g, runlist_pri_base + NV_RUNLIST_SUBMIT_GA100, submit.raw); | ||
| 227 | } | 270 | } |
| 228 | return 0; | 271 | return 0; |
| 229 | } | 272 | } |
