summaryrefslogtreecommitdiff
path: root/drivers/remoteproc
diff options
context:
space:
mode:
authorSarangdhar Joshi <spjoshi@codeaurora.org>2016-10-25 13:57:26 -0700
committerBjorn Andersson <bjorn.andersson@linaro.org>2016-11-16 22:32:24 -0800
commitf33a73586f4d9f23e2cbb4d978b97dc54dcdfb95 (patch)
treefba2afe4b3942b2d7c6c7ef80bca8b8aebf7f972 /drivers/remoteproc
parentcc7d54b05057acb0c6c4c57f27cfd25af823a91c (diff)
remoteproc: Add support for xo clock
Add xo clock support required to boot up Qualcomm ADSP processor. The ADSP remoteproc driver keeps xo clock enabled until the driver receives "handover" irq, in order to allow ADSP processor to vote for xo clock with rpm. Signed-off-by: Sarangdhar Joshi <spjoshi@codeaurora.org> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Diffstat (limited to 'drivers/remoteproc')
-rw-r--r--drivers/remoteproc/qcom_adsp_pil.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/remoteproc/qcom_adsp_pil.c b/drivers/remoteproc/qcom_adsp_pil.c
index 914163315091..5bb25d18c9f5 100644
--- a/drivers/remoteproc/qcom_adsp_pil.c
+++ b/drivers/remoteproc/qcom_adsp_pil.c
@@ -15,6 +15,7 @@
* GNU General Public License for more details.
*/
+#include <linux/clk.h>
#include <linux/firmware.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
@@ -48,6 +49,8 @@ struct qcom_adsp {
struct qcom_smem_state *state;
unsigned stop_bit;
+ struct clk *xo;
+
struct regulator *cx_supply;
struct completion start_done;
@@ -102,10 +105,14 @@ static int adsp_start(struct rproc *rproc)
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
int ret;
- ret = regulator_enable(adsp->cx_supply);
+ ret = clk_prepare_enable(adsp->xo);
if (ret)
return ret;
+ ret = regulator_enable(adsp->cx_supply);
+ if (ret)
+ goto disable_clocks;
+
ret = qcom_scm_pas_auth_and_reset(ADSP_PAS_ID);
if (ret) {
dev_err(adsp->dev,
@@ -126,6 +133,8 @@ static int adsp_start(struct rproc *rproc)
disable_regulators:
regulator_disable(adsp->cx_supply);
+disable_clocks:
+ clk_disable_unprepare(adsp->xo);
return ret;
}
@@ -223,6 +232,21 @@ static irqreturn_t adsp_stop_ack_interrupt(int irq, void *dev)
return IRQ_HANDLED;
}
+static int adsp_init_clock(struct qcom_adsp *adsp)
+{
+ int ret;
+
+ adsp->xo = devm_clk_get(adsp->dev, "xo");
+ if (IS_ERR(adsp->xo)) {
+ ret = PTR_ERR(adsp->xo);
+ if (ret != -EPROBE_DEFER)
+ dev_err(adsp->dev, "failed to get xo clock");
+ return ret;
+ }
+
+ return 0;
+}
+
static int adsp_init_regulator(struct qcom_adsp *adsp)
{
adsp->cx_supply = devm_regulator_get(adsp->dev, "cx");
@@ -320,6 +344,10 @@ static int adsp_probe(struct platform_device *pdev)
if (ret)
goto free_rproc;
+ ret = adsp_init_clock(adsp);
+ if (ret)
+ goto free_rproc;
+
ret = adsp_init_regulator(adsp);
if (ret)
goto free_rproc;