diff mbox series

[v2,06/10] rpi4: add a mapping for the PCIe XHCI controller MMIO registers (ARM 32bit)

Message ID 20200504124523.23484-7-s.nawrocki@samsung.com
State Superseded
Delegated to: Matthias Brugger
Headers show
Series USB host support for Raspberry Pi 4 board | expand

Commit Message

Sylwester Nawrocki May 4, 2020, 12:45 p.m. UTC
From: Marek Szyprowski <m.szyprowski@samsung.com>

Create a non-cacheable mapping for the 0x600000000 physical memory region,
where MMIO registers for the PCIe XHCI controller are instantiated by the
PCIe bridge. Due to 32bit limit in the CPU virtual address space in ARM
32bit mode, this region is mapped at 0xff800000 CPU virtual address.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes since v1:
 - none.
---
 arch/arm/mach-bcm283x/Kconfig             |  1 +
 arch/arm/mach-bcm283x/include/mach/base.h |  7 +++++
 arch/arm/mach-bcm283x/init.c              | 52 +++++++++++++++++++++++++++++++
 3 files changed, 60 insertions(+)

Comments

Matthias Brugger May 5, 2020, 2:25 p.m. UTC | #1
On 04/05/2020 14:45, Sylwester Nawrocki wrote:
> From: Marek Szyprowski <m.szyprowski@samsung.com>
> 
> Create a non-cacheable mapping for the 0x600000000 physical memory region,
> where MMIO registers for the PCIe XHCI controller are instantiated by the
> PCIe bridge. Due to 32bit limit in the CPU virtual address space in ARM
> 32bit mode, this region is mapped at 0xff800000 CPU virtual address.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
> Changes since v1:
>  - none.
> ---
>  arch/arm/mach-bcm283x/Kconfig             |  1 +
>  arch/arm/mach-bcm283x/include/mach/base.h |  7 +++++
>  arch/arm/mach-bcm283x/init.c              | 52 +++++++++++++++++++++++++++++++
>  3 files changed, 60 insertions(+)
> 
> diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
> index 00419bf..bcb7f1d 100644
> --- a/arch/arm/mach-bcm283x/Kconfig
> +++ b/arch/arm/mach-bcm283x/Kconfig
> @@ -36,6 +36,7 @@ config BCM2711_32B
>  	select BCM2711
>  	select ARMV7_LPAE
>  	select CPU_V7A
> +	select PHYS_64BIT
>  
>  config BCM2711_64B
>  	bool "Broadcom BCM2711 SoC 64-bit support"
> diff --git a/arch/arm/mach-bcm283x/include/mach/base.h b/arch/arm/mach-bcm283x/include/mach/base.h
> index c4ae398..1d10dc9 100644
> --- a/arch/arm/mach-bcm283x/include/mach/base.h
> +++ b/arch/arm/mach-bcm283x/include/mach/base.h
> @@ -6,6 +6,13 @@
>  #ifndef _BCM283x_BASE_H_
>  #define _BCM283x_BASE_H_
>  
> +#include <linux/types.h>
> +
>  extern unsigned long rpi_bcm283x_base;
>  
> +#ifdef CONFIG_ARMV7_LPAE
> +extern void *rpi4_phys_to_virt(phys_addr_t paddr);
> +#define phys_to_virt(x) rpi4_phys_to_virt(x)
> +#endif
> +
>  #endif
> diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
> index 6a748da..5d0d160 100644
> --- a/arch/arm/mach-bcm283x/init.c
> +++ b/arch/arm/mach-bcm283x/init.c
> @@ -145,6 +145,58 @@ int mach_cpu_init(void)
>  }
>  
>  #ifdef CONFIG_ARMV7_LPAE
> +
> +#define BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT	0xff800000UL
> +
> +void *rpi4_phys_to_virt(phys_addr_t paddr)
> +{
> +	if (paddr >= BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS)
> +		paddr = paddr - BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS +
> +			BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT;
> +	return (void *)(unsigned long)paddr;
> +}
> +
> +static void set_section_phys(unsigned int section, phys_addr_t phys,
> +			     enum dcache_option option)
> +{
> +	u64 *page_table = (u64 *)gd->arch.tlb_addr;
> +	/* Need to set the access flag to not fault */
> +	u64 value = TTB_SECT_AP | TTB_SECT_AF;
> +
> +	/* Add the page offset */
> +	value |= (phys);
> +
> +	/* Add caching bits */
> +	value |= option;
> +
> +	/* Set PTE */
> +	page_table[section] = value;
> +}
> +
> +static void rpi4_create_pcie_xhci_mapping(void)
> +{
> +	unsigned sect = BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT >> MMU_SECTION_SHIFT;
> +	phys_addr_t phys_addr = BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS;
> +	unsigned int size = BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE;
> +
> +	while (size) {
> +		set_section_phys(sect, phys_addr, DCACHE_OFF);
> +		sect++;
> +		phys_addr += MMU_SECTION_SIZE;
> +		size -= MMU_SECTION_SIZE;
> +	}

Why can't we reuse mmu_set_region_dcache_behaviour()?

> +}
> +
> +void arm_init_domains(void)
> +{
> +	/*
> +	 * Hijack this function to prepare a mappings for the PCIe MMIO
> +	 * region for the XHCI controller on RPi4 board.
> +	 * This code is called before enabling the MMU in ARM 32bit mode.
> +	 */
> +	rpi4_create_pcie_xhci_mapping();

I think this indirection is not necessary.

Regards,
Matthias

> +}
> +
>  void enable_caches(void)
>  {
>  	dcache_enable();
>
Marek Szyprowski May 5, 2020, 2:43 p.m. UTC | #2
Hi Matthias,

On 05.05.2020 16:25, Matthias Brugger wrote:
> On 04/05/2020 14:45, Sylwester Nawrocki wrote:
>> From: Marek Szyprowski <m.szyprowski@samsung.com>
>>
>> Create a non-cacheable mapping for the 0x600000000 physical memory region,
>> where MMIO registers for the PCIe XHCI controller are instantiated by the
>> PCIe bridge. Due to 32bit limit in the CPU virtual address space in ARM
>> 32bit mode, this region is mapped at 0xff800000 CPU virtual address.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
>> ---
>> Changes since v1:
>>   - none.
>> ---
>>   arch/arm/mach-bcm283x/Kconfig             |  1 +
>>   arch/arm/mach-bcm283x/include/mach/base.h |  7 +++++
>>   arch/arm/mach-bcm283x/init.c              | 52 +++++++++++++++++++++++++++++++
>>   3 files changed, 60 insertions(+)
>>
>> diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
>> index 00419bf..bcb7f1d 100644
>> --- a/arch/arm/mach-bcm283x/Kconfig
>> +++ b/arch/arm/mach-bcm283x/Kconfig
>> @@ -36,6 +36,7 @@ config BCM2711_32B
>>   	select BCM2711
>>   	select ARMV7_LPAE
>>   	select CPU_V7A
>> +	select PHYS_64BIT
>>   
>>   config BCM2711_64B
>>   	bool "Broadcom BCM2711 SoC 64-bit support"
>> diff --git a/arch/arm/mach-bcm283x/include/mach/base.h b/arch/arm/mach-bcm283x/include/mach/base.h
>> index c4ae398..1d10dc9 100644
>> --- a/arch/arm/mach-bcm283x/include/mach/base.h
>> +++ b/arch/arm/mach-bcm283x/include/mach/base.h
>> @@ -6,6 +6,13 @@
>>   #ifndef _BCM283x_BASE_H_
>>   #define _BCM283x_BASE_H_
>>   
>> +#include <linux/types.h>
>> +
>>   extern unsigned long rpi_bcm283x_base;
>>   
>> +#ifdef CONFIG_ARMV7_LPAE
>> +extern void *rpi4_phys_to_virt(phys_addr_t paddr);
>> +#define phys_to_virt(x) rpi4_phys_to_virt(x)
>> +#endif
>> +
>>   #endif
>> diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
>> index 6a748da..5d0d160 100644
>> --- a/arch/arm/mach-bcm283x/init.c
>> +++ b/arch/arm/mach-bcm283x/init.c
>> @@ -145,6 +145,58 @@ int mach_cpu_init(void)
>>   }
>>   
>>   #ifdef CONFIG_ARMV7_LPAE
>> +
>> +#define BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT	0xff800000UL
>> +
>> +void *rpi4_phys_to_virt(phys_addr_t paddr)
>> +{
>> +	if (paddr >= BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS)
>> +		paddr = paddr - BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS +
>> +			BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT;
>> +	return (void *)(unsigned long)paddr;
>> +}
>> +
>> +static void set_section_phys(unsigned int section, phys_addr_t phys,
>> +			     enum dcache_option option)
>> +{
>> +	u64 *page_table = (u64 *)gd->arch.tlb_addr;
>> +	/* Need to set the access flag to not fault */
>> +	u64 value = TTB_SECT_AP | TTB_SECT_AF;
>> +
>> +	/* Add the page offset */
>> +	value |= (phys);
>> +
>> +	/* Add caching bits */
>> +	value |= option;
>> +
>> +	/* Set PTE */
>> +	page_table[section] = value;
>> +}
>> +
>> +static void rpi4_create_pcie_xhci_mapping(void)
>> +{
>> +	unsigned sect = BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT >> MMU_SECTION_SHIFT;
>> +	phys_addr_t phys_addr = BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS;
>> +	unsigned int size = BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE;
>> +
>> +	while (size) {
>> +		set_section_phys(sect, phys_addr, DCACHE_OFF);
>> +		sect++;
>> +		phys_addr += MMU_SECTION_SIZE;
>> +		size -= MMU_SECTION_SIZE;
>> +	}
> Why can't we reuse mmu_set_region_dcache_behaviour()?

Because it doesn't allow to set arbirtary physical address - it only 
works for the cases where phys == virt.


>
>> +}
>> +
>> +void arm_init_domains(void)
>> +{
>> +	/*
>> +	 * Hijack this function to prepare a mappings for the PCIe MMIO
>> +	 * region for the XHCI controller on RPi4 board.
>> +	 * This code is called before enabling the MMU in ARM 32bit mode.
>> +	 */
>> +	rpi4_create_pcie_xhci_mapping();
> I think this indirection is not necessary.

Okay.


Best regards
Matthias Brugger May 8, 2020, 9:26 p.m. UTC | #3
Adding Tom as he is the arm maintainer.

On 04/05/2020 14:45, Sylwester Nawrocki wrote:
> From: Marek Szyprowski <m.szyprowski@samsung.com>
> 
> Create a non-cacheable mapping for the 0x600000000 physical memory region,
> where MMIO registers for the PCIe XHCI controller are instantiated by the
> PCIe bridge. Due to 32bit limit in the CPU virtual address space in ARM
> 32bit mode, this region is mapped at 0xff800000 CPU virtual address.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
> Changes since v1:
>  - none.
> ---
>  arch/arm/mach-bcm283x/Kconfig             |  1 +
>  arch/arm/mach-bcm283x/include/mach/base.h |  7 +++++
>  arch/arm/mach-bcm283x/init.c              | 52 +++++++++++++++++++++++++++++++
>  3 files changed, 60 insertions(+)
> 
> diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
> index 00419bf..bcb7f1d 100644
> --- a/arch/arm/mach-bcm283x/Kconfig
> +++ b/arch/arm/mach-bcm283x/Kconfig
> @@ -36,6 +36,7 @@ config BCM2711_32B
>  	select BCM2711
>  	select ARMV7_LPAE
>  	select CPU_V7A
> +	select PHYS_64BIT
>  
>  config BCM2711_64B
>  	bool "Broadcom BCM2711 SoC 64-bit support"
> diff --git a/arch/arm/mach-bcm283x/include/mach/base.h b/arch/arm/mach-bcm283x/include/mach/base.h
> index c4ae398..1d10dc9 100644
> --- a/arch/arm/mach-bcm283x/include/mach/base.h
> +++ b/arch/arm/mach-bcm283x/include/mach/base.h
> @@ -6,6 +6,13 @@
>  #ifndef _BCM283x_BASE_H_
>  #define _BCM283x_BASE_H_
>  
> +#include <linux/types.h>
> +
>  extern unsigned long rpi_bcm283x_base;
>  
> +#ifdef CONFIG_ARMV7_LPAE
> +extern void *rpi4_phys_to_virt(phys_addr_t paddr);
> +#define phys_to_virt(x) rpi4_phys_to_virt(x)
> +#endif
> +
>  #endif
> diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
> index 6a748da..5d0d160 100644
> --- a/arch/arm/mach-bcm283x/init.c
> +++ b/arch/arm/mach-bcm283x/init.c
> @@ -145,6 +145,58 @@ int mach_cpu_init(void)
>  }
>  
>  #ifdef CONFIG_ARMV7_LPAE
> +
> +#define BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT	0xff800000UL
> +
> +void *rpi4_phys_to_virt(phys_addr_t paddr)
> +{
> +	if (paddr >= BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS)
> +		paddr = paddr - BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS +
> +			BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT;
> +	return (void *)(unsigned long)paddr;

I think for this cases we have addrmap_phys_to_virt() which up to now is only
used by powerpc.

> +}
> +
> +static void set_section_phys(unsigned int section, phys_addr_t phys,
> +			     enum dcache_option option)
> +{
> +	u64 *page_table = (u64 *)gd->arch.tlb_addr;
> +	/* Need to set the access flag to not fault */
> +	u64 value = TTB_SECT_AP | TTB_SECT_AF;
> +
> +	/* Add the page offset */
> +	value |= (phys);
> +
> +	/* Add caching bits */
> +	value |= option;
> +
> +	/* Set PTE */
> +	page_table[section] = value;
> +}
> +
> +static void rpi4_create_pcie_xhci_mapping(void)
> +{
> +	unsigned sect = BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT >> MMU_SECTION_SHIFT;
> +	phys_addr_t phys_addr = BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS;
> +	unsigned int size = BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE;
> +
> +	while (size) {
> +		set_section_phys(sect, phys_addr, DCACHE_OFF);
> +		sect++;
> +		phys_addr += MMU_SECTION_SIZE;
> +		size -= MMU_SECTION_SIZE;
> +	}
> +}

