1 /* 2 * Copyright 2014 Advanced Micro Devices, Inc. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 19 * USE OR OTHER DEALINGS IN THE SOFTWARE. 20 * 21 * The above copyright notice and this permission notice (including the 22 * next paragraph) shall be included in all copies or substantial portions 23 * of the Software. 24 * 25 * Authors: Christian König <christian.koenig@amd.com> 26 */ 27 28 #include <linux/firmware.h> 29 #include <drm/drmP.h> 30 #include "amdgpu.h" 31 #include "amdgpu_vce.h" 32 #include "vid.h" 33 #include "vce/vce_3_0_d.h" 34 #include "vce/vce_3_0_sh_mask.h" 35 #include "oss/oss_2_0_d.h" 36 #include "oss/oss_2_0_sh_mask.h" 37 38 #define VCE_V3_0_FW_SIZE (384 * 1024) 39 #define VCE_V3_0_STACK_SIZE (64 * 1024) 40 #define VCE_V3_0_DATA_SIZE ((16 * 1024 * AMDGPU_MAX_VCE_HANDLES) + (52 * 1024)) 41 42 static void vce_v3_0_mc_resume(struct amdgpu_device *adev); 43 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev); 44 static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev); 45 46 /** 47 * vce_v3_0_ring_get_rptr - get read pointer 48 * 49 * @ring: amdgpu_ring pointer 50 * 51 * Returns the current hardware read pointer 52 */ 53 static uint32_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring) 54 { 55 struct amdgpu_device *adev = ring->adev; 56 57 if (ring == &adev->vce.ring[0]) 58 return RREG32(mmVCE_RB_RPTR); 59 else 60 return RREG32(mmVCE_RB_RPTR2); 61 } 62 63 /** 64 * vce_v3_0_ring_get_wptr - get write pointer 65 * 66 * @ring: amdgpu_ring pointer 67 * 68 * Returns the current hardware write pointer 69 */ 70 static uint32_t vce_v3_0_ring_get_wptr(struct amdgpu_ring *ring) 71 { 72 struct amdgpu_device *adev = ring->adev; 73 74 if (ring == &adev->vce.ring[0]) 75 return RREG32(mmVCE_RB_WPTR); 76 else 77 return RREG32(mmVCE_RB_WPTR2); 78 } 79 80 /** 81 * vce_v3_0_ring_set_wptr - set write pointer 82 * 83 * @ring: amdgpu_ring pointer 84 * 85 * Commits the write pointer to the hardware 86 */ 87 static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring) 88 { 89 struct amdgpu_device *adev = ring->adev; 90 91 if (ring == &adev->vce.ring[0]) 92 WREG32(mmVCE_RB_WPTR, ring->wptr); 93 else 94 WREG32(mmVCE_RB_WPTR2, ring->wptr); 95 } 96 97 /** 98 * vce_v3_0_start - start VCE block 99 * 100 * @adev: amdgpu_device pointer 101 * 102 * Setup and start the VCE block 103 */ 104 static int vce_v3_0_start(struct amdgpu_device *adev) 105 { 106 struct amdgpu_ring *ring; 107 int i, j, r; 108 109 vce_v3_0_mc_resume(adev); 110 111 /* set BUSY flag */ 112 WREG32_P(mmVCE_STATUS, 1, ~1); 113 114 ring = &adev->vce.ring[0]; 115 WREG32(mmVCE_RB_RPTR, ring->wptr); 116 WREG32(mmVCE_RB_WPTR, ring->wptr); 117 WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr); 118 WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 119 WREG32(mmVCE_RB_SIZE, ring->ring_size / 4); 120 121 ring = &adev->vce.ring[1]; 122 WREG32(mmVCE_RB_RPTR2, ring->wptr); 123 WREG32(mmVCE_RB_WPTR2, ring->wptr); 124 WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr); 125 WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); 126 WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4); 127 128 WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, ~VCE_VCPU_CNTL__CLK_EN_MASK); 129 130 WREG32_P(mmVCE_SOFT_RESET, 131 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, 132 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 133 134 mdelay(100); 135 136 WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 137 138 for (i = 0; i < 10; ++i) { 139 uint32_t status; 140 for (j = 0; j < 100; ++j) { 141 status = RREG32(mmVCE_STATUS); 142 if (status & 2) 143 break; 144 mdelay(10); 145 } 146 r = 0; 147 if (status & 2) 148 break; 149 150 DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n"); 151 WREG32_P(mmVCE_SOFT_RESET, VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, 152 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 153 mdelay(10); 154 WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 155 mdelay(10); 156 r = -1; 157 } 158 159 /* clear BUSY flag */ 160 WREG32_P(mmVCE_STATUS, 0, ~1); 161 162 if (r) { 163 DRM_ERROR("VCE not responding, giving up!!!\n"); 164 return r; 165 } 166 167 return 0; 168 } 169 170 static int vce_v3_0_early_init(struct amdgpu_device *adev) 171 { 172 vce_v3_0_set_ring_funcs(adev); 173 vce_v3_0_set_irq_funcs(adev); 174 175 return 0; 176 } 177 178 static int vce_v3_0_sw_init(struct amdgpu_device *adev) 179 { 180 struct amdgpu_ring *ring; 181 int r; 182 183 /* VCE */ 184 r = amdgpu_irq_add_id(adev, 167, &adev->vce.irq); 185 if (r) 186 return r; 187 188 r = amdgpu_vce_sw_init(adev, VCE_V3_0_FW_SIZE + 189 (VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE) * 2); 190 if (r) 191 return r; 192 193 r = amdgpu_vce_resume(adev); 194 if (r) 195 return r; 196 197 ring = &adev->vce.ring[0]; 198 sprintf(ring->name, "vce0"); 199 r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf, 200 &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE); 201 if (r) 202 return r; 203 204 ring = &adev->vce.ring[1]; 205 sprintf(ring->name, "vce1"); 206 r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf, 207 &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE); 208 if (r) 209 return r; 210 211 return r; 212 } 213 214 static int vce_v3_0_sw_fini(struct amdgpu_device *adev) 215 { 216 int r; 217 218 r = amdgpu_vce_suspend(adev); 219 if (r) 220 return r; 221 222 r = amdgpu_vce_sw_fini(adev); 223 if (r) 224 return r; 225 226 return r; 227 } 228 229 static int vce_v3_0_hw_init(struct amdgpu_device *adev) 230 { 231 struct amdgpu_ring *ring; 232 int r; 233 234 r = vce_v3_0_start(adev); 235 if (r) 236 return r; 237 238 ring = &adev->vce.ring[0]; 239 ring->ready = true; 240 r = amdgpu_ring_test_ring(ring); 241 if (r) { 242 ring->ready = false; 243 return r; 244 } 245 246 ring = &adev->vce.ring[1]; 247 ring->ready = true; 248 r = amdgpu_ring_test_ring(ring); 249 if (r) { 250 ring->ready = false; 251 return r; 252 } 253 254 DRM_INFO("VCE initialized successfully.\n"); 255 256 return 0; 257 } 258 259 static int vce_v3_0_hw_fini(struct amdgpu_device *adev) 260 { 261 // TODO 262 return 0; 263 } 264 265 static int vce_v3_0_suspend(struct amdgpu_device *adev) 266 { 267 int r; 268 269 r = vce_v3_0_hw_fini(adev); 270 if (r) 271 return r; 272 273 r = amdgpu_vce_suspend(adev); 274 if (r) 275 return r; 276 277 return r; 278 } 279 280 static int vce_v3_0_resume(struct amdgpu_device *adev) 281 { 282 int r; 283 284 r = amdgpu_vce_resume(adev); 285 if (r) 286 return r; 287 288 r = vce_v3_0_hw_init(adev); 289 if (r) 290 return r; 291 292 return r; 293 } 294 295 static void vce_v3_0_mc_resume(struct amdgpu_device *adev) 296 { 297 uint32_t offset, size; 298 299 WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16)); 300 WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000); 301 WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F); 302 WREG32(mmVCE_CLOCK_GATING_B, 0xf7); 303 304 WREG32(mmVCE_LMI_CTRL, 0x00398000); 305 WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1); 306 WREG32(mmVCE_LMI_SWAP_CNTL, 0); 307 WREG32(mmVCE_LMI_SWAP_CNTL1, 0); 308 WREG32(mmVCE_LMI_VM_CTRL, 0); 309 310 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8)); 311 offset = AMDGPU_VCE_FIRMWARE_OFFSET; 312 size = VCE_V3_0_FW_SIZE; 313 WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff); 314 WREG32(mmVCE_VCPU_CACHE_SIZE0, size); 315 316 offset += size; 317 size = VCE_V3_0_STACK_SIZE; 318 WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff); 319 WREG32(mmVCE_VCPU_CACHE_SIZE1, size); 320 321 offset += size; 322 size = VCE_V3_0_DATA_SIZE; 323 WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff); 324 WREG32(mmVCE_VCPU_CACHE_SIZE2, size); 325 326 WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100); 327 328 WREG32_P(mmVCE_SYS_INT_EN, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK, 329 ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK); 330 } 331 332 static bool vce_v3_0_is_idle(struct amdgpu_device *adev) 333 { 334 return !(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK); 335 } 336 337 static int vce_v3_0_wait_for_idle(struct amdgpu_device *adev) 338 { 339 unsigned i; 340 341 for (i = 0; i < adev->usec_timeout; i++) { 342 if (!(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK)) 343 return 0; 344 } 345 return -ETIMEDOUT; 346 } 347 348 static int vce_v3_0_soft_reset(struct amdgpu_device *adev) 349 { 350 WREG32_P(mmSRBM_SOFT_RESET, SRBM_SOFT_RESET__SOFT_RESET_VCE_MASK, 351 ~SRBM_SOFT_RESET__SOFT_RESET_VCE_MASK); 352 mdelay(5); 353 354 return vce_v3_0_start(adev); 355 } 356 357 static void vce_v3_0_print_status(struct amdgpu_device *adev) 358 { 359 dev_info(adev->dev, "VCE 3.0 registers\n"); 360 dev_info(adev->dev, " VCE_STATUS=0x%08X\n", 361 RREG32(mmVCE_STATUS)); 362 dev_info(adev->dev, " VCE_VCPU_CNTL=0x%08X\n", 363 RREG32(mmVCE_VCPU_CNTL)); 364 dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET0=0x%08X\n", 365 RREG32(mmVCE_VCPU_CACHE_OFFSET0)); 366 dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE0=0x%08X\n", 367 RREG32(mmVCE_VCPU_CACHE_SIZE0)); 368 dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET1=0x%08X\n", 369 RREG32(mmVCE_VCPU_CACHE_OFFSET1)); 370 dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE1=0x%08X\n", 371 RREG32(mmVCE_VCPU_CACHE_SIZE1)); 372 dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET2=0x%08X\n", 373 RREG32(mmVCE_VCPU_CACHE_OFFSET2)); 374 dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE2=0x%08X\n", 375 RREG32(mmVCE_VCPU_CACHE_SIZE2)); 376 dev_info(adev->dev, " VCE_SOFT_RESET=0x%08X\n", 377 RREG32(mmVCE_SOFT_RESET)); 378 dev_info(adev->dev, " VCE_RB_BASE_LO2=0x%08X\n", 379 RREG32(mmVCE_RB_BASE_LO2)); 380 dev_info(adev->dev, " VCE_RB_BASE_HI2=0x%08X\n", 381 RREG32(mmVCE_RB_BASE_HI2)); 382 dev_info(adev->dev, " VCE_RB_SIZE2=0x%08X\n", 383 RREG32(mmVCE_RB_SIZE2)); 384 dev_info(adev->dev, " VCE_RB_RPTR2=0x%08X\n", 385 RREG32(mmVCE_RB_RPTR2)); 386 dev_info(adev->dev, " VCE_RB_WPTR2=0x%08X\n", 387 RREG32(mmVCE_RB_WPTR2)); 388 dev_info(adev->dev, " VCE_RB_BASE_LO=0x%08X\n", 389 RREG32(mmVCE_RB_BASE_LO)); 390 dev_info(adev->dev, " VCE_RB_BASE_HI=0x%08X\n", 391 RREG32(mmVCE_RB_BASE_HI)); 392 dev_info(adev->dev, " VCE_RB_SIZE=0x%08X\n", 393 RREG32(mmVCE_RB_SIZE)); 394 dev_info(adev->dev, " VCE_RB_RPTR=0x%08X\n", 395 RREG32(mmVCE_RB_RPTR)); 396 dev_info(adev->dev, " VCE_RB_WPTR=0x%08X\n", 397 RREG32(mmVCE_RB_WPTR)); 398 dev_info(adev->dev, " VCE_CLOCK_GATING_A=0x%08X\n", 399 RREG32(mmVCE_CLOCK_GATING_A)); 400 dev_info(adev->dev, " VCE_CLOCK_GATING_B=0x%08X\n", 401 RREG32(mmVCE_CLOCK_GATING_B)); 402 dev_info(adev->dev, " VCE_UENC_CLOCK_GATING=0x%08X\n", 403 RREG32(mmVCE_UENC_CLOCK_GATING)); 404 dev_info(adev->dev, " VCE_UENC_REG_CLOCK_GATING=0x%08X\n", 405 RREG32(mmVCE_UENC_REG_CLOCK_GATING)); 406 dev_info(adev->dev, " VCE_SYS_INT_EN=0x%08X\n", 407 RREG32(mmVCE_SYS_INT_EN)); 408 dev_info(adev->dev, " VCE_LMI_CTRL2=0x%08X\n", 409 RREG32(mmVCE_LMI_CTRL2)); 410 dev_info(adev->dev, " VCE_LMI_CTRL=0x%08X\n", 411 RREG32(mmVCE_LMI_CTRL)); 412 dev_info(adev->dev, " VCE_LMI_VM_CTRL=0x%08X\n", 413 RREG32(mmVCE_LMI_VM_CTRL)); 414 dev_info(adev->dev, " VCE_LMI_SWAP_CNTL=0x%08X\n", 415 RREG32(mmVCE_LMI_SWAP_CNTL)); 416 dev_info(adev->dev, " VCE_LMI_SWAP_CNTL1=0x%08X\n", 417 RREG32(mmVCE_LMI_SWAP_CNTL1)); 418 dev_info(adev->dev, " VCE_LMI_CACHE_CTRL=0x%08X\n", 419 RREG32(mmVCE_LMI_CACHE_CTRL)); 420 } 421 422 static int vce_v3_0_set_interrupt_state(struct amdgpu_device *adev, 423 struct amdgpu_irq_src *source, 424 unsigned type, 425 enum amdgpu_interrupt_state state) 426 { 427 uint32_t val = 0; 428 429 if (state == AMDGPU_IRQ_STATE_ENABLE) 430 val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK; 431 432 WREG32_P(mmVCE_SYS_INT_EN, val, ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK); 433 return 0; 434 } 435 436 static int vce_v3_0_process_interrupt(struct amdgpu_device *adev, 437 struct amdgpu_irq_src *source, 438 struct amdgpu_iv_entry *entry) 439 { 440 DRM_DEBUG("IH: VCE\n"); 441 switch (entry->src_data) { 442 case 0: 443 amdgpu_fence_process(&adev->vce.ring[0]); 444 break; 445 case 1: 446 amdgpu_fence_process(&adev->vce.ring[1]); 447 break; 448 default: 449 DRM_ERROR("Unhandled interrupt: %d %d\n", 450 entry->src_id, entry->src_data); 451 break; 452 } 453 454 return 0; 455 } 456 457 static int vce_v3_0_set_clockgating_state(struct amdgpu_device *adev, 458 enum amdgpu_clockgating_state state) 459 { 460 //TODO 461 return 0; 462 } 463 464 static int vce_v3_0_set_powergating_state(struct amdgpu_device *adev, 465 enum amdgpu_powergating_state state) 466 { 467 /* This doesn't actually powergate the VCE block. 468 * That's done in the dpm code via the SMC. This 469 * just re-inits the block as necessary. The actual 470 * gating still happens in the dpm code. We should 471 * revisit this when there is a cleaner line between 472 * the smc and the hw blocks 473 */ 474 if (state == AMDGPU_PG_STATE_GATE) 475 /* XXX do we need a vce_v3_0_stop()? */ 476 return 0; 477 else 478 return vce_v3_0_start(adev); 479 } 480 481 const struct amdgpu_ip_funcs vce_v3_0_ip_funcs = { 482 .early_init = vce_v3_0_early_init, 483 .late_init = NULL, 484 .sw_init = vce_v3_0_sw_init, 485 .sw_fini = vce_v3_0_sw_fini, 486 .hw_init = vce_v3_0_hw_init, 487 .hw_fini = vce_v3_0_hw_fini, 488 .suspend = vce_v3_0_suspend, 489 .resume = vce_v3_0_resume, 490 .is_idle = vce_v3_0_is_idle, 491 .wait_for_idle = vce_v3_0_wait_for_idle, 492 .soft_reset = vce_v3_0_soft_reset, 493 .print_status = vce_v3_0_print_status, 494 .set_clockgating_state = vce_v3_0_set_clockgating_state, 495 .set_powergating_state = vce_v3_0_set_powergating_state, 496 }; 497 498 static const struct amdgpu_ring_funcs vce_v3_0_ring_funcs = { 499 .get_rptr = vce_v3_0_ring_get_rptr, 500 .get_wptr = vce_v3_0_ring_get_wptr, 501 .set_wptr = vce_v3_0_ring_set_wptr, 502 .parse_cs = amdgpu_vce_ring_parse_cs, 503 .emit_ib = amdgpu_vce_ring_emit_ib, 504 .emit_fence = amdgpu_vce_ring_emit_fence, 505 .emit_semaphore = amdgpu_vce_ring_emit_semaphore, 506 .test_ring = amdgpu_vce_ring_test_ring, 507 .test_ib = amdgpu_vce_ring_test_ib, 508 .is_lockup = amdgpu_ring_test_lockup, 509 }; 510 511 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev) 512 { 513 adev->vce.ring[0].funcs = &vce_v3_0_ring_funcs; 514 adev->vce.ring[1].funcs = &vce_v3_0_ring_funcs; 515 } 516 517 static const struct amdgpu_irq_src_funcs vce_v3_0_irq_funcs = { 518 .set = vce_v3_0_set_interrupt_state, 519 .process = vce_v3_0_process_interrupt, 520 }; 521 522 static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev) 523 { 524 adev->vce.irq.num_types = 1; 525 adev->vce.irq.funcs = &vce_v3_0_irq_funcs; 526 }; 527