diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9a62b55786..ce51d87ac0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -931,6 +931,7 @@ config ARCH_APPLE select DM select DM_GPIO select DM_KEYBOARD + select DM_MAILBOX select DM_SERIAL select DM_USB select DM_VIDEO diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index dd4b0ac0c3..73db2af0b8 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -10,6 +10,17 @@ config DM_MAILBOX the basis of a variety of inter-process/inter-CPU communication protocols. +config APPLE_MBOX + bool "Enable Apple IOP controller support" + depends on DM_MAILBOX && ARCH_APPLE + default y + help + Enable support for the mailboxes that provide a comminucation + channel with Apple IOP controllers integrated on Apple SoCs. + These IOP controllers are used to implement various functions + such as the System Management Controller (SMC) and NVMe and this + driver is required to get that functionality up and running. + config SANDBOX_MBOX bool "Enable the sandbox mailbox test driver" depends on DM_MAILBOX && SANDBOX diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index d2ace8cd21..59e8d0de93 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -4,6 +4,7 @@ # obj-$(CONFIG_$(SPL_)DM_MAILBOX) += mailbox-uclass.o +obj-$(CONFIG_APPLE_MBOX) += apple-mbox.o obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox.o obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox-test.o obj-$(CONFIG_STM32_IPCC) += stm32-ipcc.o diff --git a/drivers/mailbox/apple-mbox.c b/drivers/mailbox/apple-mbox.c new file mode 100644 index 0000000000..30c8e2f03f --- /dev/null +++ b/drivers/mailbox/apple-mbox.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Mark Kettenis + */ + +#include +#include +#include +#include +#include +#include + +#define REG_A2I_STAT 0x110 +#define REG_A2I_STAT_EMPTY BIT(17) +#define REG_A2I_STAT_FULL BIT(16) +#define REG_I2A_STAT 0x114 +#define REG_I2A_STAT_EMPTY BIT(17) +#define REG_I2A_STAT_FULL BIT(16) +#define REG_A2I_MSG0 0x800 +#define REG_A2I_MSG1 0x808 +#define REG_I2A_MSG0 0x830 +#define REG_I2A_MSG1 0x838 + +struct apple_mbox_priv { + void *base; +}; + +static int apple_mbox_of_xlate(struct mbox_chan *chan, + struct ofnode_phandle_args *args) +{ + if (args->args_count != 0) + return -EINVAL; + + return 0; +} + +static int apple_mbox_send(struct mbox_chan *chan, const void *data) +{ + struct apple_mbox_priv *priv = dev_get_priv(chan->dev); + const struct apple_mbox_msg *msg = data; + + writeq(msg->msg0, priv->base + REG_A2I_MSG0); + writeq(msg->msg1, priv->base + REG_A2I_MSG1); + while (readl(priv->base + REG_A2I_STAT) & REG_A2I_STAT_FULL) + udelay(1); + + return 0; +} + +static int apple_mbox_recv(struct mbox_chan *chan, void *data) +{ + struct apple_mbox_priv *priv = dev_get_priv(chan->dev); + struct apple_mbox_msg *msg = data; + + if (readl(priv->base + REG_I2A_STAT) & REG_I2A_STAT_EMPTY) + return -ENODATA; + + msg->msg0 = readq(priv->base + REG_I2A_MSG0); + msg->msg1 = readq(priv->base + REG_I2A_MSG1); + return 0; +} + +struct mbox_ops apple_mbox_ops = { + .of_xlate = apple_mbox_of_xlate, + .send = apple_mbox_send, + .recv = apple_mbox_recv, +}; + +static int apple_mbox_probe(struct udevice *dev) +{ + struct apple_mbox_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev); + if (!priv->base) + return -EINVAL; + + return 0; +} + +static const struct udevice_id apple_mbox_of_match[] = { + { .compatible = "apple,asc-mailbox-v4" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(apple_mbox) = { + .name = "apple-mbox", + .id = UCLASS_MAILBOX, + .of_match = apple_mbox_of_match, + .probe = apple_mbox_probe, + .priv_auto = sizeof(struct apple_mbox_priv), + .ops = &apple_mbox_ops, +}; diff --git a/include/linux/apple-mailbox.h b/include/linux/apple-mailbox.h new file mode 100644 index 0000000000..720fbb7029 --- /dev/null +++ b/include/linux/apple-mailbox.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +/* + * Apple mailbox message format + * + * Copyright (C) 2021 The Asahi Linux Contributors + */ + +#ifndef _LINUX_APPLE_MAILBOX_H_ +#define _LINUX_APPLE_MAILBOX_H_ + +#include + +/* encodes a single 96bit message sent over the single channel */ +struct apple_mbox_msg { + u64 msg0; + u32 msg1; +}; + +#endif