diff --git a/README.md b/README.md index 00027a7..01d95d8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,22 @@ # cmsis-svd-generator Generates CMSIS-SVD xml files from DTS info and Register templates in the regmaps directory. + +# Generating a compatible DTS file + +Many DTS files are multi-level, and have both C and DSTI includes. + +To flatten the DTS file, one can run the C preprocessor and device tree compiler: + +```bash +# run CPP to handle any C-style includes + +cpp -nostdinc -I include -I arch -undef -x assembler-with-cpp /path/to/input.dts > processed.dts + +# run DTC to handle any DTSI includes + +dtc -I dts -O dts -o output.dts processed.dts + +# finally, run generate-svd.py + +./generate-svd.py -o output.svd -d output.dts +``` diff --git a/generate_svd.py b/generate_svd.py index 3b394d7..48f40b6 100755 --- a/generate_svd.py +++ b/generate_svd.py @@ -7,13 +7,31 @@ """ import argparse +import logging import os import sys import inspect import pydevicetree +from scripts.arm_pl022 import generate_registers_arm_pl022 +from scripts.cdns_qspi_nor import generate_registers_cdns_qspi from scripts.riscv_clint0_control import generate_registers_riscv_clint0 from scripts.sifive_clic0_control import generate_registers_sifive_clic0 from scripts.riscv_plic0_control import generate_registers_riscv_plic0 +from scripts.snps_designware_i2c import generate_registers_snps_designware_i2c +from scripts.snps_dw_apb_uart import generate_registers_snps_dw_apb_uart +from scripts.starfive_common import generate_interrupt +from scripts.starfive_jh7110_dmc_ctrl import generate_registers_starfive_jh7110_dmc_ctrl +from scripts.starfive_jh7110_dmc_phy import generate_registers_starfive_jh7110_dmc_phy +from scripts.starfive_jh7110_pmu import generate_registers_starfive_jh7110_pmu +from scripts.starfive_jh7110_stgcrg import generate_registers_starfive_jh7110_stgcrg +from scripts.starfive_jh7110_syscrg import generate_registers_starfive_jh7110_syscrg +from scripts.starfive_jh7110_aoncrg import generate_registers_starfive_jh7110_aoncrg +from scripts.starfive_jh7110_aon_pinctrl import generate_registers_starfive_jh7110_aon_iomux_cfg +from scripts.starfive_jh7110_aon_syscon import generate_registers_starfive_jh7110_aon_syscon +from scripts.starfive_jh7110_stg_syscon import generate_registers_starfive_jh7110_stg_syscon +from scripts.starfive_jh7110_sys_pinctrl import generate_registers_starfive_jh7110_sys_iomux_cfg +from scripts.starfive_jh7110_sys_syscon import generate_registers_starfive_jh7110_sys_syscon +from scripts.starfive_jh7110_trng import generate_registers_starfive_jh7110_trng def parse_arguments(argv): """Parse the arguments into a dictionary with argparse""" @@ -24,6 +42,10 @@ def parse_arguments(argv): arg_parser.add_argument("-o", "--output", required=True, type=argparse.FileType('w'), help="The path of the CMSIS SVD file to output") + arg_parser.add_argument("-l", "--log", required=False, + default="WARN", + type=str, + help="The path of the CMSIS SVD file to output") return arg_parser.parse_args(argv) @@ -63,25 +85,69 @@ def generate_peripherals(dts): idx[compatible] = 0 for peripheral in soc.child_nodes(): - if peripheral.get_field("compatible") is not None and \ - peripheral.get_field("reg-names") is not None: + if peripheral.get_field("compatible") is not None: + reg = peripheral.get_fields("reg") + + if reg is None: + reg_cells = 0 + else: + reg_cells = len(peripheral.get_fields("reg").values) + + exp_reg_cells = peripheral.address_cells() + peripheral.size_cells() + + if peripheral.get_fields("reg") is not None and reg_cells % exp_reg_cells != 0: + logging.debug("Unexpected number of reg cells {}, expected {}".format(reg_cells, exp_reg_cells)) + continue + compatibles = peripheral.get_fields("compatible") - reg_names = peripheral.get_fields("reg-names") + + reg_names = {} + if peripheral.get_field("reg-names") is not None: + reg_names = peripheral.get_fields("reg-names") + else: + reg_names = {""} + for comp in compatibles: for reg in reg_names: + if len(reg) == 0: + rn = "" + else: + rn = "_" + reg + regmap_root = os.path.abspath(os.path.dirname(sys.argv[0])) - regmap_name = get_name_as_id(comp) + "_" + reg + ".svd" + regmap_name = get_name_as_id(comp) + rn + ".svd" regmap_path = os.path.join(regmap_root, "regmaps", regmap_name) - script_name = get_name_as_id(comp) + "_" + reg + ".py" + script_name = get_name_as_id(comp) + rn + ".py" script_path = os.path.join(regmap_root, "scripts", script_name) + + logging.debug("Compatible: {}".format(comp)) + logging.debug(" Regmap path: {}".format(regmap_path)) + logging.debug(" Script path: {}".format(script_path)) + + if "clint" in comp and not os.path.exists(script_path): + regmap_path = "" + script_path = os.path.join(regmap_root, "scripts", "riscv_clint0_control.py") + elif "plic" in comp and not os.path.exists(script_path): + regmap_path = "" + script_path = os.path.join(regmap_root, "scripts", "riscv_plic0_control.py") + elif "clic" in comp and not os.path.exists(script_path): + regmap_path = "" + script_path = os.path.join(regmap_root, "scripts", "sifive_clic0_control.py") + if os.path.exists(regmap_path): ext = str(idx[comp]) + logging.info("Regmap path: {}".format(regmap_path)) txt += generate_peripheral(dts, peripheral, comp, ext, reg, regmap_path) idx[comp] += 1 elif os.path.exists(script_path): ext = str(idx[comp]) + logging.info("Script path: {}".format(script_path)) txt += generate_peripheral(dts, peripheral, comp, ext, reg, script_path) idx[comp] += 1 + else: + ext = str(idx[comp]) + txt += generate_peripheral(dts, peripheral, comp, ext, reg, "") + idx[comp] += 1 return txt @@ -89,13 +155,74 @@ def generate_peripherals(dts): def generate_peripheral(dts, peripheral, comp, ext, reg, regmap_path): """Generate xml string for peripheral""" reg_dict = peripheral.get_reg() + + if reg_dict is None: + logging.debug("No peripheral found for {}".format(peripheral)) + return "" + reg_pair = reg_dict.get_by_name(reg) + + addr_cells = peripheral.address_cells() + size_cells = peripheral.size_cells() + group_size = addr_cells + size_cells + + if reg_pair is None and len(reg_dict.values) == group_size: + # no reg-names field was present, so parse according to the spec + reg_pair = [reg_dict.values[addr_cells - 1], reg_dict.values[group_size - 1]] + elif reg_pair is None: + logging.debug("Malformed DTS entry: {}".format(peripheral)) + # malformed DTS, give up + return "" + reg_desc = comp + """,""" + reg - print("Emitting registers for '" + peripheral.name + "' soc peripheral node") + logging.info("Emitting registers for '" + peripheral.name + "' soc peripheral node") + + if regmap_path.endswith("arm_pl022.py"): + name = "spi{}".format(ext) + elif regmap_path.endswith("cdns_qspi_nor.py"): + name = "qspi".format(ext) + elif regmap_path.endswith("riscv_clint0_control.py"): + name = "clint" + elif regmap_path.endswith("riscv_plic0_control.py"): + name = "plic" + elif regmap_path.endswith("sifive_clic0_control.py"): + name = "clic" + elif regmap_path.endswith("snps_dw_apb_uart.py"): + name = "uart{}".format(ext) + elif regmap_path.endswith("snps_designware_i2c.py"): + name = "i2c{}".format(ext) + elif regmap_path.endswith("starfive_jh7110_pmu.py"): + name = "pmu" + elif regmap_path.endswith("starfive_jh7110_syscrg.py"): + name = "syscrg" + elif regmap_path.endswith("starfive_jh7110_stgcrg.py"): + name = "stgcrg" + elif regmap_path.endswith("starfive_jh7110_aoncrg.py"): + name = "aoncrg" + elif regmap_path.endswith("starfive_jh7110_aon_pinctrl.py"): + name = "aon_pinctrl" + elif regmap_path.endswith("starfive_jh7110_aon_syscon.py"): + name = "aon_syscon" + elif regmap_path.endswith("starfive_jh7110_stg_syscon.py"): + name = "stg_syscon" + elif regmap_path.endswith("starfive_jh7110_sys_pinctrl.py"): + name = "sys_pinctrl" + elif regmap_path.endswith("starfive_jh7110_sys_syscon.py"): + name = "sys_syscon" + elif regmap_path.endswith("starfive_jh7110_pwm.py") or regmap_path.endswith("starfive_jh7110_pwm.svd"): + name = "pwm" + elif regmap_path.endswith("starfive_jh7110_trng.py"): + name = "trng" + elif regmap_path.endswith("starfive_jh7110_dmc_ctrl.py"): + name = "dmc_ctrl" + elif regmap_path.endswith("starfive_jh7110_dmc_phy.py"): + name = "dmc_phy" + else: + name = "{}_{}".format(get_name_as_id(comp), ext) return """\ - """ + get_name_as_id(comp) + """_""" + ext + """ + """ + name + """ From """ + reg_desc + """ peripheral generator """ + "0x{:X}".format(reg_pair[0]) + """ @@ -103,18 +230,59 @@ def generate_peripheral(dts, peripheral, comp, ext, reg, regmap_path): """ + "0x{:X}".format(reg_pair[1]) + """ registers +""" + generate_interrupt("jh7110", name) + """\ """ + generate_registers(dts, peripheral, regmap_path) + """\ """ def generate_registers(dts, peripheral, regmap_path): + if regmap_path == "": + logging.debug("No regmap file found for {}".format(peripheral)) + logging.debug("\tRegmap path: {}".format(regmap_path)) + # FIXME: instead of just giving up here, attempt to parse register data from the DTS + return "" + """Generate xml string for registers from regmap file or generator code""" + if regmap_path.endswith("arm_pl022.py"): + return generate_registers_arm_pl022(dts, peripheral) + if regmap_path.endswith("cdns_qspi_nor.py"): + return generate_registers_cdns_qspi(dts, peripheral) if regmap_path.endswith("riscv_clint0_control.py"): return generate_registers_riscv_clint0(dts) if regmap_path.endswith("sifive_clic0_control.py"): return generate_registers_sifive_clic0(dts, peripheral) if regmap_path.endswith("riscv_plic0_control.py"): return generate_registers_riscv_plic0(dts, peripheral) + if regmap_path.endswith("snps_designware_i2c.py"): + return generate_registers_snps_designware_i2c(dts, peripheral) + if regmap_path.endswith("snps_dw_apb_uart.py"): + return generate_registers_snps_dw_apb_uart(dts, peripheral) + if regmap_path.endswith("starfive_jh7110_dmc_ctrl.py"): + return generate_registers_starfive_jh7110_dmc_ctrl(dts, peripheral) + if regmap_path.endswith("starfive_jh7110_dmc_phy.py"): + return generate_registers_starfive_jh7110_dmc_phy(dts, peripheral) + if regmap_path.endswith("starfive_jh7110_pmu.py"): + return generate_registers_starfive_jh7110_pmu(dts, peripheral) + if regmap_path.endswith("starfive_jh7110_syscrg.py"): + return generate_registers_starfive_jh7110_syscrg(dts, peripheral) + if regmap_path.endswith("starfive_jh7110_stgcrg.py"): + return generate_registers_starfive_jh7110_stgcrg(dts, peripheral) + if regmap_path.endswith("starfive_jh7110_aoncrg.py"): + return generate_registers_starfive_jh7110_aoncrg(dts, peripheral) + if regmap_path.endswith("starfive_jh7110_aon_pinctrl.py"): + return generate_registers_starfive_jh7110_aon_iomux_cfg(dts, peripheral) + if regmap_path.endswith("starfive_jh7110_aon_syscon.py"): + return generate_registers_starfive_jh7110_aon_syscon(dts, peripheral) + if regmap_path.endswith("starfive_jh7110_stg_syscon.py"): + return generate_registers_starfive_jh7110_stg_syscon(dts, peripheral) + if regmap_path.endswith("starfive_jh7110_sys_pinctrl.py"): + return generate_registers_starfive_jh7110_sys_iomux_cfg(dts, peripheral) + if regmap_path.endswith("starfive_jh7110_sys_syscon.py"): + return generate_registers_starfive_jh7110_sys_syscon(dts, peripheral) + if regmap_path.endswith("starfive_jh7110_trng.py"): + return generate_registers_starfive_jh7110_trng(dts, peripheral) + + logging.debug("Reading registers from regmap file: {}".format(regmap_path)) regmap_file = open(regmap_path, "r") txt = "" @@ -128,7 +296,16 @@ def get_name_as_id(name): def main(argv): """Parse arguments, extract data, and render clean cmsis svd xml to file""" + + parsed_args = parse_arguments(argv) + + # set the logging level from the command line + numeric_level = getattr(logging, parsed_args.log.upper(), None) + if not isinstance(numeric_level, int): + raise ValueError('Invalid log level: %s' % parsed_args.log) + logging.basicConfig(level=numeric_level) + dts = pydevicetree.Devicetree.parseFile(parsed_args.dts, followIncludes=True) text = generate_device(dts) output = inspect.cleandoc(text) diff --git a/regmaps/starfive_jh7110_pwm.svd b/regmaps/starfive_jh7110_pwm.svd new file mode 100644 index 0000000..737b849 --- /dev/null +++ b/regmaps/starfive_jh7110_pwm.svd @@ -0,0 +1,102 @@ + + + cntr + PTC counter register + 0x0 + + + cntr + PWM PTC counter + [31:0] + read-write + + + + + hrc + PTC duty-cycle register + 0x4 + + + hrc + PWM PTC duty-cycle value + [31:0] + read-write + + + + + lrc + PTC period register + 0x8 + + + lrc + PWM PTC period value + [31:0] + read-write + + + + + ctrl + PTC control register + 0xc + + + en + PWM PTC enable + [0:0] + read-write + + + eclk + PWM PTC enable clock + [1:1] + read-write + + + nec + PWM PTC nec + [2:2] + read-write + + + oe + PWM PTC oe + [3:3] + read-write + + + single + PWM PTC single + [4:4] + read-write + + + inte + PWM PTC interrupt enable + [5:5] + read-write + + + int + PWM PTC interrupt + [6:6] + read-write + + + cntrrst + PWM PTC counter reset + [7:7] + read-write + + + capte + PWM PTC capte + [8:8] + read-write + + + + diff --git a/scripts/arm_pl022.py b/scripts/arm_pl022.py new file mode 100755 index 0000000..88634ac --- /dev/null +++ b/scripts/arm_pl022.py @@ -0,0 +1,423 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for arm PL022 (SPI) +""" + +def generate_registers_arm_pl022(dts, peripheral): + """Generate xml string for registers for arm_pl022 peripheral""" + txt = """\ + +""" + + txt += generate_register_ssp_cr0() + txt += generate_register_ssp_cr1() + txt += generate_register_ssp_dr() + txt += generate_register_ssp_sr() + txt += generate_register_ssp_cpsr() + txt += generate_register_ssp_imsc() + txt += generate_register_ssp_ris() + txt += generate_register_ssp_mis() + txt += generate_register_ssp_icr() + txt += generate_register_ssp_dmacr() + txt += generate_register_ssp_periph_id0() + txt += generate_register_ssp_periph_id1() + txt += generate_register_ssp_periph_id2() + txt += generate_register_ssp_periph_id3() + + for i in range(4): + txt += generate_register_ssp_pcell_id(i) + + return txt + """\ + +""" + +def generate_register_ssp_cr0(): + return generate_register( + "ssp_cr0", + "SSPCR0 is control register 0 and contains five bit fields that control various functions within the PrimeCell SSP.", + 0x00, + [ + ( + "dss", + "Data Size Select - 0000, 0001, 0010: Reserved, 0011: 4-bit data, 0100: 5-bit data, 6-bit data, 0110: 7-bit data, 0111: 8-bit data, 1000: 9-bit data, 1001: 10-bit data, 1010: 11-bit data, 1011: 12-bit data, 1100: 13-bit data, 1101: 14-bit data, 1110: 15-bit data, 1111: 16-bit data", + "[3:0]", + "read-write" + ), + ( + "frf", + "Frame format - 00: Motorola SPI frame format, 01: TI synchronous serial frame format, 10: National Microwire frame format, 11: Reserved", + "[5:4]", + "read-write" + ), + ( + "spo", + "SSPCLKOUT polarity, applicable to Motorola SPI frame format only.", + "[6:6]", + "read-write" + ), + ( + "sph", + "SSPCLKOUT phase, applicable to Motorola SPI frame format only.", + "[6:6]", + "read-write" + ), + ( + "scr", + "Serial clock rate. The value SCR is used to generate the transmit and receive bit rate of the PrimeCell SSP. The bit rate is: (F[sspclk] / (CPSDVR * (1 + SCR))), where CPSDVSR is an even value from [2:254], programmed through the SSPCPSR register and SCR is a value from [0:255]", + "[15:8]", + "read-write" + ) + ], + 16 + ) + +def generate_register_ssp_cr1(): + return generate_register( + "ssp_cr1", + "SSPCR1 is the control register 1 and contains four different bit fields, that control various functions within the PrimeCell SSP.", + 0x04, + [ + ( + "lbm", + "Loop back mode - 0: Normal serial port operation enabled, 1: Output of transmit serial shifter is connected to input of receive serial shifter internally", + "[0:0]", + "read-write" + ), + ( + "sse", + "Synchronous serial port enable - 0: SSP operation disabled, 1: SSP operation enabled", + "[1:1]", + "read-write" + ), + ( + "ms", + "Master or slave mode select. This bit can be modified only when the PrimeCell SSP is disabled, SSE=0 - 0: Device configured as master (default), 1: Device configured as slave", + "[2:2]", + "read-write" + ), + ( + "sod", + "Slave-mode output disable. This bit is relevant only in the slave mode, MS=1. In multiple-slave systems, it is possible for an PrimeCell SSP master to broadcast a message to all slaves in the system while ensuring that only one slave drives data onto its serial output line. In such systems the RXD lines from multiple slaves could be tied together. To operate in such systems, the SOD bit can be set if the PrimeCell SSP slave is not supposed to drive the SSPTXD line - 0: SSP can drive the SSPTXD output in slave mode, 1: SSP must not drive the SSPTXD output in slave mode", + "[3:3]", + "read-write" + ) + ], + 16 + ) + +def generate_register_ssp_dr(): + return generate_register( + "ssp_dr", + "SSPDR is the data register and is 16-bits wide. When SSPDR is read, the entry in the receive FIFO, pointed to by the current FIFO read pointer, is accessed. As data values are removed by the PrimeCell SSP receive logic from the incoming data frame, they are placed into the entry in the receive FIFO, pointed to by the current FIFO write pointer. When SSPDR is written to, the entry in the transmit FIFO, pointed to by the write pointer, is written to. Data values are removed from the transmit FIFO one value at a time by the transmit logic. It is loaded into the transmit serial shifter, then serially shifted out onto the SSPTXD pin at the programmed bit rate. When a data size of less than 16 bits is selected, the user must right-justify data written to the transmit FIFO. The transmit logic ignores the unused bits. Received data less than 16 bits is automatically right-justified in the receive buffer.", + 0x08, + [ + ( + "data", + "Transmit/Receive FIFO - Read: Receive FIFO, Write: Transmit FIFO. You must right-justify data when the PrimeCell SSP is programmed for a data size that is less than 16 bits. Unused bits at the top are ignored by transmit logic. The receive logic automatically right-justifies.", + "[15:0]", + "read-write" + ) + ], + 16 + ) + +def generate_register_ssp_sr(): + return generate_register( + "ssp_sr", + "SSPSR is a RO status register that contains bits that indicate the FIFO fill status and the PrimeCell SSP busy status.", + 0x0c, + [ + ( + "tfe", + "Transmit FIFO empty, RO - 0: Transmit FIFO is not empty, 1: Transmit FIFO is empty.", + "[0:0]", + "read-only" + ), + ( + "tnf", + "Transmit FIFO not full, RO - 0: Transmit FIFO is full, 1: Transmit FIFO is not full.", + "[1:1]", + "read-only" + ), + ( + "rne", + "Receive FIFO not empty, RO - 0: Receive FIFO is empty, 1: Receive FIFO is not empty.", + "[2:2]", + "read-only" + ), + ( + "rff", + "Receive FIFO full, RO - 0: Receive FIFO is not full, 1: Receive FIFO is full.", + "[3:3]", + "read-only" + ), + ( + "bsy", + "PrimeCell SSP busy flag, RO - 0: SSP is idle, 1: SSP is currently transmitting and/or receiving a frame or the transmit FIFO is not empty.", + "[4:4]", + "read-only" + ) + ], + 16 + ) + +def generate_register_ssp_cpsr(): + return generate_register( + "ssp_cpsr", + "SSPCPSR is the clock prescale register and specifies the division factor by which the input SSPCLK must be internally divided before further use. The value programmed into this register must be an even number between [2:254]. The least significant bit of the programmed number is hard-coded to zero. If an odd number is written to this register, data read back from this register has the least significant bit as zero.", + 0x10, + [ + ( + "cpsdvsr", + "Clock prescale divisor. Must be an even number from 2-254, depending on the frequency of SSPCLK. The least significant bit always returns zero on reads.", + "[7:0]", + "read-write" + ) + ], + 16 + ) + +def generate_register_ssp_imsc(): + return generate_register( + "ssp_imsc", + "The SSPIMSC register is the interrupt mask set or clear register. It is a RW register. On a read this register gives the current value of the mask on the relevant interrupt. A write of 1 to the particular bit sets the mask, enabling the interrupt to be read. A write of 0 clears the corresponding mask. All the bits are cleared to 0 when reset.", + 0x14, + [ + ( + "rorim", + "Receive overrun interrupt mask - 0: Receive FIFO written to while full condition interrupt is masked, 1: Receive FIFO written to while full condition interrupt is not masked", + "[0:0]", + "read-write" + ), + ( + "rtim", + "Receive timeout interrupt mask - 0: Receive FIFO not empty and no read prior to timeout period interrupt is masked, 1: Receive FIFO not empty and no read prior to timeout period interrupt is not masked", + "[1:1]", + "read-write" + ), + ( + "rxim", + "Receive FIFO interrupt mask - 0: Receive FIFO half full or less condition interrupt is masked, 1: Receive FIFO half full or less condition interrupt is not masked", + "[2:2]", + "read-write" + ), + ( + "txim", + "Transmit FIFO interrupt mask - 0: Transmit FIFO half empty or less condition interrupt is masked, 1: Transmit FIFO half empty or less condition interrupt is not masked", + "[2:2]", + "read-write" + ) + ], + 16 + ) + +def generate_register_ssp_ris(): + return generate_register( + "ssp_ris", + "The SSPRIS register is the raw interrupt status register. It is a RO register. On a read this register gives the current raw status value of the corresponding interrupt prior to masking. A write has no effect.", + 0x18, + [ + ( + "rorris", + "Gives the raw interrupt state, prior to masking, of the SSPRORINTR interrupt", + "[0:0]", + "read-only" + ), + ( + "rtris", + "Gives the raw interrupt state, prior to masking, of the SSPRTINTR interrupt", + "[1:1]", + "read-only" + ), + ( + "rxris", + "Gives the raw interrupt state, prior to masking, of the SSPRXINTR interrupt", + "[2:2]", + "read-only" + ), + ( + "txris", + "Gives the raw interrupt state, prior to masking, of the SSPTXINTR interrupt", + "[3:3]", + "read-only" + ) + ], + 16 + ) + +def generate_register_ssp_mis(): + return generate_register( + "ssp_mis", + "The SSPMIS register is the masked interrupt status register. It is a RO register. On a read this register gives the current masked status value of the corresponding interrupt. A write has no effect.", + 0x1c, + [ + ( + "rormis", + "Gives the receive over run masked interrupt status, after masking, of the SSPRORINTR interrupt", + "[0:0]", + "read-only" + ), + ( + "rtmis", + "Gives the receive timeout masked interrupt state, after masking, of the SSPRTINTR interrupt", + "[1:1]", + "read-only" + ), + ( + "rxmis", + "Gives the receive FIFO masked interrupt state, after masking, of the SSPRXINTR interrupt", + "[2:2]", + "read-only" + ), + ( + "txmis", + "Gives the transmit FIFO masked interrupt state, after masking, of the SSPTXINTR interrupt", + "[3:3]", + "read-only" + ) + ], + 16 + ) + +def generate_register_ssp_icr(): + return generate_register( + "ssp_icr", + "The SSPICR register is the interrupt clear register and is write-only. On a write of 1, the corresponding interrupt is cleared. A write of 0 has no effect.", + 0x20, + [ + ( + "roric", + "Clears the SSPRORINTR interrupt", + "[0:0]", + "read-write" + ), + ( + "rtic", + "Clears the SSPRTINTR interrupt", + "[1:1]", + "read-write" + ) + ], + 16 + ) + +def generate_register_ssp_dmacr(): + return generate_register( + "ssp_dmacr", + "The SSPDMACR register is the DMA control register. It is a RW register. All the bits are cleared to 0 on reset.", + 0x24, + [ + ( + "rxdmae", + "Receive DMA Enable. If this bit is set to 1, DMA for the receive FIFO is enabled.", + "[0:0]", + "read-write" + ), + ( + "txdmae", + "Transmit DMA Enable. If this bit is set to 1, DMA for the transmit FIFO is enabled.", + "[1:1]", + "read-write" + ) + ], + 16 + ) + +def generate_register_ssp_periph_id0(): + return generate_register( + "ssp_periph_id0", + "The SSPPeriphID0 register is hard-coded and the fields within the register determine reset value. The SSPPeriphID0-3 registers are four 8-bit registers, that span address locations 0xFE0 to 0xFEC. The registers can conceptually be treated as a single 32-bit register.", + 0xfe0, + [ + ( + "part_number0", + "These bits read back as 0x22", + "[7:0]", + "read-only" + ) + ], + 16 + ) + +def generate_register_ssp_periph_id1(): + return generate_register( + "ssp_periph_id1", + "The SSPPeriphID1 register is hard-coded and the fields within the register determine reset value. The SSPPeriphID0-3 registers are four 8-bit registers, that span address locations 0xFE0 to 0xFEC. The registers can conceptually be treated as a single 32-bit register.", + 0xfe4, + [ + ( + "part_number1", + "These bits read back as 0x0", + "[3:0]", + "read-only" + ), + ( + "designer0", + "These bits read back as 0x1", + "[7:4]", + "read-only" + ) + ], + 16 + ) + +def generate_register_ssp_periph_id2(): + return generate_register( + "ssp_periph_id2", + "The SSPPeriphID2 register is hard-coded and the fields within the register determine reset value. The SSPPeriphID0-3 registers are four 8-bit registers, that span address locations 0xFE0 to 0xFEC. The registers can conceptually be treated as a single 32-bit register.", + 0xfe8, + [ + ( + "designer1", + "These bits read back as 0x4", + "[3:0]", + "read-only" + ), + ( + "revision", + "These bits return the peripheral revision", + "[7:4]", + "read-only" + ) + ], + 16 + ) + +def generate_register_ssp_periph_id3(): + return generate_register( + "ssp_periph_id3", + "The SSPPeriphID3 register is hard-coded and the fields within the register determine reset value. The SSPPeriphID0-3 registers are four 8-bit registers, that span address locations 0xFE0 to 0xFEC. The registers can conceptually be treated as a single 32-bit register.", + 0xfec, + [ + ( + "configuration", + "These bits read back as 0x80", + "[7:0]", + "read-only" + ) + ], + 16 + ) + +def generate_register_ssp_pcell_id(num): + magic = [0x0d, 0xf0, 0x05, 0xb1] + + return generate_register( + "ssp_pcell_id{}".format(num), + "The SSPPCellID0-3 registers are four 8-bit wide registers, that span address locations 0xFF0-0xFFC. The registers can conceptually be treated as a 32-bit register. The register is used as a standard cross-peripheral identification system. The SSPPCellID register is set to 0xB105F00D.", + 0xff0 + (num * 4), + [ + ( + "ssp_pcell_id{}".format(num), + "The bits are read as 0x{:X}".format(magic[num]), + "[7:0]", + "read-only" + ) + ], + 16 + ) diff --git a/scripts/cdns_qspi_nor.py b/scripts/cdns_qspi_nor.py new file mode 100755 index 0000000..2adac03 --- /dev/null +++ b/scripts/cdns_qspi_nor.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for cadence QSPI +""" + +def generate_registers_cdns_qspi(dts, peripheral): + """Generate xml string for registers for cadence_qspi peripheral""" + txt = """\ + +""" + txt += generate_register("config", "Cadence QSPI Configuration", 0x00, [ + ("enable", "Enable the QSPI controller", "[0:0]", "read-write"), + ("enb_dir_acc_ctrl", "Enable direct access controller", "[7:7]", "read-write"), + ("decode", "Enable the QSPI decoder", "[9:9]", "read-write"), + ("chipselect", "Chip select - CS0: 0b1110, CS1: 0b1101, CS2: 0b1011, CS3: 0b0111", "[13:10]", "read-write"), + ("dma", "Enable Direct Memory Access", "[15:15]", "read-write"), + ("baud", "Set the QSPI BAUD rate divisor", "[22:19]", "read-write"), + ("dtr_proto", "Enable DTR Protocol", "[24:24]", "read-write"), + ("dual_opcode", "Enable Dual Opcode Mode", "[30:30]", "read-write"), + ("idle", "Set Idle", "[31:31]", "read-write"), + ]) + + txt += generate_register("rd_instr", "Cadence QSPI Read Instruction", 0x04, [ + ("opcode", "Instruction Opcode", "[7:0]", "read-write"), + ("type_instr", "Type of Instruction", "[9:8]", "read-write"), + ("type_addr", "Type of Address", "[13:12]", "read-write"), + ("type_data", "", "[17:16]", "read-write"), + ("mode_en", "Mode ", "[20:20]", "read-write"), + ("dummy", "Send dummy signal to stall the device", "[28:24]", "read-write"), + ]) + + txt += generate_register("wr_instr", "Cadence QSPI Write Instruction", 0x08, [ + ("opcode", "Instruction Opcode", "[7:0]", "read-write"), + ("type_addr", "Type of Address", "[13:12]", "read-write"), + ("type_data", "", "[17:16]", "read-write"), + ]) + + txt += generate_register("delay", "Cadence QSPI Delay", 0x0c, [ + ("tslch", "TSLCH Delay Value", "[7:0]", "read-write"), + ("tchsh", "TCHSH Delay Value", "[15:8]", "read-write"), + ("tsd2d", "TSD2D Delay Value", "[23:16]", "read-write"), + ("tshsl", "TSHSL Delay Value", "[31:24]", "read-write"), + ]) + + txt += generate_register("read_capture", "Cadence QSPI Read Capture", 0x10, [ + ("bypass", "Bypass the Read Capture", "[0:0]", "read-write"), + ("delay", "Read Capture Delay Value", "[4:1]", "read-write"), + ]) + + txt += generate_register("size", "Cadence QSPI Size Configuration", 0x14, [ + ("address", "Address Size in Bytes", "[3:0]", "read-write"), + ("page", "Page Size in Bytes", "[15:4]", "read-write"), + ("block", "Block Size in Bytes", "[21:16]", "read-write"), + ]) + + txt += generate_register("sram_partition", "Cadence QSPI SRAM Partition Size", 0x18, [ + ("size", "Partition size in bytes", "[31:0]", "read-write"), + ]) + + txt += generate_register("indirect_trigger", "Cadence QSPI Indirect Trigger Address", 0x1c, [ + ("address", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("dma", "Cadence QSPI Direct Memory Access", 0x20, [ + ("single", "", "[7:0]", "read-write"), + ("burst", "", "[15:8]", "read-write"), + ]) + + txt += generate_register("remap", "Cadence QSPI Remap Address", 0x24, [ + ("address", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("mode_bit", "Cadence QSPI Mode Bit(s)", 0x28, [ + ("mode", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("sdram_level", "Cadence QSPI SDRAM Level", 0x2c, [ + ("rd", "SDRAM Read Level", "[15:0]", "read-only"), + ("wr", "SDRAM Write Level", "[31:16]", "read-only"), + ]) + + txt += generate_register("wr_completion_ctrl", "Cadence QSPI Write Completion Control", 0x38, [ + # FIXME: fill out the remaining control fields. This is the only field in the Linux driver. + ("disable_auto_poll", "SPI NAND flashes require the address of the status register to be passed in the Read SR command. Also, some SPI NOR flashes like the Cypress Semper flash expect a 4-byte dummy address in the Read SR command in DTR mode. But this controller does not support address phase in the Read SR command when doing auto-HW polling. So, disable write completion polling on the controller's side. spi-nand and spi-nor will take care of polling the status register.", "[14:14]", "read-write"), + ]) + + txt += generate_register("irq_status", "Cadence QSPI IRQ Status", 0x40, [ + ("mode_err", "Mode error interrupt", "[0:0]", "read-write"), + ("underflow", "Buffer underflow interrupt", "[1:1]", "read-write"), + ("ind_comp", "Indirect computation interrupt", "[2:2]", "read-write"), + ("ind_rd_reject", "Indirect read rejection interrupt", "[3:3]", "read-write"), + ("wr_protected_err", "Write protected error interrupt", "[4:4]", "read-write"), + ("illegal_ahb_err", "Illegal AHB clock error interrupt", "[5:5]", "read-write"), + ("watermark", "Watermark interrupt", "[6:6]", "read-write"), + ("ind_sram_full", "Indirect SRAM full interrupt", "[12:12]", "read-write"), + # Reset value: (0b1_1111_1111_1111) + ], 32, 0x1ffff) + + txt += generate_register("irq_mask", "Cadence QSPI IRQ Mask", 0x44, [ + ("mode_err", "Mode error interrupt", "[0:0]", "read-write"), + ("underflow", "Buffer underflow interrupt", "[1:1]", "read-write"), + ("ind_comp", "Indirect computation interrupt", "[2:2]", "read-write"), + ("ind_rd_reject", "Indirect read rejection interrupt", "[3:3]", "read-write"), + ("wr_protected_err", "Write protected error interrupt", "[4:4]", "read-write"), + ("illegal_ahb_err", "Illegal AHB clock error interrupt", "[5:5]", "read-write"), + ("watermark", "Watermark interrupt", "[6:6]", "read-write"), + ("ind_sram_full", "Indirect SRAM full interrupt", "[12:12]", "read-write"), + # Reset value: (IND_COMP | WATERMARK | UNDERFLOW) + ], 32, 0x46) + + txt += generate_register("indirect_rd", "Cadence QSPI Indirect Read", 0x60, [ + ("start", "Start indirect read", "[0:0]", "read-write"), + ("cancel", "Cancel indirect read", "[1:1]", "read-write"), + ("done", "Indirect read done", "[5:5]", "read-write"), + ]) + + txt += generate_register("indirect_rd_watermark", "Cadence QSPI Indirect Read Watermark", 0x64, [ + ("watermark", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("indirect_rd_start_addr", "Cadence QSPI Indirect Read Start Address", 0x68, [ + ("address", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("indirect_rd_bytes", "Cadence QSPI Indirect Read Bytes", 0x6c, [ + ("bytes", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("indirect_wr", "Cadence QSPI Indirect Write", 0x70, [ + ("start", "Start indirect write", "[0:0]", "read-write"), + ("cancel", "Cancel indirect write", "[1:1]", "read-write"), + ("done", "Indirect write done", "[5:5]", "read-write"), + ]) + + txt += generate_register("indirect_wr_watermark", "Cadence QSPI Indirect Write Watermark", 0x74, [ + ("watermark", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("indirect_wr_start_addr", "Cadence QSPI Indirect Write Start Address", 0x78, [ + ("address", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("indirect_wr_bytes", "Cadence QSPI Indirect Write Bytes", 0x7c, [ + ("bytes", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("cmd_ctrl", "Cadence QSPI Command Control", 0x90, [ + ("execute", "Execute-in-Place (XIP)", "[0:0]", "read-write"), + ("in_progress", "Command in progress", "[1:1]", "read-write"), + ("dummy", "Dummy command", "[11:7]", "read-write"), + ("wr_bytes", "Write bytes", "[14:12]", "read-write"), + ("wr_en", "Write enable", "[15:15]", "read-write"), + ("add_bytes", "Add command bytes", "[17:16]", "read-write"), + ("addr_en", "Address enable", "[19:19]", "read-write"), + ("rd_bytes", "Read bytes", "[22:20]", "read-write"), + ("rd_en", "Read enable", "[23:23]", "read-write"), + ("opcode", "Command opcode", "[31:24]", "read-write"), + ]) + + txt += generate_register("cmd_address", "Cadence QSPI Command Address", 0x94, [ + ("address", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("cmd_read_at_lower", "Cadence QSPI Command Read at Lower", 0xa0, [ + ("read_at_lower", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("cmd_read_at_upper", "Cadence QSPI Command Read at Upper", 0xa4, [ + ("read_at_upper", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("cmd_write_at_lower", "Cadence QSPI Command Write at Lower", 0xa8, [ + ("write_at_lower", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("cmd_write_at_upper", "Cadence QSPI Command Write at Upper", 0xac, [ + ("write_at_upper", "", "[31:0]", "read-write"), + ]) + + txt += generate_register("polling_status", "Cadence QSPI Polling Status", 0xb0, [ + ("status", "", "[15:0]", "read-write"), + ("dummy", "", "[20:16]", "read-write"), + ]) + + txt += generate_register("ext_lower", "Cadence QSPI Extension Lower", 0xe0, [ + ("stig", "", "[15:0]", "read-write"), + ("write", "", "[23:16]", "read-write"), + ("read", "", "[31:24]", "read-write"), + ]) + + return txt + """\ + +""" diff --git a/scripts/riscv_clint0_control.py b/scripts/riscv_clint0_control.py index 4658155..f5f5d6e 100755 --- a/scripts/riscv_clint0_control.py +++ b/scripts/riscv_clint0_control.py @@ -51,6 +51,16 @@ def generate_registers_riscv_clint0_msip(hart, addr): msip_""" + hart + """ MSIP Register for hart """ + hart + """ """ + addr + """ + 32 + 0 + + + control + + [0:0] + read-write + + """ @@ -62,6 +72,15 @@ def generate_registers_riscv_clint0_mtimecmp(hart, addr): MTIMECMP Register for hart """ + hart + """ """ + addr + """ 64 + 0 + + + cycles + + [63:0] + read-write + + """ @@ -73,5 +92,14 @@ def generate_registers_riscv_clint0_mtime(addr): MTIME Register """ + addr + """ 64 + 0 + + + cycles + + [63:0] + read-write + + """ diff --git a/scripts/riscv_plic0_control.py b/scripts/riscv_plic0_control.py index fd68fc8..e8bb306 100755 --- a/scripts/riscv_plic0_control.py +++ b/scripts/riscv_plic0_control.py @@ -77,6 +77,16 @@ def generate_registers_riscv_plic0_priority(intr, addr): priority_""" + intr + """ PRIORITY Register for interrupt id """ + intr + """ """ + addr + """ + 32 + 0 + + + priority + + [31:0] + read-write + + """ @@ -88,6 +98,16 @@ def generate_registers_riscv_plic0_pending(inta, inth, intl, addr): pending_""" + inta + """ PENDING Register for interrupt ids """ + temp + """ """ + addr + """ + 32 + 0 + + + pending + + [31:0] + read-write + + """ @@ -99,6 +119,15 @@ def generate_registers_riscv_plic0_enable(inta, inth, intl, hart, addr): enable_""" + inta + """_""" + hart + """ ENABLE Register for interrupt ids """ + temp + """ """ + addr + """ + 0 + + + enable + + [31:0] + read-write + + """ @@ -109,6 +138,16 @@ def generate_registers_riscv_plic0_threshold(hart, addr): threshold_""" + hart + """ PRIORITY THRESHOLD Register for hart """ + hart + """ """ + addr + """ + 32 + 0 + + + priority + + [31:0] + read-write + + """ @@ -119,5 +158,15 @@ def generate_registers_riscv_plic0_claimplete(hart, addr): claimplete_""" + hart + """ CLAIM and COMPLETE Register for hart """ + hart + """ """ + addr + """ + 32 + 0 + + + claimplete + + [31:0] + read-write + + """ diff --git a/scripts/snps_designware_i2c.py b/scripts/snps_designware_i2c.py new file mode 100755 index 0000000..2ffbda1 --- /dev/null +++ b/scripts/snps_designware_i2c.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for designware I2C +""" + +def generate_registers_snps_designware_i2c(dts, peripheral): + """Generate xml string for registers for designware_i2c peripheral""" + txt = """\ + +""" + + txt += generate_register("con", "DesignWare I2C CON", 0x00, [ + ("master", "I2C Master Connection - 0: Slave, 1: Master", "[0:0]", "read-write"), + ("speed", "I2C Speed - 01: Standard, 10: Fast, 11: High", "[2:1]", "read-write"), + ("slave_10bitaddr", "I2C Slave 10-bit Address - 0: False, 1: True", "[3:3]", "read-write"), + ("master_10bitaddr", "I2C Master 10-bit Address - 0: False, 1: True", "[4:4]", "read-write"), + ("restart_en", "I2C Restart Enable - 0: False, 1: True", "[5:5]", "read-write"), + ("slave_disable", "I2C Slave Disable - 0: False, 1: True", "[6:6]", "read-write"), + ("stop_det_ifaddressed", "I2C Stop DET If Addressed - 0: False, 1: True", "[7:7]", "read-write"), + ("tx_empty_ctrl", "I2C TX Empty Control - 0: False, 1: True", "[8:8]", "read-write"), + ("rx_fifo_full_hld_ctrl", "I2C RX FIFO Full Hold Control - 0: False, 1: True", "[9:9]", "read-write"), + ("bus_clear_ctrl", "I2C Bus Clear Control - 0: False, 1: True", "[11:11]", "read-write"), + ]) + txt += generate_register("tar", "DesignWare I2C TAR", 0x04, [ + ("address_7bit", "Target address, 7-bit mode", "[6:0]", "read-write"), + ("address_10bit", "Target address, 10-bit mode", "[9:0]", "read-write"), + ("mode", "Target addressing mode - 0: 7-bit, 1: 10-bit", "[12:12]", "read-write") + ]) + txt += generate_register("sar", "DesignWare I2C SAR", 0x08, [ + ("address_7bit", "Slave address, 7-bit mode", "[6:0]", "read-write"), + ("address_10bit", "Slave address, 10-bit mode", "[9:0]", "read-write"), + ]) + txt += generate_register("data_cmd", "DesignWare I2C Data Command", 0x10, [ + ("dat", "Data Command Data Byte", "[7:0]", "read-write"), + ("read", "Data Command READ Bit - 0: Write, 1: Read", "[8:8]", "read-write"), + ("stop", "Data Command STOP Bit - 0: Non-terminal DATA command byte, 1: Terminal DATA command byte", "[9:9]", "read-write"), + ("restart", "Data Command RESTART Bit - 0: Do not restart the transfer, 1: Restart the transfer", "[10:10]", "read-write"), + ("first_data_byte", "Data Command First Data Byte - 0: False, 1: True", "[11:11]", "read-write"), + ]) + txt += generate_register("ss_scl_hcnt", "DesignWare I2C SS SCL HCNT", 0x14, [ + ("ss_scl_hcnt", "", "[31:0]", "read-write") + ]) + txt += generate_register("ss_scl_lcnt", "DesignWare I2C SS SCL LCNT", 0x18, [ + ("ss_scl_lcnt", "", "[31:0]", "read-write") + ]) + txt += generate_register("fs_scl_hcnt", "DesignWare I2C FS SCL HCNT", 0x1c, [ + ("fs_scl_hcnt", "", "[31:0]", "read-write") + ]) + txt += generate_register("fs_scl_lcnt", "DesignWare I2C FS SCL LCNT", 0x20, [ + ("fs_scl_lcnt", "", "[31:0]", "read-write") + ]) + txt += generate_register("hs_scl_hcnt", "DesignWare I2C HS SCL HCNT", 0x24, [ + ("hs_scl_hcnt", "", "[31:0]", "read-write") + ]) + txt += generate_register("hs_scl_lcnt", "DesignWare I2C HS SCL LCNT", 0x28, [ + ("hs_scl_lcnt", "", "[31:0]", "read-write") + ]) + txt += generate_register("intr_stat", "DesignWare I2C Interrupt Status", 0x2c, generate_intr_fields("read-only")) + txt += generate_register("intr_mask", "DesignWare I2C Interrupt Mask", 0x30, generate_intr_fields("read-write")) + txt += generate_register("raw_intr_stat", "DesignWare I2C Raw Interrupt Status", 0x34, generate_intr_fields("read-only")) + txt += generate_register("rx_tl", "DesignWare I2C RX TL", 0x38, [ + ("rx_tl", "", "[31:0]", "read-write") + ]) + txt += generate_register("tx_tl", "DesignWare I2C TX TL", 0x3c, [ + ("tx_tl", "", "[31:0]", "read-write") + ]) + txt += generate_register("clr_intr", "DesignWare I2C Clear Interrrupt", 0x40, generate_intr_fields("read-write")) + txt += generate_register("clr_rx_under", "DesignWare I2C Clear RX Underrun", 0x44, [("clr_rx_under", "", "[31:0]", "read-write")]) + txt += generate_register("clr_rx_over", "DesignWare I2C Clear RX Overrun", 0x48, [ + ("clr_rx_over", "", "[31:0]", "read-write") + ]) + txt += generate_register("clr_tx_over", "DesignWare I2C Clear TX Overrun", 0x4c, [ + ("clr_tx_over", "", "[31:0]", "read-write") + ]) + txt += generate_register("clr_rd_req", "DesignWare I2C Clear Read Request", 0x50, [ + ("clr_rd_req", "", "[31:0]", "read-write") + ]) + txt += generate_register("clr_tx_abrt", "DesignWare I2C Clear TX Abort", 0x54, [ + ("clr_tx_abrt", "", "[31:0]", "read-write") + ]) + txt += generate_register("clr_rx_done", "DesignWare I2C Clear RX Done", 0x58, [ + ("clr_rx_done", "", "[31:0]", "read-write") + ]) + txt += generate_register("clr_activity", "DesignWare I2C Clear Activity", 0x5c, [ + ("clr_activity", "", "[31:0]", "read-write") + ]) + txt += generate_register("clr_stop_det", "DesignWare I2C Clear Stop DET", 0x60, [ + ("clr_stop_det", "", "[31:0]", "read-write") + ]) + txt += generate_register("clr_start_det", "DesignWare I2C Clear Start DET", 0x64, [ + ("clr_start_det", "", "[31:0]", "read-write") + ]) + txt += generate_register("clr_gen_call", "DesignWare I2C Clear General Call", 0x68, [ + ("clr_gen_call", "", "[31:0]", "read-write") + ]) + txt += generate_register("enable", "DesignWare I2C Enable", 0x6c, [ + ("abort", "", "[1:1]", "read-write") + ]) + txt += generate_register("status", "DesignWare I2C Status", 0x70, [ + ("activity", "", "[0:0]", "read-only"), + ("tfe", "", "[2:2]", "read-only"), + ("rfne", "", "[3:3]", "read-only"), + ("master_activity", "", "[5:5]", "read-only"), + ("slave_activity", "", "[6:6]", "read-only") + ]) + txt += generate_register("txflr", "DesignWare I2C TX Failure", 0x74, [ + ("txflr", "", "[31:0]", "read-write") + ]) + txt += generate_register("rxflr", "DesignWare I2C RX Failure", 0x78, [ + ("rxflr", "", "[31:0]", "read-write") + ]) + txt += generate_register("sda_hold", "DesignWare I2C SDA Hold", 0x7c, [ + ("sda_hold", "", "[31:0]", "read-write") + ]) + # From linux i2c-designware-core: only expected abort codes are listed here + # Refer to the datasheet for the full list + txt += generate_register("tx_abrt_source", "DesignWare I2C TX Abort Source", 0x80, [ + ("b7_addr_noack", "", "[0:0]", "read-only"), + ("b10_addr1_noack", "", "[1:1]", "read-only"), + ("b10_addr2_noack", "", "[2:2]", "read-only"), + ("txdata_noack", "", "[3:3]", "read-only"), + ("gcall_noack", "", "[4:4]", "read-only"), + ("gcall_read", "", "[5:5]", "read-only"), + ("sbyte_ackdet", "", "[7:7]", "read-only"), + ("sbyte_norstrt", "", "[9:9]", "read-only"), + ("b10_rd_norstrt", "", "[10:10]", "read-only"), + ("master_dis", "", "[11:11]", "read-only"), + ("arb_lost", "", "[12:12]", "read-only"), + ("slave_flush_txfifo", "", "[13:13]", "read-only"), + ("slave_arblost", "", "[14:14]", "read-only"), + ("slave_rd_intx", "", "[15:15]", "read-only") + ]) + txt += generate_register("enable_status", "DesignWare I2C Enable Status", 0x9c, [ + ("activity", "", "[0:0]", "read-write"), + ("tfe", "", "[2:2]", "read-write"), + ("rfne", "", "[3:3]", "read-write"), + ("master_activity", "", "[5:5]", "read-write"), + ("slave_activity", "", "[6:6]", "read-write") + ]) + txt += generate_register("clr_restart_det", "DesignWare I2C Clear Restart DET", 0xa8, [ + ("clr_restart_det", "", "[31:0]", "read-write") + ]) + txt += generate_register("comp_param_1", "DesignWare I2C Compatibility Parameter 1", 0xf4, [ + ("speed", "Speed mask - 01: Standard, 10: Full, 11: High", "[3:2]", "read-only") + ]) + # Hold MIN Version: eg. 0x3131312a ( "111*" == v1.11* ) + txt += generate_register("comp_version", "DesignWare I2C Compatibility Version", 0xf8, [ + ("comp_version", "", "[31:0]", "read-only") + ]) + # I2C Type: 0x44570140 ( "DW" + 0x0140 ) + txt += generate_register("comp_type", "DesignWare I2C Compatibility Type", 0xfc, [ + ("comp_type", "", "[31:0]", "read-only") + ]) + + return txt + """\ + +""" + +def generate_intr_fields(access): + return [ + ("rx_under", "RX FIFO Underrun", "[0:0]", access), + ("rx_over", "RX FIFO Overrun", "[1:1]", access), + ("rx_full", "RX FIFO Full", "[2:2]", access), + ("tx_over", "TX FIFO Overrun", "[3:3]", access), + ("tx_empty", "TX FIFO Empty", "[4:4]", access), + ("rd_req", "Read Request", "[5:5]", access), + ("tx_abrt", "TX Abort", "[6:6]", access), + ("rx_done", "RX Done", "[7:7]", access), + ("activity", "Activity", "[8:8]", access), + ("stop_det", "Stop DET", "[9:9]", access), + ("start_det", "Start DET", "[10:10]", access), + ("gen_call", "General Call", "[11:11]", access), + ("restart_det", "Restart DET", "[12:12]", access), + ("mst_on_hold", "Master on Hold", "[13:13]", access) + ] diff --git a/scripts/snps_dw_apb_uart.py b/scripts/snps_dw_apb_uart.py new file mode 100755 index 0000000..9df6d11 --- /dev/null +++ b/scripts/snps_dw_apb_uart.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for designware APB UART +""" + +def generate_registers_snps_dw_apb_uart(dts, peripheral): + """Generate xml string for registers for designware_apb_uart peripheral""" + txt = """\ + +""" + + # UART repurposes the same address range for read-write semantics, and also changes meaning depending on the value of the DLAB (LCR[7]) bit. + + txt += generate_register("rbr", "Receive Buffer Register", 0x0, [ + ("rbr", "Data byte received on the serial input port (sin) in UART mode, or the serial infrared input (sir_in) in infrared mode. The data in this register is valid only if the Data Ready (DR) bit in the Line Status Register (LCR) is set. If in non-FIFO mode (FIFO_MODE == NONE) or FIFOs are disabled (FCR[0] set to zero), the data in the RBR must be read before the next data arrives, otherwise it is overwritten, resulting in an over-run error. If in FIFO mode (FIFO_MODE != NONE) and FIFOs are enabled (FCR[0] set to one), this register accesses the head of the receive FIFO. If the receive FIFO is full and this register is not read before the next data character arrives, then the data already in the FIFO is preserved, but any incoming data are lost and an over-run error occurs.", "[7:0]", "read-only") + ]) + txt += generate_register("thr", "Transmit Holding Register", 0x0, [ + ("thr", "Data to be transmitted on the serial output port (sout) in UART mode or the serial infrared output (sir_out_n) in infrared mode. Data should only be written to the THR when the THR Empty (THRE) bit (LSR[5]) is set. If in non-FIFO mode or FIFOs are disabled (FCR[0] = 0) and THRE is set, writing a single character to the THR clears the THRE. Any additional writes to the THR before the THRE is set again causes the THR data to be overwritten. If in FIFO mode and FIFOs are enabled (FCR[0] = 1) and THRE is set, x number of characters of data may be written to the THR before the FIFO is full. The number x (default=16) is determined by the value of FIFO Depth that you set during configuration. Any attempt to write data when the FIFO is full results in the write data being lost.", "[7:0]", "write-only") + ]) + txt += generate_register("dll", "Divisor Latch Low", 0x0, [ + ("dll", "Lower 8 bits of a 16-bit, read/write, Divisor Latch register that contains the baud rate divisor for the UART. This register may only be accessed when the DLAB bit (LCR[7]) is set and the UART is not busy (USR[0] is zero). The output baud rate is equal to the serial clock (pclk if one clock design, sclk if two clock design (CLOCK_MODE == Enabled)) frequency divided by sixteen times the value of the baud rate divisor, as follows: baud rate = (serial clock freq) / (16 * divisor). Note that with the Divisor Latch Registers (DLL and DLH) set to zero, the baud clock is disabled and no serial communications occur. Also, once the DLL is set, at least 8 clock cycles of the slowest DW_apb_uart clock should be allowed to pass before transmitting or receiving data.", "[7:0]", "read-write") + ]) + + txt += generate_register("dlh", "Divisor Latch High", 0x4, [ + ("dlh", "Upper 8-bits of a 16-bit, read/write, Divisor Latch register that contains the baud rate divisor for the UART. This register may only be accessed when the DLAB bit (LCR[7]) is set and the UART is not busy (USR[0] is zero). The output baud rate is equal to the serial clock (pclk if one clock design, sclk if two clock design (CLOCK_MODE == Enabled)) frequency divided by sixteen times the value of the baud rate divisor, as follows: baud rate = (serial clock freq) / (16 * divisor). Note that with the Divisor Latch Registers (DLL and DLH) set to zero, the baud clock is disabled and no serial communications occur. Also, once the DLH is set, at least 8 clock cycles of the slowest DW_apb_uart clock should be allowed to pass before transmitting or receiving data.", "[7:0]", "read-write") + ]) + txt += generate_register("ier", "Interrupt Enable Register", 0x4, [ + ("ptime", "Programmable THRE Interrupt Mode Enable that can be written to only when THRE_MODE_USER == Enabled, always readable. This is used to enable/disable the generation of THRE Interrupt. 0 = disabled 1 = enabled", "[7:7]", "read-write"), + ("edssi", "Enable Modem Status Interrupt. This is used to enable/disable the generation of Modem Status Interrupt. This is the fourth highest priority interrupt. 0 = disabled 1 = enabled", "[3:3]", "read-write"), + ("elsi", "Enable Receiver Line Status Interrupt. This is used to enable/disable the generation of Receiver Line Status Interrupt. This is the highest priority interrupt. 0 = disabled 1 = enabled", "[2:2]", "read-write"), + ("etbei", "Enable Transmit Holding Register Empty Interrupt. This is used to enable/disable the generation of Transmitter Holding Register Empty Interrupt. This is the third highest priority interrupt. 0 = disabled 1 = enabled", "[1:1]", "read-write"), + ("erbfi", "Enable Received Data Available Interrupt. This is used to enable/disable the generation of Received Data Available Interrupt and the Character Timeout Interrupt (if in FIFO mode and FIFOs enabled). These are the second highest priority interrupts. 0 = disabled 1 = enabled", "[0:0]", "read-write") + ]) + + txt += generate_register("iir", "Interrupt Identity Register", 0x8, [ + ("fifose", "FIFOs Enabled. This is used to indicate whether the FIFOs are enabled or disabled. 00 = disabled 11 = enabled", "[7:6]", "read-only"), + ("iid", "Interrupt ID. This indicates the highest priority pending interrupt which can be one of the following types: 0000 = modem status 0001 = no interrupt pending 0010 = THR empty 0100 = received data available 0110 = receiver line status 0111 = busy detect 1100 = character timeout The interrupt priorities are split into four levels that are detailed in Table 8 on page 97. Bit 3 indicates an interrupt can only occur when the FIFOs are enabled and used to distinguish a Character Timeout condition interrupt.", "[3:0]", "read-only") + ], 32, 0x1) + txt += generate_register("fcr", "FIFO Control Register", 0x8, [ + ("rt", "RCVR Trigger. This is used to select the trigger level in the receiver FIFO at which the Received Data Available Interrupt is generated. In auto flow control mode it is used to determine when the rts_n signal is de-asserted. It also determines when the dma_rx_req_n signal is asserted in certain modes of operation. For details on DMA support, refer to “DMA Support” on page 58. The following trigger levels are supported: 00 = 1 character in the FIFO 01 = FIFO ¼ full 10 = FIFO ½ full 11 = FIFO 2 less than full", "[7:6]", "write-only"), + ("tet", "TX Empty Trigger. Writes have no effect when THRE_MODE_USER == Disabled. This is used to select the empty threshold level at which the THRE Interrupts are generated when the mode is active. It also determines when the dma_tx_req_n signal is asserted when in certain modes of operation. For details on DMA support, refer to “DMA Support” on page 58. The following trigger levels are supported: 00 = FIFO empty 01 = 2 characters in the FIFO 10 = FIFO ¼ full 11 = FIFO ½ full", "[5:4]", "write-only"), + ("dmam", "DMA Mode. This determines the DMA signalling mode used for the dma_tx_req_n and dma_rx_req_n output signals when additional DMA handshaking signals are not selected (DMA_EXTRA == No). For details on DMA support, refer to “DMA Support” on page 58. 0 = mode 0 1 = mode 1", "[3:3]", "write-only"), + ("xfifor", "XMIT FIFO Reset. This resets the control portion of the transmit FIFO and treats the FIFO as empty. This also de-asserts the DMA TX request and single signals when additional DMA handshaking signals are selected (DMA_EXTRA == YES). Note that this bit is 'self-clearing'. It is not necessary to clear this bit.", "[2:2]", "write-only"), + ("rfifor", "RCVR FIFO Reset. This resets the control portion of the receive FIFO and treats the FIFO as empty. This also de-asserts the DMA RX request and single signals when additional DMA handshaking signals are selected (DMA_EXTRA == YES). Note that this bit is 'self-clearing'. It is not necessary to clear this bit.", "[1:1]", "write-only"), + ("fifoe", "FIFO Enable. This enables/disables the transmit (XMIT) and receive (RCVR) FIFOs. Whenever the value of this bit is changed both the XMIT and RCVR controller portion of FIFOs is reset.", "[0:0]", "write-only") + ]) + + txt += generate_register("lcr", "Line Control Register", 0xc, [ + ("dlab", "Divisor Latch Access Bit. Writeable only when UART is not busy (USR[0] is zero), always readable. This bit is used to enable reading and writing of the Divisor Latch register (DLL and DLH) to set the baud rate of the UART. This bit must be cleared after initial baud rate setup in order to access other registers.", "[7:7]", "read-write"), + ("bc", "Break Control Bit.This is used to cause a break condition to be transmitted to the receiving device. If set to one the serial output is forced to the spacing (logic 0) state. When not in Loopback Mode, as determined by MCR[4], the sout line is forced low until the Break bit is cleared. If SIR_MODE == Enabled and active (MCR[6] set to one) the sir_out_n line is continuously pulsed. When in Loopback Mode, the break condition is internally looped back to the receiver and the sir_out_n line is forced low.", "[6:6]", "read-write"), + ("eps", "Even Parity Select. Writeable only when UART is not busy (USR[0] is zero), always readable. This is used to select between even and odd parity, when parity is enabled (PEN set to one). If set to one, an even number of logic 1s is transmitted or checked. If set to zero, an odd number of logic 1s is transmitted or checked.", "[4:4]", "read-write"), + ("pen", "Parity Enable. Writeable only when UART is not busy (USR[0] is zero), always readable. This bit is used to enable and disable parity generation and detection in transmitted and received serial character respectively. 0 = parity disabled 1 = parity enabled", "[3:3]", "read-write"), + ("stop", "Number of stop bits. Writeable only when UART is not busy (USR[0] is zero), always readable. This is used to select the number of stop bits per character that the peripheral transmits and receives. If set to zero, one stop bit is transmitted in the serial data. If set to one and the data bits are set to 5 (LCR[1:0] set to zero) one and a half stop bits is transmitted. Otherwise, two stop bits are transmitted. Note that regardless of the number of stop bits selected, the receiver checks only the first stop bit. 0 = 1 stop bit 1 = 1.5 stop bits when DLS (LCR[1:0]) is zero, else 2 stop bit", "[2:2]", "read-write"), + ("dls", "Data Length Select. Writeable only when UART is not busy (USR[0] is zero), always readable. This is used to select the number of data bits per character that the peripheral transmits and receives. The number of bit that may be selected areas follows: 00 = 5 bits 01 = 6 bits 10 = 7 bits 11 = 8 bits", "[1:0]", "read-write") + ]) + + txt += generate_register("mcr", "Modem Control Register", 0x10, [ + ("sire", "SIR Mode Enable. Writeable only when SIR_MODE == Enabled, always readable. This is used to enable/disable the IrDA SIR Mode features as described in “IrDA 1.0 SIR Protocol” on page 47. 0 = IrDA SIR Mode disabled 1 = IrDA SIR Mode enabled", "[6:6]", "read-write"), + ("afce", "Auto Flow Control Enable. Writeable only when AFCE_MODE == Enabled, always readable. When FIFOs are enabled and the Auto Flow Control Enable (AFCE) bit is set, Auto Flow Control features are enabled as described in “Auto Flow Control” on page 51. 0 = Auto Flow Control Mode disabled 1 = Auto Flow Control Mode enabled", "[5:5]", "read-write"), + ("lb", "LoopBack Bit. This is used to put the UART into a diagnostic mode for test purposes. If operating in UART mode (SIR_MODE != Enabled or not active, MCR[6] set to zero), data on the sout line is held high, while serial data output is looped back to the sin line, internally. In this mode all the interrupts are fully functional. Also, in loopback mode, the modem control inputs (dsr_n, cts_n, ri_n, dcd_n) are disconnected and the modem control outputs (dtr_n, rts_n, out1_n, out2_n) are looped back to the inputs, internally. If operating in infrared mode (SIR_MODE == Enabled AND active, MCR[6] set to one), data on the sir_out_n line is held low, while serial data output is inverted and looped back to the sir_in line", "[4:4]", "read-write"), + ("out2", "OUT2. This is used to directly control the user-designated Output2 (out2_n) output. The value written to this location is inverted and driven out on out2_n, that is: 0 = out2_n de-asserted (logic 1) 1 = out2_n asserted (logic 0) Note that in Loopback mode (MCR[4] set to one), the out2_n output is held inactive high while the value of this location is internally looped back to an input.", "[3:3]", "read-write"), + ("out1", "OUT1. This is used to directly control the user-designated Output1 (out1_n) output. The value written to this location is inverted and driven out on out1_n, that is: 0 = out1_n de-asserted (logic 1) 1 = out1_n asserted (logic 0) Note that in Loopback mode (MCR[4] set to one), the out1_n output is held inactive high while the value of this location is internally looped back to an input.", "[2:2]", "read-write"), + ("rts", "Request to Send. This is used to directly control the Request to Send (rts_n) output. The Request To Send (rts_n) output is used to inform the modem or data set that the UART is ready to exchange data. When Auto RTS Flow Control is not enabled (MCR[5] set to zero), the rts_n signal is set low by programming MCR[1] (RTS) to a high.In Auto Flow Control, AFCE_MODE == Enabled and active (MCR[5] set to one) and FIFOs enable (FCR[0] set to one), the rts_n output is controlled in the same way, but is also gated with the receiver FIFO threshold trigger (rts_n is inactive high when above the threshold). The rts_n signal is de-asserted when MCR[1] is set low. Note that in Loopback mode (MCR[4] set to one), the rts_n output is held inactive high while the value of this location is internally looped back to an input.", "[1:1]", "read-write"), + ("dtr", "Data Terminal Ready. This is used to directly control the Data Terminal Ready (dtr_n) output. The value written to this location is inverted and driven out on dtr_n, that is: 0 = dtr_n de-asserted (logic 1) 1 = dtr_n asserted (logic 0) The Data Terminal Ready output is used to inform the modem or data set that the UART is ready to establish communications. Note that in Loopback mode (MCR[4] set to one), the dtr_n output is held inactive high while the value of this location is internally looped back to an input.", "[0:0]", "read-write"), + ]) + + txt += generate_register("lsr", "Line Status Register", 0x14, [ + ("rfe", "Receiver FIFO Error bit. This bit is only relevant when FIFO_MODE != NONE AND FIFOs are enabled (FCR[0] set to one). This is used to indicate if there is at least one parity error, framing error, or break indication in the FIFO. 0 = no error in RX FIFO 1 = error in RX FIFO This bit is cleared when the LSR is read and the character with the error is at the top of the receiver FIFO and there are no subsequent errors in the FIFO.", "[7:7]", "read-only"), + ("temt", "Transmitter Empty bit. If in FIFO mode (FIFO_MODE != NONE) and FIFOs enabled (FCR[0] set to one), this bit is set whenever the Transmitter Shift Register and the FIFO are both empty. If in non-FIFO mode or FIFOs are disabled, this bit is set whenever the Transmitter Holding Register and the Transmitter Shift Register are both empty.", "[6:6]", "read-only"), + ("thre", "Transmit Holding Register Empty bit. If THRE_MODE_USER == Disabled or THRE mode is disabled (IER[7] set to zero) and regardless of FIFO's being implemented/enabled or not, this bit indicates that the THR or TX FIFO is empty. This bit is set whenever data is transferred from the THR or TX FIFO to the transmitter shift register and no new data has been written to the THR or TX FIFO. This also causes a THRE Interrupt to occur, if the THRE Interrupt is enabled. If THRE_MODE_USER == Enabled AND FIFO_MODE != NONE and both modes are active (IER[7] set to one and FCR[0] set to one respectively), the functionality is switched to indicate the transmitter FIFO is full, and no longer controls THRE interrupts, which are then controlled by the FCR[5:4] threshold setting. For more details, see “Programmable THRE Interrupt” on page 54.", "[5:5]", "read-only"), + ("bi", "Break Interrupt bit. This is used to indicate the detection of a break sequence on the serial input data. If in UART mode (SIR_MODE == Disabled), it is set whenever the serial input, sin, is held in a logic '0' state for longer than the sum of start time + data bits + parity + stop bits. If in infrared mode (SIR_MODE == Enabled), it is set whenever the serial input, sir_in, is continuously pulsed to logic '0' for longer than the sum of start time + data bits + parity + stop bits. A break condition on serial input causes one and only one character, consisting of all zeros, to be received by the UART. In the FIFO mode, the character associated with the break condition is carried through the FIFO and is revealed when the character is at the top of the FIFO. Reading the LSR clears the BI bit. In the non-FIFO mode, the BI indication occurs immediately and persists until the LSR is read.", "[4:4]", "read-only"), + ("fe", "Framing Error bit. This is used to indicate the occurrence of a framing error in the receiver. A framing error occurs when the receiver does not detect a valid STOP bit in the received data. In the FIFO mode, since the framing error is associated with a character received, it is revealed when the character with the framing error is at the top of the FIFO. When a framing error occurs, the UART tries to resynchronize. It does this by assuming that the error was due to the start bit of the next character and then continues receiving the other bit i.e. data, and/or parity and stop. It should be noted that the Framing Error (FE) bit (LSR[3]) is set if a break interrupt has occurred, as indicated by Break Interrupt (BI) bit (LSR[4]). 0 = no framing error 1 = framing error Reading the LSR clears the FE bit.", "[3:3]", "read-only"), + ("pe", "Parity Error bit. This is used to indicate the occurrence of a parity error in the receiver if the Parity Enable (PEN) bit (LCR[3]) is set. In the FIFO mode, since the parity error is associated with a character received, it is revealed when the character with the parity error arrives at the top of the FIFO. It should be noted that the Parity Error (PE) bit (LSR[2]) is set if a break interrupt has occurred, as indicated by Break Interrupt (BI) bit (LSR[4]). 0 = no parity error 1 = parity error Reading the LSR clears the PE bit.", "[2:2]", "read-only"), + ("oe", "Overrun error bit. This is used to indicate the occurrence of an overrun error. This occurs if a new data character was received before the previous data was read. In the non-FIFO mode, the OE bit is set when a new character arrives in the receiver before the previous character was read from the RBR. When this happens, the data in the RBR is overwritten. In the FIFO mode, an overrun error occurs when the FIFO is full and a new character arrives at the receiver. The data in the FIFO is retained and the data in the receive shift register is lost. 0 = no overrun error 1 = overrun error Reading the LSR clears the OE bit.", "[1:1]", "read-only"), + ("dr", "Data Ready bit. This is used to indicate that the receiver contains at least one character in the RBR or the receiver FIFO. 0 = no data ready 1 = data ready This bit is cleared when the RBR is read in non-FIFO mode, or when the receiver FIFO is empty, in FIFO mode.", "[0:0]", "read-only") + ]) + + txt += generate_register("msr", "Line Status Register", 0x18, [ + ("dcd", "Data Carrier Detect. This is used to indicate the current state of the modem control line dcd_n. This bit is the complement of dcd_n. When the Data Carrier Detect input (dcd_n) is asserted it is an indication that the carrier has been detected by the modem or data set. 0 = dcd_n input is de-asserted (logic 1) 1 = dcd_n input is asserted (logic 0) In Loopback Mode (MCR[4] set to one), DCD is the same as MCR[3] (Out2).", "[7:7]", "read-only"), + ("ri", "Ring Indicator. This is used to indicate the current state of the modem control line ri_n. This bit is the complement of ri_n. When the Ring Indicator input (ri_n) is asserted it is an indication that a telephone ringing signal has been received by the modem or data set. 0 = ri_n input is de-asserted (logic 1) 1 = ri_n input is asserted (logic 0) In Loopback Mode (MCR[4] set to one), RI is the same as MCR[2] (Out1).", "[6:6]", "read-only"), + ("dsr", "Data Set Ready. This is used to indicate the current state of the modem control line dsr_n. This bit is the complement of dsr_n. When the Data Set Ready input (dsr_n) is asserted it is an indication that the modem or data set is ready to establish communications with the DW_apb_uart. 0 = dsr_n input is de-asserted (logic 1) 1 = dsr_n input is asserted (logic 0) In Loopback Mode (MCR[4] set to one), DSR is the same as MCR[0] (DTR).", "[5:5]", "read-only"), + ("cts", "Clear to Send. This is used to indicate the current state of the modem control line cts_n. This bit is the complement of cts_n. When the Clear to Send input (cts_n) is asserted it is an indication that the modem or data set is ready to exchange data with the DW_apb_uart. 0 = cts_n input is de-asserted (logic 1) 1 = cts_n input is asserted (logic 0) In Loopback Mode (MCR[4] = 1), CTS is the same as MCR[1] (RTS)", "[4:4]", "read-only"), + ("ddcd", "Delta Data Carrier Detect. This is used to indicate that the modem control line dcd_n has changed since the last time the MSR was read. 0 = no change on dcd_n since last read of MSR 1 = change on dcd_n since last read of MSR Reading the MSR clears the DDCD bit. In Loopback Mode (MCR[4] = 1), DDCD reflects changes on MCR[3] (Out2). Note, if the DDCD bit is not set and the dcd_n signal is asserted (low) and a reset occurs (software or otherwise), then the DDCD bit is set when the reset is removed if the dcd_n signal remains asserted.", "[3:3]", "read-only"), + ("teri", "Trailing Edge of Ring Indicator. This is used to indicate that a change on the input ri_n (from an active-low to an inactive-high state) has occurred since the last time the MSR was read. 0 = no change on ri_n since last read of MSR 1 = change on ri_n since last read of MSR Reading the MSR clears the TERI bit. In Loopback Mode (MCR[4] = 1), TERI reflects when MCR[2] (Out1) has changed state from a high to a low.", "[2:2]", "read-only"), + ("ddsr", "Delta Data Set Ready. This is used to indicate that the modem control line dsr_n has changed since the last time the MSR was read. 0 = no change on dsr_n since last read of MSR 1 = change on dsr_n since last read of MSR Reading the MSR clears the DDSR bit. In Loopback Mode (MCR[4] = 1), DDSR reflects changes on MCR[0] (DTR). Note, if the DDSR bit is not set and the dsr_n signal is asserted (low) and a reset occurs (software or otherwise), then the DDSR bit is set when the reset is removed if the dsr_n signal remains asserted.", "[1:1]", "read-only"), + ("dcts", "Delta Clear to Send. This is used to indicate that the modem control line cts_n has changed since the last time the MSR was read. 0 = no change on ctsdsr_n since last read of MSR 1 = change on ctsdsr_n since last read of MSR Reading the MSR clears the DCTS bit. In Loopback Mode (MCR[4] = 1), DCTS reflects changes on MCR[1] (RTS). Note, if the DCTS bit is not set and the cts_n signal is asserted (low) and a reset occurs (software or otherwise), then the DCTS bit is set when the reset is removed if the cts_n signal remains asserted.", "[0:0]", "read-only") + ]) + + txt += generate_register("scr", "Scratch Pad Register", 0x1c, [ + ("scr", "This register is for programmers to use as a temporary storage space. It has no defined purpose in the DW_apb_uart.", "[7:0]", "read-write") + ]) + + txt += generate_register("lpdll", "Low Power Divisor Latch Low Register: This register is only valid when the DW_apb_uart is configured to have SIR low-power reception capabilities implemented (SIR_LP_RX = Yes). If SIR low-power reception capabilities are not implemented, this register does not exist and reading from thsi register address returns zero.", 0x20, [ + ("lpdll", "This register makes up the lower 8-bits of a 16-bit, read/write, Low Power Divisor Latch register that contains the baud rate divisor for the UART, which must give a baud rate of 115.2K. This is required for SIR Low Power (minimum pulse width) detection at the receiver. This register may only be accessed when the DLAB bit (LCR[7]) is set and the UART is not busy (USR[0]) is 0). The output low-power baud rate is equal to the serial clock (sclk) frequency divided by sixteen times the value of the baud rate divisor, as follows: Low power baud rate = (serial clock frequency)/(16* divisor) Therefore, a divisor must be selected to give a baud rate of 115.2K. NOTE: When the Low Power Divisor Latch registers (LPDLL and LPDLH) are set to 0, the low-power baud clock is disabled and no low-power pulse detection (or any pulse detection) occurs at the receiver. Also, once the LPDLL is set, at least eight clock cycles of the slowest DW_apb_uart clock should be allowed to pass before transmitting or receiving data.", "[7:0]", "read-write") + ]) + + txt += generate_register("lpdlh", "Low Power Divisor Latch High Register: This register is only valid when the DW_apb_uart is configured to have SIR low-power reception capabilities implemented (SIR_LP_RX = Yes). If SIR low-power reception capabilities are not implemented, this register does not exist and reading from thsi register address returns zero.", 0x24, [ + ("lpdlh", "This register makes up the upper 8-bits of a 16-bit, read/write, Low Power Divisor Latch register that contains the baud rate divisor for the UART, which must give a baud rate of 115.2K. This is required for SIR Low Power (minimum pulse width) detection at the receiver. This register may only be accessed when the DLAB bit (LCR[7]) is set and the UART is not busy (USR[0]) is 0). The output low-power baud rate is equal to the serial clock (sclk) frequency divided by sixteen times the value of the baud rate divisor, as follows: Low power baud rate = (serial clock frequency)/(16* divisor) Therefore, a divisor must be selected to give a baud rate of 115.2K. NOTE: When the Low Power Divisor Latch registers (LPDLL and LPDLH) are set to 0, the low-power baud clock is disabled and no low-power pulse detection (or any pulse detection) occurs at the receiver. Also, once the LPDLH is set, at least eight clock cycles of the slowest DW_apb_uart clock should be allowed to pass before transmitting or receiving data", "[7:0]", "read-write") + ]) + + for reg in range(16): + txt += generate_register("srbr{}".format(reg), "Shadow Receive Buffer Register {}: This register is only valid when the DW_apb_uart is configured to have additional shadow registers implemented (SHADOW == YES). If shadow registers are not implemented, this register does not exist and reading from this register address returns zero.".format(reg), 0x30 + (reg * 4), [ + ("srbr", "This is a shadow register for the RBR and has been allocated sixteen 32-bit locations so as to accommodate burst accesses from the master. This register contains the data byte received on the serial input port (sin) in UART mode or the serial infrared input (sir_in) in infrared mode. The data in this register is valid only if the Data Ready (DR) bit in the Line status Register (LSR) is set. If in non-FIFO mode (FIFO_MODE == NONE) or FIFOs are disabled (FCR[0] set to zero), the data in the RBR must be read before the next data arrives, otherwise it is overwritten, resulting in an overrun error. If in FIFO mode (FIFO_MODE != NONE) and FIFOs are enabled (FCR[0] set to one), this register accesses the head of the receive FIFO. If the receive FIFO is full and this register is not read before the next data character arrives, then the data already in the FIFO are preserved, but any incoming data is lost. An overrun error also occurs.", "[7:0]", "read-only") + ]) + + txt += generate_register("sthr{}".format(reg), "Shadow Transmit Holding Register {}: This register is only valid when the DW_apb_uart is configured to have additional shadow registers implemented (SHADOW == YES). If shadow registers are not implemented, this register does not exist and reading from this register address returns zero.".format(reg), 0x30 + (reg * 4), [ + ("sthr", "This is a shadow register for the THR and has been allocated sixteen 32-bit locations so as to accommodate burst accesses from the master. This register contains data to be transmitted on the serial output port (sout) in UART mode or the serial infrared output (sir_out_n) in infrared mode. Data should only be written to the THR when the THR Empty (THRE) bit (LSR[5]) is set. If in non-FIFO mode or FIFOs are disabled (FCR[0] set to zero) and THRE is set, writing a single character to the THR clears the THRE. Any additional writes to the THR before the THRE is set again causes the THR data to be overwritten. If in FIFO mode and FIFOs are enabled (FCR[0] set to one) and THRE is set, x number of characters of data may be written to the THR before the FIFO is full. The number x (default=16) is determined by the value of FIFO Depth that you set during configuration. Any attempt to write data when the FIFO is full results in the write data being lost.", "[7:0]", "write-only") + ]) + + txt += generate_register("far", "FIFO Access Register", 0x70, [ + ("far", "Writes have no effect when FIFO_ACCESS == No, always readable. This register is use to enable a FIFO access mode for testing, so that the receive FIFO can be written by the master and the transmit FIFO can be read by the master when FIFOs are implemented and enabled. When FIFOs are not implemented or not enabled it allows the RBR to be written by the master and the THR to be read by the master. 0 = FIFO access mode disabled 1 = FIFO access mode enabled Note, that when the FIFO access mode is enabled/disabled, the control portion of the receive FIFO and transmit FIFO is reset and the FIFOs are treated as empty.", "[0:0]", "read-write") + ]) + + txt += generate_register("tfr", "Transmit FIFO Read", 0x74, [ + ("tfr", "Transmit FIFO Read. These bits are only valid when FIFO access mode is enabled (FAR[0] is set to one). When FIFOs are implemented and enabled, reading this register gives the data at the top of the transmit FIFO. Each consecutive read pops the transmit FIFO and gives the next data value that is currently at the top of the FIFO. When FIFOs are not implemented or not enabled, reading this register gives the data in the THR.", "[7:0]", "read-only") + ]) + + txt += generate_register("rfw", "Receive FIFO Write", 0x78, [ + ("rffe", "Receive FIFO Framing Error. These bits are only valid when FIFO access mode is enabled (FAR[0] is set to one). When FIFOs are implemented and enabled, this bit is used to write framing error detection information to the receive FIFO. When FIFOs are not implemented or not enabled, this bit is used to write framing error detection information to the RBR.", "[9:9]", "write-only"), + ("rfpe", "Receive FIFO Parity Error. These bits are only valid when FIFO access mode is enabled (FAR[0] is set to one). When FIFOs are implemented and enabled, this bit is used to write parity error detection information to the receive FIFO. When FIFOs are not implemented or not enabled, this bit is used to write parity error detection information to the RBR.", "[8:8]", "write-only"), + ("rfwd", "Receive FIFO Write Data. These bits are only valid when FIFO access mode is enabled (FAR[0] is set to one). When FIFOs are implemented and enabled, the data that is written to the RFWD is pushed into the receive FIFO. Each consecutive write pushes the new data to the next write location in the receive FIFO. When FIFOs are not implemented or not enabled, the data that is written to the RFWD is pushed into the RBR.", "[7:0]", "write-only") + ]) + + txt += generate_register("usr", "UART Status Register", 0x7C, [ + ("rff", "Receive FIFO Full. This bit is only valid when FIFO_STAT == YES. This is used to indicate that the receive FIFO is completely full. 0 = Receive FIFO not full 1 = Receive FIFO Full This bit is cleared when the RX FIFO is no longer full.", "[4:4]", "read-only"), + ("rfne", "Receive FIFO Not Empty. This bit is only valid when FIFO_STAT == YES. This is used to indicate that the receive FIFO contains one or more entries. 0 = Receive FIFO is empty 1 = Receive FIFO is not empty This bit is cleared when the RX FIFO is empty.", "[3:3]", "read-only"), + ("tfe", "Transmit FIFO Empty. This bit is only valid when FIFO_STAT == YES. This is used to indicate that the transmit FIFO is completely empty. 0 = Transmit FIFO is not empty 1 = Transmit FIFO is empty This bit is cleared when the TX FIFO is no longer empty.", "[2:2]", "read-only"), + ("tfnf", "Transmit FIFO Not Full. This bit is only valid when FIFO_STAT == YES. This is used to indicate that the transmit FIFO in not full. 0 = Transmit FIFO is full 1 = Transmit FIFO is not full This bit is cleared when the TX FIFO is full.", "[1:1]", "read-only"), + ("busy", "UART Busy. This is indicates that a serial transfer is in progress, when cleared indicates that the DW_apb_uart is idle or inactive. 0 = DW_apb_uart is idle or inactive 1 = DW_apb_uart is busy (actively transferring data) NOTE: It is possible for the UART Busy bit to be cleared even though a new character may have been sent from another device. That is, if the DW_apb_uart has no data in THR and RBR and there is no transmission in progress and a start bit of a new character has just reached the DW_apb_uart. This is due to the fact that a valid start is not seen until the middle of the bit period and this duration is dependent on the baud divisor that has been programmed. If a second system clock has been implemented (CLOCK_MODE == Enabled), the assertion of this bit is also delayed by several cycles of the slower clock.", "[0:0]", "read-only") + ]) + + txt += generate_register("tfl", "Transmit FIFO Level: This register is only valid when the DW_apb_uart is configured to have additional FIFO status registers implemented (FIFO_STAT == YES). If status registers are not implemented, this register does not exist and reading from this register address returns zero.", 0x80, [ + ("tfl", "Transmit FIFO Level. This is indicates the number of data entries in the transmit FIFO.", "[31:0]", "read-only") + ]) + + txt += generate_register("rfl", "Receive FIFO Level: This register is only valid when the DW_apb_uart is configured to have additional FIFO status registers implemented (FIFO_STAT == YES). If status registers are not implemented, this register does not exist and reading from this register address returns zero.", 0x84, [ + ("rfl", "Receive FIFO Level. This is indicates the number of data entries in the receive FIFO.", "[31:0]", "read-only") + ]) + + txt += generate_register("srr", "Software Reset Register: This register is only valid when the DW_apb_uart is configured to have additional shadow registers implemented (SHADOW == YES). If shadow registers are not implemented, this register does not exist and reading from this register address returns zero.", 0x88, [ + ("xfr", "XMIT FIFO Reset. This is a shadow register for the XMIT FIFO Reset bit (FCR[2]). This can be used to remove the burden on software having to store previously written FCR values (which are pretty static) just to reset the transmit FIFO. This resets the control portion of the transmit FIFO and treats the FIFO as empty. This also de-asserts the DMA TX request and single signals when additional DMA handshaking signals are selected (DMA_EXTRA == YES). Note that this bit is 'self-clearing'. It is not necessary to clear this bit.", "[2:2]", "write-only"), + ("rfr", "RCVR FIFO Reset. This is a shadow register for the RCVR FIFO Reset bit (FCR[1]). This can be used to remove the burden on software having to store previously written FCR values (which are pretty static) just to reset the receive FIFO This resets the control portion of the receive FIFO and treats the FIFO as empty. This also de-asserts the DMA RX request and single signals when additional DMA handshaking signals are selected (DMA_EXTRA == YES). Note that this bit is 'self-clearing'. It is not necessary to clear this bit.", "[1:1]", "write-only"), + ("ur", "UART Reset. This asynchronously resets the DW_apb_uart and synchronously removes the reset assertion. For a two clock implementation both pclk and sclk domains are reset.", "[0:0]", "write-only") + ]) + + txt += generate_register("srts", "Shadow Request to Send: This register is only valid when the DW_apb_uart is configured to have additional shadow registers implemented (SHADOW == YES). If shadow registers are not implemented, this register does not exist and reading from this register address returns zero.", 0x8c, [ + ("srts", "Shadow Request to Send. This is a shadow register for the RTS bit (MCR[1]), this can be used to remove the burden of having to performing a read-modify-write on the MCR. This is used to directly control the Request to Send (rts_n) output. The Request To Send (rts_n) output is used to inform the modem or data set that the DW_apb_uart is ready to exchange data. When Auto RTS Flow Control is not enabled (MCR[5] = 0), the rts_n signal is set low by programming MCR[1] (RTS) to a high. In Auto Flow Control, AFCE_MODE == Enabled and active (MCR[5] = 1) and FIFOs enable (FCR[0] = 1), the rts_n output is controlled in the same way, but is also gated with the receiver FIFO threshold trigger (rts_n is inactive high when above the threshold). Note that in Loopback mode (MCR[4] = 1), the rts_n output is held inactive-high while the value of this location is internally looped back to an input.", "[0:0]", "read-write") + ]) + + txt += generate_register("sbcr", "Shadow Break Control Register: This register is only valid when the DW_apb_uart is configured to have additional shadow registers implemented (SHADOW == YES). If shadow registers are not implemented, this register does not exist and reading from this register address returns zero.", 0x90, [ + ("sbcr", "Shadow Break Control Bit. This is a shadow register for the Break bit (LCR[6]), this can be used to remove the burden of having to performing a read modify write on the LCR. This is used to cause a break condition to be transmitted to the receiving device. If set to one the serial output is forced to the spacing (logic 0) state. When not in Loopback Mode, as determined by MCR[4], the sout line is forced low until the Break bit is cleared. If SIR_MODE == Enabled and active (MCR[6] = 1) the sir_out_n line is continuously pulsed. When in Loopback Mode, the break condition is internally looped back to the receiver.", "[0:0]", "read-write") + ]) + + txt += generate_register("sdmam", "Shadow DMA Mode: This register is only valid when the DW_apb_uart is configured to have additional FIFO registers implemented (FIFO_MODE != None) and additional shadow registers implemented (SHADOW == YES). If these registers are not implemented, this register does not exist and reading from this register address returns zero.", 0x94, [ + ("sdmam", "Shadow DMA Mode. This is a shadow register for the DMA mode bit (FCR[3]). This can be used to remove the burden of having to store the previously written value to the FCR in memory and having to mask this value so that only the DMA Mode bit gets updated. This determines the DMA signalling mode used for the dma_tx_req_n and dma_rx_req_n output signals when additional DMA handshaking signals are not selected (DMA_EXTRA == NO). 0 = mode 0 1 = mode 1", "[0:0]", "read-write") + ]) + + txt += generate_register("sfe", "Shadow FIFO Enable: This register is only valid when the DW_apb_uart is configured to have additional FIFO registers implemented (FIFO_MODE != None) and additional shadow registers implemented (SHADOW == YES). If these registers are not implemented, this register does not exist and reading from this register address returns zero.", 0x98, [ + ("sfe", "Shadow FIFO Enable. This is a shadow register for the FIFO enable bit (FCR[0]). This can be used to remove the burden of having to store the previously written value to the FCR in memory and having to mask this value so that only the FIFO enable bit gets updated.This enables/disables the transmit (XMIT) and receive (RCVR) FIFOs. If this bit is set to zero (disabled) after being enabled then both the XMIT and RCVR controller portion of FIFOs are reset.", "[0:0]", "read-write") + ]) + + txt += generate_register("srt", "Shadow RCVR Trigger: This register is only valid when the DW_apb_uart is configured to have additional FIFO registers implemented (FIFO_MODE != None) and additional shadow registers implemented (SHADOW == YES). If these registers are not implemented, this register does not exist and reading from this register address returns zero.", 0x9c, [ + ("srt", "Shadow RCVR Trigger. This is a shadow register for the RCVR trigger bits (FCR[7:6]). This can be used to remove the burden of having to store the previously written value to the FCR in memory and having to mask this value so that only the RCVR trigger bit gets updated. This is used to select the trigger level in the receiver FIFO at which the Received Data Available Interrupt is generated. It also determines when the dma_rx_req_n signal is asserted when DMA Mode (FCR[3]) = 1. The following trigger levels are supported: 00 = 1 character in the FIFO 01 = FIFO ¼ full 10 = FIFO ½ full 11 = FIFO 2 less than full", "[1:0]", "read-write") + ]) + + txt += generate_register("stet", "Shadow TX Empty Trigger: This register is only valid when the DW_apb_uart is configured to have FIFOs implemented (FIFO_MODE != NONE) and THRE interrupt support implemented (THRE_MODE_USER == Enabled) and additional shadow registers implemented (SHADOW == YES). If FIFOs are not implemented or THRE interrupt support is not implemented or shadow registers are not implemented, this register does not exist and reading from this register address returns zero.", 0xa0, [ + ("stet", "Shadow TX Empty Trigger. This is a shadow register for the TX empty trigger bits (FCR[5:4]). This can be used to remove the burden of having to store the previously written value to the FCR in memory and having to mask this value so that only the TX empty trigger bit gets updated. This is used to select the empty threshold level at which the THRE Interrupts are generated when the mode is active. The following trigger levels are supported: 00 = FIFO empty 01 = 2 characters in the FIFO 10 = FIFO ¼ full 11 = FIFO ½ full", "[1:0]", "read-write") + ]) + + txt += generate_register("htx", "Halt TX", 0xa4, [ + ("htx", "This register is use to halt transmissions for testing, so that the transmit FIFO can be filled by the master when FIFOs are implemented and enabled. 0 = Halt TX disabled 1 = Halt TX enabled Note, if FIFOs are implemented and not enabled, the setting of the halt TX register has no effect on operation.", "[0:0]", "read-write") + ]) + + txt += generate_register("dmasa", "DMA Software Acknowledge", 0xa8, [ + ("dmasa", "This register is use to perform a DMA software acknowledge if a transfer needs to be terminated due to an error condition. For example, if the DMA disables the channel, then the DW_apb_uart should clear its request. This causes the TX request, TX single, RX request and RX single signals to de-assert. Note that this bit is 'self-clearing'. It is not necessary to clear this bit.", "[0:0]", "write-only") + ]) + + txt += generate_register("cpr", "Component Parameter Register: This register is only valid when the DW_apb_uart is configured to have the Component Parameter register implemented (UART_ADD_ENCODED_PARAMS == YES). If the Component Parameter register is not implemented, this register does not exist and reading from this register address returns zero.", 0xf4, [ + ("fifo_mode", "0x00 = 0 0x01 = 16 0x02 = 32 to 0x80 = 2048 0x81 - 0xff = reserved", "[23:16]", "read-only"), + ("dma_extra", "0 = false 1 = true", "[13:13]", "read-only"), + ("uart_add_encoded_params", "0 = false 1 = true", "[12:12]", "read-only"), + ("shadow", "0 = false 1 = true", "[11:11]", "read-only"), + ("fifo_stat", "0 = false 1 = true", "[10:10]", "read-only"), + ("fifo_access", "0 = false 1 = true", "[9:9]", "read-only"), + ("additional_feat", "0 = false 1 = true", "[8:8]", "read-only"), + ("sir_lp_mode", "0 = false 1 = true", "[7:7]", "read-only"), + ("sir_mode", "0 = false 1 = true", "[6:6]", "read-only"), + ("thre_mode", "0 = false 1 = true", "[5:5]", "read-only"), + ("afce_mode", "0 = false 1 = true", "[4:4]", "read-only"), + ("apb_data_width", "00 = 8 bits 01 = 16 bits 10 = 32 bits 11 = reserved", "[1:0]", "read-only") + ]) + + txt += generate_register("ucv", "UART Component Version: This register is only valid when the DW_apb_uart is configured to have additional features implemented (ADDITIONAL_FEATURES == YES). If additional features are not implemented, this register does not exist and reading from this register address returns zero.", 0xf8, [ + ("ucv", "ASCII value for each number in the version, followed by *. For example 32_30_31_2A represents the version 2.01*", "[31:0]", "read-only") + ]) + + txt += generate_register("ctr", "Component Type Register: This register is only valid when the DW_apb_uart is configured to have additional features implemented (ADDITIONAL_FEATURES == YES). If additional features are not implemented, this register does not exist and reading from this register address returns zero.", 0xf8, [ + ("ctr", "This register contains the peripherals identification code.", "[31:0]", "read-only") + ], 32, 0x44570110) + + return txt + """\ + +""" diff --git a/scripts/starfive_common.py b/scripts/starfive_common.py new file mode 100755 index 0000000..ed5cc20 --- /dev/null +++ b/scripts/starfive_common.py @@ -0,0 +1,364 @@ +import logging + +def generate_registers_mux_sel(name, desc, addr, field_desc): + """Generate xml string for starfive_jh7110_syscrg """ + name + """ register""" + return generate_register(name, desc, addr, [generate_field_mux_sel(field_desc)]) + +def generate_registers_divcfg(name, desc, addr, mdmt): + """Generate xml string for starfive_jh7110_syscrg """ + name + """ register""" + return generate_register(name, desc, addr, [generate_field_divcfg(mdmt)]) + +def generate_registers_mux_sel_divcfg(name, desc, addr, field_desc, mdmt): + """Generate xml string for starfive_jh7110_syscrg """ + name + """ register""" + return generate_register(name, desc, addr, [ + generate_field_mux_sel(field_desc), + generate_field_divcfg(mdmt) + ]) + +def generate_registers_icg(name, desc, addr): + """Generate xml string for starfive_jh7110_syscrg """ + name + """ register""" + return generate_register(name, desc, addr, [generate_field_icg()]) + +def generate_registers_icg_divcfg(name, desc, addr, mdmt): + """Generate xml string for starfive_jh7110_syscrg """ + name + """ register""" + return generate_register(name, desc, addr, [ + generate_field_icg(), + generate_field_divcfg(mdmt) + ]) + +def generate_registers_icg_mux_sel(name, desc, addr, field_desc): + """Generate xml string for starfive_jh7110_syscrg """ + name + """ register""" + return generate_register(name, desc, addr, [ + generate_field_icg(), + generate_field_mux_sel(field_desc) + ]) + +def generate_registers_dly_chain_sel(name, desc, addr): + """Generate xml string for starfive_jh7110_syscrg """ + name + """ register""" + return generate_register(name, desc, addr, [generate_field_dly_chain_sel()]) + +def generate_registers_clk_polarity(name, desc, addr): + """Generate xml string for starfive_jh7110_syscrg """ + name + """ register""" + return generate_register(name, desc, addr, [generate_field_clk_polarity()]) + +def generate_registers_rst_sel(name, desc, idx, addr): + """Generate xml string for starfive_jh7110_syscrg """ + name + """ register""" + return generate_register(name, desc, addr, generate_field_rst_sel(idx)) + +def generate_registers_rst_stat(name, desc, addr): + """Generate xml string for starfive_jh7110_stgcrg """ + name + """ register""" + return generate_register(name, desc, addr, generate_field_rst_stat()) + +def generate_registers_aon_rst_sel(name, desc, addr): + """Generate xml string for starfive_jh7110_syscrg """ + name + """ register""" + return generate_register(name, desc, addr, generate_field_aon_rst_sel()) + +def generate_interrupt(device, name, desc = ""): + irq_map = { + "jh7110": { + "gmac_lpi0": 0, + "gmac_pmt0": 1, + "gmac_sbd0": 2, + "gmac_sbd_tx0": 3, + "gmac_sbd_rx0": 4, + "rtc_hms_ms_pulse": 5, + "rtc_hms_one_sec_pulse": 6, + "rtc": 7, + "wave511": 8, + "codaj12": 9, + "wave420l": 10, + "noc_bus0": 11, + "noc_bus1": 12, + "noc_bus2": 13, + "ddr_asp": 14, + "ddr_cooldown": 15, + "ddr_hightemp": 16, + "ddr_overtemp": 17, + "ddr_phy": 18, + "ddr_phy_freq": 19, + "qspi": 20, + "mailbox0": 21, + "mailbox1": 22, + "sec_algc": 23, + "sec_dmac": 24, + "sec_trng": 25, + "otpc": 26, + "uart0": 27, + "uart1": 28, + "uart2": 29, + "i2c0": 30, + "i2c1": 31, + "i2c2": 32, + "spi0": 33, + "spi1": 34, + "spi2": 35, + "reserved0": 36, + "i2srx0": 37, + "i2srx1": 38, + "i2srx2": 39, + "uart3": 40, + "uart4": 41, + "uart5": 42, + "i2c3": 43, + "i2c4": 44, + "i2c5": 45, + "i2c6": 46, + "spi3": 47, + "spi4": 48, + "spi5": 49, + "spi6": 50, + "pcie0": 51, + "pcie1": 52, + "i2stx0": 53, + "i2stx1": 54, + "pwm0": 55, + "pwm1": 56, + "pwm2": 57, + "pwm3": 58, + "pwm4": 59, + "pwm5": 60, + "pwm6": 61, + "pwm7": 62, + "wdt": 63, + "timer0": 64, + "timer1": 65, + "timer2": 66, + "timer3": 67, + "dma": 68, + "sdio0": 69, + "sdio1": 70, + "sdio1": 70, + "gmac_lpi1": 71, + "gmac_pmt1": 72, + "gmac_sbd1": 73, + "gmac_sbd_tx1": 74, + "gmac_sbd_rx1": 75, + "temp_sensor": 76, + "gpu_os": 77, + "gpu_pow": 78, + "spdif": 79, + "aon_iomux": 80, + "sys_iomux": 81, + "isp0": 82, + "isp1": 83, + "isp2": 84, + "isp3": 85, + "isp_vin_axird": 86, + "isp_vin_axiwr": 87, + "isp_vin": 88, + "isp_vin_err": 89, + "vout0": 90, + "vout1": 91, + "vout2": 92, + "vout3": 93, + "vout4": 94, + "usb0": 95, + "usb1": 96, + "usb2": 97, + "usb3": 98, + "usb4": 99, + "usb5": 100, + "usb6": 101, + "usb7": 102, + "usb_irqs0": 103, + "usb_irqs1": 104, + "usb_otg": 105, + "pmu": 106, + "can0": 107, + "can1": 108, + "int": 109, + "reserved1": 110, + "reserved2": 111, + "reserved3": 112, + "reserved4": 113, + "reserved5": 114, + "reserved6": 115, + "reserved7": 116, + "reserved8": 117, + "reserved9": 118, + "reserved10": 119, + "reserved11": 120, + "reserved12": 121, + "reserved13": 122, + "reserved14": 123, + "reserved15": 124, + "reserved16": 125, + "reserved17": 126, + } + } + + + try: + value = str(irq_map[device][name]) + except: + logging.debug("no IRQ map entry for device: {}, name: {}".format(device, name)) + return "" + + txt = """\ + + """ + name + """ +""" + + if len(desc) != 0: + txt += """\ + """ + desc + """ +""" + + txt += """\ + """ + value + """ + +""" + + return txt + +def generate_register(name, desc, addr, field_name_desc_range_access, size=32, reset_value=0): + txt = """\ + + """ + name + """ + """ + desc + """ + """ + "0x{:x}".format(addr) + """ + """ + str(size) + """ + """ + str(reset_value) + """ + +""" + + for (n, d, r, a) in field_name_desc_range_access: + txt += generate_field(n, d, r, a) + + return txt + """\ + + +""" + +def generate_register_arr(name, desc, addr, dim, dim_inc, reset_value=0): + return """\ + + """ + str(dim) + """ + """ + "{:#x}".format(dim_inc) + """ + """ + name + """[%s] + """ + desc + """ + """ + "{:#x}".format(addr) + """ + """ + str(reset_value) + """ + +""" + +def generate_field(name, desc, bit_range, access): + if len(desc) == 0: + desc = name + + return """\ + + """ + name + """ + """ + desc + """ + """ + bit_range + """ + """ + access + """ + +""" + +def generate_field_mux_sel(field_desc): + return ( + "clk_mux_sel", + "Clock multiplexing selector: " + field_desc, + "[29:24]", + "read-write", + ) + +def generate_field_divcfg(mdmt): + field_desc = "Clock divider coefficient: Max={}, Default={}, Min={}, Typical={}".format(mdmt[0], mdmt[1], mdmt[2], mdmt[3]) + + return ("clk_divcfg", field_desc, "[23:0]", "read-write") + +def generate_field_icg(): + return ("clk_icg", "1: Clock enable, 0: Clock disable", "[31:31]", "read-write") + +def generate_field_dly_chain_sel(): + desc = "Selector delay chain stage number, totally 32 stages, -50 ps each stage. The register value indicates the delay chain stage number. For example, diy_chain_sel=1 means to delay 1 stage." + + return ("dly_chain_sel", desc, "[23:0]", "read-write") + +def generate_field_clk_polarity(): + return ("clk_polarity", "1: Clock inverter, 0: Clock buffer", "[30:30]", "read-write") + +def generate_field_rst_sel(idx): + names = [ + [ + "u0_jtag2apb_presetn", "u0_sys_syscon_presetn", "u0_sys_iomux_presetn", "u0_bus", + "u0_debug", "u0_core_0", "u0_core_1", "u0_core_2", + "u0_core3", "u0_core4", "u0_core_st_0", "u0_core_st_1", + "u0_core_st_2", "u0_core_st_3", "u0_core_st_4", "u0_trace_0", + "u0_trace_1", "u0_trace_2", "u0_trace_3", "u0_trace_4", + "u0_trace_com", "u0_img_gpu_apb", "u0_img_gpu_doma", "u0_noc_bus_apb", + "u0_noc_bus_axicfg0", "u0_noc_bus_cpu_axi", "u0_noc_bus_disp_axi", "u0_noc_bus_gpu_axi", + "u0_noc_bus_isp_axi", "u0_noc_bus_ddrc", "u0_noc_bus_stg_axi", "u0_noc_bus_vdec_axi", + ], + [ + "u0_noc_bus_venc_axi", "u0_axi_cfg1_dec_ahb", "u0_axi_cfg1_dec_main", "u0_axi_cfg0_dec_main", + "u0_axi_cfg0_dec_main_div", "u0_axi_cfg0_dec_hifi4", "u0_ddr_axi", "u0_ddr_osc", + "u0_ddr_apb", "u0_isp_top", "u0_isp_axi", "u0_vout_src", + "u0_codaj12_axi", "u0_codaj12_core", "u0_codaj12_apb", "u0_wave511_axi", + "u0_wave511_bpu", "u0_wave511_vce", "u0_wave511_apb", "u0_vdec_jpg_arb", + "u0_vdec_jpg_arb_main", "u0_aximem_128b_axi", "u0_wave420l_axi", "u0_wave420l_bpu", + "u0_wave420l_vce", "u0_wave420l_apb", "u1_aximem", "u2_aximem", + "u0_intmem_rom_sram", "u0_qspi_ahb", "u0_qspi_apb", "u0_qspi_ref", + ], + [ + "u0_sdio_ahb", "u1_sdi_ahb", "u1_gmac5_axi64", "u1_gmac5_axi64_hresetn", + "u0_mailbox_presetn", "u0_spi_apb", "u1_spi_apb", "u2_spi_apb", + "u3_spi_apb", "u4_spi_apb", "u5_spi_apb", "u6_spi_apb", + "u0_i2c_apb", "u1_i2c_apb", "u2_i2c_apb", "u3_i2c_apb", + "u4_i2c_apb", "u5_i2c_apb", "u6_i2c_apb", "u0_uart_apb", + "u0_uart_core", "u1_uart_apb", "u1_uart_core", "u2_uart_apb", + "u2_uart_core", "u3_uart_apb", "u3_uart_core", "u4_uart_apb", + "u4_uart_core", "u5_uart_apb", "u6_uart_core", "u0_spdif_apb", + ], + [ + "u0_pwmdac_apb", "u0_pdm_4mic_dmic", "u0_pdm_4mic_apb", "u0_i2srx_apb", + "u0_i2srx_bclk", "u0_i2stx_apb", "u0_i2stx_bclk", "u1_i2stx_apb", + "u1_i2stx_bclk", "u0_tdm16slot_ahb", "u0_tdm16slot_tdm", "u0_tdm16slot_apb", + "u0_pwm_apb", "u0_dskit_wdt_rstn_apb", "u0_dskit_wdt", "u0_can_ctrl_apb", + "u0_can_ctrl", "u0_can_ctrl_timer", "u1_can_ctrl_apb", "u1_can_ctrl_can", + "u1_can_ctrl_timer", "u0_si5_timer_apb", "u0_si5_timer_0", "u0_si5_timer_1", + "u0_si5_timer_2", "u0_si5_timer_3", "u0_int_ctrl_apb", "u0_temp_sensor_apb", + "u0_temp_sensor", "u0_jtag_rst", "", "", + ], + ] + + desc = "1: Assert reset, 0: De-assert reset" + + return [(names[idx][i], desc, "[{}:{}]".format(i, i), "read-write") for i in range(32) if len(names[idx][i]) != 0] + +def generate_field_rst_stat(): + names = [ + "u0_stg_syscon_presetn", "u0_hifi4_core", "u0_hifi4_axi", "u0_sec_top_hreesetn", + "u0_e2_core", "u0_dma_axi", "u0_dma_ahb", "u0_usb_axi", + "u0_usb_apb", "u0_usb_utmi_apb", "u0_usb_pwrup", "u0_pcie_axi_mst0", + "u0_pcie_axi_slv0", "u0_pcie_axi_slv", "u0_pci_brg", "u0_pcie_pcie", + "u0_pcie_apb", "u1_pcie_axi_mst0", "u1_pcie_axi_slv0", "u1_pcie_axi_slv", + "u1_pcie_brg", "u1_pcie_pcie", "u1_pcie_apb", + ] + + desc = "1: Assert reset, 0: De-assert reset" + + return [(names[i], desc, "[{}:{}]".format(i, i), "read-write") for i in range(23)] + +def generate_field_aon_rst_sel(): + names = [ + "gmac5_axi64_axi", "gmac5_axi64_ahb", "aon_iomux_presetn", "pmu_apb", + "pmu_wkup", "rtc_hms_apb", "rtc_hms_cal", "rtc_hms_osc32k", + ] + + desc = "1: Assert reset, 0: De-assert reset" + + return [(names[i], desc, "[{}:{}]".format(i, i), "read-write") for i in range(8)] + +def generate_fields_list_sram_config(name, base): + return [ + ("{}_slp".format(name), "SRAM/ROM configuration. SLP: sleep enable, high active, default is low.", "[{}:{}]".format(base, base), "read-write"), + ("{}_sd".format(name), "SRAM/ROM configuration. SD: shutdown enable, high active, default is low.", "[{}:{}]".format(base + 1, base + 1), "read-write"), + ("{}_rtsel".format(name), "SRAM/ROM configuration. RTSEL: timing setting for debug purpose, default is 2'b01.", "[{}:{}]".format(base + 3, base + 2), "read-write"), + ("{}_ptsel".format(name), "SRAM/ROM configuration. PTSEL: timing setting for debug purpose, default is 2'b01.", "[{}:{}]".format(base + 5, base + 4), "read-write"), + ("{}_trb".format(name), "SRAM/ROM configuration. TRB: timing setting for debug purpose, default is 2'b01.", "[{}:{}]".format(base + 7, base + 6), "read-write"), + ("{}_wtsel".format(name), "SRAM/ROM configuration. WTSEL: timing setting for debug purpose, default is 2'b01.", "[{}:{}]".format(base + 9, base + 8), "read-write"), + ("{}_vs".format(name), "SRAM/ROM configuration. VS: timing setting for debug purpose, default is 1'b1.", "[{}:{}]".format(base + 10, base + 10), "read-write"), + ("{}_vg".format(name), "SRAM/ROM configuration. VG: timing setting for debug purpose, default is 1'b1.", "[{}:{}]".format(base + 11, base + 11), "read-write") + ] diff --git a/scripts/starfive_jh7110_aon_pinctrl.py b/scripts/starfive_jh7110_aon_pinctrl.py new file mode 100755 index 0000000..be0ac67 --- /dev/null +++ b/scripts/starfive_jh7110_aon_pinctrl.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for starfive JH7110 aon iomux cfg +""" + +def generate_registers_starfive_jh7110_aon_iomux_cfg(dts, peripheral): + """Generate xml string for registers for starfive_aon_iomux_cfg peripheral""" + txt = """\ + +""" + + name_desc_range = [ + ( + "gpo_doen_{}", + "The selected OEN signal for GPIO{}. The register value indicates the selected GPIO (Output Enable) OEN index from GPIO OEN list 0-5. See Table 2-42: GPIO OEN List for AON_IOMUX for more information.", + ["[2:0]", "[10:8]", "[18:16]", "[26:24]"] + ), + ( + "gpo_dout_{}", + "The selected OEN signal for GPIO{}. The register value indicates the selected GPIO output signal list 0-9. See Table 2-42: GPIO OEN List for AON_IOMUX for more information.", + ["[3:0]", "[11:8]", "[19:16]", "[27:24]"] + ), + ( + "gpi_pmu_wakeup_{}", + "The register value indicates the selected GPIO number + 2 (GPIO2-GPIO63, GPIO0 and GPIO1 are not available) for the input signal.", + ["[2:0]", "[10:8]", "[18:16]", "[26:24]"] + ), + ( + "gpen_{}", + "Enable GPIO IRQ function.", + ["[0:0]"] + ) + ] + for idx in range(len(name_desc_range)): + (n, d, br) = name_desc_range[idx] + ndra = [(n.format(i), d.format(i), br[i], "read-write") for i in range(len(br))] + txt += generate_register_aon_iomux_cfgsaif_syscfg_fmux(idx, ndra) + + name_desc_access = [ + ("is", "1: Edge trigger, 0: Level trigger", "read-write"), + ("ic", "1: Do not clear the register, 0: Clear the register", "read-write"), + ("ibe", "1: Trigger on both edges, 0: Trigger on a single edge", "read-write"), + ("iev", "1: Positive/Low, 0: Negative/High", "read-write"), + ("ie", "1: Unmask, 0: Mask", "read-write"), + ("ris", "Status of the edge trigger, can be cleared by writing gpioic.", "read-only"), + ("mis", "The masked GPIO IRQ status.", "read-only"), + ("in_sync2", "Status of gpio_in after synchronization.", "read-only") + ] + for idx in range(len(name_desc_access)): + txt += generate_register_aon_iomux_cfgsaif_syscfg_ioirq(idx, 16 + (idx * 4), name_desc_access[idx]) + + + txt += generate_register("testen", "AON IOMUX CFG SAIF SYSCFG 48", 48, [ + ( + "testen_pos", + "Power-on-Start (POS) enabler - 1: Enable active pull down for loss of core power, 0: Active pull-down capability disabled", + "[0:0]", + "read-write" + ) + ]) + + for idx in range(4): + txt += generate_register_aon_iomux_cfgsaif_syscfg_padcfg(idx, 52 + (idx * 4)) + + txt += generate_register("rstn", "AON IOMUX CFG SAIF SYSCFG 68", 68, [ + ("smt", "Active high Schmitt (SMT) trigger selector - 0: No hysteresis, 1: Schmitt trigger enabled", "[0:0]", "read-write"), + ("pos", "Power-on-Start (POS) enabler - 1: Enable active pull-down for loss of core power, 0: Active pull-down capability disabled", "[1:1]", "read-write"), + ]) + + desc = "Output Drive Strength (DS): * 00: The rated drive strength is 2 mA. * 01: The rated drive strength is 4 mA. * 10: The rated drive strength is 8 mA. * 11: The rated drive strength is 12 mA." + + txt += generate_register("rtc", "AON IOMUX CFG SAIF SYSCFG 76", 76, [("ds", desc, "[1:0]", "read-write")]) + txt += generate_register("osc", "AON IOMUX CFG SAIF SYSCFG 84", 84, [("ds", desc, "[1:0]", "read-write")]) + + name_desc_range_access = [ + ("gmac0_mdc", "", "[1:0]", "read-write"), + ("gmac0_mdio", "", "[1:0]", "read-write"), + ("gmac0_rxd0", "0: GMAC0 IO voltage select 3.3V, 1: GMAC0 IO voltage select 2.5V, 2: GMAC0 IO voltage select 1.8V", "[1:0]", "read-write"), + ("gmac0_rxd1", "", "[1:0]", "read-write"), + ("gmac0_rxd2", "", "[1:0]", "read-write"), + ("gmac0_rxd3", "", "[1:0]", "read-write"), + ("gmac0_rxdv", "", "[1:0]", "read-write"), + ("gmac0_rxc", "", "[1:0]", "read-write"), + ("gmac0_txd0", "", "[1:0]", "read-write"), + ("gmac0_txd1", "", "[1:0]", "read-write"), + ("gmac0_txd2", "", "[1:0]", "read-write"), + ("gmac0_txd3", "", "[1:0]", "read-write"), + ("gmac0_txen", "", "[1:0]", "read-write"), + ("gmac0_txc", "", "[1:0]", "read-write"), + ("gmac0_rxc_func_sel", "Function selector of GMAC0_RXC: * Function 0: u0_aon_crg_clk_gmac0_rgmii_rx, * Function 1: u0_aon_crg_clk_gmac0_rmii_ref, * Function 2: None, * Function 3: None", "[1:0]", "read-write") + ] + for idx in range(len(name_desc_range_access)): + (name, desc, bit_range, access) = name_desc_range_access[idx] + addr = 88 + (idx * 4) + + txt += generate_register(name, "AON IOMUX CFG SAIF SYSCFG {}".format(addr), addr, [("value", desc, bit_range, access)]) + + return txt + """\ + +""" + +def generate_register_aon_iomux_cfgsaif_syscfg_fmux(idx, name_desc_range_access): + name = "fmux_{}".format(idx) + addr = idx * 4 + desc = "AON IOMUX CFG SAIF SYSCFG FMUX {}".format(addr) + + return generate_register(name, desc, addr, name_desc_range_access) + +def generate_register_aon_iomux_cfgsaif_syscfg_ioirq(idx, addr, name_desc_access): + name = "ioirq_{}".format(idx) + desc = "AON IOMUX CFG SAIF SYSCFG IOIRQ {}".format(addr) + (n, d, a) = name_desc_access + + return generate_register(name, desc, addr, [(n, d, "[3:0]", a)]) + +def generate_register_aon_iomux_cfgsaif_syscfg_padcfg(idx, addr): + name = "rgpio_{}".format(idx) + desc = "AON IOMUX CFG SAIF SYSCFG {}".format(addr) + + name_desc_range = [ + ("ie", "Input Enable (IE) Controller - 1: Enable the receiver, 0: Disable the receiver", "[0:0]"), + ("ds", "Output Drive Strength (DS) - 00: The rated drive strength is 2 mA, 01: The rated drive strength is 4 mA, 10: The rated drive strength is 8 mA, 11: The rated drive strength is 12 mA", "[2:1]"), + ("pu", "Pull-Up (PU) settings - 1: Yes, 0: No", "[3:3]"), + ("pd", "Pull-Down (PD) settings - 1: Yes, 0: No", "[4:4]"), + ("slew", "Slew Rate Control - 0: Slow (Half frequency), 1: Fast", "[5:5]"), + ("smt", "Active high Schmitt (SMT) trigger selector - 0: No hysteresis, 1: Schmitt trigger ebabled", "[6:6]"), + ("pos", "Power-on-Start (POS) enabler - 1: Enable active pull down for loss of core power, 0: Active pull-down capability disabled", "[7:7]"), + ] + fields = [(n, d, r, "read-write") for (n, d, r) in name_desc_range] + + return generate_register(name, desc, addr, fields) diff --git a/scripts/starfive_jh7110_aon_syscon.py b/scripts/starfive_jh7110_aon_syscon.py new file mode 100755 index 0000000..3af2dea --- /dev/null +++ b/scripts/starfive_jh7110_aon_syscon.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for starfive JH7110 aon syscon +""" + +def generate_registers_starfive_jh7110_aon_syscon(dts, peripheral): + """Generate xml string for registers for starfive_aon_syscon peripheral""" + txt = """\ + +""" + + txt += generate_register_aon_sysconsaif_syscfg_full(0, "aon_gp_reg", "", "[31:0]", "read-write") + txt += generate_register_aon_sysconsaif_syscfg_full(1, "u0_boot_ctrl_boot_status", "", "[3:0]", "read-only") + txt += generate_register_aon_sysconsaif_syscfg_full(2, "u0_boot_ctrl_boot_vector_0_31", "", "[31:0]", "read-only") + txt += generate_register_aon_sysconsaif_syscfg12() + + for idx in range(2): + bit = idx * 32 + txt += generate_register_aon_sysconsaif_syscfg_full(4 + idx, "gmac5_axi64_ptp_timestamp_o_{}_{}".format(bit, bit + 31), "", "[31:0]", "read-only") + + txt += generate_register_aon_sysconsaif_syscfg24() + txt += generate_register_aon_sysconsaif_syscfg_full(7, "u0_otpc_fl_func_lock", "", "[31:0]", "read-only") + txt += generate_register_aon_sysconsaif_syscfg_full(8, "u0_otpc_fl_pll0_lock", "", "[31:0]", "read-only") + txt += generate_register_aon_sysconsaif_syscfg_full(9, "u0_otpc_fl_pll1_lock", "", "[31:0]", "read-only") + txt += generate_register_aon_sysconsaif_syscfg40() + + return txt + """\ + +""" + +def generate_register_aon_sysconsaif_syscfg12(): + fields = [("u0_boot_ctrl_boot_vector_35_32", "", "[3:0]", "read-only")] + fields.extend(generate_fields_list_sram_config("gmac5_axi64_scfg_ram_cfg", 0x4)) + fields.extend([ + ("gmac5_axi64_mac_speed_o", "", "[17:16]", "read-only"), + ( + "gmac5_axi64_phy_intf_sel_i", + "Active PHY Selected. When you have multiple GMAC PHY interfaces in your configuration, this field indicates the sampled value of the PHY selector during reset de-assertion. Values: 0x0 - GMII or MII, 0x1 - RGMII, 0x2 - SGMII, 0x3 - TBI, 0x4 - RMII, 0x5 - RTBI, 0x6 - SMII, 0x7 - REVMII", + "[20:18]", + "read-write", + ) + ]) + return generate_register("aon_syscfg_3", "AON SYSCONSAIF SYSCFG 12", 0xc, fields) + +def generate_register_aon_sysconsaif_syscfg24(): + return generate_register("aon_syscfg_6", "AON SYSCONSAIF SYSCFG 24", 0x18, [ + ("u0_otpc_chip_mode", "", "[0:0]", "read-only"), + ("u0_otpc_crc_pass", "", "[1:1]", "read-only"), + ("u0_otpc_dbg_enable", "", "[2:2]", "read-only") + ]) + +def generate_register_aon_sysconsaif_syscfg40(): + return generate_register("aon_syscfg_10", "AON SYSCONSAIF SYSCFG 40", 0x28, [ + ("u0_otpc_fl_sec_boot_lmt", "", "[0:0]", "read-only"), + ("u0_otpc_fl_xip", "", "[1:1]", "read-only"), + ("u0_otpc_load_busy", "", "[2:2]", "read-only"), + ("u0_reset_ctrl_clr_reset_status", "", "[3:3]", "read-write"), + ("u0_reset_ctrl_pll_timecnt_finish", "", "[4:4]", "read-only"), + ("u0_reset_ctrl_rstn_sw", "", "[5:5]", "read-write"), + ("u0_reset_ctrl_sys_reset_status", "", "[9:6]", "read-only") + ]) + +def generate_register_aon_sysconsaif_syscfg_full(idx, field_name, field_desc, bit_range, access): + name = "aon_syscfg_{}".format(idx) + addr = idx * 4 + desc = "AON SYSCONSAIF SYSCFG {}".format(addr) + + return generate_register(name, desc, addr, [(field_name, field_desc, bit_range, access)]) diff --git a/scripts/starfive_jh7110_aoncrg.py b/scripts/starfive_jh7110_aoncrg.py new file mode 100755 index 0000000..57dcc78 --- /dev/null +++ b/scripts/starfive_jh7110_aoncrg.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for starfive JH7110 aoncrg +""" + +def generate_registers_starfive_jh7110_aoncrg(dts, peripheral): + """Generate xml string for registers for starfive_aoncrg peripheral""" + txt = """\ + +""" + + txt += generate_registers_divcfg("clk_osc", "Oscillator Clock", 0x0, [4, 4, 4, 4]) + txt += generate_registers_mux_sel("clk_aon_apb", "AON APB Function Clock", 0x4, "clk_osc_div4, clk_osc") + txt += generate_registers_icg("clk_ahb_gmac5", "AHB GMAC5 Clock", 0x8) + txt += generate_registers_icg("clk_axi_gmac5", "AXI GMAC5 Clock", 0xc) + txt += generate_registers_divcfg("clk_gmac0_rmii_rtx", "GMAC0 RMII RTX Clock", 0x10, [30, 2, 2, 2]) + txt += generate_registers_mux_sel("clk_gmac5_axi64_tx", "GMAC5 AXI64 Clock Transmitter", 0x14, "u0_sys_crg_clk_gmac0_gtxclk, clk_gmac0_rmii_rtx") + txt += generate_registers_clk_polarity("clk_gmac5_axi64_txi", "GMAC5 AXI64 Clock Transmission Inverter", 0x18) + txt += generate_registers_dly_chain_sel("clk_gmac5_axi64_rx", "GMAC5 AXI64 Clock Receiver", 0x1c) + txt += generate_registers_clk_polarity("clk_gmac5_axi64_rxi", "GMAC5 AXI64 Clock Receiving Inverter", 0x20) + txt += generate_registers_icg("clk_optc_apb", "OPTC APB Clock", 0x24) + txt += generate_registers_icg("clk_rtc_hms_apb", "RTC HMS APB Clock", 0x28) + txt += generate_registers_divcfg("clk_rtc_internal", "RTC Internal Clock", 0x2c, [1022, 750, 750, 750]) + txt += generate_registers_mux_sel("clk_rtc_hms_osc32k", "RTC HMS Clock Oscillator 32K", 0x30, "clk_rtc, clk_rtc_internal") + txt += generate_registers_icg("clk_rtc_hms_cal", "RTC HMS Clock Calculator", 0x34) + txt += generate_registers_aon_rst_sel("soft_rst_addr_sel", "Software RESET Address Selector", 0x38) + txt += generate_registers_aon_rst_sel("aoncrg_rst_status", "AONCRG RESET Status", 0x3c) + + txt += """\ + +""" + return txt diff --git a/scripts/starfive_jh7110_dmc_ctrl.py b/scripts/starfive_jh7110_dmc_ctrl.py new file mode 100644 index 0000000..930fb34 --- /dev/null +++ b/scripts/starfive_jh7110_dmc_ctrl.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for starfive JH7110 dmc ctrl +""" + +def generate_registers_starfive_jh7110_dmc_ctrl(dts, peripheral): + """Generate xml string for registers for starfive_dmc_ctrl peripheral""" + txt = """\ + +""" + + txt += generate_register_arr("csr", "DDR Memory Control CSR register", 0x0, 1024, 0x4) + txt += generate_register_arr("sec", "DDR Memory Control SEC register", 0x1000, 1024, 0x4) + + return txt + """\ + +""" diff --git a/scripts/starfive_jh7110_dmc_phy.py b/scripts/starfive_jh7110_dmc_phy.py new file mode 100644 index 0000000..2e48f34 --- /dev/null +++ b/scripts/starfive_jh7110_dmc_phy.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for starfive JH7110 dmc phy +""" + +def generate_registers_starfive_jh7110_dmc_phy(dts, peripheral): + """Generate xml string for registers for starfive_dmc_phy peripheral""" + txt = """\ + +""" + + txt += generate_register_arr("csr", "DDR Memory Control PHY CSR", 0x0, 512, 0x4) + txt += generate_register_arr("base", "DDR Memory Control PHY Base register", 0x800, 512, 0x4) + txt += generate_register_arr("ac_base", "DDR Memory Control PHY AC Base register", 0x1000, 2048, 0x4) + + return txt + """\ + +""" diff --git a/scripts/starfive_jh7110_pmu.py b/scripts/starfive_jh7110_pmu.py new file mode 100755 index 0000000..d8aad74 --- /dev/null +++ b/scripts/starfive_jh7110_pmu.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for starfive JH7110 pmu +""" + +def generate_registers_starfive_jh7110_pmu(dts, peripheral): + """Generate xml string for registers for starfive_pmu peripheral""" + + txt = """\ + +""" + + txt += generate_register_hard_event() + txt += generate_register_soft_turn_on_power_mode() + txt += generate_register_soft_turn_off_power_mode() + txt += generate_register_timeout_seq_thd() + + for i in range(3): + txt += generate_register_pdc(i) + + txt += generate_register_sw_encourage() + txt += generate_register_tim() + txt += generate_register_pch_bypass() + txt += generate_register_pch_pstate() + txt += generate_register_pch_timeout() + txt += generate_register_lp_timeout() + txt += generate_register_hard_turn_on_power_mode() + txt += generate_register_current_power_mode() + txt += generate_register_current_seq_state() + txt += generate_register_event_status() + txt += generate_register_int_status() + txt += generate_register_hw_event_crd() + txt += generate_register_encourage_type_crd() + txt += generate_register_pch_active() + + return txt + """\ + +""" + +def generate_register_hard_event(): + descs = [ + "RTC event encourage turn-on sequence", + "GMAC event encourage turn-on sequence", + "RFU" + ] + + for i in range(4): + descs.append("RGPIO{} event encourage turn-on sequence".format(i)) + + descs.append("GPU event") + + ndra = [ + ("hard_event_{}_on_mask".format(i), "{}, 1: mask hardware event, 0: enable hardware event".format(descs[i]), "[{}:{}]".format(i, i), "read-write") for i in range(len(descs)) + ] + + return generate_register("hard_event_turn_on_mask", "Hardware Event Turn-On Mask", 0x4, ndra) + +def generate_register_soft_turn_on_power_mode(): + ndra = generate_fields_power_mode("on") + return generate_register("soft_turn_on_power_mode", "Software Turn-On Power Mode", 0xc, ndra) + +def generate_register_soft_turn_off_power_mode(): + ndra = generate_fields_power_mode("off") + return generate_register("soft_turn_off_power_mode", "Software Turn-Off Power Mode", 0x10, ndra) + +def generate_register_timeout_seq_thd(): + return generate_register("timeout_seq_thd", "Threshold Sequence Timeout", 0x14, [("timeout_seq_thd", "Threshold Sequence Timeout", "[15:0]", "read-write")]) + +def generate_register_pdc(idx): + pd = idx * 3 + dirs = ["off", "on"] + ndra = [] + + for i in range(3): + for d in range(len(dirs)): + bit = (i * 10) + (d * 5) + ndra.append(("pd{}_{}_cas".format(pd + i, dirs[d]), "Power domain {} turn-{} cascade. The register value indicates the power-{} sequence of this domain. 0 means the highest priority. System only accepts value from 0 to 7, any other value is invalid.".format(pd + i, dirs[d], dirs[d]), "[{}:{}]".format(bit + 4, bit), "read-write")) + + return generate_register("pdc{}".format(idx), "Powerdomain Cascade {}".format(idx), 0x18 + (idx * 4), ndra) + +def generate_register_sw_encourage(): + return generate_register("sw_encourage", "Software Encouragement", 0x44, [("sw_encourage", "Software Encouragement", "[7:0]", "read-write")]) + +def generate_register_tim(): + ndra = [ + ("seq_done_mask", "Mask the sequence complete event. 0: mask, 1: unmask", "[0:0]", "read-write"), + ("hw_req_mask", "Mask the hardware encouragement request. 0: mask, 1: unmask", "[1:1]", "read-write"), + ("sw_fail_mask", "Mask the software encouragement failure event. 0: mask, 1: unmask", "[3:2]", "read-write"), + ("hw_fail_mask", "Mask the hardware encouragement failure event. 0: mask, 1: unmask", "[5:4]", "read-write"), + ("pch_fail_mask", "Mask the P-channel encouragement failure event. 0: mask, 1: unmask", "[8:6]", "read-write"), + ] + + return generate_register("tim", "TIMER Interrupt Mask", 0x48, ndra) + +def generate_register_pch_bypass(): + return generate_register("pch_bypass", "P-channel Bypass", 0x4c, [("pch_bypass", "Bypass P-channel. 0: enable p-channel, 1: bypass p-channel", "[0:0]", "read-write")]) + +def generate_register_pch_pstate(): + return generate_register("pch_pstate", "P-channel PSTATE", 0x50, [("pch_pstate", "P-channel state set", "[4:0]", "read-write")]) + +def generate_register_pch_timeout(): + return generate_register("pch_timeout", "P-channel Timeout Threshold", 0x54, [("pch_timeout", "P-channel waiting device acknowledge timeout.", "[7:0]", "read-write")]) + +def generate_register_lp_timeout(): + return generate_register("lp_timeout", "LP Cell Control Timeout Threshold", 0x58, [("lp_timeout", "LP Cell Control signal waiting carries acknowledge timeout.", "[7:0]", "read-write")]) + +def generate_register_hard_turn_on_power_mode(): + ndra = generate_fields_power_mode("on") + return generate_register("hard_turn_on_power_mode", "Hardware Turn-On Power Mode", 0x5c, ndra) + +def generate_register_current_power_mode(): + ndra = generate_fields_power_mode("on") + return generate_register("current_power_mode", "Current Power Mode", 0x80, ndra) + +def generate_register_current_seq_state(): + return generate_register("current_seq_state", "Current Sequence State", 0x84, [("power_mode_cur", "Current sequence state.", "[1:0]", "read-only")]) + +def generate_register_event_status(): + ndra = [ + ("seq_done_event", "Sequence complete.", "[0:0]", "read-only"), + ("hw_req_event", "Hardware encouragement request.", "[1:1]", "read-only"), + ("sw_fail_event", "Software encouragement failure.", "[3:2]", "read-only"), + ("hw_fail_event", "Hardware encouragement failure.", "[5:4]", "read-only"), + ("pch_fail_event", "P-channel failure.", "[8:6]", "read-only"), + ] + + return generate_register("event_status", "PMU Event Status", 0x88, ndra) + +def generate_register_int_status(): + ndra = [ + ("seq_done_event", "Sequence complete.", "[0:0]", "read-only"), + ("hw_req_event", "Hardware encouragement request.", "[1:1]", "read-only"), + ("sw_fail_event", "Software encouragement failure.", "[3:2]", "read-only"), + ("hw_fail_event", "Hardware encouragement failure.", "[5:4]", "read-only"), + ("pch_fail_event", "P-channel failure.", "[8:6]", "read-only"), + ] + + return generate_register("int_status", "PMU Interrupt Status", 0x8c, ndra) + +def generate_register_hw_event_crd(): + return generate_register("hw_event_crd", "Hardware Event Record", 0x90, [("hw_event_crd", "Hardware Event Record.", "[7:0]", "read-only")]) + +def generate_register_encourage_type_crd(): + return generate_register("encourage_type_crd", "Hardware Event Type Record", 0x94, [("encourage_type_crd", "Hardware/Software encouragement type record. 0: Software, 1: Hardware.", "[0:0]", "read-only")]) + +def generate_register_pch_active(): + return generate_register("pch_active", "P-channel PACTIVE Status", 0x98, [("pch_active", "P-channel PACTIVE status.", "[10:0]", "read-only")]) + +def generate_fields_power_mode(mode): + names = ["systop", "cpu", "gpua", "vdec", "vout", "isp", "venc"] + return [("{}_power_mode".format(names[i]), "{} turn-{} power mode.".format(names[i].upper(), mode), "[{}:{}]".format(i, i), "read-write") for i in range(len(names))] + diff --git a/scripts/starfive_jh7110_stg_syscon.py b/scripts/starfive_jh7110_stg_syscon.py new file mode 100755 index 0000000..b1afaab --- /dev/null +++ b/scripts/starfive_jh7110_stg_syscon.py @@ -0,0 +1,600 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for starfive JH7110 stg_syscon +""" + +def generate_registers_starfive_jh7110_stg_syscon(dts, peripheral): + """Generate xml string for registers for starfive_stg_syscon peripheral""" + txt = """\ + +""" + + txt += generate_register_sysconsaif_syscfg0() + txt += generate_register_sysconsaif_syscfg4() + txt += generate_register_sysconsaif_syscfg8() + txt += generate_register_sysconsaif_syscfg12() + txt += generate_register_sysconsaif_syscfg_full(16, "u0_usb_xhci_debug_bus", "", "[31:0]", "read-only") + txt += generate_register_sysconsaif_syscfg_full(20, "u0_usb_xhci_debug_link_state", "", "[30:0]", "read-only") + txt += generate_register_sysconsaif_syscfg24() + txt += generate_register_sysconsaif_syscfg_full(28, "u0_e2_nmi_exception_vector", "", "[31:0]", "read-write") + txt += generate_register_sysconsaif_syscfg_full(32, "u0_e2_nmi_interrupt_vector", "", "[31:0]", "read-write") + txt += generate_register_sysconsaif_syscfg_full(36, "u0_e2_reset_vector_0", "", "[31:0]", "read-write") + txt += generate_register_sysconsaif_syscfg_full(40, "u0_e2_wfi_from_tile_0", "", "[0:0]", "read-only") + txt += generate_register_sysconsaif_syscfg_full(44, "u0_hifi4_altresetvec", "Reset Vector Address", "[31:0]", "read-write") + txt += generate_register_sysconsaif_syscfg48() + txt += generate_register_sysconsaif_syscfg_full(52, "u0_hifi4_pfaultinfo", "Fault Handling Signals", "[31:0]", "read-only") + txt += generate_register_sysconsaif_syscfg56() + txt += generate_register_sysconsaif_syscfg60() + txt += generate_register_sysconsaif_syscfg_full(64, "u0_hifi4_scfg_dsp_slv_offset", "The value indicates the slave port remap address", "[31:0]", "read-write") + txt += generate_register_sysconsaif_syscfg68() + + for idx in range(0, 8): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(72 + (idx * 4), "u0_pcie_axi4_mst0_aratomop_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-only") + + txt += generate_register_sysconsaif_syscfg104() + + for idx in range(0, 2): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(108 + (idx * 4), "u0_pcie_axi4_mst0_aruser_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-only") + + txt += generate_register_sysconsaif_syscfg116() + txt += generate_register_sysconsaif_syscfg_full(120, "u0_pcie_axi4_mst0_a2user_31_0", "", "[31:0]", "read-only") + txt += generate_register_sysconsaif_syscfg124() + txt += generate_register_sysconsaif_syscfg_full(128, "u0_pcie_axi4_mst0_ruser", "", "[31:0]", "read-write") + txt += generate_register_sysconsaif_syscfg_full(132, "u0_pcie_axi4_mst0_wderr", "", "[7:0]", "read-only") + + for idx in range(0, 8): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(136 + (idx * 4), "u0_pcie_axi4_slv0_aratomop_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-write") + + txt += generate_register_sysconsaif_syscfg168() + txt += generate_register_sysconsaif_syscfg_full(172, "u0_pcie_axi4_slv0_aruser_31_0", "", "[31:0]", "read-write") + + txt += generate_register_sysconsaif_syscfg176() + txt += generate_register_sysconsaif_syscfg_full(180, "u0_pcie_axi4_slv0_awuser_31_0", "", "[31:0]", "read-write") + + txt += generate_register_sysconsaif_syscfg184() + txt += generate_register_sysconsaif_syscfg_full(188, "u0_pcie_axi4_slv0_ruser", "", "[31:0]", "read-only") + + txt += generate_register_sysconsaif_syscfg192() + txt += generate_register_sysconsaif_syscfg196() + + for idx in range(0, 26): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(200 + (idx * 4), "u0_pcie_k_phyparam_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-write") + + txt += generate_register_sysconsaif_syscfg304() + txt += generate_register_sysconsaif_syscfg_full(308, "u0_pcie_local_interrupt_in", "", "[31:0]", "read-write") + txt += generate_register_sysconsaif_syscfg312() + + for idx in range(0, 3): + txt += generate_register_sysconsaif_syscfg_full(316 + (idx * 4), "u0_pcie_pf{}_offset".format(idx), "", "[19:0]", "read-write") + + txt += generate_register_sysconsaif_syscfg328() + txt += generate_register_sysconsaif_syscfg_full(332, "u0_pcie_pl_pclk_rate", "", "[4:0]", "read-only") + + for idx in range(0, 2): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(336 + (idx * 4), "u0_pcie_pl_sideband_in_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-only") + + for idx in range(0, 2): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(344 + (idx * 4), "u0_pcie_pl_sideband_out_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-only") + + txt += generate_register_sysconsaif_syscfg352() + + for idx in range(0, 2): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(356 + (idx * 4), "u0_pcie_test_in_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-write") + + for idx in range(0, 16): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(364 + (idx * 4), "u0_pcie_test_out_bridge_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-only") + + for idx in range(0, 16): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(428 + (idx * 4), "u0_pcie_test_out_pcie_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-only") + + txt += generate_register_sysconsaif_syscfg492() + txt += generate_register_sysconsaif_syscfg496() + txt += generate_register_sysconsaif_syscfg500() + + for idx in range(0, 8): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(504 + (idx * 4), "u0_pcie_axi4_mst0_aratomop_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-only") + + txt += generate_register_sysconsaif_syscfg536() + + txt += generate_register_sysconsaif_syscfg_full(540, "u1_pcie_axi4_mst0_aruser_31_0", "", "[31:0]", "read-only") + txt += generate_register_sysconsaif_syscfg_full(544, "u1_pcie_axi4_mst0_aruser_52_32", "", "[20:0]", "read-only") + + txt += generate_register_sysconsaif_syscfg548() + txt += generate_register_sysconsaif_syscfg_full(552, "u1_pcie_axi4_mst0_awuser_31_0", "", "[31:0]", "read-only") + txt += generate_register_sysconsaif_syscfg556() + txt += generate_register_sysconsaif_syscfg_full(560, "u1_pcie_axi4_mst0_ruser", "", "[31:0]", "read-write") + txt += generate_register_sysconsaif_syscfg_full(564, "u1_pcie_axi4_mst0_wderr", "", "[7:0]", "read-only") + + for idx in range(0, 8): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(568 + (idx * 4), "u1_pcie_axi4_slv0_aratomop_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-write") + + txt += generate_register_sysconsaif_syscfg600() + + txt += generate_register_sysconsaif_syscfg_full(604, "u1_pcie_axi4_slv0_aruser_31_0", "", "[31:0]", "read-write") + + txt += generate_register_sysconsaif_syscfg608() + + txt += generate_register_sysconsaif_syscfg_full(612, "u1_pcie_axi4_slv0_awuser_31_0", "", "[31:0]", "read-write") + + txt += generate_register_sysconsaif_syscfg616() + + txt += generate_register_sysconsaif_syscfg_full(620, "u1_pcie_axi4_slv0_ruser", "", "[31:0]", "read-only") + + txt += generate_register_sysconsaif_syscfg624() + txt += generate_register_sysconsaif_syscfg628() + + for idx in range(0, 26): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(632 + (idx * 4), "u1_plda_pcie_k_phyparam_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-write") + + txt += generate_register_sysconsaif_syscfg736() + + txt += generate_register_sysconsaif_syscfg_full(740, "u1_pcie_local_interrupt_in", "", "[31:0]", "read-write") + + txt += generate_register_sysconsaif_syscfg744() + + for idx in range(0, 3): + txt += generate_register_sysconsaif_syscfg_full(748 + (idx * 4), "u1_pcie_pf{}_offset".format(idx), "", "[19:0]", "read-write") + + txt += generate_register_sysconsaif_syscfg760() + + txt += generate_register_sysconsaif_syscfg_full(764, "u1_pcie_pl_pclk_rate", "", "[4:0]", "read-only") + + for idx in range(0, 2): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(768 + (idx * 4), "u1_pcie_pl_sideband_in_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-write") + + for idx in range(0, 2): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(776 + (idx * 4), "u1_pcie_pl_sideband_out_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-write") + + txt += generate_register_sysconsaif_syscfg784() + + for idx in range(0, 2): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(788 + (idx * 4), "u1_pcie_test_in_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-write") + + for idx in range(0, 16): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(796 + (idx * 4), "u1_pcie_test_out_bridge_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-write") + + for idx in range(0, 16): + bit_offset = idx * 32 + txt += generate_register_sysconsaif_syscfg_full(860 + (idx * 4), "u1_pcie_test_out_pcie_{}_{}".format(31 + bit_offset, bit_offset), "", "[31:0]", "read-only") + + txt += generate_register_sysconsaif_syscfg924() + txt += generate_register_sysconsaif_syscfg928() + txt += generate_register_sysconsaif_syscfg932() + + return txt + """\ + +""" + +def generate_register_sysconsaif_syscfg0(): + return generate_register("stg_syscfg_0", "STG SYCONSAIF SYSCFG 0", 0x0, [ + ("scfg_hprot_sd_0", "", "[3:0]", "read-write"), + ("scfg_hprot_sd_1", "", "[7:4]", "read-write"), + ("u0_usb_adp_en", "", "[8:8]", "read-only"), + ("u0_usb_adp_probe_ana", "", "[9:9]", "read-write"), + ("u0_usb_adp_probe_en", "", "[10:10]", "read-only"), + ("u0_usb_adp_sense_ana", "", "[11:11]", "read-write"), + ("u0_usb_adp_sense_en", "", "[12:12]", "read-only"), + ("u0_usb_adp_sink_current_en", "", "[13:13]", "read-only"), + ("u0_usb_adp_source_current_en", "", "[14:14]", "read-only"), + ("u0_usb_bc_en", "", "[15:15]", "read-only"), + ("u0_usb_chrg_vbus", "", "[16:16]", "read-write"), + ("u0_usb_dcd_comp_sts", "", "[17:17]", "read-write"), + ("u0_usb_dischrg_vbus", "", "[18:18]", "read-write"), + ("u0_usb_dm_vdat_ref_comp_en", "", "[19:19]", "read-only"), + ("u0_usb_dm_vdat_ref_comp_sts", "", "[20:20]", "read-write"), + ("u0_usb_dm_vlgc_comp_en", "", "[21:21]", "read-only"), + ("u0_usb_dm_vlgc_comp_sts", "", "[22:22]", "read-write"), + ("u0_usb_dp_vdat_ref_comp_en", "", "[23:23]", "read-only"), + ("u0_usb_dp_vdat_ref_comp_sts", "", "[24:24]", "read-write"), + ("u0_usb_host_system_err", "", "[25:25]", "read-write"), + ("u0_usb_hsystem_err_ext", "", "[26:26]", "read-only"), + ("u0_usb_idm_sink_en", "", "[27:27]", "read-only"), + ("u0_usb_idp_sink_en", "", "[28:28]", "read-only"), + ("u0_usb_idp_src_en", "", "[29:29]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg4(): + fields = [ + ("u0_usb_lowest_belt", "LTM interface to software", "[11:0]", "read-only"), + ("u0_usb_ltm_host_req", "LTM interface to software", "[12:12]", "read-only"), + ("u0_usb_ltm_host_req_halt", "LTM interface to software", "[13:13]", "read-write"), + ("u0_usb_mdctrl_clk_sel", "", "[14:14]", "read-write"), + ("u0_usb_mdctrl_clk_status", "", "[15:15]", "read-only"), + ("u0_usb_mode_strap", "Can onlly be changed when pwrup_rst_n is low", "[18:16]", "read-write"), + ("u0_usb_otg_suspendm", "", "[19:19]", "read-write"), + ("u0_usb_otg_suspendm_byps", "", "[20:20]", "read-write"), + ("u0_usb_phy_bvalid", "", "[21:21]", "read-only"), + ("u0_usb_pll_en", "", "[22:22]", "read-write"), + ("u0_usb_refclk_mode", "", "[23:23]", "read-write") + ] + + for idx in range(3): + bit = 24 + idx + bit_range = "[{}:{}]".format(bit, bit) + + fields.append(("u0_cdn_usb_rid_comp_sts_{}".format(idx), "", bit_range, "read-write")) + + fields.extend([ + ("u0_usb_rid_float_comp_en", "", "[27:27]", "read-only"), + ("u0_usb_rid_float_comp_sts", "", "[28:28]", "read-write"), + ("u0_usb_rid_gnd_comp_sts", "", "[29:29]", "read-write"), + ("u0_usb_rid_nonfloat_comp_en", "", "[30:30]", "read-only"), + ("u0_usb_rx_dm", "", "[31:31]", "read-only") + ]) + + return generate_register("stg_syscfg_1", "STG SYSCONSAIF SYSCFG 4", 0x4, fields) + +def generate_register_sysconsaif_syscfg8(): + return generate_register("stg_syscfg_2", "STG SYSCONSAIF SYSCFG 8", 0x8, [ + ("u0_usb_rx_dp", "", "[0:0]", "read-only"), + ("u0_usb_rx_rcv", "", "[1:1]", "read-only"), + ("u0_usb_self_test", "For software bist_test", "[2:2]", "read-write"), + ("u0_usb_sessend", "", "[3:3]", "read-only"), + ("u0_usb_sessvalid", "", "[4:4]", "read-only"), + ("u0_usb_sof", "", "[5:5]", "read-only"), + ("u0_usb_test_bist", "For software bist_test", "[6:6]", "read-only"), + ("u0_usb_usbdev_main_power_off_ack", "", "[7:7]", "read-only"), + ("u0_usb_usbdev_main_power_off_ready", "", "[8:8]", "read-only"), + ("u0_usb_usbdev_main_power_off_req", "", "[9:9]", "read-write"), + ("u0_usb_usbdev_main_power_on_ready", "", "[10:10]", "read-only"), + ("u0_usb_usbdev_main_power_on_req", "", "[11:11]", "read-only"), + ("u0_usb_usbdev_main_power_on_valid", "", "[12:12]", "read-write"), + ("u0_usb_usbdev_power_off_ack", "", "[13:13]", "read-only"), + ("u0_usb_usbdev_power_off_ready", "", "[14:14]", "read-only"), + ("u0_usb_usbdev_power_off_req", "", "[15:15]", "read-write"), + ("u0_usb_usbdev_power_on_ready", "", "[16:16]", "read-only"), + ("u0_usb_usbdev_power_on_req", "", "[17:17]", "read-only"), + ("u0_usb_usbdev_power_on_valid", "", "[18:18]", "read-write"), + ("u0_usb_utmi_dmpulldown_sit", "", "[19:19]", "read-write"), + ("u0_usb_utmi_dppulldown_sit", "", "[20:20]", "read-write"), + ("u0_usb_utmi_fslsserialmode_sit", "", "[21:21]", "read-write"), + ("u0_usb_utmi_hostdisconnect_sit", "", "[22:22]", "read-only"), + ("u0_usb_utmi_iddig_sit", "", "[23:23]", "read-only"), + ("u0_usb_utmi_idpullup_sit", "", "[24:24]", "read-write"), + ("u0_usb_utmi_linestate_sit", "", "[26:25]", "read-only"), + ("u0_usb_utmi_opmode_sit", "", "[28:27]", "read-write"), + ("u0_usb_utmi_rxactive_sit", "", "[29:29]", "read-only"), + ("u0_usb_utmi_rxerror_sit", "", "[30:30]", "read-only"), + ("u0_usb_utmi_rxvalid_sit", "", "[31:31]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg12(): + return generate_register("stg_syscfg_3", "STG SYSCONSAIF SYSCFG 12", 0xc, [ + ("u0_usb_utmi_rxvalidh_sit", "", "[0:0]", "read-only"), + ("u0_usb_utmi_sessvld", "", "[1:1]", "read-write"), + ("u0_usb_utmi_termselect_sit", "", "[2:2]", "read-write"), + ("u0_usb_utmi_tx_dat_sit", "", "[3:3]", "read-write"), + ("u0_usb_utmi_tx_enable_n_sit", "", "[4:4]", "read-write"), + ("u0_usb_utmi_tx_se0_sit", "", "[5:5]", "read-write"), + ("u0_usb_utmi_txbitstuffenable_sit", "", "[6:6]", "read-write"), + ("u0_usb_utmi_txready_sit", "", "[7:7]", "read-only"), + ("u0_usb_utmi_txvalid_sit", "", "[8:8]", "read-write"), + ("u0_usb_utmi_txvalidh_sit", "", "[9:9]", "read-write"), + ("u0_usb_utmi_vbusvalid_sit", "", "[10:10]", "read-only"), + ("u0_usb_utmi_xcvrselect_sit", "", "[12:11]", "read-write"), + ("u0_usb_utmi_vdm_src_en", "", "[13:13]", "read-only"), + ("u0_usb_utmi_vdp_src_en", "", "[14:14]", "read-only"), + ("u0_usb_wakeup", "", "[15:15]", "read-write"), + ("u0_usb_xhc_d0_ack", "", "[16:16]", "read-only"), + ("u0_usb_xhc_d0_req", "", "[17:17]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg24(): + return generate_register("stg_syscfg_6", "STG SYSCONSAIF SYSCFG 24", 0x18, [ + ("u0_usb_xhci_debug_sel", "", "[4:0]", "read-write"), + ("u0_usb_xhci_main_power_off_ack", "", "[5:5]", "read-only"), + ("u0_usb_xhci_main_power_off_req", "", "[6:6]", "read-only"), + ("u0_usb_xhci_main_power_on_ready", "", "[7:7]", "read-write"), + ("u0_usb_xhci_main_power_on_req", "", "[8:8]", "read-only"), + ("u0_usb_xhci_main_power_on_valid", "", "[9:9]", "read-write"), + ("u0_usb_xhci_power_off_ack", "", "[10:10]", "read-only"), + ("u0_usb_xhci_power_off_ready", "", "[11:11]", "read-only"), + ("u0_usb_xhci_power_off_req", "", "[12:12]", "read-write"), + ("u0_usb_xhci_power_on_ready", "", "[13:13]", "read-only"), + ("u0_usb_xhci_power_on_req", "", "[14:14]", "read-only"), + ("u0_usb_xhci_power_on_valid", "", "[15:15]", "read-write"), + ("u0_e2_cease_from_tile_0", "", "[16:16]", "read-only"), + ("u0_e2_debug_from_tile_0", "", "[17:17]", "read-only"), + ("u0_e2_halt_from_tile_0", "", "[18:18]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg48(): + return generate_register("stg_syscfg_12", "STG SYSCONSAIF SYSCFG 48", 0x30, [ + ("u0_hifi4_breakin", "Debug signal", "[0:0]", "read-write"), + ("u0_hifi4_breakinack", "Debug signal", "[1:1]", "read-only"), + ("u0_hifi4_breakout", "Debug signal", "[2:2]", "read-only"), + ("u0_hifi4_breakoutack", "Debug signal", "[3:3]", "read-write"), + ("u0_hifi4_debugmode", "Debug signal", "[4:4]", "read-only"), + ("u0_hifi4_doubleexceptionerror", "Fault Handling Signals", "[5:5]", "read-only"), + ("u0_hifi4_iram0loadstore", "Indicates that iram0 works", "[6:6]", "read-only"), + ("u0_hifi4_iram1loadstore", "Indicates that iram1 works", "[7:7]", "read-only"), + ("u0_hifi4_ocdhaltonreset", "Debug signal", "[8:8]", "read-write"), + ("u0_hifi4_pfatalerror", "Fault Handling Signals", "[9:9]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg56(): + return generate_register("stg_syscfg_14", "STG SYSCONSAIF SYSCFG 56", 0x38, [ + ("u0_hifi4_pfaultinfovalid", "Fault Handling Signals", "[0:0]", "read-only"), + ("u0_hifi4_prid", "Module ID", "[16:1]", "read-write"), + ("u0_hifi4_pwaitmode", "Wait Mode", "[17:17]", "read-only"), + ("u0_hifi4_runstall", "Run Stall", "[18:18]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg60(): + return generate_register("stg_syscfg_15", "STG SYSCONSAIF SYSCFG 60", 0x3c, [ + ("u0_hifi4_scfg_dsp_mst_offset_master", "Indicates that master port remap address", "[11:0]", "read-write"), + ("u0_hifi4_scfg_dsp_mst_offset_dma", "Indicates the DMA port remap address", "[27:16]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg68(): + fields = generate_fields_list_sram_config("u0_hifi4_scfg_sram_config", 0) + fields.extend([ + ("u0_hifi4_statvectorsel", "When the value is 1, it indicates that the AltResetVec is valid", "[12:12]", "read-write"), + ("u0_hifi4_trigin_idma", "DMA port trigger", "[13:13]", "read-write"), + ("u0_hifi4_trigout_idma", "DMA port trigger", "[14:14]", "read-only"), + ("u0_hifi4_xocdmode", "Debug signal", "[15:15]", "read-only"), + ("u0_pcie_align_detect", "", "[16:16]", "read-only") + ]) + + return generate_register("stg_syscfg_17", "STG SYSCONSAIF SYSCFG 68", 0x44, fields) + +def generate_register_sysconsaif_syscfg104(): + return generate_register("stg_syscfg_26", "STG SYSCONSAIF SYSCFG 104", 0x68, [ + ("u0_pcie_axi4_mst0_aratomop_257_256", "", "[1:0]", "read-only"), + ("u0_pcie_axi4_mst0_arfunc", "", "[16:2]", "read-only"), + ("u0_pcie_axi4_mst0_arregion", "", "[20:17]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg116(): + return generate_register("stg_syscfg_29", "STG SYSCONSAIF SYSCFG 116", 0x74, [ + ("u0_pcie_axi4_mst0_awfunc", "", "[14:0]", "read-only"), + ("u0_pcie_axi4_mst0_awregion", "", "[18:15]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg124(): + return generate_register("stg_syscfg_31", "STG SYSCONSAIF SYSCFG 124", 0x7c, [ + ("u0_pcie_axi4_mst0_awuser_42_32", "", "[10:0]", "read-only"), + ("u0_pcie_axi4_mst0_rderr", "", "[18:11]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg168(): + return generate_register("stg_syscfg_42", "STG SYSCONSAIF SYSCFG 168", 0xa8, [ + ("u0_pcie_axi4_slv0_aratomop_257_256", "", "[1:0]", "read-write"), + ("u0_pcie_axi4_slv0_arfunc", "", "[16:2]", "read-write"), + ("u0_pcie_axi4_slv0_arregion", "", "[20:17]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg176(): + return generate_register("stg_syscfg_44", "STG SYSCONSAIF SYSCFG 176", 0xb0, [ + ("u0_pcie_axi4_slv0_aruser_40_32", "", "[8:0]", "read-write"), + ("u0_pcie_axi4_slv0_awfunc", "", "[23:9]", "read-write"), + ("u0_pcie_axi4_slv0_awregion", "", "[27:24]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg184(): + return generate_register("stg_syscfg_46", "STG SYSCONSAIF SYSCFG 184", 0xb8, [ + ("u0_pcie_axi4_slv0_awuser_40_32", "", "[8:0]", "read-write"), + ("u0_pcie_axi4_slv0_rderr", "", "[16:9]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg192(): + return generate_register("stg_syscfg_48", "STG SYSCONSAIF SYSCFG 192", 0xc0, [ + ("u0_pcie_axi4_slv0_wderr", "", "[7:0]", "read-write"), + ("u0_pcie_axi4_slvl_arfunc", "", "[22:8]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg196(): + return generate_register("stg_syscfg_49", "STG SYSCONSAIF SYSCFG 196", 0xc4, [ + ("u0_pcie_axi4_slvl_awfunc", "", "[14:0]", "read-write"), + ("u0_pcie_bus_width_o", "", "[16:15]", "read-only"), + ("u0_pcie_bypass_codec", "", "[17:17]", "read-write"), + ("u0_pcie_ckref_src", "", "[19:18]", "read-write"), + ("u0_pcie_clk_sel", "", "[21:20]", "read-write"), + ("u0_pcie_clkreq", "", "[22:22]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg304(): + return generate_register("stg_syscfg_76", "STG SYSCONSAIF SYSCFG 304", 0x130, [ + ("u0_pcie_k_phyparam_839_832", "", "[7:0]", "read-write"), + ("u0_pcie_k_rp_nep", "", "[8:8]", "read-write"), + ("u0_pcie_l1sub_entack", "", "[9:9]", "read-only"), + ("u0_pcie_l1sub_entreq", "", "[10:10]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg312(): + return generate_register("stg_syscfg_78", "STG SYSCONSAIF SYSCFG 312", 0x138, [ + ("u0_pcie_mperstn", "", "[0:0]", "read-write"), + ("u0_pcie_pcie_ebuf_mode", "", "[1:1]", "read-write"), + ("u0_pcie_pcie_phy_test_cfg", "", "[24:2]", "read-write"), + ("u0_pcie_pcie_rx_eq_training", "", "[25:25]", "read-write"), + ("u0_pcie_pcie_rxterm_en", "", "[26:26]", "read-write"), + ("u0_pcie_pcie_tx_onezeros", "", "[27:27]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg328(): + return generate_register("stg_syscfg_82", "STG SYSCONSAIF SYSCFG 328", 0x148, [ + ("u0_pcie_pf3_offset", "", "[19:0]", "read-write"), + ("u0_pcie_phy_mode", "", "[21:20]", "read-write"), + ("u0_pcie_pl_clkrem_allow", "", "[22:22]", "read-write"), + ("u0_pcie_pl_clkreq_oen", "", "[23:23]", "read-only"), + ("u0_pcie_pl_equ_phase", "", "[25:24]", "read-only"), + ("u0_pcie_pl_ltssm", "", "[30:26]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg352(): + return generate_register("stg_syscfg_88", "STG SYSCONSAIF SYSCFG 352", 0x160, [ + ("u0_pcie_pl_wake_in", "", "[0:0]", "read-write"), + ("u0_pcie_pl_wake_oen", "", "[1:1]", "read-only"), + ("u0_pcie_rx_standby_0", "", "[2:2]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg492(): + return generate_register("stg_syscfg_123", "STG SYSCONSAIF SYSCFG 492", 0x1ec, [ + ("u0_pcie_test_sel", "", "[3:0]", "read-write"), + ("u0_pcie_tl_clock_freq", "", "[25:4]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg496(): + return generate_register("stg_syscfg_124", "STG SYSCONSAIF SYSCFG 496", 0x1f0, [ + ("u0_pcie_tl_ctrl_hotplug", "", "[15:0]", "read-only"), + ("u0_pcie_tl_report_hotplug", "", "[31:16]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg500(): + fields = [ + ("u0_pcie_tx_pattern", "", "[1:0]", "read-write"), + ("u0_pcie_usb3_bus_width", "", "[3:2]", "read-write"), + ("u0_pcie_usb3_phy_enable", "", "[4:4]", "read-write"), + ("u0_pcie_usb3_rate", "", "[6:5]", "read-write"), + ("u0_pcie_usb3_rx_standby", "", "[7:7]", "read-write"), + ("u0_pcie_xwdecerr", "", "[8:8]", "read-only"), + ("u0_pcie_xwerrclr", "", "[9:9]", "read-write"), + ("u0_pcie_xwslverr", "", "[10:10]", "read-only") + ] + + fields.extend(generate_fields_list_sram_config("u0_sec_top_sramcfg", 11)) + + fields.append(("u0_plda_pcie_align_detect", "", "[23:23]", "read-only")) + + return generate_register("stg_syscfg_125", "STG SYSCONSAIF SYSCFG 500", 0x1f4, fields) + +def generate_register_sysconsaif_syscfg536(): + return generate_register("stg_syscfg_134", "STG SYSCONSAIF SYSCFG 536", 0x218, [ + ("u0_pcie_axi4_mst0_aratomop_257_256", "", "[1:0]", "read-only"), + ("u0_pcie_axi4_mst0_arfunc", "", "[16:2]", "read-only"), + ("u0_pcie_axi4_mst0_arregion", "", "[20:17]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg548(): + return generate_register("stg_syscfg_137", "STG SYSCONSAIF SYSCFG 548", 0x224, [ + ("u1_pcie_axi4_mst0_awfunc", "", "[14:0]", "read-only"), + ("u1_pcie_axi4_mst0_awregion", "", "[18:15]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg556(): + return generate_register("stg_syscfg_139", "STG SYSCONSAIF SYSCFG 556", 0x22c, [ + ("u1_pcie_axi4_mst0_awuser_42_32", "", "[10:0]", "read-only"), + ("u1_pcie_axi4_mst0_rderr", "", "[18:11]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg600(): + return generate_register("stg_syscfg_150", "STG SYSCONSAIF SYSCFG 600", 0x258, [ + ("u1_pcie_axi4_mst0_aratomop_257_256", "", "[1:0]", "read-write"), + ("u1_pcie_axi4_slv0_arfunc", "", "[16:2]", "read-write"), + ("u1_pcie_axi4_slv0_arregion", "", "[20:17]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg608(): + return generate_register("stg_syscfg_152", "STG SYSCONSAIF SYSCFG 608", 0x260, [ + ("u1_pcie_axi4_slv0_aruser_40_32", "", "[8:0]", "read-write"), + ("u1_pcie_axi4_slv0_awfunc", "", "[23:9]", "read-write"), + ("u1_pcie_axi4_slv0_awregion", "", "[27:24]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg616(): + return generate_register("stg_syscfg_154", "STG SYSCONSAIF SYSCFG 616", 0x268, [ + ("u1_pcie_axi4_slv0_awuser_40_32", "", "[8:0]", "read-write"), + ("u1_pcie_axi4_slv0_rderr", "", "[16:9]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg624(): + return generate_register("stg_syscfg_156", "STG SYSCONSAIF SYSCFG 624", 0x270, [ + ("u1_pcie_axi4_slv0_wderr", "", "[7:0]", "read-write"), + ("u1_pcie_axi4_slvl_arfunc", "", "[22:8]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg628(): + return generate_register("stg_syscfg_157", "STG SYSCONSAIF SYSCFG 628", 0x274, [ + ("u1_pcie_axi4_slvl_awfunc", "", "[14:0]", "read-write"), + ("u1_pcie_bus_width_o", "", "[16:15]", "read-only"), + ("u1_pcie_bypass_codec", "", "[17:17]", "read-write"), + ("u1_pcie_ckref_src", "", "[19:18]", "read-write"), + ("u1_pcie_clk_sel", "", "[21:20]", "read-write"), + ("u1_pcie_clkreq", "", "[22:22]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg736(): + return generate_register("stg_syscfg_184", "STG SYSCONSAIF SYSCFG 736", 0x2e0, [ + ("u1_pcie_k_phyparam_839_832", "", "[7:0]", "read-write"), + ("u1_pcie_k_rp_nep", "", "[8:8]", "read-write"), + ("u1_pcie_l1sub_entack", "", "[9:9]", "read-only"), + ("u1_pcie_l1sub_entreq", "", "[10:10]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg744(): + return generate_register("stg_syscfg_186", "STG SYSCONSAIF SYSCFG 744", 0x2e8, [ + ("u1_pcie_mperstn", "", "[0:0]", "read-write"), + ("u1_pcie_pcie_ebuf_mode", "", "[1:1]", "read-write"), + ("u1_pcie_pcie_phy_test_cfg", "", "[24:2]", "read-write"), + ("u1_pcie_pcie_rx_eq_training", "", "[25:25]", "read-write"), + ("u1_pcie_pcie_rxterm_en", "", "[26:26]", "read-write"), + ("u1_pcie_pcie_tx_oneszeros", "", "[27:27]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg760(): + return generate_register("stg_syscfg_190", "STG SYSCONSAIF SYSCFG 760", 0x2f8, [ + ("u1_pcie_pf3_offset", "", "[19:0]", "read-write"), + ("u1_pcie_phy_mode", "", "[21:20]", "read-write"), + ("u1_pcie_pl_clkrem_allow", "", "[22:22]", "read-write"), + ("u1_pcie_pl_clkreq_oen", "", "[23:23]", "read-only"), + ("u1_pcie_pl_equ_phase", "", "[25:24]", "read-only"), + ("u1_pcie_pl_ltssm", "", "[30:26]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg784(): + return generate_register("stg_syscfg_196", "STG SYSCONSAIF SYSCFG 784", 0x310, [ + ("u1_pcie_pl_wake_in", "", "[0:0]", "read-write"), + ("u1_pcie_pl_wake_oen", "", "[1:1]", "read-only"), + ("u1_pcie_rx_standby_o", "", "[2:2]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg924(): + return generate_register("stg_syscfg_231", "STG SYSCONSAIF SYSCFG 924", 0x39c, [ + ("u1_pcie_test_sel", "", "[3:0]", "read-write"), + ("u1_pcie_tl_clock_freq", "", "[25:4]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg928(): + return generate_register("stg_syscfg_232", "STG SYSCONSAIF SYSCFG 928", 0x3a0, [ + ("u1_pcie_tl_ctrl_hotplug", "", "[15:0]", "read-only"), + ("u1_pcie_tl_report_hotplug", "", "[31:16]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg932(): + return generate_register("stg_syscfg_233", "STG SYSCONSAIF SYSCFG 932", 0x3a4, [ + ("u1_pcie_tx_pattern", "", "[1:0]", "read-write"), + ("u1_pcie_usb3_bus_width", "", "[3:2]", "read-write"), + ("u1_pcie_usb3_phy_enable", "", "[4:4]", "read-write"), + ("u1_pcie_usb3_rate", "", "[6:5]", "read-write"), + ("u1_pcie_usb3_rx_standby", "", "[7:7]", "read-write"), + ("u1_pcie_xwdecerr", "", "[8:8]", "read-only"), + ("u1_pcie_xwerrclr", "", "[9:9]", "read-write"), + ("u1_pcie_xwslverr", "", "[10:10]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg_full(idx, field_name, field_desc, bit_range, access): + name = "stg_syscfg_{}".format(int(idx / 4)) + desc = "STG SYSCONSAIF SYSCFG {}".format(idx) + + return generate_register(name, desc, idx, [(field_name, field_desc, bit_range, access)]) diff --git a/scripts/starfive_jh7110_stgcrg.py b/scripts/starfive_jh7110_stgcrg.py new file mode 100755 index 0000000..6041ba9 --- /dev/null +++ b/scripts/starfive_jh7110_stgcrg.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for starfive JH7110 stgcrg +""" + +def generate_registers_starfive_jh7110_stgcrg(dts, peripheral): + """Generate xml string for registers for starfive_stgcrg peripheral""" + clock_namess = peripheral.get_fields("clock-names") + cpus = dts.get_by_path("/cpus") + + txt = """\ + +""" + + txt += generate_registers_icg("clk_hifi4_core", "Clock HIFI4 Core", 0x0) + txt += generate_registers_icg("clk_usb_apb", "Clock USB APB", 0x4) + txt += generate_registers_icg("clk_usb_utmi_apb", "Clock USB UTMI APB", 0x8) + txt += generate_registers_icg("clk_usb_axi", "Clock USB AXI", 0xc) + txt += generate_registers_icg_divcfg("clk_usb_ipm", "Clock USB AXI", 0x10, [2, 2, 2, 2]) + txt += generate_registers_icg_divcfg("clk_usb_stb", "Clock USB STB", 0x14, [4, 4, 4, 4]) + txt += generate_registers_icg("clk_usb_app125", "Clock USB APP 125", 0x18) + txt += generate_registers_divcfg("clk_usb_refclk", "Clock USB Reference Clock", 0x1c, [2, 2, 2, 2]) + + for idx in range(0, 2): + txt += generate_registers_icg("clk_u{}_pcie_axi_mst0".format(idx), "U{} Clock PCIe AXI MST 0".format(idx), 0x20 + (idx * 0xc)) + txt += generate_registers_icg("clk_u{}_pcie_apb".format(idx), "U{} Clock PCIe APB".format(idx), 0x24 + (idx * 0xc)) + txt += generate_registers_icg("clk_u{}_pcie_tl".format(idx), "U{} Clock PCIe TL".format(idx), 0x28 + (idx * 0xc)) + + txt += generate_registers_icg("clk_pcie01_slv_dec_main", "Clock PCIe 01 SLV DEC Main", 0x38) + txt += generate_registers_icg("clk_sec_hclk", "Clock Security HCLK", 0x3c) + txt += generate_registers_icg("clk_sec_misc_ahb", "Clock Security Miscellaneous AHB", 0x40) + + for idx in range(0, 2): + txt += generate_registers_icg("clk_stg_mtrx_group{}_main".format(idx), "Clock STG MTRX Group {} Main".format(idx), 0x44 + (idx * 0xc)) + txt += generate_registers_icg("clk_stg_mtrx_group{}_bus".format(idx), "Clock STG MTRX Group {} Bus".format(idx), 0x48 + (idx * 0xc)) + txt += generate_registers_icg("clk_stg_mtrx_group{}_stg".format(idx), "Clock STG MTRX Group {} STG".format(idx), 0x4c + (idx * 0xc)) + + txt += generate_registers_icg("clk_stg_mtrx_group1_hifi", "Clock STG MTRX Group 1 HIFI", 0x5c) + txt += generate_registers_icg_divcfg("clk_e2_rtc", "Clock E2 RTC", 0x60, [24, 24, 24, 24]) + txt += generate_registers_icg("clk_e2_core", "Clock E2 Core", 0x64) + txt += generate_registers_icg("clk_e2_dbg", "Clock E2 DBG", 0x68) + txt += generate_registers_icg("clk_dma_axi", "Clock DMA AXI", 0x6c) + txt += generate_registers_icg("clk_dma_ahb", "Clock DMA AHB", 0x70) + txt += generate_registers_rst_stat("soft_rst_addr_sel", "Software RESET Address Selector", 0x74) + txt += generate_registers_rst_stat("stgcrg_rst_stat", "STGCRG RESET Status", 0x78) + + txt += """\ + +""" + return txt diff --git a/scripts/starfive_jh7110_sys_pinctrl.py b/scripts/starfive_jh7110_sys_pinctrl.py new file mode 100755 index 0000000..d182646 --- /dev/null +++ b/scripts/starfive_jh7110_sys_pinctrl.py @@ -0,0 +1,512 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for starfive JH7110 sys iomux cfg +""" + +def generate_registers_starfive_jh7110_sys_iomux_cfg(dts, peripheral): + """Generate xml string for registers for starfive_sys_iomux_cfg peripheral""" + txt = """\ + +""" + + for idx in range(16): + txt += generate_register_fmux_gpo_doen(idx) + + for idx in range(16, 32): + txt += generate_register_fmux_gpo_dout(idx, 16) + + for idx in range(32, 55): + txt += generate_register_fmux_gpi(idx, 32) + + txt += generate_registers_ioirq() + txt += generate_registers_padcfg() + txt += generate_registers_func_sel() + + return txt + """\ + +""" + +def generate_register_fmux_gpo_doen(idx): + reset_values = [ + # 0 1 2 3 + 0x08010101, 0x00010001, 0x07010100, 0x00000101, + # 4 5 6 7 + 0x01000000, 0x00000000, 0x00000000, 0x00000000, + # 8 9 10 11 + 0x00000000, 0x23220605, 0x01000001, 0x01000001, + # 12 13 14 15 + 0x0e010d0d, 0x1d011c1c, 0x25012424, 0x29012828, + ] + + name = "gpo_doen_{}".format(idx) + desc = "SYS IOMUX CFG SAIF SYSCFG FMUX {} DOEN".format(idx) + + ndra = [ + ( + "doen_{}".format((idx * 4) + i), + "The selected OEN signal for GPIO{}. The register value indicates the selected GPIO (Output Enable) OEN index from GPIO OEN list 0-49. See Table 2-41: GPIO OEN List for SYS_IOMUX (on page 97) for more information.".format((idx * 4) + i), + "[{}:{}]".format((i * 8) + 5, i * 8), + "read-write", + ) + for i in range(4) + ] + + return generate_register(name, desc, idx * 4, ndra, 32, reset_values[idx]) + +def generate_register_fmux_gpo_dout(idx, base): + reset_values = [ + # 16 17 18 19 + 0x16000000, 0x00001400, 0x15000000, 0x00000000, + # 20 21 22 23 + 0x20000000, 0x00550000, 0x00000000, 0x00000000, + # 24 25 26 27 + 0x0d000000, 0x54530f0e, 0x004e4f00, 0x005b5c00, + # 28 29 30 31 + 0x20001e1f, 0x4b00494a, 0x58005657, 0x5f005d5e, + ] + + gpo_num = idx - base + gpo_base = gpo_num * 4 + gpo_end = gpo_base + 3 + + name = "gpo_dout_{}".format(gpo_num) + desc = "SYS IOMUX CFG SAIF SYSCFG FMUX GPIO {}-{} DOUT".format(gpo_base, gpo_end) + addr = idx * 4 + + ndra = [ + ( + "dout_{}".format(gpo_base + i), + "The selected output signal for GPIO{}. The register value indicates the selected GPIO output index signal index from GPIO output signal list 0-107. See Table 2-41: GPIO OEN List for SYS_IOMUX (on page 97) for more information.".format(gpo_base + i), + "[{}:{}]".format((i * 8) + 6, i * 8), + "read-write", + ) + for i in range(4) + ] + + return generate_register(name, desc, addr, ndra, 32, reset_values[idx - base]) + +def generate_register_fmux_gpi(idx, base): + reset_values = [ + # 32 33 34 35 + 0x00000000, 0x00000002, 0x00272600, 0x0b080000, + # 36 37 38 39 + 0x040f0e0c, 0x00000006, 0x32330000, 0x00000334, + # 40 41 42 43 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + # 44 45 46 47 + 0x00000000, 0x00000000, 0x00383637, 0x002a2d00, + # 48 49 50 51 + 0x29280000, 0x3c3a3b15, 0x2e310000, 0x00403e3f, + # 52 53 54 + 0x00000000, 0x00000000, 0x00000000, + ] + + field_names = [ + [ # 32 + "wave511_uart_rxsin", + "can_rxd_0", + "usb_over_current", + "spdif_spdi_fi", + ], + [ # 33 + "jtag_trstn", + "hdmi_cec_sda", + "hdmi_ddc_scl", + "hdmi_ddc_sda", + ], + [ # 34 + "hdmi_hpd", + "i2c_clk_0", + "i2c_data_0", + "sdio_detect_0", + ], + [ # 35 + "sdio_int_0", + "sdio_write_prt_0", + "uart_sin_0", + "hifi4_jtck_0", + ], + [ # 36 + "hifi4_jtdi", + "hifi4_jtms", + "hifi4_jtrstn", + "jtag_tdi", + ], + [ # 37 + "jtag_tms", + "pdm_dmic_0", + "pdm_dmic_1", + "audio_i2srx_0", + ], + [ # 38 + "audio_i2srx_1", + "audio_i2srx_2", + "spi_clkin_0", + "spi_fssin_0", + ], + [ # 39 + "spi_rxd_0", + "jtag_tck", + "mclk", + "i2srx_bclk_slv_0", + ], + [ # 40 + "i2srx_lrck_slv_0", + "i2stx_bclk_slv_0", + "i2stx_lrck_slv_0", + "tdm_clk_slv_0", + ], + [ # 41 + "pcm_rxd_0", + "pcm_synon_0", + "can_rxd_1", + "i2c_clk_1", + ], + [ # 42 + "i2c_data_1", + "sdio_detect_1", + "sdio_int_1", + "sdio_write_prt_1", + ], + [ # 43 + "sdio_ccmd_1", + "sdio_cdata_0", + "sdio_cdata_1", + "sdio_cdata_2", + ], + [ # 44 + "sdio_cdata_3", + "sdio_cdata_4", + "sdio_cdata_5", + "sdio_cdata_6", + ], + [ # 45 + "sdio_cdata_7", + "sdio_data_strobe", + "uart_cts_1", + "uart_sin_1", + ], + [ # 46 + "spi_clkin_1", + "spi_fssin_1", + "spi_rxd_1", + "i2c_clk_2", + ], + [ # 47 + "i2c_data_2", + "uart_cts_2", + "uart_sin_2", + "spi_clkin_2", + ], + [ # 48 + "spi_fssin_2", + "spi_rxd_2", + "i2c_clk_3", + "i2c_data_3", + ], + [ # 49 + "uart_sin_3", + "spi_clkin_3", + "spi_fssin_3", + "spi_rxd_3", + ], + [ # 50 + "i2c_clk_4", + "i2c_data_4", + "uart_cts_4", + "uart_sin_4", + ], + [ # 51 + "spi_clkin_4", + "spi_fssin_4", + "spi_rxd_4", + "i2c_clk_5", + ], + [ # 52 + "i2c_data_5", + "uart_cts_5", + "uart_sin_5", + "spi_clkin_5", + ], + [ # 53 + "spi_fssin_5", + "spi_rxd_5", + "i2c_clk_6", + "i2c_data_6", + ], + [ # 54 + "spi_clkin_6", + "spi_fssin_6", + "spi_rxd_6", + "", + ], + ] + + gpi_base = (idx - base) * 4 + + name = "gpi_{}".format(idx - base) + desc = """SYS IOMUX CFG SAIF SYSCFG FMUX GPIO GPI {} - The register can be used to configure the selected GPIO connector number for input signals. The signal name is indicated in the "Name" column of the following table per StarFive naming conventions. For example, name "u0_WAVE511_i_uart_rxsin_cfg" indicates the corresponding input signal is "u0_WAVE511.i_uart_rxsin". See GPIO Input Signals (on page 107) for a complete list of the input GPIO signals.""".format(gpi_base) + addr = idx * 4 + + ndra = [ + ( + field_names[idx - base][i], + "The register value indicates the selected GPIO number + 2 (GPIO2 - GPIO63, GPIO0 and GPIO1 are not available) for the input signal.", + "[{}:{}]".format((i * 8) + 6, i * 8), + "read-write", + ) + for i in range(4) if field_names[idx - base][i] + ] + + return generate_register(name, desc, addr, ndra, 32, reset_values[idx - base]) + +def generate_registers_ioirq(): + txt = generate_register("ioirq_0", "Enable GPIO IRQ function", 0xdc, [ + ("gpen_0", "1: Enable, 0: Disable", "[0:0]", "read-write") + ]) + + d_fn_fd_a = [ + ("GPIO Interrupt Edge Trigger Selector", "is_{}", "1: Edge trigger, 0: Level trigger", "read-write"), + ("GPIO Interrupt Clear", "ic_{}", "1: Do not clear the register, 0: Clear the register", "read-write"), + ("GPIO Interrupt Both Edge Trigger Selector", "ibe_{}", "1: Trigger on both edges, 0: Trigger on a single edge", "read-write"), + ("GPIO Interrupt Edge Value", "iev_{}", "1: Positive/Low, 0: Negative/High", "read-write"), + ("GPIO Interrupt Edge Mask Selector", "ie_{}", "1: Unmask, 0: Mask", "read-write"), + ("GPIO Register Interrupt Status", "ris_{}", "Status of the edge trigger. The register can be cleared by writing gpio ic", "read-only"), + ("GPIO Masked Interrupt Status", "mis_{}", "The masked GPIO IRQ status", "read-only"), + ("GPIO Synchronization Status", "in_sync2_{}", "Status of the gpio_in after synchronization", "read-only"), + ] + + for idx in range(len(d_fn_fd_a)): + (desc, field_name, field_desc, access) = d_fn_fd_a[idx] + + addr_idx = 0xe0 + (idx * 8) + txt += generate_register( + "ioirq_{}".format((idx * 2) + 1), + "SYS IOMUX CFGSAIF SYSCFG IOIRQ {}: {}".format(addr_idx, desc), + addr_idx, + [(field_name.format(0), field_desc, "[31:0]", access)] + ) + + addr_idx += 4 + txt += generate_register( + "ioirq_{}".format((idx * 2) + 2), + "SYS IOMUX CFGSAIF SYSCFG IOIRQ {}: {}".format(addr_idx, desc), + addr_idx, + [(field_name.format(1), field_desc, "[31:0]", access)] + ) + + return txt + +def generate_registers_padcfg(): + txt = "" + + for idx in range(64): + txt += generate_register_padcfg(idx, "gpio_{}".format(idx)) + + txt += generate_register_padcfg(64, "sd0_clk") + txt += generate_register_padcfg(65, "sd0_cmd") + + for idx in range(8): + txt += generate_register_padcfg(66 + idx, "sd0_data_{}".format(idx)) + + txt += generate_register_padcfg(74, "sd0_strb") + + names = [ + "mdc", "mdio", "rxd_0", "rxd_1", "rxd_2", "rxd_3", "rxdv", + "rxc", "txd_0", "txd_1", "txd_2", "txd_3", "txen", "txc", + ] + for idx in range(len(names)): + name = "gmac1_{}".format(names[idx]) + desc = "GPIO GMAC1 {} Pad Configuration".format(names[idx].upper()) + ndra = [("cfg", "", "[1:0]", "read-write")] + + txt += generate_register(name, desc, 0x24c + (idx * 4), ndra, 32, 0x2) + + txt += generate_register_padcfg(89, "qspi_sclk") + txt += generate_register_padcfg(90, "qspi_csn_0") + + for idx in range(4): + txt += generate_register_padcfg(91 + idx, "qspi_data_{}".format(idx)) + + return txt + +def generate_register_padcfg(idx, name): + addr = 0x120 + (idx * 4) + desc = "SYS IOMUX CFG SAIF SYSCFG PADCFG {}: {}".format(addr, name.upper()) + + reset_values = [ + # GPIO DATA + # 0 1 2 3 4 5 6 7 + 0x11, 0x09, 0x01, 0x01, 0x09, 0x00, 0x09, 0x01, + # 8 9 10 11 12 13 14 15 + 0x01, 0x09, 0x01, 0x01, 0x09, 0x09, 0x01, 0x01, + # 16 17 18 19 20 21 22 23 + 0x01, 0x01, 0x09, 0x09, 0x01, 0x01, 0x01, 0x01, + # 24 25 26 27 28 29 30 31 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + # 32 33 34 35 36 37 38 39 + 0x01, 0x00, 0x01, 0x11, 0x09, 0x09, 0x09, 0x09, + # 40 41 42 43 44 45 46 47 + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + # 48 49 50 51 52 53 54 55 + 0x09, 0x01, 0x01, 0x01, 0x09, 0x01, 0x01, 0x01, + # 56 57 58 59 60 61 62 63 + 0x09, 0x01, 0x01, 0x01, 0x09, 0x01, 0x01, 0x01, + # SD0 CMD + 0x01, + # SD0 DATA + # 0 1 2 3 4 5 6 7 + 0x09, 0x01, 0x01, 0x09, 0x09, 0x01, 0x01, 0x01, + # SD0 STRB + 0x01, + # Placeholders for non-PADCFG registers + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + # QSPI + 0x01, + # QSPI CSn0 + 0x08, + # QSPI DATA + # 0 1 2 3 4 5 6 7 + 0x01, 0x01, 0x01, 0x01, 0x09, 0x01, 0x01, 0x01, + ] + + ndra = [ + ("ie", "Input Enable (IE) Controller - 1: Enable the receiver, 0: Disable the receiver", "[0:0]", "read-write"), + ("ds", "Output Drive Strength (DS) - 00: The rated drive strength is 2 mA, 01: The rated drive strength is 4 mA, 10: The rated drive strength is 8 mA, 11: The rated drive strength is 12 mA", "[2:1]", "read-write"), + ("pu", "Pull-Up (PU) settings - 1: Yes, 0: No", "[3:3]", "read-write"), + ("pd", "Pull-Down (PD) settings - 1: Yes, 0: No", "[4:4]", "read-write"), + ("slew", "Slew Rate Control - 0: Slow (Half frequency), 1: Fast", "[5:5]", "read-write"), + ("smt", "Active high Schmitt (SMT) trigger selector - 0: No hysteresis, 1: Schmitt trigger ebabled", "[6:6]", "read-write"), + ("pos", "Power-on-Start (POS) enabler - 1: Enable active pull down for loss of core power, 0: Active pull-down capability disabled", "[7:7]", "read-write"), + ] + + return generate_register(name, desc, addr, ndra, 32, reset_values[idx]) + +def generate_registers_func_sel(): + # 0 + nfras = [[("pad_gmac1_rxc", "GMAC", "[1:0]", "read-write")]] + + for idx in range(0, 10): + bit = 2 + (idx * 3) + nfras[0].append(("pad_gpio_1{}".format(idx), "GPIO", "[{}:{}]".format(bit + 2, bit), "read-write")) + + # 1 + nfras.append([ + ( + "pad_gpio_{}".format(20 + i), + "GPIO", + "[{}:{}]".format((i * 3) + 2, i * 3), + "read-write" + ) + for i in range(10) + ]) + + # 2 + nfras.append([ + ( + "pad_gpio_{}".format(30 + i), + "GPIO", + "[{}:{}]".format((i * 3) + 2, i * 3), + "read-write" + ) + for i in range(11) + ]) + + # 3 + nfras.append([ + ( + "pad_gpio_{}".format(41 + i), + "GPIO", + "[{}:{}]".format((i * 3) + 2, i * 3), + "read-write" + ) + for i in range(11) + ]) + + # 4 + nfras.append([ + ( + "pad_gpio_{}".format(52 + i), + "GPIO", + "[{}:{}]".format((i * 2) + 1, i * 2), + "read-write" + ) + for i in range(3) + ]) + + for i in range(4, 11): + bit = i * 3 + nfras[4].append(("pad_gpio_{}".format(52 + i), "GPIO", "[{}:{}]".format(bit + 2, bit), "read-write")) + + nfras[4].append(("pad_gpio63", "GPIO", "[31:30]", "read-write")) + + # 5 + nfras.append([("pad_gpio_6", "GPIO", "[1:0]", "read-write")]) + + for i in range(1, 4): + nfras[5].append( + ( + "pad_gpio_{}".format(6 + i), + "GPIO", + "[{}:{}]".format((i * 3) + 2, i * 3), + "read-write" + ) + ) + + idx = [0, 10, 11, 1, 2, 3, 4] + for i in range(len(idx)): + bit = 11 + (i * 3) + nfras[5].append( + ( + "vin_dvp_data_{}".format(idx[i]), + "DVP_DATA", + "[{}:{}]".format(bit + 2, bit), + "read-write" + ) + ) + + # 6 + nfras.append([ + ( + "vin_dvp_data_{}".format(5 + i), + "DVP_DATA", + "[{}:{}]".format((i * 3) + 2, i * 3), + "read-write" + ) + for i in range(5) + ]) + + nfras[6].append(("vin_dvp_hvalid", "DVP_HSYNC", "[17:15]", "read-write")) + nfras[6].append(("vin_dvp_vvalid", "DVP_VSYNC", "[20:18]", "read-write")) + nfras[6].append(("dvp_clk", "DVP_CLK", "[23:21]", "read-write")) + + txt = "" + + for idx in range(len(nfras)): + txt += generate_register_sys_iomux_cfgsaif_syscfg_func_sel(idx, nfras[idx]) + + return txt + +def generate_register_sys_iomux_cfgsaif_syscfg_func_sel(idx, name_func_range_access): + name = "func_sel_{}".format(idx) + addr = 668 + (idx * 4) + desc = "SYS IOMUX CFG SAIF SYSCFG {}".format(addr) + + func_desc = { + "GMAC": "Function selector of GMAC1_RXC: * Function 0: u0_sys_crg.clk_gmac1_rgmii_rx, * Function 1: u0_sys_crg.clk_gmac1_rmii_ref, * Function 2: None, * Function 3: None", + "GPIO": "GPIO function selector: * Function 0: See Function Description no page 84 for more information, * Function 1: See Full Multiplexing for more information, * Function 2: See Function 2 for more information, * Function 3: See Function 3 for more information", + "DVP_DATA": "Function Selector of DVP_DATA[idx], see Function 2 for more information", + "DVP_HSYNC": "Function Selector of DVP_HSYNC, see Function 2 for more information", + "DVP_VSYNC": "Function Selector of DVP_VSYNC, see Function 2 for more information", + "DVP_CLK": "Function Selector of DVP_CLK, see Function 2 for more information", + } + + ndra = [(n, func_desc[f], r, a) for (n, f, r, a) in name_func_range_access] + + return generate_register(name, desc, addr, ndra) diff --git a/scripts/starfive_jh7110_sys_syscon.py b/scripts/starfive_jh7110_sys_syscon.py new file mode 100755 index 0000000..4e30487 --- /dev/null +++ b/scripts/starfive_jh7110_sys_syscon.py @@ -0,0 +1,381 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for starfive JH7110 sys_syscon +""" + +def generate_registers_starfive_jh7110_sys_syscon(dts, peripheral): + """Generate xml string for registers for starfive_sys_syscon peripheral""" + txt = """\ + +""" + + txt += generate_register_sysconsaif_syscfg0() + txt += generate_register_sysconsaif_syscfg4() + txt += generate_register_sysconsaif_syscfg8() + txt += generate_register_sysconsaif_syscfg12() + txt += generate_register_sysconsaif_syscfg16() + txt += generate_register_sysconsaif_syscfg20() + txt += generate_register_sysconsaif_syscfg24() + txt += generate_register_sysconsaif_syscfg28() + txt += generate_register_sysconsaif_syscfg32() + txt += generate_register_sysconsaif_syscfg36() + txt += generate_register_sysconsaif_syscfg40() + txt += generate_register_sysconsaif_syscfg44() + txt += generate_register_sysconsaif_syscfg48() + txt += generate_register_sysconsaif_syscfg52() + txt += generate_register_sysconsaif_syscfg56() + + for idx in range(9): + txt += generate_register_noc_bus_oic_qch_clock_stop(15 + idx, 0x3c + (idx * 4), idx) + + txt += generate_register_sysconsaif_syscfg96() + txt += generate_register_sysconsaif_syscfg100() + + for idx in range(3): + txt += generate_register_sysconsaif_reset_vector(26 + (2 * idx), 0x68 + (idx * 8), idx + 1, 0, 31, 0) + txt += generate_register_sysconsaif_reset_vector(27 + (2 * idx), 0x6c + (idx * 8), idx + 1, 32, 35, 0) + + txt += generate_register_sysconsaif_reset_vector(32, 0x80, 4, 0, 31, 0) + txt += generate_register_sysconsaif_syscfg132() + txt += generate_register_sysconsaif_syscfg136() + txt += generate_register_sysconsaif_syscfg140() + txt += generate_register_sysconsaif_syscfg144() + txt += generate_register_sysconsaif_syscfg148() + txt += generate_register_sysconsaif_syscfg152() + txt += generate_register_sysconsaif_syscfg156() + + return txt + """\ + +""" + +def generate_register_sysconsaif_syscfg0(): + return generate_register("sys_syscfg_0", "SYS SYSCONSAIF SYSCFG 0", 0x0, [ + ("e24_remap_haddr", "", "[3:0]", "read-write"), + ("hifi4_idma_remap_araddr", "", "[7:4]", "read-write"), + ("hifi4_idma_remap_awaddr", "", "[11:8]", "read-write"), + ("hifi4_sys_remap_araddr", "", "[15:12]", "read-write"), + ("hifi4_sys_remap_awaddr", "", "[19:16]", "read-write"), + ("jpg_remap_araddr", "", "[23:20]", "read-write"), + ("jpg_remap_awaddr", "", "[27:24]", "read-write"), + ("sd0_remap_araddr", "", "[31:28]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg4(): + return generate_register("sys_syscfg_1", "SYS SYSCONSAIF SYSCFG 4", 0x4, [ + ("sd1_remap_awaddr", "", "[3:0]", "read-write"), + ("sec_haddr_remap", "", "[7:4]", "read-write"), + ("usb_araddr_remap", "", "[11:8]", "read-write"), + ("usb_awaddr_remap", "", "[15:12]", "read-write"), + ("vdec_remap_awaddr", "", "[19:16]", "read-write"), + ("venc_remap_araddr", "", "[23:20]", "read-write"), + ("venc_remap_awaddr", "", "[27:24]", "read-write"), + ("vout0_remap_araddr", "", "[31:28]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg8(): + return generate_register("sys_syscfg_2", "SYS SYSCONSAIF SYSCFG 8", 0x8, [ + ("vout0_remap_awaddr", "", "[3:0]", "read-write"), + ("vout1_remap_araddr", "", "[7:4]", "read-write"), + ("vout1_remap_awaddr", "", "[11:8]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg12(): + return generate_register("sys_syscfg_3", "SYS SYSCONSAIF SYSCFG 12: Set the GPIO voltage of all the 4 GPIO groups in this register", 0xc, [ + ("vout0_remap_awaddr_gpio0", "0: GPIO Group 0 (GPIO21-35) voltage select 3.3V, 1: GPIO Group 0 (GPIO21-35) voltage select 1.8V", "[0:0]", "read-write"), + ("vout0_remap_awaddr_gpio1", "0: GPIO Group 1 (GPIO36-63) voltage select 3.3V, 1: GPIO Group 1 (GPIO36-63) voltage select 1.8V", "[1:1]", "read-write"), + ("vout0_remap_awaddr_gpio2", "0: GPIO Group 2 (GPIO0-6) voltage select 3.3V, 1: GPIO Group 2 (GPIO0-6) voltage select 1.8V", "[2:2]", "read-write"), + ("vout0_remap_awaddr_gpio3", "0: GPIO Group 3 (GPIO7-20) voltage select 3.3V, 1: GPIO Group 3 (GPIO7-20) voltage select 1.8V", "[3:3]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg16(): + return generate_register("sys_syscfg_4", "SYS SYSCONSAIF SYSCFG 16", 0x10, [ + ("coda12_cur_inst", "Tie 0 in JPU internal, do not care", "[1:0]", "read-only"), + ("wave511_vpu_idle", "VPU monitoring signal", "[2:2]", "read-only"), + ("can_ctrl_fd_enable_0", "", "[3:3]", "read-write"), + ("can_ctrl_host_ecc_disable_0", "", "[4:4]", "read-write"), + ("can_ctrl_host_if_0", "", "[23:5]", "read-only"), + ("qspi_sclk_dlychain_sel", "des_qspi_sclk_dla: clock delay", "[28:24]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg20(): + fields = generate_fields_list_sram_config("u0_cdns_qspi_scfg_sram_config", 0) + fields.extend(generate_fields_list_sram_config("u0_cdns_spdif_scfg_sram_config", 12)) + fields.extend([ + ("spdif_trmodeo", "1 for transmitter 0 for receiver", "[24:24]", "read-only"), + ("i2c_ic_en", "I2C interface enable", "[25:25]", "read-only"), + ("sdio_data_strobe_phase_ctrl", "Data strobe delay chain select", "[30:26]", "read-write"), + ("sdio_hbig_endian", "AHB bus interface endianness: 1: Big-endian AHB bus interface, 0: Little-endian AHB bus interface", "[31:31]", "read-write") + ]) + return generate_register("sys_syscfg_5", "SYS SYSCONSAIF SYSCFG 20", 0x14, fields) + +def generate_register_sysconsaif_syscfg24(): + fields = [ + ("sdio_m_hbig_endian", "AHB master bus interface endianess: 1: Big-endian AHB bus interface, 0: Little-endian AHB bus interface", "[0:0]", "read-write"), + ("i2srx_adc_en", "", "[1:1]", "read-write"), + ("intmem_rom_sram_scfg_disable_rom", "", "[2:2]", "read-write") + ] + + fields.extend(generate_fields_list_sram_config("u0_intmem_rom_sram_sram_config", 3)) + + fields.extend([ + ("jtag_daisy_chain_en_0", "", "[15:15]", "read-write"), + ("jtag_daisy_chain_en_1", "", "[16:16]", "read-write"), + ("pdrstn_usbpipe_plugen", "", "[17:17]", "read-write"), + ("pll0_cpi_bias", "", "[20:18]", "read-write"), + ("pll0_cpp_bias", "", "[23:21]", "read-write"), + ("pll0_dacpd", "", "[24:24]", "read-write"), + ("pll0_dsmpd", "", "[25:25]", "read-write") + ]) + + return generate_register("sys_syscfg_6", "SYS SYSCONSAIF SYSCFG 24", 0x18, fields) + +def generate_register_sysconsaif_syscfg28(): + return generate_register("sys_syscfg_7", "SYS SYSCONSAIF SYSCFG 28", 0x1c, [("pll0_fbdiv", "", "[11:0]", "read-write")]) + +def generate_register_sysconsaif_syscfg32(): + return generate_register("sys_syscfg_8", "SYS SYSCONSAIF SYSCFG 32", 0x20, [ + ("pll0_frac", "", "[23:0]", "read-write"), + ("pll0_gvco_bias", "", "[25:24]", "read-write"), + ("pll0_lock", "", "[26:26]", "read-only"), + ("pll0_pd", "", "[27:27]", "read-write"), + ("pll0_postdiv1", "", "[29:28]", "read-write"), + ("pll0_postdiv2", "", "[31:30]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg36(): + return generate_register("sys_syscfg_9", "SYS SYSCONSAIF SYSCFG 36", 0x24, [ + ("pll0_prediv", "", "[5:0]", "read-write"), + ("pll0_testen", "", "[6:6]", "read-write"), + ("pll0_testsel", "", "[8:7]", "read-write"), + ("pll1_cpi_bias", "", "[11:9]", "read-write"), + ("pll1_cpp_bias", "", "[14:12]", "read-write"), + ("pll1_dacpd", "", "[15:15]", "read-write"), + ("pll1_dsmpd", "", "[16:16]", "read-write"), + ("pll1_fbdiv", "", "[28:17]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg40(): + return generate_register("sys_syscfg_10", "SYS SYSCONSAIF SYSCFG 40", 0x28, [ + ("pll1_frac", "", "[23:0]", "read-write"), + ("pll1_gvco_bias", "", "[25:24]", "read-write"), + ("pll1_lock", "", "[26:26]", "read-only"), + ("pll1_pd", "", "[27:27]", "read-write"), + ("pll1_postdiv1", "", "[29:28]", "read-write"), + ("pll1_postdiv2", "", "[31:30]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg44(): + return generate_register("sys_syscfg_11", "SYS SYSCONSAIF SYSCFG 44", 0x2c, [ + ("pll1_prediv", "", "[5:0]", "read-write"), + ("pll1_testen", "", "[6:6]", "read-write"), + ("pll1_testsel", "", "[8:7]", "read-write"), + ("pll2_cpi_bias", "", "[11:9]", "read-write"), + ("pll2_cpp_bias", "", "[14:12]", "read-write"), + ("pll2_dacpd", "", "[15:15]", "read-write"), + ("pll2_dsmpd", "", "[16:16]", "read-write"), + ("pll2_fbdiv", "", "[28:17]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg48(): + return generate_register("sys_syscfg_12", "SYS SYSCONSAIF SYSCFG 48", 0x30, [ + ("pll2_frac", "", "[23:0]", "read-write"), + ("pll2_gvco_bias", "", "[25:24]", "read-write"), + ("pll2_lock", "", "[26:26]", "read-only"), + ("pll2_pd", "", "[27:27]", "read-write"), + ("pll2_postdiv1", "", "[29:28]", "read-write"), + ("pll2_postdiv2", "", "[31:30]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg52(): + fields = [ + ("pll2_prediv", "", "[5:0]", "read-write"), + ("pll2_testen", "", "[6:6]", "read-write"), + ("pll2_testsel", "", "[8:7]", "read-write"), + ("pll_test_mode", "PLL test mode, only used for PLL BIST through jtag2apb", "[9:9]", "read-write"), + ("audio_i2sdin_sel", "", "[17:10]", "read-write"), + ("noc_bus_clock_gating_off", "", "[18:18]", "read-write") + ] + + for idx in range(0, 6): + fields.extend(generate_fields_noc_bus_oic_evemon(idx, 19 + (idx * 2))) + + fields.append(generate_field_noc_bus_oic_evemon("start", 6, 31, "read-write")) + + return generate_register("sys_syscfg_13", "SYS SYSCONSAIF SYSCFG 52", 0x34, fields) + +def generate_register_sysconsaif_syscfg56(): + fields = [generate_field_noc_bus_oic_evemon("trigger", 6, 0, "read-only")] + + for idx in range(7, 9): + fields.extend(generate_fields_noc_bus_oic_evemon(idx, 1 + (idx * 2))) + + for idx in range(0, 5): + name = "noc_bus_oic_ignore_modifiable_{}".format(idx) + + bit = 5 + idx + bit_range = "[{}:{}]".format(bit, bit) + + fields.append((name, "", bit_range, "read-write")) + + return generate_register("sys_syscfg_14", "SYS SYSCONSAIF SYSCFG 56", 0x38, fields) + +def generate_register_noc_bus_oic_qch_clock_stop(cfg, addr, idx): + name = "sys_syscfg_{}".format(cfg) + desc = "SYS SYSCONSAIF SYSCFG {}".format(cfg * 4) + + return generate_register(name, desc, addr, [ + ("noc_bus_oic_qch_clock_stop_threshold_{}".format(idx), "", "[31:0]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg96(): + fields = [ + ("tdm16slot_clkpol", "", "[0:0]", "read-only"), + ("tdm16slot_pcm_ms", "", "[1:1]", "read-only") + ] + + for idx in range(3): + bit = 2 + (idx * 10) + + bit_range = "[{}:{}]".format(bit + 4, bit) + fields.append(("u0_trace_mtx_in0_{}".format(idx), "", bit_range, "read-write")) + + bit_range = "[{}:{}]".format(bit + 9, bit + 5) + fields.append(("u0_trace_mtx_in1_{}".format(idx), "", bit_range, "read-write")) + + return generate_register("sys_syscfg_24", "SYS SYSCONSAIF SYSCFG 96", 0x60, fields) + +def generate_register_sysconsaif_syscfg100(): + fields = [] + for idx in range(3, 5): + bit = 0 + ((idx - 3) * 10) + + bit_range = "[{}:{}]".format(bit + 4, bit) + fields.append(("u0_trace_mtx_scfg_c{}_in0_ctl".format(idx), "", bit_range, "read-write")) + + bit_range = "[{}:{}]".format(bit + 9, bit + 5) + fields.append(("u0_trace_mtx_scfg_c{}_in1_ctl".format(idx), "", bit_range, "read-write")) + + for idx in range(0, 5): + name = "u0_cease_from_tile_{}".format(idx) + bit = 20 + idx + + fields.append((name, "", "[{}:{}]".format(bit, bit), "read-only")) + + for idx in range(0, 5): + name = "u0_halt_from_tile_{}".format(idx) + bit = 25 + idx + + fields.append((name, "", "[{}:{}]".format(bit, bit), "read-only")) + + return generate_register("sys_syscfg_25", "SYS SYSCONSAIF SYSCFG 100", 0x64, fields) + +def generate_register_sysconsaif_reset_vector(num, addr, idx, start, end, start_bit): + name = "sys_syscfg_{}".format(num) + desc = "SYS SYSCONSAIF SYSCFG {}".format(num) + fields = generate_fields_reset_vector(idx, start, end, start_bit) + + return generate_register(name, desc, addr, fields) + +def generate_register_sysconsaif_syscfg132(): + fields = generate_fields_reset_vector(4, 32, 35, 0) + + for idx in range(1, 5): + bit = 3 + idx + bit_range = "[{}:{}]".format(bit, bit) + + fields.append(("u0_suppress_fetch_{}".format(idx), "", bit_range, "read-write")) + + for idx in range(0, 5): + bit = 8 + idx + bit_range = "[{}:{}]".format(bit, bit) + + fields.append(("u0_wfi_from_tile_{}".format(idx), "", bit_range, "read-write")) + + fields.extend(generate_fields_list_sram_config("u0_vdec_intsram_sram_config", 13)) + + return generate_register("sys_syscfg_33", "SYS SYSCONSAIF SYSCFG 132", 0x84, fields) + +def generate_register_sysconsaif_syscfg136(): + fields = generate_fields_list_sram_config("u0_venc_intsram_sram_config", 0) + fields.extend([ + ("wave420l_ipu_current_buffer", "This signal indicates which buffer is currently active so that the VPU can correctly use the ipu_end_of_row signal for row counter.", "[14:12]", "read-write"), + ("wave420l_ipu_end_of_row", "This signal is flipped every time when the IPU completes writing a row.", "[15:15]", "read-write"), + ("wave420l_ipu_new_frame", "This signal is flipped every time when the IPU completes writing a new frame.", "[16:16]", "read-write"), + ("wave420l_vpu_idle", "VPU monitoring signal. This signal gives out an opposite value of VPU_BUSY register.", "[17:17]", "read-only"), + ("can_ctrl_fd_enable_1", "", "[18:18]", "read-write"), + ("can_ctrl_host_ecc_disable_1", "", "[19:19]", "read-write") + ]) + + return generate_register("sys_syscfg_34", "SYS SYSCONSAIF SYSCFG 136", 0x88, fields) + +def generate_register_sysconsaif_syscfg140(): + fields = [("can_ctrl_host_if_1", "", "[18:0]", "read-only")] + fields.extend(generate_fields_list_sram_config("u1_gmac5_axi64_scfg_ram_cfg", 19)) + + return generate_register("sys_syscfg_35", "SYS SYSCONSAIF SYSCFG 140", 0x8c, fields) + +def generate_register_sysconsaif_syscfg144(): + return generate_register("sys_syscfg_36", "SYS SYSCONSAIF SYSCFG 144", 0x90, [ + ("gmac5_axi64_mac_speed", "", "[1:0]", "read-only"), + ("gmac5_axi64_phy_intf_sel", "Active PHY Selected | When you have multiple GMAC PHY interfaces in your configuration, this field indicates the sampled value of the PHY selector during reset de-assertion. | Values: 0x0:(GMII or MII), 0x01:RGMII, 0x2:SGMII, 0x3:TBI, 0x4:RMII, 0x5:RTBI, 0x6:SMII, 0x7:REVMII", "[4:2]", "read-write") + ]) + +def generate_register_sysconsaif_syscfg148(): + return generate_register("sys_syscfg_37", "SYS SYSCONSAIF SYSCFG 148", 0x94, [ + ("gmac5_axi64_ptp_timestamp_0_31", "", "[31:0]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg152(): + return generate_register("sys_syscfg_38", "SYS SYSCONSAIF SYSCFG 152", 0x98, [ + ("gmac5_axi64_ptp_timestamp_32_63", "", "[31:0]", "read-only") + ]) + +def generate_register_sysconsaif_syscfg156(): + fields = [ + ("i2c_ic_en_1", "I2C interface enable.", "[0:0]", "read-only"), + ("sdio_data_strobe_phase_ctrl_1", "Data strobe delay chain select.", "[5:1]", "read-write"), + ("sdio_hbig_endian_1", "AHB bus interface endianness: 1: Big-endian AHB bus interface, 0: Little-endian AHB bus interface", "[6:6]", "read-write"), + ("sdio_m_hbig_endian_1", "AHB bus interface endianness: 1: Big-endian AHB bus interface, 0: Little-endian AHB bus interface", "[7:7]", "read-write"), + ("reset_ctrl_clr_reset_status_1", "", "[8:8]", "read-write"), + ("reset_ctrl_pll_timecnt_finish_1", "", "[9:9]", "read-only"), + ("reset_ctrl_rstn_sw_1", "", "[10:10]", "read-write"), + ("reset_ctrl_sys_reset_status_1", "", "[14:11]", "read-only") + ] + + for idx in range(2, 7): + bit = 13 + idx + bit_range = "[{}:{}]".format(bit, bit) + + fields.append(("i2c_ic_en_{}".format(idx), "I2C interface enable.", bit_range, "read-only")) + + return generate_register("sys_syscfg_39", "SYS SYSCONSAIF SYSCFG 156", 0x9c, fields) + +def generate_fields_noc_bus_oic_evemon(idx, bit): + return [ + generate_field_noc_bus_oic_evemon("start", idx, bit, "read-write"), + generate_field_noc_bus_oic_evemon("trigger", idx, bit + 1, "read-only") + ] + +def generate_field_noc_bus_oic_evemon(field, idx, bit, access): + name = "noc_bus_oic_evemon_{}_{}".format(field, idx) + bitfield = "[{}:{}]".format(bit, bit) + + return (name, "", bitfield, access) + +def generate_fields_reset_vector(idx, start, end, start_bit): + vectors = [int(i) for i in range(start, end + 1)] + + return [ + ( + "reset_vector_{}_{}".format(idx, vectors[i]), + "U0 U74MC Reset Vector {}: {}".format(idx, vectors[i]), + "[{}:{}]".format(start_bit + i, start_bit + i), + "read-write", + ) + for i in range(len(vectors)) + ] diff --git a/scripts/starfive_jh7110_syscrg.py b/scripts/starfive_jh7110_syscrg.py new file mode 100755 index 0000000..7579764 --- /dev/null +++ b/scripts/starfive_jh7110_syscrg.py @@ -0,0 +1,221 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for starfive JH7110 syscrg +""" + +def generate_registers_starfive_jh7110_syscrg(dts, peripheral): + """Generate xml string for registers for starfive_syscrg peripheral""" + clock_namess = peripheral.get_fields("clock-names") + cpus = dts.get_by_path("/cpus") + txt = """\ + +""" + + txt += generate_registers_mux_sel("clk_cpu_root", "Clock CPU Root", 0x0, "clk_osc, clk_pll0") + txt += generate_registers_divcfg("clk_cpu_core", "Clock CPU Core", 0x4, [7, 1, 1, 1]) + txt += generate_registers_divcfg("clk_cpu_bus", "Clock CPU Bus", 0x8, [2, 2, 2, 2]) + txt += generate_registers_mux_sel("clk_gpu_root", "Clock GPU Root", 0xc, "clk_pll2, clk_pll1") + txt += generate_registers_mux_sel_divcfg("clk_peripheral_root", "Clock Peripheral Root", 0x10, "clk_pll0, clk_pll2", [2, 2, 2, 2]) + txt += generate_registers_mux_sel("clk_bus_root", "Clock Bus Root", 0x14, "clk_osc, clk_pll2") + txt += generate_registers_divcfg("clk_nocstg_bus", "Clock NOCSTG Bus", 0x18, [3, 3, 3, 3]) + txt += generate_registers_divcfg("clk_axi_cfg0", "Clock AXI Configuration 0", 0x1c, [3, 3, 3, 3]) + txt += generate_registers_divcfg("clk_stg_axiahb", "Clock STG AXI AHB", 0x20, [2, 2, 2, 2]) + + for idx in range(0, 2): + txt += generate_registers_icg("clk_ahb{}".format(idx), "Clock AHB " + str(idx), 0x24 + (idx * 4)) + + txt += generate_registers_divcfg("clk_apb_bus", "Clock APB Bus", 0x2c, [8, 4, 4, 4]) + txt += generate_registers_icg("clk_apb0", "Clock APB 0", 0x30) + + for idx in range(0, 3): + txt += generate_registers_divcfg("clk_pll{}_div2".format(idx), "Clock PLL {} Divider 2".format(idx), 0x34 + (idx * 4), [2, 2, 2, 2]) + + txt += generate_registers_divcfg("clk_audio_root", "Clock Audio Root", 0x40, [8, 2, 2, 2]) + txt += generate_registers_divcfg("clk_mclk_inner", "Clock MCLK Inner", 0x44, [64, 12, 12, 12]) + txt += generate_registers_mux_sel("clk_mclk", "Clock MCLK", 0x48, "clk_mclk_inner, clk_mclk_ext") + txt += generate_registers_icg("clk_mclk_out", "Clock MCLK Out", 0x4c) + txt += generate_registers_mux_sel_divcfg("clk_isp_2x", "Clock ISP 2x", 0x50, "clk_pll2, clk_pll1", [8, 2, 2, 2]) + txt += generate_registers_divcfg("clk_isp_axi", "Clock ISP AXI", 0x54, [4, 2, 2, 2]) + + mdmt = [ + [62, 20, 16, 20], + [62, 16, 16, 16], + [62, 12, 12, 12], + ] + for idx in range(0, 3): + txt += generate_registers_icg_divcfg("clk_gclk_{}".format(idx), "Clock GCLK {}".format(idx), 0x58 + (idx * 4), mdmt[idx]) + + + for idx in range(0, 5): + txt += generate_registers_icg("clk_u7mc_core_{}".format(idx), "U7MC Core Clock {}".format(idx), 0x64 + (idx * 4)) + + txt += generate_registers_icg("clk_u7mc_debug", "U7MC Debug Clock", 0x78) + txt += generate_registers_divcfg("u7mc_rtc_toggle", "U7MC RTC Toggle", 0x7c, [6, 6, 6, 6]) + + for idx in range(0, 5): + txt += generate_registers_icg("clk_u7mc_trace_{}".format(idx), "U7MC Trace Clock {}".format(idx), 0x80 + (idx * 4)) + + txt += generate_registers_icg("clk_u7mc_trace_com", "U7MC Trace Clock COM", 0x94) + txt += generate_registers_icg("clk_u0_noc_bus_cpu_axi", "clk_u0_sft7110_noc_bus_clk_cpu_axi", 0x98) + txt += generate_registers_icg("clk_u0_noc_bus_axicfg0_axi", "clk_u0_sft7110_noc_bus_clk_axicfg0_axi", 0x9c) + txt += generate_registers_divcfg("clk_osc_div2", "clk_osc_div2", 0xa0, [2, 2, 2, 2]) + txt += generate_registers_divcfg("clk_pll1_div4", "clk_pll1_div4", 0xa4, [2, 2, 2, 2]) + txt += generate_registers_divcfg("clk_pll1_div8", "clk_pll1_div8", 0xa8, [2, 2, 2, 2]) + txt += generate_registers_mux_sel("clk_ddr_bus", "clk_ddr_bus", 0xac, "clk_osc_div2, clk_pll1_div4, clk_pll1_div8") + txt += generate_registers_icg("clk_u0_ddr_axi", "clk_u0_ddr_axi", 0xb0) + txt += generate_registers_divcfg("clk_gpu_core", "clk_gpu_core", 0xb4, [7, 3, 3, 3]) + txt += generate_registers_icg("clk_u0_img_gpu_core_clk", "clk_u0_img_gpu_core_clk", 0xb8) + txt += generate_registers_icg("clk_u0_img_gpu_sys_clk", "clk_u0_img_gpu_sys_clk", 0xbc) + txt += generate_registers_icg("clk_u0_img_gpu_clk_apb", "clk_u0_img_gpu_clk_apb", 0xc0) + txt += generate_registers_icg_divcfg("clk_u0_gpu_rtc_toggle", "clk_u0_gpu_rtc_toggle", 0xc4, [12, 12, 12, 12]) + txt += generate_registers_icg("clk_u0_noc_bus_gpu_axi", "clk_u0_sft7110_noc_bus_clk_gpu_axi", 0xc8) + txt += generate_registers_icg("clk_u0_isp_ispcore_2x", "clk_u0_dom_isp_top_clk_dom_isp_top_clk_ispcore_2x", 0xcc) + txt += generate_registers_icg("clk_u0_isp_axi", "clk_u0_dom_isp_top_clk_dom_isp_top_clk_isp_axi", 0xd0) + txt += generate_registers_icg("clk_u0_noc_bus_isp_axi", "clk_u0_sft7110_noc_bus_clk_isp_axi", 0xd4) + txt += generate_registers_divcfg("clk_hifi4_core", "clk_hifi4_core", 0xd8, [15, 3, 3, 3]) + txt += generate_registers_divcfg("clk_hifi4_axi", "clk_hifi4_axi", 0xdc, [2, 2, 2, 2]) + txt += generate_registers_icg("clk_u0_axi_cfg1_dec_clk_main", "clk_u0_axi_cfg1_dec_clk_main", 0xe0) + txt += generate_registers_icg("clk_u0_axi_cfg1_dec_clk_ahb", "clk_u0_axi_cfg1_dec_clk_ahb", 0xe4) + txt += generate_registers_icg("clk_u0_vout_src", "clk_u0_dom_vout_top_clk_dom_vout_top_clk_vout_src", 0xe8) + txt += generate_registers_divcfg("clk_vout_axi_divcfg", "Clock Video Output AXI DIVCFG", 0xec, [7, 2, 2, 2]) + txt += generate_registers_icg("clk_noc_display_axi", "Clock NOC Display AXI", 0xf0) + txt += generate_registers_icg("clk_vout_ahb", "Clock Video Output AHB", 0xf4) + txt += generate_registers_icg("clk_vout_axi_icg", "Clock Video Output AXI ICG", 0xf8) + txt += generate_registers_icg("clk_vout_hdmi_tx0_mclk", "Clock Video Output HDMI TX0 MCLK", 0xfc) + txt += generate_registers_divcfg("clk_vout_mipi_phy", "Clock Video Output MIPI PHY Reference", 0x100, [2, 2, 2, 2]) + txt += generate_registers_divcfg("clk_jpeg_codec_axi", "Clock JPEG Codec AXI", 0x104, [16, 6, 6, 6]) + txt += generate_registers_icg("clk_codaj12_axi", "CODAJ12 Clock AXI", 0x108) + txt += generate_registers_icg_divcfg("clk_codaj12_core", "CODAJ12 Clock Core", 0x10c, [16, 6, 6, 6]) + txt += generate_registers_icg("clk_codaj12_apb", "CODAJ12 Clock APB", 0x110) + txt += generate_registers_divcfg("clk_vdec_axi", "Clock Video Decoder AXI", 0x114, [7, 3, 3, 3]) + txt += generate_registers_icg("clk_wave511_axi", "Clock WAVE511 AXI", 0x118) + txt += generate_registers_icg_divcfg("clk_wave511_bpu", "Clock WAVE511 BPU", 0x11c, [7, 3, 3, 3]) + txt += generate_registers_icg_divcfg("clk_wave511_vce", "Clock WAVE511 VCE", 0x120, [7, 2, 3, 2]) + txt += generate_registers_icg("clk_wave511_apb", "Clock WAVE511 APB", 0x124) + txt += generate_registers_icg("clk_wave511_jpg_arb", "Clock WAVE511 JPG ARB", 0x128) + txt += generate_registers_icg("clk_wave511_jpg_main", "Clock WAVE511 JPG Main", 0x12c) + txt += generate_registers_icg("clk_noc_vdec_axi", "Clock NOC Video Decoder AXI", 0x130) + txt += generate_registers_divcfg("clk_venc_axi", "Clock Video Encoder AXI", 0x134, [15, 5, 5, 5]) + txt += generate_registers_icg("clk_wave420l_axi", "Clock WAVE420L AXI", 0x138) + txt += generate_registers_icg_divcfg("clk_wave420l_bpu", "Clock WAVE420L BPU", 0x13c, [15, 5, 5, 5]) + txt += generate_registers_icg_divcfg("clk_wave420l_vce", "Clock WAVE420L VCE", 0x140, [15, 5, 5, 5]) + txt += generate_registers_icg("clk_wave420l_apb", "Clock WAVE420L APB", 0x144) + txt += generate_registers_icg("clk_noc_venc_axi", "Clock NOC Video Encoder AXI", 0x148) + txt += generate_registers_icg("clk_axi_cfg0_dec_main_div", "Clock AXI Config 0 DEC Main Divider", 0x14c) + txt += generate_registers_icg("clk_axi_cfg0_dec_main", "Clock AXI Config 0 DEC Main", 0x150) + txt += generate_registers_icg("clk_axi_cfg0_dec_hifi4", "Clock AXI Config 0 DEC HIFI4", 0x154) + txt += generate_registers_icg("clk_aximem_128b_axi", "Clock AXIMEM 128B AXI", 0x158) + txt += generate_registers_icg("clk_qspi_ahb", "Clock QSPI AHB", 0x15c) + txt += generate_registers_icg("clk_qspi_apb", "Clock QSPI APB", 0x160) + txt += generate_registers_divcfg("clk_qspi_ref_src", "Clock QSPI Reference Source", 0x164, [16, 10, 10, 10]) + txt += generate_registers_icg_mux_sel("clk_qspi_ref", "Clock QSPI Reference", 0x168, "clk_osc, clk_qspi_ref_src") + + for idx in range(0, 2): + txt += generate_registers_icg("clk_u{}_sd_ahb".format(idx), "U{} SD Clock AHB".format(idx), 0x16c + (idx * 0x4)) + + for idx in range(0, 2): + txt += generate_registers_icg_divcfg("clk_u{}_sd_card".format(idx), "U{} SD Card Clock".format(idx), 0x174 + (idx * 0x4), [15, 2, 2, 2]) + + txt += generate_registers_divcfg("clk_usb_125m", "Clock USB 125M", 0x17c, [15, 8, 12, 10]) + txt += generate_registers_icg("clk_noc_stg_axi", "Clock NOC STG AXI", 0x180) + txt += generate_registers_icg("clk_gmac5_axi64_ahb", "Clock GMAC 5 AXI 64 AHB", 0x184) + txt += generate_registers_icg("clk_gmac5_axi64_axi", "Clock GMAC 5 AXI 64 AXI", 0x188) + txt += generate_registers_divcfg("clk_gmac_src", "Clock GMAC Source", 0x18c, [7, 2, 2, 2]) + txt += generate_registers_divcfg("clk_gmac1_gtx", "Clock GMAC 1 GTX", 0x190, [15, 8, 12, 10]) + txt += generate_registers_divcfg("clk_gmac1_rmii_rtx", "Clock GMAC 1 RMII RTX", 0x194, [30, 2, 2, 2]) + txt += generate_registers_icg_divcfg("clk_gmac5_axi64_ptp", "Clock GMAC 5 AXI 64 PTP", 0x198, [31, 10, 15, 10]) + txt += generate_registers_dly_chain_sel("clk_gmac5_axi64_rx", "Clock GMAC 5 AXI 64 RX", 0x19c) + txt += generate_registers_clk_polarity("clk_gmac5_axi64_rxi", "Clock GMAC 5 AXI 64 RX Inverter", 0x1a0) + txt += generate_registers_icg_mux_sel("clk_gmac5_axi64_tx", "Clock GMAC 5 AXI 64 TX", 0x1a4, "clk_gmac1_gtxclk, clk_gmac1_rmii_rtx") + txt += generate_registers_clk_polarity("clk_gmac5_axi64_txi", "Clock GMAC 5 AXI 64 TX Inverter", 0x1a8) + txt += generate_registers_dly_chain_sel("clk_gmac1_gtxclk", "Clock GMAC 1 GTXC", 0x1ac) + txt += generate_registers_icg_divcfg("clk_gmac0_gtx", "Clock GMAC 0 GTX", 0x1b0, [15, 8, 12, 10]) + txt += generate_registers_icg_divcfg("clk_gmac0_ptp", "Clock GMAC 0 PTP", 0x1b4, [31, 10, 15, 25]) + txt += generate_registers_icg_divcfg("clk_gmac_phy", "Clock GMAC PHY", 0x1b8, [31, 10, 15, 25]) + txt += generate_registers_dly_chain_sel("clk_gmac0_gtxclk", "Clock GMAC 0 GTXC", 0x1bc) + txt += generate_registers_icg("clk_pclk", "Clock SYS IOMUX PCLK", 0x1c0) + txt += generate_registers_icg("clk_mbox_apb", "Clock Mailbox APB", 0x1c4) + txt += generate_registers_icg("clk_internal_ctrl_apb", "Clock Internal Controller APB", 0x1c8) + + for idx in range(0, 2): + txt += generate_registers_icg("clk_u{}_can_ctrl_apb".format(idx), "U{} Clock CAN Controller APB".format(idx), 0x1cc + (idx * 0xc)) + txt += generate_registers_icg_divcfg("clk_u{}_can_ctrl_tim".format(idx), "U{} Clock CAN Controller Timer".format(idx), 0x1d0 + (idx * 0xc), [24, 24, 6, 24]) + txt += generate_registers_icg_divcfg("clk_u{}_can_ctrl_can".format(idx), "U{} Clock CAN Controller CAN".format(idx), 0x1d4 + (idx * 0xc), [63, 8, 8, 8]) + + txt += generate_registers_icg("clk_pwm_apb", "Clock PWM APB", 0x1e4) + txt += generate_registers_icg("clk_wdt_apb", "Clock WDT APB", 0x1e8) + txt += generate_registers_icg("clk_wdt", "Clock WDT", 0x1ec) + txt += generate_registers_icg("clk_tim_apb", "Clock Timer APB", 0x1f0) + + for idx in range(0, 4): + txt += generate_registers_icg("clk_tim_{}".format(idx), "Clock Timer {}".format(idx), 0x1f4 + (idx * 4)) + + txt += generate_registers_icg("clk_temp_sensor_apb", "Clock Temperature Sensor APB", 0x204) + txt += generate_registers_icg_divcfg("clk_temp_sensor", "Clock Temperature Sensor", 0x208, [24, 24, 24, 24]) + + for idx in range(0, 7): + txt += generate_registers_icg("clk_u{}_spi_apb".format(idx), "U{} Clock SPI APB".format(idx), 0x20c + (idx * 4)) + + for idx in range(0, 7): + txt += generate_registers_icg("clk_u{}_i2c_apb".format(idx), "U{} Clock I2C APB".format(idx), 0x228 + (idx * 4)) + + for idx in range(0, 3): + txt += generate_registers_icg("clk_u{}_uart_apb".format(idx), "U{} Clock UART APB".format(idx), 0x244 + (idx * 8)) + txt += generate_registers_icg("clk_u{}_uart_core".format(idx), "U{} Clock UART Core".format(idx), 0x248 + (idx * 8)) + + for idx in range(3, 6): + txt += generate_registers_icg("clk_u{}_uart_apb".format(idx), "U{} Clock UART APB".format(idx), 0x244 + (idx * 8)) + txt += generate_registers_icg_divcfg("clk_u{}_uart_core".format(idx), "U{} Clock UART Core".format(idx), 0x248 + (idx * 8), [131071, 2560, 2560, 2560]) + + txt += generate_registers_icg("clk_pwmdac_apb", "Clock PWMDAC APB", 0x274) + txt += generate_registers_icg_divcfg("clk_pwmdac_core", "Clock PWMDAC Core", 0x278, [256, 12, 12, 12]) + + txt += generate_registers_icg("clk_spdif_apb", "Clock SPDIF APB", 0x27c) + txt += generate_registers_icg("clk_spdif_core", "Clock SPDIF Core", 0x280) + + for idx in range(0, 2): + txt += generate_registers_icg("clk_u{}_i2s_tx_apb".format(idx), "U{} Clock I2S TX APB".format(idx), 0x284 + (idx * 0x1c)) + txt += generate_registers_icg_divcfg("clk_u{}_i2stx_4ch{}_bclk_mst".format(idx, idx), "U{} Clock I2S TX {} BCLK MST".format(idx, idx), 0x288 + (idx * 0x1c), [32, 4, 4, 4]) + txt += generate_registers_clk_polarity("clk_u{}_i2stx_4ch{}_bclk_mst_inv".format(idx, idx), "U{} Clock I2S TX {} BCLK MST Inverter".format(idx, idx), 0x28c + (idx * 0x1c)) + txt += generate_registers_mux_sel_divcfg("clk_i2stx{}_lrck_mst".format(idx), "Clock I2S TX {} LRCK MST".format(idx), 0x290 + (idx * 0x1c), "clk_i2stx_4ch0_bclk_mst_inv, clk_i2stx_4ch0_bclk_mst", [64, 64, 64, 64]) + txt += generate_registers_mux_sel("clk_u{}_i2stx_bclk".format(idx), "U{} Clock I2S TX BCLK".format(idx), 0x294 + (idx * 0x1c), "clk_i2stx_4ch{}_bclk_mst, clk_i2stx_bclk_ext".format(idx)) + txt += generate_registers_clk_polarity("clk_u{}_i2stx_bclk_neg".format(idx), "U{} Clock I2S TX BCLK Negative".format(idx), 0x298 + (idx * 0x1c)) + txt += generate_registers_mux_sel("clk_u{}_i2stx_lrck".format(idx), "U{} Clock I2S TX LRCK".format(idx), 0x29c + (idx * 0x1c), "clk_i2stx_4ch{}_lrck_mst, clk_i2stx_lrck_ext".format(idx)) + + txt += generate_registers_icg("clk_i2s_apb", "Clock I2S APB", 0x2bc) + txt += generate_registers_icg_divcfg("clk_i2s_bclk_mst", "Clock I2S BCLK MST", 0x2c0, [32, 4, 4, 4]) + txt += generate_registers_clk_polarity("clk_i2s_bclk_mst_inv", "Clock I2S BCLK MST Inverter", 0x2c4) + txt += generate_registers_mux_sel_divcfg("clk_i2s_lrck_mst", "Clock I2S LRCK MST", 0x2c8, "clk_i2srx_3ch_bclk_mst_inv, clk_i2srx_3ch_bclk_mst", [64, 64, 64, 64]) + txt += generate_registers_mux_sel("clk_i2s_bclk", "Clock I2S BCLK", 0x2cc, "clk_i2srx_3ch_bclk_mst, clk_i2srx_3ch_bclk_ext") + txt += generate_registers_clk_polarity("clk_i2s_bclk_neg", "Clock I2S BCLK Negative", 0x2d0) + txt += generate_registers_mux_sel("clk_i2s_lrck", "Clock I2S LRCK", 0x2d4, "clk_i2srx_3ch_lrck_mst, clk_i2srx_3ch_lrck_ext") + txt += generate_registers_icg_divcfg("clk_pdm_dmic", "Clock PDM DMIC", 0x2d8, [64, 8, 8, 8]) + + txt += generate_registers_icg("clk_pdm_apb", "Clock PDM APB", 0x2dc) + txt += generate_registers_icg("clk_tdm_ahb", "Clock TDM AHB", 0x2e0) + txt += generate_registers_icg("clk_tdm_apb", "Clock TDM APB", 0x2e4) + txt += generate_registers_icg_divcfg("clk_tdm_internal", "Clock TDM Internal", 0x2e8, [64, 1, 1, 1]) + txt += generate_registers_mux_sel("clk_tdm", "Clock TDM", 0x2ec, "clk_tdm_internal, clk_tdm_ext") + txt += generate_registers_clk_polarity("clk_tdm_neg", "Clock TDM Negative", 0x2f0) + + txt += generate_registers_divcfg("clk_jtag_trng", "Clock JTAG Certification TRNG", 0x2f4, [4, 4, 4, 4]) + + for idx in range(0, 4): + name = "soft_rst_addr_sel_{}".format(idx) + desc = "Software RESET {} Address Selector".format(idx) + txt += generate_registers_rst_sel(name, desc, idx, 0x2f8 + (idx * 4)) + + for idx in range(0, 4): + name = "syscrg_rst_status_{}".format(idx) + desc = "SYSCRG RESET Status {}".format(idx) + txt += generate_registers_rst_sel(name, desc, idx, 0x308 + (idx * 4)) + + txt += """\ + +""" + return txt diff --git a/scripts/starfive_jh7110_trng.py b/scripts/starfive_jh7110_trng.py new file mode 100755 index 0000000..7fd963b --- /dev/null +++ b/scripts/starfive_jh7110_trng.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 +# Copyleft (c) 2023 cmsis-svd-generator developers +# SPDX-License-Identifier: Apache-2.0 + +from scripts.starfive_common import * + +""" +This program generates CMSIS SVD xml for starfive JH7110 trng +""" + +def generate_registers_starfive_jh7110_trng(dts, peripheral): + """Generate xml string for registers for starfive_trng peripheral""" + + txt = """\ + +""" + + txt += generate_register_trng_ctrl("ctrl"); + txt += generate_register_trng_stat("stat"); + txt += generate_register_trng_mode("mode"); + txt += generate_register_trng_smode("smode"); + txt += generate_register_trng_ie("ie"); + txt += generate_register_trng_istat("istat"); + + for idx in range(8): + txt += generate_register_trng_rand("rand_{}".format(idx), 0x20 + (idx * 4), idx) + + txt += generate_register_trng_auto_rqsts("auto_rqsts") + txt += generate_register_trng_auto_age("auto_age") + + txt += """\ + +""" + return txt + +def generate_register_trng_ctrl(name): + """Generate xml string for starfive_jh7110_trng """ + name + """ register""" + return generate_register(name, "TRNG CTRL Register", 0x0, [ + ("exec_nop", "Execute a NOP instruction", "[0:0]", "read-write"), + ("gen_rand", "Generate a random number", "[1:1]", "read-write"), + ("reseed", "Reseed the TRNG from noise sources", "[2:2]", "read-write") + ]) + +def generate_register_trng_stat(name): + """Generate xml string for starfive_jh7110_trng """ + name + """ register""" + fields = [ + ("nonce_mode", "TRNG Nonce operating mode", "[2:2]", "read-only"), + ("r256", "TRNG 256-bit random number operating mode", "[3:3]", "read-only"), + ("mission_mode", "TRNG Mission Mode operating mode", "[8:8]", "read-only"), + ("seeded", "TRNG Seeded operating mode", "[9:9]", "read-only") + ] + + # There are 8 RAND fields + # FIXME: do these LAST_RESEED fields directly correspond to the RAND fields? + # These fields are a best-guess based on the Linux char driver + for idx in range(8): + # last reseed fields start at bit offset 16 (0x10 hex) + bit = 0x10 + idx + fields.append(( + "last_reseed_{}".format(idx), + "TRNG Last Reseed {} status".format(idx), + "[{}:{}]".format(bit, bit), + "read-only" + )) + + fields.extend([ + ("srvc_rqst", "TRNG Service Request", "[27:27]", "read-only"), + ("rand_generating", "TRNG Random Number Generating Status", "[30:30]", "read-only"), + ("rand_seeding", "TRNG Random Number Seeding Status", "[31:31]", "read-only") + ]) + + return generate_register(name, "TRNG STAT Register", 0x4, fields) + +def generate_register_trng_mode(name): + """Generate xml string for starfive_jh7110_trng """ + name + """ register""" + return generate_register(name, "TRNG MODE Register", 0x8, [ + ("r256", "256-bit operation mode: 0 - 128-bit mode, 1 - 256-bit mode", "[3:3]", "read-write") + ]) + +def generate_register_trng_smode(name): + """Generate xml string for starfive_jh7110_trng """ + name + """ register""" + return generate_register(name, "TRNG SMODE Register", 0xc, [ + ("nonce_mode", "Nonce operation mode", "[2:2]", "read-write"), + ("mission_mode", "Mission operation mode", "[8:8]", "read-write"), + ("max_rejects", "TRNG Maximum Rejects", "[31:16]", "read-write") + ]) + +def generate_register_trng_ie(name): + """Generate xml string for starfive_jh7110_trng """ + name + """ register""" + return generate_register(name, "TRNG Interrupt Enable Register", 0x10, [ + ("rand_rdy_en", "RAND Ready Enable", "[0:0]", "read-write"), + ("seed_done_en", "Seed Done Enable", "[1:1]", "read-write"), + ("lfsr_lockup_en", "LFSR Lockup Enable", "[4:4]", "read-write"), + ("glbl_en", "Global Enable", "[31:31]", "read-write") + ]) + +def generate_register_trng_istat(name): + """Generate xml string for starfive_jh7110_trng """ + name + """ register""" + return generate_register(name, "TRNG Interrupt Status Register", 0x14, [ + ("rand_rdy", "RAND Ready Enable", "[0:0]", "read-only"), + ("seed_done", "Seed Done Enable", "[1:1]", "read-only"), + ("lfsr_lockup_en", "LFSR Lockup Enable", "[4:4]", "read-only") + ]) + +def generate_register_trng_rand(name, addr, idx): + """Generate xml string for starfive_jh7110_trng """ + name + """ register""" + return generate_register(name, "TRNG RAND {} Status Register".format(idx), addr, [("rand", "Random number bits", "[31:0]", "read-only")]) + +def generate_register_trng_auto_rqsts(name): + """Generate xml string for starfive_jh7110_trng """ + name + """ register""" + return generate_register( + name, + "Auto-reseeding after random number requests by host reaches specified counter: 0 - disable counter, other - reload value for internal counter", + 0x60, + [("rqsts", "Threshold number of reseed requests for auto-reseed counter", "[31:0]", "read-write")], + ) + +def generate_register_trng_auto_age(name): + """Generate xml string for starfive_jh7110_trng """ + name + """ register""" + return generate_register( + name, + "Auto-reseeding after specified timer countdowns to 0: 0 - disable timer, other - reload value for internal timer", + 0x64, + [("age", "Countdown value for auto-reseed timer", "[31:0]", "read-write")], + )