summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/bus/Kconfig16
-rw-r--r--drivers/bus/Makefile6
-rw-r--r--drivers/bus/uniphier-system-bus.c100
-rw-r--r--drivers/clk/at91/clk-master.c4
-rw-r--r--drivers/clk/at91/clk-peripheral.c4
-rw-r--r--drivers/clk/at91/pmc.c6
-rw-r--r--drivers/clk/clk-uclass.c11
-rw-r--r--drivers/core/device.c28
-rw-r--r--drivers/core/root.c6
-rw-r--r--drivers/core/simple-bus.c4
-rw-r--r--drivers/gpio/at91_gpio.c4
-rw-r--r--drivers/gpio/da8xx_gpio.c4
-rw-r--r--drivers/gpio/mxs_gpio.c8
-rw-r--r--drivers/gpio/rk_gpio.c4
-rw-r--r--drivers/gpio/sandbox.c6
-rw-r--r--drivers/i2c/rk_i2c.c6
-rw-r--r--drivers/input/cros_ec_keyb.c4
-rw-r--r--drivers/misc/cros_ec_sandbox.c4
-rw-r--r--drivers/misc/irq-uclass.c10
-rw-r--r--drivers/mmc/bcm2835_sdhci.c2
-rw-r--r--drivers/mmc/davinci_mmc.c2
-rw-r--r--drivers/mmc/ftsdc010_mci.c2
-rw-r--r--drivers/mmc/mxsmmc.c7
-rw-r--r--drivers/mmc/rockchip_dw_mmc.c7
-rw-r--r--drivers/mmc/rockchip_sdhci.c2
-rw-r--r--drivers/mtd/nand/raw/denali.c11
-rw-r--r--drivers/mtd/nand/raw/denali.h1
-rw-r--r--drivers/mtd/nand/raw/denali_dt.c8
-rw-r--r--drivers/mtd/spi/sandbox.c2
-rw-r--r--drivers/mtd/spi/sf-uclass.c2
-rw-r--r--drivers/mtd/spi/sf_probe.c6
-rw-r--r--drivers/pci/Kconfig9
-rw-r--r--drivers/pci/Makefile1
-rw-r--r--drivers/pci/pci-rcar-gen3.c8
-rw-r--r--drivers/pci/pci_rom.c22
-rw-r--r--drivers/pci/pcie_brcmstb.c623
-rw-r--r--drivers/pci/pcie_intel_fpga.c3
-rw-r--r--drivers/pinctrl/nxp/pinctrl-mxs.c6
-rw-r--r--drivers/pinctrl/pinctrl-at91.c6
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rk3188.c2
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rk3288.c2
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rk3328.c2
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rk3368.c2
-rw-r--r--drivers/power/pmic/rk8xx.c6
-rw-r--r--drivers/power/regulator/fixed.c4
-rw-r--r--drivers/ram/rockchip/dmc-rk3368.c2
-rw-r--r--drivers/ram/rockchip/sdram_rk3188.c2
-rw-r--r--drivers/ram/rockchip/sdram_rk3288.c2
-rw-r--r--drivers/ram/rockchip/sdram_rk3328.c2
-rw-r--r--drivers/ram/rockchip/sdram_rk3399.c2
-rw-r--r--drivers/reset/Kconfig11
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/reset-raspberrypi.c60
-rw-r--r--drivers/serial/ns16550.c4
-rw-r--r--drivers/serial/sandbox.c10
-rw-r--r--drivers/serial/serial_uniphier.c90
-rw-r--r--drivers/spi/mxs_spi.c8
-rw-r--r--drivers/spi/rk_spi.c10
-rw-r--r--drivers/spi/sandbox_spi.c4
-rw-r--r--drivers/tpm/tpm_tis_sandbox.c4
-rw-r--r--drivers/usb/host/xhci-mem.c5
-rw-r--r--drivers/usb/host/xhci.c35
-rw-r--r--drivers/video/Kconfig31
-rw-r--r--drivers/video/broadwell_igd.c16
-rw-r--r--drivers/video/console_normal.c26
-rw-r--r--drivers/video/console_rotate.c103
-rw-r--r--drivers/video/console_truetype.c43
-rw-r--r--drivers/video/ivybridge_igd.c26
-rw-r--r--drivers/video/rockchip/rk3288_vop.c4
-rw-r--r--drivers/video/sandbox_sdl.c14
-rw-r--r--drivers/video/vesa.c30
-rw-r--r--drivers/video/vidconsole-uclass.c38
-rw-r--r--drivers/video/video-uclass.c93
-rw-r--r--drivers/video/video_bmp.c16
-rw-r--r--drivers/watchdog/at91sam9_wdt.c4
77 files changed, 1459 insertions, 223 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index e34a22708c..7a839fa1aa 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -10,6 +10,8 @@ source "drivers/ata/Kconfig"
source "drivers/axi/Kconfig"
+source "drivers/bus/Kconfig"
+
source "drivers/block/Kconfig"
source "drivers/bootcount/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 94e8c5da17..afd159e903 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -74,6 +74,7 @@ ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TPL_BUILD),)
obj-y += adc/
obj-y += ata/
+obj-y += bus/
obj-$(CONFIG_DM_DEMO) += demo/
obj-$(CONFIG_BIOSEMU) += bios_emulator/
obj-y += block/
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
new file mode 100644
index 0000000000..07a33c6287
--- /dev/null
+++ b/drivers/bus/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Bus Devices
+#
+
+menu "Bus devices"
+
+config UNIPHIER_SYSTEM_BUS
+ bool "UniPhier System Bus driver"
+ depends on ARCH_UNIPHIER
+ default y
+ help
+ Support for UniPhier System Bus, a simple external bus. This is
+ needed to use on-board devices connected to UniPhier SoCs.
+
+endmenu
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
new file mode 100644
index 0000000000..0b97fc1f8b
--- /dev/null
+++ b/drivers/bus/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the bus drivers.
+#
+
+obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o
diff --git a/drivers/bus/uniphier-system-bus.c b/drivers/bus/uniphier-system-bus.c
new file mode 100644
index 0000000000..ea08d66a07
--- /dev/null
+++ b/drivers/bus/uniphier-system-bus.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+#include <linux/types.h>
+#include <dm.h>
+
+/* System Bus Controller registers */
+#define UNIPHIER_SBC_BASE 0x100 /* base address of bank0 space */
+#define UNIPHIER_SBC_BASE_BE BIT(0) /* bank_enable */
+#define UNIPHIER_SBC_CTRL0 0x200 /* timing parameter 0 of bank0 */
+#define UNIPHIER_SBC_CTRL1 0x204 /* timing parameter 1 of bank0 */
+#define UNIPHIER_SBC_CTRL2 0x208 /* timing parameter 2 of bank0 */
+#define UNIPHIER_SBC_CTRL3 0x20c /* timing parameter 3 of bank0 */
+#define UNIPHIER_SBC_CTRL4 0x300 /* timing parameter 4 of bank0 */
+
+#define UNIPHIER_SBC_STRIDE 0x10 /* register stride to next bank */
+
+#if 1
+/* slower but LED works */
+#define SBCTRL0_VALUE 0x55450000
+#define SBCTRL1_VALUE 0x07168d00
+#define SBCTRL2_VALUE 0x34000009
+#define SBCTRL4_VALUE 0x02110110
+
+#else
+/* faster but LED does not work */
+#define SBCTRL0_VALUE 0x55450000
+#define SBCTRL1_VALUE 0x06057700
+/* NOR flash needs more wait counts than SRAM */
+#define SBCTRL2_VALUE 0x34000009
+#define SBCTRL4_VALUE 0x02110210
+#endif
+
+void uniphier_system_bus_set_reg(void __iomem *membase)
+{
+ void __iomem *bank0_base = membase;
+ void __iomem *bank1_base = membase + UNIPHIER_SBC_STRIDE;
+
+ /*
+ * Only CS1 is connected to support card.
+ * BKSZ[1:0] should be set to "01".
+ */
+ writel(SBCTRL0_VALUE, bank1_base + UNIPHIER_SBC_CTRL0);
+ writel(SBCTRL1_VALUE, bank1_base + UNIPHIER_SBC_CTRL1);
+ writel(SBCTRL2_VALUE, bank1_base + UNIPHIER_SBC_CTRL2);
+ writel(SBCTRL4_VALUE, bank1_base + UNIPHIER_SBC_CTRL4);
+
+ if (readl(bank1_base + UNIPHIER_SBC_BASE) & UNIPHIER_SBC_BASE_BE) {
+ /*
+ * Boot Swap On: boot from external NOR/SRAM
+ * 0x42000000-0x43ffffff is a mirror of 0x40000000-0x41ffffff.
+ *
+ * 0x40000000-0x41efffff, 0x42000000-0x43efffff: memory bank
+ * 0x41f00000-0x41ffffff, 0x43f00000-0x43ffffff: peripherals
+ */
+ writel(0x0000bc01, bank0_base + UNIPHIER_SBC_BASE);
+ } else {
+ /*
+ * Boot Swap Off: boot from mask ROM
+ * 0x40000000-0x41ffffff: mask ROM
+ * 0x42000000-0x43efffff: memory bank (31MB)
+ * 0x43f00000-0x43ffffff: peripherals (1MB)
+ */
+ writel(0x0000be01, bank0_base + UNIPHIER_SBC_BASE); /* dummy */
+ writel(0x0200be01, bank0_base + UNIPHIER_SBC_BASE);
+ }
+}
+
+static int uniphier_system_bus_probe(struct udevice *dev)
+{
+ fdt_addr_t base;
+ void __iomem *membase;
+
+ base = dev_read_addr(dev);
+ if (base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ membase = devm_ioremap(dev, base, SZ_1K);
+ if (!membase)
+ return -ENOMEM;
+
+ uniphier_system_bus_set_reg(membase);
+
+ return 0;
+}
+
+static const struct udevice_id uniphier_system_bus_match[] = {
+ { .compatible = "socionext,uniphier-system-bus" },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(uniphier_system_bus_driver) = {
+ .name = "uniphier-system-bus",
+ .id = UCLASS_SIMPLE_BUS,
+ .of_match = uniphier_system_bus_match,
+ .probe = uniphier_system_bus_probe,
+};
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index 4fa33c4715..e078fab7b4 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -25,8 +25,8 @@ static const struct udevice_id at91_master_clk_match[] = {
{}
};
-U_BOOT_DRIVER(at91_master_clk) = {
- .name = "at91-master-clk",
+U_BOOT_DRIVER(atmel_at91rm9200_clk_master) = {
+ .name = "atmel_at91rm9200_clk_master",
.id = UCLASS_CLK,
.of_match = at91_master_clk_match,
.ops = &at91_master_clk_ops,
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index c55e6214b2..cd9d5e77c0 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -43,8 +43,8 @@ static const struct udevice_id sam9x5_periph_clk_match[] = {
{}
};
-U_BOOT_DRIVER(sam9x5_periph_clk) = {
- .name = "sam9x5-periph-clk",
+U_BOOT_DRIVER(atmel_at91rm9200_clk_peripheral) = {
+ .name = "atmel_at91rm9200_clk_peripheral",
.id = UCLASS_MISC,
.of_match = sam9x5_periph_clk_match,
.bind = sam9x5_periph_clk_bind,
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 9d9d77d861..54ae0d281d 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -25,12 +25,14 @@ static const struct udevice_id at91_pmc_match[] = {
{}
};
-U_BOOT_DRIVER(at91_pmc) = {
- .name = "at91-pmc",
+U_BOOT_DRIVER(atmel_at91rm9200_pmc) = {
+ .name = "atmel_at91rm9200_pmc",
.id = UCLASS_SIMPLE_BUS,
.of_match = at91_pmc_match,
};
+U_BOOT_DRIVER_ALIAS(atmel_at91rm9200_pmc, atmel_at91sam9260_pmc)
+
/*---------------------------------------------------------*/
int at91_pmc_core_probe(struct udevice *dev)
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 70df9d410f..15656f5973 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -27,17 +27,16 @@ static inline const struct clk_ops *clk_dev_ops(struct udevice *dev)
#if CONFIG_IS_ENABLED(OF_CONTROL)
# if CONFIG_IS_ENABLED(OF_PLATDATA)
-int clk_get_by_index_platdata(struct udevice *dev, int index,
- struct phandle_1_arg *cells, struct clk *clk)
+int clk_get_by_driver_info(struct udevice *dev, struct phandle_1_arg *cells,
+ struct clk *clk)
{
int ret;
- if (index != 0)
- return -ENOSYS;
- ret = uclass_get_device(UCLASS_CLK, 0, &clk->dev);
+ ret = device_get_by_driver_info((struct driver_info *)cells->node,
+ &clk->dev);
if (ret)
return ret;
- clk->id = cells[0].arg[0];
+ clk->id = cells->arg[0];
return 0;
}
diff --git a/drivers/core/device.c b/drivers/core/device.c
index a7408d9c76..476133f172 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -248,10 +248,11 @@ int device_bind_ofnode(struct udevice *parent, const struct driver *drv,
}
int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
- const struct driver_info *info, struct udevice **devp)
+ struct driver_info *info, struct udevice **devp)
{
struct driver *drv;
uint platdata_size = 0;
+ int ret;
drv = lists_driver_lookup_name(info->name);
if (!drv)
@@ -262,9 +263,16 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
#if CONFIG_IS_ENABLED(OF_PLATDATA)
platdata_size = info->platdata_size;
#endif
- return device_bind_common(parent, drv, info->name,
- (void *)info->platdata, 0, ofnode_null(), platdata_size,
- devp);
+ ret = device_bind_common(parent, drv, info->name,
+ (void *)info->platdata, 0, ofnode_null(),
+ platdata_size, devp);
+ if (ret)
+ return ret;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ info->dev = *devp;
+#endif
+
+ return ret;
}
static void *alloc_priv(int size, uint flags)
@@ -729,6 +737,18 @@ int device_get_global_by_ofnode(ofnode ofnode, struct udevice **devp)
return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
}
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+int device_get_by_driver_info(const struct driver_info *info,
+ struct udevice **devp)
+{
+ struct udevice *dev;
+
+ dev = info->dev;
+
+ return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
+}
+#endif
+
int device_find_first_child(const struct udevice *parent, struct udevice **devp)
{
if (list_empty(&parent->child_head)) {
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 7d257ea887..0de5d7c70d 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -26,7 +26,7 @@
DECLARE_GLOBAL_DATA_PTR;
-static const struct driver_info root_info = {
+static struct driver_info root_info = {
.name = "root_driver",
};
@@ -347,6 +347,10 @@ int dm_init_and_scan(bool pre_reloc_only)
{
int ret;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ dm_populate_phandle_data();
+#endif
+
ret = dm_init(IS_ENABLED(CONFIG_OF_LIVE));
if (ret) {
debug("dm_init() failed: %d\n", ret);
diff --git a/drivers/core/simple-bus.c b/drivers/core/simple-bus.c
index 7fc23ef82d..7cc1d46009 100644
--- a/drivers/core/simple-bus.c
+++ b/drivers/core/simple-bus.c
@@ -56,8 +56,8 @@ static const struct udevice_id generic_simple_bus_ids[] = {
{ }
};
-U_BOOT_DRIVER(simple_bus_drv) = {
- .name = "generic_simple_bus",
+U_BOOT_DRIVER(simple_bus) = {
+ .name = "simple_bus",
.id = UCLASS_SIMPLE_BUS,
.of_match = generic_simple_bus_ids,
.flags = DM_FLAG_PRE_RELOC,
diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c
index 3621cf2408..4a8b2e6ff6 100644
--- a/drivers/gpio/at91_gpio.c
+++ b/drivers/gpio/at91_gpio.c
@@ -624,8 +624,8 @@ static const struct udevice_id at91_gpio_ids[] = {
};
#endif
-U_BOOT_DRIVER(gpio_at91) = {
- .name = "gpio_at91",
+U_BOOT_DRIVER(atmel_at91rm9200_gpio) = {
+ .name = "atmel_at91rm9200_gpio",
.id = UCLASS_GPIO,
#if CONFIG_IS_ENABLED(OF_CONTROL)
.of_match = at91_gpio_ids,
diff --git a/drivers/gpio/da8xx_gpio.c b/drivers/gpio/da8xx_gpio.c
index 0d0e9d2254..ab0a5cfd33 100644
--- a/drivers/gpio/da8xx_gpio.c
+++ b/drivers/gpio/da8xx_gpio.c
@@ -553,8 +553,8 @@ static int davinci_gpio_ofdata_to_platdata(struct udevice *dev)
return 0;
}
-U_BOOT_DRIVER(gpio_davinci) = {
- .name = "gpio_davinci",
+U_BOOT_DRIVER(ti_dm6441_gpio) = {
+ .name = "ti_dm6441_gpio",
.id = UCLASS_GPIO,
.ops = &gpio_davinci_ops,
.ofdata_to_platdata = of_match_ptr(davinci_gpio_ofdata_to_platdata),
diff --git a/drivers/gpio/mxs_gpio.c b/drivers/gpio/mxs_gpio.c
index 815339a156..cb797261b7 100644
--- a/drivers/gpio/mxs_gpio.c
+++ b/drivers/gpio/mxs_gpio.c
@@ -299,12 +299,8 @@ static const struct udevice_id mxs_gpio_ids[] = {
};
#endif
-U_BOOT_DRIVER(gpio_mxs) = {
-#ifdef CONFIG_MX28
- .name = "fsl_imx28_gpio",
-#else /* CONFIG_MX23 */
+U_BOOT_DRIVER(fsl_imx23_gpio) = {
.name = "fsl_imx23_gpio",
-#endif
.id = UCLASS_GPIO,
.ops = &gpio_mxs_ops,
.probe = mxs_gpio_probe,
@@ -315,4 +311,6 @@ U_BOOT_DRIVER(gpio_mxs) = {
.ofdata_to_platdata = mxs_ofdata_to_platdata,
#endif
};
+
+U_BOOT_DRIVER_ALIAS(fsl_imx23_gpio, fsl_imx28_gpio)
#endif /* DM_GPIO */
diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c
index 3d96678a45..8cc288581c 100644
--- a/drivers/gpio/rk_gpio.c
+++ b/drivers/gpio/rk_gpio.c
@@ -172,8 +172,8 @@ static const struct udevice_id rockchip_gpio_ids[] = {
{ }
};
-U_BOOT_DRIVER(gpio_rockchip) = {
- .name = "gpio_rockchip",
+U_BOOT_DRIVER(rockchip_gpio_bank) = {
+ .name = "rockchip_gpio_bank",
.id = UCLASS_GPIO,
.of_match = rockchip_gpio_ids,
.ops = &gpio_rockchip_ops,
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index 98b7fa4bb3..b9a1d65acc 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -244,8 +244,8 @@ static const struct udevice_id sandbox_gpio_ids[] = {
{ }
};
-U_BOOT_DRIVER(gpio_sandbox) = {
- .name = "gpio_sandbox",
+U_BOOT_DRIVER(sandbox_gpio) = {
+ .name = "sandbox_gpio",
.id = UCLASS_GPIO,
.of_match = sandbox_gpio_ids,
.ofdata_to_platdata = sandbox_gpio_ofdata_to_platdata,
@@ -254,6 +254,8 @@ U_BOOT_DRIVER(gpio_sandbox) = {
.ops = &gpio_sandbox_ops,
};
+U_BOOT_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias)
+
/* pincontrol: used only to check GPIO pin configuration (pinmux command) */
struct sb_pinctrl_priv {
diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c
index fa6f69f400..659461088b 100644
--- a/drivers/i2c/rk_i2c.c
+++ b/drivers/i2c/rk_i2c.c
@@ -485,8 +485,8 @@ static const struct udevice_id rockchip_i2c_ids[] = {
{ }
};
-U_BOOT_DRIVER(i2c_rockchip) = {
- .name = "i2c_rockchip",
+U_BOOT_DRIVER(rockchip_rk3066_i2c) = {
+ .name = "rockchip_rk3066_i2c",
.id = UCLASS_I2C,
.of_match = rockchip_i2c_ids,
.ofdata_to_platdata = rockchip_i2c_ofdata_to_platdata,
@@ -494,3 +494,5 @@ U_BOOT_DRIVER(i2c_rockchip) = {
.priv_auto_alloc_size = sizeof(struct rk_i2c),
.ops = &rockchip_i2c_ops,
};
+
+U_BOOT_DRIVER_ALIAS(rockchip_rk3066_i2c, rockchip_rk3288_i2c)
diff --git a/drivers/input/cros_ec_keyb.c b/drivers/input/cros_ec_keyb.c
index 6f12ec8b0a..00bf58f2b5 100644
--- a/drivers/input/cros_ec_keyb.c
+++ b/drivers/input/cros_ec_keyb.c
@@ -225,8 +225,8 @@ static const struct udevice_id cros_ec_kbd_ids[] = {
{ }
};
-U_BOOT_DRIVER(cros_ec_kbd) = {
- .name = "cros_ec_kbd",
+U_BOOT_DRIVER(google_cros_ec_keyb) = {
+ .name = "google_cros_ec_keyb",
.id = UCLASS_KEYBOARD,
.of_match = cros_ec_kbd_ids,
.probe = cros_ec_kbd_probe,
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index c9fa7abd71..a191f061b8 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -572,8 +572,8 @@ static const struct udevice_id cros_ec_ids[] = {
{ }
};
-U_BOOT_DRIVER(cros_ec_sandbox) = {
- .name = "cros_ec_sandbox",
+U_BOOT_DRIVER(google_cros_ec_sandbox) = {
+ .name = "google_cros_ec_sandbox",
.id = UCLASS_CROS_EC,
.of_match = cros_ec_ids,
.probe = cros_ec_probe,
diff --git a/drivers/misc/irq-uclass.c b/drivers/misc/irq-uclass.c
index 16dc0be75c..ec70866cc3 100644
--- a/drivers/misc/irq-uclass.c
+++ b/drivers/misc/irq-uclass.c
@@ -64,17 +64,15 @@ int irq_read_and_clear(struct irq *irq)
}
#if CONFIG_IS_ENABLED(OF_PLATDATA)
-int irq_get_by_index_platdata(struct udevice *dev, int index,
- struct phandle_1_arg *cells, struct irq *irq)
+int irq_get_by_driver_info(struct udevice *dev,
+ struct phandle_1_arg *cells, struct irq *irq)
{
int ret;
- if (index != 0)
- return -ENOSYS;
- ret = uclass_get_device(UCLASS_IRQ, 0, &irq->dev);
+ ret = device_get_by_driver_info(cells->node, &irq->dev);
if (ret)
return ret;
- irq->id = cells[0].arg[0];
+ irq->id = cells->arg[0];
return 0;
}
diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
index dc3dffb657..5cdf3c506f 100644
--- a/drivers/mmc/bcm2835_sdhci.c
+++ b/drivers/mmc/bcm2835_sdhci.c
@@ -210,7 +210,7 @@ static int bcm2835_sdhci_probe(struct udevice *dev)
priv->last_write = 0;
host->name = dev->name;
- host->ioaddr = (void *)base;
+ host->ioaddr = (void *)(uintptr_t)base;
host->quirks = SDHCI_QUIRK_BROKEN_VOLTAGE | SDHCI_QUIRK_BROKEN_R1B |
SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_NO_HISPD_BIT;
host->max_clk = emmc_freq;
diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c
index 4ef9f7cc8b..f3ccd021d8 100644
--- a/drivers/mmc/davinci_mmc.c
+++ b/drivers/mmc/davinci_mmc.c
@@ -522,7 +522,7 @@ static const struct udevice_id davinci_mmc_ids[] = {
{},
};
#endif
-U_BOOT_DRIVER(davinci_mmc_drv) = {
+U_BOOT_DRIVER(ti_da830_mmc) = {
.name = "davinci_mmc",
.id = UCLASS_MMC,
#if CONFIG_IS_ENABLED(OF_CONTROL)
diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c
index b37523e26f..fb28f0166f 100644
--- a/drivers/mmc/ftsdc010_mci.c
+++ b/drivers/mmc/ftsdc010_mci.c
@@ -439,7 +439,7 @@ static int ftsdc010_mmc_probe(struct udevice *dev)
chip->priv = dev;
chip->dev_index = 1;
memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
- ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+ ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->clk);
if (ret < 0)
return ret;
#endif
diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c
index e3c352b44a..c6a06b9ca8 100644
--- a/drivers/mmc/mxsmmc.c
+++ b/drivers/mmc/mxsmmc.c
@@ -711,12 +711,8 @@ static const struct udevice_id mxsmmc_ids[] = {
};
#endif
-U_BOOT_DRIVER(mxsmmc) = {
-#ifdef CONFIG_MX28
- .name = "fsl_imx28_mmc",
-#else /* CONFIG_MX23 */
+U_BOOT_DRIVER(fsl_imx23_mmc) = {
.name = "fsl_imx23_mmc",
-#endif
.id = UCLASS_MMC,
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
.of_match = mxsmmc_ids,
@@ -731,4 +727,5 @@ U_BOOT_DRIVER(mxsmmc) = {
.platdata_auto_alloc_size = sizeof(struct mxsmmc_platdata),
};
+U_BOOT_DRIVER_ALIAS(fsl_imx23_mmc, fsl_imx28_mmc)
#endif /* CONFIG_DM_MMC */
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index 638107a7ff..f1dafa6ce7 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -122,7 +122,7 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
priv->minmax[0] = 400000; /* 400 kHz */
priv->minmax[1] = dtplat->max_frequency;
- ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+ ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->clk);
if (ret < 0)
return ret;
#else
@@ -168,7 +168,7 @@ static const struct udevice_id rockchip_dwmmc_ids[] = {
{ }
};
-U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
+U_BOOT_DRIVER(rockchip_rk3288_dw_mshc) = {
.name = "rockchip_rk3288_dw_mshc",
.id = UCLASS_MMC,
.of_match = rockchip_dwmmc_ids,
@@ -180,6 +180,9 @@ U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
.platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat),
};
+U_BOOT_DRIVER_ALIAS(rockchip_rk3288_dw_mshc, rockchip_rk3328_dw_mshc)
+U_BOOT_DRIVER_ALIAS(rockchip_rk3288_dw_mshc, rockchip_rk3368_dw_mshc)
+
#ifdef CONFIG_PWRSEQ
static int rockchip_dwmmc_pwrseq_set_power(struct udevice *dev, bool enable)
{
diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index b440996b26..b073f1a08d 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -46,7 +46,7 @@ static int arasan_sdhci_probe(struct udevice *dev)
host->name = dev->name;
host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
max_frequency = dtplat->max_frequency;
- ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk);
+ ret = clk_get_by_driver_info(dev, dtplat->clocks, &clk);
#else
max_frequency = dev_read_u32_default(dev, "max-frequency", 0);
ret = clk_get_by_index(dev, 0, &clk);
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
index 15e90291de..ab91db8546 100644
--- a/drivers/mtd/nand/raw/denali.c
+++ b/drivers/mtd/nand/raw/denali.c
@@ -1220,6 +1220,17 @@ static int denali_multidev_fixup(struct denali_nand_info *denali)
return 0;
}
+int denali_wait_reset_complete(struct denali_nand_info *denali)
+{
+ u32 irq_status;
+
+ irq_status = denali_wait_for_irq(denali, INTR__RST_COMP);
+ if (!(irq_status & INTR__RST_COMP))
+ return -EIO;
+
+ return 0;
+}
+
int denali_init(struct denali_nand_info *denali)
{
struct nand_chip *chip = &denali->nand;
diff --git a/drivers/mtd/nand/raw/denali.h b/drivers/mtd/nand/raw/denali.h
index 019deda094..6cd02b2e26 100644
--- a/drivers/mtd/nand/raw/denali.h
+++ b/drivers/mtd/nand/raw/denali.h
@@ -321,6 +321,7 @@ struct denali_nand_info {
#define DENALI_CAP_DMA_64BIT BIT(1)
int denali_calc_ecc_bytes(int step_size, int strength);
+int denali_wait_reset_complete(struct denali_nand_info *denali);
int denali_init(struct denali_nand_info *denali);
#endif /* __DENALI_H__ */
diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c
index 2728e8098f..8318ff507f 100644
--- a/drivers/mtd/nand/raw/denali_dt.c
+++ b/drivers/mtd/nand/raw/denali_dt.c
@@ -148,6 +148,8 @@ static int denali_dt_probe(struct udevice *dev)
if (ret) {
dev_warn(dev, "Can't get reset: %d\n", ret);
} else {
+ reset_assert_bulk(&resets);
+ udelay(2);
reset_deassert_bulk(&resets);
/*
@@ -155,7 +157,11 @@ static int denali_dt_probe(struct udevice *dev)
* kicked (bootstrap process). The driver must wait until it is
* finished. Otherwise, it will result in unpredictable behavior.
*/
- udelay(200);
+ ret = denali_wait_reset_complete(denali);
+ if (ret) {
+ dev_err(denali->dev, "reset not completed.\n");
+ return ret;
+ }
}
return denali_init(denali);
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 8cbe97ee20..0b602dc914 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -44,7 +44,6 @@ enum sandbox_sf_state {
SF_WRITE_STATUS, /* write the flash's status register */
};
-#if CONFIG_IS_ENABLED(LOG)
static const char *sandbox_sf_state_name(enum sandbox_sf_state state)
{
static const char * const states[] = {
@@ -53,7 +52,6 @@ static const char *sandbox_sf_state_name(enum sandbox_sf_state state)
};
return states[state];
}
-#endif /* LOG */
/* Bits for the status register */
#define STAT_WIP (1 << 0)
diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
index 9ce2ecb99a..09c11439b0 100644
--- a/drivers/mtd/spi/sf-uclass.c
+++ b/drivers/mtd/spi/sf-uclass.c
@@ -68,7 +68,7 @@ int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
str = strdup(name);
#endif
ret = spi_get_bus_and_cs(busnum, cs, max_hz, spi_mode,
- "spi_flash_std", str, &bus, &slave);
+ "jedec_spi_nor", str, &bus, &slave);
if (ret)
return ret;
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index afda241dd0..475f6c31db 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -160,8 +160,8 @@ static const struct udevice_id spi_flash_std_ids[] = {
{ }
};
-U_BOOT_DRIVER(spi_flash_std) = {
- .name = "spi_flash_std",
+U_BOOT_DRIVER(jedec_spi_nor) = {
+ .name = "jedec_spi_nor",
.id = UCLASS_SPI_FLASH,
.of_match = spi_flash_std_ids,
.probe = spi_flash_std_probe,
@@ -170,4 +170,6 @@ U_BOOT_DRIVER(spi_flash_std) = {
.ops = &spi_flash_std_ops,
};
+U_BOOT_DRIVER_ALIAS(jedec_spi_nor, spansion_m25p16)
+
#endif /* CONFIG_DM_SPI_FLASH */
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 6d8c22aacf..7e1e51d9ea 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -205,4 +205,13 @@ config PCIE_ROCKCHIP
Say Y here if you want to enable PCIe controller support on
Rockchip SoCs.
+config PCI_BRCMSTB
+ bool "Broadcom STB PCIe controller"
+ depends on DM_PCI
+ depends on ARCH_BCM283X
+ help
+ Say Y here if you want to enable support for PCIe controller
+ on Broadcom set-top-box (STB) SoCs.
+ This driver currently supports only BCM2711 SoC and RC mode
+ of the controller.
endif
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 955351c5c2..29092916a6 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -44,3 +44,4 @@ obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o
obj-$(CONFIG_PCI_KEYSTONE) += pcie_dw_ti.o
obj-$(CONFIG_PCIE_MEDIATEK) += pcie_mediatek.o
obj-$(CONFIG_PCIE_ROCKCHIP) += pcie_rockchip.o pcie_rockchip_phy.o
+obj-$(CONFIG_PCI_BRCMSTB) += pcie_brcmstb.o
diff --git a/drivers/pci/pci-rcar-gen3.c b/drivers/pci/pci-rcar-gen3.c
index df7b37a592..1f51854ccc 100644
--- a/drivers/pci/pci-rcar-gen3.c
+++ b/drivers/pci/pci-rcar-gen3.c
@@ -118,14 +118,6 @@
#define RCAR_PCI_MAX_RESOURCES 4
#define MAX_NR_INBOUND_MAPS 6
-#define PCI_EXP_FLAGS 2 /* Capabilities register */
-#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */
-#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */
-#define PCI_EXP_LNKCAP 12 /* Link Capabilities */
-#define PCI_EXP_LNKCAP_DLLLARC 0x00100000 /* Data Link Layer Link Active Reporting Capable */
-#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */
-#define PCI_EXP_SLTCAP_PSN 0xfff80000 /* Physical Slot Number */
-
enum {
RCAR_PCI_ACCESS_READ,
RCAR_PCI_ACCESS_WRITE,
diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index 6a9bc49978..fa29d69e85 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -22,6 +22,8 @@
* Copyright 1997 -- 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*/
+#define LOG_CATEGORY UCLASS_PCI
+
#include <common.h>
#include <bios_emul.h>
#include <bootstage.h>
@@ -344,7 +346,16 @@ int vbe_setup_video_priv(struct vesa_mode_info *vesa,
default:
return -EPROTONOSUPPORT;
}
- plat->base = vesa->phys_base_ptr;
+
+ /* Use double buffering if enabled */
+ if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
+ if (!plat->base)
+ return log_msg_ret("copy", -ENFILE);
+ plat->copy_base = vesa->phys_base_ptr;
+ } else {
+ plat->base = vesa->phys_base_ptr;
+ }
+ log_debug("base = %lx, copy_base = %lx\n", plat->base, plat->copy_base);
plat->size = vesa->bytes_per_scanline * vesa->y_resolution;
return 0;
@@ -372,6 +383,15 @@ int vbe_setup_video(struct udevice *dev, int (*int15_handler)(void))
ret = vbe_setup_video_priv(&mode_info.vesa, uc_priv, plat);
if (ret) {
+ if (ret == -ENFILE) {
+ /*
+ * See video-uclass.c for how to set up reserved memory
+ * in your video driver
+ */
+ log_err("CONFIG_VIDEO_COPY enabled but driver '%s' set up no reserved memory\n",
+ dev->driver->name);
+ }
+
debug("No video mode configured\n");
return ret;
}
diff --git a/drivers/pci/pcie_brcmstb.c b/drivers/pci/pcie_brcmstb.c
new file mode 100644
index 0000000000..dade79e9c8
--- /dev/null
+++ b/drivers/pci/pcie_brcmstb.c
@@ -0,0 +1,623 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Broadcom STB PCIe controller driver
+ *
+ * Copyright (C) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Based on upstream Linux kernel driver:
+ * drivers/pci/controller/pcie-brcmstb.c
+ * Copyright (C) 2009 - 2017 Broadcom
+ *
+ * Based driver by Nicolas Saenz Julienne
+ * Copyright (C) 2020 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <dm/ofnode.h>
+#include <pci.h>
+#include <asm/io.h>
+#include <linux/bitfield.h>
+#include <linux/log2.h>
+#include <linux/iopoll.h>
+
+/* Offset of the mandatory PCIe capability config registers */
+#define BRCM_PCIE_CAP_REGS 0x00ac
+
+/* The PCIe controller register offsets */
+#define PCIE_RC_CFG_VENDOR_SPECIFIC_REG1 0x0188
+#define VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK 0xc
+#define VENDOR_SPECIFIC_REG1_LITTLE_ENDIAN 0x0
+
+#define PCIE_RC_CFG_PRIV1_ID_VAL3 0x043c
+#define CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff
+
+#define PCIE_RC_DL_MDIO_ADDR 0x1100
+#define PCIE_RC_DL_MDIO_WR_DATA 0x1104
+#define PCIE_RC_DL_MDIO_RD_DATA 0x1108
+
+#define PCIE_MISC_MISC_CTRL 0x4008
+#define MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000
+#define MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000
+#define MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000
+#define MISC_CTRL_MAX_BURST_SIZE_128 0x0
+#define MISC_CTRL_SCB0_SIZE_MASK 0xf8000000
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c
+#define PCIE_MEM_WIN0_LO(win) \
+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 4)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI 0x4010
+#define PCIE_MEM_WIN0_HI(win) \
+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 4)
+
+#define PCIE_MISC_RC_BAR1_CONFIG_LO 0x402c
+#define RC_BAR1_CONFIG_LO_SIZE_MASK 0x1f
+
+#define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034
+#define RC_BAR2_CONFIG_LO_SIZE_MASK 0x1f
+#define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038
+
+#define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c
+#define RC_BAR3_CONFIG_LO_SIZE_MASK 0x1f
+
+#define PCIE_MISC_PCIE_STATUS 0x4068
+#define STATUS_PCIE_PORT_MASK 0x80
+#define STATUS_PCIE_PORT_SHIFT 7
+#define STATUS_PCIE_DL_ACTIVE_MASK 0x20
+#define STATUS_PCIE_DL_ACTIVE_SHIFT 5
+#define STATUS_PCIE_PHYLINKUP_MASK 0x10
+#define STATUS_PCIE_PHYLINKUP_SHIFT 4
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070
+#define MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000
+#define MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0
+#define MEM_WIN0_BASE_LIMIT_BASE_HI_SHIFT 12
+#define PCIE_MEM_WIN0_BASE_LIMIT(win) \
+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + ((win) * 4)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI 0x4080
+#define MEM_WIN0_BASE_HI_BASE_MASK 0xff
+#define PCIE_MEM_WIN0_BASE_HI(win) \
+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + ((win) * 8)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084
+#define PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK 0xff
+#define PCIE_MEM_WIN0_LIMIT_HI(win) \
+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
+
+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204
+#define PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2
+#define PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000
+
+#define PCIE_MSI_INTR2_CLR 0x4508
+#define PCIE_MSI_INTR2_MASK_SET 0x4510
+
+#define PCIE_EXT_CFG_DATA 0x8000
+
+#define PCIE_EXT_CFG_INDEX 0x9000
+#define PCIE_EXT_BUSNUM_SHIFT 20
+#define PCIE_EXT_SLOT_SHIFT 15
+#define PCIE_EXT_FUNC_SHIFT 12
+
+#define PCIE_RGR1_SW_INIT_1 0x9210
+#define RGR1_SW_INIT_1_PERST_MASK 0x1
+#define RGR1_SW_INIT_1_INIT_MASK 0x2
+
+/* PCIe parameters */
+#define BRCM_NUM_PCIE_OUT_WINS 4
+
+/* MDIO registers */
+#define MDIO_PORT0 0x0
+#define MDIO_DATA_MASK 0x7fffffff
+#define MDIO_DATA_SHIFT 0
+#define MDIO_PORT_MASK 0xf0000
+#define MDIO_PORT_SHIFT 16
+#define MDIO_REGAD_MASK 0xffff
+#define MDIO_REGAD_SHIFT 0
+#define MDIO_CMD_MASK 0xfff00000
+#define MDIO_CMD_SHIFT 20
+#define MDIO_CMD_READ 0x1
+#define MDIO_CMD_WRITE 0x0
+#define MDIO_DATA_DONE_MASK 0x80000000
+#define SSC_REGS_ADDR 0x1100
+#define SET_ADDR_OFFSET 0x1f
+#define SSC_CNTL_OFFSET 0x2
+#define SSC_CNTL_OVRD_EN_MASK 0x8000
+#define SSC_CNTL_OVRD_VAL_MASK 0x4000
+#define SSC_STATUS_OFFSET 0x1
+#define SSC_STATUS_SSC_MASK 0x400
+#define SSC_STATUS_SSC_SHIFT 10
+#define SSC_STATUS_PLL_LOCK_MASK 0x800
+#define SSC_STATUS_PLL_LOCK_SHIFT 11
+
+/**
+ * struct brcm_pcie - the PCIe controller state
+ * @base: Base address of memory mapped IO registers of the controller
+ * @gen: Non-zero value indicates limitation of the PCIe controller operation
+ * to a specific generation (1, 2 or 3)
+ * @ssc: true indicates active Spread Spectrum Clocking operation
+ */
+struct brcm_pcie {
+ void __iomem *base;
+
+ int gen;
+ bool ssc;
+};
+
+/**
+ * brcm_pcie_encode_ibar_size() - Encode the inbound "BAR" region size
+ * @size: The inbound region size
+ *
+ * This function converts size of the inbound "BAR" region to the non-linear
+ * values of the PCIE_MISC_RC_BAR[123]_CONFIG_LO register SIZE field.
+ *
+ * Return: The encoded inbound region size
+ */
+static int brcm_pcie_encode_ibar_size(u64 size)
+{
+ int log2_in = ilog2(size);
+
+ if (log2_in >= 12 && log2_in <= 15)
+ /* Covers 4KB to 32KB (inclusive) */
+ return (log2_in - 12) + 0x1c;
+ else if (log2_in >= 16 && log2_in <= 37)
+ /* Covers 64KB to 32GB, (inclusive) */
+ return log2_in - 15;
+
+ /* Something is awry so disable */
+ return 0;
+}
+
+/**
+ * brcm_pcie_rc_mode() - Check if PCIe controller is in RC mode
+ * @pcie: Pointer to the PCIe controller state
+ *
+ * The controller is capable of serving in both RC and EP roles.
+ *
+ * Return: true for RC mode, false for EP mode.
+ */
+static bool brcm_pcie_rc_mode(struct brcm_pcie *pcie)
+{
+ u32 val;
+
+ val = readl(pcie->base + PCIE_MISC_PCIE_STATUS);
+
+ return (val & STATUS_PCIE_PORT_MASK) >> STATUS_PCIE_PORT_SHIFT;
+}
+
+/**
+ * brcm_pcie_link_up() - Check whether the PCIe link is up
+ * @pcie: Pointer to the PCIe controller state
+ *
+ * Return: true if the link is up, false otherwise.
+ */
+static bool brcm_pcie_link_up(struct brcm_pcie *pcie)
+{
+ u32 val, dla, plu;
+
+ val = readl(pcie->base + PCIE_MISC_PCIE_STATUS);
+ dla = (val & STATUS_PCIE_DL_ACTIVE_MASK) >> STATUS_PCIE_DL_ACTIVE_SHIFT;
+ plu = (val & STATUS_PCIE_PHYLINKUP_MASK) >> STATUS_PCIE_PHYLINKUP_SHIFT;
+
+ return dla && plu;
+}
+
+static int brcm_pcie_config_address(const struct udevice *dev, pci_dev_t bdf,
+ uint offset, void **paddress)
+{
+ struct brcm_pcie *pcie = dev_get_priv(dev);
+ unsigned int pci_bus = PCI_BUS(bdf);
+ unsigned int pci_dev = PCI_DEV(bdf);
+ unsigned int pci_func = PCI_FUNC(bdf);
+ int idx;
+
+ /*
+ * Busses 0 (host PCIe bridge) and 1 (its immediate child)
+ * are limited to a single device each
+ */
+ if (pci_bus < 2 && pci_dev > 0)
+ return -EINVAL;
+
+ /* Accesses to the RC go right to the RC registers */
+ if (pci_bus == 0) {
+ *paddress = pcie->base + offset;
+ return 0;
+ }
+
+ /* For devices, write to the config space index register */
+ idx = (pci_bus << PCIE_EXT_BUSNUM_SHIFT)
+ | (pci_dev << PCIE_EXT_SLOT_SHIFT)
+ | (pci_func << PCIE_EXT_FUNC_SHIFT);
+
+ writel(idx, pcie->base + PCIE_EXT_CFG_INDEX);
+ *paddress = pcie->base + PCIE_EXT_CFG_DATA + offset;
+
+ return 0;
+}
+
+static int brcm_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
+ uint offset, ulong *valuep,
+ enum pci_size_t size)
+{
+ return pci_generic_mmap_read_config(bus, brcm_pcie_config_address,
+ bdf, offset, valuep, size);
+}
+
+static int brcm_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
+ uint offset, ulong value,
+ enum pci_size_t size)
+{
+ return pci_generic_mmap_write_config(bus, brcm_pcie_config_address,
+ bdf, offset, value, size);
+}
+
+static const char *link_speed_to_str(unsigned int cls)
+{
+ switch (cls) {
+ case PCI_EXP_LNKSTA_CLS_2_5GB: return "2.5";
+ case PCI_EXP_LNKSTA_CLS_5_0GB: return "5.0";
+ case PCI_EXP_LNKSTA_CLS_8_0GB: return "8.0";
+ default:
+ break;
+ }
+
+ return "??";
+}
+
+static u32 brcm_pcie_mdio_form_pkt(unsigned int port, unsigned int regad,
+ unsigned int cmd)
+{
+ u32 pkt;
+
+ pkt = (port << MDIO_PORT_SHIFT) & MDIO_PORT_MASK;
+ pkt |= (regad << MDIO_REGAD_SHIFT) & MDIO_REGAD_MASK;
+ pkt |= (cmd << MDIO_CMD_SHIFT) & MDIO_CMD_MASK;
+
+ return pkt;
+}
+
+/**
+ * brcm_pcie_mdio_read() - Perform a register read on the internal MDIO bus
+ * @base: Pointer to the PCIe controller IO registers
+ * @port: The MDIO port number
+ * @regad: The register address
+ * @val: A pointer at which to store the read value
+ *
+ * Return: 0 on success and register value in @val, negative error value
+ * on failure.
+ */
+static int brcm_pcie_mdio_read(void __iomem *base, unsigned int port,
+ unsigned int regad, u32 *val)
+{
+ u32 data, addr;
+ int ret;
+
+ addr = brcm_pcie_mdio_form_pkt(port, regad, MDIO_CMD_READ);
+ writel(addr, base + PCIE_RC_DL_MDIO_ADDR);
+ readl(base + PCIE_RC_DL_MDIO_ADDR);
+
+ ret = readl_poll_timeout(base + PCIE_RC_DL_MDIO_RD_DATA, data,
+ (data & MDIO_DATA_DONE_MASK), 100);
+
+ *val = data & MDIO_DATA_MASK;
+
+ return ret;
+}
+
+/**
+ * brcm_pcie_mdio_write() - Perform a register write on the internal MDIO bus
+ * @base: Pointer to the PCIe controller IO registers
+ * @port: The MDIO port number
+ * @regad: Address of the register
+ * @wrdata: The value to write
+ *
+ * Return: 0 on success, negative error value on failure.
+ */
+static int brcm_pcie_mdio_write(void __iomem *base, unsigned int port,
+ unsigned int regad, u16 wrdata)
+{
+ u32 data, addr;
+
+ addr = brcm_pcie_mdio_form_pkt(port, regad, MDIO_CMD_WRITE);
+ writel(addr, base + PCIE_RC_DL_MDIO_ADDR);
+ readl(base + PCIE_RC_DL_MDIO_ADDR);
+ writel(MDIO_DATA_DONE_MASK | wrdata, base + PCIE_RC_DL_MDIO_WR_DATA);
+
+ return readl_poll_timeout(base + PCIE_RC_DL_MDIO_WR_DATA, data,
+ !(data & MDIO_DATA_DONE_MASK), 100);
+}
+
+/**
+ * brcm_pcie_set_ssc() - Configure the controller for Spread Spectrum Clocking
+ * @base: pointer to the PCIe controller IO registers
+ *
+ * Return: 0 on success, negative error value on failure.
+ */
+static int brcm_pcie_set_ssc(void __iomem *base)
+{
+ int pll, ssc;
+ int ret;
+ u32 tmp;
+
+ ret = brcm_pcie_mdio_write(base, MDIO_PORT0, SET_ADDR_OFFSET,
+ SSC_REGS_ADDR);
+ if (ret < 0)
+ return ret;
+
+ ret = brcm_pcie_mdio_read(base, MDIO_PORT0, SSC_CNTL_OFFSET, &tmp);
+ if (ret < 0)
+ return ret;
+
+ tmp |= (SSC_CNTL_OVRD_EN_MASK | SSC_CNTL_OVRD_VAL_MASK);
+
+ ret = brcm_pcie_mdio_write(base, MDIO_PORT0, SSC_CNTL_OFFSET, tmp);
+ if (ret < 0)
+ return ret;
+
+ udelay(1000);
+ ret = brcm_pcie_mdio_read(base, MDIO_PORT0, SSC_STATUS_OFFSET, &tmp);
+ if (ret < 0)
+ return ret;
+
+ ssc = (tmp & SSC_STATUS_SSC_MASK) >> SSC_STATUS_SSC_SHIFT;
+ pll = (tmp & SSC_STATUS_PLL_LOCK_MASK) >> SSC_STATUS_PLL_LOCK_SHIFT;
+
+ return ssc && pll ? 0 : -EIO;
+}
+
+/**
+ * brcm_pcie_set_gen() - Limits operation to a specific generation (1, 2 or 3)
+ * @pcie: pointer to the PCIe controller state
+ * @gen: PCIe generation to limit the controller's operation to
+ */
+static void brcm_pcie_set_gen(struct brcm_pcie *pcie, unsigned int gen)
+{
+ void __iomem *cap_base = pcie->base + BRCM_PCIE_CAP_REGS;
+
+ u16 lnkctl2 = readw(cap_base + PCI_EXP_LNKCTL2);
+ u32 lnkcap = readl(cap_base + PCI_EXP_LNKCAP);
+
+ lnkcap = (lnkcap & ~PCI_EXP_LNKCAP_SLS) | gen;
+ writel(lnkcap, cap_base + PCI_EXP_LNKCAP);
+
+ lnkctl2 = (lnkctl2 & ~0xf) | gen;
+ writew(lnkctl2, cap_base + PCI_EXP_LNKCTL2);
+}
+
+static void brcm_pcie_set_outbound_win(struct brcm_pcie *pcie,
+ unsigned int win, u64 phys_addr,
+ u64 pcie_addr, u64 size)
+{
+ void __iomem *base = pcie->base;
+ u32 phys_addr_mb_high, limit_addr_mb_high;
+ phys_addr_t phys_addr_mb, limit_addr_mb;
+ int high_addr_shift;
+ u32 tmp;
+
+ /* Set the base of the pcie_addr window */
+ writel(lower_32_bits(pcie_addr), base + PCIE_MEM_WIN0_LO(win));
+ writel(upper_32_bits(pcie_addr), base + PCIE_MEM_WIN0_HI(win));
+
+ /* Write the addr base & limit lower bits (in MBs) */
+ phys_addr_mb = phys_addr / SZ_1M;
+ limit_addr_mb = (phys_addr + size - 1) / SZ_1M;
+
+ tmp = readl(base + PCIE_MEM_WIN0_BASE_LIMIT(win));
+ u32p_replace_bits(&tmp, phys_addr_mb,
+ MEM_WIN0_BASE_LIMIT_BASE_MASK);
+ u32p_replace_bits(&tmp, limit_addr_mb,
+ MEM_WIN0_BASE_LIMIT_LIMIT_MASK);
+ writel(tmp, base + PCIE_MEM_WIN0_BASE_LIMIT(win));
+
+ /* Write the cpu & limit addr upper bits */
+ high_addr_shift = MEM_WIN0_BASE_LIMIT_BASE_HI_SHIFT;
+ phys_addr_mb_high = phys_addr_mb >> high_addr_shift;
+ tmp = readl(base + PCIE_MEM_WIN0_BASE_HI(win));
+ u32p_replace_bits(&tmp, phys_addr_mb_high,
+ MEM_WIN0_BASE_HI_BASE_MASK);
+ writel(tmp, base + PCIE_MEM_WIN0_BASE_HI(win));
+
+ limit_addr_mb_high = limit_addr_mb >> high_addr_shift;
+ tmp = readl(base + PCIE_MEM_WIN0_LIMIT_HI(win));
+ u32p_replace_bits(&tmp, limit_addr_mb_high,
+ PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK);
+ writel(tmp, base + PCIE_MEM_WIN0_LIMIT_HI(win));
+}
+
+static int brcm_pcie_probe(struct udevice *dev)
+{
+ struct udevice *ctlr = pci_get_controller(dev);
+ struct pci_controller *hose = dev_get_uclass_priv(ctlr);
+ struct brcm_pcie *pcie = dev_get_priv(dev);
+ void __iomem *base = pcie->base;
+ bool ssc_good = false;
+ int num_out_wins = 0;
+ u64 rc_bar2_offset, rc_bar2_size;
+ unsigned int scb_size_val;
+ int i, ret;
+ u16 nlw, cls, lnksta;
+ u32 tmp;
+
+ /*
+ * Reset the bridge, assert the fundamental reset. Note for some SoCs,
+ * e.g. BCM7278, the fundamental reset should not be asserted here.
+ * This will need to be changed when support for other SoCs is added.
+ */
+ setbits_le32(base + PCIE_RGR1_SW_INIT_1,
+ RGR1_SW_INIT_1_INIT_MASK | RGR1_SW_INIT_1_PERST_MASK);
+ /*
+ * The delay is a safety precaution to preclude the reset signal
+ * from looking like a glitch.
+ */
+ udelay(100);
+
+ /* Take the bridge out of reset */
+ clrbits_le32(base + PCIE_RGR1_SW_INIT_1, RGR1_SW_INIT_1_INIT_MASK);
+
+ clrbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,
+ PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);
+
+ /* Wait for SerDes to be stable */
+ udelay(100);
+
+ /* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */
+ clrsetbits_le32(base + PCIE_MISC_MISC_CTRL,
+ MISC_CTRL_MAX_BURST_SIZE_MASK,
+ MISC_CTRL_SCB_ACCESS_EN_MASK |
+ MISC_CTRL_CFG_READ_UR_MODE_MASK |
+ MISC_CTRL_MAX_BURST_SIZE_128);
+ /*
+ * TODO: When support for other SoCs than BCM2711 is added we may
+ * need to use the base address and size(s) provided in the dma-ranges
+ * property.
+ */
+ rc_bar2_offset = 0;
+ rc_bar2_size = 0xc0000000;
+
+ tmp = lower_32_bits(rc_bar2_offset);
+ u32p_replace_bits(&tmp, brcm_pcie_encode_ibar_size(rc_bar2_size),
+ RC_BAR2_CONFIG_LO_SIZE_MASK);
+ writel(tmp, base + PCIE_MISC_RC_BAR2_CONFIG_LO);
+ writel(upper_32_bits(rc_bar2_offset),
+ base + PCIE_MISC_RC_BAR2_CONFIG_HI);
+
+ scb_size_val = rc_bar2_size ?
+ ilog2(rc_bar2_size) - 15 : 0xf; /* 0xf is 1GB */
+
+ tmp = readl(base + PCIE_MISC_MISC_CTRL);
+ u32p_replace_bits(&tmp, scb_size_val,
+ MISC_CTRL_SCB0_SIZE_MASK);
+ writel(tmp, base + PCIE_MISC_MISC_CTRL);
+
+ /* Disable the PCIe->GISB memory window (RC_BAR1) */
+ clrbits_le32(base + PCIE_MISC_RC_BAR1_CONFIG_LO,
+ RC_BAR1_CONFIG_LO_SIZE_MASK);
+
+ /* Disable the PCIe->SCB memory window (RC_BAR3) */
+ clrbits_le32(base + PCIE_MISC_RC_BAR3_CONFIG_LO,
+ RC_BAR3_CONFIG_LO_SIZE_MASK);
+
+ /* Mask all interrupts since we are not handling any yet */
+ writel(0xffffffff, base + PCIE_MSI_INTR2_MASK_SET);
+
+ /* Clear any interrupts we find on boot */
+ writel(0xffffffff, base + PCIE_MSI_INTR2_CLR);
+
+ if (pcie->gen)
+ brcm_pcie_set_gen(pcie, pcie->gen);
+
+ /* Unassert the fundamental reset */
+ clrbits_le32(pcie->base + PCIE_RGR1_SW_INIT_1,
+ RGR1_SW_INIT_1_PERST_MASK);
+
+ /* Give the RC/EP time to wake up, before trying to configure RC.
+ * Intermittently check status for link-up, up to a total of 100ms.
+ */
+ for (i = 0; i < 100 && !brcm_pcie_link_up(pcie); i += 5)
+ mdelay(5);
+
+ if (!brcm_pcie_link_up(pcie)) {
+ printf("PCIe BRCM: link down\n");
+ return -EINVAL;
+ }
+
+ if (!brcm_pcie_rc_mode(pcie)) {
+ printf("PCIe misconfigured; is in EP mode\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < hose->region_count; i++) {
+ struct pci_region *reg = &hose->regions[i];
+
+ if (reg->flags != PCI_REGION_MEM)
+ continue;
+
+ if (num_out_wins >= BRCM_NUM_PCIE_OUT_WINS)
+ return -EINVAL;
+
+ brcm_pcie_set_outbound_win(pcie, num_out_wins, reg->phys_start,
+ reg->bus_start, reg->size);
+
+ num_out_wins++;
+ }
+
+ /*
+ * For config space accesses on the RC, show the right class for
+ * a PCIe-PCIe bridge (the default setting is to be EP mode).
+ */
+ clrsetbits_le32(base + PCIE_RC_CFG_PRIV1_ID_VAL3,
+ CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK, 0x060400);
+
+ if (pcie->ssc) {
+ ret = brcm_pcie_set_ssc(pcie->base);
+ if (!ret)
+ ssc_good = true;
+ else
+ printf("PCIe BRCM: failed attempt to enter SSC mode\n");
+ }
+
+ lnksta = readw(base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKSTA);
+ cls = lnksta & PCI_EXP_LNKSTA_CLS;
+ nlw = (lnksta & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT;
+
+ printf("PCIe BRCM: link up, %s Gbps x%u %s\n", link_speed_to_str(cls),
+ nlw, ssc_good ? "(SSC)" : "(!SSC)");
+
+ /* PCIe->SCB endian mode for BAR */
+ clrsetbits_le32(base + PCIE_RC_CFG_VENDOR_SPECIFIC_REG1,
+ VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK,
+ VENDOR_SPECIFIC_REG1_LITTLE_ENDIAN);
+ /*
+ * Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1
+ * is enabled => setting the CLKREQ_DEBUG_ENABLE field to 1.
+ */
+ setbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,
+ PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK);
+
+ return 0;
+}
+
+static int brcm_pcie_ofdata_to_platdata(struct udevice *dev)
+{
+ struct brcm_pcie *pcie = dev_get_priv(dev);
+ ofnode dn = dev_ofnode(dev);
+ u32 max_link_speed;
+ int ret;
+
+ /* Get the controller base address */
+ pcie->base = dev_read_addr_ptr(dev);
+ if (!pcie->base)
+ return -EINVAL;
+
+ pcie->ssc = ofnode_read_bool(dn, "brcm,enable-ssc");
+
+ ret = ofnode_read_u32(dn, "max-link-speed", &max_link_speed);
+ if (ret < 0 || max_link_speed > 4)
+ pcie->gen = 0;
+ else
+ pcie->gen = max_link_speed;
+
+ return 0;
+}
+
+static const struct dm_pci_ops brcm_pcie_ops = {
+ .read_config = brcm_pcie_read_config,
+ .write_config = brcm_pcie_write_config,
+};
+
+static const struct udevice_id brcm_pcie_ids[] = {
+ { .compatible = "brcm,bcm2711-pcie" },
+ { }
+};
+
+U_BOOT_DRIVER(pcie_brcm_base) = {
+ .name = "pcie_brcm",
+ .id = UCLASS_PCI,
+ .ops = &brcm_pcie_ops,
+ .of_match = brcm_pcie_ids,
+ .probe = brcm_pcie_probe,
+ .ofdata_to_platdata = brcm_pcie_ofdata_to_platdata,
+ .priv_auto_alloc_size = sizeof(struct brcm_pcie),
+};
diff --git a/drivers/pci/pcie_intel_fpga.c b/drivers/pci/pcie_intel_fpga.c
index aa1903e547..9f102c64c6 100644
--- a/drivers/pci/pcie_intel_fpga.c
+++ b/drivers/pci/pcie_intel_fpga.c
@@ -67,9 +67,6 @@
#define IS_ROOT_PORT(pcie, bdf) \
((PCI_BUS(bdf) == pcie->first_busno) ? true : false)
-#define PCI_EXP_LNKSTA 18 /* Link Status */
-#define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */
-
/**
* struct intel_fpga_pcie - Intel FPGA PCIe controller state
* @bus: Pointer to the PCI bus
diff --git a/drivers/pinctrl/nxp/pinctrl-mxs.c b/drivers/pinctrl/nxp/pinctrl-mxs.c
index a403114f21..db463fc04b 100644
--- a/drivers/pinctrl/nxp/pinctrl-mxs.c
+++ b/drivers/pinctrl/nxp/pinctrl-mxs.c
@@ -180,8 +180,8 @@ static const struct udevice_id mxs_pinctrl_match[] = {
{ /* sentinel */ }
};
-U_BOOT_DRIVER(mxs_pinctrl) = {
- .name = "mxs-pinctrl",
+U_BOOT_DRIVER(fsl_imx23_pinctrl) = {
+ .name = "fsl_imx23_pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(mxs_pinctrl_match),
.probe = mxs_pinctrl_probe,
@@ -191,3 +191,5 @@ U_BOOT_DRIVER(mxs_pinctrl) = {
.priv_auto_alloc_size = sizeof(struct mxs_pinctrl_priv),
.ops = &mxs_pinctrl_ops,
};
+
+U_BOOT_DRIVER_ALIAS(fsl_imx23_pinctrl, fsl_imx28_pinctrl)
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index b3fa124cfb..cd7b32ce34 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -519,11 +519,13 @@ static const struct udevice_id at91_pinctrl_match[] = {
{}
};
-U_BOOT_DRIVER(at91_pinctrl) = {
- .name = "pinctrl_at91",
+U_BOOT_DRIVER(atmel_sama5d3_pinctrl) = {
+ .name = "atmel_sama5d3_pinctrl",
.id = UCLASS_PINCTRL,
.of_match = at91_pinctrl_match,
.probe = at91_pinctrl_probe,
.priv_auto_alloc_size = sizeof(struct at91_pinctrl_priv),
.ops = &at91_pinctrl_ops,
};
+
+U_BOOT_DRIVER_ALIAS(atmel_sama5d3_pinctrl, atmel_at91rm9200_pinctrl)
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3188.c b/drivers/pinctrl/rockchip/pinctrl-rk3188.c
index afde809854..8f197110e5 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3188.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3188.c
@@ -120,7 +120,7 @@ static const struct udevice_id rk3188_pinctrl_ids[] = {
{ }
};
-U_BOOT_DRIVER(pinctrl_rk3188) = {
+U_BOOT_DRIVER(rockchip_rk3188_pinctrl) = {
.name = "rockchip_rk3188_pinctrl",
.id = UCLASS_PINCTRL,
.of_match = rk3188_pinctrl_ids,
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c
index faaa2ce1f7..011ca286ec 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c
@@ -242,7 +242,7 @@ static const struct udevice_id rk3288_pinctrl_ids[] = {
{ }
};
-U_BOOT_DRIVER(pinctrl_rk3288) = {
+U_BOOT_DRIVER(rockchip_rk3288_pinctrl) = {
.name = "rockchip_rk3288_pinctrl",
.id = UCLASS_PINCTRL,
.of_match = rk3288_pinctrl_ids,
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3328.c b/drivers/pinctrl/rockchip/pinctrl-rk3328.c
index f9160f26c7..61eb9e0af0 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3328.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3328.c
@@ -317,7 +317,7 @@ static const struct udevice_id rk3328_pinctrl_ids[] = {
{ }
};
-U_BOOT_DRIVER(pinctrl_rk3328) = {
+U_BOOT_DRIVER(rockchip_rk3328_pinctrl) = {
.name = "rockchip_rk3328_pinctrl",
.id = UCLASS_PINCTRL,
.of_match = rk3328_pinctrl_ids,
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3368.c b/drivers/pinctrl/rockchip/pinctrl-rk3368.c
index 7a6059959e..d8ccd4de57 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3368.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3368.c
@@ -171,7 +171,7 @@ static const struct udevice_id rk3368_pinctrl_ids[] = {
{ }
};
-U_BOOT_DRIVER(pinctrl_rk3368) = {
+U_BOOT_DRIVER(rockchip_rk3368_pinctrl) = {
.name = "rockchip_rk3368_pinctrl",
.id = UCLASS_PINCTRL,
.of_match = rk3368_pinctrl_ids,
diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index 195884bde9..148ee29cca 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -183,8 +183,8 @@ static const struct udevice_id rk8xx_ids[] = {
{ }
};
-U_BOOT_DRIVER(pmic_rk8xx) = {
- .name = "rk8xx pmic",
+U_BOOT_DRIVER(rockchip_rk805) = {
+ .name = "rockchip_rk805",
.id = UCLASS_PMIC,
.of_match = rk8xx_ids,
#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
@@ -194,3 +194,5 @@ U_BOOT_DRIVER(pmic_rk8xx) = {
.probe = rk8xx_probe,
.ops = &rk8xx_ops,
};
+
+U_BOOT_DRIVER_ALIAS(rockchip_rk805, rockchip_rk808)
diff --git a/drivers/power/regulator/fixed.c b/drivers/power/regulator/fixed.c
index f9f9659621..b5f7aec353 100644
--- a/drivers/power/regulator/fixed.c
+++ b/drivers/power/regulator/fixed.c
@@ -82,8 +82,8 @@ static const struct udevice_id fixed_regulator_ids[] = {
{ },
};
-U_BOOT_DRIVER(fixed_regulator) = {
- .name = "fixed regulator",
+U_BOOT_DRIVER(regulator_fixed) = {
+ .name = "regulator_fixed",
.id = UCLASS_REGULATOR,
.ops = &fixed_regulator_ops,
.of_match = fixed_regulator_ids,
diff --git a/drivers/ram/rockchip/dmc-rk3368.c b/drivers/ram/rockchip/dmc-rk3368.c
index 92457a1fa4..4fa632152f 100644
--- a/drivers/ram/rockchip/dmc-rk3368.c
+++ b/drivers/ram/rockchip/dmc-rk3368.c
@@ -992,7 +992,7 @@ static const struct udevice_id rk3368_dmc_ids[] = {
{ }
};
-U_BOOT_DRIVER(dmc_rk3368) = {
+U_BOOT_DRIVER(rockchip_rk3368_dmc) = {
.name = "rockchip_rk3368_dmc",
.id = UCLASS_RAM,
.of_match = rk3368_dmc_ids,
diff --git a/drivers/ram/rockchip/sdram_rk3188.c b/drivers/ram/rockchip/sdram_rk3188.c
index 7aedb4fbac..06f9eba1a5 100644
--- a/drivers/ram/rockchip/sdram_rk3188.c
+++ b/drivers/ram/rockchip/sdram_rk3188.c
@@ -945,7 +945,7 @@ static const struct udevice_id rk3188_dmc_ids[] = {
{ }
};
-U_BOOT_DRIVER(dmc_rk3188) = {
+U_BOOT_DRIVER(rockchip_rk3188_dmc) = {
.name = "rockchip_rk3188_dmc",
.id = UCLASS_RAM,
.of_match = rk3188_dmc_ids,
diff --git a/drivers/ram/rockchip/sdram_rk3288.c b/drivers/ram/rockchip/sdram_rk3288.c
index 64d704ef26..26e8d059b5 100644
--- a/drivers/ram/rockchip/sdram_rk3288.c
+++ b/drivers/ram/rockchip/sdram_rk3288.c
@@ -1113,7 +1113,7 @@ static const struct udevice_id rk3288_dmc_ids[] = {
{ }
};
-U_BOOT_DRIVER(dmc_rk3288) = {
+U_BOOT_DRIVER(rockchip_rk3288_dmc) = {
.name = "rockchip_rk3288_dmc",
.id = UCLASS_RAM,
.of_match = rk3288_dmc_ids,
diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
index 3f3926f9e4..98c7feb6cf 100644
--- a/drivers/ram/rockchip/sdram_rk3328.c
+++ b/drivers/ram/rockchip/sdram_rk3328.c
@@ -606,7 +606,7 @@ static const struct udevice_id rk3328_dmc_ids[] = {
{ }
};
-U_BOOT_DRIVER(dmc_rk3328) = {
+U_BOOT_DRIVER(rockchip_rk3328_dmc) = {
.name = "rockchip_rk3328_dmc",
.id = UCLASS_RAM,
.of_match = rk3328_dmc_ids,
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 60a1ab8b51..0fe2cedc52 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -3128,7 +3128,7 @@ static int rk3399_dmc_init(struct udevice *dev)
priv->cic, priv->pmugrf, priv->pmusgrf, priv->pmucru, priv->pmu);
#if CONFIG_IS_ENABLED(OF_PLATDATA)
- ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->ddr_clk);
+ ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->ddr_clk);
#else
ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
#endif
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 58ba0c686e..6d53561223 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -153,4 +153,15 @@ config RESET_SYSCON
depends on DM_RESET
help
Support generic syscon mapped register reset devices.
+
+config RESET_RASPBERRYPI
+ bool "Raspberry Pi 4 Firmware Reset Controller Driver"
+ depends on DM_RESET && ARCH_BCM283X
+ default USB_XHCI_PCI
+ help
+ Raspberry Pi 4's co-processor controls some of the board's HW
+ initialization process, but it's up to Linux to trigger it when
+ relevant. This driver provides a reset controller capable of
+ interfacing with RPi4's co-processor and model these firmware
+ initialization routines as reset lines.
endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 433f1eca54..8e0124b8de 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o
obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o
+obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
diff --git a/drivers/reset/reset-raspberrypi.c b/drivers/reset/reset-raspberrypi.c
new file mode 100644
index 0000000000..e2d284e5ac
--- /dev/null
+++ b/drivers/reset/reset-raspberrypi.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Raspberry Pi 4 firmware reset driver
+ *
+ * Copyright (C) 2020 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+ */
+#include <common.h>
+#include <dm.h>
+#include <reset-uclass.h>
+#include <asm/arch/msg.h>
+#include <dt-bindings/reset/raspberrypi,firmware-reset.h>
+
+static int raspberrypi_reset_request(struct reset_ctl *reset_ctl)
+{
+ if (reset_ctl->id >= RASPBERRYPI_FIRMWARE_RESET_NUM_IDS)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int raspberrypi_reset_free(struct reset_ctl *reset_ctl)
+{
+ return 0;
+}
+
+static int raspberrypi_reset_assert(struct reset_ctl *reset_ctl)
+{
+ switch (reset_ctl->id) {
+ case RASPBERRYPI_FIRMWARE_RESET_ID_USB:
+ bcm2711_notify_vl805_reset();
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int raspberrypi_reset_deassert(struct reset_ctl *reset_ctl)
+{
+ return 0;
+}
+
+struct reset_ops raspberrypi_reset_ops = {
+ .request = raspberrypi_reset_request,
+ .rfree = raspberrypi_reset_free,
+ .rst_assert = raspberrypi_reset_assert,
+ .rst_deassert = raspberrypi_reset_deassert,
+};
+
+static const struct udevice_id raspberrypi_reset_ids[] = {
+ { .compatible = "raspberrypi,firmware-reset" },
+ { }
+};
+
+U_BOOT_DRIVER(raspberrypi_reset) = {
+ .name = "raspberrypi-reset",
+ .id = UCLASS_RESET,
+ .of_match = raspberrypi_reset_ids,
+ .ops = &raspberrypi_reset_ops,
+};
+
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index cca798d7e4..702109b23b 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -620,6 +620,10 @@ U_BOOT_DRIVER(ns16550_serial) = {
.flags = DM_FLAG_PRE_RELOC,
#endif
};
+
+U_BOOT_DRIVER_ALIAS(ns16550_serial, rockchip_rk3328_uart)
+U_BOOT_DRIVER_ALIAS(ns16550_serial, rockchip_rk3368_uart)
+U_BOOT_DRIVER_ALIAS(ns16550_serial, ti_da830_uart)
#endif
#endif /* SERIAL_PRESENT */
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index 545ff3f747..f09d291e04 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -93,7 +93,9 @@ static int sandbox_serial_putc(struct udevice *dev, const char ch)
struct sandbox_serial_priv *priv = dev_get_priv(dev);
struct sandbox_serial_platdata *plat = dev->platdata;
- if (priv->start_of_line && plat->colour != -1) {
+ /* With of-platdata we don't real the colour correctly, so disable it */
+ if (!CONFIG_IS_ENABLED(OF_PLATDATA) && priv->start_of_line &&
+ plat->colour != -1) {
priv->start_of_line = false;
output_ansi_colour(plat->colour);
}
@@ -252,8 +254,8 @@ static const struct udevice_id sandbox_serial_ids[] = {
{ }
};
-U_BOOT_DRIVER(serial_sandbox) = {
- .name = "serial_sandbox",
+U_BOOT_DRIVER(sandbox_serial) = {
+ .name = "sandbox_serial",
.id = UCLASS_SERIAL,
.of_match = sandbox_serial_ids,
.ofdata_to_platdata = sandbox_serial_ofdata_to_platdata,
@@ -270,7 +272,7 @@ static const struct sandbox_serial_platdata platdata_non_fdt = {
};
U_BOOT_DEVICE(serial_sandbox_non_fdt) = {
- .name = "serial_sandbox",
+ .name = "sandbox_serial",
.platdata = &platdata_non_fdt,
};
#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c
index c7f46e5598..ad691b66da 100644
--- a/drivers/serial/serial_uniphier.c
+++ b/drivers/serial/serial_uniphier.c
@@ -7,6 +7,8 @@
#include <common.h>
#include <dm.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/io.h>
#include <linux/serial_reg.h>
@@ -15,77 +17,72 @@
#include <serial.h>
#include <fdtdec.h>
-/*
- * Note: Register map is slightly different from that of 16550.
- */
-struct uniphier_serial {
- u32 rx; /* In: Receive buffer */
-#define tx rx /* Out: Transmit buffer */
- u32 ier; /* Interrupt Enable Register */
- u32 iir; /* In: Interrupt ID Register */
- u32 char_fcr; /* Charactor / FIFO Control Register */
- u32 lcr_mcr; /* Line/Modem Control Register */
-#define LCR_SHIFT 8
-#define LCR_MASK (0xff << (LCR_SHIFT))
- u32 lsr; /* In: Line Status Register */
- u32 msr; /* In: Modem Status Register */
- u32 __rsv0;
- u32 __rsv1;
- u32 dlr; /* Divisor Latch Register */
-};
+#define UNIPHIER_UART_REGSHIFT 2
+
+#define UNIPHIER_UART_RX (0 << (UNIPHIER_UART_REGSHIFT))
+#define UNIPHIER_UART_TX UNIPHIER_UART_RX
+/* bit[15:8] = CHAR, bit[7:0] = FCR */
+#define UNIPHIER_UART_CHAR_FCR (3 << (UNIPHIER_UART_REGSHIFT))
+#define UNIPHIER_UART_FCR_MASK GENMASK(7, 0)
+/* bit[15:8] = LCR, bit[7:0] = MCR */
+#define UNIPHIER_UART_LCR_MCR (4 << (UNIPHIER_UART_REGSHIFT))
+#define UNIPHIER_UART_LCR_MASK GENMASK(15, 8)
+#define UNIPHIER_UART_LSR (5 << (UNIPHIER_UART_REGSHIFT))
+/* Divisor Latch Register */
+#define UNIPHIER_UART_DLR (9 << (UNIPHIER_UART_REGSHIFT))
struct uniphier_serial_priv {
- struct uniphier_serial __iomem *membase;
+ void __iomem *membase;
unsigned int uartclk;
};
-#define uniphier_serial_port(dev) \
- ((struct uniphier_serial_priv *)dev_get_priv(dev))->membase
-
static int uniphier_serial_setbrg(struct udevice *dev, int baudrate)
{
struct uniphier_serial_priv *priv = dev_get_priv(dev);
- struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
- const unsigned int mode_x_div = 16;
+ static const unsigned int mode_x_div = 16;
unsigned int divisor;
divisor = DIV_ROUND_CLOSEST(priv->uartclk, mode_x_div * baudrate);
- writel(divisor, &port->dlr);
+ /* flush the trasmitter before changing hw setting */
+ while (!(readl(priv->membase + UNIPHIER_UART_LSR) & UART_LSR_TEMT))
+ ;
+
+ writel(divisor, priv->membase + UNIPHIER_UART_DLR);
return 0;
}
static int uniphier_serial_getc(struct udevice *dev)
{
- struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
+ struct uniphier_serial_priv *priv = dev_get_priv(dev);
- if (!(readl(&port->lsr) & UART_LSR_DR))
+ if (!(readl(priv->membase + UNIPHIER_UART_LSR) & UART_LSR_DR))
return -EAGAIN;
- return readl(&port->rx);
+ return readl(priv->membase + UNIPHIER_UART_RX);
}
static int uniphier_serial_putc(struct udevice *dev, const char c)
{
- struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
+ struct uniphier_serial_priv *priv = dev_get_priv(dev);
- if (!(readl(&port->lsr) & UART_LSR_THRE))
+ if (!(readl(priv->membase + UNIPHIER_UART_LSR) & UART_LSR_THRE))
return -EAGAIN;
- writel(c, &port->tx);
+ writel(c, priv->membase + UNIPHIER_UART_TX);
return 0;
}
static int uniphier_serial_pending(struct udevice *dev, bool input)
{
- struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
+ struct uniphier_serial_priv *priv = dev_get_priv(dev);
if (input)
- return readl(&port->lsr) & UART_LSR_DR;
+ return readl(priv->membase + UNIPHIER_UART_LSR) & UART_LSR_DR;
else
- return !(readl(&port->lsr) & UART_LSR_THRE);
+ return !(readl(priv->membase + UNIPHIER_UART_LSR) & UART_LSR_THRE);
}
/*
@@ -113,7 +110,6 @@ static const struct uniphier_serial_clk_data uniphier_serial_clk_data[] = {
static int uniphier_serial_probe(struct udevice *dev)
{
struct uniphier_serial_priv *priv = dev_get_priv(dev);
- struct uniphier_serial __iomem *port;
const struct uniphier_serial_clk_data *clk_data;
ofnode root_node;
fdt_addr_t base;
@@ -123,12 +119,10 @@ static int uniphier_serial_probe(struct udevice *dev)
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
- port = devm_ioremap(dev, base, SZ_64);
- if (!port)
+ priv->membase = devm_ioremap(dev, base, SZ_64);
+ if (!priv->membase)
return -ENOMEM;
- priv->membase = port;
-
root_node = ofnode_path("/");
clk_data = uniphier_serial_clk_data;
while (clk_data->compatible) {
@@ -143,10 +137,20 @@ static int uniphier_serial_probe(struct udevice *dev)
priv->uartclk = clk_data->clk_rate;
- tmp = readl(&port->lcr_mcr);
- tmp &= ~LCR_MASK;
- tmp |= UART_LCR_WLEN8 << LCR_SHIFT;
- writel(tmp, &port->lcr_mcr);
+ /* flush the trasmitter empty before changing hw setting */
+ while (!(readl(priv->membase + UNIPHIER_UART_LSR) & UART_LSR_TEMT))
+ ;
+
+ /* enable FIFO */
+ tmp = readl(priv->membase + UNIPHIER_UART_CHAR_FCR);
+ tmp &= ~UNIPHIER_UART_FCR_MASK;
+ tmp |= FIELD_PREP(UNIPHIER_UART_FCR_MASK, UART_FCR_ENABLE_FIFO);
+ writel(tmp, priv->membase + UNIPHIER_UART_CHAR_FCR);
+
+ tmp = readl(priv->membase + UNIPHIER_UART_LCR_MCR);
+ tmp &= ~UNIPHIER_UART_LCR_MASK;
+ tmp |= FIELD_PREP(UNIPHIER_UART_LCR_MASK, UART_LCR_WLEN8);
+ writel(tmp, priv->membase + UNIPHIER_UART_LCR_MCR);
return 0;
}
diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c
index e231e96e58..3c1af839c0 100644
--- a/drivers/spi/mxs_spi.c
+++ b/drivers/spi/mxs_spi.c
@@ -486,12 +486,8 @@ static const struct udevice_id mxs_spi_ids[] = {
};
#endif
-U_BOOT_DRIVER(mxs_spi) = {
-#ifdef CONFIG_MX28
- .name = "fsl_imx28_spi",
-#else /* CONFIG_MX23 */
+U_BOOT_DRIVER(fsl_imx23_spi) = {
.name = "fsl_imx23_spi",
-#endif
.id = UCLASS_SPI,
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
.of_match = mxs_spi_ids,
@@ -502,3 +498,5 @@ U_BOOT_DRIVER(mxs_spi) = {
.priv_auto_alloc_size = sizeof(struct mxs_spi_priv),
.probe = mxs_spi_probe,
};
+
+U_BOOT_DRIVER_ALIAS(fsl_imx23_spi, fsl_imx28_spi)
diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
index 833cb04922..b6f95fa9a4 100644
--- a/drivers/spi/rk_spi.c
+++ b/drivers/spi/rk_spi.c
@@ -183,7 +183,7 @@ static int conv_of_platdata(struct udevice *dev)
plat->base = dtplat->reg[0];
plat->frequency = 20000000;
- ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+ ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->clk);
if (ret < 0)
return ret;
dev->req_seq = 0;
@@ -553,12 +553,8 @@ static const struct udevice_id rockchip_spi_ids[] = {
{ }
};
-U_BOOT_DRIVER(rockchip_spi) = {
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
+U_BOOT_DRIVER(rockchip_rk3288_spi) = {
.name = "rockchip_rk3288_spi",
-#else
- .name = "rockchip_spi",
-#endif
.id = UCLASS_SPI,
.of_match = rockchip_spi_ids,
.ops = &rockchip_spi_ops,
@@ -567,3 +563,5 @@ U_BOOT_DRIVER(rockchip_spi) = {
.priv_auto_alloc_size = sizeof(struct rockchip_spi_priv),
.probe = rockchip_spi_probe,
};
+
+U_BOOT_DRIVER_ALIAS(rockchip_rk3288_spi, rockchip_rk3368_spi)
diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c
index b0a46c8868..570ae285f2 100644
--- a/drivers/spi/sandbox_spi.c
+++ b/drivers/spi/sandbox_spi.c
@@ -146,8 +146,8 @@ static const struct udevice_id sandbox_spi_ids[] = {
{ }
};
-U_BOOT_DRIVER(spi_sandbox) = {
- .name = "spi_sandbox",
+U_BOOT_DRIVER(sandbox_spi) = {
+ .name = "sandbox_spi",
.id = UCLASS_SPI,
.of_match = sandbox_spi_ids,
.ops = &sandbox_spi_ops,
diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c
index 2dff0d3eee..e167d0a2fe 100644
--- a/drivers/tpm/tpm_tis_sandbox.c
+++ b/drivers/tpm/tpm_tis_sandbox.c
@@ -355,8 +355,8 @@ static const struct udevice_id sandbox_tpm_ids[] = {
{ }
};
-U_BOOT_DRIVER(sandbox_tpm) = {
- .name = "sandbox_tpm",
+U_BOOT_DRIVER(google_sandbox_tpm) = {
+ .name = "google_sandbox_tpm",
.id = UCLASS_TPM,
.of_match = sandbox_tpm_ids,
.ops = &sandbox_tpm_ops,
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 2d968aafb0..108f4bd8cf 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -180,6 +180,8 @@ void xhci_cleanup(struct xhci_ctrl *ctrl)
xhci_free_virt_devices(ctrl);
free(ctrl->erst.entries);
free(ctrl->dcbaa);
+ if (reset_valid(&ctrl->reset))
+ reset_free(&ctrl->reset);
memset(ctrl, '\0', sizeof(struct xhci_ctrl));
}
@@ -395,6 +397,9 @@ static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl)
scratchpad->sp_array[i] = cpu_to_le64(ptr);
}
+ xhci_flush_cache((uintptr_t)scratchpad->sp_array,
+ sizeof(u64) * num_sp);
+
return 0;
fail_sp3:
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ebd2954571..f635bb39f6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -190,6 +190,37 @@ static int xhci_start(struct xhci_hcor *hcor)
return ret;
}
+#if CONFIG_IS_ENABLED(DM_USB)
+/**
+ * Resets XHCI Hardware
+ *
+ * @param ctrl pointer to host controller
+ * @return 0 if OK, or a negative error code.
+ */
+static int xhci_reset_hw(struct xhci_ctrl *ctrl)
+{
+ int ret;
+
+ ret = reset_get_by_index(ctrl->dev, 0, &ctrl->reset);
+ if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
+ dev_err(ctrl->dev, "failed to get reset\n");
+ return ret;
+ }
+
+ if (reset_valid(&ctrl->reset)) {
+ ret = reset_assert(&ctrl->reset);
+ if (ret)
+ return ret;
+
+ ret = reset_deassert(&ctrl->reset);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+#endif
+
/**
* Resets the XHCI Controller
*
@@ -1508,6 +1539,10 @@ int xhci_register(struct udevice *dev, struct xhci_hccr *hccr,
ctrl->dev = dev;
+ ret = xhci_reset_hw(ctrl);
+ if (ret)
+ goto err;
+
/*
* XHCI needs to issue a Address device command to setup
* proper device context structures, before it can interact
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 0cf13adc7d..89ad603d88 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -22,6 +22,37 @@ config BACKLIGHT
This provides backlight uclass driver that enables basic panel
backlight support.
+config VIDEO_PCI_DEFAULT_FB_SIZE
+ hex "Default framebuffer size to use if no drivers request it"
+ depends on DM_VIDEO
+ default 0x1000000 if X86 && PCI
+ default 0 if !(X86 && PCI)
+ help
+ Generally, video drivers request the amount of memory they need for
+ the frame buffer when they are bound, by setting the size field in
+ struct video_uc_platdata. That memory is then reserved for use after
+ relocation. But PCI drivers cannot be bound before relocation unless
+ they are mentioned in the devicetree.
+
+ With this value set appropriately, it is possible for PCI video
+ devices to have a framebuffer allocated by U-Boot.
+
+ Note: the framebuffer needs to be large enough to store all pixels at
+ maximum resolution. For example, at 1920 x 1200 with 32 bits per
+ pixel, 2560 * 1600 * 32 / 8 = 0xfa0000 bytes are needed.
+
+config VIDEO_COPY
+ bool "Enable copying the frame buffer to a hardware copy"
+ depends on DM_VIDEO
+ help
+ On some machines (e.g. x86), reading from the frame buffer is very
+ slow because it is uncached. To improve performance, this feature
+ allows the frame buffer to be kept in cached memory (allocated by
+ U-Boot) and then copied to the hardware frame-buffer as needed.
+
+ To use this, your video driver must set @copy_base in
+ struct video_uc_platdata.
+
config BACKLIGHT_PWM
bool "Generic PWM based Backlight Driver"
depends on BACKLIGHT && DM_PWM
diff --git a/drivers/video/broadwell_igd.c b/drivers/video/broadwell_igd.c
index 8e8fe9d9b3..df6a761d2d 100644
--- a/drivers/video/broadwell_igd.c
+++ b/drivers/video/broadwell_igd.c
@@ -664,6 +664,7 @@ static int broadwell_igd_probe(struct udevice *dev)
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
bool is_broadwell;
+ ulong fbbase;
int ret;
if (!ll_boot_init()) {
@@ -690,7 +691,8 @@ static int broadwell_igd_probe(struct udevice *dev)
return ret;
/* Use write-combining for the graphics memory, 256MB */
- ret = mtrr_add_request(MTRR_TYPE_WRCOMB, plat->base, 256 << 20);
+ fbbase = IS_ENABLED(CONFIG_VIDEO_COPY) ? plat->copy_base : plat->base;
+ ret = mtrr_add_request(MTRR_TYPE_WRCOMB, fbbase, 256 << 20);
if (!ret)
ret = mtrr_commit(true);
if (ret && ret != -ENOSYS) {
@@ -752,6 +754,17 @@ static int broadwell_igd_ofdata_to_platdata(struct udevice *dev)
return 0;
}
+static int broadwell_igd_bind(struct udevice *dev)
+{
+ struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+ /* Set the maximum supported resolution */
+ uc_plat->size = 2560 * 1600 * 4;
+ log_debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
+ return 0;
+}
+
static const struct video_ops broadwell_igd_ops = {
};
@@ -766,6 +779,7 @@ U_BOOT_DRIVER(broadwell_igd) = {
.of_match = broadwell_igd_ids,
.ops = &broadwell_igd_ops,
.ofdata_to_platdata = broadwell_igd_ofdata_to_platdata,
+ .bind = broadwell_igd_bind,
.probe = broadwell_igd_probe,
.priv_auto_alloc_size = sizeof(struct broadwell_igd_priv),
.platdata_auto_alloc_size = sizeof(struct broadwell_igd_plat),
diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
index c3f7ef8add..04f022491e 100644
--- a/drivers/video/console_normal.c
+++ b/drivers/video/console_normal.c
@@ -16,8 +16,9 @@
static int console_normal_set_row(struct udevice *dev, uint row, int clr)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
- void *line;
+ void *line, *end;
int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
+ int ret;
int i;
line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * vid_priv->line_length;
@@ -28,6 +29,7 @@ static int console_normal_set_row(struct udevice *dev, uint row, int clr)
for (i = 0; i < pixels; i++)
*dst++ = clr;
+ end = dst;
break;
}
case VIDEO_BPP16:
@@ -36,6 +38,7 @@ static int console_normal_set_row(struct udevice *dev, uint row, int clr)
for (i = 0; i < pixels; i++)
*dst++ = clr;
+ end = dst;
break;
}
case VIDEO_BPP32:
@@ -44,11 +47,15 @@ static int console_normal_set_row(struct udevice *dev, uint row, int clr)
for (i = 0; i < pixels; i++)
*dst++ = clr;
+ end = dst;
break;
}
default:
return -ENOSYS;
}
+ ret = vidconsole_sync_copy(dev, line, end);
+ if (ret)
+ return ret;
return 0;
}
@@ -59,10 +66,15 @@ static int console_normal_move_rows(struct udevice *dev, uint rowdst,
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
void *dst;
void *src;
+ int size;
+ int ret;
dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * vid_priv->line_length;
src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * vid_priv->line_length;
- memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
+ size = VIDEO_FONT_HEIGHT * vid_priv->line_length * count;
+ ret = vidconsole_memmove(dev, dst, src, size);
+ if (ret)
+ return ret;
return 0;
}
@@ -74,8 +86,13 @@ static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y,
struct udevice *vid = dev->parent;
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
int i, row;
- void *line = vid_priv->fb + y * vid_priv->line_length +
+ void *start;
+ void *line;
+ int ret;
+
+ start = vid_priv->fb + y * vid_priv->line_length +
VID_TO_PIXEL(x_frac) * VNBYTES(vid_priv->bpix);
+ line = start;
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
@@ -126,6 +143,9 @@ static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y,
}
line += vid_priv->line_length;
}
+ ret = vidconsole_sync_copy(dev, start, line);
+ if (ret)
+ return ret;
return VID_TO_POS(VIDEO_FONT_WIDTH);
}
diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
index b485255598..36c8d0609d 100644
--- a/drivers/video/console_rotate.c
+++ b/drivers/video/console_rotate.c
@@ -15,11 +15,13 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
int pbytes = VNBYTES(vid_priv->bpix);
- void *line;
+ void *start, *line;
int i, j;
+ int ret;
- line = vid_priv->fb + vid_priv->line_length -
+ start = vid_priv->fb + vid_priv->line_length -
(row + 1) * VIDEO_FONT_HEIGHT * pbytes;
+ line = start;
for (j = 0; j < vid_priv->ysize; j++) {
switch (vid_priv->bpix) {
case VIDEO_BPP8:
@@ -51,6 +53,9 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr)
}
line += vid_priv->line_length;
}
+ ret = vidconsole_sync_copy(dev, start, line);
+ if (ret)
+ return ret;
return 0;
}
@@ -59,10 +64,10 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
uint count)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+ int pbytes = VNBYTES(vid_priv->bpix);
void *dst;
void *src;
- int pbytes = VNBYTES(vid_priv->bpix);
- int j;
+ int j, ret;
dst = vid_priv->fb + vid_priv->line_length -
(rowdst + count) * VIDEO_FONT_HEIGHT * pbytes;
@@ -70,7 +75,10 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
(rowsrc + count) * VIDEO_FONT_HEIGHT * pbytes;
for (j = 0; j < vid_priv->ysize; j++) {
- memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
+ ret = vidconsole_memmove(dev, dst, src,
+ VIDEO_FONT_HEIGHT * pbytes * count);
+ if (ret)
+ return ret;
src += vid_priv->line_length;
dst += vid_priv->line_length;
}
@@ -83,14 +91,16 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
+ uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
int pbytes = VNBYTES(vid_priv->bpix);
- int i, col;
+ int i, col, x, linenum, ret;
int mask = 0x80;
- void *line;
- uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
+ void *start, *line;
- line = vid_priv->fb + (VID_TO_PIXEL(x_frac) + 1) *
- vid_priv->line_length - (y + 1) * pbytes;
+ linenum = VID_TO_PIXEL(x_frac) + 1;
+ x = y + 1;
+ start = vid_priv->fb + linenum * vid_priv->line_length - x * pbytes;
+ line = start;
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
@@ -135,6 +145,10 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
line += vid_priv->line_length;
mask >>= 1;
}
+ /* We draw backwards from 'start, so account for the first line */
+ ret = vidconsole_sync_copy(dev, start - vid_priv->line_length, line);
+ if (ret)
+ return ret;
return VID_TO_POS(VIDEO_FONT_WIDTH);
}
@@ -143,12 +157,13 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
static int console_set_row_2(struct udevice *dev, uint row, int clr)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
- void *line;
+ void *start, *line, *end;
int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
- int i;
+ int i, ret;
- line = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
+ start = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
(row + 1) * VIDEO_FONT_HEIGHT * vid_priv->line_length;
+ line = start;
switch (vid_priv->bpix) {
case VIDEO_BPP8:
if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
@@ -156,6 +171,7 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
for (i = 0; i < pixels; i++)
*dst++ = clr;
+ end = dst;
break;
}
case VIDEO_BPP16:
@@ -164,6 +180,7 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
for (i = 0; i < pixels; i++)
*dst++ = clr;
+ end = dst;
break;
}
case VIDEO_BPP32:
@@ -172,11 +189,15 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
for (i = 0; i < pixels; i++)
*dst++ = clr;
+ end = dst;
break;
}
default:
return -ENOSYS;
}
+ ret = vidconsole_sync_copy(dev, start, end);
+ if (ret)
+ return ret;
return 0;
}
@@ -194,7 +215,8 @@ static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
vid_priv->line_length;
src = end - (rowsrc + count) * VIDEO_FONT_HEIGHT *
vid_priv->line_length;
- memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
+ vidconsole_memmove(dev, dst, src,
+ VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
return 0;
}
@@ -204,16 +226,16 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
- int i, row;
- void *line;
+ int pbytes = VNBYTES(vid_priv->bpix);
+ int i, row, x, linenum, ret;
+ void *start, *line;
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
-
- line = vid_priv->fb + (vid_priv->ysize - y - 1) *
- vid_priv->line_length +
- (vid_priv->xsize - VID_TO_PIXEL(x_frac) -
- VIDEO_FONT_WIDTH - 1) * VNBYTES(vid_priv->bpix);
+ linenum = vid_priv->ysize - y - 1;
+ x = vid_priv->xsize - VID_TO_PIXEL(x_frac) - 1;
+ start = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes;
+ line = start;
for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row;
@@ -261,6 +283,10 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
}
line -= vid_priv->line_length;
}
+ /* Add 4 bytes to allow for the first pixel writen */
+ ret = vidconsole_sync_copy(dev, start + 4, line);
+ if (ret)
+ return ret;
return VID_TO_POS(VIDEO_FONT_WIDTH);
}
@@ -269,10 +295,11 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
int pbytes = VNBYTES(vid_priv->bpix);
- void *line;
- int i, j;
+ void *start, *line;
+ int i, j, ret;
- line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
+ start = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
+ line = start;
for (j = 0; j < vid_priv->ysize; j++) {
switch (vid_priv->bpix) {
case VIDEO_BPP8:
@@ -304,6 +331,9 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr)
}
line += vid_priv->line_length;
}
+ ret = vidconsole_sync_copy(dev, start, line);
+ if (ret)
+ return ret;
return 0;
}
@@ -312,16 +342,19 @@ static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
uint count)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+ int pbytes = VNBYTES(vid_priv->bpix);
void *dst;
void *src;
- int pbytes = VNBYTES(vid_priv->bpix);
- int j;
+ int j, ret;
dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * pbytes;
src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * pbytes;
for (j = 0; j < vid_priv->ysize; j++) {
- memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
+ ret = vidconsole_memmove(dev, dst, src,
+ VIDEO_FONT_HEIGHT * pbytes * count);
+ if (ret)
+ return ret;
src += vid_priv->line_length;
dst += vid_priv->line_length;
}
@@ -334,17 +367,17 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
+ uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
int pbytes = VNBYTES(vid_priv->bpix);
- int i, col;
+ int i, col, x, ret;
int mask = 0x80;
- void *line = vid_priv->fb +
- (vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1) *
- vid_priv->line_length + y * pbytes;
- uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
+ void *start, *line;
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
-
+ x = vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1;
+ start = vid_priv->fb + x * vid_priv->line_length + y * pbytes;
+ line = start;
for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
switch (vid_priv->bpix) {
case VIDEO_BPP8:
@@ -386,6 +419,10 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
line -= vid_priv->line_length;
mask >>= 1;
}
+ /* Add a line to allow for the first pixels writen */
+ ret = vidconsole_sync_copy(dev, start + vid_priv->line_length, line);
+ if (ret)
+ return ret;
return VID_TO_POS(VIDEO_FONT_WIDTH);
}
diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index 5f7f03904b..22b2ea7191 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -127,9 +127,9 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
struct console_tt_priv *priv = dev_get_priv(dev);
- void *line;
+ void *end, *line;
int pixels = priv->font_size * vid_priv->line_length;
- int i;
+ int i, ret;
line = vid_priv->fb + row * priv->font_size * vid_priv->line_length;
switch (vid_priv->bpix) {
@@ -139,6 +139,7 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
for (i = 0; i < pixels; i++)
*dst++ = clr;
+ end = dst;
break;
}
#endif
@@ -148,6 +149,7 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
for (i = 0; i < pixels; i++)
*dst++ = clr;
+ end = dst;
break;
}
#endif
@@ -157,12 +159,16 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
for (i = 0; i < pixels; i++)
*dst++ = clr;
+ end = dst;
break;
}
#endif
default:
return -ENOSYS;
}
+ ret = vidconsole_sync_copy(dev, line, end);
+ if (ret)
+ return ret;
return 0;
}
@@ -174,11 +180,14 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst,
struct console_tt_priv *priv = dev_get_priv(dev);
void *dst;
void *src;
- int i, diff;
+ int i, diff, ret;
dst = vid_priv->fb + rowdst * priv->font_size * vid_priv->line_length;
src = vid_priv->fb + rowsrc * priv->font_size * vid_priv->line_length;
- memmove(dst, src, priv->font_size * vid_priv->line_length * count);
+ ret = vidconsole_memmove(dev, dst, src, priv->font_size *
+ vid_priv->line_length * count);
+ if (ret)
+ return ret;
/* Scroll up our position history */
diff = (rowsrc - rowdst) * priv->font_size;
@@ -203,8 +212,8 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
struct pos_info *pos;
u8 *bits, *data;
int advance;
- void *line;
- int row;
+ void *start, *end, *line;
+ int row, ret;
/* First get some basic metrics about this character */
stbtt_GetCodepointHMetrics(font, ch, &advance, &lsb);
@@ -253,11 +262,12 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
/* Figure out where to write the character in the frame buffer */
bits = data;
- line = vid_priv->fb + y * vid_priv->line_length +
+ start = vid_priv->fb + y * vid_priv->line_length +
VID_TO_PIXEL(x) * VNBYTES(vid_priv->bpix);
linenum = priv->baseline + yoff;
if (linenum > 0)
- line += linenum * vid_priv->line_length;
+ start += linenum * vid_priv->line_length;
+ line = start;
/*
* Write a row at a time, converting the 8bpp image into the colour
@@ -286,6 +296,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
*dst++ &= out;
bits++;
}
+ end = dst;
break;
}
#endif
@@ -307,6 +318,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
*dst++ &= out;
bits++;
}
+ end = dst;
break;
}
#endif
@@ -317,6 +329,9 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
line += vid_priv->line_length;
}
+ ret = vidconsole_sync_copy(dev, start, line);
+ if (ret)
+ return ret;
free(data);
return width_frac;
@@ -340,12 +355,13 @@ static int console_truetype_erase(struct udevice *dev, int xstart, int ystart,
int xend, int yend, int clr)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
- void *line;
+ void *start, *line;
int pixels = xend - xstart;
- int row, i;
+ int row, i, ret;
- line = vid_priv->fb + ystart * vid_priv->line_length;
- line += xstart * VNBYTES(vid_priv->bpix);
+ start = vid_priv->fb + ystart * vid_priv->line_length;
+ start += xstart * VNBYTES(vid_priv->bpix);
+ line = start;
for (row = ystart; row < yend; row++) {
switch (vid_priv->bpix) {
#ifdef CONFIG_VIDEO_BPP8
@@ -380,6 +396,9 @@ static int console_truetype_erase(struct udevice *dev, int xstart, int ystart,
}
line += vid_priv->line_length;
}
+ ret = vidconsole_sync_copy(dev, start, line);
+ if (ret)
+ return ret;
return 0;
}
diff --git a/drivers/video/ivybridge_igd.c b/drivers/video/ivybridge_igd.c
index 4c57e311d1..2587f53ac1 100644
--- a/drivers/video/ivybridge_igd.c
+++ b/drivers/video/ivybridge_igd.c
@@ -11,6 +11,7 @@
#include <log.h>
#include <pci_rom.h>
#include <vbe.h>
+#include <video.h>
#include <asm/intel_regs.h>
#include <asm/io.h>
#include <asm/mtrr.h>
@@ -722,7 +723,6 @@ static int gma_func0_init(struct udevice *dev)
{
struct udevice *nbridge;
void *gtt_bar;
- ulong base;
u32 reg32;
int ret;
int rev;
@@ -742,11 +742,6 @@ static int gma_func0_init(struct udevice *dev)
reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
dm_pci_write_config32(dev, PCI_COMMAND, reg32);
- /* Use write-combining for the graphics memory, 256MB */
- base = dm_pci_read_bar32(dev, 2);
- mtrr_add_request(MTRR_TYPE_WRCOMB, base, 256 << 20);
- mtrr_commit(true);
-
gtt_bar = (void *)(ulong)dm_pci_read_bar32(dev, 0);
debug("GT bar %p\n", gtt_bar);
ret = gma_pm_init_pre_vbios(gtt_bar, rev);
@@ -758,6 +753,8 @@ static int gma_func0_init(struct udevice *dev)
static int bd82x6x_video_probe(struct udevice *dev)
{
+ struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+ ulong fbbase;
void *gtt_bar;
int ret, rev;
@@ -774,6 +771,22 @@ static int bd82x6x_video_probe(struct udevice *dev)
if (ret)
return ret;
+ /* Use write-combining for the graphics memory, 256MB */
+ fbbase = IS_ENABLED(CONFIG_VIDEO_COPY) ? plat->copy_base : plat->base;
+ mtrr_add_request(MTRR_TYPE_WRCOMB, fbbase, 256 << 20);
+ mtrr_commit(true);
+
+ return 0;
+}
+
+static int bd82x6x_video_bind(struct udevice *dev)
+{
+ struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+ /* Set the maximum supported resolution */
+ uc_plat->size = 2560 * 1600 * 4;
+ log_debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
return 0;
}
@@ -786,5 +799,6 @@ U_BOOT_DRIVER(bd82x6x_video) = {
.name = "bd82x6x_video",
.id = UCLASS_VIDEO,
.of_match = bd82x6x_video_ids,
+ .bind = bd82x6x_video_bind,
.probe = bd82x6x_video_probe,
};
diff --git a/drivers/video/rockchip/rk3288_vop.c b/drivers/video/rockchip/rk3288_vop.c
index 25ef25b870..68d1507cda 100644
--- a/drivers/video/rockchip/rk3288_vop.c
+++ b/drivers/video/rockchip/rk3288_vop.c
@@ -97,8 +97,8 @@ static const struct udevice_id rk3288_vop_ids[] = {
static const struct video_ops rk3288_vop_ops = {
};
-U_BOOT_DRIVER(rk_vop) = {
- .name = "rk3288_vop",
+U_BOOT_DRIVER(rockchip_rk3288_vop) = {
+ .name = "rockchip_rk3288_vop",
.id = UCLASS_VIDEO,
.of_match = rk3288_vop_ids,
.ops = &rk3288_vop_ops,
diff --git a/drivers/video/sandbox_sdl.c b/drivers/video/sandbox_sdl.c
index 20248e6607..d806f35deb 100644
--- a/drivers/video/sandbox_sdl.c
+++ b/drivers/video/sandbox_sdl.c
@@ -23,6 +23,7 @@ enum {
static int sandbox_sdl_probe(struct udevice *dev)
{
+ struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
struct sandbox_sdl_plat *plat = dev_get_platdata(dev);
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
struct sandbox_state *state = state_get_current();
@@ -40,6 +41,8 @@ static int sandbox_sdl_probe(struct udevice *dev)
uc_priv->rot = plat->rot;
uc_priv->vidconsole_drv_name = plat->vidconsole_drv_name;
uc_priv->font_size = plat->font_size;
+ if (IS_ENABLED(CONFIG_VIDEO_COPY))
+ uc_plat->copy_base = uc_plat->base - uc_plat->size / 2;
return 0;
}
@@ -53,8 +56,13 @@ static int sandbox_sdl_bind(struct udevice *dev)
plat->xres = dev_read_u32_default(dev, "xres", LCD_MAX_WIDTH);
plat->yres = dev_read_u32_default(dev, "yres", LCD_MAX_HEIGHT);
plat->bpix = dev_read_u32_default(dev, "log2-depth", VIDEO_BPP16);
+ plat->rot = dev_read_u32_default(dev, "rotate", 0);
uc_plat->size = plat->xres * plat->yres * (1 << plat->bpix) / 8;
- debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
+ /* Allow space for two buffers, the lower one being the copy buffer */
+ log_debug("Frame buffer size %x\n", uc_plat->size);
+ if (IS_ENABLED(CONFIG_VIDEO_COPY))
+ uc_plat->size *= 2;
return ret;
}
@@ -64,8 +72,8 @@ static const struct udevice_id sandbox_sdl_ids[] = {
{ }
};
-U_BOOT_DRIVER(sdl_sandbox) = {
- .name = "sdl_sandbox",
+U_BOOT_DRIVER(sandbox_lcd_sdl) = {
+ .name = "sandbox_lcd_sdl",
.id = UCLASS_VIDEO,
.of_match = sandbox_sdl_ids,
.bind = sandbox_sdl_bind,
diff --git a/drivers/video/vesa.c b/drivers/video/vesa.c
index 6c03611e80..9656326bdb 100644
--- a/drivers/video/vesa.c
+++ b/drivers/video/vesa.c
@@ -5,12 +5,39 @@
#include <common.h>
#include <dm.h>
+#include <log.h>
#include <pci.h>
#include <vbe.h>
+#include <video.h>
+#include <asm/mtrr.h>
static int vesa_video_probe(struct udevice *dev)
{
- return vbe_setup_video(dev, NULL);
+ struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+ ulong fbbase;
+ int ret;
+
+ ret = vbe_setup_video(dev, NULL);
+ if (ret)
+ return log_ret(ret);
+
+ /* Use write-combining for the graphics memory, 256MB */
+ fbbase = IS_ENABLED(CONFIG_VIDEO_COPY) ? plat->copy_base : plat->base;
+ mtrr_add_request(MTRR_TYPE_WRCOMB, fbbase, 256 << 20);
+ mtrr_commit(true);
+
+ return 0;
+}
+
+static int vesa_video_bind(struct udevice *dev)
+{
+ struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+ /* Set the maximum supported resolution */
+ uc_plat->size = 2560 * 1600 * 4;
+ log_debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
+ return 0;
}
static const struct udevice_id vesa_video_ids[] = {
@@ -22,6 +49,7 @@ U_BOOT_DRIVER(vesa_video) = {
.name = "vesa_video",
.id = UCLASS_VIDEO,
.of_match = vesa_video_ids,
+ .bind = vesa_video_bind,
.probe = vesa_video_probe,
};
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index 3f20f70e9a..3a07f36ce2 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -9,12 +9,13 @@
#include <common.h>
#include <command.h>
+#include <console.h>
#include <log.h>
-#include <linux/ctype.h>
#include <dm.h>
#include <video.h>
#include <video_console.h>
#include <video_font.h> /* Bitmap font for code page 437 */
+#include <linux/ctype.h>
/*
* Structure to describe a console color
@@ -556,16 +557,31 @@ int vidconsole_put_string(struct udevice *dev, const char *str)
static void vidconsole_putc(struct stdio_dev *sdev, const char ch)
{
struct udevice *dev = sdev->priv;
+ int ret;
- vidconsole_put_char(dev, ch);
+ ret = vidconsole_put_char(dev, ch);
+ if (ret) {
+#ifdef DEBUG
+ console_puts_select_stderr(true, "[vc err: putc]");
+#endif
+ }
video_sync(dev->parent, false);
}
static void vidconsole_puts(struct stdio_dev *sdev, const char *s)
{
struct udevice *dev = sdev->priv;
+ int ret;
+
+ ret = vidconsole_put_string(dev, s);
+ if (ret) {
+#ifdef DEBUG
+ char str[30];
- vidconsole_put_string(dev, s);
+ snprintf(str, sizeof(str), "[vc err: puts %d]", ret);
+ console_puts_select_stderr(true, str);
+#endif
+ }
video_sync(dev->parent, false);
}
@@ -613,6 +629,22 @@ UCLASS_DRIVER(vidconsole) = {
.per_device_auto_alloc_size = sizeof(struct vidconsole_priv),
};
+#ifdef CONFIG_VIDEO_COPY
+int vidconsole_sync_copy(struct udevice *dev, void *from, void *to)
+{
+ struct udevice *vid = dev_get_parent(dev);
+
+ return video_sync_copy(vid, from, to);
+}
+
+int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
+ int size)
+{
+ memmove(dst, src, size);
+ return vidconsole_sync_copy(dev, dst, dst + size);
+}
+#endif
+
#if CONFIG_IS_ENABLED(CMD_VIDCONSOLE)
void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row)
{
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index 1f2874554a..650891e49d 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -4,6 +4,7 @@
*/
#include <common.h>
+#include <console.h>
#include <cpu_func.h>
#include <dm.h>
#include <log.h>
@@ -45,6 +46,19 @@
*/
DECLARE_GLOBAL_DATA_PTR;
+/**
+ * struct video_uc_priv - Information for the video uclass
+ *
+ * @video_ptr: Current allocation position of the video framebuffer pointer.
+ * While binding devices after relocation, this points to the next
+ * available address to use for a device's framebuffer. It starts at
+ * gd->video_top and works downwards, running out of space when it hits
+ * gd->video_bottom.
+ */
+struct video_uc_priv {
+ ulong video_ptr;
+};
+
void video_set_flush_dcache(struct udevice *dev, bool flush)
{
struct video_priv *priv = dev_get_uclass_priv(dev);
@@ -83,6 +97,11 @@ int video_reserve(ulong *addrp)
debug("%s: Reserving %lx bytes at %lx for video device '%s'\n",
__func__, size, *addrp, dev->name);
}
+
+ /* Allocate space for PCI video devices in case there were not bound */
+ if (*addrp == gd->video_top)
+ *addrp -= CONFIG_VIDEO_PCI_DEFAULT_FB_SIZE;
+
gd->video_bottom = *addrp;
gd->fb_base = *addrp;
debug("Video frame buffers from %lx to %lx\n", gd->video_bottom,
@@ -94,6 +113,7 @@ int video_reserve(ulong *addrp)
int video_clear(struct udevice *dev)
{
struct video_priv *priv = dev_get_uclass_priv(dev);
+ int ret;
switch (priv->bpix) {
case VIDEO_BPP16:
@@ -118,6 +138,9 @@ int video_clear(struct udevice *dev)
memset(priv->fb, priv->colour_bg, priv->fb_size);
break;
}
+ ret = video_sync_copy(dev, priv->fb, priv->fb + priv->fb_size);
+ if (ret)
+ return ret;
return 0;
}
@@ -201,6 +224,59 @@ int video_get_ysize(struct udevice *dev)
return priv->ysize;
}
+#ifdef CONFIG_VIDEO_COPY
+int video_sync_copy(struct udevice *dev, void *from, void *to)
+{
+ struct video_priv *priv = dev_get_uclass_priv(dev);
+
+ if (priv->copy_fb) {
+ long offset, size;
+
+ /* Find the offset of the first byte to copy */
+ if ((ulong)to > (ulong)from) {
+ size = to - from;
+ offset = from - priv->fb;
+ } else {
+ size = from - to;
+ offset = to - priv->fb;
+ }
+
+ /*
+ * Allow a bit of leeway for valid requests somewhere near the
+ * frame buffer
+ */
+ if (offset < -priv->fb_size || offset > 2 * priv->fb_size) {
+#ifdef DEBUG
+ char str[80];
+
+ snprintf(str, sizeof(str),
+ "[sync_copy fb=%p, from=%p, to=%p, offset=%lx]",
+ priv->fb, from, to, offset);
+ console_puts_select_stderr(true, str);
+#endif
+ return -EFAULT;
+ }
+
+ /*
+ * Silently crop the memcpy. This allows callers to avoid doing
+ * this themselves. It is common for the end pointer to go a
+ * few lines after the end of the frame buffer, since most of
+ * the update algorithms terminate a line after their last write
+ */
+ if (offset + size > priv->fb_size) {
+ size = priv->fb_size - offset;
+ } else if (offset < 0) {
+ size += offset;
+ offset = 0;
+ }
+
+ memcpy(priv->copy_fb + offset, priv->fb + offset, size);
+ }
+
+ return 0;
+}
+#endif
+
/* Set up the colour map */
static int video_pre_probe(struct udevice *dev)
{
@@ -239,6 +315,9 @@ static int video_post_probe(struct udevice *dev)
priv->fb_size = priv->line_length * priv->ysize;
+ if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_base)
+ priv->copy_fb = map_sysmem(plat->copy_base, plat->size);
+
/* Set up colors */
video_set_default_colors(dev, false);
@@ -290,12 +369,21 @@ static int video_post_probe(struct udevice *dev)
/* Post-relocation, allocate memory for the frame buffer */
static int video_post_bind(struct udevice *dev)
{
- ulong addr = gd->video_top;
+ struct video_uc_priv *uc_priv;
+ ulong addr;
ulong size;
/* Before relocation there is nothing to do here */
if (!(gd->flags & GD_FLG_RELOC))
return 0;
+
+ /* Set up the video pointer, if this is the first device */
+ uc_priv = dev->uclass->priv;
+ if (!uc_priv->video_ptr)
+ uc_priv->video_ptr = gd->video_top;
+
+ /* Allocate framebuffer space for this device */
+ addr = uc_priv->video_ptr;
size = alloc_fb(dev, &addr);
if (addr < gd->video_bottom) {
/* Device tree node may need the 'u-boot,dm-pre-reloc' or
@@ -307,7 +395,7 @@ static int video_post_bind(struct udevice *dev)
}
debug("%s: Claiming %lx bytes at %lx for video device '%s'\n",
__func__, size, addr, dev->name);
- gd->video_bottom = addr;
+ uc_priv->video_ptr = addr;
return 0;
}
@@ -320,6 +408,7 @@ UCLASS_DRIVER(video) = {
.pre_probe = video_pre_probe,
.post_probe = video_post_probe,
.pre_remove = video_pre_remove,
+ .priv_auto_alloc_size = sizeof(struct video_uc_priv),
.per_device_auto_alloc_size = sizeof(struct video_priv),
.per_device_platdata_auto_alloc_size = sizeof(struct video_uc_platdata),
};
diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c
index 7d7f37b445..5a4d12c68d 100644
--- a/drivers/video/video_bmp.c
+++ b/drivers/video/video_bmp.c
@@ -192,7 +192,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
struct video_priv *priv = dev_get_uclass_priv(dev);
ushort *cmap_base = NULL;
int i, j;
- uchar *fb;
+ uchar *start, *fb;
struct bmp_image *bmp = map_sysmem(bmp_image, 0);
uchar *bmap;
ushort padded_width;
@@ -201,6 +201,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
unsigned colours, bpix, bmp_bpix;
struct bmp_color_table_entry *palette;
int hdr_size;
+ int ret;
if (!bmp || !(bmp->header.signature[0] == 'B' &&
bmp->header.signature[1] == 'M')) {
@@ -261,8 +262,11 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
height = priv->ysize - y;
bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
- fb = (uchar *)(priv->fb +
- (y + height - 1) * priv->line_length + x * bpix / 8);
+ start = (uchar *)(priv->fb +
+ (y + height) * priv->line_length + x * bpix / 8);
+
+ /* Move back to the final line to be drawn */
+ fb = start - priv->line_length;
switch (bmp_bpix) {
case 1:
@@ -369,6 +373,12 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
break;
};
+ /* Find the position of the top left of the image in the framebuffer */
+ fb = (uchar *)(priv->fb + y * priv->line_length + x * bpix / 8);
+ ret = video_sync_copy(dev, start, fb);
+ if (ret)
+ return log_ret(ret);
+
video_sync(dev, false);
return 0;
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 18756e34df..33f5c351d5 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -113,8 +113,8 @@ static int at91_wdt_probe(struct udevice *dev)
return 0;
}
-U_BOOT_DRIVER(at91_wdt) = {
- .name = "at91_wdt",
+U_BOOT_DRIVER(atmel_at91sam9260_wdt) = {
+ .name = "atmel_at91sam9260_wdt",
.id = UCLASS_WDT,
.of_match = at91_wdt_ids,
.priv_auto_alloc_size = sizeof(struct at91_wdt_priv),