Re: [PATCH 7/7] mailbox: goog-mba: Introduce the goog-mba mailbox driver

From: Jassi Brar

Date: Sun Sep 20 2026 - 16:30:13 EST


On Sat, Sep 19, 2026 at 3:40 PM Doug Anderson <dianders@xxxxxxxxxxxx> wrote:

>
> Imagine we have three clocks: They are: "clk_i2c1", "clk_i2c2", and
> "clk_spi". The "clk_i2c1" needs to be turned on when we're going to
> start an I2C transfer on I2C bus 1. "clk_i2c2" is the same but for the
> I2C bus 2. "clk_spi" needs to be turned on when we want to start a a
> SPI transfer.
>
clk_prepare() is allowed to sleep, so any path, that includes the
call, can not be expected to have low or even deterministic latency.


> In the i2c/spi drivers, we've got "clk_prepare(clk)" calls to turn on
> the clocks. The three clocks are operated independently by their
> respective users. An I2C or SPI transfer may take place at any time.
> The I2C and SPI drivers need to know for sure when the clock has
> finished enabling because as soon as the clk_prepare() calls return
> they will start transferring.
>
> All three clocks are backed by a single clock driver. We'll call it
> the "clk_mailbox" driver. The "clk_mailbox" driver takes the request
> to turn on the clock and encodes it as a mailbox message to a remote
> processor. Let's imagine that the mailbox message looks like a 2-word
> transfer. The first word contains a 0 or a 1 for enable/disable and
> the second word contains the ID of the clock: 0 for "clk_i2c1", 1 for
> "clk_i2c2", and 2 for "clk_i3c3".
>
> Now, imagine that we want to turn on all three clocks simultaneously.

Why? (not that it can't be done) I2C and SPI clients run independent
of each other.


> The "clk_mailbox" driver will see 3 calls to turn on the clocks and it
> needs to convert those to messages to send the remote processor. It
> will then call mbox_send_message() to queue those messages with the
> mailbox controller. In other words, we'll see these three calls happen
> nearly simultaneously:
>
> mbox_send_message(chan, &{0x1, 0x0});
> mbox_send_message(chan, &{0x1, 0x1});
> mbox_send_message(chan, &{0x1, 0x2});
>
> The LGA mailbox controller knows "txdone". That is, when the remote
> processor "acks" a message, the LGA mailbox controller can tell (and
> get an interrupt). This "ack" signals that the clock has finished
> enabling. This means that the "clk_mailbox" cannot run the state
> machine and it can't call "txdone" itself.
>
> Without my patches, when the above 3 mbox_send_message() calls are
> made, the first one will go straight to the LGA mailbox controller and
> the second two will be queued up. Once the "txdone" for the first
> message arrives, we'll queue the second message. Once the "txdone" for
> the second message arrives, we'll queue the third message. This means
> that the messages are not being processed simultaneously. The third
> clk_prepare() call will be processed much more slowly since it has to
> wait in line. If we had 10 clocks enabling at the same time, the 10th
> clock could have a pretty significant wait.
>
> With my patches, the LGA mailbox controller is given the second and
> third message even though the first message isn't done yet. The LGA
> mailbox controller can queue the second and third messages even though
> the txdone for the first message hasn't arrived yet. If things are
> fast enough, all three messages can be queued up before the remote
> processor has even started processing the first one. The remote
> processor can process all three messages concurrently and acknowledge
> all three at once. The LGA mailbox controller can get a single
> interrupt representing all three "txdone" ACKs and call "txdone" for
> all three messages simultaneously.
>
If your remote (host) can actually act on multiple requests parallely,
you need a way to map ACKs back onto the requests. Currently you
don't.
Looking at the goog_mba_handle_tx_interrupt() implementation, consider
the situation when 5 requests are submitted in the h/w fifo and 3 are
reported ACKed by the interrupt after some time.
You assume the three done are the first three -- which implies that
the remote handles requests in the order they arrive i.e, serially.
Otherwise, say, request-1 may be wrongly completed if the ACKs were
for requests 2, 3 & 4.
So it seems mostly an illusion of parallelism - remote is acting on
requests (or atleast sending ACKs) serially. We can keep the core
unchanged and the driver much simpler if we simply use the buffering
in the core.

Regards,
Jassi