I wonder if we can't do all this in the pcie driver probe function. Maybe we can
create a new function like mmu_set_region_dcache_behaviour_phys which allows us
to update a mapping that's not 1:1.

Tom what do you think?

Regards,
Matthias

> +
> +void arm_init_domains(void)
> +{
> +	/*
> +	 * Hijack this function to prepare a mappings for the PCIe MMIO
> +	 * region for the XHCI controller on RPi4 board.
> +	 * This code is called before enabling the MMU in ARM 32bit mode.
> +	 */
> +	rpi4_create_pcie_xhci_mapping();
> +}
> +
>  void enable_caches(void)
>  {
>  	dcache_enable();
>
Tom Rini May 11, 2020, 7:44 p.m. UTC | #4
On Fri, May 08, 2020 at 11:26:36PM +0200, Matthias Brugger wrote:
> Adding Tom as he is the arm maintainer.
> 
> On 04/05/2020 14:45, Sylwester Nawrocki wrote:
> > From: Marek Szyprowski <m.szyprowski@samsung.com>
> > 
> > Create a non-cacheable mapping for the 0x600000000 physical memory region,
> > where MMIO registers for the PCIe XHCI controller are instantiated by the
> > PCIe bridge. Due to 32bit limit in the CPU virtual address space in ARM
> > 32bit mode, this region is mapped at 0xff800000 CPU virtual address.
> > 
> > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > ---
> > Changes since v1:
> >  - none.
> > ---
> >  arch/arm/mach-bcm283x/Kconfig             |  1 +
> >  arch/arm/mach-bcm283x/include/mach/base.h |  7 +++++
> >  arch/arm/mach-bcm283x/init.c              | 52 +++++++++++++++++++++++++++++++
> >  3 files changed, 60 insertions(+)
> > 
> > diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
> > index 00419bf..bcb7f1d 100644
> > --- a/arch/arm/mach-bcm283x/Kconfig
> > +++ b/arch/arm/mach-bcm283x/Kconfig
> > @@ -36,6 +36,7 @@ config BCM2711_32B
> >  	select BCM2711
> >  	select ARMV7_LPAE
> >  	select CPU_V7A
> > +	select PHYS_64BIT
> >  
> >  config BCM2711_64B
> >  	bool "Broadcom BCM2711 SoC 64-bit support"
> > diff --git a/arch/arm/mach-bcm283x/include/mach/base.h b/arch/arm/mach-bcm283x/include/mach/base.h
> > index c4ae398..1d10dc9 100644
> > --- a/arch/arm/mach-bcm283x/include/mach/base.h
> > +++ b/arch/arm/mach-bcm283x/include/mach/base.h
> > @@ -6,6 +6,13 @@
> >  #ifndef _BCM283x_BASE_H_
> >  #define _BCM283x_BASE_H_
> >  
> > +#include <linux/types.h>
> > +
> >  extern unsigned long rpi_bcm283x_base;
> >  
> > +#ifdef CONFIG_ARMV7_LPAE
> > +extern void *rpi4_phys_to_virt(phys_addr_t paddr);
> > +#define phys_to_virt(x) rpi4_phys_to_virt(x)
> > +#endif
> > +
> >  #endif
> > diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
> > index 6a748da..5d0d160 100644
> > --- a/arch/arm/mach-bcm283x/init.c
> > +++ b/arch/arm/mach-bcm283x/init.c
> > @@ -145,6 +145,58 @@ int mach_cpu_init(void)
> >  }
> >  
> >  #ifdef CONFIG_ARMV7_LPAE
> > +
> > +#define BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT	0xff800000UL
> > +
> > +void *rpi4_phys_to_virt(phys_addr_t paddr)
> > +{
> > +	if (paddr >= BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS)
> > +		paddr = paddr - BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS +
> > +			BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT;
> > +	return (void *)(unsigned long)paddr;
> 
> I think for this cases we have addrmap_phys_to_virt() which up to now is only
> used by powerpc.
> 
> > +}
> > +
> > +static void set_section_phys(unsigned int section, phys_addr_t phys,
> > +			     enum dcache_option option)
> > +{
> > +	u64 *page_table = (u64 *)gd->arch.tlb_addr;
> > +	/* Need to set the access flag to not fault */
> > +	u64 value = TTB_SECT_AP | TTB_SECT_AF;
> > +
> > +	/* Add the page offset */
> > +	value |= (phys);
> > +
> > +	/* Add caching bits */
> > +	value |= option;
> > +
> > +	/* Set PTE */
> > +	page_table[section] = value;
> > +}
> > +
> > +static void rpi4_create_pcie_xhci_mapping(void)
> > +{
> > +	unsigned sect = BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT >> MMU_SECTION_SHIFT;
> > +	phys_addr_t phys_addr = BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS;
> > +	unsigned int size = BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE;
> > +
> > +	while (size) {
> > +		set_section_phys(sect, phys_addr, DCACHE_OFF);
> > +		sect++;
> > +		phys_addr += MMU_SECTION_SIZE;
> > +		size -= MMU_SECTION_SIZE;
> > +	}
> > +}
> 
> I wonder if we can't do all this in the pcie driver probe function. Maybe we can
> create a new function like mmu_set_region_dcache_behaviour_phys which allows us
> to update a mapping that's not 1:1.
> 
> Tom what do you think?

