mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 00/11] Recover from failure to probe GPU
@ 2022-12-28 16:30 Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 01/11] drm/amd: Delay removal of the firmware framebuffer Mario Limonciello
                   ` (12 more replies)
  0 siblings, 13 replies; 17+ messages in thread
From: Mario Limonciello @ 2022-12-28 16:30 UTC (permalink / raw)
  To: Javier Martinez Canillas, Alex Deucher
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, Mario Limonciello, linux-kernel

One of the first thing that KMS drivers do during initialization is
destroy the system firmware framebuffer by means of
`drm_aperture_remove_conflicting_pci_framebuffers`

This means that if for any reason the GPU failed to probe the user
will be stuck with at best a screen frozen at the last thing that
was shown before the KMS driver continued it's probe.

The problem is most pronounced when new GPU support is introduced
because users will need to have a recent linux-firmware snapshot
on their system when they boot a kernel with matching support.

However the problem is further exaggerated in the case of amdgpu because
it has migrated to "IP discovery" where amdgpu will attempt to load
on "ALL" AMD GPUs even if the driver is missing support for IP blocks
contained in that GPU.

IP discovery requires some probing and isn't run until after the
framebuffer has been destroyed.

This means a situation can occur where a user purchases a new GPU not
yet supported by a distribution and when booting the installer it will
"freeze" even if the distribution doesn't have the matching kernel support
for those IP blocks.

The perfect example of this is Ubuntu 22.10 and the new dGPUs just
launched by AMD.  The installation media ships with kernel 5.19 (which
has IP discovery) but the amdgpu support for those IP blocks landed in
kernel 6.0. The matching linux-firmware was released after 22.10's launch.
The screen will freeze without nomodeset. Even if a user manages to install
and then upgrades to kernel 6.0 after install they'll still have the
problem of missing firmware, and the same experience.

This is quite jarring for users, particularly if they don't know
that they have to use "nomodeset" to install.

To help the situation make changes to GPU discovery:
1) Delay releasing the firmware framebuffer until after IP discovery has
completed.  This will help the situation of an older kernel that doesn't
yet support the IP blocks probing a new GPU.
2) Request loading all PSP, VCN, SDMA, MES and GC microcode into memory
during IP discovery. This will help the situation of new enough kernel for
the IP discovery phase to otherwise pass but missing microcode from
linux-firmware.git.

Not all requested firmware will be loaded during IP discovery as some of it
will require larger driver architecture changes. For example SMU firmware
isn't loaded on certain products, but that's not known until later on when
the early_init phase of the SMU load occurs.

v1->v2:
 * Take the suggestion from v1 thread to delay the framebuffer release until
   ip discovery is done. This patch is CC to stable to that older stable
   kernels with IP discovery won't try to probe unknown IP.
 * Drop changes to drm aperature.
 * Fetch SDMA, VCN, MES, GC and PSP microcode during IP discovery.

Mario Limonciello (11):
  drm/amd: Delay removal of the firmware framebuffer
  drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode"
  drm/amd: Convert SMUv11 microcode init to use
    `amdgpu_ucode_ip_version_decode`
  drm/amd: Convert SMU v13 to use `amdgpu_ucode_ip_version_decode`
  drm/amd: Request SDMA microcode during IP discovery
  drm/amd: Request VCN microcode during IP discovery
  drm/amd: Request MES microcode during IP discovery
  drm/amd: Request GFX9 microcode during IP discovery
  drm/amd: Request GFX10 microcode during IP discovery
  drm/amd: Request GFX11 microcode during IP discovery
  drm/amd: Request PSP microcode during IP discovery

 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    |   8 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 590 +++++++++++++++++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |   6 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c       |   2 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c      |   9 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h      |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c     | 208 ++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c       |  85 +--
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c        | 180 +-----
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        |  64 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c         | 143 +----
 drivers/gpu/drm/amd/amdgpu/mes_v10_1.c        |  28 -
 drivers/gpu/drm/amd/amdgpu/mes_v11_0.c        |  25 +-
 drivers/gpu/drm/amd/amdgpu/psp_v10_0.c        | 106 +---
 drivers/gpu/drm/amd/amdgpu/psp_v11_0.c        | 165 +----
 drivers/gpu/drm/amd/amdgpu/psp_v12_0.c        | 102 +--
 drivers/gpu/drm/amd/amdgpu/psp_v13_0.c        |  82 ---
 drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c      |  36 --
 drivers/gpu/drm/amd/amdgpu/psp_v3_1.c         |  36 --
 drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c        |  61 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c        |  42 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c        |  65 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c        |  30 +-
 .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c    |  35 +-
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c    |  12 +-
 25 files changed, 919 insertions(+), 1203 deletions(-)


base-commit: de9a71e391a92841582ca3008e7b127a0b8ccf41
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 01/11] drm/amd: Delay removal of the firmware framebuffer
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
@ 2022-12-28 16:30 ` Mario Limonciello
  2022-12-29 14:35   ` Javier Martinez Canillas
  2022-12-28 16:30 ` [PATCH v2 02/11] drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode" Mario Limonciello
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Mario Limonciello @ 2022-12-28 16:30 UTC (permalink / raw)
  To: Javier Martinez Canillas, Alex Deucher, linux-kernel
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, Mario Limonciello, stable,
	Alex Deucher, Pan, Xinhui

Removing the firmware framebuffer from the driver means that even
if the driver doesn't support the IP blocks in a GPU it will no
longer be functional after the driver fails to initialize.

This change will ensure that unsupported IP blocks at least cause
the driver to work with the EFI framebuffer.

Cc: stable@vger.kernel.org
Suggested-by: Alex Deucher <alex.deucher@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 ++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c    | 6 ------
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 9a1a5c2864a0..84d83be2087c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -37,6 +37,7 @@
 #include <linux/pci-p2pdma.h>
 
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_aperture.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/amdgpu_drm.h>
 #include <linux/vgaarb.h>
@@ -89,6 +90,8 @@ MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin");
 #define AMDGPU_MAX_RETRY_LIMIT		2
 #define AMDGPU_RETRY_SRIOV_RESET(r) ((r) == -EBUSY || (r) == -ETIMEDOUT || (r) == -EINVAL)
 
+static const struct drm_driver amdgpu_kms_driver;
+
 const char *amdgpu_asic_name[] = {
 	"TAHITI",
 	"PITCAIRN",
@@ -2140,6 +2143,11 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
 		break;
 	}
 
+	/* Get rid of things like offb */
+	r = drm_aperture_remove_conflicting_pci_framebuffers(adev->pdev, &amdgpu_kms_driver);
+	if (r)
+		return r;
+
 	if (amdgpu_has_atpx() &&
 	    (amdgpu_is_atpx_hybrid() ||
 	     amdgpu_has_atpx_dgpu_power_cntl()) &&
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index db7e34eacc35..b9f14ec9edb2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -23,7 +23,6 @@
  */
 
 #include <drm/amdgpu_drm.h>
-#include <drm/drm_aperture.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_gem.h>
 #include <drm/drm_vblank.h>
@@ -2096,11 +2095,6 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
 	}
 #endif
 
-	/* Get rid of things like offb */
-	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &amdgpu_kms_driver);
-	if (ret)
-		return ret;
-
 	adev = devm_drm_dev_alloc(&pdev->dev, &amdgpu_kms_driver, typeof(*adev), ddev);
 	if (IS_ERR(adev))
 		return PTR_ERR(adev);
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 02/11] drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode"
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 01/11] drm/amd: Delay removal of the firmware framebuffer Mario Limonciello
@ 2022-12-28 16:30 ` Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 03/11] drm/amd: Convert SMUv11 microcode init to use `amdgpu_ucode_ip_version_decode` Mario Limonciello
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Mario Limonciello @ 2022-12-28 16:30 UTC (permalink / raw)
  To: Javier Martinez Canillas, Alex Deucher, linux-kernel
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, Mario Limonciello, Pan, Xinhui

This will allow other parts of the driver that currently special
case firmware file names to before IP version style naming to just
have a single call to `amdgpu_ucode_ip_version_decode`.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 208 ++++++++++++++++++++++
 1 file changed, 208 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
index 5cb62e6249c2..5392c1fe434b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
@@ -1059,12 +1059,220 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
 	return 0;
 }
 
+static const char *amdgpu_ucode_legacy_naming(struct amdgpu_device *adev, int block_type)
+{
+	if (block_type == MP0_HWIP) {
+		switch (adev->ip_versions[MP0_HWIP][0]) {
+		case IP_VERSION(9, 0, 0):
+			switch (adev->asic_type) {
+			case CHIP_VEGA10:
+				return "vega10";
+			case CHIP_VEGA12:
+				return "vega12";
+			default:
+				return NULL;
+			}
+			break;
+		case IP_VERSION(10, 0, 0):
+		case IP_VERSION(10, 0, 1):
+			if (adev->asic_type == CHIP_RAVEN) {
+				if (adev->apu_flags & AMD_APU_IS_RAVEN2)
+					return "raven2";
+				else if (adev->apu_flags & AMD_APU_IS_PICASSO)
+					return "picasso";
+				else
+					return "raven";
+			}
+			break;
+		case IP_VERSION(11, 0, 0):
+			return "navi10";
+		case IP_VERSION(11, 0, 2):
+			return "vega20";
+		case IP_VERSION(11, 0, 4):
+			return "arcturus";
+		case IP_VERSION(11, 0, 5):
+			return "navi14";
+		case IP_VERSION(11, 0, 7):
+			return "sienna_cichlid";
+		case IP_VERSION(11, 0, 9):
+			return "navi12";
+		case IP_VERSION(11, 0, 11):
+			return "navy_flounder";
+		case IP_VERSION(11, 0, 12):
+			return "dimgrey_cavefish";
+		case IP_VERSION(11, 0, 13):
+			return "beige_goby";
+		case IP_VERSION(11, 5, 0):
+			return "vangogh";
+		case IP_VERSION(12, 0, 1):
+			if (adev->asic_type == CHIP_RENOIR) {
+				if (adev->apu_flags & AMD_APU_IS_RENOIR)
+					return "renoir";
+				else
+					return "green_sardine";
+			}
+			break;
+		case IP_VERSION(13, 0, 2):
+			return "aldebaran";
+		case IP_VERSION(13, 0, 1):
+		case IP_VERSION(13, 0, 3):
+			return "yellow_carp";
+		}
+	} else if (block_type == MP1_HWIP) {
+		switch (adev->ip_versions[MP1_HWIP][0]) {
+		case IP_VERSION(9, 0, 0):
+		case IP_VERSION(10, 0, 0):
+		case IP_VERSION(10, 0, 1):
+		case IP_VERSION(11, 0, 2):
+			if (adev->asic_type == CHIP_ARCTURUS)
+				return "arcturus_smc";
+			return NULL;
+		case IP_VERSION(11, 0, 0):
+			return "navi10_smc";
+		case IP_VERSION(11, 0, 5):
+			return "navi14_smc";
+		case IP_VERSION(11, 0, 9):
+			return "navi12_smc";
+		case IP_VERSION(11, 0, 7):
+			return "sienna_cichlid_smc";
+		case IP_VERSION(11, 0, 11):
+			return "navy_flounder_smc";
+		case IP_VERSION(11, 0, 12):
+			return "dimgrey_cavefish_smc";
+		case IP_VERSION(11, 0, 13):
+			return "beige_goby_smc";
+		case IP_VERSION(13, 0, 2):
+			return "aldebaran_smc";
+		}
+	} else if (block_type == SDMA0_HWIP) {
+		switch (adev->ip_versions[SDMA0_HWIP][0]) {
+		case IP_VERSION(4, 0, 0):
+			return "vega10";
+		case IP_VERSION(4, 0, 1):
+			return "vega12";
+		case IP_VERSION(4, 1, 0):
+		case IP_VERSION(4, 1, 1):
+			if (adev->apu_flags & AMD_APU_IS_RAVEN2)
+				return "raven2";
+			else if (adev->apu_flags & AMD_APU_IS_PICASSO)
+				return "picasso";
+			else
+				return "raven";
+		case IP_VERSION(4, 1, 2):
+			if (adev->apu_flags & AMD_APU_IS_RENOIR)
+				return "renoir";
+			else
+				return "green_sardine";
+		case IP_VERSION(4, 2, 0):
+			return "vega20";
+		case IP_VERSION(4, 2, 2):
+			return "arcturus";
+		case IP_VERSION(4, 4, 0):
+			return "aldebaran";
+		case IP_VERSION(5, 0, 0):
+			return "navi10";
+		case IP_VERSION(5, 0, 1):
+			return "cyan_skillfish2";
+		case IP_VERSION(5, 0, 2):
+			return "navi14";
+		case IP_VERSION(5, 0, 5):
+			return "navi12";
+		case IP_VERSION(5, 2, 0):
+			return "sienna_cichlid_sdma";
+		case IP_VERSION(5, 2, 2):
+			return "navy_flounder_sdma";
+		case IP_VERSION(5, 2, 4):
+			return "dimgrey_cavefish_sdma";
+		case IP_VERSION(5, 2, 5):
+			return "beige_goby_sdma";
+		case IP_VERSION(5, 2, 3):
+			return "yellow_carp_sdma";
+		case IP_VERSION(5, 2, 1):
+			return "vangogh_sdma";
+		}
+	} else if (block_type == UVD_HWIP) {
+		switch (adev->ip_versions[UVD_HWIP][0]) {
+		case IP_VERSION(1, 0, 0):
+		case IP_VERSION(1, 0, 1):
+			if (adev->apu_flags & AMD_APU_IS_RAVEN2)
+				return "raven2_vcn";
+			else if (adev->apu_flags & AMD_APU_IS_PICASSO)
+				return "picasso_vcn";
+			else
+				return "raven_vcn";
+			break;
+		case IP_VERSION(2, 5, 0):
+			return "arcturus_vcn";
+		case IP_VERSION(2, 2, 0):
+			if (adev->apu_flags & AMD_APU_IS_RENOIR)
+				return "renoir_vcn";
+			return "green_sardine_vcn";
+		case IP_VERSION(2, 6, 0):
+			return "aldebaran_vcn";
+		case IP_VERSION(2, 0, 0):
+			return "navi10_vcn";
+		case IP_VERSION(2, 0, 2):
+			if (adev->asic_type == CHIP_NAVI12)
+				return "navi12_vcn";
+			else
+				return "navi14_vcn";
+		case IP_VERSION(3, 0, 0):
+		case IP_VERSION(3, 0, 64):
+		case IP_VERSION(3, 0, 192):
+			if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0))
+				return "sienna_cichlid_vcn";
+			else
+				return "navy_flounder_vcn";
+		case IP_VERSION(3, 0, 2):
+			return "vangogh_vcn";
+		case IP_VERSION(3, 0, 16):
+			return "dimgrey_cavefish_vcn";
+		case IP_VERSION(3, 0, 33):
+			return "beige_goby_vcn";
+		case IP_VERSION(3, 1, 1):
+			return "yellow_carp_vcn";
+		}
+	} else if (block_type == GC_HWIP) {
+		switch (adev->ip_versions[GC_HWIP][0]) {
+		case IP_VERSION(10, 1, 10):
+			return "navi10";
+		case IP_VERSION(10, 1, 1):
+			return "navi14";
+		case IP_VERSION(10, 1, 2):
+			return "navi12";
+		case IP_VERSION(10, 3, 0):
+			return "sienna_cichlid";
+		case IP_VERSION(10, 3, 2):
+			return "navy_flounder";
+		case IP_VERSION(10, 3, 1):
+			return "vangogh";
+		case IP_VERSION(10, 3, 4):
+			return "dimgrey_cavefish";
+		case IP_VERSION(10, 3, 5):
+			return "beige_goby";
+		case IP_VERSION(10, 3, 3):
+			return "yellow_carp";
+		case IP_VERSION(10, 1, 3):
+		case IP_VERSION(10, 1, 4):
+			return "cyan_skillfish2";
+		}
+	}
+	return NULL;
+}
+
 void amdgpu_ucode_ip_version_decode(struct amdgpu_device *adev, int block_type, char *ucode_prefix, int len)
 {
 	int maj, min, rev;
 	char *ip_name;
+	const char *legacy;
 	uint32_t version = adev->ip_versions[block_type][0];
 
+	legacy = amdgpu_ucode_legacy_naming(adev, block_type);
+	if (legacy) {
+		snprintf(ucode_prefix, len, "%s", legacy);
+		return;
+	}
+
 	switch (block_type) {
 	case GC_HWIP:
 		ip_name = "gc";
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 03/11] drm/amd: Convert SMUv11 microcode init to use `amdgpu_ucode_ip_version_decode`
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 01/11] drm/amd: Delay removal of the firmware framebuffer Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 02/11] drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode" Mario Limonciello
@ 2022-12-28 16:30 ` Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 04/11] drm/amd: Convert SMU v13 " Mario Limonciello
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Mario Limonciello @ 2022-12-28 16:30 UTC (permalink / raw)
  To: Javier Martinez Canillas, Alex Deucher, linux-kernel
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, Mario Limonciello, Evan Quan,
	Pan, Xinhui

Remove the special casing from SMU v11 code. No intended functional
changes.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c    | 35 ++-----------------
 1 file changed, 3 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
index ad66d57aa102..d4756bd30830 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
@@ -93,7 +93,7 @@ static void smu_v11_0_poll_baco_exit(struct smu_context *smu)
 int smu_v11_0_init_microcode(struct smu_context *smu)
 {
 	struct amdgpu_device *adev = smu->adev;
-	const char *chip_name;
+	char ucode_prefix[30];
 	char fw_name[SMU_FW_NAME_LEN];
 	int err = 0;
 	const struct smc_firmware_header_v1_0 *hdr;
@@ -105,38 +105,9 @@ int smu_v11_0_init_microcode(struct smu_context *smu)
 	     (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7))))
 		return 0;
 
-	switch (adev->ip_versions[MP1_HWIP][0]) {
-	case IP_VERSION(11, 0, 0):
-		chip_name = "navi10";
-		break;
-	case IP_VERSION(11, 0, 5):
-		chip_name = "navi14";
-		break;
-	case IP_VERSION(11, 0, 9):
-		chip_name = "navi12";
-		break;
-	case IP_VERSION(11, 0, 7):
-		chip_name = "sienna_cichlid";
-		break;
-	case IP_VERSION(11, 0, 11):
-		chip_name = "navy_flounder";
-		break;
-	case IP_VERSION(11, 0, 12):
-		chip_name = "dimgrey_cavefish";
-		break;
-	case IP_VERSION(11, 0, 13):
-		chip_name = "beige_goby";
-		break;
-	case IP_VERSION(11, 0, 2):
-		chip_name = "arcturus";
-		break;
-	default:
-		dev_err(adev->dev, "Unsupported IP version 0x%x\n",
-			adev->ip_versions[MP1_HWIP][0]);
-		return -EINVAL;
-	}
+	amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, sizeof(ucode_prefix));
 
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_smc.bin", chip_name);
+	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix);
 
 	err = request_firmware(&adev->pm.fw, fw_name, adev->dev);
 	if (err)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 04/11] drm/amd: Convert SMU v13 to use `amdgpu_ucode_ip_version_decode`
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
                   ` (2 preceding siblings ...)
  2022-12-28 16:30 ` [PATCH v2 03/11] drm/amd: Convert SMUv11 microcode init to use `amdgpu_ucode_ip_version_decode` Mario Limonciello
@ 2022-12-28 16:30 ` Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 05/11] drm/amd: Request SDMA microcode during IP discovery Mario Limonciello
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Mario Limonciello @ 2022-12-28 16:30 UTC (permalink / raw)
  To: Javier Martinez Canillas, Alex Deucher, linux-kernel
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, Mario Limonciello, Evan Quan,
	Pan, Xinhui

The special case for the one dGPU has been moved into
`amdgpu_ucode_ip_version_decode`, so simplify this code.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
index 0ac9cac805f9..506a49a4b425 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
@@ -88,7 +88,6 @@ static const int link_speed[] = {25, 50, 80, 160};
 int smu_v13_0_init_microcode(struct smu_context *smu)
 {
 	struct amdgpu_device *adev = smu->adev;
-	const char *chip_name;
 	char fw_name[30];
 	char ucode_prefix[30];
 	int err = 0;
@@ -100,16 +99,9 @@ int smu_v13_0_init_microcode(struct smu_context *smu)
 	if (amdgpu_sriov_vf(adev))
 		return 0;
 
-	switch (adev->ip_versions[MP1_HWIP][0]) {
-	case IP_VERSION(13, 0, 2):
-		chip_name = "aldebaran_smc";
-		break;
-	default:
-		amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, sizeof(ucode_prefix));
-		chip_name = ucode_prefix;
-	}
+	amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, sizeof(ucode_prefix));
 
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", chip_name);
+	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix);
 
 	err = request_firmware(&adev->pm.fw, fw_name, adev->dev);
 	if (err)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 05/11] drm/amd: Request SDMA microcode during IP discovery
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
                   ` (3 preceding siblings ...)
  2022-12-28 16:30 ` [PATCH v2 04/11] drm/amd: Convert SMU v13 " Mario Limonciello
@ 2022-12-28 16:30 ` Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 06/11] drm/amd: Request VCN " Mario Limonciello
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Mario Limonciello @ 2022-12-28 16:30 UTC (permalink / raw)
  To: Javier Martinez Canillas, Alex Deucher, linux-kernel
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, Mario Limonciello, Pan, Xinhui

If SDMA microcode is not available during early init, the microcode
framebuffer will have already been released and the screen will
freeze.

Move the request from SDMA microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 57 ++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c      |  9 +--
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h      |  2 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c        | 61 +----------------
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c        | 42 +-----------
 drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c        | 65 +------------------
 drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c        | 30 +--------
 7 files changed, 66 insertions(+), 200 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index b719852daa07..f51ff86293b3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -90,6 +90,40 @@ MODULE_FIRMWARE(FIRMWARE_IP_DISCOVERY);
 #define mmMM_INDEX_HI		0x6
 #define mmMM_DATA		0x1
 
+MODULE_FIRMWARE("amdgpu/navi10_sdma.bin");
+MODULE_FIRMWARE("amdgpu/navi10_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/navi14_sdma.bin");
+MODULE_FIRMWARE("amdgpu/navi14_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/navi12_sdma.bin");
+MODULE_FIRMWARE("amdgpu/navi12_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_sdma.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/vega10_sdma.bin");
+MODULE_FIRMWARE("amdgpu/vega10_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/vega12_sdma.bin");
+MODULE_FIRMWARE("amdgpu/vega12_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/vega20_sdma.bin");
+MODULE_FIRMWARE("amdgpu/vega20_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/raven_sdma.bin");
+MODULE_FIRMWARE("amdgpu/picasso_sdma.bin");
+MODULE_FIRMWARE("amdgpu/raven2_sdma.bin");
+MODULE_FIRMWARE("amdgpu/arcturus_sdma.bin");
+MODULE_FIRMWARE("amdgpu/renoir_sdma.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_sdma.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_sdma.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_sdma.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_sdma.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_sdma.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_sdma.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_sdma.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_sdma.bin");
+MODULE_FIRMWARE("amdgpu/sdma_5_2_6.bin");
+MODULE_FIRMWARE("amdgpu/sdma_5_2_7.bin");
+MODULE_FIRMWARE("amdgpu/sdma_6_0_0.bin");
+MODULE_FIRMWARE("amdgpu/sdma_6_0_1.bin");
+MODULE_FIRMWARE("amdgpu/sdma_6_0_2.bin");
+MODULE_FIRMWARE("amdgpu/sdma_6_0_3.bin");
+
 static const char *hw_id_names[HW_ID_MAX] = {
 	[MP1_HWID]		= "MP1",
 	[MP2_HWID]		= "MP2",
@@ -1821,8 +1855,26 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
 	return 0;
 }
 
+static int amdgpu_discovery_load_sdma_fw(struct amdgpu_device *adev, u32 instance,
+					 const char *chip_name)
+{
+	char fw_name[40];
+
+	if (instance == 0)
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", chip_name);
+	else
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma1.bin", chip_name);
+
+	return request_firmware(&adev->sdma.instance[instance].fw, fw_name, adev->dev);
+}
+
 static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
 {
+	char ucode_prefix[30];
+	int i, r;
+
+	amdgpu_ucode_ip_version_decode(adev, SDMA0_HWIP, ucode_prefix, sizeof(ucode_prefix));
+
 	switch (adev->ip_versions[SDMA0_HWIP][0]) {
 	case IP_VERSION(4, 0, 0):
 	case IP_VERSION(4, 0, 1):
@@ -1862,6 +1914,11 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
 			adev->ip_versions[SDMA0_HWIP][0]);
 		return -EINVAL;
 	}
+	for (i = 0; i < adev->sdma.num_instances; i++) {
+		r = amdgpu_discovery_load_sdma_fw(adev, i, ucode_prefix);
+		if (r)
+			return r;
+	}
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
index ea5278f094c0..9e46d8034c03 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
@@ -205,8 +205,7 @@ void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev,
 }
 
 int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
-			       char *fw_name, u32 instance,
-			       bool duplicate)
+			       u32 instance, bool duplicate)
 {
 	struct amdgpu_firmware_info *info = NULL;
 	const struct common_firmware_header *header = NULL;
@@ -214,10 +213,6 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
 	const struct sdma_firmware_header_v2_0 *sdma_hdr;
 	uint16_t version_major;
 
-	err = request_firmware(&adev->sdma.instance[instance].fw, fw_name, adev->dev);
-	if (err)
-		goto out;
-
 	header = (const struct common_firmware_header *)
 		adev->sdma.instance[instance].fw->data;
 	version_major = le16_to_cpu(header->header_version_major);
@@ -280,7 +275,7 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
 
 out:
 	if (err) {
-		DRM_ERROR("SDMA: Failed to init firmware \"%s\"\n", fw_name);
+		DRM_ERROR("SDMA: Failed to init sdma firmware\n");
 		amdgpu_sdma_destroy_inst_ctx(adev, duplicate);
 	}
 	return err;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
index 7d99205c2e01..fa06681b97c0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
@@ -125,7 +125,7 @@ int amdgpu_sdma_process_ecc_irq(struct amdgpu_device *adev,
 				      struct amdgpu_irq_src *source,
 				      struct amdgpu_iv_entry *entry);
 int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
-        char *fw_name, u32 instance, bool duplicate);
+        u32 instance, bool duplicate);
 void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev,
         bool duplicate);
 void amdgpu_sdma_unset_buffer_funcs_helper(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 4d780e4430e7..bbaee1cfc92d 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -58,20 +58,6 @@
 #include "amdgpu_ras.h"
 #include "sdma_v4_4.h"
 
-MODULE_FIRMWARE("amdgpu/vega10_sdma.bin");
-MODULE_FIRMWARE("amdgpu/vega10_sdma1.bin");
-MODULE_FIRMWARE("amdgpu/vega12_sdma.bin");
-MODULE_FIRMWARE("amdgpu/vega12_sdma1.bin");
-MODULE_FIRMWARE("amdgpu/vega20_sdma.bin");
-MODULE_FIRMWARE("amdgpu/vega20_sdma1.bin");
-MODULE_FIRMWARE("amdgpu/raven_sdma.bin");
-MODULE_FIRMWARE("amdgpu/picasso_sdma.bin");
-MODULE_FIRMWARE("amdgpu/raven2_sdma.bin");
-MODULE_FIRMWARE("amdgpu/arcturus_sdma.bin");
-MODULE_FIRMWARE("amdgpu/renoir_sdma.bin");
-MODULE_FIRMWARE("amdgpu/green_sardine_sdma.bin");
-MODULE_FIRMWARE("amdgpu/aldebaran_sdma.bin");
-
 #define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK  0x000000F8L
 #define SDMA0_POWER_CNTL__ON_OFF_STATUS_DURATION_TIME_MASK 0xFC000000L
 
@@ -575,60 +561,17 @@ static void sdma_v4_0_setup_ulv(struct amdgpu_device *adev)
 // vega10 real chip need to use PSP to load firmware
 static int sdma_v4_0_init_microcode(struct amdgpu_device *adev)
 {
-	const char *chip_name;
-	char fw_name[30];
 	int ret, i;
 
-	DRM_DEBUG("\n");
-
-	switch (adev->ip_versions[SDMA0_HWIP][0]) {
-	case IP_VERSION(4, 0, 0):
-		chip_name = "vega10";
-		break;
-	case IP_VERSION(4, 0, 1):
-		chip_name = "vega12";
-		break;
-	case IP_VERSION(4, 2, 0):
-		chip_name = "vega20";
-		break;
-	case IP_VERSION(4, 1, 0):
-	case IP_VERSION(4, 1, 1):
-		if (adev->apu_flags & AMD_APU_IS_RAVEN2)
-			chip_name = "raven2";
-		else if (adev->apu_flags & AMD_APU_IS_PICASSO)
-			chip_name = "picasso";
-		else
-			chip_name = "raven";
-		break;
-	case IP_VERSION(4, 2, 2):
-		chip_name = "arcturus";
-		break;
-	case IP_VERSION(4, 1, 2):
-		if (adev->apu_flags & AMD_APU_IS_RENOIR)
-			chip_name = "renoir";
-		else
-			chip_name = "green_sardine";
-		break;
-	case IP_VERSION(4, 4, 0):
-		chip_name = "aldebaran";
-		break;
-	default:
-		BUG();
-	}
-
 	for (i = 0; i < adev->sdma.num_instances; i++) {
-		if (i == 0)
-			snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma.bin", chip_name);
-		else
-			snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma%d.bin", chip_name, i);
 		if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 2) ||
                     adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 4, 0)) {
 			/* Acturus & Aldebaran will leverage the same FW memory
 			   for every SDMA instance */
-			ret = amdgpu_sdma_init_microcode(adev, fw_name, 0, true);
+			ret = amdgpu_sdma_init_microcode(adev, 0, true);
 			break;
 		} else {
-			ret = amdgpu_sdma_init_microcode(adev, fw_name, i, false);
+			ret = amdgpu_sdma_init_microcode(adev, i, false);
 			if (ret)
 				return ret;
 		}
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index d4d9f196db83..4154b511ae94 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -42,18 +42,6 @@
 #include "sdma_common.h"
 #include "sdma_v5_0.h"
 
-MODULE_FIRMWARE("amdgpu/navi10_sdma.bin");
-MODULE_FIRMWARE("amdgpu/navi10_sdma1.bin");
-
-MODULE_FIRMWARE("amdgpu/navi14_sdma.bin");
-MODULE_FIRMWARE("amdgpu/navi14_sdma1.bin");
-
-MODULE_FIRMWARE("amdgpu/navi12_sdma.bin");
-MODULE_FIRMWARE("amdgpu/navi12_sdma1.bin");
-
-MODULE_FIRMWARE("amdgpu/cyan_skillfish2_sdma.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish2_sdma1.bin");
-
 #define SDMA1_REG_OFFSET 0x600
 #define SDMA0_HYP_DEC_REG_START 0x5880
 #define SDMA0_HYP_DEC_REG_END 0x5893
@@ -237,39 +225,13 @@ static void sdma_v5_0_init_golden_registers(struct amdgpu_device *adev)
 // emulation only, won't work on real chip
 // navi10 real chip need to use PSP to load firmware
 static int sdma_v5_0_init_microcode(struct amdgpu_device *adev)
-{
-	const char *chip_name;
-	char fw_name[40];
-	int ret, i;
+{	int ret, i;
 
 	if (amdgpu_sriov_vf(adev) && (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(5, 0, 5)))
 		return 0;
 
-	DRM_DEBUG("\n");
-
-	switch (adev->ip_versions[SDMA0_HWIP][0]) {
-	case IP_VERSION(5, 0, 0):
-		chip_name = "navi10";
-		break;
-	case IP_VERSION(5, 0, 2):
-		chip_name = "navi14";
-		break;
-	case IP_VERSION(5, 0, 5):
-		chip_name = "navi12";
-		break;
-	case IP_VERSION(5, 0, 1):
-		chip_name = "cyan_skillfish2";
-		break;
-	default:
-		BUG();
-	}
-
 	for (i = 0; i < adev->sdma.num_instances; i++) {
-		if (i == 0)
-			snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma.bin", chip_name);
-		else
-			snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma1.bin", chip_name);
-		ret = amdgpu_sdma_init_microcode(adev, fw_name, i, false);
+		ret = amdgpu_sdma_init_microcode(adev, i, false);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
index 65e7a710298d..4757c119cdfe 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
@@ -44,16 +44,6 @@
 #include "sdma_common.h"
 #include "sdma_v5_2.h"
 
-MODULE_FIRMWARE("amdgpu/sienna_cichlid_sdma.bin");
-MODULE_FIRMWARE("amdgpu/navy_flounder_sdma.bin");
-MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_sdma.bin");
-MODULE_FIRMWARE("amdgpu/beige_goby_sdma.bin");
-
-MODULE_FIRMWARE("amdgpu/vangogh_sdma.bin");
-MODULE_FIRMWARE("amdgpu/yellow_carp_sdma.bin");
-MODULE_FIRMWARE("amdgpu/sdma_5_2_6.bin");
-MODULE_FIRMWARE("amdgpu/sdma_5_2_7.bin");
-
 #define SDMA1_REG_OFFSET 0x600
 #define SDMA3_REG_OFFSET 0x400
 #define SDMA0_HYP_DEC_REG_START 0x5880
@@ -89,59 +79,6 @@ static u32 sdma_v5_2_get_reg_offset(struct amdgpu_device *adev, u32 instance, u3
 	return base + internal_offset;
 }
 
-/**
- * sdma_v5_2_init_microcode - load ucode images from disk
- *
- * @adev: amdgpu_device pointer
- *
- * Use the firmware interface to load the ucode images into
- * the driver (not loaded into hw).
- * Returns 0 on success, error on failure.
- */
-
-// emulation only, won't work on real chip
-// navi10 real chip need to use PSP to load firmware
-static int sdma_v5_2_init_microcode(struct amdgpu_device *adev)
-{
-	const char *chip_name;
-	char fw_name[40];
-
-	DRM_DEBUG("\n");
-
-	switch (adev->ip_versions[SDMA0_HWIP][0]) {
-	case IP_VERSION(5, 2, 0):
-		chip_name = "sienna_cichlid_sdma";
-		break;
-	case IP_VERSION(5, 2, 2):
-		chip_name = "navy_flounder_sdma";
-		break;
-	case IP_VERSION(5, 2, 1):
-		chip_name = "vangogh_sdma";
-		break;
-	case IP_VERSION(5, 2, 4):
-		chip_name = "dimgrey_cavefish_sdma";
-		break;
-	case IP_VERSION(5, 2, 5):
-		chip_name = "beige_goby_sdma";
-		break;
-	case IP_VERSION(5, 2, 3):
-		chip_name = "yellow_carp_sdma";
-		break;
-	case IP_VERSION(5, 2, 6):
-		chip_name = "sdma_5_2_6";
-		break;
-	case IP_VERSION(5, 2, 7):
-		chip_name = "sdma_5_2_7";
-		break;
-	default:
-		BUG();
-	}
-
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", chip_name);
-
-	return amdgpu_sdma_init_microcode(adev, fw_name, 0, true);
-}
-
 static unsigned sdma_v5_2_ring_init_cond_exec(struct amdgpu_ring *ring)
 {
 	unsigned ret;
@@ -1288,7 +1225,7 @@ static int sdma_v5_2_sw_init(void *handle)
 			return r;
 	}
 
-	r = sdma_v5_2_init_microcode(adev);
+	r = amdgpu_sdma_init_microcode(adev, 0, true);
 	if (r) {
 		DRM_ERROR("Failed to load sdma firmware!\n");
 		return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
index 049c26a45d85..9c65e2f98d44 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
@@ -44,11 +44,6 @@
 #include "sdma_v6_0.h"
 #include "v11_structs.h"
 
-MODULE_FIRMWARE("amdgpu/sdma_6_0_0.bin");
-MODULE_FIRMWARE("amdgpu/sdma_6_0_1.bin");
-MODULE_FIRMWARE("amdgpu/sdma_6_0_2.bin");
-MODULE_FIRMWARE("amdgpu/sdma_6_0_3.bin");
-
 #define SDMA1_REG_OFFSET 0x600
 #define SDMA0_HYP_DEC_REG_START 0x5880
 #define SDMA0_HYP_DEC_REG_END 0x589a
@@ -78,29 +73,6 @@ static u32 sdma_v6_0_get_reg_offset(struct amdgpu_device *adev, u32 instance, u3
 	return base + internal_offset;
 }
 
-/**
- * sdma_v6_0_init_microcode - load ucode images from disk
- *
- * @adev: amdgpu_device pointer
- *
- * Use the firmware interface to load the ucode images into
- * the driver (not loaded into hw).
- * Returns 0 on success, error on failure.
- */
-static int sdma_v6_0_init_microcode(struct amdgpu_device *adev)
-{
-	char fw_name[30];
-	char ucode_prefix[30];
-
-	DRM_DEBUG("\n");
-
-	amdgpu_ucode_ip_version_decode(adev, SDMA0_HWIP, ucode_prefix, sizeof(ucode_prefix));
-
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix);
-
-	return amdgpu_sdma_init_microcode(adev, fw_name, 0, true);
-}
-
 static unsigned sdma_v6_0_ring_init_cond_exec(struct amdgpu_ring *ring)
 {
 	unsigned ret;
@@ -1260,7 +1232,7 @@ static int sdma_v6_0_sw_init(void *handle)
 	if (r)
 		return r;
 
-	r = sdma_v6_0_init_microcode(adev);
+	r = amdgpu_sdma_init_microcode(adev, 0, true);
 	if (r) {
 		DRM_ERROR("Failed to load sdma firmware!\n");
 		return r;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 06/11] drm/amd: Request VCN microcode during IP discovery
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
                   ` (4 preceding siblings ...)
  2022-12-28 16:30 ` [PATCH v2 05/11] drm/amd: Request SDMA microcode during IP discovery Mario Limonciello
@ 2022-12-28 16:30 ` Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 07/11] drm/amd: Request MES " Mario Limonciello
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Mario Limonciello @ 2022-12-28 16:30 UTC (permalink / raw)
  To: Javier Martinez Canillas, Alex Deucher, linux-kernel
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, Mario Limonciello, Pan, Xinhui

If VCN microcode is not available during early init, the microcode
framebuffer will have already been released and the screen will
freeze.

Move the request for VCN microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 41 ++++++++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c       | 85 +------------------
 2 files changed, 41 insertions(+), 85 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index f51ff86293b3..1c26a3a60394 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -124,6 +124,27 @@ MODULE_FIRMWARE("amdgpu/sdma_6_0_1.bin");
 MODULE_FIRMWARE("amdgpu/sdma_6_0_2.bin");
 MODULE_FIRMWARE("amdgpu/sdma_6_0_3.bin");
 
+MODULE_FIRMWARE("amdgpu/raven_vcn.bin");
+MODULE_FIRMWARE("amdgpu/picasso_vcn.bin");
+MODULE_FIRMWARE("amdgpu/raven2_vcn.bin");
+MODULE_FIRMWARE("amdgpu/arcturus_vcn.bin");
+MODULE_FIRMWARE("amdgpu/renoir_vcn.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_vcn.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_vcn.bin");
+MODULE_FIRMWARE("amdgpu/navi10_vcn.bin");
+MODULE_FIRMWARE("amdgpu/navi14_vcn.bin");
+MODULE_FIRMWARE("amdgpu/navi12_vcn.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_vcn.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_vcn.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_vcn.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_vcn.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_vcn.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_vcn.bin");
+MODULE_FIRMWARE("amdgpu/vcn_3_1_2.bin");
+MODULE_FIRMWARE("amdgpu/vcn_4_0_0.bin");
+MODULE_FIRMWARE("amdgpu/vcn_4_0_2.bin");
+MODULE_FIRMWARE("amdgpu/vcn_4_0_4.bin");
+
 static const char *hw_id_names[HW_ID_MAX] = {
 	[MP1_HWID]		= "MP1",
 	[MP2_HWID]		= "MP2",
@@ -1922,8 +1943,23 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
 	return 0;
 }
 
+static int amdgpu_discovery_load_vcn_fw(struct amdgpu_device *adev,
+					char *fname)
+{
+	char fw_name[40];
+
+	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", fname);
+
+	return request_firmware(&adev->vcn.fw, fw_name, adev->dev);
+}
+
 static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
 {
+	char ucode_prefix[30];
+	int r = 0;
+
+	amdgpu_ucode_ip_version_decode(adev, UVD_HWIP, ucode_prefix, sizeof(ucode_prefix));
+
 	if (adev->ip_versions[VCE_HWIP][0]) {
 		switch (adev->ip_versions[UVD_HWIP][0]) {
 		case IP_VERSION(7, 0, 0):
@@ -2001,7 +2037,10 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
 			return -EINVAL;
 		}
 	}
-	return 0;
+	if (*ucode_prefix)
+		r = amdgpu_discovery_load_vcn_fw(adev, ucode_prefix);
+	return r;
+}
 }
 
 static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index a23e26b272b4..370c9644a3b3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -35,55 +35,11 @@
 #include "amdgpu_vcn.h"
 #include "soc15d.h"
 
-/* Firmware Names */
-#define FIRMWARE_RAVEN		"amdgpu/raven_vcn.bin"
-#define FIRMWARE_PICASSO	"amdgpu/picasso_vcn.bin"
-#define FIRMWARE_RAVEN2		"amdgpu/raven2_vcn.bin"
-#define FIRMWARE_ARCTURUS	"amdgpu/arcturus_vcn.bin"
-#define FIRMWARE_RENOIR		"amdgpu/renoir_vcn.bin"
-#define FIRMWARE_GREEN_SARDINE	"amdgpu/green_sardine_vcn.bin"
-#define FIRMWARE_NAVI10		"amdgpu/navi10_vcn.bin"
-#define FIRMWARE_NAVI14		"amdgpu/navi14_vcn.bin"
-#define FIRMWARE_NAVI12		"amdgpu/navi12_vcn.bin"
-#define FIRMWARE_SIENNA_CICHLID	"amdgpu/sienna_cichlid_vcn.bin"
-#define FIRMWARE_NAVY_FLOUNDER	"amdgpu/navy_flounder_vcn.bin"
-#define FIRMWARE_VANGOGH	"amdgpu/vangogh_vcn.bin"
-#define FIRMWARE_DIMGREY_CAVEFISH	"amdgpu/dimgrey_cavefish_vcn.bin"
-#define FIRMWARE_ALDEBARAN	"amdgpu/aldebaran_vcn.bin"
-#define FIRMWARE_BEIGE_GOBY	"amdgpu/beige_goby_vcn.bin"
-#define FIRMWARE_YELLOW_CARP	"amdgpu/yellow_carp_vcn.bin"
-#define FIRMWARE_VCN_3_1_2	"amdgpu/vcn_3_1_2.bin"
-#define FIRMWARE_VCN4_0_0	"amdgpu/vcn_4_0_0.bin"
-#define FIRMWARE_VCN4_0_2	"amdgpu/vcn_4_0_2.bin"
-#define FIRMWARE_VCN4_0_4      "amdgpu/vcn_4_0_4.bin"
-
-MODULE_FIRMWARE(FIRMWARE_RAVEN);
-MODULE_FIRMWARE(FIRMWARE_PICASSO);
-MODULE_FIRMWARE(FIRMWARE_RAVEN2);
-MODULE_FIRMWARE(FIRMWARE_ARCTURUS);
-MODULE_FIRMWARE(FIRMWARE_RENOIR);
-MODULE_FIRMWARE(FIRMWARE_GREEN_SARDINE);
-MODULE_FIRMWARE(FIRMWARE_ALDEBARAN);
-MODULE_FIRMWARE(FIRMWARE_NAVI10);
-MODULE_FIRMWARE(FIRMWARE_NAVI14);
-MODULE_FIRMWARE(FIRMWARE_NAVI12);
-MODULE_FIRMWARE(FIRMWARE_SIENNA_CICHLID);
-MODULE_FIRMWARE(FIRMWARE_NAVY_FLOUNDER);
-MODULE_FIRMWARE(FIRMWARE_VANGOGH);
-MODULE_FIRMWARE(FIRMWARE_DIMGREY_CAVEFISH);
-MODULE_FIRMWARE(FIRMWARE_BEIGE_GOBY);
-MODULE_FIRMWARE(FIRMWARE_YELLOW_CARP);
-MODULE_FIRMWARE(FIRMWARE_VCN_3_1_2);
-MODULE_FIRMWARE(FIRMWARE_VCN4_0_0);
-MODULE_FIRMWARE(FIRMWARE_VCN4_0_2);
-MODULE_FIRMWARE(FIRMWARE_VCN4_0_4);
-
 static void amdgpu_vcn_idle_work_handler(struct work_struct *work);
 
 int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
 {
 	unsigned long bo_size;
-	const char *fw_name;
 	const struct common_firmware_header *hdr;
 	unsigned char fw_check;
 	unsigned int fw_shared_size, log_offset;
@@ -99,46 +55,27 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
 	switch (adev->ip_versions[UVD_HWIP][0]) {
 	case IP_VERSION(1, 0, 0):
 	case IP_VERSION(1, 0, 1):
-		if (adev->apu_flags & AMD_APU_IS_RAVEN2)
-			fw_name = FIRMWARE_RAVEN2;
-		else if (adev->apu_flags & AMD_APU_IS_PICASSO)
-			fw_name = FIRMWARE_PICASSO;
-		else
-			fw_name = FIRMWARE_RAVEN;
-		break;
 	case IP_VERSION(2, 5, 0):
-		fw_name = FIRMWARE_ARCTURUS;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
 		break;
 	case IP_VERSION(2, 2, 0):
-		if (adev->apu_flags & AMD_APU_IS_RENOIR)
-			fw_name = FIRMWARE_RENOIR;
-		else
-			fw_name = FIRMWARE_GREEN_SARDINE;
-
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
 		break;
 	case IP_VERSION(2, 6, 0):
-		fw_name = FIRMWARE_ALDEBARAN;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
 		break;
 	case IP_VERSION(2, 0, 0):
-		fw_name = FIRMWARE_NAVI10;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
 		break;
 	case IP_VERSION(2, 0, 2):
-		if (adev->asic_type == CHIP_NAVI12)
-			fw_name = FIRMWARE_NAVI12;
-		else
-			fw_name = FIRMWARE_NAVI14;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
@@ -146,58 +83,46 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
 	case IP_VERSION(3, 0, 0):
 	case IP_VERSION(3, 0, 64):
 	case IP_VERSION(3, 0, 192):
-		if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0))
-			fw_name = FIRMWARE_SIENNA_CICHLID;
-		else
-			fw_name = FIRMWARE_NAVY_FLOUNDER;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
 		break;
 	case IP_VERSION(3, 0, 2):
-		fw_name = FIRMWARE_VANGOGH;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
 		break;
 	case IP_VERSION(3, 0, 16):
-		fw_name = FIRMWARE_DIMGREY_CAVEFISH;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
 		break;
 	case IP_VERSION(3, 0, 33):
-		fw_name = FIRMWARE_BEIGE_GOBY;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
 		break;
 	case IP_VERSION(3, 1, 1):
-		fw_name = FIRMWARE_YELLOW_CARP;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
 		break;
 	case IP_VERSION(3, 1, 2):
-		fw_name = FIRMWARE_VCN_3_1_2;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
 		break;
 	case IP_VERSION(4, 0, 0):
-		fw_name = FIRMWARE_VCN4_0_0;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 			(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
 		break;
 	case IP_VERSION(4, 0, 2):
-		fw_name = FIRMWARE_VCN4_0_2;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 			(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
 		break;
 	case IP_VERSION(4, 0, 4):
-		fw_name = FIRMWARE_VCN4_0_4;
 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 			(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 			adev->vcn.indirect_sram = true;
@@ -206,17 +131,9 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
 		return -EINVAL;
 	}
 
-	r = request_firmware(&adev->vcn.fw, fw_name, adev->dev);
-	if (r) {
-		dev_err(adev->dev, "amdgpu_vcn: Can't load firmware \"%s\"\n",
-			fw_name);
-		return r;
-	}
-
 	r = amdgpu_ucode_validate(adev->vcn.fw);
 	if (r) {
-		dev_err(adev->dev, "amdgpu_vcn: Can't validate firmware \"%s\"\n",
-			fw_name);
+		dev_err(adev->dev, "amdgpu_vcn: Can't validate firmware\n");
 		release_firmware(adev->vcn.fw);
 		adev->vcn.fw = NULL;
 		return r;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 07/11] drm/amd: Request MES microcode during IP discovery
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
                   ` (5 preceding siblings ...)
  2022-12-28 16:30 ` [PATCH v2 06/11] drm/amd: Request VCN " Mario Limonciello
@ 2022-12-28 16:30 ` Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 08/11] drm/amd: Request GFX9 " Mario Limonciello
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Mario Limonciello @ 2022-12-28 16:30 UTC (permalink / raw)
  To: Javier Martinez Canillas, Alex Deucher, linux-kernel
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, Mario Limonciello, Pan, Xinhui

If MES microcode is required but not available during early init, the
microcode framebuffer will have already been released and the screen will
freeze.

Move the request for MES microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 39 +++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/mes_v10_1.c        | 28 -------------
 drivers/gpu/drm/amd/amdgpu/mes_v11_0.c        | 25 +-----------
 3 files changed, 40 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 1c26a3a60394..479266ed2b7f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -145,6 +145,19 @@ MODULE_FIRMWARE("amdgpu/vcn_4_0_0.bin");
 MODULE_FIRMWARE("amdgpu/vcn_4_0_2.bin");
 MODULE_FIRMWARE("amdgpu/vcn_4_0_4.bin");
 
+MODULE_FIRMWARE("amdgpu/navi10_mes.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_mes.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_mes1.bin");
+
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes1.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes1.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
+
 static const char *hw_id_names[HW_ID_MAX] = {
 	[MP1_HWID]		= "MP1",
 	[MP2_HWID]		= "MP2",
@@ -2041,10 +2054,29 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
 		r = amdgpu_discovery_load_vcn_fw(adev, ucode_prefix);
 	return r;
 }
+
+static int amdgpu_discovery_load_mes_fw(struct amdgpu_device *adev,
+					enum admgpu_mes_pipe pipe,
+					const char *ucode_prefix)
+{
+	char fw_name[40];
+
+	if (pipe == AMDGPU_MES_SCHED_PIPE)
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes.bin",
+			 ucode_prefix);
+	else
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes1.bin",
+			 ucode_prefix);
+
+	return request_firmware(&adev->mes.fw[pipe], fw_name, adev->dev);
 }
 
 static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
 {
+	char ucode_prefix[30];
+	int pipe, r;
+	amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix));
+
 	switch (adev->ip_versions[GC_HWIP][0]) {
 	case IP_VERSION(10, 1, 10):
 	case IP_VERSION(10, 1, 1):
@@ -2077,6 +2109,13 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
 	default:
 		break;
 	}
