linux/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c

/*
 * Copyright 2016 Advanced Micro Devices, Inc.
 *
 * 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, sublicense,
 * 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 above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
 *
 * Author: Huang Rui
 *
 */

#include <linux/firmware.h>
#include <drm/drm_drv.h>

#include "amdgpu.h"
#include "amdgpu_psp.h"
#include "amdgpu_ucode.h"
#include "amdgpu_xgmi.h"
#include "soc15_common.h"
#include "psp_v3_1.h"
#include "psp_v10_0.h"
#include "psp_v11_0.h"
#include "psp_v11_0_8.h"
#include "psp_v12_0.h"
#include "psp_v13_0.h"
#include "psp_v13_0_4.h"
#include "psp_v14_0.h"

#include "amdgpu_ras.h"
#include "amdgpu_securedisplay.h"
#include "amdgpu_atomfirmware.h"

#define AMD_VBIOS_FILE_MAX_SIZE_B

static int psp_load_smu_fw(struct psp_context *psp);
static int psp_rap_terminate(struct psp_context *psp);
static int psp_securedisplay_terminate(struct psp_context *psp);

static int psp_ring_init(struct psp_context *psp,
			 enum psp_ring_type ring_type)
{}

/*
 * Due to DF Cstate management centralized to PMFW, the firmware
 * loading sequence will be updated as below:
 *   - Load KDB
 *   - Load SYS_DRV
 *   - Load tOS
 *   - Load PMFW
 *   - Setup TMR
 *   - Load other non-psp fw
 *   - Load ASD
 *   - Load XGMI/RAS/HDCP/DTM TA if any
 *
 * This new sequence is required for
 *   - Arcturus and onwards
 */
static void psp_check_pmfw_centralized_cstate_management(struct psp_context *psp)
{}

static int psp_init_sriov_microcode(struct psp_context *psp)
{}

static int psp_early_init(void *handle)
{}

void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx)
{}

static void psp_free_shared_bufs(struct psp_context *psp)
{}

static void psp_memory_training_fini(struct psp_context *psp)
{}

static int psp_memory_training_init(struct psp_context *psp)
{}

/*
 * Helper funciton to query psp runtime database entry
 *
 * @adev: amdgpu_device pointer
 * @entry_type: the type of psp runtime database entry
 * @db_entry: runtime database entry pointer
 *
 * Return false if runtime database doesn't exit or entry is invalid
 * or true if the specific database entry is found, and copy to @db_entry
 */
static bool psp_get_runtime_db_entry(struct amdgpu_device *adev,
				     enum psp_runtime_entry_type entry_type,
				     void *db_entry)
{}

static int psp_sw_init(void *handle)
{}

static int psp_sw_fini(void *handle)
{}

int psp_wait_for(struct psp_context *psp, uint32_t reg_index,
		 uint32_t reg_val, uint32_t mask, bool check_changed)
{}

int psp_wait_for_spirom_update(struct psp_context *psp, uint32_t reg_index,
			       uint32_t reg_val, uint32_t mask, uint32_t msec_timeout)
{}

static const char *psp_gfx_cmd_name(enum psp_gfx_cmd_id cmd_id)
{}

static bool psp_err_warn(struct psp_context *psp)
{}

static int
psp_cmd_submit_buf(struct psp_context *psp,
		   struct amdgpu_firmware_info *ucode,
		   struct psp_gfx_cmd_resp *cmd, uint64_t fence_mc_addr)
{}

static struct psp_gfx_cmd_resp *acquire_psp_cmd_buf(struct psp_context *psp)
{}

static void release_psp_cmd_buf(struct psp_context *psp)
{}

static void psp_prep_tmr_cmd_buf(struct psp_context *psp,
				 struct psp_gfx_cmd_resp *cmd,
				 uint64_t tmr_mc, struct amdgpu_bo *tmr_bo)
{}

static void psp_prep_load_toc_cmd_buf(struct psp_gfx_cmd_resp *cmd,
				      uint64_t pri_buf_mc, uint32_t size)
{}

/* Issue LOAD TOC cmd to PSP to part toc and calculate tmr size needed */
static int psp_load_toc(struct psp_context *psp,
			uint32_t *tmr_size)
{}

/* Set up Trusted Memory Region */
static int psp_tmr_init(struct psp_context *psp)
{}

static bool psp_skip_tmr(struct psp_context *psp)
{}

static int psp_tmr_load(struct psp_context *psp)
{}

static void psp_prep_tmr_unload_cmd_buf(struct psp_context *psp,
					struct psp_gfx_cmd_resp *cmd)
{}

static int psp_tmr_unload(struct psp_context *psp)
{}

static int psp_tmr_terminate(struct psp_context *psp)
{}

int psp_get_fw_attestation_records_addr(struct psp_context *psp,
					uint64_t *output_ptr)
{}

static int psp_boot_config_get(struct amdgpu_device *adev, uint32_t *boot_cfg)
{}

static int psp_boot_config_set(struct amdgpu_device *adev, uint32_t boot_cfg)
{}