I think a harder look at how PowerPC handled this situation is in order,
and then following / extending that path is in order.
Matthias Brugger May 11, 2020, 7:47 p.m. UTC | #5
On 11/05/2020 21:44, Tom Rini wrote:
> On Fri, May 08, 2020 at 11:26:36PM +0200, Matthias Brugger wrote:
>> Adding Tom as he is the arm maintainer.
>>
>> On 04/05/2020 14:45, Sylwester Nawrocki wrote:
>>> From: Marek Szyprowski <m.szyprowski@samsung.com>
>>>
>>> Create a non-cacheable mapping for the 0x600000000 physical memory region,
>>> where MMIO registers for the PCIe XHCI controller are instantiated by the
>>> PCIe bridge. Due to 32bit limit in the CPU virtual address space in ARM
>>> 32bit mode, this region is mapped at 0xff800000 CPU virtual address.
>>>
>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
>>> ---
>>> Changes since v1:
>>>  - none.
>>> ---
>>>  arch/arm/mach-bcm283x/Kconfig             |  1 +
>>>  arch/arm/mach-bcm283x/include/mach/base.h |  7 +++++
>>>  arch/arm/mach-bcm283x/init.c              | 52 +++++++++++++++++++++++++++++++
>>>  3 files changed, 60 insertions(+)
>>>
>>> diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
>>> index 00419bf..bcb7f1d 100644
>>> --- a/arch/arm/mach-bcm283x/Kconfig
>>> +++ b/arch/arm/mach-bcm283x/Kconfig
>>> @@ -36,6 +36,7 @@ config BCM2711_32B
>>>  	select BCM2711
>>>  	select ARMV7_LPAE
>>>  	select CPU_V7A
>>> +	select PHYS_64BIT
>>>  
>>>  config BCM2711_64B
>>>  	bool "Broadcom BCM2711 SoC 64-bit support"
>>> diff --git a/arch/arm/mach-bcm283x/include/mach/base.h b/arch/arm/mach-bcm283x/include/mach/base.h
>>> index c4ae398..1d10dc9 100644
>>> --- a/arch/arm/mach-bcm283x/include/mach/base.h
>>> +++ b/arch/arm/mach-bcm283x/include/mach/base.h
>>> @@ -6,6 +6,13 @@
>>>  #ifndef _BCM283x_BASE_H_
>>>  #define _BCM283x_BASE_H_
>>>  
>>> +#include <linux/types.h>
>>> +
>>>  extern unsigned long rpi_bcm283x_base;
>>>  
>>> +#ifdef CONFIG_ARMV7_LPAE
>>> +extern void *rpi4_phys_to_virt(phys_addr_t paddr);
>>> +#define phys_to_virt(x) rpi4_phys_to_virt(x)
>>> +#endif
>>> +
>>>  #endif
>>> diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
>>> index 6a748da..5d0d160 100644
>>> --- a/arch/arm/mach-bcm283x/init.c
>>> +++ b/arch/arm/mach-bcm283x/init.c
>>> @@ -145,6 +145,58 @@ int mach_cpu_init(void)
>>>  }
>>>  
>>>  #ifdef CONFIG_ARMV7_LPAE
>>> +
>>> +#define BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT	0xff800000UL
>>> +
>>> +void *rpi4_phys_to_virt(phys_addr_t paddr)
>>> +{
>>> +	if (paddr >= BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS)
>>> +		paddr = paddr - BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS +
>>> +			BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT;
>>> +	return (void *)(unsigned long)paddr;
>>
>> I think for this cases we have addrmap_phys_to_virt() which up to now is only
>> used by powerpc.
>>
>>> +}
>>> +
>>> +static void set_section_phys(unsigned int section, phys_addr_t phys,
>>> +			     enum dcache_option option)
>>> +{
>>> +	u64 *page_table = (u64 *)gd->arch.tlb_addr;
>>> +	/* Need to set the access flag to not fault */
>>> +	u64 value = TTB_SECT_AP | TTB_SECT_AF;
>>> +
>>> +	/* Add the page offset */
>>> +	value |= (phys);
>>> +
>>> +	/* Add caching bits */
>>> +	value |= option;
>>> +
>>> +	/* Set PTE */
>>> +	page_table[section] = value;
>>> +}
>>> +
>>> +static void rpi4_create_pcie_xhci_mapping(void)
>>> +{
>>> +	unsigned sect = BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT >> MMU_SECTION_SHIFT;
>>> +	phys_addr_t phys_addr = BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS;
>>> +	unsigned int size = BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE;
>>> +
>>> +	while (size) {
>>> +		set_section_phys(sect, phys_addr, DCACHE_OFF);
>>> +		sect++;
>>> +		phys_addr += MMU_SECTION_SIZE;
>>> +		size -= MMU_SECTION_SIZE;
>>> +	}
>>> +}
>>
>> I wonder if we can't do all this in the pcie driver probe function. Maybe we can
>> create a new function like mmu_set_region_dcache_behaviour_phys which allows us
>> to update a mapping that's not 1:1.
>>
>> Tom what do you think?
> 
> I think a harder look at how PowerPC handled this situation is in order,
> and then following / extending that path is in order.
> 

Thanks Tom for the feedback.
Sylwester, I propose to split the series in two. One for adding the driver to
64-bit U-Boot and another one to add support for rpi_4_32b_defconfig. This way
we could get the driver merged for 2020.07 for sure, while 32-bit parts could
take more cycles to be ready. What do you think?

Regards,
Matthias
Sylwester Nawrocki May 12, 2020, 10:25 a.m. UTC | #6
On 11.05.2020 21:47, Matthias Brugger wrote:
>>>> static void rpi4_create_pcie_xhci_mapping(void)
>>>> +{
>>>> +	unsigned sect = BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT >> MMU_SECTION_SHIFT;
>>>> +	phys_addr_t phys_addr = BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS;
>>>> +	unsigned int size = BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE;
>>>> +
>>>> +	while (size) {
>>>> +		set_section_phys(sect, phys_addr, DCACHE_OFF);
>>>> +		sect++;
>>>> +		phys_addr += MMU_SECTION_SIZE;
>>>> +		size -= MMU_SECTION_SIZE;
>>>> +	}
>>>> +}
>>> I wonder if we can't do all this in the pcie driver probe function. Maybe we can
>>> create a new function like mmu_set_region_dcache_behaviour_phys which allows us
>>> to update a mapping that's not 1:1.
>>>
>>> Tom what do you think?
>> I think a harder look at how PowerPC handled this situation is in order,
>> and then following / extending that path is in order.
>>
> Thanks Tom for the feedback.
> Sylwester, I propose to split the series in two. One for adding the driver to
> 64-bit U-Boot and another one to add support for rpi_4_32b_defconfig. This way
> we could get the driver merged for 2020.07 for sure, while 32-bit parts could
> take more cycles to be ready. What do you think?

