Thread (66 messages) 66 messages, 10 authors, 2014-05-28

[PATCH 06/17] pci: host: pcie-designware: Use *base-mask* for configuring the iATU

From: Kishon Vijay Abraham I <hidden>
Date: 2014-05-16 09:01:55
Also in: linux-devicetree, linux-omap, linux-pci, lkml

Hi Arnd,

On Wednesday 14 May 2014 06:15 PM, Arnd Bergmann wrote:
On Wednesday 14 May 2014 11:14:45 Kishon Vijay Abraham I wrote:
quoted
hi Arnd,

On Tuesday 13 May 2014 07:04 PM, Arnd Bergmann wrote:
quoted
On Tuesday 13 May 2014 15:27:46 Arnd Bergmann wrote:
quoted
On Tuesday 13 May 2014 18:56:23 Kishon Vijay Abraham I wrote:
quoted
quoted
If you have a case where the outbound translation is a 256MB (i.e. 28bit)
section of the CPU address space, that could be represented as

      ranges = <0x82000000 0 0  0xb0000000  0 0x10000000>;

or 

      ranges = <0x82000000 0 0xb0000000  0xb0000000  0 0x10000000>;

depending on whether you want the BARs to be programmed using a low
address 0x0-0x0fffffff or an address matching the window
0xb0000000-0xbfffffff.
The problem is, for configuring the window starting at 0xb0000000, the ATU
should be programmed 0x0000000 (the cpu address for it will be 0xb0000000 though).
Then use the first of the two?
To clarify: using <0x82000000 0 0  0xb0000000  0 0x10000000> will give you 
a mem_offset of 0xb0000000, which should work just fine for this case.

What I don't understand is why the ATU cares about whether the outbound
address is 0x0000000 or 0xb0000000 if it just decodes the lower 28 bit
anyway. Did you mean that we have to program the BARs using low addresses
regardless of what is programmed in the ATU? That would make more sense,
and it also matches what I suggested.
No, It's not like it decodes only the lower 28bits. The BARs is programmed with
32 bit value.

My pcie dt node has
 ranges = <0x00000800 0 0x20001000 0x20001000 0 0x00002000  /* CONFIG */
           0x81000000 0 0          0x20003000 0 0x00010000  /* IO */
           0x82000000 0 0x20013000 0x20013000 0 0xffed000>; /* MEM */

Consider MEM address space..

Here both PCI address and CPU address is 0x20013000. So when there is a write
to cpu addr 0x20013000 [writel(virt_addr(0x20013000)], we want it to be
translated to PCI addr 0x20013000. So in 'ATU', we would expect *base* to be
programmed to *0x20013000* and target to be programmed to *0x20013000*. But
that's not the case for DRA7xx. For DRA7xx *base* should be programmed to
*0x0013000* and target should be programmed to *0x20013000*.
Ok, got it, thanks for your patience.

I think this would best be modeled as a separate bus node that contains the
restriction, like this:

/ {
	#address-cells = <1>; // or <2> if you support > 4GB address space
	#size-cells = <1>;

	soc {
		#address-cells <1>;
		#size-cells = <1>;
		ranges;
		dma-ranges;

		... // all normal devices

		axi at 20000000 {
			#size-cells = <1>;
			#address-cells = <1>;
			dma-ranges; // can access all 4GB outbound
			ranges = <0 0x20000000 0x10000000>; // 28-bit bus

			pci at 0 {
				reg = <0x0    0x1000>, // internal regs
				      <0x1000 0x2000>; // config space
The internal reg address space starts at 0x51000000. By Using this <0
0x20000000 0x10000000>; as ranges, we are not able to get the memory resource
properly. Can we use multiple ranges? how do we specify which ranges the *reg*
property to use?

Btw I was using *simple-bus* as compatible to *axi*. Or should I create a new
*axi* driver to create the pcie memory resources myself?

Thanks
Kishon
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help