+	if (adev->enable_mes) {
+		for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) {
+			r = amdgpu_discovery_load_mes_fw(adev, pipe, ucode_prefix);
+			if (r)
+				return r;
+		}
+	}
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c b/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c
index 614394118a53..9faa9867b3c9 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c
@@ -37,10 +37,6 @@
 #define mmRLC_CP_SCHEDULERS_Sienna_Cichlid		0x4ca1
 #define mmRLC_CP_SCHEDULERS_Sienna_Cichlid_BASE_IDX	1
 
-MODULE_FIRMWARE("amdgpu/navi10_mes.bin");
-MODULE_FIRMWARE("amdgpu/sienna_cichlid_mes.bin");
-MODULE_FIRMWARE("amdgpu/sienna_cichlid_mes1.bin");
-
 static int mes_v10_1_hw_fini(void *handle);
 static int mes_v10_1_kiq_hw_init(struct amdgpu_device *adev);
 
@@ -382,34 +378,10 @@ static const struct amdgpu_mes_funcs mes_v10_1_funcs = {
 static int mes_v10_1_init_microcode(struct amdgpu_device *adev,
 				    enum admgpu_mes_pipe pipe)
 {
-	const char *chip_name;
-	char fw_name[30];
 	int err;
 	const struct mes_firmware_header_v1_0 *mes_hdr;
 	struct amdgpu_firmware_info *info;
 
-	switch (adev->ip_versions[GC_HWIP][0]) {
-	case IP_VERSION(10, 1, 10):
-		chip_name = "navi10";
-		break;
-	case IP_VERSION(10, 3, 0):
-		chip_name = "sienna_cichlid";
-		break;
-	default:
-		BUG();
-	}
-
-	if (pipe == AMDGPU_MES_SCHED_PIPE)
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes.bin",
-			 chip_name);
-	else
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes1.bin",
-			 chip_name);
-
-	err = request_firmware(&adev->mes.fw[pipe], fw_name, adev->dev);
-	if (err)
-		return err;
-
 	err = amdgpu_ucode_validate(adev->mes.fw[pipe]);
 	if (err) {
 		release_firmware(adev->mes.fw[pipe]);
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
index 970b066b37bb..27176a1259ac 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
@@ -32,15 +32,6 @@
 #include "v11_structs.h"
 #include "mes_v11_api_def.h"
 
-MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes1.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes1.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
-
 static int mes_v11_0_hw_fini(void *handle);
 static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev);
 static int mes_v11_0_kiq_hw_fini(struct amdgpu_device *adev);
@@ -462,25 +453,11 @@ static const struct amdgpu_mes_funcs mes_v11_0_funcs = {
 static int mes_v11_0_init_microcode(struct amdgpu_device *adev,
 				    enum admgpu_mes_pipe pipe)
 {
-	char fw_name[30];
-	char ucode_prefix[30];
+
 	int err;
 	const struct mes_firmware_header_v1_0 *mes_hdr;
 	struct amdgpu_firmware_info *info;
 
-	amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix));
-
-	if (pipe == AMDGPU_MES_SCHED_PIPE)
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes.bin",
-			 ucode_prefix);
-	else
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes1.bin",
-			 ucode_prefix);
-
-	err = request_firmware(&adev->mes.fw[pipe], fw_name, adev->dev);
-	if (err)
-		return err;
-
 	err = amdgpu_ucode_validate(adev->mes.fw[pipe]);
 	if (err) {
 		release_firmware(adev->mes.fw[pipe]);
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 08/11] drm/amd: Request GFX9 microcode during IP discovery
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
                   ` (6 preceding siblings ...)
  2022-12-28 16:30 ` [PATCH v2 07/11] drm/amd: Request MES " Mario Limonciello
@ 2022-12-28 16:30 ` Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 09/11] drm/amd: Request GFX10 " Mario Limonciello
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Mario Limonciello @ 2022-12-28 16:30 UTC (permalink / raw)
  To: Javier Martinez Canillas, Alex Deucher, linux-kernel
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, Mario Limonciello, Pan, Xinhui

If GFX9 microcode is required but not available during early init, the
microcode framebuffer will have already been released and the screen will
freeze.

Move the request for GFX9 microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 144 ++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c         | 143 +----------------
 2 files changed, 152 insertions(+), 135 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 479266ed2b7f..0da16abd6b24 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -158,6 +158,68 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
 MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
 MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
 
+
+/* gfx9 */
+MODULE_FIRMWARE("amdgpu/vega10_ce.bin");
+MODULE_FIRMWARE("amdgpu/vega10_pfp.bin");
+MODULE_FIRMWARE("amdgpu/vega10_me.bin");
+MODULE_FIRMWARE("amdgpu/vega10_mec.bin");
+MODULE_FIRMWARE("amdgpu/vega10_mec2.bin");
+MODULE_FIRMWARE("amdgpu/vega10_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/vega12_ce.bin");
+MODULE_FIRMWARE("amdgpu/vega12_pfp.bin");
+MODULE_FIRMWARE("amdgpu/vega12_me.bin");
+MODULE_FIRMWARE("amdgpu/vega12_mec.bin");
+MODULE_FIRMWARE("amdgpu/vega12_mec2.bin");
+MODULE_FIRMWARE("amdgpu/vega12_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/vega20_ce.bin");
+MODULE_FIRMWARE("amdgpu/vega20_pfp.bin");
+MODULE_FIRMWARE("amdgpu/vega20_me.bin");
+MODULE_FIRMWARE("amdgpu/vega20_mec.bin");
+MODULE_FIRMWARE("amdgpu/vega20_mec2.bin");
+MODULE_FIRMWARE("amdgpu/vega20_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/raven_ce.bin");
+MODULE_FIRMWARE("amdgpu/raven_pfp.bin");
+MODULE_FIRMWARE("amdgpu/raven_me.bin");
+MODULE_FIRMWARE("amdgpu/raven_mec.bin");
+MODULE_FIRMWARE("amdgpu/raven_mec2.bin");
+MODULE_FIRMWARE("amdgpu/raven_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/picasso_ce.bin");
+MODULE_FIRMWARE("amdgpu/picasso_pfp.bin");
+MODULE_FIRMWARE("amdgpu/picasso_me.bin");
+MODULE_FIRMWARE("amdgpu/picasso_mec.bin");
+MODULE_FIRMWARE("amdgpu/picasso_mec2.bin");
+MODULE_FIRMWARE("amdgpu/picasso_rlc.bin");
+MODULE_FIRMWARE("amdgpu/picasso_rlc_am4.bin");
+
+MODULE_FIRMWARE("amdgpu/raven2_ce.bin");
+MODULE_FIRMWARE("amdgpu/raven2_pfp.bin");
+MODULE_FIRMWARE("amdgpu/raven2_me.bin");
+MODULE_FIRMWARE("amdgpu/raven2_mec.bin");
+MODULE_FIRMWARE("amdgpu/raven2_mec2.bin");
+MODULE_FIRMWARE("amdgpu/raven2_rlc.bin");
+MODULE_FIRMWARE("amdgpu/raven_kicker_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/arcturus_mec.bin");
+MODULE_FIRMWARE("amdgpu/arcturus_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/renoir_ce.bin");
+MODULE_FIRMWARE("amdgpu/renoir_pfp.bin");
+MODULE_FIRMWARE("amdgpu/renoir_me.bin");
+MODULE_FIRMWARE("amdgpu/renoir_mec.bin");
+MODULE_FIRMWARE("amdgpu/renoir_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/green_sardine_ce.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_pfp.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_me.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_mec.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_mec2.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_rlc.bin");
+
 static const char *hw_id_names[HW_ID_MAX] = {
 	[MP1_HWID]		= "MP1",
 	[MP2_HWID]		= "MP2",
@@ -1845,8 +1907,87 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
 	return 0;
 }
 
+static int amdgpu_discovery_load_gfx9(struct amdgpu_device *adev, char *ucode_prefix)
+{
+	uint32_t smu_version;
+	char fw_name[40];
+	int r;
+
+	/* No CPG in Arcturus */
+	if (adev->gfx.num_gfx_rings) {
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", ucode_prefix);
+		r = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev);
+		if (r)
+			return r;
+
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", ucode_prefix);
+		r = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev);
+		if (r)
+			return r;
+
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", ucode_prefix);
+		r = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev);
+		if (r)
+			return r;
+	}
+
+	if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_ALDEBARAN))
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sjt_mec.bin", ucode_prefix);
+	else
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", ucode_prefix);
+	r = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
+	if (r)
+		return r;
+
+	/*
+	 * For Picasso && AM4 SOCKET board, we use picasso_rlc_am4.bin
+	 * instead of picasso_rlc.bin.
+	 * Judgment method:
+	 * PCO AM4: revision >= 0xC8 && revision <= 0xCF
+	 *          or revision >= 0xD8 && revision <= 0xDF
+	 * otherwise is PCO FP5
+	 */
+	if (!strcmp(ucode_prefix, "picasso") &&
+		(((adev->pdev->revision >= 0xC8) && (adev->pdev->revision <= 0xCF)) ||
+		((adev->pdev->revision >= 0xD8) && (adev->pdev->revision <= 0xDF))))
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc_am4.bin", ucode_prefix);
+	else if (!strcmp(ucode_prefix, "raven") && (amdgpu_pm_load_smu_firmware(adev, &smu_version) == 0) &&
+		(smu_version >= 0x41e2b))
+		/**
+		*SMC is loaded by SBIOS on APU and it's able to get the SMU version directly.
+		*/
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_kicker_rlc.bin", ucode_prefix);
+	else
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", ucode_prefix);
+	r = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
+	if (r)
+		return r;
+
+	/* mec2 fw bin support */
+	if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2) ||
+		adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 1) ||
+		adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 3, 0)) {
+
+		if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_ALDEBARAN))
+			snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sjt_mec2.bin", ucode_prefix);
+		else
+			snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", ucode_prefix);
+
+		r = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev);
+		if (r)
+			return r;
+	}
+
+	return 0;
+}
+
 static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
 {
+	char ucode_prefix[30];
+	int r;
+
+	amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix));
+
 	switch (adev->ip_versions[GC_HWIP][0]) {
 	case IP_VERSION(9, 0, 1):
 	case IP_VERSION(9, 1, 0):
@@ -1856,6 +1997,9 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
 	case IP_VERSION(9, 4, 0):
 	case IP_VERSION(9, 4, 1):
 	case IP_VERSION(9, 4, 2):
+		r = amdgpu_discovery_load_gfx9(adev, ucode_prefix);
+		if (r)
+			return r;
 		amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
 		break;
 	case IP_VERSION(10, 1, 10):
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index f202b45c413c..3d6e6b7d461d 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -65,72 +65,6 @@
 #define mmGCEA_PROBE_MAP                        0x070c
 #define mmGCEA_PROBE_MAP_BASE_IDX               0
 
-MODULE_FIRMWARE("amdgpu/vega10_ce.bin");
-MODULE_FIRMWARE("amdgpu/vega10_pfp.bin");
-MODULE_FIRMWARE("amdgpu/vega10_me.bin");
-MODULE_FIRMWARE("amdgpu/vega10_mec.bin");
-MODULE_FIRMWARE("amdgpu/vega10_mec2.bin");
-MODULE_FIRMWARE("amdgpu/vega10_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/vega12_ce.bin");
-MODULE_FIRMWARE("amdgpu/vega12_pfp.bin");
-MODULE_FIRMWARE("amdgpu/vega12_me.bin");
-MODULE_FIRMWARE("amdgpu/vega12_mec.bin");
-MODULE_FIRMWARE("amdgpu/vega12_mec2.bin");
-MODULE_FIRMWARE("amdgpu/vega12_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/vega20_ce.bin");
-MODULE_FIRMWARE("amdgpu/vega20_pfp.bin");
-MODULE_FIRMWARE("amdgpu/vega20_me.bin");
-MODULE_FIRMWARE("amdgpu/vega20_mec.bin");
-MODULE_FIRMWARE("amdgpu/vega20_mec2.bin");
-MODULE_FIRMWARE("amdgpu/vega20_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/raven_ce.bin");
-MODULE_FIRMWARE("amdgpu/raven_pfp.bin");
-MODULE_FIRMWARE("amdgpu/raven_me.bin");
-MODULE_FIRMWARE("amdgpu/raven_mec.bin");
-MODULE_FIRMWARE("amdgpu/raven_mec2.bin");
-MODULE_FIRMWARE("amdgpu/raven_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/picasso_ce.bin");
-MODULE_FIRMWARE("amdgpu/picasso_pfp.bin");
-MODULE_FIRMWARE("amdgpu/picasso_me.bin");
-MODULE_FIRMWARE("amdgpu/picasso_mec.bin");
-MODULE_FIRMWARE("amdgpu/picasso_mec2.bin");
-MODULE_FIRMWARE("amdgpu/picasso_rlc.bin");
-MODULE_FIRMWARE("amdgpu/picasso_rlc_am4.bin");
-
-MODULE_FIRMWARE("amdgpu/raven2_ce.bin");
-MODULE_FIRMWARE("amdgpu/raven2_pfp.bin");
-MODULE_FIRMWARE("amdgpu/raven2_me.bin");
-MODULE_FIRMWARE("amdgpu/raven2_mec.bin");
-MODULE_FIRMWARE("amdgpu/raven2_mec2.bin");
-MODULE_FIRMWARE("amdgpu/raven2_rlc.bin");
-MODULE_FIRMWARE("amdgpu/raven_kicker_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/arcturus_mec.bin");
-MODULE_FIRMWARE("amdgpu/arcturus_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/renoir_ce.bin");
-MODULE_FIRMWARE("amdgpu/renoir_pfp.bin");
-MODULE_FIRMWARE("amdgpu/renoir_me.bin");
-MODULE_FIRMWARE("amdgpu/renoir_mec.bin");
-MODULE_FIRMWARE("amdgpu/renoir_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/green_sardine_ce.bin");
-MODULE_FIRMWARE("amdgpu/green_sardine_pfp.bin");
-MODULE_FIRMWARE("amdgpu/green_sardine_me.bin");
-MODULE_FIRMWARE("amdgpu/green_sardine_mec.bin");
-MODULE_FIRMWARE("amdgpu/green_sardine_mec2.bin");
-MODULE_FIRMWARE("amdgpu/green_sardine_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/aldebaran_mec.bin");
-MODULE_FIRMWARE("amdgpu/aldebaran_mec2.bin");
-MODULE_FIRMWARE("amdgpu/aldebaran_rlc.bin");
-MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec.bin");
-MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec2.bin");
-
 #define mmTCP_CHAN_STEER_0_ARCT								0x0b03
 #define mmTCP_CHAN_STEER_0_ARCT_BASE_IDX							0
 #define mmTCP_CHAN_STEER_1_ARCT								0x0b04
@@ -1253,31 +1187,18 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev)
 static int gfx_v9_0_init_cp_gfx_microcode(struct amdgpu_device *adev,
 					  const char *chip_name)
 {
-	char fw_name[30];
 	int err;
 
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", chip_name);
-	err = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
 	err = amdgpu_ucode_validate(adev->gfx.pfp_fw);
 	if (err)
 		goto out;
 	amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_PFP);
 
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", chip_name);
-	err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
 	err = amdgpu_ucode_validate(adev->gfx.me_fw);
 	if (err)
 		goto out;
 	amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_ME);
 
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", chip_name);
-	err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
 	err = amdgpu_ucode_validate(adev->gfx.ce_fw);
 	if (err)
 		goto out;
@@ -1286,8 +1207,7 @@ static int gfx_v9_0_init_cp_gfx_microcode(struct amdgpu_device *adev,
 out:
 	if (err) {
 		dev_err(adev->dev,
-			"gfx9: Failed to init firmware \"%s\"\n",
-			fw_name);
+			"gfx9: Failed to init firmware\n");
 		release_firmware(adev->gfx.pfp_fw);
 		adev->gfx.pfp_fw = NULL;
 		release_firmware(adev->gfx.me_fw);
@@ -1301,36 +1221,11 @@ static int gfx_v9_0_init_cp_gfx_microcode(struct amdgpu_device *adev,
 static int gfx_v9_0_init_rlc_microcode(struct amdgpu_device *adev,
 					  const char *chip_name)
 {
-	char fw_name[30];
 	int err;
 	const struct rlc_firmware_header_v2_0 *rlc_hdr;
 	uint16_t version_major;
 	uint16_t version_minor;
-	uint32_t smu_version;
 
-	/*
-	 * For Picasso && AM4 SOCKET board, we use picasso_rlc_am4.bin
-	 * instead of picasso_rlc.bin.
-	 * Judgment method:
-	 * PCO AM4: revision >= 0xC8 && revision <= 0xCF
-	 *          or revision >= 0xD8 && revision <= 0xDF
-	 * otherwise is PCO FP5
-	 */
-	if (!strcmp(chip_name, "picasso") &&
-		(((adev->pdev->revision >= 0xC8) && (adev->pdev->revision <= 0xCF)) ||
-		((adev->pdev->revision >= 0xD8) && (adev->pdev->revision <= 0xDF))))
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc_am4.bin", chip_name);
-	else if (!strcmp(chip_name, "raven") && (amdgpu_pm_load_smu_firmware(adev, &smu_version) == 0) &&
-		(smu_version >= 0x41e2b))
-		/**
-		*SMC is loaded by SBIOS on APU and it's able to get the SMU version directly.
-		*/
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_kicker_rlc.bin", chip_name);
-	else
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name);
-	err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
 	err = amdgpu_ucode_validate(adev->gfx.rlc_fw);
 	if (err)
 		goto out;
@@ -1342,8 +1237,7 @@ static int gfx_v9_0_init_rlc_microcode(struct amdgpu_device *adev,
 out:
 	if (err) {
 		dev_err(adev->dev,
-			"gfx9: Failed to init firmware \"%s\"\n",
-			fw_name);
+			"gfx9: Failed to init firmware\n");
 		release_firmware(adev->gfx.rlc_fw);
 		adev->gfx.rlc_fw = NULL;
 	}
@@ -1363,17 +1257,8 @@ static bool gfx_v9_0_load_mec2_fw_bin_support(struct amdgpu_device *adev)
 static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev,
 					  const char *chip_name)
 {
-	char fw_name[30];
 	int err;
 
-	if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_ALDEBARAN))
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sjt_mec.bin", chip_name);
-	else
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name);
-
-	err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
 	err = amdgpu_ucode_validate(adev->gfx.mec_fw);
 	if (err)
 		goto out;
@@ -1381,22 +1266,11 @@ static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev,
 	amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1_JT);
 
 	if (gfx_v9_0_load_mec2_fw_bin_support(adev)) {
-		if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_ALDEBARAN))
-			snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sjt_mec2.bin", chip_name);
-		else
-			snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name);
-
-		err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev);
-		if (!err) {
-			err = amdgpu_ucode_validate(adev->gfx.mec2_fw);
-			if (err)
-				goto out;
-			amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2);
-			amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2_JT);
-		} else {
-			err = 0;
-			adev->gfx.mec2_fw = NULL;
-		}
+		err = amdgpu_ucode_validate(adev->gfx.mec2_fw);
+		if (err)
+			goto out;
+		amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2);
+		amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2_JT);
 	} else {
 		adev->gfx.mec2_fw_version = adev->gfx.mec_fw_version;
 		adev->gfx.mec2_feature_version = adev->gfx.mec_feature_version;
@@ -1407,8 +1281,7 @@ static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev,
 	gfx_v9_0_check_fw_write_wait(adev);
 	if (err) {
 		dev_err(adev->dev,
-			"gfx9: Failed to init firmware \"%s\"\n",
-			fw_name);
+			"gfx9: Failed to init firmware\n");
 		release_firmware(adev->gfx.mec_fw);
 		adev->gfx.mec_fw = NULL;
 		release_firmware(adev->gfx.mec2_fw);
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 09/11] drm/amd: Request GFX10 microcode during IP discovery
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
                   ` (7 preceding siblings ...)
  2022-12-28 16:30 ` [PATCH v2 08/11] drm/amd: Request GFX9 " Mario Limonciello
@ 2022-12-28 16:30 ` Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 10/11] drm/amd: Request GFX11 " Mario Limonciello
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Mario Limonciello @ 2022-12-28 16:30 UTC (permalink / raw)
  To: Javier Martinez Canillas, Alex Deucher, linux-kernel
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, Mario Limonciello, Pan, Xinhui

