Merge "dsp: Enable remoteproc on adsp-loader" into audio-kernel.lnx.5.10
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
7b85983896
@@ -16,7 +16,9 @@
|
|||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/nvmem-consumer.h>
|
#include <linux/nvmem-consumer.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <soc/qcom/subsystem_restart.h>
|
#include <linux/remoteproc.h>
|
||||||
|
#include <linux/remoteproc/qcom_rproc.h>
|
||||||
|
|
||||||
|
|
||||||
#define Q6_PIL_GET_DELAY_MS 100
|
#define Q6_PIL_GET_DELAY_MS 100
|
||||||
#define BOOT_CMD 1
|
#define BOOT_CMD 1
|
||||||
@@ -24,11 +26,11 @@
|
|||||||
#define IMAGE_UNLOAD_CMD 0
|
#define IMAGE_UNLOAD_CMD 0
|
||||||
#define MAX_FW_IMAGES 4
|
#define MAX_FW_IMAGES 4
|
||||||
|
|
||||||
enum apr_subsys_state {
|
enum spf_subsys_state {
|
||||||
APR_SUBSYS_DOWN,
|
SPF_SUBSYS_DOWN,
|
||||||
APR_SUBSYS_UP,
|
SPF_SUBSYS_UP,
|
||||||
APR_SUBSYS_LOADED,
|
SPF_SUBSYS_LOADED,
|
||||||
APR_SUBSYS_UNKNOWN,
|
SPF_SUBSYS_UNKNOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t adsp_boot_store(struct kobject *kobj,
|
static ssize_t adsp_boot_store(struct kobject *kobj,
|
||||||
@@ -62,52 +64,6 @@ static struct work_struct adsp_ldr_work;
|
|||||||
static struct platform_device *adsp_private;
|
static struct platform_device *adsp_private;
|
||||||
static void adsp_loader_unload(struct platform_device *pdev);
|
static void adsp_loader_unload(struct platform_device *pdev);
|
||||||
|
|
||||||
static int adsp_restart_subsys(void)
|
|
||||||
{
|
|
||||||
struct subsys_device *adsp_dev = NULL;
|
|
||||||
struct platform_device *pdev = adsp_private;
|
|
||||||
struct adsp_loader_private *priv = NULL;
|
|
||||||
int rc = -EINVAL;
|
|
||||||
|
|
||||||
priv = platform_get_drvdata(pdev);
|
|
||||||
if (!priv)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
adsp_dev = (struct subsys_device *)priv->pil_h;
|
|
||||||
if (!adsp_dev)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
/* subsystem_restart_dev has worker queue to handle */
|
|
||||||
rc = subsystem_restart_dev(adsp_dev);
|
|
||||||
if (rc) {
|
|
||||||
dev_err(&pdev->dev, "subsystem_restart_dev failed\n");
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
pr_debug("%s :: Restart Success %d\n", __func__, rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void adsp_load_state_notify_cb(enum apr_subsys_state state,
|
|
||||||
void *phandle)
|
|
||||||
{
|
|
||||||
struct platform_device *pdev = adsp_private;
|
|
||||||
struct adsp_loader_private *priv = NULL;
|
|
||||||
|
|
||||||
priv = platform_get_drvdata(pdev);
|
|
||||||
if (!priv)
|
|
||||||
return;
|
|
||||||
if (phandle != adsp_private) {
|
|
||||||
pr_err("%s:callback is not for adsp-loader client\n", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pr_debug("%s:: Received cb for ADSP restart\n", __func__);
|
|
||||||
if (state == APR_SUBSYS_UNKNOWN)
|
|
||||||
adsp_restart_subsys();
|
|
||||||
else
|
|
||||||
pr_debug("%s:Ignore restart request for ADSP", __func__);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void adsp_load_fw(struct work_struct *adsp_ldr_work)
|
static void adsp_load_fw(struct work_struct *adsp_ldr_work)
|
||||||
{
|
{
|
||||||
@@ -116,8 +72,10 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work)
|
|||||||
const char *adsp_dt = "qcom,adsp-state";
|
const char *adsp_dt = "qcom,adsp-state";
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
u32 adsp_state;
|
u32 adsp_state;
|
||||||
const char *img_name;
|
struct property *prop;
|
||||||
// void *padsp_restart_cb = &adsp_load_state_notify_cb;
|
int size;
|
||||||
|
phandle rproc_phandle;
|
||||||
|
struct rproc *rproc;
|
||||||
|
|
||||||
if (!pdev) {
|
if (!pdev) {
|
||||||
dev_err(&pdev->dev, "%s: Platform device null\n", __func__);
|
dev_err(&pdev->dev, "%s: Platform device null\n", __func__);
|
||||||
@@ -130,6 +88,13 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv = platform_get_drvdata(pdev);
|
||||||
|
if (!priv) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
" %s: Private data get failed\n", __func__);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
rc = of_property_read_u32(pdev->dev.of_node, adsp_dt, &adsp_state);
|
rc = of_property_read_u32(pdev->dev.of_node, adsp_dt, &adsp_state);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
@@ -137,84 +102,68 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = of_property_read_string(pdev->dev.of_node,
|
prop = of_find_property(pdev->dev.of_node, "qcom,proc-img-to-load",
|
||||||
"qcom,proc-img-to-load",
|
&size);
|
||||||
&img_name);
|
if (!prop) {
|
||||||
|
|
||||||
if (rc) {
|
|
||||||
dev_dbg(&pdev->dev,
|
dev_dbg(&pdev->dev,
|
||||||
"%s: loading default image ADSP\n", __func__);
|
"%s: loading default image ADSP\n", __func__);
|
||||||
goto load_adsp;
|
goto load_adsp;
|
||||||
}
|
}
|
||||||
if (!strcmp(img_name, "modem")) {
|
|
||||||
/* adsp_state always returns "0". So load modem image based on
|
|
||||||
* apr_modem_state to prevent loading of image twice
|
|
||||||
*/
|
|
||||||
//adsp_state = apr_get_modem_state();
|
|
||||||
if (adsp_state == APR_SUBSYS_DOWN) {
|
|
||||||
priv = platform_get_drvdata(pdev);
|
|
||||||
if (!priv) {
|
|
||||||
dev_err(&pdev->dev,
|
|
||||||
" %s: Private data get failed\n", __func__);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->pil_h = subsystem_get("modem");
|
rproc_phandle = be32_to_cpup(prop->value);
|
||||||
if (IS_ERR(priv->pil_h)) {
|
priv->pil_h = rproc_get_by_phandle(rproc_phandle);
|
||||||
|
if (!priv->pil_h)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
rproc = priv->pil_h;
|
||||||
|
if (!strcmp(rproc->name, "modem")) {
|
||||||
|
if (adsp_state == SPF_SUBSYS_DOWN) {
|
||||||
|
rc = rproc_boot(priv->pil_h);
|
||||||
|
if (IS_ERR(priv->pil_h) || rc) {
|
||||||
dev_err(&pdev->dev, "%s: pil get failed,\n",
|
dev_err(&pdev->dev, "%s: pil get failed,\n",
|
||||||
__func__);
|
__func__);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the state of the ADSP in APR driver */
|
} else if (adsp_state == SPF_SUBSYS_LOADED) {
|
||||||
//apr_set_modem_state(APR_SUBSYS_LOADED);
|
|
||||||
} else if (adsp_state == APR_SUBSYS_LOADED) {
|
|
||||||
dev_dbg(&pdev->dev,
|
dev_dbg(&pdev->dev,
|
||||||
"%s: MDSP state = %x\n", __func__, adsp_state);
|
"%s: MDSP state = %x\n", __func__, adsp_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "%s: Q6/MDSP image is loaded\n", __func__);
|
dev_dbg(&pdev->dev, "%s: Q6/MDSP image is loaded\n", __func__);
|
||||||
goto success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
load_adsp:
|
load_adsp:
|
||||||
{
|
{
|
||||||
|
prop = of_find_property(pdev->dev.of_node, "qcom,rproc-handle",
|
||||||
|
&size);
|
||||||
|
if (!prop) {
|
||||||
|
dev_err(&pdev->dev, "Missing remotproc handle\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
rproc_phandle = be32_to_cpup(prop->value);
|
||||||
|
priv->pil_h = rproc_get_by_phandle(rproc_phandle);
|
||||||
|
if (!priv->pil_h)
|
||||||
|
goto fail;
|
||||||
adsp_state = spf_core_is_apm_ready();
|
adsp_state = spf_core_is_apm_ready();
|
||||||
if (adsp_state == APR_SUBSYS_DOWN) {
|
if (adsp_state == SPF_SUBSYS_DOWN) {
|
||||||
priv = platform_get_drvdata(pdev);
|
rc = rproc_boot(priv->pil_h);
|
||||||
if (!priv) {
|
if (rc) {
|
||||||
dev_err(&pdev->dev,
|
|
||||||
" %s: Private data get failed\n", __func__);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (!priv->adsp_fw_name) {
|
|
||||||
dev_dbg(&pdev->dev, "%s: Load default ADSP\n",
|
|
||||||
__func__);
|
|
||||||
priv->pil_h = subsystem_get("adsp");
|
|
||||||
} else {
|
|
||||||
dev_dbg(&pdev->dev, "%s: Load ADSP with fw name %s\n",
|
|
||||||
__func__, priv->adsp_fw_name);
|
|
||||||
priv->pil_h = subsystem_get_with_fwname("adsp", priv->adsp_fw_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_ERR(priv->pil_h)) {
|
|
||||||
dev_err(&pdev->dev, "%s: pil get failed,\n",
|
dev_err(&pdev->dev, "%s: pil get failed,\n",
|
||||||
__func__);
|
__func__);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
} else if (adsp_state == APR_SUBSYS_LOADED) {
|
} else if (adsp_state == SPF_SUBSYS_LOADED) {
|
||||||
dev_dbg(&pdev->dev,
|
dev_dbg(&pdev->dev,
|
||||||
"%s: ADSP state = %x\n", __func__, adsp_state);
|
"%s: ADSP state = %x\n", __func__, adsp_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "%s: Q6/ADSP image is loaded\n", __func__);
|
dev_dbg(&pdev->dev, "%s: Q6/ADSP image is loaded\n", __func__);
|
||||||
// apr_register_adsp_state_cb(padsp_restart_cb, adsp_private);
|
return;
|
||||||
goto success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
dev_err(&pdev->dev, "%s: Q6 image loading failed\n", __func__);
|
dev_err(&pdev->dev, "%s: Q6 image loading failed\n", __func__);
|
||||||
success:
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adsp_loader_do(struct platform_device *pdev)
|
static void adsp_loader_do(struct platform_device *pdev)
|
||||||
@@ -228,15 +177,15 @@ static ssize_t adsp_ssr_store(struct kobject *kobj,
|
|||||||
size_t count)
|
size_t count)
|
||||||
{
|
{
|
||||||
int ssr_command = 0;
|
int ssr_command = 0;
|
||||||
|
struct rproc *adsp_dev = NULL;
|
||||||
struct platform_device *pdev = adsp_private;
|
struct platform_device *pdev = adsp_private;
|
||||||
struct adsp_loader_private *priv = NULL;
|
struct adsp_loader_private *priv = NULL;
|
||||||
int rc = -EINVAL;
|
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "%s: going to call adsp ssr\n ", __func__);
|
dev_dbg(&pdev->dev, "%s: going to call adsp ssr\n ", __func__);
|
||||||
|
|
||||||
priv = platform_get_drvdata(pdev);
|
priv = platform_get_drvdata(pdev);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return rc;
|
return -EINVAL;
|
||||||
|
|
||||||
if (kstrtoint(buf, 10, &ssr_command) < 0)
|
if (kstrtoint(buf, 10, &ssr_command) < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -244,7 +193,15 @@ static ssize_t adsp_ssr_store(struct kobject *kobj,
|
|||||||
if (ssr_command != SSR_RESET_CMD)
|
if (ssr_command != SSR_RESET_CMD)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
adsp_restart_subsys();
|
adsp_dev = (struct rproc *)priv->pil_h;
|
||||||
|
if (!adsp_dev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dev_err(&pdev->dev, "requesting for ADSP restart\n");
|
||||||
|
|
||||||
|
/* subsystem_restart_dev has worker queue to handle */
|
||||||
|
rproc_report_crash(adsp_dev, RPROC_FATAL_ERROR);
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "%s :: ADSP restarted\n", __func__);
|
dev_dbg(&pdev->dev, "%s :: ADSP restarted\n", __func__);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@@ -281,8 +238,7 @@ static void adsp_loader_unload(struct platform_device *pdev)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (priv->pil_h) {
|
if (priv->pil_h) {
|
||||||
dev_dbg(&pdev->dev, "%s: calling subsystem put\n", __func__);
|
rproc_shutdown(priv->pil_h);
|
||||||
subsystem_put(priv->pil_h);
|
|
||||||
priv->pil_h = NULL;
|
priv->pil_h = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,7 +308,7 @@ static int adsp_loader_remove(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (priv->pil_h) {
|
if (priv->pil_h) {
|
||||||
subsystem_put(priv->pil_h);
|
rproc_shutdown(priv->pil_h);
|
||||||
priv->pil_h = NULL;
|
priv->pil_h = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user