Re: [PATCH v4 3/8] mailbox: mtk-cmdq: Add driver data to support for MT8196
From: Jason-JH Lin (林睿祥)
Date: Wed Mar 05 2025 - 03:37:28 EST
Hi Angelo,
Thanks for the reviews.
On Tue, 2025-03-04 at 10:32 +0100, AngeloGioacchino Del Regno wrote:
>
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> Il 18/02/25 06:41, Jason-JH Lin ha scritto:
> > MT8196 has 3 new hardware configuration compared with the previous
> > SoC,
> > which correspond to the 3 new driver data:
> >
> > 1. mminfra_offset: For GCE data plane control
> > Since GCE has been moved into mminfra, GCE needs to append the
> > mminfra offset to the DRAM address when accessing the DRAM.
> >
> > 2. gce_vm: For GCE hardware virtualization
> > Currently, the first version of the mt8196 mailbox controller
> > only
> > requires setting the VM-related registers to enable the
> > permissions
> > of a host VM.
>
> I think that the GCE VM changes should go to a different commit, as
> that
> looks like being something not critical for basic functionality of
> the
> MMINFRA GCE.
>
> I really like seeing support for that, but please split the basic
> stuff
> from the extra functionality :-)
>
The VM configuration is the basic configuration for MT8196, so I put it
together with other configurations in one patch.
But I can understand you want the new function as a independent patch.
So I will split the VM related part, mminfra_offset part and dma_mask
part to 3 single pathes. Then add them as a driver data for MT8196 in
this patch.
> >
> > 3. dma_mask_bit: For dma address bit control
> > In order to avoid the hardware limitations of MT8196 accessing
> > DRAM,
> > GCE needs to configure the DMA address to be less than 35 bits.
> >
> > Signed-off-by: Jason-JH Lin <jason-jh.lin@xxxxxxxxxxxx>
> > ---
> > drivers/mailbox/mtk-cmdq-mailbox.c | 90
> > +++++++++++++++++++++---
> > include/linux/mailbox/mtk-cmdq-mailbox.h | 2 +
> > 2 files changed, 84 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > index d186865b8dce..0abe10a7fef9 100644
> > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > @@ -43,6 +43,17 @@
> > #define GCE_CTRL_BY_SW GENMASK(2, 0)
> > #define GCE_DDR_EN GENMASK(18, 16)
> >
> > +#define GCE_VM_ID_MAP0 0x5018
> > +#define GCE_VM_MAP0_ALL_HOST GENMASK(29, 0)
> > +#define GCE_VM_ID_MAP1 0x501c
> > +#define GCE_VM_MAP1_ALL_HOST GENMASK(29, 0)
> > +#define GCE_VM_ID_MAP2 0x5020
> > +#define GCE_VM_MAP2_ALL_HOST GENMASK(29, 0)
> > +#define GCE_VM_ID_MAP3 0x5024
> > +#define GCE_VM_MAP3_ALL_HOST GENMASK(5, 0)
> > +#define GCE_VM_CPR_GSIZE 0x50c4
> > +#define GCE_VM_CPR_GSIZE_HSOT GENMASK(3, 0)
>
> typo: GSIZE_HOST....
>
Thanks, I'll fix it.
> ...but also, if you could add some brief description of what the
> VMIDs are used for
> and what the GSIZE is... that'd be very much appreciated from whoever
> is reading
> this.
>
VMID_MAP configuration is in the previous reply mail for CK.
CPR_GSIZE is the setting for allocating the CPR SRAM size to each VM.
> The GCE stuff isn't even properly described in datasheets - I do
> (probably!)
> understand what those are for, but asking people to get years of
> experience on
> MediaTek to understand what's going on would be a bit rude, wouldn't
> it? :-D
>
I agree with you :-)
I'll put them in the VM patch and add some brief description for them.
> > +
> > #define CMDQ_THR_ACTIVE_SLOT_CYCLES 0x3200
> > #define CMDQ_THR_ENABLED 0x1
> > #define CMDQ_THR_DISABLED 0x0
> > @@ -87,11 +98,24 @@ struct cmdq {
> > struct gce_plat {
> > u32 thread_nr;
> > u8 shift;
> > + dma_addr_t mminfra_offset;
>
> It looks like this is exactly the DRAM's iostart... at least, I can
> see that in the
> downstream devicetree that's where it starts.
>
> memory: memory@80000000 {
> device_type = "memory";
> reg = <0 0x80000000 0 0x40000000>;
> };
>
> It doesn't really look like being a coincidence, but, for the sake of
> asking:
> is this just a coincidence? :-)
>
As the confirmation with the hardware designer in previous reply mail
for CK:
https://patchwork.kernel.org/project/linux-mediatek/patch/20250218054405.2017918-4-jason-jh.lin@xxxxxxxxxxxx/#26258463
Since the MMINFRA remap subtracting 2G is done in the hardware circuit
and cannot be configured by software, the address +2G adjustment is
necessary to implement in the CMDQ driver.
So that might not be a coincidence.
But even if DRAM start address changes, this mminfra_offset is still
subtracting 2G, so I think it is a better choice to define it as the
driver data for MT8196.
> > bool control_by_sw;
> > bool sw_ddr_en;
> > + bool gce_vm;
> > + u32 dma_mask_bit;
> > u32 gce_num;
> > };
> >
> > +static inline u32 cmdq_reg_shift_addr(dma_addr_t addr, const
> > struct gce_plat *pdata)
> > +{
> > + return ((addr + pdata->mminfra_offset) >> pdata->shift);
> > +}
> > +
> > +static inline u32 cmdq_reg_revert_addr(dma_addr_t addr, const
> > struct gce_plat *pdata)
> > +{
> > + return ((addr << pdata->shift) - pdata->mminfra_offset);
> > +}
>
> I'm not sure that you really need those two functions... probably
> it's simply
> cleaner and easier to just write that single line every time... and
> I'm
> saying that especially for how you're using those functions, with
> some readl()
> passed directly as param, decreasing human readability by "a whole
> lot" :-)
>
The reason why I use API wrapper instead of writing it directly in
readl() is to avoid missing the shift or mminfra_offset conversion in
some places.
This problem is not easy to debug, and I have encountered it at least
twice...
I think the advantage of using function is that it can be uniformly
modified to all places that need to handle DRAM address conversion.
What do you think? :-)
> > +
> > static void cmdq_sw_ddr_enable(struct cmdq *cmdq, bool enable)
> > {
> > WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks));
> > @@ -112,6 +136,30 @@ u8 cmdq_get_shift_pa(struct mbox_chan *chan)
> > }
> > EXPORT_SYMBOL(cmdq_get_shift_pa);
> >
> > +dma_addr_t cmdq_get_offset_pa(struct mbox_chan *chan)
> > +{
> > + struct cmdq *cmdq = container_of(chan->mbox, struct cmdq,
> > mbox);
> > +
> > + return cmdq->pdata->mminfra_offset;
> > +}
> > +EXPORT_SYMBOL(cmdq_get_offset_pa);
>
> I think I remember this get_offset_pa from the old times, then CK
> removed it (and I
> was really happy about that disappearing), or am I confusing this
> with something
> else?
>
> (of course, this wasn't used for mminfra, but for something else!)
>
I can't find any remove history in mtk-cmdq-mailbox.c.
Maybe you mean the patch in this series?
https://lore.kernel.org/all/171213938049.123698.15573779837703602591.b4-ty@xxxxxxxxxxxxx/
> > +
> > +bool cmdq_addr_need_offset(struct mbox_chan *chan, dma_addr_t
> > addr)
> > +{
> > + struct cmdq *cmdq = container_of(chan->mbox, struct cmdq,
> > mbox);
> > +
> > + if (cmdq->pdata->mminfra_offset == 0)
> > + return false;
> > +
> > + /*
> > + * mminfra will recognize the addr that greater than the
> > mminfra_offset
> > + * as a transaction to DRAM.
> > + * So the caller needs to append mminfra_offset for the true
> > case.
> > + */
> > + return (addr >= cmdq->pdata->mminfra_offset);
>
>
> /**
> * cmdq_is_mminfra_gce() - Brief description
> * @args.....
> *
> * The MMINFRA GCE will recognize an address greater than DRAM
> iostart as a
> * DRAM transaction instead of ....xyz
> *
> * In order for callers to perform (xyz) transactions through the
> CMDQ, those
> * need to know if they are using a GCE located in MMINFRA.
> */
> bool cmdq_is_mminfra_gce(...)
> {
> return cmdq->pdata->mminfra_offset &&
> (addr >= cmdq->pdata->mminfra_offset)
>
> > +}
> > +EXPORT_SYMBOL(cmdq_addr_need_offset);
> > +
>
OK, I'll modify the API like this.
> ...but then, is there really no way of just handling the GCE being in
> MMINFRA
> transparently from the callers? Do the callers really *need* to know
> that they're
> using a new GCE?!
>
Since the address subtracting is done in MMINFRA hardware, I think GCE
users really need to handle it in driver.
> Another way of saying: can't we just handle the address translation
> in here instead
> of instructing each and every driver about how to communicate with
> the new GCE?!
>
The DRAM address may not only be the command buffer to GCE, but also
the working buffer provided by CMDQ users and being a part of GCE
instruction, so we need to handle the address translation in CMDQ
helper driver for the instruction generation.
E.g. ISP drivers may use GCE to write a hardware settings to a DRAM as
backup buffer. The GCE write instruction will be:
WRITE the value of ISP register to DRAM address + mminfra_offset.
But most of the CMDQ users only need to use GCE to write hardware
register, so I only keep the translation in cmdq_pkt_mem_move(),
cmdq_pkt_poll_addr() and cmdq_pkt_jump_abs() at the latest series.
Regards,
Jason-JH lin
>
> Cheers,
> Angelo