[PATCH 0/6] Convert MIPS Malta boards to PCI DM

This series converts the PCI host controller drivers used by MIPS Malta and the board-specific PCI setup code to PCI driver model. Because the AMD PCNET driver is already converted to ETH driver model, simply enable CONFIG_DM_ETH as well.
A patch in PCI uclass core is currently required for MIPS wanting to use PCI DM (except Octeon MIPS64) due to CONFIG_SYS_SDRAM_BASE being used as a virtual address on all MIPS boards.
The series for now is only tested with Qemu and the GT64120 PCI controller. The Malta Qemu tests are already covered by U-Boot CI Support for the MSC01 controller is prepared. The used PCI controller depends on the plugged core card (Qemu emulates the CoreLV card with GT64120).
Dynamic selection of the according PCI DT nodes via CONFIG_OF_BOARD_FIXUP is prepared but not yet enabled. This requires fixing of the call order of fix_fdt() in board_init_f, otherwise the passed-in rw_fdt_blob pointer will point to a read-only NOR flash address. I'll send a separate RFC patch for this.
I'll send a cleanup series for removing non-DM code after the merge windows has closed and the PCI DM conversion deadline has been enforced.
Daniel Schwierzeck (6): dm: pci: add option to map virtual system memory base address pci: gt64120: convert to driver model pci: msc01: convert to driver model MIPS: malta: add DT bindings for PCI host controller MIPS: malta: add support for PCI driver model MIPS: malta: enable PCI driver model
arch/mips/Kconfig | 4 ++ arch/mips/dts/mti,malta.dts | 28 +++++++++++++ board/imgtec/malta/malta.c | 84 ++++++++++++++++++++++++++++++++++++- drivers/pci/Kconfig | 13 ++++++ drivers/pci/pci-uclass.c | 9 ++-- drivers/pci/pci_gt64120.c | 72 ++++++++++++++++++++++++++++++- drivers/pci/pci_msc01.c | 70 ++++++++++++++++++++++++++++++- 7 files changed, 274 insertions(+), 6 deletions(-)

