gen_defines: generate ranges defines for PCIe I/O and memory regions
As described in IEEE Std 1275-1994, the PCIe bindings uses the ranges property to describe the PCI I/O and memory regions. Write _RANGES_ defines that will be used to determines the I/O and memory regions from PCIe Controller drivers. Also exclude "ranges" & "dma-ranges" property's length generation alogn "reg" and "interrupt". Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
This commit is contained in:
parent
2f4a6646cf
commit
1e8f0f3bd1
1 changed files with 49 additions and 3 deletions
|
@ -355,6 +355,7 @@ def write_special_props(node):
|
|||
# Macros that are special to the devicetree specification
|
||||
out_comment("Macros for properties that are special in the specification:")
|
||||
write_regs(node)
|
||||
write_ranges(node)
|
||||
write_interrupts(node)
|
||||
write_compatibles(node)
|
||||
write_status(node)
|
||||
|
@ -364,6 +365,49 @@ def write_special_props(node):
|
|||
write_pinctrls(node)
|
||||
write_fixed_partitions(node)
|
||||
|
||||
def write_ranges(node):
|
||||
# ranges property: edtlib knows the right #address-cells and
|
||||
# #size-cells of parent and child, and can therefore pack the
|
||||
# child & parent addresses and sizes correctly
|
||||
|
||||
idx_vals = []
|
||||
path_id = node.z_path_id
|
||||
|
||||
if node.ranges is not None:
|
||||
idx_vals.append((f"{path_id}_RANGES_NUM", len(node.ranges)))
|
||||
|
||||
for i,range in enumerate(node.ranges):
|
||||
idx_vals.append((f"{path_id}_RANGES_IDX_{i}_EXISTS", 1))
|
||||
|
||||
if node.bus == "pcie":
|
||||
idx_vals.append((f"{path_id}_RANGES_IDX_{i}_VAL_CHILD_BUS_FLAGS_EXISTS", 1))
|
||||
idx_macro = f"{path_id}_RANGES_IDX_{i}_VAL_CHILD_BUS_FLAGS"
|
||||
idx_value = range.child_bus_addr >> ((range.child_bus_cells - 1) * 32)
|
||||
idx_vals.append((idx_macro,
|
||||
f"{idx_value} /* {hex(idx_value)} */"))
|
||||
if range.child_bus_addr is not None:
|
||||
idx_macro = f"{path_id}_RANGES_IDX_{i}_VAL_CHILD_BUS_ADDRESS"
|
||||
if node.bus == "pcie":
|
||||
idx_value = range.child_bus_addr & ((1 << (range.child_bus_cells - 1) * 32) - 1)
|
||||
else:
|
||||
idx_value = range.child_bus_addr
|
||||
idx_vals.append((idx_macro,
|
||||
f"{idx_value} /* {hex(idx_value)} */"))
|
||||
if range.parent_bus_addr is not None:
|
||||
idx_macro = f"{path_id}_RANGES_IDX_{i}_VAL_PARENT_BUS_ADDRESS"
|
||||
idx_vals.append((idx_macro,
|
||||
f"{range.parent_bus_addr} /* {hex(range.parent_bus_addr)} */"))
|
||||
if range.length is not None:
|
||||
idx_macro = f"{path_id}_RANGES_IDX_{i}_VAL_LENGTH"
|
||||
idx_vals.append((idx_macro,
|
||||
f"{range.length} /* {hex(range.length)} */"))
|
||||
|
||||
for macro, val in idx_vals:
|
||||
out_dt_define(macro, val)
|
||||
|
||||
out_dt_define(f"{path_id}_FOREACH_RANGE(fn)",
|
||||
" ".join(f"fn(DT_{path_id}, {i})" for i,range in enumerate(node.ranges)))
|
||||
|
||||
def write_regs(node):
|
||||
# reg property: edtlib knows the right #address-cells and
|
||||
# #size-cells, and can therefore pack the register base addresses
|
||||
|
@ -682,10 +726,12 @@ def prop_len(prop):
|
|||
# Returns the property's length if and only if we should generate
|
||||
# a _LEN macro for the property. Otherwise, returns None.
|
||||
#
|
||||
# This deliberately excludes reg and interrupts.
|
||||
# This deliberately excludes ranges, dma-ranges, reg and interrupts.
|
||||
# While they have array type, their lengths as arrays are
|
||||
# basically nonsense semantically due to #address-cells and
|
||||
# #size-cells for "reg" and #interrupt-cells for "interrupts".
|
||||
# #size-cells for "reg", #interrupt-cells for "interrupts"
|
||||
# and #address-cells, #size-cells and the #address-cells from the
|
||||
# parent node for "ranges" and "dma-ranges".
|
||||
#
|
||||
# We have special purpose macros for the number of register blocks
|
||||
# / interrupt specifiers. Excluding them from this list means
|
||||
|
@ -698,7 +744,7 @@ def prop_len(prop):
|
|||
|
||||
if (prop.type in ["array", "uint8-array", "string-array",
|
||||
"phandles", "phandle-array"] and
|
||||
prop.name not in ["reg", "interrupts"]):
|
||||
prop.name not in ["ranges", "dma-ranges", "reg", "interrupts"]):
|
||||
return len(prop.val)
|
||||
|
||||
return None
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue