allwinner: Add security setup
Some peripherals are TrustZone aware, so they need to be configured to
be accessible from non-secure world, as we don't need any of them being
exclusive to the secure world.
This affects some clocks, DMA channels and the Secure Peripheral
Controller (SPC). The latter controls access to most devices, but is not
active unless booting with the secure boot fuse burnt.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
diff --git a/plat/allwinner/common/sunxi_security.c b/plat/allwinner/common/sunxi_security.c
new file mode 100644
index 0000000..e760072
--- /dev/null
+++ b/plat/allwinner/common/sunxi_security.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <mmio.h>
+#include <sunxi_mmap.h>
+
+#ifdef SUNXI_SPC_BASE
+#define SPC_DECPORT_STA_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0x4)
+#define SPC_DECPORT_SET_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0x8)
+#define SPC_DECPORT_CLR_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0xc)
+#endif
+
+#define R_PRCM_SEC_SWITCH_REG 0x1d0
+#define DMA_SEC_REG 0x20
+
+/*
+ * Setup the peripherals to be accessible by non-secure world.
+ * This will not work for the Secure Peripherals Controller (SPC) unless
+ * a fuse it burnt (seems to be an erratum), but we do it nevertheless,
+ * to allow booting on boards using secure boot.
+ */
+void sunxi_security_setup(void)
+{
+ int i;
+
+#ifdef SUNXI_SPC_BASE
+ INFO("Configuring SPC Controller\n");
+ /* SPC setup: set all devices to non-secure */
+ for (i = 0; i < 6; i++)
+ mmio_write_32(SPC_DECPORT_SET_REG(i), 0xff);
+#endif
+
+ /* set MBUS clocks, bus clocks (AXI/AHB/APB) and PLLs to non-secure */
+ mmio_write_32(SUNXI_CCU_SEC_SWITCH_REG, 0x7);
+
+ /* set R_PRCM clocks to non-secure */
+ mmio_write_32(SUNXI_R_PRCM_BASE + R_PRCM_SEC_SWITCH_REG, 0x7);
+
+ /* Set all DMA channels (16 max.) to non-secure */
+ mmio_write_32(SUNXI_DMA_BASE + DMA_SEC_REG, 0xffff);
+}