If GFX10 microcode is required but not available during early init, the
microcode framebuffer will have already been released and the screen will
freeze.

Move the request for GFX10 microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 137 +++++++++++++
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c        | 180 +-----------------
 2 files changed, 144 insertions(+), 173 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 0da16abd6b24..d31559600cae 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -220,6 +220,102 @@ MODULE_FIRMWARE("amdgpu/green_sardine_mec.bin");
 MODULE_FIRMWARE("amdgpu/green_sardine_mec2.bin");
 MODULE_FIRMWARE("amdgpu/green_sardine_rlc.bin");
 
+/* gfx10 */
+MODULE_FIRMWARE("amdgpu/aldebaran_mec.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_mec2.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_rlc.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec2.bin");
+
+MODULE_FIRMWARE("amdgpu/navi10_ce.bin");
+MODULE_FIRMWARE("amdgpu/navi10_pfp.bin");
+MODULE_FIRMWARE("amdgpu/navi10_me.bin");
+MODULE_FIRMWARE("amdgpu/navi10_mec.bin");
+MODULE_FIRMWARE("amdgpu/navi10_mec2.bin");
+MODULE_FIRMWARE("amdgpu/navi10_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/navi14_ce_wks.bin");
+MODULE_FIRMWARE("amdgpu/navi14_pfp_wks.bin");
+MODULE_FIRMWARE("amdgpu/navi14_me_wks.bin");
+MODULE_FIRMWARE("amdgpu/navi14_mec_wks.bin");
+MODULE_FIRMWARE("amdgpu/navi14_mec2_wks.bin");
+MODULE_FIRMWARE("amdgpu/navi14_ce.bin");
+MODULE_FIRMWARE("amdgpu/navi14_pfp.bin");
+MODULE_FIRMWARE("amdgpu/navi14_me.bin");
+MODULE_FIRMWARE("amdgpu/navi14_mec.bin");
+MODULE_FIRMWARE("amdgpu/navi14_mec2.bin");
+MODULE_FIRMWARE("amdgpu/navi14_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/navi12_ce.bin");
+MODULE_FIRMWARE("amdgpu/navi12_pfp.bin");
+MODULE_FIRMWARE("amdgpu/navi12_me.bin");
+MODULE_FIRMWARE("amdgpu/navi12_mec.bin");
+MODULE_FIRMWARE("amdgpu/navi12_mec2.bin");
+MODULE_FIRMWARE("amdgpu/navi12_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_ce.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_pfp.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_me.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_mec.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_mec2.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/navy_flounder_ce.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_pfp.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_me.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_mec.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_mec2.bin");
+MODULE_FIRMWARE("amdgpu/navy_flounder_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/vangogh_ce.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_pfp.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_me.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_mec.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_mec2.bin");
+MODULE_FIRMWARE("amdgpu/vangogh_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_ce.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_pfp.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_me.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_mec.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_mec2.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/beige_goby_ce.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_pfp.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_me.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_mec.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_mec2.bin");
+MODULE_FIRMWARE("amdgpu/beige_goby_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/yellow_carp_ce.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_pfp.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_me.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_mec.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_mec2.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_ce.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_pfp.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_me.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_mec.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_mec2.bin");
+MODULE_FIRMWARE("amdgpu/cyan_skillfish2_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_ce.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_mec2.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_ce.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec2.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_rlc.bin");
+
 static const char *hw_id_names[HW_ID_MAX] = {
 	[MP1_HWID]		= "MP1",
 	[MP2_HWID]		= "MP2",
@@ -1981,6 +2077,44 @@ static int amdgpu_discovery_load_gfx9(struct amdgpu_device *adev, char *ucode_pr
 	return 0;
 }
 
+static int amdgpu_discovery_load_gfx10(struct amdgpu_device *adev, char *ucode_prefix)
+{
+	char fw_name[40];
+	char *wks = "";
+	int r;
+
+	if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 1) &&
+		!(adev->pdev->device == 0x7340 &&
+			adev->pdev->revision != 0x00))
+		wks = "_wks";
+	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp%s.bin", ucode_prefix, wks);
+	r = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev);
+	if (r)
+		return r;
+	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me%s.bin", ucode_prefix, wks);
+	r = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev);
+	if (r)
+		return r;
+	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce%s.bin", ucode_prefix, wks);
+	r = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev);
+	if (r)
+		return r;
+	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", ucode_prefix);
+	r = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
+	if (r)
+		return r;
+	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec%s.bin", ucode_prefix, wks);
+	r = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
+	if (r)
+		return r;
+	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2%s.bin", ucode_prefix, wks);
+	r = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev);
+	if (r)
+		return r;
+
+	return 0;
+}
+
 static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
 {
 	char ucode_prefix[30];
@@ -2015,6 +2149,9 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
 	case IP_VERSION(10, 3, 6):
 	case IP_VERSION(10, 3, 3):
 	case IP_VERSION(10, 3, 7):
+		r = amdgpu_discovery_load_gfx10(adev, ucode_prefix);
+		if (r)
+			return r;
 		amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
 		break;
 	case IP_VERSION(11, 0, 0):
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index 49d34c7bbf20..319548b81454 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -182,95 +182,6 @@
 #define mmRLC_SPARE_INT_0_Sienna_Cichlid               0x4ca5
 #define mmRLC_SPARE_INT_0_Sienna_Cichlid_BASE_IDX      1
 
-MODULE_FIRMWARE("amdgpu/navi10_ce.bin");
-MODULE_FIRMWARE("amdgpu/navi10_pfp.bin");
-MODULE_FIRMWARE("amdgpu/navi10_me.bin");
-MODULE_FIRMWARE("amdgpu/navi10_mec.bin");
-MODULE_FIRMWARE("amdgpu/navi10_mec2.bin");
-MODULE_FIRMWARE("amdgpu/navi10_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/navi14_ce_wks.bin");
-MODULE_FIRMWARE("amdgpu/navi14_pfp_wks.bin");
-MODULE_FIRMWARE("amdgpu/navi14_me_wks.bin");
-MODULE_FIRMWARE("amdgpu/navi14_mec_wks.bin");
-MODULE_FIRMWARE("amdgpu/navi14_mec2_wks.bin");
-MODULE_FIRMWARE("amdgpu/navi14_ce.bin");
-MODULE_FIRMWARE("amdgpu/navi14_pfp.bin");
-MODULE_FIRMWARE("amdgpu/navi14_me.bin");
-MODULE_FIRMWARE("amdgpu/navi14_mec.bin");
-MODULE_FIRMWARE("amdgpu/navi14_mec2.bin");
-MODULE_FIRMWARE("amdgpu/navi14_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/navi12_ce.bin");
-MODULE_FIRMWARE("amdgpu/navi12_pfp.bin");
-MODULE_FIRMWARE("amdgpu/navi12_me.bin");
-MODULE_FIRMWARE("amdgpu/navi12_mec.bin");
-MODULE_FIRMWARE("amdgpu/navi12_mec2.bin");
-MODULE_FIRMWARE("amdgpu/navi12_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/sienna_cichlid_ce.bin");
-MODULE_FIRMWARE("amdgpu/sienna_cichlid_pfp.bin");
-MODULE_FIRMWARE("amdgpu/sienna_cichlid_me.bin");
-MODULE_FIRMWARE("amdgpu/sienna_cichlid_mec.bin");
-MODULE_FIRMWARE("amdgpu/sienna_cichlid_mec2.bin");
-MODULE_FIRMWARE("amdgpu/sienna_cichlid_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/navy_flounder_ce.bin");
-MODULE_FIRMWARE("amdgpu/navy_flounder_pfp.bin");
-MODULE_FIRMWARE("amdgpu/navy_flounder_me.bin");
-MODULE_FIRMWARE("amdgpu/navy_flounder_mec.bin");
-MODULE_FIRMWARE("amdgpu/navy_flounder_mec2.bin");
-MODULE_FIRMWARE("amdgpu/navy_flounder_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/vangogh_ce.bin");
-MODULE_FIRMWARE("amdgpu/vangogh_pfp.bin");
-MODULE_FIRMWARE("amdgpu/vangogh_me.bin");
-MODULE_FIRMWARE("amdgpu/vangogh_mec.bin");
-MODULE_FIRMWARE("amdgpu/vangogh_mec2.bin");
-MODULE_FIRMWARE("amdgpu/vangogh_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_ce.bin");
-MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_pfp.bin");
-MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_me.bin");
-MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_mec.bin");
-MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_mec2.bin");
-MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/beige_goby_ce.bin");
-MODULE_FIRMWARE("amdgpu/beige_goby_pfp.bin");
-MODULE_FIRMWARE("amdgpu/beige_goby_me.bin");
-MODULE_FIRMWARE("amdgpu/beige_goby_mec.bin");
-MODULE_FIRMWARE("amdgpu/beige_goby_mec2.bin");
-MODULE_FIRMWARE("amdgpu/beige_goby_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/yellow_carp_ce.bin");
-MODULE_FIRMWARE("amdgpu/yellow_carp_pfp.bin");
-MODULE_FIRMWARE("amdgpu/yellow_carp_me.bin");
-MODULE_FIRMWARE("amdgpu/yellow_carp_mec.bin");
-MODULE_FIRMWARE("amdgpu/yellow_carp_mec2.bin");
-MODULE_FIRMWARE("amdgpu/yellow_carp_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/cyan_skillfish2_ce.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish2_pfp.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish2_me.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish2_mec.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish2_mec2.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish2_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/gc_10_3_6_ce.bin");
-MODULE_FIRMWARE("amdgpu/gc_10_3_6_pfp.bin");
-MODULE_FIRMWARE("amdgpu/gc_10_3_6_me.bin");
-MODULE_FIRMWARE("amdgpu/gc_10_3_6_mec.bin");
-MODULE_FIRMWARE("amdgpu/gc_10_3_6_mec2.bin");
-MODULE_FIRMWARE("amdgpu/gc_10_3_6_rlc.bin");
-
-MODULE_FIRMWARE("amdgpu/gc_10_3_7_ce.bin");
-MODULE_FIRMWARE("amdgpu/gc_10_3_7_pfp.bin");
-MODULE_FIRMWARE("amdgpu/gc_10_3_7_me.bin");
-MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec.bin");
-MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec2.bin");
-MODULE_FIRMWARE("amdgpu/gc_10_3_7_rlc.bin");
-
 static const struct soc15_reg_golden golden_settings_gc_10_1[] =
 {
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014),
@@ -3974,9 +3885,6 @@ static void gfx_v10_0_check_gfxoff_flag(struct amdgpu_device *adev)
 
 static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
 {
-	const char *chip_name;
-	char fw_name[40];
-	char *wks = "";
 	int err;
 	const struct rlc_firmware_header_v2_0 *rlc_hdr;
 	uint16_t version_major;
@@ -3984,91 +3892,29 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
 
 	DRM_DEBUG("\n");
 
-	switch (adev->ip_versions[GC_HWIP][0]) {
-	case IP_VERSION(10, 1, 10):
-		chip_name = "navi10";
-		break;
-	case IP_VERSION(10, 1, 1):
-		chip_name = "navi14";
-		if (!(adev->pdev->device == 0x7340 &&
-		      adev->pdev->revision != 0x00))
-			wks = "_wks";
-		break;
-	case IP_VERSION(10, 1, 2):
-		chip_name = "navi12";
-		break;
-	case IP_VERSION(10, 3, 0):
-		chip_name = "sienna_cichlid";
-		break;
-	case IP_VERSION(10, 3, 2):
-		chip_name = "navy_flounder";
-		break;
-	case IP_VERSION(10, 3, 1):
-		chip_name = "vangogh";
-		break;
-	case IP_VERSION(10, 3, 4):
-		chip_name = "dimgrey_cavefish";
-		break;
-	case IP_VERSION(10, 3, 5):
-		chip_name = "beige_goby";
-		break;
-	case IP_VERSION(10, 3, 3):
-		chip_name = "yellow_carp";
-		break;
-	case IP_VERSION(10, 3, 6):
-		chip_name = "gc_10_3_6";
-		break;
-	case IP_VERSION(10, 1, 3):
-	case IP_VERSION(10, 1, 4):
-		chip_name = "cyan_skillfish2";
-		break;
-	case IP_VERSION(10, 3, 7):
-		chip_name = "gc_10_3_7";
-		break;
-	default:
-		BUG();
-	}
-
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp%s.bin", chip_name, wks);
-	err = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
 	err = amdgpu_ucode_validate(adev->gfx.pfp_fw);
 	if (err)
 		goto out;
 	amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_PFP);
 
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me%s.bin", chip_name, wks);
-	err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
 	err = amdgpu_ucode_validate(adev->gfx.me_fw);
 	if (err)
 		goto out;
 	amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_ME);
 
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce%s.bin", chip_name, wks);
-	err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
 	err = amdgpu_ucode_validate(adev->gfx.ce_fw);
 	if (err)
 		goto out;
 	amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_CE);
 
 	if (!amdgpu_sriov_vf(adev)) {
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name);
-		err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
-		if (err)
-			goto out;
 		/* don't check this.  There are apparently firmwares in the wild with
 		 * incorrect size in the header
 		 */
 		err = amdgpu_ucode_validate(adev->gfx.rlc_fw);
 		if (err)
 			dev_dbg(adev->dev,
-				"gfx10: amdgpu_ucode_validate() failed \"%s\"\n",
-				fw_name);
+				"gfx10: amdgpu_ucode_validate() failed\n");
 		rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
 		version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
 		version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
@@ -4077,35 +3923,23 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
 			goto out;
 	}
 
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec%s.bin", chip_name, wks);
-	err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
 	err = amdgpu_ucode_validate(adev->gfx.mec_fw);
 	if (err)
 		goto out;
 	amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1);
 	amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1_JT);
 
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2%s.bin", chip_name, wks);
-	err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev);
-	if (!err) {
-		err = amdgpu_ucode_validate(adev->gfx.mec2_fw);
-		if (err)
-			goto out;
-		amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2);
-		amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2_JT);
-	} else {
-		err = 0;
-		adev->gfx.mec2_fw = NULL;
-	}
+	err = amdgpu_ucode_validate(adev->gfx.mec2_fw);
+	if (err)
+		goto out;
+	amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2);
+	amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2_JT);
 
 	gfx_v10_0_check_fw_write_wait(adev);
 out:
 	if (err) {
 		dev_err(adev->dev,
-			"gfx10: Failed to init firmware \"%s\"\n",
-			fw_name);
+			"gfx10: Failed to init firmware\n");
 		release_firmware(adev->gfx.pfp_fw);
 		adev->gfx.pfp_fw = NULL;
 		release_firmware(adev->gfx.me_fw);
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 10/11] drm/amd: Request GFX11 microcode during IP discovery
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
                   ` (8 preceding siblings ...)
  2022-12-28 16:30 ` [PATCH v2 09/11] drm/amd: Request GFX10 " Mario Limonciello
@ 2022-12-28 16:30 ` Mario Limonciello
  2022-12-28 16:30 ` [PATCH v2 11/11] drm/amd: Request PSP " Mario Limonciello
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Mario Limonciello @ 2022-12-28 16:30 UTC (permalink / raw)
  To: Javier Martinez Canillas, Alex Deucher, linux-kernel
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, Mario Limonciello, Pan, Xinhui

If GFX11 microcode is required but not available during early init, the
microcode framebuffer will have already been released and the screen will
freeze.

Move the request for GFX11 microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 52 +++++++++++++++
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 64 +------------------
 2 files changed, 53 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index d31559600cae..c8c538a768fe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -316,6 +316,29 @@ MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec.bin");
 MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec2.bin");
 MODULE_FIRMWARE("amdgpu/gc_10_3_7_rlc.bin");
 
+/* gfx11 */
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_rlc.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_0_toc.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_1_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_1_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_1_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_1_rlc.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_2_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_2_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_2_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_2_rlc.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_3_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_3_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_3_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_3_rlc.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_4_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_4_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_4_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_11_0_4_rlc.bin");
+
 static const char *hw_id_names[HW_ID_MAX] = {
 	[MP1_HWID]		= "MP1",
 	[MP2_HWID]		= "MP2",
@@ -2111,6 +2134,32 @@ static int amdgpu_discovery_load_gfx10(struct amdgpu_device *adev, char *ucode_p
 	r = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev);
 	if (r)
 		return r;
+	return 0;
+}
+
+static int amdgpu_discovery_load_gfx11(struct amdgpu_device *adev, char *ucode_prefix)
+{
+	char fw_name[40];
+	int r;
+
+	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", ucode_prefix);
+	r = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev);
+	if (r)
+		return r;
+	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", ucode_prefix);
+	r = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev);
+	if (r)
+		return r;
+	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", ucode_prefix);
+	r = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
+	if (r)
+		return r;
+	if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) {
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_toc.bin", ucode_prefix);
+		r = request_firmware(&adev->psp.toc_fw, fw_name, adev->dev);
+		if (r)
+			return r;
+	}
 
 	return 0;
 }
@@ -2159,6 +2208,9 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
 	case IP_VERSION(11, 0, 2):
 	case IP_VERSION(11, 0, 3):
 	case IP_VERSION(11, 0, 4):
+		r = amdgpu_discovery_load_gfx11(adev, ucode_prefix);
+		if (r)
+			return r;
 		amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block);
 		break;
 	default:
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index a56c6e106d00..576fa591c6da 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -60,27 +60,6 @@
 #define regRLC_RLCS_BOOTLOAD_STATUS_gc_11_0_1	0x4e7e
 #define regRLC_RLCS_BOOTLOAD_STATUS_gc_11_0_1_BASE_IDX	1
 
-MODULE_FIRMWARE("amdgpu/gc_11_0_0_pfp.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_0_me.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_0_mec.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_0_rlc.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_0_toc.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_1_pfp.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_1_me.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_1_mec.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_1_rlc.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_2_pfp.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_2_me.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_2_mec.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_2_rlc.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_3_pfp.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_3_me.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_3_mec.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_3_rlc.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_4_pfp.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_4_me.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_4_mec.bin");
-MODULE_FIRMWARE("amdgpu/gc_11_0_4_rlc.bin");
 
 static const struct soc15_reg_golden golden_settings_gc_11_0_1[] =
 {
@@ -445,8 +424,6 @@ static void gfx_v11_0_free_microcode(struct amdgpu_device *adev)
 
 static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)
 {
-	char fw_name[40];
-	char ucode_prefix[30];
 	int err;
 	const struct rlc_firmware_header_v2_0 *rlc_hdr;
 	uint16_t version_major;
@@ -454,12 +431,6 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)
 
 	DRM_DEBUG("\n");
 
