Commit 900fc60d authored by Bjorn Andersson's avatar Bjorn Andersson

remoteproc: qcom_q6v5_mss: Don't reassign mpss region on shutdown

Trying to reclaim mpss memory while the mba is not running causes the
system to crash on devices with security fuses blown, so leave it
assigned to the remote on shutdown and recover it on a subsequent boot.

Fixes: 6c5a9dc2 ("remoteproc: qcom: Make secure world call for mem ownership switch")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: default avatarSibi Sankar <sibis@codeaurora.org>
Tested-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/20200304194729.27979-2-sibis@codeaurora.orgSigned-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
parent bb6d3fb3
...@@ -1001,11 +1001,6 @@ static void q6v5_mba_reclaim(struct q6v5 *qproc) ...@@ -1001,11 +1001,6 @@ static void q6v5_mba_reclaim(struct q6v5 *qproc)
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
} }
ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm,
false, qproc->mpss_phys,
qproc->mpss_size);
WARN_ON(ret);
q6v5_reset_assert(qproc); q6v5_reset_assert(qproc);
q6v5_clk_disable(qproc->dev, qproc->reset_clks, q6v5_clk_disable(qproc->dev, qproc->reset_clks,
...@@ -1095,6 +1090,14 @@ static int q6v5_mpss_load(struct q6v5 *qproc) ...@@ -1095,6 +1090,14 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K); max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K);
} }
/**
* In case of a modem subsystem restart on secure devices, the modem
* memory can be reclaimed only after MBA is loaded. For modem cold
* boot this will be a nop
*/
q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false,
qproc->mpss_phys, qproc->mpss_size);
mpss_reloc = relocate ? min_addr : qproc->mpss_phys; mpss_reloc = relocate ? min_addr : qproc->mpss_phys;
qproc->mpss_reloc = mpss_reloc; qproc->mpss_reloc = mpss_reloc;
/* Load firmware segments */ /* Load firmware segments */
...@@ -1184,8 +1187,16 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc, ...@@ -1184,8 +1187,16 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc,
void *ptr = rproc_da_to_va(rproc, segment->da, segment->size); void *ptr = rproc_da_to_va(rproc, segment->da, segment->size);
/* Unlock mba before copying segments */ /* Unlock mba before copying segments */
if (!qproc->dump_mba_loaded) if (!qproc->dump_mba_loaded) {
ret = q6v5_mba_load(qproc); ret = q6v5_mba_load(qproc);
if (!ret) {
/* Reset ownership back to Linux to copy segments */
ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm,
false,
qproc->mpss_phys,
qproc->mpss_size);
}
}
if (!ptr || ret) if (!ptr || ret)
memset(dest, 0xff, segment->size); memset(dest, 0xff, segment->size);
...@@ -1196,8 +1207,14 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc, ...@@ -1196,8 +1207,14 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc,
/* Reclaim mba after copying segments */ /* Reclaim mba after copying segments */
if (qproc->dump_segment_mask == qproc->dump_complete_mask) { if (qproc->dump_segment_mask == qproc->dump_complete_mask) {
if (qproc->dump_mba_loaded) if (qproc->dump_mba_loaded) {
/* Try to reset ownership back to Q6 */
q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm,
true,
qproc->mpss_phys,
qproc->mpss_size);
q6v5_mba_reclaim(qproc); q6v5_mba_reclaim(qproc);
}
} }
} }
...@@ -1237,10 +1254,6 @@ static int q6v5_start(struct rproc *rproc) ...@@ -1237,10 +1254,6 @@ static int q6v5_start(struct rproc *rproc)
return 0; return 0;
reclaim_mpss: reclaim_mpss:
xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm,
false, qproc->mpss_phys,
qproc->mpss_size);
WARN_ON(xfermemop_ret);
q6v5_mba_reclaim(qproc); q6v5_mba_reclaim(qproc);
return ret; return ret;
......
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