diff mbox

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

Message ID 1399383244-14556-7-git-send-email-kishon@ti.com (mailing list archive)
State New, archived
Delegated to: Bjorn Helgaas
Headers show

Commit Message

Kishon Vijay Abraham I May 6, 2014, 1:33 p.m. UTC
In DRA7, the cpu sees 32bit address, but the pcie controller can see only 28bit
address. So whenever the cpu issues a read/write request, the 4 most
significant bits are used by L3 to determine the target controller.
For example, the cpu reserves 0x2000_0000 - 0x2FFF_FFFF for PCIe controller but
the PCIe controller will see only (0x000_0000 - 0xFFF_FFF). So for programming
the outbound translation window the *base* should be programmed as 0x000_0000.
Whenever we try to write to say 0x2000_0000, it will be translated to whatever
we have programmed in the translation window with base as 0x000_0000.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Marek Vasut <marex@denx.de>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Acked-by: Mohit Kumar <mohit.kumar@st.com>
---
 .../devicetree/bindings/pci/designware-pcie.txt    |    1 +
 drivers/pci/host/pcie-designware.c                 |   39 ++++++++++++++------
 drivers/pci/host/pcie-designware.h                 |    1 +
 3 files changed, 29 insertions(+), 12 deletions(-)

Comments

Arnd Bergmann May 6, 2014, 1:59 p.m. UTC | #1
On Tuesday 06 May 2014 19:03:52 Kishon Vijay Abraham I wrote:
> In DRA7, the cpu sees 32bit address, but the pcie controller can see only 28bit
> address. So whenever the cpu issues a read/write request, the 4 most
> significant bits are used by L3 to determine the target controller.
> For example, the cpu reserves 0x2000_0000 - 0x2FFF_FFFF for PCIe controller but
> the PCIe controller will see only (0x000_0000 - 0xFFF_FFF). So for programming
> the outbound translation window the *base* should be programmed as 0x000_0000.
> Whenever we try to write to say 0x2000_0000, it will be translated to whatever
> we have programmed in the translation window with base as 0x000_0000.
> 
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Marek Vasut <marex@denx.de>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> Acked-by: Jingoo Han <jg1.han@samsung.com>
> Acked-by: Mohit Kumar <mohit.kumar@st.com>

Sorry, but NAK.

We have a standard 'dma-ranges' property to handle this, so use it.

See the x-gene PCIe driver patches for an example. Please also talk
to Santosh about it, as he is implementing generic support for
parsing dma-ranges in platform devices at the moment.

I also suspect you will have to implement swiotlb support to make
generic PCI devices work behind this bridge. Otherwise you end up
with random physical addresses passed into DMA registers.

	Arnd

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jingoo Han May 8, 2014, 9:05 a.m. UTC | #2
On Tuesday, May 06, 2014 10:59 PM, Arnd Bergmann wrote:
> On Tuesday 06 May 2014 19:03:52 Kishon Vijay Abraham I wrote:
> > In DRA7, the cpu sees 32bit address, but the pcie controller can see only 28bit
> > address. So whenever the cpu issues a read/write request, the 4 most
> > significant bits are used by L3 to determine the target controller.
> > For example, the cpu reserves 0x2000_0000 - 0x2FFF_FFFF for PCIe controller but
> > the PCIe controller will see only (0x000_0000 - 0xFFF_FFF). So for programming
> > the outbound translation window the *base* should be programmed as 0x000_0000.
> > Whenever we try to write to say 0x2000_0000, it will be translated to whatever
> > we have programmed in the translation window with base as 0x000_0000.
> >
> > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > Cc: Marek Vasut <marex@denx.de>
> > Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> > Acked-by: Jingoo Han <jg1.han@samsung.com>
> > Acked-by: Mohit Kumar <mohit.kumar@st.com>
> 
> Sorry, but NAK.
> 
> We have a standard 'dma-ranges' property to handle this, so use it.
> 
> See the x-gene PCIe driver patches for an example. Please also talk
> to Santosh about it, as he is implementing generic support for
> parsing dma-ranges in platform devices at the moment.

Hi Arnd,

Do you mean the following patch?
http://www.spinics.net/lists/kernel/msg1737725.html

Thank you.

Best regards,
Jingoo Han

