Question about a quirky (DesignWare) PCIe RC in Allwinner H6

Marc Gonzalez marc_gonzalez at sigmadesigns.com
Thu Mar 8 03:55:03 PST 2018


On 08/03/2018 06:48, Icenowy Zheng wrote:

> I'm trying to implement a driver for the quirky (DW) PCIe RC in the
> Allwinner H6 SoC.
> 
> The quirk is that only the "dbi" space is always mapped, but at the 
> same time only 64KiB of other spaces (config, downstream IO and non- 
> prefetchable memory) are accessible. To access a certain address the 
> high 16-bit of the address (all bus addresses in H6 SoC are 32- bit 
> despite the CPU is 64-bit) needs to be written into the 
> PCIE_ADDR_PAGE_CFG register (a vendor-defined register in DBI 
> space). So the access to these spaces cannot be processed correctly 
> with just readl/writel, as the existing code does.
> 
> Is it possible to workaround this in the PCI subsystem of Linux?

I didn't think anyone would come up with something more broken
than tango's PCIe host bridge...

It's hard to understand what's going on inside the minds of these
HW devs. I mean, if the steps required are

	WRITE MAGIC CONFIG REG
	READ/WRITE ADDRESS REG

then the whole operation is clearly not atomic, and bad things happen
when 2+ operations race.

Do they think in terms of single core systems with non-multitasking OS?
Probably not.

Maybe they think it is not a problem to wrap the operation using a
mutex? I'll confess I have no idea how bad that is for performance.
However, that is not an option in Linux, because mem space accesses
are just plain mmio accesses, and it's not possible to rewrite the
drivers, even as an out-of-tree patch.

I suppose it could be possible to make the first write "magic" in the
sense that it could "lock" the bus until the second access is performed?
Sort of like an implicit HW mutex. Actually, tango has explicit HW
mutexes that work along these lines.

> (I have thought a workaround that only maps the current accessible 
> 64KiB with the MMU, and when accessing the non-accessible part, 
> catch the page fault and re-setup the map to the new 64KiB page. But 
> surely it will kill the performance.)

The implementation might be non-trivial, as well.

> [tango is] still less quirky than Allwinner H6 PCIe. It's only a
> config/MMIO mux on tango; however on H6 PCIe both config space and
> MMIO space are splitted to many pages. So on H6 if no solution is
> worked out, it will not be unreliable -- it will be unusable
> instead.

I have only limited experience, but it seems that many useful PCIe
adapters require only very little mem address space.

For example, the USB3 PCIe adapter I tested my implementation with
requires only 8 KB.

01:00.0 USB controller: Renesas Technology Corp. uPD720201 USB 3.0 Host Controller (rev 03) (prog-if 30 [XHCI])
        Flags: fast devsel
        Memory at 50400000 (64-bit, non-prefetchable) [size=8K]
        Capabilities: [50] Power Management version 3
        Capabilities: [70] MSI: Enable- Count=1/8 Maskable- 64bit+
        Capabilities: [90] MSI-X: Enable- Count=8 Masked-
        Capabilities: [a0] Express Endpoint, MSI 00
        Capabilities: [100] Advanced Error Reporting
        Capabilities: [150] Latency Tolerance Reporting


Same thing for the following WiFi adapter.

01:00.0 Network controller: Intel Corporation Wireless 7260 (rev bb)
        Subsystem: Intel Corporation Dual Band Wireless-AC 7260
        Flags: fast devsel, IRQ 22
        Memory at 50400000 (64-bit, non-prefetchable) [disabled] [size=8K]
        Capabilities: [c8] Power Management version 3
        Capabilities: [d0] MSI: Enable- Count=1/1 Maskable- 64bit+
        Capabilities: [40] Express Endpoint, MSI 00
        Capabilities: [100] Advanced Error Reporting
        Capabilities: [140] Device Serial Number 48-51-b7-ff-ff-84-69-26
        Capabilities: [14c] Latency Tolerance Reporting
        Capabilities: [154] Vendor Specific Information: ID=cafe Rev=1 Len=014 <?>


Maybe you can decide that you will support only 64 KB?

Regards.




More information about the linux-arm-kernel mailing list