dm: pci: tegra: Convert Tegra PCI to driver model
Subsystems (5)
v4 cover dm: pci: tegra: Convert Tegra PCI to driver model
This series converts all Tegra boards to use driver model for PCI. The net effect should be no change in functionality.
A few additional features are added to make this possible:
- Helper functions to support accessing 8- and 16-bit values within a 32-bit word
- Fixing a build error for CONFIG_CMD_PCI_ENUM
- Decoding the PCI ranges property such that configuration ranges are ignored
- Supporting bus-master devices on boards where RAM does not start at 0
This series is tested on beaver. It is available at u-boot-dm/tegra-working.
Changes in v4:
- Fix Kconig typo in commit message
- Drop CONFIG_CMD_PCI_ENUM for p2371-2180 also
- Fix merge conflict resolution error in v3
- Add compatible string for T210 (from Stephen Warren)
Changes in v3:
- Rebase onto tegra/master
- Enable DM_PCI for Tegra 210 family too
Changes in v2:
- Update commit message to explain that the feature is not important
- Drop the feature from tegra boards
- Rename 'addr' to 'size'
- Correct logic for use of gd->pci_ram_top
- Update commit message to mention future work
- Use the device_is_on_pci_bus() API
- Leave pci_skip_dev() at the bottom of the file to reduce the diff size
Simon Glass (8):
dm: tegra: pci: Move CONFIG_PCI_TEGRA to Kconfig
dm: pci: Avoid a driver model build error with CONFIG_CMD_PCI_ENUM
dm: pci: Set up the SDRAM mapping correctly
dm: pci: Support decoding ranges with duplicate entries
dm: pci: Add functions to emulate 8- and 16-bit access
dm: pci: Add a function to get the controller for a bus
dm: pci: Add a function to find the regions for a PCI bus
dm: tegra: pci: Convert tegra boards to driver model for PCI
arch/arm/mach-tegra/Kconfig | 2 + common/cmd_pci.c | 4 + configs/apalis_t30_defconfig | 1 + configs/beaver_defconfig | 1 + configs/cardhu_defconfig | 1 + configs/jetson-tk1_defconfig | 1 + configs/p2371-2180_defconfig | 1 + configs/trimslice_defconfig | 1 + drivers/pci/Kconfig | 10 + drivers/pci/pci-uclass.c | 105 +++++++++- drivers/pci/pci_tegra.c | 467 ++++++++++++++----------------------------- include/configs/apalis_t30.h | 2 - include/configs/beaver.h | 2 - include/configs/cardhu.h | 2 - include/configs/jetson-tk1.h | 2 - include/configs/p2371-2180.h | 2 - include/configs/trimslice.h | 2 - include/fdtdec.h | 4 - include/pci.h | 51 +++++ lib/fdtdec.c | 4 - 20 files changed, 319 insertions(+), 346 deletions(-)
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v4 1/8 dm: tegra: pci: Move CONFIG_PCI_TEGRA to Kconfig
Move this option to Kconfig and fix up all users.
---
Changes in v4:
- Fix Kconig typo in commit message
Changes in v3: None
Changes in v2: None
configs/apalis_t30_defconfig | 1 + configs/beaver_defconfig | 1 + configs/cardhu_defconfig | 1 + configs/jetson-tk1_defconfig | 1 + configs/p2371-2180_defconfig | 1 + configs/trimslice_defconfig | 1 + drivers/pci/Kconfig | 10 ++++++++++ include/configs/apalis_t30.h | 1 - include/configs/beaver.h | 1 - include/configs/cardhu.h | 1 - include/configs/jetson-tk1.h | 1 - include/configs/p2371-2180.h | 1 - include/configs/trimslice.h | 1 - 13 files changed, 16 insertions(+), 6 deletions(-)
configs/apalis_t30_defconfig +1 -0
@@ -12,6 +12,7 @@ CONFIG_SYS_PROMPT="Apalis T30 # " # CONFIG_CMD_NFS is not set CONFIG_NETDEVICES=y CONFIG_E1000=y +CONFIG_PCI_TEGRA=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USE_PRIVATE_LIBGCC=y
configs/beaver_defconfig +1 -0
@@ -12,6 +12,7 @@ CONFIG_SYS_PROMPT="Tegra30 (Beaver) # " # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_NFS is not set CONFIG_SPI_FLASH=y +CONFIG_PCI_TEGRA=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USE_PRIVATE_LIBGCC=y
configs/cardhu_defconfig +1 -0
@@ -12,6 +12,7 @@ CONFIG_SYS_PROMPT="Tegra30 (Cardhu) # " # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_NFS is not set CONFIG_SPI_FLASH=y +CONFIG_PCI_TEGRA=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USE_PRIVATE_LIBGCC=y
configs/jetson-tk1_defconfig +1 -0
@@ -12,6 +12,7 @@ CONFIG_SYS_PROMPT="Tegra124 (Jetson TK1) # " # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_NFS is not set CONFIG_SPI_FLASH=y +CONFIG_PCI_TEGRA=y CONFIG_TEGRA114_SPI=y CONFIG_USB=y CONFIG_DM_USB=y
configs/p2371-2180_defconfig +1 -0
@@ -12,5 +12,6 @@ CONFIG_SYS_PROMPT="Tegra210 (P2371-2180) # " # CONFIG_CMD_NFS is not set CONFIG_SPI_FLASH=y CONFIG_TEGRA114_SPI=y +CONFIG_PCI_TEGRA=y CONFIG_USB=y CONFIG_DM_USB=y
configs/trimslice_defconfig +1 -0
@@ -12,6 +12,7 @@ CONFIG_SYS_PROMPT="Tegra20 (TrimSlice) # " # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_NFS is not set CONFIG_SPI_FLASH=y +CONFIG_PCI_TEGRA=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USE_PRIVATE_LIBGCC=y
drivers/pci/Kconfig +10 -0
@@ -19,4 +19,14 @@ config PCI_SANDBOX the device tree but the normal PCI scan technique is used to find then. +config PCI_TEGRA + bool "Tegra PCI support" + depends on TEGRA + help + Enable support for the PCIe controller found on some generations of + Tegra. Tegra20 has 2 root ports with a total of 4 lanes, Tegra30 has + 3 root ports with a total of 6 lanes and Tegra124 has 2 root ports + with a total of 5 lanes. Some boards require this for Ethernet + support to work (e.g. beaver, jetson-tk1). + endmenu
include/configs/apalis_t30.h +0 -1
@@ -49,7 +49,6 @@/* PCI host support */ #define CONFIG_PCI -#define CONFIG_PCI_TEGRA #define CONFIG_PCI_PNP #define CONFIG_CMD_PCI #define CONFIG_CMD_PCI_ENUM
include/configs/beaver.h +0 -1
@@ -73,7 +73,6 @@/* PCI host support */ #define CONFIG_PCI -#define CONFIG_PCI_TEGRA #define CONFIG_PCI_PNP #define CONFIG_CMD_PCI #define CONFIG_CMD_PCI_ENUM
include/configs/cardhu.h +0 -1
@@ -75,7 +75,6 @@/* PCI host support */ #define CONFIG_PCI -#define CONFIG_PCI_TEGRA #define CONFIG_PCI_PNP #define CONFIG_CMD_PCI #define CONFIG_CMD_PCI_ENUM
include/configs/jetson-tk1.h +0 -1
@@ -59,7 +59,6 @@/* PCI host support */ #define CONFIG_PCI -#define CONFIG_PCI_TEGRA #define CONFIG_PCI_PNP #define CONFIG_CMD_PCI #define CONFIG_CMD_PCI_ENUM
include/configs/p2371-2180.h +0 -1
@@ -55,7 +55,6 @@/* PCI host support */ #define CONFIG_PCI -#define CONFIG_PCI_TEGRA #define CONFIG_PCI_PNP #define CONFIG_CMD_PCI #define CONFIG_CMD_PCI_ENUM
include/configs/trimslice.h +0 -1
@@ -58,7 +58,6 @@/* PCI host support */ #define CONFIG_PCI -#define CONFIG_PCI_TEGRA #define CONFIG_PCI_PNP #define CONFIG_CMD_PCI #define CONFIG_CMD_PCI_ENUM
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v4 2/8 dm: pci: Avoid a driver model build error with CONFIG_CMD_PCI_ENUM
In reply to Simon GlassThis is not supported with driver model, so print a message instead of generating a build error. Rescanning PCI is not yet implemented.
This function will be implemented later once some additional PCI driver model improvements are merged. It was confirmed on the mailing list that no one on the tegra side will miss this feature, so it is disabled for tegra.
---
Changes in v4:
- Drop CONFIG_CMD_PCI_ENUM for p2371-2180 also
Changes in v3: None
Changes in v2:
- Update commit message to explain that the feature is not important
- Drop the feature from tegra boards
common/cmd_pci.c | 4 ++++ include/configs/apalis_t30.h | 1 - include/configs/beaver.h | 1 - include/configs/cardhu.h | 1 - include/configs/jetson-tk1.h | 1 - include/configs/p2371-2180.h | 1 - include/configs/trimslice.h | 1 - 7 files changed, 4 insertions(+), 6 deletions(-)
common/cmd_pci.c +4 -0
@@ -457,7 +457,11 @@ static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])return pci_cfg_display (bdf, addr, size, value);#ifdef CONFIG_CMD_PCI_ENUM case 'e' : +# ifdef CONFIG_DM_PCI +printf ("This command is not yet supported with driver model\n" ); +# else pci_init (); +# endif return 0 ;#endif case 'n' :/* next */
include/configs/apalis_t30.h +0 -1
@@ -51,7 +51,6 @@#define CONFIG_PCI #define CONFIG_PCI_PNP #define CONFIG_CMD_PCI -#define CONFIG_CMD_PCI_ENUM /* PCI networking support */ #define CONFIG_E1000_NO_NVM
include/configs/beaver.h +0 -1
@@ -75,7 +75,6 @@#define CONFIG_PCI #define CONFIG_PCI_PNP #define CONFIG_CMD_PCI -#define CONFIG_CMD_PCI_ENUM /* PCI networking support */ #define CONFIG_RTL8169
include/configs/cardhu.h +0 -1
@@ -77,7 +77,6 @@#define CONFIG_PCI #define CONFIG_PCI_PNP #define CONFIG_CMD_PCI -#define CONFIG_CMD_PCI_ENUM /* PCI networking support */ #define CONFIG_RTL8169
include/configs/jetson-tk1.h +0 -1
@@ -61,7 +61,6 @@#define CONFIG_PCI #define CONFIG_PCI_PNP #define CONFIG_CMD_PCI -#define CONFIG_CMD_PCI_ENUM /* PCI networking support */ #define CONFIG_RTL8169
include/configs/p2371-2180.h +0 -1
@@ -57,7 +57,6 @@#define CONFIG_PCI #define CONFIG_PCI_PNP #define CONFIG_CMD_PCI -#define CONFIG_CMD_PCI_ENUM /* PCI networking support */ #define CONFIG_RTL8169
include/configs/trimslice.h +0 -1
@@ -60,7 +60,6 @@#define CONFIG_PCI #define CONFIG_PCI_PNP #define CONFIG_CMD_PCI -#define CONFIG_CMD_PCI_ENUM /* PCI networking support */ #define CONFIG_RTL8169
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v4 3/8 dm: pci: Set up the SDRAM mapping correctly
In reply to Simon GlassSDRAM doesn't always start at 0. Adjust the region mapping so that it works on platforms where SDRAM is somewhere else.
This needs testing on other platforms.
---
Changes in v4: None
Changes in v3: None
Changes in v2:
- Rename 'addr' to 'size'
- Correct logic for use of gd->pci_ram_top
drivers/pci/pci-uclass.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/pci/pci-uclass.c +9 -6
@@ -680,8 +680,8 @@ static int decode_regions(struct pci_controller *hose, const void *blob, int parent_node, int node) { int pci_addr_cells, addr_cells, size_cells; +phys_addr_t base =0 , size;int cells_per_record; -phys_addr_t addr;const u32 *prop;int len;int i;
@@ -732,11 +732,14 @@ static int decode_regions(struct pci_controller *hose, const void *blob, }/* Add a region for our local memory */ - addr = gd->ram_size; -if (gd->pci_ram_top && gd->pci_ram_top < addr) - addr = gd->pci_ram_top; -pci_set_region (hose->regions + hose->region_count++,0 ,0 , addr, -PCI_REGION_MEM |PCI_REGION_SYS_MEMORY ); + size = gd->ram_size; +#ifdef CONFIG_SYS_SDRAM_BASE + base =CONFIG_SYS_SDRAM_BASE ; +#endif +if (gd->pci_ram_top && gd->pci_ram_top < base + size) + size = gd->pci_ram_top - base; +pci_set_region (hose->regions + hose->region_count++, base, base, + size,PCI_REGION_MEM |PCI_REGION_SYS_MEMORY );return 0 ; }
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v4 4/8 dm: pci: Support decoding ranges with duplicate entries
In reply to Simon GlassAt present we add a new resource entry for every range entry. But some range entries refer to configuration regions. To make this work, avoid adding two regions of the same type. The later ranges will overwrite the earlier (configuration) ones.
There does not seem to be a way to distinguish the configuration ranges other than by ordering (as per the device tree binding).
We could perhaps instead just store one region of each type in a simple array. Once we are sure that we don't need to support multiple regions, we could change this. It would be easier to do it when all drivers are converted to use driver model for PCI.
---
Changes in v4: None
Changes in v3: None
Changes in v2:
- Update commit message to mention future work
drivers/pci/pci-uclass.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/pci/pci-uclass.c +10 -3
@@ -704,6 +704,7 @@ static int decode_regions(struct pci_controller *hose, const void *blob,int space_code;u32 flags;int type; +int pos;if (len < cells_per_record)break ;
@@ -726,9 +727,15 @@ static int decode_regions(struct pci_controller *hose, const void *blob, }else {continue ; } -debug (" - type=%d\n" , type); -pci_set_region (hose->regions + hose->region_count++, pci_addr, - addr, size, type); + pos =-1 ; +for (i =0 ; i < hose->region_count; i++) { +if (hose->regions[i].flags == type) + pos = i; + } +if (pos ==-1 ) + pos = hose->region_count++; +debug (" - type=%d, pos=%d\n" , type, pos); +pci_set_region (hose->regions + pos, pci_addr, addr, size, type); }/* Add a region for our local memory */
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v4 5/8 dm: pci: Add functions to emulate 8- and 16-bit access
In reply to Simon GlassProvide a few functions to support using 32-bit access to emulate 8- and 16-bit access.
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/pci/pci-uclass.c | 39 +++++++++++++++++++++++++++++++++++++++ include/pci.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+)
drivers/pci/pci-uclass.c +39 -0
@@ -927,6 +927,45 @@ int pci_find_first_device(struct udevice **devp)return skip_to_next_device (bus, devp); } +ulong pci_conv_32_to_size (ulong value,uint offset,enum pci_size_t size) +{ +switch (size) { +case PCI_SIZE_8 : +return (value >> ((offset &3 ) *8 )) &0xff ; +case PCI_SIZE_16 : +return (value >> ((offset &2 ) *8 )) &0xffff ; +default : +return value; + } +} + +ulong pci_conv_size_to_32 (ulong old,ulong value,uint offset, +enum pci_size_t size) +{ +uint off_mask; +uint val_mask, shift; +ulong ldata, mask; + +switch (size) { +case PCI_SIZE_8 : + off_mask =3 ; + val_mask =0xff ; +break ; +case PCI_SIZE_16 : + off_mask =2 ; + val_mask =0xffff ; +break ; +default : +return value; + } + shift = (offset & off_mask) *8 ; + ldata = (value & val_mask) << shift; + mask = val_mask << shift; + value = (old & ~mask) | ldata; + +return value; +} +UCLASS_DRIVER (pci) = { .id =UCLASS_PCI , .name ="pci" ,
include/pci.h +31 -0
@@ -1092,6 +1092,37 @@ static inline int pci_read_config_byte(pci_dev_t pcidev, int offset, }/** +* pci_conv_32_to_size() - convert a 32-bit read value to the given size +* +* Some PCI buses must always perform 32-bit reads. The data must then be +* shifted and masked to reflect the required access size and offset. This +* function performs this transformation. +* +* @value: Value to transform (32-bit value read from @offset & ~3) +* @offset: Register offset that was read +* @size: Required size of the result +* @return the value that would have been obtained if the read had been +* performed@the given offset with the correct size +*/ +ulong pci_conv_32_to_size (ulong value,uint offset,enum pci_size_t size); + +/** +* pci_conv_size_to_32() - update a 32-bit value to prepare for a write +* +* Some PCI buses must always perform 32-bit writes. To emulate a smaller +* write the old 32-bit data must be read, updated with the required new data +* and written back as a 32-bit value. This function performs the +* transformation from the old value to the new value. +* +* @value: Value to transform (32-bit value read from @offset & ~3) +* @offset: Register offset that should be written +* @size: Required size of the write +* @return the value that should be written as a 32-bit access to @offset & ~3. +*/ +ulong pci_conv_size_to_32 (ulong old,ulong value,uint offset, +enum pci_size_t size); + +/** * struct dm_pci_emul_ops - PCI device emulator operations */ struct dm_pci_emul_ops {
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v4 6/8 dm: pci: Add a function to get the controller for a bus
In reply to Simon GlassA PCI bus may be a bridge device where the controller is the bridge's parent. Add a function to return the controller device, given a PCI device.
---
Changes in v4: None
Changes in v3: None
Changes in v2:
- Use the device_is_on_pci_bus() API
drivers/pci/pci-uclass.c | 8 ++++++++ include/pci.h | 8 ++++++++ 2 files changed, 16 insertions(+)
drivers/pci/pci-uclass.c +8 -0
@@ -53,6 +53,14 @@ struct pci_controller *pci_bus_to_hose(int busnum)return dev_get_uclass_priv (bus); } +struct udevice *pci_get_controller (struct udevice *dev) +{ +while (device_is_on_pci_bus (dev)) + dev = dev->parent; + +return dev; +} +pci_dev_t pci_get_bdf (struct udevice *dev) {struct pci_child_platdata *pplat =dev_get_parent_platdata (dev);
include/pci.h +8 -0
@@ -1123,6 +1123,14 @@ ulong pci_conv_size_to_32(ulong old, ulong value, uint offset, enum pci_size_t size);/** +* pci_get_controller() - obtain the controller to use for a bus +* +* @dev: Device to check +* @return pointer to the controller device for this bus +*/ +struct udevice *pci_get_controller (struct udevice *dev); + +/** * struct dm_pci_emul_ops - PCI device emulator operations */ struct dm_pci_emul_ops {
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v4 7/8 dm: pci: Add a function to find the regions for a PCI bus
In reply to Simon GlassThis function looks up the controller and returns a pointer to each region type.
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/pci/pci-uclass.c | 30 ++++++++++++++++++++++++++++++ include/pci.h | 12 ++++++++++++ 2 files changed, 42 insertions(+)
drivers/pci/pci-uclass.c +30 -0
@@ -974,6 +974,36 @@ ulong pci_conv_size_to_32(ulong old, ulong value, uint offset,return value; } +int pci_get_regions (struct udevice *dev,struct pci_region **iop, +struct pci_region **memp,struct pci_region **prefp) +{ +struct udevice *bus =pci_get_controller (dev); +struct pci_controller *hose =dev_get_uclass_priv (bus); +int i; + + *iop =NULL ; + *memp =NULL ; + *prefp =NULL ; +for (i =0 ; i < hose->region_count; i++) { +switch (hose->regions[i].flags) { +case PCI_REGION_IO : +if (!*iop || (*iop)->size < hose->regions[i].size) + *iop = hose->regions + i; +break ; +case PCI_REGION_MEM : +if (!*memp || (*memp)->size < hose->regions[i].size) + *memp = hose->regions + i; +break ; +case (PCI_REGION_MEM |PCI_REGION_PREFETCH ): +if (!*prefp || (*prefp)->size < hose->regions[i].size) + *prefp = hose->regions + i; +break ; + } + } + +return (*iop !=NULL ) + (*memp !=NULL ) + (*prefp !=NULL ); +} +UCLASS_DRIVER (pci) = { .id =UCLASS_PCI , .name ="pci" ,
include/pci.h +12 -0
@@ -1131,6 +1131,18 @@ ulong pci_conv_size_to_32(ulong old, ulong value, uint offset,struct udevice *pci_get_controller (struct udevice *dev);/** +* pci_get_regions() - obtain pointers to all the region types +* +* @dev: Device to check +* @iop: Returns a pointer to the I/O region, or NULL if none +* @memp: Returns a pointer to the memory region, or NULL if none +* @prefp: Returns a pointer to the pre-fetch region, or NULL if none +* @return the number of non-NULL regions returned, normally 3 +*/ +int pci_get_regions (struct udevice *dev,struct pci_region **iop, +struct pci_region **memp,struct pci_region **prefp); + +/** * struct dm_pci_emul_ops - PCI device emulator operations */ struct dm_pci_emul_ops {
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v4 8/8 dm: tegra: pci: Convert tegra boards to driver model for PCI
In reply to Simon GlassAdjust the Tegra PCI driver to support driver model and move all boards over at the same time. This can make use of some generic driver model code, such as the range-decoding logic.
---
Changes in v4:
- Fix merge conflict resolution error in v3
- Add compatible string for T210 (from Stephen Warren)
Changes in v3:
- Rebase onto tegra/master
- Enable DM_PCI for Tegra 210 family too
Changes in v2:
- Leave pci_skip_dev() at the bottom of the file to reduce the diff size
arch/arm/mach-tegra/Kconfig | 2 + drivers/pci/pci_tegra.c | 467 ++++++++++++++------------------------------ include/fdtdec.h | 4 - lib/fdtdec.c | 4 - 4 files changed, 152 insertions(+), 325 deletions(-)
arch/arm/mach-tegra/Kconfig +2 -0
@@ -12,6 +12,7 @@ config TEGRA_ARMV7_COMMON select DM_I2C select DM_SPI select DM_GPIO + select DM_PCI choice prompt "Tegra SoC select"
@@ -43,6 +44,7 @@ config TEGRA210 select DM_I2C select DM_SPI select DM_GPIO + select DM_PCI endchoice
drivers/pci/pci_tegra.c +150 -317
638 lines not on this page · raw message
include/fdtdec.h +0 -4
@@ -129,10 +129,6 @@ enum fdt_compat_id {COMPAT_NVIDIA_TEGRA124_SDMMC ,/* Tegra124 SDMMC controller */ COMPAT_NVIDIA_TEGRA30_SDMMC ,/* Tegra30 SDMMC controller */ COMPAT_NVIDIA_TEGRA20_SDMMC ,/* Tegra20 SDMMC controller */ -COMPAT_NVIDIA_TEGRA124_PCIE ,/* Tegra 124 PCIe controller */ -COMPAT_NVIDIA_TEGRA210_PCIE ,/* Tegra 210 PCIe controller */ -COMPAT_NVIDIA_TEGRA30_PCIE ,/* Tegra 30 PCIe controller */ -COMPAT_NVIDIA_TEGRA20_PCIE ,/* Tegra 20 PCIe controller */ COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL ,/* Tegra124 XUSB pad controller */ COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL,
lib/fdtdec.c +0 -4
@@ -35,10 +35,6 @@ static const char * const compat_names[COMPAT_COUNT] = {COMPAT (NVIDIA_TEGRA124_SDMMC ,"nvidia,tegra124-sdhci" ),COMPAT (NVIDIA_TEGRA30_SDMMC ,"nvidia,tegra30-sdhci" ),COMPAT (NVIDIA_TEGRA20_SDMMC ,"nvidia,tegra20-sdhci" ), -COMPAT (NVIDIA_TEGRA124_PCIE ,"nvidia,tegra124-pcie" ), -COMPAT (NVIDIA_TEGRA210_PCIE ,"nvidia,tegra210-pcie" ), -COMPAT (NVIDIA_TEGRA30_PCIE ,"nvidia,tegra30-pcie" ), -COMPAT (NVIDIA_TEGRA20_PCIE ,"nvidia,tegra20-pcie" ),COMPAT (NVIDIA_TEGRA124_XUSB_PADCTL ,"nvidia,tegra124-xusb-padctl" ),COMPAT (NVIDIA_TEGRA210_XUSB_PADCTL ,"nvidia,tegra210-xusb-padctl" ), COMPAT(SMSC_LAN9215, "smsc,lan9215"),
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v4 8/8 dm: tegra: pci: Convert tegra boards to driver model for PCI
Quoted 3 lines · Simon Glass
Adjust the Tegra PCI driver to support driver model and move all boards over at the same time. This can make use of some generic driver model code, such as the range-decoding logic.
To make this series work on Jetson TX1, two things need to happen.
First, this patch reverts a change I made earlier to move the call to tegra_pcie_board_init() to an earlier point in the initialization process, i.e. before /any/ part of the PCIe or pad HW is accessed. To solve that, apply the following:
Quoted 38 lines
drivers/pci/pci_tegra.c +7
-5@@ -433,6 +435,11 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node,return 0 ; } +int __weak tegra_pcie_board_init (void ) +{ +return 0 ; +} +static int tegra_pcie_parse_dt (const void *fdt,int node,enum tegra_pci_id id,struct tegra_pcie *pcie) {@@ -460,6 +467,8 @@ static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id,return err; } +tegra_pcie_board_init (); + pcie->phy =tegra_xusb_phy_get (TEGRA_XUSB_PADCTL_PCIE );if (pcie->phy) { err =tegra_xusb_phy_prepare (pcie->phy);@@ -512,11 +521,6 @@ static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id,return 0 ; } -int __weak tegra_pcie_board_init (void ) -{ -return 0 ; -} -static int tegra_pcie_power_on (struct tegra_pcie *pcie) {const struct tegra_pcie_soc *soc = pcie->soc;
drivers/pci/pci_tegra.c static int tegra_pcie_power_on(struct tegra_pcie *pcie) · line 543
Quoted 8 lines
drivers/pci/pci_tegra.c +0
-2@@ -534,8 +538,6 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)return err; } -tegra_pcie_board_init (); - err =tegra_powergate_sequence_power_up (TEGRA_POWERGATE_PCIE ,PERIPH_ID_PCIE );if (err <0 ) {
Second, the removal of the following piece of code:
drivers/pci/pci_tegra.c static int tegra_pcie_enable(struct tegra_pcie *pcie) · line 1058
Quoted 13 lines
drivers/pci/pci_tegra.c +0
-10-static int process_nodes (const void *fdt,int nodes[],unsigned int count) { -unsigned int i; -uint64_t dram_end; -uint32_t pci_dram_size; - -/* Clip PCI-accessible DRAM to 32-bits */ - dram_end = ((uint64_t )NV_PA_SDRAM_BASE ) + gd->ram_size; -if (dram_end >0x100000000 ) - dram_end =0x100000000 ; - pci_dram_size = dram_end -NV_PA_SDRAM_BASE ;
... means that the PCI resource structure that represents system memory ends up with size=0 rather than the expected size=0x80000000. That's because gd->ram_size is 4GB and sizeof(res->size)==4.
Perhaps I could solve this by defining CONFIG_SYS_PCI_64BIT, which changes the size of res->size to 8 bytes. However:
a) I'm a bit worried that changing the size of that type will lead to other unexpected behavioural changes, e.g. interactions with DT parsing due to cell count differences.
b) This only solves the integer overflow issue. In fact, res->base+res->size should fit inside 32-bits since IIRC the PCIe controller can only access 32-bit addresses, and hence we need to clip the RAM size to acknowledge that, which the code above was doing. Doing such a clipping operation in the generic/shared decode_regions() doesn't feel like a good idea, at least not unconditionally.
In practice, (a) doesn't seem to be a problem, and perhaps we can ignore (b), since board_get_usable_ram_top() (in arch/arm/mach-tegra/board2.c) limits usable RAM size to fit within 32 bits for similar reasons. So, I know that no allocated memory buffer will ever be above 32 bits, so it doesn't matter in practice whether a PCI region's base+size fits into 32 bits or not.
What are your thoughts on this?
BTW, your V4 plus these fixes is available at:
git://github.com/swarren/u-boot.git test-pci-dm-v4
PATCH v4 8/8 dm: tegra: pci: Convert tegra boards to driver model for PCI
Hi Stephen,
Quoted 8 lines · Stephen Warren
Quoted 6 lines · Simon Glass
Adjust the Tegra PCI driver to support driver model and move all boards over
at the same time. This can make use of some generic driver model code, such
as the range-decoding logic.
Thanks for looking at this.
Quoted 54 lines
To make this series work on Jetson TX1, two things need to happen.
First, this patch reverts a change I made earlier to move the call to
tegra_pcie_board_init()to an earlier point in the initialization process, i.e. before /any/ part of the PCIe or pad HW is accessed. To solve that, apply the following:Quoted 46 lines
drivers/pci/pci_tegra.c +5
-0@@ -433,6 +435,11 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node, return 0; } +int __weak tegra_pcie_board_init (void ) +{ +return 0 ; +} + static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id,struct
tegra_pcie*pcie)
{drivers/pci/pci_tegra.c +2
-0@@ -460,6 +467,8 @@ static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id, return err; } +tegra_pcie_board_init (); + pcie->phy =tegra_xusb_phy_get (TEGRA_XUSB_PADCTL_PCIE );if (pcie->phy) {err = tegra_xusb_phy_prepare(pcie->phy);drivers/pci/pci_tegra.c +0
-5@@ -512,11 +521,6 @@ static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id, return 0; } -int __weak tegra_pcie_board_init (void ) -{ -return 0 ; -} -static int tegra_pcie_power_on (struct tegra_pcie *pcie) {const struct tegra_pcie_soc *soc = pcie->soc;drivers/pci/pci_tegra.c +0
-0@@ -534,8 +538,6 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)return err; }
Quoted 6 lines
Quoted 5 lines
drivers/pci/pci_tegra.c +0
-2-tegra_pcie_board_init (); - err =tegra_powergate_sequence_power_up (TEGRA_POWERGATE_PCIE ,PERIPH_ID_PCIE );if (err < 0) {
OK
Quoted 38 lines
Second, the removal of the following piece of code:
Quoted 6 lines
drivers/pci/pci_tegra.c +0
-1-static int process_nodes(const void *fdt, int nodes[], unsigned intcount)
{drivers/pci/pci_tegra.c static int tegra_pcie_enable(struct tegra_pcie *pcie) · line 1058
Quoted 9 lines
drivers/pci/pci_tegra.c +0
-9-unsigned int i; -uint64_t dram_end; -uint32_t pci_dram_size; - -/* Clip PCI-accessible DRAM to 32-bits */ - dram_end = ((uint64_t )NV_PA_SDRAM_BASE ) + gd->ram_size; -if (dram_end >0x100000000 ) - dram_end =0x100000000 ; - pci_dram_size = dram_end -NV_PA_SDRAM_BASE ;... means that the PCI resource structure that represents system memory ends up with size=0 rather than the expected size=0x80000000. That's because
gd->ram_sizeis 4GB and sizeof(res->size)==4.Perhaps I could solve this by defining
CONFIG_SYS_PCI_64BIT, which changes the size ofres->sizeto 8 bytes. However:a) I'm a bit worried that changing the size of that type will lead to other unexpected behavioural changes, e.g. interactions with DT parsing due to cell count differences.
b) This only solves the integer overflow issue. In fact, res->base+res->size should fit inside 32-bits since IIRC the PCIe controller can only access 32-bit addresses, and hence we need to clip the RAM size to acknowledge that, which the code above was doing. Doing such a clipping operation in the generic/shared
decode_regions()doesn't feel like a good idea, at least not unconditionally.
Quoted 8 lines
In practice, (a) doesn't seem to be a problem, and perhaps we can ignore (b), since
board_get_usable_ram_top()(inarch/arm/mach-tegra/board2.c) limits usable RAM size to fit within 32 bits for similar reasons. So, I know that no allocated memory buffer will ever be above 32 bits, so it doesn't matter in practice whether a PCI region's base+size fits into 32 bits or not.What are your thoughts on this?
Does gd->pci_ram_top in decode_regions() do what you want?
Quoted 4 lines
BTW, your V4 plus these fixes is available at:
git://github.com/swarren/u-boot.gittest-pci-dm-v4
Thanks!
Regards,
Simon
PATCH v4 8/8 dm: tegra: pci: Convert tegra boards to driver model for PCI
Quoted 9 lines · Simon Glass
Quoted 4 lines · Stephen Warren
Quoted 3 lines · Simon Glass
Adjust the Tegra PCI driver to support driver model and move all boards over at the same time. This can make use of some generic driver model code, such as the range-decoding logic.
Thanks for looking at this.
Quoted 1 line
To make this series work on Jetson TX1, two things need to happen.
...
Quoted 41 lines
Quoted 41 lines
Quoted 5 lines
drivers/pci/pci_tegra.c +0
-1-static int process_nodes(const void *fdt, int nodes[], unsigned intcount)
{drivers/pci/pci_tegra.c static int tegra_pcie_enable(struct tegra_pcie *pcie) · line 1058
Quoted 9 lines
drivers/pci/pci_tegra.c +0
-9-unsigned int i; -uint64_t dram_end; -uint32_t pci_dram_size; - -/* Clip PCI-accessible DRAM to 32-bits */ - dram_end = ((uint64_t )NV_PA_SDRAM_BASE ) + gd->ram_size; -if (dram_end >0x100000000 ) - dram_end =0x100000000 ; - pci_dram_size = dram_end -NV_PA_SDRAM_BASE ;... means that the PCI resource structure that represents system memory ends up with size=0 rather than the expected size=0x80000000. That's because
gd->ram_sizeis 4GB and sizeof(res->size)==4.Perhaps I could solve this by defining
CONFIG_SYS_PCI_64BIT, which changes the size ofres->sizeto 8 bytes. However:a) I'm a bit worried that changing the size of that type will lead to other unexpected behavioural changes, e.g. interactions with DT parsing due to cell count differences.
b) This only solves the integer overflow issue. In fact, res->base+res->size should fit inside 32-bits since IIRC the PCIe controller can only access 32-bit addresses, and hence we need to clip the RAM size to acknowledge that, which the code above was doing. Doing such a clipping operation in the generic/shared
decode_regions()doesn't feel like a good idea, at least not unconditionally.In practice, (a) doesn't seem to be a problem, and perhaps we can ignore (b), since
board_get_usable_ram_top()(inarch/arm/mach-tegra/board2.c) limits usable RAM size to fit within 32 bits for similar reasons. So, I know that no allocated memory buffer will ever be above 32 bits, so it doesn't matter in practice whether a PCI region's base+size fits into 32 bits or not.
Quoted 3 lines
Quoted 1 line
What are your thoughts on this?
Does
gd->pci_ram_topindecode_regions()do what you want?
Ah of course; the following does solve the problem:
Quoted 13 lines
arch/arm/mach-tegra/board2.c +2
-0@@ -377,6 +377,8 @@ void dram_init_banksize(void) gd->bd->bi_dram[0 ].start =CONFIG_SYS_SDRAM_BASE ; gd->bd->bi_dram[0 ].size =usable_ram_size_below_4g (); + gd->pci_ram_top = gd->bd->bi_dram[0 ].start + gd->bd->bi_dram[0 ].size; +#ifdef CONFIG_PHYS_64BIT if (gd->ram_size >SZ_2G ) { gd->bd->bi_dram[1 ].start =0x100000000 ;
v4 cover dm: pci: tegra: Convert Tegra PCI to driver model
In reply to Simon GlassQuoted 2 lines · Simon Glass
This series converts all Tegra boards to use driver model for PCI. The net effect should be no change in functionality.
In v4, Jetson TK1 now works as expected. However, the issues on p2371-2180 (Jetson TX1) still remain. I'll try and look into these.