mbox series

[0/3] Apple Mailbox Controller support

Message ID 20210907145501.69161-1-sven@svenpeter.dev (mailing list archive)
Headers show
Series Apple Mailbox Controller support | expand

Message

Sven Peter Sept. 7, 2021, 2:54 p.m. UTC
Hi,

This series adds support for the mailbox HW found in the Apple M1. These SoCs
have various co-processors controlling different peripherals (NVMe, display
controller, SMC (required for WiFi), Thunderbolt, and probably more
we don't know about yet). All these co-processors communicate with the main CPU
using these mailboxes. These mailboxes transmit 64+32 bit messages, are
backed by a hardware FIFO and have four interrupts (FIFO empty and FIFO not
empty for the transmit and receive FIFO each).

The hardware itself allows to send 64+32 bit message using two hardware
registers. A write to or read from the second register transmits or receives a
message. Usually, the first 64 bit register is used for the message itself and 
8 bits of the second register are used as an endpoint. I originally considered
to have the endpoint exposed as a mailbox-channel, but finally decided against
it: The hardware itself only provides a single channel to the co-processor and
the endpoint bits are only an implementation detail of the firmware. There's
even one co-processor (SEP) which uses 8 bits of the first register as its
endpoint number instead.
There was a similar discussion about the BCM2835 / Raspberry Pi mailboxes
which came to the same conclusion [1].

These mailboxes also have a hardware FIFO which make implementing them with the
current mailbox a bit tricky: There is no "transmission done" interrupt because
most transmissions are "done" immediately. There is only a "transmission fifo
empty" level interrupt. I have instead implemented this by adding a fast-path to
the core mailbox code as a new txready_fifo mode.
The other possibilities (which would not require any changes to the core mailbox
code) are to either use the polling mode or to enable the "tx fifo empty"
interrupt in send_message and then call txready from the irq handler before
disabling it again. I'd like to avoid those though since so far I've never seen
the TX FIFO run full which allows to almost always avoid the context switch when
sending a message. I can easily switch to one of these modes if you prefer to
keep the core code untouched though.


Best,

Sven

Sven Peter (3):
  mailbox: Add txdone_fifo
  dt-bindings: mailbox: Add Apple mailbox bindings
  mailbox: apple: Add driver for Apple mailboxes

 .../bindings/mailbox/apple,mailbox.yaml       |  81 ++++
 MAINTAINERS                                   |   3 +
 drivers/mailbox/Kconfig                       |  12 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/apple-mailbox.c               | 432 ++++++++++++++++++
 drivers/mailbox/mailbox.c                     |  66 ++-
 drivers/mailbox/mailbox.h                     |   1 +
 include/linux/apple-mailbox.h                 |  18 +
 include/linux/mailbox_controller.h            |  15 +
 9 files changed, 621 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml
 create mode 100644 drivers/mailbox/apple-mailbox.c
 create mode 100644 include/linux/apple-mailbox.h

Comments

Jassi Brar Sept. 8, 2021, 8:48 p.m. UTC | #1
On Tue, Sep 7, 2021 at 9:55 AM Sven Peter <sven@svenpeter.dev> wrote:
>
> Hi,
>
> This series adds support for the mailbox HW found in the Apple M1. These SoCs
> have various co-processors controlling different peripherals (NVMe, display
> controller, SMC (required for WiFi), Thunderbolt, and probably more
> we don't know about yet). All these co-processors communicate with the main CPU
> using these mailboxes. These mailboxes transmit 64+32 bit messages, are
> backed by a hardware FIFO and have four interrupts (FIFO empty and FIFO not
> empty for the transmit and receive FIFO each).
>
> The hardware itself allows to send 64+32 bit message using two hardware
> registers. A write to or read from the second register transmits or receives a
> message. Usually, the first 64 bit register is used for the message itself and
> 8 bits of the second register are used as an endpoint. I originally considered
> to have the endpoint exposed as a mailbox-channel, but finally decided against
> it: The hardware itself only provides a single channel to the co-processor and
> the endpoint bits are only an implementation detail of the firmware. There's
> even one co-processor (SEP) which uses 8 bits of the first register as its
> endpoint number instead.
> There was a similar discussion about the BCM2835 / Raspberry Pi mailboxes
> which came to the same conclusion [1].
>
> These mailboxes also have a hardware FIFO which make implementing them with the
> current mailbox a bit tricky: There is no "transmission done" interrupt because
> most transmissions are "done" immediately. There is only a "transmission fifo
> empty" level interrupt. I have instead implemented this by adding a fast-path to
> the core mailbox code as a new txready_fifo mode.
> The other possibilities (which would not require any changes to the core mailbox
> code) are to either use the polling mode or to enable the "tx fifo empty"
> interrupt in send_message and then call txready from the irq handler before
> disabling it again. I'd like to avoid those though since so far I've never seen
> the TX FIFO run full which allows to almost always avoid the context switch when
> sending a message. I can easily switch to one of these modes if you prefer to
> keep the core code untouched though.
>
Yes, please keep the api unchanged.
Let us please not dig our own tunnels when the existing ways serve the purpose.

Thanks.
Sven Peter Sept. 9, 2021, 10:44 a.m. UTC | #2
On Wed, Sep 8, 2021, at 22:48, Jassi Brar wrote:
> On Tue, Sep 7, 2021 at 9:55 AM Sven Peter <sven@svenpeter.dev> wrote:
> >
> > Hi,
> >
> > This series adds support for the mailbox HW found in the Apple M1. These SoCs
> > have various co-processors controlling different peripherals (NVMe, display
> > controller, SMC (required for WiFi), Thunderbolt, and probably more
> > we don't know about yet). All these co-processors communicate with the main CPU
> > using these mailboxes. These mailboxes transmit 64+32 bit messages, are
> > backed by a hardware FIFO and have four interrupts (FIFO empty and FIFO not
> > empty for the transmit and receive FIFO each).
> >
> > The hardware itself allows to send 64+32 bit message using two hardware
> > registers. A write to or read from the second register transmits or receives a
> > message. Usually, the first 64 bit register is used for the message itself and
> > 8 bits of the second register are used as an endpoint. I originally considered
> > to have the endpoint exposed as a mailbox-channel, but finally decided against
> > it: The hardware itself only provides a single channel to the co-processor and
> > the endpoint bits are only an implementation detail of the firmware. There's
> > even one co-processor (SEP) which uses 8 bits of the first register as its
> > endpoint number instead.
> > There was a similar discussion about the BCM2835 / Raspberry Pi mailboxes
> > which came to the same conclusion [1].
> >
> > These mailboxes also have a hardware FIFO which make implementing them with the
> > current mailbox a bit tricky: There is no "transmission done" interrupt because
> > most transmissions are "done" immediately. There is only a "transmission fifo
> > empty" level interrupt. I have instead implemented this by adding a fast-path to
> > the core mailbox code as a new txready_fifo mode.
> > The other possibilities (which would not require any changes to the core mailbox
> > code) are to either use the polling mode or to enable the "tx fifo empty"
> > interrupt in send_message and then call txready from the irq handler before
> > disabling it again. I'd like to avoid those though since so far I've never seen
> > the TX FIFO run full which allows to almost always avoid the context switch when
> > sending a message. I can easily switch to one of these modes if you prefer to
> > keep the core code untouched though.
> >
> Yes, please keep the api unchanged.
> Let us please not dig our own tunnels when the existing ways serve the purpose.
> 

Ok, I'll use txdone_irq for v2 then and just ignore the HW FIFO.

Thanks,

Sven