Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon/kms: add ucode loading for SI

Currently the driver required 5 sets of ucode:
1. pfp - pre-fetch parser, part of the CP
2. me - micro engine, part of the CP
3. ce - constant engine, part of the CP
4. rlc - interrupt controller
5. mc - memory controller

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Alex Deucher and committed by
Dave Airlie
0f0de06c 1b5475db

+156
+1
drivers/gpu/drm/radeon/radeon.h
··· 1527 1527 const struct firmware *pfp_fw; /* r6/700 PFP firmware */ 1528 1528 const struct firmware *rlc_fw; /* r6/700 RLC firmware */ 1529 1529 const struct firmware *mc_fw; /* NI MC firmware */ 1530 + const struct firmware *ce_fw; /* SI CE firmware */ 1530 1531 struct r600_blit r600_blit; 1531 1532 struct r600_vram_scratch vram_scratch; 1532 1533 int msi_enabled; /* msi enabled */
+155
drivers/gpu/drm/radeon/si.c
··· 21 21 * 22 22 * Authors: Alex Deucher 23 23 */ 24 + #include <linux/firmware.h> 25 + #include <linux/platform_device.h> 26 + #include <linux/slab.h> 27 + #include <linux/module.h> 24 28 #include "drmP.h" 25 29 #include "radeon.h" 26 30 #include "radeon_asic.h" 27 31 #include "radeon_drm.h" 28 32 #include "sid.h" 29 33 #include "atom.h" 34 + 35 + #define SI_PFP_UCODE_SIZE 2144 36 + #define SI_PM4_UCODE_SIZE 2144 37 + #define SI_CE_UCODE_SIZE 2144 38 + #define SI_RLC_UCODE_SIZE 2048 39 + #define SI_MC_UCODE_SIZE 7769 40 + 41 + MODULE_FIRMWARE("radeon/TAHITI_pfp.bin"); 42 + MODULE_FIRMWARE("radeon/TAHITI_me.bin"); 43 + MODULE_FIRMWARE("radeon/TAHITI_ce.bin"); 44 + MODULE_FIRMWARE("radeon/TAHITI_mc.bin"); 45 + MODULE_FIRMWARE("radeon/TAHITI_rlc.bin"); 46 + MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin"); 47 + MODULE_FIRMWARE("radeon/PITCAIRN_me.bin"); 48 + MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin"); 49 + MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin"); 50 + MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin"); 51 + MODULE_FIRMWARE("radeon/VERDE_pfp.bin"); 52 + MODULE_FIRMWARE("radeon/VERDE_me.bin"); 53 + MODULE_FIRMWARE("radeon/VERDE_ce.bin"); 54 + MODULE_FIRMWARE("radeon/VERDE_mc.bin"); 55 + MODULE_FIRMWARE("radeon/VERDE_rlc.bin"); 30 56 31 57 extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev); 32 58 extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); ··· 75 49 actual_temp = (actual_temp * 1000); 76 50 77 51 return actual_temp; 52 + } 53 + 54 + static int si_init_microcode(struct radeon_device *rdev) 55 + { 56 + struct platform_device *pdev; 57 + const char *chip_name; 58 + const char *rlc_chip_name; 59 + size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size; 60 + char fw_name[30]; 61 + int err; 62 + 63 + DRM_DEBUG("\n"); 64 + 65 + pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); 66 + err = IS_ERR(pdev); 67 + if (err) { 68 + printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); 69 + return -EINVAL; 70 + } 71 + 72 + switch (rdev->family) { 73 + case CHIP_TAHITI: 74 + chip_name = "TAHITI"; 75 + rlc_chip_name = "TAHITI"; 76 + pfp_req_size = SI_PFP_UCODE_SIZE * 4; 77 + me_req_size = SI_PM4_UCODE_SIZE * 4; 78 + ce_req_size = SI_CE_UCODE_SIZE * 4; 79 + rlc_req_size = SI_RLC_UCODE_SIZE * 4; 80 + mc_req_size = SI_MC_UCODE_SIZE * 4; 81 + break; 82 + case CHIP_PITCAIRN: 83 + chip_name = "PITCAIRN"; 84 + rlc_chip_name = "PITCAIRN"; 85 + pfp_req_size = SI_PFP_UCODE_SIZE * 4; 86 + me_req_size = SI_PM4_UCODE_SIZE * 4; 87 + ce_req_size = SI_CE_UCODE_SIZE * 4; 88 + rlc_req_size = SI_RLC_UCODE_SIZE * 4; 89 + mc_req_size = SI_MC_UCODE_SIZE * 4; 90 + break; 91 + case CHIP_VERDE: 92 + chip_name = "VERDE"; 93 + rlc_chip_name = "VERDE"; 94 + pfp_req_size = SI_PFP_UCODE_SIZE * 4; 95 + me_req_size = SI_PM4_UCODE_SIZE * 4; 96 + ce_req_size = SI_CE_UCODE_SIZE * 4; 97 + rlc_req_size = SI_RLC_UCODE_SIZE * 4; 98 + mc_req_size = SI_MC_UCODE_SIZE * 4; 99 + break; 100 + default: BUG(); 101 + } 102 + 103 + DRM_INFO("Loading %s Microcode\n", chip_name); 104 + 105 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); 106 + err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); 107 + if (err) 108 + goto out; 109 + if (rdev->pfp_fw->size != pfp_req_size) { 110 + printk(KERN_ERR 111 + "si_cp: Bogus length %zu in firmware \"%s\"\n", 112 + rdev->pfp_fw->size, fw_name); 113 + err = -EINVAL; 114 + goto out; 115 + } 116 + 117 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); 118 + err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); 119 + if (err) 120 + goto out; 121 + if (rdev->me_fw->size != me_req_size) { 122 + printk(KERN_ERR 123 + "si_cp: Bogus length %zu in firmware \"%s\"\n", 124 + rdev->me_fw->size, fw_name); 125 + err = -EINVAL; 126 + } 127 + 128 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name); 129 + err = request_firmware(&rdev->ce_fw, fw_name, &pdev->dev); 130 + if (err) 131 + goto out; 132 + if (rdev->ce_fw->size != ce_req_size) { 133 + printk(KERN_ERR 134 + "si_cp: Bogus length %zu in firmware \"%s\"\n", 135 + rdev->ce_fw->size, fw_name); 136 + err = -EINVAL; 137 + } 138 + 139 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name); 140 + err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev); 141 + if (err) 142 + goto out; 143 + if (rdev->rlc_fw->size != rlc_req_size) { 144 + printk(KERN_ERR 145 + "si_rlc: Bogus length %zu in firmware \"%s\"\n", 146 + rdev->rlc_fw->size, fw_name); 147 + err = -EINVAL; 148 + } 149 + 150 + snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); 151 + err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev); 152 + if (err) 153 + goto out; 154 + if (rdev->mc_fw->size != mc_req_size) { 155 + printk(KERN_ERR 156 + "si_mc: Bogus length %zu in firmware \"%s\"\n", 157 + rdev->mc_fw->size, fw_name); 158 + err = -EINVAL; 159 + } 160 + 161 + out: 162 + platform_device_unregister(pdev); 163 + 164 + if (err) { 165 + if (err != -EINVAL) 166 + printk(KERN_ERR 167 + "si_cp: Failed to load firmware \"%s\"\n", 168 + fw_name); 169 + release_firmware(rdev->pfp_fw); 170 + rdev->pfp_fw = NULL; 171 + release_firmware(rdev->me_fw); 172 + rdev->me_fw = NULL; 173 + release_firmware(rdev->ce_fw); 174 + rdev->ce_fw = NULL; 175 + release_firmware(rdev->rlc_fw); 176 + rdev->rlc_fw = NULL; 177 + release_firmware(rdev->mc_fw); 178 + rdev->mc_fw = NULL; 179 + } 180 + return err; 78 181 } 79 182 80 183 /* watermark setup */