2175 lines · c
1/*2 * Copyright 2016 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 */23 24#include <linux/firmware.h>25 26#include "amdgpu.h"27#include "amdgpu_cs.h"28#include "amdgpu_vcn.h"29#include "amdgpu_pm.h"30#include "soc15.h"31#include "soc15d.h"32#include "soc15_common.h"33 34#include "vcn/vcn_1_0_offset.h"35#include "vcn/vcn_1_0_sh_mask.h"36#include "mmhub/mmhub_9_1_offset.h"37#include "mmhub/mmhub_9_1_sh_mask.h"38 39#include "ivsrcid/vcn/irqsrcs_vcn_1_0.h"40#include "jpeg_v1_0.h"41#include "vcn_v1_0.h"42 43#define mmUVD_RBC_XX_IB_REG_CHECK_1_0 0x05ab44#define mmUVD_RBC_XX_IB_REG_CHECK_1_0_BASE_IDX 145#define mmUVD_REG_XX_MASK_1_0 0x05ac46#define mmUVD_REG_XX_MASK_1_0_BASE_IDX 147 48static const struct amdgpu_hwip_reg_entry vcn_reg_list_1_0[] = {49 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_POWER_STATUS),50 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_STATUS),51 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_CONTEXT_ID),52 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_CONTEXT_ID2),53 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_GPCOM_VCPU_DATA0),54 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_GPCOM_VCPU_DATA1),55 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_GPCOM_VCPU_CMD),56 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI),57 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO),58 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI2),59 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO2),60 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI3),61 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO3),62 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI4),63 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO4),64 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR),65 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR),66 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR2),67 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR2),68 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR3),69 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR3),70 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR4),71 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR4),72 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE),73 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE2),74 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE3),75 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE4),76 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_PGFSM_CONFIG),77 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_PGFSM_STATUS),78 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_LMA_CTL),79 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_LMA_DATA),80 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_LMA_MASK),81 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_PAUSE)82};83 84static int vcn_v1_0_stop(struct amdgpu_device *adev);85static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);86static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev);87static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev);88static int vcn_v1_0_set_powergating_state(void *handle, enum amd_powergating_state state);89static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev,90 int inst_idx, struct dpg_pause_state *new_state);91 92static void vcn_v1_0_idle_work_handler(struct work_struct *work);93static void vcn_v1_0_ring_begin_use(struct amdgpu_ring *ring);94 95/**96 * vcn_v1_0_early_init - set function pointers and load microcode97 *98 * @handle: amdgpu_device pointer99 *100 * Set ring and irq function pointers101 * Load microcode from filesystem102 */103static int vcn_v1_0_early_init(void *handle)104{105 struct amdgpu_device *adev = (struct amdgpu_device *)handle;106 107 adev->vcn.num_enc_rings = 2;108 109 vcn_v1_0_set_dec_ring_funcs(adev);110 vcn_v1_0_set_enc_ring_funcs(adev);111 vcn_v1_0_set_irq_funcs(adev);112 113 jpeg_v1_0_early_init(handle);114 115 return amdgpu_vcn_early_init(adev);116}117 118/**119 * vcn_v1_0_sw_init - sw init for VCN block120 *121 * @handle: amdgpu_device pointer122 *123 * Load firmware and sw initialization124 */125static int vcn_v1_0_sw_init(void *handle)126{127 struct amdgpu_ring *ring;128 int i, r;129 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_1_0);130 uint32_t *ptr;131 struct amdgpu_device *adev = (struct amdgpu_device *)handle;132 133 /* VCN DEC TRAP */134 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,135 VCN_1_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst->irq);136 if (r)137 return r;138 139 /* VCN ENC TRAP */140 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {141 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, i + VCN_1_0__SRCID__UVD_ENC_GENERAL_PURPOSE,142 &adev->vcn.inst->irq);143 if (r)144 return r;145 }146 147 r = amdgpu_vcn_sw_init(adev);148 if (r)149 return r;150 151 /* Override the work func */152 adev->vcn.idle_work.work.func = vcn_v1_0_idle_work_handler;153 154 amdgpu_vcn_setup_ucode(adev);155 156 r = amdgpu_vcn_resume(adev);157 if (r)158 return r;159 160 ring = &adev->vcn.inst->ring_dec;161 ring->vm_hub = AMDGPU_MMHUB0(0);162 sprintf(ring->name, "vcn_dec");163 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0,164 AMDGPU_RING_PRIO_DEFAULT, NULL);165 if (r)166 return r;167 168 adev->vcn.internal.scratch9 = adev->vcn.inst->external.scratch9 =169 SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9);170 adev->vcn.internal.data0 = adev->vcn.inst->external.data0 =171 SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0);172 adev->vcn.internal.data1 = adev->vcn.inst->external.data1 =173 SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1);174 adev->vcn.internal.cmd = adev->vcn.inst->external.cmd =175 SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD);176 adev->vcn.internal.nop = adev->vcn.inst->external.nop =177 SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP);178 179 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {180 enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(i);181 182 ring = &adev->vcn.inst->ring_enc[i];183 ring->vm_hub = AMDGPU_MMHUB0(0);184 sprintf(ring->name, "vcn_enc%d", i);185 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0,186 hw_prio, NULL);187 if (r)188 return r;189 }190 191 adev->vcn.pause_dpg_mode = vcn_v1_0_pause_dpg_mode;192 193 if (amdgpu_vcnfw_log) {194 volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared.cpu_addr;195 196 fw_shared->present_flag_0 = 0;197 amdgpu_vcn_fwlog_init(adev->vcn.inst);198 }199 200 r = jpeg_v1_0_sw_init(handle);201 202 /* Allocate memory for VCN IP Dump buffer */203 ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL);204 if (!ptr) {205 DRM_ERROR("Failed to allocate memory for VCN IP Dump\n");206 adev->vcn.ip_dump = NULL;207 } else {208 adev->vcn.ip_dump = ptr;209 }210 return r;211}212 213/**214 * vcn_v1_0_sw_fini - sw fini for VCN block215 *216 * @handle: amdgpu_device pointer217 *218 * VCN suspend and free up sw allocation219 */220static int vcn_v1_0_sw_fini(void *handle)221{222 int r;223 struct amdgpu_device *adev = (struct amdgpu_device *)handle;224 225 r = amdgpu_vcn_suspend(adev);226 if (r)227 return r;228 229 jpeg_v1_0_sw_fini(handle);230 231 r = amdgpu_vcn_sw_fini(adev);232 233 kfree(adev->vcn.ip_dump);234 235 return r;236}237 238/**239 * vcn_v1_0_hw_init - start and test VCN block240 *241 * @handle: amdgpu_device pointer242 *243 * Initialize the hardware, boot up the VCPU and do some testing244 */245static int vcn_v1_0_hw_init(void *handle)246{247 struct amdgpu_device *adev = (struct amdgpu_device *)handle;248 struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec;249 int i, r;250 251 r = amdgpu_ring_test_helper(ring);252 if (r)253 return r;254 255 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {256 ring = &adev->vcn.inst->ring_enc[i];257 r = amdgpu_ring_test_helper(ring);258 if (r)259 return r;260 }261 262 ring = adev->jpeg.inst->ring_dec;263 r = amdgpu_ring_test_helper(ring);264 265 return r;266}267 268/**269 * vcn_v1_0_hw_fini - stop the hardware block270 *271 * @handle: amdgpu_device pointer272 *273 * Stop the VCN block, mark ring as not ready any more274 */275static int vcn_v1_0_hw_fini(void *handle)276{277 struct amdgpu_device *adev = (struct amdgpu_device *)handle;278 279 cancel_delayed_work_sync(&adev->vcn.idle_work);280 281 if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||282 (adev->vcn.cur_state != AMD_PG_STATE_GATE &&283 RREG32_SOC15(VCN, 0, mmUVD_STATUS))) {284 vcn_v1_0_set_powergating_state(adev, AMD_PG_STATE_GATE);285 }286 287 return 0;288}289 290/**291 * vcn_v1_0_suspend - suspend VCN block292 *293 * @handle: amdgpu_device pointer294 *295 * HW fini and suspend VCN block296 */297static int vcn_v1_0_suspend(void *handle)298{299 int r;300 struct amdgpu_device *adev = (struct amdgpu_device *)handle;301 bool idle_work_unexecuted;302 303 idle_work_unexecuted = cancel_delayed_work_sync(&adev->vcn.idle_work);304 if (idle_work_unexecuted) {305 if (adev->pm.dpm_enabled)306 amdgpu_dpm_enable_uvd(adev, false);307 }308 309 r = vcn_v1_0_hw_fini(adev);310 if (r)311 return r;312 313 r = amdgpu_vcn_suspend(adev);314 315 return r;316}317 318/**319 * vcn_v1_0_resume - resume VCN block320 *321 * @handle: amdgpu_device pointer322 *323 * Resume firmware and hw init VCN block324 */325static int vcn_v1_0_resume(void *handle)326{327 int r;328 struct amdgpu_device *adev = (struct amdgpu_device *)handle;329 330 r = amdgpu_vcn_resume(adev);331 if (r)332 return r;333 334 r = vcn_v1_0_hw_init(adev);335 336 return r;337}338 339/**340 * vcn_v1_0_mc_resume_spg_mode - memory controller programming341 *342 * @adev: amdgpu_device pointer343 *344 * Let the VCN memory controller know it's offsets345 */346static void vcn_v1_0_mc_resume_spg_mode(struct amdgpu_device *adev)347{348 uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw[0]->size + 4);349 uint32_t offset;350 351 /* cache window 0: fw */352 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {353 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,354 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo));355 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,356 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi));357 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0, 0);358 offset = 0;359 } else {360 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,361 lower_32_bits(adev->vcn.inst->gpu_addr));362 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,363 upper_32_bits(adev->vcn.inst->gpu_addr));364 offset = size;365 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0,366 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);367 }368 369 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE0, size);370 371 /* cache window 1: stack */372 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,373 lower_32_bits(adev->vcn.inst->gpu_addr + offset));374 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,375 upper_32_bits(adev->vcn.inst->gpu_addr + offset));376 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1, 0);377 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);378 379 /* cache window 2: context */380 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,381 lower_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));382 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,383 upper_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));384 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2, 0);385 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);386 387 WREG32_SOC15(UVD, 0, mmUVD_UDEC_ADDR_CONFIG,388 adev->gfx.config.gb_addr_config);389 WREG32_SOC15(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG,390 adev->gfx.config.gb_addr_config);391 WREG32_SOC15(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG,392 adev->gfx.config.gb_addr_config);393 WREG32_SOC15(UVD, 0, mmUVD_UDEC_DBW_UV_ADDR_CONFIG,394 adev->gfx.config.gb_addr_config);395 WREG32_SOC15(UVD, 0, mmUVD_MIF_CURR_ADDR_CONFIG,396 adev->gfx.config.gb_addr_config);397 WREG32_SOC15(UVD, 0, mmUVD_MIF_CURR_UV_ADDR_CONFIG,398 adev->gfx.config.gb_addr_config);399 WREG32_SOC15(UVD, 0, mmUVD_MIF_RECON1_ADDR_CONFIG,400 adev->gfx.config.gb_addr_config);401 WREG32_SOC15(UVD, 0, mmUVD_MIF_RECON1_UV_ADDR_CONFIG,402 adev->gfx.config.gb_addr_config);403 WREG32_SOC15(UVD, 0, mmUVD_MIF_REF_ADDR_CONFIG,404 adev->gfx.config.gb_addr_config);405 WREG32_SOC15(UVD, 0, mmUVD_MIF_REF_UV_ADDR_CONFIG,406 adev->gfx.config.gb_addr_config);407 WREG32_SOC15(UVD, 0, mmUVD_JPEG_ADDR_CONFIG,408 adev->gfx.config.gb_addr_config);409 WREG32_SOC15(UVD, 0, mmUVD_JPEG_UV_ADDR_CONFIG,410 adev->gfx.config.gb_addr_config);411}412 413static void vcn_v1_0_mc_resume_dpg_mode(struct amdgpu_device *adev)414{415 uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw[0]->size + 4);416 uint32_t offset;417 418 /* cache window 0: fw */419 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {420 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,421 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo),422 0xFFFFFFFF, 0);423 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,424 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi),425 0xFFFFFFFF, 0);426 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0, 0,427 0xFFFFFFFF, 0);428 offset = 0;429 } else {430 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,431 lower_32_bits(adev->vcn.inst->gpu_addr), 0xFFFFFFFF, 0);432 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,433 upper_32_bits(adev->vcn.inst->gpu_addr), 0xFFFFFFFF, 0);434 offset = size;435 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0,436 AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0xFFFFFFFF, 0);437 }438 439 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_SIZE0, size, 0xFFFFFFFF, 0);440 441 /* cache window 1: stack */442 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,443 lower_32_bits(adev->vcn.inst->gpu_addr + offset), 0xFFFFFFFF, 0);444 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,445 upper_32_bits(adev->vcn.inst->gpu_addr + offset), 0xFFFFFFFF, 0);446 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1, 0,447 0xFFFFFFFF, 0);448 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE,449 0xFFFFFFFF, 0);450 451 /* cache window 2: context */452 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,453 lower_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE),454 0xFFFFFFFF, 0);455 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,456 upper_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE),457 0xFFFFFFFF, 0);458 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2, 0, 0xFFFFFFFF, 0);459 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE,460 0xFFFFFFFF, 0);461 462 /* VCN global tiling registers */463 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_UDEC_ADDR_CONFIG,464 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);465 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG,466 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);467 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG,468 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);469 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_UDEC_DBW_UV_ADDR_CONFIG,470 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);471 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MIF_CURR_ADDR_CONFIG,472 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);473 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MIF_CURR_UV_ADDR_CONFIG,474 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);475 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MIF_RECON1_ADDR_CONFIG,476 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);477 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MIF_RECON1_UV_ADDR_CONFIG,478 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);479 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MIF_REF_ADDR_CONFIG,480 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);481 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MIF_REF_UV_ADDR_CONFIG,482 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);483}484 485/**486 * vcn_v1_0_disable_clock_gating - disable VCN clock gating487 *488 * @adev: amdgpu_device pointer489 *490 * Disable clock gating for VCN block491 */492static void vcn_v1_0_disable_clock_gating(struct amdgpu_device *adev)493{494 uint32_t data;495 496 /* JPEG disable CGC */497 data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL);498 499 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)500 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;501 else502 data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE_MASK;503 504 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;505 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;506 WREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL, data);507 508 data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_GATE);509 data &= ~(JPEG_CGC_GATE__JPEG_MASK | JPEG_CGC_GATE__JPEG2_MASK);510 WREG32_SOC15(VCN, 0, mmJPEG_CGC_GATE, data);511 512 /* UVD disable CGC */513 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);514 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)515 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;516 else517 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;518 519 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;520 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;521 WREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL, data);522 523 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_GATE);524 data &= ~(UVD_CGC_GATE__SYS_MASK525 | UVD_CGC_GATE__UDEC_MASK526 | UVD_CGC_GATE__MPEG2_MASK527 | UVD_CGC_GATE__REGS_MASK528 | UVD_CGC_GATE__RBC_MASK529 | UVD_CGC_GATE__LMI_MC_MASK530 | UVD_CGC_GATE__LMI_UMC_MASK531 | UVD_CGC_GATE__IDCT_MASK532 | UVD_CGC_GATE__MPRD_MASK533 | UVD_CGC_GATE__MPC_MASK534 | UVD_CGC_GATE__LBSI_MASK535 | UVD_CGC_GATE__LRBBM_MASK536 | UVD_CGC_GATE__UDEC_RE_MASK537 | UVD_CGC_GATE__UDEC_CM_MASK538 | UVD_CGC_GATE__UDEC_IT_MASK539 | UVD_CGC_GATE__UDEC_DB_MASK540 | UVD_CGC_GATE__UDEC_MP_MASK541 | UVD_CGC_GATE__WCB_MASK542 | UVD_CGC_GATE__VCPU_MASK543 | UVD_CGC_GATE__SCPU_MASK);544 WREG32_SOC15(VCN, 0, mmUVD_CGC_GATE, data);545 546 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);547 data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK548 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK549 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK550 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK551 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK552 | UVD_CGC_CTRL__SYS_MODE_MASK553 | UVD_CGC_CTRL__UDEC_MODE_MASK554 | UVD_CGC_CTRL__MPEG2_MODE_MASK555 | UVD_CGC_CTRL__REGS_MODE_MASK556 | UVD_CGC_CTRL__RBC_MODE_MASK557 | UVD_CGC_CTRL__LMI_MC_MODE_MASK558 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK559 | UVD_CGC_CTRL__IDCT_MODE_MASK560 | UVD_CGC_CTRL__MPRD_MODE_MASK561 | UVD_CGC_CTRL__MPC_MODE_MASK562 | UVD_CGC_CTRL__LBSI_MODE_MASK563 | UVD_CGC_CTRL__LRBBM_MODE_MASK564 | UVD_CGC_CTRL__WCB_MODE_MASK565 | UVD_CGC_CTRL__VCPU_MODE_MASK566 | UVD_CGC_CTRL__SCPU_MODE_MASK);567 WREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL, data);568 569 /* turn on */570 data = RREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_GATE);571 data |= (UVD_SUVD_CGC_GATE__SRE_MASK572 | UVD_SUVD_CGC_GATE__SIT_MASK573 | UVD_SUVD_CGC_GATE__SMP_MASK574 | UVD_SUVD_CGC_GATE__SCM_MASK575 | UVD_SUVD_CGC_GATE__SDB_MASK576 | UVD_SUVD_CGC_GATE__SRE_H264_MASK577 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK578 | UVD_SUVD_CGC_GATE__SIT_H264_MASK579 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK580 | UVD_SUVD_CGC_GATE__SCM_H264_MASK581 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK582 | UVD_SUVD_CGC_GATE__SDB_H264_MASK583 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK584 | UVD_SUVD_CGC_GATE__SCLR_MASK585 | UVD_SUVD_CGC_GATE__UVD_SC_MASK586 | UVD_SUVD_CGC_GATE__ENT_MASK587 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK588 | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK589 | UVD_SUVD_CGC_GATE__SITE_MASK590 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK591 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK592 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK593 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK594 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK);595 WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_GATE, data);596 597 data = RREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL);598 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK599 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK600 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK601 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK602 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK603 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK604 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK605 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK606 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK607 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);608 WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL, data);609}610 611/**612 * vcn_v1_0_enable_clock_gating - enable VCN clock gating613 *614 * @adev: amdgpu_device pointer615 *616 * Enable clock gating for VCN block617 */618static void vcn_v1_0_enable_clock_gating(struct amdgpu_device *adev)619{620 uint32_t data = 0;621 622 /* enable JPEG CGC */623 data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL);624 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)625 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;626 else627 data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;628 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;629 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;630 WREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL, data);631 632 data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_GATE);633 data |= (JPEG_CGC_GATE__JPEG_MASK | JPEG_CGC_GATE__JPEG2_MASK);634 WREG32_SOC15(VCN, 0, mmJPEG_CGC_GATE, data);635 636 /* enable UVD CGC */637 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);638 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)639 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;640 else641 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;642 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;643 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;644 WREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL, data);645 646 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);647 data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK648 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK649 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK650 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK651 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK652 | UVD_CGC_CTRL__SYS_MODE_MASK653 | UVD_CGC_CTRL__UDEC_MODE_MASK654 | UVD_CGC_CTRL__MPEG2_MODE_MASK655 | UVD_CGC_CTRL__REGS_MODE_MASK656 | UVD_CGC_CTRL__RBC_MODE_MASK657 | UVD_CGC_CTRL__LMI_MC_MODE_MASK658 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK659 | UVD_CGC_CTRL__IDCT_MODE_MASK660 | UVD_CGC_CTRL__MPRD_MODE_MASK661 | UVD_CGC_CTRL__MPC_MODE_MASK662 | UVD_CGC_CTRL__LBSI_MODE_MASK663 | UVD_CGC_CTRL__LRBBM_MODE_MASK664 | UVD_CGC_CTRL__WCB_MODE_MASK665 | UVD_CGC_CTRL__VCPU_MODE_MASK666 | UVD_CGC_CTRL__SCPU_MODE_MASK);667 WREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL, data);668 669 data = RREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL);670 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK671 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK672 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK673 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK674 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK675 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK676 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK677 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK678 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK679 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);680 WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL, data);681}682 683static void vcn_v1_0_clock_gating_dpg_mode(struct amdgpu_device *adev, uint8_t sram_sel)684{685 uint32_t reg_data = 0;686 687 /* disable JPEG CGC */688 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)689 reg_data = 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;690 else691 reg_data = 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;692 reg_data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;693 reg_data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;694 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmJPEG_CGC_CTRL, reg_data, 0xFFFFFFFF, sram_sel);695 696 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmJPEG_CGC_GATE, 0, 0xFFFFFFFF, sram_sel);697 698 /* enable sw clock gating control */699 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)700 reg_data = 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;701 else702 reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;703 reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;704 reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;705 reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |706 UVD_CGC_CTRL__UDEC_CM_MODE_MASK |707 UVD_CGC_CTRL__UDEC_IT_MODE_MASK |708 UVD_CGC_CTRL__UDEC_DB_MODE_MASK |709 UVD_CGC_CTRL__UDEC_MP_MODE_MASK |710 UVD_CGC_CTRL__SYS_MODE_MASK |711 UVD_CGC_CTRL__UDEC_MODE_MASK |712 UVD_CGC_CTRL__MPEG2_MODE_MASK |713 UVD_CGC_CTRL__REGS_MODE_MASK |714 UVD_CGC_CTRL__RBC_MODE_MASK |715 UVD_CGC_CTRL__LMI_MC_MODE_MASK |716 UVD_CGC_CTRL__LMI_UMC_MODE_MASK |717 UVD_CGC_CTRL__IDCT_MODE_MASK |718 UVD_CGC_CTRL__MPRD_MODE_MASK |719 UVD_CGC_CTRL__MPC_MODE_MASK |720 UVD_CGC_CTRL__LBSI_MODE_MASK |721 UVD_CGC_CTRL__LRBBM_MODE_MASK |722 UVD_CGC_CTRL__WCB_MODE_MASK |723 UVD_CGC_CTRL__VCPU_MODE_MASK |724 UVD_CGC_CTRL__SCPU_MODE_MASK);725 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_CGC_CTRL, reg_data, 0xFFFFFFFF, sram_sel);726 727 /* turn off clock gating */728 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_CGC_GATE, 0, 0xFFFFFFFF, sram_sel);729 730 /* turn on SUVD clock gating */731 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_SUVD_CGC_GATE, 1, 0xFFFFFFFF, sram_sel);732 733 /* turn on sw mode in UVD_SUVD_CGC_CTRL */734 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_SUVD_CGC_CTRL, 0, 0xFFFFFFFF, sram_sel);735}736 737static void vcn_1_0_disable_static_power_gating(struct amdgpu_device *adev)738{739 uint32_t data = 0;740 741 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {742 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT743 | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT744 | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT745 | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT746 | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT747 | 2 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT748 | 2 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT749 | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT750 | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT751 | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT752 | 2 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT);753 754 WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data);755 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON, 0xFFFFFF);756 } else {757 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT758 | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT759 | 1 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT760 | 1 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT761 | 1 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT762 | 1 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT763 | 1 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT764 | 1 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT765 | 1 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT766 | 1 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT767 | 1 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT);768 WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data);769 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, 0, 0xFFFFFFFF);770 }771 772 /* polling UVD_PGFSM_STATUS to confirm UVDM_PWR_STATUS , UVDU_PWR_STATUS are 0 (power on) */773 774 data = RREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS);775 data &= ~0x103;776 if (adev->pg_flags & AMD_PG_SUPPORT_VCN)777 data |= UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON | UVD_POWER_STATUS__UVD_PG_EN_MASK;778 779 WREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS, data);780}781 782static void vcn_1_0_enable_static_power_gating(struct amdgpu_device *adev)783{784 uint32_t data = 0;785 786 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {787 /* Before power off, this indicator has to be turned on */788 data = RREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS);789 data &= ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK;790 data |= UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF;791 WREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS, data);792 793 794 data = (2 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT795 | 2 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT796 | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT797 | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT798 | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT799 | 2 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT800 | 2 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT801 | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT802 | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT803 | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT804 | 2 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT);805 806 WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data);807 808 data = (2 << UVD_PGFSM_STATUS__UVDM_PWR_STATUS__SHIFT809 | 2 << UVD_PGFSM_STATUS__UVDU_PWR_STATUS__SHIFT810 | 2 << UVD_PGFSM_STATUS__UVDF_PWR_STATUS__SHIFT811 | 2 << UVD_PGFSM_STATUS__UVDC_PWR_STATUS__SHIFT812 | 2 << UVD_PGFSM_STATUS__UVDB_PWR_STATUS__SHIFT813 | 2 << UVD_PGFSM_STATUS__UVDIL_PWR_STATUS__SHIFT814 | 2 << UVD_PGFSM_STATUS__UVDIR_PWR_STATUS__SHIFT815 | 2 << UVD_PGFSM_STATUS__UVDTD_PWR_STATUS__SHIFT816 | 2 << UVD_PGFSM_STATUS__UVDTE_PWR_STATUS__SHIFT817 | 2 << UVD_PGFSM_STATUS__UVDE_PWR_STATUS__SHIFT818 | 2 << UVD_PGFSM_STATUS__UVDW_PWR_STATUS__SHIFT);819 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, data, 0xFFFFFFFF);820 }821}822 823/**824 * vcn_v1_0_start_spg_mode - start VCN block825 *826 * @adev: amdgpu_device pointer827 *828 * Setup and start the VCN block829 */830static int vcn_v1_0_start_spg_mode(struct amdgpu_device *adev)831{832 struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec;833 uint32_t rb_bufsz, tmp;834 uint32_t lmi_swap_cntl;835 int i, j, r;836 837 /* disable byte swapping */838 lmi_swap_cntl = 0;839 840 vcn_1_0_disable_static_power_gating(adev);841 842 tmp = RREG32_SOC15(UVD, 0, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;843 WREG32_SOC15(UVD, 0, mmUVD_STATUS, tmp);844 845 /* disable clock gating */846 vcn_v1_0_disable_clock_gating(adev);847 848 /* disable interupt */849 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0,850 ~UVD_MASTINT_EN__VCPU_EN_MASK);851 852 /* initialize VCN memory controller */853 tmp = RREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL);854 WREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL, tmp |855 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |856 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |857 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |858 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);859 860#ifdef __BIG_ENDIAN861 /* swap (8 in 32) RB and IB */862 lmi_swap_cntl = 0xa;863#endif864 WREG32_SOC15(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl);865 866 tmp = RREG32_SOC15(UVD, 0, mmUVD_MPC_CNTL);867 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;868 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;869 WREG32_SOC15(UVD, 0, mmUVD_MPC_CNTL, tmp);870 871 WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA0,872 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |873 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |874 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |875 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));876 877 WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB0,878 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |879 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |880 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |881 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));882 883 WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUX,884 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |885 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |886 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));887 888 vcn_v1_0_mc_resume_spg_mode(adev);889 890 WREG32_SOC15(UVD, 0, mmUVD_REG_XX_MASK_1_0, 0x10);891 WREG32_SOC15(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK_1_0,892 RREG32_SOC15(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK_1_0) | 0x3);893 894 /* enable VCPU clock */895 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, UVD_VCPU_CNTL__CLK_EN_MASK);896 897 /* boot up the VCPU */898 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0,899 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);900 901 /* enable UMC */902 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0,903 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);904 905 tmp = RREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET);906 tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;907 tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;908 WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, tmp);909 910 for (i = 0; i < 10; ++i) {911 uint32_t status;912 913 for (j = 0; j < 100; ++j) {914 status = RREG32_SOC15(UVD, 0, mmUVD_STATUS);915 if (status & UVD_STATUS__IDLE)916 break;917 mdelay(10);918 }919 r = 0;920 if (status & UVD_STATUS__IDLE)921 break;922 923 DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n");924 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),925 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,926 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);927 mdelay(10);928 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0,929 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);930 mdelay(10);931 r = -1;932 }933 934 if (r) {935 DRM_ERROR("VCN decode not responding, giving up!!!\n");936 return r;937 }938 /* enable master interrupt */939 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN),940 UVD_MASTINT_EN__VCPU_EN_MASK, ~UVD_MASTINT_EN__VCPU_EN_MASK);941 942 /* enable system interrupt for JRBC, TODO: move to set interrupt*/943 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SYS_INT_EN),944 UVD_SYS_INT_EN__UVD_JRBC_EN_MASK,945 ~UVD_SYS_INT_EN__UVD_JRBC_EN_MASK);946 947 /* clear the busy bit of UVD_STATUS */948 tmp = RREG32_SOC15(UVD, 0, mmUVD_STATUS) & ~UVD_STATUS__UVD_BUSY;949 WREG32_SOC15(UVD, 0, mmUVD_STATUS, tmp);950 951 /* force RBC into idle state */952 rb_bufsz = order_base_2(ring->ring_size);953 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);954 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);955 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);956 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);957 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);958 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp);959 960 /* set the write pointer delay */961 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL, 0);962 963 /* set the wb address */964 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR_ADDR,965 (upper_32_bits(ring->gpu_addr) >> 2));966 967 /* program the RB_BASE for ring buffer */968 WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,969 lower_32_bits(ring->gpu_addr));970 WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,971 upper_32_bits(ring->gpu_addr));972 973 /* Initialize the ring buffer's read and write pointers */974 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR, 0);975 976 WREG32_SOC15(UVD, 0, mmUVD_SCRATCH2, 0);977 978 ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR);979 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,980 lower_32_bits(ring->wptr));981 982 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0,983 ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK);984 985 ring = &adev->vcn.inst->ring_enc[0];986 WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));987 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));988 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr);989 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));990 WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4);991 992 ring = &adev->vcn.inst->ring_enc[1];993 WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));994 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));995 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr);996 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));997 WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4);998 999 jpeg_v1_0_start(adev, 0);1000 1001 return 0;1002}1003 1004static int vcn_v1_0_start_dpg_mode(struct amdgpu_device *adev)1005{1006 struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec;1007 uint32_t rb_bufsz, tmp;1008 uint32_t lmi_swap_cntl;1009 1010 /* disable byte swapping */1011 lmi_swap_cntl = 0;1012 1013 vcn_1_0_enable_static_power_gating(adev);1014 1015 /* enable dynamic power gating mode */1016 tmp = RREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS);1017 tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;1018 tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK;1019 WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, tmp);1020 1021 /* enable clock gating */1022 vcn_v1_0_clock_gating_dpg_mode(adev, 0);1023 1024 /* enable VCPU clock */1025 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);1026 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;1027 tmp |= UVD_VCPU_CNTL__MIF_WR_LOW_THRESHOLD_BP_MASK;1028 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CNTL, tmp, 0xFFFFFFFF, 0);1029 1030 /* disable interupt */1031 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MASTINT_EN,1032 0, UVD_MASTINT_EN__VCPU_EN_MASK, 0);1033 1034 /* initialize VCN memory controller */1035 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_CTRL,1036 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |1037 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |1038 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |1039 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |1040 UVD_LMI_CTRL__REQ_MODE_MASK |1041 UVD_LMI_CTRL__CRC_RESET_MASK |1042 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |1043 0x00100000L, 0xFFFFFFFF, 0);1044 1045#ifdef __BIG_ENDIAN1046 /* swap (8 in 32) RB and IB */1047 lmi_swap_cntl = 0xa;1048#endif1049 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl, 0xFFFFFFFF, 0);1050 1051 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MPC_CNTL,1052 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0xFFFFFFFF, 0);1053 1054 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MPC_SET_MUXA0,1055 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |1056 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |1057 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |1058 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0xFFFFFFFF, 0);1059 1060 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MPC_SET_MUXB0,1061 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |1062 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |1063 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |1064 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0xFFFFFFFF, 0);1065 1066 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MPC_SET_MUX,1067 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |1068 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |1069 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0xFFFFFFFF, 0);1070 1071 vcn_v1_0_mc_resume_dpg_mode(adev);1072 1073 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_REG_XX_MASK, 0x10, 0xFFFFFFFF, 0);1074 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK, 0x3, 0xFFFFFFFF, 0);1075 1076 /* boot up the VCPU */1077 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_SOFT_RESET, 0, 0xFFFFFFFF, 0);1078 1079 /* enable UMC */1080 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_CTRL2,1081 0x1F << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT,1082 0xFFFFFFFF, 0);1083 1084 /* enable master interrupt */1085 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MASTINT_EN,1086 UVD_MASTINT_EN__VCPU_EN_MASK, UVD_MASTINT_EN__VCPU_EN_MASK, 0);1087 1088 vcn_v1_0_clock_gating_dpg_mode(adev, 1);1089 /* setup mmUVD_LMI_CTRL */1090 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_CTRL,1091 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |1092 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |1093 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |1094 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |1095 UVD_LMI_CTRL__REQ_MODE_MASK |1096 UVD_LMI_CTRL__CRC_RESET_MASK |1097 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |1098 0x00100000L, 0xFFFFFFFF, 1);1099 1100 tmp = adev->gfx.config.gb_addr_config;1101 /* setup VCN global tiling registers */1102 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_JPEG_ADDR_CONFIG, tmp, 0xFFFFFFFF, 1);1103 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_JPEG_UV_ADDR_CONFIG, tmp, 0xFFFFFFFF, 1);1104 1105 /* enable System Interrupt for JRBC */1106 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_SYS_INT_EN,1107 UVD_SYS_INT_EN__UVD_JRBC_EN_MASK, 0xFFFFFFFF, 1);1108 1109 /* force RBC into idle state */1110 rb_bufsz = order_base_2(ring->ring_size);1111 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);1112 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);1113 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);1114 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);1115 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);1116 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp);1117 1118 /* set the write pointer delay */1119 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL, 0);1120 1121 /* set the wb address */1122 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR_ADDR,1123 (upper_32_bits(ring->gpu_addr) >> 2));1124 1125 /* program the RB_BASE for ring buffer */1126 WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,1127 lower_32_bits(ring->gpu_addr));1128 WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,1129 upper_32_bits(ring->gpu_addr));1130 1131 /* Initialize the ring buffer's read and write pointers */1132 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR, 0);1133 1134 WREG32_SOC15(UVD, 0, mmUVD_SCRATCH2, 0);1135 1136 ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR);1137 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,1138 lower_32_bits(ring->wptr));1139 1140 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0,1141 ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK);1142 1143 jpeg_v1_0_start(adev, 1);1144 1145 return 0;1146}1147 1148static int vcn_v1_0_start(struct amdgpu_device *adev)1149{1150 return (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ?1151 vcn_v1_0_start_dpg_mode(adev) : vcn_v1_0_start_spg_mode(adev);1152}1153 1154/**1155 * vcn_v1_0_stop_spg_mode - stop VCN block1156 *1157 * @adev: amdgpu_device pointer1158 *1159 * stop the VCN block1160 */1161static int vcn_v1_0_stop_spg_mode(struct amdgpu_device *adev)1162{1163 int tmp;1164 1165 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7);1166 1167 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |1168 UVD_LMI_STATUS__READ_CLEAN_MASK |1169 UVD_LMI_STATUS__WRITE_CLEAN_MASK |1170 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;1171 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_LMI_STATUS, tmp, tmp);1172 1173 /* stall UMC channel */1174 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),1175 UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,1176 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);1177 1178 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK |1179 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;1180 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_LMI_STATUS, tmp, tmp);1181 1182 /* disable VCPU clock */1183 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL), 0,1184 ~UVD_VCPU_CNTL__CLK_EN_MASK);1185 1186 /* reset LMI UMC/LMI */1187 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),1188 UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK,1189 ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);1190 1191 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),1192 UVD_SOFT_RESET__LMI_SOFT_RESET_MASK,1193 ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK);1194 1195 /* put VCPU into reset */1196 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),1197 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,1198 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);1199 1200 WREG32_SOC15(UVD, 0, mmUVD_STATUS, 0);1201 1202 vcn_v1_0_enable_clock_gating(adev);1203 vcn_1_0_enable_static_power_gating(adev);1204 return 0;1205}1206 1207static int vcn_v1_0_stop_dpg_mode(struct amdgpu_device *adev)1208{1209 uint32_t tmp;1210 1211 /* Wait for power status to be UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF */1212 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,1213 UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,1214 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);1215 1216 /* wait for read ptr to be equal to write ptr */1217 tmp = RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR);1218 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RB_RPTR, tmp, 0xFFFFFFFF);1219 1220 tmp = RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2);1221 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RB_RPTR2, tmp, 0xFFFFFFFF);1222 1223 tmp = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR);1224 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_JRBC_RB_RPTR, tmp, 0xFFFFFFFF);1225 1226 tmp = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF;1227 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF);1228 1229 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,1230 UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,1231 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);1232 1233 /* disable dynamic power gating mode */1234 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), 0,1235 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);1236 1237 return 0;1238}1239 1240static int vcn_v1_0_stop(struct amdgpu_device *adev)1241{1242 int r;1243 1244 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)1245 r = vcn_v1_0_stop_dpg_mode(adev);1246 else1247 r = vcn_v1_0_stop_spg_mode(adev);1248 1249 return r;1250}1251 1252static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev,1253 int inst_idx, struct dpg_pause_state *new_state)1254{1255 int ret_code;1256 uint32_t reg_data = 0;1257 uint32_t reg_data2 = 0;1258 struct amdgpu_ring *ring;1259 1260 /* pause/unpause if state is changed */1261 if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) {1262 DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d",1263 adev->vcn.inst[inst_idx].pause_state.fw_based,1264 adev->vcn.inst[inst_idx].pause_state.jpeg,1265 new_state->fw_based, new_state->jpeg);1266 1267 reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) &1268 (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);1269 1270 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {1271 ret_code = 0;1272 1273 if (!(reg_data & UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK))1274 ret_code = SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,1275 UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,1276 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);1277 1278 if (!ret_code) {1279 /* pause DPG non-jpeg */1280 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;1281 WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);1282 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE,1283 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,1284 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);1285 1286 /* Restore */1287 ring = &adev->vcn.inst->ring_enc[0];1288 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr);1289 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));1290 WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4);1291 WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));1292 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));1293 1294 ring = &adev->vcn.inst->ring_enc[1];1295 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr);1296 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));1297 WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4);1298 WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));1299 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));1300 1301 ring = &adev->vcn.inst->ring_dec;1302 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,1303 RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF);1304 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,1305 UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON,1306 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);1307 }1308 } else {1309 /* unpause dpg non-jpeg, no need to wait */1310 reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;1311 WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);1312 }1313 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;1314 }1315 1316 /* pause/unpause if state is changed */1317 if (adev->vcn.inst[inst_idx].pause_state.jpeg != new_state->jpeg) {1318 DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d",1319 adev->vcn.inst[inst_idx].pause_state.fw_based,1320 adev->vcn.inst[inst_idx].pause_state.jpeg,1321 new_state->fw_based, new_state->jpeg);1322 1323 reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) &1324 (~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK);1325 1326 if (new_state->jpeg == VCN_DPG_STATE__PAUSE) {1327 ret_code = 0;1328 1329 if (!(reg_data & UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK))1330 ret_code = SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,1331 UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,1332 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);1333 1334 if (!ret_code) {1335 /* Make sure JPRG Snoop is disabled before sending the pause */1336 reg_data2 = RREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS);1337 reg_data2 |= UVD_POWER_STATUS__JRBC_SNOOP_DIS_MASK;1338 WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, reg_data2);1339 1340 /* pause DPG jpeg */1341 reg_data |= UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;1342 WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);1343 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE,1344 UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK,1345 UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK);1346 1347 /* Restore */1348 ring = adev->jpeg.inst->ring_dec;1349 WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_VMID, 0);1350 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,1351 UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK |1352 UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);1353 WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,1354 lower_32_bits(ring->gpu_addr));1355 WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,1356 upper_32_bits(ring->gpu_addr));1357 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR, ring->wptr);1358 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, ring->wptr);1359 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,1360 UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);1361 1362 ring = &adev->vcn.inst->ring_dec;1363 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,1364 RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF);1365 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,1366 UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON,1367 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);1368 }1369 } else {1370 /* unpause dpg jpeg, no need to wait */1371 reg_data &= ~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;1372 WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);1373 }1374 adev->vcn.inst[inst_idx].pause_state.jpeg = new_state->jpeg;1375 }1376 1377 return 0;1378}1379 1380static bool vcn_v1_0_is_idle(void *handle)1381{1382 struct amdgpu_device *adev = (struct amdgpu_device *)handle;1383 1384 return (RREG32_SOC15(VCN, 0, mmUVD_STATUS) == UVD_STATUS__IDLE);1385}1386 1387static int vcn_v1_0_wait_for_idle(void *handle)1388{1389 struct amdgpu_device *adev = (struct amdgpu_device *)handle;1390 int ret;1391 1392 ret = SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_STATUS, UVD_STATUS__IDLE,1393 UVD_STATUS__IDLE);1394 1395 return ret;1396}1397 1398static int vcn_v1_0_set_clockgating_state(void *handle,1399 enum amd_clockgating_state state)1400{1401 struct amdgpu_device *adev = (struct amdgpu_device *)handle;1402 bool enable = (state == AMD_CG_STATE_GATE);1403 1404 if (enable) {1405 /* wait for STATUS to clear */1406 if (!vcn_v1_0_is_idle(handle))1407 return -EBUSY;1408 vcn_v1_0_enable_clock_gating(adev);1409 } else {1410 /* disable HW gating and enable Sw gating */1411 vcn_v1_0_disable_clock_gating(adev);1412 }1413 return 0;1414}1415 1416/**1417 * vcn_v1_0_dec_ring_get_rptr - get read pointer1418 *1419 * @ring: amdgpu_ring pointer1420 *1421 * Returns the current hardware read pointer1422 */1423static uint64_t vcn_v1_0_dec_ring_get_rptr(struct amdgpu_ring *ring)1424{1425 struct amdgpu_device *adev = ring->adev;1426 1427 return RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR);1428}1429 1430/**1431 * vcn_v1_0_dec_ring_get_wptr - get write pointer1432 *1433 * @ring: amdgpu_ring pointer1434 *1435 * Returns the current hardware write pointer1436 */1437static uint64_t vcn_v1_0_dec_ring_get_wptr(struct amdgpu_ring *ring)1438{1439 struct amdgpu_device *adev = ring->adev;1440 1441 return RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR);1442}1443 1444/**1445 * vcn_v1_0_dec_ring_set_wptr - set write pointer1446 *1447 * @ring: amdgpu_ring pointer1448 *1449 * Commits the write pointer to the hardware1450 */1451static void vcn_v1_0_dec_ring_set_wptr(struct amdgpu_ring *ring)1452{1453 struct amdgpu_device *adev = ring->adev;1454 1455 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)1456 WREG32_SOC15(UVD, 0, mmUVD_SCRATCH2,1457 lower_32_bits(ring->wptr) | 0x80000000);1458 1459 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));1460}1461 1462/**1463 * vcn_v1_0_dec_ring_insert_start - insert a start command1464 *1465 * @ring: amdgpu_ring pointer1466 *1467 * Write a start command to the ring.1468 */1469static void vcn_v1_0_dec_ring_insert_start(struct amdgpu_ring *ring)1470{1471 struct amdgpu_device *adev = ring->adev;1472 1473 amdgpu_ring_write(ring,1474 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));1475 amdgpu_ring_write(ring, 0);1476 amdgpu_ring_write(ring,1477 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));1478 amdgpu_ring_write(ring, VCN_DEC_CMD_PACKET_START << 1);1479}1480 1481/**1482 * vcn_v1_0_dec_ring_insert_end - insert a end command1483 *1484 * @ring: amdgpu_ring pointer1485 *1486 * Write a end command to the ring.1487 */1488static void vcn_v1_0_dec_ring_insert_end(struct amdgpu_ring *ring)1489{1490 struct amdgpu_device *adev = ring->adev;1491 1492 amdgpu_ring_write(ring,1493 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));1494 amdgpu_ring_write(ring, VCN_DEC_CMD_PACKET_END << 1);1495}1496 1497/**1498 * vcn_v1_0_dec_ring_emit_fence - emit an fence & trap command1499 *1500 * @ring: amdgpu_ring pointer1501 * @addr: address1502 * @seq: sequence number1503 * @flags: fence related flags1504 *1505 * Write a fence and a trap command to the ring.1506 */1507static void vcn_v1_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,1508 unsigned flags)1509{1510 struct amdgpu_device *adev = ring->adev;1511 1512 WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);1513 1514 amdgpu_ring_write(ring,1515 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0));1516 amdgpu_ring_write(ring, seq);1517 amdgpu_ring_write(ring,1518 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));1519 amdgpu_ring_write(ring, addr & 0xffffffff);1520 amdgpu_ring_write(ring,1521 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0));1522 amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff);1523 amdgpu_ring_write(ring,1524 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));1525 amdgpu_ring_write(ring, VCN_DEC_CMD_FENCE << 1);1526 1527 amdgpu_ring_write(ring,1528 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));1529 amdgpu_ring_write(ring, 0);1530 amdgpu_ring_write(ring,1531 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0));1532 amdgpu_ring_write(ring, 0);1533 amdgpu_ring_write(ring,1534 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));1535 amdgpu_ring_write(ring, VCN_DEC_CMD_TRAP << 1);1536}1537 1538/**1539 * vcn_v1_0_dec_ring_emit_ib - execute indirect buffer1540 *1541 * @ring: amdgpu_ring pointer1542 * @job: job to retrieve vmid from1543 * @ib: indirect buffer to execute1544 * @flags: unused1545 *1546 * Write ring commands to execute the indirect buffer1547 */1548static void vcn_v1_0_dec_ring_emit_ib(struct amdgpu_ring *ring,1549 struct amdgpu_job *job,1550 struct amdgpu_ib *ib,1551 uint32_t flags)1552{1553 struct amdgpu_device *adev = ring->adev;1554 unsigned vmid = AMDGPU_JOB_GET_VMID(job);1555 1556 amdgpu_ring_write(ring,1557 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_VMID), 0));1558 amdgpu_ring_write(ring, vmid);1559 1560 amdgpu_ring_write(ring,1561 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_LOW), 0));1562 amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));1563 amdgpu_ring_write(ring,1564 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH), 0));1565 amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));1566 amdgpu_ring_write(ring,1567 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_IB_SIZE), 0));1568 amdgpu_ring_write(ring, ib->length_dw);1569}1570 1571static void vcn_v1_0_dec_ring_emit_reg_wait(struct amdgpu_ring *ring,1572 uint32_t reg, uint32_t val,1573 uint32_t mask)1574{1575 struct amdgpu_device *adev = ring->adev;1576 1577 amdgpu_ring_write(ring,1578 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));1579 amdgpu_ring_write(ring, reg << 2);1580 amdgpu_ring_write(ring,1581 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0));1582 amdgpu_ring_write(ring, val);1583 amdgpu_ring_write(ring,1584 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GP_SCRATCH8), 0));1585 amdgpu_ring_write(ring, mask);1586 amdgpu_ring_write(ring,1587 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));1588 amdgpu_ring_write(ring, VCN_DEC_CMD_REG_READ_COND_WAIT << 1);1589}1590 1591static void vcn_v1_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring,1592 unsigned vmid, uint64_t pd_addr)1593{1594 struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->vm_hub];1595 uint32_t data0, data1, mask;1596 1597 pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);1598 1599 /* wait for register write */1600 data0 = hub->ctx0_ptb_addr_lo32 + vmid * hub->ctx_addr_distance;1601 data1 = lower_32_bits(pd_addr);1602 mask = 0xffffffff;1603 vcn_v1_0_dec_ring_emit_reg_wait(ring, data0, data1, mask);1604}1605 1606static void vcn_v1_0_dec_ring_emit_wreg(struct amdgpu_ring *ring,1607 uint32_t reg, uint32_t val)1608{1609 struct amdgpu_device *adev = ring->adev;1610 1611 amdgpu_ring_write(ring,1612 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));1613 amdgpu_ring_write(ring, reg << 2);1614 amdgpu_ring_write(ring,1615 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0));1616 amdgpu_ring_write(ring, val);1617 amdgpu_ring_write(ring,1618 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));1619 amdgpu_ring_write(ring, VCN_DEC_CMD_WRITE_REG << 1);1620}1621 1622/**1623 * vcn_v1_0_enc_ring_get_rptr - get enc read pointer1624 *1625 * @ring: amdgpu_ring pointer1626 *1627 * Returns the current hardware enc read pointer1628 */1629static uint64_t vcn_v1_0_enc_ring_get_rptr(struct amdgpu_ring *ring)1630{1631 struct amdgpu_device *adev = ring->adev;1632 1633 if (ring == &adev->vcn.inst->ring_enc[0])1634 return RREG32_SOC15(UVD, 0, mmUVD_RB_RPTR);1635 else1636 return RREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2);1637}1638 1639 /**1640 * vcn_v1_0_enc_ring_get_wptr - get enc write pointer1641 *1642 * @ring: amdgpu_ring pointer1643 *1644 * Returns the current hardware enc write pointer1645 */1646static uint64_t vcn_v1_0_enc_ring_get_wptr(struct amdgpu_ring *ring)1647{1648 struct amdgpu_device *adev = ring->adev;1649 1650 if (ring == &adev->vcn.inst->ring_enc[0])1651 return RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR);1652 else1653 return RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2);1654}1655 1656 /**1657 * vcn_v1_0_enc_ring_set_wptr - set enc write pointer1658 *1659 * @ring: amdgpu_ring pointer1660 *1661 * Commits the enc write pointer to the hardware1662 */1663static void vcn_v1_0_enc_ring_set_wptr(struct amdgpu_ring *ring)1664{1665 struct amdgpu_device *adev = ring->adev;1666 1667 if (ring == &adev->vcn.inst->ring_enc[0])1668 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR,1669 lower_32_bits(ring->wptr));1670 else1671 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2,1672 lower_32_bits(ring->wptr));1673}1674 1675/**1676 * vcn_v1_0_enc_ring_emit_fence - emit an enc fence & trap command1677 *1678 * @ring: amdgpu_ring pointer1679 * @addr: address1680 * @seq: sequence number1681 * @flags: fence related flags1682 *1683 * Write enc a fence and a trap command to the ring.1684 */1685static void vcn_v1_0_enc_ring_emit_fence(struct amdgpu_ring *ring, u64 addr,1686 u64 seq, unsigned flags)1687{1688 WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);1689 1690 amdgpu_ring_write(ring, VCN_ENC_CMD_FENCE);1691 amdgpu_ring_write(ring, addr);1692 amdgpu_ring_write(ring, upper_32_bits(addr));1693 amdgpu_ring_write(ring, seq);1694 amdgpu_ring_write(ring, VCN_ENC_CMD_TRAP);1695}1696 1697static void vcn_v1_0_enc_ring_insert_end(struct amdgpu_ring *ring)1698{1699 amdgpu_ring_write(ring, VCN_ENC_CMD_END);1700}1701 1702/**1703 * vcn_v1_0_enc_ring_emit_ib - enc execute indirect buffer1704 *1705 * @ring: amdgpu_ring pointer1706 * @job: job to retrive vmid from1707 * @ib: indirect buffer to execute1708 * @flags: unused1709 *1710 * Write enc ring commands to execute the indirect buffer1711 */1712static void vcn_v1_0_enc_ring_emit_ib(struct amdgpu_ring *ring,1713 struct amdgpu_job *job,1714 struct amdgpu_ib *ib,1715 uint32_t flags)1716{1717 unsigned vmid = AMDGPU_JOB_GET_VMID(job);1718 1719 amdgpu_ring_write(ring, VCN_ENC_CMD_IB);1720 amdgpu_ring_write(ring, vmid);1721 amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));1722 amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));1723 amdgpu_ring_write(ring, ib->length_dw);1724}1725 1726static void vcn_v1_0_enc_ring_emit_reg_wait(struct amdgpu_ring *ring,1727 uint32_t reg, uint32_t val,1728 uint32_t mask)1729{1730 amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WAIT);1731 amdgpu_ring_write(ring, reg << 2);1732 amdgpu_ring_write(ring, mask);1733 amdgpu_ring_write(ring, val);1734}1735 1736static void vcn_v1_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring,1737 unsigned int vmid, uint64_t pd_addr)1738{1739 struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->vm_hub];1740 1741 pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);1742 1743 /* wait for reg writes */1744 vcn_v1_0_enc_ring_emit_reg_wait(ring, hub->ctx0_ptb_addr_lo32 +1745 vmid * hub->ctx_addr_distance,1746 lower_32_bits(pd_addr), 0xffffffff);1747}1748 1749static void vcn_v1_0_enc_ring_emit_wreg(struct amdgpu_ring *ring,1750 uint32_t reg, uint32_t val)1751{1752 amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WRITE);1753 amdgpu_ring_write(ring, reg << 2);1754 amdgpu_ring_write(ring, val);1755}1756 1757static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev,1758 struct amdgpu_irq_src *source,1759 unsigned type,1760 enum amdgpu_interrupt_state state)1761{1762 return 0;1763}1764 1765static int vcn_v1_0_process_interrupt(struct amdgpu_device *adev,1766 struct amdgpu_irq_src *source,1767 struct amdgpu_iv_entry *entry)1768{1769 DRM_DEBUG("IH: VCN TRAP\n");1770 1771 switch (entry->src_id) {1772 case 124:1773 amdgpu_fence_process(&adev->vcn.inst->ring_dec);1774 break;1775 case 119:1776 amdgpu_fence_process(&adev->vcn.inst->ring_enc[0]);1777 break;1778 case 120:1779 amdgpu_fence_process(&adev->vcn.inst->ring_enc[1]);1780 break;1781 default:1782 DRM_ERROR("Unhandled interrupt: %d %d\n",1783 entry->src_id, entry->src_data[0]);1784 break;1785 }1786 1787 return 0;1788}1789 1790static void vcn_v1_0_dec_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)1791{1792 struct amdgpu_device *adev = ring->adev;1793 int i;1794 1795 WARN_ON(ring->wptr % 2 || count % 2);1796 1797 for (i = 0; i < count / 2; i++) {1798 amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP), 0));1799 amdgpu_ring_write(ring, 0);1800 }1801}1802 1803static int vcn_v1_0_set_powergating_state(void *handle,1804 enum amd_powergating_state state)1805{1806 /* This doesn't actually powergate the VCN block.1807 * That's done in the dpm code via the SMC. This1808 * just re-inits the block as necessary. The actual1809 * gating still happens in the dpm code. We should1810 * revisit this when there is a cleaner line between1811 * the smc and the hw blocks1812 */1813 int ret;1814 struct amdgpu_device *adev = (struct amdgpu_device *)handle;1815 1816 if (state == adev->vcn.cur_state)1817 return 0;1818 1819 if (state == AMD_PG_STATE_GATE)1820 ret = vcn_v1_0_stop(adev);1821 else1822 ret = vcn_v1_0_start(adev);1823 1824 if (!ret)1825 adev->vcn.cur_state = state;1826 return ret;1827}1828 1829static void vcn_v1_0_idle_work_handler(struct work_struct *work)1830{1831 struct amdgpu_device *adev =1832 container_of(work, struct amdgpu_device, vcn.idle_work.work);1833 unsigned int fences = 0, i;1834 1835 for (i = 0; i < adev->vcn.num_enc_rings; ++i)1836 fences += amdgpu_fence_count_emitted(&adev->vcn.inst->ring_enc[i]);1837 1838 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {1839 struct dpg_pause_state new_state;1840 1841 if (fences)1842 new_state.fw_based = VCN_DPG_STATE__PAUSE;1843 else1844 new_state.fw_based = VCN_DPG_STATE__UNPAUSE;1845 1846 if (amdgpu_fence_count_emitted(adev->jpeg.inst->ring_dec))1847 new_state.jpeg = VCN_DPG_STATE__PAUSE;1848 else1849 new_state.jpeg = VCN_DPG_STATE__UNPAUSE;1850 1851 adev->vcn.pause_dpg_mode(adev, 0, &new_state);1852 }1853 1854 fences += amdgpu_fence_count_emitted(adev->jpeg.inst->ring_dec);1855 fences += amdgpu_fence_count_emitted(&adev->vcn.inst->ring_dec);1856 1857 if (fences == 0) {1858 amdgpu_gfx_off_ctrl(adev, true);1859 if (adev->pm.dpm_enabled)1860 amdgpu_dpm_enable_uvd(adev, false);1861 else1862 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,1863 AMD_PG_STATE_GATE);1864 } else {1865 schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);1866 }1867}1868 1869static void vcn_v1_0_ring_begin_use(struct amdgpu_ring *ring)1870{1871 struct amdgpu_device *adev = ring->adev;1872 bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);1873 1874 mutex_lock(&adev->vcn.vcn1_jpeg1_workaround);1875 1876 if (amdgpu_fence_wait_empty(ring->adev->jpeg.inst->ring_dec))1877 DRM_ERROR("VCN dec: jpeg dec ring may not be empty\n");1878 1879 vcn_v1_0_set_pg_for_begin_use(ring, set_clocks);1880 1881}1882 1883void vcn_v1_0_set_pg_for_begin_use(struct amdgpu_ring *ring, bool set_clocks)1884{1885 struct amdgpu_device *adev = ring->adev;1886 1887 if (set_clocks) {1888 amdgpu_gfx_off_ctrl(adev, false);1889 if (adev->pm.dpm_enabled)1890 amdgpu_dpm_enable_uvd(adev, true);1891 else1892 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,1893 AMD_PG_STATE_UNGATE);1894 }1895 1896 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {1897 struct dpg_pause_state new_state;1898 unsigned int fences = 0, i;1899 1900 for (i = 0; i < adev->vcn.num_enc_rings; ++i)1901 fences += amdgpu_fence_count_emitted(&adev->vcn.inst->ring_enc[i]);1902 1903 if (fences)1904 new_state.fw_based = VCN_DPG_STATE__PAUSE;1905 else1906 new_state.fw_based = VCN_DPG_STATE__UNPAUSE;1907 1908 if (amdgpu_fence_count_emitted(adev->jpeg.inst->ring_dec))1909 new_state.jpeg = VCN_DPG_STATE__PAUSE;1910 else1911 new_state.jpeg = VCN_DPG_STATE__UNPAUSE;1912 1913 if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)1914 new_state.fw_based = VCN_DPG_STATE__PAUSE;1915 else if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG)1916 new_state.jpeg = VCN_DPG_STATE__PAUSE;1917 1918 adev->vcn.pause_dpg_mode(adev, 0, &new_state);1919 }1920}1921 1922void vcn_v1_0_ring_end_use(struct amdgpu_ring *ring)1923{1924 schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT);1925 mutex_unlock(&ring->adev->vcn.vcn1_jpeg1_workaround);1926}1927 1928static void vcn_v1_0_print_ip_state(void *handle, struct drm_printer *p)1929{1930 struct amdgpu_device *adev = (struct amdgpu_device *)handle;1931 int i, j;1932 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_1_0);1933 uint32_t inst_off, is_powered;1934 1935 if (!adev->vcn.ip_dump)1936 return;1937 1938 drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst);1939 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {1940 if (adev->vcn.harvest_config & (1 << i)) {1941 drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i);1942 continue;1943 }1944 1945 inst_off = i * reg_count;1946 is_powered = (adev->vcn.ip_dump[inst_off] &1947 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1;1948 1949 if (is_powered) {1950 drm_printf(p, "\nActive Instance:VCN%d\n", i);1951 for (j = 0; j < reg_count; j++)1952 drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_1_0[j].reg_name,1953 adev->vcn.ip_dump[inst_off + j]);1954 } else {1955 drm_printf(p, "\nInactive Instance:VCN%d\n", i);1956 }1957 }1958}1959 1960static void vcn_v1_0_dump_ip_state(void *handle)1961{1962 struct amdgpu_device *adev = (struct amdgpu_device *)handle;1963 int i, j;1964 bool is_powered;1965 uint32_t inst_off;1966 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_1_0);1967 1968 if (!adev->vcn.ip_dump)1969 return;1970 1971 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {1972 if (adev->vcn.harvest_config & (1 << i))1973 continue;1974 1975 inst_off = i * reg_count;1976 /* mmUVD_POWER_STATUS is always readable and is first element of the array */1977 adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, mmUVD_POWER_STATUS);1978 is_powered = (adev->vcn.ip_dump[inst_off] &1979 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1;1980 1981 if (is_powered)1982 for (j = 1; j < reg_count; j++)1983 adev->vcn.ip_dump[inst_off + j] =1984 RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_1_0[j], i));1985 }1986}1987 1988static const struct amd_ip_funcs vcn_v1_0_ip_funcs = {1989 .name = "vcn_v1_0",1990 .early_init = vcn_v1_0_early_init,1991 .late_init = NULL,1992 .sw_init = vcn_v1_0_sw_init,1993 .sw_fini = vcn_v1_0_sw_fini,1994 .hw_init = vcn_v1_0_hw_init,1995 .hw_fini = vcn_v1_0_hw_fini,1996 .suspend = vcn_v1_0_suspend,1997 .resume = vcn_v1_0_resume,1998 .is_idle = vcn_v1_0_is_idle,1999 .wait_for_idle = vcn_v1_0_wait_for_idle,2000 .check_soft_reset = NULL /* vcn_v1_0_check_soft_reset */,2001 .pre_soft_reset = NULL /* vcn_v1_0_pre_soft_reset */,2002 .soft_reset = NULL /* vcn_v1_0_soft_reset */,2003 .post_soft_reset = NULL /* vcn_v1_0_post_soft_reset */,2004 .set_clockgating_state = vcn_v1_0_set_clockgating_state,2005 .set_powergating_state = vcn_v1_0_set_powergating_state,2006 .dump_ip_state = vcn_v1_0_dump_ip_state,2007 .print_ip_state = vcn_v1_0_print_ip_state,2008};2009 2010/*2011 * It is a hardware issue that VCN can't handle a GTT TMZ buffer on2012 * CHIP_RAVEN series ASIC. Move such a GTT TMZ buffer to VRAM domain2013 * before command submission as a workaround.2014 */2015static int vcn_v1_0_validate_bo(struct amdgpu_cs_parser *parser,2016 struct amdgpu_job *job,2017 uint64_t addr)2018{2019 struct ttm_operation_ctx ctx = { false, false };2020 struct amdgpu_fpriv *fpriv = parser->filp->driver_priv;2021 struct amdgpu_vm *vm = &fpriv->vm;2022 struct amdgpu_bo_va_mapping *mapping;2023 struct amdgpu_bo *bo;2024 int r;2025 2026 addr &= AMDGPU_GMC_HOLE_MASK;2027 if (addr & 0x7) {2028 DRM_ERROR("VCN messages must be 8 byte aligned!\n");2029 return -EINVAL;2030 }2031 2032 mapping = amdgpu_vm_bo_lookup_mapping(vm, addr/AMDGPU_GPU_PAGE_SIZE);2033 if (!mapping || !mapping->bo_va || !mapping->bo_va->base.bo)2034 return -EINVAL;2035 2036 bo = mapping->bo_va->base.bo;2037 if (!(bo->flags & AMDGPU_GEM_CREATE_ENCRYPTED))2038 return 0;2039 2040 amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_VRAM);2041 r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);2042 if (r) {2043 DRM_ERROR("Failed to validate the VCN message BO (%d)!\n", r);2044 return r;2045 }2046 2047 return r;2048}2049 2050static int vcn_v1_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,2051 struct amdgpu_job *job,2052 struct amdgpu_ib *ib)2053{2054 uint32_t msg_lo = 0, msg_hi = 0;2055 int i, r;2056 2057 if (!(ib->flags & AMDGPU_IB_FLAGS_SECURE))2058 return 0;2059 2060 for (i = 0; i < ib->length_dw; i += 2) {2061 uint32_t reg = amdgpu_ib_get_value(ib, i);2062 uint32_t val = amdgpu_ib_get_value(ib, i + 1);2063 2064 if (reg == PACKET0(p->adev->vcn.internal.data0, 0)) {2065 msg_lo = val;2066 } else if (reg == PACKET0(p->adev->vcn.internal.data1, 0)) {2067 msg_hi = val;2068 } else if (reg == PACKET0(p->adev->vcn.internal.cmd, 0)) {2069 r = vcn_v1_0_validate_bo(p, job,2070 ((u64)msg_hi) << 32 | msg_lo);2071 if (r)2072 return r;2073 }2074 }2075 2076 return 0;2077}2078 2079static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = {2080 .type = AMDGPU_RING_TYPE_VCN_DEC,2081 .align_mask = 0xf,2082 .support_64bit_ptrs = false,2083 .no_user_fence = true,2084 .secure_submission_supported = true,2085 .get_rptr = vcn_v1_0_dec_ring_get_rptr,2086 .get_wptr = vcn_v1_0_dec_ring_get_wptr,2087 .set_wptr = vcn_v1_0_dec_ring_set_wptr,2088 .patch_cs_in_place = vcn_v1_0_ring_patch_cs_in_place,2089 .emit_frame_size =2090 6 + 6 + /* hdp invalidate / flush */2091 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +2092 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +2093 8 + /* vcn_v1_0_dec_ring_emit_vm_flush */2094 14 + 14 + /* vcn_v1_0_dec_ring_emit_fence x2 vm fence */2095 6,2096 .emit_ib_size = 8, /* vcn_v1_0_dec_ring_emit_ib */2097 .emit_ib = vcn_v1_0_dec_ring_emit_ib,2098 .emit_fence = vcn_v1_0_dec_ring_emit_fence,2099 .emit_vm_flush = vcn_v1_0_dec_ring_emit_vm_flush,2100 .test_ring = amdgpu_vcn_dec_ring_test_ring,2101 .test_ib = amdgpu_vcn_dec_ring_test_ib,2102 .insert_nop = vcn_v1_0_dec_ring_insert_nop,2103 .insert_start = vcn_v1_0_dec_ring_insert_start,2104 .insert_end = vcn_v1_0_dec_ring_insert_end,2105 .pad_ib = amdgpu_ring_generic_pad_ib,2106 .begin_use = vcn_v1_0_ring_begin_use,2107 .end_use = vcn_v1_0_ring_end_use,2108 .emit_wreg = vcn_v1_0_dec_ring_emit_wreg,2109 .emit_reg_wait = vcn_v1_0_dec_ring_emit_reg_wait,2110 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,2111};2112 2113static const struct amdgpu_ring_funcs vcn_v1_0_enc_ring_vm_funcs = {2114 .type = AMDGPU_RING_TYPE_VCN_ENC,2115 .align_mask = 0x3f,2116 .nop = VCN_ENC_CMD_NO_OP,2117 .support_64bit_ptrs = false,2118 .no_user_fence = true,2119 .get_rptr = vcn_v1_0_enc_ring_get_rptr,2120 .get_wptr = vcn_v1_0_enc_ring_get_wptr,2121 .set_wptr = vcn_v1_0_enc_ring_set_wptr,2122 .emit_frame_size =2123 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +2124 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +2125 4 + /* vcn_v1_0_enc_ring_emit_vm_flush */2126 5 + 5 + /* vcn_v1_0_enc_ring_emit_fence x2 vm fence */2127 1, /* vcn_v1_0_enc_ring_insert_end */2128 .emit_ib_size = 5, /* vcn_v1_0_enc_ring_emit_ib */2129 .emit_ib = vcn_v1_0_enc_ring_emit_ib,2130 .emit_fence = vcn_v1_0_enc_ring_emit_fence,2131 .emit_vm_flush = vcn_v1_0_enc_ring_emit_vm_flush,2132 .test_ring = amdgpu_vcn_enc_ring_test_ring,2133 .test_ib = amdgpu_vcn_enc_ring_test_ib,2134 .insert_nop = amdgpu_ring_insert_nop,2135 .insert_end = vcn_v1_0_enc_ring_insert_end,2136 .pad_ib = amdgpu_ring_generic_pad_ib,2137 .begin_use = vcn_v1_0_ring_begin_use,2138 .end_use = vcn_v1_0_ring_end_use,2139 .emit_wreg = vcn_v1_0_enc_ring_emit_wreg,2140 .emit_reg_wait = vcn_v1_0_enc_ring_emit_reg_wait,2141 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,2142};2143 2144static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev)2145{2146 adev->vcn.inst->ring_dec.funcs = &vcn_v1_0_dec_ring_vm_funcs;2147}2148 2149static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev)2150{2151 int i;2152 2153 for (i = 0; i < adev->vcn.num_enc_rings; ++i)2154 adev->vcn.inst->ring_enc[i].funcs = &vcn_v1_0_enc_ring_vm_funcs;2155}2156 2157static const struct amdgpu_irq_src_funcs vcn_v1_0_irq_funcs = {2158 .set = vcn_v1_0_set_interrupt_state,2159 .process = vcn_v1_0_process_interrupt,2160};2161 2162static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev)2163{2164 adev->vcn.inst->irq.num_types = adev->vcn.num_enc_rings + 2;2165 adev->vcn.inst->irq.funcs = &vcn_v1_0_irq_funcs;2166}2167 2168const struct amdgpu_ip_block_version vcn_v1_0_ip_block = {2169 .type = AMD_IP_BLOCK_TYPE_VCN,2170 .major = 1,2171 .minor = 0,2172 .rev = 0,2173 .funcs = &vcn_v1_0_ip_funcs,2174};2175