-	amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix));
-
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", ucode_prefix);
-	err = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
 	err = amdgpu_ucode_validate(adev->gfx.pfp_fw);
 	if (err)
 		goto out;
@@ -476,10 +447,6 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)
 		amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_PFP);
 	}
 
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", ucode_prefix);
-	err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
 	err = amdgpu_ucode_validate(adev->gfx.me_fw);
 	if (err)
 		goto out;
@@ -492,10 +459,6 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)
 	}
 
 	if (!amdgpu_sriov_vf(adev)) {
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", ucode_prefix);
-		err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
-		if (err)
-			goto out;
 		err = amdgpu_ucode_validate(adev->gfx.rlc_fw);
 		if (err)
 			goto out;
@@ -507,10 +470,6 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)
 			goto out;
 	}
 
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", ucode_prefix);
-	err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
 	err = amdgpu_ucode_validate(adev->gfx.mec_fw);
 	if (err)
 		goto out;
@@ -530,9 +489,7 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)
 
 out:
 	if (err) {
-		dev_err(adev->dev,
-			"gfx11: Failed to init firmware \"%s\"\n",
-			fw_name);
+		dev_err(adev->dev, "gfx11: Failed to init firmware\n");
 		release_firmware(adev->gfx.pfp_fw);
 		adev->gfx.pfp_fw = NULL;
 		release_firmware(adev->gfx.me_fw);
@@ -549,20 +506,6 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)
 static int gfx_v11_0_init_toc_microcode(struct amdgpu_device *adev)
 {
 	const struct psp_firmware_header_v1_0 *toc_hdr;
-	int err = 0;
-	char fw_name[40];
-	char ucode_prefix[30];
-
-	amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix));
-
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_toc.bin", ucode_prefix);
-	err = request_firmware(&adev->psp.toc_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
-
-	err = amdgpu_ucode_validate(adev->psp.toc_fw);
-	if (err)
-		goto out;
 
 	toc_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.toc_fw->data;
 	adev->psp.toc.fw_version = le32_to_cpu(toc_hdr->header.ucode_version);
@@ -571,11 +514,6 @@ static int gfx_v11_0_init_toc_microcode(struct amdgpu_device *adev)
 	adev->psp.toc.start_addr = (uint8_t *)toc_hdr +
 				le32_to_cpu(toc_hdr->header.ucode_array_offset_bytes);
 	return 0;
-out:
-	dev_err(adev->dev, "Failed to load TOC microcode\n");
-	release_firmware(adev->psp.toc_fw);
-	adev->psp.toc_fw = NULL;
-	return err;
 }
 
 static u32 gfx_v11_0_get_csb_size(struct amdgpu_device *adev)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 11/11] drm/amd: Request PSP microcode during IP discovery
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
                   ` (9 preceding siblings ...)
  2022-12-28 16:30 ` [PATCH v2 10/11] drm/amd: Request GFX11 " Mario Limonciello
@ 2022-12-28 16:30 ` Mario Limonciello
  2022-12-29 17:33   ` Alex Deucher
  2022-12-29 17:31 ` [PATCH v2 00/11] Recover from failure to probe GPU Alex Deucher
  2023-01-03 10:10 ` Lazar, Lijo
  12 siblings, 1 reply; 17+ messages in thread
From: Mario Limonciello @ 2022-12-28 16:30 UTC (permalink / raw)
  To: Javier Martinez Canillas, Alex Deucher, linux-kernel
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, Mario Limonciello, Pan, Xinhui

If PSP microcode is required but not available during early init, the
firmware framebuffer will have already been released and the screen will
freeze.

Move the request for PSP microcode into the IP discovery phase
so that if it's not available, IP discovery will fail.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 120 ++++++++++++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c       |   2 -
 drivers/gpu/drm/amd/amdgpu/psp_v10_0.c        | 106 +++--------
 drivers/gpu/drm/amd/amdgpu/psp_v11_0.c        | 165 ++++--------------
 drivers/gpu/drm/amd/amdgpu/psp_v12_0.c        | 102 +++--------
 drivers/gpu/drm/amd/amdgpu/psp_v13_0.c        |  82 ---------
 drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c      |  36 ----
 drivers/gpu/drm/amd/amdgpu/psp_v3_1.c         |  36 ----
 8 files changed, 202 insertions(+), 447 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index c8c538a768fe..6199ab078bc7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -158,6 +158,40 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
 MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
 MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
 
+MODULE_FIRMWARE("amdgpu/aldebaran_sos.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_ta.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_cap.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_asd.bin");
+MODULE_FIRMWARE("amdgpu/green_sardine_ta.bin");
+MODULE_FIRMWARE("amdgpu/raven_asd.bin");
+MODULE_FIRMWARE("amdgpu/picasso_asd.bin");
+MODULE_FIRMWARE("amdgpu/raven2_asd.bin");
+MODULE_FIRMWARE("amdgpu/picasso_ta.bin");
+MODULE_FIRMWARE("amdgpu/raven2_ta.bin");
+MODULE_FIRMWARE("amdgpu/raven_ta.bin");
+MODULE_FIRMWARE("amdgpu/renoir_asd.bin");
+MODULE_FIRMWARE("amdgpu/renoir_ta.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_toc.bin");
+MODULE_FIRMWARE("amdgpu/yellow_carp_ta.bin");
+MODULE_FIRMWARE("amdgpu/vega10_sos.bin");
+MODULE_FIRMWARE("amdgpu/vega10_asd.bin");
+MODULE_FIRMWARE("amdgpu/vega10_cap.bin");
+MODULE_FIRMWARE("amdgpu/vega12_sos.bin");
+MODULE_FIRMWARE("amdgpu/vega12_asd.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_5_toc.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_5_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_8_toc.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_8_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_0_sos.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_10_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_4_toc.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_4_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_11_toc.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_11_ta.bin");
 
 /* gfx9 */
 MODULE_FIRMWARE("amdgpu/vega10_ce.bin");
@@ -1858,12 +1892,30 @@ static int amdgpu_discovery_set_ih_ip_blocks(struct amdgpu_device *adev)
 
 static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
 {
+	char ucode_prefix[30];
+	int r;
+
+	amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
+	adev->psp.adev = adev;
+
 	switch (adev->ip_versions[MP0_HWIP][0]) {
 	case IP_VERSION(9, 0, 0):
+		r = psp_init_sos_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		r = psp_init_asd_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
 		amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block);
 		break;
 	case IP_VERSION(10, 0, 0):
 	case IP_VERSION(10, 0, 1):
+		r = psp_init_asd_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
 		amdgpu_device_ip_block_add(adev, &psp_v10_0_ip_block);
 		break;
 	case IP_VERSION(11, 0, 0):
@@ -1871,11 +1923,34 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
 	case IP_VERSION(11, 0, 4):
 	case IP_VERSION(11, 0, 5):
 	case IP_VERSION(11, 0, 9):
+		r = psp_init_sos_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		r = psp_init_asd_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		break;
 	case IP_VERSION(11, 0, 7):
 	case IP_VERSION(11, 0, 11):
 	case IP_VERSION(11, 0, 12):
 	case IP_VERSION(11, 0, 13):
+		r = psp_init_sos_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		break;
 	case IP_VERSION(11, 5, 0):
+		r = psp_init_asd_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		r = psp_init_toc_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
 		amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
 		break;
 	case IP_VERSION(11, 0, 8):
@@ -1883,20 +1958,57 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
 		break;
 	case IP_VERSION(11, 0, 3):
 	case IP_VERSION(12, 0, 1):
+		r = psp_init_asd_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
 		amdgpu_device_ip_block_add(adev, &psp_v12_0_ip_block);
 		break;
-	case IP_VERSION(13, 0, 0):
-	case IP_VERSION(13, 0, 1):
 	case IP_VERSION(13, 0, 2):
+		r = psp_init_sos_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		/* It's not necessary to load ras ta on Guest side */
+		if (!amdgpu_sriov_vf(adev)) {
+			r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
+			if (r)
+				return r;
+		}
+		amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
+		break;
+	case IP_VERSION(13, 0, 1):
 	case IP_VERSION(13, 0, 3):
 	case IP_VERSION(13, 0, 5):
-	case IP_VERSION(13, 0, 7):
 	case IP_VERSION(13, 0, 8):
-	case IP_VERSION(13, 0, 10):
 	case IP_VERSION(13, 0, 11):
+		r = psp_init_toc_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
+		break;
+	case IP_VERSION(13, 0, 0):
+	case IP_VERSION(13, 0, 7):
+	case IP_VERSION(13, 0, 10):
+		r = psp_init_sos_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
 		amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
 		break;
 	case IP_VERSION(13, 0, 4):
+		r = psp_init_toc_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
+		r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
+		if (r)
+			return r;
 		amdgpu_device_ip_block_add(adev, &psp_v13_0_4_ip_block);
 		break;
 	default:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 7a2fc920739b..f7103b3354c6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -188,8 +188,6 @@ static int psp_early_init(void *handle)
 		return -EINVAL;
 	}
 
-	psp->adev = adev;
-
 	psp_check_pmfw_centralized_cstate_management(psp);
 
 	return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
index 9de46fa8f46c..710445d39df1 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
@@ -37,93 +37,37 @@
 #include "gc/gc_9_1_offset.h"
 #include "sdma0/sdma0_4_1_offset.h"
 