> 
> I also suspect you will have to implement swiotlb support to make
> generic PCI devices work behind this bridge. Otherwise you end up
> with random physical addresses passed into DMA registers.


--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arnd Bergmann May 8, 2014, 9:18 a.m. UTC | #3
On Thursday 08 May 2014 18:05:11 Jingoo Han wrote:
> On Tuesday, May 06, 2014 10:59 PM, Arnd Bergmann wrote:
> > On Tuesday 06 May 2014 19:03:52 Kishon Vijay Abraham I wrote:
> > > In DRA7, the cpu sees 32bit address, but the pcie controller can see only 28bit
> > > address. So whenever the cpu issues a read/write request, the 4 most
> > > significant bits are used by L3 to determine the target controller.
> > > For example, the cpu reserves 0x2000_0000 - 0x2FFF_FFFF for PCIe controller but
> > > the PCIe controller will see only (0x000_0000 - 0xFFF_FFF). So for programming
> > > the outbound translation window the *base* should be programmed as 0x000_0000.
> > > Whenever we try to write to say 0x2000_0000, it will be translated to whatever
> > > we have programmed in the translation window with base as 0x000_0000.
> > >
> > > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > > Cc: Marek Vasut <marex@denx.de>
> > > Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> > > Acked-by: Jingoo Han <jg1.han@samsung.com>
> > > Acked-by: Mohit Kumar <mohit.kumar@st.com>
> > 
> > Sorry, but NAK.
> > 
> > We have a standard 'dma-ranges' property to handle this, so use it.
> > 
> > See the x-gene PCIe driver patches for an example. Please also talk
> > to Santosh about it, as he is implementing generic support for
> > parsing dma-ranges in platform devices at the moment.
> 
> Hi Arnd,
> 
> Do you mean the following patch?
> http://www.spinics.net/lists/kernel/msg1737725.html
> 

That is the patch Santosh did for platform devices, which is related but not
what I meant here. For the PCI inbound window setup, please have a look
at https://lkml.org/lkml/2014/3/19/607

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kishon Vijay Abraham I May 9, 2014, 11:50 a.m. UTC | #4
Hi,

On Thursday 08 May 2014 02:48 PM, Arnd Bergmann wrote:
> On Thursday 08 May 2014 18:05:11 Jingoo Han wrote:
>> On Tuesday, May 06, 2014 10:59 PM, Arnd Bergmann wrote:
>>> On Tuesday 06 May 2014 19:03:52 Kishon Vijay Abraham I wrote:
>>>> In DRA7, the cpu sees 32bit address, but the pcie controller can see only 28bit
>>>> address. So whenever the cpu issues a read/write request, the 4 most
>>>> significant bits are used by L3 to determine the target controller.
>>>> For example, the cpu reserves 0x2000_0000 - 0x2FFF_FFFF for PCIe controller but
>>>> the PCIe controller will see only (0x000_0000 - 0xFFF_FFF). So for programming
>>>> the outbound translation window the *base* should be programmed as 0x000_0000.
>>>> Whenever we try to write to say 0x2000_0000, it will be translated to whatever
>>>> we have programmed in the translation window with base as 0x000_0000.
>>>>
>>>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>>>> Cc: Marek Vasut <marex@denx.de>
>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>> Acked-by: Jingoo Han <jg1.han@samsung.com>
>>>> Acked-by: Mohit Kumar <mohit.kumar@st.com>
>>>
>>> Sorry, but NAK.
>>>
>>> We have a standard 'dma-ranges' property to handle this, so use it.
>>>
>>> See the x-gene PCIe driver patches for an example. Please also talk
>>> to Santosh about it, as he is implementing generic support for
>>> parsing dma-ranges in platform devices at the moment.
>>
>> Hi Arnd,
>>
>> Do you mean the following patch?
>> http://www.spinics.net/lists/kernel/msg1737725.html
>>
> 
> That is the patch Santosh did for platform devices, which is related but not
> what I meant here. For the PCI inbound window setup, please have a look
> at https://lkml.org/lkml/2014/3/19/607

For some reason lkml is not showing any contents. Do you have a different link?

