[PATCH] drm/amdgpu: load mc firware in driver for Polaris.

Alex Deucher alexdeucher at gmail.com
Tue Mar 21 13:35:08 UTC 2017


On Tue, Mar 21, 2017 at 1:02 AM, Rex Zhu <Rex.Zhu at amd.com> wrote:
> load mc ucode in driver if VBIOS not loaded
> a full version of MC ucode,
>
> Change-Id: I2aea697155f6b3916dc304a6bf198c3f8417bda5
> Signed-off-by: Rex Zhu <Rex.Zhu at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 84 +++++++++++++++++++++++++++++++++--
>  1 file changed, 81 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> index 5fcb64e..c9a5c31 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> @@ -253,14 +253,14 @@ static int gmc_v8_0_init_microcode(struct amdgpu_device *adev)
>  }
>
>  /**
> - * gmc_v8_0_mc_load_microcode - load MC ucode into the hw
> + * gmc_v8_0_mc_load_microcode - load tong MC ucode into the hw

tong -> tonga

With that fixed patch is:
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

>   *
>   * @adev: amdgpu_device pointer
>   *
>   * Load the GDDR MC ucode into the hw (CIK).
>   * Returns 0 on success, error on failure.
>   */
> -static int gmc_v8_0_mc_load_microcode(struct amdgpu_device *adev)
> +static int gmc_v8_0_tonga_mc_load_microcode(struct amdgpu_device *adev)
>  {
>         const struct mc_firmware_header_v1_0 *hdr;
>         const __le32 *fw_data = NULL;
> @@ -329,6 +329,76 @@ static int gmc_v8_0_mc_load_microcode(struct amdgpu_device *adev)
>         return 0;
>  }
>
> +static int gmc_v8_0_polaris_mc_load_microcode(struct amdgpu_device *adev)
> +{
> +       const struct mc_firmware_header_v1_0 *hdr;
> +       const __le32 *fw_data = NULL;
> +       const __le32 *io_mc_regs = NULL;
> +       u32 data, vbios_version;
> +       int i, ucode_size, regs_size;
> +
> +       if (!adev->mc.fw)
> +               return -EINVAL;
> +
> +       /* Skip MC ucode loading on SR-IOV capable boards.
> +        * vbios does this for us in asic_init in that case.
> +        * Skip MC ucode loading on VF, because hypervisor will do that
> +        * for this adaptor.
> +        */
> +       if (amdgpu_sriov_bios(adev))
> +               return 0;
> +
> +       WREG32(mmMC_SEQ_IO_DEBUG_INDEX, 0x9F);
> +       data = RREG32(mmMC_SEQ_IO_DEBUG_DATA);
> +       vbios_version = data & 0xf;
> +
> +       if (vbios_version == 0)
> +               return 0;
> +
> +       hdr = (const struct mc_firmware_header_v1_0 *)adev->mc.fw->data;
> +       amdgpu_ucode_print_mc_hdr(&hdr->header);
> +
> +       adev->mc.fw_version = le32_to_cpu(hdr->header.ucode_version);
> +       regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2);
> +       io_mc_regs = (const __le32 *)
> +               (adev->mc.fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes));
> +       ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
> +       fw_data = (const __le32 *)
> +               (adev->mc.fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
> +
> +       data = RREG32(mmMC_SEQ_MISC0);
> +       data &= ~(0x40);
> +       WREG32(mmMC_SEQ_MISC0, data);
> +
> +       /* load mc io regs */
> +       for (i = 0; i < regs_size; i++) {
> +               WREG32(mmMC_SEQ_IO_DEBUG_INDEX, le32_to_cpup(io_mc_regs++));
> +               WREG32(mmMC_SEQ_IO_DEBUG_DATA, le32_to_cpup(io_mc_regs++));
> +       }
> +
> +       WREG32(mmMC_SEQ_SUP_CNTL, 0x00000008);
> +       WREG32(mmMC_SEQ_SUP_CNTL, 0x00000010);
> +
> +       /* load the MC ucode */
> +       for (i = 0; i < ucode_size; i++)
> +               WREG32(mmMC_SEQ_SUP_PGM, le32_to_cpup(fw_data++));
> +
> +       /* put the engine back into the active state */
> +       WREG32(mmMC_SEQ_SUP_CNTL, 0x00000008);
> +       WREG32(mmMC_SEQ_SUP_CNTL, 0x00000004);
> +       WREG32(mmMC_SEQ_SUP_CNTL, 0x00000001);
> +
> +       /* wait for training to complete */
> +       for (i = 0; i < adev->usec_timeout; i++) {
> +               data = RREG32(mmMC_SEQ_MISC0);
> +               if (data & 0x80)
> +                       break;
> +               udelay(1);
> +       }
> +
> +       return 0;
> +}
> +
>  static void gmc_v8_0_vram_gtt_location(struct amdgpu_device *adev,
>                                        struct amdgpu_mc *mc)
>  {
> @@ -1095,7 +1165,15 @@ static int gmc_v8_0_hw_init(void *handle)
>         gmc_v8_0_mc_program(adev);
>
>         if (adev->asic_type == CHIP_TONGA) {
> -               r = gmc_v8_0_mc_load_microcode(adev);
> +               r = gmc_v8_0_tonga_mc_load_microcode(adev);
> +               if (r) {
> +                       DRM_ERROR("Failed to load MC firmware!\n");
> +                       return r;
> +               }
> +       } else if (adev->asic_type == CHIP_POLARIS11 ||
> +                       adev->asic_type == CHIP_POLARIS10 ||
> +                       adev->asic_type == CHIP_POLARIS12) {
> +               r = gmc_v8_0_polaris_mc_load_microcode(adev);
>                 if (r) {
>                         DRM_ERROR("Failed to load MC firmware!\n");
>                         return r;
> --
> 1.9.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list