On MIPS the DRAM start address respectively CONFIG_SYS_SDRAM_BASE is still used as a virtual, CPU-mapped address instead of being used as physical address. Converting all MIPS boards and generic MIPS code to fix that is not trivial. Due to the approaching deadline for PCI DM conversion, this workaround is required for MIPS boards with PCI support until the CONFIG_SYS_SDRAM_BASE issue could be solved.
Add a compile-time option to let the PCI uclass core optionally map the DRAM address to a physical address when adding the PCI region of type PCI_REGION_SYS_MEMORY.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
drivers/pci/Kconfig | 13 +++++++++++++ drivers/pci/pci-uclass.c | 9 ++++++--- 2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index b2b7b253f8..02c34077e2 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -54,6 +54,19 @@ config PCI_REGION_MULTI_ENTRY region type. This helps to add support for SoC's like OcteonTX/TX2 where every peripheral is on the PCI bus.
+config PCI_MAP_SYSTEM_MEMORY + bool "Map local system memory from a virtual base address" + depends on PCI || DM_PCI + depends on MIPS + default n + help + Say Y if base address of system memory is being used as a virtual address + instead of a physical address (e.g. on MIPS). The PCI core will then remap + the virtual memory base address to a physical address when adding the PCI + region of type PCI_REGION_SYS_MEMORY. + This should only be required on MIPS where CONFIG_SYS_SDRAM_BASE is still + being used as virtual address. + config PCI_SRIOV bool "Enable Single Root I/O Virtualization support for PCI" depends on PCI || DM_PCI diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 22a033e632..1e2ed5426e 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -998,10 +998,13 @@ static void decode_regions(struct pci_controller *hose, ofnode parent_node,
for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { if (bd->bi_dram[i].size) { + phys_addr_t start = bd->bi_dram[i].start; + + if (IS_ENABLED(CONFIG_PCI_MAP_SYSTEM_MEMORY)) + start = virt_to_phys((void *)(uintptr_t)bd->bi_dram[i].start); + pci_set_region(hose->regions + hose->region_count++, - bd->bi_dram[i].start, - bd->bi_dram[i].start, - bd->bi_dram[i].size, + start, start, bd->bi_dram[i].size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); } }

On 06.07.21 16:22, Daniel Schwierzeck wrote:
On MIPS the DRAM start address respectively CONFIG_SYS_SDRAM_BASE is still used as a virtual, CPU-mapped address instead of being used as physical address. Converting all MIPS boards and generic MIPS code to fix that is not trivial. Due to the approaching deadline for PCI DM conversion, this workaround is required for MIPS boards with PCI support until the CONFIG_SYS_SDRAM_BASE issue could be solved.
Add a compile-time option to let the PCI uclass core optionally map the DRAM address to a physical address when adding the PCI region of type PCI_REGION_SYS_MEMORY.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
drivers/pci/Kconfig | 13 +++++++++++++ drivers/pci/pci-uclass.c | 9 ++++++--- 2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index b2b7b253f8..02c34077e2 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -54,6 +54,19 @@ config PCI_REGION_MULTI_ENTRY region type. This helps to add support for SoC's like OcteonTX/TX2 where every peripheral is on the PCI bus.
+config PCI_MAP_SYSTEM_MEMORY
- bool "Map local system memory from a virtual base address"
- depends on PCI || DM_PCI
- depends on MIPS
- default n
AFAIK, "default n" is not needed as it's the "default" setting.
Apart from this:
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan
- help
Say Y if base address of system memory is being used as a virtual address
instead of a physical address (e.g. on MIPS). The PCI core will then remap
the virtual memory base address to a physical address when adding the PCI
region of type PCI_REGION_SYS_MEMORY.
This should only be required on MIPS where CONFIG_SYS_SDRAM_BASE is still
being used as virtual address.
- config PCI_SRIOV bool "Enable Single Root I/O Virtualization support for PCI" depends on PCI || DM_PCI
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 22a033e632..1e2ed5426e 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -998,10 +998,13 @@ static void decode_regions(struct pci_controller *hose, ofnode parent_node,
for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { if (bd->bi_dram[i].size) {
phys_addr_t start = bd->bi_dram[i].start;
if (IS_ENABLED(CONFIG_PCI_MAP_SYSTEM_MEMORY))
start = virt_to_phys((void *)(uintptr_t)bd->bi_dram[i].start);
pci_set_region(hose->regions + hose->region_count++,
bd->bi_dram[i].start,
bd->bi_dram[i].start,
bd->bi_dram[i].size,
} }start, start, bd->bi_dram[i].size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
Viele Grüße, Stefan

This driver is currently only used on MIPS Malta boards.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
drivers/pci/pci_gt64120.c | 72 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci_gt64120.c b/drivers/pci/pci_gt64120.c index 80f11fedd1..973815928b 100644 --- a/drivers/pci/pci_gt64120.c +++ b/drivers/pci/pci_gt64120.c @@ -8,7 +8,7 @@ * Maciej W. Rozycki macro@mips.com */
-#include <common.h> +#include <dm.h> #include <gt64120.h> #include <init.h> #include <log.h> @@ -114,6 +114,7 @@ static int gt_config_access(struct gt64120_pci_controller *gt, return 0; }
+#if !IS_ENABLED(CONFIG_DM_PCI) static int gt_read_config_dword(struct pci_controller *hose, pci_dev_t dev, int where, u32 *value) { @@ -175,3 +176,72 @@ void gt64120_pci_init(void *regs, unsigned long sys_bus, unsigned long sys_phys, pci_register_hose(hose); hose->last_busno = pci_hose_scan(hose); } +#else +static int gt64120_pci_read_config(const struct udevice *dev, pci_dev_t bdf, + uint where, ulong *val, + enum pci_size_t size) +{ + struct gt64120_pci_controller *gt = dev_get_priv(dev); + u32 data = 0; + + if (gt_config_access(gt, PCI_ACCESS_READ, bdf, where, &data)) { + *val = pci_get_ff(size); + return 0; + } + + *val = pci_conv_32_to_size(data, where, size); + return 0; +} + +static int gt64120_pci_write_config(struct udevice *dev, pci_dev_t bdf, + uint where, ulong val, + enum pci_size_t size) +{ + struct gt64120_pci_controller *gt = dev_get_priv(dev); + u32 data = 0; + + if (size == PCI_SIZE_32) { + data = val; + } else { + u32 old; + + if (gt_config_access(gt, PCI_ACCESS_READ, bdf, where, &old)) + return 0; + + data = pci_conv_size_to_32(old, val, where, size); + } + + gt_config_access(gt, PCI_ACCESS_WRITE, bdf, where, &data); + return 0; +} + +static int gt64120_pci_probe(struct udevice *dev) +{ + struct gt64120_pci_controller *gt = dev_get_priv(dev); + + gt->regs = dev_remap_addr(dev); + if (!gt->regs) + return -EINVAL; + + return 0; +} + +static const struct dm_pci_ops gt64120_pci_ops = { + .read_config = gt64120_pci_read_config, + .write_config = gt64120_pci_write_config, +}; + +static const struct udevice_id gt64120_pci_ids[] = { + { .compatible = "marvell,pci-gt64120" }, + { } +}; + +U_BOOT_DRIVER(gt64120_pci) = { + .name = "gt64120_pci", + .id = UCLASS_PCI, + .of_match = gt64120_pci_ids, + .ops = >64120_pci_ops, + .probe = gt64120_pci_probe, + .priv_auto = sizeof(struct gt64120_pci_controller), +}; +#endif

On Tue, 6 Jul 2021 at 08:22, Daniel Schwierzeck daniel.schwierzeck@gmail.com wrote:
This driver is currently only used on MIPS Malta boards.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
drivers/pci/pci_gt64120.c | 72 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-)
Reviewed-by: Simon Glass sjg@chromium.org
Normally we have a blank line before the final return.

This driver is currently only used on MIPS Malta boards.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
drivers/pci/pci_msc01.c | 70 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci_msc01.c b/drivers/pci/pci_msc01.c index 04838200a8..ad203c86d0 100644 --- a/drivers/pci/pci_msc01.c +++ b/drivers/pci/pci_msc01.c @@ -4,7 +4,7 @@ * Author: Paul Burton paul.burton@mips.com */
-#include <common.h> +#include <dm.h> #include <init.h> #include <msc01.h> #include <pci.h> @@ -62,6 +62,7 @@ static int msc01_config_access(struct msc01_pci_controller *msc01, return 0; }
+#if !IS_ENABLED(CONFIG_DM_PCI) static int msc01_read_config_dword(struct pci_controller *hose, pci_dev_t dev, int where, u32 *value) { @@ -123,3 +124,70 @@ void msc01_pci_init(void *base, unsigned long sys_bus, unsigned long sys_phys, pci_register_hose(hose); hose->last_busno = pci_hose_scan(hose); } +#else +static int msc01_pci_read_config(const struct udevice *dev, pci_dev_t bdf, + uint where, ulong *val, enum pci_size_t size) +{ + struct msc01_pci_controller *msc01 = dev_get_priv(dev); + u32 data = 0; + + if (msc01_config_access(msc01, PCI_ACCESS_READ, bdf, where, &data)) { + *val = pci_get_ff(size); + return 0; + } + + *val = pci_conv_32_to_size(data, where, size); + return 0; +} + +static int msc01_pci_write_config(struct udevice *dev, pci_dev_t bdf, + uint where, ulong val, enum pci_size_t size) +{ + struct msc01_pci_controller *msc01 = dev_get_priv(dev); + u32 data = 0; + + if (size == PCI_SIZE_32) { + data = val; + } else { + u32 old; + + if (msc01_config_access(msc01, PCI_ACCESS_READ, bdf, where, &old)) + return 0; + + data = pci_conv_size_to_32(old, val, where, size); + } + + msc01_config_access(msc01, PCI_ACCESS_WRITE, bdf, where, &data); + return 0; +} + +static int msc01_pci_probe(struct udevice *dev) +{ + struct msc01_pci_controller *msc01 = dev_get_priv(dev); + + msc01->base = dev_remap_addr(dev); + if (!msc01->base) + return -EINVAL; + + return 0; +} + +static const struct dm_pci_ops msc01_pci_ops = { + .read_config = msc01_pci_read_config, + .write_config = msc01_pci_write_config, +}; + +static const struct udevice_id msc01_pci_ids[] = { + { .compatible = "mips,pci-msc01" }, + { } +}; + +U_BOOT_DRIVER(msc01_pci) = { + .name = "msc01_pci", + .id = UCLASS_PCI, + .of_match = msc01_pci_ids, + .ops = &msc01_pci_ops, + .probe = msc01_pci_probe, + .priv_auto = sizeof(struct msc01_pci_controller), +}; +#endif

On Tue, 6 Jul 2021 at 08:22, Daniel Schwierzeck daniel.schwierzeck@gmail.com wrote:
This driver is currently only used on MIPS Malta boards.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
drivers/pci/pci_msc01.c | 70 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-)
Reviewed-by: Simon Glass sjg@chromium.org

Add DT binding for GT64120 and MSC01 PCI controllers. Only GT64120 is enabled by default to support Qemu. The MSC01 node will be dynamically enabled by Malta board code dependent on the plugged core card.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
arch/mips/dts/mti,malta.dts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/arch/mips/dts/mti,malta.dts b/arch/mips/dts/mti,malta.dts index d339229c2a..ef47a340bb 100644 --- a/arch/mips/dts/mti,malta.dts +++ b/arch/mips/dts/mti,malta.dts @@ -29,4 +29,32 @@ u-boot,dm-pre-reloc; }; }; + + pci0@1bd00000 { + compatible = "mips,pci-msc01"; + device_type = "pci"; + reg = <0x1bd00000 0x2000>; + + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0x0>; + ranges = <0x01000000 0 0x00000000 0x00000000 0 0x800000 /* I/O */ + 0x02000000 0 0x10000000 0xb0000000 0 0x10000000 /* MEM */>; + + status = "disabled"; + }; + + pci0@1be00000 { + compatible = "marvell,pci-gt64120"; + device_type = "pci"; + reg = <0x1be00000 0x2000>; + + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0x0>; + ranges = <0x01000000 0 0x00000000 0x00000000 0 0x20000 /* I/O */ + 0x02000000 0 0x10000000 0x10000000 0 0x8000000 /* MEM */>; + + status = "okay"; + }; };