Thanks
Kishon
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jingoo Han May 12, 2014, 1:44 a.m. UTC | #5
On Friday, May 09, 2014 8:50 PM, Kishon Vijay Abraham I wrote:
> On Thursday 08 May 2014 02:48 PM, Arnd Bergmann wrote:
> > On Thursday 08 May 2014 18:05:11 Jingoo Han wrote:
> >> On Tuesday, May 06, 2014 10:59 PM, Arnd Bergmann wrote:
> >>> On Tuesday 06 May 2014 19:03:52 Kishon Vijay Abraham I wrote:
> >>>> In DRA7, the cpu sees 32bit address, but the pcie controller can see only 28bit
> >>>> address. So whenever the cpu issues a read/write request, the 4 most
> >>>> significant bits are used by L3 to determine the target controller.
> >>>> For example, the cpu reserves 0x2000_0000 - 0x2FFF_FFFF for PCIe controller but
> >>>> the PCIe controller will see only (0x000_0000 - 0xFFF_FFF). So for programming
> >>>> the outbound translation window the *base* should be programmed as 0x000_0000.
> >>>> Whenever we try to write to say 0x2000_0000, it will be translated to whatever
> >>>> we have programmed in the translation window with base as 0x000_0000.
> >>>>
> >>>> Cc: Bjorn Helgaas <bhelgaas@google.com>
> >>>> Cc: Marek Vasut <marex@denx.de>
> >>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> >>>> Acked-by: Jingoo Han <jg1.han@samsung.com>
> >>>> Acked-by: Mohit Kumar <mohit.kumar@st.com>
> >>>
> >>> Sorry, but NAK.
> >>>
> >>> We have a standard 'dma-ranges' property to handle this, so use it.
> >>>
> >>> See the x-gene PCIe driver patches for an example. Please also talk
> >>> to Santosh about it, as he is implementing generic support for
> >>> parsing dma-ranges in platform devices at the moment.
> >>
> >> Hi Arnd,
> >>
> >> Do you mean the following patch?
> >> http://www.spinics.net/lists/kernel/msg1737725.html
> >>
> >
> > That is the patch Santosh did for platform devices, which is related but not
> > what I meant here. For the PCI inbound window setup, please have a look
> > at https://lkml.org/lkml/2014/3/19/607
> 
> For some reason lkml is not showing any contents. Do you have a different link?

Hi Kishon,

Please refer to the following link. :-)
http://www.spinics.net/lists/linux-pci/msg29855.html


Best regards,
Jingoo Han

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kishon Vijay Abraham I May 13, 2014, 12:31 p.m. UTC | #6
Hi Arnd,

On Thursday 08 May 2014 02:48 PM, Arnd Bergmann wrote:
> On Thursday 08 May 2014 18:05:11 Jingoo Han wrote:
>> On Tuesday, May 06, 2014 10:59 PM, Arnd Bergmann wrote:
>>> On Tuesday 06 May 2014 19:03:52 Kishon Vijay Abraham I wrote:
>>>> In DRA7, the cpu sees 32bit address, but the pcie controller can see only 28bit
>>>> address. So whenever the cpu issues a read/write request, the 4 most
>>>> significant bits are used by L3 to determine the target controller.
>>>> For example, the cpu reserves 0x2000_0000 - 0x2FFF_FFFF for PCIe controller but
>>>> the PCIe controller will see only (0x000_0000 - 0xFFF_FFF). So for programming
>>>> the outbound translation window the *base* should be programmed as 0x000_0000.
>>>> Whenever we try to write to say 0x2000_0000, it will be translated to whatever
>>>> we have programmed in the translation window with base as 0x000_0000.
>>>>
>>>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>>>> Cc: Marek Vasut <marex@denx.de>
>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>> Acked-by: Jingoo Han <jg1.han@samsung.com>
>>>> Acked-by: Mohit Kumar <mohit.kumar@st.com>
>>>
>>> Sorry, but NAK.
>>>
>>> We have a standard 'dma-ranges' property to handle this, so use it.
>>>
>>> See the x-gene PCIe driver patches for an example. Please also talk
>>> to Santosh about it, as he is implementing generic support for
>>> parsing dma-ranges in platform devices at the moment.
>>
>> Hi Arnd,
>>
>> Do you mean the following patch?
>> http://www.spinics.net/lists/kernel/msg1737725.html
>>
> 
> That is the patch Santosh did for platform devices, which is related but not
> what I meant here. For the PCI inbound window setup, please have a look
> at https://lkml.org/lkml/2014/3/19/607

Do you think it can be used for *outbound* window setup too? The problem is the
*ranges* property defines both the pci address and cpu address which should
have been enough to program the ob translation window, but the hw is designed
so that the controller sees only the 28 bits. (The most significant 4 bits is
for the l3 to address the controller).

Thanks
Kishon
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arnd Bergmann May 13, 2014, 12:47 p.m. UTC | #7
On Tuesday 13 May 2014 18:01:59 Kishon Vijay Abraham I wrote:
> On Thursday 08 May 2014 02:48 PM, Arnd Bergmann wrote:
> > On Thursday 08 May 2014 18:05:11 Jingoo Han wrote:
> >> On Tuesday, May 06, 2014 10:59 PM, Arnd Bergmann wrote:
> >>> On Tuesday 06 May 2014 19:03:52 Kishon Vijay Abraham I wrote:
> >>>> In DRA7, the cpu sees 32bit address, but the pcie controller can see only 28bit
> >>>> address. So whenever the cpu issues a read/write request, the 4 most
> >>>> significant bits are used by L3 to determine the target controller.
> >>>> For example, the cpu reserves 0x2000_0000 - 0x2FFF_FFFF for PCIe controller but
> >>>> the PCIe controller will see only (0x000_0000 - 0xFFF_FFF). So for programming
> >>>> the outbound translation window the *base* should be programmed as 0x000_0000.
> >>>> Whenever we try to write to say 0x2000_0000, it will be translated to whatever
> >>>> we have programmed in the translation window with base as 0x000_0000.
> >>>>
> >>>> Cc: Bjorn Helgaas <bhelgaas@google.com>
> >>>> Cc: Marek Vasut <marex@denx.de>
> >>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> >>>> Acked-by: Jingoo Han <jg1.han@samsung.com>
> >>>> Acked-by: Mohit Kumar <mohit.kumar@st.com>
> >>>
> >>> Sorry, but NAK.
> >>>
> >>> We have a standard 'dma-ranges' property to handle this, so use it.
> >>>
> >>> See the x-gene PCIe driver patches for an example. Please also talk
> >>> to Santosh about it, as he is implementing generic support for
> >>> parsing dma-ranges in platform devices at the moment.
> >>
> >> Hi Arnd,
> >>
> >> Do you mean the following patch?
> >> http://www.spinics.net/lists/kernel/msg1737725.html
> >>
> > 
> > That is the patch Santosh did for platform devices, which is related but not
> > what I meant here. For the PCI inbound window setup, please have a look
> > at https://lkml.org/lkml/2014/3/19/607
> 
> Do you think it can be used for *outbound* window setup too? The problem is the
> *ranges* property defines both the pci address and cpu address which should
> have been enough to program the ob translation window, but the hw is designed
> so that the controller sees only the 28 bits. (The most significant 4 bits is
> for the l3 to address the controller).

I'm not following what the problem is. You should always be able to describe
in the inbound window (that is from the CPU perspective) using dma-ranges
and the outbound window using ranges.

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.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kishon Vijay Abraham I May 13, 2014, 1:26 p.m. UTC | #8
Hi Arnd,

