/* * Copyright 2013 Advanced Micro Devices, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * Authors: Christian König <[email protected]> */ #include <linux/firmware.h> #include <linux/module.h> #include <drm/drm.h> #include <drm/drm_drv.h> #include "amdgpu.h" #include "amdgpu_pm.h" #include "amdgpu_vce.h" #include "amdgpu_cs.h" #include "cikd.h" /* 1 second timeout */ #define VCE_IDLE_TIMEOUT … /* Firmware Names */ #ifdef CONFIG_DRM_AMDGPU_CIK #define FIRMWARE_BONAIRE … #define FIRMWARE_KABINI … #define FIRMWARE_KAVERI … #define FIRMWARE_HAWAII … #define FIRMWARE_MULLINS … #endif #define FIRMWARE_TONGA … #define FIRMWARE_CARRIZO … #define FIRMWARE_FIJI … #define FIRMWARE_STONEY … #define FIRMWARE_POLARIS10 … #define FIRMWARE_POLARIS11 … #define FIRMWARE_POLARIS12 … #define FIRMWARE_VEGAM … #define FIRMWARE_VEGA10 … #define FIRMWARE_VEGA12 … #define FIRMWARE_VEGA20 … #ifdef CONFIG_DRM_AMDGPU_CIK MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); #endif MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); MODULE_FIRMWARE(…); static void amdgpu_vce_idle_work_handler(struct work_struct *work); static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, struct dma_fence **fence); static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, bool direct, struct dma_fence **fence); /** * amdgpu_vce_sw_init - allocate memory, load vce firmware * * @adev: amdgpu_device pointer * @size: size for the new BO * * First step to get VCE online, allocate memory and load the firmware */ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size) { … } /** * amdgpu_vce_sw_fini - free memory * * @adev: amdgpu_device pointer * * Last step on VCE teardown, free firmware memory */ int amdgpu_vce_sw_fini(struct amdgpu_device *adev) { … } /** * amdgpu_vce_entity_init - init entity * * @adev: amdgpu_device pointer * @ring: amdgpu_ring pointer to check * * Initialize the entity used for handle management in the kernel driver. */ int amdgpu_vce_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring) { … } /** * amdgpu_vce_suspend - unpin VCE fw memory * * @adev: amdgpu_device pointer * */ int amdgpu_vce_suspend(struct amdgpu_device *adev) { … } /** * amdgpu_vce_resume - pin VCE fw memory * * @adev: amdgpu_device pointer * */ int amdgpu_vce_resume(struct amdgpu_device *adev) { … } /** * amdgpu_vce_idle_work_handler - power off VCE * * @work: pointer to work structure * * power of VCE when it's not used any more */ static void amdgpu_vce_idle_work_handler(struct work_struct *work) { … } /** * amdgpu_vce_ring_begin_use - power up VCE * * @ring: amdgpu ring * * Make sure VCE is powerd up when we want to use it */ void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring) { … } /** * amdgpu_vce_ring_end_use - power VCE down * * @ring: amdgpu ring * * Schedule work to power VCE down again */ void amdgpu_vce_ring_end_use(struct amdgpu_ring *ring) { … } /** * amdgpu_vce_free_handles - free still open VCE handles * * @adev: amdgpu_device pointer * @filp: drm file pointer * * Close all VCE handles still open by this file pointer */ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp) { … } /** * amdgpu_vce_get_create_msg - generate a VCE create msg * * @ring: ring we should submit the msg to * @handle: VCE session handle to use * @fence: optional fence to return * * Open up a stream for HW test */ static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, struct dma_fence **fence) { … } /** * amdgpu_vce_get_destroy_msg - generate a VCE destroy msg * * @ring: ring we should submit the msg to * @handle: VCE session handle to use * @direct: direct or delayed pool * @fence: optional fence to return * * Close up a stream for HW test or if userspace failed to do so */ static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, bool direct, struct dma_fence **fence) { … } /** * amdgpu_vce_validate_bo - make sure not to cross 4GB boundary * * @p: cs parser * @ib: indirect buffer to use * @lo: address of lower dword * @hi: address of higher dword * @size: minimum size * @index: bs/fb index * * Make sure that no BO cross a 4GB boundary. */ static int amdgpu_vce_validate_bo(struct amdgpu_cs_parser *p, struct amdgpu_ib *ib, int lo, int hi, unsigned int size, int32_t index) { … } /** * amdgpu_vce_cs_reloc - command submission relocation * * @p: parser context * @ib: indirect buffer to use * @lo: address of lower dword * @hi: address of higher dword * @size: minimum size * @index: bs/fb index * * Patch relocation inside command stream with real buffer address */ static int amdgpu_vce_cs_reloc(struct amdgpu_cs_parser *p, struct amdgpu_ib *ib, int lo, int hi, unsigned int size, uint32_t index) { … } /** * amdgpu_vce_validate_handle - validate stream handle * * @p: parser context * @handle: handle to validate * @allocated: allocated a new handle? * * Validates the handle and return the found session index or -EINVAL * we don't have another free session index. */ static int amdgpu_vce_validate_handle(struct amdgpu_cs_parser *p, uint32_t handle, uint32_t *allocated) { … } /** * amdgpu_vce_ring_parse_cs - parse and validate the command stream * * @p: parser context * @job: the job to parse * @ib: the IB to patch */ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, struct amdgpu_job *job, struct amdgpu_ib *ib) { … } /** * amdgpu_vce_ring_parse_cs_vm - parse the command stream in VM mode * * @p: parser context * @job: the job to parse * @ib: the IB to patch */ int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, struct amdgpu_job *job, struct amdgpu_ib *ib) { … } /** * amdgpu_vce_ring_emit_ib - execute indirect buffer * * @ring: engine to use * @job: job to retrieve vmid from * @ib: the IB to execute * @flags: unused * */ void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_job *job, struct amdgpu_ib *ib, uint32_t flags) { … } /** * amdgpu_vce_ring_emit_fence - add a fence command to the ring * * @ring: engine to use * @addr: address * @seq: sequence number * @flags: fence related flags * */ void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, unsigned int flags) { … } /** * amdgpu_vce_ring_test_ring - test if VCE ring is working * * @ring: the engine to test on * */ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring) { … } /** * amdgpu_vce_ring_test_ib - test if VCE IBs are working * * @ring: the engine to test on * @timeout: timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT * */ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) { … } enum amdgpu_ring_priority_level amdgpu_vce_get_ring_prio(int ring) { … }