As almost all peripherals are connected via PCI dependent on the used core card, PCI setup is always required. Thus run pci_init() including PCI scanning and probing and core card specific setups in board_early_init_r().
Also prepare support for dynamically managing the status of the different PCI DT nodes dependent on used core card via option CONFIG_OF_BOARD_FIXUP. Before this feature can be enabled, the call order of the fix_fdt() init hook in board_init_f needs to be changed. Otherwise rw_fdt_blob points to a read-only NOR flash address. Thus this options needs to stay disabled until the board_init_f problem could be solved. This breaks running the default U-Boot image on real HW using the FPGA core card but Qemu emulation still works. Currently Qemu is more important as MIPS CI tests depend on Malta and the deadline for PCI DM conversion will be enforced soon.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
board/imgtec/malta/malta.c | 84 +++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-)
diff --git a/board/imgtec/malta/malta.c b/board/imgtec/malta/malta.c index c04f727961..e78d5a7fbc 100644 --- a/board/imgtec/malta/malta.c +++ b/board/imgtec/malta/malta.c @@ -4,7 +4,8 @@ * Copyright (C) 2013 Imagination Technologies */
-#include <common.h> +#include <config.h> +#include <fdt_support.h> #include <ide.h> #include <init.h> #include <net.h> @@ -24,6 +25,9 @@
DECLARE_GLOBAL_DATA_PTR;
+#define MALTA_GT_PATH "/pci0@1be00000" +#define MALTA_MSC_PATH "/pci0@1bd00000" + enum core_card { CORE_UNKNOWN, CORE_LV, @@ -120,10 +124,12 @@ int checkboard(void) return 0; }
+#if !IS_ENABLED(CONFIG_DM_ETH) int board_eth_init(struct bd_info *bis) { return pci_eth_init(bis); } +#endif
void _machine_restart(void) { @@ -167,6 +173,81 @@ int misc_init_r(void) return 0; }
+#if IS_ENABLED(CONFIG_OF_BOARD_FIXUP) +/* + * TODO: currently doesn't work because rw_fdt_blob points to a + * NOR flash address. This needs some changes in board_init_f. + */ +int board_fix_fdt(void *rw_fdt_blob) +{ + int node = -1; + + switch (malta_sys_con()) { + case SYSCON_GT64120: + node = fdt_path_offset(rw_fdt_blob, MALTA_GT_PATH); + break; + default: + case SYSCON_MSC01: + node = fdt_path_offset(rw_fdt_blob, MALTA_MSC_PATH); + break; + } + + return fdt_status_okay(rw_fdt_blob, node); +} +#endif + +#if IS_ENABLED(CONFIG_DM_PCI) +int board_early_init_r(void) +{ + struct udevice *dev; + u32 val32; + u8 val8; + int ret; + + pci_init(); + + ret = dm_pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_0, 0, &dev); + if (ret) + panic("Failed to find PIIX4 PCI bridge\n"); + + /* setup PCI interrupt routing */ + dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCA, 10); + dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCB, 10); + dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCC, 11); + dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCD, 11); + + /* mux SERIRQ onto SERIRQ pin */ + dm_pci_read_config32(dev, PCI_CFG_PIIX4_GENCFG, &val32); + val32 |= PCI_CFG_PIIX4_GENCFG_SERIRQ; + dm_pci_write_config32(dev, PCI_CFG_PIIX4_GENCFG, val32); + + /* enable SERIRQ - Linux currently depends upon this */ + dm_pci_read_config8(dev, PCI_CFG_PIIX4_SERIRQC, &val8); + val8 |= PCI_CFG_PIIX4_SERIRQC_EN | PCI_CFG_PIIX4_SERIRQC_CONT; + dm_pci_write_config8(dev, PCI_CFG_PIIX4_SERIRQC, val8); + + ret = dm_pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB, 0, &dev); + if (ret) + panic("Failed to find PIIX4 IDE controller\n"); + + /* enable bus master & IO access */ + val32 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO; + dm_pci_write_config32(dev, PCI_COMMAND, val32); + + /* set latency */ + dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40); + + /* enable IDE/ATA */ + dm_pci_write_config32(dev, PCI_CFG_PIIX4_IDETIM_PRI, + PCI_CFG_PIIX4_IDETIM_IDE); + dm_pci_write_config32(dev, PCI_CFG_PIIX4_IDETIM_SEC, + PCI_CFG_PIIX4_IDETIM_IDE); + + return 0; +} +#else void pci_init_board(void) { pci_dev_t bdf; @@ -231,3 +312,4 @@ void pci_init_board(void) pci_write_config_dword(bdf, PCI_CFG_PIIX4_IDETIM_SEC, PCI_CFG_PIIX4_IDETIM_IDE); } +#endif

() Hi Daniel,
On Tue, 6 Jul 2021 at 08:22, Daniel Schwierzeck daniel.schwierzeck@gmail.com wrote:
As almost all peripherals are connected via PCI dependent on the used core card, PCI setup is always required. Thus run pci_init() including PCI scanning and probing and core card specific setups in board_early_init_r().
Also prepare support for dynamically managing the status of the different PCI DT nodes dependent on used core card via option CONFIG_OF_BOARD_FIXUP. Before this feature can be enabled, the call order of the fix_fdt() init hook in board_init_f needs to be changed. Otherwise rw_fdt_blob points to a read-only NOR flash address. Thus this options needs to stay disabled until the board_init_f problem could be solved. This breaks running the default U-Boot image on real HW using the FPGA core card but Qemu emulation still works. Currently Qemu is more important as MIPS CI tests depend on Malta and the deadline for PCI DM conversion will be enforced soon.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
board/imgtec/malta/malta.c | 84 +++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-)
diff --git a/board/imgtec/malta/malta.c b/board/imgtec/malta/malta.c index c04f727961..e78d5a7fbc 100644 --- a/board/imgtec/malta/malta.c +++ b/board/imgtec/malta/malta.c @@ -4,7 +4,8 @@
- Copyright (C) 2013 Imagination Technologies
*/
-#include <common.h> +#include <config.h> +#include <fdt_support.h> #include <ide.h> #include <init.h> #include <net.h> @@ -24,6 +25,9 @@
DECLARE_GLOBAL_DATA_PTR;
+#define MALTA_GT_PATH "/pci0@1be00000" +#define MALTA_MSC_PATH "/pci0@1bd00000"
enum core_card { CORE_UNKNOWN, CORE_LV, @@ -120,10 +124,12 @@ int checkboard(void) return 0; }
+#if !IS_ENABLED(CONFIG_DM_ETH) int board_eth_init(struct bd_info *bis) { return pci_eth_init(bis); } +#endif
void _machine_restart(void) { @@ -167,6 +173,81 @@ int misc_init_r(void) return 0; }
+#if IS_ENABLED(CONFIG_OF_BOARD_FIXUP) +/*
- TODO: currently doesn't work because rw_fdt_blob points to a
- NOR flash address. This needs some changes in board_init_f.
- */
+int board_fix_fdt(void *rw_fdt_blob) +{
int node = -1;
switch (malta_sys_con()) {
case SYSCON_GT64120:
node = fdt_path_offset(rw_fdt_blob, MALTA_GT_PATH);
break;
default:
case SYSCON_MSC01:
node = fdt_path_offset(rw_fdt_blob,
);
break;
}
return fdt_status_okay(rw_fdt_blob, node);
+} +#endif
+#if IS_ENABLED(CONFIG_DM_PCI) +int board_early_init_r(void) +{
struct udevice *dev;
u32 val32;
u8 val8;
int ret;
pci_init();
ret = dm_pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82371AB_0, 0, &dev);
This feels a bit wonky to me. How about a sysinfo driver for your board which does this init? Then you could just probe it.
As to finding PCI devices, your sysinfo driver could have a few phandle properties to point to the two devices you need.
But if these are really SYSCON devices, why not use the SYSCON devices, give them a unique ID (perhaps you already have with SYSCON_MSC01) and then call syscon_get_regmap_by_driver_data() ?
if (ret)
panic("Failed to find PIIX4 PCI bridge\n");
/* setup PCI interrupt routing */
dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCA, 10);
dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCB, 10);
dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCC, 11);
dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCD, 11);
This feels like it should be in DT.
I don't know if this is at all similar to x86, but see create_pirq_routing_table() and intel,irq-router.txt for some ideas.
/* mux SERIRQ onto SERIRQ pin */
dm_pci_read_config32(dev, PCI_CFG_PIIX4_GENCFG, &val32);
val32 |= PCI_CFG_PIIX4_GENCFG_SERIRQ;
dm_pci_write_config32(dev, PCI_CFG_PIIX4_GENCFG, val32);
dm_pci_clrset_config32() can do these three in one line, similar below.
/* enable SERIRQ - Linux currently depends upon this */
dm_pci_read_config8(dev, PCI_CFG_PIIX4_SERIRQC, &val8);
val8 |= PCI_CFG_PIIX4_SERIRQC_EN | PCI_CFG_PIIX4_SERIRQC_CONT;
dm_pci_write_config8(dev, PCI_CFG_PIIX4_SERIRQC, val8);
ret = dm_pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82371AB, 0, &dev);
if (ret)
panic("Failed to find PIIX4 IDE controller\n");
/* enable bus master & IO access */
val32 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
dm_pci_write_config32(dev, PCI_COMMAND, val32);
/* set latency */
dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
/* enable IDE/ATA */
dm_pci_write_config32(dev, PCI_CFG_PIIX4_IDETIM_PRI,
PCI_CFG_PIIX4_IDETIM_IDE);
dm_pci_write_config32(dev, PCI_CFG_PIIX4_IDETIM_SEC,
PCI_CFG_PIIX4_IDETIM_IDE);
return 0;
+} +#else void pci_init_board(void) { pci_dev_t bdf; @@ -231,3 +312,4 @@ void pci_init_board(void) pci_write_config_dword(bdf, PCI_CFG_PIIX4_IDETIM_SEC, PCI_CFG_PIIX4_IDETIM_IDE); }
+#endif
2.32.0
Regards, Simon

Hi Simon,
Am Samstag, den 10.07.2021, 18:00 -0600 schrieb Simon Glass:
() Hi Daniel,
On Tue, 6 Jul 2021 at 08:22, Daniel Schwierzeck daniel.schwierzeck@gmail.com wrote:
As almost all peripherals are connected via PCI dependent on the used core card, PCI setup is always required. Thus run pci_init() including PCI scanning and probing and core card specific setups in board_early_init_r().
Also prepare support for dynamically managing the status of the different PCI DT nodes dependent on used core card via option CONFIG_OF_BOARD_FIXUP. Before this feature can be enabled, the call order of the fix_fdt() init hook in board_init_f needs to be changed. Otherwise rw_fdt_blob points to a read-only NOR flash address. Thus this options needs to stay disabled until the board_init_f problem could be solved. This breaks running the default U-Boot image on real HW using the FPGA core card but Qemu emulation still works. Currently Qemu is more important as MIPS CI tests depend on Malta and the deadline for PCI DM conversion will be enforced soon.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
board/imgtec/malta/malta.c | 84 +++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-)
diff --git a/board/imgtec/malta/malta.c b/board/imgtec/malta/malta.c index c04f727961..e78d5a7fbc 100644 --- a/board/imgtec/malta/malta.c +++ b/board/imgtec/malta/malta.c @@ -4,7 +4,8 @@
- Copyright (C) 2013 Imagination Technologies
*/
-#include <common.h> +#include <config.h> +#include <fdt_support.h> #include <ide.h> #include <init.h> #include <net.h> @@ -24,6 +25,9 @@
DECLARE_GLOBAL_DATA_PTR;
+#define MALTA_GT_PATH "/pci0@1be00000" +#define MALTA_MSC_PATH "/pci0@1bd00000"
enum core_card { CORE_UNKNOWN, CORE_LV, @@ -120,10 +124,12 @@ int checkboard(void) return 0; }
+#if !IS_ENABLED(CONFIG_DM_ETH) int board_eth_init(struct bd_info *bis) { return pci_eth_init(bis); } +#endif
void _machine_restart(void) { @@ -167,6 +173,81 @@ int misc_init_r(void) return 0; }
+#if IS_ENABLED(CONFIG_OF_BOARD_FIXUP) +/*
- TODO: currently doesn't work because rw_fdt_blob points to a
- NOR flash address. This needs some changes in board_init_f.
- */
+int board_fix_fdt(void *rw_fdt_blob) +{
int node = -1;
switch (malta_sys_con()) {
case SYSCON_GT64120:
node = fdt_path_offset(rw_fdt_blob,
MALTA_GT_PATH);
break;
default:
case SYSCON_MSC01:
node = fdt_path_offset(rw_fdt_blob,
);
break;
}
return fdt_status_okay(rw_fdt_blob, node);
+} +#endif
+#if IS_ENABLED(CONFIG_DM_PCI) +int board_early_init_r(void) +{
struct udevice *dev;
u32 val32;
u8 val8;
int ret;
pci_init();
ret = dm_pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82371AB_0, 0,
&dev);
This feels a bit wonky to me. How about a sysinfo driver for your board which does this init? Then you could just probe it.
As to finding PCI devices, your sysinfo driver could have a few phandle properties to point to the two devices you need.
But if these are really SYSCON devices, why not use the SYSCON devices, give them a unique ID (perhaps you already have with SYSCON_MSC01) and then call syscon_get_regmap_by_driver_data() ?
This is just a reimplementation of the original pci_init_board() function. I wanted to keep the changes small and to keep the original PCI init behaviour to get the PCI DM conversion done and get this patch series merged in this merge window ;) The Malta board is the reference board for MIPS Qemu and essential for testing and U-Boot CI. Therefore it would be very bad if it gets removed due to the PCI DM conversion deadline.
I already tried to add PIIX4 IRQ and ATA drivers for this init code. But those drivers were just bound and I didn't have an idea how to trigger a probe. I will look into it again with the next patch series for removing all non-DM code.
if (ret)
panic("Failed to find PIIX4 PCI bridge\n");
/* setup PCI interrupt routing */
dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCA, 10);
dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCB, 10);
dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCC, 11);
dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCD, 11);
This feels like it should be in DT.
I don't know if this is at all similar to x86, but see create_pirq_routing_table() and intel,irq-router.txt for some ideas.
/* mux SERIRQ onto SERIRQ pin */
dm_pci_read_config32(dev, PCI_CFG_PIIX4_GENCFG, &val32);
val32 |= PCI_CFG_PIIX4_GENCFG_SERIRQ;
dm_pci_write_config32(dev, PCI_CFG_PIIX4_GENCFG, val32);
dm_pci_clrset_config32() can do these three in one line, similar below.
I'll fix it
/* enable SERIRQ - Linux currently depends upon this */
dm_pci_read_config8(dev, PCI_CFG_PIIX4_SERIRQC, &val8);
val8 |= PCI_CFG_PIIX4_SERIRQC_EN |
PCI_CFG_PIIX4_SERIRQC_CONT;
dm_pci_write_config8(dev, PCI_CFG_PIIX4_SERIRQC, val8);
ret = dm_pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82371AB, 0,
&dev);
if (ret)
panic("Failed to find PIIX4 IDE controller\n");
/* enable bus master & IO access */
val32 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
dm_pci_write_config32(dev, PCI_COMMAND, val32);
/* set latency */
dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
/* enable IDE/ATA */
dm_pci_write_config32(dev, PCI_CFG_PIIX4_IDETIM_PRI,
PCI_CFG_PIIX4_IDETIM_IDE);
dm_pci_write_config32(dev, PCI_CFG_PIIX4_IDETIM_SEC,
PCI_CFG_PIIX4_IDETIM_IDE);
return 0;
+} +#else void pci_init_board(void) { pci_dev_t bdf; @@ -231,3 +312,4 @@ void pci_init_board(void) pci_write_config_dword(bdf, PCI_CFG_PIIX4_IDETIM_SEC, PCI_CFG_PIIX4_IDETIM_IDE); }
+#endif
2.32.0
Regards, Simon

