Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2c6b0f4 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon/cik: Add support for new ucode format (v5)



This adds CIK support for the new ucode format.

v2: add size validation, integrate debug info
v3: add support for MEC2 on KV
v4: fix typos
v4: update to latest format

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 629bd33c
Loading
Loading
Loading
Loading
+26 −13
Original line number Diff line number Diff line
@@ -213,6 +213,17 @@ int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit)
	if (!rdev->smc_fw)
		return -EINVAL;

	if (rdev->new_fw) {
		const struct smc_firmware_header_v1_0 *hdr =
			(const struct smc_firmware_header_v1_0 *)rdev->smc_fw->data;

		radeon_ucode_print_smc_hdr(&hdr->header);

		ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
		ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
		src = (const u8 *)
			(rdev->smc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
	} else {
		switch (rdev->family) {
		case CHIP_BONAIRE:
			ucode_start_address = BONAIRE_SMC_UCODE_START;
@@ -227,10 +238,12 @@ int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit)
			BUG();
		}

		src = (const u8 *)rdev->smc_fw->data;
	}

	if (ucode_size & 3)
		return -EINVAL;

	src = (const u8 *)rdev->smc_fw->data;
	spin_lock_irqsave(&rdev->smc_idx_lock, flags);
	WREG32(SMC_IND_INDEX_0, ucode_start_address);
	WREG32_P(SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, ~AUTO_INCREMENT_IND_0);
+526 −163

File changed.

Preview size limit exceeded, changes collapsed.

+43 −14
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/firmware.h>
#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_ucode.h"
#include "radeon_asic.h"
#include "radeon_trace.h"
#include "cikd.h"
@@ -419,7 +420,6 @@ static int cik_sdma_rlc_resume(struct radeon_device *rdev)
 */
static int cik_sdma_load_microcode(struct radeon_device *rdev)
{
	const __be32 *fw_data;
	int i;

	if (!rdev->sdma_fw)
@@ -428,6 +428,34 @@ static int cik_sdma_load_microcode(struct radeon_device *rdev)
	/* halt the MEs */
	cik_sdma_enable(rdev, false);

	if (rdev->new_fw) {
		const struct sdma_firmware_header_v1_0 *hdr =
			(const struct sdma_firmware_header_v1_0 *)rdev->sdma_fw->data;
		const __le32 *fw_data;
		u32 fw_size;

		radeon_ucode_print_sdma_hdr(&hdr->header);

		/* sdma0 */
		fw_data = (const __le32 *)
			(rdev->sdma_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
		fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
		WREG32(SDMA0_UCODE_ADDR + SDMA0_REGISTER_OFFSET, 0);
		for (i = 0; i < fw_size; i++)
			WREG32(SDMA0_UCODE_DATA + SDMA0_REGISTER_OFFSET, le32_to_cpup(fw_data++));
		WREG32(SDMA0_UCODE_DATA + SDMA0_REGISTER_OFFSET, CIK_SDMA_UCODE_VERSION);

		/* sdma1 */
		fw_data = (const __le32 *)
			(rdev->sdma_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
		fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
		WREG32(SDMA0_UCODE_ADDR + SDMA1_REGISTER_OFFSET, 0);
		for (i = 0; i < fw_size; i++)
			WREG32(SDMA0_UCODE_DATA + SDMA1_REGISTER_OFFSET, le32_to_cpup(fw_data++));
		WREG32(SDMA0_UCODE_DATA + SDMA1_REGISTER_OFFSET, CIK_SDMA_UCODE_VERSION);
	} else {
		const __be32 *fw_data;

		/* sdma0 */
		fw_data = (const __be32 *)rdev->sdma_fw->data;
		WREG32(SDMA0_UCODE_ADDR + SDMA0_REGISTER_OFFSET, 0);
@@ -441,6 +469,7 @@ static int cik_sdma_load_microcode(struct radeon_device *rdev)
		for (i = 0; i < CIK_SDMA_UCODE_SIZE; i++)
			WREG32(SDMA0_UCODE_DATA + SDMA1_REGISTER_OFFSET, be32_to_cpup(fw_data++));
		WREG32(SDMA0_UCODE_DATA + SDMA1_REGISTER_OFFSET, CIK_SDMA_UCODE_VERSION);
	}

	WREG32(SDMA0_UCODE_ADDR + SDMA0_REGISTER_OFFSET, 0);
	WREG32(SDMA0_UCODE_ADDR + SDMA1_REGISTER_OFFSET, 0);
+1 −0
Original line number Diff line number Diff line
@@ -2302,6 +2302,7 @@ struct radeon_device {
	const struct firmware *mc_fw;	/* NI MC firmware */
	const struct firmware *ce_fw;	/* SI CE firmware */
	const struct firmware *mec_fw;	/* CIK MEC firmware */
	const struct firmware *mec2_fw;	/* KV MEC2 firmware */
	const struct firmware *sdma_fw;	/* CIK SDMA firmware */
	const struct firmware *smc_fw;	/* SMC firmware */
	const struct firmware *uvd_fw;	/* UVD firmware */