aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/block/blk-uclass.c25
-rw-r--r--drivers/block/ide.c2
-rw-r--r--drivers/block/sandbox.c17
-rw-r--r--drivers/clk/altera/clk-arria10.c1
-rw-r--r--drivers/clk/clk_pic32.c1
-rw-r--r--drivers/clk/clk_zynq.c1
-rw-r--r--drivers/clk/exynos/clk-exynos7420.c3
-rw-r--r--drivers/clk/owl/clk_s900.c1
-rw-r--r--drivers/core/device.c2
-rw-r--r--drivers/core/dump.c2
-rw-r--r--drivers/core/lists.c9
-rw-r--r--drivers/core/ofnode.c4
-rw-r--r--drivers/core/regmap.c316
-rw-r--r--drivers/core/root.c20
-rw-r--r--drivers/core/uclass.c31
-rw-r--r--drivers/core/util.c25
-rw-r--r--drivers/cpu/mpc83xx_cpu.c2
-rw-r--r--drivers/gpio/omap_gpio.c2
-rw-r--r--drivers/gpio/stm32f7_gpio.c2
-rw-r--r--drivers/gpio/tegra186_gpio.c1
-rw-r--r--drivers/gpio/tegra_gpio.c1
-rw-r--r--drivers/i2c/omap24xx_i2c.c2
-rw-r--r--drivers/misc/Kconfig17
-rw-r--r--drivers/misc/Makefile63
-rw-r--r--drivers/misc/gdsys_soc.c74
-rw-r--r--drivers/misc/gdsys_soc.h23
-rw-r--r--drivers/misc/ihs_fpga.c867
-rw-r--r--drivers/misc/ihs_fpga.h49
-rw-r--r--drivers/misc/imx8/scu.c4
-rw-r--r--drivers/misc/swap_case.c9
-rw-r--r--drivers/mmc/mmc.c3
-rw-r--r--drivers/mmc/omap_hsmmc.c2
-rw-r--r--drivers/nvme/nvme.c1
-rw-r--r--drivers/pci/pci-uclass.c51
-rw-r--r--drivers/pinctrl/broadcom/pinctrl-bcm283x.c2
-rw-r--r--drivers/pinctrl/exynos/pinctrl-exynos7420.c1
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx5.c2
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx6.c2
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx7.c2
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx7ulp.c2
-rw-r--r--drivers/pinctrl/pinctrl-single.c1
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c2
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c2
-rw-r--r--drivers/ram/bmips_ram.c1
-rw-r--r--drivers/scsi/scsi.c1
-rw-r--r--drivers/serial/altera_jtag_uart.c1
-rw-r--r--drivers/serial/altera_uart.c1
-rw-r--r--drivers/serial/arm_dcc.c1
-rw-r--r--drivers/serial/atmel_usart.c2
-rw-r--r--drivers/serial/ns16550.c20
-rw-r--r--drivers/serial/serial-uclass.c2
-rw-r--r--drivers/serial/serial_ar933x.c1
-rw-r--r--drivers/serial/serial_arc.c1
-rw-r--r--drivers/serial/serial_bcm283x_mu.c2
-rw-r--r--drivers/serial/serial_bcm283x_pl011.c2
-rw-r--r--drivers/serial/serial_bcm6345.c1
-rw-r--r--drivers/serial/serial_efi.c1
-rw-r--r--drivers/serial/serial_intel_mid.c1
-rw-r--r--drivers/serial/serial_lpuart.c1
-rw-r--r--drivers/serial/serial_meson.c1
-rw-r--r--drivers/serial/serial_mvebu_a3700.c1
-rw-r--r--drivers/serial/serial_mxc.c2
-rw-r--r--drivers/serial/serial_omap.c2
-rw-r--r--drivers/serial/serial_owl.c1
-rw-r--r--drivers/serial/serial_pic32.c1
-rw-r--r--drivers/serial/serial_pl01x.c2
-rw-r--r--drivers/serial/serial_s5p.c1
-rw-r--r--drivers/serial/serial_sh.c2
-rw-r--r--drivers/serial/serial_sti_asc.c1
-rw-r--r--drivers/serial/serial_stm32.c2
-rw-r--r--drivers/serial/serial_xuartlite.c1
-rw-r--r--drivers/serial/serial_zynq.c1
-rw-r--r--drivers/sysreset/sysreset_x86.c1
-rw-r--r--drivers/timer/Kconfig110
-rw-r--r--drivers/timer/ag101p_timer.c1
-rw-r--r--drivers/timer/altera_timer.c1
-rw-r--r--drivers/timer/arc_timer.c1
-rw-r--r--drivers/timer/ast_timer.c1
-rw-r--r--drivers/timer/atcpit100_timer.c1
-rw-r--r--drivers/timer/atmel_pit_timer.c1
-rw-r--r--drivers/timer/cadence-ttc.c1
-rw-r--r--drivers/timer/dw-apb-timer.c1
-rw-r--r--drivers/timer/mpc83xx_timer.c1
-rw-r--r--drivers/timer/omap-timer.c1
-rw-r--r--drivers/timer/rockchip_timer.c1
-rw-r--r--drivers/timer/sti-timer.c1
-rw-r--r--drivers/timer/stm32_timer.c1
-rw-r--r--drivers/timer/timer-uclass.c2
-rw-r--r--drivers/timer/tsc_timer.c1
-rw-r--r--drivers/video/simplefb.c1
-rw-r--r--drivers/virtio/Kconfig62
-rw-r--r--drivers/virtio/Makefile11
-rw-r--r--drivers/virtio/virtio-uclass.c369
-rw-r--r--drivers/virtio/virtio_blk.c137
-rw-r--r--drivers/virtio/virtio_blk.h129
-rw-r--r--drivers/virtio/virtio_mmio.c413
-rw-r--r--drivers/virtio/virtio_mmio.h129
-rw-r--r--drivers/virtio/virtio_net.c239
-rw-r--r--drivers/virtio/virtio_net.h268
-rw-r--r--drivers/virtio/virtio_pci.h173
-rw-r--r--drivers/virtio/virtio_pci_legacy.c421
-rw-r--r--drivers/virtio/virtio_pci_modern.c609
-rw-r--r--drivers/virtio/virtio_ring.c358
-rw-r--r--drivers/virtio/virtio_sandbox.c233
-rw-r--r--drivers/watchdog/ast_wdt.c1
107 files changed, 5169 insertions, 220 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 927a2b87f6..4ac823d962 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -112,6 +112,8 @@ source "drivers/usb/Kconfig"
112 112
113source "drivers/video/Kconfig" 113source "drivers/video/Kconfig"
114 114
115source "drivers/virtio/Kconfig"
116
115source "drivers/w1/Kconfig" 117source "drivers/w1/Kconfig"
116 118
117source "drivers/w1-eeprom/Kconfig" 119source "drivers/w1-eeprom/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index fb38b67541..4453c62ad3 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_$(SPL_TPL_)SERIAL_SUPPORT) += serial/
14obj-$(CONFIG_$(SPL_TPL_)SPI_FLASH_SUPPORT) += mtd/spi/ 14obj-$(CONFIG_$(SPL_TPL_)SPI_FLASH_SUPPORT) += mtd/spi/
15obj-$(CONFIG_$(SPL_TPL_)SPI_SUPPORT) += spi/ 15obj-$(CONFIG_$(SPL_TPL_)SPI_SUPPORT) += spi/
16obj-$(CONFIG_$(SPL_TPL_)TIMER) += timer/ 16obj-$(CONFIG_$(SPL_TPL_)TIMER) += timer/
17obj-$(CONFIG_$(SPL_TPL_)VIRTIO) += virtio/
17obj-$(CONFIG_$(SPL_)DM_MAILBOX) += mailbox/ 18obj-$(CONFIG_$(SPL_)DM_MAILBOX) += mailbox/
18obj-$(CONFIG_$(SPL_)REMOTEPROC) += remoteproc/ 19obj-$(CONFIG_$(SPL_)REMOTEPROC) += remoteproc/
19 20
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index facf52711c..65a766e586 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -23,6 +23,7 @@ static const char *if_typename_str[IF_TYPE_COUNT] = {
23 [IF_TYPE_HOST] = "host", 23 [IF_TYPE_HOST] = "host",
24 [IF_TYPE_NVME] = "nvme", 24 [IF_TYPE_NVME] = "nvme",
25 [IF_TYPE_EFI] = "efi", 25 [IF_TYPE_EFI] = "efi",
26 [IF_TYPE_VIRTIO] = "virtio",
26}; 27};
27 28
28static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = { 29static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
@@ -37,6 +38,7 @@ static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
37 [IF_TYPE_HOST] = UCLASS_ROOT, 38 [IF_TYPE_HOST] = UCLASS_ROOT,
38 [IF_TYPE_NVME] = UCLASS_NVME, 39 [IF_TYPE_NVME] = UCLASS_NVME,
39 [IF_TYPE_EFI] = UCLASS_EFI, 40 [IF_TYPE_EFI] = UCLASS_EFI,
41 [IF_TYPE_VIRTIO] = UCLASS_VIRTIO,
40}; 42};
41 43
42static enum if_type if_typename_to_iftype(const char *if_typename) 44static enum if_type if_typename_to_iftype(const char *if_typename)
@@ -471,15 +473,6 @@ unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
471 return ops->erase(dev, start, blkcnt); 473 return ops->erase(dev, start, blkcnt);
472} 474}
473 475
474int blk_prepare_device(struct udevice *dev)
475{
476 struct blk_desc *desc = dev_get_uclass_platdata(dev);
477
478 part_init(desc);
479
480 return 0;
481}
482
483int blk_get_from_parent(struct udevice *parent, struct udevice **devp) 476int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
484{ 477{
485 struct udevice *dev; 478 struct udevice *dev;
@@ -526,7 +519,7 @@ int blk_find_max_devnum(enum if_type if_type)
526 return max_devnum; 519 return max_devnum;
527} 520}
528 521
529static int blk_next_free_devnum(enum if_type if_type) 522int blk_next_free_devnum(enum if_type if_type)
530{ 523{
531 int ret; 524 int ret;
532 525
@@ -644,8 +637,20 @@ int blk_unbind_all(int if_type)
644 return 0; 637 return 0;
645} 638}
646 639
640static int blk_post_probe(struct udevice *dev)
641{
642#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
643 struct blk_desc *desc = dev_get_uclass_platdata(dev);
644
645 part_init(desc);
646#endif
647
648 return 0;
649}
650
647UCLASS_DRIVER(blk) = { 651UCLASS_DRIVER(blk) = {
648 .id = UCLASS_BLK, 652 .id = UCLASS_BLK,
649 .name = "blk", 653 .name = "blk",
654 .post_probe = blk_post_probe,
650 .per_device_platdata_auto_alloc_size = sizeof(struct blk_desc), 655 .per_device_platdata_auto_alloc_size = sizeof(struct blk_desc),
651}; 656};
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index 38adb6a241..4b8a4eac17 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -1169,8 +1169,6 @@ static int ide_blk_probe(struct udevice *udev)
1169 BLK_REV_SIZE); 1169 BLK_REV_SIZE);
1170 desc->revision[BLK_REV_SIZE] = '\0'; 1170 desc->revision[BLK_REV_SIZE] = '\0';
1171 1171
1172 part_init(desc);
1173
1174 return 0; 1172 return 0;
1175} 1173}
1176 1174
diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c
index 0392437309..d3b1aaaba3 100644
--- a/drivers/block/sandbox.c
+++ b/drivers/block/sandbox.c
@@ -33,7 +33,7 @@ static unsigned long host_block_read(struct udevice *dev,
33 unsigned long start, lbaint_t blkcnt, 33 unsigned long start, lbaint_t blkcnt,
34 void *buffer) 34 void *buffer)
35{ 35{
36 struct host_block_dev *host_dev = dev_get_priv(dev); 36 struct host_block_dev *host_dev = dev_get_platdata(dev);
37 struct blk_desc *block_dev = dev_get_uclass_platdata(dev); 37 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
38 38
39#else 39#else
@@ -64,7 +64,7 @@ static unsigned long host_block_write(struct udevice *dev,
64 unsigned long start, lbaint_t blkcnt, 64 unsigned long start, lbaint_t blkcnt,
65 const void *buffer) 65 const void *buffer)
66{ 66{
67 struct host_block_dev *host_dev = dev_get_priv(dev); 67 struct host_block_dev *host_dev = dev_get_platdata(dev);
68 struct blk_desc *block_dev = dev_get_uclass_platdata(dev); 68 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
69#else 69#else
70static unsigned long host_block_write(struct blk_desc *block_dev, 70static unsigned long host_block_write(struct blk_desc *block_dev,
@@ -131,17 +131,18 @@ int host_dev_bind(int devnum, char *filename)
131 os_lseek(fd, 0, OS_SEEK_END) / 512, &dev); 131 os_lseek(fd, 0, OS_SEEK_END) / 512, &dev);
132 if (ret) 132 if (ret)
133 goto err_file; 133 goto err_file;
134
135 host_dev = dev_get_platdata(dev);
136 host_dev->fd = fd;
137 host_dev->filename = fname;
138
134 ret = device_probe(dev); 139 ret = device_probe(dev);
135 if (ret) { 140 if (ret) {
136 device_unbind(dev); 141 device_unbind(dev);
137 goto err_file; 142 goto err_file;
138 } 143 }
139 144
140 host_dev = dev_get_priv(dev); 145 return 0;
141 host_dev->fd = fd;
142 host_dev->filename = fname;
143
144 return blk_prepare_device(dev);
145err_file: 146err_file:
146 os_close(fd); 147 os_close(fd);
147err: 148err:
@@ -226,7 +227,7 @@ U_BOOT_DRIVER(sandbox_host_blk) = {
226 .name = "sandbox_host_blk", 227 .name = "sandbox_host_blk",
227 .id = UCLASS_BLK, 228 .id = UCLASS_BLK,
228 .ops = &sandbox_host_blk_ops, 229 .ops = &sandbox_host_blk_ops,
229 .priv_auto_alloc_size = sizeof(struct host_block_dev), 230 .platdata_auto_alloc_size = sizeof(struct host_block_dev),
230}; 231};
231#else 232#else
232U_BOOT_LEGACY_BLK(sandbox_host) = { 233U_BOOT_LEGACY_BLK(sandbox_host) = {
diff --git a/drivers/clk/altera/clk-arria10.c b/drivers/clk/altera/clk-arria10.c
index 78102c760d..612a1718dc 100644
--- a/drivers/clk/altera/clk-arria10.c
+++ b/drivers/clk/altera/clk-arria10.c
@@ -352,7 +352,6 @@ static const struct udevice_id socfpga_a10_clk_match[] = {
352U_BOOT_DRIVER(socfpga_a10_clk) = { 352U_BOOT_DRIVER(socfpga_a10_clk) = {
353 .name = "clk-a10", 353 .name = "clk-a10",
354 .id = UCLASS_CLK, 354 .id = UCLASS_CLK,
355 .flags = DM_FLAG_PRE_RELOC,
356 .of_match = socfpga_a10_clk_match, 355 .of_match = socfpga_a10_clk_match,
357 .ops = &socfpga_a10_clk_ops, 356 .ops = &socfpga_a10_clk_ops,
358 .bind = socfpga_a10_clk_bind, 357 .bind = socfpga_a10_clk_bind,
diff --git a/drivers/clk/clk_pic32.c b/drivers/clk/clk_pic32.c
index fdf95a12da..b3ac0d5a92 100644
--- a/drivers/clk/clk_pic32.c
+++ b/drivers/clk/clk_pic32.c
@@ -418,7 +418,6 @@ U_BOOT_DRIVER(pic32_clk) = {
418 .name = "pic32_clk", 418 .name = "pic32_clk",
419 .id = UCLASS_CLK, 419 .id = UCLASS_CLK,
420 .of_match = pic32_clk_ids, 420 .of_match = pic32_clk_ids,
421 .flags = DM_FLAG_PRE_RELOC,
422 .ops = &pic32_pic32_clk_ops, 421 .ops = &pic32_pic32_clk_ops,
423 .probe = pic32_clk_probe, 422 .probe = pic32_clk_probe,
424 .priv_auto_alloc_size = sizeof(struct pic32_clk_priv), 423 .priv_auto_alloc_size = sizeof(struct pic32_clk_priv),
diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c
index d647e0a01e..482f0937cb 100644
--- a/drivers/clk/clk_zynq.c
+++ b/drivers/clk/clk_zynq.c
@@ -480,7 +480,6 @@ U_BOOT_DRIVER(zynq_clk) = {
480 .name = "zynq_clk", 480 .name = "zynq_clk",
481 .id = UCLASS_CLK, 481 .id = UCLASS_CLK,
482 .of_match = zynq_clk_ids, 482 .of_match = zynq_clk_ids,
483 .flags = DM_FLAG_PRE_RELOC,
484 .ops = &zynq_clk_ops, 483 .ops = &zynq_clk_ops,
485 .priv_auto_alloc_size = sizeof(struct zynq_clk_priv), 484 .priv_auto_alloc_size = sizeof(struct zynq_clk_priv),
486 .probe = zynq_clk_probe, 485 .probe = zynq_clk_probe,
diff --git a/drivers/clk/exynos/clk-exynos7420.c b/drivers/clk/exynos/clk-exynos7420.c
index 763567b17c..aa86c7ca44 100644
--- a/drivers/clk/exynos/clk-exynos7420.c
+++ b/drivers/clk/exynos/clk-exynos7420.c
@@ -201,7 +201,6 @@ U_BOOT_DRIVER(exynos7420_clk_topc) = {
201 .probe = exynos7420_clk_topc_probe, 201 .probe = exynos7420_clk_topc_probe,
202 .priv_auto_alloc_size = sizeof(struct exynos7420_clk_topc_priv), 202 .priv_auto_alloc_size = sizeof(struct exynos7420_clk_topc_priv),
203 .ops = &exynos7420_clk_topc_ops, 203 .ops = &exynos7420_clk_topc_ops,
204 .flags = DM_FLAG_PRE_RELOC,
205}; 204};
206 205
207static const struct udevice_id exynos7420_clk_top0_compat[] = { 206static const struct udevice_id exynos7420_clk_top0_compat[] = {
@@ -216,7 +215,6 @@ U_BOOT_DRIVER(exynos7420_clk_top0) = {
216 .probe = exynos7420_clk_top0_probe, 215 .probe = exynos7420_clk_top0_probe,
217 .priv_auto_alloc_size = sizeof(struct exynos7420_clk_top0_priv), 216 .priv_auto_alloc_size = sizeof(struct exynos7420_clk_top0_priv),
218 .ops = &exynos7420_clk_top0_ops, 217 .ops = &exynos7420_clk_top0_ops,
219 .flags = DM_FLAG_PRE_RELOC,
220}; 218};
221 219
222static const struct udevice_id exynos7420_clk_peric1_compat[] = { 220static const struct udevice_id exynos7420_clk_peric1_compat[] = {
@@ -229,5 +227,4 @@ U_BOOT_DRIVER(exynos7420_clk_peric1) = {
229 .id = UCLASS_CLK, 227 .id = UCLASS_CLK,
230 .of_match = exynos7420_clk_peric1_compat, 228 .of_match = exynos7420_clk_peric1_compat,
231 .ops = &exynos7420_clk_peric1_ops, 229 .ops = &exynos7420_clk_peric1_ops,
232 .flags = DM_FLAG_PRE_RELOC,
233}; 230};
diff --git a/drivers/clk/owl/clk_s900.c b/drivers/clk/owl/clk_s900.c
index 2b39bb99af..a7c15d2812 100644
--- a/drivers/clk/owl/clk_s900.c
+++ b/drivers/clk/owl/clk_s900.c
@@ -134,5 +134,4 @@ U_BOOT_DRIVER(clk_owl) = {
134 .ops = &owl_clk_ops, 134 .ops = &owl_clk_ops,
135 .priv_auto_alloc_size = sizeof(struct owl_clk_priv), 135 .priv_auto_alloc_size = sizeof(struct owl_clk_priv),
136 .probe = owl_clk_probe, 136 .probe = owl_clk_probe,
137 .flags = DM_FLAG_PRE_RELOC,
138}; 137};
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 5176aa3f86..47a697f3e5 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -834,5 +834,5 @@ int dev_enable_by_path(const char *path)
834 if (ret) 834 if (ret)
835 return ret; 835 return ret;
836 836
837 return lists_bind_fdt(parent, node, NULL); 837 return lists_bind_fdt(parent, node, NULL, false);
838} 838}
diff --git a/drivers/core/dump.c b/drivers/core/dump.c
index d7cdb1475d..9068084404 100644
--- a/drivers/core/dump.c
+++ b/drivers/core/dump.c
@@ -89,7 +89,7 @@ void dm_dump_uclass(void)
89 printf("uclass %d: %s\n", id, uc->uc_drv->name); 89 printf("uclass %d: %s\n", id, uc->uc_drv->name);
90 if (list_empty(&uc->dev_head)) 90 if (list_empty(&uc->dev_head))
91 continue; 91 continue;
92 list_for_each_entry(dev, &uc->dev_head, uclass_node) { 92 uclass_foreach_dev(dev, uc) {
93 dm_display_line(dev, i); 93 dm_display_line(dev, i);
94 i++; 94 i++;
95 } 95 }
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index a1677269d8..a1f828463e 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -122,7 +122,8 @@ static int driver_check_compatible(const struct udevice_id *of_match,
122 return -ENOENT; 122 return -ENOENT;
123} 123}
124 124
125int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp) 125int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
126 bool pre_reloc_only)
126{ 127{
127 struct driver *driver = ll_entry_start(struct driver, driver); 128 struct driver *driver = ll_entry_start(struct driver, driver);
128 const int n_ents = ll_entry_count(struct driver, driver); 129 const int n_ents = ll_entry_count(struct driver, driver);
@@ -171,6 +172,12 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp)
171 if (entry == driver + n_ents) 172 if (entry == driver + n_ents)
172 continue; 173 continue;
173 174
175 if (pre_reloc_only) {
176 if (!dm_ofnode_pre_reloc(node) &&
177 !(entry->flags & DM_FLAG_PRE_RELOC))
178 return 0;
179 }
180
174 pr_debug(" - found match at '%s'\n", entry->name); 181 pr_debug(" - found match at '%s'\n", entry->name);
175 ret = device_bind_with_driver_data(parent, entry, name, 182 ret = device_bind_with_driver_data(parent, entry, name,
176 id->data, node, &dev); 183 id->data, node, &dev);
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index b7b7ad3a62..d9b5280b2d 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -831,8 +831,10 @@ int ofnode_write_prop(ofnode node, const char *propname, int len,
831 return -ENOMEM; 831 return -ENOMEM;
832 832
833 new->name = strdup(propname); 833 new->name = strdup(propname);
834 if (!new->name) 834 if (!new->name) {
835 free(new);
835 return -ENOMEM; 836 return -ENOMEM;
837 }
836 838
837 new->value = (void *)value; 839 new->value = (void *)value;
838 new->length = len; 840 new->length = len;
diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
index 8e5c3bcf61..5ef0f71c8b 100644
--- a/drivers/core/regmap.c
+++ b/drivers/core/regmap.c
@@ -17,6 +17,12 @@
17 17
18DECLARE_GLOBAL_DATA_PTR; 18DECLARE_GLOBAL_DATA_PTR;
19 19
20/**
21 * regmap_alloc() - Allocate a regmap with a given number of ranges.
22 *
23 * @count: Number of ranges to be allocated for the regmap.
24 * Return: A pointer to the newly allocated regmap, or NULL on error.
25 */
20static struct regmap *regmap_alloc(int count) 26static struct regmap *regmap_alloc(int count)
21{ 27{
22 struct regmap *map; 28 struct regmap *map;
@@ -50,6 +56,58 @@ int regmap_init_mem_platdata(struct udevice *dev, fdt_val_t *reg, int count,
50 return 0; 56 return 0;
51} 57}
52#else 58#else
59/**
60 * init_range() - Initialize a single range of a regmap
61 * @node: Device node that will use the map in question
62 * @range: Pointer to a regmap_range structure that will be initialized
63 * @addr_len: The length of the addr parts of the reg property
64 * @size_len: The length of the size parts of the reg property
65 * @index: The index of the range to initialize
66 *
67 * This function will read the necessary 'reg' information from the device tree
68 * (the 'addr' part, and the 'length' part), and initialize the range in
69 * quesion.
70 *
71 * Return: 0 if OK, -ve on error
72 */
73static int init_range(ofnode node, struct regmap_range *range, int addr_len,
74 int size_len, int index)
75{
76 fdt_size_t sz;
77 struct resource r;
78
79 if (of_live_active()) {
80 int ret;
81
82 ret = of_address_to_resource(ofnode_to_np(node),
83 index, &r);
84 if (ret) {
85 debug("%s: Could not read resource of range %d (ret = %d)\n",
86 ofnode_get_name(node), index, ret);
87 return ret;
88 }
89
90 range->start = r.start;
91 range->size = r.end - r.start + 1;
92 } else {
93 int offset = ofnode_to_offset(node);
94
95 range->start = fdtdec_get_addr_size_fixed(gd->fdt_blob, offset,
96 "reg", index,
97 addr_len, size_len,
98 &sz, true);
99 if (range->start == FDT_ADDR_T_NONE) {
100 debug("%s: Could not read start of range %d\n",
101 ofnode_get_name(node), index);
102 return -EINVAL;
103 }
104
105 range->size = sz;
106 }
107
108 return 0;
109}
110
53int regmap_init_mem(ofnode node, struct regmap **mapp) 111int regmap_init_mem(ofnode node, struct regmap **mapp)
54{ 112{
55 struct regmap_range *range; 113 struct regmap_range *range;
@@ -58,19 +116,41 @@ int regmap_init_mem(ofnode node, struct regmap **mapp)
58 int addr_len, size_len, both_len; 116 int addr_len, size_len, both_len;
59 int len; 117 int len;
60 int index; 118 int index;
61 struct resource r;
62 119
63 addr_len = ofnode_read_simple_addr_cells(ofnode_get_parent(node)); 120 addr_len = ofnode_read_simple_addr_cells(ofnode_get_parent(node));
121 if (addr_len < 0) {
122 debug("%s: Error while reading the addr length (ret = %d)\n",
123 ofnode_get_name(node), addr_len);
124 return addr_len;
125 }
126
64 size_len = ofnode_read_simple_size_cells(ofnode_get_parent(node)); 127 size_len = ofnode_read_simple_size_cells(ofnode_get_parent(node));
128 if (size_len < 0) {
129 debug("%s: Error while reading the size length: (ret = %d)\n",
130 ofnode_get_name(node), size_len);
131 return size_len;
132 }
133
65 both_len = addr_len + size_len; 134 both_len = addr_len + size_len;
135 if (!both_len) {
136 debug("%s: Both addr and size length are zero\n",
137 ofnode_get_name(node));
138 return -EINVAL;
139 }
66 140
67 len = ofnode_read_size(node, "reg"); 141 len = ofnode_read_size(node, "reg");
68 if (len < 0) 142 if (len < 0) {
143 debug("%s: Error while reading reg size (ret = %d)\n",
144 ofnode_get_name(node), len);
69 return len; 145 return len;
146 }
70 len /= sizeof(fdt32_t); 147 len /= sizeof(fdt32_t);
71 count = len / both_len; 148 count = len / both_len;
72 if (!count) 149 if (!count) {
150 debug("%s: Not enough data in reg property\n",
151 ofnode_get_name(node));
73 return -EINVAL; 152 return -EINVAL;
153 }
74 154
75 map = regmap_alloc(count); 155 map = regmap_alloc(count);
76 if (!map) 156 if (!map)
@@ -78,19 +158,21 @@ int regmap_init_mem(ofnode node, struct regmap **mapp)
78 158
79 for (range = map->ranges, index = 0; count > 0; 159 for (range = map->ranges, index = 0; count > 0;
80 count--, range++, index++) { 160 count--, range++, index++) {
81 fdt_size_t sz; 161 int ret = init_range(node, range, addr_len, size_len, index);
82 if (of_live_active()) { 162
83 of_address_to_resource(ofnode_to_np(node), index, &r); 163 if (ret)
84 range->start = r.start; 164 return ret;
85 range->size = r.end - r.start + 1;
86 } else {
87 range->start = fdtdec_get_addr_size_fixed(gd->fdt_blob,
88 ofnode_to_offset(node), "reg", index,
89 addr_len, size_len, &sz, true);
90 range->size = sz;
91 }
92 } 165 }
93 166
167 if (ofnode_read_bool(node, "little-endian"))
168 map->endianness = REGMAP_LITTLE_ENDIAN;
169 else if (ofnode_read_bool(node, "big-endian"))
170 map->endianness = REGMAP_BIG_ENDIAN;
171 else if (ofnode_read_bool(node, "native-endian"))
172 map->endianness = REGMAP_NATIVE_ENDIAN;
173 else /* Default: native endianness */
174 map->endianness = REGMAP_NATIVE_ENDIAN;
175
94 *mapp = map; 176 *mapp = map;
95 177
96 return 0; 178 return 0;
@@ -115,24 +197,218 @@ int regmap_uninit(struct regmap *map)
115 return 0; 197 return 0;
116} 198}
117 199
118int regmap_read(struct regmap *map, uint offset, uint *valp) 200static inline u8 __read_8(u8 *addr, enum regmap_endianness_t endianness)
119{ 201{
120 u32 *ptr = map_physmem(map->ranges[0].start + offset, 4, MAP_NOCACHE); 202 return readb(addr);
203}
121 204
122 *valp = le32_to_cpu(readl(ptr)); 205static inline u16 __read_16(u16 *addr, enum regmap_endianness_t endianness)
206{
207 switch (endianness) {
208 case REGMAP_LITTLE_ENDIAN:
209 return in_le16(addr);
210 case REGMAP_BIG_ENDIAN:
211 return in_be16(addr);
212 case REGMAP_NATIVE_ENDIAN:
213 return readw(addr);
214 }
215
216 return readw(addr);
217}
218
219static inline u32 __read_32(u32 *addr, enum regmap_endianness_t endianness)
220{
221 switch (endianness) {
222 case REGMAP_LITTLE_ENDIAN:
223 return in_le32(addr);
224 case REGMAP_BIG_ENDIAN:
225 return in_be32(addr);
226 case REGMAP_NATIVE_ENDIAN:
227 return readl(addr);
228 }
229
230 return readl(addr);
231}
232
233#if defined(in_le64) && defined(in_be64) && defined(readq)
234static inline u64 __read_64(u64 *addr, enum regmap_endianness_t endianness)
235{
236 switch (endianness) {
237 case REGMAP_LITTLE_ENDIAN:
238 return in_le64(addr);
239 case REGMAP_BIG_ENDIAN:
240 return in_be64(addr);
241 case REGMAP_NATIVE_ENDIAN:
242 return readq(addr);
243 }
244
245 return readq(addr);
246}
247#endif
248
249int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
250 void *valp, size_t val_len)
251{
252 struct regmap_range *range;
253 void *ptr;
254
255 if (range_num >= map->range_count) {
256 debug("%s: range index %d larger than range count\n",
257 __func__, range_num);
258 return -ERANGE;
259 }
260 range = &map->ranges[range_num];
261
262 ptr = map_physmem(range->start + offset, val_len, MAP_NOCACHE);
263
264 if (offset + val_len > range->size) {
265 debug("%s: offset/size combination invalid\n", __func__);
266 return -ERANGE;
267 }
268
269 switch (val_len) {
270 case REGMAP_SIZE_8:
271 *((u8 *)valp) = __read_8(ptr, map->endianness);
272 break;
273 case REGMAP_SIZE_16:
274 *((u16 *)valp) = __read_16(ptr, map->endianness);
275 break;
276 case REGMAP_SIZE_32:
277 *((u32 *)valp) = __read_32(ptr, map->endianness);
278 break;
279#if defined(in_le64) && defined(in_be64) && defined(readq)
280 case REGMAP_SIZE_64:
281 *((u64 *)valp) = __read_64(ptr, map->endianness);
282 break;
283#endif
284 default:
285 debug("%s: regmap size %zu unknown\n", __func__, val_len);
286 return -EINVAL;
287 }
123 288
124 return 0; 289 return 0;
125} 290}
126 291
127int regmap_write(struct regmap *map, uint offset, uint val) 292int regmap_raw_read(struct regmap *map, uint offset, void *valp, size_t val_len)
128{ 293{
129 u32 *ptr = map_physmem(map->ranges[0].start + offset, 4, MAP_NOCACHE); 294 return regmap_raw_read_range(map, 0, offset, valp, val_len);
295}
130 296
131 writel(cpu_to_le32(val), ptr); 297int regmap_read(struct regmap *map, uint offset, uint *valp)
298{
299 return regmap_raw_read(map, offset, valp, REGMAP_SIZE_32);
300}
301
302static inline void __write_8(u8 *addr, const u8 *val,
303 enum regmap_endianness_t endianness)
304{
305 writeb(*val, addr);
306}
307
308static inline void __write_16(u16 *addr, const u16 *val,
309 enum regmap_endianness_t endianness)
310{
311 switch (endianness) {
312 case REGMAP_NATIVE_ENDIAN:
313 writew(*val, addr);
314 break;
315 case REGMAP_LITTLE_ENDIAN:
316 out_le16(addr, *val);
317 break;
318 case REGMAP_BIG_ENDIAN:
319 out_be16(addr, *val);
320 break;
321 }
322}
323
324static inline void __write_32(u32 *addr, const u32 *val,
325 enum regmap_endianness_t endianness)
326{
327 switch (endianness) {
328 case REGMAP_NATIVE_ENDIAN:
329 writel(*val, addr);
330 break;
331 case REGMAP_LITTLE_ENDIAN:
332 out_le32(addr, *val);
333 break;
334 case REGMAP_BIG_ENDIAN:
335 out_be32(addr, *val);
336 break;
337 }
338}
339
340#if defined(out_le64) && defined(out_be64) && defined(writeq)
341static inline void __write_64(u64 *addr, const u64 *val,
342 enum regmap_endianness_t endianness)
343{
344 switch (endianness) {
345 case REGMAP_NATIVE_ENDIAN:
346 writeq(*val, addr);
347 break;
348 case REGMAP_LITTLE_ENDIAN:
349 out_le64(addr, *val);
350 break;
351 case REGMAP_BIG_ENDIAN:
352 out_be64(addr, *val);
353 break;
354 }
355}
356#endif
357
358int regmap_raw_write_range(struct regmap *map, uint range_num, uint offset,
359 const void *val, size_t val_len)
360{
361 struct regmap_range *range;
362 void *ptr;
363
364 if (range_num >= map->range_count) {
365 debug("%s: range index %d larger than range count\n",
366 __func__, range_num);
367 return -ERANGE;
368 }
369 range = &map->ranges[range_num];
370
371 ptr = map_physmem(range->start + offset, val_len, MAP_NOCACHE);
372
373 if (offset + val_len > range->size) {
374 debug("%s: offset/size combination invalid\n", __func__);
375 return -ERANGE;
376 }
377
378 switch (val_len) {
379 case REGMAP_SIZE_8:
380 __write_8(ptr, val, map->endianness);
381 break;
382 case REGMAP_SIZE_16:
383 __write_16(ptr, val, map->endianness);
384 break;
385 case REGMAP_SIZE_32:
386 __write_32(ptr, val, map->endianness);
387 break;
388#if defined(out_le64) && defined(out_be64) && defined(writeq)
389 case REGMAP_SIZE_64:
390 __write_64(ptr, val, map->endianness);
391 break;
392#endif
393 default:
394 debug("%s: regmap size %zu unknown\n", __func__, val_len);
395 return -EINVAL;
396 }
132 397
133 return 0; 398 return 0;
134} 399}
135 400
401int regmap_raw_write(struct regmap *map, uint offset, const void *val,
402 size_t val_len)
403{
404 return regmap_raw_write_range(map, 0, offset, val, val_len);
405}
406
407int regmap_write(struct regmap *map, uint offset, uint val)
408{
409 return regmap_raw_write(map, offset, &val, REGMAP_SIZE_32);
410}
411
136int regmap_update_bits(struct regmap *map, uint offset, uint mask, uint val) 412int regmap_update_bits(struct regmap *map, uint offset, uint mask, uint val)
137{ 413{
138 uint reg; 414 uint reg;
diff --git a/drivers/core/root.c b/drivers/core/root.c
index b54bf5bcdc..4ce55f9cc8 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -222,14 +222,22 @@ static int dm_scan_fdt_live(struct udevice *parent,
222 int ret = 0, err; 222 int ret = 0, err;
223 223
224 for (np = node_parent->child; np; np = np->sibling) { 224 for (np = node_parent->child; np; np = np->sibling) {
225 if (pre_reloc_only && 225 /* "chosen" node isn't a device itself but may contain some: */
226 !of_find_property(np, "u-boot,dm-pre-reloc", NULL)) 226 if (!strcmp(np->name, "chosen")) {
227 pr_debug("parsing subnodes of \"chosen\"\n");
228
229 err = dm_scan_fdt_live(parent, np, pre_reloc_only);
230 if (err && !ret)
231 ret = err;
227 continue; 232 continue;
233 }
234
228 if (!of_device_is_available(np)) { 235 if (!of_device_is_available(np)) {
229 pr_debug(" - ignoring disabled device\n"); 236 pr_debug(" - ignoring disabled device\n");
230 continue; 237 continue;
231 } 238 }
232 err = lists_bind_fdt(parent, np_to_ofnode(np), NULL); 239 err = lists_bind_fdt(parent, np_to_ofnode(np), NULL,
240 pre_reloc_only);
233 if (err && !ret) { 241 if (err && !ret) {
234 ret = err; 242 ret = err;
235 debug("%s: ret=%d\n", np->name, ret); 243 debug("%s: ret=%d\n", np->name, ret);
@@ -282,14 +290,12 @@ static int dm_scan_fdt_node(struct udevice *parent, const void *blob,
282 continue; 290 continue;
283 } 291 }
284 292
285 if (pre_reloc_only &&
286 !dm_fdt_pre_reloc(blob, offset))
287 continue;
288 if (!fdtdec_get_is_enabled(blob, offset)) { 293 if (!fdtdec_get_is_enabled(blob, offset)) {
289 pr_debug(" - ignoring disabled device\n"); 294 pr_debug(" - ignoring disabled device\n");
290 continue; 295 continue;
291 } 296 }
292 err = lists_bind_fdt(parent, offset_to_ofnode(offset), NULL); 297 err = lists_bind_fdt(parent, offset_to_ofnode(offset), NULL,
298 pre_reloc_only);
293 if (err && !ret) { 299 if (err && !ret) {
294 ret = err; 300 ret = err;
295 debug("%s: ret=%d\n", node_name, ret); 301 debug("%s: ret=%d\n", node_name, ret);
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 3113d6a56b..6cfcde8918 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -180,7 +180,7 @@ int dev_get_uclass_index(struct udevice *dev, struct uclass **ucp)
180 if (list_empty(&uc->dev_head)) 180 if (list_empty(&uc->dev_head))
181 return -ENODEV; 181 return -ENODEV;
182 182
183 list_for_each_entry(iter, &uc->dev_head, uclass_node) { 183 uclass_foreach_dev(iter, uc) {
184 if (iter == dev) { 184 if (iter == dev) {
185 if (ucp) 185 if (ucp)
186 *ucp = uc; 186 *ucp = uc;
@@ -205,7 +205,7 @@ int uclass_find_device(enum uclass_id id, int index, struct udevice **devp)
205 if (list_empty(&uc->dev_head)) 205 if (list_empty(&uc->dev_head))
206 return -ENODEV; 206 return -ENODEV;
207 207
208 list_for_each_entry(dev, &uc->dev_head, uclass_node) { 208 uclass_foreach_dev(dev, uc) {
209 if (!index--) { 209 if (!index--) {
210 *devp = dev; 210 *devp = dev;
211 return 0; 211 return 0;
@@ -259,7 +259,7 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name,
259 if (ret) 259 if (ret)
260 return ret; 260 return ret;
261 261
262 list_for_each_entry(dev, &uc->dev_head, uclass_node) { 262 uclass_foreach_dev(dev, uc) {
263 if (!strncmp(dev->name, name, strlen(name))) { 263 if (!strncmp(dev->name, name, strlen(name))) {
264 *devp = dev; 264 *devp = dev;
265 return 0; 265 return 0;
@@ -284,7 +284,7 @@ int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
284 if (ret) 284 if (ret)
285 return ret; 285 return ret;
286 286
287 list_for_each_entry(dev, &uc->dev_head, uclass_node) { 287 uclass_foreach_dev(dev, uc) {
288 debug(" - %d %d '%s'\n", dev->req_seq, dev->seq, dev->name); 288 debug(" - %d %d '%s'\n", dev->req_seq, dev->seq, dev->name);
289 if ((find_req_seq ? dev->req_seq : dev->seq) == 289 if ((find_req_seq ? dev->req_seq : dev->seq) ==
290 seq_or_req_seq) { 290 seq_or_req_seq) {
@@ -312,7 +312,7 @@ int uclass_find_device_by_of_offset(enum uclass_id id, int node,
312 if (ret) 312 if (ret)
313 return ret; 313 return ret;
314 314
315 list_for_each_entry(dev, &uc->dev_head, uclass_node) { 315 uclass_foreach_dev(dev, uc) {
316 if (dev_of_offset(dev) == node) { 316 if (dev_of_offset(dev) == node) {
317 *devp = dev; 317 *devp = dev;
318 return 0; 318 return 0;
@@ -337,7 +337,7 @@ int uclass_find_device_by_ofnode(enum uclass_id id, ofnode node,
337 if (ret) 337 if (ret)
338 return ret; 338 return ret;
339 339
340 list_for_each_entry(dev, &uc->dev_head, uclass_node) { 340 uclass_foreach_dev(dev, uc) {
341 log(LOGC_DM, LOGL_DEBUG_CONTENT, " - checking %s\n", 341 log(LOGC_DM, LOGL_DEBUG_CONTENT, " - checking %s\n",
342 dev->name); 342 dev->name);
343 if (ofnode_equal(dev_ofnode(dev), node)) { 343 if (ofnode_equal(dev_ofnode(dev), node)) {
@@ -372,7 +372,7 @@ static int uclass_find_device_by_phandle(enum uclass_id id,
372 if (ret) 372 if (ret)
373 return ret; 373 return ret;
374 374
375 list_for_each_entry(dev, &uc->dev_head, uclass_node) { 375 uclass_foreach_dev(dev, uc) {
376 uint phandle; 376 uint phandle;
377 377
378 phandle = dev_read_phandle(dev); 378 phandle = dev_read_phandle(dev);
@@ -399,7 +399,7 @@ int uclass_get_device_by_driver(enum uclass_id id,
399 if (ret) 399 if (ret)
400 return ret; 400 return ret;
401 401
402 list_for_each_entry(dev, &uc->dev_head, uclass_node) { 402 uclass_foreach_dev(dev, uc) {
403 if (dev->driver == find_drv) 403 if (dev->driver == find_drv)
404 return uclass_get_device_tail(dev, 0, devp); 404 return uclass_get_device_tail(dev, 0, devp);
405 } 405 }
@@ -499,7 +499,7 @@ int uclass_get_device_by_phandle_id(enum uclass_id id, uint phandle_id,
499 if (ret) 499 if (ret)
500 return ret; 500 return ret;
501 501
502 list_for_each_entry(dev, &uc->dev_head, uclass_node) { 502 uclass_foreach_dev(dev, uc) {
503 uint phandle; 503 uint phandle;
504 504
505 phandle = dev_read_phandle(dev); 505 phandle = dev_read_phandle(dev);
@@ -687,8 +687,19 @@ int uclass_pre_probe_device(struct udevice *dev)
687 687
688int uclass_post_probe_device(struct udevice *dev) 688int uclass_post_probe_device(struct udevice *dev)
689{ 689{
690 struct uclass_driver *uc_drv = dev->uclass->uc_drv; 690 struct uclass_driver *uc_drv;
691 int ret;
692
693 if (dev->parent) {
694 uc_drv = dev->parent->uclass->uc_drv;
695 if (uc_drv->child_post_probe) {
696 ret = uc_drv->child_post_probe(dev);
697 if (ret)
698 return ret;
699 }
700 }
691 701
702 uc_drv = dev->uclass->uc_drv;
692 if (uc_drv->post_probe) 703 if (uc_drv->post_probe)
693 return uc_drv->post_probe(dev); 704 return uc_drv->post_probe(dev);
694 705
diff --git a/drivers/core/util.c b/drivers/core/util.c
index 451d4766d0..27a6848703 100644
--- a/drivers/core/util.c
+++ b/drivers/core/util.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include <common.h> 6#include <common.h>
7#include <dm/ofnode.h>
7#include <dm/util.h> 8#include <dm/util.h>
8#include <linux/libfdt.h> 9#include <linux/libfdt.h>
9#include <vsprintf.h> 10#include <vsprintf.h>
@@ -53,3 +54,27 @@ bool dm_fdt_pre_reloc(const void *blob, int offset)
53 54
54 return false; 55 return false;
55} 56}
57
58bool dm_ofnode_pre_reloc(ofnode node)
59{
60 if (ofnode_read_bool(node, "u-boot,dm-pre-reloc"))
61 return true;
62
63#ifdef CONFIG_TPL_BUILD
64 if (ofnode_read_bool(node, "u-boot,dm-tpl"))
65 return true;
66#elif defined(CONFIG_SPL_BUILD)
67 if (ofnode_read_bool(node, "u-boot,dm-spl"))
68 return true;
69#else
70 /*
71 * In regular builds individual spl and tpl handling both
72 * count as handled pre-relocation for later second init.
73 */
74 if (ofnode_read_bool(node, "u-boot,dm-spl") ||
75 ofnode_read_bool(node, "u-boot,dm-tpl"))
76 return true;
77#endif
78
79 return false;
80}
diff --git a/drivers/cpu/mpc83xx_cpu.c b/drivers/cpu/mpc83xx_cpu.c
index 31717afaec..7bc86bf9b2 100644
--- a/drivers/cpu/mpc83xx_cpu.c
+++ b/drivers/cpu/mpc83xx_cpu.c
@@ -262,7 +262,7 @@ static int mpc83xx_cpu_get_desc(struct udevice *dev, char *buf, int size)
262 determine_cpu_data(dev); 262 determine_cpu_data(dev);
263 263
264 snprintf(buf, size, 264 snprintf(buf, size,
265 "CPU: %s, MPC%s%s%s, Rev: %d.%d at %s MHz, CSB: %s MHz\n", 265 "%s, MPC%s%s%s, Rev: %d.%d at %s MHz, CSB: %s MHz",
266 e300_names[priv->e300_type], 266 e300_names[priv->e300_type],
267 cpu_type_names[priv->type], 267 cpu_type_names[priv->type],
268 priv->is_e_processor ? "E" : "", 268 priv->is_e_processor ? "E" : "",
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index 555eba2662..0031415d03 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -372,7 +372,9 @@ U_BOOT_DRIVER(gpio_omap) = {
372 .ops = &gpio_omap_ops, 372 .ops = &gpio_omap_ops,
373 .probe = omap_gpio_probe, 373 .probe = omap_gpio_probe,
374 .priv_auto_alloc_size = sizeof(struct gpio_bank), 374 .priv_auto_alloc_size = sizeof(struct gpio_bank),
375#if !CONFIG_IS_ENABLED(OF_CONTROL)
375 .flags = DM_FLAG_PRE_RELOC, 376 .flags = DM_FLAG_PRE_RELOC,
377#endif
376}; 378};
377 379
378#endif /* CONFIG_DM_GPIO */ 380#endif /* CONFIG_DM_GPIO */
diff --git a/drivers/gpio/stm32f7_gpio.c b/drivers/gpio/stm32f7_gpio.c
index 4c0786fff8..b903dc46b3 100644
--- a/drivers/gpio/stm32f7_gpio.c
+++ b/drivers/gpio/stm32f7_gpio.c
@@ -123,6 +123,6 @@ U_BOOT_DRIVER(gpio_stm32) = {
123 .of_match = stm32_gpio_ids, 123 .of_match = stm32_gpio_ids,
124 .probe = gpio_stm32_probe, 124 .probe = gpio_stm32_probe,
125 .ops = &gpio_stm32_ops, 125 .ops = &gpio_stm32_ops,
126 .flags = DM_FLAG_PRE_RELOC | DM_UC_FLAG_SEQ_ALIAS, 126 .flags = DM_UC_FLAG_SEQ_ALIAS,
127 .priv_auto_alloc_size = sizeof(struct stm32_gpio_priv), 127 .priv_auto_alloc_size = sizeof(struct stm32_gpio_priv),
128}; 128};
diff --git a/drivers/gpio/tegra186_gpio.c b/drivers/gpio/tegra186_gpio.c
index 1f0e8d51da..6626b5415a 100644
--- a/drivers/gpio/tegra186_gpio.c
+++ b/drivers/gpio/tegra186_gpio.c
@@ -281,5 +281,4 @@ U_BOOT_DRIVER(tegra186_gpio) = {
281 .bind = tegra186_gpio_bind, 281 .bind = tegra186_gpio_bind,
282 .probe = tegra186_gpio_probe, 282 .probe = tegra186_gpio_probe,
283 .ops = &tegra186_gpio_ops, 283 .ops = &tegra186_gpio_ops,
284 .flags = DM_FLAG_PRE_RELOC,
285}; 284};
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index 302efddc27..a730f5c4fe 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -378,5 +378,4 @@ U_BOOT_DRIVER(gpio_tegra) = {
378 .probe = gpio_tegra_probe, 378 .probe = gpio_tegra_probe,
379 .priv_auto_alloc_size = sizeof(struct tegra_port_info), 379 .priv_auto_alloc_size = sizeof(struct tegra_port_info),
380 .ops = &gpio_tegra_ops, 380 .ops = &gpio_tegra_ops,
381 .flags = DM_FLAG_PRE_RELOC,
382}; 381};
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 54bf35e552..51f923752c 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -925,7 +925,9 @@ U_BOOT_DRIVER(i2c_omap) = {
925 .probe = omap_i2c_probe, 925 .probe = omap_i2c_probe,
926 .priv_auto_alloc_size = sizeof(struct omap_i2c), 926 .priv_auto_alloc_size = sizeof(struct omap_i2c),
927 .ops = &omap_i2c_ops, 927 .ops = &omap_i2c_ops,
928#if !CONFIG_IS_ENABLED(OF_CONTROL)
928 .flags = DM_FLAG_PRE_RELOC, 929 .flags = DM_FLAG_PRE_RELOC,
930#endif
929}; 931};
930 932
931#endif /* CONFIG_DM_I2C */ 933#endif /* CONFIG_DM_I2C */
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index c5697011f2..48febc47d2 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -312,4 +312,21 @@ config FS_LOADER
312 The consumer driver would then use this loader to program whatever, 312 The consumer driver would then use this loader to program whatever,
313 ie. the FPGA device. 313 ie. the FPGA device.
314 314
315config GDSYS_SOC
316 bool "Enable gdsys SOC driver"
317 depends on MISC
318 help
319 Support for gdsys IHS SOC, a simple bus associated with each gdsys
320 IHS (Integrated Hardware Systems) FPGA, which holds all devices whose
321 register maps are contained within the FPGA's register map.
322
323config IHS_FPGA
324 bool "Enable IHS FPGA driver"
325 depends on MISC
326 help
327 Support IHS (Integrated Hardware Systems) FPGA, the main FPGAs on
328 gdsys devices, which supply the majority of the functionality offered
329 by the devices. This driver supports both CON and CPU variants of the
330 devices, depending on the device tree entry.
331
315endmenu 332endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 759d2c791b..302d441592 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -4,11 +4,6 @@
4# Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 5
6obj-$(CONFIG_MISC) += misc-uclass.o 6obj-$(CONFIG_MISC) += misc-uclass.o
7obj-$(CONFIG_ALI152X) += ali512x.o
8obj-$(CONFIG_ALTERA_SYSID) += altera_sysid.o
9obj-$(CONFIG_ATSHA204A) += atsha204a-i2c.o
10obj-$(CONFIG_DS4510) += ds4510.o
11obj-$(CONFIG_CBMEM_CONSOLE) += cbmem_console.o
12ifndef CONFIG_SPL_BUILD 7ifndef CONFIG_SPL_BUILD
13obj-$(CONFIG_CROS_EC) += cros_ec.o 8obj-$(CONFIG_CROS_EC) += cros_ec.o
14obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o 9obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o
@@ -16,46 +11,54 @@ obj-$(CONFIG_CROS_EC_I2C) += cros_ec_i2c.o
16obj-$(CONFIG_CROS_EC_SANDBOX) += cros_ec_sandbox.o 11obj-$(CONFIG_CROS_EC_SANDBOX) += cros_ec_sandbox.o
17obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o 12obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o
18endif 13endif
19obj-$(CONFIG_FSL_IIM) += fsl_iim.o 14
20obj-$(CONFIG_LED_STATUS_GPIO) += gpio_led.o
21obj-$(CONFIG_$(SPL_)I2C_EEPROM) += i2c_eeprom.o
22obj-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o
23obj-$(CONFIG_IMX8) += imx8/
24obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o
25obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
26obj-$(CONFIG_NUVOTON_NCT6102D) += nuvoton_nct6102d.o
27obj-$(CONFIG_NS87308) += ns87308.o
28obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
29ifdef CONFIG_DM_I2C 15ifdef CONFIG_DM_I2C
30ifndef CONFIG_SPL_BUILD 16ifndef CONFIG_SPL_BUILD
31obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o 17obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o
32endif 18endif
33endif 19endif
34obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
35obj-$(CONFIG_SMSC_SIO1007) += smsc_sio1007.o
36obj-$(CONFIG_LED_STATUS) += status_led.o
37obj-$(CONFIG_SANDBOX) += swap_case.o
38ifdef CONFIG_SPL_OF_PLATDATA 20ifdef CONFIG_SPL_OF_PLATDATA
39ifdef CONFIG_SPL_BUILD 21ifdef CONFIG_SPL_BUILD
40obj-$(CONFIG_SANDBOX) += spltest_sandbox.o 22obj-$(CONFIG_SANDBOX) += spltest_sandbox.o
41endif 23endif
42endif 24endif
43obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o 25obj-$(CONFIG_ALI152X) += ali512x.o
44obj-$(CONFIG_TEGRA_CAR) += tegra_car.o 26obj-$(CONFIG_ALTERA_SYSID) += altera_sysid.o
45obj-$(CONFIG_TEGRA186_BPMP) += tegra186_bpmp.o 27obj-$(CONFIG_ATSHA204A) += atsha204a-i2c.o
46obj-$(CONFIG_TWL4030_LED) += twl4030_led.o 28obj-$(CONFIG_CBMEM_CONSOLE) += cbmem_console.o
29obj-$(CONFIG_DS4510) += ds4510.o
30obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o
47obj-$(CONFIG_FSL_IFC) += fsl_ifc.o 31obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
32obj-$(CONFIG_FSL_IIM) += fsl_iim.o
33obj-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o
48obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o 34obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o
35obj-$(CONFIG_FS_LOADER) += fs_loader.o
36obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o
37obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o
38obj-$(CONFIG_GDSYS_SOC) += gdsys_soc.o
39obj-$(CONFIG_$(SPL_)I2C_EEPROM) += i2c_eeprom.o
40obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o
41obj-$(CONFIG_IMX8) += imx8/
42obj-$(CONFIG_LED_STATUS) += status_led.o
43obj-$(CONFIG_LED_STATUS_GPIO) += gpio_led.o
44obj-$(CONFIG_MPC83XX_SERDES) += mpc83xx_serdes.o
45obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o
46obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
47obj-$(CONFIG_NS87308) += ns87308.o
48obj-$(CONFIG_NUVOTON_NCT6102D) += nuvoton_nct6102d.o
49obj-$(CONFIG_PCA9551_LED) += pca9551_led.o 49obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
50obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o 50obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
51obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
52obj-$(CONFIG_QFW) += qfw.o 51obj-$(CONFIG_QFW) += qfw.o
53obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o 52obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
54obj-$(CONFIG_STM32_RCC) += stm32_rcc.o 53obj-$(CONFIG_SANDBOX) += swap_case.o
54obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o
55obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
56obj-$(CONFIG_SMSC_SIO1007) += smsc_sio1007.o
55obj-$(CONFIG_STM32MP_FUSE) += stm32mp_fuse.o 57obj-$(CONFIG_STM32MP_FUSE) += stm32mp_fuse.o
58obj-$(CONFIG_STM32_RCC) += stm32_rcc.o
56obj-$(CONFIG_SYS_DPAA_QBMAN) += fsl_portals.o 59obj-$(CONFIG_SYS_DPAA_QBMAN) += fsl_portals.o
57obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o 60obj-$(CONFIG_TEGRA186_BPMP) += tegra186_bpmp.o
58obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o 61obj-$(CONFIG_TEGRA_CAR) += tegra_car.o
62obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
59obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress_config.o 63obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress_config.o
60obj-$(CONFIG_MPC83XX_SERDES) += mpc83xx_serdes.o 64obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
61obj-$(CONFIG_FS_LOADER) += fs_loader.o
diff --git a/drivers/misc/gdsys_soc.c b/drivers/misc/gdsys_soc.c
new file mode 100644
index 0000000000..94a21e08af
--- /dev/null
+++ b/drivers/misc/gdsys_soc.c
@@ -0,0 +1,74 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2017
4 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
5 */
6
7#include <common.h>
8#include <dm.h>
9#include <dm/lists.h>
10
11#include "gdsys_soc.h"
12
13/**
14 * struct gdsys_soc_priv - Private data for gdsys soc bus
15 * @fpga: The gdsys IHS FPGA this bus is associated with
16 */
17struct gdsys_soc_priv {
18 struct udevice *fpga;
19};
20
21static const struct udevice_id gdsys_soc_ids[] = {
22 { .compatible = "gdsys,soc" },
23 { /* sentinel */ }
24};
25
26int gdsys_soc_get_fpga(struct udevice *child, struct udevice **fpga)
27{
28 struct gdsys_soc_priv *bus_priv;
29
30 if (!child->parent) {
31 debug("%s: Invalid parent\n", child->name);
32 return -EINVAL;
33 }
34
35 if (!device_is_compatible(child->parent, "gdsys,soc")) {
36 debug("%s: Not child of a gdsys soc\n", child->name);
37 return -EINVAL;
38 }
39
40 bus_priv = dev_get_priv(child->parent);
41
42 *fpga = bus_priv->fpga;
43
44 return 0;
45}
46
47static int gdsys_soc_probe(struct udevice *dev)
48{
49 struct gdsys_soc_priv *priv = dev_get_priv(dev);
50 struct udevice *fpga;
51 int res = uclass_get_device_by_phandle(UCLASS_MISC, dev, "fpga",
52 &fpga);
53 if (res == -ENOENT) {
54 debug("%s: Could not find 'fpga' phandle\n", dev->name);
55 return -EINVAL;
56 }
57
58 if (res == -ENODEV) {
59 debug("%s: Could not get FPGA device\n", dev->name);
60 return -EINVAL;
61 }
62
63 priv->fpga = fpga;
64
65 return 0;
66}
67
68U_BOOT_DRIVER(gdsys_soc_bus) = {
69 .name = "gdsys_soc_bus",
70 .id = UCLASS_SIMPLE_BUS,
71 .of_match = gdsys_soc_ids,
72 .probe = gdsys_soc_probe,
73 .priv_auto_alloc_size = sizeof(struct gdsys_soc_priv),
74};
diff --git a/drivers/misc/gdsys_soc.h b/drivers/misc/gdsys_soc.h
new file mode 100644
index 0000000000..088d3b6523
--- /dev/null
+++ b/drivers/misc/gdsys_soc.h
@@ -0,0 +1,23 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * (C) Copyright 2017
4 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
5 */
6
7#ifndef _GDSYS_SOC_H_
8#define _GDSYS_SOC_H_
9
10/**
11 * gdsys_soc_get_fpga() - Retrieve pointer to parent bus' FPGA device
12 * @child: The child device on the FPGA bus needing access to the FPGA.
13 * @fpga: Pointer to the retrieved FPGA device.
14 *
15 * To access their register maps, devices on gdsys soc buses usually have
16 * facilitate the accessor function of the IHS FPGA their parent bus is
17 * attached to. To access the FPGA device from within the bus' children, this
18 * function returns a pointer to it.
19 *
20 * Return: 0 on success, -ve on failure
21 */
22int gdsys_soc_get_fpga(struct udevice *child, struct udevice **fpga);
23#endif /* _GDSYS_SOC_H_ */
diff --git a/drivers/misc/ihs_fpga.c b/drivers/misc/ihs_fpga.c
new file mode 100644
index 0000000000..f9e4b27a27
--- /dev/null
+++ b/drivers/misc/ihs_fpga.c
@@ -0,0 +1,867 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2017
4 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
5 *
6 * based on the ioep-fpga driver, which is
7 *
8 * (C) Copyright 2014
9 * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
10 */
11
12#include <common.h>
13#include <dm.h>
14#include <regmap.h>
15#include <asm/gpio.h>
16
17#include "ihs_fpga.h"
18
19/**
20 * struct ihs_fpga_priv - Private data structure for IHS FPGA driver
21 * @map: Register map for the FPGA's own register space
22 * @reset_gpio: GPIO to start FPGA reconfiguration
23 * @done_gpio: GPOI to read the 'ready' status of the FPGA
24 */
25struct ihs_fpga_priv {
26 struct regmap *map;
27 struct gpio_desc reset_gpio;
28 struct gpio_desc done_gpio;
29};
30
31/* Test pattern for reflection test */
32const u16 REFLECTION_TESTPATTERN = 0xdead;
33/* Delay (in ms) for each round in the reflection test */
34const uint REFLECTION_TEST_DELAY = 100;
35/* Maximum number of rounds in the reflection test */
36const uint REFLECTION_TEST_ROUNDS = 5;
37/* Delay (in ms) for each round waiting for the FPGA's done GPIO */
38const uint FPGA_DONE_WAIT_DELAY = 100;
39/* Maximum number of rounds for waiting for the FPGA's done GPIO */
40const uint FPGA_DONE_WAIT_ROUND = 5;
41
42/**
43 * enum pcb_video_type - Video type of the PCB
44 * @PCB_DVI_SL: Video type is DVI single-link
45 * @PCB_DP_165MPIX: Video type is DisplayPort (165Mpix)
46 * @PCB_DP_300MPIX: Video type is DisplayPort (300Mpix)
47 * @PCB_HDMI: Video type is HDMI
48 * @PCB_DP_1_2: Video type is DisplayPort 1.2
49 * @PCB_HDMI_2_0: Video type is HDMI 2.0
50 */
51enum pcb_video_type {
52 PCB_DVI_SL,
53 PCB_DP_165MPIX,
54 PCB_DP_300MPIX,
55 PCB_HDMI,
56 PCB_DP_1_2,
57 PCB_HDMI_2_0,
58};
59
60/**
61 * enum pcb_transmission_type - Transmission type of the PCB
62 * @PCB_CAT_1G: Transmission type is 1G Ethernet
63 * @PCB_FIBER_3G: Transmission type is 3G Fiber
64 * @PCB_CAT_10G: Transmission type is 10G Ethernet
65 * @PCB_FIBER_10G: Transmission type is 10G Fiber
66 */
67enum pcb_transmission_type {
68 PCB_CAT_1G,
69 PCB_FIBER_3G,
70 PCB_CAT_10G,
71 PCB_FIBER_10G,
72};
73
74/**
75 * enum carrier_speed - Speed of the FPGA's carrier
76 * @CARRIER_SPEED_1G: The carrier speed is 1G
77 * @CARRIER_SPEED_2_5G: The carrier speed is 2.5G
78 * @CARRIER_SPEED_3G: The carrier speed is 3G
79 * @CARRIER_SPEED_10G: The carrier speed is 10G
80 */
81enum carrier_speed {
82 CARRIER_SPEED_1G,
83 CARRIER_SPEED_3G,
84 CARRIER_SPEED_2_5G = CARRIER_SPEED_3G,
85 CARRIER_SPEED_10G,
86};
87
88/**
89 * enum ram_config - FPGA's RAM configuration
90 * @RAM_DDR2_32BIT_295MBPS: DDR2 32 bit at 295Mb/s
91 * @RAM_DDR3_32BIT_590MBPS: DDR3 32 bit at 590Mb/s
92 * @RAM_DDR3_48BIT_590MBPS: DDR3 48 bit at 590Mb/s
93 * @RAM_DDR3_64BIT_1800MBPS: DDR3 64 bit at 1800Mb/s
94 * @RAM_DDR3_48BIT_1800MBPS: DDR3 48 bit at 1800Mb/s
95 */
96enum ram_config {
97 RAM_DDR2_32BIT_295MBPS,
98 RAM_DDR3_32BIT_590MBPS,
99 RAM_DDR3_48BIT_590MBPS,
100 RAM_DDR3_64BIT_1800MBPS,
101 RAM_DDR3_48BIT_1800MBPS,
102};
103
104/**
105 * enum sysclock - Speed of the FPGA's system clock
106 * @SYSCLK_147456: System clock is 147.456 MHz
107 */
108enum sysclock {
109 SYSCLK_147456,
110};
111
112/**
113 * struct fpga_versions - Data read from the versions register
114 * @video_channel: Is the FPGA for a video channel (true) or main
115 * channel (false) device?
116 * @con_side: Is the FPGA for a CON (true) or a CPU (false) device?
117 * @pcb_video_type: Defines for whch video type the FPGA is configured
118 * @pcb_transmission_type: Defines for which transmission type the FPGA is
119 * configured
120 * @hw_version: Hardware version of the FPGA
121 */
122struct fpga_versions {
123 bool video_channel;
124 bool con_side;
125 enum pcb_video_type pcb_video_type;
126 enum pcb_transmission_type pcb_transmission_type;
127 unsigned int hw_version;
128};
129
130/**
131 * struct fpga_features - Data read from the features register
132 * @video_channels: Number of video channels supported
133 * @carriers: Number of carrier channels supported
134 * @carrier_speed: Speed of carriers
135 * @ram_config: RAM configuration of FPGA
136 * @sysclock: System clock speed of FPGA
137 * @pcm_tx: Support for PCM transmission
138 * @pcm_rx: Support for PCM reception
139 * @spdif_tx: Support for SPDIF audio transmission
140 * @spdif_rx: Support for SPDIF audio reception
141 * @usb2: Support for transparent USB2.0
142 * @rs232: Support for bidirectional RS232
143 * @compression_type1: Support for compression type 1
144 * @compression_type2: Support for compression type 2
145 * @compression_type3: Support for compression type 3
146 * @interlace: Support for interlace image formats
147 * @osd: Support for a OSD
148 * @compression_pipes: Number of compression pipes supported
149 */
150struct fpga_features {
151 u8 video_channels;
152 u8 carriers;
153 enum carrier_speed carrier_speed;
154 enum ram_config ram_config;
155 enum sysclock sysclock;
156 bool pcm_tx;
157 bool pcm_rx;
158 bool spdif_tx;
159 bool spdif_rx;
160 bool usb2;
161 bool rs232;
162 bool compression_type1;
163 bool compression_type2;
164 bool compression_type3;
165 bool interlace;
166 bool osd;
167 bool compression_pipes;
168};
169
170#ifdef CONFIG_SYS_FPGA_FLAVOR_GAZERBEAM
171
172/**
173 * get_versions() - Fill structure with info from version register.
174 * @dev: FPGA device to be queried for information
175 * @versions: Pointer to the structure to fill with information from the
176 * versions register
177 * Return: 0
178 */
179static int get_versions(struct udevice *dev, struct fpga_versions *versions)
180{
181 struct ihs_fpga_priv *priv = dev_get_priv(dev);
182 enum {
183 VERSIONS_FPGA_VIDEO_CHANNEL = BIT(12),
184 VERSIONS_FPGA_CON_SIDE = BIT(13),
185 VERSIONS_FPGA_SC = BIT(14),
186 VERSIONS_PCB_CON = BIT(9),
187 VERSIONS_PCB_SC = BIT(8),
188 VERSIONS_PCB_VIDEO_MASK = 0x3 << 6,
189 VERSIONS_PCB_VIDEO_DP_1_2 = 0x0 << 6,
190 VERSIONS_PCB_VIDEO_HDMI_2_0 = 0x1 << 6,
191 VERSIONS_PCB_TRANSMISSION_MASK = 0x3 << 4,
192 VERSIONS_PCB_TRANSMISSION_FIBER_10G = 0x0 << 4,
193 VERSIONS_PCB_TRANSMISSION_CAT_10G = 0x1 << 4,
194 VERSIONS_PCB_TRANSMISSION_FIBER_3G = 0x2 << 4,
195 VERSIONS_PCB_TRANSMISSION_CAT_1G = 0x3 << 4,
196 VERSIONS_HW_VER_MASK = 0xf << 0,
197 };
198 u16 raw_versions;
199
200 memset(versions, 0, sizeof(struct fpga_versions));
201
202 ihs_fpga_get(priv->map, versions, &raw_versions);
203
204 versions->video_channel = raw_versions & VERSIONS_FPGA_VIDEO_CHANNEL;
205 versions->con_side = raw_versions & VERSIONS_FPGA_CON_SIDE;
206
207 switch (raw_versions & VERSIONS_PCB_VIDEO_MASK) {
208 case VERSIONS_PCB_VIDEO_DP_1_2:
209 versions->pcb_video_type = PCB_DP_1_2;
210 break;
211
212 case VERSIONS_PCB_VIDEO_HDMI_2_0:
213 versions->pcb_video_type = PCB_HDMI_2_0;
214 break;
215 }
216
217 switch (raw_versions & VERSIONS_PCB_TRANSMISSION_MASK) {
218 case VERSIONS_PCB_TRANSMISSION_FIBER_10G:
219 versions->pcb_transmission_type = PCB_FIBER_10G;
220 break;
221
222 case VERSIONS_PCB_TRANSMISSION_CAT_10G:
223 versions->pcb_transmission_type = PCB_CAT_10G;
224 break;
225
226 case VERSIONS_PCB_TRANSMISSION_FIBER_3G:
227 versions->pcb_transmission_type = PCB_FIBER_3G;
228 break;
229
230 case VERSIONS_PCB_TRANSMISSION_CAT_1G:
231 versions->pcb_transmission_type = PCB_CAT_1G;
232 break;
233 }
234
235 versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
236
237 return 0;
238}
239
240/**
241 * get_features() - Fill structure with info from features register.
242 * @dev: FPGA device to be queried for information
243 * @features: Pointer to the structure to fill with information from the
244 * features register
245 * Return: 0
246 */
247static int get_features(struct udevice *dev, struct fpga_features *features)
248{
249 struct ihs_fpga_priv *priv = dev_get_priv(dev);
250 enum {
251 FEATURE_SPDIF_RX = BIT(15),
252 FEATURE_SPDIF_TX = BIT(14),
253 FEATURE_PCM_RX = BIT(13),
254 FEATURE_PCM_TX = BIT(12),
255 FEATURE_RAM_MASK = GENMASK(11, 8),
256 FEATURE_RAM_DDR2_32BIT_295MBPS = 0x0 << 8,
257 FEATURE_RAM_DDR3_32BIT_590MBPS = 0x1 << 8,
258 FEATURE_RAM_DDR3_48BIT_590MBPS = 0x2 << 8,
259 FEATURE_RAM_DDR3_64BIT_1800MBPS = 0x3 << 8,
260 FEATURE_RAM_DDR3_48BIT_1800MBPS = 0x4 << 8,
261 FEATURE_CARRIER_SPEED_MASK = GENMASK(7, 6),
262 FEATURE_CARRIER_SPEED_1G = 0x0 << 6,
263 FEATURE_CARRIER_SPEED_2_5G = 0x1 << 6,
264 FEATURE_CARRIER_SPEED_10G = 0x2 << 6,
265 FEATURE_CARRIERS_MASK = GENMASK(5, 4),
266 FEATURE_CARRIERS_0 = 0x0 << 4,
267 FEATURE_CARRIERS_1 = 0x1 << 4,
268 FEATURE_CARRIERS_2 = 0x2 << 4,
269 FEATURE_CARRIERS_4 = 0x3 << 4,
270 FEATURE_USB2 = BIT(3),
271 FEATURE_VIDEOCHANNELS_MASK = GENMASK(2, 0),
272 FEATURE_VIDEOCHANNELS_0 = 0x0 << 0,
273 FEATURE_VIDEOCHANNELS_1 = 0x1 << 0,
274 FEATURE_VIDEOCHANNELS_1_1 = 0x2 << 0,
275 FEATURE_VIDEOCHANNELS_2 = 0x3 << 0,
276 };
277
278 enum {
279 EXT_FEATURE_OSD = BIT(15),
280 EXT_FEATURE_ETHERNET = BIT(9),
281 EXT_FEATURE_INTERLACE = BIT(8),
282 EXT_FEATURE_RS232 = BIT(7),
283 EXT_FEATURE_COMPRESSION_PERF_MASK = GENMASK(6, 4),
284 EXT_FEATURE_COMPRESSION_PERF_1X = 0x0 << 4,
285 EXT_FEATURE_COMPRESSION_PERF_2X = 0x1 << 4,
286 EXT_FEATURE_COMPRESSION_PERF_4X = 0x2 << 4,
287 EXT_FEATURE_COMPRESSION_TYPE1 = BIT(0),
288 EXT_FEATURE_COMPRESSION_TYPE2 = BIT(1),
289 EXT_FEATURE_COMPRESSION_TYPE3 = BIT(2),
290 };
291
292 u16 raw_features;
293 u16 raw_extended_features;
294
295 memset(features, 0, sizeof(struct fpga_features));
296
297 ihs_fpga_get(priv->map, features, &raw_features);
298 ihs_fpga_get(priv->map, extended_features, &raw_extended_features);
299
300 switch (raw_features & FEATURE_VIDEOCHANNELS_MASK) {
301 case FEATURE_VIDEOCHANNELS_0:
302 features->video_channels = 0;
303 break;
304
305 case FEATURE_VIDEOCHANNELS_1:
306 features->video_channels = 1;
307 break;
308
309 case FEATURE_VIDEOCHANNELS_1_1:
310 case FEATURE_VIDEOCHANNELS_2:
311 features->video_channels = 2;
312 break;
313 };
314
315 switch (raw_features & FEATURE_CARRIERS_MASK) {
316 case FEATURE_CARRIERS_0:
317 features->carriers = 0;
318 break;
319
320 case FEATURE_CARRIERS_1:
321 features->carriers = 1;
322 break;
323
324 case FEATURE_CARRIERS_2:
325 features->carriers = 2;
326 break;
327
328 case FEATURE_CARRIERS_4:
329 features->carriers = 4;
330 break;
331 }
332
333 switch (raw_features & FEATURE_CARRIER_SPEED_MASK) {
334 case FEATURE_CARRIER_SPEED_1G:
335 features->carrier_speed = CARRIER_SPEED_1G;
336 break;
337 case FEATURE_CARRIER_SPEED_2_5G:
338 features->carrier_speed = CARRIER_SPEED_2_5G;
339 break;
340 case FEATURE_CARRIER_SPEED_10G:
341 features->carrier_speed = CARRIER_SPEED_10G;
342 break;
343 }
344
345 switch (raw_features & FEATURE_RAM_MASK) {
346 case FEATURE_RAM_DDR2_32BIT_295MBPS:
347 features->ram_config = RAM_DDR2_32BIT_295MBPS;
348 break;
349
350 case FEATURE_RAM_DDR3_32BIT_590MBPS:
351 features->ram_config = RAM_DDR3_32BIT_590MBPS;
352 break;
353
354 case FEATURE_RAM_DDR3_48BIT_590MBPS:
355 features->ram_config = RAM_DDR3_48BIT_590MBPS;
356 break;
357
358 case FEATURE_RAM_DDR3_64BIT_1800MBPS:
359 features->ram_config = RAM_DDR3_64BIT_1800MBPS;
360 break;
361
362 case FEATURE_RAM_DDR3_48BIT_1800MBPS:
363 features->ram_config = RAM_DDR3_48BIT_1800MBPS;
364 break;
365 }
366
367 features->pcm_tx = raw_features & FEATURE_PCM_TX;
368 features->pcm_rx = raw_features & FEATURE_PCM_RX;
369 features->spdif_tx = raw_features & FEATURE_SPDIF_TX;
370 features->spdif_rx = raw_features & FEATURE_SPDIF_RX;
371 features->usb2 = raw_features & FEATURE_USB2;
372 features->rs232 = raw_extended_features & EXT_FEATURE_RS232;
373 features->compression_type1 = raw_extended_features &
374 EXT_FEATURE_COMPRESSION_TYPE1;
375 features->compression_type2 = raw_extended_features &
376 EXT_FEATURE_COMPRESSION_TYPE2;
377 features->compression_type3 = raw_extended_features &
378 EXT_FEATURE_COMPRESSION_TYPE3;
379 features->interlace = raw_extended_features & EXT_FEATURE_INTERLACE;
380 features->osd = raw_extended_features & EXT_FEATURE_OSD;
381 features->compression_pipes = raw_extended_features &
382 EXT_FEATURE_COMPRESSION_PERF_MASK;
383
384 return 0;
385}
386
387#else
388
389/**
390 * get_versions() - Fill structure with info from version register.
391 * @fpga: Identifier of the FPGA device to be queried for information
392 * @versions: Pointer to the structure to fill with information from the
393 * versions register
394 *
395 * This is the legacy version and should be considered deprecated for new
396 * devices.
397 *
398 * Return: 0
399 */
400static int get_versions(unsigned int fpga, struct fpga_versions *versions)
401{
402 enum {
403 /* HW version encoding is a mess, leave it for the moment */
404 VERSIONS_HW_VER_MASK = 0xf << 0,
405 VERSIONS_PIX_CLOCK_GEN_IDT8N3QV01 = BIT(4),
406 VERSIONS_SFP = BIT(5),
407 VERSIONS_VIDEO_MASK = 0x7 << 6,
408 VERSIONS_VIDEO_DVI = 0x0 << 6,
409 VERSIONS_VIDEO_DP_165 = 0x1 << 6,
410 VERSIONS_VIDEO_DP_300 = 0x2 << 6,
411 VERSIONS_VIDEO_HDMI = 0x3 << 6,
412 VERSIONS_UT_MASK = 0xf << 12,
413 VERSIONS_UT_MAIN_SERVER = 0x0 << 12,
414 VERSIONS_UT_MAIN_USER = 0x1 << 12,
415 VERSIONS_UT_VIDEO_SERVER = 0x2 << 12,
416 VERSIONS_UT_VIDEO_USER = 0x3 << 12,
417 };
418 u16 raw_versions;
419
420 memset(versions, 0, sizeof(struct fpga_versions));
421
422 FPGA_GET_REG(fpga, versions, &raw_versions);
423
424 switch (raw_versions & VERSIONS_UT_MASK) {
425 case VERSIONS_UT_MAIN_SERVER:
426 versions->video_channel = false;
427 versions->con_side = false;
428 break;
429
430 case VERSIONS_UT_MAIN_USER:
431 versions->video_channel = false;
432 versions->con_side = true;
433 break;
434
435 case VERSIONS_UT_VIDEO_SERVER:
436 versions->video_channel = true;
437 versions->con_side = false;
438 break;
439
440 case VERSIONS_UT_VIDEO_USER:
441 versions->video_channel = true;
442 versions->con_side = true;
443 break;
444 }
445
446 switch (raw_versions & VERSIONS_VIDEO_MASK) {
447 case VERSIONS_VIDEO_DVI:
448 versions->pcb_video_type = PCB_DVI_SL;
449 break;
450
451 case VERSIONS_VIDEO_DP_165:
452 versions->pcb_video_type = PCB_DP_165MPIX;
453 break;
454
455 case VERSIONS_VIDEO_DP_300:
456 versions->pcb_video_type = PCB_DP_300MPIX;
457 break;
458
459 case VERSIONS_VIDEO_HDMI:
460 versions->pcb_video_type = PCB_HDMI;
461 break;
462 }
463
464 versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
465
466 if (raw_versions & VERSIONS_SFP)
467 versions->pcb_transmission_type = PCB_FIBER_3G;
468 else
469 versions->pcb_transmission_type = PCB_CAT_1G;
470
471 return 0;
472}
473
474/**
475 * get_features() - Fill structure with info from features register.
476 * @fpga: Identifier of the FPGA device to be queried for information
477 * @features: Pointer to the structure to fill with information from the
478 * features register
479 *
480 * This is the legacy version and should be considered deprecated for new
481 * devices.
482 *
483 * Return: 0
484 */
485static int get_features(unsigned int fpga, struct fpga_features *features)
486{
487 enum {
488 FEATURE_CARRIER_SPEED_2_5 = BIT(4),
489 FEATURE_RAM_MASK = 0x7 << 5,
490 FEATURE_RAM_DDR2_32BIT = 0x0 << 5,
491 FEATURE_RAM_DDR3_32BIT = 0x1 << 5,
492 FEATURE_RAM_DDR3_48BIT = 0x2 << 5,
493 FEATURE_PCM_AUDIO_TX = BIT(9),
494 FEATURE_PCM_AUDIO_RX = BIT(10),
495 FEATURE_OSD = BIT(11),
496 FEATURE_USB20 = BIT(12),
497 FEATURE_COMPRESSION_MASK = 7 << 13,
498 FEATURE_COMPRESSION_TYPE1 = 0x1 << 13,
499 FEATURE_COMPRESSION_TYPE1_TYPE2 = 0x3 << 13,
500 FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3 = 0x7 << 13,
501 };
502
503 enum {
504 EXTENDED_FEATURE_SPDIF_AUDIO_TX = BIT(0),
505 EXTENDED_FEATURE_SPDIF_AUDIO_RX = BIT(1),
506 EXTENDED_FEATURE_RS232 = BIT(2),
507 EXTENDED_FEATURE_COMPRESSION_PIPES = BIT(3),
508 EXTENDED_FEATURE_INTERLACE = BIT(4),
509 };
510
511 u16 raw_features;
512 u16 raw_extended_features;
513
514 memset(features, 0, sizeof(struct fpga_features));
515
516 FPGA_GET_REG(fpga, fpga_features, &raw_features);
517 FPGA_GET_REG(fpga, fpga_ext_features, &raw_extended_features);
518
519 features->video_channels = raw_features & 0x3;
520 features->carriers = (raw_features >> 2) & 0x3;
521
522 features->carrier_speed = (raw_features & FEATURE_CARRIER_SPEED_2_5)
523 ? CARRIER_SPEED_2_5G : CARRIER_SPEED_1G;
524
525 switch (raw_features & FEATURE_RAM_MASK) {
526 case FEATURE_RAM_DDR2_32BIT:
527 features->ram_config = RAM_DDR2_32BIT_295MBPS;
528 break;
529
530 case FEATURE_RAM_DDR3_32BIT:
531 features->ram_config = RAM_DDR3_32BIT_590MBPS;
532 break;
533
534 case FEATURE_RAM_DDR3_48BIT:
535 features->ram_config = RAM_DDR3_48BIT_590MBPS;
536 break;
537 }
538
539 features->pcm_tx = raw_features & FEATURE_PCM_AUDIO_TX;
540 features->pcm_rx = raw_features & FEATURE_PCM_AUDIO_RX;
541 features->spdif_tx = raw_extended_features &
542 EXTENDED_FEATURE_SPDIF_AUDIO_TX;
543 features->spdif_rx = raw_extended_features &
544 EXTENDED_FEATURE_SPDIF_AUDIO_RX;
545
546 features->usb2 = raw_features & FEATURE_USB20;
547 features->rs232 = raw_extended_features & EXTENDED_FEATURE_RS232;
548
549 features->compression_type1 = false;
550 features->compression_type2 = false;
551 features->compression_type3 = false;
552 switch (raw_features & FEATURE_COMPRESSION_MASK) {
553 case FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3:
554 features->compression_type3 = true;
555 /* fall-through */
556 case FEATURE_COMPRESSION_TYPE1_TYPE2:
557 features->compression_type2 = true;
558 /* fall-through */
559 case FEATURE_COMPRESSION_TYPE1:
560 features->compression_type1 = true;
561 break;
562 }
563
564 features->interlace = raw_extended_features &
565 EXTENDED_FEATURE_INTERLACE;
566 features->osd = raw_features & FEATURE_OSD;
567 features->compression_pipes = raw_extended_features &
568 EXTENDED_FEATURE_COMPRESSION_PIPES;
569
570 return 0;
571}
572
573#endif
574
575/**
576 * fpga_print_info() - Print information about FPGA device
577 * @dev: FPGA device to print information about
578 */
579static void fpga_print_info(struct udevice *dev)
580{
581 struct ihs_fpga_priv *priv = dev_get_priv(dev);
582 u16 fpga_version;
583 struct fpga_versions versions;
584 struct fpga_features features;
585
586 ihs_fpga_get(priv->map, fpga_version, &fpga_version);
587 get_versions(dev, &versions);
588 get_features(dev, &features);
589
590 if (versions.video_channel)
591 printf("Videochannel");
592 else
593 printf("Mainchannel");
594
595 if (versions.con_side)
596 printf(" User");
597 else
598 printf(" Server");
599
600 switch (versions.pcb_transmission_type) {
601 case PCB_CAT_1G:
602 case PCB_CAT_10G:
603 printf(" CAT");
604 break;
605 case PCB_FIBER_3G:
606 case PCB_FIBER_10G:
607 printf(" Fiber");
608 break;
609 };
610
611 switch (versions.pcb_video_type) {
612 case PCB_DVI_SL:
613 printf(" DVI,");
614 break;
615 case PCB_DP_165MPIX:
616 printf(" DP 165MPix/s,");
617 break;
618 case PCB_DP_300MPIX:
619 printf(" DP 300MPix/s,");
620 break;
621 case PCB_HDMI:
622 printf(" HDMI,");
623 break;
624 case PCB_DP_1_2:
625 printf(" DP 1.2,");
626 break;
627 case PCB_HDMI_2_0:
628 printf(" HDMI 2.0,");
629 break;
630 }
631
632 printf(" FPGA V %d.%02d\n features: ",
633 fpga_version / 100, fpga_version % 100);
634
635 if (!features.compression_type1 &&
636 !features.compression_type2 &&
637 !features.compression_type3)
638 printf("no compression, ");
639
640 if (features.compression_type1)
641 printf("type1, ");
642
643 if (features.compression_type2)
644 printf("type2, ");
645
646 if (features.compression_type3)
647 printf("type3, ");
648
649 printf("%sosd", features.osd ? "" : "no ");
650
651 if (features.pcm_rx && features.pcm_tx)
652 printf(", pcm rx+tx");
653 else if (features.pcm_rx)
654 printf(", pcm rx");
655 else if (features.pcm_tx)
656 printf(", pcm tx");
657
658 if (features.spdif_rx && features.spdif_tx)
659 printf(", spdif rx+tx");
660 else if (features.spdif_rx)
661 printf(", spdif rx");
662 else if (features.spdif_tx)
663 printf(", spdif tx");
664
665 puts(",\n ");
666
667 switch (features.sysclock) {
668 case SYSCLK_147456:
669 printf("clock 147.456 MHz");
670 break;
671 }
672
673 switch (features.ram_config) {
674 case RAM_DDR2_32BIT_295MBPS:
675 printf(", RAM 32 bit DDR2");
676 break;
677 case RAM_DDR3_32BIT_590MBPS:
678 printf(", RAM 32 bit DDR3");
679 break;
680 case RAM_DDR3_48BIT_590MBPS:
681 case RAM_DDR3_48BIT_1800MBPS:
682 printf(", RAM 48 bit DDR3");
683 break;
684 case RAM_DDR3_64BIT_1800MBPS:
685 printf(", RAM 64 bit DDR3");
686 break;
687 }
688
689 printf(", %d carrier(s)", features.carriers);
690
691 switch (features.carrier_speed) {
692 case CARRIER_SPEED_1G:
693 printf(", 1Gbit/s");
694 break;
695 case CARRIER_SPEED_3G:
696 printf(", 3Gbit/s");
697 break;
698 case CARRIER_SPEED_10G:
699 printf(", 10Gbit/s");
700 break;
701 }
702
703 printf(", %d video channel(s)\n", features.video_channels);
704}
705
706/**
707 * do_reflection_test() - Run reflection test on a FPGA device
708 * @dev: FPGA device to run reflection test on
709 *
710 * Return: 0 if reflection test succeeded, -ve on error
711 */
712static int do_reflection_test(struct udevice *dev)
713{
714 struct ihs_fpga_priv *priv = dev_get_priv(dev);
715 int ctr = 0;
716
717 while (1) {
718 u16 val;
719
720 ihs_fpga_set(priv->map, reflection_low, REFLECTION_TESTPATTERN);
721
722 ihs_fpga_get(priv->map, reflection_low, &val);
723 if (val == (~REFLECTION_TESTPATTERN & 0xffff))
724 return -EIO;
725
726 mdelay(REFLECTION_TEST_DELAY);
727 if (ctr++ > REFLECTION_TEST_ROUNDS)
728 return 0;
729 }
730}
731
732/**
733 * wait_for_fpga_done() - Wait until 'done'-flag is set for FPGA device
734 * @dev: FPGA device whose done flag to wait for
735 *
736 * This function waits until it detects that the done-GPIO's value was changed
737 * to 1 by the FPGA, which indicates that the device is configured and ready to
738 * use.
739 *
740 * Return: 0 if done flag was detected, -ve on error
741 */
742static int wait_for_fpga_done(struct udevice *dev)
743{
744 struct ihs_fpga_priv *priv = dev_get_priv(dev);
745 int ctr = 0;
746 int done_val;
747
748 while (1) {
749 done_val = dm_gpio_get_value(&priv->done_gpio);
750 if (done_val < 0) {
751 debug("%s: Error while reading done-GPIO (err = %d)\n",
752 dev->name, done_val);
753 return done_val;
754 }
755
756 if (done_val)
757 return 0;
758
759 mdelay(FPGA_DONE_WAIT_DELAY);
760 if (ctr++ > FPGA_DONE_WAIT_ROUND) {
761 debug("%s: FPGA init failed (done not detected)\n",
762 dev->name);
763 return -EIO;
764 }
765 }
766}
767
768static int ihs_fpga_probe(struct udevice *dev)
769{
770 struct ihs_fpga_priv *priv = dev_get_priv(dev);
771 int ret;
772
773 /* TODO(mario.six@gdsys.cc): Case of FPGA attached to MCLink bus */
774
775 ret = regmap_init_mem(dev_ofnode(dev), &priv->map);
776 if (ret) {
777 debug("%s: Could not initialize regmap (err = %d)",
778 dev->name, ret);
779 return ret;
780 }
781
782 ret = gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset_gpio,
783 GPIOD_IS_OUT);
784 if (ret) {
785 debug("%s: Could not get reset-GPIO (err = %d)\n",
786 dev->name, ret);
787 return ret;
788 }
789
790 if (!priv->reset_gpio.dev) {
791 debug("%s: Could not get reset-GPIO\n", dev->name);
792 return -ENOENT;
793 }
794
795 ret = gpio_request_by_name(dev, "done-gpios", 0, &priv->done_gpio,
796 GPIOD_IS_IN);
797 if (ret) {
798 debug("%s: Could not get done-GPIO (err = %d)\n",
799 dev->name, ret);
800 return ret;
801 }
802
803 if (!priv->done_gpio.dev) {
804 debug("%s: Could not get done-GPIO\n", dev->name);
805 return -ENOENT;
806 }
807
808 ret = dm_gpio_set_value(&priv->reset_gpio, 1);
809 if (ret) {
810 debug("%s: Error while setting reset-GPIO (err = %d)\n",
811 dev->name, ret);
812 return ret;
813 }
814
815 /* If FPGA already runs, don't initialize again */
816 if (do_reflection_test(dev))
817 goto reflection_ok;
818
819 ret = dm_gpio_set_value(&priv->reset_gpio, 0);
820 if (ret) {
821 debug("%s: Error while setting reset-GPIO (err = %d)\n",
822 dev->name, ret);
823 return ret;
824 }
825
826 ret = wait_for_fpga_done(dev);
827 if (ret) {
828 debug("%s: Error while waiting for FPGA done (err = %d)\n",
829 dev->name, ret);
830 return ret;
831 }
832
833 udelay(10);
834
835 ret = dm_gpio_set_value(&priv->reset_gpio, 1);
836 if (ret) {
837 debug("%s: Error while setting reset-GPIO (err = %d)\n",
838 dev->name, ret);
839 return ret;
840 }
841
842 if (!do_reflection_test(dev)) {
843 debug("%s: Reflection test FAILED\n", dev->name);
844 return -EIO;
845 }
846
847reflection_ok:
848 printf("%s: Reflection test passed.\n", dev->name);
849
850 fpga_print_info(dev);
851
852 return 0;
853}
854
855static const struct udevice_id ihs_fpga_ids[] = {
856 { .compatible = "gdsys,iocon_fpga" },
857 { .compatible = "gdsys,iocpu_fpga" },
858 { }
859};
860
861U_BOOT_DRIVER(ihs_fpga_bus) = {
862 .name = "ihs_fpga_bus",
863 .id = UCLASS_MISC,
864 .of_match = ihs_fpga_ids,
865 .probe = ihs_fpga_probe,
866 .priv_auto_alloc_size = sizeof(struct ihs_fpga_priv),
867};
diff --git a/drivers/misc/ihs_fpga.h b/drivers/misc/ihs_fpga.h
new file mode 100644
index 0000000000..efb5dabb9c
--- /dev/null
+++ b/drivers/misc/ihs_fpga.h
@@ -0,0 +1,49 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * (C) Copyright 2018
4 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
5 */
6
7/**
8 * struct ihs_fpga_regs - IHS FPGA register map structure
9 * @reflection_low: Lower reflection register
10 * @versions: PCB versions register
11 * @fpga_version: FPGA versions register
12 * @features: FPGA features register
13 * @extended_features: FPGA extended features register
14 * @top_interrupt: Top interrupt register
15 * @top_interrupt_enable: Top interrupt enable register
16 * @status: FPGA status register
17 * @control: FPGA control register
18 * @extended_control: FPGA extended control register
19 */
20struct ihs_fpga_regs {
21 u16 reflection_low;
22 u16 versions;
23 u16 fpga_version;
24 u16 features;
25 u16 extended_features;
26 u16 top_interrupt;
27 u16 top_interrupt_enable;
28 u16 status;
29 u16 control;
30 u16 extended_control;
31};
32
33/**
34 * ihs_fpga_set() - Convenience macro to set values in FPGA register map
35 * @map: Register map to set a value in
36 * @member: Name of member (described by ihs_fpga_regs) to set
37 * @val: Value to set the member to
38 */
39#define ihs_fpga_set(map, member, val) \
40 regmap_set(map, struct ihs_fpga_regs, member, val)
41
42/**
43 * ihs_fpga_get() - Convenience macro to get values from FPGA register map
44 * @map: Register map to read value from
45 * @member: Name of member (described by ihs_fpga_regs) to get
46 * @valp: Pointe to variable to receive the value read
47 */
48#define ihs_fpga_get(map, member, valp) \
49 regmap_get(map, struct ihs_fpga_regs, member, valp)
diff --git a/drivers/misc/imx8/scu.c b/drivers/misc/imx8/scu.c
index 0647ddf103..b824ac79e6 100644
--- a/drivers/misc/imx8/scu.c
+++ b/drivers/misc/imx8/scu.c
@@ -223,7 +223,7 @@ static int imx8_scu_bind(struct udevice *dev)
223 if (node < 0) 223 if (node < 0)
224 panic("No clk node found\n"); 224 panic("No clk node found\n");
225 225
226 ret = lists_bind_fdt(dev, offset_to_ofnode(node), &child); 226 ret = lists_bind_fdt(dev, offset_to_ofnode(node), &child, true);
227 if (ret) 227 if (ret)
228 return ret; 228 return ret;
229 229
@@ -234,7 +234,7 @@ static int imx8_scu_bind(struct udevice *dev)
234 if (node < 0) 234 if (node < 0)
235 panic("No iomuxc node found\n"); 235 panic("No iomuxc node found\n");
236 236
237 ret = lists_bind_fdt(dev, offset_to_ofnode(node), &child); 237 ret = lists_bind_fdt(dev, offset_to_ofnode(node), &child, true);
238 if (ret) 238 if (ret)
239 return ret; 239 return ret;
240 240
diff --git a/drivers/misc/swap_case.c b/drivers/misc/swap_case.c
index bffb809f14..fa608cec1b 100644
--- a/drivers/misc/swap_case.c
+++ b/drivers/misc/swap_case.c
@@ -124,12 +124,21 @@ static int sandbox_swap_case_read_config(struct udevice *emul, uint offset,
124 case PCI_CAP_ID_PM_OFFSET: 124 case PCI_CAP_ID_PM_OFFSET:
125 *valuep = (PCI_CAP_ID_EXP_OFFSET << 8) | PCI_CAP_ID_PM; 125 *valuep = (PCI_CAP_ID_EXP_OFFSET << 8) | PCI_CAP_ID_PM;
126 break; 126 break;
127 case PCI_CAP_ID_PM_OFFSET + PCI_CAP_LIST_NEXT:
128 *valuep = PCI_CAP_ID_EXP_OFFSET;
129 break;
127 case PCI_CAP_ID_EXP_OFFSET: 130 case PCI_CAP_ID_EXP_OFFSET:
128 *valuep = (PCI_CAP_ID_MSIX_OFFSET << 8) | PCI_CAP_ID_EXP; 131 *valuep = (PCI_CAP_ID_MSIX_OFFSET << 8) | PCI_CAP_ID_EXP;
129 break; 132 break;
133 case PCI_CAP_ID_EXP_OFFSET + PCI_CAP_LIST_NEXT:
134 *valuep = PCI_CAP_ID_MSIX_OFFSET;
135 break;
130 case PCI_CAP_ID_MSIX_OFFSET: 136 case PCI_CAP_ID_MSIX_OFFSET:
131 *valuep = PCI_CAP_ID_MSIX; 137 *valuep = PCI_CAP_ID_MSIX;
132 break; 138 break;
139 case PCI_CAP_ID_MSIX_OFFSET + PCI_CAP_LIST_NEXT:
140 *valuep = 0;
141 break;
133 case PCI_EXT_CAP_ID_ERR_OFFSET: 142 case PCI_EXT_CAP_ID_ERR_OFFSET:
134 *valuep = (PCI_EXT_CAP_ID_VC_OFFSET << 20) | PCI_EXT_CAP_ID_ERR; 143 *valuep = (PCI_EXT_CAP_ID_VC_OFFSET << 20) | PCI_EXT_CAP_ID_ERR;
135 break; 144 break;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 585951cd78..d6b9cdc992 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -2444,9 +2444,6 @@ static int mmc_startup(struct mmc *mmc)
2444 bdesc->product[0] = 0; 2444 bdesc->product[0] = 0;
2445 bdesc->revision[0] = 0; 2445 bdesc->revision[0] = 0;
2446#endif 2446#endif
2447#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
2448 part_init(bdesc);
2449#endif
2450 2447
2451 return 0; 2448 return 0;
2452} 2449}
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index ec853d063f..5cb97eb02a 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -1953,6 +1953,8 @@ U_BOOT_DRIVER(omap_hsmmc) = {
1953 .ops = &omap_hsmmc_ops, 1953 .ops = &omap_hsmmc_ops,
1954 .probe = omap_hsmmc_probe, 1954 .probe = omap_hsmmc_probe,
1955 .priv_auto_alloc_size = sizeof(struct omap_hsmmc_data), 1955 .priv_auto_alloc_size = sizeof(struct omap_hsmmc_data),
1956#if !CONFIG_IS_ENABLED(OF_CONTROL)
1956 .flags = DM_FLAG_PRE_RELOC, 1957 .flags = DM_FLAG_PRE_RELOC,
1958#endif
1957}; 1959};
1958#endif 1960#endif
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index eb6fdeda50..1ee0a0aefb 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -664,7 +664,6 @@ static int nvme_blk_probe(struct udevice *udev)
664 sprintf(desc->vendor, "0x%.4x", pplat->vendor); 664 sprintf(desc->vendor, "0x%.4x", pplat->vendor);
665 memcpy(desc->product, ndev->serial, sizeof(ndev->serial)); 665 memcpy(desc->product, ndev->serial, sizeof(ndev->serial));
666 memcpy(desc->revision, ndev->firmware_rev, sizeof(ndev->firmware_rev)); 666 memcpy(desc->revision, ndev->firmware_rev, sizeof(ndev->firmware_rev));
667 part_init(desc);
668 667
669 return 0; 668 return 0;
670} 669}
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index da49c96ed5..0c52337f33 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -1344,26 +1344,14 @@ void *dm_pci_map_bar(struct udevice *dev, int bar, int flags)
1344 return dm_pci_bus_to_virt(dev, pci_bus_addr, flags, 0, MAP_NOCACHE); 1344 return dm_pci_bus_to_virt(dev, pci_bus_addr, flags, 0, MAP_NOCACHE);
1345} 1345}
1346 1346
1347int dm_pci_find_capability(struct udevice *dev, int cap) 1347static int _dm_pci_find_next_capability(struct udevice *dev, u8 pos, int cap)
1348{ 1348{
1349 u16 status;
1350 u8 header_type;
1351 int ttl = PCI_FIND_CAP_TTL; 1349 int ttl = PCI_FIND_CAP_TTL;
1352 u8 id; 1350 u8 id;
1353 u16 ent; 1351 u16 ent;
1354 u8 pos;
1355
1356 dm_pci_read_config16(dev, PCI_STATUS, &status);
1357 if (!(status & PCI_STATUS_CAP_LIST))
1358 return 0;
1359
1360 dm_pci_read_config8(dev, PCI_HEADER_TYPE, &header_type);
1361 if ((header_type & 0x7f) == PCI_HEADER_TYPE_CARDBUS)
1362 pos = PCI_CB_CAPABILITY_LIST;
1363 else
1364 pos = PCI_CAPABILITY_LIST;
1365 1352
1366 dm_pci_read_config8(dev, pos, &pos); 1353 dm_pci_read_config8(dev, pos, &pos);
1354
1367 while (ttl--) { 1355 while (ttl--) {
1368 if (pos < PCI_STD_HEADER_SIZEOF) 1356 if (pos < PCI_STD_HEADER_SIZEOF)
1369 break; 1357 break;
@@ -1381,7 +1369,32 @@ int dm_pci_find_capability(struct udevice *dev, int cap)
1381 return 0; 1369 return 0;
1382} 1370}
1383 1371
1384int dm_pci_find_ext_capability(struct udevice *dev, int cap) 1372int dm_pci_find_next_capability(struct udevice *dev, u8 start, int cap)
1373{
1374 return _dm_pci_find_next_capability(dev, start + PCI_CAP_LIST_NEXT,
1375 cap);
1376}
1377
1378int dm_pci_find_capability(struct udevice *dev, int cap)
1379{
1380 u16 status;
1381 u8 header_type;
1382 u8 pos;
1383
1384 dm_pci_read_config16(dev, PCI_STATUS, &status);
1385 if (!(status & PCI_STATUS_CAP_LIST))
1386 return 0;
1387
1388 dm_pci_read_config8(dev, PCI_HEADER_TYPE, &header_type);
1389 if ((header_type & 0x7f) == PCI_HEADER_TYPE_CARDBUS)
1390 pos = PCI_CB_CAPABILITY_LIST;
1391 else
1392 pos = PCI_CAPABILITY_LIST;
1393
1394 return _dm_pci_find_next_capability(dev, pos, cap);
1395}
1396
1397int dm_pci_find_next_ext_capability(struct udevice *dev, int start, int cap)
1385{ 1398{
1386 u32 header; 1399 u32 header;
1387 int ttl; 1400 int ttl;
@@ -1390,6 +1403,9 @@ int dm_pci_find_ext_capability(struct udevice *dev, int cap)
1390 /* minimum 8 bytes per capability */ 1403 /* minimum 8 bytes per capability */
1391 ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; 1404 ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
1392 1405
1406 if (start)
1407 pos = start;
1408
1393 dm_pci_read_config32(dev, pos, &header); 1409 dm_pci_read_config32(dev, pos, &header);
1394 /* 1410 /*
1395 * If we have no capabilities, this is indicated by cap ID, 1411 * If we have no capabilities, this is indicated by cap ID,
@@ -1412,6 +1428,11 @@ int dm_pci_find_ext_capability(struct udevice *dev, int cap)
1412 return 0; 1428 return 0;
1413} 1429}
1414 1430
1431int dm_pci_find_ext_capability(struct udevice *dev, int cap)
1432{
1433 return dm_pci_find_next_ext_capability(dev, 0, cap);
1434}
1435
1415UCLASS_DRIVER(pci) = { 1436UCLASS_DRIVER(pci) = {
1416 .id = UCLASS_PCI, 1437 .id = UCLASS_PCI,
1417 .name = "pci", 1438 .name = "pci",
diff --git a/drivers/pinctrl/broadcom/pinctrl-bcm283x.c b/drivers/pinctrl/broadcom/pinctrl-bcm283x.c
index 891b4c25fd..3be080d29e 100644
--- a/drivers/pinctrl/broadcom/pinctrl-bcm283x.c
+++ b/drivers/pinctrl/broadcom/pinctrl-bcm283x.c
@@ -148,5 +148,7 @@ U_BOOT_DRIVER(pinctrl_bcm283x) = {
148 .priv_auto_alloc_size = sizeof(struct bcm283x_pinctrl_priv), 148 .priv_auto_alloc_size = sizeof(struct bcm283x_pinctrl_priv),
149 .ops = &bcm283x_pinctrl_ops, 149 .ops = &bcm283x_pinctrl_ops,
150 .probe = bcm283x_pinctl_probe, 150 .probe = bcm283x_pinctl_probe,
151#if !CONFIG_IS_ENABLED(OF_CONTROL)
151 .flags = DM_FLAG_PRE_RELOC, 152 .flags = DM_FLAG_PRE_RELOC,
153#endif
152}; 154};
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos7420.c b/drivers/pinctrl/exynos/pinctrl-exynos7420.c
index cb5975b252..ff6d6c4143 100644
--- a/drivers/pinctrl/exynos/pinctrl-exynos7420.c
+++ b/drivers/pinctrl/exynos/pinctrl-exynos7420.c
@@ -113,5 +113,4 @@ U_BOOT_DRIVER(pinctrl_exynos7420) = {
113 .priv_auto_alloc_size = sizeof(struct exynos_pinctrl_priv), 113 .priv_auto_alloc_size = sizeof(struct exynos_pinctrl_priv),
114 .ops = &exynos7420_pinctrl_ops, 114 .ops = &exynos7420_pinctrl_ops,
115 .probe = exynos_pinctrl_probe, 115 .probe = exynos_pinctrl_probe,
116 .flags = DM_FLAG_PRE_RELOC
117}; 116};
diff --git a/drivers/pinctrl/nxp/pinctrl-imx5.c b/drivers/pinctrl/nxp/pinctrl-imx5.c
index 5d17380919..4e831b6f39 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx5.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx5.c
@@ -40,5 +40,7 @@ U_BOOT_DRIVER(imx5_pinctrl) = {
40 .remove = imx_pinctrl_remove, 40 .remove = imx_pinctrl_remove,
41 .priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv), 41 .priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv),
42 .ops = &imx_pinctrl_ops, 42 .ops = &imx_pinctrl_ops,
43#if !CONFIG_IS_ENABLED(OF_CONTROL)
43 .flags = DM_FLAG_PRE_RELOC, 44 .flags = DM_FLAG_PRE_RELOC,
45#endif
44}; 46};
diff --git a/drivers/pinctrl/nxp/pinctrl-imx6.c b/drivers/pinctrl/nxp/pinctrl-imx6.c
index e63ecbdee6..d7c95bb738 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx6.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx6.c
@@ -49,5 +49,7 @@ U_BOOT_DRIVER(imx6_pinctrl) = {
49 .remove = imx_pinctrl_remove, 49 .remove = imx_pinctrl_remove,
50 .priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv), 50 .priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv),
51 .ops = &imx_pinctrl_ops, 51 .ops = &imx_pinctrl_ops,
52#if !CONFIG_IS_ENABLED(OF_CONTROL)
52 .flags = DM_FLAG_PRE_RELOC, 53 .flags = DM_FLAG_PRE_RELOC,
54#endif
53}; 55};
diff --git a/drivers/pinctrl/nxp/pinctrl-imx7.c b/drivers/pinctrl/nxp/pinctrl-imx7.c
index 769d428dda..8776fd9650 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx7.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx7.c
@@ -37,5 +37,7 @@ U_BOOT_DRIVER(imx7_pinctrl) = {
37 .remove = imx_pinctrl_remove, 37 .remove = imx_pinctrl_remove,
38 .priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv), 38 .priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv),
39 .ops = &imx_pinctrl_ops, 39 .ops = &imx_pinctrl_ops,
40#if !CONFIG_IS_ENABLED(OF_CONTROL)
40 .flags = DM_FLAG_PRE_RELOC, 41 .flags = DM_FLAG_PRE_RELOC,
42#endif
41}; 43};
diff --git a/drivers/pinctrl/nxp/pinctrl-imx7ulp.c b/drivers/pinctrl/nxp/pinctrl-imx7ulp.c
index 598bbfaf35..d778f82aac 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx7ulp.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx7ulp.c
@@ -41,5 +41,7 @@ U_BOOT_DRIVER(imx7ulp_pinctrl) = {
41 .remove = imx_pinctrl_remove, 41 .remove = imx_pinctrl_remove,
42 .priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv), 42 .priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv),
43 .ops = &imx_pinctrl_ops, 43 .ops = &imx_pinctrl_ops,
44#if !CONFIG_IS_ENABLED(OF_CONTROL)
44 .flags = DM_FLAG_PRE_RELOC, 45 .flags = DM_FLAG_PRE_RELOC,
46#endif
45}; 47};
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index d80c6eda70..9dec88c1aa 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -136,7 +136,6 @@ U_BOOT_DRIVER(single_pinctrl) = {
136 .id = UCLASS_PINCTRL, 136 .id = UCLASS_PINCTRL,
137 .of_match = single_pinctrl_match, 137 .of_match = single_pinctrl_match,
138 .ops = &single_pinctrl_ops, 138 .ops = &single_pinctrl_ops,
139 .flags = DM_FLAG_PRE_RELOC,
140 .platdata_auto_alloc_size = sizeof(struct single_pdata), 139 .platdata_auto_alloc_size = sizeof(struct single_pdata),
141 .ofdata_to_platdata = single_ofdata_to_platdata, 140 .ofdata_to_platdata = single_ofdata_to_platdata,
142}; 141};
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c
index a1da90baa4..eb5978a166 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c
@@ -171,5 +171,7 @@ U_BOOT_DRIVER(uniphier_pro4_pinctrl) = {
171 .probe = uniphier_pro4_pinctrl_probe, 171 .probe = uniphier_pro4_pinctrl_probe,
172 .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv), 172 .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
173 .ops = &uniphier_pinctrl_ops, 173 .ops = &uniphier_pinctrl_ops,
174#if !CONFIG_IS_ENABLED(OF_CONTROL)
174 .flags = DM_FLAG_PRE_RELOC, 175 .flags = DM_FLAG_PRE_RELOC,
176#endif
175}; 177};
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c
index 0ba2052b29..685d8be80c 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c
@@ -153,5 +153,7 @@ U_BOOT_DRIVER(uniphier_pro5_pinctrl) = {
153 .probe = uniphier_pro5_pinctrl_probe, 153 .probe = uniphier_pro5_pinctrl_probe,
154 .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv), 154 .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
155 .ops = &uniphier_pinctrl_ops, 155 .ops = &uniphier_pinctrl_ops,
156#if !CONFIG_IS_ENABLED(OF_CONTROL)
156 .flags = DM_FLAG_PRE_RELOC, 157 .flags = DM_FLAG_PRE_RELOC,
158#endif
157}; 159};
diff --git a/drivers/ram/bmips_ram.c b/drivers/ram/bmips_ram.c
index b5f19c983c..3e1dd9e241 100644
--- a/drivers/ram/bmips_ram.c
+++ b/drivers/ram/bmips_ram.c
@@ -173,5 +173,4 @@ U_BOOT_DRIVER(bmips_ram) = {
173 .probe = bmips_ram_probe, 173 .probe = bmips_ram_probe,
174 .priv_auto_alloc_size = sizeof(struct bmips_ram_priv), 174 .priv_auto_alloc_size = sizeof(struct bmips_ram_priv),
175 .ops = &bmips_ram_ops, 175 .ops = &bmips_ram_ops,
176 .flags = DM_FLAG_PRE_RELOC,
177}; 176};
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index bc6ac8cd32..df47e2fc78 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -592,7 +592,6 @@ static int do_scsi_scan_one(struct udevice *dev, int id, int lun, bool verbose)
592 memcpy(&bdesc->vendor, &bd.vendor, sizeof(bd.vendor)); 592 memcpy(&bdesc->vendor, &bd.vendor, sizeof(bd.vendor));
593 memcpy(&bdesc->product, &bd.product, sizeof(bd.product)); 593 memcpy(&bdesc->product, &bd.product, sizeof(bd.product));
594 memcpy(&bdesc->revision, &bd.revision, sizeof(bd.revision)); 594 memcpy(&bdesc->revision, &bd.revision, sizeof(bd.revision));
595 part_init(bdesc);
596 595
597 if (verbose) { 596 if (verbose) {
598 printf(" Device %d: ", 0); 597 printf(" Device %d: ", 0);
diff --git a/drivers/serial/altera_jtag_uart.c b/drivers/serial/altera_jtag_uart.c
index 61052a92d6..86c3de4e45 100644
--- a/drivers/serial/altera_jtag_uart.c
+++ b/drivers/serial/altera_jtag_uart.c
@@ -121,7 +121,6 @@ U_BOOT_DRIVER(altera_jtaguart) = {
121 .platdata_auto_alloc_size = sizeof(struct altera_jtaguart_platdata), 121 .platdata_auto_alloc_size = sizeof(struct altera_jtaguart_platdata),
122 .probe = altera_jtaguart_probe, 122 .probe = altera_jtaguart_probe,
123 .ops = &altera_jtaguart_ops, 123 .ops = &altera_jtaguart_ops,
124 .flags = DM_FLAG_PRE_RELOC,
125}; 124};
126 125
127#ifdef CONFIG_DEBUG_UART_ALTERA_JTAGUART 126#ifdef CONFIG_DEBUG_UART_ALTERA_JTAGUART
diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c
index b7b0a13ca1..67d47199aa 100644
--- a/drivers/serial/altera_uart.c
+++ b/drivers/serial/altera_uart.c
@@ -117,7 +117,6 @@ U_BOOT_DRIVER(altera_uart) = {
117 .platdata_auto_alloc_size = sizeof(struct altera_uart_platdata), 117 .platdata_auto_alloc_size = sizeof(struct altera_uart_platdata),
118 .probe = altera_uart_probe, 118 .probe = altera_uart_probe,
119 .ops = &altera_uart_ops, 119 .ops = &altera_uart_ops,
120 .flags = DM_FLAG_PRE_RELOC,
121}; 120};
122 121
123#ifdef CONFIG_DEBUG_UART_ALTERA_UART 122#ifdef CONFIG_DEBUG_UART_ALTERA_UART
diff --git a/drivers/serial/arm_dcc.c b/drivers/serial/arm_dcc.c
index 43e8691a93..dfcb6fd698 100644
--- a/drivers/serial/arm_dcc.c
+++ b/drivers/serial/arm_dcc.c
@@ -155,7 +155,6 @@ U_BOOT_DRIVER(serial_dcc) = {
155 .id = UCLASS_SERIAL, 155 .id = UCLASS_SERIAL,
156 .of_match = arm_dcc_ids, 156 .of_match = arm_dcc_ids,
157 .ops = &arm_dcc_ops, 157 .ops = &arm_dcc_ops,
158 .flags = DM_FLAG_PRE_RELOC,
159}; 158};
160 159
161#ifdef CONFIG_DEBUG_UART_ARM_DCC 160#ifdef CONFIG_DEBUG_UART_ARM_DCC
diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c
index 9414f5f692..aa8cdff840 100644
--- a/drivers/serial/atmel_usart.c
+++ b/drivers/serial/atmel_usart.c
@@ -294,7 +294,9 @@ U_BOOT_DRIVER(serial_atmel) = {
294#endif 294#endif
295 .probe = atmel_serial_probe, 295 .probe = atmel_serial_probe,
296 .ops = &atmel_serial_ops, 296 .ops = &atmel_serial_ops,
297#if !CONFIG_IS_ENABLED(OF_CONTROL)
297 .flags = DM_FLAG_PRE_RELOC, 298 .flags = DM_FLAG_PRE_RELOC,
299#endif
298 .priv_auto_alloc_size = sizeof(struct atmel_serial_priv), 300 .priv_auto_alloc_size = sizeof(struct atmel_serial_priv),
299}; 301};
300#endif 302#endif
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index f9041aa626..1e6fc6c668 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -267,12 +267,26 @@ static inline void _debug_uart_init(void)
267 serial_dout(&com_port->lcr, UART_LCRVAL); 267 serial_dout(&com_port->lcr, UART_LCRVAL);
268} 268}
269 269
270static inline int NS16550_read_baud_divisor(struct NS16550 *com_port)
271{
272 int ret;
273
274 serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL);
275 ret = serial_din(&com_port->dll) & 0xff;
276 ret |= (serial_din(&com_port->dlm) & 0xff) << 8;
277 serial_dout(&com_port->lcr, UART_LCRVAL);
278
279 return ret;
280}
281
270static inline void _debug_uart_putc(int ch) 282static inline void _debug_uart_putc(int ch)
271{ 283{
272 struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE; 284 struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
273 285
274 while (!(serial_din(&com_port->lsr) & UART_LSR_THRE)) 286 while (!(serial_din(&com_port->lsr) & UART_LSR_THRE)) {
275 ; 287 if (!NS16550_read_baud_divisor(com_port))
288 return;
289 }
276 serial_dout(&com_port->thr, ch); 290 serial_dout(&com_port->thr, ch);
277} 291}
278 292
@@ -473,7 +487,9 @@ U_BOOT_DRIVER(ns16550_serial) = {
473 .priv_auto_alloc_size = sizeof(struct NS16550), 487 .priv_auto_alloc_size = sizeof(struct NS16550),
474 .probe = ns16550_serial_probe, 488 .probe = ns16550_serial_probe,
475 .ops = &ns16550_serial_ops, 489 .ops = &ns16550_serial_ops,
490#if !CONFIG_IS_ENABLED(OF_CONTROL)
476 .flags = DM_FLAG_PRE_RELOC, 491 .flags = DM_FLAG_PRE_RELOC,
492#endif
477}; 493};
478#endif 494#endif
479#endif /* SERIAL_PRESENT */ 495#endif /* SERIAL_PRESENT */
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 665cca85cb..3ded62732d 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -62,7 +62,7 @@ static int serial_check_stdout(const void *blob, struct udevice **devp)
62 * anyway. 62 * anyway.
63 */ 63 */
64 if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node), 64 if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
65 devp)) { 65 devp, false)) {
66 if (!device_probe(*devp)) 66 if (!device_probe(*devp))
67 return 0; 67 return 0;
68 } 68 }
diff --git a/drivers/serial/serial_ar933x.c b/drivers/serial/serial_ar933x.c
index e91a5f7b24..5249c55398 100644
--- a/drivers/serial/serial_ar933x.c
+++ b/drivers/serial/serial_ar933x.c
@@ -189,7 +189,6 @@ U_BOOT_DRIVER(serial_ar933x) = {
189 .priv_auto_alloc_size = sizeof(struct ar933x_serial_priv), 189 .priv_auto_alloc_size = sizeof(struct ar933x_serial_priv),
190 .probe = ar933x_serial_probe, 190 .probe = ar933x_serial_probe,
191 .ops = &ar933x_serial_ops, 191 .ops = &ar933x_serial_ops,
192 .flags = DM_FLAG_PRE_RELOC,
193}; 192};
194 193
195#ifdef CONFIG_DEBUG_UART_AR933X 194#ifdef CONFIG_DEBUG_UART_AR933X
diff --git a/drivers/serial/serial_arc.c b/drivers/serial/serial_arc.c
index 925f0c2555..980b38d2a1 100644
--- a/drivers/serial/serial_arc.c
+++ b/drivers/serial/serial_arc.c
@@ -128,7 +128,6 @@ U_BOOT_DRIVER(serial_arc) = {
128 .ofdata_to_platdata = arc_serial_ofdata_to_platdata, 128 .ofdata_to_platdata = arc_serial_ofdata_to_platdata,
129 .probe = arc_serial_probe, 129 .probe = arc_serial_probe,
130 .ops = &arc_serial_ops, 130 .ops = &arc_serial_ops,
131 .flags = DM_FLAG_PRE_RELOC,
132}; 131};
133 132
134#ifdef CONFIG_DEBUG_ARC_SERIAL 133#ifdef CONFIG_DEBUG_ARC_SERIAL
diff --git a/drivers/serial/serial_bcm283x_mu.c b/drivers/serial/serial_bcm283x_mu.c
index 1f87f0cb28..bd1d89ec83 100644
--- a/drivers/serial/serial_bcm283x_mu.c
+++ b/drivers/serial/serial_bcm283x_mu.c
@@ -199,6 +199,8 @@ U_BOOT_DRIVER(serial_bcm283x_mu) = {
199 .platdata_auto_alloc_size = sizeof(struct bcm283x_mu_serial_platdata), 199 .platdata_auto_alloc_size = sizeof(struct bcm283x_mu_serial_platdata),
200 .probe = bcm283x_mu_serial_probe, 200 .probe = bcm283x_mu_serial_probe,
201 .ops = &bcm283x_mu_serial_ops, 201 .ops = &bcm283x_mu_serial_ops,
202#if !CONFIG_IS_ENABLED(OF_CONTROL)
202 .flags = DM_FLAG_PRE_RELOC, 203 .flags = DM_FLAG_PRE_RELOC,
204#endif
203 .priv_auto_alloc_size = sizeof(struct bcm283x_mu_priv), 205 .priv_auto_alloc_size = sizeof(struct bcm283x_mu_priv),
204}; 206};
diff --git a/drivers/serial/serial_bcm283x_pl011.c b/drivers/serial/serial_bcm283x_pl011.c
index 54fc9b5b39..2527bb8b1c 100644
--- a/drivers/serial/serial_bcm283x_pl011.c
+++ b/drivers/serial/serial_bcm283x_pl011.c
@@ -90,6 +90,8 @@ U_BOOT_DRIVER(bcm283x_pl011_uart) = {
90 .platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata), 90 .platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata),
91 .probe = pl01x_serial_probe, 91 .probe = pl01x_serial_probe,
92 .ops = &bcm283x_pl011_serial_ops, 92 .ops = &bcm283x_pl011_serial_ops,
93#if !CONFIG_IS_ENABLED(OF_CONTROL)
93 .flags = DM_FLAG_PRE_RELOC, 94 .flags = DM_FLAG_PRE_RELOC,
95#endif
94 .priv_auto_alloc_size = sizeof(struct pl01x_priv), 96 .priv_auto_alloc_size = sizeof(struct pl01x_priv),
95}; 97};
diff --git a/drivers/serial/serial_bcm6345.c b/drivers/serial/serial_bcm6345.c
index ee5d561bfd..a0e709a11e 100644
--- a/drivers/serial/serial_bcm6345.c
+++ b/drivers/serial/serial_bcm6345.c
@@ -264,7 +264,6 @@ U_BOOT_DRIVER(bcm6345_serial) = {
264 .probe = bcm6345_serial_probe, 264 .probe = bcm6345_serial_probe,
265 .priv_auto_alloc_size = sizeof(struct bcm6345_serial_priv), 265 .priv_auto_alloc_size = sizeof(struct bcm6345_serial_priv),
266 .ops = &bcm6345_serial_ops, 266 .ops = &bcm6345_serial_ops,
267 .flags = DM_FLAG_PRE_RELOC,
268}; 267};
269 268
270#ifdef CONFIG_DEBUG_UART_BCM6345 269#ifdef CONFIG_DEBUG_UART_BCM6345
diff --git a/drivers/serial/serial_efi.c b/drivers/serial/serial_efi.c
index 1b54d1880f..dd3e511fc9 100644
--- a/drivers/serial/serial_efi.c
+++ b/drivers/serial/serial_efi.c
@@ -152,5 +152,4 @@ U_BOOT_DRIVER(serial_efi) = {
152 .priv_auto_alloc_size = sizeof(struct serial_efi_priv), 152 .priv_auto_alloc_size = sizeof(struct serial_efi_priv),
153 .probe = serial_efi_probe, 153 .probe = serial_efi_probe,
154 .ops = &serial_efi_ops, 154 .ops = &serial_efi_ops,
155 .flags = DM_FLAG_PRE_RELOC,
156}; 155};
diff --git a/drivers/serial/serial_intel_mid.c b/drivers/serial/serial_intel_mid.c
index bdb5adb2a4..39bd40e68b 100644
--- a/drivers/serial/serial_intel_mid.c
+++ b/drivers/serial/serial_intel_mid.c
@@ -64,5 +64,4 @@ U_BOOT_DRIVER(serial_intel_mid) = {
64 .priv_auto_alloc_size = sizeof(struct NS16550), 64 .priv_auto_alloc_size = sizeof(struct NS16550),
65 .probe = mid_serial_probe, 65 .probe = mid_serial_probe,
66 .ops = &ns16550_serial_ops, 66 .ops = &ns16550_serial_ops,
67 .flags = DM_FLAG_PRE_RELOC,
68}; 67};
diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
index 6106c1f9ec..a357b00d28 100644
--- a/drivers/serial/serial_lpuart.c
+++ b/drivers/serial/serial_lpuart.c
@@ -540,5 +540,4 @@ U_BOOT_DRIVER(serial_lpuart) = {
540 .platdata_auto_alloc_size = sizeof(struct lpuart_serial_platdata), 540 .platdata_auto_alloc_size = sizeof(struct lpuart_serial_platdata),
541 .probe = lpuart_serial_probe, 541 .probe = lpuart_serial_probe,
542 .ops = &lpuart_serial_ops, 542 .ops = &lpuart_serial_ops,
543 .flags = DM_FLAG_PRE_RELOC,
544}; 543};
diff --git a/drivers/serial/serial_meson.c b/drivers/serial/serial_meson.c
index dbb853735f..b3dad77aa2 100644
--- a/drivers/serial/serial_meson.c
+++ b/drivers/serial/serial_meson.c
@@ -132,7 +132,6 @@ U_BOOT_DRIVER(serial_meson) = {
132 .of_match = meson_serial_ids, 132 .of_match = meson_serial_ids,
133 .probe = meson_serial_probe, 133 .probe = meson_serial_probe,
134 .ops = &meson_serial_ops, 134 .ops = &meson_serial_ops,
135 .flags = DM_FLAG_PRE_RELOC,
136 .ofdata_to_platdata = meson_serial_ofdata_to_platdata, 135 .ofdata_to_platdata = meson_serial_ofdata_to_platdata,
137 .platdata_auto_alloc_size = sizeof(struct meson_serial_platdata), 136 .platdata_auto_alloc_size = sizeof(struct meson_serial_platdata),
138}; 137};
diff --git a/drivers/serial/serial_mvebu_a3700.c b/drivers/serial/serial_mvebu_a3700.c
index ce26d2bd15..7e4cd6c4b4 100644
--- a/drivers/serial/serial_mvebu_a3700.c
+++ b/drivers/serial/serial_mvebu_a3700.c
@@ -129,7 +129,6 @@ U_BOOT_DRIVER(serial_mvebu) = {
129 .platdata_auto_alloc_size = sizeof(struct mvebu_platdata), 129 .platdata_auto_alloc_size = sizeof(struct mvebu_platdata),
130 .probe = mvebu_serial_probe, 130 .probe = mvebu_serial_probe,
131 .ops = &mvebu_serial_ops, 131 .ops = &mvebu_serial_ops,
132 .flags = DM_FLAG_PRE_RELOC,
133}; 132};
134 133
135#ifdef CONFIG_DEBUG_MVEBU_A3700_UART 134#ifdef CONFIG_DEBUG_MVEBU_A3700_UART
diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
index e586c18cf0..7e4e6d36b8 100644
--- a/drivers/serial/serial_mxc.c
+++ b/drivers/serial/serial_mxc.c
@@ -354,7 +354,9 @@ U_BOOT_DRIVER(serial_mxc) = {
354#endif 354#endif
355 .probe = mxc_serial_probe, 355 .probe = mxc_serial_probe,
356 .ops = &mxc_serial_ops, 356 .ops = &mxc_serial_ops,
357#if !CONFIG_IS_ENABLED(OF_CONTROL)
357 .flags = DM_FLAG_PRE_RELOC, 358 .flags = DM_FLAG_PRE_RELOC,
359#endif
358}; 360};
359#endif 361#endif
360 362
diff --git a/drivers/serial/serial_omap.c b/drivers/serial/serial_omap.c
index af3c755f96..ee6ad9c9e5 100644
--- a/drivers/serial/serial_omap.c
+++ b/drivers/serial/serial_omap.c
@@ -121,7 +121,9 @@ U_BOOT_DRIVER(omap_serial) = {
121 .priv_auto_alloc_size = sizeof(struct NS16550), 121 .priv_auto_alloc_size = sizeof(struct NS16550),
122 .probe = ns16550_serial_probe, 122 .probe = ns16550_serial_probe,
123 .ops = &ns16550_serial_ops, 123 .ops = &ns16550_serial_ops,
124#if !CONFIG_IS_ENABLED(OF_CONTROL)
124 .flags = DM_FLAG_PRE_RELOC, 125 .flags = DM_FLAG_PRE_RELOC,
126#endif
125}; 127};
126#endif 128#endif
127#endif /* DM_SERIAL */ 129#endif /* DM_SERIAL */
diff --git a/drivers/serial/serial_owl.c b/drivers/serial/serial_owl.c
index 6fd97e2502..7ead73e6b7 100644
--- a/drivers/serial/serial_owl.c
+++ b/drivers/serial/serial_owl.c
@@ -132,5 +132,4 @@ U_BOOT_DRIVER(serial_owl) = {
132 .priv_auto_alloc_size = sizeof(struct owl_serial_priv), 132 .priv_auto_alloc_size = sizeof(struct owl_serial_priv),
133 .probe = owl_serial_probe, 133 .probe = owl_serial_probe,
134 .ops = &owl_serial_ops, 134 .ops = &owl_serial_ops,
135 .flags = DM_FLAG_PRE_RELOC,
136}; 135};
diff --git a/drivers/serial/serial_pic32.c b/drivers/serial/serial_pic32.c
index ba73978e25..84600b1201 100644
--- a/drivers/serial/serial_pic32.c
+++ b/drivers/serial/serial_pic32.c
@@ -176,7 +176,6 @@ U_BOOT_DRIVER(pic32_serial) = {
176 .of_match = pic32_uart_ids, 176 .of_match = pic32_uart_ids,
177 .probe = pic32_uart_probe, 177 .probe = pic32_uart_probe,
178 .ops = &pic32_uart_ops, 178 .ops = &pic32_uart_ops,
179 .flags = DM_FLAG_PRE_RELOC,
180 .priv_auto_alloc_size = sizeof(struct pic32_uart_priv), 179 .priv_auto_alloc_size = sizeof(struct pic32_uart_priv),
181}; 180};
182 181
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index 2a5f256184..12512f6578 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -363,7 +363,9 @@ U_BOOT_DRIVER(serial_pl01x) = {
363 .platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata), 363 .platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata),
364 .probe = pl01x_serial_probe, 364 .probe = pl01x_serial_probe,
365 .ops = &pl01x_serial_ops, 365 .ops = &pl01x_serial_ops,
366#if !CONFIG_IS_ENABLED(OF_CONTROL)
366 .flags = DM_FLAG_PRE_RELOC, 367 .flags = DM_FLAG_PRE_RELOC,
368#endif
367 .priv_auto_alloc_size = sizeof(struct pl01x_priv), 369 .priv_auto_alloc_size = sizeof(struct pl01x_priv),
368}; 370};
369 371
diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c
index faea6d4c99..e3160cf1bd 100644
--- a/drivers/serial/serial_s5p.c
+++ b/drivers/serial/serial_s5p.c
@@ -211,7 +211,6 @@ U_BOOT_DRIVER(serial_s5p) = {
211 .platdata_auto_alloc_size = sizeof(struct s5p_serial_platdata), 211 .platdata_auto_alloc_size = sizeof(struct s5p_serial_platdata),
212 .probe = s5p_serial_probe, 212 .probe = s5p_serial_probe,
213 .ops = &s5p_serial_ops, 213 .ops = &s5p_serial_ops,
214 .flags = DM_FLAG_PRE_RELOC,
215}; 214};
216#endif 215#endif
217 216
diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c
index b1534981f8..c934d5f25a 100644
--- a/drivers/serial/serial_sh.c
+++ b/drivers/serial/serial_sh.c
@@ -247,7 +247,9 @@ U_BOOT_DRIVER(serial_sh) = {
247 .platdata_auto_alloc_size = sizeof(struct sh_serial_platdata), 247 .platdata_auto_alloc_size = sizeof(struct sh_serial_platdata),
248 .probe = sh_serial_probe, 248 .probe = sh_serial_probe,
249 .ops = &sh_serial_ops, 249 .ops = &sh_serial_ops,
250#if !CONFIG_IS_ENABLED(OF_CONTROL)
250 .flags = DM_FLAG_PRE_RELOC, 251 .flags = DM_FLAG_PRE_RELOC,
252#endif
251 .priv_auto_alloc_size = sizeof(struct uart_port), 253 .priv_auto_alloc_size = sizeof(struct uart_port),
252}; 254};
253 255
diff --git a/drivers/serial/serial_sti_asc.c b/drivers/serial/serial_sti_asc.c
index 5dfc6171eb..c972f1e9af 100644
--- a/drivers/serial/serial_sti_asc.c
+++ b/drivers/serial/serial_sti_asc.c
@@ -205,6 +205,5 @@ U_BOOT_DRIVER(serial_sti_asc) = {
205 .ops = &sti_asc_serial_ops, 205 .ops = &sti_asc_serial_ops,
206 .probe = sti_asc_serial_probe, 206 .probe = sti_asc_serial_probe,
207 .priv_auto_alloc_size = sizeof(struct sti_asc_serial), 207 .priv_auto_alloc_size = sizeof(struct sti_asc_serial),
208 .flags = DM_FLAG_PRE_RELOC,
209}; 208};
210 209
diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c
index 66e02d5689..31b43ee88d 100644
--- a/drivers/serial/serial_stm32.c
+++ b/drivers/serial/serial_stm32.c
@@ -230,7 +230,9 @@ U_BOOT_DRIVER(serial_stm32) = {
230 .platdata_auto_alloc_size = sizeof(struct stm32x7_serial_platdata), 230 .platdata_auto_alloc_size = sizeof(struct stm32x7_serial_platdata),
231 .ops = &stm32_serial_ops, 231 .ops = &stm32_serial_ops,
232 .probe = stm32_serial_probe, 232 .probe = stm32_serial_probe,
233#if !CONFIG_IS_ENABLED(OF_CONTROL)
233 .flags = DM_FLAG_PRE_RELOC, 234 .flags = DM_FLAG_PRE_RELOC,
235#endif
234}; 236};
235 237
236#ifdef CONFIG_DEBUG_UART_STM32 238#ifdef CONFIG_DEBUG_UART_STM32
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c
index cead3c62f5..1be777bd3b 100644
--- a/drivers/serial/serial_xuartlite.c
+++ b/drivers/serial/serial_xuartlite.c
@@ -109,7 +109,6 @@ U_BOOT_DRIVER(serial_uartlite) = {
109 .platdata_auto_alloc_size = sizeof(struct uartlite_platdata), 109 .platdata_auto_alloc_size = sizeof(struct uartlite_platdata),
110 .probe = uartlite_serial_probe, 110 .probe = uartlite_serial_probe,
111 .ops = &uartlite_serial_ops, 111 .ops = &uartlite_serial_ops,
112 .flags = DM_FLAG_PRE_RELOC,
113}; 112};
114 113
115#ifdef CONFIG_DEBUG_UART_UARTLITE 114#ifdef CONFIG_DEBUG_UART_UARTLITE
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index f689015b4a..7e486a68ff 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -210,7 +210,6 @@ U_BOOT_DRIVER(serial_zynq) = {
210 .platdata_auto_alloc_size = sizeof(struct zynq_uart_platdata), 210 .platdata_auto_alloc_size = sizeof(struct zynq_uart_platdata),
211 .probe = zynq_serial_probe, 211 .probe = zynq_serial_probe,
212 .ops = &zynq_serial_ops, 212 .ops = &zynq_serial_ops,
213 .flags = DM_FLAG_PRE_RELOC,
214}; 213};
215 214
216#ifdef CONFIG_DEBUG_UART_ZYNQ 215#ifdef CONFIG_DEBUG_UART_ZYNQ
diff --git a/drivers/sysreset/sysreset_x86.c b/drivers/sysreset/sysreset_x86.c
index 5943a63854..20b958cfd4 100644
--- a/drivers/sysreset/sysreset_x86.c
+++ b/drivers/sysreset/sysreset_x86.c
@@ -45,5 +45,4 @@ U_BOOT_DRIVER(x86_sysreset) = {
45 .id = UCLASS_SYSRESET, 45 .id = UCLASS_SYSRESET,
46 .of_match = x86_sysreset_ids, 46 .of_match = x86_sysreset_ids,
47 .ops = &x86_sysreset_ops, 47 .ops = &x86_sysreset_ops,
48 .flags = DM_FLAG_PRE_RELOC,
49}; 48};
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index d012cf71a9..d0cfc35306 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -40,6 +40,12 @@ config TIMER_EARLY
40 use an early timer. These functions must be supported by your timer 40 use an early timer. These functions must be supported by your timer
41 driver: timer_early_get_count() and timer_early_get_rate(). 41 driver: timer_early_get_count() and timer_early_get_rate().
42 42
43config AG101P_TIMER
44 bool "AG101P timer support"
45 depends on TIMER && NDS32
46 help
47 Select this to enable a timer for AG01P devices.
48
43config ALTERA_TIMER 49config ALTERA_TIMER
44 bool "Altera timer support" 50 bool "Altera timer support"
45 depends on TIMER 51 depends on TIMER
@@ -47,6 +53,34 @@ config ALTERA_TIMER
47 Select this to enable a timer for Altera devices. Please find 53 Select this to enable a timer for Altera devices. Please find
48 details on the "Embedded Peripherals IP User Guide" of Altera. 54 details on the "Embedded Peripherals IP User Guide" of Altera.
49 55
56config ARC_TIMER
57 bool "ARC timer support"
58 depends on TIMER && ARC && CLK
59 help
60 Select this to enable built-in ARC timers.
61 ARC cores may have up to 2 built-in timers: timer0 and timer1,
62 usually at least one of them exists. Either of them is supported
63 in U-Boot.
64
65config AST_TIMER
66 bool "Aspeed ast2400/ast2500 timer support"
67 depends on TIMER
68 default y if ARCH_ASPEED
69 help
70 Select this to enable timer for Aspeed ast2400/ast2500 devices.
71 This is a simple sys timer driver, it is compatible with lib/time.c,
72 but does not support any interrupts. Even though SoC has 8 hardware
73 counters, they are all treated as a single device by this driver.
74 This is mostly because they all share several registers which
75 makes it difficult to completely separate them.
76
77config ATCPIT100_TIMER
78 bool "ATCPIT100 timer support"
79 depends on TIMER
80 help
81 Select this to enable a ATCPIT100 timer which will be embedded
82 in AE3XX, AE250 boards.
83
50config ATMEL_PIT_TIMER 84config ATMEL_PIT_TIMER
51 bool "Atmel periodic interval timer support" 85 bool "Atmel periodic interval timer support"
52 depends on TIMER 86 depends on TIMER
@@ -69,18 +103,12 @@ config DESIGNWARE_APB_TIMER
69 Enables support for the Designware APB Timer driver. This timer is 103 Enables support for the Designware APB Timer driver. This timer is
70 present on Altera SoCFPGA SoCs. 104 present on Altera SoCFPGA SoCs.
71 105
72config SANDBOX_TIMER 106config MPC83XX_TIMER
73 bool "Sandbox timer support" 107 bool "MPC83xx timer support"
74 depends on SANDBOX && TIMER 108 depends on TIMER
75 help
76 Select this to enable an emulated timer for sandbox. It gets
77 time from host os.
78
79config X86_TSC_TIMER
80 bool "x86 Time-Stamp Counter (TSC) timer support"
81 depends on TIMER && X86
82 help 109 help
83 Select this to enable Time-Stamp Counter (TSC) timer for x86. 110 Select this to enable support for the timer found on
111 devices based on the MPC83xx family of SoCs.
84 112
85config X86_TSC_TIMER_EARLY_FREQ 113config X86_TSC_TIMER_EARLY_FREQ
86 int "x86 TSC timer frequency in MHz when used as the early timer" 114 int "x86 TSC timer frequency in MHz when used as the early timer"
@@ -98,17 +126,19 @@ config OMAP_TIMER
98 help 126 help
99 Select this to enable an timer for Omap devices. 127 Select this to enable an timer for Omap devices.
100 128
101config AST_TIMER 129config ROCKCHIP_TIMER
102 bool "Aspeed ast2400/ast2500 timer support" 130 bool "Rockchip timer support"
103 depends on TIMER 131 depends on TIMER
104 default y if ARCH_ASPEED
105 help 132 help
106 Select this to enable timer for Aspeed ast2400/ast2500 devices. 133 Select this to enable support for the timer found on
107 This is a simple sys timer driver, it is compatible with lib/time.c, 134 Rockchip devices.
108 but does not support any interrupts. Even though SoC has 8 hardware 135
109 counters, they are all treated as a single device by this driver. 136config SANDBOX_TIMER
110 This is mostly because they all share several registers which 137 bool "Sandbox timer support"
111 makes it difficult to completely separate them. 138 depends on SANDBOX && TIMER
139 help
140 Select this to enable an emulated timer for sandbox. It gets
141 time from host os.
112 142
113config STI_TIMER 143config STI_TIMER
114 bool "STi timer support" 144 bool "STi timer support"
@@ -117,47 +147,17 @@ config STI_TIMER
117 help 147 help
118 Select this to enable a timer for STi devices. 148 Select this to enable a timer for STi devices.
119 149
120config ARC_TIMER
121 bool "ARC timer support"
122 depends on TIMER && ARC && CLK
123 help
124 Select this to enable built-in ARC timers.
125 ARC cores may have up to 2 built-in timers: timer0 and timer1,
126 usually at least one of them exists. Either of them is supported
127 in U-Boot.
128
129config AG101P_TIMER
130 bool "AG101P timer support"
131 depends on TIMER && NDS32
132 help
133 Select this to enable a timer for AG01P devices.
134
135config ATCPIT100_TIMER
136 bool "ATCPIT100 timer support"
137 depends on TIMER
138 help
139 Select this to enable a ATCPIT100 timer which will be embeded
140 in AE3XX, AE250 boards.
141
142config ROCKCHIP_TIMER
143 bool "Rockchip timer support"
144 depends on TIMER
145 help
146 Select this to enable support for the timer found on
147 Rockchip devices.
148
149config STM32_TIMER 150config STM32_TIMER
150 bool "STM32 timer support" 151 bool "STM32 timer support"
151 depends on TIMER 152 depends on TIMER
152 help 153 help
153 Select this to enable support for the timer found on 154 Select this to enable support for the timer found on
154 STM32 devices. 155 STM32 devices.
155 156
156config MPC83XX_TIMER 157config X86_TSC_TIMER
157 bool "MPC83xx timer support" 158 bool "x86 Time-Stamp Counter (TSC) timer support"
158 depends on TIMER 159 depends on TIMER && X86
159 help 160 help
160 Select this to enable support for the timer found on 161 Select this to enable Time-Stamp Counter (TSC) timer for x86.
161 devices based on the MPC83xx family of SoCs.
162 162
163endmenu 163endmenu
diff --git a/drivers/timer/ag101p_timer.c b/drivers/timer/ag101p_timer.c
index 6e1ae68b32..6e20b4fc33 100644
--- a/drivers/timer/ag101p_timer.c
+++ b/drivers/timer/ag101p_timer.c
@@ -115,5 +115,4 @@ U_BOOT_DRIVER(altera_timer) = {
115 .platdata_auto_alloc_size = sizeof(struct atftmr_timer_platdata), 115 .platdata_auto_alloc_size = sizeof(struct atftmr_timer_platdata),
116 .probe = atftmr_timer_probe, 116 .probe = atftmr_timer_probe,
117 .ops = &ag101p_timer_ops, 117 .ops = &ag101p_timer_ops,
118 .flags = DM_FLAG_PRE_RELOC,
119}; 118};
diff --git a/drivers/timer/altera_timer.c b/drivers/timer/altera_timer.c
index bc76819674..6f504f7cc4 100644
--- a/drivers/timer/altera_timer.c
+++ b/drivers/timer/altera_timer.c
@@ -92,5 +92,4 @@ U_BOOT_DRIVER(altera_timer) = {
92 .platdata_auto_alloc_size = sizeof(struct altera_timer_platdata), 92 .platdata_auto_alloc_size = sizeof(struct altera_timer_platdata),
93 .probe = altera_timer_probe, 93 .probe = altera_timer_probe,
94 .ops = &altera_timer_ops, 94 .ops = &altera_timer_ops,
95 .flags = DM_FLAG_PRE_RELOC,
96}; 95};
diff --git a/drivers/timer/arc_timer.c b/drivers/timer/arc_timer.c
index cf9671ebbe..8c574ec5af 100644
--- a/drivers/timer/arc_timer.c
+++ b/drivers/timer/arc_timer.c
@@ -107,6 +107,5 @@ U_BOOT_DRIVER(arc_timer) = {
107 .of_match = arc_timer_ids, 107 .of_match = arc_timer_ids,
108 .probe = arc_timer_probe, 108 .probe = arc_timer_probe,
109 .ops = &arc_timer_ops, 109 .ops = &arc_timer_ops,
110 .flags = DM_FLAG_PRE_RELOC,
111 .priv_auto_alloc_size = sizeof(struct arc_timer_priv), 110 .priv_auto_alloc_size = sizeof(struct arc_timer_priv),
112}; 111};
diff --git a/drivers/timer/ast_timer.c b/drivers/timer/ast_timer.c
index 9973506f6b..21ffdbf575 100644
--- a/drivers/timer/ast_timer.c
+++ b/drivers/timer/ast_timer.c
@@ -90,5 +90,4 @@ U_BOOT_DRIVER(ast_timer) = {
90 .priv_auto_alloc_size = sizeof(struct ast_timer_priv), 90 .priv_auto_alloc_size = sizeof(struct ast_timer_priv),
91 .ofdata_to_platdata = ast_timer_ofdata_to_platdata, 91 .ofdata_to_platdata = ast_timer_ofdata_to_platdata,
92 .ops = &ast_timer_ops, 92 .ops = &ast_timer_ops,
93 .flags = DM_FLAG_PRE_RELOC,
94}; 93};
diff --git a/drivers/timer/atcpit100_timer.c b/drivers/timer/atcpit100_timer.c
index f650c1bf66..c5d43b4a4a 100644
--- a/drivers/timer/atcpit100_timer.c
+++ b/drivers/timer/atcpit100_timer.c
@@ -110,5 +110,4 @@ U_BOOT_DRIVER(atcpit100_timer) = {
110 .platdata_auto_alloc_size = sizeof(struct atcpit_timer_platdata), 110 .platdata_auto_alloc_size = sizeof(struct atcpit_timer_platdata),
111 .probe = atcpit_timer_probe, 111 .probe = atcpit_timer_probe,
112 .ops = &atcpit_timer_ops, 112 .ops = &atcpit_timer_ops,
113 .flags = DM_FLAG_PRE_RELOC,
114}; 113};
diff --git a/drivers/timer/atmel_pit_timer.c b/drivers/timer/atmel_pit_timer.c
index 603563d3de..009af2f929 100644
--- a/drivers/timer/atmel_pit_timer.c
+++ b/drivers/timer/atmel_pit_timer.c
@@ -85,5 +85,4 @@ U_BOOT_DRIVER(atmel_pit) = {
85 .platdata_auto_alloc_size = sizeof(struct atmel_pit_platdata), 85 .platdata_auto_alloc_size = sizeof(struct atmel_pit_platdata),
86 .probe = atmel_pit_probe, 86 .probe = atmel_pit_probe,
87 .ops = &atmel_pit_ops, 87 .ops = &atmel_pit_ops,
88 .flags = DM_FLAG_PRE_RELOC,
89}; 88};
diff --git a/drivers/timer/cadence-ttc.c b/drivers/timer/cadence-ttc.c
index 4125a078b3..75263c5375 100644
--- a/drivers/timer/cadence-ttc.c
+++ b/drivers/timer/cadence-ttc.c
@@ -111,5 +111,4 @@ U_BOOT_DRIVER(cadence_ttc) = {
111 .priv_auto_alloc_size = sizeof(struct cadence_ttc_priv), 111 .priv_auto_alloc_size = sizeof(struct cadence_ttc_priv),
112 .probe = cadence_ttc_probe, 112 .probe = cadence_ttc_probe,
113 .ops = &cadence_ttc_ops, 113 .ops = &cadence_ttc_ops,
114 .flags = DM_FLAG_PRE_RELOC,
115}; 114};
diff --git a/drivers/timer/dw-apb-timer.c b/drivers/timer/dw-apb-timer.c
index 031f429acb..085bfb02c5 100644
--- a/drivers/timer/dw-apb-timer.c
+++ b/drivers/timer/dw-apb-timer.c
@@ -83,7 +83,6 @@ U_BOOT_DRIVER(dw_apb_timer) = {
83 .id = UCLASS_TIMER, 83 .id = UCLASS_TIMER,
84 .ops = &dw_apb_timer_ops, 84 .ops = &dw_apb_timer_ops,
85 .probe = dw_apb_timer_probe, 85 .probe = dw_apb_timer_probe,
86 .flags = DM_FLAG_PRE_RELOC,
87 .of_match = dw_apb_timer_ids, 86 .of_match = dw_apb_timer_ids,
88 .ofdata_to_platdata = dw_apb_timer_ofdata_to_platdata, 87 .ofdata_to_platdata = dw_apb_timer_ofdata_to_platdata,
89 .priv_auto_alloc_size = sizeof(struct dw_apb_timer_priv), 88 .priv_auto_alloc_size = sizeof(struct dw_apb_timer_priv),
diff --git a/drivers/timer/mpc83xx_timer.c b/drivers/timer/mpc83xx_timer.c
index 84a9ab072a..8e541109d4 100644
--- a/drivers/timer/mpc83xx_timer.c
+++ b/drivers/timer/mpc83xx_timer.c
@@ -244,6 +244,5 @@ U_BOOT_DRIVER(mpc83xx_timer) = {
244 .of_match = mpc83xx_timer_ids, 244 .of_match = mpc83xx_timer_ids,
245 .probe = mpc83xx_timer_probe, 245 .probe = mpc83xx_timer_probe,
246 .ops = &mpc83xx_timer_ops, 246 .ops = &mpc83xx_timer_ops,
247 .flags = DM_FLAG_PRE_RELOC,
248 .priv_auto_alloc_size = sizeof(struct mpc83xx_timer_priv), 247 .priv_auto_alloc_size = sizeof(struct mpc83xx_timer_priv),
249}; 248};
diff --git a/drivers/timer/omap-timer.c b/drivers/timer/omap-timer.c
index f10df69092..a13fb71165 100644
--- a/drivers/timer/omap-timer.c
+++ b/drivers/timer/omap-timer.c
@@ -104,5 +104,4 @@ U_BOOT_DRIVER(omap_timer) = {
104 .priv_auto_alloc_size = sizeof(struct omap_timer_priv), 104 .priv_auto_alloc_size = sizeof(struct omap_timer_priv),
105 .probe = omap_timer_probe, 105 .probe = omap_timer_probe,
106 .ops = &omap_timer_ops, 106 .ops = &omap_timer_ops,
107 .flags = DM_FLAG_PRE_RELOC,
108}; 107};
diff --git a/drivers/timer/rockchip_timer.c b/drivers/timer/rockchip_timer.c
index 17bf6a44c3..69019740b0 100644
--- a/drivers/timer/rockchip_timer.c
+++ b/drivers/timer/rockchip_timer.c
@@ -163,7 +163,6 @@ U_BOOT_DRIVER(rockchip_rk3368_timer) = {
163 .of_match = rockchip_timer_ids, 163 .of_match = rockchip_timer_ids,
164 .probe = rockchip_timer_probe, 164 .probe = rockchip_timer_probe,
165 .ops = &rockchip_timer_ops, 165 .ops = &rockchip_timer_ops,
166 .flags = DM_FLAG_PRE_RELOC,
167 .priv_auto_alloc_size = sizeof(struct rockchip_timer_priv), 166 .priv_auto_alloc_size = sizeof(struct rockchip_timer_priv),
168#if CONFIG_IS_ENABLED(OF_PLATDATA) 167#if CONFIG_IS_ENABLED(OF_PLATDATA)
169 .platdata_auto_alloc_size = sizeof(struct rockchip_timer_plat), 168 .platdata_auto_alloc_size = sizeof(struct rockchip_timer_plat),
diff --git a/drivers/timer/sti-timer.c b/drivers/timer/sti-timer.c
index f7f0e72fe1..9def7e02f4 100644
--- a/drivers/timer/sti-timer.c
+++ b/drivers/timer/sti-timer.c
@@ -74,5 +74,4 @@ U_BOOT_DRIVER(sti_timer) = {
74 .priv_auto_alloc_size = sizeof(struct sti_timer_priv), 74 .priv_auto_alloc_size = sizeof(struct sti_timer_priv),
75 .probe = sti_timer_probe, 75 .probe = sti_timer_probe,
76 .ops = &sti_timer_ops, 76 .ops = &sti_timer_ops,
77 .flags = DM_FLAG_PRE_RELOC,
78}; 77};
diff --git a/drivers/timer/stm32_timer.c b/drivers/timer/stm32_timer.c
index 9a856b1b5a..76315100e2 100644
--- a/drivers/timer/stm32_timer.c
+++ b/drivers/timer/stm32_timer.c
@@ -132,6 +132,5 @@ U_BOOT_DRIVER(stm32_timer) = {
132 .priv_auto_alloc_size = sizeof(struct stm32_timer_priv), 132 .priv_auto_alloc_size = sizeof(struct stm32_timer_priv),
133 .probe = stm32_timer_probe, 133 .probe = stm32_timer_probe,
134 .ops = &stm32_timer_ops, 134 .ops = &stm32_timer_ops,
135 .flags = DM_FLAG_PRE_RELOC,
136}; 135};
137 136
diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c
index fe73f71819..12ee6eb804 100644
--- a/drivers/timer/timer-uclass.c
+++ b/drivers/timer/timer-uclass.c
@@ -108,7 +108,7 @@ int notrace dm_timer_init(void)
108 * If the timer is not marked to be bound before 108 * If the timer is not marked to be bound before
109 * relocation, bind it anyway. 109 * relocation, bind it anyway.
110 */ 110 */
111 if (!lists_bind_fdt(dm_root(), node, &dev)) { 111 if (!lists_bind_fdt(dm_root(), node, &dev, false)) {
112 ret = device_probe(dev); 112 ret = device_probe(dev);
113 if (ret) 113 if (ret)
114 return ret; 114 return ret;
diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
index da7c812908..ba940ebf1c 100644
--- a/drivers/timer/tsc_timer.c
+++ b/drivers/timer/tsc_timer.c
@@ -424,5 +424,4 @@ U_BOOT_DRIVER(tsc_timer) = {
424 .of_match = tsc_timer_ids, 424 .of_match = tsc_timer_ids,
425 .probe = tsc_timer_probe, 425 .probe = tsc_timer_probe,
426 .ops = &tsc_timer_ops, 426 .ops = &tsc_timer_ops,
427 .flags = DM_FLAG_PRE_RELOC,
428}; 427};
diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c
index 3b8da808bd..1679d20002 100644
--- a/drivers/video/simplefb.c
+++ b/drivers/video/simplefb.c
@@ -68,5 +68,4 @@ U_BOOT_DRIVER(simple_video) = {
68 .id = UCLASS_VIDEO, 68 .id = UCLASS_VIDEO,
69 .of_match = simple_video_ids, 69 .of_match = simple_video_ids,
70 .probe = simple_video_probe, 70 .probe = simple_video_probe,
71 .flags = DM_FLAG_PRE_RELOC,
72}; 71};
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
new file mode 100644
index 0000000000..a9d5fd07b7
--- /dev/null
+++ b/drivers/virtio/Kconfig
@@ -0,0 +1,62 @@
1# SPDX-License-Identifier: GPL-2.0+
2#
3# Copyright (C) 2018, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
4# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
5#
6# VirtIO is a virtualization standard for network and disk device drivers
7# where just the guest's device driver "knows" it is running in a virtual
8# environment, and cooperates with the hypervisor. This enables guests to
9# get high performance network and disk operations, and gives most of the
10# performance benefits of paravirtualization. In the U-Boot case, the guest
11# is U-Boot itself, while the virtual environment are normally QEMU targets
12# like ARM, RISC-V and x86.
13#
14# See http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf for
15# the VirtIO specification v1.0.
16
17menu "VirtIO Drivers"
18
19config VIRTIO
20 bool
21 help
22 This option is selected by any driver which implements the virtio
23 transport, such as CONFIG_VIRTIO_MMIO or CONFIG_VIRTIO_PCI.
24
25config VIRTIO_MMIO
26 bool "Platform bus driver for memory mapped virtio devices"
27 select VIRTIO
28 help
29 This driver provides support for memory mapped virtio
30 platform device driver.
31
32config VIRTIO_PCI
33 bool "PCI driver for virtio devices"
34 depends on DM_PCI
35 select VIRTIO
36 help
37 This driver provides support for virtio based paravirtual device
38 drivers over PCI.
39
40config VIRTIO_SANDBOX
41 bool "Sandbox driver for virtio devices"
42 depends on SANDBOX
43 select VIRTIO
44 help
45 This driver provides support for Sandbox implementation of virtio
46 transport driver which is used for testing purpose only.
47
48config VIRTIO_NET
49 bool "virtio net driver"
50 depends on VIRTIO
51 help
52 This is the virtual net driver for virtio. It can be used with
53 QEMU based targets.
54
55config VIRTIO_BLK
56 bool "virtio block driver"
57 depends on VIRTIO
58 help
59 This is the virtual block driver for virtio. It can be used with
60 QEMU based targets.
61
62endmenu
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
new file mode 100644
index 0000000000..4579044ae3
--- /dev/null
+++ b/drivers/virtio/Makefile
@@ -0,0 +1,11 @@
1# SPDX-License-Identifier: GPL-2.0+
2#
3# Copyright (C) 2018, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
4# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
5
6obj-y += virtio-uclass.o virtio_ring.o
7obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o
8obj-$(CONFIG_VIRTIO_PCI) += virtio_pci_legacy.o virtio_pci_modern.o
9obj-$(CONFIG_VIRTIO_SANDBOX) += virtio_sandbox.o
10obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
11obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
new file mode 100644
index 0000000000..34397d7dbb
--- /dev/null
+++ b/drivers/virtio/virtio-uclass.c
@@ -0,0 +1,369 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2018, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
4 * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
5 *
6 * VirtIO is a virtualization standard for network and disk device drivers
7 * where just the guest's device driver "knows" it is running in a virtual
8 * environment, and cooperates with the hypervisor. This enables guests to
9 * get high performance network and disk operations, and gives most of the
10 * performance benefits of paravirtualization. In the U-Boot case, the guest
11 * is U-Boot itself, while the virtual environment are normally QEMU targets
12 * like ARM, RISC-V and x86.
13 *
14 * See http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf for
15 * the VirtIO specification v1.0.
16 */
17
18#include <common.h>
19#include <dm.h>
20#include <virtio_types.h>
21#include <virtio.h>
22#include <dm/lists.h>
23
24static const char *const virtio_drv_name[VIRTIO_ID_MAX_NUM] = {
25 [VIRTIO_ID_NET] = VIRTIO_NET_DRV_NAME,
26 [VIRTIO_ID_BLOCK] = VIRTIO_BLK_DRV_NAME,
27};
28
29int virtio_get_config(struct udevice *vdev, unsigned int offset,
30 void *buf, unsigned int len)
31{
32 struct dm_virtio_ops *ops;
33
34 ops = virtio_get_ops(vdev->parent);
35
36 return ops->get_config(vdev->parent, offset, buf, len);
37}
38
39int virtio_set_config(struct udevice *vdev, unsigned int offset,
40 void *buf, unsigned int len)
41{
42 struct dm_virtio_ops *ops;
43
44 ops = virtio_get_ops(vdev->parent);
45
46 return ops->set_config(vdev->parent, offset, buf, len);
47}
48
49int virtio_generation(struct udevice *vdev, u32 *counter)
50{
51 struct dm_virtio_ops *ops;
52
53 ops = virtio_get_ops(vdev->parent);
54 if (!ops->generation)
55 return -ENOSYS;
56
57 return ops->generation(vdev->parent, counter);
58}
59
60int virtio_get_status(struct udevice *vdev, u8 *status)
61{
62 struct dm_virtio_ops *ops;
63
64 ops = virtio_get_ops(vdev->parent);
65
66 return ops->get_status(vdev->parent, status);
67}
68
69int virtio_set_status(struct udevice *vdev, u8 status)
70{
71 struct dm_virtio_ops *ops;
72
73 ops = virtio_get_ops(vdev->parent);
74
75 return ops->set_status(vdev->parent, status);
76}
77
78int virtio_reset(struct udevice *vdev)
79{
80 struct dm_virtio_ops *ops;
81
82 ops = virtio_get_ops(vdev->parent);
83
84 return ops->reset(vdev->parent);
85}
86
87int virtio_get_features(struct udevice *vdev, u64 *features)
88{
89 struct dm_virtio_ops *ops;
90
91 ops = virtio_get_ops(vdev->parent);
92
93 return ops->get_features(vdev->parent, features);
94}
95
96int virtio_set_features(struct udevice *vdev)
97{
98 struct dm_virtio_ops *ops;
99
100 ops = virtio_get_ops(vdev->parent);
101
102 return ops->set_features(vdev->parent);
103}
104
105int virtio_find_vqs(struct udevice *vdev, unsigned int nvqs,
106 struct virtqueue *vqs[])
107{
108 struct dm_virtio_ops *ops;
109
110 ops = virtio_get_ops(vdev->parent);
111
112 return ops->find_vqs(vdev->parent, nvqs, vqs);
113}
114
115int virtio_del_vqs(struct udevice *vdev)
116{
117 struct dm_virtio_ops *ops;
118
119 ops = virtio_get_ops(vdev->parent);
120
121 return ops->del_vqs(vdev->parent);
122}
123
124int virtio_notify(struct udevice *vdev, struct virtqueue *vq)
125{
126 struct dm_virtio_ops *ops;
127
128 ops = virtio_get_ops(vdev->parent);
129
130 return ops->notify(vdev->parent, vq);
131}
132
133void virtio_add_status(struct udevice *vdev, u8 status)
134{
135 u8 old;
136
137 if (!virtio_get_status(vdev, &old))
138 virtio_set_status(vdev, old | status);
139}
140
141int virtio_finalize_features(struct udevice *vdev)
142{
143 struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(vdev->parent);
144 u8 status;
145 int ret;
146
147 ret = virtio_set_features(vdev);
148 if (ret)
149 return ret;
150
151 if (uc_priv->legacy)
152 return 0;
153
154 virtio_add_status(vdev, VIRTIO_CONFIG_S_FEATURES_OK);
155 ret = virtio_get_status(vdev, &status);
156 if (ret)
157 return ret;
158 if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) {
159 debug("(%s): device refuses features %x\n", vdev->name, status);
160 return -ENODEV;
161 }
162
163 return 0;
164}
165
166void virtio_driver_features_init(struct virtio_dev_priv *priv,
167 const u32 *feature,
168 u32 feature_size,
169 const u32 *feature_legacy,
170 u32 feature_legacy_size)
171{
172 priv->feature_table = feature;
173 priv->feature_table_size = feature_size;
174 priv->feature_table_legacy = feature_legacy;
175 priv->feature_table_size_legacy = feature_legacy_size;
176}
177
178int virtio_init(void)
179{
180 struct udevice *bus;
181 int ret;
182
183 /* Enumerate all known virtio devices */
184 ret = uclass_first_device(UCLASS_VIRTIO, &bus);
185 if (ret)
186 return ret;
187
188 while (bus) {
189 ret = uclass_next_device(&bus);
190 if (ret)
191 break;
192 }
193
194 return ret;
195}
196
197static int virtio_uclass_pre_probe(struct udevice *udev)
198{
199 struct dm_virtio_ops *ops;
200
201 ops = (struct dm_virtio_ops *)(udev->driver->ops);
202
203 /*
204 * Check virtio transport driver ops here so that we don't need
205 * check these ops each time when the virtio_xxx APIs are called.
206 *
207 * Only generation op is optional. All other ops are must-have.
208 */
209 if (!ops->get_config || !ops->set_config ||
210 !ops->get_status || !ops->set_status ||
211 !ops->get_features || !ops->set_features ||
212 !ops->find_vqs || !ops->del_vqs ||
213 !ops->reset || !ops->notify)
214 return -ENOENT;
215
216 return 0;
217}
218
219static int virtio_uclass_post_probe(struct udevice *udev)
220{
221 struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(udev);
222 char dev_name[30], *str;
223 struct udevice *vdev;
224 int ret;
225
226 if (uc_priv->device > VIRTIO_ID_MAX_NUM) {
227 debug("(%s): virtio device ID %d exceeds maximum num\n",
228 udev->name, uc_priv->device);
229 return 0;
230 }
231
232 if (!virtio_drv_name[uc_priv->device]) {
233 debug("(%s): underlying virtio device driver unavailable\n",
234 udev->name);
235 return 0;
236 }
237
238 snprintf(dev_name, sizeof(dev_name), "%s#%d",
239 virtio_drv_name[uc_priv->device], udev->seq);
240 str = strdup(dev_name);
241 if (!str)
242 return -ENOMEM;
243
244 ret = device_bind_driver(udev, virtio_drv_name[uc_priv->device],
245 str, &vdev);
246 if (ret == -ENOENT) {
247 debug("(%s): no driver configured\n", udev->name);
248 return 0;
249 }
250 if (ret) {
251 free(str);
252 return ret;
253 }
254 device_set_name_alloced(vdev);
255
256 INIT_LIST_HEAD(&uc_priv->vqs);
257
258 return 0;
259}
260
261static int virtio_uclass_child_post_bind(struct udevice *vdev)
262{
263 /* Acknowledge that we've seen the device */
264 virtio_add_status(vdev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
265
266 return 0;
267}
268
269static int virtio_uclass_child_pre_probe(struct udevice *vdev)
270{
271 struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(vdev->parent);
272 u64 device_features;
273 u64 driver_features;
274 u64 driver_features_legacy;
275 int i;
276 int ret;
277
278 /*
279 * Save the real virtio device (eg: virtio-net, virtio-blk) to
280 * the transport (parent) device's uclass priv for future use.
281 */
282 uc_priv->vdev = vdev;
283
284 /*
285 * We always start by resetting the device, in case a previous driver
286 * messed it up. This also tests that code path a little.
287 */
288 ret = virtio_reset(vdev);
289 if (ret)
290 goto err;
291
292 /* We have a driver! */
293 virtio_add_status(vdev, VIRTIO_CONFIG_S_DRIVER);
294
295 /* Figure out what features the device supports */
296 virtio_get_features(vdev, &device_features);
297 debug("(%s) plain device features supported %016llx\n",
298 vdev->name, device_features);
299 if (!(device_features & (1ULL << VIRTIO_F_VERSION_1)))
300 uc_priv->legacy = true;
301
302 /* Figure out what features the driver supports */
303 driver_features = 0;
304 for (i = 0; i < uc_priv->feature_table_size; i++) {
305 unsigned int f = uc_priv->feature_table[i];
306
307 WARN_ON(f >= 64);
308 driver_features |= (1ULL << f);
309 }
310
311 /* Some drivers have a separate feature table for virtio v1.0 */
312 if (uc_priv->feature_table_legacy) {
313 driver_features_legacy = 0;
314 for (i = 0; i < uc_priv->feature_table_size_legacy; i++) {
315 unsigned int f = uc_priv->feature_table_legacy[i];
316
317 WARN_ON(f >= 64);
318 driver_features_legacy |= (1ULL << f);
319 }
320 } else {
321 driver_features_legacy = driver_features;
322 }
323
324 if (uc_priv->legacy) {
325 debug("(%s): legacy virtio device\n", vdev->name);
326 uc_priv->features = driver_features_legacy & device_features;
327 } else {
328 debug("(%s): v1.0 complaint virtio device\n", vdev->name);
329 uc_priv->features = driver_features & device_features;
330 }
331
332 /* Transport features always preserved to pass to finalize_features */
333 for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++)
334 if ((device_features & (1ULL << i)) &&
335 (i == VIRTIO_F_VERSION_1))
336 __virtio_set_bit(vdev->parent, i);
337
338 debug("(%s) final negotiated features supported %016llx\n",
339 vdev->name, uc_priv->features);
340 ret = virtio_finalize_features(vdev);
341 if (ret)
342 goto err;
343
344 return 0;
345
346err:
347 virtio_add_status(vdev, VIRTIO_CONFIG_S_FAILED);
348 return ret;
349}
350
351static int virtio_uclass_child_post_probe(struct udevice *vdev)
352{
353 /* Indicates that the driver is set up and ready to drive the device */
354 virtio_add_status(vdev, VIRTIO_CONFIG_S_DRIVER_OK);
355
356 return 0;
357}
358
359UCLASS_DRIVER(virtio) = {
360 .name = "virtio",
361 .id = UCLASS_VIRTIO,
362 .flags = DM_UC_FLAG_SEQ_ALIAS,
363 .pre_probe = virtio_uclass_pre_probe,
364 .post_probe = virtio_uclass_post_probe,
365 .child_post_bind = virtio_uclass_child_post_bind,
366 .child_pre_probe = virtio_uclass_child_pre_probe,
367 .child_post_probe = virtio_uclass_child_post_probe,
368 .per_device_auto_alloc_size = sizeof(struct virtio_dev_priv),
369};
diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c
new file mode 100644
index 0000000000..e793e34e83
--- /dev/null
+++ b/drivers/virtio/virtio_blk.c
@@ -0,0 +1,137 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2018, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
4 * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
5 */
6
7#include <common.h>
8#include <blk.h>
9#include <dm.h>
10#include <virtio_types.h>
11#include <virtio.h>
12#include <virtio_ring.h>
13#include "virtio_blk.h"
14
15struct virtio_blk_priv {
16 struct virtqueue *vq;
17};
18
19static ulong virtio_blk_do_req(struct udevice *dev, u64 sector,
20 lbaint_t blkcnt, void *buffer, u32 type)
21{
22 struct virtio_blk_priv *priv = dev_get_priv(dev);
23 unsigned int num_out = 0, num_in = 0;
24 struct virtio_sg *sgs[3];
25 u8 status;
26 int ret;
27
28 struct virtio_blk_outhdr out_hdr = {
29 .type = cpu_to_virtio32(dev, type),
30 .sector = cpu_to_virtio64(dev, sector),
31 };
32 struct virtio_sg hdr_sg = { &out_hdr, sizeof(out_hdr) };
33 struct virtio_sg data_sg = { buffer, blkcnt * 512 };
34 struct virtio_sg status_sg = { &status, sizeof(status) };
35
36 sgs[num_out++] = &hdr_sg;
37
38 if (type & VIRTIO_BLK_T_OUT)
39 sgs[num_out++] = &data_sg;
40 else
41 sgs[num_out + num_in++] = &data_sg;
42
43 sgs[num_out + num_in++] = &status_sg;
44
45 ret = virtqueue_add(priv->vq, sgs, num_out, num_in);
46 if (ret)
47 return ret;
48
49 virtqueue_kick(priv->vq);
50
51 while (!virtqueue_get_buf(priv->vq, NULL))
52 ;
53
54 return status == VIRTIO_BLK_S_OK ? blkcnt : -EIO;
55}
56
57static ulong virtio_blk_read(struct udevice *dev, lbaint_t start,
58 lbaint_t blkcnt, void *buffer)
59{
60 return virtio_blk_do_req(dev, start, blkcnt, buffer,
61 VIRTIO_BLK_T_IN);
62}
63
64static ulong virtio_blk_write(struct udevice *dev, lbaint_t start,
65 lbaint_t blkcnt, const void *buffer)
66{
67 return virtio_blk_do_req(dev, start, blkcnt, (void *)buffer,
68 VIRTIO_BLK_T_OUT);
69}
70
71static int virtio_blk_bind(struct udevice *dev)
72{
73 struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(dev->parent);
74 struct blk_desc *desc = dev_get_uclass_platdata(dev);
75 int devnum;
76
77 desc->if_type = IF_TYPE_VIRTIO;
78 /*
79 * Initialize the devnum to -ENODEV. This is to make sure that
80 * blk_next_free_devnum() works as expected, since the default
81 * value 0 is a valid devnum.
82 */
83 desc->devnum = -ENODEV;
84 devnum = blk_next_free_devnum(IF_TYPE_VIRTIO);
85 if (devnum < 0)
86 return devnum;
87 desc->devnum = devnum;
88 desc->part_type = PART_TYPE_UNKNOWN;
89 /*
90 * virtio mmio transport supplies string identification for us,
91 * while pci trnasport uses a 2-byte subvendor value.
92 */
93 if (uc_priv->vendor >> 16)
94 sprintf(desc->vendor, "%s", (char *)&uc_priv->vendor);
95 else
96 sprintf(desc->vendor, "%04x", uc_priv->vendor);
97 desc->bdev = dev;
98
99 /* Indicate what driver features we support */
100 virtio_driver_features_init(uc_priv, NULL, 0, NULL, 0);
101
102 return 0;
103}
104
105static int virtio_blk_probe(struct udevice *dev)
106{
107 struct virtio_blk_priv *priv = dev_get_priv(dev);
108 struct blk_desc *desc = dev_get_uclass_platdata(dev);
109 u64 cap;
110 int ret;
111
112 ret = virtio_find_vqs(dev, 1, &priv->vq);
113 if (ret)
114 return ret;
115
116 desc->blksz = 512;
117 virtio_cread(dev, struct virtio_blk_config, capacity, &cap);
118 desc->lba = cap;
119
120 return 0;
121}
122
123static const struct blk_ops virtio_blk_ops = {
124 .read = virtio_blk_read,
125 .write = virtio_blk_write,
126};
127
128U_BOOT_DRIVER(virtio_blk) = {
129 .name = VIRTIO_BLK_DRV_NAME,
130 .id = UCLASS_BLK,
131 .ops = &virtio_blk_ops,
132 .bind = virtio_blk_bind,
133 .probe = virtio_blk_probe,
134 .remove = virtio_reset,
135 .priv_auto_alloc_size = sizeof(struct virtio_blk_priv),
136 .flags = DM_FLAG_ACTIVE_DMA,
137};
diff --git a/drivers/virtio/virtio_blk.h b/drivers/virtio/virtio_blk.h
new file mode 100644
index 0000000000..8d8e02fa2e
--- /dev/null
+++ b/drivers/virtio/virtio_blk.h
@@ -0,0 +1,129 @@
1/* SPDX-License-Identifier: BSD-3-Clause */
2/*
3 * Copyright (C) 2018, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
4 * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
5 *
6 * From Linux kernel include/uapi/linux/virtio_blk.h
7 */
8
9#ifndef _LINUX_VIRTIO_BLK_H
10#define _LINUX_VIRTIO_BLK_H
11
12/* Feature bits */
13#define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */
14#define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */
15#define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */
16#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */
17#define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available */
18#define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */
19#define VIRTIO_BLK_F_MQ 12 /* Support more than one vq */
20
21/* Legacy feature bits */
22#ifndef VIRTIO_BLK_NO_LEGACY
23#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
24#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */
25#define VIRTIO_BLK_F_FLUSH 9 /* Flush command supported */
26#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */
27#ifndef __KERNEL__
28/* Old (deprecated) name for VIRTIO_BLK_F_FLUSH */
29#define VIRTIO_BLK_F_WCE VIRTIO_BLK_F_FLUSH
30#endif
31#endif /* !VIRTIO_BLK_NO_LEGACY */
32
33#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */
34
35struct __packed virtio_blk_config {
36 /* The capacity (in 512-byte sectors) */
37 __u64 capacity;
38 /* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */
39 __u32 size_max;
40 /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
41 __u32 seg_max;
42 /* geometry of the device (if VIRTIO_BLK_F_GEOMETRY) */
43 struct virtio_blk_geometry {