Hi Daniel,
On Mon, 12 Jul 2021 at 19:17, Daniel Schwierzeck daniel.schwierzeck@gmail.com wrote:
Hi Simon,
Am Samstag, den 10.07.2021, 18:00 -0600 schrieb Simon Glass:
() Hi Daniel,
On Tue, 6 Jul 2021 at 08:22, Daniel Schwierzeck daniel.schwierzeck@gmail.com wrote:
As almost all peripherals are connected via PCI dependent on the used core card, PCI setup is always required. Thus run pci_init() including PCI scanning and probing and core card specific setups in board_early_init_r().
Also prepare support for dynamically managing the status of the different PCI DT nodes dependent on used core card via option CONFIG_OF_BOARD_FIXUP. Before this feature can be enabled, the call order of the fix_fdt() init hook in board_init_f needs to be changed. Otherwise rw_fdt_blob points to a read-only NOR flash address. Thus this options needs to stay disabled until the board_init_f problem could be solved. This breaks running the default U-Boot image on real HW using the FPGA core card but Qemu emulation still works. Currently Qemu is more important as MIPS CI tests depend on Malta and the deadline for PCI DM conversion will be enforced soon.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
board/imgtec/malta/malta.c | 84 +++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-)
diff --git a/board/imgtec/malta/malta.c b/board/imgtec/malta/malta.c index c04f727961..e78d5a7fbc 100644 --- a/board/imgtec/malta/malta.c +++ b/board/imgtec/malta/malta.c @@ -4,7 +4,8 @@
- Copyright (C) 2013 Imagination Technologies
*/
-#include <common.h> +#include <config.h> +#include <fdt_support.h> #include <ide.h> #include <init.h> #include <net.h> @@ -24,6 +25,9 @@
DECLARE_GLOBAL_DATA_PTR;
+#define MALTA_GT_PATH "/pci0@1be00000" +#define MALTA_MSC_PATH "/pci0@1bd00000"
enum core_card { CORE_UNKNOWN, CORE_LV, @@ -120,10 +124,12 @@ int checkboard(void) return 0; }
+#if !IS_ENABLED(CONFIG_DM_ETH) int board_eth_init(struct bd_info *bis) { return pci_eth_init(bis); } +#endif
void _machine_restart(void) { @@ -167,6 +173,81 @@ int misc_init_r(void) return 0; }
+#if IS_ENABLED(CONFIG_OF_BOARD_FIXUP) +/*
- TODO: currently doesn't work because rw_fdt_blob points to a
- NOR flash address. This needs some changes in board_init_f.
- */
+int board_fix_fdt(void *rw_fdt_blob) +{
int node = -1;
switch (malta_sys_con()) {
case SYSCON_GT64120:
node = fdt_path_offset(rw_fdt_blob,
MALTA_GT_PATH);
break;
default:
case SYSCON_MSC01:
node = fdt_path_offset(rw_fdt_blob,
);
break;
}
return fdt_status_okay(rw_fdt_blob, node);
+} +#endif
+#if IS_ENABLED(CONFIG_DM_PCI) +int board_early_init_r(void) +{
struct udevice *dev;
u32 val32;
u8 val8;
int ret;
pci_init();
ret = dm_pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82371AB_0, 0,
&dev);
This feels a bit wonky to me. How about a sysinfo driver for your board which does this init? Then you could just probe it.
As to finding PCI devices, your sysinfo driver could have a few phandle properties to point to the two devices you need.
But if these are really SYSCON devices, why not use the SYSCON devices, give them a unique ID (perhaps you already have with SYSCON_MSC01) and then call syscon_get_regmap_by_driver_data() ?
This is just a reimplementation of the original pci_init_board() function. I wanted to keep the changes small and to keep the original PCI init behaviour to get the PCI DM conversion done and get this patch series merged in this merge window ;) The Malta board is the reference board for MIPS Qemu and essential for testing and U-Boot CI. Therefore it would be very bad if it gets removed due to the PCI DM conversion deadline.
I already tried to add PIIX4 IRQ and ATA drivers for this init code. But those drivers were just bound and I didn't have an idea how to trigger a probe. I will look into it again with the next patch series for removing all non-DM code.
OK.
if (ret)
panic("Failed to find PIIX4 PCI bridge\n");
/* setup PCI interrupt routing */
dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCA, 10);
dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCB, 10);
dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCC, 11);
dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCD, 11);
This feels like it should be in DT.
I don't know if this is at all similar to x86, but see create_pirq_routing_table() and intel,irq-router.txt for some ideas.
/* mux SERIRQ onto SERIRQ pin */
dm_pci_read_config32(dev, PCI_CFG_PIIX4_GENCFG, &val32);
val32 |= PCI_CFG_PIIX4_GENCFG_SERIRQ;
dm_pci_write_config32(dev, PCI_CFG_PIIX4_GENCFG, val32);
dm_pci_clrset_config32() can do these three in one line, similar below.
I'll fix it
/* enable SERIRQ - Linux currently depends upon this */
dm_pci_read_config8(dev, PCI_CFG_PIIX4_SERIRQC, &val8);
val8 |= PCI_CFG_PIIX4_SERIRQC_EN |
PCI_CFG_PIIX4_SERIRQC_CONT;
dm_pci_write_config8(dev, PCI_CFG_PIIX4_SERIRQC, val8);
ret = dm_pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82371AB, 0,
&dev);
if (ret)
panic("Failed to find PIIX4 IDE controller\n");
/* enable bus master & IO access */
val32 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
dm_pci_write_config32(dev, PCI_COMMAND, val32);
/* set latency */
dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
/* enable IDE/ATA */
dm_pci_write_config32(dev, PCI_CFG_PIIX4_IDETIM_PRI,
PCI_CFG_PIIX4_IDETIM_IDE);
dm_pci_write_config32(dev, PCI_CFG_PIIX4_IDETIM_SEC,
PCI_CFG_PIIX4_IDETIM_IDE);
return 0;
+} +#else void pci_init_board(void) { pci_dev_t bdf; @@ -231,3 +312,4 @@ void pci_init_board(void) pci_write_config_dword(bdf, PCI_CFG_PIIX4_IDETIM_SEC, PCI_CFG_PIIX4_IDETIM_IDE); }
+#endif
2.32.0
Regards, Simon

