diff options
Diffstat (limited to 'meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0348-drm-amdgpu-add-cgs_get_firmware_info-interface-v2.patch')
-rw-r--r-- | meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0348-drm-amdgpu-add-cgs_get_firmware_info-interface-v2.patch | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0348-drm-amdgpu-add-cgs_get_firmware_info-interface-v2.patch b/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0348-drm-amdgpu-add-cgs_get_firmware_info-interface-v2.patch new file mode 100644 index 00000000..4cd66846 --- /dev/null +++ b/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0348-drm-amdgpu-add-cgs_get_firmware_info-interface-v2.patch @@ -0,0 +1,264 @@ +From bf3911b06fa9c551b852af563fed393a02e48a7a Mon Sep 17 00:00:00 2001 +From: Jammy Zhou <Jammy.Zhou@amd.com> +Date: Wed, 13 May 2015 18:58:05 +0800 +Subject: [PATCH 0348/1050] drm/amdgpu: add cgs_get_firmware_info interface v2 + +This new interface can be used by IP components to retrieve the +firmware information from the core driver. + +v2: fix one typo + +Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com> +Signed-off-by: Rex Zhu <Rex.Zhou@amd.com> +Signed-off-by: Young Yang <Young.Yang@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 122 ++++++++++++++++++++++++++++++- + drivers/gpu/drm/amd/include/cgs_common.h | 46 ++++++++++++ + 2 files changed, 167 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +index ac0f124..520d017 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +@@ -25,10 +25,13 @@ + #include <linux/slab.h> + #include <linux/pci.h> + #include <drm/drmP.h> ++#include <linux/firmware.h> + #include <drm/amdgpu_drm.h> + #include "amdgpu.h" + #include "cgs_linux.h" + #include "atom.h" ++#include "amdgpu_ucode.h" ++ + + struct amdgpu_cgs_device { + struct cgs_device base; +@@ -611,6 +614,122 @@ static int amdgpu_cgs_irq_put(void *cgs_device, unsigned src_id, unsigned type) + return amdgpu_irq_put(adev, adev->irq.sources[src_id], type); + } + ++static uint32_t fw_type_convert(void *cgs_device, uint32_t fw_type) ++{ ++ CGS_FUNC_ADEV; ++ enum AMDGPU_UCODE_ID result = AMDGPU_UCODE_ID_MAXIMUM; ++ ++ switch (fw_type) { ++ case CGS_UCODE_ID_SDMA0: ++ result = AMDGPU_UCODE_ID_SDMA0; ++ break; ++ case CGS_UCODE_ID_SDMA1: ++ result = AMDGPU_UCODE_ID_SDMA1; ++ break; ++ case CGS_UCODE_ID_CP_CE: ++ result = AMDGPU_UCODE_ID_CP_CE; ++ break; ++ case CGS_UCODE_ID_CP_PFP: ++ result = AMDGPU_UCODE_ID_CP_PFP; ++ break; ++ case CGS_UCODE_ID_CP_ME: ++ result = AMDGPU_UCODE_ID_CP_ME; ++ break; ++ case CGS_UCODE_ID_CP_MEC: ++ case CGS_UCODE_ID_CP_MEC_JT1: ++ result = AMDGPU_UCODE_ID_CP_MEC1; ++ break; ++ case CGS_UCODE_ID_CP_MEC_JT2: ++ if (adev->asic_type == CHIP_TONGA) ++ result = AMDGPU_UCODE_ID_CP_MEC2; ++ else if (adev->asic_type == CHIP_CARRIZO) ++ result = AMDGPU_UCODE_ID_CP_MEC1; ++ break; ++ case CGS_UCODE_ID_RLC_G: ++ result = AMDGPU_UCODE_ID_RLC_G; ++ break; ++ default: ++ DRM_ERROR("Firmware type not supported\n"); ++ } ++ return result; ++} ++ ++static int amdgpu_cgs_get_firmware_info(void *cgs_device, ++ enum cgs_ucode_id type, ++ struct cgs_firmware_info *info) ++{ ++ CGS_FUNC_ADEV; ++ ++ if (CGS_UCODE_ID_SMU != type) { ++ uint64_t gpu_addr; ++ uint32_t data_size; ++ const struct gfx_firmware_header_v1_0 *header; ++ enum AMDGPU_UCODE_ID id; ++ struct amdgpu_firmware_info *ucode; ++ ++ id = fw_type_convert(cgs_device, type); ++ ucode = &adev->firmware.ucode[id]; ++ if (ucode->fw == NULL) ++ return -EINVAL; ++ ++ gpu_addr = ucode->mc_addr; ++ header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; ++ data_size = le32_to_cpu(header->header.ucode_size_bytes); ++ ++ if ((type == CGS_UCODE_ID_CP_MEC_JT1) || ++ (type == CGS_UCODE_ID_CP_MEC_JT2)) { ++ gpu_addr += le32_to_cpu(header->jt_offset) << 2; ++ data_size = le32_to_cpu(header->jt_size) << 2; ++ } ++ info->mc_addr = gpu_addr; ++ info->image_size = data_size; ++ info->version = (uint16_t)le32_to_cpu(header->header.ucode_version); ++ info->feature_version = (uint16_t)le32_to_cpu(header->ucode_feature_version); ++ } else { ++ char fw_name[30] = {0}; ++ int err = 0; ++ uint32_t ucode_size; ++ uint32_t ucode_start_address; ++ const uint8_t *src; ++ const struct smc_firmware_header_v1_0 *hdr; ++ ++ switch (adev->asic_type) { ++ case CHIP_TONGA: ++ strcpy(fw_name, "amdgpu/tonga_smc.bin"); ++ break; ++ default: ++ DRM_ERROR("SMC firmware not supported\n"); ++ return -EINVAL; ++ } ++ ++ err = request_firmware(&adev->pm.fw, fw_name, adev->dev); ++ if (err) { ++ DRM_ERROR("Failed to request firmware\n"); ++ return err; ++ } ++ ++ err = amdgpu_ucode_validate(adev->pm.fw); ++ if (err) { ++ DRM_ERROR("Failed to load firmware \"%s\"", fw_name); ++ release_firmware(adev->pm.fw); ++ adev->pm.fw = NULL; ++ return err; ++ } ++ ++ hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data; ++ adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version); ++ ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes); ++ ucode_start_address = le32_to_cpu(hdr->ucode_start_addr); ++ src = (const uint8_t *)(adev->pm.fw->data + ++ le32_to_cpu(hdr->header.ucode_array_offset_bytes)); ++ ++ info->version = adev->pm.fw_version; ++ info->image_size = ucode_size; ++ info->kptr = (void *)src; ++ } ++ return 0; ++} ++ + static const struct cgs_ops amdgpu_cgs_ops = { + amdgpu_cgs_gpu_mem_info, + amdgpu_cgs_gmap_kmem, +@@ -640,7 +759,8 @@ static const struct cgs_ops amdgpu_cgs_ops = { + amdgpu_cgs_pm_request_clock, + amdgpu_cgs_pm_request_engine, + amdgpu_cgs_pm_query_clock_limits, +- amdgpu_cgs_set_camera_voltages ++ amdgpu_cgs_set_camera_voltages, ++ amdgpu_cgs_get_firmware_info + }; + + static const struct cgs_os_ops amdgpu_cgs_os_ops = { +diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h +index f8cdb88..d586c24 100644 +--- a/drivers/gpu/drm/amd/include/cgs_common.h ++++ b/drivers/gpu/drm/amd/include/cgs_common.h +@@ -24,6 +24,7 @@ + #ifndef _CGS_COMMON_H + #define _CGS_COMMON_H + ++ + /** + * enum cgs_gpu_mem_type - GPU memory types + */ +@@ -85,6 +86,24 @@ enum cgs_voltage_planes { + /* ... */ + }; + ++/* ++ * enum cgs_ucode_id - Firmware types for different IPs ++ */ ++enum cgs_ucode_id { ++ CGS_UCODE_ID_SMU = 0, ++ CGS_UCODE_ID_SDMA0, ++ CGS_UCODE_ID_SDMA1, ++ CGS_UCODE_ID_CP_CE, ++ CGS_UCODE_ID_CP_PFP, ++ CGS_UCODE_ID_CP_ME, ++ CGS_UCODE_ID_CP_MEC, ++ CGS_UCODE_ID_CP_MEC_JT1, ++ CGS_UCODE_ID_CP_MEC_JT2, ++ CGS_UCODE_ID_GMCON_RENG, ++ CGS_UCODE_ID_RLC_G, ++ CGS_UCODE_ID_MAXIMUM, ++}; ++ + /** + * struct cgs_clock_limits - Clock limits + * +@@ -96,6 +115,17 @@ struct cgs_clock_limits { + unsigned sustainable; /**< Thermally sustainable frequency */ + }; + ++/** ++ * struct cgs_firmware_info - Firmware information ++ */ ++struct cgs_firmware_info { ++ uint16_t version; ++ uint16_t feature_version; ++ uint32_t image_size; ++ uint64_t mc_addr; ++ void *kptr; ++}; ++ + typedef unsigned long cgs_handle_t; + + /** +@@ -442,6 +472,18 @@ typedef int (*cgs_pm_query_clock_limits_t)(void *cgs_device, + */ + typedef int (*cgs_set_camera_voltages_t)(void *cgs_device, uint32_t mask, + const uint32_t *voltages); ++/** ++ * cgs_get_firmware_info - Get the firmware information from core driver ++ * @cgs_device: opaque device handle ++ * @type: the firmware type ++ * @info: returend firmware information ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_get_firmware_info)(void *cgs_device, ++ enum cgs_ucode_id type, ++ struct cgs_firmware_info *info); ++ + + struct cgs_ops { + /* memory management calls (similar to KFD interface) */ +@@ -478,6 +520,8 @@ struct cgs_ops { + cgs_pm_request_engine_t pm_request_engine; + cgs_pm_query_clock_limits_t pm_query_clock_limits; + cgs_set_camera_voltages_t set_camera_voltages; ++ /* Firmware Info */ ++ cgs_get_firmware_info get_firmware_info; + /* ACPI (TODO) */ + }; + +@@ -559,5 +603,7 @@ struct cgs_device + CGS_CALL(pm_query_clock_limits,dev,clock,limits) + #define cgs_set_camera_voltages(dev,mask,voltages) \ + CGS_CALL(set_camera_voltages,dev,mask,voltages) ++#define cgs_get_firmware_info(dev, type, info) \ ++ CGS_CALL(get_firmware_info, dev, type, info) + + #endif /* _CGS_COMMON_H */ +-- +1.9.1 + |