static int psp_rl_load(struct amdgpu_device *adev)
{}

int psp_spatial_partition(struct psp_context *psp, int mode)
{}

static int psp_asd_initialize(struct psp_context *psp)
{}

static void psp_prep_ta_unload_cmd_buf(struct psp_gfx_cmd_resp *cmd,
				       uint32_t session_id)
{}

int psp_ta_unload(struct psp_context *psp, struct ta_context *context)
{}

static int psp_asd_terminate(struct psp_context *psp)
{}

static void psp_prep_reg_prog_cmd_buf(struct psp_gfx_cmd_resp *cmd,
		uint32_t id, uint32_t value)
{}

int psp_reg_program(struct psp_context *psp, enum psp_reg_prog_id reg,
		uint32_t value)
{}

static void psp_prep_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
				     uint64_t ta_bin_mc,
				     struct ta_context *context)
{}

int psp_ta_init_shared_buf(struct psp_context *psp,
				  struct ta_mem_context *mem_ctx)
{}

static void psp_prep_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd,
				       uint32_t ta_cmd_id,
				       uint32_t session_id)
{}

int psp_ta_invoke(struct psp_context *psp,
		  uint32_t ta_cmd_id,
		  struct ta_context *context)
{}

int psp_ta_load(struct psp_context *psp, struct ta_context *context)
{}

int psp_xgmi_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
{}

int psp_xgmi_terminate(struct psp_context *psp)
{}

int psp_xgmi_initialize(struct psp_context *psp, bool set_extended_data, bool load_ta)
{}

int psp_xgmi_get_hive_id(struct psp_context *psp, uint64_t *hive_id)
{}

int psp_xgmi_get_node_id(struct psp_context *psp, uint64_t *node_id)
{}

static bool psp_xgmi_peer_link_info_supported(struct psp_context *psp)
{}

/*
 * Chips that support extended topology information require the driver to
 * reflect topology information in the opposite direction.  This is
 * because the TA has already exceeded its link record limit and if the
 * TA holds bi-directional information, the driver would have to do
 * multiple fetches instead of just two.
 */
static void psp_xgmi_reflect_topology_info(struct psp_context *psp,
					struct psp_xgmi_node_info node_info)
{}

int psp_xgmi_get_topology_info(struct psp_context *psp,
			       int number_devices,
			       struct psp_xgmi_topology_info *topology,
			       bool get_extended_data)
{}

int psp_xgmi_set_topology_info(struct psp_context *psp,
			       int number_devices,
			       struct psp_xgmi_topology_info *topology)
{}

// ras begin
static void psp_ras_ta_check_status(struct psp_context *psp)
{}

static int psp_ras_send_cmd(struct psp_context *psp,
		enum ras_command cmd_id, void *in, void *out)
{}

int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
{}

int psp_ras_enable_features(struct psp_context *psp,
		union ta_ras_cmd_input *info, bool enable)
{}

int psp_ras_terminate(struct psp_context *psp)
{}

int psp_ras_initialize(struct psp_context *psp)
{}

int psp_ras_trigger_error(struct psp_context *psp,
			  struct ta_ras_trigger_error_input *info, uint32_t instance_mask)
{}

int psp_ras_query_address(struct psp_context *psp,
			  struct ta_ras_query_address_input *addr_in,
			  struct ta_ras_query_address_output *addr_out)
{}
// ras end

// HDCP start
static int psp_hdcp_initialize(struct psp_context *psp)
{}

int psp_hdcp_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
{}

static int psp_hdcp_terminate(struct psp_context *psp)
{}
// HDCP end

// DTM start
static int psp_dtm_initialize(struct psp_context *psp)
{}

int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
{}

static int psp_dtm_terminate(struct psp_context *psp)
{}
// DTM end

// RAP start
static int psp_rap_initialize(struct psp_context *psp)
{}

static int psp_rap_terminate(struct psp_context *psp)
{}

int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id, enum ta_rap_status *status)
{}
// RAP end

/* securedisplay start */
static int psp_securedisplay_initialize(struct psp_context *psp)
{}

static int psp_securedisplay_terminate(struct psp_context *psp)
{}

int psp_securedisplay_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
{}
/* SECUREDISPLAY end */

int amdgpu_psp_wait_for_bootloader(struct amdgpu_device *adev)
{}

bool amdgpu_psp_get_ras_capability(struct psp_context *psp)
{}

static int psp_hw_start(struct psp_context *psp)
{}

static int psp_get_fw_type(struct amdgpu_firmware_info *ucode,
			   enum psp_gfx_fw_type *type)
{}

static void psp_print_fw_hdr(struct psp_context *psp,
			     struct amdgpu_firmware_info *ucode)
{}

static int psp_prep_load_ip_fw_cmd_buf(struct psp_context *psp,
				       struct amdgpu_firmware_info *ucode,
				       struct psp_gfx_cmd_resp *cmd)
{}

int psp_execute_ip_fw_load(struct psp_context *psp,
			   struct amdgpu_firmware_info *ucode)
{}

static int psp_load_p2s_table(struct psp_context *psp)
{}