Enable DM_PCI and DM_ETH on MIPS Malta.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
---
arch/mips/Kconfig | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e54801673b..6b1f10d9a0 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -14,8 +14,11 @@ choice
config TARGET_MALTA bool "Support malta" + select BOARD_EARLY_INIT_R select DM select DM_SERIAL + select DM_PCI + select DM_ETH select DYNAMIC_IO_PORT_BASE select MIPS_CM select MIPS_INSERT_BOOT_CONFIG @@ -23,6 +26,7 @@ config TARGET_MALTA select MIPS_L2_CACHE select OF_CONTROL select OF_ISA_BUS + select PCI_MAP_SYSTEM_MEMORY select ROM_EXCEPTION_VECTORS select SUPPORTS_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1

This series converts the PCI host controller drivers used by MIPS Malta and the board-specific PCI setup code to PCI driver model. Because the AMD PCNET driver is already converted to ETH driver model, simply enable CONFIG_DM_ETH as well.
A patch in PCI uclass core is currently required for MIPS wanting to use PCI DM (except Octeon MIPS64) due to CONFIG_SYS_SDRAM_BASE being used as a virtual address on all MIPS boards.
The series for now is only tested with Qemu and the GT64120 PCI controller. The Malta Qemu tests are already covered by U-Boot CI Support for the MSC01 controller is prepared. The used PCI controller depends on the plugged core card (Qemu emulates the CoreLV card with GT64120).
Dynamic selection of the according PCI DT nodes via CONFIG_OF_BOARD_FIXUP is prepared but not yet enabled. This requires fixing of the call order of fix_fdt() in board_init_f, otherwise the passed-in rw_fdt_blob pointer will point to a read-only NOR flash address. I'll send a separate RFC patch for this.
I'll send a cleanup series for removing non-DM code after the merge windows has closed and the PCI DM conversion deadline has been enforced.
Changes in v2: - add empty line before return statements - add empty line before return statements - use dm_pci_clrset_config32() where possible
Daniel Schwierzeck (6): dm: pci: add option to map virtual system memory base address pci: gt64120: convert to driver model pci: msc01: convert to driver model MIPS: malta: add DT bindings for PCI host controller MIPS: malta: add support for PCI driver model MIPS: malta: enable PCI driver model
arch/mips/Kconfig | 4 ++ arch/mips/dts/mti,malta.dts | 28 +++++++++++++ board/imgtec/malta/malta.c | 80 ++++++++++++++++++++++++++++++++++++- drivers/pci/Kconfig | 13 ++++++ drivers/pci/pci-uclass.c | 9 +++-- drivers/pci/pci_gt64120.c | 74 +++++++++++++++++++++++++++++++++- drivers/pci/pci_msc01.c | 72 ++++++++++++++++++++++++++++++++- 7 files changed, 274 insertions(+), 6 deletions(-)

