Re: [PATCH 7/7] mailbox: goog-mba: Introduce the goog-mba mailbox driver
From: Doug Anderson
Date: Sat Sep 19 2026 - 16:42:48 EST
Hi,
On Sat, Sep 19, 2026 at 11:32 AM Jassi Brar <jassisinghbrar@xxxxxxxxx> wrote:
>
> On Wed, Sep 9, 2026 at 11:57 AM Doug Anderson <dianders@xxxxxxxxxxxx> wrote:
> >
> > > I am suggesting to consider TX-Is-Done when send_data() returns, i.e
> > > tx submitted is seen as transferred. You anyway don't catch
> > > transmission errors. That way you fill all slots without blocking on
> > > the first message and achieve this same throughput.
> > > Without knowing the clients I am not sure if that can't be done.
> >
> > We need to know the txdone and thus we can't do what you're proposing.
> > In general, queuing mailboxes are used in cases where the remote side
> > enables a resource like a clock or power domain. Different tasks in
> > the system may independently turn on/off these resources, so allowing
> > them to work "in parallel" makes sense
> >
> It will still work in parallel - you still keep writing to the h/w
> fifo without waiting for previous ones to finish as long as there is
> space. Just like you get here.
>
> . ...but each task needs to know
> > for sure when its resource is finished turning on. If we just imagine
> > 3 clocks we want to turn on.
> >
> > clk_enable(clk_a)
> > clk_enable(clk_b)
> > clk_enable(clk_c)
> >
> > Those 3 calls can be made in 3 different contexts from 3 different
> > drivers. We want all 3 enables happening in parallel with each other
> > (not one after another), but each call needs to know when its function
> > is done.
> >
> I don't see why not? The three requests will be queued into h/w fifo
> in the order they arrive without any block - just as you do now.
>
> Btw, if you mean they need to be enabled in parallel literally, they
> should not be called from three different drivers. Instead they should
> be modelled as one "composite" clock.
>
> > Does that make sense?
> >
> The usage makes sense but I still don't see why existing api can't work.
I must be missing something because I don't see how the existing API
can work. Let me explain in more detail and maybe you can tell me what
I've got wrong.
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.
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.
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.
Does the above example make sense? Can you explain how I could make
things work without changing the mailbox core?
-Doug