Commit c5e3548c authored by Jordan Crouse's avatar Jordan Crouse Committed by Rob Clark

drm/msm/adreno: Define a list of firmware files to load per target

The number and type of firmware files required differs for each
target. Instead of using a fixed struct member for each possible
firmware file use a generic list of files that should be loaded
on boot.  Use some semi-target specific enums to help each target
find the appropriate firmware(s) that it needs to load.
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent f306953f
...@@ -256,8 +256,8 @@ static int a3xx_hw_init(struct msm_gpu *gpu) ...@@ -256,8 +256,8 @@ static int a3xx_hw_init(struct msm_gpu *gpu)
*/ */
/* Load PM4: */ /* Load PM4: */
ptr = (uint32_t *)(adreno_gpu->pm4->data); ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data);
len = adreno_gpu->pm4->size / 4; len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4;
DBG("loading PM4 ucode version: %x", ptr[1]); DBG("loading PM4 ucode version: %x", ptr[1]);
gpu_write(gpu, REG_AXXX_CP_DEBUG, gpu_write(gpu, REG_AXXX_CP_DEBUG,
...@@ -268,8 +268,8 @@ static int a3xx_hw_init(struct msm_gpu *gpu) ...@@ -268,8 +268,8 @@ static int a3xx_hw_init(struct msm_gpu *gpu)
gpu_write(gpu, REG_AXXX_CP_ME_RAM_DATA, ptr[i]); gpu_write(gpu, REG_AXXX_CP_ME_RAM_DATA, ptr[i]);
/* Load PFP: */ /* Load PFP: */
ptr = (uint32_t *)(adreno_gpu->pfp->data); ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PFP]->data);
len = adreno_gpu->pfp->size / 4; len = adreno_gpu->fw[ADRENO_FW_PFP]->size / 4;
DBG("loading PFP ucode version: %x", ptr[5]); DBG("loading PFP ucode version: %x", ptr[5]);
gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_ADDR, 0); gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_ADDR, 0);
......
...@@ -274,16 +274,16 @@ static int a4xx_hw_init(struct msm_gpu *gpu) ...@@ -274,16 +274,16 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
return ret; return ret;
/* Load PM4: */ /* Load PM4: */
ptr = (uint32_t *)(adreno_gpu->pm4->data); ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data);
len = adreno_gpu->pm4->size / 4; len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4;
DBG("loading PM4 ucode version: %u", ptr[0]); DBG("loading PM4 ucode version: %u", ptr[0]);
gpu_write(gpu, REG_A4XX_CP_ME_RAM_WADDR, 0); gpu_write(gpu, REG_A4XX_CP_ME_RAM_WADDR, 0);
for (i = 1; i < len; i++) for (i = 1; i < len; i++)
gpu_write(gpu, REG_A4XX_CP_ME_RAM_DATA, ptr[i]); gpu_write(gpu, REG_A4XX_CP_ME_RAM_DATA, ptr[i]);
/* Load PFP: */ /* Load PFP: */
ptr = (uint32_t *)(adreno_gpu->pfp->data); ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PFP]->data);
len = adreno_gpu->pfp->size / 4; len = adreno_gpu->fw[ADRENO_FW_PFP]->size / 4;
DBG("loading PFP ucode version: %u", ptr[0]); DBG("loading PFP ucode version: %u", ptr[0]);
gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_ADDR, 0); gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_ADDR, 0);
......
...@@ -123,15 +123,12 @@ reset_set(void *data, u64 val) ...@@ -123,15 +123,12 @@ reset_set(void *data, u64 val)
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
if (adreno_gpu->pm4) { release_firmware(adreno_gpu->fw[ADRENO_FW_PM4]);
release_firmware(adreno_gpu->pm4); adreno_gpu->fw[ADRENO_FW_PM4] = NULL;
adreno_gpu->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_bo) {
if (a5xx_gpu->pm4_iova) if (a5xx_gpu->pm4_iova)
msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace); msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace);
......
...@@ -523,8 +523,8 @@ static int a5xx_ucode_init(struct msm_gpu *gpu) ...@@ -523,8 +523,8 @@ static int a5xx_ucode_init(struct msm_gpu *gpu)
int ret; int ret;
if (!a5xx_gpu->pm4_bo) { if (!a5xx_gpu->pm4_bo) {
a5xx_gpu->pm4_bo = a5xx_ucode_load_bo(gpu, adreno_gpu->pm4, a5xx_gpu->pm4_bo = a5xx_ucode_load_bo(gpu,
&a5xx_gpu->pm4_iova); adreno_gpu->fw[ADRENO_FW_PM4], &a5xx_gpu->pm4_iova);
if (IS_ERR(a5xx_gpu->pm4_bo)) { if (IS_ERR(a5xx_gpu->pm4_bo)) {
ret = PTR_ERR(a5xx_gpu->pm4_bo); ret = PTR_ERR(a5xx_gpu->pm4_bo);
...@@ -536,8 +536,8 @@ static int a5xx_ucode_init(struct msm_gpu *gpu) ...@@ -536,8 +536,8 @@ static int a5xx_ucode_init(struct msm_gpu *gpu)
} }
if (!a5xx_gpu->pfp_bo) { if (!a5xx_gpu->pfp_bo) {
a5xx_gpu->pfp_bo = a5xx_ucode_load_bo(gpu, adreno_gpu->pfp, a5xx_gpu->pfp_bo = a5xx_ucode_load_bo(gpu,
&a5xx_gpu->pfp_iova); adreno_gpu->fw[ADRENO_FW_PFP], &a5xx_gpu->pfp_iova);
if (IS_ERR(a5xx_gpu->pfp_bo)) { if (IS_ERR(a5xx_gpu->pfp_bo)) {
ret = PTR_ERR(a5xx_gpu->pfp_bo); ret = PTR_ERR(a5xx_gpu->pfp_bo);
......
...@@ -261,7 +261,6 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu) ...@@ -261,7 +261,6 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
struct drm_device *drm = gpu->dev; struct drm_device *drm = gpu->dev;
const struct firmware *fw;
uint32_t dwords = 0, offset = 0, bosize; uint32_t dwords = 0, offset = 0, bosize;
unsigned int *data, *ptr, *cmds; unsigned int *data, *ptr, *cmds;
unsigned int cmds_size; unsigned int cmds_size;
...@@ -269,15 +268,7 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu) ...@@ -269,15 +268,7 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
if (a5xx_gpu->gpmu_bo) if (a5xx_gpu->gpmu_bo)
return; return;
/* Get the firmware */ data = (unsigned int *) adreno_gpu->fw[ADRENO_FW_GPMU]->data;
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;
/* /*
* The first dword is the size of the remaining data in dwords. Use it * The first dword is the size of the remaining data in dwords. Use it
...@@ -285,12 +276,14 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu) ...@@ -285,12 +276,14 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
* the firmware that we read * the firmware that we read
*/ */
if (fw->size < 8 || (data[0] < 2) || (data[0] >= (fw->size >> 2))) if (adreno_gpu->fw[ADRENO_FW_GPMU]->size < 8 ||
goto out; (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) */ /* The second dword is an ID - look for 2 (GPMU_FIRMWARE_ID) */
if (data[1] != 2) if (data[1] != 2)
goto out; return;
cmds = data + data[2] + 3; cmds = data + data[2] + 3;
cmds_size = data[0] - data[2] - 2; cmds_size = data[0] - data[2] - 2;
...@@ -325,8 +318,7 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu) ...@@ -325,8 +318,7 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
msm_gem_put_vaddr(a5xx_gpu->gpmu_bo); msm_gem_put_vaddr(a5xx_gpu->gpmu_bo);
a5xx_gpu->gpmu_dwords = dwords; a5xx_gpu->gpmu_dwords = dwords;
goto out; return;
err: err:
if (a5xx_gpu->gpmu_iova) if (a5xx_gpu->gpmu_iova)
msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->aspace); msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->aspace);
...@@ -336,8 +328,4 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu) ...@@ -336,8 +328,4 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
a5xx_gpu->gpmu_bo = NULL; a5xx_gpu->gpmu_bo = NULL;
a5xx_gpu->gpmu_iova = 0; a5xx_gpu->gpmu_iova = 0;
a5xx_gpu->gpmu_dwords = 0; a5xx_gpu->gpmu_dwords = 0;
out:
/* No need to keep that firmware laying around anymore */
release_firmware(fw);
} }
...@@ -30,61 +30,75 @@ static const struct adreno_info gpulist[] = { ...@@ -30,61 +30,75 @@ static const struct adreno_info gpulist[] = {
.rev = ADRENO_REV(3, 0, 5, ANY_ID), .rev = ADRENO_REV(3, 0, 5, ANY_ID),
.revn = 305, .revn = 305,
.name = "A305", .name = "A305",
.pm4fw = "a300_pm4.fw", .fw = {
.pfpfw = "a300_pfp.fw", [ADRENO_FW_PM4] = "a300_pm4.fw",
[ADRENO_FW_PFP] = "a300_pfp.fw",
},
.gmem = SZ_256K, .gmem = SZ_256K,
.init = a3xx_gpu_init, .init = a3xx_gpu_init,
}, { }, {
.rev = ADRENO_REV(3, 0, 6, 0), .rev = ADRENO_REV(3, 0, 6, 0),
.revn = 307, /* because a305c is revn==306 */ .revn = 307, /* because a305c is revn==306 */
.name = "A306", .name = "A306",
.pm4fw = "a300_pm4.fw", .fw = {
.pfpfw = "a300_pfp.fw", [ADRENO_FW_PM4] = "a300_pm4.fw",
[ADRENO_FW_PFP] = "a300_pfp.fw",
},
.gmem = SZ_128K, .gmem = SZ_128K,
.init = a3xx_gpu_init, .init = a3xx_gpu_init,
}, { }, {
.rev = ADRENO_REV(3, 2, ANY_ID, ANY_ID), .rev = ADRENO_REV(3, 2, ANY_ID, ANY_ID),
.revn = 320, .revn = 320,
.name = "A320", .name = "A320",
.pm4fw = "a300_pm4.fw", .fw = {
.pfpfw = "a300_pfp.fw", [ADRENO_FW_PM4] = "a300_pm4.fw",
[ADRENO_FW_PFP] = "a300_pfp.fw",
},
.gmem = SZ_512K, .gmem = SZ_512K,
.init = a3xx_gpu_init, .init = a3xx_gpu_init,
}, { }, {
.rev = ADRENO_REV(3, 3, 0, ANY_ID), .rev = ADRENO_REV(3, 3, 0, ANY_ID),
.revn = 330, .revn = 330,
.name = "A330", .name = "A330",
.pm4fw = "a330_pm4.fw", .fw = {
.pfpfw = "a330_pfp.fw", [ADRENO_FW_PM4] = "a330_pm4.fw",
[ADRENO_FW_PFP] = "a330_pfp.fw",
},
.gmem = SZ_1M, .gmem = SZ_1M,
.init = a3xx_gpu_init, .init = a3xx_gpu_init,
}, { }, {
.rev = ADRENO_REV(4, 2, 0, ANY_ID), .rev = ADRENO_REV(4, 2, 0, ANY_ID),
.revn = 420, .revn = 420,
.name = "A420", .name = "A420",
.pm4fw = "a420_pm4.fw", .fw = {
.pfpfw = "a420_pfp.fw", [ADRENO_FW_PM4] = "a420_pm4.fw",
[ADRENO_FW_PFP] = "a420_pfp.fw",
},
.gmem = (SZ_1M + SZ_512K), .gmem = (SZ_1M + SZ_512K),
.init = a4xx_gpu_init, .init = a4xx_gpu_init,
}, { }, {
.rev = ADRENO_REV(4, 3, 0, ANY_ID), .rev = ADRENO_REV(4, 3, 0, ANY_ID),
.revn = 430, .revn = 430,
.name = "A430", .name = "A430",
.pm4fw = "a420_pm4.fw", .fw = {
.pfpfw = "a420_pfp.fw", [ADRENO_FW_PM4] = "a420_pm4.fw",
[ADRENO_FW_PFP] = "a420_pfp.fw",
},
.gmem = (SZ_1M + SZ_512K), .gmem = (SZ_1M + SZ_512K),
.init = a4xx_gpu_init, .init = a4xx_gpu_init,
}, { }, {
.rev = ADRENO_REV(5, 3, 0, 2), .rev = ADRENO_REV(5, 3, 0, 2),
.revn = 530, .revn = 530,
.name = "A530", .name = "A530",
.pm4fw = "a530_pm4.fw", .fw = {
.pfpfw = "a530_pfp.fw", [ADRENO_FW_PM4] = "a530_pm4.fw",
[ADRENO_FW_PFP] = "a530_pfp.fw",
[ADRENO_FW_GPMU] = "a530v3_gpmu.fw2",
},
.gmem = SZ_1M, .gmem = SZ_1M,
.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI | .quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
ADRENO_QUIRK_FAULT_DETECT_MASK, ADRENO_QUIRK_FAULT_DETECT_MASK,
.init = a5xx_gpu_init, .init = a5xx_gpu_init,
.powerfw = "a530v3_gpmu.fw2",
.zapfw = "a530_zap.mdt", .zapfw = "a530_zap.mdt",
}, },
}; };
......
...@@ -140,23 +140,24 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname) ...@@ -140,23 +140,24 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname)
static int adreno_load_fw(struct adreno_gpu *adreno_gpu) static int adreno_load_fw(struct adreno_gpu *adreno_gpu)
{ {
int i;
for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++) {
const struct firmware *fw; const struct firmware *fw;
if (adreno_gpu->pm4) if (!adreno_gpu->info->fw[i])
return 0; continue;
fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pm4fw); /* 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)) if (IS_ERR(fw))
return PTR_ERR(fw); return PTR_ERR(fw);
adreno_gpu->pm4 = fw;
fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pfpfw); adreno_gpu->fw[i] = fw;
if (IS_ERR(fw)) {
release_firmware(adreno_gpu->pm4);
adreno_gpu->pm4 = NULL;
return PTR_ERR(fw);
} }
adreno_gpu->pfp = fw;
return 0; return 0;
} }
...@@ -569,8 +570,10 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, ...@@ -569,8 +570,10 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
{ {
release_firmware(adreno_gpu->pm4); unsigned int i;
release_firmware(adreno_gpu->pfp);
for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++)
release_firmware(adreno_gpu->fw[i]);
msm_gpu_cleanup(&adreno_gpu->base); msm_gpu_cleanup(&adreno_gpu->base);
} }
...@@ -48,6 +48,13 @@ enum adreno_regs { ...@@ -48,6 +48,13 @@ enum adreno_regs {
REG_ADRENO_REGISTER_MAX, REG_ADRENO_REGISTER_MAX,
}; };
enum {
ADRENO_FW_PM4 = 0,
ADRENO_FW_PFP = 1,
ADRENO_FW_GPMU = 2,
ADRENO_FW_MAX,
};
enum adreno_quirks { enum adreno_quirks {
ADRENO_QUIRK_TWO_PASS_USE_WFI = 1, ADRENO_QUIRK_TWO_PASS_USE_WFI = 1,
ADRENO_QUIRK_FAULT_DETECT_MASK = 2, ADRENO_QUIRK_FAULT_DETECT_MASK = 2,
...@@ -72,8 +79,7 @@ struct adreno_info { ...@@ -72,8 +79,7 @@ struct adreno_info {
struct adreno_rev rev; struct adreno_rev rev;
uint32_t revn; uint32_t revn;
const char *name; const char *name;
const char *pm4fw, *pfpfw; const char *fw[ADRENO_FW_MAX];
const char *powerfw;
uint32_t gmem; uint32_t gmem;
enum adreno_quirks quirks; enum adreno_quirks quirks;
struct msm_gpu *(*init)(struct drm_device *dev); struct msm_gpu *(*init)(struct drm_device *dev);
...@@ -115,7 +121,7 @@ struct adreno_gpu { ...@@ -115,7 +121,7 @@ struct adreno_gpu {
} fwloc; } fwloc;
/* firmware: */ /* firmware: */
const struct firmware *pm4, *pfp; const struct firmware *fw[ADRENO_FW_MAX];
/* /*
* Register offsets are different between some GPUs. * Register offsets are different between some GPUs.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment