Makes it easier to understand what's going on. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
219 lines
9.5 KiB
Python
219 lines
9.5 KiB
Python
#
|
|
# Copyright (c) 2018 Bobby Noelte
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
|
|
# NOTE: This file is part of the old device tree scripts, which will be removed
|
|
# later. They are kept to generate some legacy #defines via the
|
|
# --deprecated-only flag.
|
|
#
|
|
# The new scripts are gen_defines.py, edtlib.py, and dtlib.py.
|
|
|
|
from extract.globals import *
|
|
from extract.directive import DTDirective
|
|
|
|
##
|
|
# @brief Manage clocks related directives.
|
|
#
|
|
# Handles:
|
|
# - clocks
|
|
# directives.
|
|
#
|
|
class DTClocks(DTDirective):
|
|
def _extract_consumer(self, node_path, clocks, def_label):
|
|
clock_consumer_bindings = get_binding(node_path)
|
|
clock_consumer_label = 'DT_' + node_label(node_path)
|
|
|
|
clock_index = 0
|
|
clock_cell_index = 0
|
|
nr_clock_cells = 0
|
|
clock_provider_node_path = ''
|
|
clock_provider = {}
|
|
for cell in clocks:
|
|
if clock_cell_index == 0:
|
|
if cell not in phandles:
|
|
raise Exception(
|
|
("Could not find the clock provider node {} for clocks"
|
|
" = {} in clock consumer node {}. Did you activate"
|
|
" the clock node?. Last clock provider: {}.")
|
|
.format(str(cell), str(clocks), node_path,
|
|
str(clock_provider)))
|
|
clock_provider_node_path = phandles[cell]
|
|
clock_provider = reduced[clock_provider_node_path]
|
|
clock_provider_bindings = get_binding(
|
|
clock_provider_node_path)
|
|
nr_clock_cells = int(clock_provider['props'].get(
|
|
'#clock-cells', 0))
|
|
clock_cells_string = clock_provider_bindings.get(
|
|
'cell_string', 'CLOCK')
|
|
clock_cells_names = clock_provider_bindings.get(
|
|
'#cells', ['ID', 'CELL1', "CELL2", "CELL3"])
|
|
clock_cells = []
|
|
else:
|
|
clock_cells.append(cell)
|
|
clock_cell_index += 1
|
|
if clock_cell_index > nr_clock_cells or nr_clock_cells == 0:
|
|
# clock consumer device - clocks info
|
|
#####################################
|
|
prop_def = {}
|
|
prop_alias = {}
|
|
|
|
# Legacy clocks definitions by extract_cells
|
|
for i, cell in enumerate(clock_cells):
|
|
if i >= len(clock_cells_names):
|
|
clock_cell_name = 'CELL{}'.format(i)
|
|
else:
|
|
clock_cell_name = clock_cells_names[i]
|
|
if clock_cells_string == clock_cell_name:
|
|
clock_label = self.get_label_string([
|
|
clock_consumer_label, clock_cells_string,
|
|
str(clock_index)])
|
|
add_compat_alias(node_path,
|
|
self.get_label_string(["",
|
|
clock_cells_string, str(clock_index)]),
|
|
clock_label, prop_alias)
|
|
else:
|
|
clock_label = self.get_label_string([
|
|
clock_consumer_label, clock_cells_string,
|
|
clock_cell_name, str(clock_index)])
|
|
add_compat_alias(node_path,
|
|
self.get_label_string(["",
|
|
clock_cells_string, clock_cell_name,
|
|
str(clock_index)]),
|
|
clock_label, prop_alias)
|
|
prop_def[clock_label] = str(cell)
|
|
if clock_index == 0 and \
|
|
len(clocks) == (len(clock_cells) + 1):
|
|
index = ''
|
|
else:
|
|
index = str(clock_index)
|
|
if node_path in aliases:
|
|
if clock_cells_string == clock_cell_name:
|
|
add_prop_aliases(
|
|
node_path,
|
|
lambda alias:
|
|
self.get_label_string([
|
|
alias,
|
|
clock_cells_string,
|
|
index]),
|
|
clock_label,
|
|
prop_alias)
|
|
else:
|
|
add_prop_aliases(
|
|
node_path,
|
|
lambda alias:
|
|
self.get_label_string([
|
|
alias,
|
|
clock_cells_string,
|
|
clock_cell_name,
|
|
index]),
|
|
clock_label,
|
|
prop_alias)
|
|
# alias
|
|
if i < nr_clock_cells:
|
|
# clocks info for first clock
|
|
clock_alias_label = self.get_label_string([
|
|
clock_consumer_label, clock_cells_string,
|
|
clock_cell_name])
|
|
prop_alias[clock_alias_label] = clock_label
|
|
add_compat_alias(node_path,
|
|
self.get_label_string(["",
|
|
clock_cells_string, clock_cell_name]),
|
|
clock_label, prop_alias)
|
|
|
|
|
|
# Legacy clocks definitions by extract_controller
|
|
clock_provider_label_str = clock_provider['props'].get('label',
|
|
None)
|
|
if clock_provider_label_str is not None:
|
|
clock_cell_name = 'CLOCK_CONTROLLER'
|
|
if clock_index == 0 and \
|
|
len(clocks) == (len(clock_cells) + 1):
|
|
index = ''
|
|
else:
|
|
index = str(clock_index)
|
|
clock_label = self.get_label_string([clock_consumer_label,
|
|
clock_cell_name,
|
|
index])
|
|
add_compat_alias(node_path,
|
|
self.get_label_string(["", clock_cell_name, index]),
|
|
clock_label, prop_alias)
|
|
prop_def[clock_label] = '"' + clock_provider_label_str + '"'
|
|
if node_path in aliases:
|
|
add_prop_aliases(
|
|
node_path,
|
|
lambda alias:
|
|
self.get_label_string([
|
|
alias,
|
|
clock_cell_name,
|
|
index]),
|
|
clock_label,
|
|
prop_alias)
|
|
|
|
# If the provided clock has a fixed rate, extract its frequency
|
|
# as a macro generated for the clock consumer.
|
|
if clock_provider['props']['compatible'] == 'fixed-clock':
|
|
clock_prop_name = 'clock-frequency'
|
|
clock_prop_label = 'CLOCKS_CLOCK_FREQUENCY'
|
|
if clock_index == 0 and \
|
|
len(clocks) == (len(clock_cells) + 1):
|
|
index = ''
|
|
else:
|
|
index = str(clock_index)
|
|
clock_frequency_label = \
|
|
self.get_label_string([clock_consumer_label,
|
|
clock_prop_label,
|
|
index])
|
|
|
|
prop_def[clock_frequency_label] = \
|
|
clock_provider['props'][clock_prop_name]
|
|
add_compat_alias(
|
|
node_path,
|
|
self.get_label_string([clock_prop_label, index]),
|
|
clock_frequency_label,
|
|
prop_alias)
|
|
if node_path in aliases:
|
|
add_prop_aliases(
|
|
node_path,
|
|
lambda alias:
|
|
self.get_label_string([
|
|
alias,
|
|
clock_prop_label,
|
|
index]),
|
|
clock_frequency_label,
|
|
prop_alias)
|
|
|
|
insert_defs(node_path, prop_def, prop_alias)
|
|
|
|
clock_cell_index = 0
|
|
clock_index += 1
|
|
|
|
##
|
|
# @brief Extract clocks related directives
|
|
#
|
|
# @param node_path Path to node owning the clockxxx definition.
|
|
# @param prop clockxxx property name
|
|
# @param def_label Define label string of node owning the directive.
|
|
#
|
|
def extract(self, node_path, prop, def_label):
|
|
|
|
properties = reduced[node_path]['props'][prop]
|
|
|
|
prop_list = []
|
|
if not isinstance(properties, list):
|
|
prop_list.append(properties)
|
|
else:
|
|
prop_list = list(properties)
|
|
|
|
if prop == 'clocks':
|
|
# indicator for clock consumers
|
|
self._extract_consumer(node_path, prop_list, def_label)
|
|
else:
|
|
raise Exception(
|
|
"DTClocks.extract called with unexpected directive ({})."
|
|
.format(prop))
|
|
|
|
##
|
|
# @brief Management information for clocks.
|
|
clocks = DTClocks()
|