Re: [PATCH v1] PCI: qcom: Avoid DBI and ATU register space mirror to BAR/MMIO region

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jun 28, 2024 at 07:02:04PM -0700, Prudhvi Yarlagadda wrote:
> Hi Manivannan,
> 
> Thanks for the review comments.
> 
> On 6/21/2024 8:54 PM, Manivannan Sadhasivam wrote:
> > On Thu, Jun 20, 2024 at 02:34:05PM -0700, Prudhvi Yarlagadda wrote:
> >> PARF hardware block which is a wrapper on top of DWC PCIe controller
> >> mirrors the DBI and ATU register space. It uses PARF_SLV_ADDR_SPACE_SIZE
> >> register to get the size of the memory block to be mirrored and uses
> >> PARF_DBI_BASE_ADDR, PARF_ATU_BASE_ADDR registers to determine the base
> >> address of DBI and ATU space inside the memory block that is being
> >> mirrored.
> >>
> > 
> > This PARF_SLV_ADDR_SPACE register is a mystery to me. I tried getting to the
> > bottom of it, but nobody could explain it to me clearly. Looks like you know
> > more about it...
> > 
> > From your description, it seems like this register specifies the size of the
> > mirroring region (ATU + DBI), but the response from your colleague indicates
> > something different [1].
> > 
> > [1] https://lore.kernel.org/linux-pci/f42559f5-9d4c-4667-bf0e-7abfd9983c36@xxxxxxxxxxx/
> > 
> 
> PARF_SLV_ADDR_SPACE_SIZE is used for mirroring the region containing ATU + DBI.
> But the issue being observed in the patch pointed above and the issue I am
> observing are a bit different even though the same fix could be used for both issues.
> 
> The issue I am observing is that the DBI and ATU region is getting mirrored into the
> BAR/MMIO region and thereby the DBI and ATU registers contents are getting modified
> while accessing the BAR region content.
> 
> As per my discussions internally with Devi Priya (author of the patch pointed above),
> the issue being seen there is that the DBI register contents are not available
> at the expected address by software and this is causing enumeration failures.
> 
> Below is the memory map of the IPQ9574 platform being mentioned in the above patch
> along with the memory locations of the DBI of respective PCIe Root Complexes.
> 
>                       |--------------------|
>                       |                    |
>                       |                    |
>                       |                    |
>                       |                    |
>                       |--------------------|
>                       |                    |
>                       |       PCIe2        |
>                       |                    |
>                       |--------------------|---->0x2000_0000 ->DBI
>                       |                    |
>                       |       PCIe3        |
>                       |                    |
>                       |--------------------|---->0x1800_0000 ->DBI
>                       |                    |
>                       |       PCIe1        |
>                       |                    |
>                       |--------------------|---->0x1000_0000 ->DBI
>                       |                    |
>                       |                    |
>                       |                    |
>                       |--------------------|
> 
> Previously PARF_SLV_ADDR_SPACE_SIZE is configured as 256MB (0x1000_0000) and
> PARF_DBI_BASE_ADDR is configured as 0x0 for each of the PCIe Root complex. With
> this configuration, in the case of PCIe1 DBI contents get accessible at 0x0,
> 0x1000_0000 and 0x2000_0000 and so on due to mirroring. Although NOC allows access
> only to region 0x1000_0000 to 0x1800_0000 for PCIe1. So in the case of PCIe1 DBI
> is accessible at the expected location 0x1000_0000.
> 
> Similarly in the case of PCIe3 its DBI contents are accessible at 0x0, 0x1000_0000
> and 0x2000_0000 but the expectation is to have DBI at 0x1800_0000 (as 0x1800_0000 is
> the physical address of DBI per devicetree). This is causing enumeration failures as
> DBI is not at the expected location (same issue w.r.t ATU).
> 
> When PARF_SLV_ADDR_SPACE_SIZE is modified to 128MB (0x800_0000) and PARF_DBI_BASE_ADDR
> is kept 0x0, for PCIe3 the DBI gets accessible at 0x0, 0x800_0000, 0x1000_0000,
> 0x1800_0000, 0x2000_0000 and so on. So, now the DBI becomes accessible at the
> expected location of 0x1800_0000 and its fixing the issue in the above patch.
> 

Thanks for the explanation. This really clarifies.

> Alternate way to fix the above issue is if we use the current patch to disable
> mirroring and configure the PARF_DBI_BASE_ADDR then the DBI gets accessible only at
> the location given in PARF_DBI_BASE_ADDR register which will be the same location
> mentioned in devicetree.
> 

Agree.

