drm/msm/adreno: deal with linux-firmware fw paths
When firmware was added to linux-firmware, it was put in a qcom sub- directory, unlike what we'd been using before. For a300_pfp.fw and a300_pm4.fw symlinks were created, but we'd prefer not to have to do this in the future. So add support to look in both places when loading firmware. Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
parent
e8f3de96a9
commit
2c41ef1b6f
3 changed files with 103 additions and 8 deletions
|
@ -76,9 +76,26 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the rest of the MDT */
|
/*
|
||||||
ret = qcom_mdt_load(dev, fw, fwname, GPU_PAS_ID, mem_region, mem_phys,
|
* Load the rest of the MDT
|
||||||
mem_size);
|
*
|
||||||
|
* Note that we could be dealing with two different paths, since
|
||||||
|
* with upstream linux-firmware it would be in a qcom/ subdir..
|
||||||
|
* adreno_request_fw() handles this, but qcom_mdt_load() does
|
||||||
|
* not. But since we've already gotten thru adreno_request_fw()
|
||||||
|
* we know which of the two cases it is:
|
||||||
|
*/
|
||||||
|
if (to_adreno_gpu(gpu)->fwloc == FW_LOCATION_LEGACY) {
|
||||||
|
ret = qcom_mdt_load(dev, fw, fwname, GPU_PAS_ID,
|
||||||
|
mem_region, mem_phys, mem_size);
|
||||||
|
} else {
|
||||||
|
char newname[strlen("qcom/") + strlen(fwname) + 1];
|
||||||
|
|
||||||
|
sprintf(newname, "qcom/%s", fwname);
|
||||||
|
|
||||||
|
ret = qcom_mdt_load(dev, fw, newname, GPU_PAS_ID,
|
||||||
|
mem_region, mem_phys, mem_size);
|
||||||
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
|
@ -69,15 +69,72 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname)
|
||||||
{
|
{
|
||||||
struct drm_device *drm = adreno_gpu->base.dev;
|
struct drm_device *drm = adreno_gpu->base.dev;
|
||||||
const struct firmware *fw = NULL;
|
const struct firmware *fw = NULL;
|
||||||
|
char newname[strlen("qcom/") + strlen(fwname) + 1];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = request_firmware(&fw, fwname, drm->dev);
|
sprintf(newname, "qcom/%s", fwname);
|
||||||
if (ret) {
|
|
||||||
dev_err(drm->dev, "failed to load %s: %d\n", fwname, ret);
|
/*
|
||||||
return ERR_PTR(ret);
|
* Try first to load from qcom/$fwfile using a direct load (to avoid
|
||||||
|
* a potential timeout waiting for usermode helper)
|
||||||
|
*/
|
||||||
|
if ((adreno_gpu->fwloc == FW_LOCATION_UNKNOWN) ||
|
||||||
|
(adreno_gpu->fwloc == FW_LOCATION_NEW)) {
|
||||||
|
|
||||||
|
ret = request_firmware_direct(&fw, newname, drm->dev);
|
||||||
|
if (!ret) {
|
||||||
|
dev_info(drm->dev, "loaded %s from new location\n",
|
||||||
|
newname);
|
||||||
|
adreno_gpu->fwloc = FW_LOCATION_NEW;
|
||||||
|
return fw;
|
||||||
|
} else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
|
||||||
|
dev_err(drm->dev, "failed to load %s: %d\n",
|
||||||
|
newname, ret);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fw;
|
/*
|
||||||
|
* Then try the legacy location without qcom/ prefix
|
||||||
|
*/
|
||||||
|
if ((adreno_gpu->fwloc == FW_LOCATION_UNKNOWN) ||
|
||||||
|
(adreno_gpu->fwloc == FW_LOCATION_LEGACY)) {
|
||||||
|
|
||||||
|
ret = request_firmware_direct(&fw, fwname, drm->dev);
|
||||||
|
if (!ret) {
|
||||||
|
dev_info(drm->dev, "loaded %s from legacy location\n",
|
||||||
|
newname);
|
||||||
|
adreno_gpu->fwloc = FW_LOCATION_LEGACY;
|
||||||
|
return fw;
|
||||||
|
} else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
|
||||||
|
dev_err(drm->dev, "failed to load %s: %d\n",
|
||||||
|
fwname, ret);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Finally fall back to request_firmware() for cases where the
|
||||||
|
* usermode helper is needed (I think mainly android)
|
||||||
|
*/
|
||||||
|
if ((adreno_gpu->fwloc == FW_LOCATION_UNKNOWN) ||
|
||||||
|
(adreno_gpu->fwloc == FW_LOCATION_HELPER)) {
|
||||||
|
|
||||||
|
ret = request_firmware(&fw, newname, drm->dev);
|
||||||
|
if (!ret) {
|
||||||
|
dev_info(drm->dev, "loaded %s with helper\n",
|
||||||
|
newname);
|
||||||
|
adreno_gpu->fwloc = FW_LOCATION_HELPER;
|
||||||
|
return fw;
|
||||||
|
} else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
|
||||||
|
dev_err(drm->dev, "failed to load %s: %d\n",
|
||||||
|
newname, ret);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_err(drm->dev, "failed to load %s\n", fwname);
|
||||||
|
return ERR_PTR(-ENOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int adreno_load_fw(struct adreno_gpu *adreno_gpu)
|
static int adreno_load_fw(struct adreno_gpu *adreno_gpu)
|
||||||
|
|
|
@ -101,6 +101,27 @@ struct adreno_gpu {
|
||||||
/* interesting register offsets to dump: */
|
/* interesting register offsets to dump: */
|
||||||
const unsigned int *registers;
|
const unsigned int *registers;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Are we loading fw from legacy path? Prior to addition
|
||||||
|
* of gpu firmware to linux-firmware, the fw files were
|
||||||
|
* placed in toplevel firmware directory, following qcom's
|
||||||
|
* android kernel. But linux-firmware preferred they be
|
||||||
|
* placed in a 'qcom' subdirectory.
|
||||||
|
*
|
||||||
|
* For backwards compatibility, we try first to load from
|
||||||
|
* the new path, using request_firmware_direct() to avoid
|
||||||
|
* any potential timeout waiting for usermode helper, then
|
||||||
|
* fall back to the old path (with direct load). And
|
||||||
|
* finally fall back to request_firmware() with the new
|
||||||
|
* path to allow the usermode helper.
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
FW_LOCATION_UNKNOWN = 0,
|
||||||
|
FW_LOCATION_NEW, /* /lib/firmware/qcom/$fwfile */
|
||||||
|
FW_LOCATION_LEGACY, /* /lib/firmware/$fwfile */
|
||||||
|
FW_LOCATION_HELPER,
|
||||||
|
} fwloc;
|
||||||
|
|
||||||
/* firmware: */
|
/* firmware: */
|
||||||
const struct firmware *pm4, *pfp;
|
const struct firmware *pm4, *pfp;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue