Skip to content

Commit ff4aa3b

Browse files
robimarkoandersson
authored andcommitted
firmware: qcom_scm: disable SDI if required
IPQ5018 has SDI (Secure Debug Image) enabled by TZ by default, and that means that WDT being asserted or just trying to reboot will hang the board in the debug mode and only pulling the power and repowering will help. Some IPQ4019 boards like Google WiFI have it enabled as well. Luckily, SDI can be disabled via an SCM call. So, lets use the boolean DT property to identify boards that have SDI enabled by default and use the SCM call to disable SDI during SCM probe. It is important to disable it as soon as possible as we might have a WDT assertion at any time which would then leave the board in debug mode, thus disabling it during SCM removal is not enough. Signed-off-by: Robert Marko <robimarko@gmail.com> Reviewed-by: Guru Das Srinagesh <quic_gurus@quicinc.com> Link: https://lore.kernel.org/r/20230816164641.3371878-2-robimarko@gmail.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
1 parent 92dab9e commit ff4aa3b

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

drivers/firmware/qcom_scm.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,29 @@ int qcom_scm_set_remote_state(u32 state, u32 id)
451451
}
452452
EXPORT_SYMBOL_GPL(qcom_scm_set_remote_state);
453453

454+
static int qcom_scm_disable_sdi(void)
455+
{
456+
int ret;
457+
struct qcom_scm_desc desc = {
458+
.svc = QCOM_SCM_SVC_BOOT,
459+
.cmd = QCOM_SCM_BOOT_SDI_CONFIG,
460+
.args[0] = 1, /* Disable watchdog debug */
461+
.args[1] = 0, /* Disable SDI */
462+
.arginfo = QCOM_SCM_ARGS(2),
463+
.owner = ARM_SMCCC_OWNER_SIP,
464+
};
465+
struct qcom_scm_res res;
466+
467+
ret = qcom_scm_clk_enable();
468+
if (ret)
469+
return ret;
470+
ret = qcom_scm_call(__scm->dev, &desc, &res);
471+
472+
qcom_scm_clk_disable();
473+
474+
return ret ? : res.result[0];
475+
}
476+
454477
static int __qcom_scm_set_dload_mode(struct device *dev, bool enable)
455478
{
456479
struct qcom_scm_desc desc = {
@@ -1850,6 +1873,13 @@ static int qcom_scm_probe(struct platform_device *pdev)
18501873
if (download_mode)
18511874
qcom_scm_set_download_mode(true);
18521875

1876+
1877+
/*
1878+
* Disable SDI if indicated by DT that it is enabled by default.
1879+
*/
1880+
if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
1881+
qcom_scm_disable_sdi();
1882+
18531883
/*
18541884
* Initialize the QSEECOM interface.
18551885
*

drivers/firmware/qcom_scm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
8080
#define QCOM_SCM_SVC_BOOT 0x01
8181
#define QCOM_SCM_BOOT_SET_ADDR 0x01
8282
#define QCOM_SCM_BOOT_TERMINATE_PC 0x02
83+
#define QCOM_SCM_BOOT_SDI_CONFIG 0x09
8384
#define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10
8485
#define QCOM_SCM_BOOT_SET_ADDR_MC 0x11
8586
#define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a

0 commit comments

Comments
 (0)