Sounds good to me, I will split the series and will post the 64-bits part
first, while we work on the 32-bit part according to your suggestions.
Marek Szyprowski May 12, 2020, 12:04 p.m. UTC | #7
Hi Matthias,

On 08.05.2020 23:26, Matthias Brugger wrote:
> Adding Tom as he is the arm maintainer.
>
> On 04/05/2020 14:45, Sylwester Nawrocki wrote:
>> From: Marek Szyprowski <m.szyprowski@samsung.com>
>>
>> Create a non-cacheable mapping for the 0x600000000 physical memory region,
>> where MMIO registers for the PCIe XHCI controller are instantiated by the
>> PCIe bridge. Due to 32bit limit in the CPU virtual address space in ARM
>> 32bit mode, this region is mapped at 0xff800000 CPU virtual address.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
>> ---
>> Changes since v1:
>>   - none.
>> ---
>>   arch/arm/mach-bcm283x/Kconfig             |  1 +
>>   arch/arm/mach-bcm283x/include/mach/base.h |  7 +++++
>>   arch/arm/mach-bcm283x/init.c              | 52 +++++++++++++++++++++++++++++++
>>   3 files changed, 60 insertions(+)
>>
>> diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
>> index 00419bf..bcb7f1d 100644
>> --- a/arch/arm/mach-bcm283x/Kconfig
>> +++ b/arch/arm/mach-bcm283x/Kconfig
>> @@ -36,6 +36,7 @@ config BCM2711_32B
>>   	select BCM2711
>>   	select ARMV7_LPAE
>>   	select CPU_V7A
>> +	select PHYS_64BIT
>>   
>>   config BCM2711_64B
>>   	bool "Broadcom BCM2711 SoC 64-bit support"
>> diff --git a/arch/arm/mach-bcm283x/include/mach/base.h b/arch/arm/mach-bcm283x/include/mach/base.h
>> index c4ae398..1d10dc9 100644
>> --- a/arch/arm/mach-bcm283x/include/mach/base.h
>> +++ b/arch/arm/mach-bcm283x/include/mach/base.h
>> @@ -6,6 +6,13 @@
>>   #ifndef _BCM283x_BASE_H_
>>   #define _BCM283x_BASE_H_
>>   
>> +#include <linux/types.h>
>> +
>>   extern unsigned long rpi_bcm283x_base;
>>   
>> +#ifdef CONFIG_ARMV7_LPAE
>> +extern void *rpi4_phys_to_virt(phys_addr_t paddr);
>> +#define phys_to_virt(x) rpi4_phys_to_virt(x)
>> +#endif
>> +
>>   #endif
>> diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
>> index 6a748da..5d0d160 100644
>> --- a/arch/arm/mach-bcm283x/init.c
>> +++ b/arch/arm/mach-bcm283x/init.c
>> @@ -145,6 +145,58 @@ int mach_cpu_init(void)
>>   }
>>   
>>   #ifdef CONFIG_ARMV7_LPAE
>> +
>> +#define BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT	0xff800000UL
>> +
>> +void *rpi4_phys_to_virt(phys_addr_t paddr)
>> +{
>> +	if (paddr >= BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS)
>> +		paddr = paddr - BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS +
>> +			BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT;
>> +	return (void *)(unsigned long)paddr;
> I think for this cases we have addrmap_phys_to_virt() which up to now is only
> used by powerpc.
>
>> +}
>> +
>> +static void set_section_phys(unsigned int section, phys_addr_t phys,
>> +			     enum dcache_option option)
>> +{
>> +	u64 *page_table = (u64 *)gd->arch.tlb_addr;
>> +	/* Need to set the access flag to not fault */
>> +	u64 value = TTB_SECT_AP | TTB_SECT_AF;
>> +
>> +	/* Add the page offset */
>> +	value |= (phys);
>> +
>> +	/* Add caching bits */
>> +	value |= option;
>> +
>> +	/* Set PTE */
>> +	page_table[section] = value;
>> +}
>> +
>> +static void rpi4_create_pcie_xhci_mapping(void)
>> +{
>> +	unsigned sect = BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT >> MMU_SECTION_SHIFT;
>> +	phys_addr_t phys_addr = BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS;
>> +	unsigned int size = BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE;
>> +
>> +	while (size) {
>> +		set_section_phys(sect, phys_addr, DCACHE_OFF);
>> +		sect++;
>> +		phys_addr += MMU_SECTION_SIZE;
>> +		size -= MMU_SECTION_SIZE;
>> +	}
>> +}
> I wonder if we can't do all this in the pcie driver probe function. Maybe we can
> create a new function like mmu_set_region_dcache_behaviour_phys which allows us
> to update a mapping that's not 1:1.
>
> Tom what do you think?

