aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/allwinner
diff options
context:
space:
mode:
authorAlistair Delva <adelva@google.com>2021-02-16 21:01:22 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-02-16 21:01:22 +0000
commitefb2826bb8160e2d8e0fcec85133a7468484f9fd (patch)
tree37a21c69306801ee7cdda5167a30896c8740155b /drivers/allwinner
parentb00a71fc312c9781fa6f404dccfb55b062b2ccac (diff)
parentfaa476c0caaa598afa5a6109d17102db5fe35ec6 (diff)
downloadplatform_external_arm-trusted-firmware-master.tar.gz
platform_external_arm-trusted-firmware-master.tar.bz2
platform_external_arm-trusted-firmware-master.zip
Original change: https://android-review.googlesource.com/c/platform/external/arm-trusted-firmware/+/1589611 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I3a25534ceed4f8e188510641080d8b8ed49b8f62
Diffstat (limited to 'drivers/allwinner')
-rw-r--r--drivers/allwinner/axp/common.c22
-rw-r--r--drivers/allwinner/sunxi_msgbox.c95
2 files changed, 116 insertions, 1 deletions
diff --git a/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c
index 13437fec8..e98b16fdb 100644
--- a/drivers/allwinner/axp/common.c
+++ b/drivers/allwinner/axp/common.c
@@ -105,6 +105,25 @@ static bool should_enable_regulator(const void *fdt, int node)
return false;
}
+static bool board_uses_usb0_host_mode(const void *fdt)
+{
+ int node, length;
+ const char *prop;
+
+ node = fdt_node_offset_by_compatible(fdt, -1,
+ "allwinner,sun8i-a33-musb");
+ if (node < 0) {
+ return false;
+ }
+
+ prop = fdt_getprop(fdt, node, "dr_mode", &length);
+ if (!prop) {
+ return false;
+ }
+
+ return !strncmp(prop, "host", length);
+}
+
void axp_setup_regulators(const void *fdt)
{
int node;
@@ -121,7 +140,8 @@ void axp_setup_regulators(const void *fdt)
}
/* This applies to AXP803 only. */
- if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
+ if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL) &&
+ board_uses_usb0_host_mode(fdt)) {
axp_clrbits(0x8f, BIT(4));
axp_setbits(0x30, BIT(2));
INFO("PMIC: Enabling DRIVEVBUS\n");
diff --git a/drivers/allwinner/sunxi_msgbox.c b/drivers/allwinner/sunxi_msgbox.c
new file mode 100644
index 000000000..cc4a6ffcb
--- /dev/null
+++ b/drivers/allwinner/sunxi_msgbox.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <drivers/delay_timer.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include <sunxi_mmap.h>
+
+#define REMOTE_IRQ_EN_REG 0x0040
+#define REMOTE_IRQ_STAT_REG 0x0050
+#define LOCAL_IRQ_EN_REG 0x0060
+#define LOCAL_IRQ_STAT_REG 0x0070
+
+#define RX_IRQ(n) BIT(0 + 2 * (n))
+#define TX_IRQ(n) BIT(1 + 2 * (n))
+
+#define FIFO_STAT_REG(n) (0x0100 + 0x4 * (n))
+#define FIFO_STAT_MASK GENMASK(0, 0)
+
+#define MSG_STAT_REG(n) (0x0140 + 0x4 * (n))
+#define MSG_STAT_MASK GENMASK(2, 0)
+
+#define MSG_DATA_REG(n) (0x0180 + 0x4 * (n))
+
+#define RX_CHAN 1
+#define TX_CHAN 0
+
+#define MHU_MAX_SLOT_ID 31
+
+#define MHU_TIMEOUT_DELAY 10
+#define MHU_TIMEOUT_ITERS 10000
+
+static DEFINE_BAKERY_LOCK(mhu_secure_message_lock);
+
+static bool sunxi_msgbox_last_tx_done(unsigned int chan)
+{
+ uint32_t stat = mmio_read_32(SUNXI_MSGBOX_BASE + REMOTE_IRQ_STAT_REG);
+
+ return (stat & RX_IRQ(chan)) == 0U;
+}
+
+static bool sunxi_msgbox_peek_data(unsigned int chan)
+{
+ uint32_t stat = mmio_read_32(SUNXI_MSGBOX_BASE + MSG_STAT_REG(chan));
+
+ return (stat & MSG_STAT_MASK) != 0U;
+}
+
+void mhu_secure_message_start(unsigned int slot_id __unused)
+{
+ uint32_t timeout = MHU_TIMEOUT_ITERS;
+
+ bakery_lock_get(&mhu_secure_message_lock);
+
+ /* Wait for all previous messages to be acknowledged. */
+ while (!sunxi_msgbox_last_tx_done(TX_CHAN) && --timeout)
+ udelay(MHU_TIMEOUT_DELAY);
+}
+
+void mhu_secure_message_send(unsigned int slot_id)
+{
+ mmio_write_32(SUNXI_MSGBOX_BASE + MSG_DATA_REG(TX_CHAN), BIT(slot_id));
+}
+
+uint32_t mhu_secure_message_wait(void)
+{
+ uint32_t timeout = MHU_TIMEOUT_ITERS;
+ uint32_t msg = 0;
+
+ /* Wait for a message from the SCP. */
+ while (!sunxi_msgbox_peek_data(RX_CHAN) && --timeout)
+ udelay(MHU_TIMEOUT_DELAY);
+
+ /* Return the most recent message in the FIFO. */
+ while (sunxi_msgbox_peek_data(RX_CHAN))
+ msg = mmio_read_32(SUNXI_MSGBOX_BASE + MSG_DATA_REG(RX_CHAN));
+
+ return msg;
+}
+
+void mhu_secure_message_end(unsigned int slot_id)
+{
+ /* Acknowledge a response by clearing the IRQ status. */
+ mmio_write_32(SUNXI_MSGBOX_BASE + LOCAL_IRQ_STAT_REG, RX_IRQ(RX_CHAN));
+
+ bakery_lock_release(&mhu_secure_message_lock);
+}