Home | History | Annotate | Line # | Download | only in amdgpu
      1  1.1  riastrad /*	$NetBSD: amdgpu_vcn.c,v 1.2 2021/12/18 23:44:58 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * Copyright 2016 Advanced Micro Devices, Inc.
      5  1.1  riastrad  * All Rights Reserved.
      6  1.1  riastrad  *
      7  1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
      8  1.1  riastrad  * copy of this software and associated documentation files (the
      9  1.1  riastrad  * "Software"), to deal in the Software without restriction, including
     10  1.1  riastrad  * without limitation the rights to use, copy, modify, merge, publish,
     11  1.1  riastrad  * distribute, sub license, and/or sell copies of the Software, and to
     12  1.1  riastrad  * permit persons to whom the Software is furnished to do so, subject to
     13  1.1  riastrad  * the following conditions:
     14  1.1  riastrad  *
     15  1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     18  1.1  riastrad  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
     19  1.1  riastrad  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     20  1.1  riastrad  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     21  1.1  riastrad  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     22  1.1  riastrad  *
     23  1.1  riastrad  * The above copyright notice and this permission notice (including the
     24  1.1  riastrad  * next paragraph) shall be included in all copies or substantial portions
     25  1.1  riastrad  * of the Software.
     26  1.1  riastrad  *
     27  1.1  riastrad  */
     28  1.1  riastrad 
     29  1.1  riastrad #include <sys/cdefs.h>
     30  1.1  riastrad __KERNEL_RCSID(0, "$NetBSD: amdgpu_vcn.c,v 1.2 2021/12/18 23:44:58 riastradh Exp $");
     31  1.1  riastrad 
     32  1.1  riastrad #include <linux/firmware.h>
     33  1.1  riastrad #include <linux/module.h>
     34  1.1  riastrad #include <linux/pci.h>
     35  1.1  riastrad 
     36  1.1  riastrad #include "amdgpu.h"
     37  1.1  riastrad #include "amdgpu_pm.h"
     38  1.1  riastrad #include "amdgpu_vcn.h"
     39  1.1  riastrad #include "soc15d.h"
     40  1.1  riastrad 
     41  1.1  riastrad /* Firmware Names */
     42  1.1  riastrad #define FIRMWARE_RAVEN		"amdgpu/raven_vcn.bin"
     43  1.1  riastrad #define FIRMWARE_PICASSO	"amdgpu/picasso_vcn.bin"
     44  1.1  riastrad #define FIRMWARE_RAVEN2		"amdgpu/raven2_vcn.bin"
     45  1.1  riastrad #define FIRMWARE_ARCTURUS 	"amdgpu/arcturus_vcn.bin"
     46  1.1  riastrad #define FIRMWARE_RENOIR 	"amdgpu/renoir_vcn.bin"
     47  1.1  riastrad #define FIRMWARE_NAVI10 	"amdgpu/navi10_vcn.bin"
     48  1.1  riastrad #define FIRMWARE_NAVI14 	"amdgpu/navi14_vcn.bin"
     49  1.1  riastrad #define FIRMWARE_NAVI12 	"amdgpu/navi12_vcn.bin"
     50  1.1  riastrad 
     51  1.1  riastrad MODULE_FIRMWARE(FIRMWARE_RAVEN);
     52  1.1  riastrad MODULE_FIRMWARE(FIRMWARE_PICASSO);
     53  1.1  riastrad MODULE_FIRMWARE(FIRMWARE_RAVEN2);
     54  1.1  riastrad MODULE_FIRMWARE(FIRMWARE_ARCTURUS);
     55  1.1  riastrad MODULE_FIRMWARE(FIRMWARE_RENOIR);
     56  1.1  riastrad MODULE_FIRMWARE(FIRMWARE_NAVI10);
     57  1.1  riastrad MODULE_FIRMWARE(FIRMWARE_NAVI14);
     58  1.1  riastrad MODULE_FIRMWARE(FIRMWARE_NAVI12);
     59  1.1  riastrad 
     60  1.1  riastrad static void amdgpu_vcn_idle_work_handler(struct work_struct *work);
     61  1.1  riastrad 
     62  1.1  riastrad int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
     63  1.1  riastrad {
     64  1.1  riastrad 	unsigned long bo_size;
     65  1.1  riastrad 	const char *fw_name;
     66  1.1  riastrad 	const struct common_firmware_header *hdr;
     67  1.1  riastrad 	unsigned char fw_check;
     68  1.1  riastrad 	int i, r;
     69  1.1  riastrad 
     70  1.1  riastrad 	INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler);
     71  1.1  riastrad 
     72  1.1  riastrad 	switch (adev->asic_type) {
     73  1.1  riastrad 	case CHIP_RAVEN:
     74  1.1  riastrad 		if (adev->rev_id >= 8)
     75  1.1  riastrad 			fw_name = FIRMWARE_RAVEN2;
     76  1.1  riastrad 		else if (adev->pdev->device == 0x15d8)
     77  1.1  riastrad 			fw_name = FIRMWARE_PICASSO;
     78  1.1  riastrad 		else
     79  1.1  riastrad 			fw_name = FIRMWARE_RAVEN;
     80  1.1  riastrad 		break;
     81  1.1  riastrad 	case CHIP_ARCTURUS:
     82  1.1  riastrad 		fw_name = FIRMWARE_ARCTURUS;
     83  1.1  riastrad 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
     84  1.1  riastrad 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
     85  1.1  riastrad 			adev->vcn.indirect_sram = true;
     86  1.1  riastrad 		break;
     87  1.1  riastrad 	case CHIP_RENOIR:
     88  1.1  riastrad 		fw_name = FIRMWARE_RENOIR;
     89  1.1  riastrad 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
     90  1.1  riastrad 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
     91  1.1  riastrad 			adev->vcn.indirect_sram = true;
     92  1.1  riastrad 		break;
     93  1.1  riastrad 	case CHIP_NAVI10:
     94  1.1  riastrad 		fw_name = FIRMWARE_NAVI10;
     95  1.1  riastrad 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
     96  1.1  riastrad 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
     97  1.1  riastrad 			adev->vcn.indirect_sram = true;
     98  1.1  riastrad 		break;
     99  1.1  riastrad 	case CHIP_NAVI14:
    100  1.1  riastrad 		fw_name = FIRMWARE_NAVI14;
    101  1.1  riastrad 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
    102  1.1  riastrad 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
    103  1.1  riastrad 			adev->vcn.indirect_sram = true;
    104  1.1  riastrad 		break;
    105  1.1  riastrad 	case CHIP_NAVI12:
    106  1.1  riastrad 		fw_name = FIRMWARE_NAVI12;
    107  1.1  riastrad 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
    108  1.1  riastrad 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
    109  1.1  riastrad 			adev->vcn.indirect_sram = true;
    110  1.1  riastrad 		break;
    111  1.1  riastrad 	default:
    112  1.1  riastrad 		return -EINVAL;
    113  1.1  riastrad 	}
    114  1.1  riastrad 
    115  1.1  riastrad 	r = request_firmware(&adev->vcn.fw, fw_name, adev->dev);
    116  1.1  riastrad 	if (r) {
    117  1.1  riastrad 		dev_err(adev->dev, "amdgpu_vcn: Can't load firmware \"%s\"\n",
    118  1.1  riastrad 			fw_name);
    119  1.1  riastrad 		return r;
    120  1.1  riastrad 	}
    121  1.1  riastrad 
    122  1.1  riastrad 	r = amdgpu_ucode_validate(adev->vcn.fw);
    123  1.1  riastrad 	if (r) {
    124  1.1  riastrad 		dev_err(adev->dev, "amdgpu_vcn: Can't validate firmware \"%s\"\n",
    125  1.1  riastrad 			fw_name);
    126  1.1  riastrad 		release_firmware(adev->vcn.fw);
    127  1.1  riastrad 		adev->vcn.fw = NULL;
    128  1.1  riastrad 		return r;
    129  1.1  riastrad 	}
    130  1.1  riastrad 
    131  1.1  riastrad 	hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
    132  1.1  riastrad 	adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
    133  1.1  riastrad 
    134  1.1  riastrad 	/* Bit 20-23, it is encode major and non-zero for new naming convention.
    135  1.1  riastrad 	 * This field is part of version minor and DRM_DISABLED_FLAG in old naming
    136  1.1  riastrad 	 * convention. Since the l:wq!atest version minor is 0x5B and DRM_DISABLED_FLAG
    137  1.1  riastrad 	 * is zero in old naming convention, this field is always zero so far.
    138  1.1  riastrad 	 * These four bits are used to tell which naming convention is present.
    139  1.1  riastrad 	 */
    140  1.1  riastrad 	fw_check = (le32_to_cpu(hdr->ucode_version) >> 20) & 0xf;
    141  1.1  riastrad 	if (fw_check) {
    142  1.1  riastrad 		unsigned int dec_ver, enc_major, enc_minor, vep, fw_rev;
    143  1.1  riastrad 
    144  1.1  riastrad 		fw_rev = le32_to_cpu(hdr->ucode_version) & 0xfff;
    145  1.1  riastrad 		enc_minor = (le32_to_cpu(hdr->ucode_version) >> 12) & 0xff;
    146  1.1  riastrad 		enc_major = fw_check;
    147  1.1  riastrad 		dec_ver = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xf;
    148  1.1  riastrad 		vep = (le32_to_cpu(hdr->ucode_version) >> 28) & 0xf;
    149  1.1  riastrad 		DRM_INFO("Found VCN firmware Version ENC: %hu.%hu DEC: %hu VEP: %hu Revision: %hu\n",
    150  1.1  riastrad 			enc_major, enc_minor, dec_ver, vep, fw_rev);
    151  1.1  riastrad 	} else {
    152  1.1  riastrad 		unsigned int version_major, version_minor, family_id;
    153  1.1  riastrad 
    154  1.1  riastrad 		family_id = le32_to_cpu(hdr->ucode_version) & 0xff;
    155  1.1  riastrad 		version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff;
    156  1.1  riastrad 		version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff;
    157  1.1  riastrad 		DRM_INFO("Found VCN firmware Version: %hu.%hu Family ID: %hu\n",
    158  1.1  riastrad 			version_major, version_minor, family_id);
    159  1.1  riastrad 	}
    160  1.1  riastrad 
    161  1.1  riastrad 	bo_size = AMDGPU_VCN_STACK_SIZE + AMDGPU_VCN_CONTEXT_SIZE;
    162  1.1  riastrad 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
    163  1.1  riastrad 		bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
    164  1.1  riastrad 
    165  1.1  riastrad 	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
    166  1.1  riastrad 		if (adev->vcn.harvest_config & (1 << i))
    167  1.1  riastrad 			continue;
    168  1.1  riastrad 
    169  1.1  riastrad 		r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
    170  1.1  riastrad 						AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].vcpu_bo,
    171  1.1  riastrad 						&adev->vcn.inst[i].gpu_addr, &adev->vcn.inst[i].cpu_addr);
    172  1.1  riastrad 		if (r) {
    173  1.1  riastrad 			dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r);
    174  1.1  riastrad 			return r;
    175  1.1  riastrad 		}
    176  1.1  riastrad 
    177  1.1  riastrad 		if (adev->vcn.indirect_sram) {
    178  1.1  riastrad 			r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE,
    179  1.1  riastrad 					AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].dpg_sram_bo,
    180  1.1  riastrad 					&adev->vcn.inst[i].dpg_sram_gpu_addr, &adev->vcn.inst[i].dpg_sram_cpu_addr);
    181  1.1  riastrad 			if (r) {
    182  1.1  riastrad 				dev_err(adev->dev, "VCN %d (%d) failed to allocate DPG bo\n", i, r);
    183  1.1  riastrad 				return r;
    184  1.1  riastrad 			}
    185  1.1  riastrad 		}
    186  1.1  riastrad 	}
    187  1.1  riastrad 
    188  1.1  riastrad 	return 0;
    189  1.1  riastrad }
    190  1.1  riastrad 
    191  1.1  riastrad int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
    192  1.1  riastrad {
    193  1.1  riastrad 	int i, j;
    194  1.1  riastrad 
    195  1.1  riastrad 	cancel_delayed_work_sync(&adev->vcn.idle_work);
    196  1.1  riastrad 
    197  1.1  riastrad 	for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
    198  1.1  riastrad 		if (adev->vcn.harvest_config & (1 << j))
    199  1.1  riastrad 			continue;
    200  1.1  riastrad 		if (adev->vcn.indirect_sram) {
    201  1.1  riastrad 			amdgpu_bo_free_kernel(&adev->vcn.inst[j].dpg_sram_bo,
    202  1.1  riastrad 						  &adev->vcn.inst[j].dpg_sram_gpu_addr,
    203  1.1  riastrad 						  (void **)&adev->vcn.inst[j].dpg_sram_cpu_addr);
    204  1.1  riastrad 		}
    205  1.1  riastrad 		kvfree(adev->vcn.inst[j].saved_bo);
    206  1.1  riastrad 
    207  1.1  riastrad 		amdgpu_bo_free_kernel(&adev->vcn.inst[j].vcpu_bo,
    208  1.1  riastrad 					  &adev->vcn.inst[j].gpu_addr,
    209  1.1  riastrad 					  (void **)&adev->vcn.inst[j].cpu_addr);
    210  1.1  riastrad 
    211  1.1  riastrad 		amdgpu_ring_fini(&adev->vcn.inst[j].ring_dec);
    212  1.1  riastrad 
    213  1.1  riastrad 		for (i = 0; i < adev->vcn.num_enc_rings; ++i)
    214  1.1  riastrad 			amdgpu_ring_fini(&adev->vcn.inst[j].ring_enc[i]);
    215  1.1  riastrad 	}
    216  1.1  riastrad 
    217  1.1  riastrad 	release_firmware(adev->vcn.fw);
    218  1.1  riastrad 
    219  1.1  riastrad 	return 0;
    220  1.1  riastrad }
    221  1.1  riastrad 
    222  1.1  riastrad int amdgpu_vcn_suspend(struct amdgpu_device *adev)
    223  1.1  riastrad {
    224  1.1  riastrad 	unsigned size;
    225  1.1  riastrad 	void *ptr;
    226  1.1  riastrad 	int i;
    227  1.1  riastrad 
    228  1.1  riastrad 	cancel_delayed_work_sync(&adev->vcn.idle_work);
    229  1.1  riastrad 
    230  1.1  riastrad 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
    231  1.1  riastrad 		if (adev->vcn.harvest_config & (1 << i))
    232  1.1  riastrad 			continue;
    233  1.1  riastrad 		if (adev->vcn.inst[i].vcpu_bo == NULL)
    234  1.1  riastrad 			return 0;
    235  1.1  riastrad 
    236  1.1  riastrad 		size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo);
    237  1.1  riastrad 		ptr = adev->vcn.inst[i].cpu_addr;
    238  1.1  riastrad 
    239  1.1  riastrad 		adev->vcn.inst[i].saved_bo = kvmalloc(size, GFP_KERNEL);
    240  1.1  riastrad 		if (!adev->vcn.inst[i].saved_bo)
    241  1.1  riastrad 			return -ENOMEM;
    242  1.1  riastrad 
    243  1.1  riastrad 		memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);
    244  1.1  riastrad 	}
    245  1.1  riastrad 	return 0;
    246  1.1  riastrad }
    247  1.1  riastrad 
    248  1.1  riastrad int amdgpu_vcn_resume(struct amdgpu_device *adev)
    249  1.1  riastrad {
    250  1.1  riastrad 	unsigned size;
    251  1.1  riastrad 	void *ptr;
    252  1.1  riastrad 	int i;
    253  1.1  riastrad 
    254  1.1  riastrad 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
    255  1.1  riastrad 		if (adev->vcn.harvest_config & (1 << i))
    256  1.1  riastrad 			continue;
    257  1.1  riastrad 		if (adev->vcn.inst[i].vcpu_bo == NULL)
    258  1.1  riastrad 			return -EINVAL;
    259  1.1  riastrad 
    260  1.1  riastrad 		size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo);
    261  1.1  riastrad 		ptr = adev->vcn.inst[i].cpu_addr;
    262  1.1  riastrad 
    263  1.1  riastrad 		if (adev->vcn.inst[i].saved_bo != NULL) {
    264  1.1  riastrad 			memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size);
    265  1.1  riastrad 			kvfree(adev->vcn.inst[i].saved_bo);
    266  1.1  riastrad 			adev->vcn.inst[i].saved_bo = NULL;
    267  1.1  riastrad 		} else {
    268  1.1  riastrad 			const struct common_firmware_header *hdr;
    269  1.1  riastrad 			unsigned offset;
    270  1.1  riastrad 
    271  1.1  riastrad 			hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
    272  1.1  riastrad 			if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
    273  1.1  riastrad 				offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
    274  1.1  riastrad 				memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset,
    275  1.1  riastrad 					    le32_to_cpu(hdr->ucode_size_bytes));
    276  1.1  riastrad 				size -= le32_to_cpu(hdr->ucode_size_bytes);
    277  1.1  riastrad 				ptr += le32_to_cpu(hdr->ucode_size_bytes);
    278  1.1  riastrad 			}
    279  1.1  riastrad 			memset_io(ptr, 0, size);
    280  1.1  riastrad 		}
    281  1.1  riastrad 	}
    282  1.1  riastrad 	return 0;
    283  1.1  riastrad }
    284  1.1  riastrad 
    285  1.1  riastrad static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
    286  1.1  riastrad {
    287  1.1  riastrad 	struct amdgpu_device *adev =
    288  1.1  riastrad 		container_of(work, struct amdgpu_device, vcn.idle_work.work);
    289  1.1  riastrad 	unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0};
    290  1.1  riastrad 	unsigned int i, j;
    291  1.1  riastrad 
    292  1.1  riastrad 	for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
    293  1.1  riastrad 		if (adev->vcn.harvest_config & (1 << j))
    294  1.1  riastrad 			continue;
    295  1.1  riastrad 
    296  1.1  riastrad 		for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
    297  1.1  riastrad 			fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]);
    298  1.1  riastrad 		}
    299  1.1  riastrad 
    300  1.1  riastrad 		if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)	{
    301  1.1  riastrad 			struct dpg_pause_state new_state;
    302  1.1  riastrad 
    303  1.1  riastrad 			if (fence[j])
    304  1.1  riastrad 				new_state.fw_based = VCN_DPG_STATE__PAUSE;
    305  1.1  riastrad 			else
    306  1.1  riastrad 				new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
    307  1.1  riastrad 
    308  1.1  riastrad 			adev->vcn.pause_dpg_mode(adev, j, &new_state);
    309  1.1  riastrad 		}
    310  1.1  riastrad 
    311  1.1  riastrad 		fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_dec);
    312  1.1  riastrad 		fences += fence[j];
    313  1.1  riastrad 	}
    314  1.1  riastrad 
    315  1.1  riastrad 	if (fences == 0) {
    316  1.1  riastrad 		amdgpu_gfx_off_ctrl(adev, true);
    317  1.1  riastrad 		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
    318  1.1  riastrad 		       AMD_PG_STATE_GATE);
    319  1.1  riastrad 	} else {
    320  1.1  riastrad 		schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
    321  1.1  riastrad 	}
    322  1.1  riastrad }
    323  1.1  riastrad 
    324  1.1  riastrad void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
    325  1.1  riastrad {
    326  1.1  riastrad 	struct amdgpu_device *adev = ring->adev;
    327  1.1  riastrad 	bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
    328  1.1  riastrad 
    329  1.1  riastrad 	if (set_clocks) {
    330  1.1  riastrad 		amdgpu_gfx_off_ctrl(adev, false);
    331  1.1  riastrad 		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
    332  1.1  riastrad 		       AMD_PG_STATE_UNGATE);
    333  1.1  riastrad 	}
    334  1.1  riastrad 
    335  1.1  riastrad 	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)	{
    336  1.1  riastrad 		struct dpg_pause_state new_state;
    337  1.1  riastrad 		unsigned int fences = 0;
    338  1.1  riastrad 		unsigned int i;
    339  1.1  riastrad 
    340  1.1  riastrad 		for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
    341  1.1  riastrad 			fences += amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_enc[i]);
    342  1.1  riastrad 		}
    343  1.1  riastrad 		if (fences)
    344  1.1  riastrad 			new_state.fw_based = VCN_DPG_STATE__PAUSE;
    345  1.1  riastrad 		else
    346  1.1  riastrad 			new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
    347  1.1  riastrad 
    348  1.1  riastrad 		if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
    349  1.1  riastrad 			new_state.fw_based = VCN_DPG_STATE__PAUSE;
    350  1.1  riastrad 
    351  1.1  riastrad 		adev->vcn.pause_dpg_mode(adev, ring->me, &new_state);
    352  1.1  riastrad 	}
    353  1.1  riastrad }
    354  1.1  riastrad 
    355  1.1  riastrad void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
    356  1.1  riastrad {
    357  1.1  riastrad 	schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
    358  1.1  riastrad }
    359  1.1  riastrad 
    360  1.1  riastrad int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring)
    361  1.1  riastrad {
    362  1.1  riastrad 	struct amdgpu_device *adev = ring->adev;
    363  1.1  riastrad 	uint32_t tmp = 0;
    364  1.1  riastrad 	unsigned i;
    365  1.1  riastrad 	int r;
    366  1.1  riastrad 
    367  1.1  riastrad 	WREG32(adev->vcn.inst[ring->me].external.scratch9, 0xCAFEDEAD);
    368  1.1  riastrad 	r = amdgpu_ring_alloc(ring, 3);
    369  1.1  riastrad 	if (r)
    370  1.1  riastrad 		return r;
    371  1.1  riastrad 	amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.scratch9, 0));
    372  1.1  riastrad 	amdgpu_ring_write(ring, 0xDEADBEEF);
    373  1.1  riastrad 	amdgpu_ring_commit(ring);
    374  1.1  riastrad 	for (i = 0; i < adev->usec_timeout; i++) {
    375  1.1  riastrad 		tmp = RREG32(adev->vcn.inst[ring->me].external.scratch9);
    376  1.1  riastrad 		if (tmp == 0xDEADBEEF)
    377  1.1  riastrad 			break;
    378  1.1  riastrad 		udelay(1);
    379  1.1  riastrad 	}
    380  1.1  riastrad 
    381  1.1  riastrad 	if (i >= adev->usec_timeout)
    382  1.1  riastrad 		r = -ETIMEDOUT;
    383  1.1  riastrad 
    384  1.1  riastrad 	return r;
    385  1.1  riastrad }
    386  1.1  riastrad 
    387  1.1  riastrad static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
    388  1.1  riastrad 				   struct amdgpu_bo *bo,
    389  1.1  riastrad 				   struct dma_fence **fence)
    390  1.1  riastrad {
    391  1.1  riastrad 	struct amdgpu_device *adev = ring->adev;
    392  1.1  riastrad 	struct dma_fence *f = NULL;
    393  1.1  riastrad 	struct amdgpu_job *job;
    394  1.1  riastrad 	struct amdgpu_ib *ib;
    395  1.1  riastrad 	uint64_t addr;
    396  1.1  riastrad 	int i, r;
    397  1.1  riastrad 
    398  1.1  riastrad 	r = amdgpu_job_alloc_with_ib(adev, 64, &job);
    399  1.1  riastrad 	if (r)
    400  1.1  riastrad 		goto err;
    401  1.1  riastrad 
    402  1.1  riastrad 	ib = &job->ibs[0];
    403  1.1  riastrad 	addr = amdgpu_bo_gpu_offset(bo);
    404  1.1  riastrad 	ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0);
    405  1.1  riastrad 	ib->ptr[1] = addr;
    406  1.1  riastrad 	ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0);
    407  1.1  riastrad 	ib->ptr[3] = addr >> 32;
    408  1.1  riastrad 	ib->ptr[4] = PACKET0(adev->vcn.internal.cmd, 0);
    409  1.1  riastrad 	ib->ptr[5] = 0;
    410  1.1  riastrad 	for (i = 6; i < 16; i += 2) {
    411  1.1  riastrad 		ib->ptr[i] = PACKET0(adev->vcn.internal.nop, 0);
    412  1.1  riastrad 		ib->ptr[i+1] = 0;
    413  1.1  riastrad 	}
    414  1.1  riastrad 	ib->length_dw = 16;
    415  1.1  riastrad 
    416  1.1  riastrad 	r = amdgpu_job_submit_direct(job, ring, &f);
    417  1.1  riastrad 	if (r)
    418  1.1  riastrad 		goto err_free;
    419  1.1  riastrad 
    420  1.1  riastrad 	amdgpu_bo_fence(bo, f, false);
    421  1.1  riastrad 	amdgpu_bo_unreserve(bo);
    422  1.1  riastrad 	amdgpu_bo_unref(&bo);
    423  1.1  riastrad 
    424  1.1  riastrad 	if (fence)
    425  1.1  riastrad 		*fence = dma_fence_get(f);
    426  1.1  riastrad 	dma_fence_put(f);
    427  1.1  riastrad 
    428  1.1  riastrad 	return 0;
    429  1.1  riastrad 
    430  1.1  riastrad err_free:
    431  1.1  riastrad 	amdgpu_job_free(job);
    432  1.1  riastrad 
    433  1.1  riastrad err:
    434  1.1  riastrad 	amdgpu_bo_unreserve(bo);
    435  1.1  riastrad 	amdgpu_bo_unref(&bo);
    436  1.1  riastrad 	return r;
    437  1.1  riastrad }
    438  1.1  riastrad 
    439  1.1  riastrad static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
    440  1.1  riastrad 			      struct dma_fence **fence)
    441  1.1  riastrad {
    442  1.1  riastrad 	struct amdgpu_device *adev = ring->adev;
    443  1.1  riastrad 	struct amdgpu_bo *bo = NULL;
    444  1.1  riastrad 	uint32_t *msg;
    445  1.1  riastrad 	int r, i;
    446  1.1  riastrad 
    447  1.1  riastrad 	r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
    448  1.1  riastrad 				      AMDGPU_GEM_DOMAIN_VRAM,
    449  1.1  riastrad 				      &bo, NULL, (void **)&msg);
    450  1.1  riastrad 	if (r)
    451  1.1  riastrad 		return r;
    452  1.1  riastrad 
    453  1.1  riastrad 	msg[0] = cpu_to_le32(0x00000028);
    454  1.1  riastrad 	msg[1] = cpu_to_le32(0x00000038);
    455  1.1  riastrad 	msg[2] = cpu_to_le32(0x00000001);
    456  1.1  riastrad 	msg[3] = cpu_to_le32(0x00000000);
    457  1.1  riastrad 	msg[4] = cpu_to_le32(handle);
    458  1.1  riastrad 	msg[5] = cpu_to_le32(0x00000000);
    459  1.1  riastrad 	msg[6] = cpu_to_le32(0x00000001);
    460  1.1  riastrad 	msg[7] = cpu_to_le32(0x00000028);
    461  1.1  riastrad 	msg[8] = cpu_to_le32(0x00000010);
    462  1.1  riastrad 	msg[9] = cpu_to_le32(0x00000000);
    463  1.1  riastrad 	msg[10] = cpu_to_le32(0x00000007);
    464  1.1  riastrad 	msg[11] = cpu_to_le32(0x00000000);
    465  1.1  riastrad 	msg[12] = cpu_to_le32(0x00000780);
    466  1.1  riastrad 	msg[13] = cpu_to_le32(0x00000440);
    467  1.1  riastrad 	for (i = 14; i < 1024; ++i)
    468  1.1  riastrad 		msg[i] = cpu_to_le32(0x0);
    469  1.1  riastrad 
    470  1.1  riastrad 	return amdgpu_vcn_dec_send_msg(ring, bo, fence);
    471  1.1  riastrad }
    472  1.1  riastrad 
    473  1.1  riastrad static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
    474  1.1  riastrad 			       struct dma_fence **fence)
    475  1.1  riastrad {
    476  1.1  riastrad 	struct amdgpu_device *adev = ring->adev;
    477  1.1  riastrad 	struct amdgpu_bo *bo = NULL;
    478  1.1  riastrad 	uint32_t *msg;
    479  1.1  riastrad 	int r, i;
    480  1.1  riastrad 
    481  1.1  riastrad 	r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
    482  1.1  riastrad 				      AMDGPU_GEM_DOMAIN_VRAM,
    483  1.1  riastrad 				      &bo, NULL, (void **)&msg);
    484  1.1  riastrad 	if (r)
    485  1.1  riastrad 		return r;
    486  1.1  riastrad 
    487  1.1  riastrad 	msg[0] = cpu_to_le32(0x00000028);
    488  1.1  riastrad 	msg[1] = cpu_to_le32(0x00000018);
    489  1.1  riastrad 	msg[2] = cpu_to_le32(0x00000000);
    490  1.1  riastrad 	msg[3] = cpu_to_le32(0x00000002);
    491  1.1  riastrad 	msg[4] = cpu_to_le32(handle);
    492  1.1  riastrad 	msg[5] = cpu_to_le32(0x00000000);
    493  1.1  riastrad 	for (i = 6; i < 1024; ++i)
    494  1.1  riastrad 		msg[i] = cpu_to_le32(0x0);
    495  1.1  riastrad 
    496  1.1  riastrad 	return amdgpu_vcn_dec_send_msg(ring, bo, fence);
    497  1.1  riastrad }
    498  1.1  riastrad 
    499  1.1  riastrad int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
    500  1.1  riastrad {
    501  1.1  riastrad 	struct amdgpu_device *adev = ring->adev;
    502  1.1  riastrad 	struct dma_fence *fence;
    503  1.1  riastrad 	long r;
    504  1.1  riastrad 
    505  1.1  riastrad 	/* temporarily disable ib test for sriov */
    506  1.1  riastrad 	if (amdgpu_sriov_vf(adev))
    507  1.1  riastrad 		return 0;
    508  1.1  riastrad 
    509  1.1  riastrad 	r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL);
    510  1.1  riastrad 	if (r)
    511  1.1  riastrad 		goto error;
    512  1.1  riastrad 
    513  1.1  riastrad 	r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &fence);
    514  1.1  riastrad 	if (r)
    515  1.1  riastrad 		goto error;
    516  1.1  riastrad 
    517  1.1  riastrad 	r = dma_fence_wait_timeout(fence, false, timeout);
    518  1.1  riastrad 	if (r == 0)
    519  1.1  riastrad 		r = -ETIMEDOUT;
    520  1.1  riastrad 	else if (r > 0)
    521  1.1  riastrad 		r = 0;
    522  1.1  riastrad 
    523  1.1  riastrad 	dma_fence_put(fence);
    524  1.1  riastrad error:
    525  1.1  riastrad 	return r;
    526  1.1  riastrad }
    527  1.1  riastrad 
    528  1.1  riastrad int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)
    529  1.1  riastrad {
    530  1.1  riastrad 	struct amdgpu_device *adev = ring->adev;
    531  1.1  riastrad 	uint32_t rptr;
    532  1.1  riastrad 	unsigned i;
    533  1.1  riastrad 	int r;
    534  1.1  riastrad 
    535  1.1  riastrad 	r = amdgpu_ring_alloc(ring, 16);
    536  1.1  riastrad 	if (r)
    537  1.1  riastrad 		return r;
    538  1.1  riastrad 
    539  1.1  riastrad 	rptr = amdgpu_ring_get_rptr(ring);
    540  1.1  riastrad 
    541  1.1  riastrad 	amdgpu_ring_write(ring, VCN_ENC_CMD_END);
    542  1.1  riastrad 	amdgpu_ring_commit(ring);
    543  1.1  riastrad 
    544  1.1  riastrad 	for (i = 0; i < adev->usec_timeout; i++) {
    545  1.1  riastrad 		if (amdgpu_ring_get_rptr(ring) != rptr)
    546  1.1  riastrad 			break;
    547  1.1  riastrad 		udelay(1);
    548  1.1  riastrad 	}
    549  1.1  riastrad 
    550  1.1  riastrad 	if (i >= adev->usec_timeout)
    551  1.1  riastrad 		r = -ETIMEDOUT;
    552  1.1  riastrad 
    553  1.1  riastrad 	return r;
    554  1.1  riastrad }
    555  1.1  riastrad 
    556  1.1  riastrad static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
    557  1.1  riastrad 					 struct amdgpu_bo *bo,
    558  1.1  riastrad 					 struct dma_fence **fence)
    559  1.1  riastrad {
    560  1.1  riastrad 	const unsigned ib_size_dw = 16;
    561  1.1  riastrad 	struct amdgpu_job *job;
    562  1.1  riastrad 	struct amdgpu_ib *ib;
    563  1.1  riastrad 	struct dma_fence *f = NULL;
    564  1.1  riastrad 	uint64_t addr;
    565  1.1  riastrad 	int i, r;
    566  1.1  riastrad 
    567  1.1  riastrad 	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
    568  1.1  riastrad 	if (r)
    569  1.1  riastrad 		return r;
    570  1.1  riastrad 
    571  1.1  riastrad 	ib = &job->ibs[0];
    572  1.1  riastrad 	addr = amdgpu_bo_gpu_offset(bo);
    573  1.1  riastrad 
    574  1.1  riastrad 	ib->length_dw = 0;
    575  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000018;
    576  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000001; /* session info */
    577  1.1  riastrad 	ib->ptr[ib->length_dw++] = handle;
    578  1.1  riastrad 	ib->ptr[ib->length_dw++] = upper_32_bits(addr);
    579  1.1  riastrad 	ib->ptr[ib->length_dw++] = addr;
    580  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x0000000b;
    581  1.1  riastrad 
    582  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000014;
    583  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000002; /* task info */
    584  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x0000001c;
    585  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000000;
    586  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000000;
    587  1.1  riastrad 
    588  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000008;
    589  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */
    590  1.1  riastrad 
    591  1.1  riastrad 	for (i = ib->length_dw; i < ib_size_dw; ++i)
    592  1.1  riastrad 		ib->ptr[i] = 0x0;
    593  1.1  riastrad 
    594  1.1  riastrad 	r = amdgpu_job_submit_direct(job, ring, &f);
    595  1.1  riastrad 	if (r)
    596  1.1  riastrad 		goto err;
    597  1.1  riastrad 
    598  1.1  riastrad 	if (fence)
    599  1.1  riastrad 		*fence = dma_fence_get(f);
    600  1.1  riastrad 	dma_fence_put(f);
    601  1.1  riastrad 
    602  1.1  riastrad 	return 0;
    603  1.1  riastrad 
    604  1.1  riastrad err:
    605  1.1  riastrad 	amdgpu_job_free(job);
    606  1.1  riastrad 	return r;
    607  1.1  riastrad }
    608  1.1  riastrad 
    609  1.1  riastrad static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
    610  1.1  riastrad 					  struct amdgpu_bo *bo,
    611  1.1  riastrad 					  struct dma_fence **fence)
    612  1.1  riastrad {
    613  1.1  riastrad 	const unsigned ib_size_dw = 16;
    614  1.1  riastrad 	struct amdgpu_job *job;
    615  1.1  riastrad 	struct amdgpu_ib *ib;
    616  1.1  riastrad 	struct dma_fence *f = NULL;
    617  1.1  riastrad 	uint64_t addr;
    618  1.1  riastrad 	int i, r;
    619  1.1  riastrad 
    620  1.1  riastrad 	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
    621  1.1  riastrad 	if (r)
    622  1.1  riastrad 		return r;
    623  1.1  riastrad 
    624  1.1  riastrad 	ib = &job->ibs[0];
    625  1.1  riastrad 	addr = amdgpu_bo_gpu_offset(bo);
    626  1.1  riastrad 
    627  1.1  riastrad 	ib->length_dw = 0;
    628  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000018;
    629  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000001;
    630  1.1  riastrad 	ib->ptr[ib->length_dw++] = handle;
    631  1.1  riastrad 	ib->ptr[ib->length_dw++] = upper_32_bits(addr);
    632  1.1  riastrad 	ib->ptr[ib->length_dw++] = addr;
    633  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x0000000b;
    634  1.1  riastrad 
    635  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000014;
    636  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000002;
    637  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x0000001c;
    638  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000000;
    639  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000000;
    640  1.1  riastrad 
    641  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x00000008;
    642  1.1  riastrad 	ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */
    643  1.1  riastrad 
    644  1.1  riastrad 	for (i = ib->length_dw; i < ib_size_dw; ++i)
    645  1.1  riastrad 		ib->ptr[i] = 0x0;
    646  1.1  riastrad 
    647  1.1  riastrad 	r = amdgpu_job_submit_direct(job, ring, &f);
    648  1.1  riastrad 	if (r)
    649  1.1  riastrad 		goto err;
    650  1.1  riastrad 
    651  1.1  riastrad 	if (fence)
    652  1.1  riastrad 		*fence = dma_fence_get(f);
    653  1.1  riastrad 	dma_fence_put(f);
    654  1.1  riastrad 
    655  1.1  riastrad 	return 0;
    656  1.1  riastrad 
    657  1.1  riastrad err:
    658  1.1  riastrad 	amdgpu_job_free(job);
    659  1.1  riastrad 	return r;
    660  1.1  riastrad }
    661  1.1  riastrad 
    662  1.1  riastrad int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
    663  1.1  riastrad {
    664  1.1  riastrad 	struct amdgpu_device *adev = ring->adev;
    665  1.1  riastrad 	struct dma_fence *fence = NULL;
    666  1.1  riastrad 	struct amdgpu_bo *bo = NULL;
    667  1.1  riastrad 	long r;
    668  1.1  riastrad 
    669  1.1  riastrad 	/* temporarily disable ib test for sriov */
    670  1.1  riastrad 	if (amdgpu_sriov_vf(adev))
    671  1.1  riastrad 		return 0;
    672  1.1  riastrad 
    673  1.1  riastrad 	r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE,
    674  1.1  riastrad 				      AMDGPU_GEM_DOMAIN_VRAM,
    675  1.1  riastrad 				      &bo, NULL, NULL);
    676  1.1  riastrad 	if (r)
    677  1.1  riastrad 		return r;
    678  1.1  riastrad 
    679  1.1  riastrad 	r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL);
    680  1.1  riastrad 	if (r)
    681  1.1  riastrad 		goto error;
    682  1.1  riastrad 
    683  1.1  riastrad 	r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence);
    684  1.1  riastrad 	if (r)
    685  1.1  riastrad 		goto error;
    686  1.1  riastrad 
    687  1.1  riastrad 	r = dma_fence_wait_timeout(fence, false, timeout);
    688  1.1  riastrad 	if (r == 0)
    689  1.1  riastrad 		r = -ETIMEDOUT;
    690  1.1  riastrad 	else if (r > 0)
    691  1.1  riastrad 		r = 0;
    692  1.1  riastrad 
    693  1.1  riastrad error:
    694  1.1  riastrad 	dma_fence_put(fence);
    695  1.1  riastrad 	amdgpu_bo_unreserve(bo);
    696  1.1  riastrad 	amdgpu_bo_unref(&bo);
    697  1.1  riastrad 	return r;
    698  1.1  riastrad }
    699