-MODULE_FIRMWARE("amdgpu/raven_asd.bin");
-MODULE_FIRMWARE("amdgpu/picasso_asd.bin");
-MODULE_FIRMWARE("amdgpu/raven2_asd.bin");
-MODULE_FIRMWARE("amdgpu/picasso_ta.bin");
-MODULE_FIRMWARE("amdgpu/raven2_ta.bin");
-MODULE_FIRMWARE("amdgpu/raven_ta.bin");
-
 static int psp_v10_0_init_microcode(struct psp_context *psp)
 {
 	struct amdgpu_device *adev = psp->adev;
-	const char *chip_name;
-	char fw_name[30];
-	int err = 0;
 	const struct ta_firmware_header_v1_0 *ta_hdr;
-	DRM_DEBUG("\n");
-
-	switch (adev->asic_type) {
-	case CHIP_RAVEN:
-		if (adev->apu_flags & AMD_APU_IS_RAVEN2)
-			chip_name = "raven2";
-		else if (adev->apu_flags & AMD_APU_IS_PICASSO)
-			chip_name = "picasso";
-		else
-			chip_name = "raven";
-		break;
-	default: BUG();
-	}
-
-	err = psp_init_asd_microcode(psp, chip_name);
-	if (err)
-		goto out;
-
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
-	err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
-	if (err) {
-		release_firmware(adev->psp.ta_fw);
-		adev->psp.ta_fw = NULL;
-		dev_info(adev->dev,
-			 "psp v10.0: Failed to load firmware \"%s\"\n",
-			 fw_name);
-	} else {
-		err = amdgpu_ucode_validate(adev->psp.ta_fw);
-		if (err)
-			goto out2;
-
-		ta_hdr = (const struct ta_firmware_header_v1_0 *)
-				 adev->psp.ta_fw->data;
-		adev->psp.hdcp_context.context.bin_desc.fw_version =
-			le32_to_cpu(ta_hdr->hdcp.fw_version);
-		adev->psp.hdcp_context.context.bin_desc.size_bytes =
-			le32_to_cpu(ta_hdr->hdcp.size_bytes);
-		adev->psp.hdcp_context.context.bin_desc.start_addr =
-			(uint8_t *)ta_hdr +
-			le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
-
-		adev->psp.dtm_context.context.bin_desc.fw_version =
-			le32_to_cpu(ta_hdr->dtm.fw_version);
-		adev->psp.dtm_context.context.bin_desc.size_bytes =
-			le32_to_cpu(ta_hdr->dtm.size_bytes);
-		adev->psp.dtm_context.context.bin_desc.start_addr =
-			(uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
-			le32_to_cpu(ta_hdr->dtm.offset_bytes);
-
-		adev->psp.securedisplay_context.context.bin_desc.fw_version =
-			le32_to_cpu(ta_hdr->securedisplay.fw_version);
-		adev->psp.securedisplay_context.context.bin_desc.size_bytes =
-			le32_to_cpu(ta_hdr->securedisplay.size_bytes);
-		adev->psp.securedisplay_context.context.bin_desc.start_addr =
-			(uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
-			le32_to_cpu(ta_hdr->securedisplay.offset_bytes);
-
-		adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
-	}
 
-	return 0;
+	ta_hdr = (const struct ta_firmware_header_v1_0 *)
+			 adev->psp.ta_fw->data;
+	adev->psp.hdcp_context.context.bin_desc.fw_version =
+		le32_to_cpu(ta_hdr->hdcp.fw_version);
+	adev->psp.hdcp_context.context.bin_desc.size_bytes =
+		le32_to_cpu(ta_hdr->hdcp.size_bytes);
+	adev->psp.hdcp_context.context.bin_desc.start_addr =
+		(uint8_t *)ta_hdr +
+		le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
+	adev->psp.dtm_context.context.bin_desc.fw_version =
+		le32_to_cpu(ta_hdr->dtm.fw_version);
+	adev->psp.dtm_context.context.bin_desc.size_bytes =
+		le32_to_cpu(ta_hdr->dtm.size_bytes);
+	adev->psp.dtm_context.context.bin_desc.start_addr =
+		(uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
+		le32_to_cpu(ta_hdr->dtm.offset_bytes);
+	adev->psp.securedisplay_context.context.bin_desc.fw_version =
+		le32_to_cpu(ta_hdr->securedisplay.fw_version);
+	adev->psp.securedisplay_context.context.bin_desc.size_bytes =
+		le32_to_cpu(ta_hdr->securedisplay.size_bytes);
+	adev->psp.securedisplay_context.context.bin_desc.start_addr =
+		(uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
+		le32_to_cpu(ta_hdr->securedisplay.offset_bytes);
+	adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
 
-out2:
-	release_firmware(adev->psp.ta_fw);
-	adev->psp.ta_fw = NULL;
-out:
-	if (err) {
-		dev_err(adev->dev,
-			"psp v10.0: Failed to load firmware \"%s\"\n",
-			fw_name);
-	}
-
-	return err;
+	return 0;
 }
 
 static int psp_v10_0_ring_create(struct psp_context *psp,
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
index bd3e3e23a939..880fd90311e8 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
@@ -88,160 +88,63 @@ MODULE_FIRMWARE("amdgpu/beige_goby_ta.bin");
 static int psp_v11_0_init_microcode(struct psp_context *psp)
 {
 	struct amdgpu_device *adev = psp->adev;
-	const char *chip_name;
-	char fw_name[PSP_FW_NAME_LEN];
-	int err = 0;
 	const struct ta_firmware_header_v1_0 *ta_hdr;
 
 	DRM_DEBUG("\n");
 
-	switch (adev->ip_versions[MP0_HWIP][0]) {
-	case IP_VERSION(11, 0, 2):
-		chip_name = "vega20";
-		break;
-	case IP_VERSION(11, 0, 0):
-		chip_name = "navi10";
-		break;
-	case IP_VERSION(11, 0, 5):
-		chip_name = "navi14";
-		break;
-	case IP_VERSION(11, 0, 9):
-		chip_name = "navi12";
-		break;
-	case IP_VERSION(11, 0, 4):
-		chip_name = "arcturus";
-		break;
-	case IP_VERSION(11, 0, 7):
-		chip_name = "sienna_cichlid";
-		break;
-	case IP_VERSION(11, 0, 11):
-		chip_name = "navy_flounder";
-		break;
-	case IP_VERSION(11, 5, 0):
-		chip_name = "vangogh";
-		break;
-	case IP_VERSION(11, 0, 12):
-		chip_name = "dimgrey_cavefish";
-		break;
-	case IP_VERSION(11, 0, 13):
-		chip_name = "beige_goby";
-		break;
-	default:
-		BUG();
-	}
-
-
 	switch (adev->ip_versions[MP0_HWIP][0]) {
 	case IP_VERSION(11, 0, 2):
 	case IP_VERSION(11, 0, 4):
-		err = psp_init_sos_microcode(psp, chip_name);
-		if (err)
-			return err;
-		err = psp_init_asd_microcode(psp, chip_name);
-		if (err)
-			return err;
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
-		err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
-		if (err) {
-			release_firmware(adev->psp.ta_fw);
-			adev->psp.ta_fw = NULL;
-			dev_info(adev->dev,
-				 "psp v11.0: Failed to load firmware \"%s\"\n", fw_name);
-		} else {
-			err = amdgpu_ucode_validate(adev->psp.ta_fw);
-			if (err)
-				goto out2;
-
-			ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data;
-			adev->psp.xgmi_context.context.bin_desc.fw_version =
-				le32_to_cpu(ta_hdr->xgmi.fw_version);
-			adev->psp.xgmi_context.context.bin_desc.size_bytes =
-				le32_to_cpu(ta_hdr->xgmi.size_bytes);
-			adev->psp.xgmi_context.context.bin_desc.start_addr =
-				(uint8_t *)ta_hdr +
-				le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
-			adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
-			adev->psp.ras_context.context.bin_desc.fw_version =
-				le32_to_cpu(ta_hdr->ras.fw_version);
-			adev->psp.ras_context.context.bin_desc.size_bytes =
-				le32_to_cpu(ta_hdr->ras.size_bytes);
-			adev->psp.ras_context.context.bin_desc.start_addr =
-				(uint8_t *)adev->psp.xgmi_context.context.bin_desc.start_addr +
-				le32_to_cpu(ta_hdr->ras.offset_bytes);
-		}
+		ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data;
+		adev->psp.xgmi_context.context.bin_desc.fw_version =
+			le32_to_cpu(ta_hdr->xgmi.fw_version);
+		adev->psp.xgmi_context.context.bin_desc.size_bytes =
+			le32_to_cpu(ta_hdr->xgmi.size_bytes);
+		adev->psp.xgmi_context.context.bin_desc.start_addr =
+			(uint8_t *)ta_hdr +
+			le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
+		adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
+		adev->psp.ras_context.context.bin_desc.fw_version =
+			le32_to_cpu(ta_hdr->ras.fw_version);
+		adev->psp.ras_context.context.bin_desc.size_bytes =
+			le32_to_cpu(ta_hdr->ras.size_bytes);
+		adev->psp.ras_context.context.bin_desc.start_addr =
+			(uint8_t *)adev->psp.xgmi_context.context.bin_desc.start_addr +
+			le32_to_cpu(ta_hdr->ras.offset_bytes);
 		break;
 	case IP_VERSION(11, 0, 0):
 	case IP_VERSION(11, 0, 5):
 	case IP_VERSION(11, 0, 9):
-		err = psp_init_sos_microcode(psp, chip_name);
-		if (err)
-			return err;
-		err = psp_init_asd_microcode(psp, chip_name);
-		if (err)
-			return err;
-		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
-		err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
-		if (err) {
-			release_firmware(adev->psp.ta_fw);
-			adev->psp.ta_fw = NULL;
-			dev_info(adev->dev,
-				 "psp v11.0: Failed to load firmware \"%s\"\n", fw_name);
-		} else {
-			err = amdgpu_ucode_validate(adev->psp.ta_fw);
-			if (err)
-				goto out2;
-
-			ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data;
-			adev->psp.hdcp_context.context.bin_desc.fw_version =
-				le32_to_cpu(ta_hdr->hdcp.fw_version);
-			adev->psp.hdcp_context.context.bin_desc.size_bytes =
-				le32_to_cpu(ta_hdr->hdcp.size_bytes);
-			adev->psp.hdcp_context.context.bin_desc.start_addr =
-				(uint8_t *)ta_hdr +
-				le32_to_cpu(
-					ta_hdr->header.ucode_array_offset_bytes);
-
-			adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
-
-			adev->psp.dtm_context.context.bin_desc.fw_version =
-				le32_to_cpu(ta_hdr->dtm.fw_version);
-			adev->psp.dtm_context.context.bin_desc.size_bytes =
-				le32_to_cpu(ta_hdr->dtm.size_bytes);
-			adev->psp.dtm_context.context.bin_desc.start_addr =
-				(uint8_t *)adev->psp.hdcp_context.context
-					.bin_desc.start_addr +
-				le32_to_cpu(ta_hdr->dtm.offset_bytes);
-		}
+		ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data;
+		adev->psp.hdcp_context.context.bin_desc.fw_version =
+			le32_to_cpu(ta_hdr->hdcp.fw_version);
+		adev->psp.hdcp_context.context.bin_desc.size_bytes =
+			le32_to_cpu(ta_hdr->hdcp.size_bytes);
+		adev->psp.hdcp_context.context.bin_desc.start_addr =
+			(uint8_t *)ta_hdr +
+			le32_to_cpu(
+				ta_hdr->header.ucode_array_offset_bytes);
+		adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
+		adev->psp.dtm_context.context.bin_desc.fw_version =
+			le32_to_cpu(ta_hdr->dtm.fw_version);
+		adev->psp.dtm_context.context.bin_desc.size_bytes =
+			le32_to_cpu(ta_hdr->dtm.size_bytes);
+		adev->psp.dtm_context.context.bin_desc.start_addr =
+			(uint8_t *)adev->psp.hdcp_context.context
+				.bin_desc.start_addr +
+			le32_to_cpu(ta_hdr->dtm.offset_bytes);
 		break;
 	case IP_VERSION(11, 0, 7):
 	case IP_VERSION(11, 0, 11):
 	case IP_VERSION(11, 0, 12):
 	case IP_VERSION(11, 0, 13):
-		err = psp_init_sos_microcode(psp, chip_name);
-		if (err)
-			return err;
-		err = psp_init_ta_microcode(psp, chip_name);
-		if (err)
-			return err;
-		break;
 	case IP_VERSION(11, 5, 0):
-		err = psp_init_asd_microcode(psp, chip_name);
-		if (err)
-			return err;
-		err = psp_init_toc_microcode(psp, chip_name);
-		if (err)
-			return err;
 		break;
 	default:
 		BUG();
 	}
 
 	return 0;
-
-out2:
-	release_firmware(adev->psp.ta_fw);
-	adev->psp.ta_fw = NULL;
-	return err;
 }
 
 static int psp_v11_0_wait_for_bootloader(struct psp_context *psp)
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c
index 8ed2281b6557..0b5d63735f39 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c
@@ -37,94 +37,46 @@
 #include "oss/osssys_4_0_offset.h"
 #include "oss/osssys_4_0_sh_mask.h"
 
-MODULE_FIRMWARE("amdgpu/renoir_asd.bin");
-MODULE_FIRMWARE("amdgpu/renoir_ta.bin");
-MODULE_FIRMWARE("amdgpu/green_sardine_asd.bin");
-MODULE_FIRMWARE("amdgpu/green_sardine_ta.bin");
-
 /* address block */
 #define smnMP1_FIRMWARE_FLAGS		0x3010024
 
 static int psp_v12_0_init_microcode(struct psp_context *psp)
 {
 	struct amdgpu_device *adev = psp->adev;
-	const char *chip_name;
-	char fw_name[30];
-	int err = 0;
 	const struct ta_firmware_header_v1_0 *ta_hdr;
 	DRM_DEBUG("\n");
 
-	switch (adev->asic_type) {
-	case CHIP_RENOIR:
-		if (adev->apu_flags & AMD_APU_IS_RENOIR)
-			chip_name = "renoir";
-		else
-			chip_name = "green_sardine";
-		break;
-	default:
-		BUG();
-	}
-
-	err = psp_init_asd_microcode(psp, chip_name);
-	if (err)
-		return err;
-
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
-	err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
-	if (err) {
-		release_firmware(adev->psp.ta_fw);
-		adev->psp.ta_fw = NULL;
-		dev_info(adev->dev,
-			 "psp v12.0: Failed to load firmware \"%s\"\n",
-			 fw_name);
-	} else {
-		err = amdgpu_ucode_validate(adev->psp.ta_fw);
-		if (err)
-			goto out;
-
-		ta_hdr = (const struct ta_firmware_header_v1_0 *)
-				 adev->psp.ta_fw->data;
-		adev->psp.hdcp_context.context.bin_desc.fw_version =
-			le32_to_cpu(ta_hdr->hdcp.fw_version);
-		adev->psp.hdcp_context.context.bin_desc.size_bytes =
-			le32_to_cpu(ta_hdr->hdcp.size_bytes);
-		adev->psp.hdcp_context.context.bin_desc.start_addr =
-			(uint8_t *)ta_hdr +
-			le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
-
-		adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
-
-		adev->psp.dtm_context.context.bin_desc.fw_version =
-			le32_to_cpu(ta_hdr->dtm.fw_version);
-		adev->psp.dtm_context.context.bin_desc.size_bytes =
-			le32_to_cpu(ta_hdr->dtm.size_bytes);
-		adev->psp.dtm_context.context.bin_desc.start_addr =
+	ta_hdr = (const struct ta_firmware_header_v1_0 *)
+				adev->psp.ta_fw->data;
+	adev->psp.hdcp_context.context.bin_desc.fw_version =
+		le32_to_cpu(ta_hdr->hdcp.fw_version);
+	adev->psp.hdcp_context.context.bin_desc.size_bytes =
+		le32_to_cpu(ta_hdr->hdcp.size_bytes);
+	adev->psp.hdcp_context.context.bin_desc.start_addr =
+		(uint8_t *)ta_hdr +
+		le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
+
+	adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
+
+	adev->psp.dtm_context.context.bin_desc.fw_version =
+		le32_to_cpu(ta_hdr->dtm.fw_version);
+	adev->psp.dtm_context.context.bin_desc.size_bytes =
+		le32_to_cpu(ta_hdr->dtm.size_bytes);
+	adev->psp.dtm_context.context.bin_desc.start_addr =
+		(uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
+		le32_to_cpu(ta_hdr->dtm.offset_bytes);
+
+	if (adev->apu_flags & AMD_APU_IS_RENOIR) {
+		adev->psp.securedisplay_context.context.bin_desc.fw_version =
+			le32_to_cpu(ta_hdr->securedisplay.fw_version);
+		adev->psp.securedisplay_context.context.bin_desc.size_bytes =
+			le32_to_cpu(ta_hdr->securedisplay.size_bytes);
+		adev->psp.securedisplay_context.context.bin_desc.start_addr =
 			(uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
-			le32_to_cpu(ta_hdr->dtm.offset_bytes);
-
-		if (adev->apu_flags & AMD_APU_IS_RENOIR) {
-			adev->psp.securedisplay_context.context.bin_desc.fw_version =
-				le32_to_cpu(ta_hdr->securedisplay.fw_version);
-			adev->psp.securedisplay_context.context.bin_desc.size_bytes =
-				le32_to_cpu(ta_hdr->securedisplay.size_bytes);
-			adev->psp.securedisplay_context.context.bin_desc.start_addr =
-				(uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
-				le32_to_cpu(ta_hdr->securedisplay.offset_bytes);
-		}
+			le32_to_cpu(ta_hdr->securedisplay.offset_bytes);
 	}
 
 	return 0;
-
-out:
-	release_firmware(adev->psp.ta_fw);
-	adev->psp.ta_fw = NULL;
-	if (err) {
-		dev_err(adev->dev,
-			"psp v12.0: Failed to load firmware \"%s\"\n",
-			fw_name);
-	}
-
-	return err;
 }
 
 static int psp_v12_0_bootloader_load_sysdrv(struct psp_context *psp)
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
index e6a26a7e5e5e..2228994ef096 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
@@ -31,24 +31,6 @@
 #include "mp/mp_13_0_2_offset.h"
 #include "mp/mp_13_0_2_sh_mask.h"
 
-MODULE_FIRMWARE("amdgpu/aldebaran_sos.bin");
-MODULE_FIRMWARE("amdgpu/aldebaran_ta.bin");
-MODULE_FIRMWARE("amdgpu/aldebaran_cap.bin");
-MODULE_FIRMWARE("amdgpu/yellow_carp_toc.bin");
-MODULE_FIRMWARE("amdgpu/yellow_carp_ta.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_5_toc.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_5_ta.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_8_toc.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_8_ta.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_0_sos.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_10_ta.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_11_toc.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_11_ta.bin");
-
 /* For large FW files the time to complete can be very long */
 #define USBC_PD_POLLING_LIMIT_S 240
 
@@ -67,69 +49,6 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_11_ta.bin");
 /* memory training timeout define */
 #define MEM_TRAIN_SEND_MSG_TIMEOUT_US	3000000
 
-static int psp_v13_0_init_microcode(struct psp_context *psp)
-{
-	struct amdgpu_device *adev = psp->adev;
-	const char *chip_name;
-	char ucode_prefix[30];
-	int err = 0;
-
-	switch (adev->ip_versions[MP0_HWIP][0]) {
-	case IP_VERSION(13, 0, 2):
-		chip_name = "aldebaran";
-		break;
-	case IP_VERSION(13, 0, 1):
-	case IP_VERSION(13, 0, 3):
-		chip_name = "yellow_carp";
-		break;
-	default:
-		amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
-		chip_name = ucode_prefix;
-		break;
-	}
-
-	switch (adev->ip_versions[MP0_HWIP][0]) {
-	case IP_VERSION(13, 0, 2):
-		err = psp_init_sos_microcode(psp, chip_name);
-		if (err)
-			return err;
-		/* It's not necessary to load ras ta on Guest side */
-		if (!amdgpu_sriov_vf(adev)) {
-			err = psp_init_ta_microcode(&adev->psp, chip_name);
-			if (err)
-				return err;
-		}
-		break;
-	case IP_VERSION(13, 0, 1):
-	case IP_VERSION(13, 0, 3):
-	case IP_VERSION(13, 0, 5):
-	case IP_VERSION(13, 0, 8):
-	case IP_VERSION(13, 0, 11):
-		err = psp_init_toc_microcode(psp, chip_name);
-		if (err)
-			return err;
-		err = psp_init_ta_microcode(psp, chip_name);
-		if (err)
-			return err;
-		break;
-	case IP_VERSION(13, 0, 0):
-	case IP_VERSION(13, 0, 7):
-	case IP_VERSION(13, 0, 10):
-		err = psp_init_sos_microcode(psp, chip_name);
-		if (err)
-			return err;
-		/* It's not necessary to load ras ta on Guest side */
-		err = psp_init_ta_microcode(psp, chip_name);
-		if (err)
-			return err;
-		break;
-	default:
-		BUG();
-	}
-
-	return 0;
-}
-
 static bool psp_v13_0_is_sos_alive(struct psp_context *psp)
 {
 	struct amdgpu_device *adev = psp->adev;
@@ -697,7 +616,6 @@ static int psp_v13_0_vbflash_status(struct psp_context *psp)
 }
 
 static const struct psp_funcs psp_v13_0_funcs = {
-	.init_microcode = psp_v13_0_init_microcode,
 	.bootloader_load_kdb = psp_v13_0_bootloader_load_kdb,
 	.bootloader_load_spl = psp_v13_0_bootloader_load_spl,
 	.bootloader_load_sysdrv = psp_v13_0_bootloader_load_sysdrv,
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c
index 9d4e24e518e8..9e34c7ee9304 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c
@@ -29,41 +29,6 @@
 #include "mp/mp_13_0_4_offset.h"
 #include "mp/mp_13_0_4_sh_mask.h"
 
-MODULE_FIRMWARE("amdgpu/psp_13_0_4_toc.bin");
-MODULE_FIRMWARE("amdgpu/psp_13_0_4_ta.bin");
-
-static int psp_v13_0_4_init_microcode(struct psp_context *psp)
-{
-	struct amdgpu_device *adev = psp->adev;
-	const char *chip_name;
-	char ucode_prefix[30];
-	int err = 0;
-
-	switch (adev->ip_versions[MP0_HWIP][0]) {
-	case IP_VERSION(13, 0, 4):
-		amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
-		chip_name = ucode_prefix;
-		break;
-	default:
-		BUG();
-	}
-
-	switch (adev->ip_versions[MP0_HWIP][0]) {
-	case IP_VERSION(13, 0, 4):
-		err = psp_init_toc_microcode(psp, chip_name);
-		if (err)
-			return err;
-		err = psp_init_ta_microcode(psp, chip_name);
-		if (err)
-			return err;
-		break;
-	default:
-		BUG();
-	}
-
-	return 0;
-}
-
 static bool psp_v13_0_4_is_sos_alive(struct psp_context *psp)
 {
 	struct amdgpu_device *adev = psp->adev;
@@ -339,7 +304,6 @@ static void psp_v13_0_4_ring_set_wptr(struct psp_context *psp, uint32_t value)
 }
 
 static const struct psp_funcs psp_v13_0_4_funcs = {
-	.init_microcode = psp_v13_0_4_init_microcode,
 	.bootloader_load_kdb = psp_v13_0_4_bootloader_load_kdb,
 	.bootloader_load_spl = psp_v13_0_4_bootloader_load_spl,
 	.bootloader_load_sysdrv = psp_v13_0_4_bootloader_load_sysdrv,
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
index 157147c6c94e..a04ca4cdf211 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
@@ -42,46 +42,11 @@
 #include "oss/osssys_4_0_offset.h"
 #include "oss/osssys_4_0_sh_mask.h"
 
-MODULE_FIRMWARE("amdgpu/vega10_sos.bin");
-MODULE_FIRMWARE("amdgpu/vega10_asd.bin");
-MODULE_FIRMWARE("amdgpu/vega10_cap.bin");
-MODULE_FIRMWARE("amdgpu/vega12_sos.bin");
-MODULE_FIRMWARE("amdgpu/vega12_asd.bin");
-
-
 #define smnMP1_FIRMWARE_FLAGS 0x3010028
 
 static int psp_v3_1_ring_stop(struct psp_context *psp,
 			      enum psp_ring_type ring_type);
 
-static int psp_v3_1_init_microcode(struct psp_context *psp)
-{
-	struct amdgpu_device *adev = psp->adev;
-	const char *chip_name;
-	int err = 0;
-
-	DRM_DEBUG("\n");
-
-	switch (adev->asic_type) {
-	case CHIP_VEGA10:
-		chip_name = "vega10";
-		break;
-	case CHIP_VEGA12:
-		chip_name = "vega12";
-		break;
-	default: BUG();
-	}
-
-	err = psp_init_sos_microcode(psp, chip_name);
-	if (err)
-		return err;
-
-	err = psp_init_asd_microcode(psp, chip_name);
-	if (err)
-		return err;
-
-	return 0;
-}
 
 static int psp_v3_1_bootloader_load_sysdrv(struct psp_context *psp)
 {
@@ -372,7 +337,6 @@ static void psp_v3_1_ring_set_wptr(struct psp_context *psp, uint32_t value)
 }
 
 static const struct psp_funcs psp_v3_1_funcs = {
-	.init_microcode = psp_v3_1_init_microcode,
 	.bootloader_load_sysdrv = psp_v3_1_bootloader_load_sysdrv,
 	.bootloader_load_sos = psp_v3_1_bootloader_load_sos,
 	.ring_create = psp_v3_1_ring_create,
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 01/11] drm/amd: Delay removal of the firmware framebuffer
  2022-12-28 16:30 ` [PATCH v2 01/11] drm/amd: Delay removal of the firmware framebuffer Mario Limonciello
@ 2022-12-29 14:35   ` Javier Martinez Canillas
  0 siblings, 0 replies; 17+ messages in thread
From: Javier Martinez Canillas @ 2022-12-29 14:35 UTC (permalink / raw)
  To: Mario Limonciello, Alex Deucher, linux-kernel
  Cc: Carlos Soriano Sanchez, amd-gfx, dri-devel, David Airlie,
	Daniel Vetter, christian.koenig, stable, Alex Deucher, Pan,
	Xinhui

Hello Mario,

On 12/28/22 17:30, Mario Limonciello wrote:
> Removing the firmware framebuffer from the driver means that even
> if the driver doesn't support the IP blocks in a GPU it will no
> longer be functional after the driver fails to initialize.
> 
> This change will ensure that unsupported IP blocks at least cause
> the driver to work with the EFI framebuffer.
>
> Cc: stable@vger.kernel.org
> Suggested-by: Alex Deucher <alex.deucher@amd.com>
> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
> ---

As mentioned, I'm not familiar with this driver but the change looks
good to me. Delaying the firmware-provided framebuffer removal is the
correct thing to do IMO.

Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 00/11] Recover from failure to probe GPU
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
                   ` (10 preceding siblings ...)
  2022-12-28 16:30 ` [PATCH v2 11/11] drm/amd: Request PSP " Mario Limonciello
@ 2022-12-29 17:31 ` Alex Deucher
  2023-01-03 10:10 ` Lazar, Lijo
  12 siblings, 0 replies; 17+ messages in thread
From: Alex Deucher @ 2022-12-29 17:31 UTC (permalink / raw)
  To: Mario Limonciello
  Cc: Javier Martinez Canillas, Alex Deucher, linux-kernel, dri-devel,
	amd-gfx, Carlos Soriano Sanchez, christian.koenig

Patches 1-10 are:
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

On Wed, Dec 28, 2022 at 11:31 AM Mario Limonciello
<mario.limonciello@amd.com> wrote:
>
> One of the first thing that KMS drivers do during initialization is
> destroy the system firmware framebuffer by means of
> `drm_aperture_remove_conflicting_pci_framebuffers`
>
> This means that if for any reason the GPU failed to probe the user
> will be stuck with at best a screen frozen at the last thing that
> was shown before the KMS driver continued it's probe.
>
> The problem is most pronounced when new GPU support is introduced
> because users will need to have a recent linux-firmware snapshot
> on their system when they boot a kernel with matching support.
>
> However the problem is further exaggerated in the case of amdgpu because
> it has migrated to "IP discovery" where amdgpu will attempt to load
> on "ALL" AMD GPUs even if the driver is missing support for IP blocks
> contained in that GPU.
>
> IP discovery requires some probing and isn't run until after the
> framebuffer has been destroyed.
>
> This means a situation can occur where a user purchases a new GPU not
> yet supported by a distribution and when booting the installer it will
> "freeze" even if the distribution doesn't have the matching kernel support
> for those IP blocks.
>
> The perfect example of this is Ubuntu 22.10 and the new dGPUs just
> launched by AMD.  The installation media ships with kernel 5.19 (which
> has IP discovery) but the amdgpu support for those IP blocks landed in
> kernel 6.0. The matching linux-firmware was released after 22.10's launch.
> The screen will freeze without nomodeset. Even if a user manages to install
> and then upgrades to kernel 6.0 after install they'll still have the
> problem of missing firmware, and the same experience.
>
> This is quite jarring for users, particularly if they don't know
> that they have to use "nomodeset" to install.
>
> To help the situation make changes to GPU discovery:
> 1) Delay releasing the firmware framebuffer until after IP discovery has
> completed.  This will help the situation of an older kernel that doesn't
> yet support the IP blocks probing a new GPU.
> 2) Request loading all PSP, VCN, SDMA, MES and GC microcode into memory
> during IP discovery. This will help the situation of new enough kernel for
> the IP discovery phase to otherwise pass but missing microcode from
> linux-firmware.git.
>
> Not all requested firmware will be loaded during IP discovery as some of it
> will require larger driver architecture changes. For example SMU firmware
> isn't loaded on certain products, but that's not known until later on when
> the early_init phase of the SMU load occurs.
>
> v1->v2:
>  * Take the suggestion from v1 thread to delay the framebuffer release until
>    ip discovery is done. This patch is CC to stable to that older stable
>    kernels with IP discovery won't try to probe unknown IP.
>  * Drop changes to drm aperature.
>  * Fetch SDMA, VCN, MES, GC and PSP microcode during IP discovery.
>
> Mario Limonciello (11):
>   drm/amd: Delay removal of the firmware framebuffer
>   drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode"
>   drm/amd: Convert SMUv11 microcode init to use
>     `amdgpu_ucode_ip_version_decode`
>   drm/amd: Convert SMU v13 to use `amdgpu_ucode_ip_version_decode`
>   drm/amd: Request SDMA microcode during IP discovery
>   drm/amd: Request VCN microcode during IP discovery
>   drm/amd: Request MES microcode during IP discovery
>   drm/amd: Request GFX9 microcode during IP discovery
>   drm/amd: Request GFX10 microcode during IP discovery
>   drm/amd: Request GFX11 microcode during IP discovery
>   drm/amd: Request PSP microcode during IP discovery
>
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    |   8 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 590 +++++++++++++++++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |   6 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c       |   2 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c      |   9 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h      |   2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c     | 208 ++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c       |  85 +--
>  drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c        | 180 +-----
>  drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        |  64 +-
>  drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c         | 143 +----
>  drivers/gpu/drm/amd/amdgpu/mes_v10_1.c        |  28 -
>  drivers/gpu/drm/amd/amdgpu/mes_v11_0.c        |  25 +-
>  drivers/gpu/drm/amd/amdgpu/psp_v10_0.c        | 106 +---
>  drivers/gpu/drm/amd/amdgpu/psp_v11_0.c        | 165 +----
>  drivers/gpu/drm/amd/amdgpu/psp_v12_0.c        | 102 +--
>  drivers/gpu/drm/amd/amdgpu/psp_v13_0.c        |  82 ---
>  drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c      |  36 --
>  drivers/gpu/drm/amd/amdgpu/psp_v3_1.c         |  36 --
>  drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c        |  61 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c        |  42 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c        |  65 +-
>  drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c        |  30 +-
>  .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c    |  35 +-
>  .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c    |  12 +-
>  25 files changed, 919 insertions(+), 1203 deletions(-)
>
>
> base-commit: de9a71e391a92841582ca3008e7b127a0b8ccf41
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 11/11] drm/amd: Request PSP microcode during IP discovery
  2022-12-28 16:30 ` [PATCH v2 11/11] drm/amd: Request PSP " Mario Limonciello
@ 2022-12-29 17:33   ` Alex Deucher
  0 siblings, 0 replies; 17+ messages in thread
From: Alex Deucher @ 2022-12-29 17:33 UTC (permalink / raw)
  To: Mario Limonciello
  Cc: Javier Martinez Canillas, Alex Deucher, linux-kernel, Pan,
	Xinhui, dri-devel, amd-gfx, Carlos Soriano Sanchez,
	christian.koenig

On Wed, Dec 28, 2022 at 11:32 AM Mario Limonciello
<mario.limonciello@amd.com> wrote:
>
> If PSP microcode is required but not available during early init, the
> firmware framebuffer will have already been released and the screen will
> freeze.
>
> Move the request for PSP microcode into the IP discovery phase
> so that if it's not available, IP discovery will fail.
>
> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>

This is probably ok, but I think I'd prefer to just move the
request_firwmare() calls out into ip discovery and leave the rest of
the logic in the PSP code.

Alex


> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 120 ++++++++++++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c       |   2 -
>  drivers/gpu/drm/amd/amdgpu/psp_v10_0.c        | 106 +++--------
>  drivers/gpu/drm/amd/amdgpu/psp_v11_0.c        | 165 ++++--------------
>  drivers/gpu/drm/amd/amdgpu/psp_v12_0.c        | 102 +++--------
>  drivers/gpu/drm/amd/amdgpu/psp_v13_0.c        |  82 ---------
>  drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c      |  36 ----
>  drivers/gpu/drm/amd/amdgpu/psp_v3_1.c         |  36 ----
>  8 files changed, 202 insertions(+), 447 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> index c8c538a768fe..6199ab078bc7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> @@ -158,6 +158,40 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
>  MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
>  MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
>
> +MODULE_FIRMWARE("amdgpu/aldebaran_sos.bin");
> +MODULE_FIRMWARE("amdgpu/aldebaran_ta.bin");
> +MODULE_FIRMWARE("amdgpu/aldebaran_cap.bin");
> +MODULE_FIRMWARE("amdgpu/green_sardine_asd.bin");
> +MODULE_FIRMWARE("amdgpu/green_sardine_ta.bin");
> +MODULE_FIRMWARE("amdgpu/raven_asd.bin");
> +MODULE_FIRMWARE("amdgpu/picasso_asd.bin");
> +MODULE_FIRMWARE("amdgpu/raven2_asd.bin");
> +MODULE_FIRMWARE("amdgpu/picasso_ta.bin");
> +MODULE_FIRMWARE("amdgpu/raven2_ta.bin");
> +MODULE_FIRMWARE("amdgpu/raven_ta.bin");
> +MODULE_FIRMWARE("amdgpu/renoir_asd.bin");
> +MODULE_FIRMWARE("amdgpu/renoir_ta.bin");
> +MODULE_FIRMWARE("amdgpu/yellow_carp_toc.bin");
> +MODULE_FIRMWARE("amdgpu/yellow_carp_ta.bin");
> +MODULE_FIRMWARE("amdgpu/vega10_sos.bin");
> +MODULE_FIRMWARE("amdgpu/vega10_asd.bin");
> +MODULE_FIRMWARE("amdgpu/vega10_cap.bin");
> +MODULE_FIRMWARE("amdgpu/vega12_sos.bin");
> +MODULE_FIRMWARE("amdgpu/vega12_asd.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_5_toc.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_5_ta.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_8_toc.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_8_ta.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_0_sos.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_10_ta.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_4_toc.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_4_ta.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_11_toc.bin");
> +MODULE_FIRMWARE("amdgpu/psp_13_0_11_ta.bin");
>
>  /* gfx9 */
>  MODULE_FIRMWARE("amdgpu/vega10_ce.bin");
> @@ -1858,12 +1892,30 @@ static int amdgpu_discovery_set_ih_ip_blocks(struct amdgpu_device *adev)
>
>  static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
>  {
> +       char ucode_prefix[30];
> +       int r;
> +
> +       amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
> +       adev->psp.adev = adev;
> +
>         switch (adev->ip_versions[MP0_HWIP][0]) {
>         case IP_VERSION(9, 0, 0):
> +               r = psp_init_sos_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               r = psp_init_asd_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
>                 amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block);
>                 break;
>         case IP_VERSION(10, 0, 0):
>         case IP_VERSION(10, 0, 1):
> +               r = psp_init_asd_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
>                 amdgpu_device_ip_block_add(adev, &psp_v10_0_ip_block);
>                 break;
>         case IP_VERSION(11, 0, 0):
> @@ -1871,11 +1923,34 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
>         case IP_VERSION(11, 0, 4):
>         case IP_VERSION(11, 0, 5):
>         case IP_VERSION(11, 0, 9):
> +               r = psp_init_sos_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               r = psp_init_asd_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               break;
>         case IP_VERSION(11, 0, 7):
>         case IP_VERSION(11, 0, 11):
>         case IP_VERSION(11, 0, 12):
>         case IP_VERSION(11, 0, 13):
> +               r = psp_init_sos_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               break;
>         case IP_VERSION(11, 5, 0):
> +               r = psp_init_asd_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               r = psp_init_toc_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
>                 amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
>                 break;
>         case IP_VERSION(11, 0, 8):
> @@ -1883,20 +1958,57 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
>                 break;
>         case IP_VERSION(11, 0, 3):
>         case IP_VERSION(12, 0, 1):
> +               r = psp_init_asd_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
>                 amdgpu_device_ip_block_add(adev, &psp_v12_0_ip_block);
>                 break;
> -       case IP_VERSION(13, 0, 0):
> -       case IP_VERSION(13, 0, 1):
>         case IP_VERSION(13, 0, 2):
> +               r = psp_init_sos_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               /* It's not necessary to load ras ta on Guest side */
> +               if (!amdgpu_sriov_vf(adev)) {
> +                       r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
> +                       if (r)
> +                               return r;
> +               }
> +               amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
> +               break;
> +       case IP_VERSION(13, 0, 1):
>         case IP_VERSION(13, 0, 3):
>         case IP_VERSION(13, 0, 5):
> -       case IP_VERSION(13, 0, 7):
>         case IP_VERSION(13, 0, 8):
> -       case IP_VERSION(13, 0, 10):
>         case IP_VERSION(13, 0, 11):
> +               r = psp_init_toc_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
> +               break;
> +       case IP_VERSION(13, 0, 0):
> +       case IP_VERSION(13, 0, 7):
> +       case IP_VERSION(13, 0, 10):
> +               r = psp_init_sos_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
>                 amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
>                 break;
>         case IP_VERSION(13, 0, 4):
> +               r = psp_init_toc_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
> +               r = psp_init_ta_microcode(&adev->psp, ucode_prefix);
> +               if (r)
> +                       return r;
>                 amdgpu_device_ip_block_add(adev, &psp_v13_0_4_ip_block);
>                 break;
>         default:
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
> index 7a2fc920739b..f7103b3354c6 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
> @@ -188,8 +188,6 @@ static int psp_early_init(void *handle)
>                 return -EINVAL;
>         }
>
> -       psp->adev = adev;
> -
>         psp_check_pmfw_centralized_cstate_management(psp);
>
>         return 0;
> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
> index 9de46fa8f46c..710445d39df1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
> @@ -37,93 +37,37 @@
>  #include "gc/gc_9_1_offset.h"
>  #include "sdma0/sdma0_4_1_offset.h"
>
> -MODULE_FIRMWARE("amdgpu/raven_asd.bin");
> -MODULE_FIRMWARE("amdgpu/picasso_asd.bin");
> -MODULE_FIRMWARE("amdgpu/raven2_asd.bin");
> -MODULE_FIRMWARE("amdgpu/picasso_ta.bin");
> -MODULE_FIRMWARE("amdgpu/raven2_ta.bin");
> -MODULE_FIRMWARE("amdgpu/raven_ta.bin");
> -
>  static int psp_v10_0_init_microcode(struct psp_context *psp)
>  {
>         struct amdgpu_device *adev = psp->adev;
> -       const char *chip_name;
> -       char fw_name[30];
> -       int err = 0;
>         const struct ta_firmware_header_v1_0 *ta_hdr;
> -       DRM_DEBUG("\n");
> -
> -       switch (adev->asic_type) {
> -       case CHIP_RAVEN:
> -               if (adev->apu_flags & AMD_APU_IS_RAVEN2)
> -                       chip_name = "raven2";
> -               else if (adev->apu_flags & AMD_APU_IS_PICASSO)
> -                       chip_name = "picasso";
> -               else
> -                       chip_name = "raven";
> -               break;
> -       default: BUG();
> -       }
> -
> -       err = psp_init_asd_microcode(psp, chip_name);
> -       if (err)
> -               goto out;
> -
> -       snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
> -       err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
> -       if (err) {
> -               release_firmware(adev->psp.ta_fw);
> -               adev->psp.ta_fw = NULL;
> -               dev_info(adev->dev,
> -                        "psp v10.0: Failed to load firmware \"%s\"\n",
> -                        fw_name);
> -       } else {
> -               err = amdgpu_ucode_validate(adev->psp.ta_fw);
> -               if (err)
> -                       goto out2;
> -
> -               ta_hdr = (const struct ta_firmware_header_v1_0 *)
> -                                adev->psp.ta_fw->data;
> -               adev->psp.hdcp_context.context.bin_desc.fw_version =
> -                       le32_to_cpu(ta_hdr->hdcp.fw_version);
> -               adev->psp.hdcp_context.context.bin_desc.size_bytes =
> -                       le32_to_cpu(ta_hdr->hdcp.size_bytes);
> -               adev->psp.hdcp_context.context.bin_desc.start_addr =
> -                       (uint8_t *)ta_hdr +
> -                       le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
> -
> -               adev->psp.dtm_context.context.bin_desc.fw_version =
> -                       le32_to_cpu(ta_hdr->dtm.fw_version);
> -               adev->psp.dtm_context.context.bin_desc.size_bytes =
> -                       le32_to_cpu(ta_hdr->dtm.size_bytes);
> -               adev->psp.dtm_context.context.bin_desc.start_addr =
> -                       (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
> -                       le32_to_cpu(ta_hdr->dtm.offset_bytes);
> -
> -               adev->psp.securedisplay_context.context.bin_desc.fw_version =
> -                       le32_to_cpu(ta_hdr->securedisplay.fw_version);
> -               adev->psp.securedisplay_context.context.bin_desc.size_bytes =
> -                       le32_to_cpu(ta_hdr->securedisplay.size_bytes);
> -               adev->psp.securedisplay_context.context.bin_desc.start_addr =
> -                       (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
> -                       le32_to_cpu(ta_hdr->securedisplay.offset_bytes);
> -
> -               adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
> -       }
>
> -       return 0;
> +       ta_hdr = (const struct ta_firmware_header_v1_0 *)
> +                        adev->psp.ta_fw->data;
> +       adev->psp.hdcp_context.context.bin_desc.fw_version =
> +               le32_to_cpu(ta_hdr->hdcp.fw_version);
> +       adev->psp.hdcp_context.context.bin_desc.size_bytes =
> +               le32_to_cpu(ta_hdr->hdcp.size_bytes);
> +       adev->psp.hdcp_context.context.bin_desc.start_addr =
> +               (uint8_t *)ta_hdr +
> +               le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
> +       adev->psp.dtm_context.context.bin_desc.fw_version =
> +               le32_to_cpu(ta_hdr->dtm.fw_version);
> +       adev->psp.dtm_context.context.bin_desc.size_bytes =
> +               le32_to_cpu(ta_hdr->dtm.size_bytes);
> +       adev->psp.dtm_context.context.bin_desc.start_addr =
> +               (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
> +               le32_to_cpu(ta_hdr->dtm.offset_bytes);
> +       adev->psp.securedisplay_context.context.bin_desc.fw_version =
> +               le32_to_cpu(ta_hdr->securedisplay.fw_version);
> +       adev->psp.securedisplay_context.context.bin_desc.size_bytes =
> +               le32_to_cpu(ta_hdr->securedisplay.size_bytes);
> +       adev->psp.securedisplay_context.context.bin_desc.start_addr =
> +               (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
> +               le32_to_cpu(ta_hdr->securedisplay.offset_bytes);
> +       adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
>
> -out2:
> -       release_firmware(adev->psp.ta_fw);
> -       adev->psp.ta_fw = NULL;
> -out:
> -       if (err) {
> -               dev_err(adev->dev,
> -                       "psp v10.0: Failed to load firmware \"%s\"\n",
> -                       fw_name);
> -       }
> -
> -       return err;
> +       return 0;
>  }
>
>  static int psp_v10_0_ring_create(struct psp_context *psp,
> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
> index bd3e3e23a939..880fd90311e8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
> @@ -88,160 +88,63 @@ MODULE_FIRMWARE("amdgpu/beige_goby_ta.bin");
>  static int psp_v11_0_init_microcode(struct psp_context *psp)
>  {
>         struct amdgpu_device *adev = psp->adev;
> -       const char *chip_name;
> -       char fw_name[PSP_FW_NAME_LEN];
> -       int err = 0;
>         const struct ta_firmware_header_v1_0 *ta_hdr;
>
>         DRM_DEBUG("\n");
>
> -       switch (adev->ip_versions[MP0_HWIP][0]) {
> -       case IP_VERSION(11, 0, 2):
> -               chip_name = "vega20";
> -               break;
> -       case IP_VERSION(11, 0, 0):
> -               chip_name = "navi10";
> -               break;
> -       case IP_VERSION(11, 0, 5):
> -               chip_name = "navi14";
> -               break;
> -       case IP_VERSION(11, 0, 9):
> -               chip_name = "navi12";
> -               break;
> -       case IP_VERSION(11, 0, 4):
> -               chip_name = "arcturus";
> -               break;
> -       case IP_VERSION(11, 0, 7):
> -               chip_name = "sienna_cichlid";
> -               break;
> -       case IP_VERSION(11, 0, 11):
> -               chip_name = "navy_flounder";
> -               break;
> -       case IP_VERSION(11, 5, 0):
> -               chip_name = "vangogh";
> -               break;
> -       case IP_VERSION(11, 0, 12):
> -               chip_name = "dimgrey_cavefish";
> -               break;
> -       case IP_VERSION(11, 0, 13):
> -               chip_name = "beige_goby";
> -               break;
> -       default:
> -               BUG();
> -       }
> -
> -
>         switch (adev->ip_versions[MP0_HWIP][0]) {
>         case IP_VERSION(11, 0, 2):
>         case IP_VERSION(11, 0, 4):
> -               err = psp_init_sos_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               err = psp_init_asd_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
> -               err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
> -               if (err) {
> -                       release_firmware(adev->psp.ta_fw);
> -                       adev->psp.ta_fw = NULL;
> -                       dev_info(adev->dev,
> -                                "psp v11.0: Failed to load firmware \"%s\"\n", fw_name);
> -               } else {
> -                       err = amdgpu_ucode_validate(adev->psp.ta_fw);
> -                       if (err)
> -                               goto out2;
> -
> -                       ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data;
> -                       adev->psp.xgmi_context.context.bin_desc.fw_version =
> -                               le32_to_cpu(ta_hdr->xgmi.fw_version);
> -                       adev->psp.xgmi_context.context.bin_desc.size_bytes =
> -                               le32_to_cpu(ta_hdr->xgmi.size_bytes);
> -                       adev->psp.xgmi_context.context.bin_desc.start_addr =
> -                               (uint8_t *)ta_hdr +
> -                               le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
> -                       adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
> -                       adev->psp.ras_context.context.bin_desc.fw_version =
> -                               le32_to_cpu(ta_hdr->ras.fw_version);
> -                       adev->psp.ras_context.context.bin_desc.size_bytes =
> -                               le32_to_cpu(ta_hdr->ras.size_bytes);
> -                       adev->psp.ras_context.context.bin_desc.start_addr =
> -                               (uint8_t *)adev->psp.xgmi_context.context.bin_desc.start_addr +
> -                               le32_to_cpu(ta_hdr->ras.offset_bytes);
> -               }
> +               ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data;
> +               adev->psp.xgmi_context.context.bin_desc.fw_version =
> +                       le32_to_cpu(ta_hdr->xgmi.fw_version);
> +               adev->psp.xgmi_context.context.bin_desc.size_bytes =
> +                       le32_to_cpu(ta_hdr->xgmi.size_bytes);
> +               adev->psp.xgmi_context.context.bin_desc.start_addr =
> +                       (uint8_t *)ta_hdr +
> +                       le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
> +               adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
> +               adev->psp.ras_context.context.bin_desc.fw_version =
> +                       le32_to_cpu(ta_hdr->ras.fw_version);
> +               adev->psp.ras_context.context.bin_desc.size_bytes =
> +                       le32_to_cpu(ta_hdr->ras.size_bytes);
> +               adev->psp.ras_context.context.bin_desc.start_addr =
> +                       (uint8_t *)adev->psp.xgmi_context.context.bin_desc.start_addr +
> +                       le32_to_cpu(ta_hdr->ras.offset_bytes);
>                 break;
>         case IP_VERSION(11, 0, 0):
>         case IP_VERSION(11, 0, 5):
>         case IP_VERSION(11, 0, 9):
> -               err = psp_init_sos_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               err = psp_init_asd_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
> -               err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
> -               if (err) {
> -                       release_firmware(adev->psp.ta_fw);
> -                       adev->psp.ta_fw = NULL;
> -                       dev_info(adev->dev,
> -                                "psp v11.0: Failed to load firmware \"%s\"\n", fw_name);
> -               } else {
> -                       err = amdgpu_ucode_validate(adev->psp.ta_fw);
> -                       if (err)
> -                               goto out2;
> -
> -                       ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data;
> -                       adev->psp.hdcp_context.context.bin_desc.fw_version =
> -                               le32_to_cpu(ta_hdr->hdcp.fw_version);
> -                       adev->psp.hdcp_context.context.bin_desc.size_bytes =
> -                               le32_to_cpu(ta_hdr->hdcp.size_bytes);
> -                       adev->psp.hdcp_context.context.bin_desc.start_addr =
> -                               (uint8_t *)ta_hdr +
> -                               le32_to_cpu(
> -                                       ta_hdr->header.ucode_array_offset_bytes);
> -
> -                       adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
> -
> -                       adev->psp.dtm_context.context.bin_desc.fw_version =
> -                               le32_to_cpu(ta_hdr->dtm.fw_version);
> -                       adev->psp.dtm_context.context.bin_desc.size_bytes =
> -                               le32_to_cpu(ta_hdr->dtm.size_bytes);
> -                       adev->psp.dtm_context.context.bin_desc.start_addr =
> -                               (uint8_t *)adev->psp.hdcp_context.context
> -                                       .bin_desc.start_addr +
> -                               le32_to_cpu(ta_hdr->dtm.offset_bytes);
> -               }
> +               ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data;
> +               adev->psp.hdcp_context.context.bin_desc.fw_version =
> +                       le32_to_cpu(ta_hdr->hdcp.fw_version);
> +               adev->psp.hdcp_context.context.bin_desc.size_bytes =
> +                       le32_to_cpu(ta_hdr->hdcp.size_bytes);
> +               adev->psp.hdcp_context.context.bin_desc.start_addr =
> +                       (uint8_t *)ta_hdr +
> +                       le32_to_cpu(
> +                               ta_hdr->header.ucode_array_offset_bytes);
> +               adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
> +               adev->psp.dtm_context.context.bin_desc.fw_version =
> +                       le32_to_cpu(ta_hdr->dtm.fw_version);
> +               adev->psp.dtm_context.context.bin_desc.size_bytes =
> +                       le32_to_cpu(ta_hdr->dtm.size_bytes);
> +               adev->psp.dtm_context.context.bin_desc.start_addr =
> +                       (uint8_t *)adev->psp.hdcp_context.context
> +                               .bin_desc.start_addr +
> +                       le32_to_cpu(ta_hdr->dtm.offset_bytes);
>                 break;
>         case IP_VERSION(11, 0, 7):
>         case IP_VERSION(11, 0, 11):
>         case IP_VERSION(11, 0, 12):
>         case IP_VERSION(11, 0, 13):
> -               err = psp_init_sos_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               err = psp_init_ta_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               break;
>         case IP_VERSION(11, 5, 0):
> -               err = psp_init_asd_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               err = psp_init_toc_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
>                 break;
>         default:
>                 BUG();
>         }
>
>         return 0;
> -
> -out2:
> -       release_firmware(adev->psp.ta_fw);
> -       adev->psp.ta_fw = NULL;
> -       return err;
>  }
>
>  static int psp_v11_0_wait_for_bootloader(struct psp_context *psp)
> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c
> index 8ed2281b6557..0b5d63735f39 100644
> --- a/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c
> @@ -37,94 +37,46 @@
>  #include "oss/osssys_4_0_offset.h"
>  #include "oss/osssys_4_0_sh_mask.h"
>
> -MODULE_FIRMWARE("amdgpu/renoir_asd.bin");
> -MODULE_FIRMWARE("amdgpu/renoir_ta.bin");
> -MODULE_FIRMWARE("amdgpu/green_sardine_asd.bin");
> -MODULE_FIRMWARE("amdgpu/green_sardine_ta.bin");
> -
>  /* address block */
>  #define smnMP1_FIRMWARE_FLAGS          0x3010024
>
>  static int psp_v12_0_init_microcode(struct psp_context *psp)
>  {
>         struct amdgpu_device *adev = psp->adev;
> -       const char *chip_name;
> -       char fw_name[30];
> -       int err = 0;
>         const struct ta_firmware_header_v1_0 *ta_hdr;
>         DRM_DEBUG("\n");
>
> -       switch (adev->asic_type) {
> -       case CHIP_RENOIR:
> -               if (adev->apu_flags & AMD_APU_IS_RENOIR)
> -                       chip_name = "renoir";
> -               else
> -                       chip_name = "green_sardine";
> -               break;
> -       default:
> -               BUG();
> -       }
> -
> -       err = psp_init_asd_microcode(psp, chip_name);
> -       if (err)
> -               return err;
> -
> -       snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
> -       err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
> -       if (err) {
> -               release_firmware(adev->psp.ta_fw);
> -               adev->psp.ta_fw = NULL;
> -               dev_info(adev->dev,
> -                        "psp v12.0: Failed to load firmware \"%s\"\n",
> -                        fw_name);
> -       } else {
> -               err = amdgpu_ucode_validate(adev->psp.ta_fw);
> -               if (err)
> -                       goto out;
> -
> -               ta_hdr = (const struct ta_firmware_header_v1_0 *)
> -                                adev->psp.ta_fw->data;
> -               adev->psp.hdcp_context.context.bin_desc.fw_version =
> -                       le32_to_cpu(ta_hdr->hdcp.fw_version);
> -               adev->psp.hdcp_context.context.bin_desc.size_bytes =
> -                       le32_to_cpu(ta_hdr->hdcp.size_bytes);
> -               adev->psp.hdcp_context.context.bin_desc.start_addr =
> -                       (uint8_t *)ta_hdr +
> -                       le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
> -
> -               adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
> -
> -               adev->psp.dtm_context.context.bin_desc.fw_version =
> -                       le32_to_cpu(ta_hdr->dtm.fw_version);
> -               adev->psp.dtm_context.context.bin_desc.size_bytes =
> -                       le32_to_cpu(ta_hdr->dtm.size_bytes);
> -               adev->psp.dtm_context.context.bin_desc.start_addr =
> +       ta_hdr = (const struct ta_firmware_header_v1_0 *)
> +                               adev->psp.ta_fw->data;
> +       adev->psp.hdcp_context.context.bin_desc.fw_version =
> +               le32_to_cpu(ta_hdr->hdcp.fw_version);
> +       adev->psp.hdcp_context.context.bin_desc.size_bytes =
> +               le32_to_cpu(ta_hdr->hdcp.size_bytes);
> +       adev->psp.hdcp_context.context.bin_desc.start_addr =
> +               (uint8_t *)ta_hdr +
> +               le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
> +
> +       adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
> +
> +       adev->psp.dtm_context.context.bin_desc.fw_version =
> +               le32_to_cpu(ta_hdr->dtm.fw_version);
> +       adev->psp.dtm_context.context.bin_desc.size_bytes =
> +               le32_to_cpu(ta_hdr->dtm.size_bytes);
> +       adev->psp.dtm_context.context.bin_desc.start_addr =
> +               (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
> +               le32_to_cpu(ta_hdr->dtm.offset_bytes);
> +
> +       if (adev->apu_flags & AMD_APU_IS_RENOIR) {
> +               adev->psp.securedisplay_context.context.bin_desc.fw_version =
> +                       le32_to_cpu(ta_hdr->securedisplay.fw_version);
> +               adev->psp.securedisplay_context.context.bin_desc.size_bytes =
> +                       le32_to_cpu(ta_hdr->securedisplay.size_bytes);
> +               adev->psp.securedisplay_context.context.bin_desc.start_addr =
>                         (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
> -                       le32_to_cpu(ta_hdr->dtm.offset_bytes);
> -
> -               if (adev->apu_flags & AMD_APU_IS_RENOIR) {
> -                       adev->psp.securedisplay_context.context.bin_desc.fw_version =
> -                               le32_to_cpu(ta_hdr->securedisplay.fw_version);
> -                       adev->psp.securedisplay_context.context.bin_desc.size_bytes =
> -                               le32_to_cpu(ta_hdr->securedisplay.size_bytes);
> -                       adev->psp.securedisplay_context.context.bin_desc.start_addr =
> -                               (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
> -                               le32_to_cpu(ta_hdr->securedisplay.offset_bytes);
> -               }
> +                       le32_to_cpu(ta_hdr->securedisplay.offset_bytes);
>         }
>
>         return 0;
> -
> -out:
> -       release_firmware(adev->psp.ta_fw);
> -       adev->psp.ta_fw = NULL;
> -       if (err) {
> -               dev_err(adev->dev,
> -                       "psp v12.0: Failed to load firmware \"%s\"\n",
> -                       fw_name);
> -       }
> -
> -       return err;
>  }
>
>  static int psp_v12_0_bootloader_load_sysdrv(struct psp_context *psp)
> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
> index e6a26a7e5e5e..2228994ef096 100644
> --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
> @@ -31,24 +31,6 @@
>  #include "mp/mp_13_0_2_offset.h"
>  #include "mp/mp_13_0_2_sh_mask.h"
>
> -MODULE_FIRMWARE("amdgpu/aldebaran_sos.bin");
> -MODULE_FIRMWARE("amdgpu/aldebaran_ta.bin");
> -MODULE_FIRMWARE("amdgpu/aldebaran_cap.bin");
> -MODULE_FIRMWARE("amdgpu/yellow_carp_toc.bin");
> -MODULE_FIRMWARE("amdgpu/yellow_carp_ta.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_5_toc.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_5_ta.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_8_toc.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_8_ta.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_0_sos.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_10_ta.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_11_toc.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_11_ta.bin");
> -
>  /* For large FW files the time to complete can be very long */
>  #define USBC_PD_POLLING_LIMIT_S 240
>
> @@ -67,69 +49,6 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_11_ta.bin");
>  /* memory training timeout define */
>  #define MEM_TRAIN_SEND_MSG_TIMEOUT_US  3000000
>
> -static int psp_v13_0_init_microcode(struct psp_context *psp)
> -{
> -       struct amdgpu_device *adev = psp->adev;
> -       const char *chip_name;
> -       char ucode_prefix[30];
> -       int err = 0;
> -
> -       switch (adev->ip_versions[MP0_HWIP][0]) {
> -       case IP_VERSION(13, 0, 2):
> -               chip_name = "aldebaran";
> -               break;
> -       case IP_VERSION(13, 0, 1):
> -       case IP_VERSION(13, 0, 3):
> -               chip_name = "yellow_carp";
> -               break;
> -       default:
> -               amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
> -               chip_name = ucode_prefix;
> -               break;
> -       }
> -
> -       switch (adev->ip_versions[MP0_HWIP][0]) {
> -       case IP_VERSION(13, 0, 2):
> -               err = psp_init_sos_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               /* It's not necessary to load ras ta on Guest side */
> -               if (!amdgpu_sriov_vf(adev)) {
> -                       err = psp_init_ta_microcode(&adev->psp, chip_name);
> -                       if (err)
> -                               return err;
> -               }
> -               break;
> -       case IP_VERSION(13, 0, 1):
> -       case IP_VERSION(13, 0, 3):
> -       case IP_VERSION(13, 0, 5):
> -       case IP_VERSION(13, 0, 8):
> -       case IP_VERSION(13, 0, 11):
> -               err = psp_init_toc_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               err = psp_init_ta_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               break;
> -       case IP_VERSION(13, 0, 0):
> -       case IP_VERSION(13, 0, 7):
> -       case IP_VERSION(13, 0, 10):
> -               err = psp_init_sos_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               /* It's not necessary to load ras ta on Guest side */
> -               err = psp_init_ta_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               break;
> -       default:
> -               BUG();
> -       }
> -
> -       return 0;
> -}
> -
>  static bool psp_v13_0_is_sos_alive(struct psp_context *psp)
>  {
>         struct amdgpu_device *adev = psp->adev;
> @@ -697,7 +616,6 @@ static int psp_v13_0_vbflash_status(struct psp_context *psp)
>  }
>
>  static const struct psp_funcs psp_v13_0_funcs = {
> -       .init_microcode = psp_v13_0_init_microcode,
>         .bootloader_load_kdb = psp_v13_0_bootloader_load_kdb,
>         .bootloader_load_spl = psp_v13_0_bootloader_load_spl,
>         .bootloader_load_sysdrv = psp_v13_0_bootloader_load_sysdrv,
> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c
> index 9d4e24e518e8..9e34c7ee9304 100644
> --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c
> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c
> @@ -29,41 +29,6 @@
>  #include "mp/mp_13_0_4_offset.h"
>  #include "mp/mp_13_0_4_sh_mask.h"
>
> -MODULE_FIRMWARE("amdgpu/psp_13_0_4_toc.bin");
> -MODULE_FIRMWARE("amdgpu/psp_13_0_4_ta.bin");
> -
> -static int psp_v13_0_4_init_microcode(struct psp_context *psp)
> -{
> -       struct amdgpu_device *adev = psp->adev;
> -       const char *chip_name;
> -       char ucode_prefix[30];
> -       int err = 0;
> -
> -       switch (adev->ip_versions[MP0_HWIP][0]) {
> -       case IP_VERSION(13, 0, 4):
> -               amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
> -               chip_name = ucode_prefix;
> -               break;
> -       default:
> -               BUG();
> -       }
> -
> -       switch (adev->ip_versions[MP0_HWIP][0]) {
> -       case IP_VERSION(13, 0, 4):
> -               err = psp_init_toc_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               err = psp_init_ta_microcode(psp, chip_name);
> -               if (err)
> -                       return err;
> -               break;
> -       default:
> -               BUG();
> -       }
> -
> -       return 0;
> -}
> -
>  static bool psp_v13_0_4_is_sos_alive(struct psp_context *psp)
>  {
>         struct amdgpu_device *adev = psp->adev;
> @@ -339,7 +304,6 @@ static void psp_v13_0_4_ring_set_wptr(struct psp_context *psp, uint32_t value)
>  }
>
>  static const struct psp_funcs psp_v13_0_4_funcs = {
> -       .init_microcode = psp_v13_0_4_init_microcode,
>         .bootloader_load_kdb = psp_v13_0_4_bootloader_load_kdb,
>         .bootloader_load_spl = psp_v13_0_4_bootloader_load_spl,
>         .bootloader_load_sysdrv = psp_v13_0_4_bootloader_load_sysdrv,
> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
> index 157147c6c94e..a04ca4cdf211 100644
> --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
> @@ -42,46 +42,11 @@
>  #include "oss/osssys_4_0_offset.h"
>  #include "oss/osssys_4_0_sh_mask.h"
>
> -MODULE_FIRMWARE("amdgpu/vega10_sos.bin");
> -MODULE_FIRMWARE("amdgpu/vega10_asd.bin");
> -MODULE_FIRMWARE("amdgpu/vega10_cap.bin");
> -MODULE_FIRMWARE("amdgpu/vega12_sos.bin");
> -MODULE_FIRMWARE("amdgpu/vega12_asd.bin");
> -
> -
>  #define smnMP1_FIRMWARE_FLAGS 0x3010028
>
>  static int psp_v3_1_ring_stop(struct psp_context *psp,
>                               enum psp_ring_type ring_type);
>
> -static int psp_v3_1_init_microcode(struct psp_context *psp)
> -{
> -       struct amdgpu_device *adev = psp->adev;
> -       const char *chip_name;
> -       int err = 0;
> -
> -       DRM_DEBUG("\n");
> -
> -       switch (adev->asic_type) {
> -       case CHIP_VEGA10:
> -               chip_name = "vega10";
> -               break;
> -       case CHIP_VEGA12:
> -               chip_name = "vega12";
> -               break;
> -       default: BUG();
> -       }
> -
> -       err = psp_init_sos_microcode(psp, chip_name);
> -       if (err)
> -               return err;
> -
> -       err = psp_init_asd_microcode(psp, chip_name);
> -       if (err)
> -               return err;
> -
> -       return 0;
> -}
>
>  static int psp_v3_1_bootloader_load_sysdrv(struct psp_context *psp)
>  {
> @@ -372,7 +337,6 @@ static void psp_v3_1_ring_set_wptr(struct psp_context *psp, uint32_t value)
>  }
>
>  static const struct psp_funcs psp_v3_1_funcs = {
> -       .init_microcode = psp_v3_1_init_microcode,
>         .bootloader_load_sysdrv = psp_v3_1_bootloader_load_sysdrv,
>         .bootloader_load_sos = psp_v3_1_bootloader_load_sos,
>         .ring_create = psp_v3_1_ring_create,
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 00/11] Recover from failure to probe GPU
  2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
                   ` (11 preceding siblings ...)
  2022-12-29 17:31 ` [PATCH v2 00/11] Recover from failure to probe GPU Alex Deucher
@ 2023-01-03 10:10 ` Lazar, Lijo
  2023-01-03 14:17   ` Alex Deucher
  12 siblings, 1 reply; 17+ messages in thread
From: Lazar, Lijo @ 2023-01-03 10:10 UTC (permalink / raw)
  To: Mario Limonciello, Javier Martinez Canillas, Alex Deucher
  Cc: linux-kernel, dri-devel, amd-gfx, Daniel Vetter,
	Carlos Soriano Sanchez, David Airlie, christian.koenig



On 12/28/2022 10:00 PM, Mario Limonciello wrote:
> One of the first thing that KMS drivers do during initialization is
> destroy the system firmware framebuffer by means of
> `drm_aperture_remove_conflicting_pci_framebuffers`
> 
> This means that if for any reason the GPU failed to probe the user
> will be stuck with at best a screen frozen at the last thing that
> was shown before the KMS driver continued it's probe.
> 
> The problem is most pronounced when new GPU support is introduced
> because users will need to have a recent linux-firmware snapshot
> on their system when they boot a kernel with matching support.
> 
> However the problem is further exaggerated in the case of amdgpu because
> it has migrated to "IP discovery" where amdgpu will attempt to load
> on "ALL" AMD GPUs even if the driver is missing support for IP blocks
> contained in that GPU.
> 
> IP discovery requires some probing and isn't run until after the
> framebuffer has been destroyed.
> 
> This means a situation can occur where a user purchases a new GPU not
> yet supported by a distribution and when booting the installer it will
> "freeze" even if the distribution doesn't have the matching kernel support
> for those IP blocks.
> 
> The perfect example of this is Ubuntu 22.10 and the new dGPUs just
> launched by AMD.  The installation media ships with kernel 5.19 (which
> has IP discovery) but the amdgpu support for those IP blocks landed in
> kernel 6.0. The matching linux-firmware was released after 22.10's launch.
> The screen will freeze without nomodeset. Even if a user manages to install
> and then upgrades to kernel 6.0 after install they'll still have the
> problem of missing firmware, and the same experience.
> 
> This is quite jarring for users, particularly if they don't know
> that they have to use "nomodeset" to install.
> 
> To help the situation make changes to GPU discovery:
> 1) Delay releasing the firmware framebuffer until after IP discovery has
> completed.  This will help the situation of an older kernel that doesn't
> yet support the IP blocks probing a new GPU.
> 2) Request loading all PSP, VCN, SDMA, MES and GC microcode into memory
> during IP discovery. This will help the situation of new enough kernel for
> the IP discovery phase to otherwise pass but missing microcode from
> linux-firmware.git.
> 
> Not all requested firmware will be loaded during IP discovery as some of it
> will require larger driver architecture changes. For example SMU firmware
> isn't loaded on certain products, but that's not known until later on when
> the early_init phase of the SMU load occurs.
> 
> v1->v2:
>   * Take the suggestion from v1 thread to delay the framebuffer release until
>     ip discovery is done. This patch is CC to stable to that older stable
>     kernels with IP discovery won't try to probe unknown IP.
>   * Drop changes to drm aperature.
>   * Fetch SDMA, VCN, MES, GC and PSP microcode during IP discovery.
> 

What is the gain here in just checking if firmware files are available? 
It can fail anywhere during sw_init and it's the same situation.

Restricting IP FWs to IP specific files looks better to me than 
centralizing and creating interdependencies.

Thanks,
Lijo

> Mario Limonciello (11):
>    drm/amd: Delay removal of the firmware framebuffer
>    drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode"
>    drm/amd: Convert SMUv11 microcode init to use
>      `amdgpu_ucode_ip_version_decode`
>    drm/amd: Convert SMU v13 to use `amdgpu_ucode_ip_version_decode`
>    drm/amd: Request SDMA microcode during IP discovery
>    drm/amd: Request VCN microcode during IP discovery
>    drm/amd: Request MES microcode during IP discovery
>    drm/amd: Request GFX9 microcode during IP discovery
>    drm/amd: Request GFX10 microcode during IP discovery
>    drm/amd: Request GFX11 microcode during IP discovery
>    drm/amd: Request PSP microcode during IP discovery
> 
>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    |   8 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 590 +++++++++++++++++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |   6 -
>   drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c       |   2 -
>   drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c      |   9 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h      |   2 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c     | 208 ++++++
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c       |  85 +--
>   drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c        | 180 +-----
>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        |  64 +-
>   drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c         | 143 +----
>   drivers/gpu/drm/amd/amdgpu/mes_v10_1.c        |  28 -
>   drivers/gpu/drm/amd/amdgpu/mes_v11_0.c        |  25 +-
>   drivers/gpu/drm/amd/amdgpu/psp_v10_0.c        | 106 +---
>   drivers/gpu/drm/amd/amdgpu/psp_v11_0.c        | 165 +----
>   drivers/gpu/drm/amd/amdgpu/psp_v12_0.c        | 102 +--
>   drivers/gpu/drm/amd/amdgpu/psp_v13_0.c        |  82 ---
>   drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c      |  36 --
>   drivers/gpu/drm/amd/amdgpu/psp_v3_1.c         |  36 --
>   drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c        |  61 +-
>   drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c        |  42 +-
>   drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c        |  65 +-
>   drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c        |  30 +-
>   .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c    |  35 +-
>   .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c    |  12 +-
>   25 files changed, 919 insertions(+), 1203 deletions(-)
> 
> 
> base-commit: de9a71e391a92841582ca3008e7b127a0b8ccf41

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 00/11] Recover from failure to probe GPU
  2023-01-03 10:10 ` Lazar, Lijo
@ 2023-01-03 14:17   ` Alex Deucher
  0 siblings, 0 replies; 17+ messages in thread
From: Alex Deucher @ 2023-01-03 14:17 UTC (permalink / raw)
  To: Lazar, Lijo
  Cc: Mario Limonciello, Javier Martinez Canillas, Alex Deucher,
	linux-kernel, amd-gfx, dri-devel, Daniel Vetter,
	Carlos Soriano Sanchez, David Airlie, christian.koenig

On Tue, Jan 3, 2023 at 5:10 AM Lazar, Lijo <lijo.lazar@amd.com> wrote:
>
>
>
> On 12/28/2022 10:00 PM, Mario Limonciello wrote:
> > One of the first thing that KMS drivers do during initialization is
> > destroy the system firmware framebuffer by means of
> > `drm_aperture_remove_conflicting_pci_framebuffers`
> >
> > This means that if for any reason the GPU failed to probe the user
> > will be stuck with at best a screen frozen at the last thing that
> > was shown before the KMS driver continued it's probe.
> >
> > The problem is most pronounced when new GPU support is introduced
> > because users will need to have a recent linux-firmware snapshot
> > on their system when they boot a kernel with matching support.
> >
> > However the problem is further exaggerated in the case of amdgpu because
> > it has migrated to "IP discovery" where amdgpu will attempt to load
> > on "ALL" AMD GPUs even if the driver is missing support for IP blocks
> > contained in that GPU.
> >
> > IP discovery requires some probing and isn't run until after the
> > framebuffer has been destroyed.
> >
> > This means a situation can occur where a user purchases a new GPU not
> > yet supported by a distribution and when booting the installer it will
> > "freeze" even if the distribution doesn't have the matching kernel support
> > for those IP blocks.
> >
> > The perfect example of this is Ubuntu 22.10 and the new dGPUs just
> > launched by AMD.  The installation media ships with kernel 5.19 (which
> > has IP discovery) but the amdgpu support for those IP blocks landed in
> > kernel 6.0. The matching linux-firmware was released after 22.10's launch.
> > The screen will freeze without nomodeset. Even if a user manages to install
> > and then upgrades to kernel 6.0 after install they'll still have the
> > problem of missing firmware, and the same experience.
> >
> > This is quite jarring for users, particularly if they don't know
> > that they have to use "nomodeset" to install.
> >
> > To help the situation make changes to GPU discovery:
> > 1) Delay releasing the firmware framebuffer until after IP discovery has
> > completed.  This will help the situation of an older kernel that doesn't
> > yet support the IP blocks probing a new GPU.
> > 2) Request loading all PSP, VCN, SDMA, MES and GC microcode into memory
> > during IP discovery. This will help the situation of new enough kernel for
> > the IP discovery phase to otherwise pass but missing microcode from
> > linux-firmware.git.
> >
> > Not all requested firmware will be loaded during IP discovery as some of it
> > will require larger driver architecture changes. For example SMU firmware
> > isn't loaded on certain products, but that's not known until later on when
> > the early_init phase of the SMU load occurs.
> >
> > v1->v2:
> >   * Take the suggestion from v1 thread to delay the framebuffer release until
> >     ip discovery is done. This patch is CC to stable to that older stable
> >     kernels with IP discovery won't try to probe unknown IP.
> >   * Drop changes to drm aperature.
> >   * Fetch SDMA, VCN, MES, GC and PSP microcode during IP discovery.
> >
>
> What is the gain here in just checking if firmware files are available?
> It can fail anywhere during sw_init and it's the same situation.

Other failures are presumably a bug or hardware issue.  The missing
firmware would be a common issue when chips are first launched.
Thinking about it a bit more, another option might be to move the
calls to request_firmware() into the IP specific early_init()
functions and then move the drm_aperture release after early_init().
That would keep the firmware handling in the IPs and should still
happen early enough that we haven't messed with the hardware yet.

Alex

>
> Restricting IP FWs to IP specific files looks better to me than
> centralizing and creating interdependencies.
>
> Thanks,
> Lijo
>
> > Mario Limonciello (11):
> >    drm/amd: Delay removal of the firmware framebuffer
> >    drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode"
> >    drm/amd: Convert SMUv11 microcode init to use
> >      `amdgpu_ucode_ip_version_decode`
> >    drm/amd: Convert SMU v13 to use `amdgpu_ucode_ip_version_decode`
> >    drm/amd: Request SDMA microcode during IP discovery
> >    drm/amd: Request VCN microcode during IP discovery
> >    drm/amd: Request MES microcode during IP discovery
> >    drm/amd: Request GFX9 microcode during IP discovery
> >    drm/amd: Request GFX10 microcode during IP discovery
> >    drm/amd: Request GFX11 microcode during IP discovery
> >    drm/amd: Request PSP microcode during IP discovery
> >
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    |   8 +
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 590 +++++++++++++++++-
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |   6 -
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c       |   2 -
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c      |   9 +-
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h      |   2 +-
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c     | 208 ++++++
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c       |  85 +--
> >   drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c        | 180 +-----
> >   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        |  64 +-
> >   drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c         | 143 +----
> >   drivers/gpu/drm/amd/amdgpu/mes_v10_1.c        |  28 -
> >   drivers/gpu/drm/amd/amdgpu/mes_v11_0.c        |  25 +-
> >   drivers/gpu/drm/amd/amdgpu/psp_v10_0.c        | 106 +---
> >   drivers/gpu/drm/amd/amdgpu/psp_v11_0.c        | 165 +----
> >   drivers/gpu/drm/amd/amdgpu/psp_v12_0.c        | 102 +--
> >   drivers/gpu/drm/amd/amdgpu/psp_v13_0.c        |  82 ---
> >   drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c      |  36 --
> >   drivers/gpu/drm/amd/amdgpu/psp_v3_1.c         |  36 --
> >   drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c        |  61 +-
> >   drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c        |  42 +-
> >   drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c        |  65 +-
> >   drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c        |  30 +-
> >   .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c    |  35 +-
> >   .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c    |  12 +-
> >   25 files changed, 919 insertions(+), 1203 deletions(-)
> >
> >
> > base-commit: de9a71e391a92841582ca3008e7b127a0b8ccf41

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2023-01-03 14:17 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-28 16:30 [PATCH v2 00/11] Recover from failure to probe GPU Mario Limonciello
2022-12-28 16:30 ` [PATCH v2 01/11] drm/amd: Delay removal of the firmware framebuffer Mario Limonciello
2022-12-29 14:35   ` Javier Martinez Canillas
2022-12-28 16:30 ` [PATCH v2 02/11] drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode" Mario Limonciello
2022-12-28 16:30 ` [PATCH v2 03/11] drm/amd: Convert SMUv11 microcode init to use `amdgpu_ucode_ip_version_decode` Mario Limonciello
2022-12-28 16:30 ` [PATCH v2 04/11] drm/amd: Convert SMU v13 " Mario Limonciello
2022-12-28 16:30 ` [PATCH v2 05/11] drm/amd: Request SDMA microcode during IP discovery Mario Limonciello
2022-12-28 16:30 ` [PATCH v2 06/11] drm/amd: Request VCN " Mario Limonciello
2022-12-28 16:30 ` [PATCH v2 07/11] drm/amd: Request MES " Mario Limonciello
2022-12-28 16:30 ` [PATCH v2 08/11] drm/amd: Request GFX9 " Mario Limonciello
2022-12-28 16:30 ` [PATCH v2 09/11] drm/amd: Request GFX10 " Mario Limonciello
2022-12-28 16:30 ` [PATCH v2 10/11] drm/amd: Request GFX11 " Mario Limonciello
2022-12-28 16:30 ` [PATCH v2 11/11] drm/amd: Request PSP " Mario Limonciello
2022-12-29 17:33   ` Alex Deucher
2022-12-29 17:31 ` [PATCH v2 00/11] Recover from failure to probe GPU Alex Deucher
2023-01-03 10:10 ` Lazar, Lijo
2023-01-03 14:17   ` Alex Deucher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®