...
 
Commits (2)
......@@ -411,6 +411,7 @@ PYTHON ?= python
PYTHON2 = python2
PYTHON3 = python3
DTC ?= $(objtree)/scripts/dtc/dtc
DTOC ?= $(objtree)/tools/dtoc/dtoc
CHECK = sparse
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
......@@ -1140,8 +1141,18 @@ endif
PHONY += dtbs
dtbs: dts/dt.dtb
@:
dts/dt.dtb: u-boot
PHONY += dts/dt.dtb
dts/dt.dtb: tools
$(Q)$(MAKE) $(build)=dts dtbs
$(DTOC) compatible -d dts/dt.dtb -o include/generated/compatible.h
PHONY += compatible
compatible: include/generated/compatible.h
@:
include/generated/compatible.h: dts/dt.dtb
$(DTOC) compatible -d dts/dt.dtb -o include/generated/compatible.h
quiet_cmd_copy = COPY $@
cmd_copy = cp $< $@
......
......@@ -32,6 +32,7 @@
#include <dt-structs.h>
#include <mapmem.h>
#include <dm/ofnode.h>
#include <generated/compatible.h>
#if !CONFIG_IS_ENABLED(BLK)
#include "mmc_private.h"
......@@ -1662,6 +1663,7 @@ static const struct dm_mmc_ops fsl_esdhc_ops = {
};
#endif
#ifdef FSL_ESDHC_IMX_V2
static struct esdhc_soc_data usdhc_imx7d_data = {
.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
......@@ -1673,23 +1675,23 @@ static struct esdhc_soc_data usdhc_imx8qm_data = {
ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES,
};
#endif
static const struct udevice_id fsl_esdhc_ids[] = {
{ .compatible = "fsl,imx53-esdhc", },
{ .compatible = "fsl,imx6ul-usdhc", },
{ .compatible = "fsl,imx6sx-usdhc", },
{ .compatible = "fsl,imx6sl-usdhc", },
{ .compatible = "fsl,imx6q-usdhc", },
{ .compatible = "fsl,imx7d-usdhc", .data = (ulong)&usdhc_imx7d_data,},
{ .compatible = "fsl,imx7ulp-usdhc", },
{ .compatible = "fsl,imx8qm-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
{ .compatible = "fsl,imx8mm-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
{ .compatible = "fsl,imx8mn-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
{ .compatible = "fsl,imx8mq-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
{ .compatible = "fsl,imxrt-usdhc", },
{ .compatible = "fsl,esdhc", },
{ /* sentinel */ }
};
COMPATIBLE(FSL_ESDHC, "fsl,imx53-esdhc")
COMPATIBLE(FSL_ESDHC, "fsl,imx6ul-usdhc")
COMPATIBLE(FSL_ESDHC, "fsl,imx6sx-usdhc")
COMPATIBLE(FSL_ESDHC, "fsl,imx6sl-usdhc")
COMPATIBLE(FSL_ESDHC, "fsl,imx6q-usdhc")
COMPATIBLE(FSL_ESDHC, "fsl,imx7d-usdhc", &usdhc_imx7d_data, FSL_ESDHC_IMX_V2)
COMPATIBLE(FSL_ESDHC, "fsl,imx7ulp-usdhc")
COMPATIBLE(FSL_ESDHC, "fsl,imx8qm-usdhc", &usdhc_imx8qm_data, FSL_ESDHC_IMX_V2)
COMPATIBLE(FSL_ESDHC, "fsl,imx8mm-usdhc", &usdhc_imx8qm_data, FSL_ESDHC_IMX_V2)
COMPATIBLE(FSL_ESDHC, "fsl,imx8mn-usdhc", &usdhc_imx8qm_data, FSL_ESDHC_IMX_V2)
COMPATIBLE(FSL_ESDHC, "fsl,imx8mq-usdhc", &usdhc_imx8qm_data, FSL_ESDHC_IMX_V2)
COMPATIBLE(FSL_ESDHC, "fsl,imxrt-usdhc")
COMPATIBLE(FSL_ESDHC, "fsl,esdhc")
static const struct udevice_id fsl_esdhc_ids[] = COMPATIBLE_LIST_FSL_ESDHC;
#if CONFIG_IS_ENABLED(BLK)
static int fsl_esdhc_bind(struct udevice *dev)
......
......@@ -127,6 +127,16 @@ def get_compat_name(node):
compat, aliases = compat[0], compat[1:]
return conv_name_to_c(compat), [conv_name_to_c(a) for a in aliases]
def parse_compatible_strings(compatible_strings):
compatible_strings2 = []
for co in compatible_strings:
co2 = co[:2]
if len(co) > 2 and co[2] != '':
co2 += tuple(co[2].split(','))
compatible_strings2.append(co2)
return compatible_strings2
class DtbPlatdata(object):
"""Provide a means to convert device tree binary data to platform data
......@@ -152,6 +162,11 @@ class DtbPlatdata(object):
U_BOOT_DRIVER_ALIAS(driver_alias, driver_name)
value: Driver name declared with U_BOOT_DRIVER(driver_name)
_links: List of links to be included in dm_populate_phandle_data()
_driver_compatible_strings: Dict of compatible strings read from
drivers declared with COMPATIBLE()
key: driver name
value: list of struct udevice_id
_dtb_compatible_strings
"""
def __init__(self, dtb_fname, include_disabled, warning_disabled):
self._fdt = None
......@@ -165,6 +180,8 @@ class DtbPlatdata(object):
self._drivers = []
self._driver_aliases = {}
self._links = []
self._driver_compatible_strings = {}
self._dtb_compatible_strings = []
def get_normalized_compat_name(self, node):
"""Get a node's normalized compat name
......@@ -321,6 +338,14 @@ class DtbPlatdata(object):
continue
self._driver_aliases[alias[1]] = alias[0]
# compatible_strings = re.findall('COMPATIBLE\(\s*(\w+)\s*,\s*(\S+)\s*(,\s*(\S+)\s*)*\)',
# buff)
compatible_strings = re.findall('COMPATIBLE\(\s*(\w+)\s*,\s*\"(.+)\"\s*(?:,\s*([^\n]*))*\)',
buff)
if len(compatible_strings) != 0:
self._driver_compatible_strings[compatible_strings[0][0]] = parse_compatible_strings(compatible_strings)
def scan_drivers(self):
"""Scan the driver folders to build a list of driver names and aliases
......@@ -358,7 +383,9 @@ class DtbPlatdata(object):
if (not self._include_disabled and not status or
status.value != 'disabled'):
self._valid_nodes.append(node)
comp, aliases = get_compat_name(node)
self._dtb_compatible_strings += [comp]
self._dtb_compatible_strings += aliases
# recurse to handle any subnodes
self.scan_node(node)
......@@ -661,6 +688,37 @@ class DtbPlatdata(object):
self.out(''.join(self.get_buf()))
def generate_compatible_strings(self):
"""Generates the struct udevice_id[] to be used in drivers
This writes C code to implement struct udevice_id[] based on
COMPATIBLE(driver_name, compatible) entries found in drivers.
Additionally this function can filter entries in order to avoid
adding those that are not present in DT.
"""
constants = []
self.out('#define COMPATIBLE(__driver_name, __compatible, ...)\n\n')
for vals in self._driver_compatible_strings.values():
st = ''
for comp in vals:
if conv_name_to_c(comp[1].replace('"', '')) not in self._dtb_compatible_strings:
contin
st += '\t{.compatible = "%s"' % (comp[1])
if len(comp) >= 3:
st += ', .data = (ulong)%s},\\\n' % (comp[2])
else:
st += '},\\\n'
if len(comp) >= 4:
constants.append(comp[3])
st += '\t{ /* sentinel */ },\\\n'
self.out('#define COMPATIBLE_LIST_%s { \\\n%s}\n' % (comp[0], st))
self.out('\n')
for const in constants:
self.out('#define %s\n' % const)
def run_steps(args, dtb_file, include_disabled, output, warning_disabled=False):
"""Run all the steps of the dtoc tool
......@@ -673,20 +731,28 @@ def run_steps(args, dtb_file, include_disabled, output, warning_disabled=False):
if not args:
raise ValueError('Please specify a command: struct, platdata')
skip_scan = False
if args == ['compatible']:
skip_scan = True
warning_disabled = True
plat = DtbPlatdata(dtb_file, include_disabled, warning_disabled)
plat.scan_drivers()
plat.scan_dtb()
plat.scan_tree()
plat.scan_reg_sizes()
plat.setup_output(output)
structs = plat.scan_structs()
plat.scan_phandles()
if not skip_scan:
structs = plat.scan_structs()
plat.scan_phandles()
for cmd in args[0].split(','):
if cmd == 'struct':
plat.generate_structs(structs)
elif cmd == 'platdata':
plat.generate_tables()
elif cmd == 'compatible':
plat.generate_compatible_strings()
else:
raise ValueError("Unknown command '%s': (use: struct, platdata)" %
cmd)