> >> When a memory region which is located above the SLV_ADDR_SPACE_SIZE
> >> boundary is used for BAR region then there could be an overlap of DBI and
> >> ATU address space that is getting mirrored and the BAR region. This
> >> results in DBI and ATU address space contents getting updated when a PCIe
> >> function driver tries updating the BAR/MMIO memory region. Reference
> >> memory map of the PCIe memory region with DBI and ATU address space
> >> overlapping BAR region is as below.
> >>
> >> 			|---------------|
> >> 			|		|
> >> 			|		|
> >> 	-------	--------|---------------|
> >> 	   |	   |	|---------------|
> >> 	   |	   |	|	DBI	|
> >> 	   |	   |	|---------------|---->DBI_BASE_ADDR
> >> 	   |	   |	|		|
> >> 	   |	   |	|		|
> >> 	   |	PCIe	|		|---->2*SLV_ADDR_SPACE_SIZE
> >> 	   |	BAR/MMIO|---------------|
> >> 	   |	Region	|	ATU	|
> >> 	   |	   |	|---------------|---->ATU_BASE_ADDR
> >> 	   |	   |	|		|
> >> 	PCIe	   |	|---------------|
> >> 	Memory	   |	|	DBI	|
> >> 	Region	   |	|---------------|---->DBI_BASE_ADDR
> >> 	   |	   |	|		|
> >> 	   |	--------|		|
> >> 	   |		|		|---->SLV_ADDR_SPACE_SIZE
> >> 	   |		|---------------|
> >> 	   |		|	ATU	|
> >> 	   |		|---------------|---->ATU_BASE_ADDR
> >> 	   |		|		|
> >> 	   |		|---------------|
> >> 	   |		|	DBI	|
> >> 	   |		|---------------|---->DBI_BASE_ADDR
> >> 	   |		|		|
> >> 	   |		|		|
> >> 	----------------|---------------|
> >> 			|		|
> >> 			|		|
> >> 			|		|
> >> 			|---------------|
> >>
> >> Currently memory region beyond the SLV_ADDR_SPACE_SIZE boundary is not
> >> used for BAR region which is why the above mentioned issue is not
> >> encountered. This issue is discovered as part of internal testing when we
> >> tried moving the BAR region beyond the SLV_ADDR_SPACE_SIZE boundary. Hence
> >> we are trying to fix this.
> >>
> > 
> > I don't quite understand this. PoR value of SLV_ADDR_SPACE_SIZE is 16MB and most
> > of the platforms have the size of whole PCIe region defined in DT as 512MB
> > (registers + I/O + MEM). So the range is already crossing the
> > SLV_ADDR_SPACE_SIZE boundary.
> > 
> > Ironically, the patch I pointed out above changes the value of this register as
> > 128MB, and the PCIe region size of that platform is also 128MB. The author of
> > that patch pointed out that if the SLV_ADDR_SPACE_SIZE is set to 256MB, then
> > they are seeing enumeration failures. If we go by your description of that
> > register, the SLV_ADDR_SPACE_SIZE of 256MB should be > PCIe region size of
> > 128MB. So they should not see any issues, right?
> > 
> 
> As mentioned above, configuring PARF_SLV_ADDR_SPACE_SIZE as 256MB is causing
> issue with the PCIe instances in which DBI is not aligned with the multiples of
> 256MB and due to PARF_DBI_BASE_ADDR being configured as 0x0 instead of the
> actual DBI address given in devicetree.
> 
> >> As PARF hardware block mirrors DBI and ATU register space after every
> >> PARF_SLV_ADDR_SPACE_SIZE (default 0x1000000) boundary multiple, write
> >> U64_MAX to PARF_SLV_ADDR_SPACE_SIZE register to avoid mirroring DBI and
> >> ATU to BAR/MMIO region.
> > 
> > Looks like you are trying to avoid this mirroring on a whole. First of all, what
> > is the reasoning behind this mirroring?
> > 
> 
> The reason is to have more control over where to have the DBI and ATU register
> contents in the system memory using the PARF_DBI_BASE_ADDR, PARF_ATU_BASE_ADDR.
> For the PARF_SLV_ADDR_SPACE_SIZE register we don't have an existing use case
> to utilize mirroring functionality.
> 

Okay. Then I guess you could disable mirroring globally for all SoCs. Some SoCs
doesn't have both DBU and ATU regions, so the helper could conditionally write
the base address if available in DT.

> >> Write the physical base address of DBI and ATU
> >> register blocks to PARF_DBI_BASE_ADDR (default 0x0) and PARF_ATU_BASE_ADDR
> >> (default 0x1000) respectively to make sure DBI and ATU blocks are at
> >> expected memory locations.
> >>
> > 
> > Why is this needed? Some configs in this driver writes 0 to PARF_DBI_BASE_ADDR.
> > Does the hardware doesn't know where the registers are located?
> > 
> 
> Yes, hardware doesn't know where the DBI, ATU registers are located in the
> PARF_SLV_ADDR_SPACE_SIZE memory block or system memory. Hardware gets the location
> of DBI and ATU registers from the PARF_DBI_BASE_ADDR, PARF_ATU_BASE_ADDR
> registers. So these registers must be programmed to have the DBI and ATU at
> expected memory locations.
> 

Sounds good.

- Mani

-- 
மணிவண்ணன் சதாசிவம்




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux