diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 1fede16a0c..793a506d27 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -30,6 +30,8 @@ U_BOOT_DRIVER(atmel_at91rm9200_pmc) = {
 	.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/gpio/mxs_gpio.c b/drivers/gpio/mxs_gpio.c
index e43484d13a..bcdf08c255 100644
--- a/drivers/gpio/mxs_gpio.c
+++ b/drivers/gpio/mxs_gpio.c
@@ -309,4 +309,6 @@ U_BOOT_DRIVER(fsl_imx23_gpio) = {
 	.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/sandbox.c b/drivers/gpio/sandbox.c
index ff46d3c8d1..8923e54867 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -253,6 +253,8 @@ U_BOOT_DRIVER(sandbox_gpio) = {
 	.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 eceef80e70..e76c087b1d 100644
--- a/drivers/i2c/rk_i2c.c
+++ b/drivers/i2c/rk_i2c.c
@@ -492,3 +492,5 @@ U_BOOT_DRIVER(rockchip_rk3066_i2c) = {
 	.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/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c
index 35c336b499..afa95e57ee 100644
--- a/drivers/mmc/mxsmmc.c
+++ b/drivers/mmc/mxsmmc.c
@@ -724,4 +724,5 @@ U_BOOT_DRIVER(fsl_imx23_mmc) = {
 	.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 ef75367b3e..ac710324c8 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -178,6 +178,9 @@ U_BOOT_DRIVER(rockchip_rk3288_dw_mshc) = {
 	.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/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 1b44cc68c6..97fa22a4b3 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -180,4 +180,6 @@ U_BOOT_DRIVER(jedec_spi_nor) = {
 	.ops		= &spi_flash_std_ops,
 };
 
+U_BOOT_DRIVER_ALIAS(jedec_spi_nor, spansion_m25p16)
+
 #endif /* CONFIG_DM_SPI_FLASH */
diff --git a/drivers/pinctrl/nxp/pinctrl-mxs.c b/drivers/pinctrl/nxp/pinctrl-mxs.c
index bd434667b1..da6b95acc5 100644
--- a/drivers/pinctrl/nxp/pinctrl-mxs.c
+++ b/drivers/pinctrl/nxp/pinctrl-mxs.c
@@ -190,3 +190,5 @@ U_BOOT_DRIVER(fsl_imx23_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 0cc35042f5..b40ff8c823 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -525,3 +525,5 @@ U_BOOT_DRIVER(atmel_sama5d3_pinctrl) = {
 	.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/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index d870ed7113..c8ae28b8f3 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -193,3 +193,5 @@ U_BOOT_DRIVER(rockchip_rk805) = {
 	.probe = rk8xx_probe,
 	.ops = &rk8xx_ops,
 };
+
+U_BOOT_DRIVER_ALIAS(rockchip_rk805, rockchip_rk808)
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 6415d2e1e5..df958a688b 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -619,6 +619,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/spi/mxs_spi.c b/drivers/spi/mxs_spi.c
index 087cd50788..2779501176 100644
--- a/drivers/spi/mxs_spi.c
+++ b/drivers/spi/mxs_spi.c
@@ -618,4 +618,6 @@ U_BOOT_DRIVER(fsl_imx23_spi) = {
 	.priv_auto_alloc_size = sizeof(struct mxs_spi_priv),
 	.probe	= mxs_spi_probe,
 };
+
+U_BOOT_DRIVER_ALIAS(fsl_imx23_spi, fsl_imx28_spi)
 #endif
diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
index d25a87fad6..0ac7f767ca 100644
--- a/drivers/spi/rk_spi.c
+++ b/drivers/spi/rk_spi.c
@@ -561,3 +561,5 @@ U_BOOT_DRIVER(rockchip_rk3288_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/include/dm/device.h b/include/dm/device.h
index 975eec5d0e..2cfe10766f 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -282,6 +282,13 @@ struct driver {
 #define DM_GET_DRIVER(__name)						\
 	ll_entry_get(struct driver, __name, driver)
 
+/**
+ * Declare a macro to state a alias for a driver name. This macro will
+ * produce no code but its information will be parsed by tools like
+ * dtoc
+ */
+#define U_BOOT_DRIVER_ALIAS(__name, __alias)
+
 /**
  * dev_get_platdata() - Get the platform data for a device
  *
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index bc0de426a9..c4701d3211 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -13,6 +13,8 @@ static data.
 
 import collections
 import copy
+import os
+import re
 import sys
 
 from dtoc import fdt
@@ -143,6 +145,11 @@ class DtbPlatdata(object):
         _aliases: Dict that hold aliases for compatible strings
             key: First compatible string declared in a node
             value: List of additional compatible strings declared in a node
+        _drivers: List of valid driver names found in drivers/
+        _driver_aliases: Dict that holds aliases for driver names
+            key: Driver alias declared with
+                U_BOOT_DRIVER_ALIAS(driver_alias, driver_name)
+            value: Driver name declared with U_BOOT_DRIVER(driver_name)
     """
     def __init__(self, dtb_fname, include_disabled):
         self._fdt = None
@@ -152,6 +159,37 @@ class DtbPlatdata(object):
         self._outfile = None
         self._lines = []
         self._aliases = {}
+        self._drivers = []
+        self._driver_aliases = {}
+
+    def get_normalized_compat_name(self, node):
+        """Get a node's normalized compat name
+
+        Returns a valid driver name by retrieving node's first compatible
+        string as a C identifier and performing a check against _drivers
+        and a lookup in driver_aliases printing a warning in case of failure.
+
+        Args:
+            node: Node object to check
+        Return:
+            Tuple:
+                Driver name associated with the first compatible string
+                List of C identifiers for all the other compatible strings
+                    (possibly empty)
+                In case of no match found, the return will be the same as
+                get_compat_name()
+        """
+        compat_c, aliases_c = get_compat_name(node)
+        if compat_c not in self._drivers:
+            compat_c_old = compat_c
+            compat_c = self._driver_aliases.get(compat_c)
+            if not compat_c:
+                print('WARNING: the driver %s was not found in the driver list' % (compat_c_old))
+                compat_c = compat_c_old
+            else:
+                aliases_c = [compat_c_old] + aliases_c
+
+        return compat_c, aliases_c
 
     def setup_output(self, fname):
         """Set up the output destination
@@ -246,6 +284,48 @@ class DtbPlatdata(object):
             return PhandleInfo(max_args, args)
         return None
 
+    def scan_driver(self, fn):
+        """Scan a driver file to build a list of driver names and aliases
+
+        This procedure will populate self._drivers and self._driver_aliases
+
+        Args
+            fn: Driver filename to scan
+        """
+        with open(fn) as fd:
+            buff = fd.read()
+
+            # The following re will search for driver names declared as
+            # U_BOOT_DRIVER(driver_name)
+            drivers = re.findall('U_BOOT_DRIVER\((.*)\)', buff)
+
+            for driver in drivers:
+                self._drivers.append(driver)
+
+            # The following re will search for driver aliases declared as
+            # U_BOOT_DRIVER_ALIAS(alias, driver_name)
+            driver_aliases = re.findall('U_BOOT_DRIVER_ALIAS\(\s*(\w+)\s*,\s*(\w+)\s*\)', buff)
+
+            for alias in driver_aliases: # pragma: no cover
+                if len(alias) != 2:
+                    continue
+                self._driver_aliases[alias[1]] = alias[0]
+
+    def scan_drivers(self):
+        """Scan the driver folders to build a list of driver names and aliases
+
+        This procedure will populate self._drivers and self._driver_aliases
+
+        """
+        basedir = sys.argv[0].replace('tools/dtoc/dtoc', '')
+        if basedir == '':
+            basedir = './'
+        for (dirpath, dirnames, filenames) in os.walk(basedir):
+            for fn in filenames:
+                if not fn.endswith('.c'):
+                    continue
+                self.scan_driver(dirpath + '/' + fn)
+
     def scan_dtb(self):
         """Scan the device tree to obtain a tree of nodes and properties
 
@@ -356,7 +436,7 @@ class DtbPlatdata(object):
         """
         structs = {}
         for node in self._valid_nodes:
-            node_name, _ = get_compat_name(node)
+            node_name, _ = self.get_normalized_compat_name(node)
             fields = {}
 
             # Get a list of all the valid properties in this node.
@@ -380,14 +460,14 @@ class DtbPlatdata(object):
 
         upto = 0
         for node in self._valid_nodes:
-            node_name, _ = get_compat_name(node)
+            node_name, _ = self.get_normalized_compat_name(node)
             struct = structs[node_name]
             for name, prop in node.props.items():
                 if name not in PROP_IGNORE_LIST and name[0] != '#':
                     prop.Widen(struct[name])
             upto += 1
 
-            struct_name, aliases = get_compat_name(node)
+            struct_name, aliases = self.get_normalized_compat_name(node)
             for alias in aliases:
                 self._aliases[alias] = struct_name
 
@@ -464,7 +544,7 @@ class DtbPlatdata(object):
         Args:
             node: node to output
         """
-        struct_name, _ = get_compat_name(node)
+        struct_name, _ = self.get_normalized_compat_name(node)
         var_name = conv_name_to_c(node.name)
         self.buf('static const struct %s%s %s%s = {\n' %
                  (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
@@ -565,6 +645,7 @@ def run_steps(args, dtb_file, include_disabled, output):
         raise ValueError('Please specify a command: struct, platdata')
 
     plat = DtbPlatdata(dtb_file, include_disabled)
+    plat.scan_drivers()
     plat.scan_dtb()
     plat.scan_tree()
     plat.scan_reg_sizes()
diff --git a/tools/dtoc/dtoc_test_driver_alias.dts b/tools/dtoc/dtoc_test_driver_alias.dts
new file mode 100644
index 0000000000..da7973b2e5
--- /dev/null
+++ b/tools/dtoc/dtoc_test_driver_alias.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2020 Collabora Ltd.
+ */
+
+/dts-v1/;
+
+/ {
+	gpio_a: gpios@0 {
+		u-boot,dm-pre-reloc;
+		gpio-controller;
+		compatible = "sandbox_gpio_alias";
+		#gpio-cells = <1>;
+		gpio-bank-name = "a";
+		sandbox,gpio-count = <20>;
+	};
+
+};
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index 8498e8303c..91fc9d77f3 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -266,6 +266,39 @@ U_BOOT_DEVICE(pmic_at_9) = {
 \t.platdata_size\t= sizeof(dtv_pmic_at_9),
 };
 
+''', data)
+
+    def test_driver_alias(self):
+        """Test output from a device tree file with a driver alias"""
+        dtb_file = get_dtb_file('dtoc_test_driver_alias.dts')
+        output = tools.GetOutputFilename('output')
+        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(HEADER + '''
+struct dtd_sandbox_gpio {
+\tconst char *\tgpio_bank_name;
+\tbool\t\tgpio_controller;
+\tfdt32_t\t\tsandbox_gpio_count;
+};
+#define dtd_sandbox_gpio_alias dtd_sandbox_gpio
+''', data)
+
+        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(C_HEADER + '''
+static const struct dtd_sandbox_gpio dtv_gpios_at_0 = {
+\t.gpio_bank_name\t\t= "a",
+\t.gpio_controller\t= true,
+\t.sandbox_gpio_count\t= 0x14,
+};
+U_BOOT_DEVICE(gpios_at_0) = {
+\t.name\t\t= "sandbox_gpio",
+\t.platdata\t= &dtv_gpios_at_0,
+\t.platdata_size\t= sizeof(dtv_gpios_at_0),
+};
+
 ''', data)
 
     def test_phandle(self):
