*/
/* Load PM4: */
- ptr = (uint32_t *)(adreno_gpu->pm4->data);
- len = adreno_gpu->pm4->size / 4;
+ ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data);
+ len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4;
DBG("loading PM4 ucode version: %x", ptr[1]);
gpu_write(gpu, REG_AXXX_CP_DEBUG,
gpu_write(gpu, REG_AXXX_CP_ME_RAM_DATA, ptr[i]);
/* Load PFP: */
- ptr = (uint32_t *)(adreno_gpu->pfp->data);
- len = adreno_gpu->pfp->size / 4;
+ ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PFP]->data);
+ len = adreno_gpu->fw[ADRENO_FW_PFP]->size / 4;
DBG("loading PFP ucode version: %x", ptr[5]);
gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_ADDR, 0);
return ret;
/* Load PM4: */
- ptr = (uint32_t *)(adreno_gpu->pm4->data);
- len = adreno_gpu->pm4->size / 4;
+ ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data);
+ len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4;
DBG("loading PM4 ucode version: %u", ptr[0]);
gpu_write(gpu, REG_A4XX_CP_ME_RAM_WADDR, 0);
for (i = 1; i < len; i++)
gpu_write(gpu, REG_A4XX_CP_ME_RAM_DATA, ptr[i]);
/* Load PFP: */
- ptr = (uint32_t *)(adreno_gpu->pfp->data);
- len = adreno_gpu->pfp->size / 4;
+ ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PFP]->data);
+ len = adreno_gpu->fw[ADRENO_FW_PFP]->size / 4;
DBG("loading PFP ucode version: %u", ptr[0]);
gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_ADDR, 0);
mutex_lock(&dev->struct_mutex);
- if (adreno_gpu->pm4) {
- release_firmware(adreno_gpu->pm4);
- adreno_gpu->pm4 = NULL;
- }
+ release_firmware(adreno_gpu->fw[ADRENO_FW_PM4]);
+ adreno_gpu->fw[ADRENO_FW_PM4] = NULL;
+
+ release_firmware(adreno_gpu->fw[ADRENO_FW_PFP]);
+ adreno_gpu->fw[ADRENO_FW_PFP] = NULL;
- if (adreno_gpu->pfp) {
- release_firmware(adreno_gpu->pfp);
- adreno_gpu->pfp = NULL;
- }
if (a5xx_gpu->pm4_bo) {
if (a5xx_gpu->pm4_iova)
msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace);
int ret;
if (!a5xx_gpu->pm4_bo) {
- a5xx_gpu->pm4_bo = a5xx_ucode_load_bo(gpu, adreno_gpu->pm4,
- &a5xx_gpu->pm4_iova);
+ a5xx_gpu->pm4_bo = a5xx_ucode_load_bo(gpu,
+ adreno_gpu->fw[ADRENO_FW_PM4], &a5xx_gpu->pm4_iova);
if (IS_ERR(a5xx_gpu->pm4_bo)) {
ret = PTR_ERR(a5xx_gpu->pm4_bo);
}
if (!a5xx_gpu->pfp_bo) {
- a5xx_gpu->pfp_bo = a5xx_ucode_load_bo(gpu, adreno_gpu->pfp,
- &a5xx_gpu->pfp_iova);
+ a5xx_gpu->pfp_bo = a5xx_ucode_load_bo(gpu,
+ adreno_gpu->fw[ADRENO_FW_PFP], &a5xx_gpu->pfp_iova);
if (IS_ERR(a5xx_gpu->pfp_bo)) {
ret = PTR_ERR(a5xx_gpu->pfp_bo);
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
struct drm_device *drm = gpu->dev;
- const struct firmware *fw;
uint32_t dwords = 0, offset = 0, bosize;
unsigned int *data, *ptr, *cmds;
unsigned int cmds_size;
if (a5xx_gpu->gpmu_bo)
return;
- /* Get the firmware */
- fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->powerfw);
- if (IS_ERR(fw)) {
- DRM_ERROR("%s: Could not get GPMU firmware. GPMU will not be active\n",
- gpu->name);
- return;
- }
-
- data = (unsigned int *) fw->data;
+ data = (unsigned int *) adreno_gpu->fw[ADRENO_FW_GPMU]->data;
/*
* The first dword is the size of the remaining data in dwords. Use it
* the firmware that we read
*/
- if (fw->size < 8 || (data[0] < 2) || (data[0] >= (fw->size >> 2)))
- goto out;
+ if (adreno_gpu->fw[ADRENO_FW_GPMU]->size < 8 ||
+ (data[0] < 2) || (data[0] >=
+ (adreno_gpu->fw[ADRENO_FW_GPMU]->size >> 2)))
+ return;
/* The second dword is an ID - look for 2 (GPMU_FIRMWARE_ID) */
if (data[1] != 2)
- goto out;
+ return;
cmds = data + data[2] + 3;
cmds_size = data[0] - data[2] - 2;
msm_gem_put_vaddr(a5xx_gpu->gpmu_bo);
a5xx_gpu->gpmu_dwords = dwords;
- goto out;
-
+ return;
err:
if (a5xx_gpu->gpmu_iova)
msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->aspace);
a5xx_gpu->gpmu_bo = NULL;
a5xx_gpu->gpmu_iova = 0;
a5xx_gpu->gpmu_dwords = 0;
-
-out:
- /* No need to keep that firmware laying around anymore */
- release_firmware(fw);
}
.rev = ADRENO_REV(3, 0, 5, ANY_ID),
.revn = 305,
.name = "A305",
- .pm4fw = "a300_pm4.fw",
- .pfpfw = "a300_pfp.fw",
+ .fw = {
+ [ADRENO_FW_PM4] = "a300_pm4.fw",
+ [ADRENO_FW_PFP] = "a300_pfp.fw",
+ },
.gmem = SZ_256K,
.init = a3xx_gpu_init,
}, {
.rev = ADRENO_REV(3, 0, 6, 0),
.revn = 307, /* because a305c is revn==306 */
.name = "A306",
- .pm4fw = "a300_pm4.fw",
- .pfpfw = "a300_pfp.fw",
+ .fw = {
+ [ADRENO_FW_PM4] = "a300_pm4.fw",
+ [ADRENO_FW_PFP] = "a300_pfp.fw",
+ },
.gmem = SZ_128K,
.init = a3xx_gpu_init,
}, {
.rev = ADRENO_REV(3, 2, ANY_ID, ANY_ID),
.revn = 320,
.name = "A320",
- .pm4fw = "a300_pm4.fw",
- .pfpfw = "a300_pfp.fw",
+ .fw = {
+ [ADRENO_FW_PM4] = "a300_pm4.fw",
+ [ADRENO_FW_PFP] = "a300_pfp.fw",
+ },
.gmem = SZ_512K,
.init = a3xx_gpu_init,
}, {
.rev = ADRENO_REV(3, 3, 0, ANY_ID),
.revn = 330,
.name = "A330",
- .pm4fw = "a330_pm4.fw",
- .pfpfw = "a330_pfp.fw",
+ .fw = {
+ [ADRENO_FW_PM4] = "a330_pm4.fw",
+ [ADRENO_FW_PFP] = "a330_pfp.fw",
+ },
.gmem = SZ_1M,
.init = a3xx_gpu_init,
}, {
.rev = ADRENO_REV(4, 2, 0, ANY_ID),
.revn = 420,
.name = "A420",
- .pm4fw = "a420_pm4.fw",
- .pfpfw = "a420_pfp.fw",
+ .fw = {
+ [ADRENO_FW_PM4] = "a420_pm4.fw",
+ [ADRENO_FW_PFP] = "a420_pfp.fw",
+ },
.gmem = (SZ_1M + SZ_512K),
.init = a4xx_gpu_init,
}, {
.rev = ADRENO_REV(4, 3, 0, ANY_ID),
.revn = 430,
.name = "A430",
- .pm4fw = "a420_pm4.fw",
- .pfpfw = "a420_pfp.fw",
+ .fw = {
+ [ADRENO_FW_PM4] = "a420_pm4.fw",
+ [ADRENO_FW_PFP] = "a420_pfp.fw",
+ },
.gmem = (SZ_1M + SZ_512K),
.init = a4xx_gpu_init,
}, {
.rev = ADRENO_REV(5, 3, 0, 2),
.revn = 530,
.name = "A530",
- .pm4fw = "a530_pm4.fw",
- .pfpfw = "a530_pfp.fw",
+ .fw = {
+ [ADRENO_FW_PM4] = "a530_pm4.fw",
+ [ADRENO_FW_PFP] = "a530_pfp.fw",
+ [ADRENO_FW_GPMU] = "a530v3_gpmu.fw2",
+ },
.gmem = SZ_1M,
.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
ADRENO_QUIRK_FAULT_DETECT_MASK,
.init = a5xx_gpu_init,
- .powerfw = "a530v3_gpmu.fw2",
.zapfw = "a530_zap.mdt",
},
};
static int adreno_load_fw(struct adreno_gpu *adreno_gpu)
{
- const struct firmware *fw;
+ int i;
- if (adreno_gpu->pm4)
- return 0;
+ for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++) {
+ const struct firmware *fw;
- fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pm4fw);
- if (IS_ERR(fw))
- return PTR_ERR(fw);
- adreno_gpu->pm4 = fw;
+ if (!adreno_gpu->info->fw[i])
+ continue;
- fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pfpfw);
- if (IS_ERR(fw)) {
- release_firmware(adreno_gpu->pm4);
- adreno_gpu->pm4 = NULL;
- return PTR_ERR(fw);
+ /* Skip if the firmware has already been loaded */
+ if (adreno_gpu->fw[i])
+ continue;
+
+ fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->fw[i]);
+ if (IS_ERR(fw))
+ return PTR_ERR(fw);
+
+ adreno_gpu->fw[i] = fw;
}
- adreno_gpu->pfp = fw;
return 0;
}
void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
{
- release_firmware(adreno_gpu->pm4);
- release_firmware(adreno_gpu->pfp);
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++)
+ release_firmware(adreno_gpu->fw[i]);
msm_gpu_cleanup(&adreno_gpu->base);
}
REG_ADRENO_REGISTER_MAX,
};
+enum {
+ ADRENO_FW_PM4 = 0,
+ ADRENO_FW_PFP = 1,
+ ADRENO_FW_GPMU = 2,
+ ADRENO_FW_MAX,
+};
+
enum adreno_quirks {
ADRENO_QUIRK_TWO_PASS_USE_WFI = 1,
ADRENO_QUIRK_FAULT_DETECT_MASK = 2,
struct adreno_rev rev;
uint32_t revn;
const char *name;
- const char *pm4fw, *pfpfw;
- const char *powerfw;
+ const char *fw[ADRENO_FW_MAX];
uint32_t gmem;
enum adreno_quirks quirks;
struct msm_gpu *(*init)(struct drm_device *dev);
} fwloc;
/* firmware: */
- const struct firmware *pm4, *pfp;
+ const struct firmware *fw[ADRENO_FW_MAX];
/*
* Register offsets are different between some GPUs.