From: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
To: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: linux-remoteproc@vger.kernel.org, linux-arm-msm@vger.kernel.org,
spjoshi@codeaurora.org, kaushalk@codeaurora.org
Subject: Re: [PATCH 4/5] remoteproc: Add start and shutdown interface for q6v55
Date: Fri, 4 Nov 2016 19:16:01 +0530 [thread overview]
Message-ID: <3eddb44d-4f4b-8e34-c515-4e7cc830b22d@codeaurora.org> (raw)
In-Reply-To: <20161025192710.GP7509@tuxbot>
On 10/26/2016 12:57 AM, Bjorn Andersson wrote:
> On Mon 24 Oct 08:55 PDT 2016, Avaneesh Kumar Dwivedi wrote:
>
>> Adding start and shutdown interface to invoke q6v55 remoteproc.
>> Additionally maintaining boot count and protecting start and
>> shutdown sequence with lock.
>>
>> Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
>> ---
>> drivers/remoteproc/qcom_q6v5_pil.c | 166 +++++++++++++++++++++++++++++++++++--
>> 1 file changed, 160 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
>> index 0fac8d8..dd19d41 100644
>> --- a/drivers/remoteproc/qcom_q6v5_pil.c
>> +++ b/drivers/remoteproc/qcom_q6v5_pil.c
>> @@ -789,9 +789,8 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>> return ret < 0 ? ret : 0;
>> }
>>
>> -static int q6v5_start(struct rproc *rproc)
>> +static int q6v5_start(struct q6v5 *qproc)
>> {
>> - struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
>> int ret;
>>
>> ret = q6v5_regulator_enable(qproc);
>> @@ -873,9 +872,75 @@ static int q6v5_start(struct rproc *rproc)
>> return ret;
>> }
>>
>> -static int q6v5_stop(struct rproc *rproc)
>> +static int q6v55_start(struct q6v5 *qproc)
>> +{
> I'm sorry, but this function looks to take exactly the same steps as
> q6v5_start(). The clock handling differs and you call a different reset
> function, so please merge the clock handling and call the appropriate
> reset function based on compatible.
OK, have done away with different start functions.
>
>> + int ret;
>> +
>> + ret = q6v55_proxy_vote(qproc);
>> + if (ret) {
>> + dev_err(qproc->dev, "failed to enable supplies\n");
>> + return ret;
>> + }
>> +
>> + ret = q6v55_clk_enable(qproc);
>> + if (ret) {
>> + dev_err(qproc->dev, "failed to enable clocks\n");
>> + goto err_clks;
>> + }
>> +
>> + pil_mss_restart_reg(qproc, 0);
>> +
>> + writel_relaxed(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG);
>> +
>> + ret = q6v6proc_reset(qproc);
>> + if (ret)
>> + goto halt_axi_ports;
>> +
>> + ret = q6v5_rmb_mba_wait(qproc, 0, 5000);
>> + if (ret == -ETIMEDOUT) {
>> + dev_err(qproc->dev, "MBA boot timed out\n");
>> + goto halt_axi_ports;
>> + } else if (ret != RMB_MBA_XPU_UNLOCKED &&
>> + ret != RMB_MBA_XPU_UNLOCKED_SCRIBBLED) {
>> + dev_err(qproc->dev, "MBA returned unexpected status %d\n", ret);
>> + ret = -EINVAL;
>> + goto halt_axi_ports;
>> + }
>> +
>> + dev_info(qproc->dev, "MBA booted, loading mpss\n");
>> +
>> + ret = q6v5_mpss_load(qproc);
>> + if (ret)
>> + goto halt_axi_ports;
>> +
>> + ret = wait_for_completion_timeout(&qproc->start_done,
>> + msecs_to_jiffies(10000));
>> + if (ret == 0) {
>> + dev_err(qproc->dev, "start timed out\n");
>> + ret = -ETIMEDOUT;
>> + goto halt_axi_ports;
>> + }
>> +
>> + qproc->running = true;
>> +
>> + /* TODO: All done, release the handover resources */
>> +
>> + return 0;
>> +
>> +halt_axi_ports:
>> + q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
>> + q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
>> + q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
>> + q6v55_clk_disable(qproc);
>> +err_clks:
>> + pil_mss_restart_reg(qproc, 1);
>> + q6v55_proxy_unvote(qproc);
>> +
>> + return ret;
>> +}
>> +
>> +static int q6v5_stop(struct q6v5 *qproc)
>> {
>> - struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
>> int ret;
>>
>> qproc->running = false;
>> @@ -903,6 +968,93 @@ static int q6v5_stop(struct rproc *rproc)
>> return 0;
>> }
>>
>> +static int q6v55_stop(struct q6v5 *qproc)
>> +{
>> + int ret;
>> + u64 val;
>> +
>> + qcom_smem_state_update_bits(qproc->state,
>> + BIT(qproc->stop_bit), BIT(qproc->stop_bit));
>> +
>> + ret = wait_for_completion_timeout(&qproc->stop_done,
>> + msecs_to_jiffies(5000));
>> + if (ret == 0)
>> + dev_err(qproc->dev, "timed out on wait\n");
>> +
>> + qcom_smem_state_update_bits(qproc->state, BIT(qproc->stop_bit), 0);
>> +
>> + q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
>> + q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
>> + q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
>> +
>> + /*
>> + * Assert QDSP6 I/O clamp, memory wordline clamp, and compiler
>> + * memory clamp as a software workaround to avoid high MX
>> + * current during LPASS/MSS restart.
>> + */
>> +
>> + val = readl_relaxed(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
>> + val |= (Q6SS_CLAMP_IO | QDSP6v55_CLAMP_WL |
>> + QDSP6v55_CLAMP_QMC_MEM);
>> + writel_relaxed(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
> Is this "quirk" only for version 6? (5.5) Or should we clamp these on
> the previous versions as well?
only for q6v56
>
>> +
>> + pil_mss_restart_reg(qproc, 1);
>> + if (qproc->running) {
> Under what circumstances is will q6v55_stop() be called without
> q6v55_start() succeeding?
OK.
>
>> + q6v55_clk_disable(qproc);
>> + q6v55_proxy_unvote(qproc);
>> + qproc->running = false;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int mss_boot(struct rproc *rproc)
>> +{
>> + struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
>> + int ret;
>> +
>> + mutex_lock(&qproc->q6_lock);
>> + if (!qproc->boot_count) {
> The remoteproc framework already have a reference count and will only
> call this function in the transition from 0 to 1. So please drop this.
OK
>
>> + if (qproc->is_q6v55) {
>> + ret = q6v55_start(qproc);
>> + if (ret)
>> + goto err_start;
>> + } else {
>> + ret = q6v5_start(qproc);
>> + if (ret)
>> + goto err_start;
>> + }
>> + }
>> + qproc->boot_count++;
>> + mutex_unlock(&qproc->q6_lock);
>> + return 0;
>> +
>> +err_start:
>> + mutex_unlock(&qproc->q6_lock);
>> + if (qproc->is_q6v55)
>> + q6v55_stop(qproc);
>> + else
>> + q6v5_stop(qproc);
> The start functions should already have cleaned up all resources and
> stopped the Hexagon in case of an error, so these should not be needed.
OK, this function is removed
>
>> +
>> + return ret;
>> +}
> Please inline the few differences into the q6v5_start() and q6_stop()
> and drop these wrappers.
OK.
>
>> +
>> +static int mss_stop(struct rproc *rproc)
>> +{
>> + struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
>> + int ret;
>> +
>> + mutex_lock(&qproc->q6_lock);
>> + if (!--qproc->boot_count) {
>> + if (qproc->is_q6v55)
>> + ret = q6v55_stop(qproc);
>> + else
>> + ret = q6v5_stop(qproc);
>> + }
>> + mutex_unlock(&qproc->q6_lock);
>> + return ret;
>> +}
>> +
>> static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len)
>> {
>> struct q6v5 *qproc = rproc->priv;
>> @@ -916,8 +1068,8 @@ static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len)
>> }
>>
>> static const struct rproc_ops q6v5_ops = {
>> - .start = q6v5_start,
>> - .stop = q6v5_stop,
>> + .start = mss_boot,
>> + .stop = mss_stop,
>> .da_to_va = q6v5_da_to_va,
>> };
>>
>> @@ -972,6 +1124,8 @@ static irqreturn_t q6v5_handover_interrupt(int irq, void *dev)
>> struct q6v5 *qproc = dev;
>>
>> complete(&qproc->start_done);
>> + if (qproc->is_q6v55)
>> + q6v55_proxy_unvote(qproc);
> q6v5_start() is waiting for start_done to be completed, so please unvote
> at the point where I have the comment "TODO: All done, release the
> handover resources".
OK
>
>> return IRQ_HANDLED;
>> }
>>
> Regards,
> Bjorn
next prev parent reply other threads:[~2016-11-04 13:46 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-24 15:55 [PATCH 0/5] Self authenticating hexagon driver for q6v55 Avaneesh Kumar Dwivedi
2016-10-24 15:55 ` [PATCH 1/5] remoteproc: Add q6v55 specific parameters and enable probing " Avaneesh Kumar Dwivedi
2016-10-25 18:47 ` Bjorn Andersson
2016-11-04 13:27 ` Avaneesh Kumar Dwivedi
2016-11-08 5:28 ` Bjorn Andersson
2016-10-24 15:55 ` [PATCH 2/5] remoteproc: Adding q6v55 specific regulator, clk, reset interface Avaneesh Kumar Dwivedi
2016-10-25 19:05 ` Bjorn Andersson
2016-11-04 13:41 ` Avaneesh Kumar Dwivedi
2016-10-24 15:55 ` [PATCH 3/5] remoteproc: Adding reset sequence and halt seq changes for q6v55 Avaneesh Kumar Dwivedi
2016-10-25 19:15 ` Bjorn Andersson
2016-11-04 13:42 ` Avaneesh Kumar Dwivedi
2016-10-24 15:55 ` [PATCH 4/5] remoteproc: Add start and shutdown interface " Avaneesh Kumar Dwivedi
2016-10-25 19:27 ` Bjorn Andersson
2016-11-04 13:46 ` Avaneesh Kumar Dwivedi [this message]
2016-10-24 15:55 ` [PATCH 5/5] remoteproc: Modifying probe for initializing q6v55 specific resources Avaneesh Kumar Dwivedi
2016-10-25 19:35 ` Bjorn Andersson
2016-11-04 13:47 ` Avaneesh Kumar Dwivedi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3eddb44d-4f4b-8e34-c515-4e7cc830b22d@codeaurora.org \
--to=akdwived@codeaurora.org \
--cc=bjorn.andersson@linaro.org \
--cc=kaushalk@codeaurora.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-remoteproc@vger.kernel.org \
--cc=spjoshi@codeaurora.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.