On MIPS the DRAM start address respectively CONFIG_SYS_SDRAM_BASE is still used as a virtual, CPU-mapped address instead of being used as physical address. Converting all MIPS boards and generic MIPS code to fix that is not trivial. Due to the approaching deadline for PCI DM conversion, this workaround is required for MIPS boards with PCI support until the CONFIG_SYS_SDRAM_BASE issue could be solved.
Add a compile-time option to let the PCI uclass core optionally map the DRAM address to a physical address when adding the PCI region of type PCI_REGION_SYS_MEMORY.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Stefan Roese sr@denx.de ---
(no changes since v1)
drivers/pci/Kconfig | 13 +++++++++++++ drivers/pci/pci-uclass.c | 9 ++++++--- 2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 517cf956ea..c49cb6eac9 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -54,6 +54,19 @@ config PCI_REGION_MULTI_ENTRY region type. This helps to add support for SoC's like OcteonTX/TX2 where every peripheral is on the PCI bus.
+config PCI_MAP_SYSTEM_MEMORY + bool "Map local system memory from a virtual base address" + depends on PCI || DM_PCI + depends on MIPS + default n + help + Say Y if base address of system memory is being used as a virtual address + instead of a physical address (e.g. on MIPS). The PCI core will then remap + the virtual memory base address to a physical address when adding the PCI + region of type PCI_REGION_SYS_MEMORY. + This should only be required on MIPS where CONFIG_SYS_SDRAM_BASE is still + being used as virtual address. + config PCI_SRIOV bool "Enable Single Root I/O Virtualization support for PCI" depends on PCI || DM_PCI diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index cb9aa81835..110a12b94b 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -1003,10 +1003,13 @@ static void decode_regions(struct pci_controller *hose, ofnode parent_node,
for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { if (bd->bi_dram[i].size) { + phys_addr_t start = bd->bi_dram[i].start; + + if (IS_ENABLED(CONFIG_PCI_MAP_SYSTEM_MEMORY)) + start = virt_to_phys((void *)(uintptr_t)bd->bi_dram[i].start); + pci_set_region(hose->regions + hose->region_count++, - bd->bi_dram[i].start, - bd->bi_dram[i].start, - bd->bi_dram[i].size, + start, start, bd->bi_dram[i].size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); } }

On Thu, 15 Jul 2021 at 12:54, Daniel Schwierzeck daniel.schwierzeck@gmail.com wrote:
On MIPS the DRAM start address respectively CONFIG_SYS_SDRAM_BASE is still used as a virtual, CPU-mapped address instead of being used as physical address. Converting all MIPS boards and generic MIPS code to fix that is not trivial. Due to the approaching deadline for PCI DM conversion, this workaround is required for MIPS boards with PCI support until the CONFIG_SYS_SDRAM_BASE issue could be solved.
Add a compile-time option to let the PCI uclass core optionally map the DRAM address to a physical address when adding the PCI region of type PCI_REGION_SYS_MEMORY.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Stefan Roese sr@denx.de
(no changes since v1)
drivers/pci/Kconfig | 13 +++++++++++++ drivers/pci/pci-uclass.c | 9 ++++++--- 2 files changed, 19 insertions(+), 3 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

This driver is currently only used on MIPS Malta boards.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Simon Glass sjg@chromium.org
---
Changes in v2: - add empty line before return statements
drivers/pci/pci_gt64120.c | 74 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci_gt64120.c b/drivers/pci/pci_gt64120.c index 80f11fedd1..e57fedf036 100644 --- a/drivers/pci/pci_gt64120.c +++ b/drivers/pci/pci_gt64120.c @@ -8,7 +8,7 @@ * Maciej W. Rozycki macro@mips.com */
-#include <common.h> +#include <dm.h> #include <gt64120.h> #include <init.h> #include <log.h> @@ -114,6 +114,7 @@ static int gt_config_access(struct gt64120_pci_controller *gt, return 0; }
+#if !IS_ENABLED(CONFIG_DM_PCI) static int gt_read_config_dword(struct pci_controller *hose, pci_dev_t dev, int where, u32 *value) { @@ -175,3 +176,74 @@ void gt64120_pci_init(void *regs, unsigned long sys_bus, unsigned long sys_phys, pci_register_hose(hose); hose->last_busno = pci_hose_scan(hose); } +#else +static int gt64120_pci_read_config(const struct udevice *dev, pci_dev_t bdf, + uint where, ulong *val, + enum pci_size_t size) +{ + struct gt64120_pci_controller *gt = dev_get_priv(dev); + u32 data = 0; + + if (gt_config_access(gt, PCI_ACCESS_READ, bdf, where, &data)) { + *val = pci_get_ff(size); + return 0; + } + + *val = pci_conv_32_to_size(data, where, size); + + return 0; +} + +static int gt64120_pci_write_config(struct udevice *dev, pci_dev_t bdf, + uint where, ulong val, + enum pci_size_t size) +{ + struct gt64120_pci_controller *gt = dev_get_priv(dev); + u32 data = 0; + + if (size == PCI_SIZE_32) { + data = val; + } else { + u32 old; + + if (gt_config_access(gt, PCI_ACCESS_READ, bdf, where, &old)) + return 0; + + data = pci_conv_size_to_32(old, val, where, size); + } + + gt_config_access(gt, PCI_ACCESS_WRITE, bdf, where, &data); + + return 0; +} + +static int gt64120_pci_probe(struct udevice *dev) +{ + struct gt64120_pci_controller *gt = dev_get_priv(dev); + + gt->regs = dev_remap_addr(dev); + if (!gt->regs) + return -EINVAL; + + return 0; +} + +static const struct dm_pci_ops gt64120_pci_ops = { + .read_config = gt64120_pci_read_config, + .write_config = gt64120_pci_write_config, +}; + +static const struct udevice_id gt64120_pci_ids[] = { + { .compatible = "marvell,pci-gt64120" }, + { } +}; + +U_BOOT_DRIVER(gt64120_pci) = { + .name = "gt64120_pci", + .id = UCLASS_PCI, + .of_match = gt64120_pci_ids, + .ops = >64120_pci_ops, + .probe = gt64120_pci_probe, + .priv_auto = sizeof(struct gt64120_pci_controller), +}; +#endif

This driver is currently only used on MIPS Malta boards.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Simon Glass sjg@chromium.org
---
Changes in v2: - add empty line before return statements
drivers/pci/pci_msc01.c | 72 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci_msc01.c b/drivers/pci/pci_msc01.c index 04838200a8..c17da475d0 100644 --- a/drivers/pci/pci_msc01.c +++ b/drivers/pci/pci_msc01.c @@ -4,7 +4,7 @@ * Author: Paul Burton paul.burton@mips.com */
-#include <common.h> +#include <dm.h> #include <init.h> #include <msc01.h> #include <pci.h> @@ -62,6 +62,7 @@ static int msc01_config_access(struct msc01_pci_controller *msc01, return 0; }
+#if !IS_ENABLED(CONFIG_DM_PCI) static int msc01_read_config_dword(struct pci_controller *hose, pci_dev_t dev, int where, u32 *value) { @@ -123,3 +124,72 @@ void msc01_pci_init(void *base, unsigned long sys_bus, unsigned long sys_phys, pci_register_hose(hose); hose->last_busno = pci_hose_scan(hose); } +#else +static int msc01_pci_read_config(const struct udevice *dev, pci_dev_t bdf, + uint where, ulong *val, enum pci_size_t size) +{ + struct msc01_pci_controller *msc01 = dev_get_priv(dev); + u32 data = 0; + + if (msc01_config_access(msc01, PCI_ACCESS_READ, bdf, where, &data)) { + *val = pci_get_ff(size); + return 0; + } + + *val = pci_conv_32_to_size(data, where, size); + + return 0; +} + +static int msc01_pci_write_config(struct udevice *dev, pci_dev_t bdf, + uint where, ulong val, enum pci_size_t size) +{ + struct msc01_pci_controller *msc01 = dev_get_priv(dev); + u32 data = 0; + + if (size == PCI_SIZE_32) { + data = val; + } else { + u32 old; + + if (msc01_config_access(msc01, PCI_ACCESS_READ, bdf, where, &old)) + return 0; + + data = pci_conv_size_to_32(old, val, where, size); + } + + msc01_config_access(msc01, PCI_ACCESS_WRITE, bdf, where, &data); + + return 0; +} + +static int msc01_pci_probe(struct udevice *dev) +{ + struct msc01_pci_controller *msc01 = dev_get_priv(dev); + + msc01->base = dev_remap_addr(dev); + if (!msc01->base) + return -EINVAL; + + return 0; +} + +static const struct dm_pci_ops msc01_pci_ops = { + .read_config = msc01_pci_read_config, + .write_config = msc01_pci_write_config, +}; + +static const struct udevice_id msc01_pci_ids[] = { + { .compatible = "mips,pci-msc01" }, + { } +}; + +U_BOOT_DRIVER(msc01_pci) = { + .name = "msc01_pci", + .id = UCLASS_PCI, + .of_match = msc01_pci_ids, + .ops = &msc01_pci_ops, + .probe = msc01_pci_probe, + .priv_auto = sizeof(struct msc01_pci_controller), +}; +#endif

Add DT binding for GT64120 and MSC01 PCI controllers. Only GT64120 is enabled by default to support Qemu. The MSC01 node will be dynamically enabled by Malta board code dependent on the plugged core card.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
(no changes since v1)
arch/mips/dts/mti,malta.dts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/arch/mips/dts/mti,malta.dts b/arch/mips/dts/mti,malta.dts index d339229c2a..ef47a340bb 100644 --- a/arch/mips/dts/mti,malta.dts +++ b/arch/mips/dts/mti,malta.dts @@ -29,4 +29,32 @@ u-boot,dm-pre-reloc; }; }; + + pci0@1bd00000 { + compatible = "mips,pci-msc01"; + device_type = "pci"; + reg = <0x1bd00000 0x2000>; + + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0x0>; + ranges = <0x01000000 0 0x00000000 0x00000000 0 0x800000 /* I/O */ + 0x02000000 0 0x10000000 0xb0000000 0 0x10000000 /* MEM */>; + + status = "disabled"; + }; + + pci0@1be00000 { + compatible = "marvell,pci-gt64120"; + device_type = "pci"; + reg = <0x1be00000 0x2000>; + + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0x0>; + ranges = <0x01000000 0 0x00000000 0x00000000 0 0x20000 /* I/O */ + 0x02000000 0 0x10000000 0x10000000 0 0x8000000 /* MEM */>; + + status = "okay"; + }; };