On Tuesday 13 May 2014 06:17 PM, Arnd Bergmann wrote:
> On Tuesday 13 May 2014 18:01:59 Kishon Vijay Abraham I wrote:
>> On Thursday 08 May 2014 02:48 PM, Arnd Bergmann wrote:
>>> On Thursday 08 May 2014 18:05:11 Jingoo Han wrote:
>>>> On Tuesday, May 06, 2014 10:59 PM, Arnd Bergmann wrote:
>>>>> On Tuesday 06 May 2014 19:03:52 Kishon Vijay Abraham I wrote:
>>>>>> In DRA7, the cpu sees 32bit address, but the pcie controller can see only 28bit
>>>>>> address. So whenever the cpu issues a read/write request, the 4 most
>>>>>> significant bits are used by L3 to determine the target controller.
>>>>>> For example, the cpu reserves 0x2000_0000 - 0x2FFF_FFFF for PCIe controller but
>>>>>> the PCIe controller will see only (0x000_0000 - 0xFFF_FFF). So for programming
>>>>>> the outbound translation window the *base* should be programmed as 0x000_0000.
>>>>>> Whenever we try to write to say 0x2000_0000, it will be translated to whatever
>>>>>> we have programmed in the translation window with base as 0x000_0000.
>>>>>>
>>>>>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>>>>>> Cc: Marek Vasut <marex@denx.de>
>>>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>>>> Acked-by: Jingoo Han <jg1.han@samsung.com>
>>>>>> Acked-by: Mohit Kumar <mohit.kumar@st.com>
>>>>>
>>>>> Sorry, but NAK.
>>>>>
>>>>> We have a standard 'dma-ranges' property to handle this, so use it.
>>>>>
>>>>> See the x-gene PCIe driver patches for an example. Please also talk
>>>>> to Santosh about it, as he is implementing generic support for
>>>>> parsing dma-ranges in platform devices at the moment.
>>>>
>>>> Hi Arnd,
>>>>
>>>> Do you mean the following patch?
>>>> http://www.spinics.net/lists/kernel/msg1737725.html
>>>>
>>>
>>> That is the patch Santosh did for platform devices, which is related but not
>>> what I meant here. For the PCI inbound window setup, please have a look
>>> at https://lkml.org/lkml/2014/3/19/607
>>
>> Do you think it can be used for *outbound* window setup too? The problem is the
>> *ranges* property defines both the pci address and cpu address which should
>> have been enough to program the ob translation window, but the hw is designed
>> so that the controller sees only the 28 bits. (The most significant 4 bits is
>> for the l3 to address the controller).
> 
> I'm not following what the problem is. You should always be able to describe
> in the inbound window (that is from the CPU perspective) using dma-ranges
> and the outbound window using ranges.
> 
> 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).

Thanks
Kishon
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arnd Bergmann May 13, 2014, 1:27 p.m. UTC | #9
On Tuesday 13 May 2014 18:56:23 Kishon Vijay Abraham I wrote:
> > 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?

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arnd Bergmann May 13, 2014, 1:34 p.m. UTC | #10
On Tuesday 13 May 2014 15:27:46 Arnd Bergmann wrote:
> On Tuesday 13 May 2014 18:56:23 Kishon Vijay Abraham I wrote:
> > > 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.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kishon Vijay Abraham I May 14, 2014, 5:44 a.m. UTC | #11
hi Arnd,

On Tuesday 13 May 2014 07:04 PM, Arnd Bergmann wrote:
> On Tuesday 13 May 2014 15:27:46 Arnd Bergmann wrote:
>> On Tuesday 13 May 2014 18:56:23 Kishon Vijay Abraham I wrote:
>>>> 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*.

Thanks
Kishon
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arnd Bergmann May 14, 2014, 12:45 p.m. UTC | #12
On Wednesday 14 May 2014 11:14:45 Kishon Vijay Abraham I wrote:
> hi Arnd,
> 
> On Tuesday 13 May 2014 07:04 PM, Arnd Bergmann wrote:
> > On Tuesday 13 May 2014 15:27:46 Arnd Bergmann wrote:
> >> On Tuesday 13 May 2014 18:56:23 Kishon Vijay Abraham I wrote:
> >>>> 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@20000000 {
			#size-cells = <1>;
			#address-cells = <1>;
			dma-ranges; // can access all 4GB outbound
			ranges = <0 0x20000000 0x10000000>; // 28-bit bus

			pci@0 {
				reg = <0x0    0x1000>, // internal regs
				      <0x1000 0x2000>; // config space
				dma-ranges; // 32-bit outbound
				ranges = <0x81000000 0 0           0x3000 0 0x00010000  /* IO */
					  0x82000000 0 0x20013000 0x13000 0 0xffed000>; /* MEM */
			};
		};
	};
};


	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kishon Vijay Abraham I May 14, 2014, 3:04 p.m. UTC | #13
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:
>> hi Arnd,
>>
>> On Tuesday 13 May 2014 07:04 PM, Arnd Bergmann wrote:
>>> On Tuesday 13 May 2014 15:27:46 Arnd Bergmann wrote:
>>>> On Tuesday 13 May 2014 18:56:23 Kishon Vijay Abraham I wrote:
>>>>>> 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@20000000 {
> 			#size-cells = <1>;
> 			#address-cells = <1>;
> 			dma-ranges; // can access all 4GB outbound
> 			ranges = <0 0x20000000 0x10000000>; // 28-bit bus
> 
> 			pci@0 {
> 				reg = <0x0    0x1000>, // internal regs
> 				      <0x1000 0x2000>; // config space
> 				dma-ranges; // 32-bit outbound
> 				ranges = <0x81000000 0 0           0x3000 0 0x00010000  /* IO */
> 					  0x82000000 0 0x20013000 0x13000 0 0xffed000>; /* MEM */
> 			};
> 		};
> 	};
> };

Nice :-)

Thanks
Kishon
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kishon Vijay Abraham I May 16, 2014, 9 a.m. UTC | #14
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:
>> hi Arnd,
>>
>> On Tuesday 13 May 2014 07:04 PM, Arnd Bergmann wrote:
>>> On Tuesday 13 May 2014 15:27:46 Arnd Bergmann wrote:
>>>> On Tuesday 13 May 2014 18:56:23 Kishon Vijay Abraham I wrote:
>>>>>> 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@20000000 {
> 			#size-cells = <1>;
> 			#address-cells = <1>;
> 			dma-ranges; // can access all 4GB outbound
> 			ranges = <0 0x20000000 0x10000000>; // 28-bit bus
> 
> 			pci@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
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arnd Bergmann May 19, 2014, 12:45 p.m. UTC | #15
On Friday 16 May 2014 14:30:56 Kishon Vijay Abraham I wrote:
> On Wednesday 14 May 2014 06:15 PM, Arnd Bergmann wrote:
> > On Wednesday 14 May 2014 11:14:45 Kishon Vijay Abraham I wrote:
> > / {
> >       #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@20000000 {
> >                       #size-cells = <1>;
> >                       #address-cells = <1>;
> >                       dma-ranges; // can access all 4GB outbound
> >                       ranges = <0 0x20000000 0x10000000>; // 28-bit bus
> > 
> >                       pci@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?

Yes, multiple ranges will work fine. You can make up a representation
yourself if you don't know what the hardware really does.

Two possible ways of doing this would be

a)

	/* two separate physical connections represented as one logical bus */
	axi@20000000 {
		#address-cells = <2>;
		#size-cells = <1>;
		ranges = <0 0 0x20000000 0x10000000>, /* configurable registers */
			 <1 0 0x51000000 0x01000000>; /* PCI host registers */

		pci@1.0 {
			reg = <1 0 0x01000000>, /* host registers */
				<0 0x1000 0x2000>; /* config space */
		}

	};

b) 

	/* one physical bus, with some address munging */
	axi@20000000 {
		#address-cells = <1>;
		#size-cells = <1>;
		ranges = <0 0x20000000 0x10000000>, /* configurable registers */
			 <0x51000000 0x51000000 0x01000000>; /* PCI host registers */

		pci@1.0 {
			reg = <0x51000000 0x01000000>, /* host registers */
				<0x1000 0x2000>; /* config space */
		}

	};


> 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?

simple-bus is best here, since you don't have a complex bus that needs to
be set up using register accesses or that generates interrupts.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt
index d6fae13..c574dd3 100644
--- a/Documentation/devicetree/bindings/pci/designware-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt
@@ -27,6 +27,7 @@  Optional properties for fsl,imx6q-pcie
 - power-on-gpio: gpio pin number of power-enable signal
 - wake-up-gpio: gpio pin number of incoming wakeup signal
 - disable-gpio: gpio pin number of outgoing rfkill/endpoint disable signal
+- base-mask: address mask for the PCIe controller target port
 
 Example:
 
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index c4e3732..243f148 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -463,6 +463,9 @@  int __init dw_pcie_host_init(struct pcie_port *pp)
 		return -EINVAL;
 	}
 