static int psp_load_smu_fw(struct psp_context *psp)
{}

static bool fw_load_skip_check(struct psp_context *psp,
			       struct amdgpu_firmware_info *ucode)
{}

int psp_load_fw_list(struct psp_context *psp,
		     struct amdgpu_firmware_info **ucode_list, int ucode_count)
{}

static int psp_load_non_psp_fw(struct psp_context *psp)
{}

static int psp_load_fw(struct amdgpu_device *adev)
{}

static int psp_hw_init(void *handle)
{}

static int psp_hw_fini(void *handle)
{}

static int psp_suspend(void *handle)
{}

static int psp_resume(void *handle)
{}

int psp_gpu_reset(struct amdgpu_device *adev)
{}

int psp_rlc_autoload_start(struct psp_context *psp)
{}

int psp_ring_cmd_submit(struct psp_context *psp,
			uint64_t cmd_buf_mc_addr,
			uint64_t fence_mc_addr,
			int index)
{}

int psp_init_asd_microcode(struct psp_context *psp, const char *chip_name)
{}

int psp_init_toc_microcode(struct psp_context *psp, const char *chip_name)
{}

static int parse_sos_bin_descriptor(struct psp_context *psp,
				   const struct psp_fw_bin_desc *desc,
				   const struct psp_firmware_header_v2_0 *sos_hdr)
{}

static int psp_init_sos_base_fw(struct amdgpu_device *adev)
{}

int psp_init_sos_microcode(struct psp_context *psp, const char *chip_name)
{}

static int parse_ta_bin_descriptor(struct psp_context *psp,
				   const struct psp_fw_bin_desc *desc,
				   const struct ta_firmware_header_v2_0 *ta_hdr)
{}

static int parse_ta_v1_microcode(struct psp_context *psp)
{}

static int parse_ta_v2_microcode(struct psp_context *psp)
{}

int psp_init_ta_microcode(struct psp_context *psp, const char *chip_name)
{}

int psp_init_cap_microcode(struct psp_context *psp, const char *chip_name)
{}

static int psp_set_clockgating_state(void *handle,
				     enum amd_clockgating_state state)
{}

static int psp_set_powergating_state(void *handle,
				     enum amd_powergating_state state)
{}

static ssize_t psp_usbc_pd_fw_sysfs_read(struct device *dev,
					 struct device_attribute *attr,
					 char *buf)
{}

static ssize_t psp_usbc_pd_fw_sysfs_write(struct device *dev,
						       struct device_attribute *attr,
						       const char *buf,
						       size_t count)
{}

void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size)
{}

/**
 * DOC: usbc_pd_fw
 * Reading from this file will retrieve the USB-C PD firmware version. Writing to
 * this file will trigger the update process.
 */
static DEVICE_ATTR(usbc_pd_fw, 0644,
		   psp_usbc_pd_fw_sysfs_read,
		   psp_usbc_pd_fw_sysfs_write);

int is_psp_fw_valid(struct psp_bin_desc bin)
{}

static ssize_t amdgpu_psp_vbflash_write(struct file *filp, struct kobject *kobj,
					struct bin_attribute *bin_attr,
					char *buffer, loff_t pos, size_t count)
{}

static ssize_t amdgpu_psp_vbflash_read(struct file *filp, struct kobject *kobj,
				       struct bin_attribute *bin_attr, char *buffer,
				       loff_t pos, size_t count)
{}

/**
 * DOC: psp_vbflash
 * Writing to this file will stage an IFWI for update. Reading from this file
 * will trigger the update process.
 */
static struct bin_attribute psp_vbflash_bin_attr =;

/**
 * DOC: psp_vbflash_status
 * The status of the flash process.
 * 0: IFWI flash not complete.
 * 1: IFWI flash complete.
 */
static ssize_t amdgpu_psp_vbflash_status(struct device *dev,
					 struct device_attribute *attr,
					 char *buf)
{}
static DEVICE_ATTR(psp_vbflash_status, 0440, amdgpu_psp_vbflash_status, NULL);

static struct bin_attribute *bin_flash_attrs[] =;

static struct attribute *flash_attrs[] =;

static umode_t amdgpu_flash_attr_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
{}

static umode_t amdgpu_bin_flash_attr_is_visible(struct kobject *kobj,
						struct bin_attribute *attr,
						int idx)
{}

const struct attribute_group amdgpu_flash_attr_group =;

const struct amd_ip_funcs psp_ip_funcs =;

const struct amdgpu_ip_block_version psp_v3_1_ip_block =;

const struct amdgpu_ip_block_version psp_v10_0_ip_block =;

const struct amdgpu_ip_block_version psp_v11_0_ip_block =;

const struct amdgpu_ip_block_version psp_v11_0_8_ip_block =;

const struct amdgpu_ip_block_version psp_v12_0_ip_block =;

const struct amdgpu_ip_block_version psp_v13_0_ip_block =;

const struct amdgpu_ip_block_version psp_v13_0_4_ip_block =;

const struct amdgpu_ip_block_version psp_v14_0_ip_block =;