As almost all peripherals are connected via PCI dependent on the used core card, PCI setup is always required. Thus run pci_init() including PCI scanning and probing and core card specific setups in board_early_init_r().
Also prepare support for dynamically managing the status of the different PCI DT nodes dependent on used core card via option CONFIG_OF_BOARD_FIXUP. Before this feature can be enabled, the call order of the fix_fdt() init hook in board_init_f needs to be changed. Otherwise rw_fdt_blob points to a read-only NOR flash address. Thus this options needs to stay disabled until the board_init_f problem could be solved. This breaks running the default U-Boot image on real HW using the FPGA core card but Qemu emulation still works. Currently Qemu is more important as MIPS CI tests depend on Malta and the deadline for PCI DM conversion will be enforced soon.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
---
Changes in v2: - use dm_pci_clrset_config32() where possible
board/imgtec/malta/malta.c | 80 +++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-)
diff --git a/board/imgtec/malta/malta.c b/board/imgtec/malta/malta.c index c04f727961..9af1f92e5d 100644 --- a/board/imgtec/malta/malta.c +++ b/board/imgtec/malta/malta.c @@ -4,7 +4,8 @@ * Copyright (C) 2013 Imagination Technologies */
-#include <common.h> +#include <config.h> +#include <fdt_support.h> #include <ide.h> #include <init.h> #include <net.h> @@ -24,6 +25,9 @@
DECLARE_GLOBAL_DATA_PTR;
+#define MALTA_GT_PATH "/pci0@1be00000" +#define MALTA_MSC_PATH "/pci0@1bd00000" + enum core_card { CORE_UNKNOWN, CORE_LV, @@ -120,10 +124,12 @@ int checkboard(void) return 0; }
+#if !IS_ENABLED(CONFIG_DM_ETH) int board_eth_init(struct bd_info *bis) { return pci_eth_init(bis); } +#endif
void _machine_restart(void) { @@ -167,6 +173,77 @@ int misc_init_r(void) return 0; }
+#if IS_ENABLED(CONFIG_OF_BOARD_FIXUP) +/* + * TODO: currently doesn't work because rw_fdt_blob points to a + * NOR flash address. This needs some changes in board_init_f. + */ +int board_fix_fdt(void *rw_fdt_blob) +{ + int node = -1; + + switch (malta_sys_con()) { + case SYSCON_GT64120: + node = fdt_path_offset(rw_fdt_blob, MALTA_GT_PATH); + break; + default: + case SYSCON_MSC01: + node = fdt_path_offset(rw_fdt_blob, MALTA_MSC_PATH); + break; + } + + return fdt_status_okay(rw_fdt_blob, node); +} +#endif + +#if IS_ENABLED(CONFIG_DM_PCI) +int board_early_init_r(void) +{ + struct udevice *dev; + int ret; + + pci_init(); + + ret = dm_pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_0, 0, &dev); + if (ret) + panic("Failed to find PIIX4 PCI bridge\n"); + + /* setup PCI interrupt routing */ + dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCA, 10); + dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCB, 10); + dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCC, 11); + dm_pci_write_config8(dev, PCI_CFG_PIIX4_PIRQRCD, 11); + + /* mux SERIRQ onto SERIRQ pin */ + dm_pci_clrset_config32(dev, PCI_CFG_PIIX4_GENCFG, 0, + PCI_CFG_PIIX4_GENCFG_SERIRQ); + + /* enable SERIRQ - Linux currently depends upon this */ + dm_pci_clrset_config8(dev, PCI_CFG_PIIX4_SERIRQC, 0, + PCI_CFG_PIIX4_SERIRQC_EN | PCI_CFG_PIIX4_SERIRQC_CONT); + + ret = dm_pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB, 0, &dev); + if (ret) + panic("Failed to find PIIX4 IDE controller\n"); + + /* enable bus master & IO access */ + dm_pci_clrset_config32(dev, PCI_COMMAND, 0, + PCI_COMMAND_MASTER | PCI_COMMAND_IO); + + /* set latency */ + dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40); + + /* enable IDE/ATA */ + dm_pci_write_config32(dev, PCI_CFG_PIIX4_IDETIM_PRI, + PCI_CFG_PIIX4_IDETIM_IDE); + dm_pci_write_config32(dev, PCI_CFG_PIIX4_IDETIM_SEC, + PCI_CFG_PIIX4_IDETIM_IDE); + + return 0; +} +#else void pci_init_board(void) { pci_dev_t bdf; @@ -231,3 +308,4 @@ void pci_init_board(void) pci_write_config_dword(bdf, PCI_CFG_PIIX4_IDETIM_SEC, PCI_CFG_PIIX4_IDETIM_IDE); } +#endif

Enable DM_PCI and DM_ETH on MIPS Malta.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
---
(no changes since v1)
arch/mips/Kconfig | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e54801673b..6b1f10d9a0 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -14,8 +14,11 @@ choice
config TARGET_MALTA bool "Support malta" + select BOARD_EARLY_INIT_R select DM select DM_SERIAL + select DM_PCI + select DM_ETH select DYNAMIC_IO_PORT_BASE select MIPS_CM select MIPS_INSERT_BOOT_CONFIG @@ -23,6 +26,7 @@ config TARGET_MALTA select MIPS_L2_CACHE select OF_CONTROL select OF_ISA_BUS + select PCI_MAP_SYSTEM_MEMORY select ROM_EXCEPTION_VECTORS select SUPPORTS_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1

Am Donnerstag, den 15.07.2021, 20:53 +0200 schrieb Daniel Schwierzeck:
This series converts the PCI host controller drivers used by MIPS Malta and the board-specific PCI setup code to PCI driver model. Because the AMD PCNET driver is already converted to ETH driver model, simply enable CONFIG_DM_ETH as well.
A patch in PCI uclass core is currently required for MIPS wanting to use PCI DM (except Octeon MIPS64) due to CONFIG_SYS_SDRAM_BASE being used as a virtual address on all MIPS boards.
The series for now is only tested with Qemu and the GT64120 PCI controller. The Malta Qemu tests are already covered by U-Boot CI Support for the MSC01 controller is prepared. The used PCI controller depends on the plugged core card (Qemu emulates the CoreLV card with GT64120).
Dynamic selection of the according PCI DT nodes via CONFIG_OF_BOARD_FIXUP is prepared but not yet enabled. This requires fixing of the call order of fix_fdt() in board_init_f, otherwise the passed-in rw_fdt_blob pointer will point to a read-only NOR flash address. I'll send a separate RFC patch for this.
I'll send a cleanup series for removing non-DM code after the merge windows has closed and the PCI DM conversion deadline has been enforced.
Changes in v2:
- add empty line before return statements
- add empty line before return statements
- use dm_pci_clrset_config32() where possible
Daniel Schwierzeck (6): dm: pci: add option to map virtual system memory base address pci: gt64120: convert to driver model pci: msc01: convert to driver model MIPS: malta: add DT bindings for PCI host controller MIPS: malta: add support for PCI driver model MIPS: malta: enable PCI driver model
arch/mips/Kconfig | 4 ++ arch/mips/dts/mti,malta.dts | 28 +++++++++++++ board/imgtec/malta/malta.c | 80 ++++++++++++++++++++++++++++++++++++- drivers/pci/Kconfig | 13 ++++++ drivers/pci/pci-uclass.c | 9 +++-- drivers/pci/pci_gt64120.c | 74 +++++++++++++++++++++++++++++++++- drivers/pci/pci_msc01.c | 72 ++++++++++++++++++++++++++++++++- 7 files changed, 274 insertions(+), 6 deletions(-)
applied to u-boot-mips
participants (3)
-
Daniel Schwierzeck
-
Simon Glass
-
Stefan Roese