In theory this could be moved to pcie probe, but then how the pcie 
driver would know WHERE in the virtual address space it should create a 
mapping for the needed MMIO area? IMHO this is something SoC or board 
specific and creating such mapping in board init is justified.

I will adapt the code to use addr_map helpers.

Best regards
diff mbox series

Patch

diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
index 00419bf..bcb7f1d 100644
--- a/arch/arm/mach-bcm283x/Kconfig
+++ b/arch/arm/mach-bcm283x/Kconfig
@@ -36,6 +36,7 @@  config BCM2711_32B
 	select BCM2711
 	select ARMV7_LPAE
 	select CPU_V7A
+	select PHYS_64BIT
 
 config BCM2711_64B
 	bool "Broadcom BCM2711 SoC 64-bit support"
diff --git a/arch/arm/mach-bcm283x/include/mach/base.h b/arch/arm/mach-bcm283x/include/mach/base.h
index c4ae398..1d10dc9 100644
--- a/arch/arm/mach-bcm283x/include/mach/base.h
+++ b/arch/arm/mach-bcm283x/include/mach/base.h
@@ -6,6 +6,13 @@ 
 #ifndef _BCM283x_BASE_H_
 #define _BCM283x_BASE_H_
 
+#include <linux/types.h>
+
 extern unsigned long rpi_bcm283x_base;
 
