qti/sc7180: Do shutdown handling outside qtiseclib
With an open source SPMI driver we can now remove qtiseclib involvement
in reset and shutdown handling by setting the required registers
directly.
Change-Id: I6bf1db15734048df583daa2a4ee98701c6ece621
Signed-off-by: Julius Werner <jwerner@chromium.org>
diff --git a/plat/qti/common/src/pm8998.c b/plat/qti/common/src/pm8998.c
new file mode 100644
index 0000000..b189a8b
--- /dev/null
+++ b/plat/qti/common/src/pm8998.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/delay_timer.h>
+
+#include <qti_plat.h>
+#include <spmi_arb.h>
+
+/*
+ * This driver implements PON support for PM8998-compatible PMICs. This can
+ * include other part numbers like PM6150.
+ */
+
+#define PON_PS_HOLD_RESET_CTL 0x85a
+#define RESET_TYPE_WARM_RESET 1
+#define RESET_TYPE_SHUTDOWN 4
+
+#define PON_PS_HOLD_RESET_CTL2 0x85b
+#define S2_RESET_EN BIT(7)
+
+static void configure_ps_hold(uint32_t reset_type)
+{
+ /* QTI recommends disabling reset for 10 cycles before reconfiguring. */
+ spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, 0);
+ mdelay(1);
+
+ spmi_arb_write8(PON_PS_HOLD_RESET_CTL, reset_type);
+ spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, S2_RESET_EN);
+ mdelay(1);
+}
+
+void qti_pmic_prepare_reset(void)
+{
+ configure_ps_hold(RESET_TYPE_WARM_RESET);
+}
+
+void qti_pmic_prepare_shutdown(void)
+{
+ configure_ps_hold(RESET_TYPE_SHUTDOWN);
+}
diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c
index 4a5877c..5f1b7aa 100644
--- a/plat/qti/common/src/qti_pm.c
+++ b/plat/qti/common/src/qti_pm.c
@@ -9,6 +9,8 @@
#include <arch_helpers.h>
#include <bl31/bl31.h>
#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
#include <lib/psci/psci.h>
#include <platform.h>
@@ -204,14 +206,25 @@
/* We should never reach here */
}
+static __dead2 void assert_ps_hold(void)
+{
+ mmio_write_32(QTI_PS_HOLD_REG, 0);
+ mdelay(1000);
+
+ /* Should be dead before reaching this. */
+ panic();
+}
+
__dead2 void qti_system_off(void)
{
- qtiseclib_psci_system_off();
+ qti_pmic_prepare_shutdown();
+ assert_ps_hold();
}
__dead2 void qti_system_reset(void)
{
- qtiseclib_psci_system_reset();
+ qti_pmic_prepare_reset();
+ assert_ps_hold();
}
void qti_get_sys_suspend_power_state(psci_power_state_t *req_state)