+	if (of_property_read_u64(np, "base-mask", &pp->base_mask))
+		pp->base_mask = ~0x0ULL;
+
 	if (IS_ENABLED(CONFIG_PCI_MSI)) {
 		pp->irq_domain = irq_domain_add_linear(pp->dev->of_node,
 					MAX_MSI_IRQS, &msi_domain_ops,
@@ -502,12 +505,15 @@  int __init dw_pcie_host_init(struct pcie_port *pp)
 
 static void dw_pcie_prog_viewport_cfg0(struct pcie_port *pp, u32 busdev)
 {
+	u64 cfg0_base;
+
+	cfg0_base = pp->cfg0_base & pp->base_mask;
 	/* Program viewport 0 : OUTBOUND : CFG0 */
 	dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
 			  PCIE_ATU_VIEWPORT);
-	dw_pcie_writel_rc(pp, pp->cfg0_base, PCIE_ATU_LOWER_BASE);
-	dw_pcie_writel_rc(pp, (pp->cfg0_base >> 32), PCIE_ATU_UPPER_BASE);
-	dw_pcie_writel_rc(pp, pp->cfg0_base + pp->config.cfg0_size - 1,
+	dw_pcie_writel_rc(pp, cfg0_base, PCIE_ATU_LOWER_BASE);
+	dw_pcie_writel_rc(pp, (cfg0_base >> 32), PCIE_ATU_UPPER_BASE);
+	dw_pcie_writel_rc(pp, cfg0_base + pp->config.cfg0_size - 1,
 			  PCIE_ATU_LIMIT);
 	dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET);
 	dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET);
@@ -517,13 +523,16 @@  static void dw_pcie_prog_viewport_cfg0(struct pcie_port *pp, u32 busdev)
 
 static void dw_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev)
 {
+	u64 cfg1_base;
+
+	cfg1_base = pp->cfg1_base & pp->base_mask;
 	/* Program viewport 1 : OUTBOUND : CFG1 */
 	dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
 			  PCIE_ATU_VIEWPORT);
 	dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1);
-	dw_pcie_writel_rc(pp, pp->cfg1_base, PCIE_ATU_LOWER_BASE);
-	dw_pcie_writel_rc(pp, (pp->cfg1_base >> 32), PCIE_ATU_UPPER_BASE);
-	dw_pcie_writel_rc(pp, pp->cfg1_base + pp->config.cfg1_size - 1,
+	dw_pcie_writel_rc(pp, cfg1_base, PCIE_ATU_LOWER_BASE);
+	dw_pcie_writel_rc(pp, (cfg1_base >> 32), PCIE_ATU_UPPER_BASE);
+	dw_pcie_writel_rc(pp, cfg1_base + pp->config.cfg1_size - 1,
 			  PCIE_ATU_LIMIT);
 	dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET);
 	dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET);
@@ -532,13 +541,16 @@  static void dw_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev)
 
 static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
 {
+	u64 mem_base;
+
+	mem_base = pp->mem_base & pp->base_mask;
 	/* Program viewport 0 : OUTBOUND : MEM */
 	dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
 			  PCIE_ATU_VIEWPORT);
 	dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1);
-	dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE);
-	dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE);
-	dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1,
+	dw_pcie_writel_rc(pp, mem_base, PCIE_ATU_LOWER_BASE);
+	dw_pcie_writel_rc(pp, (mem_base >> 32), PCIE_ATU_UPPER_BASE);
+	dw_pcie_writel_rc(pp, mem_base + pp->config.mem_size - 1,
 			  PCIE_ATU_LIMIT);
 	dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET);
 	dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr),
@@ -548,13 +560,16 @@  static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
 
 static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
 {
+	u64 io_base;
+
+	io_base = pp->io_base & pp->base_mask;
 	/* Program viewport 1 : OUTBOUND : IO */
 	dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
 			  PCIE_ATU_VIEWPORT);
 	dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1);
-	dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE);
-	dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE);
-	dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1,
+	dw_pcie_writel_rc(pp, io_base, PCIE_ATU_LOWER_BASE);
+	dw_pcie_writel_rc(pp, (io_base >> 32), PCIE_ATU_UPPER_BASE);
+	dw_pcie_writel_rc(pp, io_base + pp->config.io_size - 1,
 			  PCIE_ATU_LIMIT);
 	dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET);
 	dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr),
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index 3063b35..3fa12a6 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -35,6 +35,7 @@  struct pcie_port {
 	struct device		*dev;
 	u8			root_bus_nr;
 	void __iomem		*dbi_base;
+	u64			base_mask;
 	u64			cfg0_base;
 	void __iomem		*va_cfg0_base;
 	u64			cfg1_base;