[snip] > > > CPR_GSIZE is the setting for allocating the CPR SRAM size to each > > VM. > > Would be awesome if you could then clarify the comment that you have > later in > the code here, from... > > /* config cpr size for host vm */ > > to > > /* Set the amount of CPR SRAM to allocate to each VM */ > > ...that could be a way of more properly describing what the writel > there is doing. > OK, I'll change it. > > > > > 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. > > > > Thanks, much appreciated! > > > > > + > > > > #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 > > > > That explanation was simply wonderful. > > > 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. > > > > ....so, this makes me think the following: > > 1. The DRAM start address cannot *ever* be less than 2G, because > otherwise the > MMINFRA HW would have a hole in the usable address range; > 1a. If the start address changes to less than 2G, then also the > IOMMU would > get limitations, not only the mminfra..! > 2b. This makes it very very very unlikely for the start address > to be changed > to less than 0x80000000 > > 2. If the DRAM start address changes to be ABOVE 2G (so more than > 0x80000000), > there would be no point for MMINFRA to start a "config path" > write (or read) > in the SMMU DRAM block, would it? ;-) > GCE is using IOMMU in MT8196, so all the address put into the GCE instruction or GCE register for GCE access should be IOVA. The DRAM start address is 2G(PA=0x80000000, IOVA=0x0) currently, so when GCE want to access the IOVA=0x0, it will need to +2G into the instruction, then the MMINFRA will see it as data path(IOVA > 2G) and subtract 2G for that IOVA, so GCE can finally access the IOVA=0x0. I'm not sure if I've misunderstood what you mean by ABOVE 2G. :-) If DRAM start address is changed to 3G(PA=0xc0000000) the IOVA is still 0x0, so GCE still need to + 2G to make MMINFRA go to the data path. But if you mean PA=0x80000000 and IOVA start address is 3G(0xc0000000), then MMINFRA will go to the data path without GCE +2G. However, MMINFRA will -2G when going to the data path and that will cause GCE access the wrong IOVA. So GCE still need to +2G no matter IOVA start address is already can make MMINFRA go to the data path(IOVA > 2G). We have already complained to our hardware designer that MMINFRA -2G con not be changed, which will make software operation very troublesome. So in the next few generations of SoC will change this MMINFRA -2G to software configurable. Then we can just make IOVA start address to 2G without adding the mminfra_offset to the IOVA for GCE. > I get it - if the DRAM moves up, MMINFRA is still at 2G because > that's hard baked > into the hardware, but I foresee that it'll be unlikely to see a > platform changing > the DRAM start address arbitrarily, getting out-of-sync with MMINFRA. > > I propose to just get the address from the memory node for now, and > to add a nice > comment in the code that explains that "In at least MT8196, the > MMINFRA hardware > subtracts xyz etc etc" (and that explanation from the previous email > is again > wonderful and shall not be lost: either use that in the comment, or > add it to > the commit description, because it's really that good). > > Should a new SoC appear in the future requiring an offset from the > DRAM start > address, we will think about how to make that work in the best > possible way: in > that case we could either reference something else to get the right > address or > we can just change this driver to just use the 2G offset statically > for all. > > What I'm trying to do here is to reduce the amount of changes that > we'd need for > adding new SoCs: since that 2G MMINFRA offset -> 2G DRAM start is not > a coincidence > I think that, should the DRAM start vary on new SoCs, the MMINFRA > offset will > follow the trend and vary with it. > > So what I think is: > 1. If I'm right, adding a new SoC (with different MMINFRA + DRAM > offset) will be > as easy as adding a compatible string in the bindings, no effort > in changing > this driver with new pdata offsets; > 2. If I'm wrong, adding a new SoC means adding compat string and > adding pdata and > one variable in the cmdq struct. > > Where N.2 is what we would do anyway if we don't go with my proposed > solution... > > All this is just to give you my considerations about this topic - > you're left > completely free to disagree with me. > If you disagree, I will trust your judgement, no problem here. > Yes, I think your are right. No matter the IOVA start address changing, MMINFRA will still -2G(the start address of DRAM PA). Do you mean we can get the mminfra_offset from the start address of memory in DTS, rather than defining it in pdata? > > > > 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? :-) > > > > Eh, if you put it like that... it makes sense, so.. yeah, okay :-) > > Still, please cleanup those instances of > > `cmdq_reg_revert_addr(readl(something), pdata)` > > those might be hard to read, so please just do something like: > > regval = readl(something); > curr_pa = cmdq_revert_addr(regval, pdata); > > ...reword to your own liking, of course. > OK, I'll refine that. Thanks. > > > > + > > > > 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/ > > > > Uhm, I think I may have confused something here, but yes I was > remembering the > patch series that you pointed out, definitely. > > At the end, that series is doing something else, so nevermind, was > just confusion. > OK, no problem. > > > > + > > > > +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. > > > > Since the users of this infrastructure are multimedia related > (disp/MDP3), > I'd also like to get an opinion from MediaTek engineers familiar with > that. > > CK, Moudy, any opinion on that, please? > > > > 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. > > Yeah you're choosing the best of both worlds in that case, I do > agree, but > still - if there's a way to avoid drivers to have different handling > for > mminfra vs no-mminfra, that'd still be preferred. > > Having the handling for something *centralized* somewhere, instead of > it > being sparse here and there, would make maintenance way easier... > > ...and that's why I'm asking for CK and Moudy's opinion, nothing else > :-) > Yes, I totally agree with you. Thanks for the asking! Regards, Jason-JH.Lin > Cheers! > Angelo >