1 /* 2 * Copyright 2019 Advanced Micro Devices, Inc. 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 24 #include "amdgpu.h" 25 #include "amdgpu_jpeg.h" 26 #include "soc15.h" 27 #include "soc15d.h" 28 29 #include "vcn/vcn_1_0_offset.h" 30 #include "vcn/vcn_1_0_sh_mask.h" 31 32 static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); 33 static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev); 34 35 static void jpeg_v1_0_decode_ring_patch_wreg(struct amdgpu_ring *ring, uint32_t *ptr, uint32_t reg_offset, uint32_t val) 36 { 37 struct amdgpu_device *adev = ring->adev; 38 ring->ring[(*ptr)++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0); 39 if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || 40 ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { 41 ring->ring[(*ptr)++] = 0; 42 ring->ring[(*ptr)++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0); 43 } else { 44 ring->ring[(*ptr)++] = reg_offset; 45 ring->ring[(*ptr)++] = PACKETJ(0, 0, 0, PACKETJ_TYPE0); 46 } 47 ring->ring[(*ptr)++] = val; 48 } 49 50 static void jpeg_v1_0_decode_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr) 51 { 52 struct amdgpu_device *adev = ring->adev; 53 54 uint32_t reg, reg_offset, val, mask, i; 55 56 // 1st: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW 57 reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW); 58 reg_offset = (reg << 2); 59 val = lower_32_bits(ring->gpu_addr); 60 jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); 61 62 // 2nd: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH 63 reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH); 64 reg_offset = (reg << 2); 65 val = upper_32_bits(ring->gpu_addr); 66 jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); 67 68 // 3rd to 5th: issue MEM_READ commands 69 for (i = 0; i <= 2; i++) { 70 ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE2); 71 ring->ring[ptr++] = 0; 72 } 73 74 // 6th: program mmUVD_JRBC_RB_CNTL register to enable NO_FETCH and RPTR write ability 75 reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL); 76 reg_offset = (reg << 2); 77 val = 0x13; 78 jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); 79 80 // 7th: program mmUVD_JRBC_RB_REF_DATA 81 reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA); 82 reg_offset = (reg << 2); 83 val = 0x1; 84 jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); 85 86 // 8th: issue conditional register read mmUVD_JRBC_RB_CNTL 87 reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL); 88 reg_offset = (reg << 2); 89 val = 0x1; 90 mask = 0x1; 91 92 ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0); 93 ring->ring[ptr++] = 0x01400200; 94 ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0); 95 ring->ring[ptr++] = val; 96 ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0); 97 if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || 98 ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { 99 ring->ring[ptr++] = 0; 100 ring->ring[ptr++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3); 101 } else { 102 ring->ring[ptr++] = reg_offset; 103 ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE3); 104 } 105 ring->ring[ptr++] = mask; 106 107 //9th to 21st: insert no-op 108 for (i = 0; i <= 12; i++) { 109 ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE6); 110 ring->ring[ptr++] = 0; 111 } 112 113 //22nd: reset mmUVD_JRBC_RB_RPTR 114 reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_RPTR); 115 reg_offset = (reg << 2); 116 val = 0; 117 jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); 118 119 //23rd: program mmUVD_JRBC_RB_CNTL to disable no_fetch 120 reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL); 121 reg_offset = (reg << 2); 122 val = 0x12; 123 jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); 124 } 125 126 /** 127 * jpeg_v1_0_decode_ring_get_rptr - get read pointer 128 * 129 * @ring: amdgpu_ring pointer 130 * 131 * Returns the current hardware read pointer 132 */ 133 static uint64_t jpeg_v1_0_decode_ring_get_rptr(struct amdgpu_ring *ring) 134 { 135 struct amdgpu_device *adev = ring->adev; 136 137 return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR); 138 } 139 140 /** 141 * jpeg_v1_0_decode_ring_get_wptr - get write pointer 142 * 143 * @ring: amdgpu_ring pointer 144 * 145 * Returns the current hardware write pointer 146 */ 147 static uint64_t jpeg_v1_0_decode_ring_get_wptr(struct amdgpu_ring *ring) 148 { 149 struct amdgpu_device *adev = ring->adev; 150 151 return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR); 152 } 153 154 /** 155 * jpeg_v1_0_decode_ring_set_wptr - set write pointer 156 * 157 * @ring: amdgpu_ring pointer 158 * 159 * Commits the write pointer to the hardware 160 */ 161 static void jpeg_v1_0_decode_ring_set_wptr(struct amdgpu_ring *ring) 162 { 163 struct amdgpu_device *adev = ring->adev; 164 165 WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr)); 166 } 167 168 /** 169 * jpeg_v1_0_decode_ring_insert_start - insert a start command 170 * 171 * @ring: amdgpu_ring pointer 172 * 173 * Write a start command to the ring. 174 */ 175 static void jpeg_v1_0_decode_ring_insert_start(struct amdgpu_ring *ring) 176 { 177 struct amdgpu_device *adev = ring->adev; 178 179 amdgpu_ring_write(ring, 180 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 181 amdgpu_ring_write(ring, 0x68e04); 182 183 amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0)); 184 amdgpu_ring_write(ring, 0x80010000); 185 } 186 187 /** 188 * jpeg_v1_0_decode_ring_insert_end - insert a end command 189 * 190 * @ring: amdgpu_ring pointer 191 * 192 * Write a end command to the ring. 193 */ 194 static void jpeg_v1_0_decode_ring_insert_end(struct amdgpu_ring *ring) 195 { 196 struct amdgpu_device *adev = ring->adev; 197 198 amdgpu_ring_write(ring, 199 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 200 amdgpu_ring_write(ring, 0x68e04); 201 202 amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0)); 203 amdgpu_ring_write(ring, 0x00010000); 204 } 205 206 /** 207 * jpeg_v1_0_decode_ring_emit_fence - emit an fence & trap command 208 * 209 * @ring: amdgpu_ring pointer 210 * @fence: fence to emit 211 * 212 * Write a fence and a trap command to the ring. 213 */ 214 static void jpeg_v1_0_decode_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, 215 unsigned flags) 216 { 217 struct amdgpu_device *adev = ring->adev; 218 219 WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); 220 221 amdgpu_ring_write(ring, 222 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_DATA0), 0, 0, PACKETJ_TYPE0)); 223 amdgpu_ring_write(ring, seq); 224 225 amdgpu_ring_write(ring, 226 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_DATA1), 0, 0, PACKETJ_TYPE0)); 227 amdgpu_ring_write(ring, seq); 228 229 amdgpu_ring_write(ring, 230 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); 231 amdgpu_ring_write(ring, lower_32_bits(addr)); 232 233 amdgpu_ring_write(ring, 234 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); 235 amdgpu_ring_write(ring, upper_32_bits(addr)); 236 237 amdgpu_ring_write(ring, 238 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_CMD), 0, 0, PACKETJ_TYPE0)); 239 amdgpu_ring_write(ring, 0x8); 240 241 amdgpu_ring_write(ring, 242 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_CMD), 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4)); 243 amdgpu_ring_write(ring, 0); 244 245 amdgpu_ring_write(ring, 246 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); 247 amdgpu_ring_write(ring, 0x01400200); 248 249 amdgpu_ring_write(ring, 250 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); 251 amdgpu_ring_write(ring, seq); 252 253 amdgpu_ring_write(ring, 254 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); 255 amdgpu_ring_write(ring, lower_32_bits(addr)); 256 257 amdgpu_ring_write(ring, 258 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); 259 amdgpu_ring_write(ring, upper_32_bits(addr)); 260 261 amdgpu_ring_write(ring, 262 PACKETJ(0, 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE2)); 263 amdgpu_ring_write(ring, 0xffffffff); 264 265 amdgpu_ring_write(ring, 266 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 267 amdgpu_ring_write(ring, 0x3fbc); 268 269 amdgpu_ring_write(ring, 270 PACKETJ(0, 0, 0, PACKETJ_TYPE0)); 271 amdgpu_ring_write(ring, 0x1); 272 273 /* emit trap */ 274 amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE7)); 275 amdgpu_ring_write(ring, 0); 276 } 277 278 /** 279 * jpeg_v1_0_decode_ring_emit_ib - execute indirect buffer 280 * 281 * @ring: amdgpu_ring pointer 282 * @ib: indirect buffer to execute 283 * 284 * Write ring commands to execute the indirect buffer. 285 */ 286 static void jpeg_v1_0_decode_ring_emit_ib(struct amdgpu_ring *ring, 287 struct amdgpu_job *job, 288 struct amdgpu_ib *ib, 289 uint32_t flags) 290 { 291 struct amdgpu_device *adev = ring->adev; 292 unsigned vmid = AMDGPU_JOB_GET_VMID(job); 293 294 amdgpu_ring_write(ring, 295 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0)); 296 amdgpu_ring_write(ring, (vmid | (vmid << 4))); 297 298 amdgpu_ring_write(ring, 299 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JPEG_VMID), 0, 0, PACKETJ_TYPE0)); 300 amdgpu_ring_write(ring, (vmid | (vmid << 4))); 301 302 amdgpu_ring_write(ring, 303 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); 304 amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); 305 306 amdgpu_ring_write(ring, 307 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); 308 amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); 309 310 amdgpu_ring_write(ring, 311 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_IB_SIZE), 0, 0, PACKETJ_TYPE0)); 312 amdgpu_ring_write(ring, ib->length_dw); 313 314 amdgpu_ring_write(ring, 315 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); 316 amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr)); 317 318 amdgpu_ring_write(ring, 319 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); 320 amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr)); 321 322 amdgpu_ring_write(ring, 323 PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2)); 324 amdgpu_ring_write(ring, 0); 325 326 amdgpu_ring_write(ring, 327 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); 328 amdgpu_ring_write(ring, 0x01400200); 329 330 amdgpu_ring_write(ring, 331 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); 332 amdgpu_ring_write(ring, 0x2); 333 334 amdgpu_ring_write(ring, 335 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_STATUS), 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3)); 336 amdgpu_ring_write(ring, 0x2); 337 } 338 339 static void jpeg_v1_0_decode_ring_emit_reg_wait(struct amdgpu_ring *ring, 340 uint32_t reg, uint32_t val, 341 uint32_t mask) 342 { 343 struct amdgpu_device *adev = ring->adev; 344 uint32_t reg_offset = (reg << 2); 345 346 amdgpu_ring_write(ring, 347 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); 348 amdgpu_ring_write(ring, 0x01400200); 349 350 amdgpu_ring_write(ring, 351 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); 352 amdgpu_ring_write(ring, val); 353 354 amdgpu_ring_write(ring, 355 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 356 if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || 357 ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { 358 amdgpu_ring_write(ring, 0); 359 amdgpu_ring_write(ring, 360 PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3)); 361 } else { 362 amdgpu_ring_write(ring, reg_offset); 363 amdgpu_ring_write(ring, 364 PACKETJ(0, 0, 0, PACKETJ_TYPE3)); 365 } 366 amdgpu_ring_write(ring, mask); 367 } 368 369 static void jpeg_v1_0_decode_ring_emit_vm_flush(struct amdgpu_ring *ring, 370 unsigned vmid, uint64_t pd_addr) 371 { 372 struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub]; 373 uint32_t data0, data1, mask; 374 375 pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr); 376 377 /* wait for register write */ 378 data0 = hub->ctx0_ptb_addr_lo32 + vmid * 2; 379 data1 = lower_32_bits(pd_addr); 380 mask = 0xffffffff; 381 jpeg_v1_0_decode_ring_emit_reg_wait(ring, data0, data1, mask); 382 } 383 384 static void jpeg_v1_0_decode_ring_emit_wreg(struct amdgpu_ring *ring, 385 uint32_t reg, uint32_t val) 386 { 387 struct amdgpu_device *adev = ring->adev; 388 uint32_t reg_offset = (reg << 2); 389 390 amdgpu_ring_write(ring, 391 PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 392 if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || 393 ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { 394 amdgpu_ring_write(ring, 0); 395 amdgpu_ring_write(ring, 396 PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0)); 397 } else { 398 amdgpu_ring_write(ring, reg_offset); 399 amdgpu_ring_write(ring, 400 PACKETJ(0, 0, 0, PACKETJ_TYPE0)); 401 } 402 amdgpu_ring_write(ring, val); 403 } 404 405 static void jpeg_v1_0_decode_ring_nop(struct amdgpu_ring *ring, uint32_t count) 406 { 407 int i; 408 409 WARN_ON(ring->wptr % 2 || count % 2); 410 411 for (i = 0; i < count / 2; i++) { 412 amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6)); 413 amdgpu_ring_write(ring, 0); 414 } 415 } 416 417 static int jpeg_v1_0_set_interrupt_state(struct amdgpu_device *adev, 418 struct amdgpu_irq_src *source, 419 unsigned type, 420 enum amdgpu_interrupt_state state) 421 { 422 return 0; 423 } 424 425 static int jpeg_v1_0_process_interrupt(struct amdgpu_device *adev, 426 struct amdgpu_irq_src *source, 427 struct amdgpu_iv_entry *entry) 428 { 429 DRM_DEBUG("IH: JPEG decode TRAP\n"); 430 431 switch (entry->src_id) { 432 case 126: 433 amdgpu_fence_process(&adev->jpeg.inst->ring_dec); 434 break; 435 default: 436 DRM_ERROR("Unhandled interrupt: %d %d\n", 437 entry->src_id, entry->src_data[0]); 438 break; 439 } 440 441 return 0; 442 } 443 444 /** 445 * jpeg_v1_0_early_init - set function pointers 446 * 447 * @handle: amdgpu_device pointer 448 * 449 * Set ring and irq function pointers 450 */ 451 int jpeg_v1_0_early_init(void *handle) 452 { 453 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 454 455 adev->jpeg.num_jpeg_inst = 1; 456 457 jpeg_v1_0_set_dec_ring_funcs(adev); 458 jpeg_v1_0_set_irq_funcs(adev); 459 460 return 0; 461 } 462 463 /** 464 * jpeg_v1_0_sw_init - sw init for JPEG block 465 * 466 * @handle: amdgpu_device pointer 467 * 468 */ 469 int jpeg_v1_0_sw_init(void *handle) 470 { 471 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 472 struct amdgpu_ring *ring; 473 int r; 474 475 /* JPEG TRAP */ 476 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 126, &adev->jpeg.inst->irq); 477 if (r) 478 return r; 479 480 ring = &adev->jpeg.inst->ring_dec; 481 sprintf(ring->name, "jpeg_dec"); 482 r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0); 483 if (r) 484 return r; 485 486 adev->jpeg.internal.jpeg_pitch = adev->jpeg.inst->external.jpeg_pitch = 487 SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH); 488 489 return 0; 490 } 491 492 /** 493 * jpeg_v1_0_sw_fini - sw fini for JPEG block 494 * 495 * @handle: amdgpu_device pointer 496 * 497 * JPEG free up sw allocation 498 */ 499 void jpeg_v1_0_sw_fini(void *handle) 500 { 501 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 502 503 amdgpu_ring_fini(&adev->jpeg.inst[0].ring_dec); 504 } 505 506 /** 507 * jpeg_v1_0_start - start JPEG block 508 * 509 * @adev: amdgpu_device pointer 510 * 511 * Setup and start the JPEG block 512 */ 513 void jpeg_v1_0_start(struct amdgpu_device *adev, int mode) 514 { 515 struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec; 516 517 if (mode == 0) { 518 WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_VMID, 0); 519 WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK | 520 UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK); 521 WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, lower_32_bits(ring->gpu_addr)); 522 WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, upper_32_bits(ring->gpu_addr)); 523 WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR, 0); 524 WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, 0); 525 WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK); 526 } 527 528 /* initialize wptr */ 529 ring->wptr = RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR); 530 531 /* copy patch commands to the jpeg ring */ 532 jpeg_v1_0_decode_ring_set_patch_ring(ring, 533 (ring->wptr + ring->max_dw * amdgpu_sched_hw_submission)); 534 } 535 536 static const struct amdgpu_ring_funcs jpeg_v1_0_decode_ring_vm_funcs = { 537 .type = AMDGPU_RING_TYPE_VCN_JPEG, 538 .align_mask = 0xf, 539 .nop = PACKET0(0x81ff, 0), 540 .support_64bit_ptrs = false, 541 .no_user_fence = true, 542 .vmhub = AMDGPU_MMHUB_0, 543 .extra_dw = 64, 544 .get_rptr = jpeg_v1_0_decode_ring_get_rptr, 545 .get_wptr = jpeg_v1_0_decode_ring_get_wptr, 546 .set_wptr = jpeg_v1_0_decode_ring_set_wptr, 547 .emit_frame_size = 548 6 + 6 + /* hdp invalidate / flush */ 549 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + 550 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + 551 8 + /* jpeg_v1_0_decode_ring_emit_vm_flush */ 552 26 + 26 + /* jpeg_v1_0_decode_ring_emit_fence x2 vm fence */ 553 6, 554 .emit_ib_size = 22, /* jpeg_v1_0_decode_ring_emit_ib */ 555 .emit_ib = jpeg_v1_0_decode_ring_emit_ib, 556 .emit_fence = jpeg_v1_0_decode_ring_emit_fence, 557 .emit_vm_flush = jpeg_v1_0_decode_ring_emit_vm_flush, 558 .test_ring = amdgpu_jpeg_dec_ring_test_ring, 559 .test_ib = amdgpu_jpeg_dec_ring_test_ib, 560 .insert_nop = jpeg_v1_0_decode_ring_nop, 561 .insert_start = jpeg_v1_0_decode_ring_insert_start, 562 .insert_end = jpeg_v1_0_decode_ring_insert_end, 563 .pad_ib = amdgpu_ring_generic_pad_ib, 564 .begin_use = amdgpu_vcn_ring_begin_use, 565 .end_use = amdgpu_vcn_ring_end_use, 566 .emit_wreg = jpeg_v1_0_decode_ring_emit_wreg, 567 .emit_reg_wait = jpeg_v1_0_decode_ring_emit_reg_wait, 568 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 569 }; 570 571 static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev) 572 { 573 adev->jpeg.inst->ring_dec.funcs = &jpeg_v1_0_decode_ring_vm_funcs; 574 DRM_INFO("JPEG decode is enabled in VM mode\n"); 575 } 576 577 static const struct amdgpu_irq_src_funcs jpeg_v1_0_irq_funcs = { 578 .set = jpeg_v1_0_set_interrupt_state, 579 .process = jpeg_v1_0_process_interrupt, 580 }; 581 582 static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev) 583 { 584 adev->jpeg.inst->irq.funcs = &jpeg_v1_0_irq_funcs; 585 } 586