+#ifdef CONFIG_ARMV7_LPAE
+extern void *rpi4_phys_to_virt(phys_addr_t paddr);
+#define phys_to_virt(x) rpi4_phys_to_virt(x)
+#endif
+
 #endif
diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
index 6a748da..5d0d160 100644
--- a/arch/arm/mach-bcm283x/init.c
+++ b/arch/arm/mach-bcm283x/init.c
@@ -145,6 +145,58 @@  int mach_cpu_init(void)
 }
 
 #ifdef CONFIG_ARMV7_LPAE
+
+#define BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT	0xff800000UL
+
+void *rpi4_phys_to_virt(phys_addr_t paddr)
+{
+	if (paddr >= BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS)
+		paddr = paddr - BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS +
+			BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT;
+	return (void *)(unsigned long)paddr;
+}
+
+static void set_section_phys(unsigned int section, phys_addr_t phys,
+			     enum dcache_option option)
+{
+	u64 *page_table = (u64 *)gd->arch.tlb_addr;
+	/* Need to set the access flag to not fault */
+	u64 value = TTB_SECT_AP | TTB_SECT_AF;
+
+	/* Add the page offset */
+	value |= (phys);
+
+	/* Add caching bits */
+	value |= option;
+
+	/* Set PTE */
+	page_table[section] = value;
+}
+
+static void rpi4_create_pcie_xhci_mapping(void)
+{
+	unsigned sect = BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT >> MMU_SECTION_SHIFT;
+	phys_addr_t phys_addr = BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS;
+	unsigned int size = BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE;
+
+	while (size) {
+		set_section_phys(sect, phys_addr, DCACHE_OFF);
+		sect++;
+		phys_addr += MMU_SECTION_SIZE;
+		size -= MMU_SECTION_SIZE;
+	}
+}
+
+void arm_init_domains(void)
+{
+	/*
+	 * Hijack this function to prepare a mappings for the PCIe MMIO
+	 * region for the XHCI controller on RPi4 board.
+	 * This code is called before enabling the MMU in ARM 32bit mode.
+	 */
+	rpi4_create_pcie_xhci_mapping();
+}
+
 void enable_caches(void)
 {
 	dcache_enable();